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
This commit is contained in:
@@ -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)
|
||||
|
||||
for (StringChangeTable::reverse_iterator it = aChangesTable.rbegin(); it != aChangesTable.rend(); it++)
|
||||
{
|
||||
LanguageType eCurLang = it->first;
|
||||
DoubleStringArray& rDoubleStringArray = it->second;
|
||||
if( eCurLang != eLang ) // the current language is treated later
|
||||
LanguageType eCurrentLang = it->first;
|
||||
StringChangeList& rStringChangeList = it->second;
|
||||
std::vector<SvxAutocorrWord> aDeleteWords;
|
||||
std::vector<SvxAutocorrWord> aNewWords;
|
||||
|
||||
for (sal_uInt32 i = 0; i < rStringChangeList.aDeletedEntries.size(); i++)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
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++)
|
||||
{
|
||||
DoubleString& newEntry = rStringChangeList.aNewEntries[i];
|
||||
SvxAutocorrWord aNewWord( newEntry.sShort, newEntry.sLong );
|
||||
aNewWords.push_back( aNewWord );
|
||||
}
|
||||
pAutoCorrect->MakeCombinedChanges( aNewWords, aDeleteWords, eCurrentLang );
|
||||
}
|
||||
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;
|
||||
|
||||
}
|
||||
nListBoxPos --;
|
||||
}
|
||||
nListBoxPos = nLastListBoxPos;
|
||||
if(!bFound)
|
||||
{
|
||||
pAutoCorrect->DeleteText(sEntry, eLang);
|
||||
}
|
||||
|
||||
}
|
||||
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);
|
||||
}
|
||||
else
|
||||
{
|
||||
String sLong = aReplaceTLB.GetEntryText(pEntry, 1);
|
||||
pAutoCorrect->PutText(sShort, sLong, eLang);
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
|
Reference in New Issue
Block a user