[Libreoffice-commits] core.git: include/sfx2 sfx2/Library_sfx.mk sfx2/source
Tomaž Vajngerl (via logerrit)
logerrit at kemper.freedesktop.org
Thu Feb 11 11:55:36 UTC 2021
include/sfx2/devtools/DevelopmentToolDockingWindow.hxx | 6
include/sfx2/devtools/ObjectInspectorTreeHandler.hxx | 44 +
sfx2/Library_sfx.mk | 1
sfx2/source/devtools/DevelopmentToolDockingWindow.cxx | 501 ----------------
sfx2/source/devtools/ObjectInspectorTreeHandler.cxx | 503 +++++++++++++++++
5 files changed, 557 insertions(+), 498 deletions(-)
New commits:
commit e44639f50056b843913573b4635517019e00431c
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
AuthorDate: Mon Feb 8 22:41:36 2021 +0900
Commit: Tomaž Vajngerl <quikee at gmail.com>
CommitDate: Thu Feb 11 12:54:47 2021 +0100
devtools: move handling of object inspector tree to own class/files
To make handling of object inspector tree view easier, move the
functionality to its own class and file.
Change-Id: I47ae1bc06b582d0d146e7e97bc08a3b5f82ce794
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/110734
Tested-by: Jenkins
Reviewed-by: Tomaž Vajngerl <quikee at gmail.com>
diff --git a/include/sfx2/devtools/DevelopmentToolDockingWindow.hxx b/include/sfx2/devtools/DevelopmentToolDockingWindow.hxx
index 1ed166239949..4721a424e66d 100644
--- a/include/sfx2/devtools/DevelopmentToolDockingWindow.hxx
+++ b/include/sfx2/devtools/DevelopmentToolDockingWindow.hxx
@@ -16,6 +16,7 @@
#include <vcl/weld.hxx>
#include <sfx2/devtools/DocumentModelTreeHandler.hxx>
+#include <sfx2/devtools/ObjectInspectorTreeHandler.hxx>
#include <com/sun/star/uno/XInterface.hpp>
#include <com/sun/star/uno/Reference.hxx>
@@ -37,18 +38,15 @@ private:
css::uno::Reference<css::view::XSelectionChangeListener> mxSelectionListener;
DocumentModelTreeHandler maDocumentModelTreeHandler;
+ ObjectInspectorTreeHandler maObjectInspectorTreeHandler;
DECL_LINK(DocumentModelTreeViewSelectionHandler, weld::TreeView&, void);
DECL_LINK(SelectionToggled, weld::ToggleButton&, void);
- DECL_LINK(ObjectInspectorExpandingHandler, const weld::TreeIter&, bool);
-
void inspectDocument();
void updateSelection();
void inspectSelectionOrRoot(css::uno::Reference<css::frame::XController> const& xController);
- void clearObjectInspectorChildren(weld::TreeIter const& rParent);
-
public:
DevelopmentToolDockingWindow(SfxBindings* pBindings, SfxChildWindow* pChildWindow,
vcl::Window* pParent);
diff --git a/include/sfx2/devtools/ObjectInspectorTreeHandler.hxx b/include/sfx2/devtools/ObjectInspectorTreeHandler.hxx
new file mode 100644
index 000000000000..aa6e353e6549
--- /dev/null
+++ b/include/sfx2/devtools/ObjectInspectorTreeHandler.hxx
@@ -0,0 +1,44 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ */
+
+#pragma once
+
+#include <sfx2/dllapi.h>
+#include <vcl/weld.hxx>
+
+#include <com/sun/star/uno/XInterface.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+
+class ObjectInspectorTreeHandler
+{
+private:
+ std::unique_ptr<weld::TreeView>& mpObjectInspectorTree;
+ std::unique_ptr<weld::Label>& mpClassNameLabel;
+
+ void clearObjectInspectorChildren(weld::TreeIter const& rParent);
+
+public:
+ ObjectInspectorTreeHandler(std::unique_ptr<weld::TreeView>& pObjectInspectorTree,
+ std::unique_ptr<weld::Label>& pClassNameLabel)
+ : mpObjectInspectorTree(pObjectInspectorTree)
+ , mpClassNameLabel(pClassNameLabel)
+ {
+ mpObjectInspectorTree->connect_expanding(
+ LINK(this, ObjectInspectorTreeHandler, ExpandingHandler));
+ }
+
+ DECL_LINK(ExpandingHandler, const weld::TreeIter&, bool);
+
+ void introspect(css::uno::Reference<css::uno::XInterface> const& xInterface);
+
+ void dispose();
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sfx2/Library_sfx.mk b/sfx2/Library_sfx.mk
index 52ace3c503fe..b5126ca87893 100644
--- a/sfx2/Library_sfx.mk
+++ b/sfx2/Library_sfx.mk
@@ -165,6 +165,7 @@ $(eval $(call gb_Library_add_exception_objects,sfx,\
sfx2/source/devtools/DevelopmentToolChildWindow \
sfx2/source/devtools/DevelopmentToolDockingWindow \
sfx2/source/devtools/DocumentModelTreeHandler \
+ sfx2/source/devtools/ObjectInspectorTreeHandler \
sfx2/source/dialog/alienwarn \
sfx2/source/dialog/backingcomp \
sfx2/source/dialog/backingwindow \
diff --git a/sfx2/source/devtools/DevelopmentToolDockingWindow.cxx b/sfx2/source/devtools/DevelopmentToolDockingWindow.cxx
index 89f9e878d69b..0d335b5118cc 100644
--- a/sfx2/source/devtools/DevelopmentToolDockingWindow.cxx
+++ b/sfx2/source/devtools/DevelopmentToolDockingWindow.cxx
@@ -12,433 +12,16 @@
#include <sfx2/devtools/DevelopmentToolDockingWindow.hxx>
-#include <com/sun/star/uno/XComponentContext.hpp>
-#include <com/sun/star/lang/XServiceInfo.hpp>
-
-#include <com/sun/star/beans/theIntrospection.hpp>
-#include <com/sun/star/beans/XIntrospection.hpp>
-#include <com/sun/star/beans/XIntrospectionAccess.hpp>
-#include <com/sun/star/beans/Property.hpp>
-#include <com/sun/star/beans/PropertyConcept.hpp>
-#include <com/sun/star/beans/MethodConcept.hpp>
-#include <com/sun/star/beans/XPropertySet.hpp>
-
-#include <com/sun/star/reflection/theCoreReflection.hpp>
-#include <com/sun/star/reflection/XIdlReflection.hpp>
-#include <com/sun/star/reflection/XIdlMethod.hpp>
-
-#include <com/sun/star/script/XInvocation.hpp>
-#include <com/sun/star/script/Invocation.hpp>
-
#include <com/sun/star/view/XSelectionSupplier.hpp>
-#include <comphelper/processfactory.hxx>
-
#include <sfx2/dispatch.hxx>
-#include <sfx2/sfxmodelfactory.hxx>
-
#include <sfx2/objsh.hxx>
-
#include <sfx2/viewfrm.hxx>
-#include <cppuhelper/compbase.hxx>
-#include <cppuhelper/basemutex.hxx>
-
#include "SelectionChangeHandler.hxx"
using namespace css;
-namespace
-{
-uno::Reference<reflection::XIdlClass>
-TypeToIdlClass(const uno::Type& rType, const uno::Reference<uno::XComponentContext>& xContext)
-{
- auto xReflection = reflection::theCoreReflection::get(xContext);
-
- uno::Reference<reflection::XIdlClass> xRetClass;
- typelib_TypeDescription* pTD = nullptr;
- rType.getDescription(&pTD);
- if (pTD)
- {
- OUString sOWName(pTD->pTypeName);
- xRetClass = xReflection->forName(sOWName);
- }
- return xRetClass;
-}
-
-OUString AnyToString(const uno::Any& aValue, const uno::Reference<uno::XComponentContext>& xContext)
-{
- uno::Type aValType = aValue.getValueType();
- uno::TypeClass eType = aValType.getTypeClass();
-
- OUString aRetStr;
- switch (eType)
- {
- case uno::TypeClass_TYPE:
- {
- auto xIdlClass = TypeToIdlClass(aValType, xContext);
- aRetStr = xIdlClass->getName() + " <TYPE>";
- break;
- }
- case uno::TypeClass_INTERFACE:
- {
- auto xIdlClass = TypeToIdlClass(aValType, xContext);
- aRetStr = xIdlClass->getName() + " <INTERFACE>";
- break;
- }
- case uno::TypeClass_SERVICE:
- {
- auto xIdlClass = TypeToIdlClass(aValType, xContext);
- aRetStr = xIdlClass->getName() + " <SERVICE>";
- break;
- }
- case uno::TypeClass_STRUCT:
- {
- auto xIdlClass = TypeToIdlClass(aValType, xContext);
- aRetStr = xIdlClass->getName() + " <STRUCT>";
- break;
- }
- case uno::TypeClass_TYPEDEF:
- {
- auto xIdlClass = TypeToIdlClass(aValType, xContext);
- aRetStr = xIdlClass->getName() + " <TYPEDEF>";
- break;
- }
- case uno::TypeClass_ENUM:
- {
- auto xIdlClass = TypeToIdlClass(aValType, xContext);
- aRetStr = xIdlClass->getName() + " <ENUM>";
- break;
- }
- case uno::TypeClass_EXCEPTION:
- {
- auto xIdlClass = TypeToIdlClass(aValType, xContext);
- aRetStr = xIdlClass->getName() + " <EXCEPTION>";
- break;
- }
- case uno::TypeClass_SEQUENCE:
- {
- auto xIdlClass = TypeToIdlClass(aValType, xContext);
- aRetStr = xIdlClass->getName() + " <SEQUENCE>";
- break;
- }
- case uno::TypeClass_VOID:
- {
- auto xIdlClass = TypeToIdlClass(aValType, xContext);
- aRetStr = xIdlClass->getName() + " <VOID>";
- break;
- }
- case uno::TypeClass_ANY:
- {
- auto xIdlClass = TypeToIdlClass(aValType, xContext);
- aRetStr = xIdlClass->getName() + " <ANY>";
- break;
- }
- case uno::TypeClass_UNKNOWN:
- aRetStr = "<Unknown>";
- break;
- case uno::TypeClass_BOOLEAN:
- {
- bool bBool = aValue.get<bool>();
- aRetStr = bBool ? u"True" : u"False";
- break;
- }
- case uno::TypeClass_CHAR:
- {
- sal_Unicode aChar = aValue.get<sal_Unicode>();
- aRetStr = OUString::number(aChar);
- break;
- }
- case uno::TypeClass_STRING:
- {
- aRetStr = "\"" + aValue.get<OUString>() + "\"";
- break;
- }
- case uno::TypeClass_FLOAT:
- {
- auto aNumber = aValue.get<float>();
- aRetStr = OUString::number(aNumber);
- break;
- }
- case uno::TypeClass_DOUBLE:
- {
- auto aNumber = aValue.get<double>();
- aRetStr = OUString::number(aNumber);
- break;
- }
- case uno::TypeClass_BYTE:
- {
- auto aNumber = aValue.get<sal_Int8>();
- aRetStr = OUString::number(aNumber);
- break;
- }
- case uno::TypeClass_SHORT:
- {
- auto aNumber = aValue.get<sal_Int16>();
- aRetStr = OUString::number(aNumber);
- break;
- }
- case uno::TypeClass_LONG:
- {
- auto aNumber = aValue.get<sal_Int32>();
- aRetStr = OUString::number(aNumber);
- break;
- }
- case uno::TypeClass_HYPER:
- {
- auto aNumber = aValue.get<sal_Int64>();
- aRetStr = OUString::number(aNumber);
- break;
- }
-
- default:
- break;
- }
- return aRetStr;
-}
-
-// Object inspector nodes
-
-class ObjectInspectorNode
-{
-public:
- css::uno::Reference<css::uno::XInterface> mxObject;
-
- ObjectInspectorNode() = default;
-
- ObjectInspectorNode(css::uno::Reference<css::uno::XInterface> const& xObject)
- : mxObject(xObject)
- {
- }
-
- virtual ~ObjectInspectorNode() {}
-
- virtual OUString getObjectName() = 0;
-
- virtual void fillChildren(std::unique_ptr<weld::TreeView>& rTree, weld::TreeIter const& rParent)
- = 0;
-};
-
-OUString lclAppendNode(std::unique_ptr<weld::TreeView>& pTree, ObjectInspectorNode* pEntry,
- bool bChildrenOnDemand = false)
-{
- OUString sName = pEntry->getObjectName();
- OUString sId(OUString::number(reinterpret_cast<sal_Int64>(pEntry)));
- std::unique_ptr<weld::TreeIter> pCurrent = pTree->make_iterator();
- pTree->insert(nullptr, -1, &sName, &sId, nullptr, nullptr, bChildrenOnDemand, pCurrent.get());
- pTree->set_text_emphasis(*pCurrent, true, 0);
- return sId;
-}
-
-OUString lclAppendNodeToParent(std::unique_ptr<weld::TreeView>& pTree,
- weld::TreeIter const& rParent, ObjectInspectorNode* pEntry,
- bool bChildrenOnDemand = false)
-{
- OUString sName = pEntry->getObjectName();
- OUString sId(OUString::number(reinterpret_cast<sal_Int64>(pEntry)));
- std::unique_ptr<weld::TreeIter> pCurrent = pTree->make_iterator();
- pTree->insert(&rParent, -1, &sName, &sId, nullptr, nullptr, bChildrenOnDemand, nullptr);
- pTree->set_text_emphasis(*pCurrent, true, 0);
- return sId;
-}
-
-OUString lclAppendNodeWithIterToParent(std::unique_ptr<weld::TreeView>& pTree,
- weld::TreeIter const& rParent, weld::TreeIter& rCurrent,
- ObjectInspectorNode* pEntry, bool bChildrenOnDemand = false)
-{
- OUString sName = pEntry->getObjectName();
- OUString sId(OUString::number(reinterpret_cast<sal_Int64>(pEntry)));
- pTree->insert(&rParent, -1, &sName, &sId, nullptr, nullptr, bChildrenOnDemand, &rCurrent);
- pTree->set_text_emphasis(rCurrent, true, 0);
- return sId;
-}
-
-class ObjectInspectorNamedNode : public ObjectInspectorNode
-{
-public:
- OUString msName;
-
- ObjectInspectorNamedNode(OUString const& rName,
- css::uno::Reference<css::uno::XInterface> const& xObject)
- : ObjectInspectorNode(xObject)
- , msName(rName)
- {
- }
-
- OUString getObjectName() override { return msName; }
-
- void fillChildren(std::unique_ptr<weld::TreeView>& /*rTree*/,
- weld::TreeIter const& /*rParent*/) override
- {
- }
-};
-
-class ServicesNode : public ObjectInspectorNamedNode
-{
-public:
- ServicesNode(css::uno::Reference<css::uno::XInterface> const& xObject)
- : ObjectInspectorNamedNode("Services", xObject)
- {
- }
-
- void fillChildren(std::unique_ptr<weld::TreeView>& pTree,
- weld::TreeIter const& rParent) override
- {
- auto xServiceInfo = uno::Reference<lang::XServiceInfo>(mxObject, uno::UNO_QUERY);
- const uno::Sequence<OUString> aServiceNames(xServiceInfo->getSupportedServiceNames());
- for (auto const& aServiceName : aServiceNames)
- {
- lclAppendNodeToParent(pTree, rParent,
- new ObjectInspectorNamedNode(aServiceName, mxObject));
- }
- }
-};
-
-class GenericPropertiesNode : public ObjectInspectorNamedNode
-{
-public:
- uno::Reference<uno::XComponentContext> mxContext;
-
- GenericPropertiesNode(OUString const& rName, uno::Reference<uno::XInterface> const& xObject,
- uno::Reference<uno::XComponentContext> const& xContext)
- : ObjectInspectorNamedNode(rName, xObject)
- , mxContext(xContext)
- {
- }
-
- void fillChildren(std::unique_ptr<weld::TreeView>& pTree,
- weld::TreeIter const& rParent) override
- {
- uno::Reference<beans::XIntrospection> xIntrospection
- = beans::theIntrospection::get(mxContext);
- auto xIntrospectionAccess = xIntrospection->inspect(uno::makeAny(mxObject));
- auto xInvocationFactory = css::script::Invocation::create(mxContext);
- uno::Sequence<uno::Any> aParameters = { uno::Any(mxObject) };
- auto xInvocationInterface = xInvocationFactory->createInstanceWithArguments(aParameters);
- uno::Reference<script::XInvocation> xInvocation(xInvocationInterface, uno::UNO_QUERY);
-
- const auto xProperties = xIntrospectionAccess->getProperties(
- beans::PropertyConcept::ALL - beans::PropertyConcept::DANGEROUS);
-
- for (auto const& xProperty : xProperties)
- {
- OUString aValue;
- uno::Any aAny;
- uno::Reference<uno::XInterface> xCurrent = mxObject;
-
- try
- {
- if (xInvocation->hasProperty(xProperty.Name))
- {
- aAny = xInvocation->getValue(xProperty.Name);
- aValue = AnyToString(aAny, mxContext);
- }
- }
- catch (...)
- {
- aValue = "<?>";
- }
-
- bool bComplex = false;
- if (aAny.hasValue())
- {
- auto xInterface = uno::Reference<uno::XInterface>(aAny, uno::UNO_QUERY);
- if (xInterface.is())
- {
- xCurrent = xInterface;
- bComplex = true;
- }
- }
-
- std::unique_ptr<weld::TreeIter> pCurrent = pTree->make_iterator();
- if (bComplex)
- {
- lclAppendNodeWithIterToParent(
- pTree, rParent, *pCurrent,
- new GenericPropertiesNode(xProperty.Name, xCurrent, mxContext), true);
- }
- else
- {
- lclAppendNodeWithIterToParent(
- pTree, rParent, *pCurrent,
- new ObjectInspectorNamedNode(xProperty.Name, xCurrent), false);
- }
-
- if (!aValue.isEmpty())
- {
- pTree->set_text(*pCurrent, aValue, 1);
- }
- }
- }
-};
-
-class PropertiesNode : public GenericPropertiesNode
-{
-public:
- PropertiesNode(uno::Reference<uno::XInterface> const& xObject,
- uno::Reference<uno::XComponentContext> const& xContext)
- : GenericPropertiesNode("Properties", xObject, xContext)
- {
- }
-};
-
-class InterfacesNode : public ObjectInspectorNamedNode
-{
-public:
- InterfacesNode(css::uno::Reference<css::uno::XInterface> const& xObject)
- : ObjectInspectorNamedNode("Interfaces", xObject)
- {
- }
-
- void fillChildren(std::unique_ptr<weld::TreeView>& pTree,
- weld::TreeIter const& rParent) override
- {
- uno::Reference<lang::XTypeProvider> xTypeProvider(mxObject, uno::UNO_QUERY);
- if (xTypeProvider.is())
- {
- const auto xSequenceTypes = xTypeProvider->getTypes();
- for (auto const& xType : xSequenceTypes)
- {
- OUString aName = xType.getTypeName();
- lclAppendNodeToParent(pTree, rParent,
- new ObjectInspectorNamedNode(aName, mxObject));
- }
- }
- }
-};
-
-class MethodsNode : public ObjectInspectorNamedNode
-{
-public:
- uno::Reference<uno::XComponentContext> mxContext;
-
- MethodsNode(css::uno::Reference<css::uno::XInterface> const& xObject,
- uno::Reference<uno::XComponentContext> const& xContext)
- : ObjectInspectorNamedNode("Methods", xObject)
- , mxContext(xContext)
- {
- }
-
- void fillChildren(std::unique_ptr<weld::TreeView>& pTree,
- weld::TreeIter const& rParent) override
- {
- uno::Reference<beans::XIntrospection> xIntrospection
- = beans::theIntrospection::get(mxContext);
- auto xIntrospectionAccess = xIntrospection->inspect(uno::makeAny(mxObject));
-
- const auto xMethods = xIntrospectionAccess->getMethods(beans::MethodConcept::ALL);
- for (auto const& xMethod : xMethods)
- {
- OUString aMethodName = xMethod->getName();
-
- lclAppendNodeToParent(pTree, rParent,
- new ObjectInspectorNamedNode(aMethodName, mxObject));
- }
- }
-};
-
-} // end anonymous namespace
-
DevelopmentToolDockingWindow::DevelopmentToolDockingWindow(SfxBindings* pInputBindings,
SfxChildWindow* pChildWindow,
vcl::Window* pParent)
@@ -451,12 +34,11 @@ DevelopmentToolDockingWindow::DevelopmentToolDockingWindow(SfxBindings* pInputBi
, maDocumentModelTreeHandler(
mpDocumentModelTreeView,
pInputBindings->GetDispatcher()->GetFrame()->GetObjectShell()->GetBaseModel())
+ , maObjectInspectorTreeHandler(mpClassListBox, mpClassNameLabel)
{
mpDocumentModelTreeView->connect_changed(
LINK(this, DevelopmentToolDockingWindow, DocumentModelTreeViewSelectionHandler));
mpSelectionToggle->connect_toggled(LINK(this, DevelopmentToolDockingWindow, SelectionToggled));
- mpClassListBox->connect_expanding(
- LINK(this, DevelopmentToolDockingWindow, ObjectInspectorExpandingHandler));
auto* pViewFrame = pInputBindings->GetDispatcher()->GetFrame();
@@ -482,14 +64,14 @@ void DevelopmentToolDockingWindow::inspectSelectionOrRoot(
auto xInterface = aAny.get<css::uno::Reference<css::uno::XInterface>>();
if (xInterface.is())
{
- introspect(xInterface);
+ maObjectInspectorTreeHandler.introspect(xInterface);
mpSelectionToggle->set_state(TRISTATE_TRUE);
return;
}
}
}
mpSelectionToggle->set_state(TRISTATE_FALSE);
- introspect(mxRoot);
+ maObjectInspectorTreeHandler.introspect(mxRoot);
}
IMPL_LINK(DevelopmentToolDockingWindow, DocumentModelTreeViewSelectionHandler, weld::TreeView&,
@@ -501,7 +83,7 @@ IMPL_LINK(DevelopmentToolDockingWindow, DocumentModelTreeViewSelectionHandler, w
OUString sID = rView.get_selected_id();
auto xObject = DocumentModelTreeHandler::getObjectByID(sID);
if (xObject.is())
- introspect(xObject);
+ maObjectInspectorTreeHandler.introspect(xObject);
}
IMPL_LINK_NOARG(DevelopmentToolDockingWindow, SelectionToggled, weld::ToggleButton&, void)
@@ -509,28 +91,6 @@ IMPL_LINK_NOARG(DevelopmentToolDockingWindow, SelectionToggled, weld::ToggleButt
updateSelection();
}
-void DevelopmentToolDockingWindow::clearObjectInspectorChildren(weld::TreeIter const& rParent)
-{
- bool bChild = false;
- do
- {
- bChild = mpClassListBox->iter_has_child(rParent);
- if (bChild)
- {
- std::unique_ptr<weld::TreeIter> pChild = mpClassListBox->make_iterator(&rParent);
- bChild = mpClassListBox->iter_children(*pChild);
- if (bChild)
- {
- clearObjectInspectorChildren(*pChild);
- OUString sID = mpClassListBox->get_id(*pChild);
- auto* pEntry = reinterpret_cast<ObjectInspectorNode*>(sID.toInt64());
- delete pEntry;
- mpClassListBox->remove(*pChild);
- }
- }
- } while (bChild);
-}
-
DevelopmentToolDockingWindow::~DevelopmentToolDockingWindow() { disposeOnce(); }
void DevelopmentToolDockingWindow::dispose()
@@ -541,15 +101,9 @@ void DevelopmentToolDockingWindow::dispose()
pSelectionChangeHandler->stopListening();
mxSelectionListener = uno::Reference<view::XSelectionChangeListener>();
- maDocumentModelTreeHandler.dispose();
- // destroy all ObjectInspectorNodes from the tree
- mpClassListBox->all_foreach([this](weld::TreeIter& rEntry) {
- OUString sID = mpClassListBox->get_id(rEntry);
- auto* pEntry = reinterpret_cast<ObjectInspectorNode*>(sID.toInt64());
- delete pEntry;
- return false;
- });
+ maDocumentModelTreeHandler.dispose();
+ maObjectInspectorTreeHandler.dispose();
// dispose welded objects
mpClassNameLabel.reset();
@@ -565,7 +119,7 @@ void DevelopmentToolDockingWindow::updateSelection()
TriState eTriState = mpSelectionToggle->get_state();
if (eTriState == TRISTATE_TRUE)
{
- introspect(mxCurrentSelection);
+ maObjectInspectorTreeHandler.introspect(mxCurrentSelection);
maDocumentModelTreeHandler.selectObject(mxCurrentSelection);
}
else
@@ -584,20 +138,6 @@ void DevelopmentToolDockingWindow::ToggleFloatingMode()
Invalidate();
}
-IMPL_LINK(DevelopmentToolDockingWindow, ObjectInspectorExpandingHandler, weld::TreeIter const&,
- rParent, bool)
-{
- OUString sID = mpClassListBox->get_id(rParent);
- if (sID.isEmpty())
- return true;
-
- clearObjectInspectorChildren(rParent);
- auto* pNode = reinterpret_cast<ObjectInspectorNode*>(sID.toInt64());
- pNode->fillChildren(mpClassListBox, rParent);
-
- return true;
-}
-
void DevelopmentToolDockingWindow::selectionChanged(
uno::Reference<uno::XInterface> const& xInterface)
{
@@ -605,31 +145,4 @@ void DevelopmentToolDockingWindow::selectionChanged(
updateSelection();
}
-void DevelopmentToolDockingWindow::introspect(uno::Reference<uno::XInterface> const& xInterface)
-{
- if (!xInterface.is())
- return;
-
- uno::Reference<uno::XComponentContext> xContext = comphelper::getProcessComponentContext();
- if (!xContext.is())
- return;
-
- // Set implementation name
- auto xServiceInfo = uno::Reference<lang::XServiceInfo>(xInterface, uno::UNO_QUERY);
- OUString aImplementationName = xServiceInfo->getImplementationName();
- mpClassNameLabel->set_label(aImplementationName);
-
- // fill object inspector
-
- mpClassListBox->freeze();
- mpClassListBox->clear();
-
- lclAppendNode(mpClassListBox, new ServicesNode(xInterface), true);
- lclAppendNode(mpClassListBox, new InterfacesNode(xInterface), true);
- lclAppendNode(mpClassListBox, new PropertiesNode(xInterface, xContext), true);
- lclAppendNode(mpClassListBox, new MethodsNode(xInterface, xContext), true);
-
- mpClassListBox->thaw();
-}
-
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sfx2/source/devtools/ObjectInspectorTreeHandler.cxx b/sfx2/source/devtools/ObjectInspectorTreeHandler.cxx
new file mode 100644
index 000000000000..d69f8130f82b
--- /dev/null
+++ b/sfx2/source/devtools/ObjectInspectorTreeHandler.cxx
@@ -0,0 +1,503 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ */
+
+#include <memory>
+
+#include <sfx2/devtools/ObjectInspectorTreeHandler.hxx>
+
+#include <com/sun/star/uno/XInterface.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <com/sun/star/beans/theIntrospection.hpp>
+#include <com/sun/star/beans/XIntrospection.hpp>
+#include <com/sun/star/beans/XIntrospectionAccess.hpp>
+#include <com/sun/star/beans/Property.hpp>
+#include <com/sun/star/beans/PropertyConcept.hpp>
+#include <com/sun/star/beans/MethodConcept.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+
+#include <com/sun/star/reflection/theCoreReflection.hpp>
+#include <com/sun/star/reflection/XIdlReflection.hpp>
+#include <com/sun/star/reflection/XIdlMethod.hpp>
+
+#include <com/sun/star/script/XInvocation.hpp>
+#include <com/sun/star/script/Invocation.hpp>
+
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/XTypeProvider.hpp>
+
+#include <comphelper/processfactory.hxx>
+
+using namespace css;
+
+namespace
+{
+uno::Reference<reflection::XIdlClass>
+TypeToIdlClass(const uno::Type& rType, const uno::Reference<uno::XComponentContext>& xContext)
+{
+ auto xReflection = reflection::theCoreReflection::get(xContext);
+
+ uno::Reference<reflection::XIdlClass> xRetClass;
+ typelib_TypeDescription* pTD = nullptr;
+ rType.getDescription(&pTD);
+ if (pTD)
+ {
+ OUString sOWName(pTD->pTypeName);
+ xRetClass = xReflection->forName(sOWName);
+ }
+ return xRetClass;
+}
+
+OUString AnyToString(const uno::Any& aValue, const uno::Reference<uno::XComponentContext>& xContext)
+{
+ uno::Type aValType = aValue.getValueType();
+ uno::TypeClass eType = aValType.getTypeClass();
+
+ OUString aRetStr;
+ switch (eType)
+ {
+ case uno::TypeClass_TYPE:
+ {
+ auto xIdlClass = TypeToIdlClass(aValType, xContext);
+ aRetStr = xIdlClass->getName() + " <TYPE>";
+ break;
+ }
+ case uno::TypeClass_INTERFACE:
+ {
+ auto xIdlClass = TypeToIdlClass(aValType, xContext);
+ aRetStr = xIdlClass->getName() + " <INTERFACE>";
+ break;
+ }
+ case uno::TypeClass_SERVICE:
+ {
+ auto xIdlClass = TypeToIdlClass(aValType, xContext);
+ aRetStr = xIdlClass->getName() + " <SERVICE>";
+ break;
+ }
+ case uno::TypeClass_STRUCT:
+ {
+ auto xIdlClass = TypeToIdlClass(aValType, xContext);
+ aRetStr = xIdlClass->getName() + " <STRUCT>";
+ break;
+ }
+ case uno::TypeClass_TYPEDEF:
+ {
+ auto xIdlClass = TypeToIdlClass(aValType, xContext);
+ aRetStr = xIdlClass->getName() + " <TYPEDEF>";
+ break;
+ }
+ case uno::TypeClass_ENUM:
+ {
+ auto xIdlClass = TypeToIdlClass(aValType, xContext);
+ aRetStr = xIdlClass->getName() + " <ENUM>";
+ break;
+ }
+ case uno::TypeClass_EXCEPTION:
+ {
+ auto xIdlClass = TypeToIdlClass(aValType, xContext);
+ aRetStr = xIdlClass->getName() + " <EXCEPTION>";
+ break;
+ }
+ case uno::TypeClass_SEQUENCE:
+ {
+ auto xIdlClass = TypeToIdlClass(aValType, xContext);
+ aRetStr = xIdlClass->getName() + " <SEQUENCE>";
+ break;
+ }
+ case uno::TypeClass_VOID:
+ {
+ auto xIdlClass = TypeToIdlClass(aValType, xContext);
+ aRetStr = xIdlClass->getName() + " <VOID>";
+ break;
+ }
+ case uno::TypeClass_ANY:
+ {
+ auto xIdlClass = TypeToIdlClass(aValType, xContext);
+ aRetStr = xIdlClass->getName() + " <ANY>";
+ break;
+ }
+ case uno::TypeClass_UNKNOWN:
+ aRetStr = "<Unknown>";
+ break;
+ case uno::TypeClass_BOOLEAN:
+ {
+ bool bBool = aValue.get<bool>();
+ aRetStr = bBool ? u"True" : u"False";
+ break;
+ }
+ case uno::TypeClass_CHAR:
+ {
+ sal_Unicode aChar = aValue.get<sal_Unicode>();
+ aRetStr = OUString::number(aChar);
+ break;
+ }
+ case uno::TypeClass_STRING:
+ {
+ aRetStr = "\"" + aValue.get<OUString>() + "\"";
+ break;
+ }
+ case uno::TypeClass_FLOAT:
+ {
+ auto aNumber = aValue.get<float>();
+ aRetStr = OUString::number(aNumber);
+ break;
+ }
+ case uno::TypeClass_DOUBLE:
+ {
+ auto aNumber = aValue.get<double>();
+ aRetStr = OUString::number(aNumber);
+ break;
+ }
+ case uno::TypeClass_BYTE:
+ {
+ auto aNumber = aValue.get<sal_Int8>();
+ aRetStr = OUString::number(aNumber);
+ break;
+ }
+ case uno::TypeClass_SHORT:
+ {
+ auto aNumber = aValue.get<sal_Int16>();
+ aRetStr = OUString::number(aNumber);
+ break;
+ }
+ case uno::TypeClass_LONG:
+ {
+ auto aNumber = aValue.get<sal_Int32>();
+ aRetStr = OUString::number(aNumber);
+ break;
+ }
+ case uno::TypeClass_HYPER:
+ {
+ auto aNumber = aValue.get<sal_Int64>();
+ aRetStr = OUString::number(aNumber);
+ break;
+ }
+
+ default:
+ break;
+ }
+ return aRetStr;
+}
+
+// Object inspector nodes
+
+class ObjectInspectorNode
+{
+public:
+ css::uno::Reference<css::uno::XInterface> mxObject;
+
+ ObjectInspectorNode() = default;
+
+ ObjectInspectorNode(css::uno::Reference<css::uno::XInterface> const& xObject)
+ : mxObject(xObject)
+ {
+ }
+
+ virtual ~ObjectInspectorNode() {}
+
+ virtual OUString getObjectName() = 0;
+
+ virtual void fillChildren(std::unique_ptr<weld::TreeView>& rTree, weld::TreeIter const& rParent)
+ = 0;
+};
+
+OUString lclAppendNode(std::unique_ptr<weld::TreeView>& pTree, ObjectInspectorNode* pEntry,
+ bool bChildrenOnDemand = false)
+{
+ OUString sName = pEntry->getObjectName();
+ OUString sId(OUString::number(reinterpret_cast<sal_Int64>(pEntry)));
+ std::unique_ptr<weld::TreeIter> pCurrent = pTree->make_iterator();
+ pTree->insert(nullptr, -1, &sName, &sId, nullptr, nullptr, bChildrenOnDemand, pCurrent.get());
+ pTree->set_text_emphasis(*pCurrent, true, 0);
+ return sId;
+}
+
+OUString lclAppendNodeToParent(std::unique_ptr<weld::TreeView>& pTree,
+ weld::TreeIter const& rParent, ObjectInspectorNode* pEntry,
+ bool bChildrenOnDemand = false)
+{
+ OUString sName = pEntry->getObjectName();
+ OUString sId(OUString::number(reinterpret_cast<sal_Int64>(pEntry)));
+ std::unique_ptr<weld::TreeIter> pCurrent = pTree->make_iterator();
+ pTree->insert(&rParent, -1, &sName, &sId, nullptr, nullptr, bChildrenOnDemand, nullptr);
+ pTree->set_text_emphasis(*pCurrent, true, 0);
+ return sId;
+}
+
+OUString lclAppendNodeWithIterToParent(std::unique_ptr<weld::TreeView>& pTree,
+ weld::TreeIter const& rParent, weld::TreeIter& rCurrent,
+ ObjectInspectorNode* pEntry, bool bChildrenOnDemand = false)
+{
+ OUString sName = pEntry->getObjectName();
+ OUString sId(OUString::number(reinterpret_cast<sal_Int64>(pEntry)));
+ pTree->insert(&rParent, -1, &sName, &sId, nullptr, nullptr, bChildrenOnDemand, &rCurrent);
+ pTree->set_text_emphasis(rCurrent, true, 0);
+ return sId;
+}
+
+class ObjectInspectorNamedNode : public ObjectInspectorNode
+{
+public:
+ OUString msName;
+
+ ObjectInspectorNamedNode(OUString const& rName,
+ css::uno::Reference<css::uno::XInterface> const& xObject)
+ : ObjectInspectorNode(xObject)
+ , msName(rName)
+ {
+ }
+
+ OUString getObjectName() override { return msName; }
+
+ void fillChildren(std::unique_ptr<weld::TreeView>& /*rTree*/,
+ weld::TreeIter const& /*rParent*/) override
+ {
+ }
+};
+
+class ServicesNode : public ObjectInspectorNamedNode
+{
+public:
+ ServicesNode(css::uno::Reference<css::uno::XInterface> const& xObject)
+ : ObjectInspectorNamedNode("Services", xObject)
+ {
+ }
+
+ void fillChildren(std::unique_ptr<weld::TreeView>& pTree,
+ weld::TreeIter const& rParent) override
+ {
+ auto xServiceInfo = uno::Reference<lang::XServiceInfo>(mxObject, uno::UNO_QUERY);
+ const uno::Sequence<OUString> aServiceNames(xServiceInfo->getSupportedServiceNames());
+ for (auto const& aServiceName : aServiceNames)
+ {
+ lclAppendNodeToParent(pTree, rParent,
+ new ObjectInspectorNamedNode(aServiceName, mxObject));
+ }
+ }
+};
+
+class GenericPropertiesNode : public ObjectInspectorNamedNode
+{
+public:
+ uno::Reference<uno::XComponentContext> mxContext;
+
+ GenericPropertiesNode(OUString const& rName, uno::Reference<uno::XInterface> const& xObject,
+ uno::Reference<uno::XComponentContext> const& xContext)
+ : ObjectInspectorNamedNode(rName, xObject)
+ , mxContext(xContext)
+ {
+ }
+
+ void fillChildren(std::unique_ptr<weld::TreeView>& pTree,
+ weld::TreeIter const& rParent) override
+ {
+ uno::Reference<beans::XIntrospection> xIntrospection
+ = beans::theIntrospection::get(mxContext);
+ auto xIntrospectionAccess = xIntrospection->inspect(uno::makeAny(mxObject));
+ auto xInvocationFactory = css::script::Invocation::create(mxContext);
+ uno::Sequence<uno::Any> aParameters = { uno::Any(mxObject) };
+ auto xInvocationInterface = xInvocationFactory->createInstanceWithArguments(aParameters);
+ uno::Reference<script::XInvocation> xInvocation(xInvocationInterface, uno::UNO_QUERY);
+
+ const auto xProperties = xIntrospectionAccess->getProperties(
+ beans::PropertyConcept::ALL - beans::PropertyConcept::DANGEROUS);
+
+ for (auto const& xProperty : xProperties)
+ {
+ OUString aValue;
+ uno::Any aAny;
+ uno::Reference<uno::XInterface> xCurrent = mxObject;
+
+ try
+ {
+ if (xInvocation->hasProperty(xProperty.Name))
+ {
+ aAny = xInvocation->getValue(xProperty.Name);
+ aValue = AnyToString(aAny, mxContext);
+ }
+ }
+ catch (...)
+ {
+ aValue = "<?>";
+ }
+
+ bool bComplex = false;
+ if (aAny.hasValue())
+ {
+ auto xInterface = uno::Reference<uno::XInterface>(aAny, uno::UNO_QUERY);
+ if (xInterface.is())
+ {
+ xCurrent = xInterface;
+ bComplex = true;
+ }
+ }
+
+ std::unique_ptr<weld::TreeIter> pCurrent = pTree->make_iterator();
+ if (bComplex)
+ {
+ lclAppendNodeWithIterToParent(
+ pTree, rParent, *pCurrent,
+ new GenericPropertiesNode(xProperty.Name, xCurrent, mxContext), true);
+ }
+ else
+ {
+ lclAppendNodeWithIterToParent(
+ pTree, rParent, *pCurrent,
+ new ObjectInspectorNamedNode(xProperty.Name, xCurrent), false);
+ }
+
+ if (!aValue.isEmpty())
+ {
+ pTree->set_text(*pCurrent, aValue, 1);
+ }
+ }
+ }
+};
+
+class PropertiesNode : public GenericPropertiesNode
+{
+public:
+ PropertiesNode(uno::Reference<uno::XInterface> const& xObject,
+ uno::Reference<uno::XComponentContext> const& xContext)
+ : GenericPropertiesNode("Properties", xObject, xContext)
+ {
+ }
+};
+
+class InterfacesNode : public ObjectInspectorNamedNode
+{
+public:
+ InterfacesNode(css::uno::Reference<css::uno::XInterface> const& xObject)
+ : ObjectInspectorNamedNode("Interfaces", xObject)
+ {
+ }
+
+ void fillChildren(std::unique_ptr<weld::TreeView>& pTree,
+ weld::TreeIter const& rParent) override
+ {
+ uno::Reference<lang::XTypeProvider> xTypeProvider(mxObject, uno::UNO_QUERY);
+ if (xTypeProvider.is())
+ {
+ const auto xSequenceTypes = xTypeProvider->getTypes();
+ for (auto const& xType : xSequenceTypes)
+ {
+ OUString aName = xType.getTypeName();
+ lclAppendNodeToParent(pTree, rParent,
+ new ObjectInspectorNamedNode(aName, mxObject));
+ }
+ }
+ }
+};
+
+class MethodsNode : public ObjectInspectorNamedNode
+{
+public:
+ uno::Reference<uno::XComponentContext> mxContext;
+
+ MethodsNode(css::uno::Reference<css::uno::XInterface> const& xObject,
+ uno::Reference<uno::XComponentContext> const& xContext)
+ : ObjectInspectorNamedNode("Methods", xObject)
+ , mxContext(xContext)
+ {
+ }
+
+ void fillChildren(std::unique_ptr<weld::TreeView>& pTree,
+ weld::TreeIter const& rParent) override
+ {
+ uno::Reference<beans::XIntrospection> xIntrospection
+ = beans::theIntrospection::get(mxContext);
+ auto xIntrospectionAccess = xIntrospection->inspect(uno::makeAny(mxObject));
+
+ const auto xMethods = xIntrospectionAccess->getMethods(beans::MethodConcept::ALL);
+ for (auto const& xMethod : xMethods)
+ {
+ OUString aMethodName = xMethod->getName();
+
+ lclAppendNodeToParent(pTree, rParent,
+ new ObjectInspectorNamedNode(aMethodName, mxObject));
+ }
+ }
+};
+
+} // end anonymous namespace
+
+IMPL_LINK(ObjectInspectorTreeHandler, ExpandingHandler, weld::TreeIter const&, rParent, bool)
+{
+ OUString sID = mpObjectInspectorTree->get_id(rParent);
+ if (sID.isEmpty())
+ return true;
+
+ clearObjectInspectorChildren(rParent);
+ auto* pNode = reinterpret_cast<ObjectInspectorNode*>(sID.toInt64());
+ pNode->fillChildren(mpObjectInspectorTree, rParent);
+
+ return true;
+}
+
+void ObjectInspectorTreeHandler::clearObjectInspectorChildren(weld::TreeIter const& rParent)
+{
+ bool bChild = false;
+ do
+ {
+ bChild = mpObjectInspectorTree->iter_has_child(rParent);
+ if (bChild)
+ {
+ std::unique_ptr<weld::TreeIter> pChild = mpObjectInspectorTree->make_iterator(&rParent);
+ bChild = mpObjectInspectorTree->iter_children(*pChild);
+ if (bChild)
+ {
+ clearObjectInspectorChildren(*pChild);
+ OUString sID = mpObjectInspectorTree->get_id(*pChild);
+ auto* pEntry = reinterpret_cast<ObjectInspectorNode*>(sID.toInt64());
+ delete pEntry;
+ mpObjectInspectorTree->remove(*pChild);
+ }
+ }
+ } while (bChild);
+}
+
+void ObjectInspectorTreeHandler::introspect(uno::Reference<uno::XInterface> const& xInterface)
+{
+ if (!xInterface.is())
+ return;
+
+ uno::Reference<uno::XComponentContext> xContext = comphelper::getProcessComponentContext();
+ if (!xContext.is())
+ return;
+
+ // Set implementation name
+ auto xServiceInfo = uno::Reference<lang::XServiceInfo>(xInterface, uno::UNO_QUERY);
+ OUString aImplementationName = xServiceInfo->getImplementationName();
+ mpClassNameLabel->set_label(aImplementationName);
+
+ // fill object inspector
+ mpObjectInspectorTree->freeze();
+ mpObjectInspectorTree->clear();
+
+ lclAppendNode(mpObjectInspectorTree, new ServicesNode(xInterface), true);
+ lclAppendNode(mpObjectInspectorTree, new InterfacesNode(xInterface), true);
+ lclAppendNode(mpObjectInspectorTree, new PropertiesNode(xInterface, xContext), true);
+ lclAppendNode(mpObjectInspectorTree, new MethodsNode(xInterface, xContext), true);
+
+ mpObjectInspectorTree->thaw();
+}
+
+void ObjectInspectorTreeHandler::dispose()
+{
+ // destroy all ObjectInspectorNodes from the tree
+ mpObjectInspectorTree->all_foreach([this](weld::TreeIter& rEntry) {
+ OUString sID = mpObjectInspectorTree->get_id(rEntry);
+ auto* pEntry = reinterpret_cast<ObjectInspectorNode*>(sID.toInt64());
+ delete pEntry;
+ return false;
+ });
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
More information about the Libreoffice-commits
mailing list