diff options
author | Tor Lillqvist <tml@collabora.com> | 2017-11-26 23:28:05 +0200 |
---|---|---|
committer | Andras Timar <andras.timar@collabora.com> | 2018-03-19 14:55:48 +0100 |
commit | e850cb8fc7e880b6b6a036015c111159a04a3e60 (patch) | |
tree | 1d1dba35555e11ed3e342ff4144fc0950d049466 /sc/qa | |
parent | d52ca4c0f905b252dd1d9940fad58e85d175addd (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.ods | bin | 0 -> 8428 bytes | |||
-rw-r--r-- | sc/qa/unit/cond_format_merge.cxx | 155 |
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 Binary files differnew file mode 100644 index 000000000000..43b676d22080 --- /dev/null +++ b/sc/qa/extras/testdocuments/cond_format_merge.ods 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: */ |