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
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 ---------------------------------------------
......
......@@ -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';
......
......@@ -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 );
......
......@@ -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();
......
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