[Libreoffice-commits] .: 2 commits - cui/source editeng/inc editeng/source

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Mon Dec 10 12:43:17 PST 2012


 cui/source/tabpages/autocdlg.cxx               |    4 
 editeng/inc/editeng/svxacorr.hxx               |   33 +++
 editeng/source/misc/SvXMLAutoCorrectExport.cxx |    4 
 editeng/source/misc/SvXMLAutoCorrectImport.cxx |    5 
 editeng/source/misc/svxacorr.cxx               |  226 +++++++++++++++++--------
 5 files changed, 189 insertions(+), 83 deletions(-)

New commits:
commit e7e4d6778661d039d6ee9cba1da1a22cea542f3e
Author: Michael Meeks <michael.meeks at suse.com>
Date:   Mon Dec 10 20:41:38 2012 +0000

    fdo#55570 - use a hash instead of set initially until sorting needed
    
    This rather substantially accelerates the first use of autocorrection.
    Interestingly, it also appears to accelerate the sorting of the items;
    potentially inserting sorted items into a set is a pathological balancing
    case, that is avoided by the hash algorithm's randomness.

diff --git a/editeng/inc/editeng/svxacorr.hxx b/editeng/inc/editeng/svxacorr.hxx
index 1aec424..79f8e9d 100644
--- a/editeng/inc/editeng/svxacorr.hxx
+++ b/editeng/inc/editeng/svxacorr.hxx
@@ -33,6 +33,7 @@
 
 #include <map>
 #include <set>
+#include <boost/unordered_map.hpp>
 #include <boost/ptr_container/ptr_map.hpp>
 
 class CharClass;
@@ -132,7 +133,7 @@ public:
 
     const String& GetShort() const                  { return sShort; }
     const String& GetLong() const                   { return sLong; }
-    sal_Bool IsTextOnly() const                         { return bIsTxtOnly; }
+    sal_Bool IsTextOnly() const                     { return bIsTxtOnly; }
 };
 
 struct CompareSvxAutocorrWordList
@@ -140,20 +141,32 @@ struct CompareSvxAutocorrWordList
   bool operator()( SvxAutocorrWord* const& lhs, SvxAutocorrWord* const& rhs ) const;
 };
 
-typedef std::set<SvxAutocorrWord*, CompareSvxAutocorrWordList> SvxAutocorrWordList_Base;
-class EDITENG_DLLPUBLIC SvxAutocorrWordList : SvxAutocorrWordList_Base
+typedef std::set<SvxAutocorrWord*, CompareSvxAutocorrWordList> SvxAutocorrWordList_Set;
+typedef ::boost::unordered_map< ::rtl::OUString, SvxAutocorrWord *,
+                                ::rtl::OUStringHash >          SvxAutocorrWordList_Hash;
+
+class EDITENG_DLLPUBLIC SvxAutocorrWordList
 {
+    // only one of these contains the data
+    mutable SvxAutocorrWordList_Set  maSet;
+    mutable SvxAutocorrWordList_Hash maHash; // key is 'Short'
+
+    bool                   WordMatches(const SvxAutocorrWord *pFnd,
+                                       const String &rTxt,
+                                       xub_StrLen &rStt,
+                                       xub_StrLen nEndPos) const;
 public:
-    typedef SvxAutocorrWordList_Base::iterator iterator;
+                           // free any objects still in the set
+                           ~SvxAutocorrWordList();
+    void                   DeleteAndDestroyAll();
+    bool                   Insert(SvxAutocorrWord *pWord);
+    SvxAutocorrWord*       FindAndRemove(SvxAutocorrWord *pWord);
+    void                   LoadEntry(String sWrong, String sRight, sal_Bool bOnlyTxt);
+    bool                   empty() const;
+
     typedef std::vector<SvxAutocorrWord *> Content;
-    // free any objects still in the set
-    ~SvxAutocorrWordList();
-    void DeleteAndDestroyAll();
-    bool Insert(SvxAutocorrWord *pWord);
-    SvxAutocorrWord *FindAndRemove(SvxAutocorrWord *pWord);
-    void LoadEntry(String sWrong, String sRight, sal_Bool bOnlyTxt);
-    bool     empty() const;
-    Content  getSortedContent() const;
+    Content                getSortedContent() const;
+
     const SvxAutocorrWord* SearchWordsInList(const String& rTxt, xub_StrLen& rStt, xub_StrLen nEndPos) const;
 };
 
