include/svx/xmlgrhlp.hxx                                    |   12 +
 include/vcl/gfxlink.hxx                                     |    2 
 include/vcl/graphicfilter.hxx                               |   15 +
 include/vcl/pdfread.hxx                                     |    5 
 include/xmloff/xmlimp.hxx                                   |    3 
 offapi/com/sun/star/document/XGraphicStorageHandler.idl     |    4 
 schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng |    9 +
 svx/source/xml/xmlgrhlp.cxx                                 |   49 ++++-
 sw/inc/docsh.hxx                                            |    6 
 sw/inc/rdfhelper.hxx                                        |   26 +--
 sw/source/core/doc/rdfhelper.cxx                            |  103 ++++--------
 sw/source/core/edit/edfcol.cxx                              |   97 +++++------
 sw/source/core/txtnode/thints.cxx                           |    3 
 sw/source/core/unocore/unoobj2.cxx                          |    7 
 sw/source/filter/ww8/docxattributeoutput.cxx                |    9 -
 sw/source/filter/ww8/docxexport.cxx                         |   28 +--
 sw/source/uibase/app/docsh.cxx                              |    6 
 sw/source/uibase/sidebar/WriterInspectorTextPanel.cxx       |    5 
 vcl/inc/impgraph.hxx                                        |    2 
 vcl/source/filter/graphicfilter.cxx                         |   20 +-
 vcl/source/filter/ipdf/pdfread.cxx                          |   11 -
 vcl/source/gdi/gfxlink.cxx                                  |    6 
 vcl/source/gdi/impgraph.cxx                                 |    2 
 xmloff/qa/unit/data/two-pages.pdf                           |binary
 xmloff/qa/unit/draw.cxx                                     |   45 +++++
 xmloff/source/core/xmlimp.cxx                               |    5 
 xmloff/source/draw/shapeexport.cxx                          |   17 +
 xmloff/source/draw/ximpshap.cxx                             |   14 +
 xmloff/source/draw/ximpshap.hxx                             |    1 
 29 files changed, 310 insertions(+), 202 deletions(-)

New commits:
commit f676426d3f543b022606657a34648594aae135cb
Author:     Caolán McNamara <caolan.mcnam...@collabora.com>
AuthorDate: Tue Jan 28 20:53:29 2025 +0000
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Wed Jan 29 14:36:18 2025 +0100

    xml::sax::XWriter is a xml::sax::XDocumentHandler
    
    Change-Id: I492bff5580b61c222a7e9b84d49ba70a5dc318b9
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/180865
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>

diff --git a/sw/source/filter/ww8/docxexport.cxx 
b/sw/source/filter/ww8/docxexport.cxx
index 570b1bb7e6c4..fe0b86381369 100644
--- a/sw/source/filter/ww8/docxexport.cxx
+++ b/sw/source/filter/ww8/docxexport.cxx
@@ -1545,8 +1545,7 @@ void DocxExport::WriteGlossary()
     uno::Reference< xml::sax::XSAXSerializable > serializer( glossaryDocDom, 
uno::UNO_QUERY );
     uno::Reference< xml::sax::XWriter > writer = xml::sax::Writer::create( 
comphelper::getProcessComponentContext() );
     writer->setOutputStream( xOutputStream );
-    serializer->serialize( uno::Reference< xml::sax::XDocumentHandler >( 
writer, uno::UNO_QUERY_THROW ),
-        uno::Sequence< beans::StringPair >() );
+    serializer->serialize(writer, uno::Sequence< beans::StringPair >());
 
     for (const uno::Sequence<beans::NamedValue>& glossaryElement : 
glossaryDomList)
     {
@@ -1587,8 +1586,7 @@ void DocxExport::WriteGlossary()
             continue; // External relation, no stream to write
         uno::Reference< xml::sax::XSAXSerializable > gserializer( xDom, 
uno::UNO_QUERY );
         writer->setOutputStream(GetFilter().openFragmentStream( 
"word/glossary/" + gTarget, contentType ) );
-        gserializer->serialize( uno::Reference< xml::sax::XDocumentHandler >( 
writer, uno::UNO_QUERY_THROW ),
-               uno::Sequence< beans::StringPair >() );
+        gserializer->serialize(writer, uno::Sequence< beans::StringPair >());
     }
 }
 
@@ -1710,8 +1708,7 @@ void DocxExport::WriteCustomXml()
 
                 writer->setOutputStream(xMemStream->getOutputStream());
 
-                serializer->serialize(uno::Reference< 
xml::sax::XDocumentHandler >(writer, uno::UNO_QUERY_THROW),
-                    uno::Sequence< beans::StringPair >());
+                serializer->serialize(writer, uno::Sequence< beans::StringPair 
>());
 
                 uno::Reference< io::XStream > xXSLTInStream = xMemStream;
                 uno::Reference< io::XStream > xXSLTOutStream;
@@ -1742,8 +1739,7 @@ void DocxExport::WriteCustomXml()
             {
                 writer->setOutputStream(xOutStream);
 
-                serializer->serialize(uno::Reference< 
xml::sax::XDocumentHandler >(writer, uno::UNO_QUERY_THROW),
-                    uno::Sequence< beans::StringPair >());
+                serializer->serialize(writer, uno::Sequence< beans::StringPair 
>());
             }
         }
 
@@ -1753,8 +1749,7 @@ void DocxExport::WriteCustomXml()
             uno::Reference< xml::sax::XWriter > writer = 
xml::sax::Writer::create( comphelper::getProcessComponentContext() );
             writer->setOutputStream( GetFilter().openFragmentStream( 
"customXml/itemProps"+OUString::number(j+1)+".xml",
                 
"application/vnd.openxmlformats-officedocument.customXmlProperties+xml" ) );
-            serializer->serialize( uno::Reference< xml::sax::XDocumentHandler 
>( writer, uno::UNO_QUERY_THROW ),
-                uno::Sequence< beans::StringPair >() );
+            serializer->serialize(writer, uno::Sequence< beans::StringPair 
>());
 
             // Adding itemprops's relationship entry to item.xml.rels file
             m_rFilter.addRelation( GetFilter().openFragmentStream( 
"customXml/item"+OUString::number(j+1)+".xml",
commit 5093e8c85411b7535576c9c4d018b4039db6995c
Author:     Caolán McNamara <caolan.mcnam...@collabora.com>
AuthorDate: Tue Jan 28 21:30:43 2025 +0000
Commit:     Mike Kaganski <mike.kagan...@collabora.com>
CommitDate: Wed Jan 29 11:54:18 2025 +0100

    use getFastAttributeTokens and getValueByIndex
    
    instead of getFastAttributes
    
    Change-Id: I011f0fd8bfd615ff9ee89dd7755c536740463f70
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/180867
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com>

diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx 
b/sw/source/filter/ww8/docxattributeoutput.cxx
index f4ced57b4ad5..f2b611b9e2a9 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -775,9 +775,12 @@ void SdtBlockHelper::WriteSdtBlock(const 
::sax_fastparser::FSHelperPtr& pSeriali
         }
 
         if (m_nSdtPrToken == FSNS(XML_w, XML_date) || m_nSdtPrToken == 
FSNS(XML_w, XML_docPartObj) || m_nSdtPrToken == FSNS(XML_w, XML_docPartList) || 
m_nSdtPrToken == FSNS(XML_w14, XML_checkbox)) {
-            const uno::Sequence<xml::FastAttribute> aChildren = 
m_pTokenChildren->getFastAttributes();
-            for (const auto& rChild : aChildren)
-                pSerializer->singleElement(rChild.Token, FSNS(XML_w, XML_val), 
rChild.Value);
+            const std::vector<sal_Int32>& rAttributeTokens = 
m_pTokenChildren->getFastAttributeTokens();
+            for (size_t i = 0, n = rAttributeTokens.size(); i < n; ++i)
+            {
+                pSerializer->singleElement(rAttributeTokens[i], FSNS(XML_w, 
XML_val),
+                                           
m_pTokenChildren->getValueByIndex(i));
+            }
         }
 
         pSerializer->endElement(m_nSdtPrToken);
commit 527983407624df16f9bec6499088e9b98396d0e4
Author:     Caolán McNamara <caolan.mcnam...@collabora.com>
AuthorDate: Tue Jan 28 17:00:19 2025 +0000
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Wed Jan 29 11:53:41 2025 +0100

    We already have a SwXTextDocument, don't need to cast
    
    to XDocumentMetadataAccess, it's already available
    
    also contains partial backport of:
    
    commit c69ad797408fd93afec2c5ac47ba94eba5e4c81c
    Author:     Noel Grandin <noel.gran...@collabora.co.uk>
    AuthorDate: Tue Sep 17 11:37:15 2024 +0200
    
        use more concrete UNO types in sw
    
    but with GetBaseModel override replaced with additional
    GetXTextDocument where needed for rdfhelper.
    
    Change-Id: I35965afafb4080a2315862739d602677b966245a
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/180855
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>

diff --git a/sw/inc/docsh.hxx b/sw/inc/docsh.hxx
index 3cbc43c98803..66bc38a56372 100644
--- a/sw/inc/docsh.hxx
+++ b/sw/inc/docsh.hxx
@@ -53,6 +53,7 @@ class SwDocShell;
 class SwDrawModel;
 class SwViewShell;
 class SwDocStyleSheetPool;
+class SwXTextDocument;
 namespace svt
 {
 class EmbeddedObjectRef;
@@ -120,6 +121,11 @@ class SW_DLLPUBLIC SwDocShell
     /// Make DocInfo known to the Doc.
     SAL_DLLPRIVATE virtual std::shared_ptr<SfxDocumentInfoDialog> 
CreateDocumentInfoDialog(weld::Window* pParent,
                                                                                
            const SfxItemSet &rSet) override;
+
+public:
+    rtl::Reference<SwXTextDocument> GetXTextDocument() const;
+private:
+
     /// OLE-stuff
     SAL_DLLPRIVATE virtual void Draw(OutputDevice*, const JobSetup&, 
sal_uInt16 nAspect, bool bOutputToWindow) override;
 
diff --git a/sw/inc/rdfhelper.hxx b/sw/inc/rdfhelper.hxx
index ee346c499fe2..dd7267758846 100644
--- a/sw/inc/rdfhelper.hxx
+++ b/sw/inc/rdfhelper.hxx
@@ -12,6 +12,7 @@
 
 #include <map>
 
+#include <rtl/ref.hxx>
 #include <rtl/ustring.hxx>
 
 #include "swdllapi.h"
@@ -20,7 +21,7 @@
 #include <com/sun/star/uno/Sequence.h>
 
 class SwTextNode;
-
+class SwXTextDocument;
 namespace com::sun::star {
     namespace frame {
         class XModel;
@@ -38,49 +39,42 @@ class SW_DLLPUBLIC SwRDFHelper
 public:
     /// Gets all graph-names in RDF of a given type.
     static css::uno::Sequence<css::uno::Reference<css::rdf::XURI>>
-    getGraphNames(const 
css::uno::Reference<css::rdf::XDocumentMetadataAccess>& xDocumentMetadataAccess,
+    getGraphNames(const rtl::Reference<SwXTextDocument>& xModel,
                   const css::uno::Reference<css::rdf::XURI>& xType);
 
     /// Gets all graph-names in RDF of a given type.
     static css::uno::Sequence<css::uno::Reference<css::rdf::XURI>>
-    getGraphNames(const css::uno::Reference<css::frame::XModel>& xModel, const 
OUString& rType);
+    getGraphNames(const rtl::Reference<SwXTextDocument>& xModel, const 
OUString& rType);
 
     /// Gets all (XResource, key, value) statements in RDF graphs given the 
graph-names.
     static std::map<OUString, OUString>
-    getStatements(const css::uno::Reference<css::frame::XModel>& xModel,
+    getStatements(const rtl::Reference<SwXTextDocument>& xModel,
                   const 
css::uno::Sequence<css::uno::Reference<css::rdf::XURI>>& rGraphNames,
                   const css::uno::Reference<css::rdf::XResource>& xSubject);
 
     /// Gets all (XResource, key, value) statements in RDF graphs of type 
rType.
     static std::map<OUString, OUString>
-    getStatements(const css::uno::Reference<css::frame::XModel>& xModel, const 
OUString& rType,
+    getStatements(const rtl::Reference<SwXTextDocument>& xModel, const 
OUString& rType,
                   const css::uno::Reference<css::rdf::XResource>& xSubject);
 
     /// Add an (XResource, key, value) statement in the graph of type rType -- 
or if it does not exist, create a graph at rPath first.
-    static void addStatement(const css::uno::Reference<css::frame::XModel>& 
xModel,
+    static void addStatement(const rtl::Reference<SwXTextDocument>& xModel,
                              const OUString& rType, const OUString& rPath,
                              const css::uno::Reference<css::rdf::XResource>& 
xSubject,
                              const OUString& rKey, const OUString& rValue);
 
     /// Check if a graph of type rType exists.
-    static bool hasMetadataGraph(const 
css::uno::Reference<css::frame::XModel>& xModel,
+    static bool hasMetadataGraph(const rtl::Reference<SwXTextDocument>& xModel,
                                  const OUString& rType);
 
     /// Remove an (XResource, key, value) statement in the graph of type 
rType, if it exists.
-    static void removeStatement(const css::uno::Reference<css::frame::XModel>& 
xModel,
+    static void removeStatement(const rtl::Reference<SwXTextDocument>& xModel,
                                 const OUString& rType,
                                 const 
css::uno::Reference<css::rdf::XResource>& xSubject,
                                 const OUString& rKey, const OUString& rValue);
 
-    /// Clone all statements in the graph of type rType, if any exists, from 
one subject to another.
-    static void cloneStatements(const css::uno::Reference<css::frame::XModel>& 
xSrcModel,
-                                const css::uno::Reference<css::frame::XModel>& 
xDstModel,
-                                const OUString& rType,
-                                const 
css::uno::Reference<css::rdf::XResource>& xSrcSubject,
-                                const 
css::uno::Reference<css::rdf::XResource>& xDstSubject);
-
     /// Remove all statements in the graph of type rType, if any exists.
-    static void clearStatements(const css::uno::Reference<css::frame::XModel>& 
xModel,
+    static void clearStatements(const rtl::Reference<SwXTextDocument>& xModel,
                                 const OUString& rType,
                                 const 
css::uno::Reference<css::rdf::XResource>& xSubject);
 
diff --git a/sw/source/core/doc/rdfhelper.cxx b/sw/source/core/doc/rdfhelper.cxx
index d4e5d9da2b52..12295177ebe6 100644
--- a/sw/source/core/doc/rdfhelper.cxx
+++ b/sw/source/core/doc/rdfhelper.cxx
@@ -22,16 +22,17 @@
 #include <ndtxt.hxx>
 #include <unoparagraph.hxx>
 #include <unotext.hxx>
+#include <unotxdoc.hxx>
 
 using namespace com::sun::star;
 
 css::uno::Sequence<css::uno::Reference<css::rdf::XURI>> 
SwRDFHelper::getGraphNames(
-    const css::uno::Reference<rdf::XDocumentMetadataAccess>& 
xDocumentMetadataAccess,
+    const rtl::Reference<SwXTextDocument>& xModel,
     const css::uno::Reference<rdf::XURI>& xType)
 {
     try
     {
-        return xDocumentMetadataAccess->getMetadataGraphsWithType(xType);
+        return xModel->getMetadataGraphsWithType(xType);
     }
     catch (const uno::RuntimeException&)
     {
@@ -40,7 +41,7 @@ css::uno::Sequence<css::uno::Reference<css::rdf::XURI>> 
SwRDFHelper::getGraphNam
 }
 
 css::uno::Sequence<uno::Reference<css::rdf::XURI>>
-SwRDFHelper::getGraphNames(const css::uno::Reference<css::frame::XModel>& 
xModel,
+SwRDFHelper::getGraphNames(const rtl::Reference<SwXTextDocument>& xModel,
                            const OUString& rType)
 {
     try
@@ -51,9 +52,7 @@ SwRDFHelper::getGraphNames(const 
css::uno::Reference<css::frame::XModel>& xModel
         // message: component context fails to supply service 
com.sun.star.rdf.URI of type com.sun.star.rdf.XURI
         // context: cppu::ComponentContext
         uno::Reference<rdf::XURI> xType = rdf::URI::create(xComponentContext, 
rType);
-        uno::Reference<rdf::XDocumentMetadataAccess> 
xDocumentMetadataAccess(xModel,
-                                                                             
uno::UNO_QUERY);
-        return getGraphNames(xDocumentMetadataAccess, xType);
+        return getGraphNames(xModel, xType);
     }
     catch (const ::css::uno::Exception&)
     {
@@ -62,7 +61,7 @@ SwRDFHelper::getGraphNames(const 
css::uno::Reference<css::frame::XModel>& xModel
 }
 
 std::map<OUString, OUString>
-SwRDFHelper::getStatements(const css::uno::Reference<css::frame::XModel>& 
xModel,
+SwRDFHelper::getStatements(const rtl::Reference<SwXTextDocument>& xModel,
                            const 
uno::Sequence<uno::Reference<css::rdf::XURI>>& rGraphNames,
                            const css::uno::Reference<css::rdf::XResource>& 
xSubject)
 {
@@ -70,8 +69,7 @@ SwRDFHelper::getStatements(const 
css::uno::Reference<css::frame::XModel>& xModel
     if (!rGraphNames.hasElements())
         return aRet;
 
-    uno::Reference<rdf::XDocumentMetadataAccess> 
xDocumentMetadataAccess(xModel, uno::UNO_QUERY);
-    const uno::Reference<rdf::XRepository>& xRepo = 
xDocumentMetadataAccess->getRDFRepository();
+    const uno::Reference<rdf::XRepository>& xRepo = xModel->getRDFRepository();
     for (const uno::Reference<rdf::XURI>& xGraphName : rGraphNames)
     {
         uno::Reference<rdf::XNamedGraph> xGraph = xRepo->getGraph(xGraphName);
@@ -91,76 +89,72 @@ SwRDFHelper::getStatements(const 
css::uno::Reference<css::frame::XModel>& xModel
 }
 
 std::map<OUString, OUString>
-SwRDFHelper::getStatements(const css::uno::Reference<css::frame::XModel>& 
xModel,
+SwRDFHelper::getStatements(const rtl::Reference<SwXTextDocument>& xModel,
                            const OUString& rType,
                            const css::uno::Reference<css::rdf::XResource>& 
xSubject)
 {
     return getStatements(xModel, getGraphNames(xModel, rType), xSubject);
 }
 
-void SwRDFHelper::addStatement(const css::uno::Reference<css::frame::XModel>& 
xModel,
+void SwRDFHelper::addStatement(const rtl::Reference<SwXTextDocument>& xModel,
                                const OUString& rType, const OUString& rPath,
                                const css::uno::Reference<css::rdf::XResource>& 
xSubject,
                                const OUString& rKey, const OUString& rValue)
 {
     uno::Reference<uno::XComponentContext> 
xComponentContext(comphelper::getProcessComponentContext());
     uno::Reference<rdf::XURI> xType = rdf::URI::create(xComponentContext, 
rType);
-    uno::Reference<rdf::XDocumentMetadataAccess> 
xDocumentMetadataAccess(xModel, uno::UNO_QUERY);
-    const uno::Sequence< uno::Reference<rdf::XURI> > aGraphNames = 
getGraphNames(xDocumentMetadataAccess, xType);
+    const uno::Sequence< uno::Reference<rdf::XURI> > aGraphNames = 
getGraphNames(xModel, xType);
     uno::Reference<rdf::XURI> xGraphName;
     if (aGraphNames.hasElements())
         xGraphName = aGraphNames[0];
     else
     {
         uno::Sequence< uno::Reference<rdf::XURI> > xTypes = { xType };
-        xGraphName = xDocumentMetadataAccess->addMetadataFile(rPath, xTypes);
+        xGraphName = xModel->addMetadataFile(rPath, xTypes);
     }
-    uno::Reference<rdf::XNamedGraph> xGraph = 
xDocumentMetadataAccess->getRDFRepository()->getGraph(xGraphName);
+    uno::Reference<rdf::XNamedGraph> xGraph = 
xModel->getRDFRepository()->getGraph(xGraphName);
     uno::Reference<rdf::XURI> xKey = rdf::URI::create(xComponentContext, rKey);
     uno::Reference<rdf::XLiteral> xValue = 
rdf::Literal::create(xComponentContext, rValue);
     xGraph->addStatement(xSubject, xKey, xValue);
 }
 
-bool SwRDFHelper::hasMetadataGraph(const 
css::uno::Reference<css::frame::XModel>& xModel, const OUString& rType)
+bool SwRDFHelper::hasMetadataGraph(const rtl::Reference<SwXTextDocument>& 
xModel, const OUString& rType)
 {
     uno::Reference<uno::XComponentContext> 
xComponentContext(comphelper::getProcessComponentContext());
     uno::Reference<rdf::XURI> xType = rdf::URI::create(xComponentContext, 
rType);
-    uno::Reference<rdf::XDocumentMetadataAccess> 
xDocumentMetadataAccess(xModel, uno::UNO_QUERY);
-    return getGraphNames(xDocumentMetadataAccess, xType).hasElements();
+    return getGraphNames(xModel, xType).hasElements();
 }
 
-void SwRDFHelper::removeStatement(const 
css::uno::Reference<css::frame::XModel>& xModel,
+void SwRDFHelper::removeStatement(const rtl::Reference<SwXTextDocument>& 
xModel,
                                   const OUString& rType,
                                   const 
css::uno::Reference<css::rdf::XResource>& xSubject,
                                   const OUString& rKey, const OUString& rValue)
 {
     uno::Reference<uno::XComponentContext> 
xComponentContext(comphelper::getProcessComponentContext());
     uno::Reference<rdf::XURI> xType = rdf::URI::create(xComponentContext, 
rType);
-    uno::Reference<rdf::XDocumentMetadataAccess> 
xDocumentMetadataAccess(xModel, uno::UNO_QUERY);
-    const uno::Sequence< uno::Reference<rdf::XURI> > aGraphNames = 
getGraphNames(xDocumentMetadataAccess, xType);
+    const uno::Sequence< uno::Reference<rdf::XURI> > aGraphNames = 
getGraphNames(xModel, xType);
     if (!aGraphNames.hasElements())
         return;
 
-    uno::Reference<rdf::XNamedGraph> xGraph = 
xDocumentMetadataAccess->getRDFRepository()->getGraph(aGraphNames[0]);
+    uno::Reference<rdf::XNamedGraph> xGraph = 
xModel->getRDFRepository()->getGraph(aGraphNames[0]);
     uno::Reference<rdf::XURI> xKey = rdf::URI::create(xComponentContext, rKey);
     uno::Reference<rdf::XLiteral> xValue = 
rdf::Literal::create(xComponentContext, rValue);
     xGraph->removeStatements(xSubject, xKey, xValue);
 }
 
-void SwRDFHelper::clearStatements(const 
css::uno::Reference<css::frame::XModel>& xModel,
+void SwRDFHelper::clearStatements(const rtl::Reference<SwXTextDocument>& 
xModel,
                                   const OUString& rType,
                                   const 
css::uno::Reference<css::rdf::XResource>& xSubject)
 {
     uno::Reference<uno::XComponentContext> 
xComponentContext(comphelper::getProcessComponentContext());
     uno::Reference<rdf::XURI> xType = rdf::URI::create(xComponentContext, 
rType);
-    uno::Reference<rdf::XDocumentMetadataAccess> 
xDocumentMetadataAccess(xModel, uno::UNO_QUERY);
-    const uno::Sequence< uno::Reference<rdf::XURI> > aGraphNames = 
getGraphNames(xDocumentMetadataAccess, xType);
+    const uno::Sequence< uno::Reference<rdf::XURI> > aGraphNames = 
getGraphNames(xModel, xType);
     if (!aGraphNames.hasElements())
         return;
 
     for (const uno::Reference<rdf::XURI>& xGraphName : aGraphNames)
     {
-        uno::Reference<rdf::XNamedGraph> xGraph = 
xDocumentMetadataAccess->getRDFRepository()->getGraph(xGraphName);
+        uno::Reference<rdf::XNamedGraph> xGraph = 
xModel->getRDFRepository()->getGraph(xGraphName);
         uno::Reference<container::XEnumeration> xStatements = 
xGraph->getStatements(xSubject, uno::Reference<rdf::XURI>(), 
uno::Reference<rdf::XURI>());
         while (xStatements->hasMoreElements())
         {
@@ -172,57 +166,35 @@ void SwRDFHelper::clearStatements(const 
css::uno::Reference<css::frame::XModel>&
     }
 }
 
-void SwRDFHelper::cloneStatements(const 
css::uno::Reference<css::frame::XModel>& xSrcModel,
-                                  const 
css::uno::Reference<css::frame::XModel>& xDstModel,
-                                  const OUString& rType,
-                                  const 
css::uno::Reference<css::rdf::XResource>& xSrcSubject,
-                                  const 
css::uno::Reference<css::rdf::XResource>& xDstSubject)
-{
-    uno::Reference<uno::XComponentContext> 
xComponentContext(comphelper::getProcessComponentContext());
-    uno::Reference<rdf::XURI> xType = rdf::URI::create(xComponentContext, 
rType);
-    uno::Reference<rdf::XDocumentMetadataAccess> 
xDocumentMetadataAccess(xSrcModel, uno::UNO_QUERY);
-    const uno::Sequence< uno::Reference<rdf::XURI> > aGraphNames = 
getGraphNames(xDocumentMetadataAccess, xType);
-    if (!aGraphNames.hasElements())
-        return;
-
-    for (const uno::Reference<rdf::XURI>& xGraphName : aGraphNames)
-    {
-        uno::Reference<rdf::XNamedGraph> xGraph = 
xDocumentMetadataAccess->getRDFRepository()->getGraph(xGraphName);
-        uno::Reference<container::XEnumeration> xStatements = 
xGraph->getStatements(xSrcSubject, uno::Reference<rdf::XURI>(), 
uno::Reference<rdf::XURI>());
-        while (xStatements->hasMoreElements())
-        {
-            const rdf::Statement aStatement = 
xStatements->nextElement().get<rdf::Statement>();
-
-            const OUString sKey = aStatement.Predicate->getStringValue();
-            const OUString sValue = aStatement.Object->getStringValue();
-            addStatement(xDstModel, rType, xGraphName->getLocalName(), 
xDstSubject, sKey, sValue);
-        }
-    }
-}
-
 std::map<OUString, OUString> SwRDFHelper::getTextNodeStatements(const 
OUString& rType, SwTextNode& rTextNode)
 {
     uno::Reference<rdf::XResource> 
xTextNode(SwXParagraph::CreateXParagraph(rTextNode.GetDoc(), &rTextNode, 
nullptr));
-    return getStatements(rTextNode.GetDoc().GetDocShell()->GetBaseModel(), 
rType, xTextNode);
+    SwDocShell* pShell = rTextNode.GetDoc().GetDocShell();
+    if (!pShell)
+        return std::map<OUString, OUString>();
+    return getStatements(pShell->GetXTextDocument(), rType, xTextNode);
 }
 
 void SwRDFHelper::addTextNodeStatement(const OUString& rType, const OUString& 
rPath, SwTextNode& rTextNode, const OUString& rKey, const OUString& rValue)
 {
     uno::Reference<rdf::XResource> 
xSubject(SwXParagraph::CreateXParagraph(rTextNode.GetDoc(), &rTextNode, 
nullptr));
-    addStatement(rTextNode.GetDoc().GetDocShell()->GetBaseModel(), rType, 
rPath, xSubject, rKey, rValue);
+    addStatement(rTextNode.GetDoc().GetDocShell()->GetXTextDocument(), rType, 
rPath, xSubject, rKey, rValue);
 }
 
 void SwRDFHelper::removeTextNodeStatement(const OUString& rType, SwTextNode& 
rTextNode, const OUString& rKey, const OUString& rValue)
 {
     uno::Reference<uno::XComponentContext> 
xComponentContext(comphelper::getProcessComponentContext());
     uno::Reference<rdf::XURI> xType = rdf::URI::create(xComponentContext, 
rType);
-    uno::Reference<rdf::XDocumentMetadataAccess> 
xDocumentMetadataAccess(rTextNode.GetDoc().GetDocShell()->GetBaseModel(), 
uno::UNO_QUERY);
-    const uno::Sequence< uno::Reference<rdf::XURI> > aGraphNames = 
getGraphNames(xDocumentMetadataAccess, xType);
+    SwDocShell* pShell = rTextNode.GetDoc().GetDocShell();
+    if (!pShell)
+        return;
+    rtl::Reference<SwXTextDocument> xModel(pShell->GetXTextDocument());
+    const uno::Sequence< uno::Reference<rdf::XURI> > aGraphNames = 
getGraphNames(xModel, xType);
     if (!aGraphNames.hasElements())
         return;
 
-    uno::Reference<rdf::XURI> xGraphName = aGraphNames[0];
-    uno::Reference<rdf::XNamedGraph> xGraph = 
xDocumentMetadataAccess->getRDFRepository()->getGraph(xGraphName);
+    const uno::Reference<rdf::XURI>& xGraphName = aGraphNames[0];
+    uno::Reference<rdf::XNamedGraph> xGraph = 
xModel->getRDFRepository()->getGraph(xGraphName);
     uno::Reference<rdf::XResource> 
xSubject(SwXParagraph::CreateXParagraph(rTextNode.GetDoc(), &rTextNode, 
nullptr));
     uno::Reference<rdf::XURI> xKey = rdf::URI::create(xComponentContext, rKey);
     uno::Reference<rdf::XLiteral> xValue = 
rdf::Literal::create(xComponentContext, rValue);
@@ -233,8 +205,11 @@ void SwRDFHelper::updateTextNodeStatement(const OUString& 
rType, const OUString&
 {
     uno::Reference<uno::XComponentContext> 
xComponentContext(comphelper::getProcessComponentContext());
     uno::Reference<rdf::XURI> xType = rdf::URI::create(xComponentContext, 
rType);
-    uno::Reference<rdf::XDocumentMetadataAccess> 
xDocumentMetadataAccess(rTextNode.GetDoc().GetDocShell()->GetBaseModel(), 
uno::UNO_QUERY);
-    const uno::Sequence< uno::Reference<rdf::XURI> > aGraphNames = 
getGraphNames(xDocumentMetadataAccess, xType);
+    SwDocShell* pShell = rTextNode.GetDoc().GetDocShell();
+    if (!pShell)
+        return;
+    rtl::Reference<SwXTextDocument> xModel(pShell->GetXTextDocument());
+    const uno::Sequence< uno::Reference<rdf::XURI> > aGraphNames = 
getGraphNames(xModel, xType);
     uno::Reference<rdf::XURI> xGraphName;
     if (aGraphNames.hasElements())
     {
@@ -243,10 +218,10 @@ void SwRDFHelper::updateTextNodeStatement(const OUString& 
rType, const OUString&
     else
     {
         uno::Sequence< uno::Reference<rdf::XURI> > xTypes = { xType };
-        xGraphName = xDocumentMetadataAccess->addMetadataFile(rPath, xTypes);
+        xGraphName = xModel->addMetadataFile(rPath, xTypes);
     }
 
-    uno::Reference<rdf::XNamedGraph> xGraph = 
xDocumentMetadataAccess->getRDFRepository()->getGraph(xGraphName);
+    uno::Reference<rdf::XNamedGraph> xGraph = 
xModel->getRDFRepository()->getGraph(xGraphName);
     uno::Reference<rdf::XResource> 
xSubject(SwXParagraph::CreateXParagraph(rTextNode.GetDoc(), &rTextNode, 
nullptr));
     uno::Reference<rdf::XURI> xKey = rdf::URI::create(xComponentContext, rKey);
 
diff --git a/sw/source/core/edit/edfcol.cxx b/sw/source/core/edit/edfcol.cxx
index d3d9d75063a4..5158c4425a4e 100644
--- a/sw/source/core/edit/edfcol.cxx
+++ b/sw/source/core/edit/edfcol.cxx
@@ -266,7 +266,7 @@ OString lcl_getParagraphBodyText(const 
uno::Reference<text::XTextContent>& xText
 }
 
 template <typename T>
-std::map<OUString, OUString> lcl_getRDFStatements(const 
uno::Reference<frame::XModel>& xModel,
+std::map<OUString, OUString> lcl_getRDFStatements(const 
rtl::Reference<SwXTextDocument>& xModel,
                                                   const T& xRef)
 {
     try
@@ -282,7 +282,7 @@ std::map<OUString, OUString> lcl_getRDFStatements(const 
uno::Reference<frame::XM
 }
 
 /// Returns RDF (key, value) pair associated with the field, if any.
-std::pair<OUString, OUString> lcl_getFieldRDFByPrefix(const 
uno::Reference<frame::XModel>& xModel,
+std::pair<OUString, OUString> lcl_getFieldRDFByPrefix(const 
rtl::Reference<SwXTextDocument>& xModel,
                                                       const 
uno::Reference<css::text::XTextField>& xField,
                                                       std::u16string_view 
sPrefix)
 {
@@ -297,7 +297,7 @@ std::pair<OUString, OUString> lcl_getFieldRDFByPrefix(const 
uno::Reference<frame
 
 /// Returns RDF (key, value) pair associated with the field, if any.
 template <typename T>
-std::pair<OUString, OUString> lcl_getRDF(const uno::Reference<frame::XModel>& 
xModel,
+std::pair<OUString, OUString> lcl_getRDF(const 
rtl::Reference<SwXTextDocument>& xModel,
                                          const T& xRef,
                                          const OUString& sRDFName)
 {
@@ -308,13 +308,13 @@ std::pair<OUString, OUString> lcl_getRDF(const 
uno::Reference<frame::XModel>& xM
 
 /// Returns true iff the field in question is paragraph signature.
 /// Note: must have associated RDF, since signatures are otherwise just 
metadata fields.
-bool lcl_IsParagraphSignatureField(const uno::Reference<frame::XModel>& xModel,
+bool lcl_IsParagraphSignatureField(const rtl::Reference<SwXTextDocument>& 
xModel,
                                    const 
uno::Reference<css::text::XTextField>& xField)
 {
     return (lcl_getRDF(xModel, xField, ParagraphSignatureIdRDFName).first == 
ParagraphSignatureIdRDFName);
 }
 
-uno::Reference<text::XTextField> lcl_findFieldByRDF(const 
uno::Reference<frame::XModel>& xModel,
+uno::Reference<text::XTextField> lcl_findFieldByRDF(const 
rtl::Reference<SwXTextDocument>& xModel,
                                                     const 
uno::Reference<text::XTextContent>& xParagraph,
                                                     const OUString& sRDFName,
                                                     std::u16string_view 
sRDFValue)
@@ -358,7 +358,7 @@ struct SignatureDescr
     bool isValid() const { return !msSignature.isEmpty(); }
 };
 
-SignatureDescr lcl_getSignatureDescr(const uno::Reference<frame::XModel>& 
xModel,
+SignatureDescr lcl_getSignatureDescr(const rtl::Reference<SwXTextDocument>& 
xModel,
                                      const 
uno::Reference<css::text::XTextContent>& xParagraph,
                                      std::u16string_view sFieldId)
 {
@@ -379,7 +379,7 @@ SignatureDescr lcl_getSignatureDescr(const 
uno::Reference<frame::XModel>& xModel
     return aDescr;
 }
 
-SignatureDescr lcl_getSignatureDescr(const uno::Reference<frame::XModel>& 
xModel,
+SignatureDescr lcl_getSignatureDescr(const rtl::Reference<SwXTextDocument>& 
xModel,
                                      const 
uno::Reference<css::text::XTextContent>& xParagraph,
                                      const 
uno::Reference<css::text::XTextField>& xField)
 {
@@ -424,7 +424,7 @@ std::pair<bool, OUString> 
lcl_MakeParagraphSignatureFieldText(const SignatureDes
 
 /// Validate and return validation result and signature field display text.
 std::pair<bool, OUString>
-lcl_MakeParagraphSignatureFieldText(const uno::Reference<frame::XModel>& 
xModel,
+lcl_MakeParagraphSignatureFieldText(const rtl::Reference<SwXTextDocument>& 
xModel,
                                     const 
uno::Reference<css::text::XTextContent>& xParagraph,
                                     const 
uno::Reference<css::text::XTextField>& xField,
                                     const OString& utf8Text)
@@ -434,7 +434,7 @@ lcl_MakeParagraphSignatureFieldText(const 
uno::Reference<frame::XModel>& xModel,
 }
 
 /// Generate the next valid ID for the new signature on this paragraph.
-OUString lcl_getNextSignatureId(const uno::Reference<frame::XModel>& xModel,
+OUString lcl_getNextSignatureId(const rtl::Reference<SwXTextDocument>& xModel,
                                 const uno::Reference<text::XTextContent>& 
xParagraph)
 {
     const OUString sFieldId = lcl_getRDF(xModel, xParagraph, 
ParagraphSignatureLastIdRDFName).second;
@@ -442,12 +442,12 @@ OUString lcl_getNextSignatureId(const 
uno::Reference<frame::XModel>& xModel,
 }
 
 /// Creates and inserts Paragraph Signature Metadata field and creates the RDF 
entry
-uno::Reference<text::XTextField> lcl_InsertParagraphSignature(const 
uno::Reference<frame::XModel>& xModel,
+uno::Reference<text::XTextField> lcl_InsertParagraphSignature(const 
rtl::Reference<SwXTextDocument>& xModel,
                                                               const 
uno::Reference<text::XTextContent>& xParagraph,
                                                               const OUString& 
signature,
                                                               const OUString& 
usage)
 {
-    uno::Reference<lang::XMultiServiceFactory> xMultiServiceFactory(xModel, 
uno::UNO_QUERY);
+    uno::Reference<lang::XMultiServiceFactory> xMultiServiceFactory(xModel);
     auto xField = 
uno::Reference<text::XTextField>(xMultiServiceFactory->createInstance(MetadataFieldServiceName),
 uno::UNO_QUERY);
 
     // Add the signature at the end.
@@ -516,7 +516,7 @@ bool lcl_DoUpdateParagraphSignatureField(SwDoc& rDoc,
 
 /// Updates the signature field text if changed and returns true only iff 
updated.
 bool lcl_UpdateParagraphSignatureField(SwDoc& rDoc,
-                                       const uno::Reference<frame::XModel>& 
xModel,
+                                       const rtl::Reference<SwXTextDocument>& 
xModel,
                                        const 
uno::Reference<css::text::XTextContent>& xParagraph,
                                        const 
uno::Reference<css::text::XTextField>& xField,
                                        const OString& utf8Text)
@@ -534,7 +534,7 @@ void lcl_RemoveParagraphMetadataField(const 
uno::Reference<css::text::XTextField
 
 /// Returns true iff the field in question is paragraph classification.
 /// Note: must have associated RDF, since classifications are otherwise just 
metadata fields.
-bool lcl_IsParagraphClassificationField(const uno::Reference<frame::XModel>& 
xModel,
+bool lcl_IsParagraphClassificationField(const rtl::Reference<SwXTextDocument>& 
xModel,
                                         const 
uno::Reference<css::text::XTextField>& xField,
                                         std::u16string_view sKey)
 {
@@ -542,7 +542,7 @@ bool lcl_IsParagraphClassificationField(const 
uno::Reference<frame::XModel>& xMo
     return rdfPair.first == ParagraphClassificationNameRDFName && 
(sKey.empty() || rdfPair.second == sKey);
 }
 
-uno::Reference<text::XTextField> lcl_FindParagraphClassificationField(const 
uno::Reference<frame::XModel>& xModel,
+uno::Reference<text::XTextField> lcl_FindParagraphClassificationField(const 
rtl::Reference<SwXTextDocument>& xModel,
                                                                       const 
rtl::Reference<SwXParagraph>& xParagraph,
                                                                       
std::u16string_view sKey = u"")
 {
@@ -578,10 +578,10 @@ uno::Reference<text::XTextField> 
lcl_FindParagraphClassificationField(const uno:
 }
 
 /// Creates and inserts Paragraph Classification Metadata field and creates 
the RDF entry
-uno::Reference<text::XTextField> lcl_InsertParagraphClassification(const 
uno::Reference<frame::XModel>& xModel,
+uno::Reference<text::XTextField> lcl_InsertParagraphClassification(const 
rtl::Reference<SwXTextDocument>& xModel,
                                                                    const 
uno::Reference<text::XTextContent>& xParent)
 {
-    uno::Reference<lang::XMultiServiceFactory> xMultiServiceFactory(xModel, 
uno::UNO_QUERY);
+    uno::Reference<lang::XMultiServiceFactory> xMultiServiceFactory(xModel);
     auto xField = 
uno::Reference<text::XTextField>(xMultiServiceFactory->createInstance(MetadataFieldServiceName),
 uno::UNO_QUERY);
 
     // Add the classification at the start.
@@ -591,7 +591,7 @@ uno::Reference<text::XTextField> 
lcl_InsertParagraphClassification(const uno::Re
 
 /// Updates the paragraph classification field text if changed and returns 
true only iff updated.
 bool lcl_UpdateParagraphClassificationField(SwDoc* pDoc,
-                                            const 
uno::Reference<frame::XModel>& xModel,
+                                            const 
rtl::Reference<SwXTextDocument>& xModel,
                                             const 
uno::Reference<css::text::XTextContent>& xTextNode,
                                             const OUString& sKey,
                                             const OUString& sValue,
@@ -623,7 +623,7 @@ void lcl_ValidateParagraphSignatures(SwDoc& rDoc, const 
uno::Reference<text::XTe
     if (!pDocShell)
         return;
 
-    uno::Reference<frame::XModel> xModel = pDocShell->GetBaseModel();
+    rtl::Reference<SwXTextDocument> xModel = pDocShell->GetXTextDocument();
 
     // Check if the paragraph is signed.
     try
@@ -1168,7 +1168,7 @@ void SwEditShell::SetClassification(const OUString& 
rName, SfxClassificationPoli
 // We pass xParent and xNodeSubject even though they point to the same thing 
because the UNO_QUERY is
 // on a performance-sensitive path.
 static void lcl_ApplyParagraphClassification(SwDoc* pDoc,
-                                      const uno::Reference<frame::XModel>& 
xModel,
+                                      const rtl::Reference<SwXTextDocument>& 
xModel,
                                       const rtl::Reference<SwXParagraph>& 
xParent,
                                       const 
css::uno::Reference<css::rdf::XResource>& xNodeSubject,
                                       std::vector<svx::ClassificationResult> 
aResults)
@@ -1285,12 +1285,12 @@ void 
SwEditShell::ApplyParagraphClassification(std::vector<svx::ClassificationRe
         SetParagraphSignatureValidation(bOldValidationFlag);
     });
 
-    uno::Reference<frame::XModel> xModel = pDocShell->GetBaseModel();
+    rtl::Reference<SwXTextDocument> xModel = pDocShell->GetXTextDocument();
     rtl::Reference<SwXParagraph> xParent = 
SwXParagraph::CreateXParagraph(pNode->GetDoc(), pNode, nullptr);
     lcl_ApplyParagraphClassification(GetDoc(), xModel, xParent, 
css::uno::Reference<css::rdf::XResource>(xParent), std::move(aResults));
 }
 
-static std::vector<svx::ClassificationResult> 
lcl_CollectParagraphClassification(const uno::Reference<frame::XModel>& xModel, 
const uno::Reference<text::XTextContent>& xParagraph)
+static std::vector<svx::ClassificationResult> 
lcl_CollectParagraphClassification(const rtl::Reference<SwXTextDocument>& 
xModel, const uno::Reference<text::XTextContent>& xParagraph)
 {
     std::vector<svx::ClassificationResult> aResult;
 
@@ -1361,7 +1361,7 @@ std::vector<svx::ClassificationResult> 
SwEditShell::CollectParagraphClassificati
         return aResult;
 
     rtl::Reference<SwXParagraph> xParent = 
SwXParagraph::CreateXParagraph(pNode->GetDoc(), pNode, nullptr);
-    uno::Reference<frame::XModel> xModel = pDocShell->GetBaseModel();
+    rtl::Reference<SwXTextDocument> xModel = pDocShell->GetXTextDocument();
     return lcl_CollectParagraphClassification(xModel, xParent);
 }
 
@@ -1688,18 +1688,21 @@ SwUndoParagraphSigning::SwUndoParagraphSigning(SwDoc& 
rDoc,
     m_bRemove(bRemove)
 {
     // Save the metadata and field content to undo/redo.
-    uno::Reference<frame::XModel> xModel = 
m_rDoc.GetDocShell()->GetBaseModel();
-    const std::map<OUString, OUString> aStatements = 
lcl_getRDFStatements(xModel, m_xField);
-    const auto it = aStatements.find(ParagraphSignatureIdRDFName);
-    if (it != aStatements.end())
-        m_signature = it->second;
-
-    const auto it2 = aStatements.find(ParagraphSignatureUsageRDFName);
-    if (it2 != aStatements.end())
-        m_usage = it2->second;
-
-    uno::Reference<css::text::XTextRange> xText(m_xField, uno::UNO_QUERY);
-    m_display = xText->getString();
+    if (SwDocShell* pShell = m_rDoc.GetDocShell())
+    {
+        rtl::Reference<SwXTextDocument> xModel = pShell->GetXTextDocument();
+        const std::map<OUString, OUString> aStatements = 
lcl_getRDFStatements(xModel, m_xField);
+        const auto it = aStatements.find(ParagraphSignatureIdRDFName);
+        if (it != aStatements.end())
+            m_signature = it->second;
+
+        const auto it2 = aStatements.find(ParagraphSignatureUsageRDFName);
+        if (it2 != aStatements.end())
+            m_usage = it2->second;
+
+        uno::Reference<css::text::XTextRange> xText(m_xField, uno::UNO_QUERY);
+        m_display = xText->getString();
+    }
 }
 
 void SwUndoParagraphSigning::UndoImpl(::sw::UndoRedoContext&)
@@ -1738,7 +1741,7 @@ void SwUndoParagraphSigning::Insert()
             m_rDoc.GetIDocumentUndoRedo().DoUndo(isUndoEnabled);
         });
 
-    m_xField = 
lcl_InsertParagraphSignature(m_rDoc.GetDocShell()->GetBaseModel(), m_xParent, 
m_signature, m_usage);
+    m_xField = 
lcl_InsertParagraphSignature(m_rDoc.GetDocShell()->GetXTextDocument(), 
m_xParent, m_signature, m_usage);
     lcl_DoUpdateParagraphSignatureField(m_rDoc, m_xField, m_display);
 }
 
@@ -1825,7 +1828,7 @@ void SwEditShell::SignParagraph()
 
     rDoc.GetIDocumentUndoRedo().StartUndo(SwUndoId::PARA_SIGN_ADD, nullptr);
 
-    const uno::Reference<frame::XModel> xModel = pDocShell->GetBaseModel();
+    const rtl::Reference<SwXTextDocument> xModel = 
pDocShell->GetXTextDocument();
     uno::Reference<css::text::XTextField> xField = 
lcl_InsertParagraphSignature(xModel, xParagraph, signature, aUsage);
 
     lcl_UpdateParagraphSignatureField(*GetDoc(), xModel, xParagraph, xField, 
utf8Text);
@@ -1855,7 +1858,7 @@ void SwEditShell::ValidateParagraphSignatures(SwTextNode* 
pNode, bool updateDont
     if (!pDocShell)
         return;
 
-    uno::Sequence<uno::Reference<css::rdf::XURI>> aGraphNames = 
SwRDFHelper::getGraphNames(pDocShell->GetBaseModel(), MetaNS);
+    uno::Sequence<uno::Reference<css::rdf::XURI>> aGraphNames = 
SwRDFHelper::getGraphNames(pDocShell->GetXTextDocument(), MetaNS);
     rtl::Reference<SwXParagraph> xParentText = 
SwXParagraph::CreateXParagraph(*GetDoc(), pNode, nullptr);
     lcl_ValidateParagraphSignatures(*GetDoc(), xParentText, updateDontRemove, 
aGraphNames);
 }
@@ -1893,7 +1896,7 @@ void SwEditShell::ValidateAllParagraphSignatures(bool 
updateDontRemove)
     uno::Reference<container::XEnumeration> xParagraphs = 
xParagraphEnumerationAccess->createEnumeration();
     if (!xParagraphs.is())
         return;
-    uno::Sequence<uno::Reference<css::rdf::XURI>> aGraphNames = 
SwRDFHelper::getGraphNames(pDocShell->GetBaseModel(), MetaNS);
+    uno::Sequence<uno::Reference<css::rdf::XURI>> aGraphNames = 
SwRDFHelper::getGraphNames(pDocShell->GetXTextDocument(), MetaNS);
     while (xParagraphs->hasMoreElements())
     {
         uno::Reference<text::XTextContent> 
xParagraph(xParagraphs->nextElement(), uno::UNO_QUERY);
@@ -1914,7 +1917,7 @@ static uno::Reference<text::XTextField> 
lcl_GetParagraphMetadataFieldAtIndex(con
             if (::sw::Meta* pMeta = rFormatMeta.GetMeta())
             {
                 const css::uno::Reference<css::rdf::XResource> xSubject = 
pMeta->MakeUnoObject();
-                uno::Reference<frame::XModel> xModel = pDocSh->GetBaseModel();
+                rtl::Reference<SwXTextDocument> xModel = 
pDocSh->GetXTextDocument();
                 const std::map<OUString, OUString> aStatements = 
lcl_getRDFStatements(xModel, xSubject);
                 if (aStatements.find(ParagraphSignatureIdRDFName) != 
aStatements.end() ||
                     aStatements.find(ParagraphClassificationNameRDFName) != 
aStatements.end())
@@ -1940,9 +1943,8 @@ void 
SwEditShell::RestoreMetadataFieldsAndValidateParagraphSignatures()
             SetParagraphSignatureValidation(bOldValidationFlag);
         });
 
-    uno::Reference<frame::XModel> xModel = pDocShell->GetBaseModel();
-    const rtl::Reference<SwXTextDocument> 
xDoc(dynamic_cast<SwXTextDocument*>(xModel.get()));
-    rtl::Reference<SwXBodyText> xBodyText = xDoc->getBodyText();
+    rtl::Reference<SwXTextDocument> xModel = pDocShell->GetXTextDocument();
+    rtl::Reference<SwXBodyText> xBodyText = xModel->getBodyText();
     if (!xBodyText.is())
         return;
     rtl::Reference<SwXParagraphEnumeration> xParagraphs = 
xBodyText->createParagraphEnumeration();
@@ -2042,7 +2044,7 @@ void 
SwEditShell::RestoreMetadataFieldsAndValidateParagraphSignatures()
                 uno::Reference<text::XTextField> xField = 
lcl_findFieldByRDF(xModel, xParagraph, ParagraphSignatureIdRDFName, pair.first);
                 if (!xField.is())
                 {
-                    uno::Reference<lang::XMultiServiceFactory> 
xMultiServiceFactory(xModel, uno::UNO_QUERY);
+                    uno::Reference<lang::XMultiServiceFactory> 
xMultiServiceFactory(xModel);
                     xField = 
uno::Reference<text::XTextField>(xMultiServiceFactory->createInstance(MetadataFieldServiceName),
 uno::UNO_QUERY);
 
                     // Add the signature at the end.
@@ -2104,7 +2106,7 @@ bool SwEditShell::RemoveParagraphMetadataFieldAtCursor()
 }
 
 static OUString lcl_GetParagraphClassification(SfxClassificationHelper & 
rHelper, sfx::ClassificationKeyCreator const & rKeyCreator,
-                                        const uno::Reference<frame::XModel>& 
xModel, const rtl::Reference<SwXParagraph>& xParagraph)
+                                        const rtl::Reference<SwXTextDocument>& 
xModel, const rtl::Reference<SwXParagraph>& xParagraph)
 {
     uno::Reference<text::XTextField> xTextField;
     xTextField = lcl_FindParagraphClassificationField(xModel, xParagraph, 
rKeyCreator.makeCategoryIdentifierKey());
@@ -2138,9 +2140,8 @@ static OUString 
lcl_GetHighestClassificationParagraphClass(SwPaM* pCursor)
     SfxClassificationHelper aHelper(pDocShell->getDocProperties());
     sfx::ClassificationKeyCreator 
aKeyCreator(SfxClassificationHelper::getPolicyType());
 
-    uno::Reference<frame::XModel> xModel = pDocShell->GetBaseModel();
-    const rtl::Reference<SwXTextDocument> 
xDoc(dynamic_cast<SwXTextDocument*>(xModel.get()));
-    rtl::Reference<SwXBodyText> xBodyText = xDoc->getBodyText();
+    rtl::Reference<SwXTextDocument> xModel = pDocShell->GetXTextDocument();
+    rtl::Reference<SwXBodyText> xBodyText = xModel->getBodyText();
 
     rtl::Reference<SwXParagraphEnumeration> xParagraphs = 
xBodyText->createParagraphEnumeration();
     while (xParagraphs->hasMoreElements())
@@ -2161,7 +2162,7 @@ void SwEditShell::ClassifyDocPerHighestParagraphClass()
         return;
 
     // Bail out as early as possible if we don't have paragraph classification.
-    if (!SwRDFHelper::hasMetadataGraph(pDocShell->GetBaseModel(), MetaNS))
+    if (!SwRDFHelper::hasMetadataGraph(pDocShell->GetXTextDocument(), MetaNS))
         return;
 
     uno::Reference<document::XDocumentProperties> xDocumentProperties = 
pDocShell->getDocProperties();
diff --git a/sw/source/core/txtnode/thints.cxx 
b/sw/source/core/txtnode/thints.cxx
index 942cb0080abd..f7d8949fceac 100644
--- a/sw/source/core/txtnode/thints.cxx
+++ b/sw/source/core/txtnode/thints.cxx
@@ -82,6 +82,7 @@
 
 #include <rdfhelper.hxx>
 #include <hints.hxx>
+#include <unotxdoc.hxx>
 
 #ifdef DBG_UTIL
 #define CHECK           Check(true);
@@ -1287,7 +1288,7 @@ void SwTextNode::DestroyAttr( SwTextAttr* pAttr )
             {
                 static constexpr OUStringLiteral metaNS(u"urn:bails");
                 const css::uno::Reference<css::rdf::XResource> xSubject = 
pMeta->MakeUnoObject();
-                uno::Reference<frame::XModel> xModel = pDocSh->GetBaseModel();
+                rtl::Reference<SwXTextDocument> xModel = 
pDocSh->GetXTextDocument();
                 SwRDFHelper::clearStatements(xModel, metaNS, xSubject);
             }
         }
diff --git a/sw/source/filter/ww8/docxexport.cxx 
b/sw/source/filter/ww8/docxexport.cxx
index f8ed32ae415c..570b1bb7e6c4 100644
--- a/sw/source/filter/ww8/docxexport.cxx
+++ b/sw/source/filter/ww8/docxexport.cxx
@@ -100,6 +100,7 @@
 #include <sal/log.hxx>
 #include <unotools/ucbstreamhelper.hxx>
 #include <comphelper/diagnose_ex.hxx>
+#include <unotxdoc.hxx>
 
 using namespace sax_fastparser;
 using namespace ::comphelper;
@@ -1227,7 +1228,7 @@ void DocxExport::WriteSettings()
         m_pAttrOutput->WriteFootnoteEndnotePr( pFS, XML_endnotePr, 
m_rDoc.GetEndNoteInfo(), XML_endnote );
 
     // Has themeFontLang information
-    uno::Reference< beans::XPropertySet > xPropSet( pDocShell->GetBaseModel(), 
uno::UNO_QUERY_THROW );
+    rtl::Reference< SwXTextDocument > xPropSet( pDocShell->GetXTextDocument() 
);
 
     bool bUseGrabBagProtection = false;
     bool bWriterWantsToProtect = false;
@@ -1501,7 +1502,7 @@ void DocxExport::WriteTheme()
 // See OOXMLDocumentImpl::resolveGlossaryStream
 void DocxExport::WriteGlossary()
 {
-    uno::Reference< beans::XPropertySet > xPropSet( 
m_rDoc.GetDocShell()->GetBaseModel(), uno::UNO_QUERY_THROW );
+    rtl::Reference< SwXTextDocument > xPropSet( 
m_rDoc.GetDocShell()->GetXTextDocument() );
 
     uno::Reference< beans::XPropertySetInfo > xPropSetInfo = 
xPropSet->getPropertySetInfo();
     OUString aName = UNO_NAME_MISC_OBJ_INTEROPGRABBAG;
@@ -1664,7 +1665,7 @@ static void lcl_UpdateXmlValues(const SdtData& sdtData, 
const uno::Reference<css
 
 void DocxExport::WriteCustomXml()
 {
-    uno::Reference< beans::XPropertySet > xPropSet( 
m_rDoc.GetDocShell()->GetBaseModel(), uno::UNO_QUERY_THROW );
+    rtl::Reference< SwXTextDocument > xPropSet( 
m_rDoc.GetDocShell()->GetXTextDocument() );
 
     uno::Reference< beans::XPropertySetInfo > xPropSetInfo = 
xPropSet->getPropertySetInfo();
     if ( !xPropSetInfo->hasPropertyByName( UNO_NAME_MISC_OBJ_INTEROPGRABBAG ) )
@@ -1766,7 +1767,7 @@ void DocxExport::WriteCustomXml()
 
 void DocxExport::WriteVBA()
 {
-    uno::Reference<document::XStorageBasedDocument> 
xStorageBasedDocument(m_rDoc.GetDocShell()->GetBaseModel(), uno::UNO_QUERY);
+    rtl::Reference<SwXTextDocument> 
xStorageBasedDocument(m_rDoc.GetDocShell()->GetXTextDocument());
     if (!xStorageBasedDocument.is())
         return;
 
@@ -1825,7 +1826,7 @@ void DocxExport::WriteVBA()
 
 void DocxExport::WriteEmbeddings()
 {
-    uno::Reference< beans::XPropertySet > xPropSet( 
m_rDoc.GetDocShell()->GetBaseModel(), uno::UNO_QUERY_THROW );
+    rtl::Reference< SwXTextDocument > xPropSet( 
m_rDoc.GetDocShell()->GetXTextDocument() );
 
     uno::Reference< beans::XPropertySetInfo > xPropSetInfo = 
xPropSet->getPropertySetInfo();
     OUString aName = UNO_NAME_MISC_OBJ_INTEROPGRABBAG;
@@ -2075,7 +2076,7 @@ sal_Int32 DocxExport::WriteOutliner(const 
OutlinerParaObject& rParaObj, sal_uInt
 sal_Int32 DocxExport::getWordCompatibilityModeFromGrabBag() const
 {
     sal_Int32 nWordCompatibilityMode = -1;
-    uno::Reference< beans::XPropertySet > 
xPropSet(m_rDoc.GetDocShell()->GetBaseModel(), uno::UNO_QUERY_THROW);
+    rtl::Reference< SwXTextDocument > 
xPropSet(m_rDoc.GetDocShell()->GetXTextDocument());
     uno::Reference< beans::XPropertySetInfo > xPropSetInfo = 
xPropSet->getPropertySetInfo();
     if (xPropSetInfo->hasPropertyByName(UNO_NAME_MISC_OBJ_INTEROPGRABBAG))
     {
diff --git a/sw/source/uibase/app/docsh.cxx b/sw/source/uibase/app/docsh.cxx
index 1cddf3070bfe..e74ecfa34974 100644
--- a/sw/source/uibase/app/docsh.cxx
+++ b/sw/source/uibase/app/docsh.cxx
@@ -103,6 +103,7 @@
 #include <iodetect.hxx>
 
 #include <comphelper/processfactory.hxx>
+#include <unotxdoc.hxx>
 
 using namespace ::com::sun::star;
 using namespace ::com::sun::star::uno;
@@ -887,6 +888,11 @@ void SwDocShell::Draw( OutputDevice* pDev, const JobSetup& 
rSetup,
         EnableSetModified();
 }
 
+rtl::Reference<SwXTextDocument> SwDocShell::GetXTextDocument() const
+{
+    return dynamic_cast<SwXTextDocument*>(GetBaseModel().get());
+}
+
 void SwDocShell::SetVisArea( const tools::Rectangle &rRect )
 {
     tools::Rectangle aRect( rRect );
diff --git a/sw/source/uibase/sidebar/WriterInspectorTextPanel.cxx 
b/sw/source/uibase/sidebar/WriterInspectorTextPanel.cxx
index c6376910f1a5..09c1f5ae0994 100644
--- a/sw/source/uibase/sidebar/WriterInspectorTextPanel.cxx
+++ b/sw/source/uibase/sidebar/WriterInspectorTextPanel.cxx
@@ -46,6 +46,7 @@
 #include <inspectorproperties.hrc>
 #include <strings.hrc>
 #include <rdfhelper.hxx>
+#include <unotxdoc.hxx>
 
 namespace sw::sidebar
 {
@@ -439,8 +440,8 @@ static void MetadataToTreeNode(const 
css::uno::Reference<css::uno::XInterface>&
                                                                              
uno::UNO_QUERY);
         const uno::Reference<rdf::XRepository>& xRepo = 
xDocumentMetadataAccess->getRDFRepository();
         const css::uno::Reference<css::rdf::XResource> xSubject(rSource, 
uno::UNO_QUERY);
-        std::map<OUString, OUString> xStatements
-            = SwRDFHelper::getStatements(pDocSh->GetBaseModel(), 
xRepo->getGraphNames(), xSubject);
+        std::map<OUString, OUString> xStatements = SwRDFHelper::getStatements(
+            pDocSh->GetXTextDocument(), xRepo->getGraphNames(), xSubject);
         for (const auto& pair : xStatements)
             aCurNode.children.push_back(SimplePropToTreeNode(pair.first, 
uno::Any(pair.second)));
     }
commit 4925d959785830edced1376f9a7c561d9eaadb60
Author:     Caolán McNamara <caolan.mcnam...@collabora.com>
AuthorDate: Tue Jan 28 19:56:25 2025 +0000
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Wed Jan 29 10:55:54 2025 +0100

    SwXTextDocument::getBodyText can be used instead of getText here
    
    and that's already a rtl::Reference to SwXBodyText which is
    derived from SwXText
    
    Change-Id: I071c0711fef911deec4258ef9e6719b721a39de2
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/180864
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>

diff --git a/sw/source/core/unocore/unoobj2.cxx 
b/sw/source/core/unocore/unoobj2.cxx
index 5cb73bf7b8f0..9420380fbbe2 100644
--- a/sw/source/core/unocore/unoobj2.cxx
+++ b/sw/source/core/unocore/unoobj2.cxx
@@ -74,6 +74,7 @@
 #include <frameformats.hxx>
 #include <algorithm>
 #include <iterator>
+#include <unotxdoc.hxx>
 
 using namespace ::com::sun::star;
 
@@ -1344,10 +1345,8 @@ CreateParentXText(SwDoc & rDoc, const SwPosition& rPos)
             if (SwDocShell *const pDocSh = rDoc.GetDocShell())
             {
                 // then it is the body text
-                const uno::Reference<frame::XModel> xModel = 
pDocSh->GetBaseModel();
-                const uno::Reference< text::XTextDocument > xDoc(
-                    xModel, uno::UNO_QUERY);
-                xParentText = dynamic_cast<SwXText*>(xDoc->getText().get());
+                const rtl::Reference<SwXTextDocument> xModel = 
pDocSh->GetXTextDocument();
+                xParentText = xModel->getBodyText();
             }
         }
     }
commit d197333db0fbf6647dce19e20bee265885224a74
Author:     Jaume Pujantell <jaume.pujant...@collabora.com>
AuthorDate: Tue Jan 28 10:13:11 2025 +0100
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Wed Jan 29 09:10:11 2025 +0100

    [API CHANGE] sd pdfium: add page number when saving/loading pdf pages as 
images
    
    When a pdf file is opened with pdfium and then saved as odg, each page
    is saved as a draw:image of the pdf. But since no page number info was
    given, when opening the odg file, all the pages are shown as the first
    one.
    
    This adds a loext:page-number to the saved odg and the logic to load a
    specific page from an embedded pdf.
    
    Added loadGraphicAtPage to XGraphicStorageHandler.
    
    Change-Id: I398b7ad7f03cc7fb930a4e7b7620c6f238b41c0d
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/180815
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>

diff --git a/include/svx/xmlgrhlp.hxx b/include/svx/xmlgrhlp.hxx
index 177d1afc4be6..6e84eb340e56 100644
--- a/include/svx/xmlgrhlp.hxx
+++ b/include/svx/xmlgrhlp.hxx
@@ -56,7 +56,8 @@ private:
     std::vector< css::uno::Reference< css::io::XOutputStream > >
                                 maGrfStms;
 
-    std::unordered_map<OUString, css::uno::Reference<css::graphic::XGraphic>> 
maGraphicObjects;
+    std::unordered_map<OUString, 
std::vector<css::uno::Reference<css::graphic::XGraphic>>>
+        maGraphicObjects;
     std::unordered_map<Graphic, std::pair<OUString, OUString>> 
maExportGraphics;
 
     SvXMLGraphicHelperMode      meCreateMode;
@@ -71,8 +72,9 @@ private:
                                             ImplGetGraphicStream( const 
OUString& rPictureStorageName,
                                                       const OUString& 
rPictureStreamName );
     SVX_DLLPRIVATE static OUString      ImplGetGraphicMimeType( 
std::u16string_view rFileName );
-    SVX_DLLPRIVATE Graphic                  ImplReadGraphic( const OUString& 
rPictureStorageName,
-                                                 const OUString& 
rPictureStreamName );
+    SVX_DLLPRIVATE Graphic ImplReadGraphic(const OUString& rPictureStorageName,
+                                           const OUString& rPictureStreamName,
+                                           sal_Int32 nPage = -1);
 
                                 SvXMLGraphicHelper();
                                 virtual ~SvXMLGraphicHelper() override;
@@ -101,6 +103,10 @@ public:
     virtual css::uno::Reference<css::graphic::XGraphic> SAL_CALL
         loadGraphic(OUString const & aURL) override;
 
+    // XGraphicStorageHandler
+    virtual css::uno::Reference<css::graphic::XGraphic>
+        SAL_CALL loadGraphicAtPage(OUString const& aURL, sal_Int32 nPage) 
override;
+
     virtual css::uno::Reference<css::graphic::XGraphic> SAL_CALL
         
loadGraphicFromOutputStream(css::uno::Reference<css::io::XOutputStream> const & 
rxOutputStream) override;
 
diff --git a/include/vcl/gfxlink.hxx b/include/vcl/gfxlink.hxx
index 531633b3f738..1f0e0cf99f53 100644
--- a/include/vcl/gfxlink.hxx
+++ b/include/vcl/gfxlink.hxx
@@ -103,7 +103,7 @@ public:
 
     bool                IsNative() const;
 
-    bool                LoadNative( Graphic& rGraphic ) const;
+    bool LoadNative(Graphic& rGraphic, sal_Int32 nPageNum = -1) const;
 
     bool                ExportNative( SvStream& rOStream ) const;
 
diff --git a/include/vcl/graphicfilter.hxx b/include/vcl/graphicfilter.hxx
index fd6c205bd491..2279feb9c499 100644
--- a/include/vcl/graphicfilter.hxx
+++ b/include/vcl/graphicfilter.hxx
@@ -275,10 +275,11 @@ public:
                                       sal_uInt16 nFormat,
                                       sal_uInt16 * pDeterminedFormat);
 
-    ErrCode             ImportGraphic( Graphic& rGraphic, std::u16string_view 
rPath,
-                                   SvStream& rStream,
-                                   sal_uInt16 nFormat = 
GRFILTER_FORMAT_DONTKNOW,
-                                   sal_uInt16 * pDeterminedFormat = nullptr, 
GraphicFilterImportFlags nImportFlags = GraphicFilterImportFlags::NONE );
+    ErrCode ImportGraphic(Graphic& rGraphic, std::u16string_view rPath, 
SvStream& rStream,
+                          sal_uInt16 nFormat = GRFILTER_FORMAT_DONTKNOW,
+                          sal_uInt16* pDeterminedFormat = nullptr,
+                          GraphicFilterImportFlags nImportFlags = 
GraphicFilterImportFlags::NONE,
+                          sal_Int32 nPageNum = -1);
 
     /// Imports multiple graphics.
     ///
@@ -292,7 +293,8 @@ public:
     void MakeGraphicsAvailableThreaded(std::vector< Graphic* >& rGraphics);
 
     // Setting sizeLimit limits how much will be read from the stream.
-    Graphic ImportUnloadedGraphic(SvStream& rIStream, sal_uInt64 sizeLimit = 
0, const Size* pSizeHint = nullptr);
+    Graphic ImportUnloadedGraphic(SvStream& rIStream, sal_uInt64 sizeLimit = 0,
+                                  const Size* pSizeHint = nullptr, sal_Int32 
nPage = -1);
 
     const ErrCode&          GetLastError() const { return *mxErrorEx;}
     void                    ResetLastError();
@@ -320,7 +322,8 @@ public:
     static ErrCode readWMF(SvStream & rStream, Graphic & rGraphic, GfxLinkType 
& rLinkType);
     static ErrCode readEMF(SvStream & rStream, Graphic & rGraphic, GfxLinkType 
& rLinkType);
 
-    static ErrCode readPDF(SvStream & rStream, Graphic & rGraphic, GfxLinkType 
& rLinkType);
+    static ErrCode readPDF(SvStream& rStream, Graphic& rGraphic, GfxLinkType& 
rLinkType,
+                           sal_Int32 nPageIndex = -1);
     static ErrCode readTIFF(SvStream & rStream, Graphic & rGraphic, 
GfxLinkType & rLinkType);
     static ErrCode readWithTypeSerializer(SvStream & rStream, Graphic & 
rGraphic, GfxLinkType & rLinkType, std::u16string_view aFilterName);
     static ErrCode readBMP(SvStream & rStream, Graphic & rGraphic, GfxLinkType 
& rLinkType);
diff --git a/include/vcl/pdfread.hxx b/include/vcl/pdfread.hxx
index 72508a548293..4a78aa68b156 100644
--- a/include/vcl/pdfread.hxx
+++ b/include/vcl/pdfread.hxx
@@ -37,10 +37,11 @@ VCL_DLLPUBLIC size_t RenderPDFBitmaps(const void* pBuffer, 
int nSize,
 /// Imports a PDF stream as a VectorGraphicData.
 VCL_DLLPUBLIC bool
 importPdfVectorGraphicData(SvStream& rStream,
-                           std::shared_ptr<VectorGraphicData>& 
rVectorGraphicData);
+                           std::shared_ptr<VectorGraphicData>& 
rVectorGraphicData,
+                           sal_Int32 nPageIndex = -1);
 
 /// Imports a PDF stream into rGraphic.
-VCL_DLLPUBLIC bool ImportPDF(SvStream& rStream, Graphic& rGraphic);
+VCL_DLLPUBLIC bool ImportPDF(SvStream& rStream, Graphic& rGraphic, sal_Int32 
nPageIndex = -1);
 
 // When inserting a PDF file as an image or pasting PDF data from the 
clipboard, at least on a
 // Retina iMac, the resulting rendered image does not look sharp without this 
surprisingly large
diff --git a/include/xmloff/xmlimp.hxx b/include/xmloff/xmlimp.hxx
index b4616056c4ec..8df68e378629 100644
--- a/include/xmloff/xmlimp.hxx
+++ b/include/xmloff/xmlimp.hxx
@@ -410,7 +410,8 @@ public:
         mxNumberFormatsSupplier = _xNumberFormatSupplier;
     }
 
-    css::uno::Reference<css::graphic::XGraphic> loadGraphicByURL(OUString 
const & rURL);
+    css::uno::Reference<css::graphic::XGraphic> loadGraphicByURL(OUString 
const& rURL,
+                                                                 sal_Int32 
nPageNum = -1);
     css::uno::Reference<css::graphic::XGraphic> 
loadGraphicFromBase64(css::uno::Reference<css::io::XOutputStream> const & 
rxOutputStream);
 
     css::uno::Reference< css::io::XOutputStream > 
GetStreamForGraphicObjectURLFromBase64() const;
diff --git a/offapi/com/sun/star/document/XGraphicStorageHandler.idl 
b/offapi/com/sun/star/document/XGraphicStorageHandler.idl
index b36379890243..7390b189394f 100644
--- a/offapi/com/sun/star/document/XGraphicStorageHandler.idl
+++ b/offapi/com/sun/star/document/XGraphicStorageHandler.idl
@@ -21,6 +21,10 @@ interface XGraphicStorageHandler : 
com::sun::star::uno::XInterface
     */
     com::sun::star::graphic::XGraphic loadGraphic([in] string aURL);
 
+    /** load a specific page from a graphic defined by the URL from the storage
+    */
+    com::sun::star::graphic::XGraphic loadGraphicAtPage([in] string aURL, [in] 
long nPage);
+
     /** load a graphic from the output stream
     */
     com::sun::star::graphic::XGraphic loadGraphicFromOutputStream([in] 
com::sun::star::io::XOutputStream xOutputStream);
diff --git a/schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng 
b/schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng
index a68033d1954e..551a5ee46735 100644
--- a/schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng
+++ b/schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng
@@ -3896,4 +3896,13 @@ 
xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.
       </rng:attribute>
     </rng:optional>
   </rng:define>
+
+  <!-- TODO no proposal for page number on multipage formats -->
+  <rng:define name="draw-image-attlist" combine="interleave">
+    <rng:optional>
+      <rng:attribute name="loext:page-number">
+        <rng:ref name="integer"/>
+      </rng:attribute>
+      </rng:optional>
+  </rng:define>
 </rng:grammar>
diff --git a/svx/source/xml/xmlgrhlp.cxx b/svx/source/xml/xmlgrhlp.cxx
index 03e42c961b13..cccee7ce99f2 100644
--- a/svx/source/xml/xmlgrhlp.cxx
+++ b/svx/source/xml/xmlgrhlp.cxx
@@ -491,8 +491,8 @@ OUString SvXMLGraphicHelper::ImplGetGraphicMimeType( 
std::u16string_view rFileNa
     return OUString();
 }
 
-Graphic SvXMLGraphicHelper::ImplReadGraphic( const OUString& 
rPictureStorageName,
-                                             const OUString& 
rPictureStreamName )
+Graphic SvXMLGraphicHelper::ImplReadGraphic(const OUString& 
rPictureStorageName,
+                                            const OUString& 
rPictureStreamName, sal_Int32 nPage)
 {
     Graphic aReturnGraphic;
     SvxGraphicHelperStream_Impl aStream( ImplGetGraphicStream( 
rPictureStorageName, rPictureStreamName ) );
@@ -500,11 +500,12 @@ Graphic SvXMLGraphicHelper::ImplReadGraphic( const 
OUString& rPictureStorageName
     {
         GraphicFilter& rGraphicFilter = GraphicFilter::GetGraphicFilter();
         std::unique_ptr<SvStream> 
pStream(utl::UcbStreamHelper::CreateStream(aStream.xStream));
-        Graphic aGraphic = rGraphicFilter.ImportUnloadedGraphic(*pStream);
+        Graphic aGraphic = rGraphicFilter.ImportUnloadedGraphic(*pStream, 0, 
nullptr, nPage);
         if (!aGraphic.IsNone())
             aReturnGraphic = aGraphic;
         else
-            rGraphicFilter.ImportGraphic(aReturnGraphic, u"", *pStream);
+            rGraphicFilter.ImportGraphic(aReturnGraphic, u"", *pStream, 
GRFILTER_FORMAT_DONTKNOW,
+                                         nullptr, 
GraphicFilterImportFlags::NONE, nPage);
     }
 
     return aReturnGraphic;
@@ -566,6 +567,13 @@ OUString SAL_CALL 
SvXMLGraphicHelper::resolveGraphicObjectURL( const OUString& /
 
 // XGraphicStorageHandler
 uno::Reference<graphic::XGraphic> SAL_CALL 
SvXMLGraphicHelper::loadGraphic(OUString const & rURL)
+{
+    return loadGraphicAtPage(rURL, -1);
+}
+
+// XGraphicStorageHandler
+uno::Reference<graphic::XGraphic>
+    SAL_CALL SvXMLGraphicHelper::loadGraphicAtPage(OUString const& rURL, 
sal_Int32 nPage)
 {
     std::unique_lock aGuard(m_aMutex);
 
@@ -575,22 +583,36 @@ uno::Reference<graphic::XGraphic> SAL_CALL 
SvXMLGraphicHelper::loadGraphic(OUStr
     OUString aUserData;
     splitUserDataFromURL(rURL, aURLOnly, aUserData);
 
+    size_t nIndex = (nPage >= 0 ? nPage : 0);
     auto aIterator = maGraphicObjects.find(aURLOnly);
-    if (aIterator != maGraphicObjects.end())
+    if (aIterator != maGraphicObjects.end() && aIterator->second.size() > 
nIndex
+        && aIterator->second[nIndex].is())
     {
-        return aIterator->second;
+        return aIterator->second[nIndex];
     }
 
     OUString aPictureStorageName, aPictureStreamName;
 
     if (ImplGetStreamNames(aURLOnly, aPictureStorageName, aPictureStreamName))
     {
-        const GraphicObject 
aGraphicObject(ImplReadGraphic(aPictureStorageName, aPictureStreamName));
+        const GraphicObject aGraphicObject(
+            ImplReadGraphic(aPictureStorageName, aPictureStreamName, nPage));
 
         if (aGraphicObject.GetType() != GraphicType::NONE)
         {
             xGraphic = aGraphicObject.GetGraphic().GetXGraphic();
-            maGraphicObjects[aURLOnly] = xGraphic;
+            if (aIterator != maGraphicObjects.end())
+            {
+                if (aIterator->second.size() <= nIndex)
+                    aIterator->second.resize(nIndex + 1);
+                aIterator->second[nIndex] = xGraphic;
+            }
+            else
+            {
+                maGraphicObjects.emplace(
+                    aURLOnly, 
std::vector<uno::Reference<graphic::XGraphic>>(nIndex + 1));
+                maGraphicObjects[aURLOnly][nIndex] = xGraphic;
+            }
         }
     }
 
@@ -958,6 +980,10 @@ protected:
     virtual css::uno::Reference<css::graphic::XGraphic> SAL_CALL
         loadGraphic(const OUString& aURL) override;
 
+    // ____ XGraphicStorageHandler ____
+    virtual css::uno::Reference<css::graphic::XGraphic>
+        SAL_CALL loadGraphicAtPage(const OUString& aURL, sal_Int32 nPage) 
override;
+
     virtual css::uno::Reference<css::graphic::XGraphic> SAL_CALL
         
loadGraphicFromOutputStream(css::uno::Reference<css::io::XOutputStream> const & 
rxOutputStream) override;
 
@@ -1021,6 +1047,13 @@ uno::Reference<graphic::XGraphic> SAL_CALL 
SvXMLGraphicImportExportHelper::loadG
     return m_xXMLGraphicHelper->loadGraphic(rURL);
 }
 
+// ____ XGraphicStorageHandler ____
+uno::Reference<graphic::XGraphic> SAL_CALL
+SvXMLGraphicImportExportHelper::loadGraphicAtPage(OUString const& rURL, 
sal_Int32 nPage)
+{
+    return m_xXMLGraphicHelper->loadGraphicAtPage(rURL, nPage);
+}
+
 uno::Reference<graphic::XGraphic> SAL_CALL 
SvXMLGraphicImportExportHelper::loadGraphicFromOutputStream(uno::Reference<io::XOutputStream>
 const & rxOutputStream)
 {
     return m_xXMLGraphicHelper->loadGraphicFromOutputStream(rxOutputStream);
diff --git a/vcl/inc/impgraph.hxx b/vcl/inc/impgraph.hxx
index 2e2b00640a20..9d6acd77e680 100644
--- a/vcl/inc/impgraph.hxx
+++ b/vcl/inc/impgraph.hxx
@@ -39,7 +39,7 @@ struct ImpSwapInfo
     bool mbIsAlpha;
 
     sal_uInt32 mnAnimationLoopCount;
-    sal_Int32 mnPageIndex;
+    sal_Int32 mnPageIndex = -1;
 };
 
 class OutputDevice;
diff --git a/vcl/source/filter/graphicfilter.cxx 
b/vcl/source/filter/graphicfilter.cxx
index a7e0ffe972a4..0939702c57f0 100644
--- a/vcl/source/filter/graphicfilter.cxx
+++ b/vcl/source/filter/graphicfilter.cxx
@@ -718,7 +718,7 @@ void 
GraphicFilter::MakeGraphicsAvailableThreaded(std::vector<Graphic*>& graphic
 }
 
 Graphic GraphicFilter::ImportUnloadedGraphic(SvStream& rIStream, sal_uInt64 
sizeLimit,
-                                             const Size* pSizeHint)
+                                             const Size* pSizeHint, sal_Int32 
nPage)
 {
     Graphic aGraphic;
     sal_uInt16 nFormat = GRFILTER_FORMAT_DONTKNOW;
@@ -907,7 +907,10 @@ Graphic GraphicFilter::ImportUnloadedGraphic(SvStream& 
rIStream, sal_uInt64 size
                     pSizeHint = &aLogicSize;
                 }
             }
-            aGraphic.SetGfxLink(std::make_shared<GfxLink>(aGraphicContent, 
eLinkType));
+            if (eLinkType == GfxLinkType::NativePdf && nPage >= 0)
+                aGraphic = Graphic(std::make_shared<GfxLink>(aGraphicContent, 
eLinkType), nPage);
+            else
+                aGraphic.SetGfxLink(std::make_shared<GfxLink>(aGraphicContent, 
eLinkType));
             aGraphic.ImplGetImpGraphic()->setPrepared(bAnimated, pSizeHint);
         }
     }
@@ -1115,9 +1118,10 @@ ErrCode GraphicFilter::readEMF(SvStream & rStream, 
Graphic & rGraphic, GfxLinkTy
     return readWMF_EMF(rStream, rGraphic, rLinkType, 
VectorGraphicDataType::Emf);
 }
 
-ErrCode GraphicFilter::readPDF(SvStream & rStream, Graphic & rGraphic, 
GfxLinkType & rLinkType)
+ErrCode GraphicFilter::readPDF(SvStream& rStream, Graphic& rGraphic, 
GfxLinkType& rLinkType,
+                               sal_Int32 nPageIndex)
 {
-    if (vcl::ImportPDF(rStream, rGraphic))
+    if (vcl::ImportPDF(rStream, rGraphic, nPageIndex))
     {
         rLinkType = GfxLinkType::NativePdf;
         return ERRCODE_NONE;
@@ -1274,8 +1278,10 @@ ErrCode GraphicFilter::readWEBP(SvStream & rStream, 
Graphic & rGraphic, GfxLinkT
         return ERRCODE_GRFILTER_FILTERERROR;
 }
 
-ErrCode GraphicFilter::ImportGraphic(Graphic& rGraphic, std::u16string_view 
rPath, SvStream& rIStream,
-                                     sal_uInt16 nFormat, sal_uInt16* 
pDeterminedFormat, GraphicFilterImportFlags nImportFlags)
+ErrCode GraphicFilter::ImportGraphic(Graphic& rGraphic, std::u16string_view 
rPath,
+                                     SvStream& rIStream, sal_uInt16 nFormat,
+                                     sal_uInt16* pDeterminedFormat,
+                                     GraphicFilterImportFlags nImportFlags, 
sal_Int32 nPageIndex)
 {
     OUString aFilterName;
     sal_uInt64 nStreamBegin;
@@ -1375,7 +1381,7 @@ ErrCode GraphicFilter::ImportGraphic(Graphic& rGraphic, 
std::u16string_view rPat
         }
         else if (aFilterName.equalsIgnoreAsciiCase(IMP_PDF))
         {
-            nStatus = readPDF(rIStream, rGraphic, eLinkType);
+            nStatus = readPDF(rIStream, rGraphic, eLinkType, nPageIndex);
         }
         else if (aFilterName.equalsIgnoreAsciiCase(IMP_TIFF) )
         {
diff --git a/vcl/source/filter/ipdf/pdfread.cxx 
b/vcl/source/filter/ipdf/pdfread.cxx
index 148a46f5da11..a5f939c7be50 100644
--- a/vcl/source/filter/ipdf/pdfread.cxx
+++ b/vcl/source/filter/ipdf/pdfread.cxx
@@ -102,7 +102,8 @@ size_t RenderPDFBitmaps(const void* pBuffer, int nSize, 
std::vector<BitmapEx>& r
 }
 
 bool importPdfVectorGraphicData(SvStream& rStream,
-                                std::shared_ptr<VectorGraphicData>& 
rVectorGraphicData)
+                                std::shared_ptr<VectorGraphicData>& 
rVectorGraphicData,
+                                sal_Int32 nPageIndex)
 {
     BinaryDataContainer aDataContainer = 
vcl::pdf::createBinaryDataContainer(rStream);
     if (aDataContainer.isEmpty())
@@ -111,16 +112,16 @@ bool importPdfVectorGraphicData(SvStream& rStream,
         return false;
     }
 
-    rVectorGraphicData
-        = std::make_shared<VectorGraphicData>(aDataContainer, 
VectorGraphicDataType::Pdf);
+    rVectorGraphicData = std::make_shared<VectorGraphicData>(
+        aDataContainer, VectorGraphicDataType::Pdf, nPageIndex);
 
     return true;
 }
 
-bool ImportPDF(SvStream& rStream, Graphic& rGraphic)
+bool ImportPDF(SvStream& rStream, Graphic& rGraphic, sal_Int32 nPageIndex)
 {
     std::shared_ptr<VectorGraphicData> pVectorGraphicData;
-    if (!importPdfVectorGraphicData(rStream, pVectorGraphicData))
+    if (!importPdfVectorGraphicData(rStream, pVectorGraphicData, nPageIndex))
         return false;
     rGraphic = Graphic(pVectorGraphicData);
     return true;
diff --git a/vcl/source/gdi/gfxlink.cxx b/vcl/source/gdi/gfxlink.cxx
index c6ca4678b007..aff0e9778980 100644
--- a/vcl/source/gdi/gfxlink.cxx
+++ b/vcl/source/gdi/gfxlink.cxx
@@ -101,7 +101,7 @@ void GfxLink::SetPrefMapMode( const MapMode& rPrefMapMode )
     mbPrefMapModeValid = true;
 }
 
-bool GfxLink::LoadNative( Graphic& rGraphic ) const
+bool GfxLink::LoadNative(Graphic& rGraphic, sal_Int32 nPageNum) const
 {
     bool bRet = false;
 
@@ -132,7 +132,9 @@ bool GfxLink::LoadNative( Graphic& rGraphic ) const
             {
                 GraphicFilter& rFilter = GraphicFilter::GetGraphicFilter();
                 sal_uInt16 nFormat = 
rFilter.GetImportFormatNumberForShortName(aShortName);
-                ErrCode nResult = rFilter.ImportGraphic(rGraphic, u"", 
aMemoryStream, nFormat);
+                ErrCode nResult
+                    = rFilter.ImportGraphic(rGraphic, u"", aMemoryStream, 
nFormat, nullptr,
+                                            GraphicFilterImportFlags::NONE, 
nPageNum);
                 if (nResult == ERRCODE_NONE)
                     bRet = true;
             }
diff --git a/vcl/source/gdi/impgraph.cxx b/vcl/source/gdi/impgraph.cxx
index ac36d2c72be4..6c5f8f870154 100644
--- a/vcl/source/gdi/impgraph.cxx
+++ b/vcl/source/gdi/impgraph.cxx
@@ -1502,7 +1502,7 @@ bool ImpGraphic::swapIn()
     if (mbPrepared)
     {
         Graphic aGraphic;
-        if (!mpGfxLink->LoadNative(aGraphic))
+        if (!mpGfxLink->LoadNative(aGraphic, getPageNumber()))
             return false;
 
         updateFromLoadedGraphic(aGraphic.ImplGetImpGraphic());
diff --git a/xmloff/qa/unit/data/two-pages.pdf 
b/xmloff/qa/unit/data/two-pages.pdf
new file mode 100644
index 000000000000..838c2d3232b1
Binary files /dev/null and b/xmloff/qa/unit/data/two-pages.pdf differ
diff --git a/xmloff/qa/unit/draw.cxx b/xmloff/qa/unit/draw.cxx
index 8d89065d4438..525c703c5eaa 100644
--- a/xmloff/qa/unit/draw.cxx
+++ b/xmloff/qa/unit/draw.cxx
@@ -31,6 +31,7 @@
 #include <docmodel/uno/UnoComplexColor.hxx>
 #include <docmodel/uno/UnoTheme.hxx>
 #include <docmodel/theme/Theme.hxx>
+#include <comphelper/scopeguard.hxx>
 
 using namespace ::com::sun::star;
 
@@ -810,6 +811,50 @@ CPPUNIT_TEST_FIXTURE(XmloffDrawTest, 
testTdf157018_ThemeImportDraw)
     CPPUNIT_ASSERT_EQUAL(Color(0x0A0A0A), 
pColorSet->getColor(model::ThemeColorType::Hyperlink));
     CPPUNIT_ASSERT_EQUAL(Color(0x440000), 
pColorSet->getColor(model::ThemeColorType::Accent1));
 }
+
+CPPUNIT_TEST_FIXTURE(XmloffDrawTest, testPdfExportAsOdg)
+{
+    auto pPdfium = vcl::pdf::PDFiumLibrary::get();
+    if (!pPdfium)
+    {
+        return;
+    }
+
+// setenv only works on unix based systems
+#ifndef _WIN32
+    // We need to enable PDFium import (and make sure to disable after the 
test)
+    bool bResetEnvVar = false;
+    if (getenv("LO_IMPORT_USE_PDFIUM") == nullptr)
+    {
+        bResetEnvVar = true;
+        setenv("LO_IMPORT_USE_PDFIUM", "1", false);
+    }
+    comphelper::ScopeGuard aPDFiumEnvVarGuard([&]() {
+        if (bResetEnvVar)
+            unsetenv("LO_IMPORT_USE_PDFIUM");
+    });
+
+    loadFromFile(u"two-pages.pdf");
+    // save and reload as odg
+    saveAndReload("draw8");
+
+    // Check that the graphic in the second page of the document is the second 
page of the pdf
+    uno::Reference<drawing::XDrawPagesSupplier> xDrawPagesSupplier(mxComponent,
+                                                                   
uno::UNO_QUERY_THROW);
+    CPPUNIT_ASSERT(xDrawPagesSupplier.is());
+    uno::Reference<drawing::XDrawPages> 
xDrawPages(xDrawPagesSupplier->getDrawPages());
+    uno::Reference<drawing::XDrawPage> xDrawPage(xDrawPages->getByIndex(1), 
uno::UNO_QUERY_THROW);
+    uno::Reference<drawing::XShape> xImage(xDrawPage->getByIndex(0), 
uno::UNO_QUERY_THROW);
+    CPPUNIT_ASSERT(xImage.is());
+    uno::Reference<beans::XPropertySet> xShapeProps(xImage, uno::UNO_QUERY);
+    uno::Reference<graphic::XGraphic> xGraphic;
+    CPPUNIT_ASSERT(xShapeProps->getPropertyValue("Graphic") >>= xGraphic);
+
+    Graphic aGraphic(xGraphic);
+    CPPUNIT_ASSERT_EQUAL(1, aGraphic.getPageNumber());
+#endif
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/core/xmlimp.cxx b/xmloff/source/core/xmlimp.cxx
index e6b1aa66ee7f..cd89ce6cd303 100644
--- a/xmloff/source/core/xmlimp.cxx
+++ b/xmloff/source/core/xmlimp.cxx
@@ -1302,7 +1302,8 @@ bool SvXMLImport::IsPackageURL( std::u16string_view rURL 
) const
     return true;
 }
 
-uno::Reference<graphic::XGraphic> SvXMLImport::loadGraphicByURL(OUString const 
& rURL)
+uno::Reference<graphic::XGraphic> SvXMLImport::loadGraphicByURL(OUString 
const& rURL,
+                                                                sal_Int32 
nPageNum)
 {
     uno::Reference<graphic::XGraphic> xGraphic;
 
@@ -1312,7 +1313,7 @@ uno::Reference<graphic::XGraphic> 
SvXMLImport::loadGraphicByURL(OUString const &
         {
             if (IsPackageURL(rURL))
             {
-                xGraphic = mxGraphicStorageHandler->loadGraphic(rURL);
+                xGraphic = mxGraphicStorageHandler->loadGraphicAtPage(rURL, 
nPageNum);
             }
             else
             {
diff --git a/xmloff/source/draw/shapeexport.cxx 
b/xmloff/source/draw/shapeexport.cxx
index cbb027829713..0ac3fe2cc475 100644
--- a/xmloff/source/draw/shapeexport.cxx
+++ b/xmloff/source/draw/shapeexport.cxx
@@ -2496,12 +2496,12 @@ void XMLShapeExport::ImpExportGraphicObjectShape(
         }
 
         {
+            if (sOutMimeType.isEmpty())
+            {
+                GetExport().GetGraphicMimeTypeFromStream(xGraphic, 
sOutMimeType);
+            }
             if (GetExport().getSaneDefaultVersion() > 
SvtSaveOptions::ODFSVER_012)
             {
-                if (sOutMimeType.isEmpty())
-                {
-                    GetExport().GetGraphicMimeTypeFromStream(xGraphic, 
sOutMimeType);
-                }
                 if (!sOutMimeType.isEmpty())
                 {   // ODF 1.3 OFFICE-3943
                     GetExport().AddAttribute(
@@ -2512,6 +2512,15 @@ void XMLShapeExport::ImpExportGraphicObjectShape(
                 }
             }
 
+            if (sOutMimeType == "application/pdf")
+            {
+                Graphic aGraphic(xGraphic);
+                sal_Int32 nPage = aGraphic.getPageNumber();
+                if (nPage >= 0)
+                    GetExport().AddAttribute(XML_NAMESPACE_LO_EXT, 
XML_PAGE_NUMBER,
+                                             OUString::number(nPage));
+            }
+
             SvXMLElementExport aElement(mrExport, XML_NAMESPACE_DRAW, 
XML_IMAGE, true, true);
 
             // optional office:binary-data
diff --git a/xmloff/source/draw/ximpshap.cxx b/xmloff/source/draw/ximpshap.cxx
index aaee9668fa37..45929e2fb6f4 100644
--- a/xmloff/source/draw/ximpshap.cxx
+++ b/xmloff/source/draw/ximpshap.cxx
@@ -2358,10 +2358,10 @@ bool SdXMLCaptionShapeContext::processAttribute( const 
sax_fastparser::FastAttri
 
 
 SdXMLGraphicObjectShapeContext::SdXMLGraphicObjectShapeContext(
-    SvXMLImport& rImport,
-    const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
-    uno::Reference< drawing::XShapes > const & rShapes)
-:   SdXMLShapeContext( rImport, xAttrList, rShapes, false/*bTemporaryShape*/ )
+    SvXMLImport& rImport, const 
css::uno::Reference<css::xml::sax::XFastAttributeList>& xAttrList,
+    uno::Reference<drawing::XShapes> const& rShapes)
+    : SdXMLShapeContext(rImport, xAttrList, rShapes, false /*bTemporaryShape*/)
+    , mnPage(-1)
 {
 }
 
@@ -2377,6 +2377,9 @@ bool SdXMLGraphicObjectShapeContext::processAttribute( 
const sax_fastparser::Fas
     case XML_ELEMENT(LO_EXT, XML_MIME_TYPE):
         msMimeType = aIter.toString();
         break;
+    case XML_ELEMENT(LO_EXT, XML_PAGE_NUMBER):
+        mnPage = aIter.toInt32();
+        break;
     default:
         return SdXMLShapeContext::processAttribute(aIter);
     }
@@ -2429,7 +2432,8 @@ void SdXMLGraphicObjectShapeContext::startFastElement 
(sal_Int32 nElement,
         {
             if( !maURL.isEmpty() )
             {
-                uno::Reference<graphic::XGraphic> xGraphic = 
GetImport().loadGraphicByURL(maURL);
+                uno::Reference<graphic::XGraphic> xGraphic
+                    = GetImport().loadGraphicByURL(maURL, mnPage);
                 if (xGraphic.is())
                 {
                     xPropset->setPropertyValue("Graphic", uno::Any(xGraphic));
diff --git a/xmloff/source/draw/ximpshap.hxx b/xmloff/source/draw/ximpshap.hxx
index 9a61f4b594de..6a00cb252e5f 100644
--- a/xmloff/source/draw/ximpshap.hxx
+++ b/xmloff/source/draw/ximpshap.hxx
@@ -392,6 +392,7 @@ private:
     OUString maURL;
     OUString msMimeType;
     css::uno::Reference < css::io::XOutputStream > mxBase64Stream;
+    sal_Int32 mnPage;
 
 public:
     OUString const& getMimeType() const { return msMimeType; }

Reply via email to