summaryrefslogtreecommitdiffstats
path: root/sc/qa
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 09:27:30 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 09:27:30 +0000
commita2baea7faff31d26459dab3668a39eae85e4991b (patch)
treeeaa2048ce9c715481f932dcfe20368e252b77d2f /sc/qa
parentAdding upstream version 4:24.2.0. (diff)
downloadlibreoffice-a2baea7faff31d26459dab3668a39eae85e4991b.tar.xz
libreoffice-a2baea7faff31d26459dab3668a39eae85e4991b.zip
Adding upstream version 4:24.2.1.upstream/4%24.2.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'sc/qa')
-rw-r--r--sc/qa/extras/macros-test.cxx27
-rw-r--r--sc/qa/extras/testdocuments/tdf159412.fods41
-rw-r--r--sc/qa/filter/html/data/bool.html8
-rw-r--r--sc/qa/filter/html/data/text.html8
-rw-r--r--sc/qa/filter/html/html.cxx123
-rw-r--r--sc/qa/uitest/autofilter/autofilterBugs.py24
-rw-r--r--sc/qa/uitest/autofilter2/tdf158314_EmptyError.py94
-rw-r--r--sc/qa/uitest/calc_tests8/navigator.py27
-rw-r--r--sc/qa/unit/data/xlsx/tdf159581_optimalRowHeight.xlsxbin0 -> 7074 bytes
-rw-r--r--sc/qa/unit/subsequent_filters_test2.cxx11
-rw-r--r--sc/qa/unit/tiledrendering/data/invalidate-on-save.odsbin0 -> 10807 bytes
-rw-r--r--sc/qa/unit/tiledrendering/tiledrendering.cxx30
12 files changed, 393 insertions, 0 deletions
diff --git a/sc/qa/extras/macros-test.cxx b/sc/qa/extras/macros-test.cxx
index 4494f3f65b..92878cf2be 100644
--- a/sc/qa/extras/macros-test.cxx
+++ b/sc/qa/extras/macros-test.cxx
@@ -897,6 +897,33 @@ CPPUNIT_TEST_FIXTURE(ScMacrosTest, testTdf116127)
CPPUNIT_ASSERT_EQUAL(Any(true), aRet);
}
+CPPUNIT_TEST_FIXTURE(ScMacrosTest, testTdf159412)
+{
+ // Run a macro, that itself calls two other functions using invoke,
+ // passing a small integer value to agruments of types Long and Double
+ createScDoc("tdf159412.fods");
+
+ css::uno::Any aRet;
+ css::uno::Sequence<sal_Int16> aOutParamIndex;
+ css::uno::Sequence<css::uno::Any> aOutParam;
+ css::uno::Sequence<css::uno::Any> aParams;
+
+ SfxObjectShell::CallXScript(
+ mxComponent,
+ "vnd.sun.Star.script:Standard.Module1.TestInvoke?language=Basic&location=document",
+ aParams, aRet, aOutParamIndex, aOutParam);
+
+ OUString aReturnValue;
+ aRet >>= aReturnValue;
+
+ // Without the fix in place, this test would have failed with
+ // - Expected: 1 Long/2 Double
+ // - Actual : 0 Long/0 Double
+ // i.e., the passed 1 and 2 values were lost.
+
+ CPPUNIT_ASSERT_EQUAL(u"1 Long/2 Double"_ustr, aReturnValue);
+}
+
ScMacrosTest::ScMacrosTest()
: ScModelTestBase("/sc/qa/extras/testdocuments")
{
diff --git a/sc/qa/extras/testdocuments/tdf159412.fods b/sc/qa/extras/testdocuments/tdf159412.fods
new file mode 100644
index 0000000000..ec537dd061
--- /dev/null
+++ b/sc/qa/extras/testdocuments/tdf159412.fods
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<office:document xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:ooo="http://openoffice.org/2004/office" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" office:version="1.3" office:mimetype="application/vnd.oasis.opendocument.spreadsheet">
+ <office:scripts>
+ <office:script script:language="ooo:Basic">
+ <ooo:libraries>
+ <ooo:library-embedded ooo:name="Standard">
+ <ooo:module ooo:name="Module1">
+ <ooo:source-code>REM ***** BASIC *****
+
+Function TestInvoke
+ script = ThisComponent.scriptProvider.getScript(&quot;vnd.sun.star.script:Standard.Module1.S_Ref_Long?language=Basic&amp;location=document&quot;)
+ ret = script.invoke(Array(1), Array(), Array())
+
+ script = ThisComponent.scriptProvider.getScript(&quot;vnd.sun.star.script:Standard.Module1.S_Ref_Dbl?language=Basic&amp;location=document&quot;)
+ ret = ret &amp; &quot;/&quot; &amp; script.invoke(Array(2), Array(), Array())
+
+ TestInvoke = ret
+End Function
+
+Function S_Ref_Long(n As Long)
+ S_Ref_Long = CStr(n) &amp; &quot; &quot; &amp; TypeName(n)
+End Function
+
+Function S_Ref_Dbl(n As Double)
+ S_Ref_Dbl = CStr(n) &amp; &quot; &quot; &amp; TypeName(n)
+End Function
+
+
+ </ooo:source-code>
+ </ooo:module>
+ </ooo:library-embedded>
+ </ooo:libraries>
+ </office:script>
+ </office:scripts>
+ <office:body>
+ <office:spreadsheet>
+ <table:table table:name="Sheet1"/>
+ </office:spreadsheet>
+ </office:body>
+</office:document> \ No newline at end of file
diff --git a/sc/qa/filter/html/data/bool.html b/sc/qa/filter/html/data/bool.html
new file mode 100644
index 0000000000..8fe27993f1
--- /dev/null
+++ b/sc/qa/filter/html/data/bool.html
@@ -0,0 +1,8 @@
+<table>
+ <tr>
+ <td data-sheets-value="{&quot;1&quot;:4,&quot;4&quot;:1}">WAHR</td>
+ </tr>
+ <tr>
+ <td data-sheets-value="{&quot;1&quot;:4,&quot;4&quot;:0}">FALSCH</td>
+ </tr>
+</table>
diff --git a/sc/qa/filter/html/data/text.html b/sc/qa/filter/html/data/text.html
new file mode 100644
index 0000000000..eadb34b5e1
--- /dev/null
+++ b/sc/qa/filter/html/data/text.html
@@ -0,0 +1,8 @@
+<table>
+ <tr>
+ <td data-sheets-value="{&quot;1&quot;:3,&quot;3&quot;:1}">1</td>
+ </tr>
+ <tr>
+ <td data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;01&quot;,&quot;6&quot;:1}">01</td>
+ </tr>
+</table>
diff --git a/sc/qa/filter/html/html.cxx b/sc/qa/filter/html/html.cxx
new file mode 100644
index 0000000000..6ab2cc7fb0
--- /dev/null
+++ b/sc/qa/filter/html/html.cxx
@@ -0,0 +1,123 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <test/unoapixml_test.hxx>
+#include <test/htmltesttools.hxx>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+#include <com/sun/star/table/XCellRange.hpp>
+
+#include <comphelper/propertyvalue.hxx>
+#include <svl/numformat.hxx>
+#include <svl/zformat.hxx>
+
+#include <helper/qahelper.hxx>
+#include <impex.hxx>
+
+using namespace com::sun::star;
+
+namespace
+{
+/// Covers sc/source/filter/html/ fixes.
+class Test : public ScModelTestBase, public HtmlTestTools
+{
+public:
+ Test()
+ : ScModelTestBase("/sc/qa/filter/html/data/")
+ {
+ }
+};
+
+CPPUNIT_TEST_FIXTURE(Test, testTdAsText)
+{
+ // Given a document with an A2 cell that contains "02" as text:
+ OUString aURL = createFileURL(u"text.html");
+
+ // When loading that document to Calc:
+ uno::Sequence<beans::PropertyValue> aParams = {
+ comphelper::makePropertyValue("DocumentService",
+ OUString("com.sun.star.sheet.SpreadsheetDocument")),
+ };
+ loadWithParams(aURL, aParams);
+
+ // Then make sure "01" is not auto-converted to 1, as a number:
+ uno::Reference<sheet::XSpreadsheetDocument> xDocument(mxComponent, uno::UNO_QUERY);
+ uno::Reference<container::XIndexAccess> xSheets(xDocument->getSheets(), uno::UNO_QUERY);
+ uno::Reference<table::XCellRange> xSheet(xSheets->getByIndex(0), uno::UNO_QUERY);
+ uno::Reference<beans::XPropertySet> xCell(xSheet->getCellByPosition(0, 1), uno::UNO_QUERY);
+ table::CellContentType eType{};
+ xCell->getPropertyValue("CellContentType") >>= eType;
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 2 (TEXT)
+ // - Actual : 1 (VALUE)
+ // i.e. data-sheets-value was ignored on import.
+ CPPUNIT_ASSERT_EQUAL(table::CellContentType_TEXT, eType);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testPasteTdAsText)
+{
+ // Given an empty document:
+ createScDoc();
+
+ // When pasting HTML with an A2 cell that contains "01" as text:
+ ScDocument* pDoc = getScDoc();
+ ScAddress aCellPos(/*nColP=*/0, /*nRowP=*/0, /*nTabP=*/0);
+ ScImportExport aImporter(*pDoc, aCellPos);
+ SvFileStream aFile(createFileURL(u"text.html"), StreamMode::READ);
+ SvMemoryStream aMemory;
+ aMemory.WriteStream(aFile);
+ aMemory.Seek(0);
+ CPPUNIT_ASSERT(aImporter.ImportStream(aMemory, OUString(), SotClipboardFormatId::HTML));
+
+ // Then make sure "01" is not auto-converted to 1, as a number:
+ aCellPos = ScAddress(/*nColP=*/0, /*nRowP=*/1, /*nTabP=*/0);
+ CellType eCellType = pDoc->GetCellType(aCellPos);
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 2 (CELLTYPE_STRING)
+ // - Actual : 1 (CELLTYPE_VALUE)
+ // i.e. data-sheets-value was ignored on paste.
+ CPPUNIT_ASSERT_EQUAL(CELLTYPE_STRING, eCellType);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testPasteTdAsBools)
+{
+ // Given an empty document:
+ createScDoc();
+
+ // When pasting HTML with bool cells:
+ ScDocument* pDoc = getScDoc();
+ ScAddress aCellPos(/*nColP=*/0, /*nRowP=*/0, /*nTabP=*/0);
+ ScImportExport aImporter(*pDoc, aCellPos);
+ SvFileStream aFile(createFileURL(u"bool.html"), StreamMode::READ);
+ SvMemoryStream aMemory;
+ aMemory.WriteStream(aFile);
+ aMemory.Seek(0);
+ CPPUNIT_ASSERT(aImporter.ImportStream(aMemory, OUString(), SotClipboardFormatId::HTML));
+
+ // Then make sure A1's type is bool, value is true:
+ sal_uInt32 nNumberFormat = pDoc->GetNumberFormat(/*col=*/0, /*row=*/0, /*tab=*/0);
+ const SvNumberformat* pNumberFormat = pDoc->GetFormatTable()->GetEntry(nNumberFormat);
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: BOOLEAN
+ // - Actual : General
+ // i.e. data-sheets-value's bool case was ignored.
+ CPPUNIT_ASSERT_EQUAL(OUString("BOOLEAN"), pNumberFormat->GetFormatstring());
+ CPPUNIT_ASSERT_EQUAL(static_cast<double>(1), pDoc->GetValue(/*col=*/0, /*row=*/0, /*tab=*/0));
+ // And make sure A2's type is bool, value is true:
+ nNumberFormat = pDoc->GetNumberFormat(/*col=*/0, /*row=*/1, /*tab=*/0);
+ pNumberFormat = pDoc->GetFormatTable()->GetEntry(nNumberFormat);
+ CPPUNIT_ASSERT_EQUAL(OUString("BOOLEAN"), pNumberFormat->GetFormatstring());
+ CPPUNIT_ASSERT_EQUAL(static_cast<double>(0), pDoc->GetValue(/*col=*/0, /*row=*/1, /*tab=*/0));
+}
+}
+
+CPPUNIT_PLUGIN_IMPLEMENT();
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/qa/uitest/autofilter/autofilterBugs.py b/sc/qa/uitest/autofilter/autofilterBugs.py
index 6fa029985f..849351861d 100644
--- a/sc/qa/uitest/autofilter/autofilterBugs.py
+++ b/sc/qa/uitest/autofilter/autofilterBugs.py
@@ -73,6 +73,30 @@ class autofilter(UITestCase):
self.assertEqual(get_state_as_dict(xTreeList.getChild("4"))["Text"], "vröude")
self.assertEqual(get_state_as_dict(xTreeList.getChild("5"))["Text"], "vröudᵉ")
+ def test_tdf158326(self):
+ with self.ui_test.create_doc_in_start_center("calc"):
+ calcDoc = self.xUITest.getTopFocusWindow()
+ xGridWindow = calcDoc.getChild("grid_window")
+ enter_text_to_cell(xGridWindow, "A1", "vröude")
+ enter_text_to_cell(xGridWindow, "A2", "vröudᵉ")
+ enter_text_to_cell(xGridWindow, "A3", "vröude")
+ enter_text_to_cell(xGridWindow, "A4", "vröudᵉ")
+ enter_text_to_cell(xGridWindow, "A5", "vröude")
+ enter_text_to_cell(xGridWindow, "A6", "vröudᵉ")
+ xGridWindow.executeAction("SELECT", mkPropertyValues({"RANGE": "A1:A6"}))
+
+ with self.ui_test.execute_dialog_through_command(".uno:DataFilterAutoFilter", close_button="no"):
+ pass
+
+ xGridWindow.executeAction("LAUNCH", mkPropertyValues({"AUTOFILTER": "", "COL": "0", "ROW": "0"}))
+ xFloatWindow = self.xUITest.getFloatWindow()
+ xTreeList = xFloatWindow.getChild("check_list_box")
+
+ # Without the fix in place, there would be 5 items since they will not be removed
+ self.assertEqual(2, len(xTreeList.getChildren()))
+ self.assertEqual(get_state_as_dict(xTreeList.getChild("0"))["Text"], "vröude")
+ self.assertEqual(get_state_as_dict(xTreeList.getChild("1"))["Text"], "vröudᵉ")
+
def test_tdf94055(self):
with self.ui_test.create_doc_in_start_center("calc") as document:
calcDoc = self.xUITest.getTopFocusWindow()
diff --git a/sc/qa/uitest/autofilter2/tdf158314_EmptyError.py b/sc/qa/uitest/autofilter2/tdf158314_EmptyError.py
new file mode 100644
index 0000000000..2ced88c80d
--- /dev/null
+++ b/sc/qa/uitest/autofilter2/tdf158314_EmptyError.py
@@ -0,0 +1,94 @@
+# -*- tab-width: 4; indent-tabs-mode: nil; py-indent-offset: 4 -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+from uitest.framework import UITestCase
+from uitest.uihelper.calc import enter_text_to_cell
+from uitest.uihelper.common import get_state_as_dict
+from libreoffice.uno.propertyvalue import mkPropertyValues
+from libreoffice.calc.document import is_row_hidden
+
+# Bug 158314 - Autofilter dropdown list always shows "Empty" entry as active
+
+class tdf158314_EmptyEntries(UITestCase):
+ def testTdf158314(self):
+ with self.ui_test.create_doc_in_start_center("calc") as calcDoc:
+ xCalcDoc = self.xUITest.getTopFocusWindow()
+ xGridWin = xCalcDoc.getChild("grid_window")
+
+ # Fill the sheet with test data
+ enter_text_to_cell(xGridWin, "A1", "a")
+ enter_text_to_cell(xGridWin, "A2", "1")
+ enter_text_to_cell(xGridWin, "A3", "2")
+ enter_text_to_cell(xGridWin, "A4", "3")
+ enter_text_to_cell(xGridWin, "A5", "4")
+
+ enter_text_to_cell(xGridWin, "B1", "b")
+ enter_text_to_cell(xGridWin, "B2", "5")
+ enter_text_to_cell(xGridWin, "B3", "")
+ enter_text_to_cell(xGridWin, "B4", "=1/0")
+ enter_text_to_cell(xGridWin, "B5", "8")
+
+ # Select the data range and set autofilter
+ xGridWin.executeAction("SELECT", mkPropertyValues({"RANGE": "A1:B5"}))
+ self.xUITest.executeCommand(".uno:DataFilterAutoFilter")
+
+ # Click the autofilter dropdown in column A
+ xGridWin.executeAction("LAUNCH", mkPropertyValues({"AUTOFILTER": "", "COL": "0", "ROW": "0"}))
+ xFloatWindow = self.xUITest.getFloatWindow()
+ xCheckListMenu = xFloatWindow.getChild("FilterDropDown")
+ xTreeList = xCheckListMenu.getChild("check_list_box")
+
+ # Select the first entry only. Uncheck all other entries.
+ for i in xTreeList.getChildren():
+ if i != "0":
+ xEntry = xTreeList.getChild(i)
+ xEntry.executeAction("CLICK", tuple())
+
+ xOkButton = xFloatWindow.getChild("ok")
+ xOkButton.executeAction("CLICK", tuple())
+
+ # Check that only row#2 is visible
+ self.assertFalse(is_row_hidden(calcDoc, 1))
+ self.assertTrue(is_row_hidden(calcDoc, 2))
+ self.assertTrue(is_row_hidden(calcDoc, 3))
+ self.assertTrue(is_row_hidden(calcDoc, 4))
+
+ # Click the autofilter dropdown in column B
+ xGridWin.executeAction("LAUNCH", mkPropertyValues({"AUTOFILTER": "", "COL": "1", "ROW": "0"}))
+ xFloatWindow = self.xUITest.getFloatWindow()
+ xCheckListMenu = xFloatWindow.getChild("FilterDropDown")
+ xTreeList = xCheckListMenu.getChild("check_list_box")
+
+ # There should be at least one entry in the dropdown
+ # (i.e., the feature of showing inactive autofilter entries may be disabled)
+ self.assertEqual(True, len(xTreeList.getChildren()) >= 1)
+
+ for i in xTreeList.getChildren():
+ state = get_state_as_dict(xTreeList.getChild(i))
+ # The Text of the first element should be '5' and it should be checked and active
+ if i == "0":
+ self.assertEqual("5", state["Text"])
+ self.assertEqual("true", state["IsChecked"])
+ self.assertEqual("true", state["IsSelected"])
+ self.assertEqual("false", state["IsSemiTransparent"])
+ # All other elements (including the Empty and #DIV/0!) should be unchecked and inactive
+ else:
+ self.assertEqual("false", state["IsChecked"])
+ self.assertEqual("false", state["IsSelected"])
+ self.assertEqual("true", state["IsSemiTransparent"])
+
+ # Close the popup window
+ xOkButton = xFloatWindow.getChild("ok")
+ xOkButton.executeAction("CLICK", tuple())
+
+ # Check again that only row#2 is visible
+ self.assertFalse(is_row_hidden(calcDoc, 1))
+ self.assertTrue(is_row_hidden(calcDoc, 2))
+ self.assertTrue(is_row_hidden(calcDoc, 3))
+ self.assertTrue(is_row_hidden(calcDoc, 4))
+# vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/sc/qa/uitest/calc_tests8/navigator.py b/sc/qa/uitest/calc_tests8/navigator.py
index ec8fa2ae9a..9c1769dcf4 100644
--- a/sc/qa/uitest/calc_tests8/navigator.py
+++ b/sc/qa/uitest/calc_tests8/navigator.py
@@ -10,6 +10,7 @@
from uitest.framework import UITestCase
from libreoffice.uno.propertyvalue import mkPropertyValues
from uitest.uihelper.common import get_state_as_dict, get_url_for_data_file
+from uitest.uihelper.calc import enter_text_to_cell
class navigator(UITestCase):
@@ -181,4 +182,30 @@ class navigator(UITestCase):
self.xUITest.executeCommand(".uno:Sidebar")
+
+ def test_tdf158652(self):
+ with self.ui_test.create_doc_in_start_center("calc"):
+ xCalcDoc = self.xUITest.getTopFocusWindow()
+ xGridWin = xCalcDoc.getChild("grid_window")
+
+ self.xUITest.executeCommand(".uno:Sidebar")
+
+ xGridWin.executeAction("SIDEBAR", mkPropertyValues({"PANEL": "ScNavigatorPanel"}))
+
+ xCalcDoc = self.xUITest.getTopFocusWindow()
+ xNavigatorPanel = xCalcDoc.getChild("NavigatorPanel")
+ xContentBox = xNavigatorPanel.getChild('contentbox')
+ enter_text_to_cell(xGridWin, "A1", "1")
+
+ commentText = mkPropertyValues({"Text":"CommentText"})
+ self.xUITest.executeCommandWithParameters(".uno:InsertAnnotation", commentText)
+ xComments = xContentBox.getChild("6")
+ self.assertEqual(len(xComments.getChildren()), 1)
+
+ self.xUITest.executeCommand(".uno:DeleteNote")
+ xComments = xContentBox.getChild("6")
+ self.assertEqual(len(xComments.getChildren()), 0)
+
+ self.xUITest.executeCommand(".uno:Sidebar")
+
# vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/sc/qa/unit/data/xlsx/tdf159581_optimalRowHeight.xlsx b/sc/qa/unit/data/xlsx/tdf159581_optimalRowHeight.xlsx
new file mode 100644
index 0000000000..8df7720804
--- /dev/null
+++ b/sc/qa/unit/data/xlsx/tdf159581_optimalRowHeight.xlsx
Binary files differ
diff --git a/sc/qa/unit/subsequent_filters_test2.cxx b/sc/qa/unit/subsequent_filters_test2.cxx
index dd63f0b8a9..2b8ff43962 100644
--- a/sc/qa/unit/subsequent_filters_test2.cxx
+++ b/sc/qa/unit/subsequent_filters_test2.cxx
@@ -159,6 +159,17 @@ CPPUNIT_TEST_FIXTURE(ScFiltersTest2, testTdf123026_optimalRowHeight)
CPPUNIT_ASSERT_GREATER(2000, nHeight);
}
+CPPUNIT_TEST_FIXTURE(ScFiltersTest2, testTdf159581_optimalRowHeight)
+{
+ createScDoc("xlsx/tdf159581_optimalRowHeight.xlsx");
+ SCTAB nTab = 1;
+ SCROW nRow = 0; // row 1
+ int nHeight = convertTwipToMm100(getScDoc()->GetRowHeight(nRow, nTab, false));
+
+ // Without the fix, this was 2027. It should be 450.
+ CPPUNIT_ASSERT_LESS(500, nHeight);
+}
+
CPPUNIT_TEST_FIXTURE(ScFiltersTest2, testCustomNumFormatHybridCellODS)
{
createScDoc("ods/custom-numfmt-hybrid-cell.ods");
diff --git a/sc/qa/unit/tiledrendering/data/invalidate-on-save.ods b/sc/qa/unit/tiledrendering/data/invalidate-on-save.ods
new file mode 100644
index 0000000000..efe2c225a4
--- /dev/null
+++ b/sc/qa/unit/tiledrendering/data/invalidate-on-save.ods
Binary files differ
diff --git a/sc/qa/unit/tiledrendering/tiledrendering.cxx b/sc/qa/unit/tiledrendering/tiledrendering.cxx
index 00fda9336f..9e07c0c060 100644
--- a/sc/qa/unit/tiledrendering/tiledrendering.cxx
+++ b/sc/qa/unit/tiledrendering/tiledrendering.cxx
@@ -3113,6 +3113,36 @@ CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, testGetViewRenderState)
CPPUNIT_ASSERT_EQUAL(";Default"_ostr, pModelObj->getViewRenderState());
}
+// Saving shouldn't trigger an invalidation
+CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, testNoInvalidateOnSave)
+{
+ comphelper::LibreOfficeKit::setCompatFlag(
+ comphelper::LibreOfficeKit::Compat::scPrintTwipsMsgs);
+
+ loadFromFile(u"invalidate-on-save.ods");
+
+ // .uno:Save modifies the original file, make a copy first
+ saveAndReload("calc8");
+ ScModelObj* pModelObj = comphelper::getFromUnoTunnel<ScModelObj>(mxComponent);
+ CPPUNIT_ASSERT(pModelObj);
+ pModelObj->initializeForTiledRendering(uno::Sequence<beans::PropertyValue>());
+
+ ScTabViewShell* pView = dynamic_cast<ScTabViewShell*>(SfxViewShell::Current());
+ CPPUNIT_ASSERT(pView);
+
+ Scheduler::ProcessEventsToIdle();
+
+ // track invalidations
+ ViewCallback aView;
+
+ uno::Sequence<beans::PropertyValue> aArgs;
+ dispatchCommand(mxComponent, ".uno:Save", aArgs);
+
+ Scheduler::ProcessEventsToIdle();
+
+ CPPUNIT_ASSERT(!aView.m_bInvalidateTiles);
+}
+
CPPUNIT_PLUGIN_IMPLEMENT();
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */