LUAEditorFindDialog.cpp 54 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419
  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/Serialization/SerializeContext.h>
  9. #include <AzCore/Script/ScriptAsset.h>
  10. #include <AzCore/StringFunc/StringFunc.h>
  11. #include <AzCore/Casting/numeric_cast.h>
  12. #include <AzCore/Component/TickBus.h>
  13. #include "LUAEditorFindDialog.hxx"
  14. #include "LUAEditorMainWindow.hxx"
  15. #include "LUAEditorContextMessages.h"
  16. #include "LUAEditorBlockState.h"
  17. #include <Source/LUA/ui_LUAEditorFindDialog.h>
  18. #include <QMessageBox>
  19. #include <QListWidgetItem>
  20. #include <QTextDocument>
  21. #include <QTimer>
  22. namespace LUAEditorInternal
  23. {
  24. // this stuff goes in the user preferences rather than the global stuff:
  25. class FindSavedState
  26. : public AZ::UserSettings
  27. {
  28. public:
  29. AZ_RTTI(FindSavedState, "{2B880623-63A9-4B39-B8B9-47609590D7D2}", AZ::UserSettings);
  30. AZ_CLASS_ALLOCATOR(FindSavedState, AZ::SystemAllocator);
  31. FindSavedState()
  32. {
  33. m_lastSearchInFilesMode = 0;
  34. m_findWrap = true;
  35. }
  36. int m_lastSearchInFilesMode;
  37. bool m_findWrap;
  38. static void Reflect(AZ::ReflectContext* reflection)
  39. {
  40. AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(reflection);
  41. if (serializeContext)
  42. {
  43. serializeContext->Class<FindSavedState>()
  44. ->Field("m_lastSearchInFilesMode", &FindSavedState::m_lastSearchInFilesMode)
  45. ->Field("m_findWrap", &FindSavedState::m_findWrap);
  46. }
  47. }
  48. };
  49. }
  50. namespace LUAEditor
  51. {
  52. extern AZ::Uuid ContextID;
  53. //////////////////////////////////////////////////////////////////////////
  54. //find dialog
  55. // QDialog(/*parent*/) strip the parent from QDialog and this window will no longer be forced on top all the time
  56. LUAEditorFindDialog::LUAEditorFindDialog(QWidget* parent)
  57. : QDialog(parent)
  58. {
  59. pLUAEditorMainWindow = qobject_cast<LUAEditorMainWindow*>(parent);
  60. AZ_Assert(pLUAEditorMainWindow, "Parent Widget is NULL or not the LUAEditorMainWindow!");
  61. m_bAnyDocumentsOpen = false;
  62. LUAViewMessages::Bus::Handler::BusConnect();
  63. m_bWasFindInAll = false;
  64. m_gui = azcreate(Ui::LUAEditorFindDialog, ());
  65. m_gui->setupUi(this);
  66. this->setFixedSize(this->size());
  67. m_gui->searchDownRadioButton->setChecked(true);
  68. m_gui->searchAndReplaceGroupBox->setChecked(false);
  69. m_gui->regularExpressionCheckBox->setChecked(false);
  70. auto pState = AZ::UserSettings::CreateFind<LUAEditorInternal::FindSavedState>(AZ_CRC("FindInCurrent", 0xba0962af), AZ::UserSettings::CT_LOCAL);
  71. m_gui->wrapCheckBox->setChecked((pState ? pState->m_findWrap : true));
  72. connect(m_gui->wrapCheckBox, &QCheckBox::stateChanged, this, [](int newState)
  73. {
  74. auto pState = AZ::UserSettings::CreateFind<LUAEditorInternal::FindSavedState>(AZ_CRC("FindInCurrent", 0xba0962af), AZ::UserSettings::CT_LOCAL);
  75. pState->m_findWrap = (newState == Qt::Checked);
  76. });
  77. m_bFoundFirst = false;
  78. m_bLastForward = m_gui->searchDownRadioButton->isChecked();
  79. m_bLastWrap = m_gui->wrapCheckBox->isChecked();
  80. //stored dialog state for find/replace
  81. m_bCaseSensitiveIsChecked = false;
  82. m_bWholeWordIsChecked = false;
  83. m_bRegExIsChecked = false;
  84. //find in files stuff
  85. m_bCancelFindSignal = false;
  86. m_bFindThreadRunning = false;
  87. //replace in files stuff
  88. m_bCancelReplaceSignal = false;
  89. m_bReplaceThreadRunning = false;
  90. connect(m_gui->searchWhereComboBox, static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &LUAEditorFindDialog::OnSearchWhereChanged);
  91. connect(this, &LUAEditorFindDialog::triggerFindInFilesNext, this, &LUAEditorFindDialog::FindInFilesNext, Qt::QueuedConnection);
  92. connect(this, &LUAEditorFindDialog::triggerReplaceInFilesNext, this, &LUAEditorFindDialog::ReplaceInFilesNext, Qt::QueuedConnection);
  93. connect(this, &LUAEditorFindDialog::triggerFindNextInView, this, &LUAEditorFindDialog::FindNextInView, Qt::QueuedConnection);
  94. QString stylesheet(R"(QLabel[LUAEditorFindDialogLabel="true"],QGroupBox,QCheckBox,QRadioButton,QPushButton
  95. {
  96. font-size: 12px;
  97. };
  98. QLabel[IdleLabel="true"]
  99. {
  100. font-size:18px;
  101. }
  102. )");
  103. setStyleSheet(stylesheet);
  104. }
  105. LUAViewWidget* LUAEditorFindDialog::GetViewFromParent()
  106. {
  107. LUAViewWidget* pLUAViewWidget = pLUAEditorMainWindow->GetCurrentView();
  108. return pLUAViewWidget;
  109. }
  110. LUAEditorFindDialog::~LUAEditorFindDialog()
  111. {
  112. LUAViewMessages::Bus::Handler::BusDisconnect();
  113. azdestroy(m_gui);
  114. }
  115. void LUAEditorFindDialog::SetAnyDocumentsOpen(bool value)
  116. {
  117. m_bAnyDocumentsOpen = value;
  118. m_gui->searchWhereComboBox->clear();
  119. if (m_bAnyDocumentsOpen)
  120. {
  121. m_gui->searchWhereComboBox->addItem(tr("Current File"));
  122. m_gui->searchWhereComboBox->addItem(tr("All Open Files"));
  123. m_gui->searchWhereComboBox->setCurrentIndex(0);
  124. // TODO: Enable when asset database is in used
  125. //m_gui->searchWhereComboBox->addItem(tr("All LUA Assets"));
  126. // since at least one document is open take this opportunity
  127. // to copy any selected text block to the string to find in the dialog
  128. LUAViewWidget* pLUAViewWidget = GetViewFromParent();
  129. if (pLUAViewWidget)
  130. {
  131. if (pLUAViewWidget->HasSelectedText())
  132. {
  133. QString qstr = pLUAViewWidget->GetSelectedText();
  134. m_gui->txtFind->setText(qstr);
  135. }
  136. }
  137. }
  138. else
  139. {
  140. // TODO: Enable when asset database is in used
  141. //m_gui->searchWhereComboBox->addItem(tr("All LUA Assets"));
  142. m_gui->searchWhereComboBox->setCurrentIndex(0);
  143. }
  144. m_gui->txtFind->setFocus();
  145. m_gui->txtFind->selectAll();
  146. }
  147. // make the "find next" button match the file scope from the pull-down menu
  148. void LUAEditorFindDialog::OnSearchWhereChanged(int index)
  149. {
  150. if (m_bAnyDocumentsOpen)
  151. {
  152. switch (index)
  153. {
  154. case 0:
  155. m_gui->findNextButton->setEnabled(true);
  156. break;
  157. case 1:
  158. case 2:
  159. m_gui->findNextButton->setEnabled(false);
  160. break;
  161. }
  162. }
  163. m_gui->findNextButton->setDefault(m_gui->findNextButton->isEnabled());
  164. m_gui->findAllButton->setDefault(!m_gui->findNextButton->isEnabled());
  165. m_gui->findNextButton->setAutoDefault(m_gui->findNextButton->isEnabled());
  166. m_gui->findAllButton->setAutoDefault(!m_gui->findNextButton->isEnabled());
  167. }
  168. void LUAEditorFindDialog::SaveState()
  169. {
  170. if (m_bAnyDocumentsOpen)
  171. {
  172. auto pState = AZ::UserSettings::CreateFind<LUAEditorInternal::FindSavedState>(m_bWasFindInAll ? AZ_CRC("LUAFindInAny", 0x9b85f4f9) : AZ_CRC("FindInCurrent", 0xba0962af), AZ::UserSettings::CT_LOCAL);
  173. pState->m_lastSearchInFilesMode = m_gui->searchWhereComboBox->currentIndex();
  174. }
  175. }
  176. void LUAEditorFindDialog::SetToFindInAllOpen(bool findInAny)
  177. {
  178. m_bWasFindInAll = findInAny;
  179. // restore prior global mode:
  180. if (m_bAnyDocumentsOpen)
  181. {
  182. auto pState = AZ::UserSettings::Find<LUAEditorInternal::FindSavedState>(findInAny ? AZ_CRC("LUAFindInAny", 0x9b85f4f9) : AZ_CRC("FindInCurrent", 0xba0962af), AZ::UserSettings::CT_LOCAL);
  183. if (pState)
  184. {
  185. m_gui->searchWhereComboBox->setCurrentIndex(pState->m_lastSearchInFilesMode); // theres three options!
  186. m_gui->findNextButton->setEnabled(m_gui->searchWhereComboBox->currentIndex() == 0);
  187. }
  188. else
  189. {
  190. // TODO: When the asset database is in use, this test may want to default to AllLUAAssets instead
  191. m_gui->searchWhereComboBox->setCurrentIndex(findInAny ? AllOpenDocs : CurrentDoc);
  192. m_gui->findNextButton->setEnabled(m_gui->searchWhereComboBox->currentIndex() == 0);
  193. }
  194. }
  195. else
  196. {
  197. m_gui->searchWhereComboBox->setCurrentIndex(CurrentDoc); // theres only one option, no files are open
  198. m_gui->findNextButton->setEnabled(false);
  199. }
  200. m_gui->findNextButton->setDefault(m_gui->findNextButton->isEnabled());
  201. m_gui->findAllButton->setDefault(!m_gui->findNextButton->isEnabled());
  202. m_gui->findNextButton->setAutoDefault(m_gui->findNextButton->isEnabled());
  203. m_gui->findAllButton->setAutoDefault(!m_gui->findNextButton->isEnabled());
  204. if (m_bWasFindInAll)
  205. {
  206. this->setWindowTitle("Find in files...");
  207. }
  208. else
  209. {
  210. this->setWindowTitle("Find...");
  211. }
  212. }
  213. void LUAEditorFindDialog::ResetSearch()
  214. {
  215. m_bFoundFirst = false;
  216. }
  217. // currently used to mark a wrap point for multiple-view searching
  218. void LUAEditorFindDialog::SetNewSearchStarting(bool bOverride, bool bSearchForwards)
  219. {
  220. if (bOverride && bSearchForwards)
  221. {
  222. m_gui->searchDownRadioButton->setChecked(true);
  223. }
  224. else if (bOverride)
  225. {
  226. m_gui->searchUpRadioButton->setChecked(true);
  227. }
  228. m_WrapWidget = GetViewFromParent();
  229. if (m_WrapWidget)
  230. {
  231. m_WrapWidget->GetCursorPosition(m_WrapLine, m_WrapIndex);
  232. }
  233. }
  234. void LUAEditorFindDialog::OnFindNext()
  235. {
  236. if (m_bFindThreadRunning)
  237. {
  238. m_bCancelFindSignal = true;
  239. }
  240. LUAViewWidget* pLUAViewWidget = pLUAEditorMainWindow->GetCurrentView();
  241. if (!pLUAViewWidget)
  242. {
  243. return;
  244. }
  245. if (!m_gui->txtFind->text().isEmpty())
  246. {
  247. if (m_lastSearchText != m_gui->txtFind->text() || m_bLastWrap != m_gui->wrapCheckBox->isChecked())
  248. {
  249. m_bFoundFirst = false;
  250. }
  251. //if we switched from finding forward to backward after finding a first
  252. //the the cursor will be in front of the last find, so the first finding backward
  253. //will re-find the current find (the one we are already found). This is unintuitive
  254. //to the user so instead we find backward to move the cursor to the beginning
  255. //of the current selection then call find next to actually find the next previous
  256. //occurrence as the user intended
  257. //whats strange is this only happens for find backward, find forward seems
  258. //to be smart enough to take this into account already.... so on do another find next
  259. //if searching up
  260. if (m_bFoundFirst &&
  261. m_bLastForward != m_gui->searchDownRadioButton->isChecked())
  262. {
  263. m_findOperation = pLUAViewWidget->FindFirst(m_gui->txtFind->text(),
  264. m_gui->regularExpressionCheckBox->isChecked(),
  265. m_gui->caseSensitiveCheckBox->isChecked(),
  266. m_gui->wholeWordsCheckBox->isChecked(),
  267. m_gui->wrapCheckBox->isChecked(),
  268. m_gui->searchDownRadioButton->isChecked());
  269. if (!m_gui->searchDownRadioButton->isChecked())
  270. {
  271. pLUAViewWidget->FindNext(m_findOperation);
  272. }
  273. }
  274. else if (m_bFoundFirst)
  275. {
  276. pLUAViewWidget->FindNext(m_findOperation);
  277. }
  278. else
  279. {
  280. // if moving backwards move the last result's cursor back one character
  281. // because it's placed at the end of the word and searching back from
  282. // the end of the word simply returns the word again
  283. if (!m_gui->searchDownRadioButton->isChecked())
  284. {
  285. pLUAViewWidget->MoveCursor(-1);
  286. }
  287. m_findOperation = pLUAViewWidget->FindFirst(m_gui->txtFind->text(),
  288. m_gui->regularExpressionCheckBox->isChecked(),
  289. m_gui->caseSensitiveCheckBox->isChecked(),
  290. m_gui->wholeWordsCheckBox->isChecked(),
  291. m_gui->wrapCheckBox->isChecked(),
  292. m_gui->searchDownRadioButton->isChecked());
  293. }
  294. m_lastSearchText = m_gui->txtFind->text();
  295. m_bLastForward = m_gui->searchDownRadioButton->isChecked();
  296. m_bLastWrap = m_gui->wrapCheckBox->isChecked();
  297. }
  298. else
  299. {
  300. QMessageBox::warning(this, "Error!", "You may not search for an empty string!");
  301. }
  302. if (!m_findOperation)
  303. {
  304. QMessageBox::warning(this, "Search failed!", tr("Could not find \"%1\" within/further this context.").arg(m_gui->txtFind->text()));
  305. }
  306. }
  307. void LUAEditorFindDialog::FindInView(LUAViewWidget* pLUAViewWidget, QListWidget* pCurrentFindListView)
  308. {
  309. if (!pLUAViewWidget)
  310. {
  311. return;
  312. }
  313. pLUAViewWidget->SetCursorPosition(0, 0);
  314. auto findOperation = pLUAViewWidget->FindFirst(m_gui->txtFind->text(),
  315. m_gui->regularExpressionCheckBox->isChecked(),
  316. m_gui->caseSensitiveCheckBox->isChecked(),
  317. m_gui->wholeWordsCheckBox->isChecked(),
  318. false,
  319. m_gui->searchDownRadioButton->isChecked());
  320. if (findOperation)
  321. {
  322. emit triggerFindNextInView(&findOperation, pLUAViewWidget, pCurrentFindListView);
  323. }
  324. }
  325. void LUAEditorFindDialog::FindNextInView(LUAViewWidget::FindOperation* operation, LUAViewWidget* pLUAViewWidget, QListWidget* pCurrentFindListView)
  326. {
  327. int line = 0;
  328. int index = 0;
  329. pLUAViewWidget->GetCursorPosition(line, index);
  330. QString itemText;
  331. QString lineTxt;
  332. lineTxt.setNum(line + 1); //files are 1 based
  333. AZStd::string assetFileName(pLUAViewWidget->m_Info.m_assetName + ".lua");
  334. itemText = assetFileName.c_str();
  335. itemText += "(";
  336. itemText += lineTxt;
  337. itemText += "): ";
  338. itemText += pLUAViewWidget->GetLineText(line).trimmed();
  339. QListWidgetItem* pItem = new QListWidgetItem(pCurrentFindListView);
  340. pItem->setText(itemText);
  341. //char buf[64];
  342. //pLUAViewWidget->m_Info.m_assetId.ToString(buf,AZ_ARRAY_SIZE(buf),true,true);
  343. pItem->setData(Qt::UserRole + 1, QVariant(/*buf*/ pLUAViewWidget->m_Info.m_assetId.c_str()));
  344. AZStd::string assetFileName2(pLUAViewWidget->m_Info.m_assetName + ".lua");
  345. pItem->setData(Qt::UserRole + 2, QVariant(assetFileName2.c_str()));
  346. pItem->setData(Qt::UserRole + 3, QVariant(line));
  347. pItem->setData(Qt::UserRole + 4, QVariant(index));
  348. pItem->setData(Qt::UserRole + 5, QVariant(m_gui->txtFind->text().length()));
  349. pCurrentFindListView->addItem(pItem);
  350. pLUAViewWidget->FindNext(*operation);
  351. if (operation && !m_bCancelFindSignal)
  352. {
  353. emit triggerFindNextInView(operation, pLUAViewWidget, pCurrentFindListView);
  354. }
  355. else
  356. {
  357. BusyOff();
  358. }
  359. }
  360. void LUAEditorFindDialog::OnFindAll()
  361. {
  362. if (m_bReplaceThreadRunning)
  363. {
  364. QMessageBox::warning(this, "Error!", "You may not run Find ALL while a Replace All is running!");
  365. return;
  366. }
  367. m_resultList.clear();
  368. m_bCancelFindSignal = false;
  369. m_bFindThreadRunning = true;
  370. int widgetIndex = 0;
  371. if (m_gui->m_find1RadioButton->isChecked())
  372. {
  373. widgetIndex = 0;
  374. }
  375. else if (m_gui->m_find2RadioButton->isChecked())
  376. {
  377. widgetIndex = 1;
  378. }
  379. else if (m_gui->m_find3RadioButton->isChecked())
  380. {
  381. widgetIndex = 2;
  382. }
  383. else if (m_gui->m_find4RadioButton->isChecked())
  384. {
  385. widgetIndex = 3;
  386. }
  387. pLUAEditorMainWindow->SetCurrentFindListWidget(widgetIndex);
  388. auto resultsWidget = pLUAEditorMainWindow->GetFindResultsWidget(widgetIndex);
  389. resultsWidget->Clear();
  390. pLUAEditorMainWindow->ResetSearchClicks();
  391. if (!m_gui->txtFind->text().isEmpty())
  392. {
  393. int theMode = m_gui->searchWhereComboBox->currentIndex();
  394. if (!m_bAnyDocumentsOpen)
  395. {
  396. // TODO: Enable when the asset database is used.
  397. //theMode = AllLUAAssets;
  398. }
  399. else
  400. {
  401. theMode = AllOpenDocs;
  402. }
  403. BusyOn();
  404. m_lastSearchWhere = theMode;
  405. if (theMode == CurrentDoc)
  406. {
  407. FindInFilesSetUp(theMode, resultsWidget);
  408. emit triggerFindInFilesNext(theMode);
  409. }
  410. else if (theMode == AllOpenDocs)
  411. {
  412. FindInFilesSetUp(theMode, resultsWidget);
  413. emit triggerFindInFilesNext(theMode);
  414. }
  415. else if (theMode == AllLUAAssets)
  416. {
  417. FindInFilesSetUp(theMode, resultsWidget);
  418. emit triggerFindInFilesNext(theMode);
  419. }
  420. }
  421. else
  422. {
  423. QMessageBox::warning(this, "Error!", "You may not search for an empty string!");
  424. }
  425. }
  426. void LUAEditorFindDialog::FindInFilesSetUp(int theMode, FindResults* resultsWidget)
  427. {
  428. m_FIFData.m_TotalMatchesFound = 0;
  429. m_FIFData.m_OpenView = pLUAEditorMainWindow->GetAllViews();
  430. if (theMode == CurrentDoc)
  431. {
  432. m_FIFData.m_openViewIter = m_FIFData.m_OpenView.begin();
  433. while (*m_FIFData.m_openViewIter != pLUAEditorMainWindow->GetCurrentView() && m_FIFData.m_openViewIter != m_FIFData.m_OpenView.end())
  434. {
  435. ++m_FIFData.m_openViewIter;
  436. }
  437. }
  438. else
  439. {
  440. m_FIFData.m_openViewIter = m_FIFData.m_OpenView.begin();
  441. }
  442. m_FIFData.m_resultsWidget = resultsWidget;
  443. //get a list of all the lua assets info
  444. m_dFindAllLUAAssetsInfo.clear();
  445. if (theMode == AllLUAAssets)
  446. {
  447. AZ_Assert(false, "Fix assets!");
  448. //AZ::u32 platformFeatureFlags = PLATFORM_FEATURE_FLAGS_ALL;
  449. //EditorFramework::EditorAssetCatalogMessages::Bus::BroadcastResult(
  450. // platformFeatureFlags, &EditorFramework::EditorAssetCatalogMessages::Bus::Events::GetCurrentPlatformFeatureFlags);
  451. //EditorFramework::EditorAssetCatalogMessages::Bus::Broadcast(
  452. // &EditorFramework::EditorAssetCatalogMessages::Bus::Events::FindEditorAssetsByType,
  453. // m_dFindAllLUAAssetsInfo,
  454. // AZ::ScriptAsset::StaticAssetType(),
  455. // platformFeatureFlags);
  456. }
  457. m_SearchText = m_gui->txtFind->text();
  458. m_FIFData.m_dOpenView.clear();
  459. m_FIFData.m_bWholeWordIsChecked = m_gui->wholeWordsCheckBox->isChecked();
  460. m_FIFData.m_bRegExIsChecked = m_gui->regularExpressionCheckBox->isChecked();
  461. m_FIFData.m_bCaseSensitiveIsChecked = m_gui->caseSensitiveCheckBox->isChecked();
  462. if (m_FIFData.m_bWholeWordIsChecked)
  463. {
  464. if (!m_SearchText.startsWith("\b", Qt::CaseInsensitive) &&
  465. !m_SearchText.endsWith("\b", Qt::CaseInsensitive))
  466. {
  467. m_FIFData.m_SearchText = "\\b";
  468. m_FIFData.m_SearchText += m_SearchText;
  469. m_FIFData.m_SearchText += "\\b";
  470. }
  471. }
  472. else
  473. {
  474. m_FIFData.m_SearchText = m_SearchText;
  475. }
  476. m_FIFData.m_assetInfoIter = m_dFindAllLUAAssetsInfo.begin();
  477. }
  478. void LUAEditorFindDialog::FindInFilesNext(int theMode)
  479. {
  480. // one at a time parse the open documents and store their name strings away
  481. if ((!m_bCancelFindSignal) && m_FIFData.m_openViewIter != m_FIFData.m_OpenView.end())
  482. {
  483. // this block mimics the original FindInView() call, localized to the FIF callback scheme
  484. bool syncResult = pLUAEditorMainWindow->SyncDocumentToContext((*m_FIFData.m_openViewIter)->m_Info.m_assetId);
  485. if (syncResult)
  486. {
  487. // successful sync between the QScintilla document and the raw buffer version that we need
  488. const char* buffer = nullptr;
  489. AZStd::size_t actualSize = 0;
  490. Context_DocumentManagement::Bus::Broadcast(
  491. &Context_DocumentManagement::Bus::Events::GetDocumentData,
  492. (*m_FIFData.m_openViewIter)->m_Info.m_assetId,
  493. &buffer,
  494. actualSize);
  495. /************************************************************************/
  496. /* Open files are similar but not identical to closed file processing */
  497. /************************************************************************/
  498. char* pBuf = (char*)azmalloc(actualSize + 1);
  499. char* pCur = pBuf;
  500. pCur[actualSize] = '\0';
  501. memcpy(pCur, buffer, actualSize);
  502. AZStd::vector<char*> dLines;
  503. AZStd::string assetName = (*m_FIFData.m_openViewIter)->m_Info.m_assetName + ".lua";
  504. while (aznumeric_cast<size_t>(pCur - pBuf) <= actualSize)
  505. {
  506. dLines.push_back(pCur);
  507. while (*pCur != '\n' && aznumeric_cast<size_t>(pCur - pBuf) <= actualSize)
  508. {
  509. pCur++;
  510. }
  511. if (aznumeric_cast<size_t>(pCur - pBuf) <= actualSize)
  512. {
  513. *pCur = '\0';
  514. pCur++;
  515. }
  516. }
  517. for (int line = 0; line < dLines.size(); ++line)
  518. {
  519. ResultEntry entry;
  520. entry.m_lineText = dLines[line];
  521. QRegExp regex(m_FIFData.m_SearchText, m_FIFData.m_bCaseSensitiveIsChecked ? Qt::CaseSensitive : Qt::CaseInsensitive);
  522. int index = 0;
  523. if (m_FIFData.m_bRegExIsChecked || m_FIFData.m_bWholeWordIsChecked)
  524. {
  525. index = entry.m_lineText.indexOf(regex, index);
  526. }
  527. else
  528. {
  529. index = entry.m_lineText.indexOf(m_FIFData.m_SearchText, index, m_FIFData.m_bCaseSensitiveIsChecked ? Qt::CaseSensitive : Qt::CaseInsensitive);
  530. }
  531. if (index > -1)
  532. {
  533. const auto& docInfo = (*m_FIFData.m_openViewIter)->m_Info;
  534. ++m_FIFData.m_TotalMatchesFound;
  535. QString qAssetName = assetName.c_str();
  536. if (m_resultList.find(qAssetName) == m_resultList.end())
  537. {
  538. m_resultList[qAssetName].m_assetId = docInfo.m_assetId;
  539. }
  540. entry.m_lineNumber = line + 1;
  541. entry.m_lineText = entry.m_lineText.trimmed();
  542. while (index > -1)
  543. {
  544. if (m_FIFData.m_bRegExIsChecked || m_FIFData.m_bWholeWordIsChecked)
  545. {
  546. entry.m_matches.push_back(AZStd::make_pair(index, regex.matchedLength()));
  547. }
  548. else
  549. {
  550. entry.m_matches.push_back(AZStd::make_pair(index, m_FIFData.m_SearchText.length()));
  551. }
  552. index++;
  553. if (m_FIFData.m_bRegExIsChecked || m_FIFData.m_bWholeWordIsChecked)
  554. {
  555. index = entry.m_lineText.indexOf(regex, index);
  556. }
  557. else
  558. {
  559. index = entry.m_lineText.indexOf(m_FIFData.m_SearchText, index, m_FIFData.m_bCaseSensitiveIsChecked ? Qt::CaseSensitive : Qt::CaseInsensitive);
  560. }
  561. }
  562. m_resultList[qAssetName].m_entries.push_back(entry);
  563. }
  564. }
  565. azfree(pBuf);
  566. }
  567. /************************************************************************/
  568. /* */
  569. /************************************************************************/
  570. if (theMode == CurrentDoc)
  571. {
  572. m_FIFData.m_dOpenView.push_back((*m_FIFData.m_openViewIter)->m_Info.m_assetName + ".lua");
  573. m_FIFData.m_openViewIter = m_FIFData.m_OpenView.end();
  574. }
  575. else
  576. {
  577. ++m_FIFData.m_openViewIter;
  578. if (m_FIFData.m_openViewIter == m_FIFData.m_OpenView.end())
  579. {
  580. for (AZStd::vector<LUAViewWidget*>::iterator openViewIter = m_FIFData.m_OpenView.begin();
  581. openViewIter != m_FIFData.m_OpenView.end(); ++openViewIter)
  582. {
  583. m_FIFData.m_dOpenView.push_back((*openViewIter)->m_Info.m_assetName + ".lua");
  584. }
  585. }
  586. }
  587. emit triggerFindInFilesNext(theMode);
  588. return;
  589. }
  590. if ((!m_bCancelFindSignal) && m_FIFData.m_assetInfoIter != m_dFindAllLUAAssetsInfo.end())
  591. {
  592. // from the previously prepared list of strings of names of open files, is THIS asset open?
  593. bool bIsOpen = false;
  594. for (AZStd::vector<AZStd::string>::iterator iter = m_FIFData.m_dOpenView.begin();
  595. !bIsOpen && iter != m_FIFData.m_dOpenView.end(); ++iter)
  596. {
  597. AZ_Assert(false, "check under!");
  598. //if (*iter == m_FIFData.m_assetInfoIter->m_physicalPath)
  599. if (*iter == *m_FIFData.m_assetInfoIter)
  600. {
  601. bIsOpen = true;
  602. break;
  603. }
  604. }
  605. if (!bIsOpen)
  606. {
  607. /* AZ::IO::Stream* pStream = AZ::IO::g_streamer->RegisterStream(m_FIFData.m_assetInfoIter->m_StreamName.c_str());
  608. if (!pStream)
  609. {
  610. AZ_TracePrintf("LUA", "FindInFilesNext (%s) NULL stream\n",m_FIFData.m_assetInfoIter->m_StreamName);
  611. }
  612. else
  613. {
  614. size_t fileSize = pStream->Size();
  615. char* buf = (char*)dhmalloc(fileSize+1);
  616. buf[fileSize]='\0';
  617. size_t offset=0;
  618. while(size_t bytesRead = AZ::IO::g_streamer->Read(pStream,offset,fileSize-offset,buf+offset))
  619. {
  620. offset += bytesRead;
  621. if(offset == fileSize)
  622. break;
  623. }
  624. AZ::IO::g_streamer->UnRegisterStream(pStream);
  625. char* pCur = buf;
  626. AZStd::vector<char*> dLines;
  627. while(aznumeric_cast<size_t>(pCur - buf) <= fileSize)
  628. {
  629. dLines.push_back(pCur);
  630. while(*pCur != '\n' && aznumeric_cast<size_t>(pCur - buf) <= fileSize)
  631. pCur++;
  632. if(aznumeric_cast<size_t>(pCur - buf) <= fileSize)
  633. {
  634. *pCur = '\0';
  635. pCur++;
  636. }
  637. }
  638. for(int line=0; line<dLines.size(); ++line)
  639. {
  640. ResultEntry entry;
  641. entry.m_lineText = dLines[line];
  642. QRegExp regex(m_FIFData.m_SearchText, m_FIFData.m_bCaseSensitiveIsChecked ? Qt::CaseSensitive : Qt::CaseInsensitive);
  643. int index = 0;
  644. if(m_FIFData.m_bRegExIsChecked || m_FIFData.m_bWholeWordIsChecked)
  645. index = entry.m_lineText.indexOf(regex, index);
  646. else
  647. index = entry.m_lineText.indexOf(m_FIFData.m_SearchText, index, m_FIFData.m_bCaseSensitiveIsChecked ? Qt::CaseSensitive : Qt::CaseInsensitive);
  648. if(index > -1)
  649. {
  650. ++m_FIFData.m_TotalMatchesFound;
  651. QString qAssetName = assetName.c_str();
  652. if (m_resultList.find(qAssetName) == m_resultList.end())
  653. {
  654. m_resultList[qAssetName].m_assetId = AZ::Data::AssetId::CreateNull();
  655. }
  656. entry.m_lineNumber = line;
  657. entry.m_lineText = entry.m_lineText.trimmed();
  658. while (index > -1)
  659. {
  660. if (m_FIFData.m_bRegExIsChecked || m_FIFData.m_bWholeWordIsChecked)
  661. {
  662. entry.m_matches.push_back(AZStd::make_pair(index, regex.matchedLength()));
  663. }
  664. else
  665. {
  666. entry.m_matches.push_back(AZStd::make_pair(index, m_FIFData.m_SearchText.length()));
  667. }
  668. index++;
  669. if (m_FIFData.m_bRegExIsChecked || m_FIFData.m_bWholeWordIsChecked)
  670. index = entry.m_lineText.indexOf(regex, index);
  671. else
  672. index = entry.m_lineText.indexOf(m_FIFData.m_SearchText, index, m_FIFData.m_bCaseSensitiveIsChecked ? Qt::CaseSensitive : Qt::CaseInsensitive);
  673. }
  674. m_resultList[qAssetName].m_entries.push_back(entry);
  675. }
  676. }
  677. dhfree(buf);
  678. }
  679. */
  680. }
  681. ++m_FIFData.m_assetInfoIter;
  682. emit triggerFindInFilesNext(theMode);
  683. return;
  684. }
  685. if (!m_resultList.empty() || m_bCancelFindSignal)
  686. {
  687. if (!m_bCancelFindSignal)
  688. {
  689. PostProcessOn();
  690. AZ::SystemTickBus::QueueFunction(&LUAEditorFindDialog::ProcessFindItems, this);
  691. }
  692. else
  693. {
  694. BusyOff();
  695. }
  696. m_bFindThreadRunning = false;
  697. AZ_TracePrintf("LUA", "Find In Files Matches Found = %d\n", m_FIFData.m_TotalMatchesFound);
  698. }
  699. else
  700. {
  701. m_bFindThreadRunning = false;
  702. BusyOff();
  703. }
  704. }
  705. void LUAEditorFindDialog::ProcessFindItems()
  706. {
  707. auto doc = m_FIFData.m_resultsWidget->Document();
  708. auto setFoldLevel = [&doc](int lineNum, int foldLevel, int depth)
  709. {
  710. QTBlockState blockState;
  711. auto block = doc->findBlockByNumber(lineNum);
  712. AZ_Assert(block.isValid(), "should only be setting fold level on a just added line");
  713. blockState.m_qtBlockState = block.userState();
  714. blockState.m_blockState.m_uninitialized = 0;
  715. blockState.m_blockState.m_folded = 0;
  716. blockState.m_blockState.m_foldLevel = foldLevel;
  717. blockState.m_blockState.m_syntaxHighlighterState = depth;
  718. block.setUserState(blockState.m_qtBlockState);
  719. };
  720. int currentLine = 0;
  721. m_FIFData.m_resultsWidget->Clear();
  722. QString hits;
  723. if (m_FIFData.m_TotalMatchesFound == 1)
  724. {
  725. hits.append("hit");
  726. }
  727. else
  728. {
  729. hits.append("hits");
  730. }
  731. QString files;
  732. if (m_resultList.size() == 1)
  733. {
  734. files.append("file");
  735. }
  736. else
  737. {
  738. files.append("files");
  739. }
  740. QString header("Find \"%1\" (%2 %4 in %3 %5)");
  741. header = header.arg(m_FIFData.m_SearchText).arg(m_FIFData.m_TotalMatchesFound).arg(m_resultList.size()).arg(hits).arg(files);
  742. m_FIFData.m_resultsWidget->AppendPlainText(header);
  743. setFoldLevel(currentLine, 0, 0);
  744. for (auto iter = m_resultList.begin(); iter != m_resultList.end(); ++iter)
  745. {
  746. ++currentLine;
  747. if (iter->m_entries.size() == 1)
  748. {
  749. hits = "hit";
  750. }
  751. else
  752. {
  753. hits = "hits";
  754. }
  755. QString text("\t\"%1\" (%2 %3)");
  756. text = text.arg(iter.key()).arg(iter->m_entries.size()).arg(hits);
  757. m_FIFData.m_resultsWidget->AppendPlainText(text);
  758. setFoldLevel(currentLine, 1, 1);
  759. for (auto& entry : iter->m_entries)
  760. {
  761. ++currentLine;
  762. text = "\t\t\tLine %1: %2";
  763. text = text.arg(entry.m_lineNumber).arg(entry.m_lineText);
  764. m_FIFData.m_resultsWidget->AppendPlainText(text);
  765. AZ_Assert(!entry.m_matches.empty(), "shouldn't be an entry at all if there wasn't at least one match");
  766. setFoldLevel(currentLine, 1, 2);
  767. auto block = doc->findBlockByNumber(currentLine);
  768. AZ_Assert(block.isValid(), "should only be setting data on a just added line");
  769. auto resultsWidget = m_FIFData.m_resultsWidget;
  770. auto assignAssetId = [resultsWidget](const AZStd::string& assetName, const AZStd::string& assetId) {resultsWidget->AssignAssetId(assetName, assetId); };
  771. block.setUserData(aznew FindResultsBlockInfo {iter->m_assetId, iter.key().toUtf8().data(), entry.m_lineNumber,
  772. entry.m_matches[0].first, assignAssetId});
  773. }
  774. setFoldLevel(currentLine, 0, 2);
  775. }
  776. m_FIFData.m_resultsWidget->FinishedAddingText(m_FIFData.m_SearchText, m_FIFData.m_bRegExIsChecked,
  777. m_FIFData.m_bWholeWordIsChecked, m_FIFData.m_bCaseSensitiveIsChecked);
  778. BusyOff();
  779. int findWindow = 0;
  780. if (m_gui->m_find1RadioButton->isChecked())
  781. {
  782. findWindow = 0;
  783. }
  784. else if (m_gui->m_find2RadioButton->isChecked())
  785. {
  786. findWindow = 1;
  787. }
  788. else if (m_gui->m_find3RadioButton->isChecked())
  789. {
  790. findWindow = 2;
  791. }
  792. else if (m_gui->m_find4RadioButton->isChecked())
  793. {
  794. findWindow = 3;
  795. }
  796. //get the find tab and let see it
  797. QTabWidget* pLuaFindTabWidget = pLUAEditorMainWindow->GetFindTabWidget();
  798. AZ_Assert(pLuaFindTabWidget, "LUAEditorMainWindow cant find the FindTabWidget!");
  799. pLuaFindTabWidget->show();
  800. pLuaFindTabWidget->raise();
  801. pLuaFindTabWidget->activateWindow();
  802. pLuaFindTabWidget->setFocus();
  803. pLUAEditorMainWindow->OnOpenFindView(findWindow);
  804. m_resultList.clear();
  805. }
  806. void LUAEditorFindDialog::OnCancel()
  807. {
  808. m_bCancelFindSignal = true;
  809. m_bCancelReplaceSignal = true;
  810. //this->close();
  811. }
  812. void LUAEditorFindDialog::OnReplace()
  813. {
  814. if (m_bFindThreadRunning)
  815. {
  816. m_bCancelFindSignal = true;
  817. }
  818. LUAViewWidget* pLUAViewWidget = GetViewFromParent();
  819. if (!pLUAViewWidget)
  820. {
  821. return;
  822. }
  823. if (pLUAViewWidget->HasSelectedText())
  824. {
  825. if (pLUAViewWidget->m_Info.m_bSourceControl_BusyRequestingEdit ||
  826. pLUAViewWidget->m_Info.m_bSourceControl_BusyGettingStats ||
  827. pLUAViewWidget->m_Info.m_bSourceControl_Ready == false)
  828. {
  829. AZ::SystemTickBus::QueueFunction(&LUAEditorFindDialog::OnReplace, this);
  830. }
  831. else if (!pLUAViewWidget->m_Info.m_bSourceControl_CanWrite &&
  832. pLUAViewWidget->m_Info.m_bSourceControl_CanCheckOut)
  833. {
  834. // check it out for edit
  835. Context_DocumentManagement::Bus::Broadcast(
  836. &Context_DocumentManagement::Bus::Events::DocumentCheckOutRequested, pLUAViewWidget->m_Info.m_assetId);
  837. AZ::SystemTickBus::QueueFunction(&LUAEditorFindDialog::OnReplace, this);
  838. }
  839. else if (!pLUAViewWidget->m_Info.m_bSourceControl_CanWrite)
  840. {
  841. QMessageBox::warning(this, "Error!", "Can not check out file for replace!");
  842. }
  843. else
  844. {
  845. pLUAViewWidget->ReplaceSelectedText(m_gui->txtReplaceWith->text());
  846. int startLine = 0;
  847. int startIndex = 0;
  848. pLUAViewWidget->GetCursorPosition(startLine, startIndex);
  849. pLUAViewWidget->SetCursorPosition(startLine, startIndex + 1);
  850. OnFindNext();
  851. }
  852. }
  853. else
  854. {
  855. OnFindNext();
  856. }
  857. }
  858. void LUAEditorFindDialog::ReplaceInFilesSetUp()
  859. {
  860. BusyOn();
  861. m_bReplaceThreadRunning = true;
  862. m_bCancelReplaceSignal = false;
  863. //get a list of all the lua assets info
  864. m_RIFData.m_dReplaceProcessList.clear();
  865. m_RIFData.m_dReplaceAllLUAAssetsInfo.clear();
  866. AZ_Assert(false, "Fix assets!");
  867. //AZ::u32 platformFeatureFlags = PLATFORM_FEATURE_FLAGS_ALL;
  868. //EditorFramework::EditorAssetCatalogMessages::Bus::BroadcastResult(
  869. // platformFeatureFlags, &EditorFramework::EditorAssetCatalogMessages::Bus::Events::GetCurrentPlatformFeatureFlags);
  870. //EditorFramework::EditorAssetCatalogMessages::Bus::Broadcast(
  871. // &EditorFramework::EditorAssetCatalogMessages::Bus::Events::FindEditorAssetsByType,
  872. // m_RIFData.m_dReplaceAllLUAAssetsInfo,
  873. // AZ::ScriptAsset::StaticAssetType(),
  874. // platformFeatureFlags);
  875. m_RIFData.m_OpenView = pLUAEditorMainWindow->GetAllViews();
  876. m_SearchText = m_gui->txtFind->text();
  877. m_RIFData.m_dOpenView.clear();
  878. for (auto iter = m_RIFData.m_OpenView.begin(); iter != m_RIFData.m_OpenView.end(); ++iter)
  879. {
  880. m_RIFData.m_dOpenView.push_back((*iter)->m_Info.m_assetName + ".lua");
  881. }
  882. m_RIFData.m_bWholeWordIsChecked = m_gui->wholeWordsCheckBox->isChecked();
  883. m_RIFData.m_bRegExIsChecked = m_gui->regularExpressionCheckBox->isChecked();
  884. m_RIFData.m_bCaseSensitiveIsChecked = m_gui->caseSensitiveCheckBox->isChecked();
  885. if (m_RIFData.m_bWholeWordIsChecked)
  886. {
  887. if (!m_SearchText.startsWith("\b", Qt::CaseInsensitive) &&
  888. !m_SearchText.endsWith("\b", Qt::CaseInsensitive))
  889. {
  890. m_RIFData.m_SearchText = "\\b";
  891. m_RIFData.m_SearchText += m_SearchText;
  892. m_RIFData.m_SearchText += "\\b";
  893. }
  894. }
  895. else
  896. {
  897. m_RIFData.m_SearchText = m_SearchText;
  898. }
  899. m_RIFData.m_assetInfoIter = m_RIFData.m_dReplaceAllLUAAssetsInfo.begin();
  900. }
  901. void LUAEditorFindDialog::ReplaceInFilesNext()
  902. {
  903. if (m_bCancelReplaceSignal)
  904. {
  905. BusyOff();
  906. m_bReplaceThreadRunning = false;
  907. m_bCancelReplaceSignal = false;
  908. return; // return with no timer set to call back ends this run
  909. }
  910. if (m_RIFData.m_assetInfoIter != m_RIFData.m_dReplaceAllLUAAssetsInfo.end())
  911. {
  912. //for each asset name, if the asset is not open already, open it search it and close it
  913. {
  914. bool bIsOpen = false;
  915. for (AZStd::vector<AZStd::string>::iterator openViewIter = m_RIFData.m_dOpenView.begin();
  916. openViewIter != m_RIFData.m_dOpenView.end(); ++openViewIter)
  917. {
  918. // is this the right check?
  919. if (*openViewIter == *m_RIFData.m_assetInfoIter)
  920. //if (*openViewIter == m_RIFData.m_assetInfoIter->m_physicalPath)
  921. {
  922. bIsOpen = true;
  923. break;
  924. }
  925. }
  926. if (!bIsOpen)
  927. {
  928. /*
  929. AZ::IO::Stream* pStream = AZ::IO::g_streamer->RegisterStream(m_RIFData.m_assetInfoIter->m_StreamName.c_str());
  930. if (!pStream)
  931. {
  932. AZ_TracePrintf("LUA", "ReplaceInFilesNext (%s) NULL stream\n",m_FIFData.m_assetInfoIter->m_StreamName);
  933. }
  934. else
  935. {
  936. size_t fileSize = pStream->Size();
  937. char* buf = (char*)dhmalloc(fileSize+1);
  938. buf[fileSize]=NULL;
  939. size_t offset=0;
  940. while(size_t bytesRead = AZ::IO::g_streamer->Read(pStream,offset,fileSize-offset,buf+offset))
  941. {
  942. offset += bytesRead;
  943. if(offset == fileSize)
  944. break;
  945. }
  946. AZ::IO::g_streamer->UnRegisterStream(pStream);
  947. char* pCur = buf;
  948. AZStd::vector<char*> dLines;
  949. while(aznumeric_cast<size_t>(pCur - buf) <= fileSize)
  950. {
  951. dLines.push_back(pCur);
  952. while(*pCur != '\n' && aznumeric_cast<size_t>(pCur - buf) <= fileSize)
  953. pCur++;
  954. if(aznumeric_cast<size_t>(pCur - buf) <= fileSize)
  955. {
  956. *pCur = NULL;
  957. pCur++;
  958. }
  959. }
  960. for(AZStd::size_t line=0; line<dLines.size(); ++line)
  961. {
  962. QString str(dLines[line]);
  963. QRegExp regex(m_RIFData.m_SearchText, m_bCaseSensitiveIsChecked ? Qt::CaseSensitive : Qt::CaseInsensitive);
  964. int index = 0;
  965. if(m_bRegExIsChecked || m_bWholeWordIsChecked)
  966. index = str.indexOf(regex, index);
  967. else
  968. index = str.indexOf(m_RIFData.m_SearchText, index, m_bCaseSensitiveIsChecked ? Qt::CaseSensitive : Qt::CaseInsensitive);
  969. if(index > -1)
  970. {
  971. m_RIFData.m_dReplaceProcessList.push_back(assetName.c_str());
  972. line = dLines.size();
  973. }
  974. }
  975. delete buf;
  976. }
  977. */
  978. }
  979. }
  980. ++m_RIFData.m_assetInfoIter;
  981. // are we done with the search and dispatch?
  982. if (m_RIFData.m_assetInfoIter == m_RIFData.m_dReplaceAllLUAAssetsInfo.end())
  983. {
  984. if (!m_RIFData.m_dReplaceProcessList.empty())
  985. {
  986. PostReplaceOn();
  987. QTimer::singleShot(0, this, &LUAEditorFindDialog::ProcessReplaceItems);
  988. }
  989. else
  990. {
  991. m_bReplaceThreadRunning = false;
  992. m_bCancelReplaceSignal = false;
  993. BusyOff();
  994. }
  995. return;
  996. }
  997. QTimer::singleShot(1, this, &LUAEditorFindDialog::ReplaceInFilesNext);
  998. }
  999. }
  1000. void LUAEditorFindDialog::ProcessReplaceItems()
  1001. {
  1002. if (m_bCancelReplaceSignal)
  1003. {
  1004. BusyOff();
  1005. m_bReplaceThreadRunning = false;
  1006. m_bCancelReplaceSignal = false;
  1007. return; // return with no timer set to call back ends this run
  1008. }
  1009. if (!m_RIFData.m_dReplaceProcessList.empty())
  1010. {
  1011. AZStd::string assetName = AZStd::move(m_RIFData.m_dReplaceProcessList.back());
  1012. m_RIFData.m_dReplaceProcessList.pop_back();
  1013. m_RIFData.m_waitingForOpenToComplete.insert(assetName);
  1014. //split physical path into the components saved by the database
  1015. AZStd::string projectRoot, databaseRoot, databasePath, databaseFile, fileExtension;
  1016. if (!AZ::StringFunc::AssetDatabasePath::Split(assetName.c_str(), &projectRoot, &databaseRoot, &databasePath, &databaseFile, &fileExtension))
  1017. {
  1018. AZ_Warning("LUAEditorFindDialog", false, AZStd::string::format("<span severity=\"err\">Path is invalid: '%s'</span>", assetName.c_str()).c_str());
  1019. return;
  1020. }
  1021. //find it in the database
  1022. //AZStd::vector<EditorFramework::EditorAsset> dAssetInfo;
  1023. //EditorFramework::EditorAssetCatalogMessages::Bus::Broadcast(
  1024. // &EditorFramework::EditorAssetCatalogMessages::Bus::Events::FindEditorAssetsByName,
  1025. // dAssetInfo,
  1026. // databaseRoot.c_str(),
  1027. // databasePath.c_str(),
  1028. // databaseFile.c_str(),
  1029. // fileExtension.c_str());
  1030. //if (dAssetInfo.empty())
  1031. // return;
  1032. //request it be opened
  1033. //EditorFramework::AssetManagementMessages::Bus::Event(
  1034. // LUAEditor::ContextID,
  1035. // &EditorFramework::AssetManagementMessages::Bus::Events::AssetOpenRequested,
  1036. // dAssetInfo[0].m_databaseAsset.m_assetId,
  1037. // AZ::ScriptAsset::StaticAssetType());
  1038. QTimer::singleShot(0, this, &LUAEditorFindDialog::ProcessReplaceItems);
  1039. }
  1040. else
  1041. {
  1042. // getting here means we've dispatched all the requests to open the files.
  1043. if ((m_PendingReplaceInViewOperations.empty()) && (m_RIFData.m_waitingForOpenToComplete.empty()))
  1044. {
  1045. BusyOff();
  1046. m_bReplaceThreadRunning = false;
  1047. m_bCancelReplaceSignal = false;
  1048. }
  1049. }
  1050. }
  1051. void LUAEditorFindDialog::OnDataLoadedAndSet(const DocumentInfo& info, LUAViewWidget* pLUAViewWidget)
  1052. {
  1053. auto searcher = m_RIFData.m_waitingForOpenToComplete.find(info.m_assetName);
  1054. if (searcher != m_RIFData.m_waitingForOpenToComplete.end())
  1055. {
  1056. m_RIFData.m_waitingForOpenToComplete.erase(searcher);
  1057. bool wasEmpty = m_PendingReplaceInViewOperations.empty();
  1058. m_PendingReplaceInViewOperations.push_back(pLUAViewWidget);
  1059. // only start iterating the first time:
  1060. if (wasEmpty)
  1061. {
  1062. QTimer::singleShot(0, this, &LUAEditorFindDialog::OnReplaceInViewIterate);
  1063. }
  1064. }
  1065. }
  1066. void LUAEditorFindDialog::OnReplaceInViewIterate()
  1067. {
  1068. if ((m_PendingReplaceInViewOperations.empty()) && (m_RIFData.m_waitingForOpenToComplete.empty()))
  1069. {
  1070. BusyOff();
  1071. m_bCancelReplaceSignal = false;
  1072. m_bReplaceThreadRunning = false;
  1073. return;
  1074. }
  1075. LUAViewWidget* pWidget = m_PendingReplaceInViewOperations.back();
  1076. int result = ReplaceInView(pWidget);
  1077. if (m_bCancelReplaceSignal)
  1078. {
  1079. BusyOff();
  1080. m_bReplaceThreadRunning = false;
  1081. m_bCancelReplaceSignal = false;
  1082. return;
  1083. }
  1084. // any result besides -2 means we're done with this item:
  1085. if (result != -2)
  1086. {
  1087. m_PendingReplaceInViewOperations.pop_back();
  1088. }
  1089. if (!m_PendingReplaceInViewOperations.empty())
  1090. {
  1091. QTimer::singleShot(0, this, &LUAEditorFindDialog::OnReplaceInViewIterate);
  1092. }
  1093. if ((m_PendingReplaceInViewOperations.empty()) && (m_RIFData.m_waitingForOpenToComplete.empty()))
  1094. {
  1095. BusyOff();
  1096. m_bCancelReplaceSignal = false;
  1097. m_bReplaceThreadRunning = false;
  1098. return;
  1099. }
  1100. }
  1101. int LUAEditorFindDialog::ReplaceInView(LUAViewWidget* pLUAViewWidget)
  1102. {
  1103. if (m_bCancelReplaceSignal)
  1104. {
  1105. BusyOff();
  1106. m_bReplaceThreadRunning = false;
  1107. m_bCancelReplaceSignal = false;
  1108. return 0;
  1109. }
  1110. if (pLUAViewWidget->m_Info.m_bSourceControl_BusyRequestingEdit ||
  1111. pLUAViewWidget->m_Info.m_bSourceControl_BusyGettingStats ||
  1112. pLUAViewWidget->m_Info.m_bSourceControl_Ready == false)
  1113. {
  1114. return -2;
  1115. }
  1116. else if (!pLUAViewWidget->m_Info.m_bSourceControl_CanWrite &&
  1117. pLUAViewWidget->m_Info.m_bSourceControl_CanCheckOut)
  1118. {
  1119. // check it out for edit
  1120. Context_DocumentManagement::Bus::Broadcast(
  1121. &Context_DocumentManagement::Bus::Events::DocumentCheckOutRequested, pLUAViewWidget->m_Info.m_assetId);
  1122. return -2;
  1123. }
  1124. else if (!pLUAViewWidget->m_Info.m_bSourceControl_CanWrite)
  1125. {
  1126. QMessageBox::warning(this, "Can not check out file!", (pLUAViewWidget->m_Info.m_assetName + ".lua").c_str());
  1127. return -1;
  1128. }
  1129. int count = 0;
  1130. pLUAViewWidget->SetCursorPosition(0, 0);
  1131. const int advance = m_gui->txtReplaceWith->text().size();
  1132. int firstFoundLine = 0;
  1133. int firstFoundIndex = 0;
  1134. if (pLUAViewWidget->FindFirst(m_gui->txtFind->text(),
  1135. m_gui->regularExpressionCheckBox->isChecked(),
  1136. m_gui->caseSensitiveCheckBox->isChecked(),
  1137. m_gui->wholeWordsCheckBox->isChecked(),
  1138. m_gui->wrapCheckBox->isChecked(),
  1139. m_gui->searchDownRadioButton->isChecked()))
  1140. {
  1141. pLUAViewWidget->GetCursorPosition(firstFoundLine, firstFoundIndex);
  1142. pLUAViewWidget->ReplaceSelectedText(m_gui->txtReplaceWith->text());
  1143. count++;
  1144. while (pLUAViewWidget->FindFirst(m_gui->txtFind->text(),
  1145. m_gui->regularExpressionCheckBox->isChecked(),
  1146. m_gui->caseSensitiveCheckBox->isChecked(),
  1147. m_gui->wholeWordsCheckBox->isChecked(),
  1148. m_gui->wrapCheckBox->isChecked(),
  1149. m_gui->searchDownRadioButton->isChecked()))
  1150. {
  1151. int startLine = 0;
  1152. int startIndex = 0;
  1153. pLUAViewWidget->GetCursorPosition(startLine, startIndex);
  1154. if (startLine == firstFoundLine && startIndex == firstFoundIndex)
  1155. {
  1156. break;
  1157. }
  1158. pLUAViewWidget->ReplaceSelectedText(m_gui->txtReplaceWith->text());
  1159. pLUAViewWidget->GetCursorPosition(startLine, startIndex);
  1160. pLUAViewWidget->SetCursorPosition(startLine, startIndex + advance);
  1161. count++;
  1162. }
  1163. }
  1164. return count;
  1165. }
  1166. void LUAEditorFindDialog::OnReplaceAll()
  1167. {
  1168. if (m_bFindThreadRunning)
  1169. {
  1170. QMessageBox::warning(this, "Error!", "You may not run Replace ALL while a Find All is running!");
  1171. return;
  1172. }
  1173. if (!m_gui->txtFind->text().isEmpty())
  1174. {
  1175. int theMode = m_gui->searchWhereComboBox->currentIndex();
  1176. if (!m_bAnyDocumentsOpen)
  1177. {
  1178. theMode = AllLUAAssets;
  1179. }
  1180. m_lastSearchWhere = theMode;
  1181. if (theMode == CurrentDoc)
  1182. {
  1183. BusyOn();
  1184. m_PendingReplaceInViewOperations.push_back(pLUAEditorMainWindow->GetCurrentView());
  1185. QTimer::singleShot(0, this, &LUAEditorFindDialog::OnReplaceInViewIterate);
  1186. }
  1187. else if (theMode == AllOpenDocs || theMode == AllLUAAssets)
  1188. {
  1189. BusyOn();
  1190. AZStd::vector<LUAViewWidget*> dOpenView = pLUAEditorMainWindow->GetAllViews();
  1191. for (AZStd::vector<LUAViewWidget*>::iterator openViewIter = dOpenView.begin(); openViewIter != dOpenView.end(); ++openViewIter)
  1192. {
  1193. m_PendingReplaceInViewOperations.push_back(*openViewIter);
  1194. }
  1195. QTimer::singleShot(0, this, &LUAEditorFindDialog::OnReplaceInViewIterate);
  1196. if (theMode == AllLUAAssets)
  1197. {
  1198. ReplaceInFilesSetUp();
  1199. emit triggerReplaceInFilesNext();
  1200. }
  1201. }
  1202. }
  1203. else
  1204. {
  1205. QMessageBox::warning(this, "Error!", "You may not replace an empty string!");
  1206. }
  1207. }
  1208. void LUAEditorFindDialog::BusyOn()
  1209. {
  1210. m_gui->cancelButton->setEnabled(true);
  1211. m_gui->busyLabel->setText("Working");
  1212. }
  1213. void LUAEditorFindDialog::BusyOff()
  1214. {
  1215. m_gui->cancelButton->setEnabled(false);
  1216. m_gui->busyLabel->setText("Idle");
  1217. }
  1218. void LUAEditorFindDialog::PostProcessOn()
  1219. {
  1220. m_gui->cancelButton->setEnabled(false);
  1221. m_gui->busyLabel->setText("List Prep");
  1222. }
  1223. void LUAEditorFindDialog::PostReplaceOn()
  1224. {
  1225. BusyOff();
  1226. m_bReplaceThreadRunning = false;
  1227. m_gui->cancelButton->setEnabled(true);
  1228. m_gui->busyLabel->setText("Replacing");
  1229. }
  1230. void LUAEditorFindDialog::showEvent(QShowEvent* event)
  1231. {
  1232. raise();
  1233. QDialog::showEvent(event);
  1234. }
  1235. void LUAEditorFindDialog::Reflect(AZ::ReflectContext* reflection)
  1236. {
  1237. LUAEditorInternal::FindSavedState::Reflect(reflection);
  1238. }
  1239. }//namespace LUAEditor
  1240. #include <Source/LUA/moc_LUAEditorFindDialog.cpp>