sd/inc/drawdoc.hxx                   |    3 +++
 sd/inc/sdpage.hxx                    |    2 +-
 sd/source/core/drawdoc2.cxx          |   11 +++++------
 sd/source/core/sdpage.cxx            |    7 +++++++
 sd/source/ui/unoidl/unopage.cxx      |    4 ++++
 xmloff/source/draw/sdxmlimp.cxx      |   33 +++++++++++++++++++++++++++++++++
 xmloff/source/draw/sdxmlimp_impl.hxx |   13 ++++++++++++-
 xmloff/source/draw/ximpshap.cxx      |    9 +++++++++
 8 files changed, 74 insertions(+), 8 deletions(-)

New commits:
commit da71ff1beab031f382de5bcf94eeabbea8146c61
Author:     Mohit Marathe <[email protected]>
AuthorDate: Fri Dec 5 17:01:14 2025 +0530
Commit:     Mohit Marathe <[email protected]>
CommitDate: Tue Jan 13 09:04:44 2026 +0100

    xmloff: svx: handle import of page shapes that are inside canvas page
    
    Since the canvas page is the first page, the reference page of the page
    shapes are not properly set during import as the other pages does
    not exist yet.
    
    Hence, store the corresponding page number in SdXMLImport, and resolve it
    in SdXMLImport::endDocument()
    
    This went unnoticed as the canvas page got repaired during import.
    
    Signed-off-by: Mohit Marathe <[email protected]>
    Change-Id: Ice966768eafaaaad3a65c3148e3573d20fec8026
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/195076
    Reviewed-by: Michael Stahl <[email protected]>
    Tested-by: Jenkins CollaboraOffice <[email protected]>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/196816
    Tested-by: Jenkins

diff --git a/sd/source/core/drawdoc2.cxx b/sd/source/core/drawdoc2.cxx
index a1a06941d402..d76557587d00 100644
--- a/sd/source/core/drawdoc2.cxx
+++ b/sd/source/core/drawdoc2.cxx
@@ -1499,6 +1499,11 @@ bool SdDrawDocument::ValidateCanvasPage(const SdPage* 
pPage) const
             continue;
         SdrPageObj* pPageObj = static_cast<SdrPageObj*>(pObj);
         SdrPage* pPreviewPage = pPageObj->GetReferencedPage();
+        if (!pPreviewPage)
+        {
+            SAL_WARN("sd", "SdrObject does point to a valid page");
+            return false;
+        }
         if (aPreviewPageSet.contains(pPreviewPage))
             return false;
         else
diff --git a/sd/source/ui/unoidl/unopage.cxx b/sd/source/ui/unoidl/unopage.cxx
index f9bf3a7ddd41..56f3da3e8157 100644
--- a/sd/source/ui/unoidl/unopage.cxx
+++ b/sd/source/ui/unoidl/unopage.cxx
@@ -454,6 +454,10 @@ rtl::Reference<SdrObject> 
SdGenericDrawPage::CreateSdrObject_( const Reference<
     {
         if( GetPage()->GetPageKind() == PageKind::Notes && 
GetPage()->IsMasterPage() )
             eObjKind = PresObjKind::Title;
+        else if (GetPage()->GetPageKind() == PageKind::Standard
+            && !GetPage()->IsMasterPage())
+            // might be a canvas page
+            eObjKind = PresObjKind::PagePreview;
         else
             eObjKind = PresObjKind::Page;
     }
diff --git a/xmloff/source/draw/sdxmlimp.cxx b/xmloff/source/draw/sdxmlimp.cxx
index c46d397c1167..5df294a8f6f9 100644
--- a/xmloff/source/draw/sdxmlimp.cxx
+++ b/xmloff/source/draw/sdxmlimp.cxx
@@ -405,6 +405,34 @@ void SAL_CALL SdXMLImport::initialize( const 
uno::Sequence< uno::Any >& aArgumen
     }
 }
 
+void SAL_CALL SdXMLImport::endDocument()
+{
+    SvXMLImport::endDocument();
+
+    // Resolve SdrPageObj references that couldn't be resolved during import
+    // (because the target page didn't exist yet at import time).
+    for (const auto& rRef : maPageShapeRefs)
+    {
+        if (!rRef.mxShape.is())
+            continue;
+
+        uno::Reference<beans::XPropertySet> xPropSet(rRef.mxShape, 
uno::UNO_QUERY);
+        if (!xPropSet.is())
+            continue;
+
+        if 
(xPropSet->getPropertySetInfo()->hasPropertyByName(u"PageNumber"_ustr))
+        {
+            sal_Int32 nPageNum = 0;
+            if ((xPropSet->getPropertyValue(u"PageNumber"_ustr) >>= nPageNum) 
&& nPageNum == 0)
+            {
+                xPropSet->setPropertyValue(u"PageNumber"_ustr, 
uno::Any(rRef.mnPageNumber));
+            }
+        }
+    }
+
+    maPageShapeRefs.clear();
+}
+
 SvXMLImportContext *SdXMLImport::CreateFastContext( sal_Int32 nElement,
         const uno::Reference< xml::sax::XFastAttributeList >& xAttrList )
 {
@@ -630,6 +658,11 @@ void SdXMLImport::AddDateTimeDecl( const OUString& rName, 
const OUString& rText,
     }
 }
 
