[Libreoffice-commits] core.git: 2 commits - comphelper/source include/svl sc/source sd/source svl/CppunitTest_svl_items.mk svl/Library_svl.mk svl/Module_svl.mk svl/qa svl/source

Tobias Lippert drtl at fastmail.fm
Tue Mar 11 06:54:50 PDT 2014


 comphelper/source/misc/accessiblecontexthelper.cxx |    2 
 include/svl/IndexedStyleSheets.hxx                 |  180 ++++++++++++++
 include/svl/style.hxx                              |   39 ++-
 sc/source/core/data/stlpool.cxx                    |   51 +++
 sd/source/core/drawdoc4.cxx                        |    1 
 sd/source/core/stlpool.cxx                         |   99 +++++--
 svl/CppunitTest_svl_items.mk                       |   42 +++
 svl/Library_svl.mk                                 |    1 
 svl/Module_svl.mk                                  |    1 
 svl/qa/unit/items/test_IndexedStyleSheets.cxx      |  160 ++++++++++++
 svl/source/items/IndexedStyleSheets.cxx            |  210 ++++++++++++++++
 svl/source/items/style.cxx                         |  268 ++++++++++++---------
 12 files changed, 895 insertions(+), 159 deletions(-)

New commits:
commit 0c17ccc493d0c7a80f37600dae76a09a119bef78
Author: Tobias Lippert <drtl at fastmail.fm>
Date:   Wed Mar 5 20:06:39 2014 +0100

    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 at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/include/svl/IndexedStyleSheets.hxx b/include/svl/IndexedStyleSheets.hxx
new file mode 100644
index 0000000..6980a97
--- /dev/null
+++ b/include/svl/IndexedStyleSheets.hxx
@@ -0,0 +1,180 @@
+/* -*- 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/.
+ */
+
+#ifndef SVL_INDEXEDSTYLESHEETS_HXX_
+#define SVL_INDEXEDSTYLESHEETS_HXX_
+
+#include <sal/types.h>
+
+#include <rtl/ustring.hxx>
+#include <rtl/ref.hxx>
+
+#include <boost/unordered_map.hpp>
+#include <vector>
+
+class SfxStyleSheetBase;
+
+namespace svl {
+
+/** Function object to check whether a style sheet a fulfills specific criteria.
+ * Derive from this class and override the Check() method.
+ */
+struct StyleSheetPredicate {
+    virtual bool Check(const SfxStyleSheetBase& styleSheet) = 0;
+    virtual ~StyleSheetPredicate() {;}
+};
+
+/** Function object for cleanup-Strategy for IndexedSfxStyleSheets::Clear().
+ * Derive from it and do what is necessary to dispose of a style sheet in Dispose().
+ */
+struct StyleSheetDisposer {
+    virtual void Dispose(rtl::Reference<SfxStyleSheetBase> styleSheet) = 0;
+    virtual ~StyleSheetDisposer() {;}
+};
+
+/** Function object to apply a method on all style sheets.
+ * Derive from it and do whatever you want to with the style sheet in the DoIt() method.
+ */
+struct StyleSheetCallback {
+    virtual void DoIt(const SfxStyleSheetBase& styleSheet) = 0;
+    virtual ~StyleSheetCallback() {;}
+};
+
+/** This class holds SfxStyleSheets and allows for access via an id and a name.
+ *
+ * @warning
+ * The identification of style sheets happens by their name. If the name of a sheet changes,
+ * it will not be found again! Please call Reindex() after changing a style sheet's name.
+ *
+ * @internal
+ * This class was implemented to mitigate solve #fdo 30770.
+ * The issue describes an Excel file which takes several hours to open.
+ * An analysis revealed that the time is spent searching for style sheets with linear scans in an array.
+ * This class implements access to the style sheets via their name in (usually) constant time.
+ *
+ * The return type for most methods is a vector of unsigned integers which denote the position
+ * of the style sheets in the vector, and not of pointers to style sheets.
+ * You will need a non-const StyleSheetPool to obtain the actual style sheets.
+ *
+ *
+ * Index-based access is required in several code portions. Hence we have to store the style sheets
+ * in a vector as well as in a map.
+ */
+class SAL_DLLPUBLIC IndexedStyleSheets SAL_FINAL {
+public:
+    IndexedStyleSheets();
+
+    /** Destructor.
+     *
+     * @internal
+     * Is explicit because it has to know how to dispose of SfxStyleSheetBase objects.
+     */
+    ~IndexedStyleSheets();
+
+    /** Adds a style sheet.
+     *
+     * If the style sheet is already contained, this call has no effect.
+     */
+    void
+    AddStyleSheet(rtl::Reference< SfxStyleSheetBase > style);
+
+    /** Removes a style sheet. */
+    bool
+    RemoveStyleSheet(rtl::Reference< SfxStyleSheetBase > style);
+
+    /** Check whether a specified style sheet is stored. */
+    bool
+    HasStyleSheet(rtl::Reference< SfxStyleSheetBase > style) const;
+
+    /** Obtain the number of style sheets which are held */
+    unsigned
+    GetNumberOfStyleSheets() const;
+
+    /** Obtain the number of style sheets for which a certain condition holds */
+    unsigned
+    GetNumberOfStyleSheetsWithPredicate(StyleSheetPredicate& predicate) const;
+
+    /** Return the stylesheet by its position.
+     * You can obtain the position by, e.g., FindStyleSheetPosition()
+     * @internal
+     * Method is not const because the returned style sheet is not const
+     */
+    rtl::Reference< SfxStyleSheetBase >
+    GetStyleSheetByPosition(unsigned pos);
+
+    /** Find the position of a provided style.
+     *
+     * @throws std::runtime_error if the style has not been found.
+     */
+    unsigned
+    FindStyleSheetPosition(const SfxStyleSheetBase& style) const;
+
+    /** Obtain the positions of all styles which have a given name
+     */
+    std::vector<unsigned>
+    FindPositionsByName(const rtl::OUString& name) const;
+
+    /** Obtain the positions of all styles which have a certain name and fulfill a certain condition.
+     *
+     * This method is fast because it can use the name-based index
+     */
+    std::vector<unsigned>
+    FindPositionsByNameAndPredicate(const rtl::OUString& name, StyleSheetPredicate& predicate) const;
+
+    /** Obtain the positions of all styles which fulfill a certain condition.
+     *
+     * This method is slow because it cannot use the name-based index
+     */
+    std::vector<unsigned>
+    FindPositionsByPredicate(StyleSheetPredicate& predicate) const;
+
+    /** Execute a callback on all style sheets */
+    void
+    ApplyToAllStyleSheets(StyleSheetCallback& callback) const;
+
+    /** Clear the contents of the index.
+     * The StyleSheetDisposer::Dispose() method is called on each style sheet, e.g., if you want to broadcast
+     * changes.
+     */
+    void
+    Clear(StyleSheetDisposer& cleanup);
+
+    void
+    Reindex();
+
+    /** Warning: counting for n starts at 0, i.e., the 0th style sheet is the first that is found. */
+    rtl::Reference<SfxStyleSheetBase>
+    GetNthStyleSheetThatMatchesPredicate(unsigned n, StyleSheetPredicate& predicate,
+            unsigned startAt = 0);
+
+private:
+    /** Register the position of a styleName in the index */
+    void
+    Register(const rtl::OUString& styleName, unsigned pos);
+
+    typedef std::vector<rtl::Reference<SfxStyleSheetBase> > VectorType;
+    /** Vector with the stylesheets to allow for index-based access.
+     */
+    VectorType mStyleSheets;
+
+    /** The map type that is used to store the mapping from strings to ids in mStyleSheets
+     *
+     * @internal
+     * Must be an unordered map. A regular map is too slow for some files. */
+    typedef boost::unordered_multimap<rtl::OUString, unsigned, rtl::OUStringHash> MapType;
+
+    /** A map which stores the positions of style sheets by their name */
+    MapType mPositionsByName;
+};
+
+} /* namespace svl */
+
+#endif /* SVL_INDEXEDSTYLESHEETS_HXX_ */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/svl/style.hxx b/include/svl/style.hxx
index 7a558e4..da6931b 100644
--- a/include/svl/style.hxx
+++ b/include/svl/style.hxx
@@ -43,6 +43,7 @@ class SfxItemPool;
 class SfxStyleSheetBasePool;
 class SvStream;
 
+namespace svl { class IndexedStyleSheets; }
 /*
 Everyone changing instances of SfxStyleSheetBasePool or SfxStyleSheetBase
 must broadcast this using <SfxStyleSheetBasePool::GetBroadcaster()> broadcasts.
@@ -144,12 +145,6 @@ public:
     virtual sal_uInt16 GetVersion() const;
 };
 
-
-
-typedef std::vector< rtl::Reference< SfxStyleSheetBase > > SfxStyles;
-
-
-
 class SVL_DLLPUBLIC SfxStyleSheetIterator
 
 /*  [Beschreibung]
@@ -174,18 +169,18 @@ public:
     virtual SfxStyleSheetBase* Find(const OUString& rStr);
     virtual ~SfxStyleSheetIterator();
 
+    bool                    SearchUsed() const { return bSearchUsed; }
+
 protected:
 
     SfxStyleSheetBasePool*  pBasePool;
     SfxStyleFamily          nSearchFamily;
     sal_uInt16              nMask;
 
-    bool                    SearchUsed() const { return bSearchUsed; }
 
 private:
     sal_uInt16                  GetPos() { return nAktPosition; }
     SVL_DLLPRIVATE bool         IsTrivialSearch();
-    SVL_DLLPRIVATE bool         DoesStyleMatch(SfxStyleSheetBase *pStyle);
 
     SfxStyleSheetBase*      pAktStyle;
     sal_uInt16              nAktPosition;
@@ -211,17 +206,24 @@ protected:
 
     OUString                    aAppName;
     SfxItemPool&                rPool;
-    SfxStyles                   aStyles;
     SfxStyleFamily              nSearchFamily;
     sal_uInt16                  nMask;
 
-    SfxStyleSheetBase&          Add( SfxStyleSheetBase& );
     void                        ChangeParent( const OUString&, const OUString&, bool bVirtual = true );
     virtual SfxStyleSheetBase*  Create( const OUString&, SfxStyleFamily, sal_uInt16 );
     virtual SfxStyleSheetBase*  Create( const SfxStyleSheetBase& );
 
     virtual                     ~SfxStyleSheetBasePool();
 
+    void                        StoreStyleSheet(rtl::Reference< SfxStyleSheetBase >);
+
+    /** Obtain the indexed style sheets.
+     */
+    const svl::IndexedStyleSheets&
+                                GetIndexedStyleSheets() const;
+    rtl::Reference<SfxStyleSheetBase>
+                                GetStyleSheetByPositionInIndex(unsigned pos);
+
 public:
                                 SfxStyleSheetBasePool( SfxItemPool& );
                                 SfxStyleSheetBasePool( const SfxStyleSheetBasePool& );
@@ -250,6 +252,8 @@ public:
     SfxStyleSheetBasePool&      operator=( const SfxStyleSheetBasePool& );
     SfxStyleSheetBasePool&      operator+=( const SfxStyleSheetBasePool& );
 
+    unsigned                    GetNumberOfStyles();
+
     virtual SfxStyleSheetBase*  First();
     virtual SfxStyleSheetBase*  Next();
     virtual SfxStyleSheetBase*  Find( const OUString&, SfxStyleFamily eFam, sal_uInt16 n=SFXSTYLEBIT_ALL );
@@ -264,6 +268,21 @@ public:
     void                        SetSearchMask(SfxStyleFamily eFam, sal_uInt16 n=SFXSTYLEBIT_ALL );
     sal_uInt16                      GetSearchMask() const;
     SfxStyleFamily              GetSearchFamily() const  { return nSearchFamily; }
+
+    void                        Reindex();
+    /** Add a style sheet.
+     * Not an actual public function. Do not call it from non-subclasses.
+     */
+    SfxStyleSheetBase&          Add( const SfxStyleSheetBase& );
+
+private:
+    /** This member holds the indexed style sheets.
+     *
+     * @internal
+     * This member is private and not protected in order to have more control which style sheets are added
+     * where. Ideally, all calls which add/remove/change style sheets are done in the base class.
+     */
+    boost::shared_ptr<svl::IndexedStyleSheets> mIndexedStyleSheets;
 };
 
 
diff --git a/sc/source/core/data/stlpool.cxx b/sc/source/core/data/stlpool.cxx
index 455c483..67a2862 100644
--- a/sc/source/core/data/stlpool.cxx
+++ b/sc/source/core/data/stlpool.cxx
@@ -36,6 +36,7 @@
 #include <editeng/justifyitem.hxx>
 #include <svl/itemset.hxx>
 #include <svl/zforlist.hxx>
+#include <svl/IndexedStyleSheets.hxx>
 #include <unotools/charclass.hxx>
 #include <unotools/fontcvt.hxx>
 #include <vcl/outdev.hxx>
@@ -93,7 +94,7 @@ SfxStyleSheetBase& ScStyleSheetPool::Make( const OUString& rName,
     if ( rName == STRING_STANDARD && Find( rName, eFam ) != NULL )
     {
         OSL_FAIL("renaming additional default style");
-        sal_uInt32 nCount = aStyles.size();
+        sal_uInt32 nCount = GetIndexedStyleSheets().GetNumberOfStyleSheets();
         for ( sal_uInt32 nAdd = 1; nAdd <= nCount; nAdd++ )
         {
             OUString aNewName = ScGlobal::GetRscString(STR_STYLENAME_STANDARD);
@@ -102,7 +103,6 @@ SfxStyleSheetBase& ScStyleSheetPool::Make( const OUString& rName,
                 return SfxStyleSheetPool::Make(aNewName, eFam, mask);
         }
     }
-
     return SfxStyleSheetPool::Make(rName, eFam, mask);
 }
 
@@ -480,25 +480,54 @@ void ScStyleSheetPool::CreateStandardStyles()
     DELETEZ( pEdEngine );
 }
 
+namespace {
+
+struct CaseInsensitiveNamePredicate : svl::StyleSheetPredicate
+{
+    CaseInsensitiveNamePredicate(const rtl::OUString& rName, SfxStyleFamily eFam)
+    : mFamily(eFam)
+    {
+        mUppercaseName = ScGlobal::pCharClass->uppercase(rName);
+    }
+
+    bool
+    Check(const SfxStyleSheetBase& rStyleSheet)
+    {
+        if (rStyleSheet.GetFamily() == mFamily)
+        {
+            rtl::OUString aUpName = ScGlobal::pCharClass->uppercase(rStyleSheet.GetName());
+            if (mUppercaseName == aUpName)
+            {
+                return true;
+            }
+        }
+        return false;
+    }
 
+    rtl::OUString mUppercaseName;
+    SfxStyleFamily mFamily;
+};
 
+}
 
+// Functor object to find all style sheets of a family which match a given name caseinsensitively
 ScStyleSheet* ScStyleSheetPool::FindCaseIns( const OUString& rName, SfxStyleFamily eFam )
 {
-    OUString aUpSearch = ScGlobal::pCharClass->uppercase(rName);
+    CaseInsensitiveNamePredicate aPredicate(rName, eFam);
+    std::vector<unsigned> aFoundPositions = GetIndexedStyleSheets().FindPositionsByPredicate(aPredicate);
+    std::vector<unsigned>::const_iterator it = aFoundPositions.begin();
 
-    sal_uInt32 nCount = aStyles.size();
-    for (sal_uInt32 n=0; n<nCount; n++)
+    for (/**/;it != aFoundPositions.end(); ++it)
     {
-        SfxStyleSheetBase* pStyle = aStyles[n].get();
-        if ( pStyle->GetFamily() == eFam )
+        SfxStyleSheetBase *pFound = GetStyleSheetByPositionInIndex(*it).get();
+        ScStyleSheet* pSheet = NULL;
+        // we do not know what kind of sheets we have.
+        pSheet = dynamic_cast<ScStyleSheet*>(pFound);
+        if (pSheet != NULL)
         {
-            OUString aUpName = ScGlobal::pCharClass->uppercase(pStyle->GetName());
-            if (aUpName == aUpSearch)
-                return (ScStyleSheet*)pStyle;
+            return pSheet;
         }
     }
-
     return NULL;
 }
 
diff --git a/sd/source/core/drawdoc4.cxx b/sd/source/core/drawdoc4.cxx
index a6f939b..8ebb925 100644
--- a/sd/source/core/drawdoc4.cxx
+++ b/sd/source/core/drawdoc4.cxx
@@ -1103,6 +1103,7 @@ void SdDrawDocument::RenameLayoutTemplate(const OUString& rOldLayoutName, const
             aReplList.push_back(aReplData);
 
             pSheet->SetName(aSheetName);
+            mxStyleSheetPool.get()->Reindex();
         }
 
         pSheet = aIter.Next();
diff --git a/sd/source/core/stlpool.cxx b/sd/source/core/stlpool.cxx
index 457350a..6b88b0b 100644
--- a/sd/source/core/stlpool.cxx
+++ b/sd/source/core/stlpool.cxx
@@ -53,6 +53,7 @@
 #include <editeng/adjustitem.hxx>
 #include <editeng/numdef.hxx>
 #include <svl/itempool.hxx>
+#include <svl/IndexedStyleSheets.hxx>
 
 #include "stlpool.hxx"
 #include "sdresid.hxx"
@@ -127,8 +128,6 @@ SdStyleSheetPool::SdStyleSheetPool(SfxItemPool const& _rPool, SdDrawDocument* pD
     }
 }
 
-
-
 SdStyleSheetPool::~SdStyleSheetPool()
 {
     DBG_ASSERT( mpDoc == NULL, "sd::SdStyleSheetPool::~SdStyleSheetPool(), dispose me first!" );
@@ -624,41 +623,66 @@ void SdStyleSheetPool::CopySheets(SdStyleSheetPool& rSourcePool, SfxStyleFamily
     CopySheets(rSourcePool, eFamily, rCreatedSheets, emptyName);
 }
 
+namespace
+{
+
+struct HasFamilyPredicate : svl::StyleSheetPredicate
+{
+    HasFamilyPredicate(SfxStyleFamily eFamily)
+    : meFamily(eFamily) {;}
+
+    bool Check(const SfxStyleSheetBase& sheet)
+    {
+        return sheet.GetFamily() == meFamily;
+    }
+    SfxStyleFamily meFamily;
+};
+
+}
+
 void SdStyleSheetPool::CopySheets(SdStyleSheetPool& rSourcePool, SfxStyleFamily eFamily, SdStyleSheetVector& rCreatedSheets, OUString& rRenameSuffix)
 {
     OUString aHelpFile;
 
-    sal_uInt32 nCount = rSourcePool.aStyles.size();
-
     std::vector< std::pair< rtl::Reference< SfxStyleSheetBase >, OUString > > aNewStyles;
     std::vector< std::pair< OUString, OUString > > aRenamedList;
 
-    for (sal_uInt32 n = 0; n < nCount; n++)
+    // find all style sheets of the source pool which have the same family
+    HasFamilyPredicate aHasFamilyPredicate(eFamily);
+    std::vector<unsigned> aSheetsWithFamily = rSourcePool.GetIndexedStyleSheets().FindPositionsByPredicate(aHasFamilyPredicate);
+
+    for (std::vector<unsigned>::const_iterator it = aSheetsWithFamily.begin();
+         it != aSheetsWithFamily.end(); ++it )
     {
-        rtl::Reference< SfxStyleSheetBase > xSheet( rSourcePool.aStyles[sal::static_int_cast<sal_uInt16>(n)] );
+        rtl::Reference< SfxStyleSheetBase > xSheet = GetStyleSheetByPositionInIndex( *it );
+        rtl::OUString aName( xSheet->GetName() );
 
-        if( xSheet->GetFamily() == eFamily )
+        // now check whether we already have a sheet with the same name
+        std::vector<unsigned> aSheetsWithName = GetIndexedStyleSheets().FindPositionsByName(aName);
+        bool bAddToList = false;
+        if (!aSheetsWithName.empty() && !rRenameSuffix.isEmpty())
         {
-            bool bAddToList = false;
-            OUString aName( xSheet->GetName() );
-            SfxStyleSheetBase* pExistingSheet = Find(aName, eFamily);
-            if( pExistingSheet && !rRenameSuffix.isEmpty() )
+            // if we have a rename suffix, try to find a new name
+            SfxStyleSheetBase* pExistingSheet = GetStyleSheetByPositionInIndex(aSheetsWithName.front()).get();
+            sal_Int32 nHash = xSheet->GetItemSet().getHash();
+            if( pExistingSheet->GetItemSet().getHash() != nHash )
             {
-                sal_Int32 nHash = xSheet->GetItemSet().getHash();
-                if( pExistingSheet->GetItemSet().getHash() != nHash )
+                // we have found a sheet with the same name, but different contents. Try to find a new name.
+                // If we already have a sheet with the new name, and it is equal to the one in the source pool,
+                // do nothing.
+                OUString aTmpName = aName + rRenameSuffix;
+                sal_Int32 nSuffix = 1;
+                do
                 {
-                    OUString aTmpName = aName + rRenameSuffix;
-                    sal_Int32 nSuffix = 1;
-                    do
-                    {
-                        aTmpName = aName + rRenameSuffix + OUString::number(nSuffix);
-                        pExistingSheet = Find(aTmpName, eFamily);
-                        nSuffix++;
-                    } while( pExistingSheet && pExistingSheet->GetItemSet().getHash() != nHash );
-                    aName = aTmpName;
-                    bAddToList = true;
-                }
+                    aTmpName = aName + rRenameSuffix + OUString::number(nSuffix);
+                    pExistingSheet = Find(aTmpName, eFamily);
+                    nSuffix++;
+                } while( pExistingSheet && pExistingSheet->GetItemSet().getHash() != nHash );
+                aName = aTmpName;
+                bAddToList = true;
             }
+
+            // we do not already have a sheet with the same name and contents. Create a new one.
             if ( !pExistingSheet )
             {
                 rtl::Reference< SfxStyleSheetBase > xNewSheet( &Make( aName, eFamily ) );
@@ -701,6 +725,8 @@ void SdStyleSheetPool::CopySheets(SdStyleSheetPool& rSourcePool, SfxStyleFamily
         DBG_ASSERT( rSourcePool.Find( (*aIter).second, eFamily ), "StyleSheet has invalid parent: Family mismatch" );
         (*aIter).first->SetParent( (*aIter).second );
     }
+    // we have changed names of style sheets. Trigger reindexing.
+    Reindex();
 }
 
 
@@ -902,15 +928,30 @@ void SdStyleSheetPool::CreatePseudosIfNecessary()
 |*
 \************************************************************************/
 
+namespace
+{
+struct StyleSheetIsUserDefinedPredicate : svl::StyleSheetPredicate
+{
+    StyleSheetIsUserDefinedPredicate()
+    {;}
+
+    bool Check(const SfxStyleSheetBase& sheet)
+    {
+        return sheet.IsUserDefined();
+    }
+};
+}
+
 void SdStyleSheetPool::UpdateStdNames()
 {
     OUString aHelpFile;
-    sal_uInt32  nCount = aStyles.size();
+    StyleSheetIsUserDefinedPredicate aPredicate;
     std::vector<SfxStyleSheetBase*> aEraseList;
-
-    for( sal_uInt32 n=0; n < nCount; n++ )
+    std::vector<unsigned> aUserDefinedStyles = GetIndexedStyleSheets().FindPositionsByPredicate(aPredicate);
+    for (std::vector<unsigned>::const_iterator it = aUserDefinedStyles.begin();
+            it != aUserDefinedStyles.end(); ++it)
     {
-        SfxStyleSheetBase* pStyle = aStyles[ n ].get();
+        SfxStyleSheetBase* pStyle = GetStyleSheetByPositionInIndex(*it).get();
 
         if( !pStyle->IsUserDefined() )
         {
@@ -991,6 +1032,7 @@ void SdStyleSheetPool::UpdateStdNames()
                         // Sheet does exist: old sheet has to be removed
                         aEraseList.push_back( pStyle );
                     }
+                    Reindex();
                 }
             }
         }
@@ -999,6 +1041,7 @@ void SdStyleSheetPool::UpdateStdNames()
     // styles that could not be renamed, must be removed
     for ( size_t i = 0, n = aEraseList.size(); i < n; ++i )
         Remove( aEraseList[ i ] );
+    Reindex();
 }
 
 // Set new SvxNumBulletItem for the respective style sheet
diff --git a/svl/CppunitTest_svl_items.mk b/svl/CppunitTest_svl_items.mk
new file mode 100644
index 0000000..d51b8fc
--- /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 ba4d9b9..a53b223 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 684642c..2e5e6a0 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 0000000..ec8d82d
--- /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 0000000..ca45b53
--- /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 126cd81..ab9800e 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: */
commit e3e1f9f30d80961fd282f9ce765ffb1111201344
Author: Stephan Bergmann <sbergman at redhat.com>
Date:   Tue Mar 11 14:53:54 2014 +0100

    Leftover SAL_CALL
    
    Change-Id: I895b2132ee752f191f30d6adc0af35cad005afe5

diff --git a/comphelper/source/misc/accessiblecontexthelper.cxx b/comphelper/source/misc/accessiblecontexthelper.cxx
index dc9d6ec..0daab35 100644
--- a/comphelper/source/misc/accessiblecontexthelper.cxx
+++ b/comphelper/source/misc/accessiblecontexthelper.cxx
@@ -176,7 +176,7 @@ namespace comphelper
     }
 
 
-    void SAL_CALL OAccessibleContextHelper::NotifyAccessibleEvent( const sal_Int16 _nEventId,
+    void OAccessibleContextHelper::NotifyAccessibleEvent( const sal_Int16 _nEventId,
         const Any& _rOldValue, const Any& _rNewValue )
     {
         if ( !m_pImpl->getClientId( ) )


More information about the Libreoffice-commits mailing list