2787 lines
97 KiB
C++
2787 lines
97 KiB
C++
/*************************************************************************
|
|
*
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
*
|
|
* Copyright 2000, 2010 Oracle and/or its affiliates.
|
|
*
|
|
* OpenOffice.org - a multi-platform office productivity suite
|
|
*
|
|
* This file is part of OpenOffice.org.
|
|
*
|
|
* OpenOffice.org is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Lesser General Public License version 3
|
|
* only, as published by the Free Software Foundation.
|
|
*
|
|
* OpenOffice.org is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Lesser General Public License version 3 for more details
|
|
* (a copy is included in the LICENSE file that accompanied this code).
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
* version 3 along with OpenOffice.org. If not, see
|
|
* <http://www.openoffice.org/license.html>
|
|
* for a copy of the LGPLv3 License.
|
|
*
|
|
************************************************************************/
|
|
|
|
// MARKER(update_precomp.py): autogen include statement, do not remove
|
|
#include "precompiled_editeng.hxx"
|
|
|
|
|
|
#include <com/sun/star/io/XStream.hpp>
|
|
#include <com/sun/star/lang/Locale.hpp>
|
|
#include <tools/urlobj.hxx>
|
|
#include <tools/table.hxx>
|
|
#include <i18npool/mslangid.hxx>
|
|
#include <vcl/svapp.hxx>
|
|
#include <sot/storinfo.hxx>
|
|
// fuer die Sort-String-Arrays aus dem SVMEM.HXX
|
|
#define _SVSTDARR_STRINGSISORTDTOR
|
|
#define _SVSTDARR_STRINGSDTOR
|
|
#include <svl/svstdarr.hxx>
|
|
#include <svl/fstathelper.hxx>
|
|
#include <svtools/helpopt.hxx>
|
|
#include <svl/urihelper.hxx>
|
|
#include <unotools/charclass.hxx>
|
|
#include <com/sun/star/i18n/UnicodeType.hdl>
|
|
#include <unotools/collatorwrapper.hxx>
|
|
#include <com/sun/star/i18n/CollatorOptions.hpp>
|
|
#include <unotools/localedatawrapper.hxx>
|
|
#include <unotools/transliterationwrapper.hxx>
|
|
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
|
|
#include <comphelper/processfactory.hxx>
|
|
#include <com/sun/star/io/XActiveDataSource.hpp>
|
|
#include <editeng/editids.hrc>
|
|
#include <sot/storage.hxx>
|
|
#include <comphelper/storagehelper.hxx>
|
|
#include <editeng/udlnitem.hxx>
|
|
#include <editeng/wghtitem.hxx>
|
|
#include <editeng/escpitem.hxx>
|
|
#include <editeng/svxacorr.hxx>
|
|
#include <editeng/unolingu.hxx>
|
|
#include <helpid.hrc>
|
|
#include <comphelper/processfactory.hxx>
|
|
#include <com/sun/star/xml/sax/InputSource.hpp>
|
|
#include <com/sun/star/xml/sax/XParser.hpp>
|
|
#include <unotools/streamwrap.hxx>
|
|
#include <SvXMLAutoCorrectImport.hxx>
|
|
#include <SvXMLAutoCorrectExport.hxx>
|
|
#include <ucbhelper/content.hxx>
|
|
#include <com/sun/star/ucb/XCommandEnvironment.hpp>
|
|
#include <com/sun/star/ucb/TransferInfo.hpp>
|
|
#include <com/sun/star/ucb/NameClash.hpp>
|
|
#include <xmloff/xmltoken.hxx>
|
|
#include <vcl/help.hxx>
|
|
|
|
#define CHAR_HARDBLANK ((sal_Unicode)0x00A0)
|
|
|
|
using namespace ::com::sun::star::ucb;
|
|
using namespace ::com::sun::star::uno;
|
|
using namespace ::com::sun::star;
|
|
using namespace ::xmloff::token;
|
|
using namespace ::rtl;
|
|
using namespace ::utl;
|
|
|
|
const int C_NONE = 0x00;
|
|
const int C_FULL_STOP = 0x01;
|
|
const int C_EXCLAMATION_MARK = 0x02;
|
|
const int C_QUESTION_MARK = 0x04;
|
|
|
|
static const sal_Char pImplWrdStt_ExcptLstStr[] = "WordExceptList";
|
|
static const sal_Char pImplCplStt_ExcptLstStr[] = "SentenceExceptList";
|
|
static const sal_Char pImplAutocorr_ListStr[] = "DocumentList";
|
|
static const sal_Char pXMLImplWrdStt_ExcptLstStr[] = "WordExceptList.xml";
|
|
static const sal_Char pXMLImplCplStt_ExcptLstStr[] = "SentenceExceptList.xml";
|
|
static const sal_Char pXMLImplAutocorr_ListStr[] = "DocumentList.xml";
|
|
|
|
static const sal_Char
|
|
/* auch bei diesen Anfaengen - Klammern auf und alle Arten von Anf.Zei. */
|
|
sImplSttSkipChars[] = "\"\'([{\x83\x84\x89\x91\x92\x93\x94",
|
|
/* auch bei diesen Ende - Klammern auf und alle Arten von Anf.Zei. */
|
|
sImplEndSkipChars[] = "\"\')]}\x83\x84\x89\x91\x92\x93\x94";
|
|
|
|
// diese Zeichen sind in Worten erlaubt: (fuer FnCptlSttSntnc)
|
|
static const sal_Char sImplWordChars[] = "-'";
|
|
|
|
void EncryptBlockName_Imp( String& rName );
|
|
void DecryptBlockName_Imp( String& rName );
|
|
|
|
|
|
// FileVersions Nummern fuer die Ersetzungs-/Ausnahmelisten getrennt
|
|
#define WORDLIST_VERSION_358 1
|
|
#define EXEPTLIST_VERSION_358 0
|
|
|
|
|
|
_SV_IMPL_SORTAR_ALG( SvxAutocorrWordList, SvxAutocorrWordPtr )
|
|
TYPEINIT0(SvxAutoCorrect)
|
|
|
|
typedef SvxAutoCorrectLanguageLists* SvxAutoCorrectLanguageListsPtr;
|
|
DECLARE_TABLE( SvxAutoCorrLanguageTable_Impl, SvxAutoCorrectLanguageListsPtr)
|
|
|
|
DECLARE_TABLE( SvxAutoCorrLastFileAskTable_Impl, long )
|
|
|
|
|
|
inline int IsWordDelim( const sal_Unicode c )
|
|
{
|
|
return ' ' == c || '\t' == c || 0x0a == c ||
|
|
0xA0 == c || 0x2011 == c || 0x1 == c;
|
|
}
|
|
|
|
inline int IsLowerLetter( sal_Int32 nCharType )
|
|
{
|
|
return CharClass::isLetterType( nCharType ) &&
|
|
0 == ( ::com::sun::star::i18n::KCharacterType::UPPER & nCharType);
|
|
}
|
|
inline int IsUpperLetter( sal_Int32 nCharType )
|
|
{
|
|
return CharClass::isLetterType( nCharType ) &&
|
|
0 == ( ::com::sun::star::i18n::KCharacterType::LOWER & nCharType);
|
|
}
|
|
|
|
BOOL lcl_IsSymbolChar( CharClass& rCC, const String& rTxt,
|
|
xub_StrLen nStt, xub_StrLen nEnd )
|
|
{
|
|
for( ; nStt < nEnd; ++nStt )
|
|
{
|
|
#if OSL_DEBUG_LEVEL > 1
|
|
sal_Int32 nCharType;
|
|
sal_Int32 nChType;
|
|
nCharType = rCC.getCharacterType( rTxt, nStt );
|
|
nChType = rCC.getType( rTxt, nStt );
|
|
#endif
|
|
if( ::com::sun::star::i18n::UnicodeType::PRIVATE_USE ==
|
|
rCC.getType( rTxt, nStt ))
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
static BOOL lcl_IsInAsciiArr( const sal_Char* pArr, const sal_Unicode c )
|
|
{
|
|
BOOL bRet = FALSE;
|
|
for( ; *pArr; ++pArr )
|
|
if( *pArr == c )
|
|
{
|
|
bRet = TRUE;
|
|
break;
|
|
}
|
|
return bRet;
|
|
}
|
|
|
|
SvxAutoCorrDoc::~SvxAutoCorrDoc()
|
|
{
|
|
}
|
|
|
|
|
|
// wird nach dem austauschen der Zeichen von den Funktionen
|
|
// - FnCptlSttWrd
|
|
// - FnCptlSttSntnc
|
|
// gerufen. Dann koennen die Worte ggfs. in die Ausnahmelisten
|
|
// aufgenommen werden.
|
|
void SvxAutoCorrDoc::SaveCpltSttWord( ULONG, xub_StrLen, const String&,
|
|
sal_Unicode )
|
|
{
|
|
}
|
|
|
|
LanguageType SvxAutoCorrDoc::GetLanguage( xub_StrLen , BOOL ) const
|
|
{
|
|
return LANGUAGE_SYSTEM;
|
|
}
|
|
|
|
static ::com::sun::star::uno::Reference<
|
|
::com::sun::star::lang::XMultiServiceFactory >& GetProcessFact()
|
|
{
|
|
static ::com::sun::star::uno::Reference<
|
|
::com::sun::star::lang::XMultiServiceFactory > xMSF =
|
|
::comphelper::getProcessServiceFactory();
|
|
return xMSF;
|
|
}
|
|
|
|
static USHORT GetAppLang()
|
|
{
|
|
return Application::GetSettings().GetLanguage();
|
|
}
|
|
static LocaleDataWrapper& GetLocaleDataWrapper( USHORT nLang )
|
|
{
|
|
static LocaleDataWrapper aLclDtWrp( GetProcessFact(),
|
|
SvxCreateLocale( GetAppLang() ) );
|
|
::com::sun::star::lang::Locale aLcl( SvxCreateLocale( nLang ));
|
|
const ::com::sun::star::lang::Locale& rLcl = aLclDtWrp.getLoadedLocale();
|
|
if( aLcl.Language != rLcl.Language ||
|
|
aLcl.Country != rLcl.Country ||
|
|
aLcl.Variant != rLcl.Variant )
|
|
aLclDtWrp.setLocale( aLcl );
|
|
return aLclDtWrp;
|
|
}
|
|
static TransliterationWrapper& GetIgnoreTranslWrapper()
|
|
{
|
|
static int bIsInit = 0;
|
|
static TransliterationWrapper aWrp( GetProcessFact(),
|
|
::com::sun::star::i18n::TransliterationModules_IGNORE_CASE |
|
|
::com::sun::star::i18n::TransliterationModules_IGNORE_KANA |
|
|
::com::sun::star::i18n::TransliterationModules_IGNORE_WIDTH );
|
|
if( !bIsInit )
|
|
{
|
|
aWrp.loadModuleIfNeeded( GetAppLang() );
|
|
bIsInit = 1;
|
|
}
|
|
return aWrp;
|
|
}
|
|
static CollatorWrapper& GetCollatorWrapper()
|
|
{
|
|
static int bIsInit = 0;
|
|
static CollatorWrapper aCollWrp( GetProcessFact() );
|
|
if( !bIsInit )
|
|
{
|
|
aCollWrp.loadDefaultCollator( SvxCreateLocale( GetAppLang() ), 0 );
|
|
bIsInit = 1;
|
|
}
|
|
return aCollWrp;
|
|
}
|
|
|
|
|
|
void SvxAutocorrWordList::DeleteAndDestroy( USHORT nP, USHORT nL )
|
|
{
|
|
if( nL )
|
|
{
|
|
DBG_ASSERT( nP < nA && nP + nL <= nA, "ERR_VAR_DEL" );
|
|
for( USHORT n=nP; n < nP + nL; n++ )
|
|
delete *((SvxAutocorrWordPtr*)pData+n);
|
|
SvPtrarr::Remove( nP, nL );
|
|
}
|
|
}
|
|
|
|
|
|
BOOL SvxAutocorrWordList::Seek_Entry( const SvxAutocorrWordPtr aE, USHORT* pP ) const
|
|
{
|
|
register USHORT nO = SvxAutocorrWordList_SAR::Count(),
|
|
nM,
|
|
nU = 0;
|
|
if( nO > 0 )
|
|
{
|
|
CollatorWrapper& rCmp = ::GetCollatorWrapper();
|
|
nO--;
|
|
while( nU <= nO )
|
|
{
|
|
nM = nU + ( nO - nU ) / 2;
|
|
long nCmp = rCmp.compareString( aE->GetShort(),
|
|
(*((SvxAutocorrWordPtr*)pData + nM))->GetShort() );
|
|
if( 0 == nCmp )
|
|
{
|
|
if( pP ) *pP = nM;
|
|
return TRUE;
|
|
}
|
|
else if( 0 < nCmp )
|
|
nU = nM + 1;
|
|
else if( nM == 0 )
|
|
{
|
|
if( pP ) *pP = nU;
|
|
return FALSE;
|
|
}
|
|
else
|
|
nO = nM - 1;
|
|
}
|
|
}
|
|
if( pP ) *pP = nU;
|
|
return FALSE;
|
|
}
|
|
|
|
/* -----------------18.11.98 15:28-------------------
|
|
*
|
|
* --------------------------------------------------*/
|
|
void lcl_ClearTable(SvxAutoCorrLanguageTable_Impl& rLangTable)
|
|
{
|
|
SvxAutoCorrectLanguageListsPtr pLists = rLangTable.Last();
|
|
while(pLists)
|
|
{
|
|
delete pLists;
|
|
pLists = rLangTable.Prev();
|
|
}
|
|
rLangTable.Clear();
|
|
}
|
|
|
|
/* -----------------03.11.06 10:15-------------------
|
|
*
|
|
* --------------------------------------------------*/
|
|
|
|
sal_Bool SvxAutoCorrect::IsAutoCorrectChar( sal_Unicode cChar )
|
|
{
|
|
return cChar == '\0' || cChar == '\t' || cChar == 0x0a ||
|
|
cChar == ' ' || cChar == '\'' || cChar == '\"' ||
|
|
cChar == '*' || cChar == '_' ||
|
|
cChar == '.' || cChar == ',' || cChar == ';' ||
|
|
cChar == ':' || cChar == '?' || cChar == '!' || cChar == '/';
|
|
}
|
|
|
|
sal_Bool SvxAutoCorrect::NeedsHardspaceAutocorr( sal_Unicode cChar )
|
|
{
|
|
return cChar == ';' || cChar == ':' || cChar == '?' || cChar == '!' ||
|
|
cChar == '/' /*case for the urls exception*/;
|
|
}
|
|
|
|
/* -----------------19.11.98 10:15-------------------
|
|
*
|
|
* --------------------------------------------------*/
|
|
long SvxAutoCorrect::GetDefaultFlags()
|
|
{
|
|
long nRet = Autocorrect
|
|
| CptlSttSntnc
|
|
| CptlSttWrd
|
|
| ChgOrdinalNumber
|
|
| ChgToEnEmDash
|
|
| AddNonBrkSpace
|
|
| ChgWeightUnderl
|
|
| SetINetAttr
|
|
| ChgQuotes
|
|
| SaveWordCplSttLst
|
|
| SaveWordWrdSttLst;
|
|
LanguageType eLang = GetAppLang();
|
|
switch( eLang )
|
|
{
|
|
case LANGUAGE_ENGLISH:
|
|
case LANGUAGE_ENGLISH_US:
|
|
case LANGUAGE_ENGLISH_UK:
|
|
case LANGUAGE_ENGLISH_AUS:
|
|
case LANGUAGE_ENGLISH_CAN:
|
|
case LANGUAGE_ENGLISH_NZ:
|
|
case LANGUAGE_ENGLISH_EIRE:
|
|
case LANGUAGE_ENGLISH_SAFRICA:
|
|
case LANGUAGE_ENGLISH_JAMAICA:
|
|
case LANGUAGE_ENGLISH_CARRIBEAN:
|
|
nRet &= ~(ChgQuotes|ChgSglQuotes);
|
|
break;
|
|
}
|
|
return nRet;
|
|
}
|
|
|
|
|
|
SvxAutoCorrect::SvxAutoCorrect( const String& rShareAutocorrFile,
|
|
const String& rUserAutocorrFile )
|
|
: sShareAutoCorrFile( rShareAutocorrFile ),
|
|
sUserAutoCorrFile( rUserAutocorrFile ),
|
|
pLangTable( new SvxAutoCorrLanguageTable_Impl ),
|
|
pLastFileTable( new SvxAutoCorrLastFileAskTable_Impl ),
|
|
pCharClass( 0 ), bRunNext( false ),
|
|
cStartDQuote( 0 ), cEndDQuote( 0 ), cStartSQuote( 0 ), cEndSQuote( 0 )
|
|
{
|
|
nFlags = SvxAutoCorrect::GetDefaultFlags();
|
|
|
|
cEmDash = ByteString::ConvertToUnicode( '\x97', RTL_TEXTENCODING_MS_1252 );
|
|
cEnDash = ByteString::ConvertToUnicode( '\x96', RTL_TEXTENCODING_MS_1252 );
|
|
}
|
|
|
|
SvxAutoCorrect::SvxAutoCorrect( const SvxAutoCorrect& rCpy )
|
|
: sShareAutoCorrFile( rCpy.sShareAutoCorrFile ),
|
|
sUserAutoCorrFile( rCpy.sUserAutoCorrFile ),
|
|
|
|
aSwFlags( rCpy.aSwFlags ),
|
|
|
|
pLangTable( new SvxAutoCorrLanguageTable_Impl ),
|
|
pLastFileTable( new SvxAutoCorrLastFileAskTable_Impl ),
|
|
pCharClass( 0 ), bRunNext( false ),
|
|
|
|
nFlags( rCpy.nFlags & ~(ChgWordLstLoad|CplSttLstLoad|WrdSttLstLoad)),
|
|
cStartDQuote( rCpy.cStartDQuote ), cEndDQuote( rCpy.cEndDQuote ),
|
|
cStartSQuote( rCpy.cStartSQuote ), cEndSQuote( rCpy.cEndSQuote ),
|
|
cEmDash( rCpy.cEmDash ), cEnDash( rCpy.cEnDash )
|
|
{
|
|
}
|
|
|
|
|
|
SvxAutoCorrect::~SvxAutoCorrect()
|
|
{
|
|
lcl_ClearTable(*pLangTable);
|
|
delete pLangTable;
|
|
delete pLastFileTable;
|
|
delete pCharClass;
|
|
}
|
|
|
|
void SvxAutoCorrect::_GetCharClass( LanguageType eLang )
|
|
{
|
|
delete pCharClass;
|
|
pCharClass = new CharClass( SvxCreateLocale( eLang ));
|
|
eCharClassLang = eLang;
|
|
}
|
|
|
|
void SvxAutoCorrect::SetAutoCorrFlag( long nFlag, BOOL bOn )
|
|
{
|
|
long nOld = nFlags;
|
|
nFlags = bOn ? nFlags | nFlag
|
|
: nFlags & ~nFlag;
|
|
|
|
if( !bOn )
|
|
{
|
|
if( (nOld & CptlSttSntnc) != (nFlags & CptlSttSntnc) )
|
|
nFlags &= ~CplSttLstLoad;
|
|
if( (nOld & CptlSttWrd) != (nFlags & CptlSttWrd) )
|
|
nFlags &= ~WrdSttLstLoad;
|
|
if( (nOld & Autocorrect) != (nFlags & Autocorrect) )
|
|
nFlags &= ~ChgWordLstLoad;
|
|
}
|
|
}
|
|
|
|
|
|
// Zwei Grossbuchstaben am Wort-Anfang ??
|
|
BOOL SvxAutoCorrect::FnCptlSttWrd( SvxAutoCorrDoc& rDoc, const String& rTxt,
|
|
xub_StrLen nSttPos, xub_StrLen nEndPos,
|
|
LanguageType eLang )
|
|
{
|
|
BOOL bRet = FALSE;
|
|
CharClass& rCC = GetCharClass( eLang );
|
|
|
|
// loesche alle nicht alpanum. Zeichen am Wortanfang/-ende und
|
|
// teste dann ( erkennt: "(min.", "/min.", usw.)
|
|
for( ; nSttPos < nEndPos; ++nSttPos )
|
|
if( rCC.isLetterNumeric( rTxt, nSttPos ))
|
|
break;
|
|
for( ; nSttPos < nEndPos; --nEndPos )
|
|
if( rCC.isLetterNumeric( rTxt, nEndPos - 1 ))
|
|
break;
|
|
|
|
// Zwei Grossbuchstaben am Wort-Anfang ??
|
|
if( nSttPos+2 < nEndPos &&
|
|
IsUpperLetter( rCC.getCharacterType( rTxt, nSttPos )) &&
|
|
IsUpperLetter( rCC.getCharacterType( rTxt, ++nSttPos )) &&
|
|
// ist das 3. Zeichen ein klein geschiebenes Alpha-Zeichen
|
|
IsLowerLetter( rCC.getCharacterType( rTxt, nSttPos +1 )) &&
|
|
// keine Sonder-Attribute ersetzen
|
|
0x1 != rTxt.GetChar( nSttPos ) && 0x2 != rTxt.GetChar( nSttPos ))
|
|
{
|
|
// teste ob das Wort in einer Ausnahmeliste steht
|
|
String sWord( rTxt.Copy( nSttPos - 1, nEndPos - nSttPos + 1 ));
|
|
if( !FindInWrdSttExceptList(eLang, sWord) )
|
|
{
|
|
sal_Unicode cSave = rTxt.GetChar( nSttPos );
|
|
String sChar( cSave );
|
|
rCC.toLower( sChar );
|
|
if( sChar.GetChar(0) != cSave && rDoc.Replace( nSttPos, sChar ))
|
|
{
|
|
if( SaveWordWrdSttLst & nFlags )
|
|
rDoc.SaveCpltSttWord( CptlSttWrd, nSttPos, sWord, cSave );
|
|
bRet = TRUE;
|
|
}
|
|
}
|
|
}
|
|
return bRet;
|
|
}
|
|
|
|
|
|
BOOL SvxAutoCorrect::FnChgOrdinalNumber(
|
|
SvxAutoCorrDoc& rDoc, const String& rTxt,
|
|
xub_StrLen nSttPos, xub_StrLen nEndPos,
|
|
LanguageType eLang )
|
|
{
|
|
// 1st, 2nd, 3rd, 4 - 0th
|
|
// 201th oder 201st
|
|
// 12th oder 12nd
|
|
CharClass& rCC = GetCharClass( eLang );
|
|
BOOL bChg = FALSE;
|
|
|
|
for( ; nSttPos < nEndPos; ++nSttPos )
|
|
if( !lcl_IsInAsciiArr( sImplSttSkipChars, rTxt.GetChar( nSttPos ) ))
|
|
break;
|
|
for( ; nSttPos < nEndPos; --nEndPos )
|
|
if( !lcl_IsInAsciiArr( sImplEndSkipChars, rTxt.GetChar( nEndPos - 1 ) ))
|
|
break;
|
|
|
|
if( 2 < nEndPos - nSttPos &&
|
|
rCC.isDigit( rTxt, nEndPos - 3 ) )
|
|
{
|
|
static sal_Char __READONLY_DATA
|
|
sAll[] = "th", /* rest */
|
|
sFirst[] = "st", /* 1 */
|
|
sSecond[] = "nd", /* 2 */
|
|
sThird[] = "rd"; /* 3 */
|
|
static const sal_Char* __READONLY_DATA aNumberTab[ 4 ] =
|
|
{
|
|
sAll, sFirst, sSecond, sThird
|
|
};
|
|
|
|
sal_Unicode c = rTxt.GetChar( nEndPos - 3 );
|
|
if( ( c -= '0' ) > 3 )
|
|
c = 0;
|
|
|
|
bChg = ( ((sal_Unicode)*((aNumberTab[ c ])+0)) ==
|
|
rTxt.GetChar( nEndPos - 2 ) &&
|
|
((sal_Unicode)*((aNumberTab[ c ])+1)) ==
|
|
rTxt.GetChar( nEndPos - 1 )) ||
|
|
( 3 < nEndPos - nSttPos &&
|
|
( ((sal_Unicode)*(sAll+0)) == rTxt.GetChar( nEndPos - 2 ) &&
|
|
((sal_Unicode)*(sAll+1)) == rTxt.GetChar( nEndPos - 1 )));
|
|
|
|
if( bChg )
|
|
{
|
|
// dann pruefe mal, ob alle bis zum Start alle Zahlen sind
|
|
for( xub_StrLen n = nEndPos - 3; nSttPos < n; )
|
|
if( !rCC.isDigit( rTxt, --n ) )
|
|
{
|
|
bChg = !rCC.isLetter( rTxt, n );
|
|
break;
|
|
}
|
|
|
|
if( bChg ) // dann setze mal das Escapement Attribut
|
|
{
|
|
SvxEscapementItem aSvxEscapementItem( DFLT_ESC_AUTO_SUPER,
|
|
DFLT_ESC_PROP, SID_ATTR_CHAR_ESCAPEMENT );
|
|
rDoc.SetAttr( nEndPos - 2, nEndPos,
|
|
SID_ATTR_CHAR_ESCAPEMENT,
|
|
aSvxEscapementItem);
|
|
}
|
|
}
|
|
|
|
}
|
|
return bChg;
|
|
}
|
|
|
|
|
|
BOOL SvxAutoCorrect::FnChgToEnEmDash(
|
|
SvxAutoCorrDoc& rDoc, const String& rTxt,
|
|
xub_StrLen nSttPos, xub_StrLen nEndPos,
|
|
LanguageType eLang )
|
|
{
|
|
BOOL bRet = FALSE;
|
|
CharClass& rCC = GetCharClass( eLang );
|
|
if (eLang == LANGUAGE_SYSTEM)
|
|
eLang = GetAppLang();
|
|
bool bAlwaysUseEmDash = (cEmDash && (eLang == LANGUAGE_RUSSIAN || eLang == LANGUAGE_UKRAINIAN));
|
|
|
|
// ersetze " - " oder " --" durch "enDash"
|
|
if( cEnDash && 1 < nSttPos && 1 <= nEndPos - nSttPos )
|
|
{
|
|
sal_Unicode cCh = rTxt.GetChar( nSttPos );
|
|
if( '-' == cCh )
|
|
{
|
|
if( ' ' == rTxt.GetChar( nSttPos-1 ) &&
|
|
'-' == rTxt.GetChar( nSttPos+1 ))
|
|
{
|
|
xub_StrLen n;
|
|
for( n = nSttPos+2; n < nEndPos && lcl_IsInAsciiArr(
|
|
sImplSttSkipChars,(cCh = rTxt.GetChar( n )));
|
|
++n )
|
|
;
|
|
|
|
// found: " --[<AnySttChars>][A-z0-9]
|
|
if( rCC.isLetterNumeric( cCh ) )
|
|
{
|
|
for( n = nSttPos-1; n && lcl_IsInAsciiArr(
|
|
sImplEndSkipChars,(cCh = rTxt.GetChar( --n ))); )
|
|
;
|
|
|
|
// found: "[A-z0-9][<AnyEndChars>] --[<AnySttChars>][A-z0-9]
|
|
if( rCC.isLetterNumeric( cCh ))
|
|
{
|
|
rDoc.Delete( nSttPos, nSttPos + 2 );
|
|
rDoc.Insert( nSttPos, bAlwaysUseEmDash ? cEmDash : cEnDash );
|
|
bRet = TRUE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if( 3 < nSttPos &&
|
|
' ' == rTxt.GetChar( nSttPos-1 ) &&
|
|
'-' == rTxt.GetChar( nSttPos-2 ))
|
|
{
|
|
xub_StrLen n, nLen = 1, nTmpPos = nSttPos - 2;
|
|
if( '-' == ( cCh = rTxt.GetChar( nTmpPos-1 )) )
|
|
{
|
|
--nTmpPos;
|
|
++nLen;
|
|
cCh = rTxt.GetChar( nTmpPos-1 );
|
|
}
|
|
if( ' ' == cCh )
|
|
{
|
|
for( n = nSttPos; n < nEndPos && lcl_IsInAsciiArr(
|
|
sImplSttSkipChars,(cCh = rTxt.GetChar( n )));
|
|
++n )
|
|
;
|
|
|
|
// found: " - [<AnySttChars>][A-z0-9]
|
|
if( rCC.isLetterNumeric( cCh ) )
|
|
{
|
|
cCh = ' ';
|
|
for( n = nTmpPos-1; n && lcl_IsInAsciiArr(
|
|
sImplEndSkipChars,(cCh = rTxt.GetChar( --n ))); )
|
|
;
|
|
// found: "[A-z0-9][<AnyEndChars>] - [<AnySttChars>][A-z0-9]
|
|
if( rCC.isLetterNumeric( cCh ))
|
|
{
|
|
rDoc.Delete( nTmpPos, nTmpPos + nLen );
|
|
rDoc.Insert( nTmpPos, bAlwaysUseEmDash ? cEmDash : cEnDash );
|
|
bRet = TRUE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Replace [A-z0-9]--[A-z0-9] double dash with "emDash" or "enDash".
|
|
// Finnish and Hungarian use enDash instead of emDash.
|
|
bool bEnDash = (eLang == LANGUAGE_HUNGARIAN || eLang == LANGUAGE_FINNISH);
|
|
if( ((cEmDash && !bEnDash) || (cEnDash && bEnDash)) && 4 <= nEndPos - nSttPos )
|
|
{
|
|
String sTmp( rTxt.Copy( nSttPos, nEndPos - nSttPos ) );
|
|
xub_StrLen nFndPos = sTmp.SearchAscii( "--" );
|
|
if( STRING_NOTFOUND != nFndPos && nFndPos &&
|
|
nFndPos + 2 < sTmp.Len() &&
|
|
( rCC.isLetterNumeric( sTmp, nFndPos - 1 ) ||
|
|
lcl_IsInAsciiArr( sImplEndSkipChars, rTxt.GetChar( nFndPos - 1 ) )) &&
|
|
( rCC.isLetterNumeric( sTmp, nFndPos + 2 ) ||
|
|
lcl_IsInAsciiArr( sImplSttSkipChars, rTxt.GetChar( nFndPos + 2 ) )))
|
|
{
|
|
nSttPos = nSttPos + nFndPos;
|
|
rDoc.Delete( nSttPos, nSttPos + 2 );
|
|
rDoc.Insert( nSttPos, (bEnDash ? cEnDash : cEmDash) );
|
|
bRet = TRUE;
|
|
}
|
|
}
|
|
return bRet;
|
|
}
|
|
|
|
BOOL SvxAutoCorrect::FnAddNonBrkSpace(
|
|
SvxAutoCorrDoc& rDoc, const String& rTxt,
|
|
xub_StrLen, xub_StrLen nEndPos,
|
|
LanguageType eLang )
|
|
{
|
|
bool bRet = false;
|
|
|
|
CharClass& rCC = GetCharClass( eLang );
|
|
const lang::Locale rLocale = rCC.getLocale( );
|
|
|
|
if ( rLocale.Language == OUString::createFromAscii( "fr" ) )
|
|
{
|
|
bool bFrCA = rLocale.Country == OUString::createFromAscii( "CA" );
|
|
OUString allChars = OUString::createFromAscii( ":;!?" );
|
|
OUString chars( allChars );
|
|
if ( bFrCA )
|
|
chars = OUString::createFromAscii( ":" );
|
|
|
|
sal_Unicode cChar = rTxt.GetChar( nEndPos );
|
|
bool bHasSpace = chars.indexOf( sal_Unicode( cChar ) ) != -1;
|
|
bool bIsSpecial = allChars.indexOf( sal_Unicode( cChar ) ) != -1;
|
|
if ( bIsSpecial )
|
|
{
|
|
// Get the last word delimiter position
|
|
xub_StrLen nSttWdPos = nEndPos;
|
|
while( nSttWdPos && !IsWordDelim( rTxt.GetChar( --nSttWdPos )))
|
|
;
|
|
|
|
// Check the presence of "://" in the word
|
|
xub_StrLen nStrPos = rTxt.Search( String::CreateFromAscii( "://" ), nSttWdPos + 1 );
|
|
if ( STRING_NOTFOUND == nStrPos && nEndPos > 0 )
|
|
{
|
|
// Check the previous char
|
|
sal_Unicode cPrevChar = rTxt.GetChar( nEndPos - 1 );
|
|
if ( ( chars.indexOf( sal_Unicode( cPrevChar ) ) == -1 ) && cPrevChar != '\t' )
|
|
{
|
|
// Remove any previous normal space
|
|
xub_StrLen nPos = nEndPos - 1;
|
|
while ( cPrevChar == ' ' || cPrevChar == CHAR_HARDBLANK )
|
|
{
|
|
if ( nPos == 0 ) break;
|
|
nPos--;
|
|
cPrevChar = rTxt.GetChar( nPos );
|
|
}
|
|
|
|
if ( nPos != 0 )
|
|
{
|
|
nPos++;
|
|
if ( nEndPos - nPos > 0 )
|
|
rDoc.Delete( nPos, nEndPos );
|
|
|
|
// Add the non-breaking space at the end pos
|
|
if ( bHasSpace )
|
|
rDoc.Insert( nPos, CHAR_HARDBLANK );
|
|
bRunNext = true;
|
|
bRet = true;
|
|
}
|
|
}
|
|
else if ( chars.indexOf( sal_Unicode( cPrevChar ) ) != -1 )
|
|
bRunNext = true;
|
|
}
|
|
}
|
|
else if ( cChar == '/' && nEndPos > 1 && rTxt.Len() > (nEndPos - 1) )
|
|
{
|
|
// Remove the hardspace right before to avoid formatting URLs
|
|
sal_Unicode cPrevChar = rTxt.GetChar( nEndPos - 1 );
|
|
sal_Unicode cMaybeSpaceChar = rTxt.GetChar( nEndPos - 2 );
|
|
if ( cPrevChar == ':' && cMaybeSpaceChar == CHAR_HARDBLANK )
|
|
{
|
|
rDoc.Delete( nEndPos - 2, nEndPos - 1 );
|
|
bRet = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
BOOL SvxAutoCorrect::FnSetINetAttr( SvxAutoCorrDoc& rDoc, const String& rTxt,
|
|
xub_StrLen nSttPos, xub_StrLen nEndPos,
|
|
LanguageType eLang )
|
|
{
|
|
String sURL( URIHelper::FindFirstURLInText( rTxt, nSttPos, nEndPos,
|
|
GetCharClass( eLang ) ));
|
|
BOOL bRet = 0 != sURL.Len();
|
|
if( bRet ) // also Attribut setzen:
|
|
rDoc.SetINetAttr( nSttPos, nEndPos, sURL );
|
|
return bRet;
|
|
}
|
|
|
|
|
|
BOOL SvxAutoCorrect::FnChgWeightUnderl( SvxAutoCorrDoc& rDoc, const String& rTxt,
|
|
xub_StrLen, xub_StrLen nEndPos,
|
|
LanguageType eLang )
|
|
{
|
|
// Bedingung:
|
|
// Am Anfang: _ oder * hinter Space mit nachfolgenden !Space
|
|
// Am Ende: _ oder * vor Space (Worttrenner?)
|
|
|
|
sal_Unicode c, cInsChar = rTxt.GetChar( nEndPos ); // unterstreichen oder fett
|
|
if( ++nEndPos != rTxt.Len() &&
|
|
!IsWordDelim( rTxt.GetChar( nEndPos ) ) )
|
|
return FALSE;
|
|
|
|
--nEndPos;
|
|
|
|
BOOL bAlphaNum = FALSE;
|
|
xub_StrLen nPos = nEndPos, nFndPos = STRING_NOTFOUND;
|
|
CharClass& rCC = GetCharClass( eLang );
|
|
|
|
while( nPos )
|
|
{
|
|
switch( c = rTxt.GetChar( --nPos ) )
|
|
{
|
|
case '_':
|
|
case '*':
|
|
if( c == cInsChar )
|
|
{
|
|
if( bAlphaNum && nPos+1 < nEndPos && ( !nPos ||
|
|
IsWordDelim( rTxt.GetChar( nPos-1 ))) &&
|
|
!IsWordDelim( rTxt.GetChar( nPos+1 )))
|
|
nFndPos = nPos;
|
|
else
|
|
// Bedingung ist nicht erfuellt, also abbrechen
|
|
nFndPos = STRING_NOTFOUND;
|
|
nPos = 0;
|
|
}
|
|
break;
|
|
default:
|
|
if( !bAlphaNum )
|
|
bAlphaNum = rCC.isLetterNumeric( rTxt, nPos );
|
|
}
|
|
}
|
|
|
|
if( STRING_NOTFOUND != nFndPos )
|
|
{
|
|
// ueber den gefundenen Bereich das Attribut aufspannen und
|
|
// das gefunde und am Ende stehende Zeichen loeschen
|
|
if( '*' == cInsChar ) // Fett
|
|
{
|
|
SvxWeightItem aSvxWeightItem( WEIGHT_BOLD, SID_ATTR_CHAR_WEIGHT );
|
|
rDoc.SetAttr( nFndPos + 1, nEndPos,
|
|
SID_ATTR_CHAR_WEIGHT,
|
|
aSvxWeightItem);
|
|
}
|
|
else // unterstrichen
|
|
{
|
|
SvxUnderlineItem aSvxUnderlineItem( UNDERLINE_SINGLE, SID_ATTR_CHAR_UNDERLINE );
|
|
rDoc.SetAttr( nFndPos + 1, nEndPos,
|
|
SID_ATTR_CHAR_UNDERLINE,
|
|
aSvxUnderlineItem);
|
|
}
|
|
rDoc.Delete( nEndPos, nEndPos + 1 );
|
|
rDoc.Delete( nFndPos, nFndPos + 1 );
|
|
}
|
|
|
|
return STRING_NOTFOUND != nFndPos;
|
|
}
|
|
|
|
|
|
BOOL SvxAutoCorrect::FnCptlSttSntnc( SvxAutoCorrDoc& rDoc,
|
|
const String& rTxt, BOOL bNormalPos,
|
|
xub_StrLen nSttPos, xub_StrLen nEndPos,
|
|
LanguageType eLang )
|
|
{
|
|
// Grossbuchstabe am Satz-Anfang ??
|
|
if( !rTxt.Len() || nEndPos <= nSttPos )
|
|
return FALSE;
|
|
|
|
CharClass& rCC = GetCharClass( eLang );
|
|
String aText( rTxt );
|
|
const sal_Unicode *pStart = aText.GetBuffer(),
|
|
*pStr = pStart + nEndPos,
|
|
*pWordStt = 0,
|
|
*pDelim = 0;
|
|
|
|
BOOL bAtStart = FALSE, bPrevPara = FALSE;
|
|
do {
|
|
--pStr;
|
|
if( rCC.isLetter(
|
|
aText, sal::static_int_cast< xub_StrLen >( pStr - pStart ) ) )
|
|
{
|
|
if( !pWordStt )
|
|
pDelim = pStr+1;
|
|
pWordStt = pStr;
|
|
}
|
|
else if( pWordStt &&
|
|
!rCC.isDigit(
|
|
aText,
|
|
sal::static_int_cast< xub_StrLen >( pStr - pStart ) ) )
|
|
{
|
|
if( lcl_IsInAsciiArr( sImplWordChars, *pStr ) &&
|
|
pWordStt - 1 == pStr &&
|
|
// --> FME 2005-02-14 #i38971#
|
|
// l'intallazione at beginning of paragraph. Replaced < by <=
|
|
(long)(pStart + 1) <= (long)pStr &&
|
|
// <--
|
|
rCC.isLetter(
|
|
aText,
|
|
sal::static_int_cast< xub_StrLen >( pStr-1 - pStart ) ) )
|
|
pWordStt = --pStr;
|
|
else
|
|
break;
|
|
}
|
|
} while( 0 == ( bAtStart = (pStart == pStr)) );
|
|
|
|
|
|
if( !pWordStt ||
|
|
rCC.isDigit(
|
|
aText, sal::static_int_cast< xub_StrLen >( pStr - pStart ) ) ||
|
|
IsUpperLetter(
|
|
rCC.getCharacterType(
|
|
aText,
|
|
sal::static_int_cast< xub_StrLen >( pWordStt - pStart ) ) ) ||
|
|
0x1 == *pWordStt || 0x2 == *pWordStt )
|
|
return FALSE; // kein zu ersetzendes Zeichen, oder schon ok
|
|
|
|
// JP 27.10.97: wenn das Wort weniger als 3 Zeichen hat und der Trenner
|
|
// ein "Num"-Trenner ist, dann nicht ersetzen!
|
|
// Damit wird ein "a.", "a)", "a-a" nicht ersetzt!
|
|
if( *pDelim && 2 >= pDelim - pWordStt &&
|
|
lcl_IsInAsciiArr( ".-)>", *pDelim ) )
|
|
return FALSE;
|
|
|
|
if( !bAtStart ) // noch kein Absatz Anfang ?
|
|
{
|
|
if ( IsWordDelim( *pStr ) )
|
|
{
|
|
while( 0 == ( bAtStart = (pStart == pStr--) ) && IsWordDelim( *pStr ))
|
|
;
|
|
}
|
|
// Asian full stop, full width full stop, full width exclamation mark
|
|
// and full width question marks are treated as word delimiters
|
|
else if ( 0x3002 != *pStr && 0xFF0E != *pStr && 0xFF01 != *pStr &&
|
|
0xFF1F != *pStr )
|
|
return FALSE; // kein gueltiger Trenner -> keine Ersetzung
|
|
}
|
|
|
|
if( bAtStart ) // am Absatz Anfang ?
|
|
{
|
|
// Ueberpruefe den vorherigen Absatz, wenn es diesen gibt.
|
|
// Wenn ja, dann pruefe auf SatzTrenner am Ende.
|
|
const String* pPrevPara = rDoc.GetPrevPara( bNormalPos );
|
|
if( !pPrevPara )
|
|
{
|
|
// gueltiger Trenner -> Ersetze
|
|
String sChar( *pWordStt );
|
|
rCC.toUpper( sChar );
|
|
return sChar != *pWordStt &&
|
|
rDoc.Replace( xub_StrLen( pWordStt - pStart ), sChar );
|
|
}
|
|
|
|
aText = *pPrevPara;
|
|
bPrevPara = TRUE;
|
|
bAtStart = FALSE;
|
|
pStart = aText.GetBuffer();
|
|
pStr = pStart + aText.Len();
|
|
|
|
do { // alle Blanks ueberlesen
|
|
--pStr;
|
|
if( !IsWordDelim( *pStr ))
|
|
break;
|
|
} while( 0 == ( bAtStart = (pStart == pStr)) );
|
|
|
|
if( bAtStart )
|
|
return FALSE; // kein gueltiger Trenner -> keine Ersetzung
|
|
}
|
|
|
|
// bis hierhier wurde [ \t]+[A-Z0-9]+ gefunden. Test jetzt auf den
|
|
// Satztrenner. Es koennen alle 3 vorkommen, aber nicht mehrfach !!
|
|
const sal_Unicode* pExceptStt = 0;
|
|
if( !bAtStart )
|
|
{
|
|
BOOL bWeiter = TRUE;
|
|
int nFlag = C_NONE;
|
|
do {
|
|
switch( *pStr )
|
|
{
|
|
// Western and Asian full stop
|
|
case '.':
|
|
case 0x3002 :
|
|
case 0xFF0E :
|
|
{
|
|
if( nFlag & C_FULL_STOP )
|
|
return FALSE; // kein gueltiger Trenner -> keine Ersetzung
|
|
nFlag |= C_FULL_STOP;
|
|
pExceptStt = pStr;
|
|
}
|
|
break;
|
|
case '!':
|
|
case 0xFF01 :
|
|
{
|
|
if( nFlag & C_EXCLAMATION_MARK )
|
|
return FALSE; // kein gueltiger Trenner -> keine Ersetzung
|
|
nFlag |= C_EXCLAMATION_MARK;
|
|
}
|
|
break;
|
|
case '?':
|
|
case 0xFF1F :
|
|
{
|
|
if( nFlag & C_QUESTION_MARK)
|
|
return FALSE; // kein gueltiger Trenner -> keine Ersetzung
|
|
nFlag |= C_QUESTION_MARK;
|
|
}
|
|
break;
|
|
default:
|
|
if( !nFlag )
|
|
return FALSE; // kein gueltiger Trenner -> keine Ersetzung
|
|
else
|
|
bWeiter = FALSE;
|
|
break;
|
|
}
|
|
|
|
if( bWeiter && pStr-- == pStart )
|
|
{
|
|
// !!! wenn am Anfang, dann nie ersetzen.
|
|
// if( !nFlag )
|
|
return FALSE; // kein gueltiger Trenner -> keine Ersetzung
|
|
// ++pStr;
|
|
// break; // Schleife beenden
|
|
}
|
|
} while( bWeiter );
|
|
if( C_FULL_STOP != nFlag )
|
|
pExceptStt = 0;
|
|
}
|
|
|
|
if( 2 > ( pStr - pStart ) )
|
|
return FALSE;
|
|
|
|
if( !rCC.isLetterNumeric(
|
|
aText, sal::static_int_cast< xub_StrLen >( pStr-- - pStart ) ) )
|
|
{
|
|
BOOL bValid = FALSE, bAlphaFnd = FALSE;
|
|
const sal_Unicode* pTmpStr = pStr;
|
|
while( !bValid )
|
|
{
|
|
if( rCC.isDigit(
|
|
aText,
|
|
sal::static_int_cast< xub_StrLen >( pTmpStr - pStart ) ) )
|
|
{
|
|
bValid = TRUE;
|
|
pStr = pTmpStr - 1;
|
|
}
|
|
else if( rCC.isLetter(
|
|
aText,
|
|
sal::static_int_cast< xub_StrLen >(
|
|
pTmpStr - pStart ) ) )
|
|
{
|
|
if( bAlphaFnd )
|
|
{
|
|
bValid = TRUE;
|
|
pStr = pTmpStr;
|
|
}
|
|
else
|
|
bAlphaFnd = TRUE;
|
|
}
|
|
else if( bAlphaFnd || IsWordDelim( *pTmpStr ) )
|
|
break;
|
|
|
|
if( pTmpStr == pStart )
|
|
break;
|
|
|
|
--pTmpStr;
|
|
}
|
|
|
|
if( !bValid )
|
|
return FALSE; // kein gueltiger Trenner -> keine Ersetzung
|
|
}
|
|
|
|
BOOL bNumericOnly = '0' <= *(pStr+1) && *(pStr+1) <= '9';
|
|
|
|
// suche den Anfang vom Wort
|
|
while( !IsWordDelim( *pStr ))
|
|
{
|
|
if( bNumericOnly &&
|
|
rCC.isLetter(
|
|
aText, sal::static_int_cast< xub_StrLen >( pStr - pStart ) ) )
|
|
bNumericOnly = FALSE;
|
|
|
|
if( pStart == pStr )
|
|
break;
|
|
|
|
--pStr;
|
|
}
|
|
|
|
if( bNumericOnly ) // besteht nur aus Zahlen, dann nicht
|
|
return FALSE;
|
|
|
|
if( IsWordDelim( *pStr ))
|
|
++pStr;
|
|
|
|
String sWord;
|
|
|
|
// ueberpruefe anhand der Exceptionliste
|
|
if( pExceptStt )
|
|
{
|
|
sWord = String(
|
|
pStr, sal::static_int_cast< xub_StrLen >( pExceptStt - pStr + 1 ) );
|
|
if( FindInCplSttExceptList(eLang, sWord) )
|
|
return FALSE;
|
|
|
|
// loesche alle nicht alpanum. Zeichen am Wortanfang/-ende und
|
|
// teste dann noch mal ( erkennt: "(min.", "/min.", usw.)
|
|
String sTmp( sWord );
|
|
while( sTmp.Len() &&
|
|
!rCC.isLetterNumeric( sTmp, 0 ) )
|
|
sTmp.Erase( 0, 1 );
|
|
|
|
// alle hinteren nicht alphanumerische Zeichen bis auf das
|
|
// Letzte entfernen
|
|
xub_StrLen nLen = sTmp.Len();
|
|
while( nLen && !rCC.isLetterNumeric( sTmp, nLen-1 ) )
|
|
--nLen;
|
|
if( nLen + 1 < sTmp.Len() )
|
|
sTmp.Erase( nLen + 1 );
|
|
|
|
if( sTmp.Len() && sTmp.Len() != sWord.Len() &&
|
|
FindInCplSttExceptList(eLang, sTmp))
|
|
return FALSE;
|
|
|
|
if(FindInCplSttExceptList(eLang, sWord, TRUE))
|
|
return FALSE;
|
|
}
|
|
|
|
// Ok, dann ersetze mal
|
|
sal_Unicode cSave = *pWordStt;
|
|
nSttPos = sal::static_int_cast< xub_StrLen >( pWordStt - rTxt.GetBuffer() );
|
|
String sChar( cSave );
|
|
rCC.toUpper( sChar );
|
|
BOOL bRet = sChar.GetChar(0) != cSave && rDoc.Replace( nSttPos, sChar );
|
|
|
|
// das Wort will vielleicht jemand haben
|
|
if( bRet && SaveWordCplSttLst & nFlags )
|
|
rDoc.SaveCpltSttWord( CptlSttSntnc, nSttPos, sWord, cSave );
|
|
|
|
return bRet;
|
|
}
|
|
//The method below is renamed from _GetQuote to GetQuote by BerryJia for Bug95846 Time:2002-8-13 15:50
|
|
sal_Unicode SvxAutoCorrect::GetQuote( sal_Unicode cInsChar, BOOL bSttQuote,
|
|
LanguageType eLang ) const
|
|
{
|
|
sal_Unicode cRet = bSttQuote ? ( '\"' == cInsChar
|
|
? GetStartDoubleQuote()
|
|
: GetStartSingleQuote() )
|
|
: ( '\"' == cInsChar
|
|
? GetEndDoubleQuote()
|
|
: GetEndSingleQuote() );
|
|
if( !cRet )
|
|
{
|
|
// dann ueber die Language das richtige Zeichen heraussuchen
|
|
if( LANGUAGE_NONE == eLang )
|
|
cRet = cInsChar;
|
|
else
|
|
{
|
|
LocaleDataWrapper& rLcl = GetLocaleDataWrapper( eLang );
|
|
String sRet( bSttQuote
|
|
? ( '\"' == cInsChar
|
|
? rLcl.getDoubleQuotationMarkStart()
|
|
: rLcl.getQuotationMarkStart() )
|
|
: ( '\"' == cInsChar
|
|
? rLcl.getDoubleQuotationMarkEnd()
|
|
: rLcl.getQuotationMarkEnd() ));
|
|
cRet = sRet.Len() ? sRet.GetChar( 0 ) : cInsChar;
|
|
}
|
|
}
|
|
return cRet;
|
|
}
|
|
|
|
void SvxAutoCorrect::InsertQuote( SvxAutoCorrDoc& rDoc, xub_StrLen nInsPos,
|
|
sal_Unicode cInsChar, BOOL bSttQuote,
|
|
BOOL bIns )
|
|
{
|
|
LanguageType eLang = rDoc.GetLanguage( nInsPos, FALSE );
|
|
sal_Unicode cRet = GetQuote( cInsChar, bSttQuote, eLang );
|
|
|
|
//JP 13.02.99: damit beim Undo das "einfuegte" Zeichen wieder erscheint,
|
|
// wird es erstmal eingefuegt und dann ueberschrieben
|
|
String sChg( cInsChar );
|
|
if( bIns )
|
|
rDoc.Insert( nInsPos, sChg );
|
|
else
|
|
rDoc.Replace( nInsPos, sChg );
|
|
|
|
//JP 13.08.97: Bug 42477 - bei doppelten Anfuehrungszeichen muss bei
|
|
// franzoesischer Sprache an Anfang ein Leerzeichen dahinter
|
|
// und am Ende ein Leerzeichen dahinter eingefuegt werden.
|
|
sChg = cRet;
|
|
|
|
if( '\"' == cInsChar )
|
|
{
|
|
if( LANGUAGE_SYSTEM == eLang )
|
|
eLang = GetAppLang();
|
|
switch( eLang )
|
|
{
|
|
case LANGUAGE_FRENCH:
|
|
case LANGUAGE_FRENCH_BELGIAN:
|
|
case LANGUAGE_FRENCH_CANADIAN:
|
|
case LANGUAGE_FRENCH_SWISS:
|
|
case LANGUAGE_FRENCH_LUXEMBOURG:
|
|
// JP 09.02.99: das zusaetzliche Zeichen immer per Insert einfuegen.
|
|
// Es ueberschreibt nichts!
|
|
{
|
|
String s( static_cast< sal_Unicode >(0xA0) );
|
|
// UNICODE code for no break space
|
|
if( rDoc.Insert( bSttQuote ? nInsPos+1 : nInsPos, s ))
|
|
{
|
|
if( !bSttQuote )
|
|
++nInsPos;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
rDoc.Replace( nInsPos, sChg );
|
|
}
|
|
|
|
String SvxAutoCorrect::GetQuote( SvxAutoCorrDoc& rDoc, xub_StrLen nInsPos,
|
|
sal_Unicode cInsChar, BOOL bSttQuote )
|
|
{
|
|
LanguageType eLang = rDoc.GetLanguage( nInsPos, FALSE );
|
|
sal_Unicode cRet = GetQuote( cInsChar, bSttQuote, eLang );
|
|
|
|
String sRet( cRet );
|
|
//JP 13.08.97: Bug 42477 - bei doppelten Anfuehrungszeichen muss bei
|
|
// franzoesischer Sprache an Anfang ein Leerzeichen dahinter
|
|
// und am Ende ein Leerzeichen dahinter eingefuegt werden.
|
|
if( '\"' == cInsChar )
|
|
{
|
|
if( LANGUAGE_SYSTEM == eLang )
|
|
eLang = GetAppLang();
|
|
switch( eLang )
|
|
{
|
|
case LANGUAGE_FRENCH:
|
|
case LANGUAGE_FRENCH_BELGIAN:
|
|
case LANGUAGE_FRENCH_CANADIAN:
|
|
case LANGUAGE_FRENCH_SWISS:
|
|
case LANGUAGE_FRENCH_LUXEMBOURG:
|
|
if( bSttQuote )
|
|
sRet += ' ';
|
|
else
|
|
sRet.Insert( ' ', 0 );
|
|
break;
|
|
}
|
|
}
|
|
return sRet;
|
|
}
|
|
|
|
ULONG SvxAutoCorrect::AutoCorrect( SvxAutoCorrDoc& rDoc, const String& rTxt,
|
|
xub_StrLen nInsPos, sal_Unicode cChar,
|
|
BOOL bInsert )
|
|
{
|
|
ULONG nRet = 0;
|
|
bool bIsNextRun = bRunNext;
|
|
bRunNext = false; // if it was set, then it has to be turned off
|
|
|
|
do{ // only for middle check loop !!
|
|
if( cChar )
|
|
{
|
|
//JP 10.02.97: doppelte Spaces verhindern
|
|
if( nInsPos && ' ' == cChar &&
|
|
IsAutoCorrFlag( IgnoreDoubleSpace ) &&
|
|
' ' == rTxt.GetChar( nInsPos - 1 ) )
|
|
{
|
|
nRet = IgnoreDoubleSpace;
|
|
break;
|
|
}
|
|
|
|
BOOL bSingle = '\'' == cChar;
|
|
BOOL bIsReplaceQuote =
|
|
(IsAutoCorrFlag( ChgQuotes ) && ('\"' == cChar )) ||
|
|
(IsAutoCorrFlag( ChgSglQuotes ) && bSingle );
|
|
if( bIsReplaceQuote )
|
|
{
|
|
sal_Unicode cPrev;
|
|
BOOL bSttQuote = !nInsPos ||
|
|
IsWordDelim( ( cPrev = rTxt.GetChar( nInsPos-1 ))) ||
|
|
// os: #56034# - Warum kein schliessendes Anfuehrungszeichen nach dem Bindestrich?
|
|
// strchr( "-([{", cPrev ) ||
|
|
lcl_IsInAsciiArr( "([{", cPrev ) ||
|
|
( cEmDash && cEmDash == cPrev ) ||
|
|
( cEnDash && cEnDash == cPrev );
|
|
|
|
InsertQuote( rDoc, nInsPos, cChar, bSttQuote, bInsert );
|
|
nRet = bSingle ? ChgSglQuotes : ChgQuotes;
|
|
break;
|
|
}
|
|
|
|
if( bInsert )
|
|
rDoc.Insert( nInsPos, cChar );
|
|
else
|
|
rDoc.Replace( nInsPos, cChar );
|
|
|
|
// Hardspaces autocorrection
|
|
if ( IsAutoCorrFlag( AddNonBrkSpace ) )
|
|
{
|
|
if ( NeedsHardspaceAutocorr( cChar ) &&
|
|
FnAddNonBrkSpace( rDoc, rTxt, 0, nInsPos, rDoc.GetLanguage( nInsPos, FALSE ) ) )
|
|
{
|
|
nRet = AddNonBrkSpace;
|
|
}
|
|
else if ( bIsNextRun && !IsAutoCorrectChar( cChar ) )
|
|
{
|
|
// Remove the NBSP if it wasn't an autocorrection
|
|
if ( nInsPos != 0 && NeedsHardspaceAutocorr( rTxt.GetChar( nInsPos - 1 ) ) &&
|
|
cChar != ' ' && cChar != '\t' && cChar != CHAR_HARDBLANK )
|
|
{
|
|
// Look for the last HARD_SPACE
|
|
xub_StrLen nPos = nInsPos - 1;
|
|
bool bContinue = true;
|
|
while ( bContinue )
|
|
{
|
|
const sal_Unicode cTmpChar = rTxt.GetChar( nPos );
|
|
if ( cTmpChar == CHAR_HARDBLANK )
|
|
{
|
|
rDoc.Delete( nPos, nPos + 1 );
|
|
nRet = AddNonBrkSpace;
|
|
bContinue = false;
|
|
}
|
|
else if ( !NeedsHardspaceAutocorr( cTmpChar ) || nPos == 0 )
|
|
bContinue = false;
|
|
nPos--;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if( !nInsPos )
|
|
break;
|
|
|
|
xub_StrLen nPos = nInsPos - 1;
|
|
|
|
// Bug 19286: nur direkt hinter dem "Wort" aufsetzen
|
|
if( IsWordDelim( rTxt.GetChar( nPos )))
|
|
break;
|
|
|
|
// automatisches Fett oder Unterstreichen setzen?
|
|
if( '*' == cChar || '_' == cChar )
|
|
{
|
|
if( IsAutoCorrFlag( ChgWeightUnderl ) &&
|
|
FnChgWeightUnderl( rDoc, rTxt, 0, nPos+1 ) )
|
|
nRet = ChgWeightUnderl;
|
|
break;
|
|
}
|
|
|
|
while( nPos && !IsWordDelim( rTxt.GetChar( --nPos )))
|
|
;
|
|
|
|
// Absatz-Anfang oder ein Blank gefunden, suche nach dem Wort
|
|
// Kuerzel im Auto
|
|
xub_StrLen nCapLttrPos = nPos+1; // auf das 1. Zeichen
|
|
if( !nPos && !IsWordDelim( rTxt.GetChar( 0 )))
|
|
--nCapLttrPos; // Absatz Anfang und kein Blank !
|
|
|
|
LanguageType eLang = rDoc.GetLanguage( nCapLttrPos, FALSE );
|
|
if( LANGUAGE_SYSTEM == eLang )
|
|
eLang = MsLangId::getSystemLanguage();
|
|
CharClass& rCC = GetCharClass( eLang );
|
|
|
|
// Bug 19285: Symbolzeichen nicht anfassen
|
|
if( lcl_IsSymbolChar( rCC, rTxt, nCapLttrPos, nInsPos ))
|
|
break;
|
|
|
|
if( IsAutoCorrFlag( Autocorrect ) )
|
|
{
|
|
const String* pPara = 0;
|
|
const String** ppPara = IsAutoCorrFlag(CptlSttSntnc) ? &pPara : 0;
|
|
|
|
BOOL bChgWord = rDoc.ChgAutoCorrWord( nCapLttrPos, nInsPos,
|
|
*this, ppPara );
|
|
if( !bChgWord )
|
|
{
|
|
// JP 16.06.98: dann versuche mal alle !AlphaNum. Zeichen los zu
|
|
// werden und teste dann nochmals
|
|
//JP 22.04.99: Bug 63883 - entferne nur die "Klammern Start/-Anfaenge",
|
|
// alle anderen Zeichen muessen drin bleiben.
|
|
xub_StrLen nCapLttrPos1 = nCapLttrPos, nInsPos1 = nInsPos;
|
|
while( nCapLttrPos1 < nInsPos &&
|
|
lcl_IsInAsciiArr( sImplSttSkipChars, rTxt.GetChar( nCapLttrPos1 ) )
|
|
)
|
|
++nCapLttrPos1;
|
|
while( nCapLttrPos1 < nInsPos1 && nInsPos1 &&
|
|
lcl_IsInAsciiArr( sImplEndSkipChars, rTxt.GetChar( nInsPos1-1 ) )
|
|
)
|
|
--nInsPos1;
|
|
|
|
if( (nCapLttrPos1 != nCapLttrPos || nInsPos1 != nInsPos ) &&
|
|
nCapLttrPos1 < nInsPos1 &&
|
|
rDoc.ChgAutoCorrWord( nCapLttrPos1, nInsPos1, *this, ppPara ))
|
|
{
|
|
bChgWord = TRUE;
|
|
nCapLttrPos = nCapLttrPos1;
|
|
}
|
|
}
|
|
|
|
if( bChgWord )
|
|
{
|
|
nRet = Autocorrect;
|
|
if( pPara )
|
|
{
|
|
xub_StrLen nEnd = nCapLttrPos;
|
|
while( nEnd < pPara->Len() &&
|
|
!IsWordDelim( pPara->GetChar( nEnd )))
|
|
++nEnd;
|
|
|
|
// Grossbuchstabe am Satz-Anfang ??
|
|
if( IsAutoCorrFlag( CptlSttSntnc ) &&
|
|
FnCptlSttSntnc( rDoc, *pPara, FALSE,
|
|
nCapLttrPos, nEnd, eLang ) )
|
|
nRet |= CptlSttSntnc;
|
|
|
|
if( IsAutoCorrFlag( ChgToEnEmDash ) &&
|
|
FnChgToEnEmDash( rDoc, rTxt, nCapLttrPos, nEnd, eLang ) )
|
|
nRet |= ChgToEnEmDash;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
if( ( IsAutoCorrFlag( nRet = ChgOrdinalNumber ) &&
|
|
FnChgOrdinalNumber( rDoc, rTxt, nCapLttrPos, nInsPos, eLang ) ) ||
|
|
( IsAutoCorrFlag( nRet = SetINetAttr ) &&
|
|
( ' ' == cChar || '\t' == cChar || 0x0a == cChar || !cChar ) &&
|
|
FnSetINetAttr( rDoc, rTxt, nCapLttrPos, nInsPos, eLang ) ) )
|
|
;
|
|
else
|
|
{
|
|
nRet = 0;
|
|
// Grossbuchstabe am Satz-Anfang ??
|
|
if( IsAutoCorrFlag( CptlSttSntnc ) &&
|
|
FnCptlSttSntnc( rDoc, rTxt, TRUE, nCapLttrPos, nInsPos, eLang ) )
|
|
nRet |= CptlSttSntnc;
|
|
|
|
// Zwei Grossbuchstaben am Wort-Anfang ??
|
|
if( IsAutoCorrFlag( CptlSttWrd ) &&
|
|
FnCptlSttWrd( rDoc, rTxt, nCapLttrPos, nInsPos, eLang ) )
|
|
nRet |= CptlSttWrd;
|
|
|
|
if( IsAutoCorrFlag( ChgToEnEmDash ) &&
|
|
FnChgToEnEmDash( rDoc, rTxt, nCapLttrPos, nInsPos, eLang ) )
|
|
nRet |= ChgToEnEmDash;
|
|
}
|
|
|
|
} while( FALSE );
|
|
|
|
if( nRet )
|
|
{
|
|
ULONG nHelpId = 0;
|
|
if( nRet & ( Autocorrect|CptlSttSntnc|CptlSttWrd|ChgToEnEmDash ) )
|
|
{
|
|
// von 0 - 15
|
|
if( nRet & ChgToEnEmDash )
|
|
nHelpId += 8;
|
|
if( nRet & Autocorrect )
|
|
nHelpId += 4;
|
|
if( nRet & CptlSttSntnc )
|
|
nHelpId += 2;
|
|
if( nRet & CptlSttWrd )
|
|
nHelpId += 1;
|
|
}
|
|
else
|
|
{
|
|
if( nRet & ChgQuotes) nHelpId = 16;
|
|
else if( nRet & ChgSglQuotes) nHelpId = 17;
|
|
else if( nRet & SetINetAttr) nHelpId = 18;
|
|
else if( nRet & IgnoreDoubleSpace) nHelpId = 19;
|
|
else if( nRet & ChgWeightUnderl) nHelpId = 20;
|
|
else if( nRet & AddNonBrkSpace) nHelpId = 21;
|
|
else if( nRet & ChgOrdinalNumber) nHelpId = 22;
|
|
}
|
|
|
|
if( nHelpId )
|
|
{
|
|
nHelpId += HID_AUTOCORR_HELP_START - 1;
|
|
Application::GetHelp()->OpenHelpAgent( nHelpId );
|
|
}
|
|
}
|
|
|
|
|
|
return nRet;
|
|
}
|
|
|
|
SvxAutoCorrectLanguageLists& SvxAutoCorrect::_GetLanguageList(
|
|
LanguageType eLang )
|
|
{
|
|
if( !pLangTable->IsKeyValid( ULONG( eLang )))
|
|
CreateLanguageFile( eLang, TRUE);
|
|
return *pLangTable->Seek( ULONG( eLang ) );
|
|
}
|
|
|
|
void SvxAutoCorrect::SaveCplSttExceptList( LanguageType eLang )
|
|
{
|
|
if( pLangTable->IsKeyValid( ULONG( eLang )))
|
|
{
|
|
SvxAutoCorrectLanguageListsPtr pLists = pLangTable->Seek(ULONG(eLang));
|
|
if( pLists )
|
|
pLists->SaveCplSttExceptList();
|
|
}
|
|
#ifdef DBG_UTIL
|
|
else
|
|
{
|
|
DBG_ERROR("speichern einer leeren Liste?");
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void SvxAutoCorrect::SaveWrdSttExceptList(LanguageType eLang)
|
|
{
|
|
if(pLangTable->IsKeyValid(ULONG(eLang)))
|
|
{
|
|
SvxAutoCorrectLanguageListsPtr pLists = pLangTable->Seek(ULONG(eLang));
|
|
if(pLists)
|
|
pLists->SaveWrdSttExceptList();
|
|
}
|
|
#ifdef DBG_UTIL
|
|
else
|
|
{
|
|
DBG_ERROR("speichern einer leeren Liste?");
|
|
}
|
|
#endif
|
|
}
|
|
|
|
|
|
// fuegt ein einzelnes Wort hinzu. Die Liste wird sofort
|
|
// in die Datei geschrieben!
|
|
BOOL SvxAutoCorrect::AddCplSttException( const String& rNew,
|
|
LanguageType eLang )
|
|
{
|
|
SvxAutoCorrectLanguageListsPtr pLists = 0;
|
|
//entweder die richtige Sprache ist vorhanden oder es kommt in die allg. Liste
|
|
if( pLangTable->IsKeyValid(ULONG(eLang)))
|
|
pLists = pLangTable->Seek(ULONG(eLang));
|
|
else if(pLangTable->IsKeyValid(ULONG(LANGUAGE_DONTKNOW))||
|
|
CreateLanguageFile(LANGUAGE_DONTKNOW, TRUE))
|
|
{
|
|
pLists = pLangTable->Seek(ULONG(LANGUAGE_DONTKNOW));
|
|
}
|
|
DBG_ASSERT(pLists, "keine Autokorrekturdatei");
|
|
return pLists->AddToCplSttExceptList(rNew);
|
|
}
|
|
|
|
|
|
// fuegt ein einzelnes Wort hinzu. Die Liste wird sofort
|
|
// in die Datei geschrieben!
|
|
BOOL SvxAutoCorrect::AddWrtSttException( const String& rNew,
|
|
LanguageType eLang )
|
|
{
|
|
SvxAutoCorrectLanguageListsPtr pLists = 0;
|
|
//entweder die richtige Sprache ist vorhanden oder es kommt in die allg. Liste
|
|
if(pLangTable->IsKeyValid(ULONG(eLang)))
|
|
pLists = pLangTable->Seek(ULONG(eLang));
|
|
else if(pLangTable->IsKeyValid(ULONG(LANGUAGE_DONTKNOW))||
|
|
CreateLanguageFile(LANGUAGE_DONTKNOW, TRUE))
|
|
pLists = pLangTable->Seek(ULONG(LANGUAGE_DONTKNOW));
|
|
DBG_ASSERT(pLists, "keine Autokorrekturdatei");
|
|
return pLists->AddToWrdSttExceptList(rNew);
|
|
}
|
|
|
|
|
|
|
|
|
|
void SvxAutoCorrect::SetUserAutoCorrFileName( const String& rNew )
|
|
{
|
|
if( sUserAutoCorrFile != rNew )
|
|
{
|
|
sUserAutoCorrFile = rNew;
|
|
|
|
// sind die Listen gesetzt sind, so muessen sie jetzt geloescht
|
|
// werden
|
|
lcl_ClearTable(*pLangTable);
|
|
nFlags &= ~(CplSttLstLoad | WrdSttLstLoad | ChgWordLstLoad );
|
|
}
|
|
}
|
|
|
|
void SvxAutoCorrect::SetShareAutoCorrFileName( const String& rNew )
|
|
{
|
|
if( sShareAutoCorrFile != rNew )
|
|
{
|
|
sShareAutoCorrFile = rNew;
|
|
|
|
// sind die Listen gesetzt sind, so muessen sie jetzt geloescht
|
|
// werden
|
|
lcl_ClearTable(*pLangTable);
|
|
nFlags &= ~(CplSttLstLoad | WrdSttLstLoad | ChgWordLstLoad );
|
|
}
|
|
}
|
|
|
|
|
|
BOOL SvxAutoCorrect::GetPrevAutoCorrWord( SvxAutoCorrDoc& rDoc,
|
|
const String& rTxt, xub_StrLen nPos,
|
|
String& rWord ) const
|
|
{
|
|
if( !nPos )
|
|
return FALSE;
|
|
|
|
xub_StrLen nEnde = nPos;
|
|
|
|
// dahinter muss ein Blank oder Tab folgen!
|
|
if( ( nPos < rTxt.Len() &&
|
|
!IsWordDelim( rTxt.GetChar( nPos ))) ||
|
|
IsWordDelim( rTxt.GetChar( --nPos )))
|
|
return FALSE;
|
|
|
|
while( nPos && !IsWordDelim( rTxt.GetChar( --nPos )))
|
|
;
|
|
|
|
// Absatz-Anfang oder ein Blank gefunden, suche nach dem Wort
|
|
// Kuerzel im Auto
|
|
xub_StrLen nCapLttrPos = nPos+1; // auf das 1. Zeichen
|
|
if( !nPos && !IsWordDelim( rTxt.GetChar( 0 )))
|
|
--nCapLttrPos; // Absatz Anfang und kein Blank !
|
|
|
|
while( lcl_IsInAsciiArr( sImplSttSkipChars, rTxt.GetChar( nCapLttrPos )) )
|
|
if( ++nCapLttrPos >= nEnde )
|
|
return FALSE;
|
|
|
|
// Bug 19285: Symbolzeichen nicht anfassen
|
|
// Interresant erst ab 3 Zeichen
|
|
if( 3 > nEnde - nCapLttrPos )
|
|
return FALSE;
|
|
|
|
LanguageType eLang = rDoc.GetLanguage( nCapLttrPos, FALSE );
|
|
if( LANGUAGE_SYSTEM == eLang )
|
|
eLang = MsLangId::getSystemLanguage();
|
|
|
|
SvxAutoCorrect* pThis = (SvxAutoCorrect*)this;
|
|
CharClass& rCC = pThis->GetCharClass( eLang );
|
|
|
|
if( lcl_IsSymbolChar( rCC, rTxt, nCapLttrPos, nEnde ))
|
|
return FALSE;
|
|
|
|
rWord = rTxt.Copy( nCapLttrPos, nEnde - nCapLttrPos );
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL SvxAutoCorrect::CreateLanguageFile( LanguageType eLang, BOOL bNewFile )
|
|
{
|
|
DBG_ASSERT(!pLangTable->IsKeyValid(ULONG(eLang)), "Sprache ist bereits vorhanden");
|
|
|
|
String sUserDirFile( GetAutoCorrFileName( eLang, TRUE, FALSE )),
|
|
sShareDirFile( sUserDirFile );
|
|
SvxAutoCorrectLanguageListsPtr pLists = 0;
|
|
|
|
Time nMinTime( 0, 2 ), nAktTime, nLastCheckTime;
|
|
ULONG nFndPos;
|
|
if( TABLE_ENTRY_NOTFOUND !=
|
|
pLastFileTable->SearchKey( ULONG( eLang ), &nFndPos ) &&
|
|
( nLastCheckTime.SetTime( pLastFileTable->GetObject( nFndPos )),
|
|
nLastCheckTime < nAktTime ) &&
|
|
( nAktTime - nLastCheckTime ) < nMinTime )
|
|
{
|
|
// no need to test the file, because the last check is not older then
|
|
// 2 minutes.
|
|
if( bNewFile )
|
|
{
|
|
sShareDirFile = sUserDirFile;
|
|
pLists = new SvxAutoCorrectLanguageLists( *this, sShareDirFile,
|
|
sUserDirFile, eLang );
|
|
pLangTable->Insert( ULONG(eLang), pLists );
|
|
pLastFileTable->Remove( ULONG( eLang ) );
|
|
}
|
|
}
|
|
else if( ( FStatHelper::IsDocument( sUserDirFile ) ||
|
|
FStatHelper::IsDocument( sShareDirFile =
|
|
GetAutoCorrFileName( eLang, FALSE, FALSE ) ) ) ||
|
|
( sShareDirFile = sUserDirFile, bNewFile ))
|
|
{
|
|
pLists = new SvxAutoCorrectLanguageLists( *this, sShareDirFile,
|
|
sUserDirFile, eLang );
|
|
pLangTable->Insert( ULONG(eLang), pLists );
|
|
pLastFileTable->Remove( ULONG( eLang ) );
|
|
}
|
|
else if( !bNewFile )
|
|
{
|
|
if( !pLastFileTable->Insert( ULONG( eLang ), nAktTime.GetTime() ))
|
|
pLastFileTable->Replace( ULONG( eLang ), nAktTime.GetTime() );
|
|
}
|
|
return pLists != 0;
|
|
}
|
|
|
|
BOOL SvxAutoCorrect::PutText( const String& rShort, const String& rLong,
|
|
LanguageType eLang )
|
|
{
|
|
BOOL bRet = FALSE;
|
|
if( pLangTable->IsKeyValid( ULONG(eLang)) || CreateLanguageFile(eLang) )
|
|
bRet = pLangTable->Seek( ULONG(eLang) )->PutText(rShort, rLong);
|
|
return bRet;
|
|
}
|
|
|
|
|
|
// - loesche einen Eintrag
|
|
BOOL SvxAutoCorrect::DeleteText( const String& rShort, LanguageType eLang )
|
|
{
|
|
BOOL bRet = FALSE;
|
|
if( pLangTable->IsKeyValid( ULONG( eLang )) )
|
|
bRet = pLangTable->Seek( ULONG( eLang ))->DeleteText( rShort );
|
|
return bRet;
|
|
}
|
|
|
|
|
|
// - return den Ersetzungstext (nur fuer SWG-Format, alle anderen
|
|
// koennen aus der Wortliste herausgeholt werden!)
|
|
BOOL SvxAutoCorrect::GetLongText( const com::sun::star::uno::Reference < com::sun::star::embed::XStorage >&, const String&, const String& , String& )
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
// - Text mit Attributierung (kann nur der SWG - SWG-Format!)
|
|
BOOL SvxAutoCorrect::PutText( const com::sun::star::uno::Reference < com::sun::star::embed::XStorage >&, const String&, const String&, SfxObjectShell&,
|
|
String& )
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
void EncryptBlockName_Imp( String& rName )
|
|
{
|
|
xub_StrLen nLen, nPos = 1;
|
|
rName.Insert( '#', 0 );
|
|
sal_Unicode* pName = rName.GetBufferAccess();
|
|
for ( nLen = rName.Len(), ++pName; nPos < nLen; ++nPos, ++pName )
|
|
{
|
|
if( lcl_IsInAsciiArr( "!/:.\\", *pName ))
|
|
*pName &= 0x0f;
|
|
}
|
|
}
|
|
|
|
/* This code is copied from SwXMLTextBlocks::GeneratePackageName */
|
|
void GeneratePackageName ( const String& rShort, String& rPackageName )
|
|
{
|
|
rPackageName = rShort;
|
|
xub_StrLen nPos = 0;
|
|
sal_Unicode pDelims[] = { '!', '/', ':', '.', '\\', 0 };
|
|
ByteString sByte ( rPackageName, RTL_TEXTENCODING_UTF7);
|
|
rPackageName = String (sByte, RTL_TEXTENCODING_ASCII_US);
|
|
while( STRING_NOTFOUND != ( nPos = rPackageName.SearchChar( pDelims, nPos )))
|
|
{
|
|
rPackageName.SetChar( nPos, '_' );
|
|
++nPos;
|
|
}
|
|
}
|
|
|
|
void DecryptBlockName_Imp( String& rName )
|
|
{
|
|
if( '#' == rName.GetChar( 0 ) )
|
|
{
|
|
rName.Erase( 0, 1 );
|
|
sal_Unicode* pName = rName.GetBufferAccess();
|
|
xub_StrLen nLen, nPos;
|
|
for ( nLen = rName.Len(), nPos = 0; nPos < nLen; ++nPos, ++pName )
|
|
switch( *pName )
|
|
{
|
|
case 0x01: *pName = '!'; break;
|
|
case 0x0A: *pName = ':'; break;
|
|
case 0x0C: *pName = '\\'; break;
|
|
case 0x0E: *pName = '.'; break;
|
|
case 0x0F: *pName = '/'; break;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* -----------------18.11.98 16:00-------------------
|
|
*
|
|
* --------------------------------------------------*/
|
|
const SvxAutocorrWord* lcl_SearchWordsInList(
|
|
SvxAutoCorrectLanguageListsPtr pList, const String& rTxt,
|
|
xub_StrLen& rStt, xub_StrLen nEndPos, SvxAutoCorrDoc& )
|
|
{
|
|
const SvxAutocorrWordList* pAutoCorrWordList = pList->GetAutocorrWordList();
|
|
TransliterationWrapper& rCmp = GetIgnoreTranslWrapper();
|
|
for( xub_StrLen nPos = 0; nPos < pAutoCorrWordList->Count(); ++nPos )
|
|
{
|
|
const SvxAutocorrWord* pFnd = (*pAutoCorrWordList)[ nPos ];
|
|
const String& rChk = pFnd->GetShort();
|
|
if( nEndPos >= rChk.Len() )
|
|
{
|
|
xub_StrLen nCalcStt = nEndPos - rChk.Len();
|
|
if( ( !nCalcStt || nCalcStt == rStt ||
|
|
( nCalcStt < rStt &&
|
|
IsWordDelim( rTxt.GetChar(nCalcStt - 1 ) ))) )
|
|
{
|
|
String sWord( rTxt.GetBuffer() + nCalcStt, rChk.Len() );
|
|
if( rCmp.isEqual( rChk, sWord ))
|
|
{
|
|
rStt = nCalcStt;
|
|
return pFnd;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
// suche das oder die Worte in der ErsetzungsTabelle
|
|
const SvxAutocorrWord* SvxAutoCorrect::SearchWordsInList(
|
|
const String& rTxt, xub_StrLen& rStt, xub_StrLen nEndPos,
|
|
SvxAutoCorrDoc& rDoc, LanguageType& rLang )
|
|
{
|
|
LanguageType eLang = rLang;
|
|
const SvxAutocorrWord* pRet = 0;
|
|
if( LANGUAGE_SYSTEM == eLang )
|
|
eLang = MsLangId::getSystemLanguage();
|
|
|
|
// zuerst nach eLang suchen, dann nach der Obersprache
|
|
// US-Englisch -> Englisch und zuletzt in LANGUAGE_DONTKNOW
|
|
|
|
if( pLangTable->IsKeyValid( ULONG( eLang ) ) ||
|
|
CreateLanguageFile( eLang, FALSE ))
|
|
{
|
|
//die Sprache ist vorhanden - also her damit
|
|
SvxAutoCorrectLanguageListsPtr pList = pLangTable->Seek(ULONG(eLang));
|
|
pRet = lcl_SearchWordsInList( pList, rTxt, rStt, nEndPos, rDoc );
|
|
if( pRet )
|
|
{
|
|
rLang = eLang;
|
|
return pRet;
|
|
}
|
|
}
|
|
|
|
// wenn es hier noch nicht gefunden werden konnte, dann weitersuchen
|
|
ULONG nTmpKey1 = eLang & 0x7ff, // die Hauptsprache in vielen Faellen u.B. DE
|
|
nTmpKey2 = eLang & 0x3ff, // sonst z.B. EN
|
|
nTmp;
|
|
|
|
if( ((nTmp = nTmpKey1) != (ULONG)eLang &&
|
|
( pLangTable->IsKeyValid( nTmpKey1 ) ||
|
|
CreateLanguageFile( LanguageType( nTmpKey1 ), FALSE ) )) ||
|
|
(( nTmp = nTmpKey2) != (ULONG)eLang &&
|
|
( pLangTable->IsKeyValid( nTmpKey2 ) ||
|
|
CreateLanguageFile( LanguageType( nTmpKey2 ), FALSE ) )) )
|
|
{
|
|
//die Sprache ist vorhanden - also her damit
|
|
SvxAutoCorrectLanguageListsPtr pList = pLangTable->Seek( nTmp );
|
|
pRet = lcl_SearchWordsInList( pList, rTxt, rStt, nEndPos, rDoc);
|
|
if( pRet )
|
|
{
|
|
rLang = LanguageType( nTmp );
|
|
return pRet;
|
|
}
|
|
}
|
|
if( pLangTable->IsKeyValid( ULONG( LANGUAGE_DONTKNOW ) ) ||
|
|
CreateLanguageFile( LANGUAGE_DONTKNOW, FALSE ) )
|
|
{
|
|
//die Sprache ist vorhanden - also her damit
|
|
SvxAutoCorrectLanguageListsPtr pList = pLangTable->Seek(ULONG(LANGUAGE_DONTKNOW));
|
|
pRet = lcl_SearchWordsInList( pList, rTxt, rStt, nEndPos, rDoc);
|
|
if( pRet )
|
|
{
|
|
rLang = LANGUAGE_DONTKNOW;
|
|
return pRet;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
/* -----------------18.11.98 13:46-------------------
|
|
*
|
|
* --------------------------------------------------*/
|
|
BOOL SvxAutoCorrect::FindInWrdSttExceptList( LanguageType eLang,
|
|
const String& sWord )
|
|
{
|
|
//zuerst nach eLang suchen, dann nach der Obersprace US-Englisch -> Englisch
|
|
//und zuletzt in LANGUAGE_DONTKNOW
|
|
ULONG nTmpKey1 = eLang & 0x7ff; // die Hauptsprache in vielen Faellen u.B. DE
|
|
ULONG nTmpKey2 = eLang & 0x3ff; // sonst z.B. EN
|
|
String sTemp(sWord);
|
|
if( pLangTable->IsKeyValid( ULONG( eLang )) ||
|
|
CreateLanguageFile( eLang, FALSE ) )
|
|
{
|
|
//die Sprache ist vorhanden - also her damit
|
|
SvxAutoCorrectLanguageListsPtr pList = pLangTable->Seek(ULONG(eLang));
|
|
String _sTemp(sWord);
|
|
if(pList->GetWrdSttExceptList()->Seek_Entry(&_sTemp))
|
|
return TRUE;
|
|
|
|
}
|
|
// wenn es hier noch nicht gefunden werden konnte, dann weitersuchen
|
|
ULONG nTmp;
|
|
if( ((nTmp = nTmpKey1) != (ULONG)eLang &&
|
|
( pLangTable->IsKeyValid( nTmpKey1 ) ||
|
|
CreateLanguageFile( LanguageType( nTmpKey1 ), FALSE ) )) ||
|
|
(( nTmp = nTmpKey2) != (ULONG)eLang &&
|
|
( pLangTable->IsKeyValid( nTmpKey2 ) ||
|
|
CreateLanguageFile( LanguageType( nTmpKey2 ), FALSE ) )) )
|
|
{
|
|
//die Sprache ist vorhanden - also her damit
|
|
SvxAutoCorrectLanguageListsPtr pList = pLangTable->Seek(nTmp);
|
|
if(pList->GetWrdSttExceptList()->Seek_Entry(&sTemp))
|
|
return TRUE;
|
|
}
|
|
if(pLangTable->IsKeyValid(ULONG(LANGUAGE_DONTKNOW))|| CreateLanguageFile(LANGUAGE_DONTKNOW, FALSE))
|
|
{
|
|
//die Sprache ist vorhanden - also her damit
|
|
SvxAutoCorrectLanguageListsPtr pList = pLangTable->Seek(ULONG(LANGUAGE_DONTKNOW));
|
|
if(pList->GetWrdSttExceptList()->Seek_Entry(&sTemp))
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
/* -----------------18.11.98 14:28-------------------
|
|
*
|
|
* --------------------------------------------------*/
|
|
BOOL lcl_FindAbbreviation( const SvStringsISortDtor* pList, const String& sWord)
|
|
{
|
|
String sAbk( '~' );
|
|
USHORT nPos;
|
|
pList->Seek_Entry( &sAbk, &nPos );
|
|
if( nPos < pList->Count() )
|
|
{
|
|
String sLowerWord( sWord ); sLowerWord.ToLowerAscii();
|
|
const String* pAbk;
|
|
for( USHORT n = nPos;
|
|
n < pList->Count() &&
|
|
'~' == ( pAbk = (*pList)[ n ])->GetChar( 0 );
|
|
++n )
|
|
{
|
|
// ~ und ~. sind nicht erlaubt!
|
|
if( 2 < pAbk->Len() && pAbk->Len() - 1 <= sWord.Len() )
|
|
{
|
|
String sLowerAbk( *pAbk ); sLowerAbk.ToLowerAscii();
|
|
for( xub_StrLen i = sLowerAbk.Len(), ii = sLowerWord.Len(); i; )
|
|
{
|
|
if( !--i ) // stimmt ueberein
|
|
return TRUE;
|
|
|
|
if( sLowerAbk.GetChar( i ) != sLowerWord.GetChar( --ii ))
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
DBG_ASSERT( !(nPos && '~' == (*pList)[ --nPos ]->GetChar( 0 ) ),
|
|
"falsch sortierte ExeptionListe?" );
|
|
return FALSE;
|
|
}
|
|
/* -----------------18.11.98 14:49-------------------
|
|
*
|
|
* --------------------------------------------------*/
|
|
BOOL SvxAutoCorrect::FindInCplSttExceptList(LanguageType eLang,
|
|
const String& sWord, BOOL bAbbreviation)
|
|
{
|
|
//zuerst nach eLang suchen, dann nach der Obersprace US-Englisch -> Englisch
|
|
//und zuletzt in LANGUAGE_DONTKNOW
|
|
ULONG nTmpKey1 = eLang & 0x7ff; // die Hauptsprache in vielen Faellen u.B. DE
|
|
ULONG nTmpKey2 = eLang & 0x3ff; // sonst z.B. EN
|
|
String sTemp( sWord );
|
|
if( pLangTable->IsKeyValid( ULONG( eLang )) ||
|
|
CreateLanguageFile( eLang, FALSE ))
|
|
{
|
|
//die Sprache ist vorhanden - also her damit
|
|
SvxAutoCorrectLanguageListsPtr pLists = pLangTable->Seek(ULONG(eLang));
|
|
const SvStringsISortDtor* pList = pLists->GetCplSttExceptList();
|
|
if(bAbbreviation ? lcl_FindAbbreviation( pList, sWord)
|
|
: pList->Seek_Entry( &sTemp ) )
|
|
return TRUE;
|
|
}
|
|
// wenn es hier noch nicht gefunden werden konnte, dann weitersuchen
|
|
ULONG nTmp;
|
|
|
|
if( ((nTmp = nTmpKey1) != (ULONG)eLang &&
|
|
( pLangTable->IsKeyValid( nTmpKey1 ) ||
|
|
CreateLanguageFile( LanguageType( nTmpKey1 ), FALSE ) )) ||
|
|
(( nTmp = nTmpKey2) != (ULONG)eLang &&
|
|
( pLangTable->IsKeyValid( nTmpKey2 ) ||
|
|
CreateLanguageFile( LanguageType( nTmpKey2 ), FALSE ) )) )
|
|
{
|
|
//die Sprache ist vorhanden - also her damit
|
|
SvxAutoCorrectLanguageListsPtr pLists = pLangTable->Seek(nTmp);
|
|
const SvStringsISortDtor* pList = pLists->GetCplSttExceptList();
|
|
if(bAbbreviation ? lcl_FindAbbreviation( pList, sWord)
|
|
: pList->Seek_Entry( &sTemp ) )
|
|
return TRUE;
|
|
}
|
|
if(pLangTable->IsKeyValid(ULONG(LANGUAGE_DONTKNOW))|| CreateLanguageFile(LANGUAGE_DONTKNOW, FALSE))
|
|
{
|
|
//die Sprache ist vorhanden - also her damit
|
|
SvxAutoCorrectLanguageListsPtr pLists = pLangTable->Seek(LANGUAGE_DONTKNOW);
|
|
const SvStringsISortDtor* pList = pLists->GetCplSttExceptList();
|
|
if(bAbbreviation ? lcl_FindAbbreviation( pList, sWord)
|
|
: pList->Seek_Entry( &sTemp ) )
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
/* -----------------20.11.98 11:53-------------------
|
|
*
|
|
* --------------------------------------------------*/
|
|
String SvxAutoCorrect::GetAutoCorrFileName( LanguageType eLang,
|
|
BOOL bNewFile, BOOL bTst ) const
|
|
{
|
|
String sRet, sExt( MsLangId::convertLanguageToIsoString( eLang ) );
|
|
sExt.Insert('_', 0);
|
|
sExt.AppendAscii( ".dat" );
|
|
if( bNewFile )
|
|
( sRet = sUserAutoCorrFile ) += sExt;
|
|
else if( !bTst )
|
|
( sRet = sShareAutoCorrFile ) += sExt;
|
|
else
|
|
{
|
|
// test first in the user directory - if not exist, then
|
|
( sRet = sUserAutoCorrFile ) += sExt;
|
|
if( !FStatHelper::IsDocument( sRet ))
|
|
( sRet = sShareAutoCorrFile ) += sExt;
|
|
}
|
|
return sRet;
|
|
}
|
|
|
|
/* -----------------18.11.98 11:16-------------------
|
|
*
|
|
* --------------------------------------------------*/
|
|
SvxAutoCorrectLanguageLists::SvxAutoCorrectLanguageLists(
|
|
SvxAutoCorrect& rParent,
|
|
const String& rShareAutoCorrectFile,
|
|
const String& rUserAutoCorrectFile,
|
|
LanguageType eLang)
|
|
: sShareAutoCorrFile( rShareAutoCorrectFile ),
|
|
sUserAutoCorrFile( rUserAutoCorrectFile ),
|
|
eLanguage(eLang),
|
|
pCplStt_ExcptLst( 0 ),
|
|
pWrdStt_ExcptLst( 0 ),
|
|
pAutocorr_List( 0 ),
|
|
rAutoCorrect(rParent),
|
|
nFlags(0)
|
|
{
|
|
}
|
|
|
|
/* -----------------18.11.98 11:16-------------------
|
|
*
|
|
* --------------------------------------------------*/
|
|
SvxAutoCorrectLanguageLists::~SvxAutoCorrectLanguageLists()
|
|
{
|
|
delete pCplStt_ExcptLst;
|
|
delete pWrdStt_ExcptLst;
|
|
delete pAutocorr_List;
|
|
}
|
|
|
|
/* -----------------18.11.98 11:26-------------------
|
|
*
|
|
* --------------------------------------------------*/
|
|
BOOL SvxAutoCorrectLanguageLists::IsFileChanged_Imp()
|
|
{
|
|
// nur alle 2 Minuten aufs FileSystem zugreifen um den
|
|
// Dateistempel zu ueberpruefen
|
|
BOOL bRet = FALSE;
|
|
|
|
Time nMinTime( 0, 2 );
|
|
Time nAktTime;
|
|
if( aLastCheckTime > nAktTime || // ueberlauf ?
|
|
( nAktTime -= aLastCheckTime ) > nMinTime ) // min Zeit vergangen
|
|
{
|
|
Date aTstDate; Time aTstTime;
|
|
if( FStatHelper::GetModifiedDateTimeOfFile( sShareAutoCorrFile,
|
|
&aTstDate, &aTstTime ) &&
|
|
( aModifiedDate != aTstDate || aModifiedTime != aTstTime ))
|
|
{
|
|
bRet = TRUE;
|
|
// dann mal schnell alle Listen entfernen!
|
|
if( CplSttLstLoad & nFlags && pCplStt_ExcptLst )
|
|
delete pCplStt_ExcptLst, pCplStt_ExcptLst = 0;
|
|
if( WrdSttLstLoad & nFlags && pWrdStt_ExcptLst )
|
|
delete pWrdStt_ExcptLst, pWrdStt_ExcptLst = 0;
|
|
if( ChgWordLstLoad & nFlags && pAutocorr_List )
|
|
delete pAutocorr_List, pAutocorr_List = 0;
|
|
nFlags &= ~(CplSttLstLoad | WrdSttLstLoad | ChgWordLstLoad );
|
|
}
|
|
aLastCheckTime = Time();
|
|
}
|
|
return bRet;
|
|
}
|
|
|
|
void SvxAutoCorrectLanguageLists::LoadXMLExceptList_Imp(
|
|
SvStringsISortDtor*& rpLst,
|
|
const sal_Char* pStrmName,
|
|
SotStorageRef& rStg)
|
|
{
|
|
if( rpLst )
|
|
rpLst->DeleteAndDestroy( 0, rpLst->Count() );
|
|
else
|
|
rpLst = new SvStringsISortDtor( 16, 16 );
|
|
|
|
{
|
|
String sStrmName( pStrmName, RTL_TEXTENCODING_MS_1252 );
|
|
String sTmp( sStrmName );
|
|
|
|
if( rStg.Is() && rStg->IsStream( sStrmName ) )
|
|
{
|
|
SvStorageStreamRef xStrm = rStg->OpenSotStream( sTmp,
|
|
( STREAM_READ | STREAM_SHARE_DENYWRITE | STREAM_NOCREATE ) );
|
|
if( SVSTREAM_OK != xStrm->GetError())
|
|
{
|
|
xStrm.Clear();
|
|
rStg.Clear();
|
|
RemoveStream_Imp( sStrmName );
|
|
}
|
|
else
|
|
{
|
|
uno::Reference< lang::XMultiServiceFactory > xServiceFactory =
|
|
comphelper::getProcessServiceFactory();
|
|
DBG_ASSERT( xServiceFactory.is(),
|
|
"XMLReader::Read: got no service manager" );
|
|
if( !xServiceFactory.is() )
|
|
{
|
|
// Throw an exception ?
|
|
}
|
|
|
|
xml::sax::InputSource aParserInput;
|
|
aParserInput.sSystemId = sStrmName;
|
|
|
|
xStrm->Seek( 0L );
|
|
xStrm->SetBufferSize( 8 * 1024 );
|
|
aParserInput.aInputStream = new utl::OInputStreamWrapper( *xStrm );
|
|
|
|
// get parser
|
|
uno::Reference< XInterface > xXMLParser = xServiceFactory->createInstance(
|
|
OUString::createFromAscii("com.sun.star.xml.sax.Parser") );
|
|
DBG_ASSERT( xXMLParser.is(),
|
|
"XMLReader::Read: com.sun.star.xml.sax.Parser service missing" );
|
|
if( !xXMLParser.is() )
|
|
{
|
|
// Maybe throw an exception?
|
|
}
|
|
|
|
// get filter
|
|
// #110680#
|
|
// uno::Reference< xml::sax::XDocumentHandler > xFilter = new SvXMLExceptionListImport ( *rpLst );
|
|
uno::Reference< xml::sax::XDocumentHandler > xFilter = new SvXMLExceptionListImport ( xServiceFactory, *rpLst );
|
|
|
|
// connect parser and filter
|
|
uno::Reference< xml::sax::XParser > xParser( xXMLParser, UNO_QUERY );
|
|
xParser->setDocumentHandler( xFilter );
|
|
|
|
// parse
|
|
try
|
|
{
|
|
xParser->parseStream( aParserInput );
|
|
}
|
|
catch( xml::sax::SAXParseException& )
|
|
{
|
|
// re throw ?
|
|
}
|
|
catch( xml::sax::SAXException& )
|
|
{
|
|
// re throw ?
|
|
}
|
|
catch( io::IOException& )
|
|
{
|
|
// re throw ?
|
|
}
|
|
}
|
|
}
|
|
|
|
// Zeitstempel noch setzen
|
|
FStatHelper::GetModifiedDateTimeOfFile( sShareAutoCorrFile,
|
|
&aModifiedDate, &aModifiedTime );
|
|
aLastCheckTime = Time();
|
|
}
|
|
|
|
}
|
|
/* -----------------18.11.98 11:26-------------------
|
|
*
|
|
* --------------------------------------------------*/
|
|
void SvxAutoCorrectLanguageLists::SaveExceptList_Imp(
|
|
const SvStringsISortDtor& rLst,
|
|
const sal_Char* pStrmName,
|
|
SotStorageRef &rStg,
|
|
BOOL bConvert )
|
|
{
|
|
if( rStg.Is() )
|
|
{
|
|
String sStrmName( pStrmName, RTL_TEXTENCODING_MS_1252 );
|
|
if( !rLst.Count() )
|
|
{
|
|
rStg->Remove( sStrmName );
|
|
rStg->Commit();
|
|
}
|
|
else
|
|
{
|
|
SotStorageStreamRef xStrm = rStg->OpenSotStream( sStrmName,
|
|
( STREAM_READ | STREAM_WRITE | STREAM_SHARE_DENYWRITE ) );
|
|
if( xStrm.Is() )
|
|
{
|
|
xStrm->SetSize( 0 );
|
|
xStrm->SetBufferSize( 8192 );
|
|
String aPropName( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM("MediaType") ) );
|
|
OUString aMime( RTL_CONSTASCII_USTRINGPARAM("text/xml") );
|
|
uno::Any aAny;
|
|
aAny <<= aMime;
|
|
xStrm->SetProperty( aPropName, aAny );
|
|
|
|
|
|
uno::Reference< lang::XMultiServiceFactory > xServiceFactory =
|
|
comphelper::getProcessServiceFactory();
|
|
DBG_ASSERT( xServiceFactory.is(),
|
|
"XMLReader::Read: got no service manager" );
|
|
if( !xServiceFactory.is() )
|
|
{
|
|
// Throw an exception ?
|
|
}
|
|
|
|
uno::Reference < XInterface > xWriter (xServiceFactory->createInstance(
|
|
OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.sax.Writer"))));
|
|
DBG_ASSERT(xWriter.is(),"com.sun.star.xml.sax.Writer service missing");
|
|
uno::Reference < io::XOutputStream> xOut = new utl::OOutputStreamWrapper( *xStrm );
|
|
uno::Reference<io::XActiveDataSource> xSrc(xWriter, uno::UNO_QUERY);
|
|
xSrc->setOutputStream(xOut);
|
|
|
|
uno::Reference<xml::sax::XDocumentHandler> xHandler(xWriter, uno::UNO_QUERY);
|
|
|
|
// #110680#
|
|
// SvXMLExceptionListExport aExp(rLst, sStrmName, xHandler);
|
|
SvXMLExceptionListExport aExp( xServiceFactory, rLst, sStrmName, xHandler );
|
|
|
|
aExp.exportDoc( XML_BLOCK_LIST );
|
|
|
|
xStrm->Commit();
|
|
if( xStrm->GetError() == SVSTREAM_OK )
|
|
{
|
|
xStrm.Clear();
|
|
if (!bConvert)
|
|
{
|
|
rStg->Commit();
|
|
if( SVSTREAM_OK != rStg->GetError() )
|
|
{
|
|
rStg->Remove( sStrmName );
|
|
rStg->Commit();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
/* -----------------18.11.98 11:26-------------------
|
|
*
|
|
* --------------------------------------------------*/
|
|
SvxAutocorrWordList* SvxAutoCorrectLanguageLists::LoadAutocorrWordList()
|
|
{
|
|
if( pAutocorr_List )
|
|
pAutocorr_List->DeleteAndDestroy( 0, pAutocorr_List->Count() );
|
|
else
|
|
pAutocorr_List = new SvxAutocorrWordList( 16, 16 );
|
|
|
|
SvStringsDtor aRemoveArr;
|
|
try
|
|
{
|
|
uno::Reference < embed::XStorage > xStg = comphelper::OStorageHelper::GetStorageFromURL( sShareAutoCorrFile, embed::ElementModes::READ );
|
|
String aXMLWordListName( pXMLImplAutocorr_ListStr, RTL_TEXTENCODING_MS_1252 );
|
|
uno::Reference < io::XStream > xStrm = xStg->openStreamElement( aXMLWordListName, embed::ElementModes::READ );
|
|
uno::Reference< lang::XMultiServiceFactory > xServiceFactory = comphelper::getProcessServiceFactory();
|
|
|
|
xml::sax::InputSource aParserInput;
|
|
aParserInput.sSystemId = aXMLWordListName;
|
|
aParserInput.aInputStream = xStrm->getInputStream();
|
|
|
|
// get parser
|
|
uno::Reference< XInterface > xXMLParser = xServiceFactory->createInstance( OUString::createFromAscii("com.sun.star.xml.sax.Parser") );
|
|
DBG_ASSERT( xXMLParser.is(), "XMLReader::Read: com.sun.star.xml.sax.Parser service missing" );
|
|
if( xXMLParser.is() )
|
|
{
|
|
uno::Reference< xml::sax::XDocumentHandler > xFilter = new SvXMLAutoCorrectImport( xServiceFactory, pAutocorr_List, rAutoCorrect, xStg );
|
|
|
|
// connect parser and filter
|
|
uno::Reference< xml::sax::XParser > xParser( xXMLParser, UNO_QUERY );
|
|
xParser->setDocumentHandler( xFilter );
|
|
|
|
// parse
|
|
xParser->parseStream( aParserInput );
|
|
}
|
|
}
|
|
catch ( uno::Exception& )
|
|
{
|
|
}
|
|
|
|
// Zeitstempel noch setzen
|
|
FStatHelper::GetModifiedDateTimeOfFile( sShareAutoCorrFile,
|
|
&aModifiedDate, &aModifiedTime );
|
|
aLastCheckTime = Time();
|
|
|
|
return pAutocorr_List;
|
|
}
|
|
|
|
/* -----------------18.11.98 11:26-------------------
|
|
*
|
|
* --------------------------------------------------*/
|
|
|
|
void SvxAutoCorrectLanguageLists::SetAutocorrWordList( SvxAutocorrWordList* pList )
|
|
{
|
|
if( pAutocorr_List && pList != pAutocorr_List )
|
|
delete pAutocorr_List;
|
|
pAutocorr_List = pList;
|
|
if( !pAutocorr_List )
|
|
{
|
|
DBG_ASSERT( !this, "keine gueltige Liste" );
|
|
pAutocorr_List = new SvxAutocorrWordList( 16, 16 );
|
|
}
|
|
nFlags |= ChgWordLstLoad;
|
|
}
|
|
|
|
/* -----------------18.11.98 11:26-------------------
|
|
*
|
|
* --------------------------------------------------*/
|
|
const SvxAutocorrWordList* SvxAutoCorrectLanguageLists::GetAutocorrWordList()
|
|
{
|
|
if( !( ChgWordLstLoad & nFlags ) || IsFileChanged_Imp() )
|
|
SetAutocorrWordList( LoadAutocorrWordList() );
|
|
return pAutocorr_List;
|
|
}
|
|
/* -----------------18.11.98 11:26-------------------
|
|
*
|
|
* --------------------------------------------------*/
|
|
SvStringsISortDtor* SvxAutoCorrectLanguageLists::GetCplSttExceptList()
|
|
{
|
|
if( !( CplSttLstLoad & nFlags ) || IsFileChanged_Imp() )
|
|
SetCplSttExceptList( LoadCplSttExceptList() );
|
|
return pCplStt_ExcptLst;
|
|
}
|
|
/* -----------------18.11.98 11:26-------------------
|
|
*
|
|
* --------------------------------------------------*/
|
|
BOOL SvxAutoCorrectLanguageLists::AddToCplSttExceptList(const String& rNew)
|
|
{
|
|
String* pNew = new String( rNew );
|
|
if( rNew.Len() && GetCplSttExceptList()->Insert( pNew ) )
|
|
{
|
|
MakeUserStorage_Impl();
|
|
SotStorageRef xStg = new SotStorage( sUserAutoCorrFile, STREAM_READWRITE, TRUE );
|
|
|
|
SaveExceptList_Imp( *pCplStt_ExcptLst, pXMLImplCplStt_ExcptLstStr, xStg );
|
|
|
|
xStg = 0;
|
|
// Zeitstempel noch setzen
|
|
FStatHelper::GetModifiedDateTimeOfFile( sUserAutoCorrFile,
|
|
&aModifiedDate, &aModifiedTime );
|
|
aLastCheckTime = Time();
|
|
}
|
|
else
|
|
delete pNew, pNew = 0;
|
|
return 0 != pNew;
|
|
}
|
|
/* -----------------18.11.98 15:20-------------------
|
|
*
|
|
* --------------------------------------------------*/
|
|
BOOL SvxAutoCorrectLanguageLists::AddToWrdSttExceptList(const String& rNew)
|
|
{
|
|
String* pNew = new String( rNew );
|
|
SvStringsISortDtor* pExceptList = LoadWrdSttExceptList();
|
|
if( rNew.Len() && pExceptList && pExceptList->Insert( pNew ) )
|
|
{
|
|
MakeUserStorage_Impl();
|
|
SotStorageRef xStg = new SotStorage( sUserAutoCorrFile, STREAM_READWRITE, TRUE );
|
|
|
|
SaveExceptList_Imp( *pWrdStt_ExcptLst, pXMLImplWrdStt_ExcptLstStr, xStg );
|
|
|
|
xStg = 0;
|
|
// Zeitstempel noch setzen
|
|
FStatHelper::GetModifiedDateTimeOfFile( sUserAutoCorrFile,
|
|
&aModifiedDate, &aModifiedTime );
|
|
aLastCheckTime = Time();
|
|
}
|
|
else
|
|
delete pNew, pNew = 0;
|
|
return 0 != pNew;
|
|
}
|
|
|
|
/* -----------------18.11.98 11:26-------------------
|
|
*
|
|
* --------------------------------------------------*/
|
|
SvStringsISortDtor* SvxAutoCorrectLanguageLists::LoadCplSttExceptList()
|
|
{
|
|
SotStorageRef xStg = new SotStorage( sShareAutoCorrFile, STREAM_READ | STREAM_SHARE_DENYNONE, TRUE );
|
|
String sTemp ( RTL_CONSTASCII_USTRINGPARAM ( pXMLImplCplStt_ExcptLstStr ) );
|
|
if( xStg.Is() && xStg->IsContained( sTemp ) )
|
|
LoadXMLExceptList_Imp( pCplStt_ExcptLst, pXMLImplCplStt_ExcptLstStr, xStg );
|
|
|
|
return pCplStt_ExcptLst;
|
|
}
|
|
|
|
/* -----------------18.11.98 11:26-------------------
|
|
*
|
|
* --------------------------------------------------*/
|
|
void SvxAutoCorrectLanguageLists::SaveCplSttExceptList()
|
|
{
|
|
MakeUserStorage_Impl();
|
|
SotStorageRef xStg = new SotStorage( sUserAutoCorrFile, STREAM_READWRITE, TRUE );
|
|
|
|
SaveExceptList_Imp( *pCplStt_ExcptLst, pXMLImplCplStt_ExcptLstStr, xStg );
|
|
|
|
xStg = 0;
|
|
|
|
// Zeitstempel noch setzen
|
|
FStatHelper::GetModifiedDateTimeOfFile( sUserAutoCorrFile,
|
|
&aModifiedDate, &aModifiedTime );
|
|
aLastCheckTime = Time();
|
|
}
|
|
|
|
/* -----------------18.11.98 11:26-------------------
|
|
*
|
|
* --------------------------------------------------*/
|
|
void SvxAutoCorrectLanguageLists::SetCplSttExceptList( SvStringsISortDtor* pList )
|
|
{
|
|
if( pCplStt_ExcptLst && pList != pCplStt_ExcptLst )
|
|
delete pCplStt_ExcptLst;
|
|
|
|
pCplStt_ExcptLst = pList;
|
|
if( !pCplStt_ExcptLst )
|
|
{
|
|
DBG_ASSERT( !this, "keine gueltige Liste" );
|
|
pCplStt_ExcptLst = new SvStringsISortDtor( 16, 16 );
|
|
}
|
|
nFlags |= CplSttLstLoad;
|
|
}
|
|
/* -----------------18.11.98 11:26-------------------
|
|
*
|
|
* --------------------------------------------------*/
|
|
SvStringsISortDtor* SvxAutoCorrectLanguageLists::LoadWrdSttExceptList()
|
|
{
|
|
SotStorageRef xStg = new SotStorage( sShareAutoCorrFile, STREAM_READ | STREAM_SHARE_DENYNONE, TRUE );
|
|
String sTemp ( RTL_CONSTASCII_USTRINGPARAM ( pXMLImplWrdStt_ExcptLstStr ) );
|
|
if( xStg.Is() && xStg->IsContained( sTemp ) )
|
|
LoadXMLExceptList_Imp( pWrdStt_ExcptLst, pXMLImplWrdStt_ExcptLstStr, xStg );
|
|
return pWrdStt_ExcptLst;
|
|
}
|
|
/* -----------------18.11.98 11:26-------------------
|
|
*
|
|
* --------------------------------------------------*/
|
|
void SvxAutoCorrectLanguageLists::SaveWrdSttExceptList()
|
|
{
|
|
MakeUserStorage_Impl();
|
|
SotStorageRef xStg = new SotStorage( sUserAutoCorrFile, STREAM_READWRITE, TRUE );
|
|
|
|
SaveExceptList_Imp( *pWrdStt_ExcptLst, pXMLImplWrdStt_ExcptLstStr, xStg );
|
|
|
|
xStg = 0;
|
|
// Zeitstempel noch setzen
|
|
FStatHelper::GetModifiedDateTimeOfFile( sUserAutoCorrFile,
|
|
&aModifiedDate, &aModifiedTime );
|
|
aLastCheckTime = Time();
|
|
}
|
|
/* -----------------18.11.98 11:26-------------------
|
|
*
|
|
* --------------------------------------------------*/
|
|
void SvxAutoCorrectLanguageLists::SetWrdSttExceptList( SvStringsISortDtor* pList )
|
|
{
|
|
if( pWrdStt_ExcptLst && pList != pWrdStt_ExcptLst )
|
|
delete pWrdStt_ExcptLst;
|
|
pWrdStt_ExcptLst = pList;
|
|
if( !pWrdStt_ExcptLst )
|
|
{
|
|
DBG_ASSERT( !this, "keine gueltige Liste" );
|
|
pWrdStt_ExcptLst = new SvStringsISortDtor( 16, 16 );
|
|
}
|
|
nFlags |= WrdSttLstLoad;
|
|
}
|
|
/* -----------------18.11.98 11:26-------------------
|
|
*
|
|
* --------------------------------------------------*/
|
|
SvStringsISortDtor* SvxAutoCorrectLanguageLists::GetWrdSttExceptList()
|
|
{
|
|
if( !( WrdSttLstLoad & nFlags ) || IsFileChanged_Imp() )
|
|
SetWrdSttExceptList( LoadWrdSttExceptList() );
|
|
return pWrdStt_ExcptLst;
|
|
}
|
|
/* -----------------18.11.98 11:26-------------------
|
|
*
|
|
* --------------------------------------------------*/
|
|
void SvxAutoCorrectLanguageLists::RemoveStream_Imp( const String& rName )
|
|
{
|
|
if( sShareAutoCorrFile != sUserAutoCorrFile )
|
|
{
|
|
SotStorageRef xStg = new SotStorage( sUserAutoCorrFile, STREAM_READWRITE, TRUE );
|
|
if( xStg.Is() && SVSTREAM_OK == xStg->GetError() &&
|
|
xStg->IsStream( rName ) )
|
|
{
|
|
xStg->Remove( rName );
|
|
xStg->Commit();
|
|
|
|
xStg = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
void SvxAutoCorrectLanguageLists::MakeUserStorage_Impl()
|
|
{
|
|
// The conversion needs to happen if the file is already in the user
|
|
// directory and is in the old format. Additionally it needs to
|
|
// happen when the file is being copied from share to user.
|
|
|
|
sal_Bool bError = sal_False, bConvert = sal_False, bCopy = sal_False;
|
|
INetURLObject aDest;
|
|
INetURLObject aSource;
|
|
|
|
// String sDestPath = sUserAutoCorrFile.Copy ( 0, sUserAutoCorrFile.Len()-3);
|
|
// sDestPath.AppendAscii ("bak");
|
|
|
|
|
|
if (sUserAutoCorrFile != sShareAutoCorrFile )
|
|
{
|
|
aSource = INetURLObject ( sShareAutoCorrFile ); //aSource.setFSysPath ( sShareAutoCorrFile, INetURLObject::FSYS_DETECT );
|
|
aDest = INetURLObject ( sUserAutoCorrFile );
|
|
if ( SotStorage::IsOLEStorage ( sShareAutoCorrFile ) )
|
|
{
|
|
aDest.SetExtension ( String::CreateFromAscii ( "bak" ) );
|
|
bConvert = sal_True;
|
|
}
|
|
bCopy = sal_True;
|
|
}
|
|
else if ( SotStorage::IsOLEStorage ( sUserAutoCorrFile ) )
|
|
{
|
|
aSource = INetURLObject ( sUserAutoCorrFile );
|
|
aDest = INetURLObject ( sUserAutoCorrFile );
|
|
aDest.SetExtension ( String::CreateFromAscii ( "bak" ) );
|
|
bCopy = bConvert = sal_True;
|
|
}
|
|
if (bCopy)
|
|
{
|
|
try
|
|
{
|
|
String sMain(aDest.GetMainURL( INetURLObject::DECODE_TO_IURI ));
|
|
sal_Unicode cSlash = '/';
|
|
xub_StrLen nSlashPos = sMain.SearchBackward(cSlash);
|
|
sMain.Erase(nSlashPos);
|
|
::ucbhelper::Content aNewContent( sMain, uno::Reference< XCommandEnvironment > ());
|
|
Any aAny;
|
|
TransferInfo aInfo;
|
|
aInfo.NameClash = NameClash::OVERWRITE;
|
|
aInfo.NewTitle = aDest.GetName();
|
|
aInfo.SourceURL = aSource.GetMainURL( INetURLObject::DECODE_TO_IURI );
|
|
aInfo.MoveData = FALSE;
|
|
aAny <<= aInfo;
|
|
aNewContent.executeCommand( OUString ( RTL_CONSTASCII_USTRINGPARAM( "transfer" ) ), aAny);
|
|
}
|
|
catch (...)
|
|
{
|
|
bError = sal_True;
|
|
}
|
|
}
|
|
if (bConvert && !bError)
|
|
{
|
|
SotStorageRef xSrcStg = new SotStorage( aDest.GetMainURL( INetURLObject::DECODE_TO_IURI ), STREAM_READ, TRUE );
|
|
SotStorageRef xDstStg = new SotStorage( sUserAutoCorrFile, STREAM_WRITE, TRUE );
|
|
|
|
if( xSrcStg.Is() && xDstStg.Is() )
|
|
{
|
|
String sWord ( RTL_CONSTASCII_USTRINGPARAM ( pImplWrdStt_ExcptLstStr ) );
|
|
String sSentence ( RTL_CONSTASCII_USTRINGPARAM ( pImplCplStt_ExcptLstStr ) );
|
|
String sXMLWord ( RTL_CONSTASCII_USTRINGPARAM ( pXMLImplWrdStt_ExcptLstStr ) );
|
|
String sXMLSentence ( RTL_CONSTASCII_USTRINGPARAM ( pXMLImplCplStt_ExcptLstStr ) );
|
|
SvStringsISortDtor *pTmpWordList = NULL;
|
|
|
|
if (xSrcStg->IsContained( sXMLWord ) )
|
|
LoadXMLExceptList_Imp( pTmpWordList, pXMLImplWrdStt_ExcptLstStr, xSrcStg );
|
|
|
|
if (pTmpWordList)
|
|
{
|
|
SaveExceptList_Imp( *pTmpWordList, pXMLImplWrdStt_ExcptLstStr, xDstStg, TRUE );
|
|
pTmpWordList->DeleteAndDestroy( 0, pTmpWordList->Count() );
|
|
pTmpWordList = NULL;
|
|
}
|
|
|
|
|
|
if (xSrcStg->IsContained( sXMLSentence ) )
|
|
LoadXMLExceptList_Imp( pTmpWordList, pXMLImplCplStt_ExcptLstStr, xSrcStg );
|
|
|
|
if (pTmpWordList)
|
|
{
|
|
SaveExceptList_Imp( *pTmpWordList, pXMLImplCplStt_ExcptLstStr, xDstStg, TRUE );
|
|
pTmpWordList->DeleteAndDestroy( 0, pTmpWordList->Count() );
|
|
}
|
|
|
|
GetAutocorrWordList();
|
|
MakeBlocklist_Imp( *xDstStg );
|
|
// xDstStg is committed in MakeBlocklist_Imp
|
|
/*xSrcStg->CopyTo( &xDstStg );*/
|
|
sShareAutoCorrFile = sUserAutoCorrFile;
|
|
xDstStg = 0;
|
|
try
|
|
{
|
|
::ucbhelper::Content aContent ( aDest.GetMainURL( INetURLObject::DECODE_TO_IURI ), uno::Reference < XCommandEnvironment > ());
|
|
aContent.executeCommand ( OUString ( RTL_CONSTASCII_USTRINGPARAM ( "delete" ) ), makeAny ( sal_Bool (sal_True ) ) );
|
|
}
|
|
catch (...)
|
|
{
|
|
}
|
|
}
|
|
}
|
|
else if( bCopy && !bError )
|
|
sShareAutoCorrFile = sUserAutoCorrFile;
|
|
}
|
|
|
|
/* -----------------18.11.98 11:26-------------------
|
|
*
|
|
* --------------------------------------------------*/
|
|
BOOL SvxAutoCorrectLanguageLists::MakeBlocklist_Imp( SvStorage& rStg )
|
|
{
|
|
String sStrmName( pXMLImplAutocorr_ListStr, RTL_TEXTENCODING_MS_1252 );
|
|
BOOL bRet = TRUE, bRemove = !pAutocorr_List || !pAutocorr_List->Count();
|
|
if( !bRemove )
|
|
{
|
|
/*
|
|
if ( rStg.IsContained( sStrmName) )
|
|
{
|
|
rStg.Remove ( sStrmName );
|
|
rStg.Commit();
|
|
}
|
|
*/
|
|
SvStorageStreamRef refList = rStg.OpenSotStream( sStrmName,
|
|
( STREAM_READ | STREAM_WRITE | STREAM_SHARE_DENYWRITE ) );
|
|
if( refList.Is() )
|
|
{
|
|
refList->SetSize( 0 );
|
|
refList->SetBufferSize( 8192 );
|
|
String aPropName( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM("MediaType") ) );
|
|
OUString aMime( RTL_CONSTASCII_USTRINGPARAM("text/xml") );
|
|
uno::Any aAny;
|
|
aAny <<= aMime;
|
|
refList->SetProperty( aPropName, aAny );
|
|
|
|
uno::Reference< lang::XMultiServiceFactory > xServiceFactory =
|
|
comphelper::getProcessServiceFactory();
|
|
DBG_ASSERT( xServiceFactory.is(),
|
|
"XMLReader::Read: got no service manager" );
|
|
if( !xServiceFactory.is() )
|
|
{
|
|
// Throw an exception ?
|
|
}
|
|
|
|
uno::Reference < XInterface > xWriter (xServiceFactory->createInstance(
|
|
OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.sax.Writer"))));
|
|
DBG_ASSERT(xWriter.is(),"com.sun.star.xml.sax.Writer service missing");
|
|
uno::Reference < io::XOutputStream> xOut = new utl::OOutputStreamWrapper( *refList );
|
|
uno::Reference<io::XActiveDataSource> xSrc(xWriter, uno::UNO_QUERY);
|
|
xSrc->setOutputStream(xOut);
|
|
|
|
uno::Reference<xml::sax::XDocumentHandler> xHandler(xWriter, uno::UNO_QUERY);
|
|
|
|
// #110680#
|
|
// SvXMLAutoCorrectExport aExp(pAutocorr_List, sStrmName, xHandler);
|
|
SvXMLAutoCorrectExport aExp( xServiceFactory, pAutocorr_List, sStrmName, xHandler );
|
|
|
|
aExp.exportDoc( XML_BLOCK_LIST );
|
|
|
|
refList->Commit();
|
|
bRet = SVSTREAM_OK == refList->GetError();
|
|
if( bRet )
|
|
{
|
|
refList.Clear();
|
|
rStg.Commit();
|
|
if( SVSTREAM_OK != rStg.GetError() )
|
|
{
|
|
bRemove = TRUE;
|
|
bRet = FALSE;
|
|
}
|
|
}
|
|
|
|
/*
|
|
refList->SetSize( 0 );
|
|
refList->SetBufferSize( 8192 );
|
|
rtl_TextEncoding eEncoding = gsl_getSystemTextEncoding();
|
|
|
|
String aDummy; // Erkennungszeichen fuer neue Streams
|
|
refList->WriteByteString( aDummy, RTL_TEXTENCODING_MS_1252 )
|
|
<< (BYTE) 4 // Laenge des Headers (ohne den Leerstring)
|
|
<< (USHORT)WORDLIST_VERSION_358 // Version des Streams
|
|
<< (BYTE)eEncoding; // der Zeichensatz
|
|
|
|
for( USHORT i = 0; i < pAutocorr_List->Count() &&
|
|
SVSTREAM_OK == refList->GetError(); ++i )
|
|
{
|
|
SvxAutocorrWord* p = pAutocorr_List->GetObject( i );
|
|
refList->WriteByteString( p->GetShort(), eEncoding ).
|
|
WriteByteString( p->IsTextOnly()
|
|
? p->GetLong()
|
|
: p->GetShort(), eEncoding );
|
|
}
|
|
refList->Commit();
|
|
bRet = SVSTREAM_OK == refList->GetError();
|
|
if( bRet )
|
|
{
|
|
refList.Clear();
|
|
rStg.Commit();
|
|
if( SVSTREAM_OK != rStg.GetError() )
|
|
{
|
|
bRemove = TRUE;
|
|
bRet = FALSE;
|
|
}
|
|
}
|
|
*/
|
|
}
|
|
else
|
|
bRet = FALSE;
|
|
}
|
|
|
|
if( bRemove )
|
|
{
|
|
rStg.Remove( sStrmName );
|
|
rStg.Commit();
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
/* -----------------18.11.98 11:26-------------------
|
|
*
|
|
* --------------------------------------------------*/
|
|
BOOL SvxAutoCorrectLanguageLists::PutText( const String& rShort,
|
|
const String& rLong )
|
|
{
|
|
// erstmal akt. Liste besorgen!
|
|
GetAutocorrWordList();
|
|
|
|
MakeUserStorage_Impl();
|
|
SotStorageRef xStg = new SotStorage( sUserAutoCorrFile, STREAM_READWRITE, TRUE );
|
|
|
|
BOOL bRet = xStg.Is() && SVSTREAM_OK == xStg->GetError();
|
|
|
|
/* if( bRet )
|
|
{
|
|
// PutText( *xStg, rShort );
|
|
}
|
|
*/
|
|
// die Wortliste aktualisieren
|
|
if( bRet )
|
|
{
|
|
USHORT nPos;
|
|
SvxAutocorrWord* pNew = new SvxAutocorrWord( rShort, rLong, TRUE );
|
|
if( pAutocorr_List->Seek_Entry( pNew, &nPos ) )
|
|
{
|
|
if( !(*pAutocorr_List)[ nPos ]->IsTextOnly() )
|
|
{
|
|
// dann ist der Storage noch zu entfernen
|
|
String sStgNm( rShort );
|
|
if (xStg->IsOLEStorage())
|
|
EncryptBlockName_Imp( sStgNm );
|
|
else
|
|
GeneratePackageName ( rShort, sStgNm);
|
|
|
|
if( xStg->IsContained( sStgNm ) )
|
|
xStg->Remove( sStgNm );
|
|
}
|
|
pAutocorr_List->DeleteAndDestroy( nPos );
|
|
}
|
|
|
|
if( pAutocorr_List->Insert( pNew ) )
|
|
{
|
|
bRet = MakeBlocklist_Imp( *xStg );
|
|
xStg = 0;
|
|
}
|
|
else
|
|
{
|
|
delete pNew;
|
|
bRet = FALSE;
|
|
}
|
|
}
|
|
return bRet;
|
|
}
|
|
/* -----------------18.11.98 11:26-------------------
|
|
*
|
|
* --------------------------------------------------*/
|
|
// - Text mit Attributierung (kann nur der SWG - SWG-Format!)
|
|
BOOL SvxAutoCorrectLanguageLists::PutText( const String& rShort,
|
|
SfxObjectShell& rShell )
|
|
{
|
|
// erstmal akt. Liste besorgen!
|
|
GetAutocorrWordList();
|
|
|
|
MakeUserStorage_Impl();
|
|
|
|
BOOL bRet = FALSE;
|
|
String sLong;
|
|
try
|
|
{
|
|
uno::Reference < embed::XStorage > xStg = comphelper::OStorageHelper::GetStorageFromURL( sUserAutoCorrFile, embed::ElementModes::READWRITE );
|
|
// String aName( rShort );
|
|
// EncryptBlockName_Imp( aName );
|
|
// bRet = PutText( *xStg, aName, rShell, sLong );
|
|
bRet = rAutoCorrect.PutText( xStg, sUserAutoCorrFile, rShort, rShell, sLong );
|
|
xStg = 0;
|
|
|
|
// die Wortliste aktualisieren
|
|
if( bRet )
|
|
{
|
|
SvxAutocorrWord* pNew = new SvxAutocorrWord( rShort, sLong, FALSE );
|
|
if( pAutocorr_List->Insert( pNew ) )
|
|
{
|
|
SotStorageRef xStor = new SotStorage( sUserAutoCorrFile, STREAM_READWRITE, TRUE );
|
|
MakeBlocklist_Imp( *xStor );
|
|
}
|
|
else
|
|
delete pNew;
|
|
}
|
|
}
|
|
catch ( uno::Exception& )
|
|
{
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
/* -----------------18.11.98 11:26-------------------
|
|
*
|
|
* --------------------------------------------------*/
|
|
// - loesche einen Eintrag
|
|
BOOL SvxAutoCorrectLanguageLists::DeleteText( const String& rShort )
|
|
{
|
|
// erstmal akt. Liste besorgen!
|
|
GetAutocorrWordList();
|
|
|
|
MakeUserStorage_Impl();
|
|
|
|
SotStorageRef xStg = new SotStorage( sUserAutoCorrFile, STREAM_READWRITE, TRUE );
|
|
BOOL bRet = xStg.Is() && SVSTREAM_OK == xStg->GetError();
|
|
if( bRet )
|
|
{
|
|
USHORT nPos;
|
|
SvxAutocorrWord aTmp( rShort, rShort );
|
|
if( pAutocorr_List->Seek_Entry( &aTmp, &nPos ) )
|
|
{
|
|
SvxAutocorrWord* pFnd = (*pAutocorr_List)[ nPos ];
|
|
if( !pFnd->IsTextOnly() )
|
|
{
|
|
String aName( rShort );
|
|
if (xStg->IsOLEStorage())
|
|
EncryptBlockName_Imp( aName );
|
|
else
|
|
GeneratePackageName ( rShort, aName );
|
|
if( xStg->IsContained( aName ) )
|
|
{
|
|
xStg->Remove( aName );
|
|
bRet = xStg->Commit();
|
|
}
|
|
|
|
}
|
|
// die Wortliste aktualisieren
|
|
pAutocorr_List->DeleteAndDestroy( nPos );
|
|
MakeBlocklist_Imp( *xStg );
|
|
xStg = 0;
|
|
}
|
|
else
|
|
bRet = FALSE;
|
|
}
|
|
return bRet;
|
|
}
|