cui/uiconfig/ui/pageformatpage.ui                 |    5 +
 cui/uiconfig/ui/paratabspage.ui                   |   20 ++++
 download.lst                                      |    4 
 formula/source/core/api/FormulaCompiler.cxx       |   26 +++++
 oox/source/export/drawingml.cxx                   |  107 +++++++++++++++-------
 sc/source/filter/excel/xistyle.cxx                |   10 +-
 sc/source/ui/inc/gridwin.hxx                      |    1 
 sc/source/ui/view/gridwin.cxx                     |   13 ++
 sd/qa/unit/export-tests-ooxml3.cxx                |    7 +
 sd/qa/unit/tiledrendering/data/TextBoxAndRect.odg |binary
 sd/qa/unit/tiledrendering/tiledrendering.cxx      |   38 +++++++
 sd/source/ui/view/drviews1.cxx                    |    2 
 sd/source/ui/view/drviews7.cxx                    |    1 
 svx/uiconfig/ui/headfootformatpage.ui             |    5 +
 sw/qa/extras/ooxmlexport/ooxmlexport13.cxx        |    6 +
 sw/source/core/txtnode/modeltoviewhelper.cxx      |    2 
 sw/uiconfig/swriter/ui/dropcapspage.ui            |    5 +
 test/source/bootstrapfixture.cxx                  |   64 -------------
 vcl/source/fontsubset/sft.cxx                     |    1 
 19 files changed, 214 insertions(+), 103 deletions(-)

New commits:
commit a02c59f0927fa39911df90614b7b4755deb8da39
Author:     [email protected] <[email protected]>
AuthorDate: Sat Jan 10 18:14:30 2026 -0500
Commit:     Andras Timar <[email protected]>
CommitDate: Fri Jan 16 11:56:08 2026 +0100

    tdf#166335 oox export: don't export invalid gluepoint fmla
    
    We started exporting gluepoints with 25.2.2
    commit/86d36ee56521438069504fbacff8dc2aff3a1afc
        "tdf165262 PPTX export: fix shape export regression"
    and some of them were not in valid OOXML format.
    
    In this case, we were exporting an empty
     fmla=""
    which is seen as a corrupt document by MS Office.
    
    make CppunitTest_sd_export_tests-ooxml3 \
        CPPUNIT_TEST_NAME=testTdf135843
    
    make CppunitTest_sw_ooxmlexport13 CPPUNIT_TEST_NAME=testTdf123435
    
    Change-Id: I4297d24b8e884199b8da0253ab855417b828aa75
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/197003
    Reviewed-by: Justin Luth <[email protected]>
    Tested-by: Jenkins
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/197365
    Reviewed-by: Miklos Vajna <[email protected]>
    Tested-by: Jenkins CollaboraOffice <[email protected]>

diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx
index 6dfb8357c6aa..46d3036a19e1 100644
--- a/oox/source/export/drawingml.cxx
+++ b/oox/source/export/drawingml.cxx
@@ -4929,23 +4929,49 @@ bool IsValidOOXMLFormula(std::u16string_view sFormula)
     return false;
 }
 
-OUString GetFormula(const OUString& sEquation, const OUString& sReplace, const 
OUString& sNewStr)
+OUString GetFormula(const OUString& sEquation)
 {
+    assert(!sEquation.isEmpty() && "surely an equation would never be 
empty...");
+    // TODO: This needs to be completely re-written. It is extremely 
simplistic/minimal.
+    // What is needed here is the reverse of convertToOOEquation.
+
     // If the equation is numerical
     sal_Int64 nValue = sEquation.toInt64();
-    if (!sEquation.isEmpty() && OUString::number(nValue) == sEquation)
+    if (OUString::number(nValue) == sEquation)
         return "val " + sEquation;
 
     OUString sFormula = sEquation;
-    size_t nPos = sFormula.indexOf(sReplace);
-    if (nPos != std::string::npos)
+
+    /* replace LO native placeholders with OOXML placeholders
+     * #1: e.g. 'logwidth'
+     * #2: e.g. 'logwidth/2'
+     * #3: e.g. '1234*logwidth/5678'
+     */
+
+    if (sEquation == "logwidth") // #1
+        return "val w";
+    if (sEquation == "logheight")
+        return "val h";
+    if (sEquation.startsWith("logwidth/")) // #2
+        sFormula = u"*/ 1 w "_ustr + sEquation.subView(9);
+    else if (sEquation.startsWith("logheight/"))
+        sFormula = u"*/ 1 h "_ustr + sEquation.subView(10);
+    else
     {
-        OUString sModifiedEquation = sFormula.replaceAt(nPos, 
sReplace.getLength(), sNewStr);
-        sFormula = "*/ " + sModifiedEquation;
+        size_t nPos = sFormula.indexOf("*logwidth/"); //#3
+        if (nPos != std::string::npos)
+            sFormula = "*/ " + sFormula.replaceAt(nPos, 10, " w ");
+        else
+        {
+            nPos = sFormula.indexOf("*logheight/");
+            if (nPos != std::string::npos)
+                sFormula = "*/ " + sFormula.replaceAt(nPos, 11, " h ");
+        }
     }
 
     if (IsValidOOXMLFormula(sFormula))
         return sFormula;
+    else SAL_WARN("oox.shape","invalid OOXML formula["<<sFormula<<"]");
 
     return OUString();
 }
@@ -4953,44 +4979,60 @@ OUString GetFormula(const OUString& sEquation, const 
OUString& sReplace, const O
 void prepareGluePoints(std::vector<Guide>& rGuideList,
                        const css::uno::Sequence<OUString>& aEquations,
                        const 
uno::Sequence<drawing::EnhancedCustomShapeParameterPair>& rGluePoints,
-                       const bool bIsOOXML, const sal_Int32 nWidth, const 
sal_Int32 nHeight)
+                       const bool /*bIsOOXML*/, const sal_Int32 nWidth, const 
sal_Int32 nHeight)
 {
     if (rGluePoints.hasElements())
     {
-        sal_Int32 nIndex = 1;
+        sal_Int32 nIndex = 0;
         for (auto const& rGluePoint : rGluePoints)
         {
+            ++nIndex;
             sal_Int32 nIdx1 = -1;
             sal_Int32 nIdx2 = -1;
-            rGluePoint.First.Value >>= nIdx1;
-            rGluePoint.Second.Value >>= nIdx2;
-
-            if (nIdx1 != -1 && nIdx2 != -1)
+            bool bValidIdx1 = false;
+            bool bValidIdx2 = false;
+            if (rGluePoint.First.Value >>= nIdx1)
             {
-                Guide aGuideX;
-                aGuideX.sName = "GluePoint"_ostr + OString::number(nIndex) + 
"X";
-
-                if (bIsOOXML && nIdx1 >= 0 && nIdx1 < aEquations.getLength())
-                    aGuideX.sFormula = GetFormula(aEquations[nIdx1], 
"*logwidth/", " w ").toUtf8();
-                if (aGuideX.sFormula.isEmpty())
-                    aGuideX.sFormula
-                        = "*/ " + OString::number(nIdx1) + " w " + 
OString::number(nWidth);
-
-                rGuideList.push_back(aGuideX);
-
-                Guide aGuideY;
-                aGuideY.sName = "GluePoint"_ostr + OString::number(nIndex) + 
"Y";
+                bValidIdx1 = rGluePoint.First.Type == 
EnhancedCustomShapeParameterType::EQUATION;
+                // I would assume that any EQUATION must define a valid index 
value.
+                assert(!bValidIdx1 || (nIdx1 >= 0 && nIdx1 < 
aEquations.getLength()));
+            }
+            else
+                continue;
 
-                if (bIsOOXML && nIdx2 >= 0 && nIdx2 < aEquations.getLength())
-                    aGuideY.sFormula = GetFormula(aEquations[nIdx2], 
"*logheight/", " h ").toUtf8();
-                if (aGuideY.sFormula.isEmpty())
-                    aGuideY.sFormula
-                        = "*/ " + OString::number(nIdx2) + " h " + 
OString::number(nHeight);
+            if (rGluePoint.Second.Value >>= nIdx2)
+            {
+                bValidIdx2 = rGluePoint.Second.Type == 
EnhancedCustomShapeParameterType::EQUATION;
+                assert(!bValidIdx2 || (nIdx2 >= 0 && nIdx2 < 
aEquations.getLength()));
+            }
+            else
+                continue;
 
-                rGuideList.push_back(aGuideY);
+            Guide aGuideX;
+            Guide aGuideY;
+            if (bValidIdx1)
+            {
+                aGuideX.sFormula = GetFormula(aEquations[nIdx1]).toUtf8();
+                if (aGuideX.sFormula.isEmpty()) // !IsValidOOXMLFormula
+                    continue;
             }
+            else
+                aGuideX.sFormula = "*/ " + OString::number(nIdx1) + " w " + 
OString::number(nWidth);
+            if (bValidIdx2)
+            {
+                aGuideY.sFormula = GetFormula(aEquations[nIdx2]).toUtf8();
+                if (aGuideY.sFormula.isEmpty()) // !IsValidOOXMLFormula
+                    continue;
+            }
+            else
+                aGuideY.sFormula
+                    = "*/ " + OString::number(nIdx2) + " h " + 
OString::number(nHeight);
+
+            aGuideX.sName = "GluePoint"_ostr + OString::number(nIndex) + "X";
+            rGuideList.push_back(aGuideX);
 
-            nIndex++;
+            aGuideY.sName = "GluePoint"_ostr + OString::number(nIndex) + "Y";
+            rGuideList.push_back(aGuideY);
         }
     }
 }
@@ -5184,6 +5226,7 @@ bool DrawingML::WriteCustomGeometry(
         mpFS->startElementNS(XML_a, XML_gdLst);
         for (auto const& elem : aGuideList)
         {
+            assert(IsValidOOXMLFormula(OUString::fromUtf8(elem.sFormula)));
             mpFS->singleElementNS(XML_a, XML_gd, XML_name, elem.sName, 
XML_fmla, elem.sFormula);
         }
         mpFS->endElementNS(XML_a, XML_gdLst);
diff --git a/sd/qa/unit/export-tests-ooxml3.cxx 
b/sd/qa/unit/export-tests-ooxml3.cxx
index 3053439ab59a..fdcd231fc974 100644
--- a/sd/qa/unit/export-tests-ooxml3.cxx
+++ b/sd/qa/unit/export-tests-ooxml3.cxx
@@ -1071,6 +1071,13 @@ CPPUNIT_TEST_FIXTURE(SdOOXMLExportTest3, testTdf135843)
     assertXPath(pXmlDoc, sPathStart + 
"/a:tr[3]/a:tc[1]/a:tcPr/a:lnR/a:solidFill");
     assertXPath(pXmlDoc, sPathStart + 
"/a:tr[3]/a:tc[1]/a:tcPr/a:lnT/a:solidFill");
     assertXPath(pXmlDoc, sPathStart + 
"/a:tr[3]/a:tc[1]/a:tcPr/a:lnB/a:solidFill");
+
+    // tdf#166335: fmla must not be an empty string
+    static constexpr OString 
sGlueStart("/p:sld/p:cSld/p:spTree/p:sp[3]/p:spPr/a:custGeom"_ostr);
+    assertXPath(pXmlDoc, sGlueStart + "/a:gdLst/a:gd[@name='GluePoint2X']", 
"fmla", u"val w");
+    assertXPath(pXmlDoc, sGlueStart + "/a:gdLst/a:gd[@name='GluePoint2Y']", 
"fmla", u"*/ 1 h 2");
+    assertXPath(pXmlDoc, sGlueStart + "/a:gdLst/a:gd[@name='GluePoint3X']", 
"fmla", u"*/ 1 w 2");
+    assertXPath(pXmlDoc, sGlueStart + "/a:gdLst/a:gd[@name='GluePoint3Y']", 
"fmla", u"val h");
 }
 
 CPPUNIT_TEST_FIXTURE(SdOOXMLExportTest3, testNegativeTimeAnimateValue)
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx
index 43c16d0c912d..75e6ae776e66 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx
@@ -671,6 +671,12 @@ DECLARE_OOXMLEXPORT_TEST(testTdf123435, "tdf123435.docx")
     // - Expected: 2
     // - Actual  : 1
     CPPUNIT_ASSERT_EQUAL(2, getShapes());
+
+    // tdf#166335: fmla must not be an empty string
+    save(TestFilter::DOCX);
+    xmlDocUniquePtr pXmlDoc = parseExport(u"word/document.xml"_ustr);
+    // without the fix, this was 8. Having an a:gd fmla="" causes MSOffice to 
report a corrupt doc.
+    assertXPath(pXmlDoc, "//a:gdLst/a:gd[@fmla='']", 0);
 }
 
 CPPUNIT_TEST_FIXTURE(Test, testTdf116371)
commit 2e9b2af3fa6aab00f7e364ede4ba912a5fe82493
Author:     Mike Kaganski <[email protected]>
AuthorDate: Wed Jan 14 09:31:30 2026 +0100
Commit:     Andras Timar <[email protected]>
CommitDate: Fri Jan 16 11:56:07 2026 +0100

    Improve assertion for the problematic case
    
    ... after commit 2b089278f3732ea35b14cd4c577b6f496bfc0998
    (sw: fix crash in the ModelToViewHelper ctor, 2026-01-06).
    
    Change-Id: I4946363569fc847d8697df9b74be4c646fb6bd99
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/197332
    Reviewed-by: Miklos Vajna <[email protected]>
    Tested-by: Jenkins CollaboraOffice <[email protected]>

diff --git a/sw/source/core/txtnode/modeltoviewhelper.cxx 
b/sw/source/core/txtnode/modeltoviewhelper.cxx
index 2573d273e460..e88d09040a04 100644
--- a/sw/source/core/txtnode/modeltoviewhelper.cxx
+++ b/sw/source/core/txtnode/modeltoviewhelper.cxx
@@ -203,7 +203,7 @@ ModelToViewHelper::ModelToViewHelper(const SwTextNode 
&rNode,
                 }
                 case CH_TXT_ATR_FIELDEND:
                 {
-                    assert(startedFields.back().first == 
rIDMA.getFieldmarkAt(SwPosition(rNode, i)));
+                    assert(!startedFields.empty() && 
startedFields.back().first == rIDMA.getFieldmarkAt(SwPosition(rNode, i)));
                     if (!startedFields.empty())
                     {
                         startedFields.pop_back();
commit 10a401f7064ad9b541322962686de41f88f80fe6
Author:     Caolán McNamara <[email protected]>
AuthorDate: Thu Jan 15 16:14:28 2026 +0000
Commit:     Andras Timar <[email protected]>
CommitDate: Fri Jan 16 11:56:07 2026 +0100

    remove unneeded test file
    
    Change-Id: Idd319ebc74d7468b5d55600d4dce0e7f73629449
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/197371
    Tested-by: Jenkins CollaboraOffice <[email protected]>
    Reviewed-by: Caolán McNamara <[email protected]>

diff --git a/sd/qa/unit/tiledrendering/data/Type-in-draw.odg 
b/sd/qa/unit/tiledrendering/data/Type-in-draw.odg
deleted file mode 100644
index afac468f1926..000000000000
Binary files a/sd/qa/unit/tiledrendering/data/Type-in-draw.odg and /dev/null 
differ
commit 6d14c3b1ad7e57aecc719ddbc517333eb2f3ac8d
Author:     Parth Raiyani <[email protected]>
AuthorDate: Thu Jan 15 18:53:15 2026 +0530
Commit:     Andras Timar <[email protected]>
CommitDate: Fri Jan 16 11:56:07 2026 +0100

    accessibility: add accessible names to various drawing areas in UI files
    
    Signed-off-by: Parth Raiyani <[email protected]>
    Change-Id: Ibef8171634fb406cea708bd8709906f002d2f235
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/197353
    Tested-by: Caolán McNamara <[email protected]>
    Reviewed-by: Caolán McNamara <[email protected]>

diff --git a/cui/uiconfig/ui/pageformatpage.ui 
b/cui/uiconfig/ui/pageformatpage.ui
index 586079e669e9..a680f0c3b25d 100644
--- a/cui/uiconfig/ui/pageformatpage.ui
+++ b/cui/uiconfig/ui/pageformatpage.ui
@@ -220,6 +220,11 @@
                     <property name="halign">center</property>
                     <property name="valign">center</property>
                     <property name="vexpand">True</property>
+                    <child internal-child="accessible">
+                      <object class="AtkObject" 
id="drawingareaPageDirection-atkobject">
+                        <property name="AtkObject::accessible-name" 
translatable="yes" 
context="pageformatpage|drawingareaPageDirection-atkobject">Page 
Direction</property>
+                      </object>
+                    </child>
                   </object>
                   <packing>
                     <property name="left-attach">0</property>
diff --git a/cui/uiconfig/ui/paratabspage.ui b/cui/uiconfig/ui/paratabspage.ui
index 56f3299e5814..a6fd96643672 100644
--- a/cui/uiconfig/ui/paratabspage.ui
+++ b/cui/uiconfig/ui/paratabspage.ui
@@ -173,6 +173,11 @@
               <object class="GtkDrawingArea" id="drawingareaWIN_TABLEFT">
                 <property name="visible">True</property>
                 <property name="can_focus">False</property>
+                <child internal-child="accessible">
+                  <object class="AtkObject" 
id="drawingareaWIN_TABLEFT-atkobject">
+                    <property name="AtkObject::accessible-name" 
translatable="yes" context="paratabspage|drawingareaWIN_TABLEFT-atkobject">Left 
tab preview</property>
+                  </object>
+                </child>
               </object>
               <packing>
                 <property name="left_attach">1</property>
@@ -183,6 +188,11 @@
               <object class="GtkDrawingArea" id="drawingareaWIN_TABRIGHT">
                 <property name="visible">True</property>
                 <property name="can_focus">False</property>
+                <child internal-child="accessible">
+                  <object class="AtkObject" 
id="drawingareaWIN_TABRIGHT-atkobject">
+                    <property name="AtkObject::accessible-name" 
translatable="yes" 
context="paratabspage|drawingareaWIN_TABRIGHT-atkobject">Right tab 
preview</property>
+                  </object>
+                </child>
               </object>
               <packing>
                 <property name="left_attach">1</property>
@@ -193,6 +203,11 @@
               <object class="GtkDrawingArea" id="drawingareaWIN_TABCENTER">
                 <property name="visible">True</property>
                 <property name="can_focus">False</property>
+                <child internal-child="accessible">
+                  <object class="AtkObject" 
id="drawingareaWIN_TABCENTER-atkobject">
+                    <property name="AtkObject::accessible-name" 
translatable="yes" 
context="paratabspage|drawingareaWIN_TABCENTER-atkobject">Center tab 
preview</property>
+                  </object>
+                </child>
               </object>
               <packing>
                 <property name="left_attach">1</property>
@@ -203,6 +218,11 @@
               <object class="GtkDrawingArea" id="drawingareaWIN_TABDECIMAL">
                 <property name="visible">True</property>
                 <property name="can_focus">False</property>
+                <child internal-child="accessible">
+                  <object class="AtkObject" 
id="drawingareaWIN_TABDECIMAL-atkobject">
+                    <property name="AtkObject::accessible-name" 
translatable="yes" 
context="paratabspage|drawingareaWIN_TABDECIMAL-atkobject">Decimal tab 
preview</property>
+                  </object>
+                </child>
               </object>
               <packing>
                 <property name="left_attach">1</property>
diff --git a/svx/uiconfig/ui/headfootformatpage.ui 
b/svx/uiconfig/ui/headfootformatpage.ui
index ffb2774b3f8b..bdad1120afeb 100644
--- a/svx/uiconfig/ui/headfootformatpage.ui
+++ b/svx/uiconfig/ui/headfootformatpage.ui
@@ -372,6 +372,11 @@
             <property name="valign">center</property>
             <property name="hexpand">True</property>
             <property name="vexpand">True</property>
+            <child internal-child="accessible">
+              <object class="AtkObject" id="drawingareaPageHF-atkobject">
+                <property name="AtkObject::accessible-name" translatable="yes" 
context="headfootformatpage|drawingareaPageHF-atkobject">Header and Footer 
Preview</property>
+              </object>
+            </child>
           </object>
           <packing>
             <property name="expand">False</property>
diff --git a/sw/uiconfig/swriter/ui/dropcapspage.ui 
b/sw/uiconfig/swriter/ui/dropcapspage.ui
index cf6d04c20347..6d3a52069c08 100644
--- a/sw/uiconfig/swriter/ui/dropcapspage.ui
+++ b/sw/uiconfig/swriter/ui/dropcapspage.ui
@@ -331,6 +331,11 @@
                 <property name="can-focus">False</property>
                 <property name="halign">center</property>
                 <property name="valign">start</property>
+                <child internal-child="accessible">
+                  <object class="AtkObject" 
id="drawingareaWN_EXAMPLE-atkobject">
+                    <property name="AtkObject::accessible-name" 
translatable="yes" 
context="dropcapspage|drawingareaWN_EXAMPLE-atkobject">Example</property>
+                  </object>
+                </child>
               </object>
             </child>
           </object>
commit a03e519cd858ba68e30e59643981dca9135127f8
Author:     Caolán McNamara <[email protected]>
AuthorDate: Thu Jan 15 09:39:14 2026 +0000
Commit:     Andras Timar <[email protected]>
CommitDate: Fri Jan 16 11:56:07 2026 +0100

    kit: Don't exit shape edit mode due to a view-switch
    
    View1 - enters text edit mode in a shape on page A
    View2 - enters text edit mode in a shape on page B
    
    There is a view switch from B to A and back to B, in which case View2
    should remain in shape edit mode and not auto-exit.
    
    Change-Id: I55f492903c80a347cd7f8287d5a60d20628f69b0
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/197340
    Tested-by: Jenkins CollaboraOffice <[email protected]>
    Reviewed-by: Caolán McNamara <[email protected]>

diff --git a/sd/qa/unit/tiledrendering/data/TextBoxAndRect.odg 
b/sd/qa/unit/tiledrendering/data/TextBoxAndRect.odg
index aa1a37b83147..d715f8180052 100644
Binary files a/sd/qa/unit/tiledrendering/data/TextBoxAndRect.odg and 
b/sd/qa/unit/tiledrendering/data/TextBoxAndRect.odg differ
diff --git a/sd/qa/unit/tiledrendering/data/Type-in-draw.odg 
b/sd/qa/unit/tiledrendering/data/Type-in-draw.odg
new file mode 100644
index 000000000000..afac468f1926
Binary files /dev/null and b/sd/qa/unit/tiledrendering/data/Type-in-draw.odg 
differ
diff --git a/sd/qa/unit/tiledrendering/tiledrendering.cxx 
b/sd/qa/unit/tiledrendering/tiledrendering.cxx
index c0a68aeea3de..64a791b01c02 100644
--- a/sd/qa/unit/tiledrendering/tiledrendering.cxx
+++ b/sd/qa/unit/tiledrendering/tiledrendering.cxx
@@ -2647,6 +2647,44 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, 
testShapeEditInMultipleViews)
         CPPUNIT_ASSERT_EQUAL(false, pView1->IsTextEdit());
         CPPUNIT_ASSERT_EQUAL(false, pView2->IsTextEdit());
     }
+
+    // Scenario 4
+    // View1 - enters text edit mode in a shape on page A
+    // View2 - enters text edit mode in a shape on page B
+    // there is a view switch from B to A and back to B.
+    // View2 should remain in shape edit mode and not exit
+    // shape edit mode on switching back to view2
+    {
+        CPPUNIT_ASSERT_EQUAL(false, pView1->IsTextEdit());
+        CPPUNIT_ASSERT_EQUAL(false, pView2->IsTextEdit());
+
+        // Switch to view 1
+        SfxLokHelper::setView(nView1);
+        pView1->SdrBeginTextEdit(pTextBoxObject);
+
+        SfxLokHelper::setView(nView2);
+        pXImpressDocument->setPart(2);
+        SdPage* pPage3 = pViewShell2->GetActualPage();
+
+        CPPUNIT_ASSERT_MESSAGE("Page Change didn't work", pPage1 != pPage3);
+
+        SdrObject* pPage3TextBoxObject = pPage3->GetObj(0);
+        CPPUNIT_ASSERT_EQUAL(u"Text Box 1"_ustr, 
pPage3TextBoxObject->GetName());
+
+        pView2->SdrBeginTextEdit(pPage3TextBoxObject);
+        CPPUNIT_ASSERT_EQUAL(true, pView2->IsTextEdit());
+
+        SfxLokHelper::setView(nView1);
+        pXImpressDocument->setPart(0);
+
+        CPPUNIT_ASSERT_EQUAL(true, pView2->IsTextEdit());
+
+        SfxLokHelper::setView(nView2);
+        pXImpressDocument->setPart(2);
+
+        // Fails before fix
+        CPPUNIT_ASSERT_EQUAL(true, pView2->IsTextEdit());
+    }
 }
 
 CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testSidebarHide)
