diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 05:54:39 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 05:54:39 +0000 |
commit | 267c6f2ac71f92999e969232431ba04678e7437e (patch) | |
tree | 358c9467650e1d0a1d7227a21dac2e3d08b622b2 /sfx2/source/devtools/DocumentModelTreeHandler.cxx | |
parent | Initial commit. (diff) | |
download | libreoffice-267c6f2ac71f92999e969232431ba04678e7437e.tar.xz libreoffice-267c6f2ac71f92999e969232431ba04678e7437e.zip |
Adding upstream version 4:24.2.0.upstream/4%24.2.0
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'sfx2/source/devtools/DocumentModelTreeHandler.cxx')
-rw-r--r-- | sfx2/source/devtools/DocumentModelTreeHandler.cxx | 840 |
1 files changed, 840 insertions, 0 deletions
diff --git a/sfx2/source/devtools/DocumentModelTreeHandler.cxx b/sfx2/source/devtools/DocumentModelTreeHandler.cxx new file mode 100644 index 0000000000..bbcb17a3f7 --- /dev/null +++ b/sfx2/source/devtools/DocumentModelTreeHandler.cxx @@ -0,0 +1,840 @@ +/* -*- 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/DocumentModelTreeHandler.hxx> + +#include <sfx2/sfxresid.hxx> +#include "DevToolsStrings.hrc" + +#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/sheet/XSpreadsheetDocument.hpp> +#include <com/sun/star/sheet/XSpreadsheet.hpp> +#include <com/sun/star/sheet/XDataPilotTablesSupplier.hpp> +#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> +#include <com/sun/star/text/XTextGraphicObjectsSupplier.hpp> +#include <com/sun/star/text/XTextEmbeddedObjectsSupplier.hpp> +#include <com/sun/star/style/XStyleFamiliesSupplier.hpp> +#include <utility> + +using namespace css; + +namespace +{ +// returns a name of the object, if available +OUString lclGetNamed(uno::Reference<uno::XInterface> const& xObject) +{ + uno::Reference<container::XNamed> xNamed(xObject, uno::UNO_QUERY); + if (!xNamed.is()) + return OUString(); + return xNamed->getName(); +} + +/** DocumentModelTreeEntry is an object "attached" to a tree node. + * + * It 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 +{ +protected: + OUString maString; + css::uno::Reference<css::uno::XInterface> mxObject; + +public: + DocumentModelTreeEntry(OUString aString, css::uno::Reference<css::uno::XInterface> xObject) + : maString(std::move(aString)) + , mxObject(std::move(xObject)) + { + } + + virtual ~DocumentModelTreeEntry() {} + + /// the node string shown in the tree view + OUString& getString() { return maString; } + + /// should show the expander for the tree view node + virtual bool shouldShowExpander() { return false; } + + /// The main UNO object for this entry + virtual css::uno::Reference<css::uno::XInterface> getMainObject() { return mxObject; } + + /// Create and fill the children to the parent tree view node. + virtual void fill(std::unique_ptr<weld::TreeView>& /*pDocumentModelTree*/, + weld::TreeIter const& /*rParent*/) + { + } +}; + +// append an entry to a input TreeView to a parent +void lclAppendToParentEntry(const std::unique_ptr<weld::TreeView>& rTree, + weld::TreeIter const& rParent, DocumentModelTreeEntry* pEntry) +{ + OUString sId(weld::toId(pEntry)); + OUString const& rString = pEntry->getString(); + rTree->insert(&rParent, -1, &rString, &sId, nullptr, nullptr, pEntry->shouldShowExpander(), + nullptr); +} + +// append a root entry to a input TreeView +OUString lclAppend(const std::unique_ptr<weld::TreeView>& rTree, DocumentModelTreeEntry* pEntry) +{ + OUString sId(weld::toId(pEntry)); + OUString const& rString = pEntry->getString(); + rTree->insert(nullptr, -1, &rString, &sId, nullptr, nullptr, pEntry->shouldShowExpander(), + nullptr); + return sId; +} + +/** Entry that represents a object, which implements a XNameAccess */ +class NameAccessTreeEntry : public DocumentModelTreeEntry +{ +protected: + NameAccessTreeEntry(OUString const& rString, uno::Reference<uno::XInterface> const& xObject) + : DocumentModelTreeEntry(rString, xObject) + { + } + + bool shouldShowExpander() override + { + uno::Reference<container::XNameAccess> xNameAccess(getMainObject(), uno::UNO_QUERY); + return xNameAccess.is() && xNameAccess->getElementNames().getLength() > 0; + } + + /// A generic fill when the UNO object implements XNameAccess interface + void fill(std::unique_ptr<weld::TreeView>& pDocumentModelTree, + weld::TreeIter const& rParent) override + { + uno::Reference<container::XNameAccess> xNameAccess(getMainObject(), uno::UNO_QUERY); + xNameAccess.set(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>(rName, xObject); + lclAppendToParentEntry(pDocumentModelTree, rParent, pEntry.release()); + } + } +}; + +/** Entry that represents the document root object */ +class DocumentRootEntry : public DocumentModelTreeEntry +{ +public: + DocumentRootEntry(OUString const& rString, uno::Reference<uno::XInterface> const& xObject) + : DocumentModelTreeEntry(rString, xObject) + { + } + + bool shouldShowExpander() override { return false; } +}; + +/** Represents a paragraph object (XParagraph) */ +class ParagraphEntry : public DocumentModelTreeEntry +{ +public: + ParagraphEntry(OUString const& rString, + css::uno::Reference<css::uno::XInterface> const& xObject) + : DocumentModelTreeEntry(rString, xObject) + { + } + + bool shouldShowExpander() override + { + uno::Reference<container::XEnumerationAccess> xEnumAccess(getMainObject(), uno::UNO_QUERY); + if (!xEnumAccess.is()) + return false; + auto xTextPortions = xEnumAccess->createEnumeration(); + if (!xTextPortions.is()) + return false; + return xTextPortions->hasMoreElements(); + } + + 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> xTextPortions = xEnumAccess->createEnumeration(); + if (!xTextPortions.is()) + return; + + for (sal_Int32 i = 0; xTextPortions->hasMoreElements(); i++) + { + uno::Reference<text::XTextRange> const xTextPortion(xTextPortions->nextElement(), + uno::UNO_QUERY); + OUString aString = lclGetNamed(xTextPortion); + if (aString.isEmpty()) + { + OUString aNumber = OUString::number(i + 1); + aString = SfxResId(STR_TEXT_PORTION).replaceFirst("%1", aNumber); + } + + auto pEntry = std::make_unique<DocumentModelTreeEntry>(aString, xTextPortion); + lclAppendToParentEntry(pDocumentModelTree, rParent, pEntry.release()); + } + } +}; + +/** Represents a list of paragraphs */ +class ParagraphsEntry : public DocumentModelTreeEntry +{ +public: + ParagraphsEntry(OUString const& rString, + css::uno::Reference<css::uno::XInterface> const& xObject) + : DocumentModelTreeEntry(rString, xObject) + { + } + + 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(); + } + + bool shouldShowExpander() override + { + uno::Reference<container::XEnumerationAccess> xEnumAccess(getMainObject(), uno::UNO_QUERY); + if (!xEnumAccess.is()) + return false; + auto xParagraphEnum = xEnumAccess->createEnumeration(); + if (!xParagraphEnum.is()) + return false; + return xParagraphEnum->hasMoreElements(); + } + + 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()) + return; + + for (sal_Int32 i = 0; xParagraphEnum->hasMoreElements(); i++) + { + uno::Reference<text::XTextContent> const xParagraph(xParagraphEnum->nextElement(), + uno::UNO_QUERY); + OUString aString = lclGetNamed(xParagraph); + if (aString.isEmpty()) + { + aString = SfxResId(STR_PARAGRAPH).replaceFirst("%1", OUString::number(i + 1)); + } + + auto pEntry = std::make_unique<ParagraphEntry>(aString, xParagraph); + lclAppendToParentEntry(pDocumentModelTree, rParent, pEntry.release()); + } + } +}; + +/** Represents a list of shapes */ +class ShapesEntry : public DocumentModelTreeEntry +{ +public: + ShapesEntry(OUString const& rString, css::uno::Reference<css::uno::XInterface> const& xObject) + : DocumentModelTreeEntry(rString, xObject) + { + } + + css::uno::Reference<css::uno::XInterface> getMainObject() override + { + uno::Reference<drawing::XDrawPageSupplier> xSupplier(mxObject, uno::UNO_QUERY); + if (!xSupplier.is()) + return mxObject; + return xSupplier->getDrawPage(); + } + + bool shouldShowExpander() override + { + uno::Reference<container::XIndexAccess> xShapes(getMainObject(), uno::UNO_QUERY); + return xShapes.is() && xShapes->getCount() > 0; + } + + void fill(std::unique_ptr<weld::TreeView>& pDocumentModelTree, + weld::TreeIter const& rParent) override + { + uno::Reference<container::XIndexAccess> xShapes(getMainObject(), uno::UNO_QUERY); + if (!xShapes.is()) + return; + for (sal_Int32 nIndexShapes = 0; nIndexShapes < xShapes->getCount(); ++nIndexShapes) + { + uno::Reference<uno::XInterface> xShape(xShapes->getByIndex(nIndexShapes), + uno::UNO_QUERY); + OUString aShapeName = lclGetNamed(xShape); + if (aShapeName.isEmpty()) + { + aShapeName + = SfxResId(STR_SHAPE).replaceFirst("%1", OUString::number(nIndexShapes + 1)); + } + + auto pEntry = std::make_unique<DocumentModelTreeEntry>(aShapeName, xShape); + lclAppendToParentEntry(pDocumentModelTree, rParent, pEntry.release()); + } + } +}; + +/** Represents a list of tables */ +class TablesEntry : public NameAccessTreeEntry +{ +public: + TablesEntry(OUString const& rString, css::uno::Reference<css::uno::XInterface> const& xObject) + : NameAccessTreeEntry(rString, xObject) + { + } + + css::uno::Reference<css::uno::XInterface> getMainObject() override + { + uno::Reference<text::XTextTablesSupplier> xSupplier(mxObject, uno::UNO_QUERY); + if (!xSupplier.is()) + return mxObject; + return xSupplier->getTextTables(); + } +}; + +/** Represents a list of frames */ +class FramesEntry : public NameAccessTreeEntry +{ +public: + FramesEntry(OUString const& rString, css::uno::Reference<css::uno::XInterface> const& xObject) + : NameAccessTreeEntry(rString, xObject) + { + } + + css::uno::Reference<css::uno::XInterface> getMainObject() override + { + uno::Reference<text::XTextFramesSupplier> xSupplier(mxObject, uno::UNO_QUERY); + if (!xSupplier.is()) + return mxObject; + return xSupplier->getTextFrames(); + } +}; + +/** Represents a list of writer graphic objects */ +class WriterGraphicObjectsEntry : public NameAccessTreeEntry +{ +public: + WriterGraphicObjectsEntry(OUString const& rString, + css::uno::Reference<css::uno::XInterface> const& xObject) + : NameAccessTreeEntry(rString, xObject) + { + } + + css::uno::Reference<css::uno::XInterface> getMainObject() override + { + uno::Reference<text::XTextGraphicObjectsSupplier> xSupplier(mxObject, uno::UNO_QUERY); + if (!xSupplier.is()) + return mxObject; + return xSupplier->getGraphicObjects(); + } +}; + +/** Represents a list of writer embedded (OLE) objects */ +class EmbeddedObjectsEntry : public NameAccessTreeEntry +{ +public: + EmbeddedObjectsEntry(OUString const& rString, + css::uno::Reference<css::uno::XInterface> const& xObject) + : NameAccessTreeEntry(rString, xObject) + { + } + + css::uno::Reference<css::uno::XInterface> getMainObject() override + { + uno::Reference<text::XTextEmbeddedObjectsSupplier> xSupplier(mxObject, uno::UNO_QUERY); + if (!xSupplier.is()) + return mxObject; + return xSupplier->getEmbeddedObjects(); + } +}; + +/** Represents a style family, which contains a list of styles */ +class StylesFamilyEntry : public NameAccessTreeEntry +{ +public: + StylesFamilyEntry(OUString const& rString, + css::uno::Reference<css::uno::XInterface> const& xObject) + : NameAccessTreeEntry(rString, xObject) + { + } +}; + +/** Represents a list of style families */ +class StylesFamiliesEntry : public DocumentModelTreeEntry +{ +public: + StylesFamiliesEntry(OUString const& rString, + css::uno::Reference<css::uno::XInterface> const& xObject) + : DocumentModelTreeEntry(rString, xObject) + { + } + + 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(); + } + + bool shouldShowExpander() override + { + uno::Reference<container::XNameAccess> xStyleFamilies(getMainObject(), uno::UNO_QUERY); + return xStyleFamilies.is() && xStyleFamilies->getElementNames().getLength() > 0; + } + + 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<uno::XInterface> xStyleFamily(xStyleFamilies->getByName(rFamilyName), + uno::UNO_QUERY); + + auto pStylesFamilyEntry + = std::make_unique<StylesFamilyEntry>(rFamilyName, xStyleFamily); + lclAppendToParentEntry(pDocumentModelTree, rParent, pStylesFamilyEntry.release()); + } + } +}; + +/** Represents a list of pages */ +class PagesEntry : public DocumentModelTreeEntry +{ +public: + PagesEntry(OUString const& rString, css::uno::Reference<css::uno::XInterface> const& xObject) + : DocumentModelTreeEntry(rString, xObject) + { + } + + 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(); + } + + bool shouldShowExpander() override + { + uno::Reference<drawing::XDrawPages> xDrawPages(getMainObject(), uno::UNO_QUERY); + return xDrawPages.is() && xDrawPages->getCount() > 0; + } + + 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<drawing::XDrawPage> xPage(xDrawPages->getByIndex(i), uno::UNO_QUERY); + if (!xPage.is()) + continue; + + OUString aPageString = lclGetNamed(xPage); + if (aPageString.isEmpty()) + aPageString = SfxResId(STR_PAGE).replaceFirst("%1", OUString::number(i + 1)); + + auto pShapesEntry = std::make_unique<ShapesEntry>(aPageString, xPage); + lclAppendToParentEntry(pDocumentModelTree, rParent, pShapesEntry.release()); + } + } +}; + +/** Represents a list of (Impress) slides */ +class SlidesEntry : public DocumentModelTreeEntry +{ +public: + SlidesEntry(OUString const& rString, css::uno::Reference<css::uno::XInterface> const& xObject) + : DocumentModelTreeEntry(rString, xObject) + { + } + + 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(); + } + + bool shouldShowExpander() override + { + uno::Reference<drawing::XDrawPages> xDrawPages(getMainObject(), uno::UNO_QUERY); + return xDrawPages.is() && xDrawPages->getCount() > 0; + } + + 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<drawing::XDrawPage> xPage(xDrawPages->getByIndex(i), uno::UNO_QUERY); + if (!xPage.is()) + continue; + + OUString aPageString = lclGetNamed(xPage); + if (aPageString.isEmpty()) + aPageString = SfxResId(STR_SLIDE).replaceFirst("%1", OUString::number(i + 1)); + + auto pShapesEntry = std::make_unique<ShapesEntry>(aPageString, xPage); + lclAppendToParentEntry(pDocumentModelTree, rParent, pShapesEntry.release()); + } + } +}; + +/** Represents a list of (Impress) master slides */ +class MasterSlidesEntry : public DocumentModelTreeEntry +{ +public: + MasterSlidesEntry(OUString const& rString, + css::uno::Reference<css::uno::XInterface> const& xObject) + : DocumentModelTreeEntry(rString, xObject) + { + } + + 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(); + } + + bool shouldShowExpander() override + { + uno::Reference<drawing::XDrawPages> xDrawPages(getMainObject(), uno::UNO_QUERY); + return xDrawPages.is() && xDrawPages->getCount() > 0; + } + + 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<drawing::XDrawPage> xPage(xDrawPages->getByIndex(i), uno::UNO_QUERY); + if (!xPage.is()) + continue; + + OUString aPageString = lclGetNamed(xPage); + if (aPageString.isEmpty()) + { + aPageString + = SfxResId(STR_MASTER_SLIDE).replaceFirst("%1", OUString::number(i + 1)); + } + + auto pShapesEntry = std::make_unique<ShapesEntry>(aPageString, xPage); + lclAppendToParentEntry(pDocumentModelTree, rParent, pShapesEntry.release()); + } + } +}; + +/** Represents a list of charts */ +class ChartsEntry : public NameAccessTreeEntry +{ +public: + ChartsEntry(OUString const& rString, css::uno::Reference<css::uno::XInterface> const& xObject) + : NameAccessTreeEntry(rString, xObject) + { + } + + 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(); + } + + 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; + NameAccessTreeEntry::fill(pDocumentModelTree, rParent); + } +}; + +/** Represents a list of pivot tables */ +class PivotTablesEntry : public NameAccessTreeEntry +{ +public: + PivotTablesEntry(OUString const& rString, + css::uno::Reference<css::uno::XInterface> const& xObject) + : NameAccessTreeEntry(rString, xObject) + { + } + + bool shouldShowExpander() override { return true; } + + 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(); + } + + 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; + NameAccessTreeEntry::fill(pDocumentModelTree, rParent); + } +}; + +/** Represents a (Calc) sheet */ +class SheetEntry : public DocumentModelTreeEntry +{ +public: + SheetEntry(OUString const& rString, css::uno::Reference<css::uno::XInterface> const& xObject) + : DocumentModelTreeEntry(rString, xObject) + { + } + + bool shouldShowExpander() override { return true; } + + void fill(std::unique_ptr<weld::TreeView>& pDocumentModelTree, + weld::TreeIter const& rParent) override + { + auto pShapesEntry + = std::make_unique<ShapesEntry>(SfxResId(STR_SHAPES_ENTRY), getMainObject()); + lclAppendToParentEntry(pDocumentModelTree, rParent, pShapesEntry.release()); + + auto pChartsEntry + = std::make_unique<ChartsEntry>(SfxResId(STR_CHARTS_ENTRY), getMainObject()); + lclAppendToParentEntry(pDocumentModelTree, rParent, pChartsEntry.release()); + + auto pPivotTablesEntry + = std::make_unique<PivotTablesEntry>(SfxResId(STR_PIVOT_TABLES_ENTRY), getMainObject()); + lclAppendToParentEntry(pDocumentModelTree, rParent, pPivotTablesEntry.release()); + } +}; + +/** Represents a list of (Calc) sheet */ +class SheetsEntry : public DocumentModelTreeEntry +{ +public: + SheetsEntry(OUString const& rString, css::uno::Reference<css::uno::XInterface> const& xObject) + : DocumentModelTreeEntry(rString, xObject) + { + } + + 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(); + } + + bool shouldShowExpander() override + { + uno::Reference<container::XIndexAccess> xIndexAccess(getMainObject(), uno::UNO_QUERY); + return xIndexAccess.is() && xIndexAccess->getCount() > 0; + } + + void fill(std::unique_ptr<weld::TreeView>& pDocumentModelTree, + weld::TreeIter const& rParent) override + { + uno::Reference<container::XIndexAccess> xIndexAccesss(getMainObject(), uno::UNO_QUERY); + if (!xIndexAccesss.is()) + return; + + for (sal_Int32 i = 0; i < xIndexAccesss->getCount(); ++i) + { + uno::Reference<sheet::XSpreadsheet> xSheet(xIndexAccesss->getByIndex(i), + uno::UNO_QUERY); + OUString aString = lclGetNamed(xSheet); + if (aString.isEmpty()) + aString = SfxResId(STR_SHEET).replaceFirst("%1", OUString::number(i + 1)); + auto pEntry = std::make_unique<SheetEntry>(aString, xSheet); + lclAppendToParentEntry(pDocumentModelTree, rParent, pEntry.release()); + } + } +}; + +} // end anonymous namespace + +DocumentModelTreeHandler::DocumentModelTreeHandler( + std::unique_ptr<weld::TreeView>& pDocumentModelTree, + css::uno::Reference<css::uno::XInterface> xDocument) + : mpDocumentModelTree(pDocumentModelTree) + , mxDocument(std::move(xDocument)) +{ + mpDocumentModelTree->connect_expanding(LINK(this, DocumentModelTreeHandler, ExpandingHandler)); +} + +uno::Reference<uno::XInterface> DocumentModelTreeHandler::getObjectByID(OUString const& rID) +{ + uno::Reference<uno::XInterface> xObject; + if (rID.isEmpty()) + return xObject; + auto* pEntry = weld::fromId<DocumentModelTreeEntry*>(rID); + return pEntry->getMainObject(); +} + +void DocumentModelTreeHandler::clearAll() +{ + // destroy all DocumentModelTreeEntries from the tree + mpDocumentModelTree->all_foreach([this](weld::TreeIter& rEntry) { + OUString sID = mpDocumentModelTree->get_id(rEntry); + auto* pEntry = weld::fromId<DocumentModelTreeEntry*>(sID); + delete pEntry; + return false; + }); + mpDocumentModelTree->clear(); +} + +void DocumentModelTreeHandler::clearChildren(weld::TreeIter const& rParent) +{ + bool bChild = false; + do + { + 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 = weld::fromId<DocumentModelTreeEntry*>(sID); + delete pEntry; + mpDocumentModelTree->remove(*pChild); + } + } + } while (bChild); +} + +void DocumentModelTreeHandler::dispose() +{ + mpDocumentModelTree->all_foreach([this](weld::TreeIter& rEntry) { + OUString sID = mpDocumentModelTree->get_id(rEntry); + auto* pEntry = weld::fromId<DocumentModelTreeEntry*>(sID); + 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 = weld::fromId<DocumentModelTreeEntry*>(sID); + pEntry->fill(mpDocumentModelTree, rParent); + + return true; +} + +void DocumentModelTreeHandler::selectObject( + css::uno::Reference<css::uno::XInterface> const& xInterface) +{ + mpDocumentModelTree->unselect_all(); + + mpDocumentModelTree->all_foreach([this, xInterface](weld::TreeIter& rEntry) { + OUString sID = mpDocumentModelTree->get_id(rEntry); + auto* pEntry = weld::fromId<DocumentModelTreeEntry*>(sID); + if (xInterface == pEntry->getMainObject()) + { + mpDocumentModelTree->select(rEntry); + return true; + } + return false; + }); +} + +void DocumentModelTreeHandler::inspectDocument() +{ + clearAll(); + + uno::Reference<lang::XServiceInfo> xDocumentServiceInfo(mxDocument, uno::UNO_QUERY_THROW); + + lclAppend(mpDocumentModelTree, new DocumentRootEntry(SfxResId(STR_DOCUMENT_ENTRY), mxDocument)); + + if (xDocumentServiceInfo->supportsService("com.sun.star.sheet.SpreadsheetDocument")) + { + lclAppend(mpDocumentModelTree, new SheetsEntry(SfxResId(STR_SHEETS_ENTRY), mxDocument)); + lclAppend(mpDocumentModelTree, + new StylesFamiliesEntry(SfxResId(STR_STYLES_ENTRY), mxDocument)); + } + else if (xDocumentServiceInfo->supportsService( + "com.sun.star.presentation.PresentationDocument")) + { + lclAppend(mpDocumentModelTree, new SlidesEntry(SfxResId(STR_SLIDES_ENTRY), mxDocument)); + lclAppend(mpDocumentModelTree, + new MasterSlidesEntry(SfxResId(STR_MASTER_SLIDES_ENTRY), mxDocument)); + lclAppend(mpDocumentModelTree, + new StylesFamiliesEntry(SfxResId(STR_STYLES_ENTRY), mxDocument)); + } + else if (xDocumentServiceInfo->supportsService("com.sun.star.drawing.DrawingDocument")) + { + lclAppend(mpDocumentModelTree, new PagesEntry(SfxResId(STR_PAGES_ENTRY), mxDocument)); + lclAppend(mpDocumentModelTree, + new StylesFamiliesEntry(SfxResId(STR_STYLES_ENTRY), mxDocument)); + } + else if (xDocumentServiceInfo->supportsService("com.sun.star.text.TextDocument") + || xDocumentServiceInfo->supportsService("com.sun.star.text.WebDocument")) + { + lclAppend(mpDocumentModelTree, + new ParagraphsEntry(SfxResId(STR_PARAGRAPHS_ENTRY), mxDocument)); + lclAppend(mpDocumentModelTree, new ShapesEntry(SfxResId(STR_SHAPES_ENTRY), mxDocument)); + lclAppend(mpDocumentModelTree, new TablesEntry(SfxResId(STR_TABLES_ENTRY), mxDocument)); + lclAppend(mpDocumentModelTree, new FramesEntry(SfxResId(STR_FRAMES_ENTRY), mxDocument)); + lclAppend(mpDocumentModelTree, + new WriterGraphicObjectsEntry(SfxResId(STR_GRAPHIC_OBJECTS_ENTRY), mxDocument)); + lclAppend(mpDocumentModelTree, + new EmbeddedObjectsEntry(SfxResId(STR_EMBEDDED_OBJECTS_ENTRY), mxDocument)); + lclAppend(mpDocumentModelTree, + new StylesFamiliesEntry(SfxResId(STR_STYLES_ENTRY), mxDocument)); + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |