basctl/source/basicide/idecodecompletiontypes.cxx | 26 + basctl/source/basicide/idedataprovider.cxx | 291 +++++++++++++++++++++- basctl/source/basicide/idetimer.cxx | 11 basctl/source/basicide/idetimer.hxx | 1 basctl/source/basicide/objectbrowser.cxx | 68 +++-- basctl/source/inc/idedataprovider.hxx | 44 +++ basctl/source/inc/objectbrowser.hxx | 14 - include/basctl/idecodecompletiontypes.hxx | 2 8 files changed, 422 insertions(+), 35 deletions(-)
New commits: commit a2d19c07041bf6fe1208dd7cb94b9c80aff33979 Author: Devansh Varshney <[email protected]> AuthorDate: Tue Sep 23 20:15:09 2025 +0530 Commit: Hossein <[email protected]> CommitDate: Tue Oct 14 18:35:47 2025 +0200 tdf#165785: basctl: Implement data provider for Object Browser This patch introduces the core data-fetching logic for the new Object Browser. It implements the logic to scan all available UNO APIs and to preload BASIC libraries. For this foundational patch, the data initialization is performed synchronously. A subsequent patch will refactor this into a non-blocking, asynchronous operation to keep the UI fully responsive. (GSoC 2025 - Object Browser: Data Provider Implementation) Change-Id: I46446fc498820d9776d77ba25c4fa3fd4ca89a8d Reviewed-on: https://gerrit.libreoffice.org/c/core/+/191405 Tested-by: Jenkins Reviewed-by: Hossein <[email protected]> diff --git a/basctl/source/basicide/idecodecompletiontypes.cxx b/basctl/source/basicide/idecodecompletiontypes.cxx index 3d9d87756c0a..22779828e520 100644 --- a/basctl/source/basicide/idecodecompletiontypes.cxx +++ b/basctl/source/basicide/idecodecompletiontypes.cxx @@ -8,6 +8,7 @@ */ #include <basctl/idecodecompletiontypes.hxx> +#include <rtl/ustrbuf.hxx> namespace basctl { @@ -50,6 +51,31 @@ void IdeSymbolInfo::AddMember(std::shared_ptr<IdeSymbolInfo> pMember) mapMembers.insert_or_assign(pMember->sName, std::move(pMember)); } +OUString CreateRootIdentifier(IdeSymbolKind eKind, std::u16string_view sOptionalPayload) +{ + OUStringBuffer sId(u"root:"); + + switch (eKind) + { + case IdeSymbolKind::ROOT_UNO_APIS: + sId.append(u"uno_apis"); + break; + case IdeSymbolKind::ROOT_APPLICATION_LIBS: + sId.append(u"app_macros"); + break; + case IdeSymbolKind::ROOT_DOCUMENT_LIBS: + sId.append(OUString::Concat(u"doc:") + sOptionalPayload); + break; + case IdeSymbolKind::ROOT_BASIC_BUILTINS: + sId.append(u"builtins"); + break; + default: + sId.append(u"unknown"); + break; + } + return sId.makeStringAndClear(); +} + } // namespace basctl /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/basctl/source/basicide/idedataprovider.cxx b/basctl/source/basicide/idedataprovider.cxx index 7cd4458ba6e8..8d6d27febcb2 100644 --- a/basctl/source/basicide/idedataprovider.cxx +++ b/basctl/source/basicide/idedataprovider.cxx @@ -8,20 +8,299 @@ */ #include <idedataprovider.hxx> -#include <vcl/svapp.hxx> +#include "idetimer.hxx" + +#include <basic/basmgr.hxx> +#include <basctl/scriptdocument.hxx> +#include <comphelper/processfactory.hxx> +#include <sal/log.hxx> + +#include <com/sun/star/container/XHierarchicalNameAccess.hpp> +#include <com/sun/star/reflection/XTypeDescriptionEnumeration.hpp> +#include <com/sun/star/reflection/XTypeDescriptionEnumerationAccess.hpp> +#include <com/sun/star/reflection/theCoreReflection.hpp> namespace basctl { -IdeDataProvider::IdeDataProvider() {} +using namespace basic; + +namespace css = ::com::sun::star; +using namespace css::container; +using namespace css::uno; +using namespace css::lang; +using namespace css::reflection; + +IdeDataProvider::IdeDataProvider() + : m_pUnoHierarchy(std::make_unique<UnoApiHierarchy>()) + , m_bInitialized(false) +{ +} + +void IdeDataProvider::Initialize() +{ + if (m_bInitialized) + return; + + IdeTimer aTotalInitTimer(u"IdeDataProvider::Initialize (Synchronous)"_ustr); + SAL_INFO("basctl", "Starting synchronous data provider initialization..."); + + // Perform a full synchronous UNO scan + SAL_INFO("basctl", "Performing full synchronous UNO scan..."); + performFullUnoScan(); + + // Preload all BASIC Libraries + IdeTimer aBasicTimer(u"IdeDataProvider::Initialize (Basic Library Preload)"_ustr); + SAL_INFO("basctl", "Starting BASIC library preload..."); + + try + { + ScriptDocument aAppDoc = ScriptDocument::getApplicationScriptDocument(); + if (aAppDoc.isAlive()) + { + Reference<css::script::XLibraryContainer> xLibContainer + = aAppDoc.getLibraryContainer(E_SCRIPTS); + if (xLibContainer.is()) + { + for (const OUString& rLibName : xLibContainer->getElementNames()) + { + try + { + if (xLibContainer->hasByName(rLibName) + && !xLibContainer->isLibraryLoaded(rLibName)) + { + xLibContainer->loadLibrary(rLibName); + } + } + catch (const Exception& e) + { + SAL_WARN("basctl", "Exception while preloading application library '" + << rLibName << "': " << e.Message); + } + } + } + } + } + catch (const Exception& e) + { + SAL_WARN("basctl", "Could not retrieve Application library container: " << e.Message); + } + + // Preload from any open documents + try + { + for (const auto& rDoc : + ScriptDocument::getAllScriptDocuments(ScriptDocument::DocumentsSorted)) + { + if (rDoc.isAlive()) + { + auto xDocLibContainer = rDoc.getLibraryContainer(E_SCRIPTS); + if (xDocLibContainer.is()) + { + for (const OUString& rLibName : xDocLibContainer->getElementNames()) + { + try + { + if (xDocLibContainer->hasByName(rLibName) + && !xDocLibContainer->isLibraryLoaded(rLibName)) + { + xDocLibContainer->loadLibrary(rLibName); + } + } + catch (const Exception& e) + { + SAL_WARN("basctl", "Exception while preloading document library '" + << rLibName << "' in document '" + << rDoc.getTitle() << "': " << e.Message); + } + } + } + } + } + } + catch (const Exception& e) + { + SAL_WARN("basctl", "Could not iterate through document libraries: " << e.Message); + } + SAL_INFO("basctl", "BASIC library preload finished."); + + m_aTopLevelNodes.clear(); + m_aTopLevelNodes.push_back( + std::make_shared<IdeSymbolInfo>(u"UNO APIs", IdeSymbolKind::ROOT_UNO_APIS, u"root")); + m_aTopLevelNodes.push_back(std::make_shared<IdeSymbolInfo>( + u"Application Macros", IdeSymbolKind::ROOT_APPLICATION_LIBS, u"root")); + + m_bInitialized = true; + SAL_INFO("basctl", "Synchronous data provider initialization complete."); +} + +void IdeDataProvider::Reset() +{ + SAL_INFO("basctl", "IdeDataProvider: Resetting state."); + m_bInitialized = false; + m_aTopLevelNodes.clear(); -IdeDataProvider::~IdeDataProvider() = default; + m_pUnoHierarchy = std::make_unique<UnoApiHierarchy>(); +} -void IdeDataProvider::AsyncInitialize(const Link<void*, void>& rFinishCallback) +void IdeDataProvider::performFullUnoScan() { - Application::PostUserEvent(rFinishCallback); + IdeTimer aScanTimer(u"IdeDataProvider::performFullUnoScan"_ustr); + sal_Int32 nProcessedCount = 0; + + try + { + Reference<XHierarchicalNameAccess> xTypeManager; + comphelper::getProcessComponentContext()->getValueByName( + u"/singletons/com.sun.star.reflection.theTypeDescriptionManager"_ustr) + >>= xTypeManager; + + if (xTypeManager.is()) + { + Reference<XTypeDescriptionEnumerationAccess> xEnumAccess(xTypeManager, UNO_QUERY_THROW); + Reference<XEnumeration> xEnum = xEnumAccess->createTypeDescriptionEnumeration( + u""_ustr, {}, TypeDescriptionSearchDepth_INFINITE); + + while (xEnum.is() && xEnum->hasMoreElements()) + { + try + { + Reference<XTypeDescription> xTypeDesc; + if ((xEnum->nextElement() >>= xTypeDesc) && xTypeDesc.is()) + { + m_pUnoHierarchy->addNode(xTypeDesc->getName(), xTypeDesc->getTypeClass()); + nProcessedCount++; + } + } + catch (const Exception& e) + { + SAL_WARN("basctl", + "performFullUnoScan: Exception processing a single UNO type: " + << e.Message); + } + } + } + } + catch (const Exception& e) + { + SAL_WARN("basctl", "Full UNO scan failed with exception: " << e.Message); + } + + sal_Int64 nFullScanTimeMs = aScanTimer.getElapsedTimeMs(); + SAL_INFO("basctl", "UNO scan completed in " << nFullScanTimeMs << " ms. Found " + << nProcessedCount << " types."); } -bool IdeDataProvider::IsInitialized() const { return m_bInitialized; } +SymbolInfoList IdeDataProvider::GetTopLevelNodes() +{ + if (!m_bInitialized) + { + SymbolInfoList aNodes; + auto pLoadingNode = std::make_shared<IdeSymbolInfo>(u"[Initializing...]", + IdeSymbolKind::PLACEHOLDER, u""); + pLoadingNode->bSelectable = false; + aNodes.push_back(pLoadingNode); + return aNodes; + } + return m_aTopLevelNodes; +} + +GroupedSymbolInfoList IdeDataProvider::GetMembers(const IdeSymbolInfo& /*rNode*/) { return {}; } + +SymbolInfoList IdeDataProvider::GetChildNodes(const IdeSymbolInfo& rParent) +{ + if (!m_bInitialized) + { + return {}; + } + + SymbolInfoList aChildren; + if (rParent.eKind == IdeSymbolKind::ROOT_UNO_APIS) + { + aChildren = m_pUnoHierarchy->m_hierarchyCache[OUString()]; + } + else if (rParent.eKind == IdeSymbolKind::UNO_NAMESPACE) + { + aChildren = m_pUnoHierarchy->m_hierarchyCache[rParent.sQualifiedName]; + } + + return aChildren; +} + +void UnoApiHierarchy::addNode(std::u16string_view sQualifiedNameView, TypeClass eTypeClass) +{ + const OUString sQualifiedName(sQualifiedNameView); + + if (sQualifiedName.isEmpty()) + return; + + OUString sParentPath; + OUString sCurrentPath; + sal_Int32 nStartIndex = 0; + sal_Int32 nDotIndex; + + do + { + nDotIndex = sQualifiedName.indexOf('.', nStartIndex); + OUString sPart = (nDotIndex == -1) + ? sQualifiedName.copy(nStartIndex) + : sQualifiedName.copy(nStartIndex, nDotIndex - nStartIndex); + + if (sPart.isEmpty()) + continue; + + sParentPath = sCurrentPath; + sCurrentPath = sCurrentPath.isEmpty() ? sPart : sCurrentPath + u"." + sPart; + + // Find the list of childern for the current parent + auto& rChildren = m_hierarchyCache[sParentPath]; + + // Avoid adding duplicate nodes + bool bExists = std::any_of(rChildren.begin(), rChildren.end(), + [&sPart](const auto& pNode) { return pNode->sName == sPart; }); + + if (!bExists) + { + IdeSymbolKind eKind = (nDotIndex == -1) ? typeClassToSymbolKind(eTypeClass) + : IdeSymbolKind::UNO_NAMESPACE; + + auto pNewNode + = std::make_shared<IdeSymbolInfo>(sPart.getStr(), eKind, sParentPath.getStr()); + pNewNode->sQualifiedName = sCurrentPath; + pNewNode->sParentName = sParentPath; + pNewNode->sIdentifier = sCurrentPath; + rChildren.push_back(std::move(pNewNode)); + } + + nStartIndex = nDotIndex + 1; + } while (nDotIndex != -1); +} + +IdeSymbolKind UnoApiHierarchy::typeClassToSymbolKind(TypeClass eTypeClass) +{ + switch (eTypeClass) + { + case TypeClass_INTERFACE: + return IdeSymbolKind::UNO_INTERFACE; + case TypeClass_STRUCT: + return IdeSymbolKind::UNO_STRUCT; + case TypeClass_ENUM: + return IdeSymbolKind::UNO_ENUM; + case TypeClass_TYPEDEF: + return IdeSymbolKind::UNO_TYPEDEF; + case TypeClass_CONSTANTS: + return IdeSymbolKind::UNO_CONSTANTS; + case TypeClass_EXCEPTION: + return IdeSymbolKind::UNO_EXCEPTION; + case TypeClass_SERVICE: + return IdeSymbolKind::UNO_SERVICE; + case TypeClass_MODULE: + return IdeSymbolKind::UNO_NAMESPACE; + case TypeClass_SINGLETON: + return IdeSymbolKind::UNO_SERVICE; // Treat singletons as services + default: + return IdeSymbolKind::UNO_TYPE; + } +} } // namespace basctl diff --git a/basctl/source/basicide/idetimer.cxx b/basctl/source/basicide/idetimer.cxx index 2818890e1999..9e8d135fda12 100644 --- a/basctl/source/basicide/idetimer.cxx +++ b/basctl/source/basicide/idetimer.cxx @@ -37,6 +37,17 @@ IdeTimer::~IdeTimer() << "' took " << fElapsedSeconds << " seconds."); } +sal_Int64 IdeTimer::getElapsedTimeMs() const +{ + TimeValue aEnd; + osl_getSystemTime(&aEnd); + + sal_Int64 nSeconds = static_cast<sal_Int64>(aEnd.Seconds) - m_aStart.Seconds; + sal_Int64 nNanos = static_cast<sal_Int64>(aEnd.Nanosec) - m_aStart.Nanosec; + + return (nSeconds * 1000) + (nNanos / 1000000); +} + } // namespace basctl /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/basctl/source/basicide/idetimer.hxx b/basctl/source/basicide/idetimer.hxx index 58f4c0bda589..2cf28b5a0264 100644 --- a/basctl/source/basicide/idetimer.hxx +++ b/basctl/source/basicide/idetimer.hxx @@ -23,6 +23,7 @@ class IdeTimer public: explicit IdeTimer(const rtl::OUString& operationName); ~IdeTimer(); + sal_Int64 getElapsedTimeMs() const; private: IdeTimer(const IdeTimer&) = delete; diff --git a/basctl/source/basicide/objectbrowser.cxx b/basctl/source/basicide/objectbrowser.cxx index 8b7c9f411ed9..5ccac1884b6f 100644 --- a/basctl/source/basicide/objectbrowser.cxx +++ b/basctl/source/basicide/objectbrowser.cxx @@ -11,15 +11,16 @@ #include <objectbrowser.hxx> #include <objectbrowsersearch.hxx> #include <idedataprovider.hxx> +#include "idetimer.hxx" #include <iderid.hxx> #include <strings.hrc> -#include <vcl/svapp.hxx> #include <vcl/taskpanelist.hxx> #include <sal/log.hxx> #include <sfx2/bindings.hxx> #include <sfx2/sfxsids.hrc> #include <sfx2/viewfrm.hxx> +#include <vcl/weld.hxx> namespace basctl { @@ -29,14 +30,13 @@ ObjectBrowser::ObjectBrowser(Shell& rShell, vcl::Window* pParent) , m_pShell(&rShell) , m_pDataProvider(std::make_unique<IdeDataProvider>()) , m_bDisposed(false) + , m_eInitState(ObjectBrowserInitState::NotInitialized) , m_bUIInitialized(false) , m_pDocNotifier(std::make_unique<DocumentEventNotifier>(*this)) { SetText(IDEResId(RID_STR_OBJECT_BROWSER)); SetBackground(GetSettings().GetStyleSettings().GetWindowColor()); EnableInput(true, true); - - Initialize(); } ObjectBrowser::~ObjectBrowser() { disposeOnce(); } @@ -103,6 +103,7 @@ void ObjectBrowser::dispose() { return; } + m_bDisposed = true; m_eInitState = ObjectBrowserInitState::Disposed; @@ -154,48 +155,82 @@ void ObjectBrowser::dispose() bool ObjectBrowser::Close() { Show(false); - - SfxBindings& rBindings = m_pShell->GetViewFrame().GetBindings(); - rBindings.Invalidate(SID_BASICIDE_OBJECT_BROWSER); - + m_pShell->GetViewFrame().GetBindings().Invalidate(SID_BASICIDE_OBJECT_BROWSER); return false; } void ObjectBrowser::Show(bool bVisible) { DockingWindow::Show(bVisible); + if (!bVisible) + return; - if (bVisible) + if (m_eInitState == ObjectBrowserInitState::NotInitialized) { - if (m_eInitState == ObjectBrowserInitState::NotInitialized) - { - Initialize(); - } + Initialize(); + } - if (!m_pDataProvider->IsInitialized()) + if (m_pDataProvider && !m_pDataProvider->IsInitialized()) + { + ShowLoadingState(); { - ShowLoadingState(); - m_pDataProvider->AsyncInitialize(LINK(this, ObjectBrowser, OnDataProviderInitialized)); + weld::WaitObject aWait(GetFrameWeld()); + m_pDataProvider->Initialize(); } + RefreshUI(); } } void ObjectBrowser::RefreshUI(bool /*bForceKeepUno*/) { - if (!m_pDataProvider->IsInitialized()) + if (m_pDataProvider && m_pDataProvider->IsInitialized()) + { + PopulateLeftTree(); + if (m_xStatusLabel) + m_xStatusLabel->set_label(u"Ready"_ustr); + } + else { ShowLoadingState(); } } +void ObjectBrowser::PopulateLeftTree() +{ + if (!m_xLeftTreeView) + return; + + m_xLeftTreeView->freeze(); + ClearTreeView(*m_xLeftTreeView, m_aLeftTreeSymbolStore); + + SymbolInfoList aTopLevelNodes = m_pDataProvider->GetTopLevelNodes(); + for (const auto& pNode : aTopLevelNodes) + { + m_aLeftTreeSymbolStore.push_back(pNode); + m_xLeftTreeView->insert(nullptr, -1, &pNode->sName, nullptr, nullptr, nullptr, true, + nullptr); + } + + m_xLeftTreeView->thaw(); +} + void ObjectBrowser::ShowLoadingState() { if (m_xLeftTreeView) { m_xLeftTreeView->freeze(); ClearTreeView(*m_xLeftTreeView, m_aLeftTreeSymbolStore); + + auto pLoadingNode = std::make_shared<IdeSymbolInfo>(u"[Initializing...]", + IdeSymbolKind::PLACEHOLDER, u""); + + m_aLeftTreeSymbolStore.push_back(pLoadingNode); + m_xLeftTreeView->insert(nullptr, -1, &pLoadingNode->sName, nullptr, nullptr, nullptr, false, + nullptr); m_xLeftTreeView->thaw(); } + if (m_xStatusLabel) + m_xStatusLabel->set_label(u"Initializing Object Browser..."_ustr); } void ObjectBrowser::ClearTreeView(weld::TreeView& rTree, @@ -215,7 +250,6 @@ void ObjectBrowser::onDocumentClosed(const ScriptDocument&) { /* STUB */} void ObjectBrowser::onDocumentTitleChanged(const ScriptDocument&) { /* STUB */} void ObjectBrowser::onDocumentModeChanged(const ScriptDocument&) { /* STUB */} -IMPL_STATIC_LINK(ObjectBrowser, OnDataProviderInitialized, void*, /*p*/, void) { /* STUB */} IMPL_STATIC_LINK(ObjectBrowser, OnLeftTreeSelect, weld::TreeView&, /*rTree*/, void) { /* STUB */} IMPL_STATIC_LINK(ObjectBrowser, OnRightTreeSelect, weld::TreeView&, /*rTree*/, void) { /* STUB */} IMPL_STATIC_LINK(ObjectBrowser, OnNodeExpand, const weld::TreeIter&, /*rParentIter*/, bool) diff --git a/basctl/source/inc/idedataprovider.hxx b/basctl/source/inc/idedataprovider.hxx index 73d46badf140..4d943b1f7556 100644 --- a/basctl/source/inc/idedataprovider.hxx +++ b/basctl/source/inc/idedataprovider.hxx @@ -12,27 +12,63 @@ #include <basctl/idecodecompletiontypes.hxx> #include <memory> +#include <vector> + +#include <rtl/ustring.hxx> #include <tools/link.hxx> +#include <com/sun/star/uno/TypeClass.hpp> + namespace basctl { +using IdeSymbolInfo = basctl::IdeSymbolInfo; +using SymbolInfoList = std::vector<std::shared_ptr<IdeSymbolInfo>>; +using GroupedSymbolInfoList = std::map<IdeSymbolKind, SymbolInfoList>; + +// Data structure for the in-memory UNO type hierarchy +struct UnoApiHierarchy +{ + std::map<OUString, SymbolInfoList> m_hierarchyCache; + void addNode(std::u16string_view sQualifiedName, css::uno::TypeClass eTypeClass); + static IdeSymbolKind typeClassToSymbolKind(css::uno::TypeClass eTypeClass); +}; + class IdeDataProviderInterface { public: virtual ~IdeDataProviderInterface() = default; - virtual void AsyncInitialize(const Link<void*, void>& rFinishCallback) = 0; + + virtual void Initialize() = 0; virtual bool IsInitialized() const = 0; + virtual void Reset() = 0; + + // Data Access Methods + virtual SymbolInfoList GetTopLevelNodes() = 0; + virtual GroupedSymbolInfoList GetMembers(const IdeSymbolInfo& rNode) = 0; + virtual SymbolInfoList GetChildNodes(const IdeSymbolInfo& rParent) = 0; }; class IdeDataProvider : public IdeDataProviderInterface { public: IdeDataProvider(); - ~IdeDataProvider() override; - void AsyncInitialize(const Link<void*, void>& rFinishCallback) override; - bool IsInitialized() const override; + + void Initialize() override; + bool IsInitialized() const override { return m_bInitialized; } + void Reset() override; + + SymbolInfoList GetTopLevelNodes() override; + GroupedSymbolInfoList GetMembers(const IdeSymbolInfo& rNode) override; + SymbolInfoList GetChildNodes(const IdeSymbolInfo& rParent) override; private: + void performFullUnoScan(); + + // Core data + std::unique_ptr<UnoApiHierarchy> m_pUnoHierarchy; + SymbolInfoList m_aTopLevelNodes; + + // State management bool m_bInitialized = false; }; diff --git a/basctl/source/inc/objectbrowser.hxx b/basctl/source/inc/objectbrowser.hxx index d280b395b524..196d009bba22 100644 --- a/basctl/source/inc/objectbrowser.hxx +++ b/basctl/source/inc/objectbrowser.hxx @@ -15,12 +15,9 @@ #include <basctl/idecodecompletiontypes.hxx> -#include <atomic> #include <memory> -#include <set> #include <vector> -#include <vcl/status.hxx> #include <vcl/weld.hxx> namespace basctl @@ -28,7 +25,6 @@ namespace basctl class Shell; class IdeDataProviderInterface; class ObjectBrowserSearch; -class ObjectBrowserNavigation; enum class ObjectBrowserInitState { @@ -45,12 +41,13 @@ public: ObjectBrowser(Shell& rShell, vcl::Window* pParent); ~ObjectBrowser() override; - virtual void dispose() override; + void dispose() override; virtual bool Close() override; void Show(bool bVisible = true); void RefreshUI(bool bForceKeepUno = false); + // DocumentEventListener stubs void onDocumentCreated(const ScriptDocument& _rDocument) override; void onDocumentOpened(const ScriptDocument& _rDocument) override; void onDocumentSave(const ScriptDocument& _rDocument) override; @@ -61,6 +58,7 @@ public: void onDocumentTitleChanged(const ScriptDocument& _rDocument) override; void onDocumentModeChanged(const ScriptDocument& _rDocument) override; + // Accessors for the Search Handler weld::Entry* GetFilterBox() { return m_pFilterBox.get(); } weld::Button* GetClearSearchButton() { return m_xClearSearchButton.get(); } @@ -70,6 +68,7 @@ private: // Core tree management methods static void ClearTreeView(weld::TreeView& rTree, std::vector<std::shared_ptr<basctl::IdeSymbolInfo>>& rStore); + void PopulateLeftTree(); void ShowLoadingState(); // Core References @@ -95,7 +94,7 @@ private: std::unique_ptr<weld::Button> m_xForwardButton; std::unique_ptr<weld::Button> m_xClearSearchButton; - // Data Storage + // Data Storage for TreeViews std::vector<std::shared_ptr<basctl::IdeSymbolInfo>> m_aLeftTreeSymbolStore; std::vector<std::shared_ptr<basctl::IdeSymbolInfo>> m_aRightTreeSymbolStore; std::map<OUString, size_t> m_aNextChunk; // For lazy-loading nodes @@ -106,8 +105,7 @@ private: // Event Handling std::unique_ptr<basctl::DocumentEventNotifier> m_pDocNotifier; - // Event Handlers - DECL_STATIC_LINK(ObjectBrowser, OnDataProviderInitialized, void*, void); + // UI Event Handlers DECL_STATIC_LINK(ObjectBrowser, OnLeftTreeSelect, weld::TreeView&, void); DECL_STATIC_LINK(ObjectBrowser, OnRightTreeSelect, weld::TreeView&, void); DECL_STATIC_LINK(ObjectBrowser, OnNodeExpand, const weld::TreeIter&, bool); diff --git a/include/basctl/idecodecompletiontypes.hxx b/include/basctl/idecodecompletiontypes.hxx index 45ab8785fbae..ff31a273e8b5 100644 --- a/include/basctl/idecodecompletiontypes.hxx +++ b/include/basctl/idecodecompletiontypes.hxx @@ -169,6 +169,8 @@ struct IdeSymbolInfo using SymbolInfoList = std::vector<std::shared_ptr<IdeSymbolInfo>>; using ParamInfoList = std::vector<IdeParamInfo>; +OUString CreateRootIdentifier(IdeSymbolKind eKind, std::u16string_view sOptionalPayload = u""); + } // namespace basctl /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
