summaryrefslogtreecommitdiff
path: root/sc/qa
diff options
context:
space:
mode:
authorTor Lillqvist <tml@collabora.com>2017-11-26 23:28:05 +0200
committerAndras Timar <andras.timar@collabora.com>2018-03-19 14:55:48 +0100
commite850cb8fc7e880b6b6a036015c111159a04a3e60 (patch)
tree1d1dba35555e11ed3e342ff4144fc0950d049466 /sc/qa
parentd52ca4c0f905b252dd1d9940fad58e85d175addd (diff)
Deduplicate conditional formats loaded from .ods
If there are several separate conditional format elements that can be represented as just one (with several ranges), try to do that. A particular customer document used to take 3 minutes 20 seconds to load, and it contained so many (tens of thousands) conditional formats that the Format> Conditional Formatting> Manage... dialog was practically impossible to use. Now loading that document takes 15 seconds and there are just a handful of separate conditional formats. Also add a simple unit test to verify the deduplication. Change-Id: I7c468af99956d4646ee5507390f1476caff52325 Reviewed-on: https://gerrit.libreoffice.org/45460 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Tor Lillqvist <tml@collabora.com> (cherry picked from commit ea55492a6e55290d92a59324b3cb31ed958981ab)
Diffstat (limited to 'sc/qa')
-rw-r--r--sc/qa/extras/testdocuments/cond_format_merge.odsbin0 -> 8428 bytes
-rw-r--r--sc/qa/unit/cond_format_merge.cxx155
2 files changed, 155 insertions, 0 deletions
diff --git a/sc/qa/extras/testdocuments/cond_format_merge.ods b/sc/qa/extras/testdocuments/cond_format_merge.ods
new file mode 100644
index 000000000000..43b676d22080
--- /dev/null
+++ b/sc/qa/extras/testdocuments/cond_format_merge.ods
Binary files differ
diff --git a/sc/qa/unit/cond_format_merge.cxx b/sc/qa/unit/cond_format_merge.cxx
new file mode 100644
index 000000000000..0ce3f21909bd
--- /dev/null
+++ b/sc/qa/unit/cond_format_merge.cxx
@@ -0,0 +1,155 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <sal/config.h>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/sheet/XConditionalFormats.hpp>
+#include <com/sun/star/sheet/XSpreadsheet.hpp>
+#include <test/bootstrapfixture.hxx>
+#include <test/calc_unoapi_test.hxx>
+
+#include <global.hxx>
+#include <document.hxx>
+
+#include "helper/qahelper.hxx"
+
+using namespace css;
+
+class ScCondFormatMergeTest : public CalcUnoApiTest
+{
+public:
+ ScCondFormatMergeTest();
+
+ void testCondFormatMerge();
+
+ CPPUNIT_TEST_SUITE(ScCondFormatMergeTest);
+ CPPUNIT_TEST(testCondFormatMerge);
+ CPPUNIT_TEST_SUITE_END();
+};
+
+ScCondFormatMergeTest::ScCondFormatMergeTest()
+ : CalcUnoApiTest("sc/qa/extras/testdocuments/")
+{
+}
+
+void ScCondFormatMergeTest::testCondFormatMerge()
+{
+ OUString aFileURL;
+ createFileURL("cond_format_merge.ods", aFileURL);
+ uno::Reference<lang::XComponent> mxComponent = loadFromDesktop(aFileURL);
+
+ CPPUNIT_ASSERT_MESSAGE("Component not loaded", mxComponent.is());
+
+ // get the first sheet
+ uno::Reference<sheet::XSpreadsheetDocument> xDoc(mxComponent, uno::UNO_QUERY_THROW);
+ uno::Reference<container::XIndexAccess> xIndex(xDoc->getSheets(), uno::UNO_QUERY_THROW);
+ uno::Reference<sheet::XSpreadsheet> xSheet(xIndex->getByIndex(0), uno::UNO_QUERY_THROW);
+
+ uno::Reference<beans::XPropertySet> xProps(xSheet, uno::UNO_QUERY_THROW);
+ uno::Any aAny = xProps->getPropertyValue("ConditionalFormats");
+ uno::Reference<sheet::XConditionalFormats> xCondFormats;
+
+ CPPUNIT_ASSERT(aAny >>= xCondFormats);
+ CPPUNIT_ASSERT(xCondFormats.is());
+
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(5), xCondFormats->getLength());
+
+ uno::Sequence<uno::Reference<sheet::XConditionalFormat>> xCondFormatSeq
+ = xCondFormats->getConditionalFormats();
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(5), xCondFormatSeq.getLength());
+
+ int nRanges = 0;
+ for (sal_Int32 i = 0, n = xCondFormatSeq.getLength(); i < n; ++i)
+ {
+ CPPUNIT_ASSERT(xCondFormatSeq[i].is());
+
+ uno::Reference<sheet::XConditionalFormat> xCondFormat = xCondFormatSeq[i];
+ CPPUNIT_ASSERT(xCondFormat.is());
+
+ uno::Reference<beans::XPropertySet> xPropSet(xCondFormat, uno::UNO_QUERY_THROW);
+
+ aAny = xPropSet->getPropertyValue("Range");
+ uno::Reference<sheet::XSheetCellRanges> xCellRanges;
+ CPPUNIT_ASSERT(aAny >>= xCellRanges);
+ CPPUNIT_ASSERT(xCellRanges.is());
+
+ uno::Sequence<table::CellRangeAddress> aRanges = xCellRanges->getRangeAddresses();
+ CPPUNIT_ASSERT_GREATEREQUAL(sal_Int32(1), aRanges.getLength());
+
+ table::CellRangeAddress aRange0 = aRanges[0];
+ CPPUNIT_ASSERT_EQUAL(sal_Int16(0), aRange0.Sheet);
+ CPPUNIT_ASSERT_EQUAL(aRange0.StartColumn, aRange0.EndColumn);
+
+ table::CellRangeAddress aRange1;
+
+ switch (aRange0.StartColumn)
+ {
+ case 3:
+ switch (aRange0.StartRow)
+ {
+ case 0: // D1:D2,D5::D8
+ nRanges++;
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), aRange0.EndRow);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(2), aRanges.getLength());
+ aRange1 = aRanges[1];
+ CPPUNIT_ASSERT_EQUAL(sal_Int16(0), aRange1.Sheet);
+ CPPUNIT_ASSERT_EQUAL(aRange1.StartColumn, aRange1.EndColumn);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(3), aRange1.StartColumn);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(4), aRange1.StartRow);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(7), aRange1.EndRow);
+ break;
+ default:
+ CPPUNIT_FAIL("Unexpected range in column D");
+ }
+ break;
+ case 5:
+ switch (aRange0.StartRow)
+ {
+ case 0: // F1:F2
+ nRanges++;
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), aRange0.EndRow);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), aRanges.getLength());
+ break;
+ case 2: // F3
+ nRanges++;
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(2), aRange0.EndRow);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), aRanges.getLength());
+ break;
+ case 3: // F4
+ nRanges++;
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(3), aRange0.EndRow);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), aRanges.getLength());
+ break;
+ case 4: // F5
+ nRanges++;
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(4), aRange0.EndRow);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), aRanges.getLength());
+ break;
+ default:
+ CPPUNIT_FAIL("Unexpected range in column F");
+ }
+ break;
+ default:
+ CPPUNIT_FAIL("Unexpected range");
+ }
+ }
+
+ CPPUNIT_ASSERT_EQUAL(5, nRanges);
+
+ closeDocument(mxComponent);
+ mxComponent.clear();
+}
+
+CPPUNIT_TEST_SUITE_REGISTRATION(ScCondFormatMergeTest);
+
+CPPUNIT_PLUGIN_IMPLEMENT();
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */