diff options
author | Tomaž Vajngerl <tomaz.vajngerl@collabora.co.uk> | 2021-01-18 08:17:01 +0900 |
---|---|---|
committer | Tomaž Vajngerl <quikee@gmail.com> | 2021-01-18 07:09:18 +0100 |
commit | 36b17f030777219e69412733feb250b8de5af9ef (patch) | |
tree | a6818988037ed0321e5b463b37bf8b8b9b3045f2 /svx/source | |
parent | cf98f078b0a4e8c36cf0579042442e5583013608 (diff) |
devtools: handle the doc. model tree with attached obects
Instead of filling the document model tree with fill* methods,
refactor that to use objects that are attached (via get_id) to the
tree nodes directly. For this introduce DocumentModelTreeEntry
and subclasses, which implement what the current UNO object is
that is being shown for a tree node and a "fill" virtual method,
which is used to fill the child nodes of the tree when expanding
a tree node.
This makes the code much easier to work with and in addition it
makes it possible to have all the tree nodes to fill the content
on demand when expanded.
Change-Id: Id5a027e060af90e483181439568f17d0172d1b35
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/109500
Tested-by: Jenkins
Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
Diffstat (limited to 'svx/source')
-rw-r--r-- | svx/source/devtools/DevelopmentToolDockingWindow.cxx | 7 | ||||
-rw-r--r-- | svx/source/devtools/DocumentModelTreeHandler.cxx | 799 |
2 files changed, 476 insertions, 330 deletions
diff --git a/svx/source/devtools/DevelopmentToolDockingWindow.cxx b/svx/source/devtools/DevelopmentToolDockingWindow.cxx index f1ebbc355836..c09bc4035c6e 100644 --- a/svx/source/devtools/DevelopmentToolDockingWindow.cxx +++ b/svx/source/devtools/DevelopmentToolDockingWindow.cxx @@ -118,10 +118,10 @@ DevelopmentToolDockingWindow::DevelopmentToolDockingWindow(SfxBindings* pInputBi } } -IMPL_LINK_NOARG(DevelopmentToolDockingWindow, LeftSideSelected, weld::TreeView&, void) +IMPL_LINK(DevelopmentToolDockingWindow, LeftSideSelected, weld::TreeView&, rView, void) { - OUString sID = mpLeftSideTreeView->get_selected_text(); - auto xObject = maDocumentModelTreeHandler.getObjectByID(sID); + OUString sID = rView.get_selected_id(); + auto xObject = DocumentModelTreeHandler::getObjectByID(sID); if (xObject.is()) introspect(xObject); } @@ -132,6 +132,7 @@ void DevelopmentToolDockingWindow::dispose() { mpClassNameLabel.reset(); mpClassListBox.reset(); + maDocumentModelTreeHandler.dispose(); mpLeftSideTreeView.reset(); SfxDockingWindow::dispose(); diff --git a/svx/source/devtools/DocumentModelTreeHandler.cxx b/svx/source/devtools/DocumentModelTreeHandler.cxx index 0aa93f8e0668..2c721dcbea8e 100644 --- a/svx/source/devtools/DocumentModelTreeHandler.cxx +++ b/svx/source/devtools/DocumentModelTreeHandler.cxx @@ -9,19 +9,18 @@ */ #include <memory> + #include <svx/devtools/DocumentModelTreeHandler.hxx> #include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/container/XNamed.hpp> +#include <com/sun/star/container/XEnumerationAccess.hpp> #include <com/sun/star/drawing/XDrawPage.hpp> #include <com/sun/star/drawing/XDrawPages.hpp> #include <com/sun/star/drawing/XDrawPagesSupplier.hpp> #include <com/sun/star/drawing/XDrawPageSupplier.hpp> #include <com/sun/star/drawing/XMasterPagesSupplier.hpp> - -#include <com/sun/star/container/XNamed.hpp> -#include <com/sun/star/container/XEnumerationAccess.hpp> - #include <com/sun/star/sheet/XSpreadsheetDocument.hpp> #include <com/sun/star/sheet/XSpreadsheet.hpp> #include <com/sun/star/sheet/XSpreadsheets.hpp> @@ -29,7 +28,6 @@ #include <com/sun/star/sheet/XDataPilotTables.hpp> #include <com/sun/star/table/XTableChartsSupplier.hpp> #include <com/sun/star/table/XTableCharts.hpp> - #include <com/sun/star/text/XTextDocument.hpp> #include <com/sun/star/text/XTextTablesSupplier.hpp> #include <com/sun/star/text/XTextFramesSupplier.hpp> @@ -41,22 +39,21 @@ using namespace css; namespace { -void lclAppendToParent(std::unique_ptr<weld::TreeView>& rTree, weld::TreeIter const& rParent, - OUString const& rString, bool bChildrenOnDemand = false) -{ - rTree->insert(&rParent, -1, &rString, nullptr, nullptr, nullptr, bChildrenOnDemand, nullptr); -} +class DocumentModelTreeEntry; -void lclAppendToParentWithIter(std::unique_ptr<weld::TreeView>& rTree, - weld::TreeIter const& rParent, weld::TreeIter& rCurrent, - OUString const& rString, bool bChildrenOnDemand = false) +void lclAppendToParentEntry(std::unique_ptr<weld::TreeView>& rTree, weld::TreeIter const& rParent, + OUString const& rString, DocumentModelTreeEntry* pEntry, + bool bChildrenOnDemand = false) { - rTree->insert(&rParent, -1, &rString, nullptr, nullptr, nullptr, bChildrenOnDemand, &rCurrent); + OUString sId(OUString::number(reinterpret_cast<sal_Int64>(pEntry))); + rTree->insert(&rParent, -1, &rString, &sId, nullptr, nullptr, bChildrenOnDemand, nullptr); } -void lclAppend(std::unique_ptr<weld::TreeView>& rTree, OUString const& rString) +void lclAppend(std::unique_ptr<weld::TreeView>& rTree, OUString const& rString, + DocumentModelTreeEntry* pEntry, bool bChildrenOnDemand = false) { - rTree->insert(nullptr, -1, &rString, nullptr, nullptr, nullptr, true, nullptr); + OUString sId(OUString::number(reinterpret_cast<sal_Int64>(pEntry))); + rTree->insert(nullptr, -1, &rString, &sId, nullptr, nullptr, bChildrenOnDemand, nullptr); } OUString lclGetNamed(uno::Reference<uno::XInterface> const& xObject) @@ -67,448 +64,596 @@ OUString lclGetNamed(uno::Reference<uno::XInterface> const& xObject) return xNamed->getName(); } -} // end anonymous namespace - -uno::Reference<uno::XInterface> DocumentModelTreeHandler::getObjectByID(OUString const& rID) +/** + * DocumentModelTreeEntry represents an object that is "attached" to + * the tree view an is responsible to provide the UNO object associated + * with the current node and on demand create and fill the children of + * the said node. + */ +class DocumentModelTreeEntry { - uno::Reference<uno::XInterface> xObject; - if (maUnoObjectMap.find(rID) == maUnoObjectMap.end()) - return xObject; - xObject = maUnoObjectMap.at(rID); - return xObject; -} +public: + css::uno::Reference<css::uno::XInterface> mxObject; + + DocumentModelTreeEntry() = default; + + DocumentModelTreeEntry(css::uno::Reference<css::uno::XInterface> const& xObject) + : mxObject(xObject) + { + } + + virtual ~DocumentModelTreeEntry() {} + + /// The main UNO object for this entry + virtual css::uno::Reference<css::uno::XInterface> getMainObject() { return mxObject; } + + /// Create and fill the childrent to the parent tree view node. + virtual void fill(std::unique_ptr<weld::TreeView>& /*pDocumentModelTree*/, + weld::TreeIter const& /*rParent*/) + { + } + +protected: + /// A generic fill when the UNO object implements XNameAccess interface + void fillNameAccess(std::unique_ptr<weld::TreeView>& pDocumentModelTree, + weld::TreeIter const& rParent) + { + uno::Reference<container::XNameAccess> xNameAccess(getMainObject(), uno::UNO_QUERY); + if (!xNameAccess.is()) + return; + + const uno::Sequence<OUString> aNames = xNameAccess->getElementNames(); + for (auto const& rName : aNames) + { + uno::Reference<uno::XInterface> xObject(xNameAccess->getByName(rName), uno::UNO_QUERY); + auto pEntry = std::make_unique<DocumentModelTreeEntry>(xObject); + lclAppendToParentEntry(pDocumentModelTree, rParent, rName, pEntry.release()); + } + } +}; -void DocumentModelTreeHandler::insertDocModelToParent( - weld::TreeIter const& rParent, OUString const& rName, - uno::Reference<uno::XInterface> const& rInterface) +class DocumentRootEntry : public DocumentModelTreeEntry { - maUnoObjectMap.emplace(rName, rInterface); - lclAppendToParent(mpDocumentModelTree, rParent, rName); -} +public: + DocumentRootEntry(css::uno::Reference<css::uno::XInterface> const& xObject) + : DocumentModelTreeEntry(xObject) + { + } +}; -void DocumentModelTreeHandler::clearChildren(weld::TreeIter const& rParent) +class ParagraphsEntry : public DocumentModelTreeEntry { - bool bChild = false; - do +public: + ParagraphsEntry(css::uno::Reference<css::uno::XInterface> const& xObject) + : DocumentModelTreeEntry(xObject) { - bChild = mpDocumentModelTree->iter_has_child(rParent); - if (bChild) + } + + css::uno::Reference<css::uno::XInterface> getMainObject() override + { + uno::Reference<text::XTextDocument> xDocument(mxObject, uno::UNO_QUERY); + if (!xDocument.is()) + return mxObject; + + return xDocument->getText()->getText(); + } + + void fill(std::unique_ptr<weld::TreeView>& pDocumentModelTree, + weld::TreeIter const& rParent) override + { + uno::Reference<container::XEnumerationAccess> xEnumAccess(getMainObject(), uno::UNO_QUERY); + if (!xEnumAccess.is()) + return; + + uno::Reference<container::XEnumeration> xParagraphEnum = xEnumAccess->createEnumeration(); + + if (xParagraphEnum.is()) { - std::unique_ptr<weld::TreeIter> pChild = mpDocumentModelTree->make_iterator(&rParent); - bChild = mpDocumentModelTree->iter_children(*pChild); - if (bChild) + for (sal_Int32 i = 0; xParagraphEnum->hasMoreElements(); i++) { - mpDocumentModelTree->remove(*pChild); + uno::Reference<text::XTextContent> const xParagraph(xParagraphEnum->nextElement(), + uno::UNO_QUERY); + OUString aString = lclGetNamed(xParagraph); + if (aString.isEmpty()) + aString = "Paragraph " + OUString::number(i + 1); + + auto pEntry = std::make_unique<DocumentModelTreeEntry>(xParagraph); + lclAppendToParentEntry(pDocumentModelTree, rParent, aString, pEntry.release()); } } - } while (bChild); -} + } +}; -IMPL_LINK(DocumentModelTreeHandler, ExpandingHandler, weld::TreeIter const&, rParent, bool) +class ShapesEntry : public DocumentModelTreeEntry { - OUString aText = mpDocumentModelTree->get_text(rParent); - if (aText == "Paragraphs") +public: + ShapesEntry(css::uno::Reference<css::uno::XInterface> const& xObject) + : DocumentModelTreeEntry(xObject) + { + } + + css::uno::Reference<css::uno::XInterface> getMainObject() override { - clearChildren(rParent); - fillParagraphs(rParent); + uno::Reference<drawing::XDrawPageSupplier> xSupplier(mxObject, uno::UNO_QUERY); + if (!xSupplier.is()) + return mxObject; + return xSupplier->getDrawPage(); } - else if (aText == "Shapes") + + void fill(std::unique_ptr<weld::TreeView>& pDocumentModelTree, + weld::TreeIter const& rParent) override { - uno::Reference<lang::XServiceInfo> xDocumentServiceInfo(mxDocument, uno::UNO_QUERY_THROW); - if (xDocumentServiceInfo->supportsService("com.sun.star.text.TextDocument")) + uno::Reference<container::XIndexAccess> xShapes(getMainObject(), uno::UNO_QUERY); + if (!xShapes.is()) + return; + for (sal_Int32 nIndexShapes = 0; nIndexShapes < xShapes->getCount(); ++nIndexShapes) { - clearChildren(rParent); - fillShapes(rParent); + uno::Reference<uno::XInterface> xShape(xShapes->getByIndex(nIndexShapes), + uno::UNO_QUERY); + OUString aShapeName = lclGetNamed(xShape); + if (aShapeName.isEmpty()) + aShapeName = "Shape " + OUString::number(nIndexShapes + 1); + + auto pEntry = std::make_unique<DocumentModelTreeEntry>(xShape); + lclAppendToParentEntry(pDocumentModelTree, rParent, aShapeName, pEntry.release()); } } - else if (aText == "Tables") +}; + +class TablesEntry : public DocumentModelTreeEntry +{ +public: + TablesEntry(css::uno::Reference<css::uno::XInterface> const& xObject) + : DocumentModelTreeEntry(xObject) { - clearChildren(rParent); - fillTables(rParent); } - else if (aText == "Frames") + + css::uno::Reference<css::uno::XInterface> getMainObject() override { - clearChildren(rParent); - fillFrames(rParent); + uno::Reference<text::XTextTablesSupplier> xSupplier(mxObject, uno::UNO_QUERY); + if (!xSupplier.is()) + return mxObject; + return xSupplier->getTextTables(); } - else if (aText == "Graphic Objects") + + void fill(std::unique_ptr<weld::TreeView>& pDocumentModelTree, + weld::TreeIter const& rParent) override { - clearChildren(rParent); - fillGraphicObjects(rParent); + fillNameAccess(pDocumentModelTree, rParent); } - else if (aText == "Embedded Objects") +}; + +class FramesEntry : public DocumentModelTreeEntry +{ +public: + FramesEntry(css::uno::Reference<css::uno::XInterface> const& xObject) + : DocumentModelTreeEntry(xObject) { - clearChildren(rParent); - fillOLEObjects(rParent); } - else if (aText == "Styles") + + css::uno::Reference<css::uno::XInterface> getMainObject() override { - clearChildren(rParent); - fillStyleFamilies(rParent); + uno::Reference<text::XTextFramesSupplier> xSupplier(mxObject, uno::UNO_QUERY); + if (!xSupplier.is()) + return mxObject; + return xSupplier->getTextFrames(); } - else if (aText == "Pages") + + void fill(std::unique_ptr<weld::TreeView>& pDocumentModelTree, + weld::TreeIter const& rParent) override { - clearChildren(rParent); - fillPages(rParent); + fillNameAccess(pDocumentModelTree, rParent); } - else if (aText == "Slides") +}; + +class WriterGraphicObjectsEntry : public DocumentModelTreeEntry +{ +public: + WriterGraphicObjectsEntry(css::uno::Reference<css::uno::XInterface> const& xObject) + : DocumentModelTreeEntry(xObject) { - clearChildren(rParent); - fillSlides(rParent); } - else if (aText == "Master Slides") + + css::uno::Reference<css::uno::XInterface> getMainObject() override { - clearChildren(rParent); - fillMasterSlides(rParent); + uno::Reference<text::XTextGraphicObjectsSupplier> xSupplier(mxObject, uno::UNO_QUERY); + if (!xSupplier.is()) + return mxObject; + return xSupplier->getGraphicObjects(); } - else if (aText == "Sheets") + + void fill(std::unique_ptr<weld::TreeView>& pDocumentModelTree, + weld::TreeIter const& rParent) override { - clearChildren(rParent); - fillSheets(rParent); + fillNameAccess(pDocumentModelTree, rParent); } +}; - return true; -} - -void DocumentModelTreeHandler::fillGraphicObjects(weld::TreeIter const& rParent) +class EmbeddedObjectsEntry : public DocumentModelTreeEntry { - uno::Reference<text::XTextGraphicObjectsSupplier> xSupplier(mxDocument, uno::UNO_QUERY); - if (!xSupplier.is()) - return; - uno::Reference<container::XNameAccess> xGraphicObjects = xSupplier->getGraphicObjects(); - const uno::Sequence<OUString> aNames = xGraphicObjects->getElementNames(); - for (auto const& rName : aNames) +public: + EmbeddedObjectsEntry(css::uno::Reference<css::uno::XInterface> const& xObject) + : DocumentModelTreeEntry(xObject) { - uno::Reference<uno::XInterface> xObject(xGraphicObjects->getByName(rName), uno::UNO_QUERY); - insertDocModelToParent(rParent, rName, xObject); } -} -void DocumentModelTreeHandler::fillOLEObjects(weld::TreeIter const& rParent) -{ - uno::Reference<text::XTextEmbeddedObjectsSupplier> xSupplier(mxDocument, uno::UNO_QUERY); - if (!xSupplier.is()) - return; - uno::Reference<container::XNameAccess> xOleObjects = xSupplier->getEmbeddedObjects(); - const uno::Sequence<OUString> aNames = xOleObjects->getElementNames(); - for (auto const& rName : aNames) + css::uno::Reference<css::uno::XInterface> getMainObject() override { - uno::Reference<uno::XInterface> xObject(xOleObjects->getByName(rName), uno::UNO_QUERY); - insertDocModelToParent(rParent, rName, xObject); + uno::Reference<text::XTextEmbeddedObjectsSupplier> xSupplier(mxObject, uno::UNO_QUERY); + if (!xSupplier.is()) + return mxObject; + return xSupplier->getEmbeddedObjects(); } -} -void DocumentModelTreeHandler::fillStyleFamilies(weld::TreeIter const& rParent) -{ - uno::Reference<style::XStyleFamiliesSupplier> xSupplier(mxDocument, uno::UNO_QUERY); - if (!xSupplier.is()) - return; - uno::Reference<container::XNameAccess> xStyleFamilies = xSupplier->getStyleFamilies(); - const uno::Sequence<OUString> aNames = xStyleFamilies->getElementNames(); - for (auto const& rFamilyName : aNames) - { - uno::Reference<container::XNameAccess> xStyleFamily(xStyleFamilies->getByName(rFamilyName), - uno::UNO_QUERY); - - std::unique_ptr<weld::TreeIter> pCurrentStyleFamily = mpDocumentModelTree->make_iterator(); - lclAppendToParentWithIter(mpDocumentModelTree, rParent, *pCurrentStyleFamily, rFamilyName); - maUnoObjectMap.emplace(rFamilyName, xStyleFamily); - - const uno::Sequence<OUString> aStyleNames = xStyleFamily->getElementNames(); - for (auto const& rStyleName : aStyleNames) - { - uno::Reference<uno::XInterface> xStyle(xStyleFamily->getByName(rStyleName), - uno::UNO_QUERY); - insertDocModelToParent(*pCurrentStyleFamily, rStyleName, xStyle); - } + void fill(std::unique_ptr<weld::TreeView>& pDocumentModelTree, + weld::TreeIter const& rParent) override + { + fillNameAccess(pDocumentModelTree, rParent); } -} +}; -void DocumentModelTreeHandler::fillFrames(weld::TreeIter const& rParent) +class StylesFamilyEntry : public DocumentModelTreeEntry { - uno::Reference<text::XTextFramesSupplier> xSupplier(mxDocument, uno::UNO_QUERY); - if (!xSupplier.is()) - return; - uno::Reference<container::XNameAccess> xFrames = xSupplier->getTextFrames(); - const uno::Sequence<OUString> aNames = xFrames->getElementNames(); - for (auto const& rName : aNames) +public: + StylesFamilyEntry(css::uno::Reference<css::uno::XInterface> const& xObject) + : DocumentModelTreeEntry(xObject) { - uno::Reference<uno::XInterface> xObject(xFrames->getByName(rName), uno::UNO_QUERY); - insertDocModelToParent(rParent, rName, xObject); } -} -void DocumentModelTreeHandler::fillTables(weld::TreeIter const& rParent) -{ - uno::Reference<text::XTextTablesSupplier> xSupplier(mxDocument, uno::UNO_QUERY); - if (!xSupplier.is()) - return; - uno::Reference<container::XNameAccess> xTables = xSupplier->getTextTables(); - const uno::Sequence<OUString> aNames = xTables->getElementNames(); - for (auto const& rName : aNames) + void fill(std::unique_ptr<weld::TreeView>& pDocumentModelTree, + weld::TreeIter const& rParent) override { - uno::Reference<uno::XInterface> xObject(xTables->getByName(rName), uno::UNO_QUERY); - insertDocModelToParent(rParent, rName, xObject); + fillNameAccess(pDocumentModelTree, rParent); } -} +}; -void DocumentModelTreeHandler::fillSheets(weld::TreeIter const& rParent) +class StylesFamiliesEntry : public DocumentModelTreeEntry { - uno::Reference<sheet::XSpreadsheetDocument> xSheetDoc(mxDocument, uno::UNO_QUERY); - if (!xSheetDoc.is()) - return; - uno::Reference<sheet::XSpreadsheets> xSheets = xSheetDoc->getSheets(); - uno::Reference<container::XIndexAccess> xIndex(xSheets, uno::UNO_QUERY); - for (sal_Int32 i = 0; i < xIndex->getCount(); ++i) +public: + StylesFamiliesEntry(css::uno::Reference<css::uno::XInterface> const& xObject) + : DocumentModelTreeEntry(xObject) { - uno::Reference<sheet::XSpreadsheet> xSheet(xIndex->getByIndex(i), uno::UNO_QUERY); + } - OUString aSlideString = lclGetNamed(xSheet); - if (aSlideString.isEmpty()) - aSlideString = "Sheet " + OUString::number(i + 1); + css::uno::Reference<css::uno::XInterface> getMainObject() override + { + uno::Reference<style::XStyleFamiliesSupplier> xSupplier(mxObject, uno::UNO_QUERY); + if (!xSupplier.is()) + return mxObject; + return xSupplier->getStyleFamilies(); + } - std::unique_ptr<weld::TreeIter> pCurrentSheet = mpDocumentModelTree->make_iterator(); - lclAppendToParentWithIter(mpDocumentModelTree, rParent, *pCurrentSheet, aSlideString); - maUnoObjectMap.emplace(aSlideString, xSheet); + void fill(std::unique_ptr<weld::TreeView>& pDocumentModelTree, + weld::TreeIter const& rParent) override + { + uno::Reference<container::XNameAccess> xStyleFamilies(getMainObject(), uno::UNO_QUERY); + if (!xStyleFamilies.is()) + return; + const uno::Sequence<OUString> aNames = xStyleFamilies->getElementNames(); + for (auto const& rFamilyName : aNames) { - uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(xSheet, uno::UNO_QUERY); - uno::Reference<container::XIndexAccess> xDraws = xDrawPageSupplier->getDrawPage(); + uno::Reference<uno::XInterface> xStyleFamily(xStyleFamilies->getByName(rFamilyName), + uno::UNO_QUERY); - std::unique_ptr<weld::TreeIter> pCurrentShapes = mpDocumentModelTree->make_iterator(); - - lclAppendToParentWithIter(mpDocumentModelTree, *pCurrentSheet, *pCurrentShapes, - "Shapes"); - maUnoObjectMap.emplace("Shapes", xDraws); + auto pStylesFamilyEntry = std::make_unique<StylesFamilyEntry>(xStyleFamily); + lclAppendToParentEntry(pDocumentModelTree, rParent, rFamilyName, + pStylesFamilyEntry.release(), true); + } + } +}; - for (sal_Int32 nIndexShapes = 0; nIndexShapes < xDraws->getCount(); ++nIndexShapes) - { - uno::Reference<uno::XInterface> xShape(xDraws->getByIndex(nIndexShapes), - uno::UNO_QUERY); - OUString aShapeName = lclGetNamed(xShape); - if (aShapeName.isEmpty()) - aShapeName = "Shape " + OUString::number(nIndexShapes + 1); +class PagesEntry : public DocumentModelTreeEntry +{ +public: + PagesEntry(css::uno::Reference<css::uno::XInterface> const& xObject) + : DocumentModelTreeEntry(xObject) + { + } - insertDocModelToParent(*pCurrentShapes, aShapeName, xShape); - } - } + css::uno::Reference<css::uno::XInterface> getMainObject() override + { + uno::Reference<drawing::XDrawPagesSupplier> xSupplier(mxObject, uno::UNO_QUERY); + if (!xSupplier.is()) + return mxObject; + return xSupplier->getDrawPages(); + } + void fill(std::unique_ptr<weld::TreeView>& pDocumentModelTree, + weld::TreeIter const& rParent) override + { + uno::Reference<drawing::XDrawPages> xDrawPages(getMainObject(), uno::UNO_QUERY); + for (sal_Int32 i = 0; i < xDrawPages->getCount(); ++i) { - uno::Reference<table::XTableChartsSupplier> xSupplier(xSheet, uno::UNO_QUERY); - uno::Reference<table::XTableCharts> xCharts = xSupplier->getCharts(); - std::unique_ptr<weld::TreeIter> pCurrentCharts = mpDocumentModelTree->make_iterator(); - lclAppendToParentWithIter(mpDocumentModelTree, *pCurrentSheet, *pCurrentCharts, - "Charts"); - maUnoObjectMap.emplace("Charts", xCharts); - - const uno::Sequence<OUString> aNames = xCharts->getElementNames(); - for (auto const& rName : aNames) - { - uno::Reference<uno::XInterface> xChart(xCharts->getByName(rName), uno::UNO_QUERY); - insertDocModelToParent(*pCurrentCharts, rName, xChart); - } - } + uno::Reference<drawing::XDrawPage> xPage(xDrawPages->getByIndex(i), uno::UNO_QUERY); + if (!xPage.is()) + continue; - { - uno::Reference<sheet::XDataPilotTablesSupplier> xSupplier(xSheet, uno::UNO_QUERY); - uno::Reference<sheet::XDataPilotTables> xPivotTables = xSupplier->getDataPilotTables(); - std::unique_ptr<weld::TreeIter> pCurrentPivotTables - = mpDocumentModelTree->make_iterator(); - lclAppendToParentWithIter(mpDocumentModelTree, *pCurrentSheet, *pCurrentPivotTables, - "Pivot Tables"); - maUnoObjectMap.emplace("Pivot Tables", xPivotTables); - - const uno::Sequence<OUString> aNames = xPivotTables->getElementNames(); - for (auto const& rName : aNames) - { - uno::Reference<uno::XInterface> xPivotTable(xPivotTables->getByName(rName), - uno::UNO_QUERY); - insertDocModelToParent(*pCurrentPivotTables, rName, xPivotTable); - } + OUString aPageString = lclGetNamed(xPage); + if (aPageString.isEmpty()) + aPageString = "Page " + OUString::number(i + 1); + + auto pShapesEntry = std::make_unique<ShapesEntry>(xPage); + lclAppendToParentEntry(pDocumentModelTree, rParent, aPageString, pShapesEntry.release(), + true); } } -} +}; -void DocumentModelTreeHandler::fillPages(weld::TreeIter const& rParent) +class SlidesEntry : public DocumentModelTreeEntry { - uno::Reference<drawing::XDrawPagesSupplier> xDrawPagesSupplier(mxDocument, uno::UNO_QUERY); - if (!xDrawPagesSupplier.is()) - return; - uno::Reference<drawing::XDrawPages> xDrawPages = xDrawPagesSupplier->getDrawPages(); - for (sal_Int32 i = 0; i < xDrawPages->getCount(); ++i) +public: + SlidesEntry(css::uno::Reference<css::uno::XInterface> const& xObject) + : DocumentModelTreeEntry(xObject) { - uno::Reference<drawing::XDrawPage> xPage(xDrawPages->getByIndex(i), uno::UNO_QUERY); - if (!xPage.is()) - continue; - - OUString aPageString = lclGetNamed(xPage); - if (aPageString.isEmpty()) - aPageString = "Page " + OUString::number(i + 1); + } - std::unique_ptr<weld::TreeIter> pCurrentPage = mpDocumentModelTree->make_iterator(); - lclAppendToParentWithIter(mpDocumentModelTree, rParent, *pCurrentPage, aPageString); - maUnoObjectMap.emplace(aPageString, xPage); + css::uno::Reference<css::uno::XInterface> getMainObject() override + { + uno::Reference<drawing::XDrawPagesSupplier> xSupplier(mxObject, uno::UNO_QUERY); + if (!xSupplier.is()) + return mxObject; + return xSupplier->getDrawPages(); + } - for (sal_Int32 nPageIndex = 0; nPageIndex < xPage->getCount(); ++nPageIndex) + void fill(std::unique_ptr<weld::TreeView>& pDocumentModelTree, + weld::TreeIter const& rParent) override + { + uno::Reference<drawing::XDrawPages> xDrawPages(getMainObject(), uno::UNO_QUERY); + for (sal_Int32 i = 0; i < xDrawPages->getCount(); ++i) { - uno::Reference<uno::XInterface> xShape(xPage->getByIndex(nPageIndex), uno::UNO_QUERY); + uno::Reference<drawing::XDrawPage> xPage(xDrawPages->getByIndex(i), uno::UNO_QUERY); + if (!xPage.is()) + continue; - OUString aShapeName = lclGetNamed(xShape); - if (aShapeName.isEmpty()) - aShapeName = "Shape " + OUString::number(nPageIndex + 1); + OUString aPageString = lclGetNamed(xPage); + if (aPageString.isEmpty()) + aPageString = "Slide " + OUString::number(i + 1); - insertDocModelToParent(*pCurrentPage, aShapeName, xShape); + auto pShapesEntry = std::make_unique<ShapesEntry>(xPage); + lclAppendToParentEntry(pDocumentModelTree, rParent, aPageString, pShapesEntry.release(), + true); } } -} +}; -void DocumentModelTreeHandler::fillSlides(weld::TreeIter const& rParent) +class MasterSlidesEntry : public DocumentModelTreeEntry { - uno::Reference<drawing::XDrawPagesSupplier> xDrawPagesSupplier(mxDocument, uno::UNO_QUERY); - if (!xDrawPagesSupplier.is()) - return; - uno::Reference<drawing::XDrawPages> xDrawPages = xDrawPagesSupplier->getDrawPages(); - for (sal_Int32 i = 0; i < xDrawPages->getCount(); ++i) +public: + MasterSlidesEntry(css::uno::Reference<css::uno::XInterface> const& xObject) + : DocumentModelTreeEntry(xObject) { - uno::Reference<drawing::XDrawPage> xPage(xDrawPages->getByIndex(i), uno::UNO_QUERY); - if (!xPage.is()) - continue; - - OUString aSlideName = lclGetNamed(xPage); - if (aSlideName.isEmpty()) - aSlideName = "Slide " + OUString::number(i + 1); + } - std::unique_ptr<weld::TreeIter> pCurrentPage = mpDocumentModelTree->make_iterator(); - lclAppendToParentWithIter(mpDocumentModelTree, rParent, *pCurrentPage, aSlideName); - maUnoObjectMap.emplace(aSlideName, xPage); + css::uno::Reference<css::uno::XInterface> getMainObject() override + { + uno::Reference<drawing::XMasterPagesSupplier> xSupplier(mxObject, uno::UNO_QUERY); + if (!xSupplier.is()) + return mxObject; + return xSupplier->getMasterPages(); + } - for (sal_Int32 nPageIndex = 0; nPageIndex < xPage->getCount(); ++nPageIndex) + void fill(std::unique_ptr<weld::TreeView>& pDocumentModelTree, + weld::TreeIter const& rParent) override + { + uno::Reference<drawing::XDrawPages> xDrawPages(getMainObject(), uno::UNO_QUERY); + for (sal_Int32 i = 0; i < xDrawPages->getCount(); ++i) { - uno::Reference<uno::XInterface> xShape(xPage->getByIndex(nPageIndex), uno::UNO_QUERY); + uno::Reference<drawing::XDrawPage> xPage(xDrawPages->getByIndex(i), uno::UNO_QUERY); + if (!xPage.is()) + continue; - OUString aShapeName = lclGetNamed(xShape); - if (aShapeName.isEmpty()) - aShapeName = "Shape " + OUString::number(nPageIndex + 1); + OUString aPageString = lclGetNamed(xPage); + if (aPageString.isEmpty()) + aPageString = "Master Slide " + OUString::number(i + 1); - insertDocModelToParent(*pCurrentPage, aShapeName, xShape); + auto pShapesEntry = std::make_unique<ShapesEntry>(xPage); + lclAppendToParentEntry(pDocumentModelTree, rParent, aPageString, pShapesEntry.release(), + true); } } -} +}; -void DocumentModelTreeHandler::fillMasterSlides(weld::TreeIter const& rParent) +class ChartsEntry : public DocumentModelTreeEntry { - uno::Reference<drawing::XMasterPagesSupplier> xSupplier(mxDocument, uno::UNO_QUERY); - if (!xSupplier.is()) - return; - uno::Reference<drawing::XDrawPages> xDrawPages = xSupplier->getMasterPages(); - for (sal_Int32 i = 0; i < xDrawPages->getCount(); ++i) +public: + ChartsEntry(css::uno::Reference<css::uno::XInterface> const& xObject) + : DocumentModelTreeEntry(xObject) { - uno::Reference<drawing::XDrawPage> xPage(xDrawPages->getByIndex(i), uno::UNO_QUERY); - if (!xPage.is()) - continue; + } - OUString aSlideName = lclGetNamed(xPage); - if (aSlideName.isEmpty()) - aSlideName = "Master " + OUString::number(i + 1); + css::uno::Reference<css::uno::XInterface> getMainObject() override + { + uno::Reference<table::XTableChartsSupplier> xSupplier(mxObject, uno::UNO_QUERY); + if (!xSupplier.is()) + return mxObject; + return xSupplier->getCharts(); + } - std::unique_ptr<weld::TreeIter> pCurrentPage = mpDocumentModelTree->make_iterator(); - lclAppendToParentWithIter(mpDocumentModelTree, rParent, *pCurrentPage, aSlideName); - maUnoObjectMap.emplace(aSlideName, xPage); + void fill(std::unique_ptr<weld::TreeView>& pDocumentModelTree, + weld::TreeIter const& rParent) override + { + uno::Reference<table::XTableCharts> xCharts(getMainObject(), uno::UNO_QUERY); + if (!xCharts.is()) + return; + fillNameAccess(pDocumentModelTree, rParent); + } +}; - for (sal_Int32 nPageIndex = 0; nPageIndex < xPage->getCount(); ++nPageIndex) - { - uno::Reference<container::XNamed> xShape(xPage->getByIndex(nPageIndex), uno::UNO_QUERY); +class PivotTablesEntry : public DocumentModelTreeEntry +{ +public: + PivotTablesEntry(css::uno::Reference<css::uno::XInterface> const& xObject) + : DocumentModelTreeEntry(xObject) + { + } - OUString aShapeName = xShape->getName(); - if (aShapeName.isEmpty()) - aShapeName = "Shape " + OUString::number(nPageIndex + 1); + css::uno::Reference<css::uno::XInterface> getMainObject() override + { + uno::Reference<sheet::XDataPilotTablesSupplier> xSupplier(mxObject, uno::UNO_QUERY); + if (!xSupplier.is()) + return mxObject; + return xSupplier->getDataPilotTables(); + } - insertDocModelToParent(*pCurrentPage, aShapeName, xShape); - } + void fill(std::unique_ptr<weld::TreeView>& pDocumentModelTree, + weld::TreeIter const& rParent) override + { + uno::Reference<sheet::XDataPilotTables> xPivotTables(getMainObject(), uno::UNO_QUERY); + if (!xPivotTables.is()) + return; + fillNameAccess(pDocumentModelTree, rParent); } -} +}; -void DocumentModelTreeHandler::fillParagraphs(weld::TreeIter const& rParent) +class SheetEntry : public DocumentModelTreeEntry { - uno::Reference<text::XTextDocument> xDocument(mxDocument, uno::UNO_QUERY); - if (!xDocument.is()) - return; - uno::Reference<container::XEnumerationAccess> xParagraphEnumAccess( - xDocument->getText()->getText(), uno::UNO_QUERY); +public: + SheetEntry(css::uno::Reference<css::uno::XInterface> const& xObject) + : DocumentModelTreeEntry(xObject) + { + } + + void fill(std::unique_ptr<weld::TreeView>& pDocumentModelTree, + weld::TreeIter const& rParent) override + { + auto pShapesEntry = std::make_unique<ShapesEntry>(getMainObject()); + lclAppendToParentEntry(pDocumentModelTree, rParent, "Shapes", pShapesEntry.release(), true); + + auto pChartsEntry = std::make_unique<ChartsEntry>(getMainObject()); + lclAppendToParentEntry(pDocumentModelTree, rParent, "Charts", pChartsEntry.release(), true); + + auto pPivotTablesEntry = std::make_unique<PivotTablesEntry>(getMainObject()); + lclAppendToParentEntry(pDocumentModelTree, rParent, "Pivot Tables", + pPivotTablesEntry.release(), true); + } +}; - if (!xParagraphEnumAccess.is()) - return; +class SheetsEntry : public DocumentModelTreeEntry +{ +public: + SheetsEntry(css::uno::Reference<css::uno::XInterface> const& xObject) + : DocumentModelTreeEntry(xObject) + { + } - uno::Reference<container::XEnumeration> xParagraphEnum - = xParagraphEnumAccess->createEnumeration(); + css::uno::Reference<css::uno::XInterface> getMainObject() override + { + uno::Reference<sheet::XSpreadsheetDocument> xSheetDocument(mxObject, uno::UNO_QUERY); + if (!xSheetDocument.is()) + return mxObject; + return xSheetDocument->getSheets(); + } - if (xParagraphEnum.is()) + void fill(std::unique_ptr<weld::TreeView>& pDocumentModelTree, + weld::TreeIter const& rParent) override { - for (sal_Int32 i = 0; xParagraphEnum->hasMoreElements(); i++) + uno::Reference<container::XIndexAccess> xIndex(getMainObject(), uno::UNO_QUERY); + if (!xIndex.is()) + return; + for (sal_Int32 i = 0; i < xIndex->getCount(); ++i) { - uno::Reference<text::XTextContent> const xParagraph(xParagraphEnum->nextElement(), - uno::UNO_QUERY); - OUString aString = lclGetNamed(xParagraph); + uno::Reference<sheet::XSpreadsheet> xSheet(xIndex->getByIndex(i), uno::UNO_QUERY); + OUString aString = lclGetNamed(xSheet); if (aString.isEmpty()) - aString = "Paragraph " + OUString::number(i + 1); - - insertDocModelToParent(rParent, aString, xParagraph); + aString = "Sheet " + OUString::number(i + 1); + auto pEntry = std::make_unique<SheetEntry>(xSheet); + lclAppendToParentEntry(pDocumentModelTree, rParent, aString, pEntry.release(), true); } } +}; + +} // end anonymous namespace + +uno::Reference<uno::XInterface> DocumentModelTreeHandler::getObjectByID(OUString const& rID) +{ + uno::Reference<uno::XInterface> xObject; + if (rID.isEmpty()) + return xObject; + auto* pEntry = reinterpret_cast<DocumentModelTreeEntry*>(rID.toInt64()); + return pEntry->getMainObject(); } -void DocumentModelTreeHandler::fillShapes(weld::TreeIter const& rParent) +void DocumentModelTreeHandler::clearChildren(weld::TreeIter const& rParent) { - uno::Reference<text::XTextDocument> xDocument(mxDocument, uno::UNO_QUERY); - if (!xDocument.is()) - return; - uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(xDocument, uno::UNO_QUERY); - uno::Reference<container::XIndexAccess> xDraws = xDrawPageSupplier->getDrawPage(); - for (sal_Int32 nIndexShapes = 0; nIndexShapes < xDraws->getCount(); ++nIndexShapes) + bool bChild = false; + do { - uno::Reference<uno::XInterface> xShape(xDraws->getByIndex(nIndexShapes), uno::UNO_QUERY); - OUString aShapeName = lclGetNamed(xShape); - if (aShapeName.isEmpty()) - aShapeName = "Shape " + OUString::number(nIndexShapes + 1); + bChild = mpDocumentModelTree->iter_has_child(rParent); + if (bChild) + { + std::unique_ptr<weld::TreeIter> pChild = mpDocumentModelTree->make_iterator(&rParent); + bChild = mpDocumentModelTree->iter_children(*pChild); + if (bChild) + { + clearChildren(*pChild); + OUString sID = mpDocumentModelTree->get_id(*pChild); + auto* pEntry = reinterpret_cast<DocumentModelTreeEntry*>(sID.toInt64()); + delete pEntry; + mpDocumentModelTree->remove(*pChild); + } + } + } while (bChild); +} - insertDocModelToParent(rParent, aShapeName, xShape); - } +void DocumentModelTreeHandler::dispose() +{ + mpDocumentModelTree->all_foreach([this](weld::TreeIter& rEntry) { + OUString sID = mpDocumentModelTree->get_id(rEntry); + auto* pEntry = reinterpret_cast<DocumentModelTreeEntry*>(sID.toInt64()); + delete pEntry; + return false; + }); +} + +IMPL_LINK(DocumentModelTreeHandler, ExpandingHandler, weld::TreeIter const&, rParent, bool) +{ + OUString sID = mpDocumentModelTree->get_id(rParent); + if (sID.isEmpty()) + return true; + + clearChildren(rParent); + auto* pEntry = reinterpret_cast<DocumentModelTreeEntry*>(sID.toInt64()); + pEntry->fill(mpDocumentModelTree, rParent); + + return true; } void DocumentModelTreeHandler::inspectDocument() { uno::Reference<lang::XServiceInfo> xDocumentServiceInfo(mxDocument, uno::UNO_QUERY_THROW); - mpDocumentModelTree->append_text("Document"); - maUnoObjectMap.emplace("Document", mxDocument); + lclAppend(mpDocumentModelTree, "Document", new DocumentRootEntry(mxDocument), false); if (xDocumentServiceInfo->supportsService("com.sun.star.sheet.SpreadsheetDocument")) { - lclAppend(mpDocumentModelTree, "Sheets"); - lclAppend(mpDocumentModelTree, "Styles"); + lclAppend(mpDocumentModelTree, "Sheets", new SheetsEntry(mxDocument), true); + lclAppend(mpDocumentModelTree, "Styles", new StylesFamiliesEntry(mxDocument), true); } else if (xDocumentServiceInfo->supportsService( "com.sun.star.presentation.PresentationDocument")) { - lclAppend(mpDocumentModelTree, "Slides"); - lclAppend(mpDocumentModelTree, "Styles"); - lclAppend(mpDocumentModelTree, "Master Slides"); + lclAppend(mpDocumentModelTree, "Slides", new SlidesEntry(mxDocument), true); + lclAppend(mpDocumentModelTree, "Master Slides", new MasterSlidesEntry(mxDocument), true); + lclAppend(mpDocumentModelTree, "Styles", new StylesFamiliesEntry(mxDocument), true); } else if (xDocumentServiceInfo->supportsService("com.sun.star.drawing.DrawingDocument")) { - lclAppend(mpDocumentModelTree, "Pages"); - lclAppend(mpDocumentModelTree, "Styles"); + lclAppend(mpDocumentModelTree, "Pages", new PagesEntry(mxDocument), true); + lclAppend(mpDocumentModelTree, "Styles", new StylesFamiliesEntry(mxDocument), true); } else if (xDocumentServiceInfo->supportsService("com.sun.star.text.TextDocument") || xDocumentServiceInfo->supportsService("com.sun.star.text.WebDocument")) { - lclAppend(mpDocumentModelTree, "Paragraphs"); - lclAppend(mpDocumentModelTree, "Shapes"); - lclAppend(mpDocumentModelTree, "Tables"); - lclAppend(mpDocumentModelTree, "Frames"); - lclAppend(mpDocumentModelTree, "Graphic Objects"); - lclAppend(mpDocumentModelTree, "Embedded Objects"); - lclAppend(mpDocumentModelTree, "Styles"); + lclAppend(mpDocumentModelTree, "Paragraphs", new ParagraphsEntry(mxDocument), true); + lclAppend(mpDocumentModelTree, "Shapes", new ShapesEntry(mxDocument), true); + lclAppend(mpDocumentModelTree, "Tables", new TablesEntry(mxDocument), true); + lclAppend(mpDocumentModelTree, "Frames", new FramesEntry(mxDocument), true); + lclAppend(mpDocumentModelTree, "Graphic Objects", new WriterGraphicObjectsEntry(mxDocument), + true); + lclAppend(mpDocumentModelTree, "Embedded Objects", new EmbeddedObjectsEntry(mxDocument), + true); + lclAppend(mpDocumentModelTree, "Styles", new StylesFamiliesEntry(mxDocument), true); } } |