LUACompletionModel.cpp 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  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 "LUACompletionModel.hxx"
  9. #include <Source/LUA/LUAEditorStyleMessages.h>
  10. #include <Source/LUA/CodeCompletion/moc_LUACompletionModel.cpp>
  11. namespace LUAEditor
  12. {
  13. void CompletionModel::LUAName::Reset()
  14. {
  15. m_children.clear();
  16. m_fastLookup.clear();
  17. }
  18. void CompletionModel::LUAName::AddName(const QStringList& nameList, int index)
  19. {
  20. if (index >= nameList.size())
  21. {
  22. return;
  23. }
  24. auto iter = m_children.find(nameList[index]);
  25. if (iter == m_children.end())
  26. {
  27. m_children.insert(nameList[index], LUAName());
  28. iter = m_children.find(nameList[index]);
  29. iter->m_name = nullptr;
  30. iter->m_parent = nullptr;
  31. }
  32. iter->AddName(nameList, index + 1);
  33. }
  34. void CompletionModel::LUAName::GenerateFastLookup()
  35. {
  36. m_fastLookup.clear();
  37. for (auto iter = m_children.begin(); iter != m_children.end(); ++iter)
  38. {
  39. iter->m_name = &iter.key();
  40. iter->m_parent = this;
  41. m_fastLookup.push_back(&iter.value());
  42. iter->GenerateFastLookup();
  43. }
  44. }
  45. CompletionModel::CompletionModel(QObject* pParent)
  46. : QAbstractItemModel(pParent)
  47. {
  48. HighlightedWordNotifications::Handler::BusConnect();
  49. UpdateKeywords();
  50. }
  51. CompletionModel::~CompletionModel()
  52. {
  53. HighlightedWordNotifications::Handler::BusDisconnect();
  54. }
  55. void CompletionModel::UpdateKeywords()
  56. {
  57. const HighlightedWords::LUAKeywordsType* keywords = nullptr;
  58. HighlightedWords::Bus::BroadcastResult(keywords, &HighlightedWords::Bus::Events::GetLUAKeywords);
  59. const HighlightedWords::LUAKeywordsType* libraryFuncs = nullptr;
  60. HighlightedWords::Bus::BroadcastResult(libraryFuncs, &HighlightedWords::Bus::Events::GetLUALibraryFunctions);
  61. m_keywords.clear();
  62. m_builtIns.Reset();
  63. for (const auto& keyword : *keywords)
  64. {
  65. m_keywords.push_back(keyword.c_str());
  66. }
  67. for (const auto& keyword : *libraryFuncs)
  68. {
  69. m_keywords.push_back(keyword.c_str());
  70. }
  71. for (const auto& keyword : m_keywords)
  72. {
  73. m_builtIns.AddName(keyword.split(luaSplitRegex));
  74. }
  75. OnScopeNamesUpdated(QStringList());
  76. }
  77. void CompletionModel::OnScopeNamesUpdated(const QStringList& scopeNames)
  78. {
  79. beginResetModel();
  80. m_root = m_builtIns;
  81. for (const auto& scopeName : scopeNames)
  82. {
  83. m_root.AddName(scopeName.split(luaSplitRegex));
  84. }
  85. m_root.GenerateFastLookup();
  86. endResetModel();
  87. }
  88. QVariant CompletionModel::data(const QModelIndex& index, int role) const
  89. {
  90. if (!index.isValid())
  91. {
  92. return QVariant();
  93. }
  94. if (!(role == Qt::DisplayRole || role == Qt::EditRole))
  95. {
  96. return QVariant();
  97. }
  98. LUAName* name = static_cast<LUAName*>(index.internalPointer());
  99. if (!name)
  100. {
  101. return QVariant();
  102. }
  103. return QVariant(*name->m_name);
  104. }
  105. Qt::ItemFlags CompletionModel::flags(const QModelIndex& index) const
  106. {
  107. if (!index.isValid())
  108. {
  109. return Qt::ItemFlags();
  110. }
  111. return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
  112. }
  113. QVariant CompletionModel::headerData([[maybe_unused]] int section, [[maybe_unused]] Qt::Orientation orientation, [[maybe_unused]] int role) const
  114. {
  115. return QVariant();
  116. }
  117. QModelIndex CompletionModel::index(int row, int column, const QModelIndex& parent) const
  118. {
  119. if (column != 0)
  120. {
  121. return QModelIndex();
  122. }
  123. const LUAName* name = nullptr;
  124. if (!parent.isValid())
  125. {
  126. name = &m_root;
  127. }
  128. else
  129. {
  130. name = static_cast<LUAName*>(parent.internalPointer());
  131. }
  132. if (!name)
  133. {
  134. return QModelIndex();
  135. }
  136. if (row < 0 || row >= name->m_children.size())
  137. {
  138. return QModelIndex();
  139. }
  140. return createIndex(row, 0, name->m_fastLookup[row]);
  141. }
  142. QModelIndex CompletionModel::parent(const QModelIndex& index) const
  143. {
  144. if (!index.isValid())
  145. {
  146. return QModelIndex();
  147. }
  148. LUAName* name = static_cast<LUAName*>(index.internalPointer());
  149. if (!name)
  150. {
  151. return QModelIndex();
  152. }
  153. if (name->m_parent == &m_root || !name->m_parent)
  154. {
  155. return QModelIndex();
  156. }
  157. AZ_Assert(name->m_parent->m_parent, "invalid code completion tree");
  158. int row = 0;
  159. for (auto childPtr : name->m_parent->m_parent->m_fastLookup)
  160. {
  161. if (childPtr == name->m_parent)
  162. {
  163. break;
  164. }
  165. ++row;
  166. }
  167. AZ_Assert(row >= 0 && row < name->m_parent->m_parent->m_children.size(), "invalid code completion tree");
  168. return createIndex(row, 0, name->m_parent);
  169. }
  170. int CompletionModel::rowCount(const QModelIndex& parent) const
  171. {
  172. if (!parent.isValid())
  173. {
  174. return m_root.m_children.size();
  175. }
  176. LUAName* name = static_cast<LUAName*>(parent.internalPointer());
  177. if (!name)
  178. {
  179. return m_root.m_children.size();
  180. }
  181. return name->m_children.size();
  182. }
  183. int CompletionModel::columnCount(const QModelIndex&) const
  184. {
  185. return 1;
  186. }
  187. void CompletionModel::LUALibraryFunctionsUpdated()
  188. {
  189. UpdateKeywords();
  190. }
  191. }