summaryrefslogtreecommitdiffstats
path: root/sc
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 09:27:54 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 09:27:54 +0000
commitadb203bc05e3e36173cbd46b9951f79821a81799 (patch)
tree6e6739df9b3f0a567330a0dd7ee0e03ae70876a3 /sc
parentAdding debian version 4:24.2.0-3. (diff)
downloadlibreoffice-adb203bc05e3e36173cbd46b9951f79821a81799.tar.xz
libreoffice-adb203bc05e3e36173cbd46b9951f79821a81799.zip
Merging upstream version 4:24.2.1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'sc')
-rw-r--r--sc/CppunitTest_sc_filter_html.mk83
-rw-r--r--sc/CppunitTest_sc_filters_test.mk1
-rw-r--r--sc/Module_sc.mk1
-rw-r--r--sc/inc/typedstrdata.hxx10
-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
-rw-r--r--sc/source/core/data/colcontainer.cxx5
-rw-r--r--sc/source/core/data/column3.cxx4
-rw-r--r--sc/source/core/data/dociter.cxx2
-rw-r--r--sc/source/core/data/documen3.cxx2
-rw-r--r--sc/source/core/data/document.cxx4
-rw-r--r--sc/source/core/data/document10.cxx17
-rw-r--r--sc/source/core/data/table2.cxx9
-rw-r--r--sc/source/core/data/table4.cxx2
-rw-r--r--sc/source/core/data/validat.cxx3
-rw-r--r--sc/source/core/tool/compiler.cxx10
-rw-r--r--sc/source/core/tool/typedstrdata.cxx54
-rw-r--r--sc/source/filter/excel/xeroot.cxx6
-rw-r--r--sc/source/filter/excel/xestream.cxx5
-rw-r--r--sc/source/filter/html/htmlpars.cxx53
-rw-r--r--sc/source/filter/inc/htmlpars.hxx3
-rw-r--r--sc/source/filter/rtf/rtfparse.cxx4
-rw-r--r--sc/source/ui/app/inputhdl.cxx3
-rw-r--r--sc/source/ui/app/transobj.cxx46
-rw-r--r--sc/source/ui/cctrl/checklistmenu.cxx9
-rw-r--r--sc/source/ui/navipi/navipi.cxx1
-rw-r--r--sc/source/ui/view/gridwin.cxx140
37 files changed, 750 insertions, 120 deletions
diff --git a/sc/CppunitTest_sc_filter_html.mk b/sc/CppunitTest_sc_filter_html.mk
new file mode 100644
index 0000000000..f3dec22c08
--- /dev/null
+++ b/sc/CppunitTest_sc_filter_html.mk
@@ -0,0 +1,83 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# 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/.
+#
+
+$(eval $(call gb_CppunitTest_CppunitTest,sc_filter_html))
+
+$(eval $(call gb_CppunitTest_use_common_precompiled_header,sc_filter_html))
+
+$(eval $(call gb_CppunitTest_add_exception_objects,sc_filter_html, \
+ sc/qa/filter/html/html \
+))
+
+$(eval $(call gb_CppunitTest_use_externals,sc_filter_html, \
+ boost_headers \
+ libxml2 \
+))
+
+$(eval $(call gb_CppunitTest_use_libraries,sc_filter_html, \
+ basegfx \
+ comphelper \
+ cppu \
+ cppuhelper \
+ drawinglayer \
+ drawinglayercore \
+ editeng \
+ for \
+ forui \
+ i18nlangtag \
+ msfilter \
+ oox \
+ sal \
+ salhelper \
+ sax \
+ sc \
+ scqahelper \
+ sfx \
+ sot \
+ subsequenttest \
+ svl \
+ svt \
+ svx \
+ svxcore \
+ test \
+ tk \
+ tl \
+ ucbhelper \
+ unotest \
+ utl \
+ vcl \
+ xo \
+))
+
+$(eval $(call gb_CppunitTest_set_include,sc_filter_html,\
+ -I$(SRCDIR)/sc/source/ui/inc \
+ -I$(SRCDIR)/sc/inc \
+ -I$(SRCDIR)/sc/qa/unit \
+ $$(INCLUDE) \
+))
+
+$(eval $(call gb_CppunitTest_use_api,sc_filter_html,\
+ udkapi \
+ offapi \
+ oovbaapi \
+))
+
+$(eval $(call gb_CppunitTest_use_packages,sc_filter_html, \
+ filter_xhtml \
+ filter_xslt \
+))
+
+$(eval $(call gb_CppunitTest_use_ure,sc_filter_html))
+$(eval $(call gb_CppunitTest_use_vcl,sc_filter_html))
+
+$(eval $(call gb_CppunitTest_use_rdb,sc_filter_html,services))
+
+$(eval $(call gb_CppunitTest_use_configuration,sc_filter_html))
+
+# vim: set noet sw=4 ts=4:
diff --git a/sc/CppunitTest_sc_filters_test.mk b/sc/CppunitTest_sc_filters_test.mk
index 67ef606640..3dae5136e1 100644
--- a/sc/CppunitTest_sc_filters_test.mk
+++ b/sc/CppunitTest_sc_filters_test.mk
@@ -118,6 +118,7 @@ $(eval $(call gb_CppunitTest_use_components,sc_filters_test,\
uui/util/uui \
vcl/vcl.common \
xmloff/util/xo \
+ xmlsecurity/util/xsec_xmlsec \
))
$(eval $(call gb_CppunitTest_use_configuration,sc_filters_test))
diff --git a/sc/Module_sc.mk b/sc/Module_sc.mk
index 0c2178b7fe..a01c9115f3 100644
--- a/sc/Module_sc.mk
+++ b/sc/Module_sc.mk
@@ -96,6 +96,7 @@ $(eval $(call gb_Module_add_slowcheck_targets,sc, \
CppunitTest_sc_uicalc2 \
CppunitTest_sc_vba_macro_test \
CppunitTest_sc_a11y \
+ CppunitTest_sc_filter_html \
))
ifneq ($(ENABLE_JUMBO_SHEETS),)
diff --git a/sc/inc/typedstrdata.hxx b/sc/inc/typedstrdata.hxx
index b4a9bc5d37..b6bed2dfc2 100644
--- a/sc/inc/typedstrdata.hxx
+++ b/sc/inc/typedstrdata.hxx
@@ -54,11 +54,21 @@ public:
bool operator() (const ScTypedStrData& left, const ScTypedStrData& right) const;
};
+ struct LessSortCaseSensitive
+ {
+ bool operator() (const ScTypedStrData& left, const ScTypedStrData& right) const;
+ };
+
struct LessCaseInsensitive
{
bool operator() (const ScTypedStrData& left, const ScTypedStrData& right) const;
};
+ struct LessSortCaseInsensitive
+ {
+ bool operator() (const ScTypedStrData& left, const ScTypedStrData& right) const;
+ };
+
struct EqualCaseSensitive
{
bool operator() (const ScTypedStrData& left, const ScTypedStrData& right) const;
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: */
diff --git a/sc/source/core/data/colcontainer.cxx b/sc/source/core/data/colcontainer.cxx
index f6ef8ff7da..a0a9d84577 100644
--- a/sc/source/core/data/colcontainer.cxx
+++ b/sc/source/core/data/colcontainer.cxx
@@ -47,10 +47,9 @@ void ScColContainer::Clear()
void ScColContainer::resize( ScSheetLimits const & rSheetLimits, const size_t aNewColSize )
{
size_t aOldColSize = aCols.size();
- if (aNewColSize > aCols.capacity())
- aCols.reserve( aNewColSize );
+ aCols.resize( aNewColSize );
for ( size_t nCol = aOldColSize; nCol < aNewColSize; ++nCol )
- aCols.emplace_back(new ScColumn(rSheetLimits));
+ aCols[nCol].reset(new ScColumn(rSheetLimits));
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index a0b0c639a0..7902722638 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -2584,7 +2584,7 @@ class FilterEntriesHandler
{
if (!mrFilterEntries.mbHasEmpties)
{
- mrFilterEntries.push_back(ScTypedStrData(OUString()));
+ mrFilterEntries.push_back(ScTypedStrData(OUString(), 0.0, 0.0, ScTypedStrData::Standard, false, mbFilteredRow));
mrFilterEntries.mbHasEmpties = true;
}
return;
@@ -2614,7 +2614,7 @@ class FilterEntriesHandler
OUString aErr = ScGlobal::GetErrorString(nErr);
if (!aErr.isEmpty())
{
- mrFilterEntries.push_back(ScTypedStrData(std::move(aErr)));
+ mrFilterEntries.push_back(ScTypedStrData(std::move(aErr), 0.0, 0.0, ScTypedStrData::Standard, false, mbFilteredRow));
return;
}
}
diff --git a/sc/source/core/data/dociter.cxx b/sc/source/core/data/dociter.cxx
index b1fca78c86..1fe1f5344d 100644
--- a/sc/source/core/data/dociter.cxx
+++ b/sc/source/core/data/dociter.cxx
@@ -1683,13 +1683,13 @@ void ScDocRowHeightUpdater::updateAll(const bool bOnlyUsedRows)
ScProgress aProgress(mrDoc.GetDocumentShell(), ScResId(STR_PROGRESS_HEIGHTING), nCellCount, true);
Fraction aZoom(1, 1);
- sc::RowHeightContext aCxt(mrDoc.MaxRow(), mfPPTX, mfPPTY, aZoom, aZoom, mpOutDev);
sal_uInt64 nProgressStart = 0;
for (SCTAB nTab = 0; nTab < mrDoc.GetTableCount(); ++nTab)
{
if (!ValidTab(nTab) || !mrDoc.maTabs[nTab])
continue;
+ sc::RowHeightContext aCxt(mrDoc.MaxRow(), mfPPTX, mfPPTY, aZoom, aZoom, mpOutDev);
SCCOL nEndCol = 0;
SCROW nEndRow = mrDoc.MaxRow();
if (!bOnlyUsedRows || mrDoc.GetPrintArea(nTab, nEndCol, nEndRow))
diff --git a/sc/source/core/data/documen3.cxx b/sc/source/core/data/documen3.cxx
index b42a8d36b5..8ae4ff6c4e 100644
--- a/sc/source/core/data/documen3.cxx
+++ b/sc/source/core/data/documen3.cxx
@@ -89,6 +89,7 @@ void sortAndRemoveDuplicates(std::vector<ScTypedStrData>& rStrings, bool bCaseSe
std::vector<ScTypedStrData>::iterator it =
std::unique(rStrings.begin(), rStrings.end(), ScTypedStrData::EqualCaseSensitive());
rStrings.erase(it, rStrings.end());
+ std::stable_sort(rStrings.begin(), rStrings.end(), ScTypedStrData::LessSortCaseSensitive());
}
else
{
@@ -96,6 +97,7 @@ void sortAndRemoveDuplicates(std::vector<ScTypedStrData>& rStrings, bool bCaseSe
std::vector<ScTypedStrData>::iterator it =
std::unique(rStrings.begin(), rStrings.end(), ScTypedStrData::EqualCaseInsensitive());
rStrings.erase(it, rStrings.end());
+ std::stable_sort(rStrings.begin(), rStrings.end(), ScTypedStrData::LessSortCaseInsensitive());
}
if (std::any_of(rStrings.begin(), rStrings.end(),
[](ScTypedStrData& rString) { return rString.IsHiddenByFilter(); })) {
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index ff6d77b432..15bb28fe61 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -6896,6 +6896,8 @@ void ScDocument::GetNotesInRange( const ScRangeList& rRangeList, std::vector<sc:
const ScRange & rRange = rRangeList[i];
for( SCTAB nTab = rRange.aStart.Tab(); nTab <= rRange.aEnd.Tab(); ++nTab )
{
+ if (!maTabs[nTab])
+ continue;
maTabs[nTab]->GetNotesInRange( rRange, rNotes );
}
}
@@ -6914,6 +6916,8 @@ bool ScDocument::ContainsNotesInRange( const ScRangeList& rRangeList ) const
const ScRange & rRange = rRangeList[i];
for( SCTAB nTab = rRange.aStart.Tab(); nTab <= rRange.aEnd.Tab(); ++nTab )
{
+ if (!maTabs[nTab])
+ continue;
bool bContainsNote = maTabs[nTab]->ContainsNotesInRange( rRange );
if(bContainsNote)
return true;
diff --git a/sc/source/core/data/document10.cxx b/sc/source/core/data/document10.cxx
index acf0f27672..df50575589 100644
--- a/sc/source/core/data/document10.cxx
+++ b/sc/source/core/data/document10.cxx
@@ -22,7 +22,7 @@
#include <refupdatecontext.hxx>
#include <sal/log.hxx>
-#include <editeng/colritem.hxx>
+#include <svx/DocumentColorHelper.hxx>
#include <scitems.hxx>
#include <datamapper.hxx>
#include <docsh.hxx>
@@ -188,17 +188,10 @@ std::set<Color> ScDocument::GetDocColors()
{
std::set<Color> aDocColors;
ScDocumentPool *pPool = GetPool();
- const sal_uInt16 pAttribs[] = {ATTR_BACKGROUND, ATTR_FONT_COLOR};
- for (sal_uInt16 nAttrib : pAttribs)
- {
- for (const SfxPoolItem* pItem : pPool->GetItemSurrogates(nAttrib))
- {
- const SvxColorItem *pColorItem = static_cast<const SvxColorItem*>(pItem);
- Color aColor( pColorItem->GetValue() );
- if (COL_AUTO != aColor)
- aDocColors.insert(aColor);
- }
- }
+
+ svx::DocumentColorHelper::queryColors<SvxBrushItem>(ATTR_BACKGROUND, pPool, aDocColors);
+ svx::DocumentColorHelper::queryColors<SvxColorItem>(ATTR_FONT_COLOR, pPool, aDocColors);
+
return aDocColors;
}
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
index afe2216b1a..6d7c5b0ac8 100644
--- a/sc/source/core/data/table2.cxx
+++ b/sc/source/core/data/table2.cxx
@@ -503,6 +503,7 @@ void ScTable::CopyToClip(
nCol2 = ClampToAllocatedColumns(nCol2);
+ pTable->CreateColumnIfNotExists(nCol2); // prevent repeated resizing
for ( SCCOL i = nCol1; i <= nCol2; i++)
aCol[i].CopyToClip(rCxt, nRow1, nRow2, pTable->CreateColumnIfNotExists(i)); // notes are handled at column level
@@ -638,6 +639,9 @@ void ScTable::CopyConditionalFormat( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCRO
{
ScRange aOldRange( nCol1 - nDx, nRow1 - nDy, pTable->nTab, nCol2 - nDx, nRow2 - nDy, pTable->nTab);
ScRange aNewRange( nCol1, nRow1, nTab, nCol2, nRow2, nTab );
+ // Don't deduplicate when undoing or creating an Undo document! It would disallow correct undo
+ bool bUndoContext = rDocument.IsUndo() || pTable->rDocument.IsUndo();
+ // Note that Undo documents use same pool as the original document
bool bSameDoc = rDocument.GetStyleSheetPool() == pTable->rDocument.GetStyleSheetPool();
for(const auto& rxCondFormat : *pTable->mpCondFormatList)
@@ -658,7 +662,7 @@ void ScTable::CopyConditionalFormat( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCRO
aRefCxt.mnTabDelta = nTab - pTable->nTab;
pNewFormat->UpdateReference(aRefCxt, true);
- if (bSameDoc && pTable->nTab == nTab && CheckAndDeduplicateCondFormat(rDocument, mpCondFormatList->GetFormat(rxCondFormat->GetKey()), pNewFormat.get(), nTab))
+ if (!bUndoContext && bSameDoc && pTable->nTab == nTab && CheckAndDeduplicateCondFormat(rDocument, mpCondFormatList->GetFormat(rxCondFormat->GetKey()), pNewFormat.get(), nTab))
{
continue;
}
@@ -668,7 +672,7 @@ void ScTable::CopyConditionalFormat( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCRO
{
// Check if there is the same format in the destination
// If there is, then simply expand its range
- if (CheckAndDeduplicateCondFormat(rDocument, rxCond.get(), pNewFormat.get(), nTab))
+ if (!bUndoContext && CheckAndDeduplicateCondFormat(rDocument, rxCond.get(), pNewFormat.get(), nTab))
{
bDuplicate = true;
break;
@@ -1348,6 +1352,7 @@ void ScTable::CopyToTable(
// can lead to repetitive splitting and rejoining of the same formula group, which can get
// quadratically expensive with large groups. So do the grouping just once at the end.
sc::DelayFormulaGroupingSwitch delayGrouping( pDestTab->rDocument, true );
+ pDestTab->CreateColumnIfNotExists(ClampToAllocatedColumns(nCol2)); // avoid repeated resizing
for (SCCOL i = nCol1; i <= ClampToAllocatedColumns(nCol2); i++)
aCol[i].CopyToColumn(rCxt, nRow1, nRow2, bToUndoDoc ? nFlags : nTempFlags, bMarked,
pDestTab->CreateColumnIfNotExists(i), pMarkData, bAsLink, bGlobalNamesToLocal);
diff --git a/sc/source/core/data/table4.cxx b/sc/source/core/data/table4.cxx
index 62b9dbb9e0..f8a03dd4c7 100644
--- a/sc/source/core/data/table4.cxx
+++ b/sc/source/core/data/table4.cxx
@@ -1314,7 +1314,7 @@ void ScTable::GetBackColorArea(SCCOL& rStartCol, SCROW& /*rStartRow*/,
const ScPatternAttr* pPattern = ColumnData(nCol).GetPattern(rEndRow + 1);
const SvxBrushItem* pBackground = &pPattern->GetItem(ATTR_BACKGROUND);
if (!pPattern->GetItem(ATTR_CONDITIONAL).GetCondFormatData().empty() ||
- pBackground != pDefBackground)
+ (pBackground->GetColor() != COL_TRANSPARENT && pBackground != pDefBackground))
{
bExtend = true;
break;
diff --git a/sc/source/core/data/validat.cxx b/sc/source/core/data/validat.cxx
index a46b09986b..5a569ef944 100644
--- a/sc/source/core/data/validat.cxx
+++ b/sc/source/core/data/validat.cxx
@@ -381,6 +381,9 @@ bool ScValidationData::DoError(weld::Window* pParent, const OUString& rInput,
if ( eErrorStyle == SC_VALERR_MACRO )
return DoMacro(rPos, rInput, nullptr, pParent);
+ if (!bShowError)
+ return true;
+
// Output error message
OUString aTitle = aErrorTitle;
diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx
index 63b1f09692..c9934c26ff 100644
--- a/sc/source/core/tool/compiler.cxx
+++ b/sc/source/core/tool/compiler.cxx
@@ -4738,6 +4738,7 @@ std::unique_ptr<ScTokenArray> ScCompiler::CompileString( const OUString& rFormul
pFunctionStack[0].eOp = ocNone;
pFunctionStack[0].nSep = 0;
size_t nFunction = 0;
+ size_t nHighWatermark = 0;
short nBrackets = 0;
bool bInArray = false;
eLastOp = ocOpen;
@@ -4757,6 +4758,7 @@ std::unique_ptr<ScTokenArray> ScCompiler::CompileString( const OUString& rFormul
++nFunction;
pFunctionStack[ nFunction ].eOp = eLastOp;
pFunctionStack[ nFunction ].nSep = 0;
+ nHighWatermark = nFunction;
}
}
break;
@@ -4795,6 +4797,7 @@ std::unique_ptr<ScTokenArray> ScCompiler::CompileString( const OUString& rFormul
++nFunction;
pFunctionStack[ nFunction ].eOp = eOp;
pFunctionStack[ nFunction ].nSep = 0;
+ nHighWatermark = nFunction;
}
}
break;
@@ -4825,6 +4828,7 @@ std::unique_ptr<ScTokenArray> ScCompiler::CompileString( const OUString& rFormul
++nFunction;
pFunctionStack[ nFunction ].eOp = eOp;
pFunctionStack[ nFunction ].nSep = 0;
+ nHighWatermark = nFunction;
}
}
break;
@@ -4867,9 +4871,9 @@ std::unique_ptr<ScTokenArray> ScCompiler::CompileString( const OUString& rFormul
// Append a parameter for WEEKNUM, all 1.0
// Function is already closed, parameter count is nSep+1
size_t nFunc = nFunction + 1;
- if (eOp == ocClose &&
- (pFunctionStack[ nFunc ].eOp == ocWeek && // 2nd week start
- pFunctionStack[ nFunc ].nSep == 0))
+ if (eOp == ocClose && nFunc <= nHighWatermark &&
+ pFunctionStack[ nFunc ].nSep == 0 &&
+ pFunctionStack[ nFunc ].eOp == ocWeek) // 2nd week start
{
if ( !static_cast<ScTokenArray*>(pArr)->Add( new FormulaToken( svSep, ocSep)) ||
!static_cast<ScTokenArray*>(pArr)->Add( new FormulaDoubleToken( 1.0)))
diff --git a/sc/source/core/tool/typedstrdata.cxx b/sc/source/core/tool/typedstrdata.cxx
index e00c1bc18d..4e3f862ae3 100644
--- a/sc/source/core/tool/typedstrdata.cxx
+++ b/sc/source/core/tool/typedstrdata.cxx
@@ -34,8 +34,31 @@ bool ScTypedStrData::LessCaseSensitive::operator() (const ScTypedStrData& left,
if (left.mbIsDate != right.mbIsDate)
return left.mbIsDate < right.mbIsDate;
- sal_Int32 nEqual = ScGlobal::GetCaseCollator().compareString(
- left.maStrValue, right.maStrValue);
+ sal_Int32 nEqual
+ = ScGlobal::GetCaseTransliteration().compareString(left.maStrValue, right.maStrValue);
+
+ if (!nEqual)
+ return left.mbIsHiddenByFilter < right.mbIsHiddenByFilter;
+
+ return nEqual < 0;
+}
+
+bool ScTypedStrData::LessSortCaseSensitive::operator() (const ScTypedStrData& left, const ScTypedStrData& right) const
+{
+ if (left.meStrType != right.meStrType)
+ return left.meStrType < right.meStrType;
+
+ if (left.meStrType == Value)
+ {
+ if (left.mfValue == right.mfValue)
+ return left.mbIsHiddenByFilter < right.mbIsHiddenByFilter;
+ return left.mfValue < right.mfValue;
+ }
+
+ if (left.mbIsDate != right.mbIsDate)
+ return left.mbIsDate < right.mbIsDate;
+
+ sal_Int32 nEqual = ScGlobal::GetCaseCollator().compareString(left.maStrValue, right.maStrValue);
if (!nEqual)
return left.mbIsHiddenByFilter < right.mbIsHiddenByFilter;
@@ -58,8 +81,31 @@ bool ScTypedStrData::LessCaseInsensitive::operator() (const ScTypedStrData& left
if (left.mbIsDate != right.mbIsDate)
return left.mbIsDate < right.mbIsDate;
- sal_Int32 nEqual = ScGlobal::GetCollator().compareString(
- left.maStrValue, right.maStrValue);
+ sal_Int32 nEqual
+ = ScGlobal::GetTransliteration().compareString(left.maStrValue, right.maStrValue);
+
+ if (!nEqual)
+ return left.mbIsHiddenByFilter < right.mbIsHiddenByFilter;
+
+ return nEqual < 0;
+}
+
+bool ScTypedStrData::LessSortCaseInsensitive::operator() (const ScTypedStrData& left, const ScTypedStrData& right) const
+{
+ if (left.meStrType != right.meStrType)
+ return left.meStrType < right.meStrType;
+
+ if (left.meStrType == Value)
+ {
+ if (left.mfValue == right.mfValue)
+ return left.mbIsHiddenByFilter < right.mbIsHiddenByFilter;
+ return left.mfValue < right.mfValue;
+ }
+
+ if (left.mbIsDate != right.mbIsDate)
+ return left.mbIsDate < right.mbIsDate;
+
+ sal_Int32 nEqual = ScGlobal::GetCaseCollator().compareString(left.maStrValue, right.maStrValue);
if (!nEqual)
return left.mbIsHiddenByFilter < right.mbIsHiddenByFilter;
diff --git a/sc/source/filter/excel/xeroot.cxx b/sc/source/filter/excel/xeroot.cxx
index ce281890f8..c1959767d9 100644
--- a/sc/source/filter/excel/xeroot.cxx
+++ b/sc/source/filter/excel/xeroot.cxx
@@ -317,8 +317,10 @@ uno::Sequence< beans::NamedValue > XclExpRoot::GenerateEncryptionData( std::u16s
{
rtlRandomPool aRandomPool = rtl_random_createPool ();
sal_uInt8 pnDocId[16];
- rtl_random_getBytes( aRandomPool, pnDocId, 16 );
-
+ if (rtl_random_getBytes(aRandomPool, pnDocId, 16) != rtl_Random_E_None)
+ {
+ throw uno::RuntimeException("rtl_random_getBytes failed");
+ }
rtl_random_destroyPool( aRandomPool );
sal_uInt16 pnPasswd[16] = {};
diff --git a/sc/source/filter/excel/xestream.cxx b/sc/source/filter/excel/xestream.cxx
index 4158fa2c15..a70e4e08bd 100644
--- a/sc/source/filter/excel/xestream.cxx
+++ b/sc/source/filter/excel/xestream.cxx
@@ -564,7 +564,10 @@ void XclExpBiff8Encrypter::Init( const Sequence< NamedValue >& rEncryptionData )
// generate the salt here
rtlRandomPool aRandomPool = rtl_random_createPool ();
- rtl_random_getBytes( aRandomPool, mpnSalt, 16 );
+ if (rtl_random_getBytes(aRandomPool, mpnSalt, 16) != rtl_Random_E_None)
+ {
+ throw uno::RuntimeException("rtl_random_getBytes failed");
+ }
rtl_random_destroyPool( aRandomPool );
memset( mpnSaltDigest, 0, sizeof( mpnSaltDigest ) );
diff --git a/sc/source/filter/html/htmlpars.cxx b/sc/source/filter/html/htmlpars.cxx
index f5f8900815..be957b1851 100644
--- a/sc/source/filter/html/htmlpars.cxx
+++ b/sc/source/filter/html/htmlpars.cxx
@@ -61,6 +61,7 @@
#include <rangelst.hxx>
#include <orcus/css_parser.hpp>
+#include <boost/property_tree/json_parser.hpp>
#include <com/sun/star/document/XDocumentProperties.hpp>
#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
@@ -71,6 +72,48 @@
using ::editeng::SvxBorderLine;
using namespace ::com::sun::star;
+namespace
+{
+/// data-sheets-value from google sheets, value is a JSON.
+void ParseDataSheetsValue(const OUString& rDataSheetsValue, std::optional<OUString>& rVal, std::optional<OUString>& rNum)
+{
+ // data-sheets-value from google sheets, value is a JSON.
+ OString aEncodedOption = rDataSheetsValue.toUtf8();
+ const char* pEncodedOption = aEncodedOption.getStr();
+ std::stringstream aStream(pEncodedOption);
+ boost::property_tree::ptree aTree;
+ boost::property_tree::read_json(aStream, aTree);
+ // The "1" key describes the original data type.
+ auto it = aTree.find("1");
+ if (it != aTree.not_found())
+ {
+ int nValueType = std::stoi(it->second.get_value<std::string>());
+ switch (nValueType)
+ {
+ case 2:
+ {
+ // 2 is text.
+ // See SfxHTMLParser::GetTableDataOptionsValNum(), we leave the parse and a number
+ // language unspecified.
+ rNum = ";;@";
+ break;
+ }
+ case 4:
+ {
+ // 4 is boolean.
+ it = aTree.find("4");
+ if (it != aTree.not_found())
+ {
+ rVal = OUString::fromUtf8(it->second.get_value<std::string>());
+ }
+ rNum = ";;BOOLEAN";
+ break;
+ }
+ }
+ }
+}
+}
+
ScHTMLStyles::ScHTMLStyles() : maEmpty() {}
void ScHTMLStyles::add(const char* pElemName, size_t nElemName, const char* pClassName, size_t nClassName,
@@ -978,6 +1021,11 @@ void ScHTMLLayoutParser::TableDataOn( HtmlImportInfo* pInfo )
mxActEntry->pNumStr = rOption.GetString();
}
break;
+ case HtmlOptionId::DSVAL:
+ {
+ ParseDataSheetsValue(rOption.GetString(), mxActEntry->pValStr, mxActEntry->pNumStr);
+ }
+ break;
default: break;
}
}
@@ -2116,6 +2164,11 @@ void ScHTMLTable::DataOn( const HtmlImportInfo& rInfo )
}
}
break;
+ case HtmlOptionId::DSVAL:
+ {
+ ParseDataSheetsValue(rOption.GetString(), pValStr, pNumStr);
+ }
+ break;
default: break;
}
}
diff --git a/sc/source/filter/inc/htmlpars.hxx b/sc/source/filter/inc/htmlpars.hxx
index fcdf6b4443..5b2d441098 100644
--- a/sc/source/filter/inc/htmlpars.hxx
+++ b/sc/source/filter/inc/htmlpars.hxx
@@ -149,6 +149,7 @@ class HTMLOption;
typedef ::std::map<SCROW, SCROW> InnerMap;
typedef ::std::map<sal_uInt16, InnerMap*> OuterMap;
+/// HTML parser used during paste into Calc.
class ScHTMLLayoutParser : public ScHTMLParser
{
private:
@@ -575,6 +576,8 @@ public:
Builds the table structure correctly, ignores extended formatting like
pictures or column widths.
+
+ Used during file load / import into Calc.
*/
class ScHTMLQueryParser : public ScHTMLParser
{
diff --git a/sc/source/filter/rtf/rtfparse.cxx b/sc/source/filter/rtf/rtfparse.cxx
index b2d2b8c252..0617a86c62 100644
--- a/sc/source/filter/rtf/rtfparse.cxx
+++ b/sc/source/filter/rtf/rtfparse.cxx
@@ -101,8 +101,8 @@ inline void ScRTFParser::NextRow()
bool ScRTFParser::SeekTwips( sal_uInt16 nTwips, SCCOL* pCol )
{
- ScRTFColTwips::const_iterator it = aColTwips.find( nTwips );
- bool bFound = it != aColTwips.end();
+ ScRTFColTwips::const_iterator it = aColTwips.lower_bound( nTwips );
+ bool bFound = it != aColTwips.end() && *it == nTwips;
sal_uInt16 nPos = it - aColTwips.begin();
*pCol = static_cast<SCCOL>(nPos);
if ( bFound )
diff --git a/sc/source/ui/app/inputhdl.cxx b/sc/source/ui/app/inputhdl.cxx
index 809ba8520e..a640d71cb2 100644
--- a/sc/source/ui/app/inputhdl.cxx
+++ b/sc/source/ui/app/inputhdl.cxx
@@ -3159,7 +3159,7 @@ void ScInputHandler::EnterHandler( ScEnterMode nBlockMode, bool bBeforeSavingInL
{
ScDocument& rDoc = pActiveViewSh->GetViewData().GetDocument();
const ScValidationData* pData = rDoc.GetValidationEntry( nValidation );
- if (pData && pData->HasErrMsg())
+ if (pData)
{
// #i67990# don't use pLastPattern in EnterHandler
const ScPatternAttr* pPattern = rDoc.GetPattern( aCursorPos.Col(), aCursorPos.Row(), aCursorPos.Tab() );
@@ -3200,6 +3200,7 @@ void ScInputHandler::EnterHandler( ScEnterMode nBlockMode, bool bBeforeSavingInL
if (pData->DoError(pActiveViewSh->GetFrameWeld(), aString, aCursorPos))
bForget = true; // Do not take over input
+
}
}
}
diff --git a/sc/source/ui/app/transobj.cxx b/sc/source/ui/app/transobj.cxx
index 6a1ef6a046..5f0599c888 100644
--- a/sc/source/ui/app/transobj.cxx
+++ b/sc/source/ui/app/transobj.cxx
@@ -312,28 +312,34 @@ bool ScTransferObj::GetData( const datatransfer::DataFlavor& rFlavor, const OUSt
ScAddress aPos(nCol, nRow, nTab);
const ScPatternAttr* pPattern = m_pDoc->GetPattern( nCol, nRow, nTab );
- ScTabEditEngine aEngine( *pPattern, m_pDoc->GetEditPool(), m_pDoc.get() );
- ScRefCellValue aCell(*m_pDoc, aPos);
- if (aCell.getType() == CELLTYPE_EDIT)
+ if (pPattern)
{
- const EditTextObject* pObj = aCell.getEditText();
- aEngine.SetTextCurrentDefaults(*pObj);
- }
- else
- {
- SvNumberFormatter* pFormatter = m_pDoc->GetFormatTable();
- sal_uInt32 nNumFmt = pPattern->GetNumberFormat(pFormatter);
- const Color* pColor;
- OUString aText = ScCellFormat::GetString(aCell, nNumFmt, &pColor, *pFormatter, *m_pDoc);
- if (!aText.isEmpty())
- aEngine.SetTextCurrentDefaults(aText);
- }
+ ScTabEditEngine aEngine(*pPattern, m_pDoc->GetEditPool(), m_pDoc.get());
+ ScRefCellValue aCell(*m_pDoc, aPos);
+ if (aCell.getType() == CELLTYPE_EDIT)
+ {
+ const EditTextObject* pObj = aCell.getEditText();
+ aEngine.SetTextCurrentDefaults(*pObj);
+ }
+ else
+ {
+ SvNumberFormatter* pFormatter = m_pDoc->GetFormatTable();
+ sal_uInt32 nNumFmt = pPattern->GetNumberFormat(pFormatter);
+ const Color* pColor;
+ OUString aText
+ = ScCellFormat::GetString(aCell, nNumFmt, &pColor, *pFormatter, *m_pDoc);
+ if (!aText.isEmpty())
+ aEngine.SetTextCurrentDefaults(aText);
+ }
- bOK = SetObject( &aEngine,
- ((nFormat == SotClipboardFormatId::RTF) ? SCTRANS_TYPE_EDIT_RTF :
- ((nFormat == SotClipboardFormatId::EDITENGINE_ODF_TEXT_FLAT) ?
- SCTRANS_TYPE_EDIT_ODF_TEXT_FLAT : SCTRANS_TYPE_EDIT_BIN)),
- rFlavor );
+ bOK = SetObject(&aEngine,
+ ((nFormat == SotClipboardFormatId::RTF)
+ ? SCTRANS_TYPE_EDIT_RTF
+ : ((nFormat == SotClipboardFormatId::EDITENGINE_ODF_TEXT_FLAT)
+ ? SCTRANS_TYPE_EDIT_ODF_TEXT_FLAT
+ : SCTRANS_TYPE_EDIT_BIN)),
+ rFlavor);
+ }
}
else if ( ScImportExport::IsFormatSupported( nFormat ) || nFormat == SotClipboardFormatId::RTF
|| nFormat == SotClipboardFormatId::RICHTEXT )
diff --git a/sc/source/ui/cctrl/checklistmenu.cxx b/sc/source/ui/cctrl/checklistmenu.cxx
index 92e7096fc2..578c248b7f 100644
--- a/sc/source/ui/cctrl/checklistmenu.cxx
+++ b/sc/source/ui/cctrl/checklistmenu.cxx
@@ -171,14 +171,7 @@ void ScCheckListMenuControl::CreateDropDown()
{
const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
- // tdf#151820 The color used for the arrow head depends on the background color
- Color aBackgroundColor = rStyleSettings.GetWindowColor();
- Color aSpinColor;
- if (aBackgroundColor.IsDark())
- aSpinColor = rStyleSettings.GetLightColor();
- else
- aSpinColor = rStyleSettings.GetDarkShadowColor();
-
+ Color aSpinColor = rStyleSettings.GetDialogTextColor();
int nWidth = (mxMenu->get_text_height() * 3) / 4;
mxDropDown->SetOutputSizePixel(Size(nWidth, nWidth), /*bErase*/true, /*bAlphaMaskTransparent*/true);
DecorationView aDecoView(mxDropDown.get());
diff --git a/sc/source/ui/navipi/navipi.cxx b/sc/source/ui/navipi/navipi.cxx
index 5fc6fee821..ae95220eef 100644
--- a/sc/source/ui/navipi/navipi.cxx
+++ b/sc/source/ui/navipi/navipi.cxx
@@ -540,6 +540,7 @@ void ScNavigatorDlg::Notify( SfxBroadcaster&, const SfxHint& rHint )
m_xLbEntries->Refresh( ScContentId::GRAPHIC );
m_xLbEntries->Refresh( ScContentId::OLEOBJECT );
m_xLbEntries->Refresh( ScContentId::DRAWING );
+ m_xLbEntries->Refresh( ScContentId::NOTE );
break;
case SfxHintId::ScAreaLinksChanged:
diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx
index 3f4f6b219c..ddbc8e2507 100644
--- a/sc/source/ui/view/gridwin.cxx
+++ b/sc/source/ui/view/gridwin.cxx
@@ -1041,8 +1041,8 @@ void ScGridWindow::LaunchAutoFilterMenu(SCCOL nCol, SCROW nRow)
mpAutoFilterPopup->setMemberSize(aFilterEntries.size());
for (auto it = aFilterEntries.begin(); it != aFilterEntries.end(); ++it)
{
- // tdf#140745 show (empty) entry on top of the checkbox list
- if (it->GetString().isEmpty())
+ // tdf#140745 show (empty) entry on top of the checkbox list if not hidden by filter
+ if (it->GetString().isEmpty() && !it->IsHiddenByFilter())
{
const OUString& aStringVal = it->GetString();
const double aDoubleVal = it->GetValue();
@@ -1051,7 +1051,8 @@ void ScGridWindow::LaunchAutoFilterMenu(SCCOL nCol, SCROW nRow)
bSelected = aSelectedString.count(aStringVal) > 0;
else if (bQueryByNonEmpty)
bSelected = false;
- mpAutoFilterPopup->addMember(aStringVal, aDoubleVal, bSelected, it->IsHiddenByFilter());
+ // it->IsHiddenByFilter() is always false here so no need to evaluate it
+ mpAutoFilterPopup->addMember(aStringVal, aDoubleVal, bSelected, false);
aFilterEntries.maStrData.erase(it);
break;
}
@@ -6168,10 +6169,16 @@ void ScGridWindow::DeleteCopySourceOverlay()
void ScGridWindow::UpdateCopySourceOverlay()
{
- MapMode aDrawMode = GetDrawMapMode();
- MapMode aOldMode = GetMapMode();
- if ( aOldMode != aDrawMode )
- SetMapMode( aDrawMode );
+ const MapMode aDrawMode = GetDrawMapMode();
+ const MapMode aOldMode = GetMapMode();
+ comphelper::ScopeGuard aMapModeGuard(
+ [&aOldMode, &aDrawMode, this] {
+ if (aOldMode != aDrawMode)
+ SetMapMode(aOldMode);
+ }
+ );
+ if (aOldMode != aDrawMode)
+ SetMapMode(aDrawMode);
DeleteCopySourceOverlay();
@@ -6222,9 +6229,6 @@ void ScGridWindow::UpdateCopySourceOverlay()
xOverlayManager->add(*pDashedBorder);
mpOOSelectionBorder->append(std::move(pDashedBorder));
}
-
- if ( aOldMode != aDrawMode )
- SetMapMode( aOldMode );
}
static std::vector<tools::Rectangle> convertPixelToLogical(
@@ -6415,10 +6419,16 @@ void ScGridWindow::UpdateCursorOverlay()
{
ScDocument& rDoc = mrViewData.GetDocument();
- MapMode aDrawMode = GetDrawMapMode();
- MapMode aOldMode = GetMapMode();
- if ( aOldMode != aDrawMode )
- SetMapMode( aDrawMode );
+ const MapMode aDrawMode = GetDrawMapMode();
+ const MapMode aOldMode = GetMapMode();
+ comphelper::ScopeGuard aMapModeGuard(
+ [&aOldMode, &aDrawMode, this] {
+ if (aOldMode != aDrawMode)
+ SetMapMode(aOldMode);
+ }
+ );
+ if (aOldMode != aDrawMode)
+ SetMapMode(aDrawMode);
// Existing OverlayObjects may be transformed in later versions.
// For now, just re-create them.
@@ -6577,9 +6587,6 @@ void ScGridWindow::UpdateCursorOverlay()
}
}
}
-
- if ( aOldMode != aDrawMode )
- SetMapMode( aOldMode );
}
void ScGridWindow::GetCellSelection(std::vector<tools::Rectangle>& rLogicRects)
@@ -6601,10 +6608,16 @@ void ScGridWindow::DeleteSelectionOverlay()
void ScGridWindow::UpdateSelectionOverlay()
{
- MapMode aDrawMode = GetDrawMapMode();
- MapMode aOldMode = GetMapMode();
- if ( aOldMode != aDrawMode )
- SetMapMode( aDrawMode );
+ const MapMode aDrawMode = GetDrawMapMode();
+ const MapMode aOldMode = GetMapMode();
+ comphelper::ScopeGuard aMapModeGuard(
+ [&aOldMode, &aDrawMode, this] {
+ if (aOldMode != aDrawMode)
+ SetMapMode(aOldMode);
+ }
+ );
+ if (aOldMode != aDrawMode)
+ SetMapMode(aDrawMode);
DeleteSelectionOverlay();
std::vector<tools::Rectangle> aRects;
@@ -6676,9 +6689,6 @@ void ScGridWindow::UpdateSelectionOverlay()
ScInputHandler::SendReferenceMarks(pViewShell, aReferenceMarks);
}
}
-
- if ( aOldMode != aDrawMode )
- SetMapMode( aOldMode );
}
void ScGridWindow::UpdateHighlightOverlay()
@@ -6744,10 +6754,16 @@ void ScGridWindow::DeleteAutoFillOverlay()
void ScGridWindow::UpdateAutoFillOverlay()
{
- MapMode aDrawMode = GetDrawMapMode();
- MapMode aOldMode = GetMapMode();
- if ( aOldMode != aDrawMode )
- SetMapMode( aDrawMode );
+ const MapMode aDrawMode = GetDrawMapMode();
+ const MapMode aOldMode = GetMapMode();
+ comphelper::ScopeGuard aMapModeGuard(
+ [&aOldMode, &aDrawMode, this] {
+ if (aOldMode != aDrawMode)
+ SetMapMode(aOldMode);
+ }
+ );
+ if (aOldMode != aDrawMode)
+ SetMapMode(aDrawMode);
DeleteAutoFillOverlay();
@@ -6826,9 +6842,6 @@ void ScGridWindow::UpdateAutoFillOverlay()
mpOOAutoFill.reset(new sdr::overlay::OverlayObjectList);
mpOOAutoFill->append(std::move(pOverlay));
}
-
- if ( aOldMode != aDrawMode )
- SetMapMode( aOldMode );
}
void ScGridWindow::DeleteDragRectOverlay()
@@ -6841,10 +6854,16 @@ void ScGridWindow::UpdateDragRectOverlay()
bool bInPrintTwips = comphelper::LibreOfficeKit::isCompatFlagSet(
comphelper::LibreOfficeKit::Compat::scPrintTwipsMsgs);
- MapMode aDrawMode = GetDrawMapMode();
- MapMode aOldMode = GetMapMode();
- if ( aOldMode != aDrawMode )
- SetMapMode( aDrawMode );
+ const MapMode aDrawMode = GetDrawMapMode();
+ const MapMode aOldMode = GetMapMode();
+ comphelper::ScopeGuard aMapModeGuard(
+ [&aOldMode, &aDrawMode, this] {
+ if (aOldMode != aDrawMode)
+ SetMapMode(aOldMode);
+ }
+ );
+ if (aOldMode != aDrawMode)
+ SetMapMode(aDrawMode);
DeleteDragRectOverlay();
@@ -6997,9 +7016,6 @@ void ScGridWindow::UpdateDragRectOverlay()
pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_TEXT_SELECTION, aRectsString);
}
}
-
- if ( aOldMode != aDrawMode )
- SetMapMode( aOldMode );
}
void ScGridWindow::DeleteHeaderOverlay()
@@ -7009,10 +7025,16 @@ void ScGridWindow::DeleteHeaderOverlay()
void ScGridWindow::UpdateHeaderOverlay()
{
- MapMode aDrawMode = GetDrawMapMode();
- MapMode aOldMode = GetMapMode();
- if ( aOldMode != aDrawMode )
- SetMapMode( aDrawMode );
+ const MapMode aDrawMode = GetDrawMapMode();
+ const MapMode aOldMode = GetMapMode();
+ comphelper::ScopeGuard aMapModeGuard(
+ [&aOldMode, &aDrawMode, this] {
+ if (aOldMode != aDrawMode)
+ SetMapMode(aOldMode);
+ }
+ );
+ if (aOldMode != aDrawMode)
+ SetMapMode(aDrawMode);
DeleteHeaderOverlay();
@@ -7043,9 +7065,6 @@ void ScGridWindow::UpdateHeaderOverlay()
mpOOHeader->append(std::move(pOverlay));
}
}
-
- if ( aOldMode != aDrawMode )
- SetMapMode( aOldMode );
}
void ScGridWindow::DeleteShrinkOverlay()
@@ -7055,10 +7074,16 @@ void ScGridWindow::DeleteShrinkOverlay()
void ScGridWindow::UpdateShrinkOverlay()
{
- MapMode aDrawMode = GetDrawMapMode();
- MapMode aOldMode = GetMapMode();
- if ( aOldMode != aDrawMode )
- SetMapMode( aDrawMode );
+ const MapMode aDrawMode = GetDrawMapMode();
+ const MapMode aOldMode = GetMapMode();
+ comphelper::ScopeGuard aMapModeGuard(
+ [&aOldMode, &aDrawMode, this] {
+ if (aOldMode != aDrawMode)
+ SetMapMode(aOldMode);
+ }
+ );
+ if (aOldMode != aDrawMode)
+ SetMapMode(aDrawMode);
DeleteShrinkOverlay();
@@ -7110,9 +7135,6 @@ void ScGridWindow::UpdateShrinkOverlay()
mpOOShrink->append(std::move(pOverlay));
}
}
-
- if ( aOldMode != aDrawMode )
- SetMapMode( aOldMode );
}
void ScGridWindow::DeleteSparklineGroupOverlay()
@@ -7122,9 +7144,14 @@ void ScGridWindow::DeleteSparklineGroupOverlay()
void ScGridWindow::UpdateSparklineGroupOverlay()
{
- MapMode aDrawMode = GetDrawMapMode();
-
- MapMode aOldMode = GetMapMode();
+ const MapMode aDrawMode = GetDrawMapMode();
+ const MapMode aOldMode = GetMapMode();
+ comphelper::ScopeGuard aMapModeGuard(
+ [&aOldMode, &aDrawMode, this] {
+ if (aOldMode != aDrawMode)
+ SetMapMode(aOldMode);
+ }
+ );
if (aOldMode != aDrawMode)
SetMapMode(aDrawMode);
@@ -7173,9 +7200,6 @@ void ScGridWindow::UpdateSparklineGroupOverlay()
}
}
}
-
- if (aOldMode != aDrawMode)
- SetMapMode(aOldMode);
}
// #i70788# central method to get the OverlayManager safely