diff --git a/editeng/source/misc/svxacorr.cxx b/editeng/source/misc/svxacorr.cxx
index 349f629..aaee953 100644
--- a/editeng/source/misc/svxacorr.cxx
+++ b/editeng/source/misc/svxacorr.cxx
@@ -2657,38 +2657,63 @@ SvxAutocorrWordList::~SvxAutocorrWordList()
 
 void SvxAutocorrWordList::DeleteAndDestroyAll()
 {
-    for( const_iterator it = SvxAutocorrWordList_Base::begin();
-         it != SvxAutocorrWordList_Base::end(); ++it )
-        delete *it;
-    clear();
+    for( SvxAutocorrWordList_Hash::const_iterator it = maHash.begin(); it != maHash.end(); ++it )
+        delete it->second;
+    maHash.clear();
+
+    for( SvxAutocorrWordList_Set::const_iterator it2 = maSet.begin(); it2 != maSet.end(); ++it2 )
+        delete *it2;
+    maSet.clear();
 }
 
+// returns true if inserted
 bool SvxAutocorrWordList::Insert(SvxAutocorrWord *pWord)
 {
-    return SvxAutocorrWordList_Base::insert( pWord ).second;
+    if ( maSet.size() == 0 ) // use the hash
+    {
+        rtl::OUString aShort( pWord->GetShort() );
+        bool bThere = maHash.find( aShort ) != maHash.end();
+        if (!bThere)
+            maHash.insert( std::pair<rtl::OUString, SvxAutocorrWord *>( aShort, pWord ) );
+        return !bThere;
+    }
+    else
+        return maSet.insert( pWord ).second;
 }
 
 void SvxAutocorrWordList::LoadEntry(String sWrong, String sRight, sal_Bool bOnlyTxt)
 {
     SvxAutocorrWord* pNew = new SvxAutocorrWord( sWrong, sRight, bOnlyTxt );
-
     if( !Insert( pNew ) )
         delete pNew;
 }
 
 bool SvxAutocorrWordList::empty() const
 {
-    return SvxAutocorrWordList_Base::empty();
+    return maHash.empty() && maSet.empty();
 }
 
 SvxAutocorrWord *SvxAutocorrWordList::FindAndRemove(SvxAutocorrWord *pWord)
 {
     SvxAutocorrWord *pMatch = NULL;
-    SvxAutocorrWordList::iterator it = find( pWord );
-    if( it != end() )
+
+    if ( maSet.size() == 0 ) // use the hash
     {
-        pMatch = *it;
-        erase (it);
+        SvxAutocorrWordList_Hash::iterator it = maHash.find( pWord->GetShort() );
+        if( it != maHash.end() )
+        {
+            pMatch = it->second;
+            maHash.erase (it);
+        }
+    }
+    else
+    {
+        SvxAutocorrWordList_Set::iterator it = maSet.find( pWord );
+        if( it != maSet.end() )
+        {
+            pMatch = *it;
+            maSet.erase (it);
+        }
     }
     return pMatch;
 }
@@ -2697,35 +2722,61 @@ SvxAutocorrWord *SvxAutocorrWordList::FindAndRemove(SvxAutocorrWord *pWord)
 SvxAutocorrWordList::Content SvxAutocorrWordList::getSortedContent() const
 {
     Content aContent;
-    for( const_iterator it = begin(); it != SvxAutocorrWordList_Base::end(); ++it )
+
+    // convert from hash to set permanantly
+    if ( maSet.size() == 0 )
+    {
+        // This beasty has some O(N log(N)) in a terribly slow ICU collate fn.
+        for( SvxAutocorrWordList_Hash::const_iterator it = maHash.begin(); it != maHash.end(); ++it )
+            maSet.insert( it->second );
+        maHash.clear();
+    }
+    for( SvxAutocorrWordList_Set::const_iterator it = maSet.begin(); it != maSet.end(); ++it )
         aContent.push_back( *it );
+
     return aContent;
 }
 
-const SvxAutocorrWord* SvxAutocorrWordList::SearchWordsInList(const String& rTxt, xub_StrLen& rStt,
-                                                              xub_StrLen nEndPos) const
+bool SvxAutocorrWordList::WordMatches(const SvxAutocorrWord *pFnd,
+                                      const String &rTxt,
+                                      xub_StrLen &rStt,
+                                      xub_StrLen nEndPos) const
 {
-    TransliterationWrapper& rCmp = GetIgnoreTranslWrapper();
-    for( SvxAutocorrWordList::const_iterator it = begin(); it != SvxAutocorrWordList_Base::end(); ++it )
+    const String& rChk = pFnd->GetShort();
+    if( nEndPos >= rChk.Len() )
     {
-        const SvxAutocorrWord* pFnd = *it;
-        const String& rChk = pFnd->GetShort();
-        if( nEndPos >= rChk.Len() )
+        xub_StrLen nCalcStt = nEndPos - rChk.Len();
+        if( ( !nCalcStt || nCalcStt == rStt ||
+              ( nCalcStt < rStt &&
+                IsWordDelim( rTxt.GetChar( nCalcStt - 1 ) ))) )
         {
-            xub_StrLen nCalcStt = nEndPos - rChk.Len();
-            if( ( !nCalcStt || nCalcStt == rStt ||
-                ( nCalcStt < rStt &&
-                    IsWordDelim( rTxt.GetChar(nCalcStt - 1 ) ))) )
+            TransliterationWrapper& rCmp = GetIgnoreTranslWrapper();
+
+            rtl::OUString sWord(rTxt.GetBuffer() + nCalcStt, rChk.Len());
+            if( rCmp.isEqual( rChk, sWord ))
             {
-                rtl::OUString sWord(rTxt.GetBuffer() + nCalcStt, rChk.Len());
-                if( rCmp.isEqual( rChk, sWord ))
-                {
-                    rStt = nCalcStt;
-                    return pFnd;
-                }
+                rStt = nCalcStt;
+                return true;
             }
         }
     }
+    return false;
+}
+
+const SvxAutocorrWord* SvxAutocorrWordList::SearchWordsInList(const String& rTxt, xub_StrLen& rStt,
+                                                              xub_StrLen nEndPos) const
+{
+    for( SvxAutocorrWordList_Hash::const_iterator it = maHash.begin(); it != maHash.end(); ++it )
+    {
+        if( WordMatches( it->second, rTxt, rStt, nEndPos ) )
+            return it->second;
+    }
+
+    for( SvxAutocorrWordList_Set::const_iterator it2 = maSet.begin(); it2 != maSet.end(); ++it2 )
+    {
+        if( WordMatches( *it2, rTxt, rStt, nEndPos ) )
+            return *it2;
+    }
     return 0;
 }
 
commit cccb0bb123ac89a0a4cb8ba335ce5cb64cdc87cf
Author: Michael Meeks <michael.meeks at suse.com>
Date:   Mon Dec 10 16:57:36 2012 +0000

    fdo#55570 - re-factor SvxAutocorrWordList to hide it's innards

diff --git a/cui/source/tabpages/autocdlg.cxx b/cui/source/tabpages/autocdlg.cxx
index 8dea328..66bf164 100644
--- a/cui/source/tabpages/autocdlg.cxx
+++ b/cui/source/tabpages/autocdlg.cxx
@@ -1024,7 +1024,9 @@ void OfaAutocorrReplacePage::RefillReplaceBox(sal_Bool bFromReset,
         SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
         SvxAutocorrWordList* pWordList = pAutoCorrect->LoadAutocorrWordList(eLang);
         aReplaceTLB.SetUpdateMode(sal_False);
-        for( SvxAutocorrWordList::iterator it = pWordList->begin(); it != pWordList->end(); ++it )
+        SvxAutocorrWordList::Content aContent = pWordList->getSortedContent();
+        for( SvxAutocorrWordList::Content::const_iterator it = aContent.begin();
+             it != aContent.end(); ++it )
         {
             SvxAutocorrWord* pWordPtr = *it;
             sal_Bool bTextOnly = pWordPtr->IsTextOnly();
diff --git a/editeng/inc/editeng/svxacorr.hxx b/editeng/inc/editeng/svxacorr.hxx
index d8920c1..1aec424 100644
--- a/editeng/inc/editeng/svxacorr.hxx
+++ b/editeng/inc/editeng/svxacorr.hxx
@@ -139,12 +139,22 @@ struct CompareSvxAutocorrWordList
 {
   bool operator()( SvxAutocorrWord* const& lhs, SvxAutocorrWord* const& rhs ) const;
 };
-class EDITENG_DLLPUBLIC SvxAutocorrWordList : public std::set<SvxAutocorrWord*, CompareSvxAutocorrWordList>
+
+typedef std::set<SvxAutocorrWord*, CompareSvxAutocorrWordList> SvxAutocorrWordList_Base;
+class EDITENG_DLLPUBLIC SvxAutocorrWordList : SvxAutocorrWordList_Base
 {
 public:
+    typedef SvxAutocorrWordList_Base::iterator iterator;
+    typedef std::vector<SvxAutocorrWord *> Content;
     // free any objects still in the set
     ~SvxAutocorrWordList();
     void DeleteAndDestroyAll();
+    bool Insert(SvxAutocorrWord *pWord);
+    SvxAutocorrWord *FindAndRemove(SvxAutocorrWord *pWord);
+    void LoadEntry(String sWrong, String sRight, sal_Bool bOnlyTxt);
+    bool     empty() const;
+    Content  getSortedContent() const;
+    const SvxAutocorrWord* SearchWordsInList(const String& rTxt, xub_StrLen& rStt, xub_StrLen nEndPos) const;
 };
 
 class EDITENG_DLLPUBLIC SvxAutoCorrectLanguageLists
diff --git a/editeng/source/misc/SvXMLAutoCorrectExport.cxx b/editeng/source/misc/SvXMLAutoCorrectExport.cxx
index 681865e..b70474a 100644
--- a/editeng/source/misc/SvXMLAutoCorrectExport.cxx
+++ b/editeng/source/misc/SvXMLAutoCorrectExport.cxx
@@ -51,7 +51,9 @@ sal_uInt32 SvXMLAutoCorrectExport::exportDoc(enum XMLTokenEnum /*eClass*/)
                    _GetNamespaceMap().GetNameByKey ( XML_NAMESPACE_BLOCKLIST ) );
     {
         SvXMLElementExport aRoot (*this, XML_NAMESPACE_BLOCKLIST, XML_BLOCK_LIST, sal_True, sal_True);
-        for ( SvxAutocorrWordList::const_iterator it = pAutocorr_List->begin(); it != pAutocorr_List->end(); ++it )
+        SvxAutocorrWordList::Content aContent = pAutocorr_List->getSortedContent();
+        for( SvxAutocorrWordList::Content::iterator it = aContent.begin();
+             it != aContent.end(); ++it )
         {
             const SvxAutocorrWord* p = *it;
 
diff --git a/editeng/source/misc/SvXMLAutoCorrectImport.cxx b/editeng/source/misc/SvXMLAutoCorrectImport.cxx
index f6341df..2cedfc2 100644
--- a/editeng/source/misc/SvXMLAutoCorrectImport.cxx
+++ b/editeng/source/misc/SvXMLAutoCorrectImport.cxx
@@ -135,10 +135,7 @@ SvXMLWordContext::SvXMLWordContext(
             bOnlyTxt = sal_True;
         }
     }
-    SvxAutocorrWord* pNew = new SvxAutocorrWord( sWrong, sRight, bOnlyTxt );
-
-    if( !rLocalRef.pAutocorr_List->insert( pNew ).second )
-        delete pNew;
+    rLocalRef.pAutocorr_List->LoadEntry( sWrong, sRight, bOnlyTxt );
 }
 
 SvXMLWordContext::~SvXMLWordContext ( void )
diff --git a/editeng/source/misc/svxacorr.cxx b/editeng/source/misc/svxacorr.cxx
index 400eb9c..349f629 100644
--- a/editeng/source/misc/svxacorr.cxx
+++ b/editeng/source/misc/svxacorr.cxx
@@ -225,14 +225,6 @@ static CollatorWrapper& GetCollatorWrapper()
     return aCollWrp;
 }
 
-
-// Keep the list sorted ...
-bool CompareSvxAutocorrWordList::operator()( SvxAutocorrWord* const& lhs, SvxAutocorrWord* const& rhs ) const
-{
-    CollatorWrapper& rCmp = ::GetCollatorWrapper();
-    return rCmp.compareString( lhs->GetShort(), rhs->GetShort() ) < 0;
-}
-
 static void lcl_ClearTable(boost::ptr_map<LanguageType, SvxAutoCorrectLanguageLists>& rLangTable)
 {
     rLangTable.clear();
@@ -1680,38 +1672,16 @@ static void GeneratePackageName ( const String& rShort, String& rPackageName )
 
 static const SvxAutocorrWord* lcl_SearchWordsInList(
                 SvxAutoCorrectLanguageListsPtr pList, const String& rTxt,
-                xub_StrLen& rStt, xub_StrLen nEndPos, SvxAutoCorrDoc& )
+                xub_StrLen& rStt, xub_StrLen nEndPos)
 {
     const SvxAutocorrWordList* pAutoCorrWordList = pList->GetAutocorrWordList();
-    TransliterationWrapper& rCmp = GetIgnoreTranslWrapper();
-    for( SvxAutocorrWordList::const_iterator it = pAutoCorrWordList->begin(); it != pAutoCorrWordList->end(); ++it )
-    {
-        const SvxAutocorrWord* pFnd = *it;
-        const String& rChk = pFnd->GetShort();
-        if( nEndPos >= rChk.Len() )
-        {
-            xub_StrLen nCalcStt = nEndPos - rChk.Len();
-            if( ( !nCalcStt || nCalcStt == rStt ||
-                ( nCalcStt < rStt &&
-                    IsWordDelim( rTxt.GetChar(nCalcStt - 1 ) ))) )
-            {
-                rtl::OUString sWord(rTxt.GetBuffer() + nCalcStt, rChk.Len());
-                if( rCmp.isEqual( rChk, sWord ))
-                {
-                    rStt = nCalcStt;
-                    return pFnd;
-                }
-            }
-        }
-    }
-    return 0;
+    return pAutoCorrWordList->SearchWordsInList( rTxt, rStt, nEndPos );
 }
 
-
 // the search for the words in the substitution table
 const SvxAutocorrWord* SvxAutoCorrect::SearchWordsInList(
                 const String& rTxt, xub_StrLen& rStt, xub_StrLen nEndPos,
-                SvxAutoCorrDoc& rDoc, LanguageType& rLang )
+                SvxAutoCorrDoc&, LanguageType& rLang )
 {
     LanguageType eLang = rLang;
     const SvxAutocorrWord* pRet = 0;
@@ -1724,7 +1694,7 @@ const SvxAutocorrWord* SvxAutoCorrect::SearchWordsInList(
     {
         //the language is available - so bring it on
         SvxAutoCorrectLanguageLists* pList = pLangTable->find(eLang)->second;
-        pRet = lcl_SearchWordsInList(  pList, rTxt, rStt, nEndPos, rDoc );
+        pRet = lcl_SearchWordsInList( pList, rTxt, rStt, nEndPos );
         if( pRet )
         {
             rLang = eLang;
@@ -1740,7 +1710,7 @@ const SvxAutocorrWord* SvxAutoCorrect::SearchWordsInList(
     {
         //the language is available - so bring it on
         SvxAutoCorrectLanguageLists* pList = pLangTable->find(nTmpKey1)->second;
-        pRet = lcl_SearchWordsInList( pList, rTxt, rStt, nEndPos, rDoc);
+        pRet = lcl_SearchWordsInList( pList, rTxt, rStt, nEndPos );
         if( pRet )
         {
             rLang = nTmpKey1;
@@ -1752,7 +1722,7 @@ const SvxAutocorrWord* SvxAutoCorrect::SearchWordsInList(
     {
         //the language is available - so bring it on
         SvxAutoCorrectLanguageLists* pList = pLangTable->find(nTmpKey2)->second;
-        pRet = lcl_SearchWordsInList( pList, rTxt, rStt, nEndPos, rDoc);
+        pRet = lcl_SearchWordsInList( pList, rTxt, rStt, nEndPos );
         if( pRet )
         {
             rLang = nTmpKey2;
@@ -1764,7 +1734,7 @@ const SvxAutocorrWord* SvxAutoCorrect::SearchWordsInList(
     {
         //the language is available - so bring it on
         SvxAutoCorrectLanguageLists* pList = pLangTable->find(LANGUAGE_DONTKNOW)->second;
-        pRet = lcl_SearchWordsInList( pList, rTxt, rStt, nEndPos, rDoc);
+        pRet = lcl_SearchWordsInList( pList, rTxt, rStt, nEndPos );
         if( pRet )
         {
             rLang = LANGUAGE_DONTKNOW;
@@ -2493,10 +2463,9 @@ sal_Bool SvxAutoCorrectLanguageLists::MakeCombinedChanges( std::vector<SvxAutoco
         for ( sal_uInt32 i=0; i < aDeleteEntries.size(); i++ )
         {
             SvxAutocorrWord aWordToDelete = aDeleteEntries[i];
-            SvxAutocorrWordList::iterator iterator = pAutocorr_List->find( &aWordToDelete );
-            if( iterator != pAutocorr_List->end() )
+            SvxAutocorrWord *pFoundEntry = pAutocorr_List->FindAndRemove( &aWordToDelete );
+            if( pFoundEntry )
             {
-                SvxAutocorrWord* pFoundEntry = *iterator;
                 if( !pFoundEntry->IsTextOnly() )
                 {
                     String aName( aWordToDelete.GetShort() );
@@ -2511,42 +2480,35 @@ sal_Bool SvxAutoCorrectLanguageLists::MakeCombinedChanges( std::vector<SvxAutoco
                         bRet = xStorage->Commit();
                     }
                 }
-                // Update the word list
                 delete pFoundEntry;
-                pAutocorr_List->erase( iterator );
             }
         }
 
         for ( sal_uInt32 i=0; i < aNewEntries.size(); i++ )
         {
-            SvxAutocorrWord* aWordToAdd = new SvxAutocorrWord( aNewEntries[i].GetShort(), aNewEntries[i].GetLong(), sal_True );
-            SvxAutocorrWordList::iterator iterator = pAutocorr_List->find( aWordToAdd );
-            if( iterator != pAutocorr_List->end() )
+            SvxAutocorrWord *pWordToAdd = new SvxAutocorrWord( aNewEntries[i].GetShort(), aNewEntries[i].GetLong(), sal_True );
+            SvxAutocorrWord *pRemoved = pAutocorr_List->FindAndRemove( pWordToAdd );
+            if( pRemoved )
             {
-                if( !(*iterator)->IsTextOnly() )
+                if( !pRemoved->IsTextOnly() )
                 {
                     // Still have to remove the Storage
-                    String sStorageName( aWordToAdd->GetShort() );
+                    String sStorageName( pWordToAdd->GetShort() );
                     if (xStorage->IsOLEStorage())
-                    {
                         EncryptBlockName_Imp( sStorageName );
-                    }
                     else
-                    {
-                        GeneratePackageName ( aWordToAdd->GetShort(), sStorageName);
-                    }
+                        GeneratePackageName ( pWordToAdd->GetShort(), sStorageName);
 
                     if( xStorage->IsContained( sStorageName ) )
                         xStorage->Remove( sStorageName );
                 }
-                delete *iterator;
-                pAutocorr_List->erase( iterator );
+                delete pRemoved;
             }
-            bRet = pAutocorr_List->insert( aWordToAdd ).second;
+            bRet = pAutocorr_List->Insert( pWordToAdd );
 
             if ( !bRet )
             {
-                delete aWordToAdd;
+                delete pWordToAdd;
                 break;
             }
         }
@@ -2573,10 +2535,10 @@ sal_Bool SvxAutoCorrectLanguageLists::PutText( const String& rShort, const Strin
     if( bRet )
     {
         SvxAutocorrWord* pNew = new SvxAutocorrWord( rShort, rLong, sal_True );
-        SvxAutocorrWordList::iterator it = pAutocorr_List->find( pNew );
-        if( it != pAutocorr_List->end() )
+        SvxAutocorrWord *pRemove = pAutocorr_List->FindAndRemove( pNew );
+        if( pRemove )
         {
-            if( !(*it)->IsTextOnly() )
+            if( !pRemove->IsTextOnly() )
             {
                 // Still have to remove the Storage
                 String sStgNm( rShort );
@@ -2588,11 +2550,10 @@ sal_Bool SvxAutoCorrectLanguageLists::PutText( const String& rShort, const Strin
                 if( xStg->IsContained( sStgNm ) )
                     xStg->Remove( sStgNm );
             }
-            delete *it;
-            pAutocorr_List->erase( it );
+            delete pRemove;
         }
 
-        if( pAutocorr_List->insert( pNew ).second )
+        if( pAutocorr_List->Insert( pNew ) )
         {
             bRet = MakeBlocklist_Imp( *xStg );
             xStg = 0;
@@ -2607,7 +2568,7 @@ sal_Bool SvxAutoCorrectLanguageLists::PutText( const String& rShort, const Strin
 }
 
 sal_Bool SvxAutoCorrectLanguageLists::PutText( const String& rShort,
-                                        SfxObjectShell& rShell )
+                                               SfxObjectShell& rShell )
 {
     // First get the current list!
     GetAutocorrWordList();
@@ -2626,7 +2587,7 @@ sal_Bool SvxAutoCorrectLanguageLists::PutText( const String& rShort,
         if( bRet )
         {
             SvxAutocorrWord* pNew = new SvxAutocorrWord( rShort, sLong, sal_False );
-            if( pAutocorr_List->insert( pNew ).second )
+            if( pAutocorr_List->Insert( pNew ) )
             {
                 SotStorageRef xStor = new SotStorage( sUserAutoCorrFile, STREAM_READWRITE, sal_True );
                 MakeBlocklist_Imp( *xStor );
@@ -2655,10 +2616,9 @@ sal_Bool SvxAutoCorrectLanguageLists::DeleteText( const String& rShort )
     if( bRet )
     {
         SvxAutocorrWord aTmp( rShort, rShort );
-        SvxAutocorrWordList::iterator it = pAutocorr_List->find( &aTmp );
-        if( it != pAutocorr_List->end() )
+        SvxAutocorrWord *pFnd = pAutocorr_List->FindAndRemove( &aTmp );
+        if( pFnd )
         {
-            SvxAutocorrWord* pFnd = *it;
             if( !pFnd->IsTextOnly() )
             {
                 String aName( rShort );
@@ -2673,9 +2633,7 @@ sal_Bool SvxAutoCorrectLanguageLists::DeleteText( const String& rShort )
                 }
 
             }
-            // Update the word list
             delete pFnd;
-            pAutocorr_List->erase( it );
             MakeBlocklist_Imp( *xStg );
             xStg = 0;
         }
@@ -2685,6 +2643,13 @@ sal_Bool SvxAutoCorrectLanguageLists::DeleteText( const String& rShort )
     return bRet;
 }
 
+// Keep the list sorted ...
+bool CompareSvxAutocorrWordList::operator()( SvxAutocorrWord* const& lhs, SvxAutocorrWord* const& rhs ) const
+{
+    CollatorWrapper& rCmp = ::GetCollatorWrapper();
+    return rCmp.compareString( lhs->GetShort(), rhs->GetShort() ) < 0;
+}
+
 SvxAutocorrWordList::~SvxAutocorrWordList()
 {
     DeleteAndDestroyAll();
@@ -2692,10 +2657,76 @@ SvxAutocorrWordList::~SvxAutocorrWordList()
 
 void SvxAutocorrWordList::DeleteAndDestroyAll()
 {
-    for( const_iterator it = begin(); it != end(); ++it )
+    for( const_iterator it = SvxAutocorrWordList_Base::begin();
+         it != SvxAutocorrWordList_Base::end(); ++it )
         delete *it;
     clear();
 }
 
+bool SvxAutocorrWordList::Insert(SvxAutocorrWord *pWord)
+{
+    return SvxAutocorrWordList_Base::insert( pWord ).second;
+}
+
+void SvxAutocorrWordList::LoadEntry(String sWrong, String sRight, sal_Bool bOnlyTxt)
+{
+    SvxAutocorrWord* pNew = new SvxAutocorrWord( sWrong, sRight, bOnlyTxt );
+
+    if( !Insert( pNew ) )
+        delete pNew;
+}
+
+bool SvxAutocorrWordList::empty() const
+{
+    return SvxAutocorrWordList_Base::empty();
+}
+
+SvxAutocorrWord *SvxAutocorrWordList::FindAndRemove(SvxAutocorrWord *pWord)
+{
+    SvxAutocorrWord *pMatch = NULL;
+    SvxAutocorrWordList::iterator it = find( pWord );
+    if( it != end() )
+    {
+        pMatch = *it;
+        erase (it);
+    }
+    return pMatch;
+}
+
+// return the sorted contents - defer sorting until we have to.
+SvxAutocorrWordList::Content SvxAutocorrWordList::getSortedContent() const
+{
+    Content aContent;
+    for( const_iterator it = begin(); it != SvxAutocorrWordList_Base::end(); ++it )
+        aContent.push_back( *it );
+    return aContent;
+}
+
+const SvxAutocorrWord* SvxAutocorrWordList::SearchWordsInList(const String& rTxt, xub_StrLen& rStt,
+                                                              xub_StrLen nEndPos) const
+{
+    TransliterationWrapper& rCmp = GetIgnoreTranslWrapper();
+    for( SvxAutocorrWordList::const_iterator it = begin(); it != SvxAutocorrWordList_Base::end(); ++it )
+    {
+        const SvxAutocorrWord* pFnd = *it;
+        const String& rChk = pFnd->GetShort();
+        if( nEndPos >= rChk.Len() )
+        {
+            xub_StrLen nCalcStt = nEndPos - rChk.Len();
+            if( ( !nCalcStt || nCalcStt == rStt ||
+                ( nCalcStt < rStt &&
+                    IsWordDelim( rTxt.GetChar(nCalcStt - 1 ) ))) )
+            {
+                rtl::OUString sWord(rTxt.GetBuffer() + nCalcStt, rChk.Len());
+                if( rCmp.isEqual( rChk, sWord ))
+                {
+                    rStt = nCalcStt;
+                    return pFnd;
+                }
+            }
+        }
+    }
+    return 0;
+}
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */


More information about the Libreoffice-commits mailing list