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 <qui...@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();
_______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits