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

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Sun Sep 23 13:01:24 PDT 2012


 cui/source/inc/autocdlg.hxx      |   35 ++++---
 cui/source/tabpages/autocdlg.cxx |  188 +++++++++++++++------------------------
 editeng/inc/editeng/svxacorr.hxx |    7 +
 editeng/source/misc/svxacorr.cxx |  101 ++++++++++++++++++++
 4 files changed, 205 insertions(+), 126 deletions(-)

New commits:
commit 0513e10635c85fc1aa214948de4992d4b76d555c
Author: Tomaž Vajngerl <quikee at gmail.com>
Date:   Sun Sep 23 21:49:45 2012 +0200

    fdo#49350 Speedup "OK" action of auto-correct dialog
    
    Instead of synchronizing the main list and the list of entries in the
    dialog, just remember what was added and removed and only add / remove
    those entries in the main "SvxAutoCorrect" list.
    Additional add MakeCombinedChanges which adds and remove entries in
    one call and only writes changes to the "acor" file once.
    
    Change-Id: Idcc4c64d25e050c3f6eb9960a59c4a55d06b5ca1

diff --git a/cui/source/inc/autocdlg.hxx b/cui/source/inc/autocdlg.hxx
index 98c8cce..5dd0bf1 100644
--- a/cui/source/inc/autocdlg.hxx
+++ b/cui/source/inc/autocdlg.hxx
@@ -223,9 +223,18 @@ struct DoubleString
     String  sLong;
     void*   pUserData; ///< CheckBox -> form. Text Bool -> selection text
 };
+
 typedef std::vector<DoubleString> DoubleStringArray;
 typedef std::map<LanguageType, DoubleStringArray> DoubleStringTable;
 
+struct StringChangeList
+{
+    DoubleStringArray aNewEntries;
+    DoubleStringArray aDeletedEntries;
+};
+
+typedef std::map<LanguageType, StringChangeList> StringChangeTable;
+
 class OfaAutocorrReplacePage : public SfxTabPage
 {
         using TabPage::ActivatePage;
@@ -233,7 +242,8 @@ class OfaAutocorrReplacePage : public SfxTabPage
 
 private:
 
-        
+        StringChangeTable aChangesTable;
+
         CheckBox        aTextOnlyCB;
         FixedText       aShortFT;
         AutoCorrEdit    aShortED;
@@ -252,32 +262,33 @@ private:
         CharClass*              pCharClass;
         LanguageType            eLang;
 
-        sal_Bool            bHasSelectionText;
-        sal_Bool            bFirstSelect:1;
-        sal_Bool            bReplaceEditChanged:1;
-        sal_Bool            bSWriter:1;
+        sal_Bool bHasSelectionText;
+        sal_Bool bFirstSelect:1;
+        sal_Bool bReplaceEditChanged:1;
+        sal_Bool bSWriter:1;
 
         DECL_LINK(SelectHdl, SvTabListBox*);
         DECL_LINK(NewDelHdl, PushButton*);
         DECL_LINK(ModifyHdl, Edit*);
 
-        void            RefillReplaceBox(sal_Bool bFromReset,
-                                        LanguageType eOldLanguage,
-                                        LanguageType eNewLanguage);
+        void RefillReplaceBox(  sal_Bool bFromReset,
+                                LanguageType eOldLanguage,
+                                LanguageType eNewLanguage);
 
 public:
                         OfaAutocorrReplacePage( Window* pParent, const SfxItemSet& rSet );
                         ~OfaAutocorrReplacePage();
 
-    static SfxTabPage*  Create( Window* pParent,
-                                const SfxItemSet& rAttrSet);
+    static SfxTabPage*  Create( Window* pParent, const SfxItemSet& rAttrSet);
 
-    virtual sal_Bool        FillItemSet( SfxItemSet& rSet );
+    virtual sal_Bool    FillItemSet( SfxItemSet& rSet );
     virtual void        Reset( const SfxItemSet& rSet );
     virtual void        ActivatePage( const SfxItemSet& );
     virtual int         DeactivatePage( SfxItemSet* pSet = 0 );
 
-    void                SetLanguage(LanguageType eSet);
+    void    SetLanguage(LanguageType eSet);
+    void    DeleteEntry(String sShort, String sLong);
+    void    NewEntry(String sShort, String sLong);
 };
 
 // class OfaAutocorrExceptPage ---------------------------------------------
diff --git a/cui/source/tabpages/autocdlg.cxx b/cui/source/tabpages/autocdlg.cxx
index a104a15..858a113 100644
--- a/cui/source/tabpages/autocdlg.cxx
+++ b/cui/source/tabpages/autocdlg.cxx
@@ -918,6 +918,8 @@ OfaAutocorrReplacePage::OfaAutocorrReplacePage( Window* pParent,
 OfaAutocorrReplacePage::~OfaAutocorrReplacePage()
 {
     aDoubleStringTable.clear();
+    aChangesTable.clear();
+
     delete pCompareClass;
     delete pCharClass;
 }
@@ -942,125 +944,30 @@ int OfaAutocorrReplacePage::DeactivatePage( SfxItemSet*  )
 sal_Bool OfaAutocorrReplacePage::FillItemSet( SfxItemSet& )
 {
     SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
-    for (DoubleStringTable::reverse_iterator it = aDoubleStringTable.rbegin(); it != aDoubleStringTable.rend(); ++it)
-    {
-        LanguageType eCurLang = it->first;
-        DoubleStringArray& rDoubleStringArray = it->second;
-        if( eCurLang != eLang ) // the current language is treated later
-        {
-            SvxAutocorrWordList* pWordList = pAutoCorrect->LoadAutocorrWordList(eCurLang);
-            sal_uInt32 nDoubleStringArrayCount = rDoubleStringArray.size();
-            sal_uInt32 nPos = nDoubleStringArrayCount;
-            sal_uInt32 nLastPos = nPos;
 
-            // 1st run: delete or change entries:
-            for( SvxAutocorrWordList::reverse_iterator it2 = pWordList->rbegin(); it2 != pWordList->rend(); ++it2 )
-            {
-                SvxAutocorrWord* pWordPtr = *it2;
-                String sEntry(pWordPtr->GetShort());
-                // formatted text is only in Writer
-                sal_Bool bFound = !bSWriter && !pWordPtr->IsTextOnly();
-                while(!bFound && nPos)
-                {
-                    DoubleString& rDouble = rDoubleStringArray[ nPos - 1];
-
-                    if( pCompareClass->compareString( sEntry, rDouble.sShort ) == 0)
-                    {
-                        nLastPos = nPos - 1;
-                        bFound = sal_True;
-                        if( !(pWordPtr->IsTextOnly() == (0 == rDouble.pUserData)
-                            && 0 == pCompareClass->compareString(
-                                pWordPtr->GetLong(), rDouble.sLong ) ) )
-                        {
-                            pAutoCorrect->PutText(sEntry, rDouble.sLong, eCurLang);
-                        }
-                        rDoubleStringArray.erase(rDoubleStringArray.begin() + nPos - 1);
-                        break;
-                    }
-                    nPos--;
-                }
-                nPos = nLastPos;
-                if(!bFound)
-                {
-                    pAutoCorrect->DeleteText(sEntry, eCurLang);
-                }
-            }
-            nDoubleStringArrayCount = rDoubleStringArray.size();
-            for(sal_uInt32 nDoubleStringArrayPos = 0; nDoubleStringArrayPos < nDoubleStringArrayCount; nDoubleStringArrayPos++ )
-            {
-                // now there should only be new entries left
-                DoubleString& rDouble = rDoubleStringArray[ nDoubleStringArrayPos ];
-                if(rDouble.pUserData == &bHasSelectionText)
-                {
-                    pAutoCorrect->PutText( rDouble.sShort, *SfxObjectShell::Current(), eCurLang );
-                }
-                else
-                {
-                    pAutoCorrect->PutText( rDouble.sShort, rDouble.sLong, eCurLang);
-                }
-            }
-        }
-    }
-    aDoubleStringTable.clear();
-    // and now the current selection
-    SvxAutocorrWordList* pWordList = pAutoCorrect->LoadAutocorrWordList(eLang);
-    sal_uInt32 nListBoxCount = (sal_uInt32) aReplaceTLB.GetEntryCount();
-
-    aReplaceTLB.SetUpdateMode(sal_False);
-    sal_uInt32 nListBoxPos = nListBoxCount;
-    sal_uInt32 nLastListBoxPos = nListBoxPos;
-    // 1st run: delete or change entries:
-
-    for( SvxAutocorrWordList::reverse_iterator it = pWordList->rbegin(); it != pWordList->rend(); ++it )
-    {
-        SvxAutocorrWord* pWordPtr = *it;
-        String sEntry(pWordPtr->GetShort());
-        // formatted text is only in Writer
-        sal_Bool bFound = !bSWriter && !pWordPtr->IsTextOnly();
-        while(!bFound && nListBoxPos)
-        {
-            SvLBoxEntry*  pEntry = aReplaceTLB.GetEntry( nListBoxPos - 1);
-            if( pCompareClass->compareString( sEntry, aReplaceTLB.GetEntryText(pEntry, 0)) == 0)
-            {
-                nLastListBoxPos = nListBoxPos - 1;
-                bFound = sal_True;
-                String sLong = aReplaceTLB.GetEntryText(pEntry, 1);
-                if( !(pWordPtr->IsTextOnly() == (0 == pEntry->GetUserData())
-                    && 0 == pCompareClass->compareString(
-                        pWordPtr->GetLong(), sLong )))
-                {
-                    pAutoCorrect->PutText(sEntry, sLong, eLang);
-                }
-                aReplaceTLB.GetModel()->Remove(pEntry);
-                break;
+    for (StringChangeTable::reverse_iterator it = aChangesTable.rbegin(); it != aChangesTable.rend(); it++)
+    {
+        LanguageType eCurrentLang = it->first;
+        StringChangeList& rStringChangeList = it->second;
+        std::vector<SvxAutocorrWord> aDeleteWords;
+        std::vector<SvxAutocorrWord> aNewWords;
 
-            }
-            nListBoxPos --;
-        }
-        nListBoxPos = nLastListBoxPos;
-        if(!bFound)
+        for (sal_uInt32 i = 0; i < rStringChangeList.aDeletedEntries.size(); i++)
         {
-            pAutoCorrect->DeleteText(sEntry, eLang);
+            DoubleString& deleteEntry = rStringChangeList.aDeletedEntries[i];
+            SvxAutocorrWord aDeleteWord( deleteEntry.sShort, deleteEntry.sLong );
+            aDeleteWords.push_back( aDeleteWord );
         }
 
-    }
-    nListBoxCount = (sal_uInt32) aReplaceTLB.GetEntryCount();
-    for( sal_uInt32 i = 0; i < nListBoxCount; i++ )
-    {
-        // now there should only be new entries left
-        SvLBoxEntry*  pEntry = aReplaceTLB.GetEntry( i );
-        String sShort = aReplaceTLB.GetEntryText(pEntry, 0);
-        if(pEntry->GetUserData() == &bHasSelectionText)
+        for (sal_uInt32 i = 0; i < rStringChangeList.aNewEntries.size(); i++)
         {
-            pAutoCorrect->PutText(sShort, *SfxObjectShell::Current(), eLang);
-        }
-        else
-        {
-            String sLong = aReplaceTLB.GetEntryText(pEntry, 1);
-            pAutoCorrect->PutText(sShort, sLong, eLang);
+            DoubleString& newEntry = rStringChangeList.aNewEntries[i];
+            SvxAutocorrWord aNewWord( newEntry.sShort, newEntry.sLong );
+            aNewWords.push_back( aNewWord );
         }
+        pAutoCorrect->MakeCombinedChanges( aNewWords, aDeleteWords, eCurrentLang );
     }
-
+    aChangesTable.clear();
     return sal_False;
 }
 
@@ -1072,6 +979,7 @@ void OfaAutocorrReplacePage::RefillReplaceBox(sal_Bool bFromReset,
     if(bFromReset)
     {
         aDoubleStringTable.clear();
+        aChangesTable.clear();
     }
     else
     {
@@ -1229,6 +1137,62 @@ IMPL_LINK(OfaAutocorrReplacePage, SelectHdl, SvTabListBox*, pBox)
     return 0;
 };
 
+void OfaAutocorrReplacePage::NewEntry(String sShort, String sLong)
+{
+    DoubleStringArray& rNewArray = aChangesTable[eLang].aNewEntries;
+    for (sal_uInt32 i = 0; i < rNewArray.size(); i++)
+    {
+        if (rNewArray[i].sShort == sShort)
+        {
+            rNewArray.erase(rNewArray.begin() + i);
+            break;
+        }
+    }
+
+    DoubleStringArray& rDeletedArray = aChangesTable[eLang].aDeletedEntries;
+    for (sal_uInt32 i = 0; i < rDeletedArray.size(); i++)
+    {
+        if (rDeletedArray[i].sShort == sShort)
+        {
+            rDeletedArray.erase(rDeletedArray.begin() + i);
+            break;
+        }
+    }
+
+    DoubleString aNewString = DoubleString();
+    aNewString.sShort = sShort;
+    aNewString.sLong = sLong;
+    rNewArray.push_back(aNewString);
+}
+
+void OfaAutocorrReplacePage::DeleteEntry(String sShort, String sLong)
+{
+    DoubleStringArray& rNewArray = aChangesTable[eLang].aNewEntries;
+    for (sal_uInt32 i = 0; i < rNewArray.size(); i++)
+    {
+        if (rNewArray[i].sShort == sShort)
+        {
+            rNewArray.erase(rNewArray.begin() + i);
+            break;
+        }
+    }
+
+    DoubleStringArray& rDeletedArray = aChangesTable[eLang].aDeletedEntries;
+    for (sal_uInt32 i = 0; i < rDeletedArray.size(); i++)
+    {
+        if (rDeletedArray[i].sShort == sShort)
+        {
+            rDeletedArray.erase(rDeletedArray.begin() + i);
+            break;
+        }
+    }
+
+    DoubleString aDeletedString = DoubleString();
+    aDeletedString.sShort = sShort;
+    aDeletedString.sLong = sLong;
+    rDeletedArray.push_back(aDeletedString);
+}
+
 IMPL_LINK(OfaAutocorrReplacePage, NewDelHdl, PushButton*, pBtn)
 {
     SvLBoxEntry* pEntry = aReplaceTLB.FirstSelected();
@@ -1237,6 +1201,7 @@ IMPL_LINK(OfaAutocorrReplacePage, NewDelHdl, PushButton*, pBtn)
         DBG_ASSERT( pEntry, "no entry selected" );
         if( pEntry )
         {
+            DeleteEntry(aReplaceTLB.GetEntryText(pEntry, 0), aReplaceTLB.GetEntryText(pEntry, 1));
             aReplaceTLB.GetModel()->Remove(pEntry);
             ModifyHdl(&aShortED);
             return 0;
@@ -1249,6 +1214,7 @@ IMPL_LINK(OfaAutocorrReplacePage, NewDelHdl, PushButton*, pBtn)
         if(sEntry.Len() && ( aReplaceED.GetText().Len() ||
                 ( bHasSelectionText && bSWriter ) ))
         {
+            NewEntry(aShortED.GetText(), aReplaceED.GetText());
             aReplaceTLB.SetUpdateMode(sal_False);
             sal_uInt32 nPos = UINT_MAX;
             sEntry += '\t';
diff --git a/editeng/inc/editeng/svxacorr.hxx b/editeng/inc/editeng/svxacorr.hxx
index 862bf1d..cb5ec5d 100644
--- a/editeng/inc/editeng/svxacorr.hxx
+++ b/editeng/inc/editeng/svxacorr.hxx
@@ -219,9 +219,10 @@ public:
     sal_Bool PutText( const String& rShort, SfxObjectShell& );
     //  - Deleting an entry
     sal_Bool DeleteText( const String& rShort );
+    //  - Make combined changes in one pass
+    sal_Bool MakeCombinedChanges( std::vector<SvxAutocorrWord>& aNewEntries, std::vector<SvxAutocorrWord>& aDeleteEntries );
 };
 
-
 class EDITENG_DLLPUBLIC SvxAutoCorrect
 {
     friend class SvxAutoCorrectLanguageLists;
@@ -344,6 +345,10 @@ public:
     //  - Delete a entry
     sal_Bool DeleteText( const String& rShort, LanguageType eLang = LANGUAGE_SYSTEM);
 
+    sal_Bool MakeCombinedChanges( std::vector<SvxAutocorrWord>& aNewEntries,
+                                  std::vector<SvxAutocorrWord>& aDeleteEntries,
+                                  LanguageType eLang = LANGUAGE_SYSTEM );
+
     // Load, Set, Get - the exception list for capital letters at the
     // beginning of a sentence
     void SaveCplSttExceptList( LanguageType eLang = LANGUAGE_SYSTEM );
diff --git a/editeng/source/misc/svxacorr.cxx b/editeng/source/misc/svxacorr.cxx
index 9d618a6..9c58090 100644
--- a/editeng/source/misc/svxacorr.cxx
+++ b/editeng/source/misc/svxacorr.cxx
@@ -1610,6 +1610,23 @@ sal_Bool SvxAutoCorrect::DeleteText( const String& rShort, LanguageType eLang )
         return nTmpVal->second->DeleteText(rShort);
     return sal_False;
 }
+sal_Bool SvxAutoCorrect::MakeCombinedChanges( std::vector<SvxAutocorrWord>& aNewEntries,
+                                              std::vector<SvxAutocorrWord>& aDeleteEntries,
+                                              LanguageType eLang )
+{
+    boost::ptr_map<LanguageType, SvxAutoCorrectLanguageLists>::iterator nTmpVal = pLangTable->find(eLang);
+    if(nTmpVal != pLangTable->end())
+    {
+        return nTmpVal->second->MakeCombinedChanges( aNewEntries, aDeleteEntries );
+    }
+    else if(CreateLanguageFile( eLang ))
+    {
+        return pLangTable->find( eLang )->second->MakeCombinedChanges( aNewEntries, aDeleteEntries );
+    }
+    return sal_False;
+
+}
+
 
     //  - return the replacement text (only for SWG-Format, all other
     //      can be taken from the word list!)
@@ -2482,8 +2499,88 @@ sal_Bool SvxAutoCorrectLanguageLists::MakeBlocklist_Imp( SvStorage& rStg )
     return bRet;
 }
 
-sal_Bool SvxAutoCorrectLanguageLists::PutText( const String& rShort,
-                                           const String& rLong )
+sal_Bool SvxAutoCorrectLanguageLists::MakeCombinedChanges( std::vector<SvxAutocorrWord>& aNewEntries, std::vector<SvxAutocorrWord>& aDeleteEntries )
+{
+    // First get the current list!
+    GetAutocorrWordList();
+
+    MakeUserStorage_Impl();
+    SotStorageRef xStorage = new SotStorage( sUserAutoCorrFile, STREAM_READWRITE, sal_True );
+
+    sal_Bool bRet = xStorage.Is() && SVSTREAM_OK == xStorage->GetError();
+
+    if( bRet )
+    {
+        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 = *iterator;
+                if( !pFoundEntry->IsTextOnly() )
+                {
+                    String aName( aWordToDelete.GetShort() );
+                    if (xStorage->IsOLEStorage())
+                        EncryptBlockName_Imp( aName );
+                    else
+                        GeneratePackageName ( aWordToDelete.GetShort(), aName );
+
+                    if( xStorage->IsContained( aName ) )
+                    {
+                        xStorage->Remove( aName );
+                        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() )
+            {
+                if( !(*iterator)->IsTextOnly() )
+                {
+                    // Still have to remove the Storage
+                    String sStorageName( aWordToAdd->GetShort() );
+                    if (xStorage->IsOLEStorage())
+                    {
+                        EncryptBlockName_Imp( sStorageName );
+                    }
+                    else
+                    {
+                        GeneratePackageName ( aWordToAdd->GetShort(), sStorageName);
+                    }
+
+                    if( xStorage->IsContained( sStorageName ) )
+                        xStorage->Remove( sStorageName );
+                }
+                delete *iterator;
+                pAutocorr_List->erase( iterator );
+            }
+            bRet = pAutocorr_List->insert( aWordToAdd ).second;
+
+            if ( !bRet )
+            {
+                delete aWordToAdd;
+                break;
+            }
+        }
+
+        if ( bRet )
+        {
+            bRet = MakeBlocklist_Imp( *xStorage );
+        }
+    }
+    return bRet;
+}
+
+sal_Bool SvxAutoCorrectLanguageLists::PutText( const String& rShort, const String& rLong )
 {
     // First get the current list!
     GetAutocorrWordList();


More information about the Libreoffice-commits mailing list