desktop/source/lib/init.cxx                                 |    2 
 include/svl/cryptosign.hxx                                  |    2 
 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 
 postprocess/CustomTarget_registry.mk                        |    4 
 schema/libreoffice/OpenDocument-v1.4+libreoffice-schema.rng |    9 ++
 sfx2/source/control/dispatch.cxx                            |    1 
 sfx2/source/sidebar/ResourceManager.cxx                     |    6 -
 svx/source/xml/xmlgrhlp.cxx                                 |   49 ++++++++++--
 sw/inc/init.hxx                                             |    5 -
 sw/qa/core/header_footer/HeaderFooterTest.cxx               |    5 +
 sw/qa/extras/rtfexport/rtfexport8.cxx                       |   12 ++
 sw/source/filter/basflt/fltini.cxx                          |   24 ++---
 sw/source/uibase/app/swdll.cxx                              |    3 
 sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx        |    2 
 sw/source/writerfilter/dmapper/PropertyMap.cxx              |   39 +++++----
 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/ProgressBarHelper.cxx                    |    4 
 xmloff/source/core/SettingsExportHelper.cxx                 |    2 
 xmloff/source/core/xmlimp.cxx                               |    5 -
 xmloff/source/draw/shapeexport.cxx                          |   17 +++-
 xmloff/source/draw/ximpshap.cxx                             |   14 ++-
 xmloff/source/draw/ximpshap.hxx                             |    1 
 33 files changed, 244 insertions(+), 90 deletions(-)

New commits:
commit 47176d05f01c714af1e3d010da1cb59016dd4a75
Author:     Patrick Luby <guibmac...@gmail.com>
AuthorDate: Tue Nov 12 10:07:29 2024 -0500
Commit:     Andras Timar <andras.ti...@collabora.com>
CommitDate: Sun Feb 9 13:08:13 2025 +0100

    Fix iOS build failure when building with Xcode 16.1 on macOS Sequoia
    
    Change-Id: I21c0ff32298bdc1309b2d0dd6152e1f5f43746e4
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/176485
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>
    Reviewed-by: Patrick Luby <guibomac...@gmail.com>

diff --git a/include/svl/cryptosign.hxx b/include/svl/cryptosign.hxx
index 154292b5f3ce..8c8e48f0da54 100644
--- a/include/svl/cryptosign.hxx
+++ b/include/svl/cryptosign.hxx
@@ -86,7 +86,7 @@ public:
 
 private:
     /// The certificate to use for signing.
-    svl::crypto::SigningContext& m_rSigningContext;
+    [[maybe_unused]] svl::crypto::SigningContext& m_rSigningContext;
 
     /// Data blocks (pointer-size pairs).
     std::vector<std::pair<const void*, sal_Int32>> m_dataBlocks;
commit 8f27023ea81490eeef6163f1aef93f5643adefb8
Author:     Justin Luth <justin.l...@collabora.com>
AuthorDate: Thu Jan 16 20:25:22 2025 -0500
Commit:     Andras Timar <andras.ti...@collabora.com>
CommitDate: Sun Feb 9 12:20:38 2025 +0100

    tdf#164748 writerfilter: fix missing even/odd header properties
    
    Lots of header/footer page style properties are ignored
    if the header/footer is not first enabled.
    So copying propertyList MUST follow completeCopyHeaderFooter()
    [which is where all those settings are turned on].
    
    However, copying properties AFTER turning on the header/footer
    was Exception'ing when trying to copy
    BottomMarginComplexColor as void().
    
    So ignore any property-copy errors,
    and then everything should work in theory...
    ...and it seems to.
    
    make CppunitTest_sw_core_header_footer \
        CPPUNIT_TEST_NAME=testBnc519228OddBreaks
    
    make CppunitTest_sw_rtfexport8 \
        CPPUNIT_TEST_NAME=testTdf160976_headerFooter
    
    Change-Id: Iecf0a070e77525c04b44c4fc38efa0f9d558eca5
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/180417
    Tested-by: Jenkins
    Reviewed-by: Justin Luth <jl...@mail.com>

diff --git a/sw/qa/core/header_footer/HeaderFooterTest.cxx 
b/sw/qa/core/header_footer/HeaderFooterTest.cxx
index af4e388dff2f..f277a0ed77aa 100644
--- a/sw/qa/core/header_footer/HeaderFooterTest.cxx
+++ b/sw/qa/core/header_footer/HeaderFooterTest.cxx
@@ -643,6 +643,8 @@ CPPUNIT_TEST_FIXTURE(HeaderFooterTest, 
testFirstPageFooterEnabled)
 CPPUNIT_TEST_FIXTURE(HeaderFooterTest, testBnc519228OddBreaks)
 {
     auto verify = [this]() {
+        CPPUNIT_ASSERT_EQUAL(5, getPages()); // logical pages - "blank page" 4 
usually not displayed
+
         // Check that all the normal styles are not set as right-only, those 
should be only those used after odd page breaks.
         auto xStyles = getStyles(u"PageStyles"_ustr);
         uno::Reference<beans::XPropertySet> xStyle;
@@ -696,6 +698,9 @@ CPPUNIT_TEST_FIXTURE(HeaderFooterTest, 
testBnc519228OddBreaks)
 
             CPPUNIT_ASSERT_EQUAL(getProperty<sal_Int32>(page1Style, 
u"TopMargin"_ustr),
                                  getProperty<sal_Int32>(page2Style, 
u"TopMargin"_ustr));
+            //tdf164748
+            CPPUNIT_ASSERT_EQUAL(getProperty<bool>(page1Style, 
u"HeaderDynamicSpacing"_ustr),
+                                 getProperty<bool>(page2Style, 
u"HeaderDynamicSpacing"_ustr));
         }
 
         // Page 5
diff --git a/sw/qa/extras/rtfexport/rtfexport8.cxx 
b/sw/qa/extras/rtfexport/rtfexport8.cxx
index 7184b7cc5b89..e8e607c59126 100644
--- a/sw/qa/extras/rtfexport/rtfexport8.cxx
+++ b/sw/qa/extras/rtfexport/rtfexport8.cxx
@@ -431,6 +431,18 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf160976_headerFooter)
     verify();
     saveAndReload(mpFilter);
     verify(/*IsExported*/ true);
+
+    //tdf#164748: export must have the all same footer settings as the first 
page
+    auto xStyles = getStyles(u"PageStyles"_ustr);
+    auto xPara = getParagraph(2, "2");
+    OUString page2StyleName = getProperty<OUString>(xPara, 
u"PageDescName"_ustr);
+    uno::Reference<beans::XPropertySet> page2Style;
+    page2Style.set(xStyles->getByName(page2StyleName), uno::UNO_QUERY);
+    CPPUNIT_ASSERT(getProperty<bool>(page2Style, 
u"FooterDynamicSpacing"_ustr));
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(915),
+                         getProperty<sal_Int32>(page2Style, 
u"FooterBodyDistance"_ustr));
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(1016), getProperty<sal_Int32>(page2Style, 
u"FooterHeight"_ustr));
+
     // note: an unexpected header surfaces on page 3.
 }
 
diff --git a/sw/source/writerfilter/dmapper/PropertyMap.cxx 
b/sw/source/writerfilter/dmapper/PropertyMap.cxx
index ce373b092890..efd038964444 100644
--- a/sw/source/writerfilter/dmapper/PropertyMap.cxx
+++ b/sw/source/writerfilter/dmapper/PropertyMap.cxx
@@ -1478,11 +1478,22 @@ void 
SectionPropertyMap::CreateEvenOddPageStyleCopy(DomainMapper_Impl& rDM_Impl,
 {
     OUString evenOddStyleName = rDM_Impl.GetUnusedPageStyleName();
     rtl::Reference<SwXPageStyle> evenOddStyle = 
rDM_Impl.GetTextDocument()->createPageStyle();
-    // Unfortunately using setParent() does not work for page styles, so make 
a deep copy of the page style.
+    rDM_Impl.GetPageStyles()->insertStyleByName(evenOddStyleName, 
evenOddStyle);
+
     rtl::Reference<SwXPageStyle> pageProperties(m_aPageStyle);
     uno::Reference<beans::XPropertySetInfo> 
pagePropertiesInfo(pageProperties->getPropertySetInfo());
     const uno::Sequence<beans::Property> 
propertyList(pagePropertiesInfo->getProperties());
 
+    if (rDM_Impl.IsNewDoc())
+    {
+        bool const 
bEvenAndOdd(rDM_Impl.GetSettingsTable()->GetEvenAndOddHeaders());
+        completeCopyHeaderFooter(pageProperties, evenOddStyle,
+            !rDM_Impl.SeenHeaderFooter(PagePartType::Header, PageType::RIGHT)
+                && (!bEvenAndOdd || 
!rDM_Impl.SeenHeaderFooter(PagePartType::Header, PageType::LEFT)),
+            !rDM_Impl.SeenHeaderFooter(PagePartType::Footer, PageType::RIGHT)
+                && (!bEvenAndOdd || 
!rDM_Impl.SeenHeaderFooter(PagePartType::Footer, PageType::LEFT)));
+    }
+
     // Ignore write-only properties.
     static constexpr auto staticDenylist = 
frozen::make_unordered_set<std::u16string_view>({
         u"FooterBackGraphicURL", u"BackGraphicURL", u"HeaderBackGraphicURL",
@@ -1492,6 +1503,7 @@ void 
SectionPropertyMap::CreateEvenOddPageStyleCopy(DomainMapper_Impl& rDM_Impl,
         u"FooterText", u"FooterTextLeft", u"FooterTextFirst"
     });
 
+    // Unfortunately page styles can't inherit from a parent, so make a deep 
copy of the page style.
     bool isMirrorMargins = PageBreakType::Even == eBreakType && 
rDM_Impl.GetSettingsTable()->GetMirrorMarginSettings();
     for (const auto& rProperty : propertyList)
     {
@@ -1507,26 +1519,21 @@ void 
SectionPropertyMap::CreateEvenOddPageStyleCopy(DomainMapper_Impl& rDM_Impl,
                     else if (rProperty.Name == u"RightMargin"_ustr)
                         sSetName = u"LeftMargin"_ustr;
                 }
-                evenOddStyle->setPropertyValue(
-                    sSetName,
-                    pageProperties->getPropertyValue(rProperty.Name));
+                try
+                {
+                    evenOddStyle->setPropertyValue(
+                        sSetName,
+                        pageProperties->getPropertyValue(rProperty.Name));
+                }
+                catch (uno::Exception&)
+                {
+                    DBG_UNHANDLED_EXCEPTION("writerfilter", "failed to copy 
page style property");
+                }
             }
         }
     }
     evenOddStyle->setPropertyValue(u"FollowStyle"_ustr, 
uno::Any(m_sPageStyleName));
 
-    rDM_Impl.GetPageStyles()->insertStyleByName(evenOddStyleName, 
evenOddStyle);
-
-    if (rDM_Impl.IsNewDoc())
-    {
-        bool const 
bEvenAndOdd(rDM_Impl.GetSettingsTable()->GetEvenAndOddHeaders());
-        completeCopyHeaderFooter(pageProperties, evenOddStyle,
-            !rDM_Impl.SeenHeaderFooter(PagePartType::Header, PageType::RIGHT)
-                && (!bEvenAndOdd || 
!rDM_Impl.SeenHeaderFooter(PagePartType::Header, PageType::LEFT)),
-            !rDM_Impl.SeenHeaderFooter(PagePartType::Footer, PageType::RIGHT)
-                && (!bEvenAndOdd || 
!rDM_Impl.SeenHeaderFooter(PagePartType::Footer, PageType::LEFT)));
-    }
-
     if (eBreakType == PageBreakType::Even)
         
evenOddStyle->setPropertyValue(getPropertyName(PROP_PAGE_STYLE_LAYOUT), 
uno::Any(style::PageStyleLayout_LEFT));
     else if (eBreakType == PageBreakType::Odd)
commit 5179087be6cff5afdf6091d44538a2dda50a4f51
Author:     Aron Budea <aron.bu...@collabora.com>
AuthorDate: Sun Jan 19 03:23:51 2025 +1030
Commit:     Andras Timar <andras.ti...@collabora.com>
CommitDate: Sun Feb 9 12:19:30 2025 +0100

    LOK: Use OOXML 2010+ format
    
    Change-Id: Ic2deac5602293cfcd1a1a73774dab94b2c4c970a
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/180458
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>
    (cherry picked from commit 6f7e5f6c26a212c3fdbff3b97522d05a5ab896cb)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/180500
    Reviewed-by: Aron Budea <aron.bu...@collabora.com>
    Tested-by: Jenkins

diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index 06ea11391d80..200bf411996c 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -322,7 +322,7 @@ constexpr ExtensionMap aWriterExtensionMap[] =
 {
     { "doc",   u"MS Word 97"_ustr },
     { "docm",  u"MS Word 2007 XML VBA"_ustr },
-    { "docx",  u"MS Word 2007 XML"_ustr },
+    { "docx",  u"Office Open XML Text"_ustr },
     { "fodt",  u"OpenDocument Text Flat XML"_ustr },
     { "html",  u"HTML (StarWriter)"_ustr },
     { "odt",   u"writer8"_ustr },
commit 013092b83a91a485896a615b03cd47d2722c1846
Author:     Aron Budea <aron.bu...@collabora.com>
AuthorDate: Mon Jan 6 18:20:34 2025 +1030
Commit:     Andras Timar <andras.ti...@collabora.com>
CommitDate: Sun Feb 9 12:18:29 2025 +0100

    Slightly more informative logging
    
    Change-Id: Ia474a208d5a562e424df76ff389cfcc4e3f2b1fc
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/179817
    Tested-by: Jenkins
    Reviewed-by: Aron Budea <aron.bu...@collabora.com>
    (cherry picked from commit 899d87a844c2aa2990df4a9268008960d8489379)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/180151
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    Reviewed-by: Andras Timar <andras.ti...@collabora.com>

diff --git a/sfx2/source/sidebar/ResourceManager.cxx 
b/sfx2/source/sidebar/ResourceManager.cxx
index cf333c1b0a8f..f4066c0eb972 100644
--- a/sfx2/source/sidebar/ResourceManager.cxx
+++ b/sfx2/source/sidebar/ResourceManager.cxx
@@ -518,7 +518,7 @@ void ResourceManager::ReadContextList (
             }
             else
             {
-                OSL_FAIL("expecting three or four values per ContextList 
entry, separated by comma");
+                SAL_WARN("sfx.sidebar", "expecting three or four values per 
ContextList entry, separated by comma, entries: " << aValues);
                 continue;
             }
         }
@@ -526,7 +526,7 @@ void ResourceManager::ReadContextList (
         const OUString sContextName(o3tl::trim(o3tl::getToken(sValue, 0, ',', 
nCharacterIndex)));
         if (nCharacterIndex < 0)
         {
-            OSL_FAIL("expecting three or four values per ContextList entry, 
separated by comma");
+            SAL_WARN("sfx.sidebar", "expecting three or four values per 
ContextList entry, separated by comma");
             continue;
         }
 
@@ -617,7 +617,7 @@ void ResourceManager::ReadContextList (
             bIsInitiallyVisible = false;
         else
         {
-            OSL_FAIL("unrecognized state");
+            SAL_WARN("sfx.sidebar", "unrecognized state");
             continue;
         }
 
diff --git a/xmloff/source/core/ProgressBarHelper.cxx 
b/xmloff/source/core/ProgressBarHelper.cxx
index 3ff70fb0434d..9f2ddcd585c3 100644
--- a/xmloff/source/core/ProgressBarHelper.cxx
+++ b/xmloff/source/core/ProgressBarHelper.cxx
@@ -20,7 +20,7 @@
 #include <utility>
 #include <xmloff/ProgressBarHelper.hxx>
 
-#include <osl/diagnose.h>
+#include <sal/log.hxx>
 
 using namespace ::com::sun::star;
 
@@ -99,7 +99,7 @@ void ProgressBarHelper::SetValue(sal_Int32 nTempValue)
 #ifdef DBG_UTIL
     else if (!m_bFailure)
     {
-        OSL_FAIL("tried to set a wrong value on the progressbar");
+        SAL_WARN("xmloff", "tried to set a wrong value (" << nTempValue << ") 
on the progressbar");
         m_bFailure = true;
     }
 #endif
diff --git a/xmloff/source/core/SettingsExportHelper.cxx 
b/xmloff/source/core/SettingsExportHelper.cxx
index 3f6f87fa1bbb..db6f29a1512b 100644
--- a/xmloff/source/core/SettingsExportHelper.cxx
+++ b/xmloff/source/core/SettingsExportHelper.cxx
@@ -168,7 +168,7 @@ void XMLSettingsExportHelper::CallTypeFunction(const 
uno::Any& rAny,
                 exportSymbolDescriptors(aProps, rName);
             }
             else {
-                OSL_FAIL("this type is not implemented now");
+                SAL_WARN("xmloff", "this type (" << aType.getTypeName() << ") 
is not implemented now");
             }
         }
         break;
commit 1ebef218cc66e19db2c0fe0f2b3237fd844a3c07
Author:     Justin Luth <justin.l...@collabora.com>
AuthorDate: Mon Dec 16 14:02:18 2024 -0500
Commit:     Andras Timar <andras.ti...@collabora.com>
CommitDate: Sun Feb 9 12:15:29 2025 +0100

    tdf#164075 rtfimport: ignore assert developed for DOCX fixing
    
    I don't exactly remember why I put the assert there,
    but it sounds reasonable to expect that if
    the paragraph defined the numbering
    that it should also have numbering rule content,
    and if it doesn't, then it is worth investigating why.
    
    Investing anything related to RTF is never worthwhile.
    
    Change-Id: I6525d0a40d9535f1888056a610576085941605a3
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/178607
    Reviewed-by: Justin Luth <jl...@mail.com>
    Tested-by: Jenkins

diff --git a/sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx 
b/sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx
index efe48d107dfe..24712f454782 100644
--- a/sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx
+++ b/sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx
@@ -2653,7 +2653,7 @@ void DomainMapper_Impl::finishParagraph( const 
PropertyMapPtr& pPropertyMap, con
                         return rValue.Name == "NumberingRules";
                     });
 
-                    assert( isNumberingViaRule == (itNumberingRules != 
aProperties.end()) );
+                    assert(isNumberingViaRule == (itNumberingRules != 
aProperties.end()) || IsRTFImport());
                     isNumberingViaRule = (itNumberingRules != 
aProperties.end());
                     if (m_StreamStateStack.top().xPreviousParagraph.is()
                         && (isNumberingViaRule || isNumberingViaStyle))
commit ec00dab0d3bfdca7a5438ed36f77802f09f2aa1f
Author:     Gökay Şatır <gokaysa...@collabora.com>
AuthorDate: Tue Jan 7 12:48:00 2025 +0300
Commit:     Andras Timar <andras.ti...@collabora.com>
CommitDate: Sun Feb 9 12:14:34 2025 +0100

    Make sure that certain accelerator files are included for LOK case.
    
    Issue:
    Accelerators-unxwnt file is omitted when window system is different than 
X11.
    This causes LOK to miss the shortcuts which has "install:module="unxwnt"" 
signature.
    
    This commit adds the required file in linux case.
    
    Change-Id: I4a8425d17a5d95b03a176153506f29a3f393c173
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/181204
    Tested-by: Jenkins
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>

diff --git a/postprocess/CustomTarget_registry.mk 
b/postprocess/CustomTarget_registry.mk
index d7c7555dc7be..7b5e52edcc12 100644
--- a/postprocess/CustomTarget_registry.mk
+++ b/postprocess/CustomTarget_registry.mk
@@ -293,6 +293,10 @@ postprocess_FILES_main += \
        $(postprocess_MOD)/org/openoffice/VCL-unixdesktop.xcu
                # Inet-unixdesktop.xcu must come after Inet.xcu
                # VCL-unixdesktop.xcu must come after VCL.xcu
+else ifeq (LINUX,$(OS))
+postprocess_FILES_main += \
+       $(postprocess_MOD)/org/openoffice/Office/Accelerators-unxwnt.xcu
+       # This condition is for LOK case. When the windowing system is not X11, 
above condition is not met. So we add the required files here.
 else ifeq (WNT,$(OS))
 postprocess_FILES_main += \
        $(postprocess_MOD)/org/openoffice/Inet-wnt.xcu \
commit 740f820b913c8c116638c5b3b5c308d096545a73
Author:     Caolán McNamara <caolan.mcnam...@collabora.com>
AuthorDate: Tue Jan 21 20:14:01 2025 +0000
Commit:     Andras Timar <andras.ti...@collabora.com>
CommitDate: Sun Feb 9 12:12:22 2025 +0100

    add loading libmswordlo.so to lok_preload_hook
    
    similar to libscfiltlo.so in calc's lok_preload_hook so the module is
    loaded before any chroot might leave the original libs unavailable to
    find.
    
    Change-Id: I94e88dcd488ba15dc7781078796930e10f32b45c
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/180560
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com>

diff --git a/sw/inc/init.hxx b/sw/inc/init.hxx
index 438be221de6c..5c6e358c0a01 100644
--- a/sw/inc/init.hxx
+++ b/sw/inc/init.hxx
@@ -48,11 +48,8 @@ public:
 
     ~Filters();
 #ifndef DISABLE_DYNLOADING
-    oslGenericFunction GetMswordLibSymbol( const char *pSymbol );
+    static oslGenericFunction GetMswordLibSymbol( const char *pSymbol );
 #endif
-
-private:
-    osl::Module msword_;
 };
 
 }
diff --git a/sw/source/filter/basflt/fltini.cxx 
b/sw/source/filter/basflt/fltini.cxx
index 6e37bfb1ebb3..744ec4a1379d 100644
--- a/sw/source/filter/basflt/fltini.cxx
+++ b/sw/source/filter/basflt/fltini.cxx
@@ -121,22 +121,22 @@ Filters::~Filters()
             rEntry.pReader = nullptr;
         }
     }
-    msword_.release();
 }
 
 #ifndef DISABLE_DYNLOADING
 
 oslGenericFunction Filters::GetMswordLibSymbol( const char *pSymbol )
 {
-    if (!msword_.is())
+    static ::osl::Module aModule;
+    if (!aModule.is())
     {
         OUString url(u"$LO_LIB_DIR/" SVLIBRARY("msword") ""_ustr);
         rtl::Bootstrap::expandMacros(url);
-        bool ok = msword_.load( url, SAL_LOADMODULE_GLOBAL | 
SAL_LOADMODULE_LAZY );
+        bool ok = aModule.load( url, SAL_LOADMODULE_GLOBAL | 
SAL_LOADMODULE_LAZY );
         SAL_WARN_IF(!ok, "sw", "failed to load msword library");
     }
-    if (msword_.is())
-        return msword_.getFunctionSymbol( OUString::createFromAscii( pSymbol ) 
);
+    if (aModule.is())
+        return aModule.getFunctionSymbol( OUString::createFromAscii( pSymbol ) 
);
     return nullptr;
 }
 
@@ -627,7 +627,7 @@ Reader* GetRTFReader()
 {
 #ifndef DISABLE_DYNLOADING
 
-    FnGetReader pFunction = reinterpret_cast<FnGetReader>( 
SwGlobals::getFilters().GetMswordLibSymbol( "ImportRTF" ) );
+    FnGetReader pFunction = reinterpret_cast<FnGetReader>( 
sw::Filters::GetMswordLibSymbol( "ImportRTF" ) );
 
     if ( pFunction )
         return (*pFunction)();
@@ -642,7 +642,7 @@ Reader* GetRTFReader()
 void GetRTFWriter( std::u16string_view rFltName, const OUString& rBaseURL, 
WriterRef& xRet )
 {
 #ifndef DISABLE_DYNLOADING
-    FnGetWriter pFunction = reinterpret_cast<FnGetWriter>( 
SwGlobals::getFilters().GetMswordLibSymbol( "ExportRTF" ) );
+    FnGetWriter pFunction = reinterpret_cast<FnGetWriter>( 
sw::Filters::GetMswordLibSymbol( "ExportRTF" ) );
 
     if ( pFunction )
         (*pFunction)( rFltName, rBaseURL, xRet );
@@ -656,7 +656,7 @@ void GetRTFWriter( std::u16string_view rFltName, const 
OUString& rBaseURL, Write
 Reader* GetWW8Reader()
 {
 #ifndef DISABLE_DYNLOADING
-    FnGetReader pFunction = reinterpret_cast<FnGetReader>( 
SwGlobals::getFilters().GetMswordLibSymbol( "ImportDOC" ) );
+    FnGetReader pFunction = reinterpret_cast<FnGetReader>( 
sw::Filters::GetMswordLibSymbol( "ImportDOC" ) );
 
     if ( pFunction )
         return (*pFunction)();
@@ -670,7 +670,7 @@ Reader* GetWW8Reader()
 void GetWW8Writer( std::u16string_view rFltName, const OUString& rBaseURL, 
WriterRef& xRet )
 {
 #ifndef DISABLE_DYNLOADING
-    FnGetWriter pFunction = reinterpret_cast<FnGetWriter>( 
SwGlobals::getFilters().GetMswordLibSymbol( "ExportDOC" ) );
+    FnGetWriter pFunction = reinterpret_cast<FnGetWriter>( 
sw::Filters::GetMswordLibSymbol( "ExportDOC" ) );
 
     if ( pFunction )
         (*pFunction)( rFltName, rBaseURL, xRet );
@@ -684,7 +684,7 @@ void GetWW8Writer( std::u16string_view rFltName, const 
OUString& rBaseURL, Write
 Reader* GetDOCXReader()
 {
 #ifndef DISABLE_DYNLOADING
-    FnGetReader pFunction = reinterpret_cast<FnGetReader>( 
SwGlobals::getFilters().GetMswordLibSymbol( "ImportDOCX" ) );
+    FnGetReader pFunction = reinterpret_cast<FnGetReader>( 
sw::Filters::GetMswordLibSymbol( "ImportDOCX" ) );
 
     if ( pFunction )
         return (*pFunction)();
@@ -701,7 +701,7 @@ typedef sal_uInt32 ( *GetSaveWarning )( SfxObjectShell& );
 ErrCode SaveOrDelMSVBAStorage( SfxObjectShell& rDoc, SotStorage& rStor, bool 
bSaveInto, const OUString& rStorageName )
 {
 #ifndef DISABLE_DYNLOADING
-    SaveOrDel pFunction = reinterpret_cast<SaveOrDel>( 
SwGlobals::getFilters().GetMswordLibSymbol( "SaveOrDelMSVBAStorage_ww8" ) );
+    SaveOrDel pFunction = reinterpret_cast<SaveOrDel>( 
sw::Filters::GetMswordLibSymbol( "SaveOrDelMSVBAStorage_ww8" ) );
     if( pFunction )
         return ErrCode(pFunction( rDoc, rStor, bSaveInto, rStorageName ));
     return ERRCODE_NONE;
@@ -713,7 +713,7 @@ ErrCode SaveOrDelMSVBAStorage( SfxObjectShell& rDoc, 
SotStorage& rStor, bool bSa
 ErrCode GetSaveWarningOfMSVBAStorage( SfxObjectShell &rDocS )
 {
 #ifndef DISABLE_DYNLOADING
-    GetSaveWarning pFunction = reinterpret_cast<GetSaveWarning>( 
SwGlobals::getFilters().GetMswordLibSymbol( "GetSaveWarningOfMSVBAStorage_ww8" 
) );
+    GetSaveWarning pFunction = reinterpret_cast<GetSaveWarning>( 
sw::Filters::GetMswordLibSymbol( "GetSaveWarningOfMSVBAStorage_ww8" ) );
     if( pFunction )
         return ErrCode(pFunction( rDocS ));
     return ERRCODE_NONE;
diff --git a/sw/source/uibase/app/swdll.cxx b/sw/source/uibase/app/swdll.cxx
index a0d0d35773dd..274b0e50c319 100644
--- a/sw/source/uibase/app/swdll.cxx
+++ b/sw/source/uibase/app/swdll.cxx
@@ -176,6 +176,9 @@ sw::Filters & SwDLL::getFilters()
 extern "C" SAL_DLLPUBLIC_EXPORT
 void lok_preload_hook()
 {
+    // msword (any symbol will do)
+    sw::Filters::GetMswordLibSymbol("ImportDOC");
+    // swui
     SwAbstractDialogFactory::Create();
 }
 
commit e724004aac8026837dd8381bf61523253d03627b
Author:     Jaume Pujantell <jaume.pujant...@collabora.com>
AuthorDate: Thu Jan 30 12:11:39 2025 +0100
Commit:     Andras Timar <andras.ti...@collabora.com>
CommitDate: Sun Feb 9 11:56:04 2025 +0100

    lok: allow save on comment only mode
    
    Allow execution of .uno:Save command on comment only mode for all types
    of files, not only pdf.
    
    Change-Id: I35387d93d00d709d209d3ed1ba2d315bd20b67d5
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/180940
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>
    (cherry picked from commit adcfa0902b8641a50b11c9fb528bb971993d5f12)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/181026
    Reviewed-by: Jaume Pujantell <jaume.pujant...@collabora.com>
    Tested-by: Jenkins

diff --git a/sfx2/source/control/dispatch.cxx b/sfx2/source/control/dispatch.cxx
index cb0f26e3c4b6..1959b5e81efa 100644
--- a/sfx2/source/control/dispatch.cxx
+++ b/sfx2/source/control/dispatch.cxx
@@ -1543,6 +1543,7 @@ bool SfxDispatcher::IsCommandAllowedInLokReadOnlyViewMode 
(const OUString & comm
         u".uno:DeleteAnnotation"_ustr,
         u".uno:EditAnnotation"_ustr,
         u".uno:PromoteComment"_ustr,
+        u".uno:Save"_ustr,
     };
 
     if (std::find(std::begin(allowedList), std::end(allowedList), commandName) 
!= std::end(allowedList))
commit a12bd4fedfc3f269f1dbb5fea36b607facd1261d
Author:     Jaume Pujantell <jaume.pujant...@collabora.com>
AuthorDate: Tue Jan 28 10:13:11 2025 +0100
Commit:     Andras Timar <andras.ti...@collabora.com>
CommitDate: Sun Feb 9 11:51:38 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 3c09f949ba26..f72f65ba9d90 100644
--- a/include/vcl/graphicfilter.hxx
+++ b/include/vcl/graphicfilter.hxx
@@ -273,10 +273,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.
     ///
@@ -290,7 +291,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();
@@ -318,7 +320,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 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 82eddedd6e45..89108377312a 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.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