diff --git a/sd/source/ui/view/drviews1.cxx b/sd/source/ui/view/drviews1.cxx
index 7c5756bdb6ca..0f2102119901 100644
--- a/sd/source/ui/view/drviews1.cxx
+++ b/sd/source/ui/view/drviews1.cxx
@@ -946,7 +946,7 @@ bool DrawViewShell::SwitchPage(sal_uInt16 nSelectedPage, 
bool bAllowChangeFocus,
             }
         }
 
-        if (bAllowChangeFocus)
+        if (bAllowChangeFocus && !SfxLokHelper::isSettingView())
             mpDrawView->SdrEndTextEdit();
 
         mpActualPage = nullptr;
commit 61c9003b67dacc33c3a2a5b7b8a6a7243f498109
Author:     Karthik Godha <[email protected]>
AuthorDate: Mon Jan 12 19:15:00 2026 +0530
Commit:     Andras Timar <[email protected]>
CommitDate: Fri Jan 16 11:56:07 2026 +0100

    XLSX - Skip unknown functions in definedName
    
    Skip export of ocNoName token during XLSX export, which is associated
    with unknown functions
    
    bug document: forum-de2-3313.xls
    
    Change-Id: I3db50028cd7a0f78d214d2af7e73b71e8e5f233a
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/197113
    Tested-by: Jenkins CollaboraOffice <[email protected]>
    Reviewed-by: Michael Stahl <[email protected]>

diff --git a/formula/source/core/api/FormulaCompiler.cxx 
b/formula/source/core/api/FormulaCompiler.cxx
index 9e9e90cd67c3..62900e0d3f46 100644
--- a/formula/source/core/api/FormulaCompiler.cxx
+++ b/formula/source/core/api/FormulaCompiler.cxx
@@ -2518,7 +2518,31 @@ void FormulaCompiler::CreateStringFromTokenArray( 
OUStringBuffer& rBuffer )
         rBuffer.append( '=');
     const FormulaToken* t = maArrIterator.First();
     while( t )
-        t = CreateStringFromToken( rBuffer, t, true );
+    {
+        // Skip writing unknown functions without a name in OOXML ex: #NAME!()
+        if (t->GetOpCode() == ocNoName && t->GetType() == svByte
+            && FormulaGrammar::isOOXML(meGrammar))
+        {
+            t = maArrIterator.Next();
+            sal_uInt16 nParenthesis = 0;
+            // traverse the array to match parentheses
+            if (t && t->GetOpCode() == ocOpen)
+            {
+                do
+                {
+                    if (t->GetOpCode() == ocOpen)
+                        nParenthesis++;
+                    else if (t->GetOpCode() == ocClose)
+                        nParenthesis--;
+
+                    t = maArrIterator.Next();
+
+                } while (nParenthesis > 0 && t);
+            }
+            continue;
+        }
+        t = CreateStringFromToken(rBuffer, t, true);
+    }
 
     if (pSaveArr != pArr)
     {
commit 3db65255e969f41bb3ab1b1b99b506cf3fa45abc
Author:     Pranam Lashkari <[email protected]>
AuthorDate: Thu Jan 15 03:50:04 2026 +0530
Commit:     Andras Timar <[email protected]>
CommitDate: Fri Jan 16 11:56:07 2026 +0100

    LOK: send notification when autofilter is changed
    
    Change-Id: I4b1e45461099404cffc0fe9cbbc5d45c09736bad
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/197302
    Tested-by: Jenkins CollaboraOffice <[email protected]>
    Reviewed-by: Caolán McNamara <[email protected]>

diff --git a/sc/source/ui/inc/gridwin.hxx b/sc/source/ui/inc/gridwin.hxx
index c9ae75c3b12c..65f5eafc7e40 100644
--- a/sc/source/ui/inc/gridwin.hxx
+++ b/sc/source/ui/inc/gridwin.hxx
@@ -242,6 +242,7 @@ class SAL_DLLPUBLIC_RTTI ScGridWindow : public 
vcl::DocWindow, public DropTarget
     bool            DoPageFieldSelection( SCCOL nCol, SCROW nRow );
     bool            DoAutoFilterButton( SCCOL nCol, SCROW nRow, const 
MouseEvent& rMEvt );
     void            SendAutofilterPopupPosition(SCCOL nCol, SCROW nRow);
+    void            SendAutofilterChange();
     void DoPushPivotButton( SCCOL nCol, SCROW nRow, const MouseEvent& rMEvt, 
bool bButton, bool bPopup, bool bMultiField );
     void DoPushPivotToggle( SCCOL nCol, SCROW nRow, const MouseEvent& rMEvt );
 
diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx
index fae88e84df97..0bab633e1d48 100644
--- a/sc/source/ui/view/gridwin.cxx
+++ b/sc/source/ui/view/gridwin.cxx
@@ -955,6 +955,18 @@ void ScGridWindow::SendAutofilterPopupPosition(SCCOL nCol, 
SCROW nRow) {
     }
 }
 
+void ScGridWindow::SendAutofilterChange() {
+    ScTabViewShell* pViewShell = mrViewData.GetViewShell();
+    if (pViewShell)
+    {
+        tools::JsonWriter writer;
+        writer.put("commandName", "AutoFilterChange");
+        writer.put("state", true);
+        OString info = writer.finishAndGetAsOString();
+        pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_STATE_CHANGED, 
info);
+    }
+}
+
 void ScGridWindow::LaunchAutoFilterMenu(SCCOL nCol, SCROW nRow)
 {
     SCTAB nTab = mrViewData.CurrentTabForData();
@@ -1328,6 +1340,7 @@ void 
ScGridWindow::UpdateAutoFilterFromMenu(AutoFilterMode eMode)
         }
     }
 
+    SendAutofilterChange();
     mrViewData.GetView()->Query(aParam, nullptr, true);
     pDBData->SetQueryParam(aParam);
 }
commit 139dfbb90dad9d75719892b4d975108abf7e898c
Author:     Karthik Godha <[email protected]>
AuthorDate: Wed Jan 14 19:56:54 2026 +0530
Commit:     Andras Timar <[email protected]>
CommitDate: Fri Jan 16 11:56:07 2026 +0100

    XLS -> XLSX: Discard overlapping merge ranges
    
    bug document: forum-en-5338.xls
    
    Change-Id: I5da6b650ae1c73606c6688210ba65f28920eeed4
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/197273
    Reviewed-by: Michael Stahl <[email protected]>
    Tested-by: Jenkins CollaboraOffice <[email protected]>

diff --git a/sc/source/filter/excel/xistyle.cxx 
b/sc/source/filter/excel/xistyle.cxx
index b421ceed9311..002471d6867d 100644
--- a/sc/source/filter/excel/xistyle.cxx
+++ b/sc/source/filter/excel/xistyle.cxx
@@ -1996,8 +1996,14 @@ void XclImpXFRangeBuffer::SetHyperlink( const XclRange& 
rXclRange, const OUStrin
 
 void XclImpXFRangeBuffer::SetMerge( SCCOL nScCol1, SCROW nScRow1, SCCOL 
nScCol2, SCROW nScRow2 )
 {
-    if( (nScCol1 < nScCol2) || (nScRow1 < nScRow2) )
-        maMergeList.push_back( ScRange( nScCol1, nScRow1, 0, nScCol2, nScRow2, 
0 ) );
+    if ((nScCol1 < nScCol2) || (nScRow1 < nScRow2))
+    {
+        ScRange aRange(nScCol1, nScRow1, 0, nScCol2, nScRow2, 0);
+        // If merge range intersects with existing merge ranges then discard 
it.
+        if (maMergeList.Intersects(aRange))
+            return;
+        maMergeList.push_back(aRange);
+    }
 }
 
 void XclImpXFRangeBuffer::Finalize()
commit 48738a96959fabd15bfe5e01f5c113fcc344a56b
Author:     Noel Grandin <[email protected]>
AuthorDate: Tue Jan 13 10:22:47 2026 +0200
Commit:     Andras Timar <[email protected]>
CommitDate: Fri Jan 16 11:56:07 2026 +0100

    we dont need this officeotron workaround anymore
    
    ever since
        commit e4978f9079cda7abb7bb424503d780566c728adf
        Author: Karthik Godha <[email protected]>
        Date:   Mon Nov 24 19:16:51 2025 +0530
        Update OOXML schema to follow ECMA-376 5th edition
    
    which was part of officeotron 0.8.1
    
    Change-Id: I0b9f8ff0d513ced06cda9f4257454ee756b28322
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/197175
    Reviewed-by: Michael Stahl <[email protected]>
    Tested-by: Jenkins
    (cherry picked from commit 4da8f78016adae7da01f3822b87a9422466f26a2)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/197234
    Tested-by: Jenkins CollaboraOffice <[email protected]>

diff --git a/test/source/bootstrapfixture.cxx b/test/source/bootstrapfixture.cxx
index c0297d7d211e..a30b10057738 100644
--- a/test/source/bootstrapfixture.cxx
+++ b/test/source/bootstrapfixture.cxx
@@ -140,58 +140,6 @@ OString loadFile(const OUString& rURL)
 
 constexpr std::u16string_view grand_total = u"Grand total of errors in 
submitted package: ";
 
-OUString filterOut(const OUString& s, std::u16string_view excludedSubstr)
-{
-    OUString result = s;
-    for (;;)
-    {
-        sal_Int32 pos = result.indexOf(excludedSubstr);
-        if (pos < 0)
-            break;
-        sal_Int32 start = result.lastIndexOf('
', pos);
-        if (!result.match("ERROR", start + 1))
-            return s; // unexpected string format
-        sal_Int32 end = result.indexOf('
', pos);
-        result = result.replaceAt(start, end - start, u""_ustr);
-        pos = result.lastIndexOf(grand_total);
-        if (pos < 0)
-            return s; // unexpected string format
-        start = end = pos + grand_total.size();
-        while (end < result.getLength() && rtl::isAsciiDigit(result[end]))
-            ++end;
-        std::u16string_view aNumber = result.subView(start, end - start);
-        sal_Int32 nErrors = o3tl::toInt32(aNumber) - 1;
-        result = result.replaceAt(start, end - start, 
OUString::number(nErrors));
-    }
-    return result;
-}
-
-OUString filterValidationResults(const OUString& s)
-{
-    OUString result = s;
-    // In ECMA-376-1 Second Edition, 2008, there is the following restriction 
for oleObj:
-    //
-    // <xsd:choice minOccurs="1" maxOccurs="1">
-    //  <xsd:element name="embed" type="CT_OleObjectEmbed"/>
-    //  <xsd:element name="link" type="CT_OleObjectLink"/>
-    //  <xsd:element name="pic" type="CT_Picture"/>
-    // </xsd:choice>
-    //
-    // This makes simultaneous use of embed (or link) and pic impossible. This 
was obviously a
-    // mistake; and the following editions of standard fixed it: e.g., in 
ECMA-376-1:2016, that
-    // rule is
-    //
-    // <xsd:choice minOccurs="1" maxOccurs="1">
-    //  <xsd:element name="embed" type="CT_OleObjectEmbed"/>
-    //  <xsd:element name="link" type="CT_OleObjectLink"/>
-    // </xsd:choice>
-    // <xsd:element name="pic" type="CT_Picture" minOccurs="1" maxOccurs="1"/>
-    //
-    // But officeotron only knows the old version...
-    result = filterOut(result, u"Invalid content was found starting with 
element 'p:pic'. No child element is expected at this point.");
-
-    return result;
-}
 }
 #endif
 
@@ -296,7 +244,6 @@ void test::BootstrapFixture::validate(const OUString& 
rPath, std::u16string_view
 
     if( eFormat == test::OOXML && !aContentOUString.isEmpty() )
     {
-        aContentOUString = filterValidationResults(aContentOUString);
         // check for validation errors here
         sal_Int32 nIndex = aContentOUString.lastIndexOf(grand_total);
         if(nIndex == -1)
commit ce28508d5014e179c7336a03fc62b620069bd5e6
Author:     Noel Grandin <[email protected]>
AuthorDate: Tue Jan 13 10:19:57 2026 +0200
Commit:     Andras Timar <[email protected]>
CommitDate: Fri Jan 16 11:56:07 2026 +0100

    update to officeotron 0.8.8
    
    which means we no longer need the workaround
    
    Change-Id: Ibdc47750a7d5eacc9a1e2251e145379f0464b7f4
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/197174
    Tested-by: Jenkins
    Reviewed-by: Noel Grandin <[email protected]>
    (cherry picked from commit 49a1acfd91b9cb30807c42845560b93f87ecc547)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/197233
    Tested-by: Jenkins CollaboraOffice <[email protected]>
    Reviewed-by: Michael Stahl <[email protected]>

diff --git a/download.lst b/download.lst
index 54587bb52103..3e83735a24de 100644
--- a/download.lst
+++ b/download.lst
@@ -607,8 +607,8 @@ ODFVALIDATOR_JAR := 
odfvalidator-0.9.0-RC2-SNAPSHOT-jar-with-dependencies-2726ab
 # three static lines
 # so that git cherry-pick
 # will not run into conflicts
-OFFICEOTRON_SHA256SUM := 
0c2a4227394ac78147387f1c1ff1063e87f2151ffc91f1eb97bb17c2650fa708
-OFFICEOTRON_JAR := officeotron-0.8.5.jar
+OFFICEOTRON_SHA256SUM := 
c72cdcb7fe7cfe917d1fb8766ddbc3f92b6124ecd5fb8c6dc0ddabb74a7e057c
+OFFICEOTRON_JAR := officeotron-0.8.8.jar
 # three static lines
 # so that git cherry-pick
 # will not run into conflicts
diff --git a/test/source/bootstrapfixture.cxx b/test/source/bootstrapfixture.cxx
index 34e48bbb16b0..c0297d7d211e 100644
--- a/test/source/bootstrapfixture.cxx
+++ b/test/source/bootstrapfixture.cxx
@@ -190,17 +190,6 @@ OUString filterValidationResults(const OUString& s)
     // But officeotron only knows the old version...
     result = filterOut(result, u"Invalid content was found starting with 
element 'p:pic'. No child element is expected at this point.");
 
-    {
-        /* While the spec says the core-properties relationship must be
-         *     officedocument/2006/relationships/metadata/core-properties
-         * MS Office actually just writes the ECMA-376-1ST EDITION version
-         * for both ECMA_Transitional and ISO_Transitional formats.
-         *
-         * officeotron doesn't care that clause 15.2.12.1 fails on all 
MSWord-produced output.
-         */
-        result = filterOut(result, u"Entry with MIME type 
\"application/vnd.openxmlformats-package.core-properties+xml\" has unrecognized 
relationship type 
\"http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties\";
 (see ISO/IEC 29500-1:2008, Clause 15.2.12.1)");
-    }
-
     return result;
 }
 }
commit 89279c0e282706ae0353c8afe29b19158c3a716b
Author:     Mohit Marathe <[email protected]>
AuthorDate: Tue Jan 13 19:21:41 2026 +0530
Commit:     Andras Timar <[email protected]>
CommitDate: Fri Jan 16 11:56:07 2026 +0100

    sd: disable .uno:CopySlide when the selected page is canvas page
    
    Signed-off-by: Mohit Marathe <[email protected]>
    Change-Id: Id4f22e768cf43ae91b57b91d922061f7ce21d933
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/197196
    Tested-by: Jenkins CollaboraOffice <[email protected]>
    Reviewed-by: Michael Stahl <[email protected]>

diff --git a/sd/source/ui/view/drviews7.cxx b/sd/source/ui/view/drviews7.cxx
index 44009a6ee9f3..0619ed62124c 100644
--- a/sd/source/ui/view/drviews7.cxx
+++ b/sd/source/ui/view/drviews7.cxx
@@ -861,6 +861,7 @@ void DrawViewShell::GetMenuState( SfxItemSet &rSet )
             rSet.DisableItem(SID_PRESENTATION_LAYOUT);
             rSet.DisableItem(SID_HIDE_SLIDE);
             rSet.DisableItem(SID_SHOW_SLIDE);
+            rSet.DisableItem(SID_COPY_SLIDE);
         }
     }
     else
commit 7542958b542825e6b86fc466582abac3dff2bda1
Author:     Caolán McNamara <[email protected]>
AuthorDate: Mon Jan 12 08:40:55 2026 +0000
Commit:     Andras Timar <[email protected]>
CommitDate: Fri Jan 16 11:56:07 2026 +0100

    cid#1680327 Uninitialized scalar field
    
    Change-Id: Ia823d38011e45dedcf16a06869b6d9b0460ebcd2
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/197073
    Tested-by: Jenkins CollaboraOffice <[email protected]>
    Reviewed-by: Miklos Vajna <[email protected]>

diff --git a/vcl/source/fontsubset/sft.cxx b/vcl/source/fontsubset/sft.cxx
index ee33a18e8178..f1c7408e7c93 100644
--- a/vcl/source/fontsubset/sft.cxx
+++ b/vcl/source/fontsubset/sft.cxx
@@ -982,6 +982,7 @@ AbstractTrueTypeFont::~AbstractTrueTypeFont()
 TrueTypeFont::TrueTypeFont(const char* pFileName, const FontCharMapRef 
xCharMap)
     : AbstractTrueTypeFont(pFileName, xCharMap)
     , fsize(-1)
+    , mmhandle(0)
     , ptr(nullptr)
     , ntables(0)
 {

Reply via email to