summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/svx/devtools/DevelopmentToolDockingWindow.hxx4
-rw-r--r--svx/source/devtools/DevelopmentToolDockingWindow.cxx471
2 files changed, 322 insertions, 153 deletions
diff --git a/include/svx/devtools/DevelopmentToolDockingWindow.hxx b/include/svx/devtools/DevelopmentToolDockingWindow.hxx
index 8e24c2d0cd8d..1f10c0c2a672 100644
--- a/include/svx/devtools/DevelopmentToolDockingWindow.hxx
+++ b/include/svx/devtools/DevelopmentToolDockingWindow.hxx
@@ -40,9 +40,13 @@ private:
DECL_LINK(LeftSideSelected, weld::TreeView&, void);
DECL_LINK(SelectionToggled, weld::ToggleButton&, void);
+ DECL_LINK(ObjectInspectorExpandingHandler, const weld::TreeIter&, bool);
+
void inspectDocument();
void updateSelection();
+ void clearObjectInspectorChildren(weld::TreeIter const& rParent);
+
public:
DevelopmentToolDockingWindow(SfxBindings* pBindings, SfxChildWindow* pChildWindow,
vcl::Window* pParent);
diff --git a/svx/source/devtools/DevelopmentToolDockingWindow.cxx b/svx/source/devtools/DevelopmentToolDockingWindow.cxx
index da3b8d5896b5..8c519e807125 100644
--- a/svx/source/devtools/DevelopmentToolDockingWindow.cxx
+++ b/svx/source/devtools/DevelopmentToolDockingWindow.cxx
@@ -100,105 +100,6 @@ private:
SelectionChangeHandler& operator=(const SelectionChangeHandler&) = delete;
};
-} // end anonymous namespace
-
-DevelopmentToolDockingWindow::DevelopmentToolDockingWindow(SfxBindings* pInputBindings,
- SfxChildWindow* pChildWindow,
- vcl::Window* pParent)
- : SfxDockingWindow(pInputBindings, pChildWindow, pParent, "DevelopmentTool",
- "svx/ui/developmenttool.ui")
- , mpClassNameLabel(m_xBuilder->weld_label("class_name_value_id"))
- , mpClassListBox(m_xBuilder->weld_tree_view("class_listbox_id"))
- , mpLeftSideTreeView(m_xBuilder->weld_tree_view("leftside_treeview_id"))
- , mpSelectionToggle(m_xBuilder->weld_toggle_button("selection_toggle"))
- , maDocumentModelTreeHandler(
- mpLeftSideTreeView,
- pInputBindings->GetDispatcher()->GetFrame()->GetObjectShell()->GetBaseModel())
-{
- mpLeftSideTreeView->connect_changed(LINK(this, DevelopmentToolDockingWindow, LeftSideSelected));
- mpSelectionToggle->connect_toggled(LINK(this, DevelopmentToolDockingWindow, SelectionToggled));
-
- auto* pViewFrame = pInputBindings->GetDispatcher()->GetFrame();
-
- uno::Reference<frame::XController> xController = pViewFrame->GetFrame().GetController();
-
- mxRoot = pInputBindings->GetDispatcher()->GetFrame()->GetObjectShell()->GetBaseModel();
-
- introspect(mxRoot);
- maDocumentModelTreeHandler.inspectDocument();
- mxSelectionListener.set(new SelectionChangeHandler(xController, this));
-}
-
-IMPL_LINK(DevelopmentToolDockingWindow, LeftSideSelected, weld::TreeView&, rView, void)
-{
- if (mpSelectionToggle->get_state() == TRISTATE_TRUE)
- return;
-
- OUString sID = rView.get_selected_id();
- auto xObject = DocumentModelTreeHandler::getObjectByID(sID);
- if (xObject.is())
- introspect(xObject);
-}
-
-IMPL_LINK_NOARG(DevelopmentToolDockingWindow, SelectionToggled, weld::ToggleButton&, void)
-{
- updateSelection();
-}
-
-DevelopmentToolDockingWindow::~DevelopmentToolDockingWindow() { disposeOnce(); }
-
-void DevelopmentToolDockingWindow::dispose()
-{
- auto* pSelectionChangeHandler
- = dynamic_cast<SelectionChangeHandler*>(mxSelectionListener.get());
- if (pSelectionChangeHandler)
- pSelectionChangeHandler->disconnect();
-
- mxSelectionListener = uno::Reference<view::XSelectionChangeListener>();
- maDocumentModelTreeHandler.dispose();
-
- mpClassNameLabel.reset();
- mpClassListBox.reset();
- mpSelectionToggle.reset();
- mpLeftSideTreeView.reset();
-
- SfxDockingWindow::dispose();
-}
-
-void DevelopmentToolDockingWindow::updateSelection()
-{
- TriState eTriState = mpSelectionToggle->get_state();
- if (eTriState == TRISTATE_TRUE)
- {
- introspect(mxCurrentSelection);
- mpLeftSideTreeView->set_sensitive(false);
- }
- else
- {
- mpLeftSideTreeView->set_sensitive(true);
- LeftSideSelected(*mpLeftSideTreeView);
- }
-}
-
-void DevelopmentToolDockingWindow::ToggleFloatingMode()
-{
- SfxDockingWindow::ToggleFloatingMode();
-
- if (GetFloatingWindow())
- GetFloatingWindow()->SetMinOutputSizePixel(Size(300, 300));
-
- Invalidate();
-}
-
-void DevelopmentToolDockingWindow::selectionChanged(
- uno::Reference<uno::XInterface> const& xInterface)
-{
- mxCurrentSelection = xInterface;
- updateSelection();
-}
-
-namespace
-{
uno::Reference<reflection::XIdlClass>
TypeToIdlClass(const uno::Type& rType, const uno::Reference<uno::XComponentContext>& xContext)
{
@@ -345,60 +246,133 @@ OUString AnyToString(const uno::Any& aValue, const uno::Reference<uno::XComponen
}
return aRetStr;
}
-}
-void DevelopmentToolDockingWindow::introspect(uno::Reference<uno::XInterface> const& xInterface)
+// Object inspector nodes
+
+class ObjectInspectorNode
{
- if (!xInterface.is())
- return;
+public:
+ css::uno::Reference<css::uno::XInterface> mxObject;
- uno::Reference<uno::XComponentContext> xContext = comphelper::getProcessComponentContext();
- if (!xContext.is())
- return;
+ ObjectInspectorNode() = default;
- auto xServiceInfo = uno::Reference<lang::XServiceInfo>(xInterface, uno::UNO_QUERY);
- OUString aImplementationName = xServiceInfo->getImplementationName();
+ ObjectInspectorNode(css::uno::Reference<css::uno::XInterface> const& xObject)
+ : mxObject(xObject)
+ {
+ }
- mpClassNameLabel->set_label(aImplementationName);
+ virtual ~ObjectInspectorNode() {}
- mpClassListBox->freeze();
- mpClassListBox->clear();
+ virtual OUString getObjectName() = 0;
+
+ virtual void fillChildren(std::unique_ptr<weld::TreeView>& rTree, weld::TreeIter const& rParent)
+ = 0;
+};
- std::unique_ptr<weld::TreeIter> pParent = mpClassListBox->make_iterator();
- OUString aServicesString("Services");
- mpClassListBox->insert(nullptr, -1, &aServicesString, nullptr, nullptr, nullptr, false,
- pParent.get());
- mpClassListBox->set_text_emphasis(*pParent, true, 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;
+}
- std::unique_ptr<weld::TreeIter> pResult = mpClassListBox->make_iterator();
- const uno::Sequence<OUString> aServiceNames(xServiceInfo->getSupportedServiceNames());
- for (auto const& aServiceName : aServiceNames)
+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)
{
- mpClassListBox->insert(pParent.get(), -1, &aServiceName, nullptr, nullptr, nullptr, false,
- pResult.get());
- mpClassListBox->set_text_emphasis(*pResult, false, 0);
}
- uno::Reference<beans::XIntrospection> xIntrospection;
- xIntrospection = beans::theIntrospection::get(xContext);
+ OUString getObjectName() override { return msName; }
- uno::Reference<beans::XIntrospectionAccess> xIntrospectionAccess;
- xIntrospectionAccess = xIntrospection->inspect(uno::makeAny(xInterface));
+ void fillChildren(std::unique_ptr<weld::TreeView>& /*rTree*/,
+ weld::TreeIter const& /*rParent*/) override
{
- OUString aPropertiesString("Properties");
+ }
+};
- mpClassListBox->insert(nullptr, -1, &aPropertiesString, nullptr, nullptr, nullptr, false,
- pParent.get());
- mpClassListBox->set_text_emphasis(*pParent, true, 0);
+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));
+ }
+ }
+};
- uno::Reference<beans::XPropertySet> xPropertySet(xInterface, uno::UNO_QUERY);
+class PropertiesNode : public ObjectInspectorNamedNode
+{
+public:
+ uno::Reference<uno::XComponentContext> mxContext;
+
+ PropertiesNode(css::uno::Reference<css::uno::XInterface> const& xObject,
+ uno::Reference<uno::XComponentContext> const& xContext)
+ : ObjectInspectorNamedNode("Properties", 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 xProperties = xIntrospectionAccess->getProperties(
beans::PropertyConcept::ALL - beans::PropertyConcept::DANGEROUS);
+
+ uno::Reference<beans::XPropertySet> xPropertySet(mxObject, uno::UNO_QUERY);
+
for (auto const& xProperty : xProperties)
{
- mpClassListBox->insert(pParent.get(), -1, &xProperty.Name, nullptr, nullptr, nullptr,
- false, pResult.get());
+ std::unique_ptr<weld::TreeIter> pCurrent = pTree->make_iterator();
+ lclAppendNodeWithIterToParent(pTree, rParent, *pCurrent,
+ new ObjectInspectorNamedNode(xProperty.Name, mxObject));
if (xPropertySet.is())
{
@@ -406,50 +380,241 @@ void DevelopmentToolDockingWindow::introspect(uno::Reference<uno::XInterface> co
try
{
uno::Any aAny = xPropertySet->getPropertyValue(xProperty.Name);
- aValue = AnyToString(aAny, xContext);
+ aValue = AnyToString(aAny, mxContext);
}
catch (const beans::UnknownPropertyException&)
{
aValue = "UnknownPropertyException";
}
- mpClassListBox->set_text(*pResult, aValue, 1);
+ pTree->set_text(*pCurrent, aValue, 1);
}
}
}
+};
+
+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(xInterface, uno::UNO_QUERY);
+ uno::Reference<lang::XTypeProvider> xTypeProvider(mxObject, uno::UNO_QUERY);
if (xTypeProvider.is())
{
- OUString aTypesString("Interfaces");
- mpClassListBox->insert(nullptr, -1, &aTypesString, nullptr, nullptr, nullptr, false,
- pParent.get());
- mpClassListBox->set_text_emphasis(*pParent, true, 0);
-
const auto xSequenceTypes = xTypeProvider->getTypes();
for (auto const& xType : xSequenceTypes)
{
OUString aName = xType.getTypeName();
- mpClassListBox->insert(pParent.get(), -1, &aName, nullptr, nullptr, nullptr, false,
- pResult.get());
+ 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)
+ : SfxDockingWindow(pInputBindings, pChildWindow, pParent, "DevelopmentTool",
+ "svx/ui/developmenttool.ui")
+ , mpClassNameLabel(m_xBuilder->weld_label("class_name_value_id"))
+ , mpClassListBox(m_xBuilder->weld_tree_view("class_listbox_id"))
+ , mpLeftSideTreeView(m_xBuilder->weld_tree_view("leftside_treeview_id"))
+ , mpSelectionToggle(m_xBuilder->weld_toggle_button("selection_toggle"))
+ , maDocumentModelTreeHandler(
+ mpLeftSideTreeView,
+ pInputBindings->GetDispatcher()->GetFrame()->GetObjectShell()->GetBaseModel())
+{
+ mpLeftSideTreeView->connect_changed(LINK(this, DevelopmentToolDockingWindow, LeftSideSelected));
+ mpSelectionToggle->connect_toggled(LINK(this, DevelopmentToolDockingWindow, SelectionToggled));
+ mpClassListBox->connect_expanding(
+ LINK(this, DevelopmentToolDockingWindow, ObjectInspectorExpandingHandler));
+
+ auto* pViewFrame = pInputBindings->GetDispatcher()->GetFrame();
+
+ uno::Reference<frame::XController> xController = pViewFrame->GetFrame().GetController();
+
+ mxRoot = pInputBindings->GetDispatcher()->GetFrame()->GetObjectShell()->GetBaseModel();
+
+ introspect(mxRoot);
+ maDocumentModelTreeHandler.inspectDocument();
+ mxSelectionListener.set(new SelectionChangeHandler(xController, this));
+}
+
+IMPL_LINK(DevelopmentToolDockingWindow, LeftSideSelected, weld::TreeView&, rView, void)
+{
+ if (mpSelectionToggle->get_state() == TRISTATE_TRUE)
+ return;
+
+ OUString sID = rView.get_selected_id();
+ auto xObject = DocumentModelTreeHandler::getObjectByID(sID);
+ if (xObject.is())
+ introspect(xObject);
+}
+
+IMPL_LINK_NOARG(DevelopmentToolDockingWindow, SelectionToggled, weld::ToggleButton&, void)
+{
+ 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);
+}
- OUString aMethodsString("Methods");
- mpClassListBox->insert(nullptr, -1, &aMethodsString, nullptr, nullptr, nullptr, false,
- pParent.get());
- mpClassListBox->set_text_emphasis(*pParent, true, 0);
+DevelopmentToolDockingWindow::~DevelopmentToolDockingWindow() { disposeOnce(); }
+
+void DevelopmentToolDockingWindow::dispose()
+{
+ auto* pSelectionChangeHandler
+ = dynamic_cast<SelectionChangeHandler*>(mxSelectionListener.get());
+ if (pSelectionChangeHandler)
+ pSelectionChangeHandler->disconnect();
+
+ 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;
+ });
+
+ // dispose welded objects
+ mpClassNameLabel.reset();
+ mpClassListBox.reset();
+ mpSelectionToggle.reset();
+ mpLeftSideTreeView.reset();
- const auto xMethods = xIntrospectionAccess->getMethods(beans::MethodConcept::ALL);
- for (auto const& xMethod : xMethods)
+ SfxDockingWindow::dispose();
+}
+
+void DevelopmentToolDockingWindow::updateSelection()
+{
+ TriState eTriState = mpSelectionToggle->get_state();
+ if (eTriState == TRISTATE_TRUE)
+ {
+ introspect(mxCurrentSelection);
+ mpLeftSideTreeView->set_sensitive(false);
+ }
+ else
{
- OUString aMethodName = xMethod->getName();
- mpClassListBox->insert(pParent.get(), -1, &aMethodName, nullptr, nullptr, nullptr, false,
- pResult.get());
- mpClassListBox->set_text_emphasis(*pResult, false, 0);
+ mpLeftSideTreeView->set_sensitive(true);
+ LeftSideSelected(*mpLeftSideTreeView);
}
+}
+
+void DevelopmentToolDockingWindow::ToggleFloatingMode()
+{
+ SfxDockingWindow::ToggleFloatingMode();
+
+ if (GetFloatingWindow())
+ GetFloatingWindow()->SetMinOutputSizePixel(Size(300, 300));
+
+ 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)
+{
+ mxCurrentSelection = xInterface;
+ 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();
}