summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomaž Vajngerl <quikee@gmail.com>2012-09-23 21:49:45 +0200
committerTomaž Vajngerl <quikee@gmail.com>2012-09-23 22:00:57 +0200
commit0513e10635c85fc1aa214948de4992d4b76d555c (patch)
tree45bf6af83c16bc35c2917111184ddc606fe4b01b
parente9cd84cfaa323ca744fc39096bb90d8f564a1411 (diff)
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
-rw-r--r--cui/source/inc/autocdlg.hxx35
-rw-r--r--cui/source/tabpages/autocdlg.cxx188
-rw-r--r--editeng/inc/editeng/svxacorr.hxx7
-rw-r--r--editeng/source/misc/svxacorr.cxx101
4 files changed, 205 insertions, 126 deletions
diff --git a/cui/source/inc/autocdlg.hxx b/cui/source/inc/autocdlg.hxx
index 98c8ccea054e..5dd0bf17a0d6 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 a104a154847f..858a11388b20 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 862bf1da71f5..cb5ec5d881bd 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 9d618a6d327e..9c5809009587 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();