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 
 sc/source/ui/view/cellsh1.cxx                               |   10 +-
 schema/libreoffice/OpenDocument-v1.4+libreoffice-schema.rng |    9 ++
 svx/source/xml/xmlgrhlp.cxx                                 |   49 ++++++++++--
 vcl/inc/impgraph.hxx                                        |    2 
 vcl/source/filter/graphicfilter.cxx                         |   21 +++--
 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 
 20 files changed, 182 insertions(+), 51 deletions(-)

New commits:
commit 6d8d9100b043db4f7e4d828261142c3271b81fd5
Author:     Gökay Şatır <gokaysa...@collabora.com>
AuthorDate: Thu Nov 21 15:19:01 2024 +0300
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Tue Feb 4 12:55:42 2025 +0100

    cool#10533
    
    LOK: Do not set the pasteMode when the view is read only.
    
    There is a chance to paste the copied content in read only view if user 
acts too fast.
    We need to set the pasteMode selectively to ensure that the action is not 
performed.
    
    Change-Id: I446469a2f1fa25c5cdf6c5958f664a46d6d1a741
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/181085
    Tested-by: Jenkins
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>

diff --git a/sc/source/ui/view/cellsh1.cxx b/sc/source/ui/view/cellsh1.cxx
index f94f19ac7c48..fcbd50bcea60 100644
--- a/sc/source/ui/view/cellsh1.cxx
+++ b/sc/source/ui/view/cellsh1.cxx
@@ -1443,7 +1443,10 @@ void ScCellShell::ExecuteEdit( SfxRequest& rReq )
                 weld::WaitObject aWait( GetViewData().GetDialogParent() );
                 pTabViewShell->CopyToClip( nullptr, false, false, true );
                 rReq.Done();
-                GetViewData().SetPasteMode( ScPasteFlags::Mode | 
ScPasteFlags::Border );
+
+                if (!comphelper::LibreOfficeKit::isActive() || 
!pTabViewShell->GetViewShell() || 
!pTabViewShell->GetViewShell()->IsLokReadOnlyView())
+                    GetViewData().SetPasteMode( ScPasteFlags::Mode | 
ScPasteFlags::Border );
+
                 pTabViewShell->ShowCursor();
                 pTabViewShell->UpdateCopySourceOverlay();
             }
@@ -1454,7 +1457,10 @@ void ScCellShell::ExecuteEdit( SfxRequest& rReq )
                 weld::WaitObject aWait( GetViewData().GetDialogParent() );
                 pTabViewShell->CutToClip();
                 rReq.Done();
-                GetViewData().SetPasteMode( ScPasteFlags::Mode | 
ScPasteFlags::Border );
+
+                if (!comphelper::LibreOfficeKit::isActive() || 
!pTabViewShell->GetViewShell() || 
!pTabViewShell->GetViewShell()->IsLokReadOnlyView())
+                    GetViewData().SetPasteMode( ScPasteFlags::Mode | 
ScPasteFlags::Border );
+
                 pTabViewShell->ShowCursor();
                 pTabViewShell->UpdateCopySourceOverlay();
             }
commit 87f132a5e81557e423456c12c1bdcde13d1e4c66
Author:     Jaume Pujantell <jaume.pujant...@collabora.com>
AuthorDate: Tue Jan 28 10:13:11 2025 +0100
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Tue Feb 4 12:55:29 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/+/181066
    Tested-by: Jenkins
    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 293e2720b76f..140fdaacff9c 100644
--- a/include/vcl/graphicfilter.hxx
+++ b/include/vcl/graphicfilter.hxx
@@ -272,10 +272,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.
     ///
@@ -289,7 +290,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;}
     SAL_DLLPRIVATE void     ResetLastError();
@@ -317,7 +319,8 @@ public:
     SAL_DLLPRIVATE static ErrCode readWMF(SvStream & rStream, Graphic & 
rGraphic, GfxLinkType & rLinkType);
     SAL_DLLPRIVATE static ErrCode readEMF(SvStream & rStream, Graphic & 
rGraphic, GfxLinkType & rLinkType);
 
-    SAL_DLLPRIVATE static ErrCode readPDF(SvStream & rStream, Graphic & 
rGraphic, GfxLinkType & rLinkType);
+    SAL_DLLPRIVATE static ErrCode readPDF(SvStream & rStream, Graphic & 
rGraphic, GfxLinkType & rLinkType,
+                           sal_Int32 nPageIndex = -1);
     SAL_DLLPRIVATE static ErrCode readTIFF(SvStream & rStream, Graphic & 
rGraphic, GfxLinkType & rLinkType);
     SAL_DLLPRIVATE static ErrCode readWithTypeSerializer(SvStream & rStream, 
Graphic & rGraphic, GfxLinkType & rLinkType, std::u16string_view aFilterName);
     SAL_DLLPRIVATE static ErrCode readBMP(SvStream & rStream, Graphic & 
rGraphic, GfxLinkType & rLinkType);
diff --git a/include/vcl/pdfread.hxx b/include/vcl/pdfread.hxx
index 00b6b44969c1..894cf8af0d85 100644
--- a/include/vcl/pdfread.hxx
+++ b/include/vcl/pdfread.hxx
@@ -31,10 +31,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 f963bd791715..44a97ddb9c3f 100644
--- a/include/xmloff/xmlimp.hxx
+++ b/include/xmloff/xmlimp.hxx
@@ -407,7 +407,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.4+libreoffice-schema.rng 
b/schema/libreoffice/OpenDocument-v1.4+libreoffice-schema.rng
index 79bb67d7da17..6a8e3149c66e 100644
--- a/schema/libreoffice/OpenDocument-v1.4+libreoffice-schema.rng
+++ b/schema/libreoffice/OpenDocument-v1.4+libreoffice-schema.rng
@@ -4025,4 +4025,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 f67f7c7c3703..e6cc29db7bfa 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 = std::move(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 cad519c87e5c..3d93621e9978 100644
--- a/vcl/inc/impgraph.hxx
+++ b/vcl/inc/impgraph.hxx
@@ -40,7 +40,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 af9b2b774b4b..b72faf93da2f 100644
--- a/vcl/source/filter/graphicfilter.cxx
+++ b/vcl/source/filter/graphicfilter.cxx
@@ -820,7 +820,7 @@ ErrCode prepareImageTypeAndData(SvStream& rStream, 
sal_uInt32 nStreamLength, Bin
 } // end anonymous namespace
 
 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;
@@ -877,8 +877,10 @@ Graphic GraphicFilter::ImportUnloadedGraphic(SvStream& 
rIStream, sal_uInt64 size
                     pSizeHint = &aLogicSize;
                 }
             }
-
-            
aGraphic.SetGfxLink(std::make_shared<GfxLink>(aBinaryDataContainer, eLinkType));
+            if (eLinkType == GfxLinkType::NativePdf && nPage >= 0)
+                aGraphic = 
Graphic(std::make_shared<GfxLink>(aBinaryDataContainer, eLinkType), nPage);
+            else
+                
aGraphic.SetGfxLink(std::make_shared<GfxLink>(aBinaryDataContainer, eLinkType));
             aGraphic.ImplGetImpGraphic()->setPrepared(bAnimated, pSizeHint);
         }
     }
@@ -1087,9 +1089,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;
@@ -1246,8 +1249,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;
@@ -1338,7 +1343,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 584497a9cb77..1a1bf2217f1a 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 347dd5dc651b..59ceacee7a04 100644
--- a/vcl/source/gdi/impgraph.cxx
+++ b/vcl/source/gdi/impgraph.cxx
@@ -1463,7 +1463,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 2d1a4c533f24..41019fbeb204 100644
--- a/xmloff/qa/unit/draw.cxx
+++ b/xmloff/qa/unit/draw.cxx
@@ -23,8 +23,10 @@
 #include <com/sun/star/text/GraphicCrop.hpp>
 
 #include <comphelper/propertyvalue.hxx>
+#include <comphelper/scopeguard.hxx>
 #include <comphelper/sequence.hxx>
 #include <comphelper/sequenceashashmap.hxx>
+#include <osl/process.h>
 #include <unotools/tempfile.hxx>
 #include <unotools/saveopt.hxx>
 #include <svx/unopage.hxx>
@@ -1084,6 +1086,49 @@ CPPUNIT_TEST_FIXTURE(XmloffDrawTest, 
testTdf161483_CircleStartEndAngle)
     }
 }
 
+CPPUNIT_TEST_FIXTURE(XmloffDrawTest, testPdfExportAsOdg)
+{
+    auto pPdfium = vcl::pdf::PDFiumLibrary::get();
+    if (!pPdfium)
+    {
+        return;
+    }
+
+    // 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;
+        osl_setEnvironment(OUString("LO_IMPORT_USE_PDFIUM").pData, 
OUString("1").pData);
+    }
+    comphelper::ScopeGuard aPDFiumEnvVarGuard([&]() {
+        if (bResetEnvVar)
+            osl_clearEnvironment(OUString("LO_IMPORT_USE_PDFIUM").pData);
+    });
+
+    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);
+    // Without the accompanying fix in place, this test would have failed with:
+    // - Expected: 1
+    // - Actual  : -1
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(1), aGraphic.getPageNumber());
+}
+
 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 54ef1abfebba..3c405d21a0d0 100644
--- a/xmloff/source/core/xmlimp.cxx
+++ b/xmloff/source/core/xmlimp.cxx
@@ -1299,7 +1299,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;
 
@@ -1309,7 +1310,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 9d9cb7506b14..92a8e0ed6d98 100644
--- a/xmloff/source/draw/shapeexport.cxx
+++ b/xmloff/source/draw/shapeexport.cxx
@@ -2498,12 +2498,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(
@@ -2514,6 +2514,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 dbaefd30b95c..f6bec74799ab 100644
--- a/xmloff/source/draw/ximpshap.cxx
+++ b/xmloff/source/draw/ximpshap.cxx
@@ -2354,10 +2354,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)
 {
 }
 
@@ -2373,6 +2373,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);
     }
@@ -2425,7 +2428,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(u"Graphic"_ustr, 
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