summaryrefslogtreecommitdiff
path: root/svl
diff options
context:
space:
mode:
authorTobias Lippert <drtl@fastmail.fm>2014-03-05 20:06:39 +0100
committerCaolán McNamara <caolanm@redhat.com>2014-03-11 08:54:37 -0500
commit0c17ccc493d0c7a80f37600dae76a09a119bef78 (patch)
tree70fd1963d59bbb8dba95ed4d92053f2c9f3115cb /svl
parente3e1f9f30d80961fd282f9ce765ffb1111201344 (diff)
fdo#30770 - Speed up xslx import
Conflicts: include/svl/style.hxx Change-Id: Ie3d855923c651b6e05c0054c8e30155218279045 Reviewed-on: https://gerrit.libreoffice.org/8485 Reviewed-by: Caolán McNamara <caolanm@redhat.com> Tested-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'svl')
-rw-r--r--svl/CppunitTest_svl_items.mk42
-rw-r--r--svl/Library_svl.mk1
-rw-r--r--svl/Module_svl.mk1
-rw-r--r--svl/qa/unit/items/test_IndexedStyleSheets.cxx160
-rw-r--r--svl/source/items/IndexedStyleSheets.cxx210
-rw-r--r--svl/source/items/style.cxx268
6 files changed, 573 insertions, 109 deletions
diff --git a/svl/CppunitTest_svl_items.mk b/svl/CppunitTest_svl_items.mk
new file mode 100644
index 000000000000..d51b8fc43af3
--- /dev/null
+++ b/svl/CppunitTest_svl_items.mk
@@ -0,0 +1,42 @@
+# -*- 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,svl_items))
+
+$(eval $(call gb_CppunitTest_use_external,svl_items,boost_headers))
+
+$(eval $(call gb_CppunitTest_use_api,svl_items, \
+ offapi \
+ udkapi \
+))
+
+
+#$(eval $(call gb_CppunitTest_use_components,svl_items, \
+# ucb/source/core/ucb1 \
+#))
+
+$(eval $(call gb_CppunitTest_add_exception_objects,svl_items, \
+ svl/qa/unit/items/test_IndexedStyleSheets \
+))
+
+$(eval $(call gb_CppunitTest_use_libraries,svl_items, \
+ svl \
+ comphelper \
+ sal \
+ cppu \
+ cppuhelper \
+))
+
+#$(eval $(call gb_CppunitTest_use_ure,svl_items))
+
+#$(eval $(call gb_CppunitTest_use_components,svl_urihelper,\
+# i18npool/util/i18npool \
+#))
+
+# vim: set noet sw=4 ts=4:
diff --git a/svl/Library_svl.mk b/svl/Library_svl.mk
index ba4d9b9b6121..a53b22340b58 100644
--- a/svl/Library_svl.mk
+++ b/svl/Library_svl.mk
@@ -79,6 +79,7 @@ $(eval $(call gb_Library_add_exception_objects,svl,\
svl/source/items/itemiter \
svl/source/items/itempool \
svl/source/items/itemprop \
+ svl/source/items/IndexedStyleSheets \
svl/source/items/itemset \
svl/source/items/lckbitem \
svl/source/items/macitem \
diff --git a/svl/Module_svl.mk b/svl/Module_svl.mk
index 684642c188ea..2e5e6a06dae3 100644
--- a/svl/Module_svl.mk
+++ b/svl/Module_svl.mk
@@ -32,6 +32,7 @@ $(eval $(call gb_Module_add_l10n_targets,svl,\
$(eval $(call gb_Module_add_check_targets,svl,\
CppunitTest_svl_lngmisc \
CppunitTest_svl_qa_cppunit \
+ CppunitTest_svl_items \
))
#TODO: CppunitTest_svl_urihelper depends on ucb, can only be added once svl is
diff --git a/svl/qa/unit/items/test_IndexedStyleSheets.cxx b/svl/qa/unit/items/test_IndexedStyleSheets.cxx
new file mode 100644
index 000000000000..ec8d82dcd5fd
--- /dev/null
+++ b/svl/qa/unit/items/test_IndexedStyleSheets.cxx
@@ -0,0 +1,160 @@
+/* -*- 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 <svl/IndexedStyleSheets.hxx>
+
+// for SfxStyleSheetBase
+#include <svl/style.hxx>
+
+#include <cppunit/TestAssert.h>
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/plugin/TestPlugIn.h>
+
+using namespace svl;
+
+class MockedStyleSheet : public SfxStyleSheetBase
+{
+ public:
+ MockedStyleSheet(const rtl::OUString& name)
+ : SfxStyleSheetBase(name, NULL, SFX_STYLE_FAMILY_CHAR, 0)
+ {;}
+
+};
+
+class IndexedStyleSheetsTest : public CppUnit::TestFixture
+{
+ void InstantiationWorks();
+ void AddedStylesheetsCanBeFoundAndRetrievedByPosition();
+ void AddingSameStylesheetTwiceHasNoEffect();
+ void RemovedStyleSheetIsNotFound();
+ void RemovingStyleSheetWhichIsNotAvailableHasNoEffect();
+ void StyleSheetsCanBeRetrievedByTheirName();
+ void KnowsThatItStoresAStyleSheet();
+
+ // Adds code needed to register the test suite
+ CPPUNIT_TEST_SUITE(IndexedStyleSheetsTest);
+
+ CPPUNIT_TEST(InstantiationWorks);
+ CPPUNIT_TEST(AddedStylesheetsCanBeFoundAndRetrievedByPosition);
+ CPPUNIT_TEST(AddingSameStylesheetTwiceHasNoEffect);
+ CPPUNIT_TEST(RemovedStyleSheetIsNotFound);
+ CPPUNIT_TEST(RemovingStyleSheetWhichIsNotAvailableHasNoEffect);
+ CPPUNIT_TEST(StyleSheetsCanBeRetrievedByTheirName);
+ CPPUNIT_TEST(KnowsThatItStoresAStyleSheet);
+
+ // End of test suite definition
+ CPPUNIT_TEST_SUITE_END();
+
+};
+
+void IndexedStyleSheetsTest::InstantiationWorks()
+{
+ IndexedStyleSheets iss;
+}
+
+void IndexedStyleSheetsTest::AddedStylesheetsCanBeFoundAndRetrievedByPosition()
+{
+ rtl::OUString name1("name1");
+ rtl::OUString name2("name2");
+ rtl::Reference<SfxStyleSheetBase> sheet1(new MockedStyleSheet(name1));
+ rtl::Reference<SfxStyleSheetBase> sheet2(new MockedStyleSheet(name2));
+ IndexedStyleSheets iss;
+ iss.AddStyleSheet(sheet1);
+ iss.AddStyleSheet(sheet2);
+ unsigned pos = iss.FindStyleSheetPosition(*sheet2);
+ rtl::Reference<SfxStyleSheetBase> retrieved = iss.GetStyleSheetByPosition(pos);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("retrieved sheet is that which has been inserted.", sheet2.get(), retrieved.get());
+}
+
+void IndexedStyleSheetsTest::AddingSameStylesheetTwiceHasNoEffect()
+{
+ rtl::Reference<SfxStyleSheetBase> sheet1(new MockedStyleSheet(rtl::OUString("sheet1")));
+ IndexedStyleSheets iss;
+ iss.AddStyleSheet(sheet1);
+ CPPUNIT_ASSERT_EQUAL(1u, iss.GetNumberOfStyleSheets());
+ iss.AddStyleSheet(sheet1);
+ CPPUNIT_ASSERT_EQUAL(1u, iss.GetNumberOfStyleSheets());
+}
+
+void IndexedStyleSheetsTest::RemovedStyleSheetIsNotFound()
+{
+ rtl::OUString name1("name1");
+ rtl::OUString name2("name2");
+ rtl::Reference<SfxStyleSheetBase> sheet1(new MockedStyleSheet(name1));
+ rtl::Reference<SfxStyleSheetBase> sheet2(new MockedStyleSheet(name2));
+ IndexedStyleSheets iss;
+ iss.AddStyleSheet(sheet1);
+ iss.AddStyleSheet(sheet2);
+ iss.RemoveStyleSheet(sheet1);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Removed style sheet is not found.",
+ false, iss.HasStyleSheet(sheet1));
+}
+
+void IndexedStyleSheetsTest::RemovingStyleSheetWhichIsNotAvailableHasNoEffect()
+{
+ rtl::Reference<SfxStyleSheetBase> sheet1(new MockedStyleSheet(rtl::OUString("sheet1")));
+ rtl::Reference<SfxStyleSheetBase> sheet2(new MockedStyleSheet(rtl::OUString("sheet2")));
+ IndexedStyleSheets iss;
+ iss.AddStyleSheet(sheet1);
+ CPPUNIT_ASSERT_EQUAL(1u, iss.GetNumberOfStyleSheets());
+ iss.RemoveStyleSheet(sheet2);
+ CPPUNIT_ASSERT_EQUAL(1u, iss.GetNumberOfStyleSheets());
+}
+
+void IndexedStyleSheetsTest::StyleSheetsCanBeRetrievedByTheirName()
+{
+ rtl::OUString name1("name1");
+ rtl::OUString name2("name2");
+ rtl::Reference<SfxStyleSheetBase> sheet1(new MockedStyleSheet(name1));
+ rtl::Reference<SfxStyleSheetBase> sheet2(new MockedStyleSheet(name2));
+ rtl::Reference<SfxStyleSheetBase> sheet3(new MockedStyleSheet(name1));
+ IndexedStyleSheets iss;
+ iss.AddStyleSheet(sheet1);
+ iss.AddStyleSheet(sheet2);
+ iss.AddStyleSheet(sheet3);
+
+ std::vector<unsigned> r = iss.FindPositionsByName(name1);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Two style sheets are found by 'name1'",
+ 2u, static_cast<unsigned>(r.size()));
+ CPPUNIT_ASSERT_EQUAL(0u, r.at(0));
+ CPPUNIT_ASSERT_EQUAL(2u, r.at(1));
+
+ r = iss.FindPositionsByName(name2);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("One style sheets is found by 'name2'",
+ 1u, static_cast<unsigned>(r.size()));
+ CPPUNIT_ASSERT_EQUAL(1u, r.at(0));
+}
+
+void IndexedStyleSheetsTest::KnowsThatItStoresAStyleSheet()
+{
+ rtl::OUString name1("name1");
+ rtl::OUString name2("name2");
+ rtl::Reference<SfxStyleSheetBase> sheet1(new MockedStyleSheet(name1));
+ rtl::Reference<SfxStyleSheetBase> sheet2(new MockedStyleSheet(name1));
+ rtl::Reference<SfxStyleSheetBase> sheet3(new MockedStyleSheet(name2));
+ rtl::Reference<SfxStyleSheetBase> sheet4(new MockedStyleSheet(name1));
+ IndexedStyleSheets iss;
+ iss.AddStyleSheet(sheet1);
+ iss.AddStyleSheet(sheet2);
+ iss.AddStyleSheet(sheet3);
+ // do not add sheet 4
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Finds first stored style sheet even though two style sheets have the same name.",
+ true, iss.HasStyleSheet(sheet1));
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Finds second stored style sheet even though two style sheets have the same name.",
+ true, iss.HasStyleSheet(sheet2));
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Does not find style sheet which is not stored and has the same name as a stored.",
+ false, iss.HasStyleSheet(sheet4));
+
+}
+
+CPPUNIT_TEST_SUITE_REGISTRATION(IndexedStyleSheetsTest);
+
+CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/svl/source/items/IndexedStyleSheets.cxx b/svl/source/items/IndexedStyleSheets.cxx
new file mode 100644
index 000000000000..ca45b534ee92
--- /dev/null
+++ b/svl/source/items/IndexedStyleSheets.cxx
@@ -0,0 +1,210 @@
+/* -*- 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 <svl/IndexedStyleSheets.hxx>
+#include <svl/style.hxx>
+
+#include <stdexcept>
+#include <utility>
+
+using rtl::OUString;
+
+namespace svl {
+
+IndexedStyleSheets::IndexedStyleSheets()
+{;}
+
+
+void
+IndexedStyleSheets::Register(const rtl::OUString& name, unsigned pos)
+{
+ mPositionsByName.insert(std::make_pair(name, pos));
+}
+
+void
+IndexedStyleSheets::Reindex()
+{
+ mPositionsByName.clear();
+ unsigned i = 0;
+ for (VectorType::const_iterator it = mStyleSheets.begin();
+ it != mStyleSheets.end(); ++it) {
+ SfxStyleSheetBase* p = it->get();
+ Register(p->GetName(), i);
+ ++i;
+ }
+}
+
+unsigned
+IndexedStyleSheets::GetNumberOfStyleSheets() const
+{
+ return mStyleSheets.size();
+}
+
+void
+IndexedStyleSheets::AddStyleSheet(rtl::Reference< SfxStyleSheetBase > style)
+{
+ if (!HasStyleSheet(style)) {
+ mStyleSheets.push_back(style);
+ // since we just added an element to the vector, we can safely do -1 as it will always be >= 1
+ Register(style->GetName(), mStyleSheets.size()-1);
+ }
+}
+
+bool
+IndexedStyleSheets::RemoveStyleSheet(rtl::Reference< SfxStyleSheetBase > style)
+{
+ rtl::OUString styleName = style->GetName();
+ std::vector<unsigned> positions = FindPositionsByName(styleName);
+ bool found = false;
+ unsigned stylePosition = 0;
+ for (std::vector<unsigned>::const_iterator it = positions.begin();
+ it != positions.end(); ++it) {
+ if (mStyleSheets.at(*it) == style) {
+ found = true;
+ stylePosition = *it;
+ break;
+ }
+ }
+
+ if (found) {
+ mStyleSheets.erase(mStyleSheets.begin() + stylePosition);
+ Reindex();
+ }
+ return found;
+}
+
+std::vector<unsigned>
+IndexedStyleSheets::FindPositionsByName(const rtl::OUString& name) const
+{
+ std::vector<unsigned> r;
+ std::pair<MapType::const_iterator, MapType::const_iterator> range = mPositionsByName.equal_range(name);
+ for (MapType::const_iterator it = range.first; it != range.second; ++it) {
+ r.push_back(it->second);
+ }
+ return r;
+}
+
+std::vector<unsigned>
+IndexedStyleSheets::FindPositionsByNameAndPredicate(const rtl::OUString& name,
+ StyleSheetPredicate& predicate) const
+{
+ std::vector<unsigned> r;
+ MapType::const_iterator it = mPositionsByName.find(name);
+ for (/**/; it != mPositionsByName.end(); ++it) {
+ unsigned pos = it->second;
+ SfxStyleSheetBase *ssheet = mStyleSheets.at(pos).get();
+ if (predicate.Check(*ssheet)) {
+ r.push_back(pos);
+ }
+ }
+ return r;
+}
+
+
+unsigned
+IndexedStyleSheets::GetNumberOfStyleSheetsWithPredicate(StyleSheetPredicate& predicate) const
+{
+ unsigned r = 0;
+ for (VectorType::const_iterator it = mStyleSheets.begin(); it != mStyleSheets.end(); ++it) {
+ const SfxStyleSheetBase *ssheet = it->get();
+ if (predicate.Check(*ssheet)) {
+ ++r;
+ }
+ }
+ return r;
+}
+
+rtl::Reference<SfxStyleSheetBase>
+IndexedStyleSheets::GetNthStyleSheetThatMatchesPredicate(
+ unsigned n,
+ StyleSheetPredicate& predicate,
+ unsigned startAt)
+{
+ rtl::Reference<SfxStyleSheetBase> retval;
+ unsigned matching = 0;
+ for (VectorType::iterator it = mStyleSheets.begin()+startAt; it != mStyleSheets.end(); ++it) {
+ SfxStyleSheetBase *ssheet = it->get();
+ if (predicate.Check(*ssheet)) {
+ if (matching == n) {
+ retval = *it;
+ break;
+ }
+ ++matching;
+ }
+ }
+ return retval;
+}
+
+unsigned
+IndexedStyleSheets::FindStyleSheetPosition(const SfxStyleSheetBase& style) const
+{
+ VectorType::const_iterator it = std::find(mStyleSheets.begin(), mStyleSheets.end(), &style);
+ if (it == mStyleSheets.end()) {
+ throw std::runtime_error("IndexedStyleSheets::FindStylePosition Looked for style not in index");
+ }
+ return std::distance(mStyleSheets.begin(), it);
+}
+
+void
+IndexedStyleSheets::Clear(StyleSheetDisposer& disposer)
+{
+ for (VectorType::iterator it = mStyleSheets.begin(); it != mStyleSheets.end(); ++it) {
+ disposer.Dispose(*it);
+ }
+ mStyleSheets.clear();
+ mPositionsByName.clear();
+}
+
+IndexedStyleSheets::~IndexedStyleSheets()
+{;}
+
+bool
+IndexedStyleSheets::HasStyleSheet(rtl::Reference< SfxStyleSheetBase > style) const
+{
+ rtl::OUString styleName = style->GetName();
+ std::vector<unsigned> positions = FindPositionsByName(styleName);
+ for (std::vector<unsigned>::const_iterator it = positions.begin();
+ it != positions.end(); ++it) {
+ if (mStyleSheets.at(*it) == style) {
+ return true;
+ }
+ }
+ return false;
+}
+
+rtl::Reference< SfxStyleSheetBase >
+IndexedStyleSheets::GetStyleSheetByPosition(unsigned pos)
+{
+ return mStyleSheets.at(pos);
+}
+
+void
+IndexedStyleSheets::ApplyToAllStyleSheets(StyleSheetCallback& callback) const
+{
+ for (VectorType::const_iterator it = mStyleSheets.begin(); it != mStyleSheets.end(); ++it) {
+ callback.DoIt(**it);
+ }
+}
+
+std::vector<unsigned>
+IndexedStyleSheets::FindPositionsByPredicate(StyleSheetPredicate& predicate) const
+{
+ std::vector<unsigned> r;
+ for (VectorType::const_iterator it = mStyleSheets.begin(); it != mStyleSheets.end(); ++it) {
+ if (predicate.Check(**it)) {
+ r.push_back(std::distance(mStyleSheets.begin(), it));
+ }
+ }
+ return r;
+}
+
+} /* namespace svl */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svl/source/items/style.cxx b/svl/source/items/style.cxx
index 126cd814b4cb..ab9800e29bb2 100644
--- a/svl/source/items/style.cxx
+++ b/svl/source/items/style.cxx
@@ -26,12 +26,16 @@
#include <svl/poolitem.hxx>
#include <svl/itemset.hxx>
#include <svl/itempool.hxx>
+#include <svl/IndexedStyleSheets.hxx>
#include <poolio.hxx>
#include <svl/itemiter.hxx>
#include <svl/style.hxx>
#include <unotools/syslocale.hxx>
#include <algorithm>
#include <comphelper/servicehelper.hxx>
+
+#include <boost/numeric/conversion/cast.hpp>
+
#include <string.h>
#ifdef DBG_UTIL
@@ -362,22 +366,35 @@ inline bool SfxStyleSheetIterator::IsTrivialSearch()
(GetSearchFamily() == SFX_STYLE_FAMILY_ALL);
}
-bool SfxStyleSheetIterator::DoesStyleMatch(SfxStyleSheetBase *pStyle)
+namespace {
+
+struct DoesStyleMatchStyleSheetPredicate SAL_FINAL : public svl::StyleSheetPredicate
{
- bool bMatchFamily = ((GetSearchFamily() == SFX_STYLE_FAMILY_ALL) ||
- ( pStyle->GetFamily() == GetSearchFamily() ));
+ DoesStyleMatchStyleSheetPredicate(SfxStyleSheetIterator *it)
+ : mIterator(it) {;}
- bool bUsed = bSearchUsed ? pStyle->IsUsed( ) : false;
+ bool
+ Check(const SfxStyleSheetBase& styleSheet)
+ {
+ bool bMatchFamily = ((mIterator->GetSearchFamily() == SFX_STYLE_FAMILY_ALL) ||
+ ( styleSheet.GetFamily() == mIterator->GetSearchFamily() ));
+
+ bool bUsed = mIterator->SearchUsed() ? styleSheet.IsUsed( ) : false;
- bool bSearchHidden = ( GetSearchMask() & SFXSTYLEBIT_HIDDEN );
- bool bMatchVisibility = !( !bSearchHidden && pStyle->IsHidden() && !bUsed );
- bool bOnlyHidden = GetSearchMask( ) == SFXSTYLEBIT_HIDDEN && pStyle->IsHidden( );
+ bool bSearchHidden = ( mIterator->GetSearchMask() & SFXSTYLEBIT_HIDDEN );
+ bool bMatchVisibility = !( !bSearchHidden && styleSheet.IsHidden() && !bUsed );
+ bool bOnlyHidden = mIterator->GetSearchMask( ) == SFXSTYLEBIT_HIDDEN && styleSheet.IsHidden( );
+
+ bool bMatches = bMatchFamily && bMatchVisibility
+ && (( styleSheet.GetMask() & ( mIterator->GetSearchMask() & ~SFXSTYLEBIT_USED )) ||
+ bUsed || bOnlyHidden ||
+ ( mIterator->GetSearchMask() & SFXSTYLEBIT_ALL_VISIBLE ) == SFXSTYLEBIT_ALL_VISIBLE );
+ return bMatches;
+ }
+
+ SfxStyleSheetIterator *mIterator;
+};
- bool bMatches = bMatchFamily && bMatchVisibility
- && (( pStyle->GetMask() & ( GetSearchMask() & ~SFXSTYLEBIT_USED )) ||
- bUsed || bOnlyHidden ||
- ( GetSearchMask() & SFXSTYLEBIT_ALL_VISIBLE ) == SFXSTYLEBIT_ALL_VISIBLE );
- return bMatches;
}
SfxStyleSheetIterator::SfxStyleSheetIterator(SfxStyleSheetBasePool *pBase,
@@ -403,111 +420,94 @@ sal_uInt16 SfxStyleSheetIterator::Count()
{
sal_uInt16 n = 0;
if( IsTrivialSearch())
- n = (sal_uInt16) pBasePool->aStyles.size();
+ {
+ n = (sal_uInt16) pBasePool->mIndexedStyleSheets->GetNumberOfStyleSheets();
+ }
else
- for(sal_uInt16 i=0; i<pBasePool->aStyles.size(); i++)
- {
- SfxStyleSheetBase* pStyle = pBasePool->aStyles[i].get();
- if(DoesStyleMatch(pStyle))
- n++;
- }
+ {
+ DoesStyleMatchStyleSheetPredicate predicate(this);
+ n = pBasePool->mIndexedStyleSheets->GetNumberOfStyleSheetsWithPredicate(predicate);
+ }
return n;
}
SfxStyleSheetBase* SfxStyleSheetIterator::operator[](sal_uInt16 nIdx)
{
+ SfxStyleSheetBase* retval = NULL;
if( IsTrivialSearch())
- return pBasePool->aStyles[nIdx].get();
-
- sal_uInt16 z = 0;
- for(sal_uInt16 n=0; n<pBasePool->aStyles.size(); n++)
{
- SfxStyleSheetBase* pStyle = pBasePool->aStyles[n].get();
- if( DoesStyleMatch(pStyle))
- {
- if(z == nIdx)
- {
- nAktPosition=n;
- return pAktStyle=pStyle;
- }
- ++z;
- }
+ retval = pBasePool->mIndexedStyleSheets->GetStyleSheetByPosition(nIdx).get();
}
- OSL_FAIL("Incorrect index");
- return 0;
-}
-
-SfxStyleSheetBase* SfxStyleSheetIterator::First()
-{
- sal_Int32 nIdx = -1;
-
- if ( IsTrivialSearch() && pBasePool->aStyles.size() )
- nIdx = 0;
else
- for( sal_uInt16 n = 0; n < pBasePool->aStyles.size(); n++ )
+ {
+ DoesStyleMatchStyleSheetPredicate predicate(this);
+ rtl::Reference< SfxStyleSheetBase > ref =
+ pBasePool->mIndexedStyleSheets->GetNthStyleSheetThatMatchesPredicate(nIdx, predicate);
+ if (ref.get() != NULL)
{
- SfxStyleSheetBase* pStyle = pBasePool->aStyles[n].get();
-
- if ( DoesStyleMatch( pStyle ) )
- {
- nIdx = n;
- break;
- }
+ nAktPosition = pBasePool->mIndexedStyleSheets->FindStyleSheetPosition(*ref);
+ retval = ref.get();
}
+ }
- if ( nIdx != -1 )
+ if (retval == NULL)
{
- nAktPosition = (sal_uInt16)nIdx;
- return pAktStyle = pBasePool->aStyles[nIdx].get();
+ OSL_FAIL("Incorrect index");
}
- return 0;
+
+ return retval;
+}
+
+SfxStyleSheetBase* SfxStyleSheetIterator::First()
+{
+ return operator[](0);
}
SfxStyleSheetBase* SfxStyleSheetIterator::Next()
{
- sal_Int32 nIdx = -1;
+ SfxStyleSheetBase* retval = NULL;
- if ( IsTrivialSearch() &&
- (sal_uInt16)pBasePool->aStyles.size() > nAktPosition + 1 )
- nIdx = nAktPosition + 1;
- else
- for( sal_uInt16 n = nAktPosition + 1; n < pBasePool->aStyles.size(); n++ )
+ if ( IsTrivialSearch() )
+ {
+ unsigned nStyleSheets = pBasePool->mIndexedStyleSheets->GetNumberOfStyleSheets();
+ unsigned newPosition = nAktPosition +1;
+ if (nStyleSheets > newPosition)
{
- SfxStyleSheetBase* pStyle = pBasePool->aStyles[n].get();
-
- if ( DoesStyleMatch( pStyle ) )
- {
- nIdx = n;
- break;
- }
+ nAktPosition = newPosition;
+ retval = pBasePool->mIndexedStyleSheets->GetStyleSheetByPosition(nAktPosition).get();
}
-
- if ( nIdx != -1 )
+ }
+ else
{
- nAktPosition = (sal_uInt16)nIdx;
- return pAktStyle = pBasePool->aStyles[nIdx].get();
+ DoesStyleMatchStyleSheetPredicate predicate(this);
+ rtl::Reference< SfxStyleSheetBase > ref =
+ pBasePool->mIndexedStyleSheets->GetNthStyleSheetThatMatchesPredicate(
+ 0, predicate, nAktPosition+1);
+ retval = ref.get();
+ if (retval != NULL) {
+ nAktPosition = pBasePool->mIndexedStyleSheets->FindStyleSheetPosition(*ref);
+ }
}
- return 0;
+ pAktStyle = retval;
+ return retval;
}
-
SfxStyleSheetBase* SfxStyleSheetIterator::Find(const OUString& rStr)
{
- for ( sal_uInt16 n = 0; n < pBasePool->aStyles.size(); ++n )
- {
- SfxStyleSheetBase* pStyle = pBasePool->aStyles[n].get();
+ DoesStyleMatchStyleSheetPredicate predicate(this);
- // #98454# performance: in case of bSearchUsed==sal_True it may be
- // significant to first compare the name and only if it matches to call
- // the style sheet IsUsed() method in DoesStyleMatch().
- if ( pStyle->GetName() == rStr && DoesStyleMatch( pStyle ) )
- {
- nAktPosition = n;
- return pAktStyle = pStyle;
- }
+ std::vector<unsigned> positions =
+ pBasePool->mIndexedStyleSheets->FindPositionsByNameAndPredicate(rStr, predicate);
+ if (positions.empty()) {
+ return NULL;
}
- return 0;
+
+ unsigned pos = positions.front();
+ SfxStyleSheetBase* pStyle = pBasePool->mIndexedStyleSheets->GetStyleSheetByPosition(pos).get();
+ nAktPosition = pos;
+ pAktStyle = pStyle;
+ return pAktStyle;
}
sal_uInt16 SfxStyleSheetIterator::GetSearchMask() const
@@ -545,6 +545,7 @@ SfxStyleSheetBasePool::SfxStyleSheetBasePool( SfxItemPool& r )
, rPool(r)
, nSearchFamily(SFX_STYLE_FAMILY_PARA)
, nMask(SFXSTYLEBIT_ALL)
+ , mIndexedStyleSheets(new svl::IndexedStyleSheets)
{
#ifdef DBG_UTIL
aDbgStyleSheetReferences.mnPools++;
@@ -560,6 +561,7 @@ SfxStyleSheetBasePool::SfxStyleSheetBasePool( const SfxStyleSheetBasePool& r )
, rPool(r.rPool)
, nSearchFamily(r.nSearchFamily)
, nMask( r.nMask )
+ , mIndexedStyleSheets(new svl::IndexedStyleSheets)
{
#ifdef DBG_UTIL
aDbgStyleSheetReferences.mnPools++;
@@ -637,7 +639,7 @@ SfxStyleSheetBase& SfxStyleSheetBasePool::Make( const OUString& rName, SfxStyleF
if( !xStyle.is() )
{
xStyle = Create( rName, eFam, mask );
- aStyles.push_back(xStyle);
+ StoreStyleSheet(xStyle);
Broadcast( SfxStyleSheetHint( SFX_STYLESHEET_CREATED, *xStyle.get() ) );
}
return *xStyle.get();
@@ -647,13 +649,15 @@ SfxStyleSheetBase& SfxStyleSheetBasePool::Make( const OUString& rName, SfxStyleF
// sie neu erzeugt. Alle Vorlagen, die diese Vorlage zum Parent haben,
// werden umgehaengt.
-SfxStyleSheetBase& SfxStyleSheetBasePool::Add( SfxStyleSheetBase& rSheet )
+SfxStyleSheetBase& SfxStyleSheetBasePool::Add( const SfxStyleSheetBase& rSheet )
{
SfxStyleSheetIterator aIter(this, rSheet.GetFamily(), nMask);
SfxStyleSheetBase* pOld = aIter.Find( rSheet.GetName() );
- Remove( pOld );
+ if (pOld) {
+ Remove( pOld );
+ }
rtl::Reference< SfxStyleSheetBase > xNew( Create( rSheet ) );
- aStyles.push_back( xNew );
+ mIndexedStyleSheets->AddStyleSheet(xNew);
Broadcast( SfxStyleSheetHint( SFX_STYLESHEET_CHANGED, *xNew.get() ) );
return *xNew.get();
}
@@ -668,15 +672,27 @@ SfxStyleSheetBasePool& SfxStyleSheetBasePool::operator=( const SfxStyleSheetBase
return *this;
}
+namespace {
+struct AddStyleSheetCallback : svl::StyleSheetCallback
+{
+ AddStyleSheetCallback(SfxStyleSheetBasePool *pool)
+ : mPool(pool) {;}
+
+ void DoIt(const SfxStyleSheetBase& ssheet)
+ {
+ mPool->Add(ssheet);
+ }
+
+ SfxStyleSheetBasePool *mPool;
+};
+}
+
SfxStyleSheetBasePool& SfxStyleSheetBasePool::operator+=( const SfxStyleSheetBasePool& r )
{
if( &r != this )
{
- SfxStyles::const_iterator aIter( r.aStyles.begin() );
- while( aIter != r.aStyles.end() )
- {
- Add(*(*aIter++).get());
- }
+ AddStyleSheetCallback callback(this);
+ mIndexedStyleSheets->ApplyToAllStyleSheets(callback);
}
return *this;
}
@@ -715,9 +731,8 @@ void SfxStyleSheetBasePool::Remove( SfxStyleSheetBase* p )
{
// Reference to keep p alive until after Broadcast call!
rtl::Reference<SfxStyleSheetBase> xP(p);
- SfxStyles::iterator const aIter(
- std::find(aStyles.begin(), aStyles.end(), xP));
- if( aIter != aStyles.end() )
+ bool bWasRemoved = mIndexedStyleSheets->RemoveStyleSheet(xP);
+ if( bWasRemoved )
{
// Alle Styles umsetzen, deren Parent dieser hier ist
ChangeParent( p->GetName(), p->GetParent() );
@@ -735,8 +750,6 @@ void SfxStyleSheetBasePool::Remove( SfxStyleSheetBase* p )
// catch( com::sun::star::uno::Exception& )
// {
// }
-
- aStyles.erase(aIter);
Broadcast( SfxStyleSheetHint( SFX_STYLESHEET_ERASED, *p ) );
}
}
@@ -756,19 +769,24 @@ void SfxStyleSheetBasePool::Insert( SfxStyleSheetBase* p )
OSL_ENSURE( pOld, "svl::SfxStyleSheetBasePool::Insert(), Parent not found!" );
}
#endif
- aStyles.push_back( rtl::Reference< SfxStyleSheetBase >( p ) );
+ StoreStyleSheet(rtl::Reference< SfxStyleSheetBase >( p ) );
Broadcast( SfxStyleSheetHint( SFX_STYLESHEET_CREATED, *p ) );
}
-void SfxStyleSheetBasePool::Clear()
+namespace
{
- SfxStyles aClearStyles;
- aClearStyles.swap( aStyles );
- SfxStyles::iterator aIter( aClearStyles.begin() );
- while( aIter != aClearStyles.end() )
+struct StyleSheetDisposerFunctor SAL_FINAL : public svl::StyleSheetDisposer
+{
+ StyleSheetDisposerFunctor(SfxStyleSheetBasePool* pool)
+ : mPool(pool) {;}
+
+ void
+ Dispose(rtl::Reference<SfxStyleSheetBase> styleSheet)
{
- com::sun::star::uno::Reference< com::sun::star::lang::XComponent > xComp( static_cast< ::cppu::OWeakObject* >((*aIter).get()), com::sun::star::uno::UNO_QUERY );
+ cppu::OWeakObject* weakObject = static_cast< ::cppu::OWeakObject* >(styleSheet.get());
+ com::sun::star::uno::Reference< com::sun::star::lang::XComponent >
+ xComp( weakObject, com::sun::star::uno::UNO_QUERY );
if( xComp.is() ) try
{
xComp->dispose();
@@ -776,9 +794,18 @@ void SfxStyleSheetBasePool::Clear()
catch( com::sun::star::uno::Exception& )
{
}
-
- Broadcast( SfxStyleSheetHint( SFX_STYLESHEET_ERASED, *(*aIter++).get() ) );
+ mPool->Broadcast( SfxStyleSheetHint( SFX_STYLESHEET_ERASED, *styleSheet.get() ) );
}
+
+ SfxStyleSheetBasePool* mPool;
+};
+
+}
+
+void SfxStyleSheetBasePool::Clear()
+{
+ StyleSheetDisposerFunctor cleanup(this);
+ mIndexedStyleSheets->Clear(cleanup);
}
void SfxStyleSheetBasePool::ChangeParent(const OUString& rOld,
@@ -928,6 +955,11 @@ SfxUnoStyleSheet* SfxUnoStyleSheet::getUnoStyleSheet( const ::com::sun::star::un
}
}
+void
+SfxStyleSheetBasePool::StoreStyleSheet(rtl::Reference< SfxStyleSheetBase > xStyle)
+{
+ mIndexedStyleSheets->AddStyleSheet(xStyle);
+}
namespace
{
@@ -939,4 +971,22 @@ const ::com::sun::star::uno::Sequence< ::sal_Int8 >& SfxUnoStyleSheet::getIdenti
return theSfxUnoStyleSheetIdentifier::get().getSeq();
}
+void
+SfxStyleSheetBasePool::Reindex()
+{
+ mIndexedStyleSheets->Reindex();
+}
+
+const svl::IndexedStyleSheets&
+SfxStyleSheetBasePool::GetIndexedStyleSheets() const
+{
+ return *mIndexedStyleSheets;
+}
+
+rtl::Reference<SfxStyleSheetBase>
+SfxStyleSheetBasePool::GetStyleSheetByPositionInIndex(unsigned pos)
+{
+ return mIndexedStyleSheets->GetStyleSheetByPosition(pos);
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */