1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: svxacorr.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svx.hxx"
35 #include <com/sun/star/io/XStream.hpp>
36 #include <com/sun/star/lang/Locale.hpp>
37 #include <tools/urlobj.hxx>
38 #include <tools/table.hxx>
39 #include <i18npool/mslangid.hxx>
40 #ifndef _APP_HXX //autogen
41 #include <vcl/svapp.hxx>
43 #ifndef _STORINFO_HXX //autogen
44 #include <sot/storinfo.hxx>
46 #ifndef _SFX_DOCFILE_HXX
47 #include <sfx2/docfile.hxx>
49 #include <sfx2/sfxhelp.hxx>
50 #include <sfx2/viewfrm.hxx>
51 // fuer die Sort-String-Arrays aus dem SVMEM.HXX
52 #define _SVSTDARR_STRINGSISORTDTOR
53 #define _SVSTDARR_STRINGSDTOR
54 #include <svtools/svstdarr.hxx>
56 #ifndef SVTOOLS_FSTATHELPER_HXX
57 #include <svtools/fstathelper.hxx>
59 #include <svtools/helpopt.hxx>
60 #include <svtools/urihelper.hxx>
61 #include <unotools/charclass.hxx>
62 #ifndef _COM_SUN_STAR_I18N_UNICODETYPE_HDL_
63 #include <com/sun/star/i18n/UnicodeType.hdl>
65 #include <unotools/collatorwrapper.hxx>
66 #include <com/sun/star/i18n/CollatorOptions.hpp>
67 #include <unotools/localedatawrapper.hxx>
68 #include <unotools/transliterationwrapper.hxx>
69 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
70 #include <comphelper/processfactory.hxx>
71 #include <com/sun/star/io/XActiveDataSource.hpp>
73 #ifndef _SVX_SVXIDS_HRC
74 #include <svx/svxids.hrc>
77 #include <sot/storage.hxx>
78 #include <comphelper/storagehelper.hxx>
80 #include <svx/udlnitem.hxx>
81 #include <svx/wghtitem.hxx>
82 #include <svx/escpitem.hxx>
83 #include <svx/svxacorr.hxx>
84 #include "unolingu.hxx"
85 #include "vcl/window.hxx"
87 #ifndef _SVX_HELPID_HRC
90 #include <comphelper/processfactory.hxx>
91 #include <com/sun/star/xml/sax/InputSource.hpp>
92 #include <com/sun/star/xml/sax/XParser.hpp>
93 #include <unotools/streamwrap.hxx>
94 #include <SvXMLAutoCorrectImport.hxx>
95 #include <SvXMLAutoCorrectExport.hxx>
96 #include <ucbhelper/content.hxx>
97 #include <com/sun/star/ucb/XCommandEnvironment.hpp>
98 #include <com/sun/star/ucb/TransferInfo.hpp>
99 #include <com/sun/star/ucb/NameClash.hpp>
100 #include <xmloff/xmltoken.hxx>
102 #define CHAR_HARDBLANK ((sal_Unicode)0x00A0)
104 using namespace ::com::sun::star::ucb
;
105 using namespace ::com::sun::star::uno
;
106 using namespace ::com::sun::star
;
107 using namespace ::xmloff::token
;
108 using namespace ::rtl
;
109 using namespace ::utl
;
111 const int C_NONE
= 0x00;
112 const int C_FULL_STOP
= 0x01;
113 const int C_EXCLAMATION_MARK
= 0x02;
114 const int C_QUESTION_MARK
= 0x04;
116 static const sal_Char pImplWrdStt_ExcptLstStr
[] = "WordExceptList";
117 static const sal_Char pImplCplStt_ExcptLstStr
[] = "SentenceExceptList";
118 static const sal_Char pImplAutocorr_ListStr
[] = "DocumentList";
119 static const sal_Char pXMLImplWrdStt_ExcptLstStr
[] = "WordExceptList.xml";
120 static const sal_Char pXMLImplCplStt_ExcptLstStr
[] = "SentenceExceptList.xml";
121 static const sal_Char pXMLImplAutocorr_ListStr
[] = "DocumentList.xml";
123 static const sal_Char
124 /* auch bei diesen Anfaengen - Klammern auf und alle Arten von Anf.Zei. */
125 sImplSttSkipChars
[] = "\"\'([{\x83\x84\x89\x91\x92\x93\x94",
126 /* auch bei diesen Ende - Klammern auf und alle Arten von Anf.Zei. */
127 sImplEndSkipChars
[] = "\"\')]}\x83\x84\x89\x91\x92\x93\x94";
129 // diese Zeichen sind in Worten erlaubt: (fuer FnCptlSttSntnc)
130 static const sal_Char sImplWordChars
[] = "-'";
132 void EncryptBlockName_Imp( String
& rName
);
133 void DecryptBlockName_Imp( String
& rName
);
136 // FileVersions Nummern fuer die Ersetzungs-/Ausnahmelisten getrennt
137 #define WORDLIST_VERSION_358 1
138 #define EXEPTLIST_VERSION_358 0
141 _SV_IMPL_SORTAR_ALG( SvxAutocorrWordList
, SvxAutocorrWordPtr
)
142 TYPEINIT0(SvxAutoCorrect
)
144 typedef SvxAutoCorrectLanguageLists
* SvxAutoCorrectLanguageListsPtr
;
145 DECLARE_TABLE( SvxAutoCorrLanguageTable_Impl
, SvxAutoCorrectLanguageListsPtr
)
147 DECLARE_TABLE( SvxAutoCorrLastFileAskTable_Impl
, long )
150 inline int IsWordDelim( const sal_Unicode c
)
152 return ' ' == c
|| '\t' == c
|| 0x0a == c
||
153 0xA0 == c
|| 0x2011 == c
|| 0x1 == c
;
156 inline int IsLowerLetter( sal_Int32 nCharType
)
158 return CharClass::isLetterType( nCharType
) &&
159 0 == ( ::com::sun::star::i18n::KCharacterType::UPPER
& nCharType
);
161 inline int IsUpperLetter( sal_Int32 nCharType
)
163 return CharClass::isLetterType( nCharType
) &&
164 0 == ( ::com::sun::star::i18n::KCharacterType::LOWER
& nCharType
);
167 BOOL
lcl_IsSymbolChar( CharClass
& rCC
, const String
& rTxt
,
168 xub_StrLen nStt
, xub_StrLen nEnd
)
170 for( ; nStt
< nEnd
; ++nStt
)
172 #if OSL_DEBUG_LEVEL > 1
175 nCharType
= rCC
.getCharacterType( rTxt
, nStt
);
176 nChType
= rCC
.getType( rTxt
, nStt
);
178 if( ::com::sun::star::i18n::UnicodeType::PRIVATE_USE
==
179 rCC
.getType( rTxt
, nStt
))
186 static BOOL
lcl_IsInAsciiArr( const sal_Char
* pArr
, const sal_Unicode c
)
189 for( ; *pArr
; ++pArr
)
198 SvxAutoCorrDoc::~SvxAutoCorrDoc()
203 // wird nach dem austauschen der Zeichen von den Funktionen
206 // gerufen. Dann koennen die Worte ggfs. in die Ausnahmelisten
207 // aufgenommen werden.
208 void SvxAutoCorrDoc::SaveCpltSttWord( ULONG
, xub_StrLen
, const String
&,
213 LanguageType
SvxAutoCorrDoc::GetLanguage( xub_StrLen
, BOOL
) const
215 return LANGUAGE_SYSTEM
;
218 static ::com::sun::star::uno::Reference
<
219 ::com::sun::star::lang::XMultiServiceFactory
>& GetProcessFact()
221 static ::com::sun::star::uno::Reference
<
222 ::com::sun::star::lang::XMultiServiceFactory
> xMSF
=
223 ::comphelper::getProcessServiceFactory();
227 static USHORT
GetAppLang()
229 return Application::GetSettings().GetLanguage();
231 static LocaleDataWrapper
& GetLocaleDataWrapper( USHORT nLang
)
233 static LocaleDataWrapper
aLclDtWrp( GetProcessFact(),
234 SvxCreateLocale( GetAppLang() ) );
235 ::com::sun::star::lang::Locale
aLcl( SvxCreateLocale( nLang
));
236 const ::com::sun::star::lang::Locale
& rLcl
= aLclDtWrp
.getLoadedLocale();
237 if( aLcl
.Language
!= rLcl
.Language
||
238 aLcl
.Country
!= rLcl
.Country
||
239 aLcl
.Variant
!= rLcl
.Variant
)
240 aLclDtWrp
.setLocale( aLcl
);
243 static TransliterationWrapper
& GetIgnoreTranslWrapper()
245 static int bIsInit
= 0;
246 static TransliterationWrapper
aWrp( GetProcessFact(),
247 ::com::sun::star::i18n::TransliterationModules_IGNORE_CASE
|
248 ::com::sun::star::i18n::TransliterationModules_IGNORE_KANA
|
249 ::com::sun::star::i18n::TransliterationModules_IGNORE_WIDTH
);
252 aWrp
.loadModuleIfNeeded( GetAppLang() );
257 static CollatorWrapper
& GetCollatorWrapper()
259 static int bIsInit
= 0;
260 static CollatorWrapper
aCollWrp( GetProcessFact() );
263 aCollWrp
.loadDefaultCollator( SvxCreateLocale( GetAppLang() ), 0 );
270 void SvxAutocorrWordList::DeleteAndDestroy( USHORT nP
, USHORT nL
)
274 DBG_ASSERT( nP
< nA
&& nP
+ nL
<= nA
, "ERR_VAR_DEL" );
275 for( USHORT n
=nP
; n
< nP
+ nL
; n
++ )
276 delete *((SvxAutocorrWordPtr
*)pData
+n
);
277 SvPtrarr::Remove( nP
, nL
);
282 BOOL
SvxAutocorrWordList::Seek_Entry( const SvxAutocorrWordPtr aE
, USHORT
* pP
) const
284 register USHORT nO
= SvxAutocorrWordList_SAR::Count(),
289 CollatorWrapper
& rCmp
= ::GetCollatorWrapper();
293 nM
= nU
+ ( nO
- nU
) / 2;
294 long nCmp
= rCmp
.compareString( aE
->GetShort(),
295 (*((SvxAutocorrWordPtr
*)pData
+ nM
))->GetShort() );
316 /* -----------------18.11.98 15:28-------------------
318 * --------------------------------------------------*/
319 void lcl_ClearTable(SvxAutoCorrLanguageTable_Impl
& rLangTable
)
321 SvxAutoCorrectLanguageListsPtr pLists
= rLangTable
.Last();
325 pLists
= rLangTable
.Prev();
330 /* -----------------03.11.06 10:15-------------------
332 * --------------------------------------------------*/
334 sal_Bool
SvxAutoCorrect::IsAutoCorrectChar( sal_Unicode cChar
)
336 return cChar
== '\0' || cChar
== '\t' || cChar
== 0x0a ||
337 cChar
== ' ' || cChar
== '\'' || cChar
== '\"' ||
338 cChar
== '*' || cChar
== '_' ||
339 cChar
== '.' || cChar
== ',' || cChar
== ';' ||
340 cChar
== ':' || cChar
== '?' || cChar
== '!';
343 /* -----------------19.11.98 10:15-------------------
345 * --------------------------------------------------*/
346 long SvxAutoCorrect::GetDefaultFlags()
348 long nRet
= Autocorrect
361 LanguageType eLang
= GetAppLang();
364 case LANGUAGE_ENGLISH
:
365 case LANGUAGE_ENGLISH_US
:
366 case LANGUAGE_ENGLISH_UK
:
367 case LANGUAGE_ENGLISH_AUS
:
368 case LANGUAGE_ENGLISH_CAN
:
369 case LANGUAGE_ENGLISH_NZ
:
370 case LANGUAGE_ENGLISH_EIRE
:
371 case LANGUAGE_ENGLISH_SAFRICA
:
372 case LANGUAGE_ENGLISH_JAMAICA
:
373 case LANGUAGE_ENGLISH_CARRIBEAN
:
374 nRet
&= ~(ChgQuotes
|ChgSglQuotes
);
381 SvxAutoCorrect::SvxAutoCorrect( const String
& rShareAutocorrFile
,
382 const String
& rUserAutocorrFile
)
383 : sShareAutoCorrFile( rShareAutocorrFile
),
384 sUserAutoCorrFile( rUserAutocorrFile
),
385 pLangTable( new SvxAutoCorrLanguageTable_Impl
),
386 pLastFileTable( new SvxAutoCorrLastFileAskTable_Impl
),
388 cStartDQuote( 0 ), cEndDQuote( 0 ), cStartSQuote( 0 ), cEndSQuote( 0 )
390 nFlags
= SvxAutoCorrect::GetDefaultFlags();
392 c1Div2
= ByteString::ConvertToUnicode( '\xBD', RTL_TEXTENCODING_MS_1252
);
393 c1Div4
= ByteString::ConvertToUnicode( '\xBC', RTL_TEXTENCODING_MS_1252
);
394 c3Div4
= ByteString::ConvertToUnicode( '\xBE', RTL_TEXTENCODING_MS_1252
);
395 cEmDash
= ByteString::ConvertToUnicode( '\x97', RTL_TEXTENCODING_MS_1252
);
396 cEnDash
= ByteString::ConvertToUnicode( '\x96', RTL_TEXTENCODING_MS_1252
);
399 SvxAutoCorrect::SvxAutoCorrect( const SvxAutoCorrect
& rCpy
)
400 : sShareAutoCorrFile( rCpy
.sShareAutoCorrFile
),
401 sUserAutoCorrFile( rCpy
.sUserAutoCorrFile
),
403 aSwFlags( rCpy
.aSwFlags
),
405 pLangTable( new SvxAutoCorrLanguageTable_Impl
),
406 pLastFileTable( new SvxAutoCorrLastFileAskTable_Impl
),
409 nFlags( rCpy
.nFlags
& ~(ChgWordLstLoad
|CplSttLstLoad
|WrdSttLstLoad
)),
410 cStartDQuote( rCpy
.cStartDQuote
), cEndDQuote( rCpy
.cEndDQuote
),
411 cStartSQuote( rCpy
.cStartSQuote
), cEndSQuote( rCpy
.cEndSQuote
),
412 c1Div2( rCpy
.c1Div2
), c1Div4( rCpy
.c1Div4
), c3Div4( rCpy
.c3Div4
),
413 cEmDash( rCpy
.cEmDash
), cEnDash( rCpy
.cEnDash
)
418 SvxAutoCorrect::~SvxAutoCorrect()
420 lcl_ClearTable(*pLangTable
);
422 delete pLastFileTable
;
426 void SvxAutoCorrect::_GetCharClass( LanguageType eLang
)
429 pCharClass
= new CharClass( SvxCreateLocale( eLang
));
430 eCharClassLang
= eLang
;
433 void SvxAutoCorrect::SetAutoCorrFlag( long nFlag
, BOOL bOn
)
436 nFlags
= bOn
? nFlags
| nFlag
441 if( (nOld
& CptlSttSntnc
) != (nFlags
& CptlSttSntnc
) )
442 nFlags
&= ~CplSttLstLoad
;
443 if( (nOld
& CptlSttWrd
) != (nFlags
& CptlSttWrd
) )
444 nFlags
&= ~WrdSttLstLoad
;
445 if( (nOld
& Autocorrect
) != (nFlags
& Autocorrect
) )
446 nFlags
&= ~ChgWordLstLoad
;
451 // Zwei Grossbuchstaben am Wort-Anfang ??
452 BOOL
SvxAutoCorrect::FnCptlSttWrd( SvxAutoCorrDoc
& rDoc
, const String
& rTxt
,
453 xub_StrLen nSttPos
, xub_StrLen nEndPos
,
457 CharClass
& rCC
= GetCharClass( eLang
);
459 // loesche alle nicht alpanum. Zeichen am Wortanfang/-ende und
460 // teste dann ( erkennt: "(min.", "/min.", usw.)
461 for( ; nSttPos
< nEndPos
; ++nSttPos
)
462 if( rCC
.isLetterNumeric( rTxt
, nSttPos
))
464 for( ; nSttPos
< nEndPos
; --nEndPos
)
465 if( rCC
.isLetterNumeric( rTxt
, nEndPos
- 1 ))
468 // Zwei Grossbuchstaben am Wort-Anfang ??
469 if( nSttPos
+2 < nEndPos
&&
470 IsUpperLetter( rCC
.getCharacterType( rTxt
, nSttPos
)) &&
471 IsUpperLetter( rCC
.getCharacterType( rTxt
, ++nSttPos
)) &&
472 // ist das 3. Zeichen ein klein geschiebenes Alpha-Zeichen
473 IsLowerLetter( rCC
.getCharacterType( rTxt
, nSttPos
+1 )) &&
474 // keine Sonder-Attribute ersetzen
475 0x1 != rTxt
.GetChar( nSttPos
) && 0x2 != rTxt
.GetChar( nSttPos
))
477 // teste ob das Wort in einer Ausnahmeliste steht
478 String
sWord( rTxt
.Copy( nSttPos
- 1, nEndPos
- nSttPos
+ 1 ));
479 if( !FindInWrdSttExceptList(eLang
, sWord
) )
481 sal_Unicode cSave
= rTxt
.GetChar( nSttPos
);
482 String
sChar( cSave
);
483 rCC
.toLower( sChar
);
484 if( sChar
.GetChar(0) != cSave
&& rDoc
.Replace( nSttPos
, sChar
))
486 if( SaveWordWrdSttLst
& nFlags
)
487 rDoc
.SaveCpltSttWord( CptlSttWrd
, nSttPos
, sWord
, cSave
);
496 BOOL
SvxAutoCorrect::FnChgFractionSymbol(
497 SvxAutoCorrDoc
& rDoc
, const String
& rTxt
,
498 xub_StrLen nSttPos
, xub_StrLen nEndPos
)
500 sal_Unicode cChar
= 0;
502 for( ; nSttPos
< nEndPos
; ++nSttPos
)
503 if( !lcl_IsInAsciiArr( sImplSttSkipChars
, rTxt
.GetChar( nSttPos
) ))
505 for( ; nSttPos
< nEndPos
; --nEndPos
)
506 if( !lcl_IsInAsciiArr( sImplEndSkipChars
, rTxt
.GetChar( nEndPos
- 1 ) ))
509 // 1/2, 1/4, ... ersetzen durch das entsprechende Zeichen vom Font
510 if( 3 == nEndPos
- nSttPos
&& '/' == rTxt
.GetChar( nSttPos
+1 ))
512 switch( ( rTxt
.GetChar( nSttPos
)) * 256 + rTxt
.GetChar( nEndPos
-1 ))
514 case '1' * 256 + '2': cChar
= c1Div2
; break;
515 case '1' * 256 + '4': cChar
= c1Div4
; break;
516 case '3' * 256 + '4': cChar
= c3Div4
; break;
522 rDoc
.Delete( nSttPos
+1, nEndPos
);
523 rDoc
.Replace( nSttPos
, cChar
);
530 BOOL
SvxAutoCorrect::FnChgOrdinalNumber(
531 SvxAutoCorrDoc
& rDoc
, const String
& rTxt
,
532 xub_StrLen nSttPos
, xub_StrLen nEndPos
,
535 // 1st, 2nd, 3rd, 4 - 0th
538 CharClass
& rCC
= GetCharClass( eLang
);
541 for( ; nSttPos
< nEndPos
; ++nSttPos
)
542 if( !lcl_IsInAsciiArr( sImplSttSkipChars
, rTxt
.GetChar( nSttPos
) ))
544 for( ; nSttPos
< nEndPos
; --nEndPos
)
545 if( !lcl_IsInAsciiArr( sImplEndSkipChars
, rTxt
.GetChar( nEndPos
- 1 ) ))
548 if( 2 < nEndPos
- nSttPos
&&
549 rCC
.isDigit( rTxt
, nEndPos
- 3 ) )
551 static sal_Char __READONLY_DATA
552 sAll
[] = "th", /* rest */
553 sFirst
[] = "st", /* 1 */
554 sSecond
[] = "nd", /* 2 */
555 sThird
[] = "rd"; /* 3 */
556 static const sal_Char
* __READONLY_DATA aNumberTab
[ 4 ] =
558 sAll
, sFirst
, sSecond
, sThird
561 sal_Unicode c
= rTxt
.GetChar( nEndPos
- 3 );
562 if( ( c
-= '0' ) > 3 )
565 bChg
= ( ((sal_Unicode
)*((aNumberTab
[ c
])+0)) ==
566 rTxt
.GetChar( nEndPos
- 2 ) &&
567 ((sal_Unicode
)*((aNumberTab
[ c
])+1)) ==
568 rTxt
.GetChar( nEndPos
- 1 )) ||
569 ( 3 < nEndPos
- nSttPos
&&
570 ( ((sal_Unicode
)*(sAll
+0)) == rTxt
.GetChar( nEndPos
- 2 ) &&
571 ((sal_Unicode
)*(sAll
+1)) == rTxt
.GetChar( nEndPos
- 1 )));
575 // dann pruefe mal, ob alle bis zum Start alle Zahlen sind
576 for( xub_StrLen n
= nEndPos
- 3; nSttPos
< n
; )
577 if( !rCC
.isDigit( rTxt
, --n
) )
579 bChg
= !rCC
.isLetter( rTxt
, n
);
583 if( bChg
) // dann setze mal das Escapement Attribut
585 SvxEscapementItem
aSvxEscapementItem( DFLT_ESC_AUTO_SUPER
,
586 DFLT_ESC_PROP
, SID_ATTR_CHAR_ESCAPEMENT
);
587 rDoc
.SetAttr( nEndPos
- 2, nEndPos
,
588 SID_ATTR_CHAR_ESCAPEMENT
,
598 BOOL
SvxAutoCorrect::FnChgToEnEmDash(
599 SvxAutoCorrDoc
& rDoc
, const String
& rTxt
,
600 xub_StrLen nSttPos
, xub_StrLen nEndPos
,
604 CharClass
& rCC
= GetCharClass( eLang
);
605 if (eLang
== LANGUAGE_SYSTEM
)
606 eLang
= GetAppLang();
607 bool bAlwaysUseEmDash
= (cEmDash
&& (eLang
== LANGUAGE_RUSSIAN
|| eLang
== LANGUAGE_UKRAINIAN
));
609 // ersetze " - " oder " --" durch "enDash"
610 if( cEnDash
&& 1 < nSttPos
&& 1 <= nEndPos
- nSttPos
)
612 sal_Unicode cCh
= rTxt
.GetChar( nSttPos
);
615 if( ' ' == rTxt
.GetChar( nSttPos
-1 ) &&
616 '-' == rTxt
.GetChar( nSttPos
+1 ))
619 for( n
= nSttPos
+2; n
< nEndPos
&& lcl_IsInAsciiArr(
620 sImplSttSkipChars
,(cCh
= rTxt
.GetChar( n
)));
624 // found: " --[<AnySttChars>][A-z0-9]
625 if( rCC
.isLetterNumeric( cCh
) )
627 for( n
= nSttPos
-1; n
&& lcl_IsInAsciiArr(
628 sImplEndSkipChars
,(cCh
= rTxt
.GetChar( --n
))); )
631 // found: "[A-z0-9][<AnyEndChars>] --[<AnySttChars>][A-z0-9]
632 if( rCC
.isLetterNumeric( cCh
))
634 rDoc
.Delete( nSttPos
, nSttPos
+ 2 );
635 rDoc
.Insert( nSttPos
, bAlwaysUseEmDash
? cEmDash
: cEnDash
);
641 else if( 3 < nSttPos
&&
642 ' ' == rTxt
.GetChar( nSttPos
-1 ) &&
643 '-' == rTxt
.GetChar( nSttPos
-2 ))
645 xub_StrLen n
, nLen
= 1, nTmpPos
= nSttPos
- 2;
646 if( '-' == ( cCh
= rTxt
.GetChar( nTmpPos
-1 )) )
650 cCh
= rTxt
.GetChar( nTmpPos
-1 );
654 for( n
= nSttPos
; n
< nEndPos
&& lcl_IsInAsciiArr(
655 sImplSttSkipChars
,(cCh
= rTxt
.GetChar( n
)));
659 // found: " - [<AnySttChars>][A-z0-9]
660 if( rCC
.isLetterNumeric( cCh
) )
663 for( n
= nTmpPos
-1; n
&& lcl_IsInAsciiArr(
664 sImplEndSkipChars
,(cCh
= rTxt
.GetChar( --n
))); )
666 // found: "[A-z0-9][<AnyEndChars>] - [<AnySttChars>][A-z0-9]
667 if( rCC
.isLetterNumeric( cCh
))
669 rDoc
.Delete( nTmpPos
, nTmpPos
+ nLen
);
670 rDoc
.Insert( nTmpPos
, bAlwaysUseEmDash
? cEmDash
: cEnDash
);
678 // Replace [A-z0-9]--[A-z0-9] double dash with "emDash" or "enDash".
679 // Finnish and Hungarian use enDash instead of emDash.
680 bool bEnDash
= (eLang
== LANGUAGE_HUNGARIAN
|| eLang
== LANGUAGE_FINNISH
);
681 if( ((cEmDash
&& !bEnDash
) || (cEnDash
&& bEnDash
)) && 4 <= nEndPos
- nSttPos
)
683 String
sTmp( rTxt
.Copy( nSttPos
, nEndPos
- nSttPos
) );
684 xub_StrLen nFndPos
= sTmp
.SearchAscii( "--" );
685 if( STRING_NOTFOUND
!= nFndPos
&& nFndPos
&&
686 nFndPos
+ 2 < sTmp
.Len() &&
687 ( rCC
.isLetterNumeric( sTmp
, nFndPos
- 1 ) ||
688 lcl_IsInAsciiArr( sImplEndSkipChars
, rTxt
.GetChar( nFndPos
- 1 ) )) &&
689 ( rCC
.isLetterNumeric( sTmp
, nFndPos
+ 2 ) ||
690 lcl_IsInAsciiArr( sImplSttSkipChars
, rTxt
.GetChar( nFndPos
+ 2 ) )))
692 nSttPos
= nSttPos
+ nFndPos
;
693 rDoc
.Delete( nSttPos
, nSttPos
+ 2 );
694 rDoc
.Insert( nSttPos
, (bEnDash
? cEnDash
: cEmDash
) );
701 BOOL
SvxAutoCorrect::FnAddNonBrkSpace(
702 SvxAutoCorrDoc
& rDoc
, const String
& rTxt
,
703 xub_StrLen
, xub_StrLen nEndPos
,
708 CharClass
& rCC
= GetCharClass( eLang
);
709 const lang::Locale rLocale
= rCC
.getLocale( );
711 if ( rLocale
.Language
== OUString::createFromAscii( "fr" ) )
713 sal_Unicode cChar
= rTxt
.GetChar( nEndPos
);
714 if ( cChar
== ':' || cChar
== ';' || cChar
== '!' || cChar
== '?' )
716 // Check the previous char
717 sal_Unicode cPrevChar
= rTxt
.GetChar( nEndPos
- 1 );
718 if ( cPrevChar
!= ':' && cPrevChar
!= ';' && cPrevChar
!= '!' && cPrevChar
!= '?' )
720 // Remove any previous normal space
721 xub_StrLen nPos
= nEndPos
- 1;
722 while ( cPrevChar
== ' ' || cPrevChar
== CHAR_HARDBLANK
)
724 if ( nPos
== 0 ) break;
726 cPrevChar
= rTxt
.GetChar( nPos
);
732 if ( nEndPos
- nPos
> 0 )
733 rDoc
.Delete( nPos
, nEndPos
);
735 // Add the non-breaking space at the end pos
736 rDoc
.Insert( nPos
, CHAR_HARDBLANK
);
746 BOOL
SvxAutoCorrect::FnSetINetAttr( SvxAutoCorrDoc
& rDoc
, const String
& rTxt
,
747 xub_StrLen nSttPos
, xub_StrLen nEndPos
,
750 String
sURL( URIHelper::FindFirstURLInText( rTxt
, nSttPos
, nEndPos
,
751 GetCharClass( eLang
) ));
752 BOOL bRet
= 0 != sURL
.Len();
753 if( bRet
) // also Attribut setzen:
754 rDoc
.SetINetAttr( nSttPos
, nEndPos
, sURL
);
759 BOOL
SvxAutoCorrect::FnChgWeightUnderl( SvxAutoCorrDoc
& rDoc
, const String
& rTxt
,
760 xub_StrLen
, xub_StrLen nEndPos
,
764 // Am Anfang: _ oder * hinter Space mit nachfolgenden !Space
765 // Am Ende: _ oder * vor Space (Worttrenner?)
767 sal_Unicode c
, cInsChar
= rTxt
.GetChar( nEndPos
); // unterstreichen oder fett
768 if( ++nEndPos
!= rTxt
.Len() &&
769 !IsWordDelim( rTxt
.GetChar( nEndPos
) ) )
774 BOOL bAlphaNum
= FALSE
;
775 xub_StrLen nPos
= nEndPos
, nFndPos
= STRING_NOTFOUND
;
776 CharClass
& rCC
= GetCharClass( eLang
);
780 switch( c
= rTxt
.GetChar( --nPos
) )
786 if( bAlphaNum
&& nPos
+1 < nEndPos
&& ( !nPos
||
787 IsWordDelim( rTxt
.GetChar( nPos
-1 ))) &&
788 !IsWordDelim( rTxt
.GetChar( nPos
+1 )))
791 // Bedingung ist nicht erfuellt, also abbrechen
792 nFndPos
= STRING_NOTFOUND
;
798 bAlphaNum
= rCC
.isLetterNumeric( rTxt
, nPos
);
802 if( STRING_NOTFOUND
!= nFndPos
)
804 // ueber den gefundenen Bereich das Attribut aufspannen und
805 // das gefunde und am Ende stehende Zeichen loeschen
806 if( '*' == cInsChar
) // Fett
808 SvxWeightItem
aSvxWeightItem( WEIGHT_BOLD
, SID_ATTR_CHAR_WEIGHT
);
809 rDoc
.SetAttr( nFndPos
+ 1, nEndPos
,
810 SID_ATTR_CHAR_WEIGHT
,
813 else // unterstrichen
815 SvxUnderlineItem
aSvxUnderlineItem( UNDERLINE_SINGLE
, SID_ATTR_CHAR_UNDERLINE
);
816 rDoc
.SetAttr( nFndPos
+ 1, nEndPos
,
817 SID_ATTR_CHAR_UNDERLINE
,
820 rDoc
.Delete( nEndPos
, nEndPos
+ 1 );
821 rDoc
.Delete( nFndPos
, nFndPos
+ 1 );
824 return STRING_NOTFOUND
!= nFndPos
;
828 BOOL
SvxAutoCorrect::FnCptlSttSntnc( SvxAutoCorrDoc
& rDoc
,
829 const String
& rTxt
, BOOL bNormalPos
,
830 xub_StrLen nSttPos
, xub_StrLen nEndPos
,
833 // Grossbuchstabe am Satz-Anfang ??
834 if( !rTxt
.Len() || nEndPos
<= nSttPos
)
837 CharClass
& rCC
= GetCharClass( eLang
);
838 String
aText( rTxt
);
839 const sal_Unicode
*pStart
= aText
.GetBuffer(),
840 *pStr
= pStart
+ nEndPos
,
844 BOOL bAtStart
= FALSE
, bPrevPara
= FALSE
;
848 aText
, sal::static_int_cast
< xub_StrLen
>( pStr
- pStart
) ) )
857 sal::static_int_cast
< xub_StrLen
>( pStr
- pStart
) ) )
859 if( lcl_IsInAsciiArr( sImplWordChars
, *pStr
) &&
860 pWordStt
- 1 == pStr
&&
861 // --> FME 2005-02-14 #i38971#
862 // l'intallazione at beginning of paragraph. Replaced < by <=
863 (long)(pStart
+ 1) <= (long)pStr
&&
867 sal::static_int_cast
< xub_StrLen
>( pStr
-1 - pStart
) ) )
872 } while( 0 == ( bAtStart
= (pStart
== pStr
)) );
877 aText
, sal::static_int_cast
< xub_StrLen
>( pStr
- pStart
) ) ||
879 rCC
.getCharacterType(
881 sal::static_int_cast
< xub_StrLen
>( pWordStt
- pStart
) ) ) ||
882 0x1 == *pWordStt
|| 0x2 == *pWordStt
)
883 return FALSE
; // kein zu ersetzendes Zeichen, oder schon ok
885 // JP 27.10.97: wenn das Wort weniger als 3 Zeichen hat und der Trenner
886 // ein "Num"-Trenner ist, dann nicht ersetzen!
887 // Damit wird ein "a.", "a)", "a-a" nicht ersetzt!
888 if( *pDelim
&& 2 >= pDelim
- pWordStt
&&
889 lcl_IsInAsciiArr( ".-)>", *pDelim
) )
892 if( !bAtStart
) // noch kein Absatz Anfang ?
894 if ( IsWordDelim( *pStr
) )
896 while( 0 == ( bAtStart
= (pStart
== pStr
--) ) && IsWordDelim( *pStr
))
899 // Asian full stop, full width full stop, full width exclamation mark
900 // and full width question marks are treated as word delimiters
901 else if ( 0x3002 != *pStr
&& 0xFF0E != *pStr
&& 0xFF01 != *pStr
&&
903 return FALSE
; // kein gueltiger Trenner -> keine Ersetzung
906 if( bAtStart
) // am Absatz Anfang ?
908 // Ueberpruefe den vorherigen Absatz, wenn es diesen gibt.
909 // Wenn ja, dann pruefe auf SatzTrenner am Ende.
910 const String
* pPrevPara
= rDoc
.GetPrevPara( bNormalPos
);
913 // gueltiger Trenner -> Ersetze
914 String
sChar( *pWordStt
);
915 rCC
.toUpper( sChar
);
916 return sChar
!= *pWordStt
&&
917 rDoc
.Replace( xub_StrLen( pWordStt
- pStart
), sChar
);
923 pStart
= aText
.GetBuffer();
924 pStr
= pStart
+ aText
.Len();
926 do { // alle Blanks ueberlesen
928 if( !IsWordDelim( *pStr
))
930 } while( 0 == ( bAtStart
= (pStart
== pStr
)) );
933 return FALSE
; // kein gueltiger Trenner -> keine Ersetzung
936 // bis hierhier wurde [ \t]+[A-Z0-9]+ gefunden. Test jetzt auf den
937 // Satztrenner. Es koennen alle 3 vorkommen, aber nicht mehrfach !!
938 const sal_Unicode
* pExceptStt
= 0;
946 // Western and Asian full stop
951 if( nFlag
& C_FULL_STOP
)
952 return FALSE
; // kein gueltiger Trenner -> keine Ersetzung
953 nFlag
|= C_FULL_STOP
;
960 if( nFlag
& C_EXCLAMATION_MARK
)
961 return FALSE
; // kein gueltiger Trenner -> keine Ersetzung
962 nFlag
|= C_EXCLAMATION_MARK
;
968 if( nFlag
& C_QUESTION_MARK
)
969 return FALSE
; // kein gueltiger Trenner -> keine Ersetzung
970 nFlag
|= C_QUESTION_MARK
;
975 return FALSE
; // kein gueltiger Trenner -> keine Ersetzung
981 if( bWeiter
&& pStr
-- == pStart
)
983 // !!! wenn am Anfang, dann nie ersetzen.
985 return FALSE
; // kein gueltiger Trenner -> keine Ersetzung
987 // break; // Schleife beenden
990 if( C_FULL_STOP
!= nFlag
)
994 if( 2 > ( pStr
- pStart
) )
997 if( !rCC
.isLetterNumeric(
998 aText
, sal::static_int_cast
< xub_StrLen
>( pStr
-- - pStart
) ) )
1000 BOOL bValid
= FALSE
, bAlphaFnd
= FALSE
;
1001 const sal_Unicode
* pTmpStr
= pStr
;
1006 sal::static_int_cast
< xub_StrLen
>( pTmpStr
- pStart
) ) )
1011 else if( rCC
.isLetter(
1013 sal::static_int_cast
< xub_StrLen
>(
1014 pTmpStr
- pStart
) ) )
1024 else if( bAlphaFnd
|| IsWordDelim( *pTmpStr
) )
1027 if( pTmpStr
== pStart
)
1034 return FALSE
; // kein gueltiger Trenner -> keine Ersetzung
1037 BOOL bNumericOnly
= '0' <= *(pStr
+1) && *(pStr
+1) <= '9';
1039 // suche den Anfang vom Wort
1040 while( !IsWordDelim( *pStr
))
1044 aText
, sal::static_int_cast
< xub_StrLen
>( pStr
- pStart
) ) )
1045 bNumericOnly
= FALSE
;
1047 if( pStart
== pStr
)
1053 if( bNumericOnly
) // besteht nur aus Zahlen, dann nicht
1056 if( IsWordDelim( *pStr
))
1061 // ueberpruefe anhand der Exceptionliste
1065 pStr
, sal::static_int_cast
< xub_StrLen
>( pExceptStt
- pStr
+ 1 ) );
1066 if( FindInCplSttExceptList(eLang
, sWord
) )
1069 // loesche alle nicht alpanum. Zeichen am Wortanfang/-ende und
1070 // teste dann noch mal ( erkennt: "(min.", "/min.", usw.)
1071 String
sTmp( sWord
);
1072 while( sTmp
.Len() &&
1073 !rCC
.isLetterNumeric( sTmp
, 0 ) )
1076 // alle hinteren nicht alphanumerische Zeichen bis auf das
1078 xub_StrLen nLen
= sTmp
.Len();
1079 while( nLen
&& !rCC
.isLetterNumeric( sTmp
, nLen
-1 ) )
1081 if( nLen
+ 1 < sTmp
.Len() )
1082 sTmp
.Erase( nLen
+ 1 );
1084 if( sTmp
.Len() && sTmp
.Len() != sWord
.Len() &&
1085 FindInCplSttExceptList(eLang
, sTmp
))
1088 if(FindInCplSttExceptList(eLang
, sWord
, TRUE
))
1092 // Ok, dann ersetze mal
1093 sal_Unicode cSave
= *pWordStt
;
1094 nSttPos
= sal::static_int_cast
< xub_StrLen
>( pWordStt
- rTxt
.GetBuffer() );
1095 String
sChar( cSave
);
1096 rCC
.toUpper( sChar
);
1097 BOOL bRet
= sChar
.GetChar(0) != cSave
&& rDoc
.Replace( nSttPos
, sChar
);
1099 // das Wort will vielleicht jemand haben
1100 if( bRet
&& SaveWordCplSttLst
& nFlags
)
1101 rDoc
.SaveCpltSttWord( CptlSttSntnc
, nSttPos
, sWord
, cSave
);
1106 bool SvxAutoCorrect::FnCorrectCapsLock( SvxAutoCorrDoc
& rDoc
, const String
& rTxt
,
1107 xub_StrLen nSttPos
, xub_StrLen nEndPos
,
1108 LanguageType eLang
)
1110 if (nEndPos
- nSttPos
< 2)
1111 // string must be at least 2-character long.
1114 CharClass
& rCC
= GetCharClass( eLang
);
1116 // Check the first 2 letters.
1117 if ( !IsLowerLetter(rCC
.getCharacterType(rTxt
, nSttPos
)) )
1120 if ( !IsUpperLetter(rCC
.getCharacterType(rTxt
, nSttPos
+1)) )
1124 aConverted
.Append( rCC
.upper(rTxt
.GetChar(nSttPos
)) );
1125 aConverted
.Append( rCC
.lower(rTxt
.GetChar(nSttPos
+1)) );
1127 for (xub_StrLen i
= nSttPos
+2; i
< nEndPos
; ++i
)
1129 if ( IsLowerLetter(rCC
.getCharacterType(rTxt
, i
)) )
1130 // A lowercase letter disqualifies the whole text.
1133 if ( IsUpperLetter(rCC
.getCharacterType(rTxt
, i
)) )
1134 // Another uppercase letter. Convert it.
1135 aConverted
.Append( rCC
.lower(rTxt
.GetChar(i
)) );
1137 // This is not an alphabetic letter. Leave it as-is.
1138 aConverted
.Append(rTxt
.GetChar(i
));
1141 // Replace the word.
1142 rDoc
.Delete(nSttPos
, nEndPos
);
1143 rDoc
.Insert(nSttPos
, aConverted
);
1148 //The method below is renamed from _GetQuote to GetQuote by BerryJia for Bug95846 Time:2002-8-13 15:50
1149 sal_Unicode
SvxAutoCorrect::GetQuote( sal_Unicode cInsChar
, BOOL bSttQuote
,
1150 LanguageType eLang
) const
1152 sal_Unicode cRet
= bSttQuote
? ( '\"' == cInsChar
1153 ? GetStartDoubleQuote()
1154 : GetStartSingleQuote() )
1155 : ( '\"' == cInsChar
1156 ? GetEndDoubleQuote()
1157 : GetEndSingleQuote() );
1160 // dann ueber die Language das richtige Zeichen heraussuchen
1161 if( LANGUAGE_NONE
== eLang
)
1165 LocaleDataWrapper
& rLcl
= GetLocaleDataWrapper( eLang
);
1166 String
sRet( bSttQuote
1167 ? ( '\"' == cInsChar
1168 ? rLcl
.getDoubleQuotationMarkStart()
1169 : rLcl
.getQuotationMarkStart() )
1170 : ( '\"' == cInsChar
1171 ? rLcl
.getDoubleQuotationMarkEnd()
1172 : rLcl
.getQuotationMarkEnd() ));
1173 cRet
= sRet
.Len() ? sRet
.GetChar( 0 ) : cInsChar
;
1179 void SvxAutoCorrect::InsertQuote( SvxAutoCorrDoc
& rDoc
, xub_StrLen nInsPos
,
1180 sal_Unicode cInsChar
, BOOL bSttQuote
,
1183 LanguageType eLang
= rDoc
.GetLanguage( nInsPos
, FALSE
);
1184 sal_Unicode cRet
= GetQuote( cInsChar
, bSttQuote
, eLang
);
1186 //JP 13.02.99: damit beim Undo das "einfuegte" Zeichen wieder erscheint,
1187 // wird es erstmal eingefuegt und dann ueberschrieben
1188 String
sChg( cInsChar
);
1190 rDoc
.Insert( nInsPos
, sChg
);
1192 rDoc
.Replace( nInsPos
, sChg
);
1194 //JP 13.08.97: Bug 42477 - bei doppelten Anfuehrungszeichen muss bei
1195 // franzoesischer Sprache an Anfang ein Leerzeichen dahinter
1196 // und am Ende ein Leerzeichen dahinter eingefuegt werden.
1199 if( '\"' == cInsChar
)
1201 if( LANGUAGE_SYSTEM
== eLang
)
1202 eLang
= GetAppLang();
1205 case LANGUAGE_FRENCH
:
1206 case LANGUAGE_FRENCH_BELGIAN
:
1207 case LANGUAGE_FRENCH_CANADIAN
:
1208 case LANGUAGE_FRENCH_SWISS
:
1209 case LANGUAGE_FRENCH_LUXEMBOURG
:
1210 // JP 09.02.99: das zusaetzliche Zeichen immer per Insert einfuegen.
1211 // Es ueberschreibt nichts!
1213 String
s( static_cast< sal_Unicode
>(0xA0) );
1214 // UNICODE code for no break space
1215 if( rDoc
.Insert( bSttQuote
? nInsPos
+1 : nInsPos
, s
))
1225 rDoc
.Replace( nInsPos
, sChg
);
1228 String
SvxAutoCorrect::GetQuote( SvxAutoCorrDoc
& rDoc
, xub_StrLen nInsPos
,
1229 sal_Unicode cInsChar
, BOOL bSttQuote
)
1231 LanguageType eLang
= rDoc
.GetLanguage( nInsPos
, FALSE
);
1232 sal_Unicode cRet
= GetQuote( cInsChar
, bSttQuote
, eLang
);
1234 String
sRet( cRet
);
1235 //JP 13.08.97: Bug 42477 - bei doppelten Anfuehrungszeichen muss bei
1236 // franzoesischer Sprache an Anfang ein Leerzeichen dahinter
1237 // und am Ende ein Leerzeichen dahinter eingefuegt werden.
1238 if( '\"' == cInsChar
)
1240 if( LANGUAGE_SYSTEM
== eLang
)
1241 eLang
= GetAppLang();
1244 case LANGUAGE_FRENCH
:
1245 case LANGUAGE_FRENCH_BELGIAN
:
1246 case LANGUAGE_FRENCH_CANADIAN
:
1247 case LANGUAGE_FRENCH_SWISS
:
1248 case LANGUAGE_FRENCH_LUXEMBOURG
:
1252 sRet
.Insert( ' ', 0 );
1259 ULONG
SvxAutoCorrect::AutoCorrect( SvxAutoCorrDoc
& rDoc
, const String
& rTxt
,
1260 xub_StrLen nInsPos
, sal_Unicode cChar
,
1261 BOOL bInsert
, Window
* pFrameWin
)
1264 do{ // only for middle check loop !!
1267 //JP 10.02.97: doppelte Spaces verhindern
1268 if( nInsPos
&& ' ' == cChar
&&
1269 IsAutoCorrFlag( IngnoreDoubleSpace
) &&
1270 ' ' == rTxt
.GetChar( nInsPos
- 1 ) )
1272 nRet
= IngnoreDoubleSpace
;
1276 BOOL bSingle
= '\'' == cChar
;
1277 BOOL bIsReplaceQuote
=
1278 (IsAutoCorrFlag( ChgQuotes
) && ('\"' == cChar
)) ||
1279 (IsAutoCorrFlag( ChgSglQuotes
) && bSingle
);
1280 if( bIsReplaceQuote
)
1283 BOOL bSttQuote
= !nInsPos
||
1284 IsWordDelim( ( cPrev
= rTxt
.GetChar( nInsPos
-1 ))) ||
1285 // os: #56034# - Warum kein schliessendes Anfuehrungszeichen nach dem Bindestrich?
1286 // strchr( "-([{", cPrev ) ||
1287 lcl_IsInAsciiArr( "([{", cPrev
) ||
1288 ( cEmDash
&& cEmDash
== cPrev
) ||
1289 ( cEnDash
&& cEnDash
== cPrev
);
1291 InsertQuote( rDoc
, nInsPos
, cChar
, bSttQuote
, bInsert
);
1292 nRet
= bSingle
? ChgSglQuotes
: ChgQuotes
;
1297 rDoc
.Insert( nInsPos
, cChar
);
1299 rDoc
.Replace( nInsPos
, cChar
);
1305 xub_StrLen nPos
= nInsPos
- 1;
1307 // Bug 19286: nur direkt hinter dem "Wort" aufsetzen
1308 if( IsWordDelim( rTxt
.GetChar( nPos
)))
1311 // automatisches Fett oder Unterstreichen setzen?
1312 if( '*' == cChar
|| '_' == cChar
)
1314 if( IsAutoCorrFlag( ChgWeightUnderl
) &&
1315 FnChgWeightUnderl( rDoc
, rTxt
, 0, nPos
+1 ) )
1316 nRet
= ChgWeightUnderl
;
1320 while( nPos
&& !IsWordDelim( rTxt
.GetChar( --nPos
)))
1323 // Absatz-Anfang oder ein Blank gefunden, suche nach dem Wort
1325 xub_StrLen nCapLttrPos
= nPos
+1; // auf das 1. Zeichen
1326 if( !nPos
&& !IsWordDelim( rTxt
.GetChar( 0 )))
1327 --nCapLttrPos
; // Absatz Anfang und kein Blank !
1329 LanguageType eLang
= rDoc
.GetLanguage( nCapLttrPos
, FALSE
);
1330 if( LANGUAGE_SYSTEM
== eLang
)
1331 eLang
= MsLangId::getSystemLanguage();
1332 CharClass
& rCC
= GetCharClass( eLang
);
1334 // Bug 19285: Symbolzeichen nicht anfassen
1335 if( lcl_IsSymbolChar( rCC
, rTxt
, nCapLttrPos
, nInsPos
))
1338 if( IsAutoCorrFlag( Autocorrect
) )
1340 const String
* pPara
= 0;
1341 const String
** ppPara
= IsAutoCorrFlag(CptlSttSntnc
) ? &pPara
: 0;
1343 BOOL bChgWord
= rDoc
.ChgAutoCorrWord( nCapLttrPos
, nInsPos
,
1347 // JP 16.06.98: dann versuche mal alle !AlphaNum. Zeichen los zu
1348 // werden und teste dann nochmals
1349 //JP 22.04.99: Bug 63883 - entferne nur die "Klammern Start/-Anfaenge",
1350 // alle anderen Zeichen muessen drin bleiben.
1351 xub_StrLen nCapLttrPos1
= nCapLttrPos
, nInsPos1
= nInsPos
;
1352 while( nCapLttrPos1
< nInsPos
&&
1353 lcl_IsInAsciiArr( sImplSttSkipChars
, rTxt
.GetChar( nCapLttrPos1
) )
1356 while( nCapLttrPos1
< nInsPos1
&& nInsPos1
&&
1357 lcl_IsInAsciiArr( sImplEndSkipChars
, rTxt
.GetChar( nInsPos1
-1 ) )
1361 if( (nCapLttrPos1
!= nCapLttrPos
|| nInsPos1
!= nInsPos
) &&
1362 nCapLttrPos1
< nInsPos1
&&
1363 rDoc
.ChgAutoCorrWord( nCapLttrPos1
, nInsPos1
, *this, ppPara
))
1366 nCapLttrPos
= nCapLttrPos1
;
1375 xub_StrLen nEnd
= nCapLttrPos
;
1376 while( nEnd
< pPara
->Len() &&
1377 !IsWordDelim( pPara
->GetChar( nEnd
)))
1380 // Grossbuchstabe am Satz-Anfang ??
1381 if( IsAutoCorrFlag( CptlSttSntnc
) &&
1382 FnCptlSttSntnc( rDoc
, *pPara
, FALSE
,
1383 nCapLttrPos
, nEnd
, eLang
) )
1384 nRet
|= CptlSttSntnc
;
1386 if( IsAutoCorrFlag( ChgToEnEmDash
) &&
1387 FnChgToEnEmDash( rDoc
, rTxt
, nCapLttrPos
, nEnd
, eLang
) )
1388 nRet
|= ChgToEnEmDash
;
1394 if( ( IsAutoCorrFlag( nRet
= ChgFractionSymbol
) &&
1395 FnChgFractionSymbol( rDoc
, rTxt
, nCapLttrPos
, nInsPos
) ) ||
1396 ( IsAutoCorrFlag( nRet
= ChgOrdinalNumber
) &&
1397 FnChgOrdinalNumber( rDoc
, rTxt
, nCapLttrPos
, nInsPos
, eLang
) ) ||
1398 ( IsAutoCorrFlag( nRet
= AddNonBrkSpace
) &&
1399 FnAddNonBrkSpace( rDoc
, rTxt
, nCapLttrPos
, nInsPos
- 1, eLang
) ) ||
1400 ( IsAutoCorrFlag( nRet
= SetINetAttr
) &&
1401 ( ' ' == cChar
|| '\t' == cChar
|| 0x0a == cChar
|| !cChar
) &&
1402 FnSetINetAttr( rDoc
, rTxt
, nCapLttrPos
, nInsPos
, eLang
) ) )
1406 bool bLockKeyOn
= pFrameWin
&& (pFrameWin
->GetIndicatorState() & INDICATOR_CAPSLOCK
);
1409 if ( bLockKeyOn
&& IsAutoCorrFlag( CorrectCapsLock
) &&
1410 FnCorrectCapsLock( rDoc
, rTxt
, nCapLttrPos
, nInsPos
, eLang
) )
1412 // Correct accidental use of cAPS LOCK key (do this only when
1413 // the caps or shift lock key is pressed). Turn off the caps
1415 nRet
|= CorrectCapsLock
;
1416 pFrameWin
->SimulateKeyPress( KEY_CAPSLOCK
);
1419 // Grossbuchstabe am Satz-Anfang ??
1420 if( IsAutoCorrFlag( CptlSttSntnc
) &&
1421 FnCptlSttSntnc( rDoc
, rTxt
, TRUE
, nCapLttrPos
, nInsPos
, eLang
) )
1422 nRet
|= CptlSttSntnc
;
1424 // Zwei Grossbuchstaben am Wort-Anfang ??
1425 if( IsAutoCorrFlag( CptlSttWrd
) &&
1426 FnCptlSttWrd( rDoc
, rTxt
, nCapLttrPos
, nInsPos
, eLang
) )
1429 if( IsAutoCorrFlag( ChgToEnEmDash
) &&
1430 FnChgToEnEmDash( rDoc
, rTxt
, nCapLttrPos
, nInsPos
, eLang
) )
1431 nRet
|= ChgToEnEmDash
;
1436 SfxViewFrame
* pVFrame
;
1437 if( nRet
&& 0 != (pVFrame
= SfxViewFrame::Current()) &&
1438 pVFrame
->GetFrame() )
1441 if( nRet
& ( Autocorrect
|CptlSttSntnc
|CptlSttWrd
|ChgToEnEmDash
) )
1444 if( nRet
& ChgToEnEmDash
)
1446 if( nRet
& Autocorrect
)
1448 if( nRet
& CptlSttSntnc
)
1450 if( nRet
& CptlSttWrd
)
1455 if( nRet
& ChgQuotes
) nHelpId
= 16;
1456 else if( nRet
& ChgSglQuotes
) nHelpId
= 17;
1457 else if( nRet
& SetINetAttr
) nHelpId
= 18;
1458 else if( nRet
& IngnoreDoubleSpace
) nHelpId
= 19;
1459 else if( nRet
& ChgWeightUnderl
) nHelpId
= 20;
1460 else if( nRet
& ChgFractionSymbol
) nHelpId
= 21;
1461 else if( nRet
& ChgOrdinalNumber
) nHelpId
= 22;
1464 DBG_ASSERT( nHelpId
&& nHelpId
< (HID_AUTOCORR_HELP_END
-
1465 HID_AUTOCORR_HELP_START
+ 1),
1466 "wrong HelpId Range" );
1470 nHelpId
+= HID_AUTOCORR_HELP_START
- 1;
1471 SfxHelp::OpenHelpAgent( pVFrame
->GetFrame(), nHelpId
);
1479 SvxAutoCorrectLanguageLists
& SvxAutoCorrect::_GetLanguageList(
1480 LanguageType eLang
)
1482 if( !pLangTable
->IsKeyValid( ULONG( eLang
)))
1483 CreateLanguageFile( eLang
, TRUE
);
1484 return *pLangTable
->Seek( ULONG( eLang
) );
1487 void SvxAutoCorrect::SaveCplSttExceptList( LanguageType eLang
)
1489 if( pLangTable
->IsKeyValid( ULONG( eLang
)))
1491 SvxAutoCorrectLanguageListsPtr pLists
= pLangTable
->Seek(ULONG(eLang
));
1493 pLists
->SaveCplSttExceptList();
1498 DBG_ERROR("speichern einer leeren Liste?");
1503 void SvxAutoCorrect::SaveWrdSttExceptList(LanguageType eLang
)
1505 if(pLangTable
->IsKeyValid(ULONG(eLang
)))
1507 SvxAutoCorrectLanguageListsPtr pLists
= pLangTable
->Seek(ULONG(eLang
));
1509 pLists
->SaveWrdSttExceptList();
1514 DBG_ERROR("speichern einer leeren Liste?");
1520 // fuegt ein einzelnes Wort hinzu. Die Liste wird sofort
1521 // in die Datei geschrieben!
1522 BOOL
SvxAutoCorrect::AddCplSttException( const String
& rNew
,
1523 LanguageType eLang
)
1525 SvxAutoCorrectLanguageListsPtr pLists
= 0;
1526 //entweder die richtige Sprache ist vorhanden oder es kommt in die allg. Liste
1527 if( pLangTable
->IsKeyValid(ULONG(eLang
)))
1528 pLists
= pLangTable
->Seek(ULONG(eLang
));
1529 else if(pLangTable
->IsKeyValid(ULONG(LANGUAGE_DONTKNOW
))||
1530 CreateLanguageFile(LANGUAGE_DONTKNOW
, TRUE
))
1532 pLists
= pLangTable
->Seek(ULONG(LANGUAGE_DONTKNOW
));
1534 DBG_ASSERT(pLists
, "keine Autokorrekturdatei");
1535 return pLists
->AddToCplSttExceptList(rNew
);
1539 // fuegt ein einzelnes Wort hinzu. Die Liste wird sofort
1540 // in die Datei geschrieben!
1541 BOOL
SvxAutoCorrect::AddWrtSttException( const String
& rNew
,
1542 LanguageType eLang
)
1544 SvxAutoCorrectLanguageListsPtr pLists
= 0;
1545 //entweder die richtige Sprache ist vorhanden oder es kommt in die allg. Liste
1546 if(pLangTable
->IsKeyValid(ULONG(eLang
)))
1547 pLists
= pLangTable
->Seek(ULONG(eLang
));
1548 else if(pLangTable
->IsKeyValid(ULONG(LANGUAGE_DONTKNOW
))||
1549 CreateLanguageFile(LANGUAGE_DONTKNOW
, TRUE
))
1550 pLists
= pLangTable
->Seek(ULONG(LANGUAGE_DONTKNOW
));
1551 DBG_ASSERT(pLists
, "keine Autokorrekturdatei");
1552 return pLists
->AddToWrdSttExceptList(rNew
);
1558 void SvxAutoCorrect::SetUserAutoCorrFileName( const String
& rNew
)
1560 if( sUserAutoCorrFile
!= rNew
)
1562 sUserAutoCorrFile
= rNew
;
1564 // sind die Listen gesetzt sind, so muessen sie jetzt geloescht
1566 lcl_ClearTable(*pLangTable
);
1567 nFlags
&= ~(CplSttLstLoad
| WrdSttLstLoad
| ChgWordLstLoad
);
1571 void SvxAutoCorrect::SetShareAutoCorrFileName( const String
& rNew
)
1573 if( sShareAutoCorrFile
!= rNew
)
1575 sShareAutoCorrFile
= rNew
;
1577 // sind die Listen gesetzt sind, so muessen sie jetzt geloescht
1579 lcl_ClearTable(*pLangTable
);
1580 nFlags
&= ~(CplSttLstLoad
| WrdSttLstLoad
| ChgWordLstLoad
);
1585 BOOL
SvxAutoCorrect::GetPrevAutoCorrWord( SvxAutoCorrDoc
& rDoc
,
1586 const String
& rTxt
, xub_StrLen nPos
,
1587 String
& rWord
) const
1592 xub_StrLen nEnde
= nPos
;
1594 // dahinter muss ein Blank oder Tab folgen!
1595 if( ( nPos
< rTxt
.Len() &&
1596 !IsWordDelim( rTxt
.GetChar( nPos
))) ||
1597 IsWordDelim( rTxt
.GetChar( --nPos
)))
1600 while( nPos
&& !IsWordDelim( rTxt
.GetChar( --nPos
)))
1603 // Absatz-Anfang oder ein Blank gefunden, suche nach dem Wort
1605 xub_StrLen nCapLttrPos
= nPos
+1; // auf das 1. Zeichen
1606 if( !nPos
&& !IsWordDelim( rTxt
.GetChar( 0 )))
1607 --nCapLttrPos
; // Absatz Anfang und kein Blank !
1609 while( lcl_IsInAsciiArr( sImplSttSkipChars
, rTxt
.GetChar( nCapLttrPos
)) )
1610 if( ++nCapLttrPos
>= nEnde
)
1613 // Bug 19285: Symbolzeichen nicht anfassen
1614 // Interresant erst ab 3 Zeichen
1615 if( 3 > nEnde
- nCapLttrPos
)
1618 LanguageType eLang
= rDoc
.GetLanguage( nCapLttrPos
, FALSE
);
1619 if( LANGUAGE_SYSTEM
== eLang
)
1620 eLang
= MsLangId::getSystemLanguage();
1622 SvxAutoCorrect
* pThis
= (SvxAutoCorrect
*)this;
1623 CharClass
& rCC
= pThis
->GetCharClass( eLang
);
1625 if( lcl_IsSymbolChar( rCC
, rTxt
, nCapLttrPos
, nEnde
))
1628 rWord
= rTxt
.Copy( nCapLttrPos
, nEnde
- nCapLttrPos
);
1632 BOOL
SvxAutoCorrect::CreateLanguageFile( LanguageType eLang
, BOOL bNewFile
)
1634 DBG_ASSERT(!pLangTable
->IsKeyValid(ULONG(eLang
)), "Sprache ist bereits vorhanden");
1636 String
sUserDirFile( GetAutoCorrFileName( eLang
, TRUE
, FALSE
)),
1637 sShareDirFile( sUserDirFile
);
1638 SvxAutoCorrectLanguageListsPtr pLists
= 0;
1640 Time
nMinTime( 0, 2 ), nAktTime
, nLastCheckTime
;
1642 if( TABLE_ENTRY_NOTFOUND
!=
1643 pLastFileTable
->SearchKey( ULONG( eLang
), &nFndPos
) &&
1644 ( nLastCheckTime
.SetTime( pLastFileTable
->GetObject( nFndPos
)),
1645 nLastCheckTime
< nAktTime
) &&
1646 ( nAktTime
- nLastCheckTime
) < nMinTime
)
1648 // no need to test the file, because the last check is not older then
1652 sShareDirFile
= sUserDirFile
;
1653 pLists
= new SvxAutoCorrectLanguageLists( *this, sShareDirFile
,
1654 sUserDirFile
, eLang
);
1655 pLangTable
->Insert( ULONG(eLang
), pLists
);
1656 pLastFileTable
->Remove( ULONG( eLang
) );
1659 else if( ( FStatHelper::IsDocument( sUserDirFile
) ||
1660 FStatHelper::IsDocument( sShareDirFile
=
1661 GetAutoCorrFileName( eLang
, FALSE
, FALSE
) ) ) ||
1662 ( sShareDirFile
= sUserDirFile
, bNewFile
))
1664 pLists
= new SvxAutoCorrectLanguageLists( *this, sShareDirFile
,
1665 sUserDirFile
, eLang
);
1666 pLangTable
->Insert( ULONG(eLang
), pLists
);
1667 pLastFileTable
->Remove( ULONG( eLang
) );
1669 else if( !bNewFile
)
1671 if( !pLastFileTable
->Insert( ULONG( eLang
), nAktTime
.GetTime() ))
1672 pLastFileTable
->Replace( ULONG( eLang
), nAktTime
.GetTime() );
1677 BOOL
SvxAutoCorrect::PutText( const String
& rShort
, const String
& rLong
,
1678 LanguageType eLang
)
1681 if( pLangTable
->IsKeyValid( ULONG(eLang
)) || CreateLanguageFile(eLang
) )
1682 bRet
= pLangTable
->Seek( ULONG(eLang
) )->PutText(rShort
, rLong
);
1687 // - loesche einen Eintrag
1688 BOOL
SvxAutoCorrect::DeleteText( const String
& rShort
, LanguageType eLang
)
1691 if( pLangTable
->IsKeyValid( ULONG( eLang
)) )
1692 bRet
= pLangTable
->Seek( ULONG( eLang
))->DeleteText( rShort
);
1697 // - return den Ersetzungstext (nur fuer SWG-Format, alle anderen
1698 // koennen aus der Wortliste herausgeholt werden!)
1699 BOOL
SvxAutoCorrect::GetLongText( const com::sun::star::uno::Reference
< com::sun::star::embed::XStorage
>&, const String
&, const String
& , String
& )
1704 // - Text mit Attributierung (kann nur der SWG - SWG-Format!)
1705 BOOL
SvxAutoCorrect::PutText( const com::sun::star::uno::Reference
< com::sun::star::embed::XStorage
>&, const String
&, const String
&, SfxObjectShell
&,
1711 void EncryptBlockName_Imp( String
& rName
)
1713 xub_StrLen nLen
, nPos
= 1;
1714 rName
.Insert( '#', 0 );
1715 sal_Unicode
* pName
= rName
.GetBufferAccess();
1716 for ( nLen
= rName
.Len(), ++pName
; nPos
< nLen
; ++nPos
, ++pName
)
1718 if( lcl_IsInAsciiArr( "!/:.\\", *pName
))
1723 /* This code is copied from SwXMLTextBlocks::GeneratePackageName */
1724 void GeneratePackageName ( const String
& rShort
, String
& rPackageName
)
1726 rPackageName
= rShort
;
1727 xub_StrLen nPos
= 0;
1728 sal_Unicode pDelims
[] = { '!', '/', ':', '.', '\\', 0 };
1729 ByteString
sByte ( rPackageName
, RTL_TEXTENCODING_UTF7
);
1730 rPackageName
= String (sByte
, RTL_TEXTENCODING_ASCII_US
);
1731 while( STRING_NOTFOUND
!= ( nPos
= rPackageName
.SearchChar( pDelims
, nPos
)))
1733 rPackageName
.SetChar( nPos
, '_' );
1738 void DecryptBlockName_Imp( String
& rName
)
1740 if( '#' == rName
.GetChar( 0 ) )
1742 rName
.Erase( 0, 1 );
1743 sal_Unicode
* pName
= rName
.GetBufferAccess();
1744 xub_StrLen nLen
, nPos
;
1745 for ( nLen
= rName
.Len(), nPos
= 0; nPos
< nLen
; ++nPos
, ++pName
)
1748 case 0x01: *pName
= '!'; break;
1749 case 0x0A: *pName
= ':'; break;
1750 case 0x0C: *pName
= '\\'; break;
1751 case 0x0E: *pName
= '.'; break;
1752 case 0x0F: *pName
= '/'; break;
1758 /* -----------------18.11.98 16:00-------------------
1760 * --------------------------------------------------*/
1761 const SvxAutocorrWord
* lcl_SearchWordsInList(
1762 SvxAutoCorrectLanguageListsPtr pList
, const String
& rTxt
,
1763 xub_StrLen
& rStt
, xub_StrLen nEndPos
, SvxAutoCorrDoc
& )
1765 const SvxAutocorrWordList
* pAutoCorrWordList
= pList
->GetAutocorrWordList();
1766 TransliterationWrapper
& rCmp
= GetIgnoreTranslWrapper();
1767 for( xub_StrLen nPos
= 0; nPos
< pAutoCorrWordList
->Count(); ++nPos
)
1769 const SvxAutocorrWord
* pFnd
= (*pAutoCorrWordList
)[ nPos
];
1770 const String
& rChk
= pFnd
->GetShort();
1771 if( nEndPos
>= rChk
.Len() )
1773 xub_StrLen nCalcStt
= nEndPos
- rChk
.Len();
1774 if( ( !nCalcStt
|| nCalcStt
== rStt
||
1775 ( nCalcStt
< rStt
&&
1776 IsWordDelim( rTxt
.GetChar(nCalcStt
- 1 ) ))) )
1778 String
sWord( rTxt
.GetBuffer() + nCalcStt
, rChk
.Len() );
1779 if( rCmp
.isEqual( rChk
, sWord
))
1791 // suche das oder die Worte in der ErsetzungsTabelle
1792 const SvxAutocorrWord
* SvxAutoCorrect::SearchWordsInList(
1793 const String
& rTxt
, xub_StrLen
& rStt
, xub_StrLen nEndPos
,
1794 SvxAutoCorrDoc
& rDoc
, LanguageType
& rLang
)
1796 LanguageType eLang
= rLang
;
1797 const SvxAutocorrWord
* pRet
= 0;
1798 if( LANGUAGE_SYSTEM
== eLang
)
1799 eLang
= MsLangId::getSystemLanguage();
1801 // zuerst nach eLang suchen, dann nach der Obersprache
1802 // US-Englisch -> Englisch und zuletzt in LANGUAGE_DONTKNOW
1804 if( pLangTable
->IsKeyValid( ULONG( eLang
) ) ||
1805 CreateLanguageFile( eLang
, FALSE
))
1807 //die Sprache ist vorhanden - also her damit
1808 SvxAutoCorrectLanguageListsPtr pList
= pLangTable
->Seek(ULONG(eLang
));
1809 pRet
= lcl_SearchWordsInList( pList
, rTxt
, rStt
, nEndPos
, rDoc
);
1817 // wenn es hier noch nicht gefunden werden konnte, dann weitersuchen
1818 ULONG nTmpKey1
= eLang
& 0x7ff, // die Hauptsprache in vielen Faellen u.B. DE
1819 nTmpKey2
= eLang
& 0x3ff, // sonst z.B. EN
1822 if( ((nTmp
= nTmpKey1
) != (ULONG
)eLang
&&
1823 ( pLangTable
->IsKeyValid( nTmpKey1
) ||
1824 CreateLanguageFile( LanguageType( nTmpKey1
), FALSE
) )) ||
1825 (( nTmp
= nTmpKey2
) != (ULONG
)eLang
&&
1826 ( pLangTable
->IsKeyValid( nTmpKey2
) ||
1827 CreateLanguageFile( LanguageType( nTmpKey2
), FALSE
) )) )
1829 //die Sprache ist vorhanden - also her damit
1830 SvxAutoCorrectLanguageListsPtr pList
= pLangTable
->Seek( nTmp
);
1831 pRet
= lcl_SearchWordsInList( pList
, rTxt
, rStt
, nEndPos
, rDoc
);
1834 rLang
= LanguageType( nTmp
);
1838 if( pLangTable
->IsKeyValid( ULONG( LANGUAGE_DONTKNOW
) ) ||
1839 CreateLanguageFile( LANGUAGE_DONTKNOW
, FALSE
) )
1841 //die Sprache ist vorhanden - also her damit
1842 SvxAutoCorrectLanguageListsPtr pList
= pLangTable
->Seek(ULONG(LANGUAGE_DONTKNOW
));
1843 pRet
= lcl_SearchWordsInList( pList
, rTxt
, rStt
, nEndPos
, rDoc
);
1846 rLang
= LANGUAGE_DONTKNOW
;
1852 /* -----------------18.11.98 13:46-------------------
1854 * --------------------------------------------------*/
1855 BOOL
SvxAutoCorrect::FindInWrdSttExceptList( LanguageType eLang
,
1856 const String
& sWord
)
1858 //zuerst nach eLang suchen, dann nach der Obersprace US-Englisch -> Englisch
1859 //und zuletzt in LANGUAGE_DONTKNOW
1860 ULONG nTmpKey1
= eLang
& 0x7ff; // die Hauptsprache in vielen Faellen u.B. DE
1861 ULONG nTmpKey2
= eLang
& 0x3ff; // sonst z.B. EN
1862 String
sTemp(sWord
);
1863 if( pLangTable
->IsKeyValid( ULONG( eLang
)) ||
1864 CreateLanguageFile( eLang
, FALSE
) )
1866 //die Sprache ist vorhanden - also her damit
1867 SvxAutoCorrectLanguageListsPtr pList
= pLangTable
->Seek(ULONG(eLang
));
1868 String
_sTemp(sWord
);
1869 if(pList
->GetWrdSttExceptList()->Seek_Entry(&_sTemp
))
1873 // wenn es hier noch nicht gefunden werden konnte, dann weitersuchen
1875 if( ((nTmp
= nTmpKey1
) != (ULONG
)eLang
&&
1876 ( pLangTable
->IsKeyValid( nTmpKey1
) ||
1877 CreateLanguageFile( LanguageType( nTmpKey1
), FALSE
) )) ||
1878 (( nTmp
= nTmpKey2
) != (ULONG
)eLang
&&
1879 ( pLangTable
->IsKeyValid( nTmpKey2
) ||
1880 CreateLanguageFile( LanguageType( nTmpKey2
), FALSE
) )) )
1882 //die Sprache ist vorhanden - also her damit
1883 SvxAutoCorrectLanguageListsPtr pList
= pLangTable
->Seek(nTmp
);
1884 if(pList
->GetWrdSttExceptList()->Seek_Entry(&sTemp
))
1887 if(pLangTable
->IsKeyValid(ULONG(LANGUAGE_DONTKNOW
))|| CreateLanguageFile(LANGUAGE_DONTKNOW
, FALSE
))
1889 //die Sprache ist vorhanden - also her damit
1890 SvxAutoCorrectLanguageListsPtr pList
= pLangTable
->Seek(ULONG(LANGUAGE_DONTKNOW
));
1891 if(pList
->GetWrdSttExceptList()->Seek_Entry(&sTemp
))
1896 /* -----------------18.11.98 14:28-------------------
1898 * --------------------------------------------------*/
1899 BOOL
lcl_FindAbbreviation( const SvStringsISortDtor
* pList
, const String
& sWord
)
1903 pList
->Seek_Entry( &sAbk
, &nPos
);
1904 if( nPos
< pList
->Count() )
1906 String
sLowerWord( sWord
); sLowerWord
.ToLowerAscii();
1908 for( USHORT n
= nPos
;
1909 n
< pList
->Count() &&
1910 '~' == ( pAbk
= (*pList
)[ n
])->GetChar( 0 );
1913 // ~ und ~. sind nicht erlaubt!
1914 if( 2 < pAbk
->Len() && pAbk
->Len() - 1 <= sWord
.Len() )
1916 String
sLowerAbk( *pAbk
); sLowerAbk
.ToLowerAscii();
1917 for( xub_StrLen i
= sLowerAbk
.Len(), ii
= sLowerWord
.Len(); i
; )
1919 if( !--i
) // stimmt ueberein
1922 if( sLowerAbk
.GetChar( i
) != sLowerWord
.GetChar( --ii
))
1928 DBG_ASSERT( !(nPos
&& '~' == (*pList
)[ --nPos
]->GetChar( 0 ) ),
1929 "falsch sortierte ExeptionListe?" );
1932 /* -----------------18.11.98 14:49-------------------
1934 * --------------------------------------------------*/
1935 BOOL
SvxAutoCorrect::FindInCplSttExceptList(LanguageType eLang
,
1936 const String
& sWord
, BOOL bAbbreviation
)
1938 //zuerst nach eLang suchen, dann nach der Obersprace US-Englisch -> Englisch
1939 //und zuletzt in LANGUAGE_DONTKNOW
1940 ULONG nTmpKey1
= eLang
& 0x7ff; // die Hauptsprache in vielen Faellen u.B. DE
1941 ULONG nTmpKey2
= eLang
& 0x3ff; // sonst z.B. EN
1942 String
sTemp( sWord
);
1943 if( pLangTable
->IsKeyValid( ULONG( eLang
)) ||
1944 CreateLanguageFile( eLang
, FALSE
))
1946 //die Sprache ist vorhanden - also her damit
1947 SvxAutoCorrectLanguageListsPtr pLists
= pLangTable
->Seek(ULONG(eLang
));
1948 const SvStringsISortDtor
* pList
= pLists
->GetCplSttExceptList();
1949 if(bAbbreviation
? lcl_FindAbbreviation( pList
, sWord
)
1950 : pList
->Seek_Entry( &sTemp
) )
1953 // wenn es hier noch nicht gefunden werden konnte, dann weitersuchen
1956 if( ((nTmp
= nTmpKey1
) != (ULONG
)eLang
&&
1957 ( pLangTable
->IsKeyValid( nTmpKey1
) ||
1958 CreateLanguageFile( LanguageType( nTmpKey1
), FALSE
) )) ||
1959 (( nTmp
= nTmpKey2
) != (ULONG
)eLang
&&
1960 ( pLangTable
->IsKeyValid( nTmpKey2
) ||
1961 CreateLanguageFile( LanguageType( nTmpKey2
), FALSE
) )) )
1963 //die Sprache ist vorhanden - also her damit
1964 SvxAutoCorrectLanguageListsPtr pLists
= pLangTable
->Seek(nTmp
);
1965 const SvStringsISortDtor
* pList
= pLists
->GetCplSttExceptList();
1966 if(bAbbreviation
? lcl_FindAbbreviation( pList
, sWord
)
1967 : pList
->Seek_Entry( &sTemp
) )
1970 if(pLangTable
->IsKeyValid(ULONG(LANGUAGE_DONTKNOW
))|| CreateLanguageFile(LANGUAGE_DONTKNOW
, FALSE
))
1972 //die Sprache ist vorhanden - also her damit
1973 SvxAutoCorrectLanguageListsPtr pLists
= pLangTable
->Seek(LANGUAGE_DONTKNOW
);
1974 const SvStringsISortDtor
* pList
= pLists
->GetCplSttExceptList();
1975 if(bAbbreviation
? lcl_FindAbbreviation( pList
, sWord
)
1976 : pList
->Seek_Entry( &sTemp
) )
1983 /* -----------------20.11.98 11:53-------------------
1985 * --------------------------------------------------*/
1986 String
SvxAutoCorrect::GetAutoCorrFileName( LanguageType eLang
,
1987 BOOL bNewFile
, BOOL bTst
) const
1989 String sRet
, sExt( MsLangId::convertLanguageToIsoString( eLang
) );
1990 sExt
.Insert('_', 0);
1991 sExt
.AppendAscii( ".dat" );
1993 ( sRet
= sUserAutoCorrFile
) += sExt
;
1995 ( sRet
= sShareAutoCorrFile
) += sExt
;
1998 // test first in the user directory - if not exist, then
1999 ( sRet
= sUserAutoCorrFile
) += sExt
;
2000 if( !FStatHelper::IsDocument( sRet
))
2001 ( sRet
= sShareAutoCorrFile
) += sExt
;
2006 /* -----------------18.11.98 11:16-------------------
2008 * --------------------------------------------------*/
2009 SvxAutoCorrectLanguageLists::SvxAutoCorrectLanguageLists(
2010 SvxAutoCorrect
& rParent
,
2011 const String
& rShareAutoCorrectFile
,
2012 const String
& rUserAutoCorrectFile
,
2014 : sShareAutoCorrFile( rShareAutoCorrectFile
),
2015 sUserAutoCorrFile( rUserAutoCorrectFile
),
2017 pCplStt_ExcptLst( 0 ),
2018 pWrdStt_ExcptLst( 0 ),
2019 pAutocorr_List( 0 ),
2020 rAutoCorrect(rParent
),
2025 /* -----------------18.11.98 11:16-------------------
2027 * --------------------------------------------------*/
2028 SvxAutoCorrectLanguageLists::~SvxAutoCorrectLanguageLists()
2030 delete pCplStt_ExcptLst
;
2031 delete pWrdStt_ExcptLst
;
2032 delete pAutocorr_List
;
2035 /* -----------------18.11.98 11:26-------------------
2037 * --------------------------------------------------*/
2038 BOOL
SvxAutoCorrectLanguageLists::IsFileChanged_Imp()
2040 // nur alle 2 Minuten aufs FileSystem zugreifen um den
2041 // Dateistempel zu ueberpruefen
2044 Time
nMinTime( 0, 2 );
2046 if( aLastCheckTime
> nAktTime
|| // ueberlauf ?
2047 ( nAktTime
-= aLastCheckTime
) > nMinTime
) // min Zeit vergangen
2049 Date aTstDate
; Time aTstTime
;
2050 if( FStatHelper::GetModifiedDateTimeOfFile( sShareAutoCorrFile
,
2051 &aTstDate
, &aTstTime
) &&
2052 ( aModifiedDate
!= aTstDate
|| aModifiedTime
!= aTstTime
))
2055 // dann mal schnell alle Listen entfernen!
2056 if( CplSttLstLoad
& nFlags
&& pCplStt_ExcptLst
)
2057 delete pCplStt_ExcptLst
, pCplStt_ExcptLst
= 0;
2058 if( WrdSttLstLoad
& nFlags
&& pWrdStt_ExcptLst
)
2059 delete pWrdStt_ExcptLst
, pWrdStt_ExcptLst
= 0;
2060 if( ChgWordLstLoad
& nFlags
&& pAutocorr_List
)
2061 delete pAutocorr_List
, pAutocorr_List
= 0;
2062 nFlags
&= ~(CplSttLstLoad
| WrdSttLstLoad
| ChgWordLstLoad
);
2064 aLastCheckTime
= Time();
2069 void SvxAutoCorrectLanguageLists::LoadXMLExceptList_Imp(
2070 SvStringsISortDtor
*& rpLst
,
2071 const sal_Char
* pStrmName
,
2072 SotStorageRef
& rStg
)
2075 rpLst
->DeleteAndDestroy( 0, rpLst
->Count() );
2077 rpLst
= new SvStringsISortDtor( 16, 16 );
2080 String
sStrmName( pStrmName
, RTL_TEXTENCODING_MS_1252
);
2081 String
sTmp( sStrmName
);
2083 if( rStg
.Is() && rStg
->IsStream( sStrmName
) )
2085 SvStorageStreamRef xStrm
= rStg
->OpenSotStream( sTmp
,
2086 ( STREAM_READ
| STREAM_SHARE_DENYWRITE
| STREAM_NOCREATE
) );
2087 if( SVSTREAM_OK
!= xStrm
->GetError())
2091 RemoveStream_Imp( sStrmName
);
2095 uno::Reference
< lang::XMultiServiceFactory
> xServiceFactory
=
2096 comphelper::getProcessServiceFactory();
2097 DBG_ASSERT( xServiceFactory
.is(),
2098 "XMLReader::Read: got no service manager" );
2099 if( !xServiceFactory
.is() )
2101 // Throw an exception ?
2104 xml::sax::InputSource aParserInput
;
2105 aParserInput
.sSystemId
= sStrmName
;
2108 xStrm
->SetBufferSize( 8 * 1024 );
2109 aParserInput
.aInputStream
= new utl::OInputStreamWrapper( *xStrm
);
2112 uno::Reference
< XInterface
> xXMLParser
= xServiceFactory
->createInstance(
2113 OUString::createFromAscii("com.sun.star.xml.sax.Parser") );
2114 DBG_ASSERT( xXMLParser
.is(),
2115 "XMLReader::Read: com.sun.star.xml.sax.Parser service missing" );
2116 if( !xXMLParser
.is() )
2118 // Maybe throw an exception?
2123 // uno::Reference< xml::sax::XDocumentHandler > xFilter = new SvXMLExceptionListImport ( *rpLst );
2124 uno::Reference
< xml::sax::XDocumentHandler
> xFilter
= new SvXMLExceptionListImport ( xServiceFactory
, *rpLst
);
2126 // connect parser and filter
2127 uno::Reference
< xml::sax::XParser
> xParser( xXMLParser
, UNO_QUERY
);
2128 xParser
->setDocumentHandler( xFilter
);
2133 xParser
->parseStream( aParserInput
);
2135 catch( xml::sax::SAXParseException
& )
2139 catch( xml::sax::SAXException
& )
2143 catch( io::IOException
& )
2150 // Zeitstempel noch setzen
2151 FStatHelper::GetModifiedDateTimeOfFile( sShareAutoCorrFile
,
2152 &aModifiedDate
, &aModifiedTime
);
2153 aLastCheckTime
= Time();
2157 /* -----------------18.11.98 11:26-------------------
2159 * --------------------------------------------------*/
2160 void SvxAutoCorrectLanguageLists::SaveExceptList_Imp(
2161 const SvStringsISortDtor
& rLst
,
2162 const sal_Char
* pStrmName
,
2163 SotStorageRef
&rStg
,
2168 String
sStrmName( pStrmName
, RTL_TEXTENCODING_MS_1252
);
2171 rStg
->Remove( sStrmName
);
2176 SotStorageStreamRef xStrm
= rStg
->OpenSotStream( sStrmName
,
2177 ( STREAM_READ
| STREAM_WRITE
| STREAM_SHARE_DENYWRITE
) );
2180 xStrm
->SetSize( 0 );
2181 xStrm
->SetBufferSize( 8192 );
2182 String
aPropName( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM("MediaType") ) );
2183 OUString
aMime( RTL_CONSTASCII_USTRINGPARAM("text/xml") );
2186 xStrm
->SetProperty( aPropName
, aAny
);
2189 uno::Reference
< lang::XMultiServiceFactory
> xServiceFactory
=
2190 comphelper::getProcessServiceFactory();
2191 DBG_ASSERT( xServiceFactory
.is(),
2192 "XMLReader::Read: got no service manager" );
2193 if( !xServiceFactory
.is() )
2195 // Throw an exception ?
2198 uno::Reference
< XInterface
> xWriter (xServiceFactory
->createInstance(
2199 OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.sax.Writer"))));
2200 DBG_ASSERT(xWriter
.is(),"com.sun.star.xml.sax.Writer service missing");
2201 uno::Reference
< io::XOutputStream
> xOut
= new utl::OOutputStreamWrapper( *xStrm
);
2202 uno::Reference
<io::XActiveDataSource
> xSrc(xWriter
, uno::UNO_QUERY
);
2203 xSrc
->setOutputStream(xOut
);
2205 uno::Reference
<xml::sax::XDocumentHandler
> xHandler(xWriter
, uno::UNO_QUERY
);
2208 // SvXMLExceptionListExport aExp(rLst, sStrmName, xHandler);
2209 SvXMLExceptionListExport
aExp( xServiceFactory
, rLst
, sStrmName
, xHandler
);
2211 aExp
.exportDoc( XML_BLOCK_LIST
);
2214 if( xStrm
->GetError() == SVSTREAM_OK
)
2220 if( SVSTREAM_OK
!= rStg
->GetError() )
2222 rStg
->Remove( sStrmName
);
2231 /* -----------------18.11.98 11:26-------------------
2233 * --------------------------------------------------*/
2234 SvxAutocorrWordList
* SvxAutoCorrectLanguageLists::LoadAutocorrWordList()
2236 if( pAutocorr_List
)
2237 pAutocorr_List
->DeleteAndDestroy( 0, pAutocorr_List
->Count() );
2239 pAutocorr_List
= new SvxAutocorrWordList( 16, 16 );
2241 SvStringsDtor aRemoveArr
;
2244 uno::Reference
< embed::XStorage
> xStg
= comphelper::OStorageHelper::GetStorageFromURL( sShareAutoCorrFile
, embed::ElementModes::READ
);
2245 String
aXMLWordListName( pXMLImplAutocorr_ListStr
, RTL_TEXTENCODING_MS_1252
);
2246 uno::Reference
< io::XStream
> xStrm
= xStg
->openStreamElement( aXMLWordListName
, embed::ElementModes::READ
);
2247 uno::Reference
< lang::XMultiServiceFactory
> xServiceFactory
= comphelper::getProcessServiceFactory();
2249 xml::sax::InputSource aParserInput
;
2250 aParserInput
.sSystemId
= aXMLWordListName
;
2251 aParserInput
.aInputStream
= xStrm
->getInputStream();
2254 uno::Reference
< XInterface
> xXMLParser
= xServiceFactory
->createInstance( OUString::createFromAscii("com.sun.star.xml.sax.Parser") );
2255 DBG_ASSERT( xXMLParser
.is(), "XMLReader::Read: com.sun.star.xml.sax.Parser service missing" );
2256 if( xXMLParser
.is() )
2258 uno::Reference
< xml::sax::XDocumentHandler
> xFilter
= new SvXMLAutoCorrectImport( xServiceFactory
, pAutocorr_List
, rAutoCorrect
, xStg
);
2260 // connect parser and filter
2261 uno::Reference
< xml::sax::XParser
> xParser( xXMLParser
, UNO_QUERY
);
2262 xParser
->setDocumentHandler( xFilter
);
2265 xParser
->parseStream( aParserInput
);
2268 catch ( uno::Exception
& )
2272 // Zeitstempel noch setzen
2273 FStatHelper::GetModifiedDateTimeOfFile( sShareAutoCorrFile
,
2274 &aModifiedDate
, &aModifiedTime
);
2275 aLastCheckTime
= Time();
2277 return pAutocorr_List
;
2280 /* -----------------18.11.98 11:26-------------------
2282 * --------------------------------------------------*/
2284 void SvxAutoCorrectLanguageLists::SetAutocorrWordList( SvxAutocorrWordList
* pList
)
2286 if( pAutocorr_List
&& pList
!= pAutocorr_List
)
2287 delete pAutocorr_List
;
2288 pAutocorr_List
= pList
;
2289 if( !pAutocorr_List
)
2291 DBG_ASSERT( !this, "keine gueltige Liste" );
2292 pAutocorr_List
= new SvxAutocorrWordList( 16, 16 );
2294 nFlags
|= ChgWordLstLoad
;
2297 /* -----------------18.11.98 11:26-------------------
2299 * --------------------------------------------------*/
2300 const SvxAutocorrWordList
* SvxAutoCorrectLanguageLists::GetAutocorrWordList()
2302 if( !( ChgWordLstLoad
& nFlags
) || IsFileChanged_Imp() )
2303 SetAutocorrWordList( LoadAutocorrWordList() );
2304 return pAutocorr_List
;
2306 /* -----------------18.11.98 11:26-------------------
2308 * --------------------------------------------------*/
2309 SvStringsISortDtor
* SvxAutoCorrectLanguageLists::GetCplSttExceptList()
2311 if( !( CplSttLstLoad
& nFlags
) || IsFileChanged_Imp() )
2312 SetCplSttExceptList( LoadCplSttExceptList() );
2313 return pCplStt_ExcptLst
;
2315 /* -----------------18.11.98 11:26-------------------
2317 * --------------------------------------------------*/
2318 BOOL
SvxAutoCorrectLanguageLists::AddToCplSttExceptList(const String
& rNew
)
2320 String
* pNew
= new String( rNew
);
2321 if( rNew
.Len() && GetCplSttExceptList()->Insert( pNew
) )
2323 MakeUserStorage_Impl();
2324 SotStorageRef xStg
= new SotStorage( sUserAutoCorrFile
, STREAM_READWRITE
, TRUE
);
2326 SaveExceptList_Imp( *pCplStt_ExcptLst
, pXMLImplCplStt_ExcptLstStr
, xStg
);
2329 // Zeitstempel noch setzen
2330 FStatHelper::GetModifiedDateTimeOfFile( sUserAutoCorrFile
,
2331 &aModifiedDate
, &aModifiedTime
);
2332 aLastCheckTime
= Time();
2335 delete pNew
, pNew
= 0;
2338 /* -----------------18.11.98 15:20-------------------
2340 * --------------------------------------------------*/
2341 BOOL
SvxAutoCorrectLanguageLists::AddToWrdSttExceptList(const String
& rNew
)
2343 String
* pNew
= new String( rNew
);
2344 SvStringsISortDtor
* pExceptList
= LoadWrdSttExceptList();
2345 if( rNew
.Len() && pExceptList
&& pExceptList
->Insert( pNew
) )
2347 MakeUserStorage_Impl();
2348 SotStorageRef xStg
= new SotStorage( sUserAutoCorrFile
, STREAM_READWRITE
, TRUE
);
2350 SaveExceptList_Imp( *pWrdStt_ExcptLst
, pXMLImplWrdStt_ExcptLstStr
, xStg
);
2353 // Zeitstempel noch setzen
2354 FStatHelper::GetModifiedDateTimeOfFile( sUserAutoCorrFile
,
2355 &aModifiedDate
, &aModifiedTime
);
2356 aLastCheckTime
= Time();
2359 delete pNew
, pNew
= 0;
2363 /* -----------------18.11.98 11:26-------------------
2365 * --------------------------------------------------*/
2366 SvStringsISortDtor
* SvxAutoCorrectLanguageLists::LoadCplSttExceptList()
2368 SotStorageRef xStg
= new SotStorage( sShareAutoCorrFile
, STREAM_READ
| STREAM_SHARE_DENYNONE
, TRUE
);
2369 String
sTemp ( RTL_CONSTASCII_USTRINGPARAM ( pXMLImplCplStt_ExcptLstStr
) );
2370 if( xStg
.Is() && xStg
->IsContained( sTemp
) )
2371 LoadXMLExceptList_Imp( pCplStt_ExcptLst
, pXMLImplCplStt_ExcptLstStr
, xStg
);
2373 return pCplStt_ExcptLst
;
2376 /* -----------------18.11.98 11:26-------------------
2378 * --------------------------------------------------*/
2379 void SvxAutoCorrectLanguageLists::SaveCplSttExceptList()
2381 MakeUserStorage_Impl();
2382 SotStorageRef xStg
= new SotStorage( sUserAutoCorrFile
, STREAM_READWRITE
, TRUE
);
2384 SaveExceptList_Imp( *pCplStt_ExcptLst
, pXMLImplCplStt_ExcptLstStr
, xStg
);
2388 // Zeitstempel noch setzen
2389 FStatHelper::GetModifiedDateTimeOfFile( sUserAutoCorrFile
,
2390 &aModifiedDate
, &aModifiedTime
);
2391 aLastCheckTime
= Time();
2394 /* -----------------18.11.98 11:26-------------------
2396 * --------------------------------------------------*/
2397 void SvxAutoCorrectLanguageLists::SetCplSttExceptList( SvStringsISortDtor
* pList
)
2399 if( pCplStt_ExcptLst
&& pList
!= pCplStt_ExcptLst
)
2400 delete pCplStt_ExcptLst
;
2402 pCplStt_ExcptLst
= pList
;
2403 if( !pCplStt_ExcptLst
)
2405 DBG_ASSERT( !this, "keine gueltige Liste" );
2406 pCplStt_ExcptLst
= new SvStringsISortDtor( 16, 16 );
2408 nFlags
|= CplSttLstLoad
;
2410 /* -----------------18.11.98 11:26-------------------
2412 * --------------------------------------------------*/
2413 SvStringsISortDtor
* SvxAutoCorrectLanguageLists::LoadWrdSttExceptList()
2415 SotStorageRef xStg
= new SotStorage( sShareAutoCorrFile
, STREAM_READ
| STREAM_SHARE_DENYNONE
, TRUE
);
2416 String
sTemp ( RTL_CONSTASCII_USTRINGPARAM ( pXMLImplWrdStt_ExcptLstStr
) );
2417 if( xStg
.Is() && xStg
->IsContained( sTemp
) )
2418 LoadXMLExceptList_Imp( pWrdStt_ExcptLst
, pXMLImplWrdStt_ExcptLstStr
, xStg
);
2419 return pWrdStt_ExcptLst
;
2421 /* -----------------18.11.98 11:26-------------------
2423 * --------------------------------------------------*/
2424 void SvxAutoCorrectLanguageLists::SaveWrdSttExceptList()
2426 MakeUserStorage_Impl();
2427 SotStorageRef xStg
= new SotStorage( sUserAutoCorrFile
, STREAM_READWRITE
, TRUE
);
2429 SaveExceptList_Imp( *pWrdStt_ExcptLst
, pXMLImplWrdStt_ExcptLstStr
, xStg
);
2432 // Zeitstempel noch setzen
2433 FStatHelper::GetModifiedDateTimeOfFile( sUserAutoCorrFile
,
2434 &aModifiedDate
, &aModifiedTime
);
2435 aLastCheckTime
= Time();
2437 /* -----------------18.11.98 11:26-------------------
2439 * --------------------------------------------------*/
2440 void SvxAutoCorrectLanguageLists::SetWrdSttExceptList( SvStringsISortDtor
* pList
)
2442 if( pWrdStt_ExcptLst
&& pList
!= pWrdStt_ExcptLst
)
2443 delete pWrdStt_ExcptLst
;
2444 pWrdStt_ExcptLst
= pList
;
2445 if( !pWrdStt_ExcptLst
)
2447 DBG_ASSERT( !this, "keine gueltige Liste" );
2448 pWrdStt_ExcptLst
= new SvStringsISortDtor( 16, 16 );
2450 nFlags
|= WrdSttLstLoad
;
2452 /* -----------------18.11.98 11:26-------------------
2454 * --------------------------------------------------*/
2455 SvStringsISortDtor
* SvxAutoCorrectLanguageLists::GetWrdSttExceptList()
2457 if( !( WrdSttLstLoad
& nFlags
) || IsFileChanged_Imp() )
2458 SetWrdSttExceptList( LoadWrdSttExceptList() );
2459 return pWrdStt_ExcptLst
;
2461 /* -----------------18.11.98 11:26-------------------
2463 * --------------------------------------------------*/
2464 void SvxAutoCorrectLanguageLists::RemoveStream_Imp( const String
& rName
)
2466 if( sShareAutoCorrFile
!= sUserAutoCorrFile
)
2468 SotStorageRef xStg
= new SotStorage( sUserAutoCorrFile
, STREAM_READWRITE
, TRUE
);
2469 if( xStg
.Is() && SVSTREAM_OK
== xStg
->GetError() &&
2470 xStg
->IsStream( rName
) )
2472 xStg
->Remove( rName
);
2480 void SvxAutoCorrectLanguageLists::MakeUserStorage_Impl()
2482 // The conversion needs to happen if the file is already in the user
2483 // directory and is in the old format. Additionally it needs to
2484 // happen when the file is being copied from share to user.
2486 sal_Bool bError
= sal_False
, bConvert
= sal_False
, bCopy
= sal_False
;
2487 INetURLObject aDest
;
2488 INetURLObject aSource
;
2490 // String sDestPath = sUserAutoCorrFile.Copy ( 0, sUserAutoCorrFile.Len()-3);
2491 // sDestPath.AppendAscii ("bak");
2494 if (sUserAutoCorrFile
!= sShareAutoCorrFile
)
2496 aSource
= INetURLObject ( sShareAutoCorrFile
); //aSource.setFSysPath ( sShareAutoCorrFile, INetURLObject::FSYS_DETECT );
2497 aDest
= INetURLObject ( sUserAutoCorrFile
);
2498 if ( SotStorage::IsOLEStorage ( sShareAutoCorrFile
) )
2500 aDest
.SetExtension ( String::CreateFromAscii ( "bak" ) );
2501 bConvert
= sal_True
;
2505 else if ( SotStorage::IsOLEStorage ( sUserAutoCorrFile
) )
2507 aSource
= INetURLObject ( sUserAutoCorrFile
);
2508 aDest
= INetURLObject ( sUserAutoCorrFile
);
2509 aDest
.SetExtension ( String::CreateFromAscii ( "bak" ) );
2510 bCopy
= bConvert
= sal_True
;
2516 String
sMain(aDest
.GetMainURL( INetURLObject::DECODE_TO_IURI
));
2517 sal_Unicode cSlash
= '/';
2518 xub_StrLen nSlashPos
= sMain
.SearchBackward(cSlash
);
2519 sMain
.Erase(nSlashPos
);
2520 ::ucbhelper::Content
aNewContent( sMain
, uno::Reference
< XCommandEnvironment
> ());
2523 aInfo
.NameClash
= NameClash::OVERWRITE
;
2524 aInfo
.NewTitle
= aDest
.GetName();
2525 aInfo
.SourceURL
= aSource
.GetMainURL( INetURLObject::DECODE_TO_IURI
);
2526 aInfo
.MoveData
= FALSE
;
2528 aNewContent
.executeCommand( OUString ( RTL_CONSTASCII_USTRINGPARAM( "transfer" ) ), aAny
);
2535 if (bConvert
&& !bError
)
2537 SotStorageRef xSrcStg
= new SotStorage( aDest
.GetMainURL( INetURLObject::DECODE_TO_IURI
), STREAM_READ
, TRUE
);
2538 SotStorageRef xDstStg
= new SotStorage( sUserAutoCorrFile
, STREAM_WRITE
, TRUE
);
2540 if( xSrcStg
.Is() && xDstStg
.Is() )
2542 String
sWord ( RTL_CONSTASCII_USTRINGPARAM ( pImplWrdStt_ExcptLstStr
) );
2543 String
sSentence ( RTL_CONSTASCII_USTRINGPARAM ( pImplCplStt_ExcptLstStr
) );
2544 String
sXMLWord ( RTL_CONSTASCII_USTRINGPARAM ( pXMLImplWrdStt_ExcptLstStr
) );
2545 String
sXMLSentence ( RTL_CONSTASCII_USTRINGPARAM ( pXMLImplCplStt_ExcptLstStr
) );
2546 SvStringsISortDtor
*pTmpWordList
= NULL
;
2548 if (xSrcStg
->IsContained( sXMLWord
) )
2549 LoadXMLExceptList_Imp( pTmpWordList
, pXMLImplWrdStt_ExcptLstStr
, xSrcStg
);
2553 SaveExceptList_Imp( *pTmpWordList
, pXMLImplWrdStt_ExcptLstStr
, xDstStg
, TRUE
);
2554 pTmpWordList
->DeleteAndDestroy( 0, pTmpWordList
->Count() );
2555 pTmpWordList
= NULL
;
2559 if (xSrcStg
->IsContained( sXMLSentence
) )
2560 LoadXMLExceptList_Imp( pTmpWordList
, pXMLImplCplStt_ExcptLstStr
, xSrcStg
);
2564 SaveExceptList_Imp( *pTmpWordList
, pXMLImplCplStt_ExcptLstStr
, xDstStg
, TRUE
);
2565 pTmpWordList
->DeleteAndDestroy( 0, pTmpWordList
->Count() );
2568 GetAutocorrWordList();
2569 MakeBlocklist_Imp( *xDstStg
);
2570 // xDstStg is committed in MakeBlocklist_Imp
2571 /*xSrcStg->CopyTo( &xDstStg );*/
2572 sShareAutoCorrFile
= sUserAutoCorrFile
;
2576 ::ucbhelper::Content
aContent ( aDest
.GetMainURL( INetURLObject::DECODE_TO_IURI
), uno::Reference
< XCommandEnvironment
> ());
2577 aContent
.executeCommand ( OUString ( RTL_CONSTASCII_USTRINGPARAM ( "delete" ) ), makeAny ( sal_Bool (sal_True
) ) );
2584 else if( bCopy
&& !bError
)
2585 sShareAutoCorrFile
= sUserAutoCorrFile
;
2588 /* -----------------18.11.98 11:26-------------------
2590 * --------------------------------------------------*/
2591 BOOL
SvxAutoCorrectLanguageLists::MakeBlocklist_Imp( SvStorage
& rStg
)
2593 String
sStrmName( pXMLImplAutocorr_ListStr
, RTL_TEXTENCODING_MS_1252
);
2594 BOOL bRet
= TRUE
, bRemove
= !pAutocorr_List
|| !pAutocorr_List
->Count();
2598 if ( rStg.IsContained( sStrmName) )
2600 rStg.Remove ( sStrmName );
2604 SvStorageStreamRef refList
= rStg
.OpenSotStream( sStrmName
,
2605 ( STREAM_READ
| STREAM_WRITE
| STREAM_SHARE_DENYWRITE
) );
2608 refList
->SetSize( 0 );
2609 refList
->SetBufferSize( 8192 );
2610 String
aPropName( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM("MediaType") ) );
2611 OUString
aMime( RTL_CONSTASCII_USTRINGPARAM("text/xml") );
2614 refList
->SetProperty( aPropName
, aAny
);
2616 uno::Reference
< lang::XMultiServiceFactory
> xServiceFactory
=
2617 comphelper::getProcessServiceFactory();
2618 DBG_ASSERT( xServiceFactory
.is(),
2619 "XMLReader::Read: got no service manager" );
2620 if( !xServiceFactory
.is() )
2622 // Throw an exception ?
2625 uno::Reference
< XInterface
> xWriter (xServiceFactory
->createInstance(
2626 OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.sax.Writer"))));
2627 DBG_ASSERT(xWriter
.is(),"com.sun.star.xml.sax.Writer service missing");
2628 uno::Reference
< io::XOutputStream
> xOut
= new utl::OOutputStreamWrapper( *refList
);
2629 uno::Reference
<io::XActiveDataSource
> xSrc(xWriter
, uno::UNO_QUERY
);
2630 xSrc
->setOutputStream(xOut
);
2632 uno::Reference
<xml::sax::XDocumentHandler
> xHandler(xWriter
, uno::UNO_QUERY
);
2635 // SvXMLAutoCorrectExport aExp(pAutocorr_List, sStrmName, xHandler);
2636 SvXMLAutoCorrectExport
aExp( xServiceFactory
, pAutocorr_List
, sStrmName
, xHandler
);
2638 aExp
.exportDoc( XML_BLOCK_LIST
);
2641 bRet
= SVSTREAM_OK
== refList
->GetError();
2646 if( SVSTREAM_OK
!= rStg
.GetError() )
2654 refList->SetSize( 0 );
2655 refList->SetBufferSize( 8192 );
2656 rtl_TextEncoding eEncoding = gsl_getSystemTextEncoding();
2658 String aDummy; // Erkennungszeichen fuer neue Streams
2659 refList->WriteByteString( aDummy, RTL_TEXTENCODING_MS_1252 )
2660 << (BYTE) 4 // Laenge des Headers (ohne den Leerstring)
2661 << (USHORT)WORDLIST_VERSION_358 // Version des Streams
2662 << (BYTE)eEncoding; // der Zeichensatz
2664 for( USHORT i = 0; i < pAutocorr_List->Count() &&
2665 SVSTREAM_OK == refList->GetError(); ++i )
2667 SvxAutocorrWord* p = pAutocorr_List->GetObject( i );
2668 refList->WriteByteString( p->GetShort(), eEncoding ).
2669 WriteByteString( p->IsTextOnly()
2671 : p->GetShort(), eEncoding );
2674 bRet = SVSTREAM_OK == refList->GetError();
2679 if( SVSTREAM_OK != rStg.GetError() )
2693 rStg
.Remove( sStrmName
);
2700 /* -----------------18.11.98 11:26-------------------
2702 * --------------------------------------------------*/
2703 BOOL
SvxAutoCorrectLanguageLists::PutText( const String
& rShort
,
2704 const String
& rLong
)
2706 // erstmal akt. Liste besorgen!
2707 GetAutocorrWordList();
2709 MakeUserStorage_Impl();
2710 SotStorageRef xStg
= new SotStorage( sUserAutoCorrFile
, STREAM_READWRITE
, TRUE
);
2712 BOOL bRet
= xStg
.Is() && SVSTREAM_OK
== xStg
->GetError();
2716 // PutText( *xStg, rShort );
2719 // die Wortliste aktualisieren
2723 SvxAutocorrWord
* pNew
= new SvxAutocorrWord( rShort
, rLong
, TRUE
);
2724 if( pAutocorr_List
->Seek_Entry( pNew
, &nPos
) )
2726 if( !(*pAutocorr_List
)[ nPos
]->IsTextOnly() )
2728 // dann ist der Storage noch zu entfernen
2729 String
sStgNm( rShort
);
2730 if (xStg
->IsOLEStorage())
2731 EncryptBlockName_Imp( sStgNm
);
2733 GeneratePackageName ( rShort
, sStgNm
);
2735 if( xStg
->IsContained( sStgNm
) )
2736 xStg
->Remove( sStgNm
);
2738 pAutocorr_List
->DeleteAndDestroy( nPos
);
2741 if( pAutocorr_List
->Insert( pNew
) )
2743 bRet
= MakeBlocklist_Imp( *xStg
);
2754 /* -----------------18.11.98 11:26-------------------
2756 * --------------------------------------------------*/
2757 // - Text mit Attributierung (kann nur der SWG - SWG-Format!)
2758 BOOL
SvxAutoCorrectLanguageLists::PutText( const String
& rShort
,
2759 SfxObjectShell
& rShell
)
2761 // erstmal akt. Liste besorgen!
2762 GetAutocorrWordList();
2764 MakeUserStorage_Impl();
2770 uno::Reference
< embed::XStorage
> xStg
= comphelper::OStorageHelper::GetStorageFromURL( sUserAutoCorrFile
, embed::ElementModes::READWRITE
);
2771 // String aName( rShort );
2772 // EncryptBlockName_Imp( aName );
2773 // bRet = PutText( *xStg, aName, rShell, sLong );
2774 bRet
= rAutoCorrect
.PutText( xStg
, sUserAutoCorrFile
, rShort
, rShell
, sLong
);
2777 // die Wortliste aktualisieren
2780 SvxAutocorrWord
* pNew
= new SvxAutocorrWord( rShort
, sLong
, FALSE
);
2781 if( pAutocorr_List
->Insert( pNew
) )
2783 SotStorageRef xStor
= new SotStorage( sUserAutoCorrFile
, STREAM_READWRITE
, TRUE
);
2784 MakeBlocklist_Imp( *xStor
);
2790 catch ( uno::Exception
& )
2797 /* -----------------18.11.98 11:26-------------------
2799 * --------------------------------------------------*/
2800 // - loesche einen Eintrag
2801 BOOL
SvxAutoCorrectLanguageLists::DeleteText( const String
& rShort
)
2803 // erstmal akt. Liste besorgen!
2804 GetAutocorrWordList();
2806 MakeUserStorage_Impl();
2808 SotStorageRef xStg
= new SotStorage( sUserAutoCorrFile
, STREAM_READWRITE
, TRUE
);
2809 BOOL bRet
= xStg
.Is() && SVSTREAM_OK
== xStg
->GetError();
2813 SvxAutocorrWord
aTmp( rShort
, rShort
);
2814 if( pAutocorr_List
->Seek_Entry( &aTmp
, &nPos
) )
2816 SvxAutocorrWord
* pFnd
= (*pAutocorr_List
)[ nPos
];
2817 if( !pFnd
->IsTextOnly() )
2819 String
aName( rShort
);
2820 if (xStg
->IsOLEStorage())
2821 EncryptBlockName_Imp( aName
);
2823 GeneratePackageName ( rShort
, aName
);
2824 if( xStg
->IsContained( aName
) )
2826 xStg
->Remove( aName
);
2827 bRet
= xStg
->Commit();
2831 // die Wortliste aktualisieren
2832 pAutocorr_List
->DeleteAndDestroy( nPos
);
2833 MakeBlocklist_Imp( *xStg
);