+void SdXMLImport::AddPageShapePageNum(const 
css::uno::Reference<css::drawing::XShape>& rxShape, sal_Int32 nPageNumber)
+{
+    maPageShapeRefs.push_back({rxShape, nPageNumber});
+}
+
 OUString SdXMLImport::GetHeaderDecl( const OUString& rName ) const
 {
     OUString aRet;
diff --git a/xmloff/source/draw/sdxmlimp_impl.hxx 
b/xmloff/source/draw/sdxmlimp_impl.hxx
index 212e65c01c16..3d52294def51 100644
--- a/xmloff/source/draw/sdxmlimp_impl.hxx
+++ b/xmloff/source/draw/sdxmlimp_impl.hxx
@@ -70,8 +70,16 @@ class SdXMLImport: public SvXMLImport
     HeaderFooterDeclMap         maFooterDeclsMap;
     DateTimeDeclMap             maDateTimeDeclsMap;
 
-protected:
+    // Storage for page shape references that need to be resolved in 
endDocument()
+    // when all pages have been imported
+    struct PageShapeRef
+    {
+        css::uno::Reference<css::drawing::XShape> mxShape;
+        sal_Int32 mnPageNumber;
+    };
+    std::vector<PageShapeRef> maPageShapeRefs;
 
+protected:
     // This method is called after the namespace map has been updated, but
     // before a context for the current element has been pushed.
     virtual SvXMLImportContext *CreateFastContext( sal_Int32 nElement,
@@ -89,6 +97,7 @@ public:
     // XInitialization
     virtual void SAL_CALL initialize( const css::uno::Sequence< css::uno::Any 
>& aArguments ) override;
 
+    virtual void SAL_CALL endDocument() override;
     virtual void SetViewSettings(const 
css::uno::Sequence<css::beans::PropertyValue>& aViewProps) override;
     virtual void SetConfigurationSettings(const 
css::uno::Sequence<css::beans::PropertyValue>& aConfigProps) override;
 
@@ -125,6 +134,8 @@ public:
     void AddHeaderDecl( const OUString& rName, const OUString& rText );
     void AddFooterDecl( const OUString& rName, const OUString& rText );
     void AddDateTimeDecl( const OUString& rName, const OUString& rText, bool 
bFixed, const OUString& rDateTimeFormat );
+    void AddPageShapePageNum(const css::uno::Reference<css::drawing::XShape>& 
rxShape,
+                         sal_Int32 nPageNumber);
 
     OUString GetHeaderDecl( const OUString& rName ) const;
     OUString GetFooterDecl( const OUString& rName ) const;
diff --git a/xmloff/source/draw/ximpshap.cxx b/xmloff/source/draw/ximpshap.cxx
index a7ca787decdc..3c840b6d4bc7 100644
--- a/xmloff/source/draw/ximpshap.cxx
+++ b/xmloff/source/draw/ximpshap.cxx
@@ -68,6 +68,7 @@
 #include <XMLReplacementImageContext.hxx>
 #include <XMLImageMapContext.hxx>
 #include "sdpropls.hxx"
+#include "sdxmlimp_impl.hxx"
 #include "eventimp.hxx"
 #include "descriptionimp.hxx"
 #include "SignatureLineContext.hxx"
@@ -2251,6 +2252,14 @@ void SdXMLPageShapeContext::startFastElement (sal_Int32 
nElement,
             xPropSet->setPropertyValue(aPageNumberStr, uno::Any( mnPageNumber 
));
     }
 
+    // For later resolution of page shape references, in case the target page 
does not
+    // exist during import. This will be resolved in SdXMLImport::endDocument()
+    if (mnPageNumber > 0)
+    {
+        if (SdXMLImport* pSdImport = dynamic_cast<SdXMLImport*>(&GetImport()))
+            pSdImport->AddPageShapePageNum(mxShape, mnPageNumber);
+    }
+
     SdXMLShapeContext::startFastElement(nElement, xAttrList);
 }
 
commit e021c187c48dc1f715136279556bb2c9c856a65c
Author:     Mohit Marathe <[email protected]>
AuthorDate: Tue Dec 9 13:51:58 2025 +0530
Commit:     Mohit Marathe <[email protected]>
CommitDate: Tue Jan 13 09:04:32 2026 +0100

    sd: refactor SdPage::SetCanvasPage
    
    Signed-off-by: Mohit Marathe <[email protected]>
    Change-Id: Iec7dd09162a9a51de3bcb9c3126a365b26c0507a
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/195286
    Tested-by: Jenkins CollaboraOffice <[email protected]>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/196815
    Reviewed-by: Michael Stahl <[email protected]>
    Tested-by: Jenkins

diff --git a/sd/inc/drawdoc.hxx b/sd/inc/drawdoc.hxx
index e267595d8c67..380c936f8c8d 100644
--- a/sd/inc/drawdoc.hxx
+++ b/sd/inc/drawdoc.hxx
@@ -36,6 +36,7 @@
 #include "sddllapi.h"
 #include "pres.hxx"
 #include "stlpool.hxx"
+#include "sdpage.hxx"
 
 namespace com::sun::star::xml::dom { class XNode; }
 namespace editeng { class SvxFieldItemUpdater; }
@@ -1074,6 +1075,8 @@ public:
         bool bUndo = true,
         const OUString& sNewName = OUString());
 
+    void StoreCanvasPage(SdPage* pPage) { mpCanvasPage = pPage; }
+
     /** Re-order the pages based on the position of their previews on canvas 
page.
      */
     void ReshufflePages();
diff --git a/sd/inc/sdpage.hxx b/sd/inc/sdpage.hxx
index 35d095513cac..b4f84812b0af 100644
--- a/sd/inc/sdpage.hxx
+++ b/sd/inc/sdpage.hxx
@@ -403,7 +403,7 @@ public:
     static sal_uInt16 mnLastPageId;
 
     bool IsCanvasPage() const { return mbIsCanvasPage; }
-    void SetCanvasPage() { mbIsCanvasPage = true; }
+    void SetCanvasPage();
 
     bool IsCanvasMasterPage() const { return mbIsCanvasMasterPage; }
     void SetCanvasMasterPage() { mbIsCanvasMasterPage = true; }
diff --git a/sd/source/core/drawdoc2.cxx b/sd/source/core/drawdoc2.cxx
index e384e2a4591d..a1a06941d402 100644
--- a/sd/source/core/drawdoc2.cxx
+++ b/sd/source/core/drawdoc2.cxx
@@ -1515,8 +1515,6 @@ void SdDrawDocument::ImportCanvasPage()
     SdPage* pPage = GetSdPage(0, PageKind::Standard);
     bool bIsCanvasPageValid = ValidateCanvasPage(pPage);
     pPage->SetCanvasPage();
-    pPage->SetExcluded(true);
-    mpCanvasPage = pPage;
     SdPage* pMPage = static_cast<SdPage*>(&pPage->TRG_GetMasterPage());
     pMPage->SetCanvasMasterPage();
     // re-populate the previews grid if not valid
@@ -1625,9 +1623,6 @@ sal_uInt16 SdDrawDocument::GetOrInsertCanvasPage()
     if (!pCanvasPage)
         return 0xffff;
 
-    // exclude from slideshow
-    pCanvasPage->SetExcluded(true);
-
     // move the canvas page to the top
     sal_uInt16 nCanvasPageNum = 2 * nCanvasPageIndex + 1;
     MovePage(nCanvasPageNum, 1); // Canvas page
@@ -1637,7 +1632,6 @@ sal_uInt16 SdDrawDocument::GetOrInsertCanvasPage()
 
     ResizeCurrentPage(pCanvasPage, aCanvasSize, PageKind::Standard);
     pCanvasPage->SetCanvasPage();
-    mpCanvasPage = pCanvasPage;
 
     SdPage* pMasterCanvas = 
static_cast<SdPage*>(&pCanvasPage->TRG_GetMasterPage());
     pMasterCanvas->SetCanvasMasterPage();
diff --git a/sd/source/core/sdpage.cxx b/sd/source/core/sdpage.cxx
index 73482c4d71df..c78bf1e21952 100644
--- a/sd/source/core/sdpage.cxx
+++ b/sd/source/core/sdpage.cxx
@@ -1402,6 +1402,13 @@ OUString SdPage::autoLayoutToString(AutoLayout nLayoutId)
     return enumtoString(nLayoutId);
 }
 
+void SdPage::SetCanvasPage()
+{
+    mbIsCanvasPage = true;
+    SetExcluded(true);
+    
static_cast<SdDrawDocument&>(getSdrModelFromSdrPage()).StoreCanvasPage(this);
+}
+
 static void CalcAutoLayoutRectangles( SdPage const & rPage,::tools::Rectangle* 
rRectangle ,const OUString& sLayoutType )
 {
     ::tools::Rectangle aTitleRect;

Reply via email to