Kaydet (Commit) 0513e106 authored tarafından Tomaž Vajngerl's avatar Tomaž Vajngerl

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
üst e9cd84cf
...@@ -223,9 +223,18 @@ struct DoubleString ...@@ -223,9 +223,18 @@ struct DoubleString
String sLong; String sLong;
void* pUserData; ///< CheckBox -> form. Text Bool -> selection text void* pUserData; ///< CheckBox -> form. Text Bool -> selection text
}; };
typedef std::vector<DoubleString> DoubleStringArray; typedef std::vector<DoubleString> DoubleStringArray;
typedef std::map<LanguageType, DoubleStringArray> DoubleStringTable; typedef std::map<LanguageType, DoubleStringArray> DoubleStringTable;
struct StringChangeList
{
DoubleStringArray aNewEntries;
DoubleStringArray aDeletedEntries;
};
typedef std::map<LanguageType, StringChangeList> StringChangeTable;
class OfaAutocorrReplacePage : public SfxTabPage class OfaAutocorrReplacePage : public SfxTabPage
{ {
using TabPage::ActivatePage; using TabPage::ActivatePage;
...@@ -233,7 +242,8 @@ class OfaAutocorrReplacePage : public SfxTabPage ...@@ -233,7 +242,8 @@ class OfaAutocorrReplacePage : public SfxTabPage
private: private:
StringChangeTable aChangesTable;
CheckBox aTextOnlyCB; CheckBox aTextOnlyCB;
FixedText aShortFT; FixedText aShortFT;
AutoCorrEdit aShortED; AutoCorrEdit aShortED;
...@@ -252,32 +262,33 @@ private: ...@@ -252,32 +262,33 @@ private:
CharClass* pCharClass; CharClass* pCharClass;
LanguageType eLang; LanguageType eLang;
sal_Bool bHasSelectionText; sal_Bool bHasSelectionText;
sal_Bool bFirstSelect:1; sal_Bool bFirstSelect:1;
sal_Bool bReplaceEditChanged:1; sal_Bool bReplaceEditChanged:1;
sal_Bool bSWriter:1; sal_Bool bSWriter:1;
DECL_LINK(SelectHdl, SvTabListBox*); DECL_LINK(SelectHdl, SvTabListBox*);
DECL_LINK(NewDelHdl, PushButton*); DECL_LINK(NewDelHdl, PushButton*);
DECL_LINK(ModifyHdl, Edit*); DECL_LINK(ModifyHdl, Edit*);
void RefillReplaceBox(sal_Bool bFromReset, void RefillReplaceBox( sal_Bool bFromReset,
LanguageType eOldLanguage, LanguageType eOldLanguage,
LanguageType eNewLanguage); LanguageType eNewLanguage);
public: public:
OfaAutocorrReplacePage( Window* pParent, const SfxItemSet& rSet ); OfaAutocorrReplacePage( Window* pParent, const SfxItemSet& rSet );
~OfaAutocorrReplacePage(); ~OfaAutocorrReplacePage();
static SfxTabPage* Create( Window* pParent, static SfxTabPage* Create( Window* pParent, const SfxItemSet& rAttrSet);
const SfxItemSet& rAttrSet);
virtual sal_Bool FillItemSet( SfxItemSet& rSet ); virtual sal_Bool FillItemSet( SfxItemSet& rSet );
virtual void Reset( const SfxItemSet& rSet ); virtual void Reset( const SfxItemSet& rSet );
virtual void ActivatePage( const SfxItemSet& ); virtual void ActivatePage( const SfxItemSet& );
virtual int DeactivatePage( SfxItemSet* pSet = 0 ); 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 --------------------------------------------- // class OfaAutocorrExceptPage ---------------------------------------------
......
...@@ -918,6 +918,8 @@ OfaAutocorrReplacePage::OfaAutocorrReplacePage( Window* pParent, ...@@ -918,6 +918,8 @@ OfaAutocorrReplacePage::OfaAutocorrReplacePage( Window* pParent,
OfaAutocorrReplacePage::~OfaAutocorrReplacePage() OfaAutocorrReplacePage::~OfaAutocorrReplacePage()
{ {
aDoubleStringTable.clear(); aDoubleStringTable.clear();
aChangesTable.clear();
delete pCompareClass; delete pCompareClass;
delete pCharClass; delete pCharClass;
} }
...@@ -942,125 +944,30 @@ int OfaAutocorrReplacePage::DeactivatePage( SfxItemSet* ) ...@@ -942,125 +944,30 @@ int OfaAutocorrReplacePage::DeactivatePage( SfxItemSet* )
sal_Bool OfaAutocorrReplacePage::FillItemSet( SfxItemSet& ) sal_Bool OfaAutocorrReplacePage::FillItemSet( SfxItemSet& )
{ {
SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect(); 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 (StringChangeTable::reverse_iterator it = aChangesTable.rbegin(); it != aChangesTable.rend(); it++)
for( SvxAutocorrWordList::reverse_iterator it2 = pWordList->rbegin(); it2 != pWordList->rend(); ++it2 ) {
{ LanguageType eCurrentLang = it->first;
SvxAutocorrWord* pWordPtr = *it2; StringChangeList& rStringChangeList = it->second;
String sEntry(pWordPtr->GetShort()); std::vector<SvxAutocorrWord> aDeleteWords;
// formatted text is only in Writer std::vector<SvxAutocorrWord> aNewWords;
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 (sal_uInt32 i = 0; i < rStringChangeList.aDeletedEntries.size(); i++)
nListBoxPos --;
}
nListBoxPos = nLastListBoxPos;
if(!bFound)
{ {
pAutoCorrect->DeleteText(sEntry, eLang); DoubleString& deleteEntry = rStringChangeList.aDeletedEntries[i];
SvxAutocorrWord aDeleteWord( deleteEntry.sShort, deleteEntry.sLong );
aDeleteWords.push_back( aDeleteWord );
} }
} for (sal_uInt32 i = 0; i < rStringChangeList.aNewEntries.size(); i++)
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)
{ {
pAutoCorrect->PutText(sShort, *SfxObjectShell::Current(), eLang); DoubleString& newEntry = rStringChangeList.aNewEntries[i];
} SvxAutocorrWord aNewWord( newEntry.sShort, newEntry.sLong );
else aNewWords.push_back( aNewWord );
{
String sLong = aReplaceTLB.GetEntryText(pEntry, 1);
pAutoCorrect->PutText(sShort, sLong, eLang);
} }
pAutoCorrect->MakeCombinedChanges( aNewWords, aDeleteWords, eCurrentLang );
} }
aChangesTable.clear();
return sal_False; return sal_False;
} }
...@@ -1072,6 +979,7 @@ void OfaAutocorrReplacePage::RefillReplaceBox(sal_Bool bFromReset, ...@@ -1072,6 +979,7 @@ void OfaAutocorrReplacePage::RefillReplaceBox(sal_Bool bFromReset,
if(bFromReset) if(bFromReset)
{ {
aDoubleStringTable.clear(); aDoubleStringTable.clear();
aChangesTable.clear();
} }
else else
{ {
...@@ -1229,6 +1137,62 @@ IMPL_LINK(OfaAutocorrReplacePage, SelectHdl, SvTabListBox*, pBox) ...@@ -1229,6 +1137,62 @@ IMPL_LINK(OfaAutocorrReplacePage, SelectHdl, SvTabListBox*, pBox)
return 0; 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) IMPL_LINK(OfaAutocorrReplacePage, NewDelHdl, PushButton*, pBtn)
{ {
SvLBoxEntry* pEntry = aReplaceTLB.FirstSelected(); SvLBoxEntry* pEntry = aReplaceTLB.FirstSelected();
...@@ -1237,6 +1201,7 @@ IMPL_LINK(OfaAutocorrReplacePage, NewDelHdl, PushButton*, pBtn) ...@@ -1237,6 +1201,7 @@ IMPL_LINK(OfaAutocorrReplacePage, NewDelHdl, PushButton*, pBtn)
DBG_ASSERT( pEntry, "no entry selected" ); DBG_ASSERT( pEntry, "no entry selected" );
if( pEntry ) if( pEntry )
{ {
DeleteEntry(aReplaceTLB.GetEntryText(pEntry, 0), aReplaceTLB.GetEntryText(pEntry, 1));
aReplaceTLB.GetModel()->Remove(pEntry); aReplaceTLB.GetModel()->Remove(pEntry);
ModifyHdl(&aShortED); ModifyHdl(&aShortED);
return 0; return 0;
...@@ -1249,6 +1214,7 @@ IMPL_LINK(OfaAutocorrReplacePage, NewDelHdl, PushButton*, pBtn) ...@@ -1249,6 +1214,7 @@ IMPL_LINK(OfaAutocorrReplacePage, NewDelHdl, PushButton*, pBtn)
if(sEntry.Len() && ( aReplaceED.GetText().Len() || if(sEntry.Len() && ( aReplaceED.GetText().Len() ||
( bHasSelectionText && bSWriter ) )) ( bHasSelectionText && bSWriter ) ))
{ {
NewEntry(aShortED.GetText(), aReplaceED.GetText());
aReplaceTLB.SetUpdateMode(sal_False); aReplaceTLB.SetUpdateMode(sal_False);
sal_uInt32 nPos = UINT_MAX; sal_uInt32 nPos = UINT_MAX;
sEntry += '\t'; sEntry += '\t';
......
...@@ -219,9 +219,10 @@ public: ...@@ -219,9 +219,10 @@ public:
sal_Bool PutText( const String& rShort, SfxObjectShell& ); sal_Bool PutText( const String& rShort, SfxObjectShell& );
// - Deleting an entry // - Deleting an entry
sal_Bool DeleteText( const String& rShort ); 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 class EDITENG_DLLPUBLIC SvxAutoCorrect
{ {
friend class SvxAutoCorrectLanguageLists; friend class SvxAutoCorrectLanguageLists;
...@@ -344,6 +345,10 @@ public: ...@@ -344,6 +345,10 @@ public:
// - Delete a entry // - Delete a entry
sal_Bool DeleteText( const String& rShort, LanguageType eLang = LANGUAGE_SYSTEM); 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 // Load, Set, Get - the exception list for capital letters at the
// beginning of a sentence // beginning of a sentence
void SaveCplSttExceptList( LanguageType eLang = LANGUAGE_SYSTEM ); void SaveCplSttExceptList( LanguageType eLang = LANGUAGE_SYSTEM );
......
...@@ -1610,6 +1610,23 @@ sal_Bool SvxAutoCorrect::DeleteText( const String& rShort, LanguageType eLang ) ...@@ -1610,6 +1610,23 @@ sal_Bool SvxAutoCorrect::DeleteText( const String& rShort, LanguageType eLang )
return nTmpVal->second->DeleteText(rShort); return nTmpVal->second->DeleteText(rShort);
return sal_False; 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 // - return the replacement text (only for SWG-Format, all other
// can be taken from the word list!) // can be taken from the word list!)
...@@ -2482,8 +2499,88 @@ sal_Bool SvxAutoCorrectLanguageLists::MakeBlocklist_Imp( SvStorage& rStg ) ...@@ -2482,8 +2499,88 @@ sal_Bool SvxAutoCorrectLanguageLists::MakeBlocklist_Imp( SvStorage& rStg )
return bRet; return bRet;
} }
sal_Bool SvxAutoCorrectLanguageLists::PutText( const String& rShort, sal_Bool SvxAutoCorrectLanguageLists::MakeCombinedChanges( std::vector<SvxAutocorrWord>& aNewEntries, std::vector<SvxAutocorrWord>& aDeleteEntries )
const String& rLong ) {
// 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! // First get the current list!
GetAutocorrWordList(); GetAutocorrWordList();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment