LUAEditorMainWindow.cpp 91 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524
  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 <AzCore/PlatformIncl.h>
  9. #include "LUAEditorMainWindow.hxx"
  10. #include <AzCore/Component/TickBus.h>
  11. #include <AzCore/Debug/Trace.h>
  12. #include <AzCore/IO/Path/Path.h>
  13. #include <AzCore/Script/ScriptAsset.h>
  14. #include <AzCore/Settings/SettingsRegistryMergeUtils.h>
  15. #include <AzCore/UserSettings/UserSettings.h>
  16. #include <AzCore/Utils/Utils.h>
  17. #include <AzCore/std/containers/map.h>
  18. #include <AzCore/std/delegate/delegate.h>
  19. #include <AzFramework/Script/ScriptRemoteDebuggingConstants.h>
  20. #include <AzFramework/StringFunc/StringFunc.h>
  21. #include <AzToolsFramework/AssetBrowser/AssetBrowserBus.h>
  22. #include <AzToolsFramework/AssetBrowser/AssetBrowserFilterModel.h>
  23. #include <AzToolsFramework/AssetBrowser/AssetBrowserModel.h>
  24. #include <AzToolsFramework/AssetBrowser/AssetSelectionModel.h>
  25. #include <AzToolsFramework/AssetBrowser/Entries/SourceAssetBrowserEntry.h>
  26. #include <AzToolsFramework/AssetBrowser/Views/AssetBrowserTreeView.h>
  27. #include <AzToolsFramework/UI/LegacyFramework/Core/EditorFrameworkAPI.h>
  28. #include <AzToolsFramework/UI/LegacyFramework/CustomMenus/CustomMenusAPI.h>
  29. #include <AzToolsFramework/UI/LegacyFramework/MainWindowSavedState.h>
  30. #include <AzToolsFramework/UI/UICore/ProgressShield.hxx>
  31. #include <AzToolsFramework/UI/UICore/SaveChangesDialog.hxx>
  32. #include <AzToolsFramework/UI/UICore/TargetSelectorButton.hxx>
  33. #include <AzToolsFramework/UI/UICore/WidgetHelpers.h>
  34. #include <Source/LUA/LUAEditorDebuggerMessages.h>
  35. #include <Source/LUA/TargetContextButton.hxx>
  36. #include "ClassReferenceFilter.hxx"
  37. #include "DebugAttachmentButton.hxx"
  38. #include "LUABreakpointTrackerMessages.h"
  39. #include "LUAEditorContextMessages.h"
  40. #include "LUAEditorGoToLineDialog.hxx"
  41. #include "LUAEditorSettingsDialog.hxx"
  42. #include "LUAEditorView.hxx"
  43. #include "RecentFiles.h"
  44. #include "WatchesPanel.hxx"
  45. #include <AzCore/Component/ComponentApplicationBus.h>
  46. #include <AzQtComponents/Components/FilteredSearchWidget.h>
  47. #include <AzQtComponents/Components/StyleManager.h>
  48. #include <Source/AssetDatabaseLocationListener.h>
  49. #include <Source/LUA/ui_LUAEditorMainWindow.h>
  50. #include <QBoxLayout>
  51. #include <QDesktopServices>
  52. #include <QDir>
  53. #include <QFileDialog>
  54. #include <QLabel>
  55. #include <QMessageBox>
  56. #include <QString>
  57. #include <QTimer>
  58. void initSharedResources()
  59. {
  60. Q_INIT_RESOURCE(sharedResources);
  61. }
  62. namespace
  63. {
  64. [[maybe_unused]] const char* LUAEditorDebugName = "LUA Debug";
  65. [[maybe_unused]] const char* LUAEditorInfoName = "LUA Editor";
  66. }
  67. namespace LUAEditor
  68. {
  69. extern AZ::Uuid ContextID;
  70. //////////////////////////////////////////////////////////////////////////
  71. //LUAEditorMainWindow
  72. LUAEditorMainWindow::LUAEditorMainWindow(QStandardItemModel* dataModel, bool connectedState, QWidget* parent, Qt::WindowFlags flags)
  73. : QMainWindow(parent, flags)
  74. , m_lastFocusedAssetId()
  75. , m_ptrFindDialog(nullptr)
  76. , m_settingsDialog(nullptr)
  77. , m_actionClearRecentFiles(nullptr)
  78. {
  79. initSharedResources();
  80. auto settingsRegistry = AZ::SettingsRegistry::Get();
  81. AZ::IO::FixedMaxPath engineRootPath;
  82. settingsRegistry->Get(engineRootPath.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_EngineRootFolder);
  83. AzQtComponents::StyleManager* m_styleSheet = new AzQtComponents::StyleManager(this);
  84. m_styleSheet->initialize(qApp, engineRootPath);
  85. LUAViewMessages::Bus::Handler::BusConnect();
  86. //m_currentTabContextMenuUUID = AZ::Uuid::CreateNull();
  87. m_gui = azcreate(Ui::LUAEditorMainWindow, ());
  88. m_gui->setupUi(this);
  89. setAcceptDrops(true);
  90. m_bIgnoreFocusRequests = false;
  91. m_bAutocompleteEnabled = true; // the default
  92. QMenu* theMenu = new QMenu(this);
  93. (void)theMenu->addAction(
  94. "Close Lua Editor App",
  95. this,
  96. SLOT(OnMenuCloseCurrentWindow()),
  97. QKeySequence("Alt+F4")
  98. );
  99. AzToolsFramework::FrameworkMessages::Bus::Broadcast(
  100. &AzToolsFramework::FrameworkMessages::Bus::Events::PopulateApplicationMenu, theMenu);
  101. menuBar()->insertMenu(m_gui->menuFile->menuAction(), theMenu);
  102. m_ptrFindDialog = aznew LUAEditorFindDialog(this);
  103. m_settingsDialog = aznew LUAEditorSettingsDialog(this);
  104. actionTabForwards = new QAction(tr("Next Document Tab"), this);
  105. actionTabBackwards = new QAction(tr("Previous Document Tab"), this);
  106. actionTabForwards->setShortcut(QKeySequence("Ctrl+Tab"));
  107. connect(actionTabForwards, SIGNAL(triggered(bool)), this, SLOT(OnTabForwards()));
  108. actionTabBackwards->setShortcut(QKeySequence("Ctrl+Shift+Tab"));
  109. connect(actionTabBackwards, SIGNAL(triggered(bool)), this, SLOT(OnTabBackwards()));
  110. m_gui->menuView->addAction(actionTabForwards);
  111. m_gui->menuView->addAction(actionTabBackwards);
  112. connect(m_gui->m_findResults1, &FindResults::ResultSelected, this, &LUAEditorMainWindow::OnFindResultClicked);
  113. connect(m_gui->m_findResults2, &FindResults::ResultSelected, this, &LUAEditorMainWindow::OnFindResultClicked);
  114. connect(m_gui->m_findResults3, &FindResults::ResultSelected, this, &LUAEditorMainWindow::OnFindResultClicked);
  115. connect(m_gui->m_findResults4, &FindResults::ResultSelected, this, &LUAEditorMainWindow::OnFindResultClicked);
  116. m_gui->findTabWidget->setCurrentIndex(0);
  117. connect(m_gui->actionCut, SIGNAL(triggered()), this, SLOT(OnEditMenuCut()));
  118. connect(m_gui->actionCopy, SIGNAL(triggered()), this, SLOT(OnEditMenuCopy()));
  119. connect(m_gui->actionSettings, SIGNAL(triggered()), this, SLOT(OnSettings()));
  120. connect(m_gui->actionLuaDocumentation, SIGNAL(triggered()), this, SLOT(OnLuaDocumentation()));
  121. m_gui->localsTreeView->SetOperatingMode(WATCHES_MODE_LOCALS);
  122. m_gui->m_logPanel->SetStorageID(AZ_CRC_CE("LUA Editor Log Panel"));
  123. connect(m_gui->m_logPanel, &AzToolsFramework::LogPanel::BaseLogPanel::TabsReset, this, &LUAEditorMainWindow::OnLogTabsReset);
  124. //m_lastProgramCounterAssetId = "";
  125. QMainWindow* pCentralWidget = new QMainWindow();
  126. setCentralWidget(pCentralWidget);
  127. pCentralWidget->setTabPosition(Qt::AllDockWidgetAreas, QTabWidget::North);
  128. pCentralWidget->setDockOptions(AllowNestedDocks | AllowTabbedDocks | AnimatedDocks);
  129. this->setTabPosition(Qt::AllDockWidgetAreas, QTabWidget::North);
  130. m_pTargetButton = aznew AzToolsFramework::TargetSelectorButtonAction(AzFramework::LuaToolsKey, this);
  131. m_gui->debugToolbar->addAction(m_pTargetButton);
  132. m_gui->menuDebug->addAction(m_pTargetButton);
  133. m_pContextButton = aznew LUA::TargetContextButtonAction(this);
  134. m_gui->debugToolbar->addAction(m_pContextButton);
  135. m_gui->menuDebug->addAction(m_pContextButton);
  136. m_pContextButton->setEnabled(false);
  137. m_pDebugAttachmentButton = aznew LUAEditor::DebugAttachmentButtonAction(this);
  138. m_gui->debugToolbar->addAction(m_pDebugAttachmentButton);
  139. m_gui->menuDebug->addAction(m_pDebugAttachmentButton);
  140. m_pDebugAttachmentButton->setEnabled(false);
  141. //turn these off by default
  142. m_settingsDialog->hide();
  143. m_ptrFindDialog->hide();
  144. m_gui->watchDockWidget->hide();
  145. m_gui->stackDockWidget->hide();
  146. m_gui->localsDockWidget->hide();
  147. m_gui->breakpointsDockWidget->hide();
  148. m_gui->findResultsDockWidget->hide();
  149. m_remoteToolsEndpointJoinedHandler = AzFramework::RemoteToolsEndpointStatusEvent::Handler(
  150. [this]([[maybe_unused]] AzFramework::RemoteToolsEndpointInfo info)
  151. {
  152. OnRemoteToolsEndpointListChanged();
  153. });
  154. m_remoteToolsEndpointLeftHandler = AzFramework::RemoteToolsEndpointStatusEvent::Handler(
  155. [this]([[maybe_unused]] AzFramework::RemoteToolsEndpointInfo info)
  156. {
  157. OnRemoteToolsEndpointListChanged();
  158. });
  159. if (auto* remoteToolsInterface = AzFramework::RemoteToolsInterface::Get())
  160. {
  161. remoteToolsInterface->RegisterRemoteToolsEndpointJoinedHandler(AzFramework::LuaToolsKey, m_remoteToolsEndpointJoinedHandler);
  162. remoteToolsInterface->RegisterRemoteToolsEndpointLeftHandler(AzFramework::LuaToolsKey, m_remoteToolsEndpointLeftHandler);
  163. }
  164. OnRemoteToolsEndpointListChanged();
  165. QTimer::singleShot(0, this, SLOT(RestoreWindowState()));
  166. m_gui->watchDockWidget->toggleViewAction()->setIcon(QIcon(":/general/watch_window"));
  167. m_gui->stackDockWidget->toggleViewAction()->setIcon(QIcon(":/general/callstack"));
  168. m_gui->localsDockWidget->toggleViewAction()->setIcon(QIcon(":/general/lua_locals"));
  169. m_gui->breakpointsDockWidget->toggleViewAction()->setIcon(QIcon(":/general/breakpoints"));
  170. m_gui->findResultsDockWidget->toggleViewAction()->setIcon(QIcon(":/general/find_results"));
  171. //construct the viewToolBar and menuView from toggle view actions
  172. m_gui->viewToolBar->addAction(m_gui->watchDockWidget->toggleViewAction());
  173. m_gui->viewToolBar->addAction(m_gui->breakpointsDockWidget->toggleViewAction());
  174. m_gui->viewToolBar->addAction(m_gui->stackDockWidget->toggleViewAction());
  175. m_gui->viewToolBar->addAction(m_gui->localsDockWidget->toggleViewAction());
  176. m_gui->viewToolBar->addAction(m_gui->findResultsDockWidget->toggleViewAction());
  177. m_gui->menuView->addAction(m_gui->watchDockWidget->toggleViewAction());
  178. m_gui->menuView->addAction(m_gui->breakpointsDockWidget->toggleViewAction());
  179. m_gui->menuView->addAction(m_gui->stackDockWidget->toggleViewAction());
  180. m_gui->menuView->addAction(m_gui->localsDockWidget->toggleViewAction());
  181. m_gui->menuView->addAction(m_gui->findResultsDockWidget->toggleViewAction());
  182. m_gui->menuView->addAction(m_gui->classReferenceDockWidget->toggleViewAction());
  183. m_gui->menuView->addAction(m_gui->m_dockLog->toggleViewAction());
  184. m_gui->menuView->addAction(m_gui->luaFilesDockWidget->toggleViewAction());
  185. LUAEditorMainWindowMessages::Handler::BusConnect();
  186. LUABreakpointTrackerMessages::Handler::BusConnect();
  187. Context_DebuggerManagement::Bus::Broadcast(&Context_DebuggerManagement::Bus::Events::CleanUpBreakpoints);
  188. SetDebugControlsToInitial();
  189. SetEditContolsToNoFilesOpen();
  190. // whats the current target anyway?
  191. // dataModel is the sole point of contact between our Context and its LUA debugger class information
  192. m_ClassReferenceFilter = aznew ClassReferenceFilterModel(this);
  193. m_ClassReferenceFilter->setSourceModel(dataModel);
  194. m_gui->classReferenceTreeView->setModel(m_ClassReferenceFilter);
  195. connect(m_gui->m_searchWidget, &AzQtComponents::FilteredSearchWidget::TextFilterChanged, this, &LUAEditorMainWindow::luaClassFilterTextChanged);
  196. connect(m_gui->actionOpen, SIGNAL(triggered(bool)), this, SLOT(OnFileMenuOpen()));
  197. UpdateOpenRecentMenu();
  198. connect(m_gui->actionAutocomplete, SIGNAL(triggered(bool)), this, SLOT(OnAutocompleteChanged(bool)));
  199. auto newState = AZ::UserSettings::CreateFind<LUAEditorMainWindowSavedState>(AZ_CRC_CE("LUA EDITOR MAIN WINDOW STATE"), AZ::UserSettings::CT_LOCAL);
  200. m_gui->actionAutoReloadUnmodifiedFiles->setChecked(newState->m_bAutoReloadUnmodifiedFiles);
  201. connect(m_gui->actionAutoReloadUnmodifiedFiles, &QAction::triggered, this, [](bool newValue)
  202. {
  203. auto newState = AZ::UserSettings::CreateFind<LUAEditorMainWindowSavedState>(AZ_CRC_CE("LUA EDITOR MAIN WINDOW STATE"), AZ::UserSettings::CT_LOCAL);
  204. newState->m_bAutoReloadUnmodifiedFiles = newValue;
  205. });
  206. connect(this, &LUAEditorMainWindow::OnReferenceDataChanged, this, [this]() {
  207. luaClassFilterTextChanged(m_ClassReferenceFilter->GetFilter());
  208. if (auto* view = GetCurrentView())
  209. {
  210. // Update syntax highlighting now that the project libraries are loaded
  211. view->UpdateFont();
  212. }
  213. });
  214. // preset our running state based on outside conditions when we are created
  215. if (connectedState)
  216. {
  217. OnConnectedToTarget();
  218. }
  219. else
  220. {
  221. OnDisconnectedFromTarget();
  222. }
  223. {
  224. // an attempt to make this all more readable!
  225. using namespace AzToolsFramework;
  226. typedef FrameworkMessages::Bus HotkeyBus;
  227. HotkeyBus::Broadcast(&HotkeyBus::Events::RegisterActionToHotkey, AZ_CRC_CE("LUALinesUpTranspose"), m_gui->actionLinesUpTranspose);
  228. HotkeyBus::Broadcast(&HotkeyBus::Events::RegisterActionToHotkey, AZ_CRC_CE("LUALinesDnTranspose"), m_gui->actionLinesDnTranspose);
  229. HotkeyBus::Broadcast(&HotkeyBus::Events::RegisterActionToHotkey, AZ_CRC_CE("GeneralOpenAssetBrowser"), m_gui->actionOpen);
  230. HotkeyBus::Broadcast(&HotkeyBus::Events::RegisterActionToHotkey, AZ_CRC_CE("LUAFind"), m_gui->actionFind);
  231. HotkeyBus::Broadcast(&HotkeyBus::Events::RegisterActionToHotkey, AZ_CRC_CE("LUAQuickFindLocal"), m_gui->actionFindLocal);
  232. HotkeyBus::Broadcast(&HotkeyBus::Events::RegisterActionToHotkey, AZ_CRC_CE("LUAQuickFindLocalReverse"), m_gui->actionFindLocalReverse);
  233. HotkeyBus::Broadcast(&HotkeyBus::Events::RegisterActionToHotkey, AZ_CRC_CE("LUAFindInFiles"), m_gui->actionFindInAllOpen);
  234. HotkeyBus::Broadcast(&HotkeyBus::Events::RegisterActionToHotkey, AZ_CRC_CE("LUAReplace"), m_gui->actionReplace);
  235. HotkeyBus::Broadcast(&HotkeyBus::Events::RegisterActionToHotkey, AZ_CRC_CE("LUAReplaceInFiles"), m_gui->actionReplaceInAllOpen);
  236. HotkeyBus::Broadcast(&HotkeyBus::Events::RegisterActionToHotkey, AZ_CRC_CE("LUAGoToLine"), m_gui->actionGoToLine);
  237. HotkeyBus::Broadcast(&HotkeyBus::Events::RegisterActionToHotkey, AZ_CRC_CE("LUAFold"), m_gui->actionFoldAll);
  238. HotkeyBus::Broadcast(&HotkeyBus::Events::RegisterActionToHotkey, AZ_CRC_CE("LUAUnfold"), m_gui->actionUnfoldAll);
  239. HotkeyBus::Broadcast(&HotkeyBus::Events::RegisterActionToHotkey, AZ_CRC_CE("LUACloseAllExceptCurrent"), m_gui->actionCloseAllExcept);
  240. HotkeyBus::Broadcast(&HotkeyBus::Events::RegisterActionToHotkey, AZ_CRC_CE("LUACloseAll"), m_gui->actionCloseAll);
  241. HotkeyBus::Broadcast(&HotkeyBus::Events::RegisterActionToHotkey, AZ_CRC_CE("LUAComment"), m_gui->actionComment_Selected_Block);
  242. HotkeyBus::Broadcast(&HotkeyBus::Events::RegisterActionToHotkey, AZ_CRC_CE("LUAUncomment"), m_gui->actionUnComment_Selected_Block);
  243. HotkeyBus::Broadcast(&HotkeyBus::Events::RegisterActionToHotkey, AZ_CRC_CE("LUAResetZoom"), m_gui->actionResetZoom);
  244. }
  245. //m_StoredTabAssetId = AZ::Uuid::CreateNull();
  246. installEventFilter(this);
  247. LegacyFramework::CustomMenusMessages::Bus::Broadcast(&LegacyFramework::CustomMenusMessages::Bus::Events::RegisterMenu, LegacyFramework::CustomMenusCommon::LUAEditor::Application, theMenu);
  248. LegacyFramework::CustomMenusMessages::Bus::Broadcast(&LegacyFramework::CustomMenusMessages::Bus::Events::RegisterMenu, LegacyFramework::CustomMenusCommon::LUAEditor::File, m_gui->menuFile);
  249. LegacyFramework::CustomMenusMessages::Bus::Broadcast(&LegacyFramework::CustomMenusMessages::Bus::Events::RegisterMenu, LegacyFramework::CustomMenusCommon::LUAEditor::Edit, m_gui->menuEdit);
  250. LegacyFramework::CustomMenusMessages::Bus::Broadcast(&LegacyFramework::CustomMenusMessages::Bus::Events::RegisterMenu, LegacyFramework::CustomMenusCommon::LUAEditor::View, m_gui->menuView);
  251. LegacyFramework::CustomMenusMessages::Bus::Broadcast(&LegacyFramework::CustomMenusMessages::Bus::Events::RegisterMenu, LegacyFramework::CustomMenusCommon::LUAEditor::Debug, m_gui->menuDebug);
  252. LegacyFramework::CustomMenusMessages::Bus::Broadcast(&LegacyFramework::CustomMenusMessages::Bus::Events::RegisterMenu, LegacyFramework::CustomMenusCommon::LUAEditor::SourceControl, m_gui->menuSource_Control);
  253. LegacyFramework::CustomMenusMessages::Bus::Broadcast(&LegacyFramework::CustomMenusMessages::Bus::Events::RegisterMenu, LegacyFramework::CustomMenusCommon::LUAEditor::Options, m_gui->menu_Options);
  254. QObject::connect(m_gui->menu_Options, &QMenu::aboutToShow, this, &LUAEditorMainWindow::OnOptionsMenuRequested);
  255. connect(m_gui->m_logPanel, &AzToolsFramework::LogPanel::TracePrintFLogPanel::LogLineSelected, this, &LUAEditorMainWindow::LogLineSelectionChanged);
  256. }
  257. void LUAEditorMainWindow::OnOptionsMenuRequested()
  258. {
  259. m_gui->actionAutocomplete->blockSignals(true);
  260. m_gui->actionAutocomplete->setCheckable(true);
  261. m_gui->actionAutocomplete->setChecked(m_bAutocompleteEnabled);
  262. m_gui->actionAutocomplete->blockSignals(false);
  263. }
  264. void LUAEditorMainWindow::UpdateOpenRecentMenu()
  265. {
  266. const QStringList recentFiles = ReadRecentFiles();
  267. QList<QAction*> actions = m_gui->menuOpenRecent->actions();
  268. for (int i = actions.size() - 1; i >= 0; i--)
  269. {
  270. m_gui->menuOpenRecent->removeAction(actions[i]);
  271. }
  272. for (auto& fileName : recentFiles)
  273. {
  274. QAction* action = new QAction(fileName, this);
  275. connect(
  276. action,
  277. &QAction::triggered,
  278. this,
  279. [fileName]([[maybe_unused]] bool checked)
  280. {
  281. constexpr bool errorOnNotFound = true;
  282. Context_DocumentManagement::Bus::Broadcast(
  283. &Context_DocumentManagement::Bus::Events::OnLoadDocument, fileName.toStdString().c_str(), errorOnNotFound);
  284. });
  285. m_gui->menuOpenRecent->addAction(action);
  286. }
  287. m_gui->menuOpenRecent->addSeparator();
  288. m_actionClearRecentFiles = new QAction("Clear Recent Files", this);
  289. connect(
  290. m_actionClearRecentFiles,
  291. &QAction::triggered,
  292. this,
  293. [this]([[maybe_unused]] bool checked)
  294. {
  295. ClearRecentFile();
  296. UpdateOpenRecentMenu();
  297. });
  298. m_gui->menuOpenRecent->addAction(m_actionClearRecentFiles);
  299. m_gui->menuOpenRecent->setEnabled(!recentFiles.isEmpty());
  300. m_actionClearRecentFiles->setEnabled(!recentFiles.isEmpty());
  301. }
  302. LUAEditorMainWindow::~LUAEditorMainWindow(void)
  303. {
  304. removeEventFilter(this);
  305. LUAViewMessages::Bus::Handler::BusDisconnect();
  306. //ClientInterface::Handler::BusDisconnect();
  307. LUAEditorMainWindowMessages::Handler::BusDisconnect();
  308. LUABreakpointTrackerMessages::Handler::BusDisconnect();
  309. azdestroy(m_gui);
  310. delete m_assetDatabaseListener;
  311. m_assetDatabaseListener = nullptr;
  312. }
  313. void LUAEditorMainWindow::SetupLuaFilesPanel()
  314. {
  315. if (m_assetDatabaseListener != nullptr)
  316. {
  317. // We have already setup the panel, so nothing to do
  318. return;
  319. }
  320. AZStd::string cacheRoot;
  321. bool cacheRootFound = false;
  322. AzToolsFramework::AssetSystemRequestBus::BroadcastResult(cacheRootFound, &AzToolsFramework::AssetSystemRequestBus::Events::GetAbsoluteAssetDatabaseLocation, cacheRoot);
  323. if (!cacheRootFound)
  324. {
  325. return;
  326. }
  327. m_assetDatabaseListener = new AssetDatabaseLocationListener();
  328. m_assetDatabaseListener->Init(cacheRoot.c_str());
  329. AZ::Data::AssetCatalogRequestBus::Broadcast(&AZ::Data::AssetCatalogRequests::StartMonitoringAssets);
  330. // Get the asset browser model
  331. AzToolsFramework::AssetBrowser::AssetBrowserModel* assetBrowserModel = nullptr;
  332. AzToolsFramework::AssetBrowser::AssetBrowserComponentRequestBus::BroadcastResult(assetBrowserModel, &AzToolsFramework::AssetBrowser::AssetBrowserComponentRequests::GetAssetBrowserModel);
  333. AZ_Assert(assetBrowserModel, "Failed to get filebrowser model");
  334. // Hook up the data set to the tree view
  335. m_filterModel = aznew AzToolsFramework::AssetBrowser::AssetBrowserFilterModel(this);
  336. m_filterModel->setSourceModel(assetBrowserModel);
  337. // Delay the setting of the filter until everything can be initialized
  338. QTimer::singleShot(1000, [this]()
  339. {
  340. m_filterModel->SetFilter(CreateFilter());
  341. });
  342. m_gui->m_assetBrowserTreeView->setModel(m_filterModel);
  343. m_gui->m_assetBrowserTreeView->SetShowSourceControlIcons(true);
  344. m_gui->m_assetBrowserTreeView->setSelectionMode(QAbstractItemView::SelectionMode::SingleSelection);
  345. // Maintains the tree expansion state between runs
  346. m_gui->m_assetBrowserTreeView->SetName("LuaIDETreeView");
  347. connect(m_gui->m_assetBrowserTreeView, &QTreeView::doubleClicked, this, [this](const QModelIndex&)
  348. {
  349. auto selectedAssets = m_gui->m_assetBrowserTreeView->GetSelectedAssets();
  350. if (selectedAssets.size() == 1)
  351. {
  352. auto selectedAsset = selectedAssets.front();
  353. const AZStd::string filePath = selectedAsset->GetFullPath();
  354. auto entryType = selectedAsset->GetEntryType();
  355. if (entryType == AzToolsFramework::AssetBrowser::AssetBrowserEntry::AssetEntryType::Source)
  356. {
  357. Context_DocumentManagement::Bus::Broadcast(&Context_DocumentManagement::Bus::Events::OnLoadDocument, filePath, true);
  358. }
  359. }
  360. });
  361. }
  362. QSharedPointer<AzToolsFramework::AssetBrowser::CompositeFilter> LUAEditorMainWindow::CreateFilter()
  363. {
  364. using namespace AzToolsFramework::AssetBrowser;
  365. // Only look at Script Assets (.lua files)
  366. // Propagate this down to cover all the parents of a script asset
  367. AssetTypeFilter* assetFilter = new AssetTypeFilter();
  368. assetFilter->SetAssetType(AZ::AzTypeInfo<AZ::ScriptAsset>::Uuid());
  369. assetFilter->SetFilterPropagation(AssetTypeFilter::PropagateDirection::Down);
  370. // We only care about sources (not products)
  371. // Do not propagate this at all
  372. EntryTypeFilter* entryTypeFilter = new EntryTypeFilter();
  373. entryTypeFilter->SetEntryType(AssetBrowserEntry::AssetEntryType::Source);
  374. entryTypeFilter->SetFilterPropagation(AssetTypeFilter::PropagateDirection::None);
  375. // Add in a string filter that comes from user input
  376. StringFilter* stringFilter = new StringFilter();
  377. stringFilter->SetFilterPropagation(AssetTypeFilter::PropagateDirection::Up);
  378. connect(m_gui->m_assetBrowserSearchWidget, &AzQtComponents::FilteredSearchWidget::TextFilterChanged, this, [&, stringFilter](const QString& newString)
  379. {
  380. stringFilter->SetFilterString(newString);
  381. if (newString.isEmpty())
  382. {
  383. m_gui->m_assetBrowserTreeView->collapseAll();
  384. }
  385. else
  386. {
  387. m_gui->m_assetBrowserTreeView->expandAll();
  388. }
  389. });
  390. // Construct the final filter where they are all and'd together
  391. // Propagate the final filter down so that any matches will show the hierarchy of folders down to the appropriate matching leaf node
  392. QSharedPointer<CompositeFilter> finalFilter(new CompositeFilter(CompositeFilter::LogicOperatorType::AND));
  393. finalFilter->AddFilter(FilterConstType(stringFilter));
  394. finalFilter->AddFilter(FilterConstType(assetFilter));
  395. finalFilter->AddFilter(FilterConstType(entryTypeFilter));
  396. finalFilter->SetFilterPropagation(AssetTypeFilter::PropagateDirection::Down);
  397. return finalFilter;
  398. }
  399. void LUAEditorMainWindow::OnSettings()
  400. {
  401. m_settingsDialog->show();
  402. }
  403. void LUAEditorMainWindow::OnLuaDocumentation()
  404. {
  405. QDesktopServices::openUrl(QUrl("https://o3de.org/docs/user-guide/scripting/lua/"));
  406. }
  407. void LUAEditorMainWindow::OnMenuCloseCurrentWindow()
  408. {
  409. AzToolsFramework::FrameworkMessages::Bus::Broadcast(
  410. &AzToolsFramework::FrameworkMessages::Bus::Events::RequestMainWindowClose, ContextID);
  411. }
  412. void LUAEditorMainWindow::OnAutocompleteChanged(bool change)
  413. {
  414. m_bAutocompleteEnabled = change;
  415. m_gui->actionAutocomplete->blockSignals(true);
  416. m_gui->actionAutocomplete->setCheckable(true);
  417. m_gui->actionAutocomplete->setChecked(m_bAutocompleteEnabled);
  418. m_gui->actionAutocomplete->blockSignals(false);
  419. for (TrackedLUAViewMap::iterator viewInfoIter = m_dOpenLUAView.begin(); viewInfoIter != m_dOpenLUAView.end(); ++viewInfoIter)
  420. {
  421. TrackedLUAView& viewInfo = viewInfoIter->second;
  422. viewInfo.luaViewWidget()->SetAutoCompletionEnabled(m_bAutocompleteEnabled);
  423. }
  424. //AZ_TracePrintf("LUA","change %d",change);
  425. }
  426. //////////////////////////////////////////////////////////////////////////
  427. void LUAEditorMainWindow::OnOpenLUAView(const DocumentInfo& docInfo)
  428. {
  429. //char output[64];
  430. //docInfo.m_assetId.ToString(output,AZ_ARRAY_SIZE(output),true,true);
  431. //AZ_TracePrintf(LUAEditorDebugName, AZStd::string::format("OnOpenLuaView %s = %s\n", (docInfo.m_assetName + ".lua").c_str(), output).c_str());
  432. show();
  433. //set focus if already created
  434. TrackedLUAViewMap::iterator viewIter = m_dOpenLUAView.find(docInfo.m_assetId);
  435. if (viewIter != m_dOpenLUAView.end())
  436. {
  437. viewIter->second.luaDockWidget()->show();
  438. viewIter->second.luaDockWidget()->raise();
  439. viewIter->second.luaViewWidget()->setFocus();
  440. return;
  441. }
  442. setAnimated(false);
  443. //make a new one
  444. LUADockWidget* luaDockWidget = aznew LUADockWidget(this->centralWidget());
  445. luaDockWidget->setFeatures(QDockWidget::DockWidgetClosable | QDockWidget::DockWidgetMovable);//do not add floatable!
  446. luaDockWidget->setAssetId(docInfo.m_assetId);
  447. QWidget* luaLayout = new QWidget();
  448. luaLayout->setLayout(aznew LUAEditorMainWindowLayout(luaLayout));
  449. luaLayout->layout()->setContentsMargins(0, 0, 0, 0);
  450. LUAViewWidget* luaViewWidget = aznew LUAViewWidget();
  451. luaViewWidget->SetLuaDockWidget(luaDockWidget);
  452. luaDockWidget->setObjectName(QString::fromUtf8(docInfo.m_displayName.c_str()));
  453. luaViewWidget->setObjectName(QString::fromUtf8(docInfo.m_displayName.c_str()));
  454. luaDockWidget->setWidget(luaLayout);
  455. luaViewWidget->Initialize(docInfo);
  456. luaViewWidget->installEventFilter(this);
  457. m_ptrPerforceStatusWidget = new QLabel(tr("Pending Status"), this);
  458. m_ptrPerforceStatusWidget->setMargin(2);
  459. m_ptrPerforceStatusWidget->setStyleSheet(QString("background: rgba(192,192,192,255); color: black; border-style: inset;\nborder-width: 1px;\nborder-color: rgba(100,100,100,255);\nborder-radius: 8px;"));
  460. m_ptrPerforceStatusWidget->setAutoFillBackground(true);
  461. m_ptrPerforceStatusWidget->setTextInteractionFlags(Qt::NoTextInteraction);
  462. m_ptrPerforceStatusWidget->setAttribute(Qt::WA_TransparentForMouseEvents);
  463. connect(luaViewWidget, SIGNAL(sourceControlStatusUpdated(QString)), m_ptrPerforceStatusWidget, SLOT(setText(QString)));
  464. luaLayout->layout()->addWidget(luaViewWidget);
  465. luaLayout->layout()->addWidget(m_ptrPerforceStatusWidget);
  466. //if we already have an open view tabbify, if not just add it to the side
  467. if (m_dOpenLUAView.size() && !m_lastFocusedAssetId.empty())
  468. {
  469. viewIter = m_dOpenLUAView.find(m_lastFocusedAssetId);
  470. if (viewIter != m_dOpenLUAView.end())
  471. {
  472. qobject_cast<QMainWindow*>(this->centralWidget())->tabifyDockWidget(viewIter->second.luaDockWidget(), luaDockWidget);
  473. }
  474. else
  475. {
  476. qobject_cast<QMainWindow*>(this->centralWidget())->addDockWidget(static_cast<Qt::DockWidgetArea>(0x4), luaDockWidget, Qt::Horizontal);
  477. }
  478. }
  479. else
  480. {
  481. qobject_cast<QMainWindow*>(this->centralWidget())->addDockWidget(static_cast<Qt::DockWidgetArea>(0x4), luaDockWidget, Qt::Horizontal);
  482. }
  483. //track it
  484. if (m_lastFocusedAssetId.empty())
  485. {
  486. m_lastFocusedAssetId = docInfo.m_assetId;
  487. }
  488. m_dOpenLUAView.insert(AZStd::make_pair(docInfo.m_assetId, TrackedLUAView(luaDockWidget, luaViewWidget, docInfo.m_assetId)));
  489. m_CtrlTabOrder.push_front(docInfo.m_assetId);
  490. //if (m_dOpenLUAView.size() == 1)
  491. {
  492. QApplication::processEvents();
  493. }
  494. AZ::SystemTickBus::QueueFunction(&LUAEditorMainWindow::OnDockWidgetLocationChanged, this, docInfo.m_assetId);
  495. luaDockWidget->show();
  496. luaDockWidget->raise();
  497. luaViewWidget->setFocus();
  498. m_ptrPerforceStatusWidget->raise();
  499. connect(luaDockWidget, SIGNAL(visibilityChanged(bool)), luaViewWidget, SLOT(OnVisibilityChanged(bool)));
  500. SetEditContolsToAtLeastOneFileOpen();
  501. setAnimated(true);
  502. };
  503. void LUAEditorMainWindow::OnDockWidgetLocationChanged(const AZStd::string assetId)
  504. {
  505. // find the widget:
  506. TrackedLUAViewMap::iterator viewInfoIter = m_dOpenLUAView.find(assetId);
  507. if (viewInfoIter == m_dOpenLUAView.end())
  508. {
  509. return;
  510. }
  511. QTabBar* pBar = nullptr;
  512. // We need to find out what we are docked to in order for this to work correctly.
  513. // this function was added in, and I can't find anything similar that will let me do the same thing.
  514. // Without this, we lose the ability to have the right click -> close all but this.
  515. //QTabBar *pBar = qobject_cast<QMainWindow*>(this->centralWidget())->tabBar(viewInfoIter->second.luaDockWidget());
  516. if (!pBar)
  517. {
  518. return;
  519. }
  520. // have we ever done this already?
  521. if (pBar->documentMode() == false)
  522. {
  523. pBar->setDocumentMode(true);
  524. pBar->setElideMode(Qt::ElideNone); // do not elide!
  525. pBar->setTabsClosable(true);
  526. connect(pBar, &QTabBar::tabCloseRequested, this,
  527. [assetId, this]()
  528. {
  529. AZ::SystemTickBus::QueueFunction(&LUAEditorMainWindow::RequestCloseDocument, this, assetId);
  530. });
  531. pBar->setContextMenuPolicy(Qt::CustomContextMenu);
  532. connect(pBar,
  533. &QWidget::customContextMenuRequested,
  534. this,
  535. [assetId, this](const QPoint& point)
  536. {
  537. this->showTabContextMenu(assetId, point);
  538. }
  539. );
  540. }
  541. }
  542. void LUAEditorMainWindow::showTabContextMenu(const AZStd::string& assetId, const QPoint& pos)
  543. {
  544. QTabBar* emitter = qobject_cast<QTabBar*>(sender());
  545. if (!emitter)
  546. {
  547. return;
  548. }
  549. int tabIdx = emitter->tabAt(pos);
  550. if (tabIdx < 0)
  551. {
  552. return;
  553. }
  554. m_currentTabContextMenuUUID = assetId;
  555. if (m_currentTabContextMenuUUID.empty())
  556. {
  557. return;
  558. }
  559. QMenu menu(this);
  560. menu.addAction("Close All Except This", this, SLOT(closeAllTabsExceptThisTabContextMenu()));
  561. menu.exec(emitter->mapToGlobal(pos));
  562. }
  563. void LUAEditorMainWindow::closeAllTabsExceptThisTabContextMenu()
  564. {
  565. if (m_currentTabContextMenuUUID.empty())
  566. {
  567. return;
  568. }
  569. for (TrackedLUAViewMap::iterator it = m_dOpenLUAView.begin(); it != m_dOpenLUAView.end(); ++it)
  570. {
  571. if (it->first != m_currentTabContextMenuUUID)
  572. {
  573. AZ::SystemTickBus::QueueFunction(&LUAEditorMainWindow::RequestCloseDocument, this, it->first);
  574. }
  575. }
  576. m_currentTabContextMenuUUID = "";
  577. }
  578. void LUAEditorMainWindow::OnOpenWatchView()
  579. {
  580. show();
  581. m_gui->watchDockWidget->show();
  582. m_gui->watchDockWidget->setFocus();
  583. }
  584. void LUAEditorMainWindow::OnOpenReferenceView()
  585. {
  586. show();
  587. m_gui->classReferenceDockWidget->show();
  588. m_gui->classReferenceDockWidget->setFocus();
  589. }
  590. void LUAEditorMainWindow::OnOpenBreakpointsView()
  591. {
  592. show();
  593. m_gui->breakpointsDockWidget->show();
  594. m_gui->breakpointsDockWidget->raise();
  595. m_gui->breakpointsDockWidget->setFocus();
  596. }
  597. void LUAEditorMainWindow::OnOpenStackView()
  598. {
  599. show();
  600. m_gui->stackDockWidget->show();
  601. m_gui->stackDockWidget->raise();
  602. m_gui->stackDockWidget->setFocus();
  603. }
  604. void LUAEditorMainWindow::OnOpenLocalsView()
  605. {
  606. show();
  607. m_gui->localsDockWidget->show();
  608. m_gui->localsDockWidget->raise();
  609. m_gui->localsDockWidget->setFocus();
  610. }
  611. void LUAEditorMainWindow::OnOpenFindView(int index)
  612. {
  613. show();
  614. m_gui->findResultsDockWidget->show();
  615. m_gui->findResultsDockWidget->raise();
  616. m_gui->findResultsDockWidget->setFocus();
  617. m_gui->findTabWidget->setCurrentIndex(index);
  618. }
  619. void LUAEditorMainWindow::ResetSearchClicks()
  620. {
  621. m_dProcessFindListClicked.clear();
  622. }
  623. void LUAEditorMainWindow::MoveProgramCursor(const AZStd::string& assetId, int lineNumber)
  624. {
  625. if ((m_lastProgramCounterAssetId != assetId) && (!m_lastProgramCounterAssetId.empty()))
  626. {
  627. // the program counter has moved from one document to another.
  628. // remove it from the old one.
  629. TrackedLUAViewMap::iterator viewInfoIter = m_dOpenLUAView.find(m_lastProgramCounterAssetId);
  630. if (viewInfoIter != m_dOpenLUAView.end())
  631. {
  632. TrackedLUAView& viewInfo = viewInfoIter->second;
  633. LUAViewWidget* pTextWidget = viewInfo.luaViewWidget();
  634. pTextWidget->UpdateCurrentExecutingLine(-1);
  635. }
  636. }
  637. m_lastProgramCounterAssetId = "";
  638. // now add it to the new one:
  639. {
  640. TrackedLUAViewMap::iterator viewInfoIter = m_dOpenLUAView.find(assetId);
  641. if (viewInfoIter != m_dOpenLUAView.end())
  642. {
  643. TrackedLUAView& viewInfo = viewInfoIter->second;
  644. LUAViewWidget* pTextWidget = viewInfo.luaViewWidget();
  645. pTextWidget->UpdateCurrentExecutingLine(lineNumber);
  646. m_lastProgramCounterAssetId = assetId;
  647. }
  648. }
  649. if (lineNumber == -1)
  650. {
  651. m_lastProgramCounterAssetId = "";
  652. }
  653. }
  654. void LUAEditorMainWindow::MoveEditCursor(const AZStd::string& assetId, int lineNumber, bool withSelection)
  655. {
  656. TrackedLUAViewMap::iterator viewInfoIter = m_dOpenLUAView.find(assetId);
  657. if (viewInfoIter != m_dOpenLUAView.end())
  658. {
  659. TrackedLUAView& viewInfo = viewInfoIter->second;
  660. LUAViewWidget* pTextWidget = viewInfo.luaViewWidget();
  661. pTextWidget->UpdateCurrentEditingLine(lineNumber);
  662. if (withSelection)
  663. {
  664. pTextWidget->SetSelection(lineNumber, 0, lineNumber + 1, 0);
  665. }
  666. }
  667. }
  668. // debug menu items
  669. void LUAEditorMainWindow::ExecuteScript(bool executeLocally)
  670. {
  671. if (m_lastFocusedAssetId.empty())
  672. {
  673. return;
  674. }
  675. if (SyncDocumentToContext(m_lastFocusedAssetId))
  676. {
  677. Context_DebuggerManagement::Bus::Broadcast(
  678. &Context_DebuggerManagement::Bus::Events::ExecuteScriptBlob, m_lastFocusedAssetId, executeLocally);
  679. }
  680. }
  681. void LUAEditorMainWindow::OnRemoteToolsEndpointListChanged()
  682. {
  683. const bool hasTarget = m_pTargetButton->HasTarget();
  684. m_gui->breakpointsWarning->setHidden(hasTarget);
  685. m_gui->stackWarning->setHidden(hasTarget);
  686. m_gui->watchWarning->setHidden(hasTarget);
  687. m_gui->localsWarning->setHidden(hasTarget);
  688. m_gui->classReferenceWarning->setHidden(hasTarget);
  689. if (hasTarget)
  690. m_pTargetButton->ConnectToFirstTargetIfNotConnected();
  691. }
  692. void LUAEditorMainWindow::OnDebugExecute()
  693. {
  694. if (m_lastFocusedAssetId.empty())
  695. {
  696. return;
  697. }
  698. LUAViewWidget* view = GetCurrentView();
  699. if (view)
  700. {
  701. view->UpdateCurrentExecutingLine(-1);
  702. }
  703. TrackedLUAViewMap::iterator viewInfoIter = m_dOpenLUAView.find(m_lastFocusedAssetId);
  704. if (viewInfoIter != m_dOpenLUAView.end())
  705. {
  706. ExecuteScript(true);
  707. }
  708. }
  709. void LUAEditorMainWindow::OnDebugExecuteOnTarget()
  710. {
  711. if (m_lastFocusedAssetId.empty())
  712. {
  713. return;
  714. }
  715. LUAViewWidget* view = GetCurrentView();
  716. if (view)
  717. {
  718. view->UpdateCurrentExecutingLine(-1);
  719. }
  720. }
  721. // execution control
  722. void LUAEditorMainWindow::OnDebugToggleBreakpoint()
  723. {
  724. // current view
  725. LUAViewWidget* view = GetCurrentView();
  726. if (view)
  727. {
  728. // current line
  729. int line, index;
  730. view->GetCursorPosition(line, index);
  731. view->BreakpointToggle(line);
  732. }
  733. }
  734. void LUAEditorMainWindow::OnDebugContinueRunning()
  735. {
  736. LUAEditorDebuggerMessages::Bus::Broadcast(&LUAEditorDebuggerMessages::Bus::Events::DebugRunContinue);
  737. }
  738. void LUAEditorMainWindow::OnDebugStepOver()
  739. {
  740. LUAEditorDebuggerMessages::Bus::Broadcast(&LUAEditorDebuggerMessages::Bus::Events::DebugRunStepOver);
  741. }
  742. void LUAEditorMainWindow::OnDebugStepIn()
  743. {
  744. LUAEditorDebuggerMessages::Bus::Broadcast(&LUAEditorDebuggerMessages::Bus::Events::DebugRunStepIn);
  745. }
  746. void LUAEditorMainWindow::OnDebugStepOut()
  747. {
  748. LUAEditorDebuggerMessages::Bus::Broadcast(&LUAEditorDebuggerMessages::Bus::Events::DebugRunStepOut);
  749. }
  750. //file menu
  751. void LUAEditorMainWindow::OnFileMenuOpen()
  752. {
  753. AssetSelectionModel selection;
  754. StringFilter* stringFilter = new StringFilter();
  755. stringFilter->SetName("Lua file (*.lua)");
  756. stringFilter->SetFilterString(".lua");
  757. stringFilter->SetFilterPropagation(AssetBrowserEntryFilter::PropagateDirection::Down);
  758. auto stringFilterPtr = FilterConstType(stringFilter);
  759. selection.SetDisplayFilter(stringFilterPtr);
  760. selection.SetSelectionFilter(stringFilterPtr);
  761. AssetBrowserComponentRequestBus::Broadcast(
  762. &AssetBrowserComponentRequests::PickAssets, selection, AzToolsFramework::GetActiveWindow());
  763. if (!selection.IsValid())
  764. {
  765. return;
  766. }
  767. auto* result = selection.GetResult();
  768. if (!result)
  769. {
  770. AZ_Assert(false, "Lua script - Incorrect entry type selected during script instantiation.");
  771. return;
  772. }
  773. const AZStd::string assetId(result->GetFullPath().data());
  774. Context_DocumentManagement::Bus::Broadcast(&Context_DocumentManagement::Bus::Events::OnLoadDocument, assetId, true);
  775. AzFramework::StringFunc::Path::Split(assetId.c_str(), nullptr, &m_lastOpenFilePath);
  776. AddRecentFile(result->GetFullPath().c_str());
  777. UpdateOpenRecentMenu();
  778. }
  779. void LUAEditorMainWindow::OnFileMenuNew()
  780. {
  781. AZStd::string assetId;
  782. if (!OnFileSaveDialog("", assetId))
  783. {
  784. return;
  785. }
  786. if (AzFramework::StringFunc::Find(assetId.c_str(), ".lua") == AZStd::string::npos)
  787. {
  788. assetId += ".lua";
  789. }
  790. Context_DocumentManagement::Bus::Broadcast(&Context_DocumentManagement::Bus::Events::OnNewDocument, assetId);
  791. SetEditContolsToAtLeastOneFileOpen();
  792. }
  793. bool LUAEditorMainWindow::SyncDocumentToContext(const AZStd::string& assetId)
  794. {
  795. if (assetId.empty())
  796. {
  797. return false;
  798. }
  799. TrackedLUAViewMap::iterator viewInfoIter = m_dOpenLUAView.find(assetId);
  800. AZ_Assert(viewInfoIter != m_dOpenLUAView.end(), "OnFileMenuClose() : Cant find view Info.");
  801. TrackedLUAView& viewInfo = viewInfoIter->second;
  802. QByteArray viewBuffer = viewInfo.luaViewWidget()->GetText().toUtf8();
  803. AZStd::size_t viewSize = viewBuffer.size();
  804. Context_DocumentManagement::Bus::Broadcast(
  805. &Context_DocumentManagement::Bus::Events::UpdateDocumentData, assetId, viewBuffer.data(), viewSize);
  806. return true;
  807. }
  808. void LUAEditorMainWindow::OnFileMenuSave()
  809. {
  810. if (m_lastFocusedAssetId.empty())
  811. {
  812. return;
  813. }
  814. TrackedLUAViewMap::iterator viewInfoIter = m_dOpenLUAView.find(m_lastFocusedAssetId);
  815. AZ_Assert(viewInfoIter != m_dOpenLUAView.end(), "OnFileMenuSave() : Cant find view Info.");
  816. TrackedLUAView& viewInfo = viewInfoIter->second;
  817. //has the views text changed?
  818. if (viewInfo.luaViewWidget()->IsReadOnly())
  819. {
  820. AZ_Warning("LUA Editor", false, "Cannot save document - it is read-only (Check out first)");
  821. return;
  822. }
  823. if (SyncDocumentToContext(m_lastFocusedAssetId))
  824. {
  825. Context_DocumentManagement::Bus::Broadcast(
  826. &Context_DocumentManagement::Bus::Events::OnSaveDocument, m_lastFocusedAssetId, false, false);
  827. }
  828. }
  829. void LUAEditorMainWindow::OnFileMenuSaveAs()
  830. {
  831. if (m_lastFocusedAssetId.empty())
  832. {
  833. return;
  834. }
  835. if (SyncDocumentToContext(m_lastFocusedAssetId))
  836. {
  837. bool saveSuccess = false;
  838. Context_DocumentManagement::Bus::BroadcastResult(
  839. saveSuccess, &Context_DocumentManagement::Bus::Events::OnSaveDocumentAs, m_lastFocusedAssetId, false);
  840. }
  841. }
  842. void LUAEditorMainWindow::OnFileMenuSaveAll()
  843. {
  844. for (TrackedLUAViewMap::iterator viewInfoIter = m_dOpenLUAView.begin(); viewInfoIter != m_dOpenLUAView.end(); ++viewInfoIter)
  845. {
  846. TrackedLUAView& viewInfo = viewInfoIter->second;
  847. //has the views text changed?
  848. if (viewInfo.luaViewWidget()->IsReadOnly())
  849. {
  850. continue;
  851. }
  852. if (SyncDocumentToContext(viewInfo.luaViewWidget()->m_Info.m_assetId))
  853. {
  854. Context_DocumentManagement::Bus::Broadcast(
  855. &Context_DocumentManagement::Bus::Events::OnSaveDocument, viewInfo.luaViewWidget()->m_Info.m_assetId, false, false);
  856. }
  857. }
  858. }
  859. void LUAEditorMainWindow::OnFileMenuReload()
  860. {
  861. if (m_lastFocusedAssetId.empty())
  862. {
  863. return;
  864. }
  865. auto currentView = GetCurrentView();
  866. if (!currentView)
  867. {
  868. return;
  869. }
  870. // if this view has been modified, prompt to be sure they want to lose the changes
  871. TrackedLUAViewMap::iterator viewInfoIter = m_dOpenLUAView.find(m_lastFocusedAssetId);
  872. if (viewInfoIter == m_dOpenLUAView.end())
  873. {
  874. return; // no such view, dafuq?
  875. }
  876. TrackedLUAView& viewInfo = viewInfoIter->second;
  877. //has the views text changed?
  878. if (!viewInfo.luaViewWidget()->IsReadOnly() &&
  879. viewInfo.luaViewWidget()->IsModified())
  880. {
  881. QMessageBox msgBox;
  882. msgBox.setText("This file has been modified.\nDo you really want to Reload and lose changes?");
  883. msgBox.setInformativeText(currentView->m_Info.m_assetName.c_str());
  884. msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
  885. msgBox.setDefaultButton(QMessageBox::Cancel);
  886. msgBox.setIcon(QMessageBox::Warning);
  887. int ret = msgBox.exec();
  888. if (ret != QMessageBox::Ok)
  889. {
  890. return;
  891. }
  892. }
  893. // Need to store this off for use on the reload since it will be cleared out/changed as part of the OnCloseDocument call
  894. AZStd::string asset = m_lastFocusedAssetId;
  895. Context_DocumentManagement::Bus::Broadcast(&Context_DocumentManagement::Bus::Events::OnCloseDocument, m_lastFocusedAssetId);
  896. Context_DocumentManagement::Bus::Broadcast(&Context_DocumentManagement::Bus::Events::OnLoadDocument, asset, true);
  897. //not sure about this... looks like legacy, may need to be removed?
  898. // instate the topmost tab as the current asset ID
  899. // so that the window we're going to reopen has something to tabify onto
  900. TrackedLUACtrlTabOrder::iterator tabIter = m_CtrlTabOrder.begin();
  901. if (tabIter != m_CtrlTabOrder.end())
  902. {
  903. m_lastFocusedAssetId = *tabIter;
  904. }
  905. }
  906. void LUAEditorMainWindow::OnFileMenuClose()
  907. {
  908. if (m_lastFocusedAssetId.empty())
  909. {
  910. return;
  911. }
  912. RequestCloseDocument(m_lastFocusedAssetId);
  913. }
  914. void LUAEditorMainWindow::OnFileMenuCloseAll()
  915. {
  916. for (TrackedLUAViewMap::iterator it = m_dOpenLUAView.begin(); it != m_dOpenLUAView.end(); ++it)
  917. {
  918. AZ::SystemTickBus::QueueFunction(&LUAEditorMainWindow::RequestCloseDocument, this, it->first);
  919. }
  920. }
  921. void LUAEditorMainWindow::OnFileMenuCloseAllExcept()
  922. {
  923. for (TrackedLUAViewMap::iterator it = m_dOpenLUAView.begin(); it != m_dOpenLUAView.end(); ++it)
  924. {
  925. if (it->first != m_lastFocusedAssetId)
  926. {
  927. AZ::SystemTickBus::QueueFunction(&LUAEditorMainWindow::RequestCloseDocument, this, it->first);
  928. }
  929. }
  930. }
  931. bool LUAEditorMainWindow::RequestCloseDocument(const AZStd::string id)
  932. {
  933. AZStd::string assetId = id;
  934. //AZ_TracePrintf(LUAEditorDebugName, AZStd::string::format("OnFileMenuClose %s\n", assetId.c_str()).c_str());
  935. TrackedLUAViewMap::iterator viewInfoIter = m_dOpenLUAView.find(assetId);
  936. if (viewInfoIter == m_dOpenLUAView.end())
  937. {
  938. return true; // no such view, probably a double click on close.
  939. }
  940. TrackedLUAView& viewInfo = viewInfoIter->second;
  941. //has the views text changed?
  942. if (!viewInfo.luaViewWidget()->IsReadOnly() &&
  943. viewInfo.luaViewWidget()->IsModified())
  944. {
  945. AzToolsFramework::SaveChangesDialog dialog(this);
  946. dialog.exec();
  947. AzToolsFramework::SaveChangesDialogResult dr = dialog.m_result;
  948. if (dr == AzToolsFramework::SCDR_Save)
  949. {
  950. //the user wants to save before closing
  951. if (!SyncDocumentToContext(assetId))
  952. {
  953. return false;
  954. }
  955. Context_DocumentManagement::Bus::Broadcast(&Context_DocumentManagement::Bus::Events::OnSaveDocument, assetId, true, false);
  956. return true;
  957. }
  958. else if (dr == AzToolsFramework::SCDR_DiscardAndContinue)
  959. {
  960. //the user has chosen to continue to close the document and lose changes
  961. Context_DocumentManagement::Bus::Broadcast(&Context_DocumentManagement::Bus::Events::OnCloseDocument, assetId);
  962. return true;
  963. }
  964. else
  965. {
  966. //the user has canceled the close //or close was pressed
  967. return false;
  968. }
  969. }
  970. else
  971. {
  972. //no changes, just close the document
  973. Context_DocumentManagement::Bus::Broadcast(&Context_DocumentManagement::Bus::Events::OnCloseDocument, assetId);
  974. return true;
  975. }
  976. }
  977. void LUAEditorMainWindow::OnCloseView(const AZStd::string& assetId)
  978. {
  979. //remove it from the tracking list
  980. setAnimated(false);
  981. TrackedLUAViewMap::iterator viewIter = m_dOpenLUAView.find(assetId);
  982. if (viewIter != m_dOpenLUAView.end())
  983. {
  984. viewIter->second.luaDockWidget()->deleteLater();
  985. m_dOpenLUAView.erase(viewIter);
  986. TrackedLUACtrlTabOrder::iterator tabIter = m_CtrlTabOrder.begin();
  987. while (tabIter != m_CtrlTabOrder.end())
  988. {
  989. if (*tabIter == assetId)
  990. {
  991. m_CtrlTabOrder.erase(tabIter);
  992. break;
  993. }
  994. ++tabIter;
  995. }
  996. }
  997. if (m_lastFocusedAssetId == assetId)
  998. {
  999. m_lastFocusedAssetId = "";
  1000. }
  1001. //if there are no open views then null out the last focused document it should be invalid now
  1002. if (m_dOpenLUAView.empty())
  1003. {
  1004. m_lastFocusedAssetId = "";
  1005. SetEditContolsToNoFilesOpen();
  1006. AZ_TracePrintf(LUAEditorDebugName, AZStd::string::format("Last Focused Document ID to nullptr\n").c_str());
  1007. }
  1008. setAnimated(true);
  1009. }
  1010. void SendKeys(QWidget* pWidget, Qt::Key keyToSend, Qt::KeyboardModifier modifiers, QAction* pActionToDisable)
  1011. {
  1012. if (!pWidget)
  1013. {
  1014. return;
  1015. }
  1016. if (pActionToDisable)
  1017. {
  1018. pActionToDisable->setDisabled(true);
  1019. }
  1020. QKeyEvent PressIt(QEvent::KeyPress, keyToSend, modifiers);
  1021. QKeyEvent ReleaseIt(QEvent::KeyRelease, keyToSend, modifiers);
  1022. QApplication::sendEvent(pWidget, &PressIt);
  1023. QApplication::sendEvent(pWidget, &ReleaseIt);
  1024. if (pActionToDisable)
  1025. {
  1026. pActionToDisable->setDisabled(false);
  1027. }
  1028. }
  1029. //edit menu
  1030. void LUAEditorMainWindow::OnEditMenuUndo()
  1031. {
  1032. SendKeys(QApplication::focusWidget(), Qt::Key_Z, Qt::ControlModifier, m_gui->actionUndo);
  1033. }
  1034. void LUAEditorMainWindow::OnEditMenuRedo()
  1035. {
  1036. SendKeys(QApplication::focusWidget(), Qt::Key_Y, Qt::ControlModifier, m_gui->actionRedo);
  1037. }
  1038. void LUAEditorMainWindow::OnEditMenuCut()
  1039. {
  1040. auto currentView = GetCurrentView();
  1041. if (!currentView)
  1042. {
  1043. return;
  1044. }
  1045. int lineFrom;
  1046. int indexFrom;
  1047. int lineTo;
  1048. int indexTo;
  1049. currentView->GetSelection(lineFrom, indexFrom, lineTo, indexTo);
  1050. // on no selection
  1051. if (lineFrom == -1)
  1052. {
  1053. // get the line and strip the whitespace
  1054. currentView->GetCursorPosition(lineFrom, indexFrom);
  1055. currentView->SetSelection(lineFrom, 0, lineFrom + 1, 0);
  1056. QString cutThis = currentView->GetLineText(lineFrom);
  1057. QString finalCut = cutThis.simplified();
  1058. if (!finalCut.length())
  1059. {
  1060. // if the string is now empty, then it was all whitespace and so remove it but not to clipboard
  1061. currentView->RemoveSelectedText();
  1062. return;
  1063. }
  1064. }
  1065. // drop through to standard cut to clipboard handling with the original or our newly selected line(s)
  1066. currentView->Cut();
  1067. }
  1068. void LUAEditorMainWindow::OnEditMenuCopy()
  1069. {
  1070. auto currentView = GetCurrentView();
  1071. if (!currentView)
  1072. {
  1073. return;
  1074. }
  1075. int lineFrom;
  1076. int indexFrom;
  1077. int lineTo;
  1078. int indexTo;
  1079. bool wasSelected = true;
  1080. currentView->GetSelection(lineFrom, indexFrom, lineTo, indexTo);
  1081. // on no selection, force this one line
  1082. if (lineFrom == -1)
  1083. {
  1084. wasSelected = false;
  1085. currentView->GetCursorPosition(lineFrom, indexFrom);
  1086. currentView->SetSelection(lineFrom, 0, lineFrom + 1, 0);
  1087. }
  1088. currentView->Copy();
  1089. if (!wasSelected)
  1090. {
  1091. currentView->SetCursorPosition(lineFrom, indexFrom);
  1092. }
  1093. }
  1094. void LUAEditorMainWindow::OnEditMenuPaste()
  1095. {
  1096. SendKeys(QApplication::focusWidget(), Qt::Key_V, Qt::ControlModifier, m_gui->actionPaste);
  1097. }
  1098. void LUAEditorMainWindow::OnEditMenuFind()
  1099. {
  1100. m_ptrFindDialog->SaveState();
  1101. m_ptrFindDialog->show();
  1102. m_ptrFindDialog->SetAnyDocumentsOpen(m_StateTrack.atLeastOneFileOpen);
  1103. m_ptrFindDialog->SetToFindInAllOpen(false);
  1104. m_ptrFindDialog->SetNewSearchStarting();
  1105. m_ptrFindDialog->ResetSearch();
  1106. m_ptrFindDialog->activateWindow();
  1107. m_ptrFindDialog->raise();
  1108. }
  1109. void LUAEditorMainWindow::OnEditMenuReplace()
  1110. {
  1111. m_ptrFindDialog->SaveState();
  1112. m_ptrFindDialog->show();
  1113. m_ptrFindDialog->SetAnyDocumentsOpen(m_StateTrack.atLeastOneFileOpen);
  1114. m_ptrFindDialog->SetToFindInAllOpen(false);
  1115. m_ptrFindDialog->SetNewSearchStarting();
  1116. m_ptrFindDialog->ResetSearch();
  1117. m_ptrFindDialog->activateWindow();
  1118. m_ptrFindDialog->raise();
  1119. }
  1120. void LUAEditorMainWindow::OnEditMenuFindInAllOpen()
  1121. {
  1122. m_ptrFindDialog->SaveState();
  1123. m_ptrFindDialog->show();
  1124. m_ptrFindDialog->SetAnyDocumentsOpen(m_StateTrack.atLeastOneFileOpen);
  1125. m_ptrFindDialog->SetToFindInAllOpen(true);
  1126. m_ptrFindDialog->SetNewSearchStarting();
  1127. m_ptrFindDialog->ResetSearch();
  1128. m_ptrFindDialog->activateWindow();
  1129. m_ptrFindDialog->raise();
  1130. }
  1131. void LUAEditorMainWindow::OnEditMenuReplaceInAllOpen()
  1132. {
  1133. m_ptrFindDialog->SaveState();
  1134. m_ptrFindDialog->show();
  1135. m_ptrFindDialog->SetAnyDocumentsOpen(m_StateTrack.atLeastOneFileOpen);
  1136. m_ptrFindDialog->SetToFindInAllOpen(true);
  1137. m_ptrFindDialog->SetNewSearchStarting();
  1138. m_ptrFindDialog->ResetSearch();
  1139. m_ptrFindDialog->activateWindow();
  1140. m_ptrFindDialog->raise();
  1141. }
  1142. void LUAEditorMainWindow::OnEditMenuFindLocal()
  1143. {
  1144. m_ptrFindDialog->SaveState();
  1145. m_ptrFindDialog->SetAnyDocumentsOpen(m_StateTrack.atLeastOneFileOpen);
  1146. m_ptrFindDialog->SetToFindInAllOpen(false);
  1147. m_ptrFindDialog->SetNewSearchStarting(true, true);
  1148. m_ptrFindDialog->OnFindNext();
  1149. }
  1150. void LUAEditorMainWindow::OnEditMenuFindLocalReverse()
  1151. {
  1152. m_ptrFindDialog->SaveState();
  1153. m_ptrFindDialog->SetAnyDocumentsOpen(m_StateTrack.atLeastOneFileOpen);
  1154. m_ptrFindDialog->SetToFindInAllOpen(false);
  1155. m_ptrFindDialog->SetNewSearchStarting(true, false);
  1156. m_ptrFindDialog->OnFindNext();
  1157. }
  1158. void LUAEditorMainWindow::OnEditMenuFindNext()
  1159. {
  1160. if (m_ptrFindDialog)
  1161. {
  1162. m_ptrFindDialog->OnFindNext();
  1163. }
  1164. }
  1165. void LUAEditorMainWindow::OnEditMenuGoToLine()
  1166. {
  1167. auto currentView = GetCurrentView();
  1168. if (!currentView)
  1169. {
  1170. return;
  1171. }
  1172. LUAEditorGoToLineDialog dlg(this);
  1173. int lineNumber = 0, lineColumn = 0;
  1174. currentView->GetCursorPosition(lineNumber, lineColumn);
  1175. dlg.setLineNumber(lineNumber, lineColumn);
  1176. if (dlg.exec() != QDialog::Rejected)
  1177. {
  1178. lineNumber = dlg.getLineNumber();
  1179. lineColumn = dlg.getColumnNumber();
  1180. currentView->SetCursorPosition(lineNumber, lineColumn);
  1181. }
  1182. }
  1183. void LUAEditorMainWindow::OnEditMenuFoldAll()
  1184. {
  1185. if (auto currentView = GetCurrentView())
  1186. {
  1187. currentView->FoldAll();
  1188. }
  1189. }
  1190. void LUAEditorMainWindow::OnEditMenuUnfoldAll()
  1191. {
  1192. if (auto currentView = GetCurrentView())
  1193. {
  1194. currentView->UnfoldAll();
  1195. }
  1196. }
  1197. void LUAEditorMainWindow::OnEditMenuSelectAll()
  1198. {
  1199. if (auto currentView = GetCurrentView())
  1200. {
  1201. currentView->SelectAll();
  1202. }
  1203. }
  1204. void LUAEditorMainWindow::OnEditMenuSelectToBrace()
  1205. {
  1206. if (auto currentView = GetCurrentView())
  1207. {
  1208. currentView->SelectToMatchingBrace();
  1209. }
  1210. }
  1211. void LUAEditorMainWindow::OnCommentSelectedBlock()
  1212. {
  1213. if (NeedsCheckout())
  1214. {
  1215. return;
  1216. }
  1217. if (auto currentView = GetCurrentView())
  1218. {
  1219. // must check read-only status at every operation that can modify the buffer
  1220. if (!currentView->IsReadOnly())
  1221. {
  1222. currentView->CommentSelectedLines();
  1223. }
  1224. }
  1225. }
  1226. void LUAEditorMainWindow::OnUnCommentSelectedBlock()
  1227. {
  1228. if (NeedsCheckout())
  1229. {
  1230. return;
  1231. }
  1232. if (auto currentView = GetCurrentView())
  1233. {
  1234. // must check read-only status at every operation that can modify the buffer
  1235. if (!currentView->IsReadOnly())
  1236. {
  1237. currentView->UncommentSelectedLines();
  1238. }
  1239. }
  1240. }
  1241. bool LUAEditorMainWindow::NeedsCheckout()
  1242. {
  1243. auto currentView = GetCurrentView();
  1244. if (!currentView)
  1245. {
  1246. return false;
  1247. }
  1248. if (currentView->IsReadOnly())
  1249. {
  1250. QMessageBox msgBox;
  1251. msgBox.setText("Checkout This File To Edit?");
  1252. msgBox.setInformativeText(currentView->m_Info.m_assetName.c_str());
  1253. msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
  1254. msgBox.setDefaultButton(QMessageBox::Cancel);
  1255. msgBox.setIcon(QMessageBox::Warning);
  1256. int ret = msgBox.exec();
  1257. if (ret == QMessageBox::Ok)
  1258. {
  1259. OnRequestCheckOut(currentView->m_Info.m_assetId);
  1260. }
  1261. return true;
  1262. }
  1263. return false;
  1264. }
  1265. void LUAEditorMainWindow::OnEditMenuTransposeUp()
  1266. {
  1267. if (NeedsCheckout())
  1268. {
  1269. return;
  1270. }
  1271. // must check read-only status at every operation that can modify the buffer
  1272. if (auto currentView = GetCurrentView())
  1273. {
  1274. if (!currentView->IsReadOnly())
  1275. {
  1276. currentView->MoveSelectedLinesUp();
  1277. }
  1278. }
  1279. }
  1280. void LUAEditorMainWindow::OnEditMenuTransposeDn()
  1281. {
  1282. if (NeedsCheckout())
  1283. {
  1284. return;
  1285. }
  1286. // must check read-only status at every operation that can modify the buffer
  1287. if (auto currentView = GetCurrentView())
  1288. {
  1289. if (!currentView->IsReadOnly())
  1290. {
  1291. currentView->MoveSelectedLinesDn();
  1292. }
  1293. }
  1294. }
  1295. //view menu
  1296. void LUAEditorMainWindow::OnViewMenuBreakpoints()
  1297. {
  1298. OnOpenBreakpointsView();
  1299. }
  1300. void LUAEditorMainWindow::OnViewMenuStack()
  1301. {
  1302. OnOpenStackView();
  1303. }
  1304. void LUAEditorMainWindow::OnViewMenuLocals()
  1305. {
  1306. OnOpenLocalsView();
  1307. }
  1308. void LUAEditorMainWindow::OnViewMenuWatch()
  1309. {
  1310. OnOpenWatchView();
  1311. }
  1312. void LUAEditorMainWindow::OnViewMenuReference()
  1313. {
  1314. OnOpenReferenceView();
  1315. }
  1316. void LUAEditorMainWindow::OnViewMenuFind1()
  1317. {
  1318. OnOpenFindView(0);
  1319. }
  1320. void LUAEditorMainWindow::OnViewMenuFind2()
  1321. {
  1322. OnOpenFindView(1);
  1323. }
  1324. void LUAEditorMainWindow::OnViewMenuFind3()
  1325. {
  1326. OnOpenFindView(2);
  1327. }
  1328. void LUAEditorMainWindow::OnViewMenuFind4()
  1329. {
  1330. OnOpenFindView(3);
  1331. }
  1332. void LUAEditorMainWindow::OnViewMenuResetZoom()
  1333. {
  1334. if (auto currentView = GetCurrentView())
  1335. {
  1336. currentView->ResetZoom();
  1337. }
  1338. }
  1339. //source control menu
  1340. void LUAEditorMainWindow::OnSourceControlMenuCheckOut()
  1341. {
  1342. // if no last document id then return
  1343. if (m_lastFocusedAssetId.empty())
  1344. {
  1345. return;
  1346. }
  1347. Context_DocumentManagement::Bus::Broadcast(&Context_DocumentManagement::Bus::Events::RefreshAllDocumentPerforceStat);
  1348. if (!SyncDocumentToContext(m_lastFocusedAssetId))
  1349. {
  1350. AZ_Warning(LUAEditorDebugName, false, "Could not sync doc data before checkout, data may be lost.");
  1351. QMessageBox::warning(this, "Error!", "Could not sync document before checkout!");
  1352. return;
  1353. }
  1354. Context_DocumentManagement::Bus::Broadcast(
  1355. &Context_DocumentManagement::Bus::Events::DocumentCheckOutRequested, m_lastFocusedAssetId);
  1356. }
  1357. //tools menu
  1358. // when the Editor Main window is requested to close, it is not destroyed.
  1359. //////////////////////////////////////////////////////////////////////////
  1360. // Qt Events
  1361. void LUAEditorMainWindow::closeEvent(QCloseEvent* event)
  1362. {
  1363. OnMenuCloseCurrentWindow();
  1364. event->ignore();
  1365. }
  1366. bool LUAEditorMainWindow::OnGetPermissionToShutDown()
  1367. {
  1368. bool willShutDown = true;
  1369. AZ_TracePrintf(LUAEditorDebugName, "LUAEditorMainWindow::OnGetPermissionToShutDown()\n");
  1370. for (TrackedLUAViewMap::iterator viewInfoIter = m_dOpenLUAView.begin(); viewInfoIter != m_dOpenLUAView.end(); ++viewInfoIter)
  1371. {
  1372. TrackedLUAView& viewInfo = viewInfoIter->second;
  1373. //have the views' text changed?
  1374. if (!viewInfo.luaViewWidget()->IsReadOnly() &&
  1375. viewInfo.luaViewWidget()->IsModified())
  1376. {
  1377. this->show();
  1378. viewInfo.luaDockWidget()->show();
  1379. viewInfo.luaDockWidget()->raise();
  1380. AzToolsFramework::SaveChangesDialog dialog(this);
  1381. dialog.exec();
  1382. AzToolsFramework::SaveChangesDialogResult dr = dialog.m_result;
  1383. if (dr == AzToolsFramework::SCDR_Save)
  1384. {
  1385. if (!SyncDocumentToContext(viewInfo.luaViewWidget()->m_Info.m_assetId))
  1386. {
  1387. AZ_Warning(LUAEditorDebugName, false, "Could not sync doc data before closing it, data may be lost.");
  1388. willShutDown = false;
  1389. AZ_TracePrintf(LUAEditorInfoName, " SyncDocumentToContext() failure\n");
  1390. break;
  1391. }
  1392. AZ_TracePrintf(LUAEditorDebugName, "LUAEditorMainWindow::OnGetPermissionToShutDown() SAVING %s\n", viewInfo.luaViewWidget()->m_Info.m_assetName.c_str());
  1393. Context_DocumentManagement::Bus::Broadcast(
  1394. &Context_DocumentManagement::Bus::Events::OnSaveDocument, viewInfo.luaViewWidget()->m_Info.m_assetId, false, false);
  1395. }
  1396. else if (dr == AzToolsFramework::SCDR_DiscardAndContinue)
  1397. {
  1398. //the user has chosen to continue and lose changes
  1399. if (viewInfo.luaViewWidget()->m_Info.m_bUntitledDocument)
  1400. {
  1401. AZ_TracePrintf(LUAEditorDebugName, " Forced close\n");
  1402. // all untitled documents are force closed to clear any tracked states that will be serialized by their trackers
  1403. Context_DocumentManagement::Bus::Broadcast(
  1404. &Context_DocumentManagement::Bus::Events::OnCloseDocument, viewInfo.luaViewWidget()->m_Info.m_assetId);
  1405. viewInfoIter = m_dOpenLUAView.begin();
  1406. }
  1407. else // all titled (i.e. preexisting or saved files, simply reload
  1408. {
  1409. AZ_TracePrintf(LUAEditorDebugName, " Forced reload\n");
  1410. Context_DocumentManagement::Bus::Broadcast(
  1411. &Context_DocumentManagement::Bus::Events::OnReloadDocument, viewInfo.luaViewWidget()->m_Info.m_assetId);
  1412. viewInfoIter = m_dOpenLUAView.begin();
  1413. }
  1414. }
  1415. else
  1416. {
  1417. //the user has canceled the close
  1418. willShutDown = false;
  1419. break;
  1420. }
  1421. }
  1422. }
  1423. return willShutDown;
  1424. }
  1425. void LUAEditorMainWindow::SaveWindowState()
  1426. {
  1427. // build state and store it.
  1428. auto newState = AZ::UserSettings::CreateFind<LUAEditorMainWindowSavedState>(AZ_CRC_CE("LUA EDITOR MAIN WINDOW STATE"), AZ::UserSettings::CT_LOCAL);
  1429. newState->Init(saveState(), saveGeometry());
  1430. newState->m_bAutocompleteEnabled = m_bAutocompleteEnabled;
  1431. // gather and store the open files in tab order
  1432. newState->m_openAssetIds.clear();
  1433. // the following is experimental, apparently widget child order doesn't match tab order, which is unfortunate
  1434. QList<QDockWidget*> dockWidgets = qobject_cast<QMainWindow*>(this->centralWidget())->findChildren<QDockWidget*>();
  1435. QList<QDockWidget*>::iterator qlit = dockWidgets.begin();
  1436. while (qlit != dockWidgets.end())
  1437. {
  1438. LUADockWidget* ldw = qobject_cast<LUADockWidget*>(*qlit);
  1439. if (ldw)
  1440. {
  1441. TrackedLUAViewMap::iterator viewInfoIter = m_dOpenLUAView.find(ldw->assetId());
  1442. if (viewInfoIter != m_dOpenLUAView.end())
  1443. {
  1444. TrackedLUAView& viewInfo = viewInfoIter->second;
  1445. newState->m_openAssetIds.push_back(viewInfo.luaViewWidget()->m_Info.m_assetId);
  1446. AZ_TracePrintf(LUAEditorDebugName, " - TAB Saved %s\n", viewInfo.luaViewWidget()->m_Info.m_assetName.c_str());
  1447. }
  1448. }
  1449. qlit++;
  1450. }
  1451. m_gui->m_logPanel->SaveState();
  1452. auto savedState = AZ::UserSettings::CreateFind<AzToolsFramework::MainWindowSavedState>(AZ_CRC_CE("INNER_LUA_WINDOW"), AZ::UserSettings::CT_LOCAL);
  1453. if (savedState)
  1454. {
  1455. // restore state.
  1456. QMainWindow* pMainWindow = static_cast<QMainWindow*>(centralWidget());
  1457. savedState->Init(pMainWindow->saveState(), pMainWindow->saveGeometry());
  1458. }
  1459. }
  1460. void LUAEditorMainWindow::OnLogTabsReset()
  1461. {
  1462. m_gui->m_logPanel->AddLogTab(AzToolsFramework::LogPanel::TabSettings("Lua Editor", "Lua Editor", ""));
  1463. }
  1464. void LUAEditorMainWindow::RestoreWindowState() // call this after you have rebuilt everything.
  1465. {
  1466. if (!m_gui->m_logPanel->LoadState())
  1467. {
  1468. OnLogTabsReset();
  1469. }
  1470. // load the state from our state block:
  1471. auto pEditorMainSavedState = AZ::UserSettings::Find<LUAEditorMainWindowSavedState>(AZ_CRC_CE("LUA EDITOR MAIN WINDOW STATE"), AZ::UserSettings::CT_LOCAL);
  1472. if (pEditorMainSavedState)
  1473. {
  1474. QByteArray editorGeomData((const char*)pEditorMainSavedState->m_windowGeometry.data(), (int)pEditorMainSavedState->m_windowGeometry.size());
  1475. QByteArray editorStateData((const char*)pEditorMainSavedState->GetWindowState().data(), (int)pEditorMainSavedState->GetWindowState().size());
  1476. for (const auto& assetId : pEditorMainSavedState->m_openAssetIds)
  1477. {
  1478. Context_DocumentManagement::Bus::Broadcast(&Context_DocumentManagement::Bus::Events::OnLoadDocument, assetId, false);
  1479. }
  1480. restoreGeometry(editorGeomData);
  1481. if (this->isMaximized())
  1482. {
  1483. this->showNormal();
  1484. this->showMaximized();
  1485. }
  1486. restoreState(editorStateData);
  1487. m_bAutocompleteEnabled = pEditorMainSavedState->m_bAutocompleteEnabled;
  1488. OnAutocompleteChanged(m_bAutocompleteEnabled);
  1489. auto pWindowSavedState = AZ::UserSettings::Find<AzToolsFramework::MainWindowSavedState>(AZ_CRC_CE("INNER_LUA_WINDOW"), AZ::UserSettings::CT_LOCAL);
  1490. if (pWindowSavedState)
  1491. {
  1492. // restore state.
  1493. QByteArray windowGeomData((const char*)pWindowSavedState->m_windowGeometry.data(), (int)pWindowSavedState->m_windowGeometry.size());
  1494. QByteArray windowStateData((const char*)pWindowSavedState->GetWindowState().data(), (int)pWindowSavedState->GetWindowState().size());
  1495. QMainWindow* pMainWindow = static_cast<QMainWindow*>(centralWidget());
  1496. pMainWindow->restoreState(windowStateData);
  1497. }
  1498. }
  1499. else
  1500. {
  1501. // default state!
  1502. }
  1503. }
  1504. LUAViewWidget* LUAEditorMainWindow::GetCurrentView()
  1505. {
  1506. if (m_lastFocusedAssetId.empty())
  1507. {
  1508. return nullptr;
  1509. }
  1510. TrackedLUAViewMap::iterator viewInfoIter = m_dOpenLUAView.find(m_lastFocusedAssetId);
  1511. AZ_Assert(viewInfoIter != m_dOpenLUAView.end(), "OnFileMenuClose() : Cant find view Info.");
  1512. TrackedLUAView& viewInfo = viewInfoIter->second;
  1513. return viewInfo.luaViewWidget();
  1514. }
  1515. AZStd::vector<LUAViewWidget*> LUAEditorMainWindow::GetAllViews()
  1516. {
  1517. AZStd::vector<LUAViewWidget*> dViews;
  1518. for (TrackedLUAViewMap::iterator viewInfoIter = m_dOpenLUAView.begin(); viewInfoIter != m_dOpenLUAView.end(); ++viewInfoIter)
  1519. {
  1520. dViews.push_back(viewInfoIter->second.luaViewWidget());
  1521. }
  1522. return dViews;
  1523. }
  1524. FindResults* LUAEditorMainWindow::GetFindResultsWidget(int index)
  1525. {
  1526. switch (index)
  1527. {
  1528. case 0:
  1529. return m_gui->m_findResults1;
  1530. case 1:
  1531. return m_gui->m_findResults2;
  1532. case 2:
  1533. return m_gui->m_findResults3;
  1534. case 3:
  1535. return m_gui->m_findResults4;
  1536. }
  1537. return nullptr;
  1538. }
  1539. void LUAEditorMainWindow::SetCurrentFindListWidget(int index)
  1540. {
  1541. AZ_Assert(index >= 0 && index < 4, "Only 4 find windows currently");
  1542. m_gui->findTabWidget->setCurrentIndex(index);
  1543. }
  1544. void LUAEditorMainWindow::OnFindResultClicked(FindResultsBlockInfo result)
  1545. {
  1546. if (OnRequestFocusView(result.m_assetId))
  1547. {
  1548. LUAViewWidget* pLUAViewWidget = GetCurrentView();
  1549. if (!pLUAViewWidget)
  1550. {
  1551. return;
  1552. }
  1553. pLUAViewWidget->SetCursorPosition(result.m_lineNumber, result.m_firstMatchPosition);
  1554. }
  1555. else
  1556. {
  1557. // the document was probably closed, request it be reopened
  1558. m_dProcessFindListClicked.push_back(result);
  1559. AZ_Assert(false, "Fix assets!");
  1560. }
  1561. }
  1562. void LUAEditorMainWindow::OnDataLoadedAndSet(const DocumentInfo& info, LUAViewWidget* pLUAViewWidget)
  1563. {
  1564. for (auto iter = m_dProcessFindListClicked.begin(); iter != m_dProcessFindListClicked.end(); ++iter)
  1565. {
  1566. if (iter->m_assetId == info.m_assetId)
  1567. {
  1568. AZ_Assert(iter->m_assignAssetId, "m_assignAssetId was never set");
  1569. iter->m_assetId = pLUAViewWidget->m_Info.m_assetId;
  1570. iter->m_assignAssetId(info.m_assetName, pLUAViewWidget->m_Info.m_assetId);
  1571. AZ::SystemTickBus::QueueFunction(&LUAEditorMainWindow::OnFindResultClicked, this, *iter);
  1572. m_dProcessFindListClicked.erase(iter);
  1573. return;
  1574. }
  1575. }
  1576. }
  1577. bool LUAEditorMainWindow::OnFileSaveDialog(const AZStd::string& assetName, AZStd::string& newAssetName)
  1578. {
  1579. const QDir rootDir { AZ::Utils::GetProjectPath().c_str() };
  1580. QString name = QFileDialog::getSaveFileName(this, QString(AZStd::string::format("Save File {%s}", assetName.c_str()).c_str()), m_lastOpenFilePath.size() > 0 ? m_lastOpenFilePath.c_str() : rootDir.absolutePath(), QString("*.lua"));
  1581. if (name.isEmpty())
  1582. {
  1583. return false;
  1584. }
  1585. AzFramework::StringFunc::Path::Split(name.toUtf8().data(), nullptr, &m_lastOpenFilePath);
  1586. newAssetName = name.toUtf8().data();
  1587. return true;
  1588. }
  1589. bool LUAEditorMainWindow::OnFileSaveAsDialog(const AZStd::string& assetName, AZStd::string& newAssetName)
  1590. {
  1591. const char* rootDirString;
  1592. AZ::ComponentApplicationBus::BroadcastResult(rootDirString, &AZ::ComponentApplicationBus::Events::GetExecutableFolder);
  1593. QDir rootDir;
  1594. rootDir.setPath(rootDirString);
  1595. rootDir.cdUp();
  1596. QString name = QFileDialog::getSaveFileName(this, QString(AZStd::string::format("Save File As {%s}", assetName.c_str()).c_str()), rootDir.absolutePath(), QString("*.lua"));
  1597. if (name.isEmpty())
  1598. {
  1599. return false;
  1600. }
  1601. //name has the full path in it, we need to convert it to an asset name
  1602. AZStd::string projectRoot, databaseRoot, databasePath, databaseFile, fileExtension;
  1603. if (!AzFramework::StringFunc::AssetDatabasePath::Split(name.toUtf8().data(), &projectRoot, &databaseRoot, &databasePath, &databaseFile, &fileExtension))
  1604. {
  1605. AZ_Warning("LUAEditorMainWindow", false, AZStd::string::format("<span severity=\"err\">Path is invalid: '%s'</span>", name.toUtf8().data()).c_str());
  1606. return false;
  1607. }
  1608. AzFramework::StringFunc::AssetDatabasePath::Join(databasePath.c_str(), databaseFile.c_str(), newAssetName);
  1609. return true;
  1610. }
  1611. //////////////////////////////////////////////////////////////////////////
  1612. // LUAEditorMainWindow Messages
  1613. void LUAEditorMainWindow::OnFocusInEvent(const AZStd::string& assetId)
  1614. {
  1615. m_lastFocusedAssetId = assetId;
  1616. if (!m_bIgnoreFocusRequests)
  1617. {
  1618. SetGUIToMatch(m_StateTrack);
  1619. }
  1620. }
  1621. void LUAEditorMainWindow::OnFocusOutEvent(const AZStd::string&)
  1622. {
  1623. }
  1624. void LUAEditorMainWindow::OnRequestCheckOut(const AZStd::string& assetId)
  1625. {
  1626. AZStd::string restoreAssetId = m_lastFocusedAssetId;
  1627. m_lastFocusedAssetId = assetId;
  1628. OnSourceControlMenuCheckOut();
  1629. m_lastFocusedAssetId = restoreAssetId;
  1630. }
  1631. //////////////////////////////////////////////////////////////////////////
  1632. bool LUAEditorMainWindow::OnRequestFocusView(const AZStd::string& assetId)
  1633. {
  1634. TrackedLUAViewMap::iterator viewIter = m_dOpenLUAView.find(assetId);
  1635. if (viewIter != m_dOpenLUAView.end())
  1636. {
  1637. viewIter->second.luaDockWidget()->show();
  1638. viewIter->second.luaDockWidget()->raise();
  1639. viewIter->second.luaViewWidget()->RegainFocusFinal();
  1640. return true;
  1641. }
  1642. return false;
  1643. }
  1644. void LUAEditorMainWindow::OnDocumentInfoUpdated(const DocumentInfo& docInfo)
  1645. {
  1646. // document has fresh information available (it was checked out or its data finished or etc)
  1647. TrackedLUAViewMap::iterator viewIter = m_dOpenLUAView.find(docInfo.m_assetId);
  1648. if (viewIter != m_dOpenLUAView.end())
  1649. {
  1650. viewIter->second.luaViewWidget()->OnDocumentInfoUpdated(docInfo);
  1651. }
  1652. }
  1653. // preliminaries for making the debug action buttons context sensitive
  1654. void LUAEditorMainWindow::BreakpointsUpdate(const LUAEditor::BreakpointMap& uniqueBreakpoints)
  1655. {
  1656. (void)uniqueBreakpoints;
  1657. }
  1658. void LUAEditorMainWindow::BreakpointHit(const LUAEditor::Breakpoint& breakpoint)
  1659. {
  1660. (void)breakpoint;
  1661. SetDebugControlsToAtBreak();
  1662. }
  1663. void LUAEditorMainWindow::BreakpointResume()
  1664. {
  1665. SetDebugControlsToRunning();
  1666. }
  1667. //////////////////////////////////////////////////////////////////////////
  1668. // externally driven context sensitive widget states
  1669. void LUAEditorMainWindow::SetDebugControlsToInitial()
  1670. {
  1671. m_StateTrack.Init();
  1672. SetGUIToMatch(m_StateTrack);
  1673. }
  1674. void LUAEditorMainWindow::SetDebugControlsToRunning()
  1675. {
  1676. AZ_TracePrintf(LUAEditorDebugName, "LUAEditorMainWindow::SetDebugControlsToRunning()\n");
  1677. m_StateTrack.scriptRunning = true;
  1678. m_StateTrack.atBreak = false;
  1679. m_StateTrack.hasExecuted = true;
  1680. SetGUIToMatch(m_StateTrack);
  1681. if (!m_lastFocusedAssetId.empty())
  1682. {
  1683. TrackedLUAViewMap::iterator viewInfoIter = m_dOpenLUAView.find(m_lastFocusedAssetId);
  1684. AZ_Assert(viewInfoIter != m_dOpenLUAView.end(), "OnFileMenuClose() : Cant find view Info.");
  1685. TrackedLUAView& viewInfo = viewInfoIter->second;
  1686. viewInfo.luaViewWidget()->UpdateCurrentExecutingLine(-1);
  1687. }
  1688. LUAEditor::LUAStackTrackerMessages::Bus::Broadcast(&LUAEditor::LUAStackTrackerMessages::Bus::Events::StackClear);
  1689. }
  1690. void LUAEditorMainWindow::SetDebugControlsToAtBreak()
  1691. {
  1692. AZ_TracePrintf(LUAEditorDebugName, "LUAEditorMainWindow::SetDebugControlsToAtBreak()\n");
  1693. m_StateTrack.scriptRunning = false;
  1694. m_StateTrack.atBreak = true;
  1695. m_StateTrack.hasExecuted = true;
  1696. SetGUIToMatch(m_StateTrack);
  1697. }
  1698. void LUAEditorMainWindow::SetEditContolsToNoFilesOpen()
  1699. {
  1700. m_StateTrack.atLeastOneFileOpen = false;
  1701. SetGUIToMatch(m_StateTrack);
  1702. }
  1703. void LUAEditorMainWindow::SetEditContolsToAtLeastOneFileOpen()
  1704. {
  1705. m_StateTrack.atLeastOneFileOpen = true;
  1706. SetGUIToMatch(m_StateTrack);
  1707. }
  1708. void LUAEditorMainWindow::luaClassFilterTextChanged(const QString& newPattern)
  1709. {
  1710. m_ClassReferenceFilter->SetFilter(newPattern);
  1711. if (newPattern.isEmpty())
  1712. {
  1713. m_gui->classReferenceTreeView->collapseAll();
  1714. }
  1715. else
  1716. {
  1717. m_gui->classReferenceTreeView->expandAll();
  1718. }
  1719. }
  1720. void LUAEditorMainWindow::OnConnectedToTarget()
  1721. {
  1722. AZ_TracePrintf(LUAEditorDebugName, "LUAEditorMainWindow::OnConnectedToTarget()\n");
  1723. m_StateTrack.targetConnected = true;
  1724. m_StateTrack.debuggerAttached = false;
  1725. m_StateTrack.scriptRunning = false;
  1726. m_StateTrack.atBreak = false;
  1727. m_StateTrack.hasExecuted = false;
  1728. SetGUIToMatch(m_StateTrack);
  1729. }
  1730. void LUAEditorMainWindow::OnDisconnectedFromTarget()
  1731. {
  1732. AZ_TracePrintf(LUAEditorDebugName, "LUAEditorMainWindow::OnDisconnectedFromTarget()\n");
  1733. m_StateTrack.targetConnected = false;
  1734. m_StateTrack.debuggerAttached = false;
  1735. m_StateTrack.scriptRunning = false;
  1736. m_StateTrack.atBreak = false;
  1737. m_StateTrack.hasExecuted = false;
  1738. SetGUIToMatch(m_StateTrack);
  1739. }
  1740. void LUAEditorMainWindow::OnConnectedToDebugger()
  1741. {
  1742. AZ_TracePrintf(LUAEditorDebugName, "LUAEditorMainWindow::OnConnectedToDebugger()\n");
  1743. m_StateTrack.debuggerAttached = true;
  1744. m_StateTrack.scriptRunning = false;
  1745. m_StateTrack.atBreak = false;
  1746. m_StateTrack.hasExecuted = false;
  1747. SetGUIToMatch(m_StateTrack);
  1748. }
  1749. void LUAEditorMainWindow::OnDisconnectedFromDebugger()
  1750. {
  1751. AZ_TracePrintf(LUAEditorDebugName, "LUAEditorMainWindow::OnDisconnectedFromDebugger()\n");
  1752. m_StateTrack.debuggerAttached = false;
  1753. m_StateTrack.scriptRunning = false;
  1754. m_StateTrack.atBreak = false;
  1755. m_StateTrack.hasExecuted = false;
  1756. SetGUIToMatch(m_StateTrack);
  1757. }
  1758. void LUAEditorMainWindow::Repaint()
  1759. {
  1760. SetGUIToMatch(m_StateTrack);
  1761. const AZStd::vector<LUAViewWidget*>& allViews = GetAllViews();
  1762. for (LUAViewWidget* view : allViews)
  1763. {
  1764. view->UpdateFont();
  1765. }
  1766. }
  1767. void LUAEditorMainWindow::OnExecuteScriptResult(bool success)
  1768. {
  1769. if (success)
  1770. {
  1771. m_StateTrack.hasExecuted = true;
  1772. SetDebugControlsToRunning();
  1773. }
  1774. }
  1775. void LUAEditorMainWindow::SetGUIToMatch(StateTrack& track)
  1776. {
  1777. if (track.atLeastOneFileOpen)
  1778. {
  1779. m_gui->actionSave->setEnabled(true);
  1780. m_gui->actionClose->setEnabled(true);
  1781. m_gui->actionSaveAll->setEnabled(true);
  1782. m_gui->actionUndo->setEnabled(true);
  1783. m_gui->actionRedo->setEnabled(true);
  1784. m_gui->actionCut->setEnabled(true);
  1785. m_gui->actionCopy->setEnabled(true);
  1786. m_gui->actionPaste->setEnabled(true);
  1787. m_gui->actionSaveAs->setEnabled(true);
  1788. m_gui->actionCheckOut->setEnabled(true);
  1789. m_gui->actionGoToLine->setEnabled(true);
  1790. m_gui->action_execute->setEnabled(true);
  1791. m_gui->action_togglebreak->setEnabled(true);
  1792. }
  1793. else
  1794. {
  1795. m_gui->actionSave->setEnabled(false);
  1796. m_gui->actionClose->setEnabled(false);
  1797. m_gui->actionSaveAll->setEnabled(false);
  1798. m_gui->actionUndo->setEnabled(false);
  1799. m_gui->actionRedo->setEnabled(false);
  1800. m_gui->actionCut->setEnabled(false);
  1801. m_gui->actionCopy->setEnabled(false);
  1802. m_gui->actionPaste->setEnabled(false);
  1803. m_gui->actionSaveAs->setEnabled(false);
  1804. m_gui->actionCheckOut->setEnabled(false);
  1805. m_gui->actionGoToLine->setEnabled(false);
  1806. m_gui->action_execute->setEnabled(false);
  1807. m_gui->action_togglebreak->setEnabled(false);
  1808. }
  1809. // special handling for the watches
  1810. m_gui->watchDockWidget->setEnabled(false);
  1811. if (track.debuggerAttached)
  1812. {
  1813. m_gui->watchDockWidget->setEnabled(true);
  1814. }
  1815. if ((!track.targetConnected) || (!track.debuggerAttached))
  1816. {
  1817. // turn off any little yellow arrows (QScintilla)
  1818. TrackedLUAViewMap::iterator viewInfoIter = m_dOpenLUAView.find(m_lastFocusedAssetId);
  1819. if (viewInfoIter != m_dOpenLUAView.end())
  1820. {
  1821. TrackedLUAView& viewInfo = viewInfoIter->second;
  1822. if (viewInfo.luaViewWidget())
  1823. {
  1824. viewInfo.luaViewWidget()->UpdateCurrentExecutingLine(-1);
  1825. }
  1826. }
  1827. }
  1828. if (!track.targetConnected)
  1829. {
  1830. m_pContextButton->setEnabled(false);
  1831. m_pDebugAttachmentButton->setEnabled(false);
  1832. m_gui->action_continue->setEnabled(false);
  1833. m_gui->action_ExecuteOnTarget->setEnabled(false);
  1834. m_gui->action_stepover->setEnabled(false);
  1835. m_gui->action_stepin->setEnabled(false);
  1836. m_gui->action_stepout->setEnabled(false);
  1837. // EARLY OUT
  1838. return;
  1839. }
  1840. // TARGET CONNECTED TRUE IS ASSUMED BEYOND THIS POINT
  1841. m_pContextButton->setEnabled(true);
  1842. m_pDebugAttachmentButton->setEnabled(true);
  1843. if (!track.debuggerAttached)
  1844. {
  1845. m_gui->action_ExecuteOnTarget->setEnabled(false);
  1846. m_gui->action_stepover->setEnabled(false);
  1847. m_gui->action_stepin->setEnabled(false);
  1848. m_gui->action_stepout->setEnabled(false);
  1849. m_gui->action_continue->setEnabled(false);
  1850. // EARLY OUT
  1851. return;
  1852. }
  1853. // DEBUGGER ATTACHED TRUE IS ASSUMED BEYOND THIS POINT
  1854. if (track.scriptRunning)
  1855. {
  1856. if (track.atBreak) // running script and at a break
  1857. {
  1858. m_gui->action_ExecuteOnTarget->setEnabled(false);
  1859. m_gui->action_stepover->setEnabled(true);
  1860. m_gui->action_stepin->setEnabled(true);
  1861. m_gui->action_stepout->setEnabled(true);
  1862. m_gui->action_continue->setEnabled(true);
  1863. }
  1864. else // running script and NOT at a break
  1865. {
  1866. m_gui->action_ExecuteOnTarget->setEnabled(true);
  1867. m_gui->action_stepover->setEnabled(false);
  1868. m_gui->action_stepin->setEnabled(false);
  1869. m_gui->action_stepout->setEnabled(false);
  1870. m_gui->action_continue->setEnabled(false); // this will make it execute remotely...
  1871. }
  1872. }
  1873. else // script NOT running
  1874. {
  1875. if (track.atBreak) // script is NOT running and we're at a break
  1876. {
  1877. m_gui->action_ExecuteOnTarget->setEnabled(false);
  1878. m_gui->action_stepover->setEnabled(track.hasExecuted);
  1879. m_gui->action_stepin->setEnabled(track.hasExecuted);
  1880. m_gui->action_stepout->setEnabled(track.hasExecuted);
  1881. m_gui->action_continue->setEnabled(track.hasExecuted);
  1882. }
  1883. else // script is NOT running and NOT at a break
  1884. {
  1885. if (track.atLeastOneFileOpen)
  1886. {
  1887. m_gui->action_ExecuteOnTarget->setEnabled(true);
  1888. m_gui->action_stepover->setEnabled(track.hasExecuted);
  1889. m_gui->action_stepin->setEnabled(track.hasExecuted);
  1890. m_gui->action_stepout->setEnabled(track.hasExecuted);
  1891. m_gui->action_continue->setEnabled(track.hasExecuted);
  1892. }
  1893. else // NO files open
  1894. {
  1895. m_gui->action_ExecuteOnTarget->setEnabled(false);
  1896. m_gui->action_stepover->setEnabled(false);
  1897. m_gui->action_stepin->setEnabled(false);
  1898. m_gui->action_stepout->setEnabled(false);
  1899. m_gui->action_continue->setEnabled(false);
  1900. }
  1901. }
  1902. }
  1903. }
  1904. bool LUAEditorMainWindow::HasAtLeastOneFileOpen() const
  1905. {
  1906. return m_StateTrack.atLeastOneFileOpen;
  1907. }
  1908. bool LUAEditorMainWindow::eventFilter(QObject* obj, QEvent* event)
  1909. {
  1910. (void)obj;
  1911. if (event->type() == QEvent::KeyPress)
  1912. {
  1913. QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
  1914. if (keyEvent->key() == Qt::Key_C && (keyEvent->modifiers() & Qt::ControlModifier))
  1915. {
  1916. OnEditMenuCopy();
  1917. return true;
  1918. }
  1919. else if (keyEvent->key() == Qt::Key_X && (keyEvent->modifiers() & Qt::ControlModifier))
  1920. {
  1921. OnEditMenuCut();
  1922. return true;
  1923. }
  1924. }
  1925. else if (event->type() == QEvent::KeyRelease)
  1926. {
  1927. QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
  1928. if (keyEvent->key() == Qt::Key_Control)
  1929. {
  1930. m_StoredTabAssetId = "";
  1931. }
  1932. }
  1933. //return QObject::eventFilter(obj, event);
  1934. return false;
  1935. }
  1936. void LUAEditorMainWindow::OnTabForwards()
  1937. {
  1938. TrackedLUACtrlTabOrder::iterator tabIter = m_CtrlTabOrder.begin();
  1939. while (tabIter != m_CtrlTabOrder.end())
  1940. {
  1941. if (*tabIter == m_lastFocusedAssetId)
  1942. {
  1943. break;
  1944. }
  1945. tabIter++;
  1946. }
  1947. if (tabIter == m_CtrlTabOrder.begin())
  1948. {
  1949. tabIter = m_CtrlTabOrder.end();
  1950. --tabIter;
  1951. }
  1952. else
  1953. {
  1954. --tabIter;
  1955. }
  1956. TrackedLUAViewMap::iterator viewInfoIter = m_dOpenLUAView.find(*tabIter);
  1957. if (viewInfoIter != m_dOpenLUAView.end())
  1958. {
  1959. viewInfoIter->second.luaDockWidget()->show();
  1960. viewInfoIter->second.luaDockWidget()->raise();
  1961. viewInfoIter->second.luaViewWidget()->setFocus();
  1962. m_lastFocusedAssetId = *tabIter;
  1963. }
  1964. }
  1965. void LUAEditorMainWindow::OnTabBackwards()
  1966. {
  1967. TrackedLUACtrlTabOrder::iterator tabIter = m_CtrlTabOrder.begin();
  1968. while (tabIter != m_CtrlTabOrder.end())
  1969. {
  1970. if (*tabIter == m_lastFocusedAssetId)
  1971. {
  1972. break;
  1973. }
  1974. tabIter++;
  1975. }
  1976. if (tabIter == m_CtrlTabOrder.end())
  1977. {
  1978. return;
  1979. }
  1980. tabIter++;
  1981. if (tabIter == m_CtrlTabOrder.end())
  1982. {
  1983. tabIter = m_CtrlTabOrder.begin();
  1984. }
  1985. TrackedLUAViewMap::iterator viewInfoIter = m_dOpenLUAView.find(*tabIter);
  1986. if (viewInfoIter != m_dOpenLUAView.end())
  1987. {
  1988. viewInfoIter->second.luaDockWidget()->show();
  1989. viewInfoIter->second.luaDockWidget()->raise();
  1990. viewInfoIter->second.luaViewWidget()->setFocus();
  1991. m_lastFocusedAssetId = *tabIter;
  1992. }
  1993. }
  1994. void LUAEditorMainWindow::dragEnterEvent(QDragEnterEvent* pEvent)
  1995. {
  1996. if (!pEvent->mimeData()->hasUrls())
  1997. {
  1998. return;
  1999. }
  2000. pEvent->acceptProposedAction();
  2001. }
  2002. void LUAEditorMainWindow::dropEvent(QDropEvent* pEvent)
  2003. {
  2004. if (!pEvent->mimeData()->hasUrls())
  2005. {
  2006. return;
  2007. }
  2008. pEvent->setDropAction(Qt::CopyAction);
  2009. pEvent->accept();
  2010. QList<QUrl> urls = pEvent->mimeData()->urls();
  2011. for (int idx = 0; idx < urls.count(); ++idx)
  2012. {
  2013. QString path = urls[idx].toLocalFile();
  2014. AZ_TracePrintf("Debug", "URL: %s\n", path.toUtf8().data());
  2015. AZStd::string assetId(path.toUtf8().data());
  2016. Context_DocumentManagement::Bus::Broadcast(&Context_DocumentManagement::Bus::Events::OnLoadDocument, assetId, true);
  2017. }
  2018. }
  2019. QTabWidget* LUAEditorMainWindow::GetFindTabWidget()
  2020. {
  2021. return m_gui->findTabWidget;
  2022. }
  2023. void LUAEditorMainWindow::AddMessageToLog(AzToolsFramework::Logging::LogLine::LogType type, const char* window, const char* message, void* userData)
  2024. {
  2025. m_gui->m_logPanel->InsertLogLine(type, window, message, userData);
  2026. }
  2027. void LUAEditorMainWindow::LogLineSelectionChanged(const AzToolsFramework::Logging::LogLine& logLine)
  2028. {
  2029. CompilationErrorData* errorData = static_cast<CompilationErrorData*>(logLine.GetUserData());
  2030. if (errorData)
  2031. {
  2032. // Use the data, if it exists from the logLine to make sure the right tab/line is highlighted in the editor
  2033. if (OnRequestFocusView(errorData->m_filename))
  2034. {
  2035. LUAViewWidget* pLUAViewWidget = GetCurrentView();
  2036. if (pLUAViewWidget)
  2037. {
  2038. pLUAViewWidget->SetCursorPosition(errorData->m_lineNumber, 0);
  2039. }
  2040. }
  2041. }
  2042. }
  2043. void LUAEditorMainWindowSavedState::Reflect(AZ::ReflectContext* reflection)
  2044. {
  2045. AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(reflection);
  2046. if (serializeContext)
  2047. {
  2048. serializeContext->Class<LUAEditorMainWindowSavedState, AzToolsFramework::MainWindowSavedState >()
  2049. ->Version(5)
  2050. ->Field("m_openAssetIds", &LUAEditorMainWindowSavedState::m_openAssetIds)
  2051. ->Field("m_bAutocompleteEnabled", &LUAEditorMainWindowSavedState::m_bAutocompleteEnabled)
  2052. ->Field("m_bAutoReloadUnmodifiedFiles", &LUAEditorMainWindowSavedState::m_bAutoReloadUnmodifiedFiles);
  2053. }
  2054. LUAEditorFindDialog::Reflect(reflection);
  2055. }
  2056. void LUAEditorMainWindowLayout::addItem(QLayoutItem* pChild)
  2057. {
  2058. children.push_back(pChild);
  2059. }
  2060. QLayoutItem* LUAEditorMainWindowLayout::itemAt(int index) const
  2061. {
  2062. if (index >= (int)children.size())
  2063. {
  2064. return nullptr;
  2065. }
  2066. return children[index];
  2067. }
  2068. QLayoutItem* LUAEditorMainWindowLayout::takeAt(int index)
  2069. {
  2070. QLayoutItem* pItem = nullptr;
  2071. if (index >= (int)children.size())
  2072. {
  2073. return nullptr;
  2074. }
  2075. pItem = children[index];
  2076. children.erase(children.begin() + index);
  2077. return pItem;
  2078. }
  2079. LUAEditorMainWindowLayout::LUAEditorMainWindowLayout(QWidget* pParent)
  2080. {
  2081. (void)pParent;
  2082. }
  2083. LUAEditorMainWindowLayout::~LUAEditorMainWindowLayout()
  2084. {
  2085. QLayoutItem* item;
  2086. item = takeAt(0);
  2087. while (item)
  2088. {
  2089. delete item;
  2090. item = takeAt(0);
  2091. }
  2092. }
  2093. int LUAEditorMainWindowLayout::count() const
  2094. {
  2095. return (int)children.size();
  2096. }
  2097. void LUAEditorMainWindowLayout::setGeometry (const QRect& r)
  2098. {
  2099. int left, top, right, bottom;
  2100. getContentsMargins(&left, &top, &right, &bottom);
  2101. QRect effectiveRect = r.adjusted(+left, +top, -right, -bottom);
  2102. for (int pos = 0; pos < (int)children.size() - 1; ++pos)
  2103. {
  2104. QLayoutItem* pItem = children[pos];
  2105. pItem->setGeometry(effectiveRect);
  2106. }
  2107. if (children.size())
  2108. {
  2109. // if we have any elements, the last element is top right aligned:
  2110. QLayoutItem* pItem = children[children.size() - 1];
  2111. QSize lastItemSize = pItem->minimumSize();
  2112. const int magicalRightEdgeOffset = pItem->widget()->style()->pixelMetric(QStyle::PM_ScrollBarExtent);
  2113. QRect topRightCorner(effectiveRect.topRight() - QPoint(lastItemSize.width() + magicalRightEdgeOffset, 0) + QPoint(-2, 2), lastItemSize);
  2114. if (pItem->geometry() != topRightCorner)
  2115. {
  2116. pItem->setGeometry(topRightCorner);
  2117. }
  2118. }
  2119. }
  2120. Qt::Orientations LUAEditorMainWindowLayout::expandingDirections() const
  2121. {
  2122. return Qt::Orientations();
  2123. }
  2124. QSize LUAEditorMainWindowLayout::sizeHint() const
  2125. {
  2126. return minimumSize();
  2127. }
  2128. QSize LUAEditorMainWindowLayout::minimumSize() const
  2129. {
  2130. QSize size;
  2131. int left, top, right, bottom;
  2132. getContentsMargins(&left, &top, &right, &bottom);
  2133. for (int pos = 0; pos < (int)children.size(); ++pos)
  2134. {
  2135. QLayoutItem* item = children[pos];
  2136. size = size.expandedTo(item->minimumSize());
  2137. }
  2138. size += (QSize(left + right, top + bottom));
  2139. return size;
  2140. }
  2141. }//namespace LUAEditor
  2142. #include <Source/LUA/moc_LUAEditorMainWindow.cpp>