1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
29 #include <com/sun/star/io/XStream.hpp>
30 #include <com/sun/star/lang/Locale.hpp>
31 #include <tools/urlobj.hxx>
32 #include <i18npool/mslangid.hxx>
33 #include <vcl/svapp.hxx>
34 #include <sot/storinfo.hxx>
35 #include <svl/svstdarr.hxx>
36 #include <svl/fstathelper.hxx>
37 #include <svtools/helpopt.hxx>
38 #include <svl/urihelper.hxx>
39 #include <unotools/charclass.hxx>
40 #include <com/sun/star/i18n/UnicodeType.hdl>
41 #include <unotools/collatorwrapper.hxx>
42 #include <com/sun/star/i18n/CollatorOptions.hpp>
43 #include <com/sun/star/i18n/UnicodeScript.hpp>
44 #include <com/sun/star/i18n/XOrdinalSuffix.hpp>
45 #include <unotools/localedatawrapper.hxx>
46 #include <unotools/transliterationwrapper.hxx>
47 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
48 #include <comphelper/processfactory.hxx>
49 #include <com/sun/star/io/XActiveDataSource.hpp>
50 #include <editeng/editids.hrc>
51 #include <sot/storage.hxx>
52 #include <comphelper/storagehelper.hxx>
53 #include <editeng/udlnitem.hxx>
54 #include <editeng/wghtitem.hxx>
55 #include <editeng/escpitem.hxx>
56 #include <editeng/svxacorr.hxx>
57 #include <editeng/unolingu.hxx>
58 #include "vcl/window.hxx"
60 #include <com/sun/star/xml/sax/InputSource.hpp>
61 #include <com/sun/star/xml/sax/XParser.hpp>
62 #include <unotools/streamwrap.hxx>
63 #include <SvXMLAutoCorrectImport.hxx>
64 #include <SvXMLAutoCorrectExport.hxx>
65 #include <ucbhelper/content.hxx>
66 #include <com/sun/star/ucb/XCommandEnvironment.hpp>
67 #include <com/sun/star/ucb/TransferInfo.hpp>
68 #include <com/sun/star/ucb/NameClash.hpp>
69 #include <xmloff/xmltoken.hxx>
70 #include <vcl/help.hxx>
71 #include <rtl/logfile.hxx>
73 #define CHAR_HARDBLANK ((sal_Unicode)0x00A0)
75 using namespace ::com::sun::star::ucb
;
76 using namespace ::com::sun::star::uno
;
77 using namespace ::com::sun::star
;
78 using namespace ::xmloff::token
;
79 using namespace ::rtl
;
80 using namespace ::utl
;
82 static const int C_NONE
= 0x00;
83 static const int C_FULL_STOP
= 0x01;
84 static const int C_EXCLAMATION_MARK
= 0x02;
85 static const int C_QUESTION_MARK
= 0x04;
87 static const sal_Char pImplWrdStt_ExcptLstStr
[] = "WordExceptList";
88 static const sal_Char pImplCplStt_ExcptLstStr
[] = "SentenceExceptList";
89 static const sal_Char pImplAutocorr_ListStr
[] = "DocumentList";
90 static const sal_Char pXMLImplWrdStt_ExcptLstStr
[] = "WordExceptList.xml";
91 static const sal_Char pXMLImplCplStt_ExcptLstStr
[] = "SentenceExceptList.xml";
92 static const sal_Char pXMLImplAutocorr_ListStr
[] = "DocumentList.xml";
95 /* also at these beginnings - Brackets and all kinds of begin characters */
96 sImplSttSkipChars
[] = "\"\'([{\x83\x84\x89\x91\x92\x93\x94",
97 /* also at these ends - Brackets and all kinds of begin characters */
98 sImplEndSkipChars
[] = "\"\')]}\x83\x84\x89\x91\x92\x93\x94";
100 // These characters are allowed in words: (for FnCptlSttSntnc)
101 static const sal_Char sImplWordChars
[] = "-'";
103 void EncryptBlockName_Imp( String
& rName
);
105 // FileVersions Number for the Substitution-/Exception list separately
106 #define WORDLIST_VERSION_358 1
107 #define EXEPTLIST_VERSION_358 0
109 _SV_IMPL_SORTAR_ALG( SvxAutocorrWordList
, SvxAutocorrWordPtr
)
110 TYPEINIT0(SvxAutoCorrect
)
112 typedef SvxAutoCorrectLanguageLists
* SvxAutoCorrectLanguageListsPtr
;
114 static inline int IsWordDelim( const sal_Unicode c
)
116 return ' ' == c
|| '\t' == c
|| 0x0a == c
||
117 0xA0 == c
|| 0x2011 == c
|| 0x1 == c
;
120 static inline int IsLowerLetter( sal_Int32 nCharType
)
122 return CharClass::isLetterType( nCharType
) &&
123 0 == ( ::com::sun::star::i18n::KCharacterType::UPPER
& nCharType
);
126 static inline int IsUpperLetter( sal_Int32 nCharType
)
128 return CharClass::isLetterType( nCharType
) &&
129 0 == ( ::com::sun::star::i18n::KCharacterType::LOWER
& nCharType
);
132 static sal_Bool
lcl_IsSymbolChar( CharClass
& rCC
, const String
& rTxt
,
133 xub_StrLen nStt
, xub_StrLen nEnd
)
135 for( ; nStt
< nEnd
; ++nStt
)
137 if( ::com::sun::star::i18n::UnicodeType::PRIVATE_USE
==
138 rCC
.getType( rTxt
, nStt
))
144 static sal_Bool
lcl_IsInAsciiArr( const sal_Char
* pArr
, const sal_Unicode c
)
146 sal_Bool bRet
= sal_False
;
147 for( ; *pArr
; ++pArr
)
156 SvxAutoCorrDoc::~SvxAutoCorrDoc()
159 // Is called by the functions:
162 // after the exchange of characters. then the words can maybe be inserted
163 // into the exception list.
164 void SvxAutoCorrDoc::SaveCpltSttWord( sal_uLong
, xub_StrLen
, const String
&,
169 LanguageType
SvxAutoCorrDoc::GetLanguage( xub_StrLen
, sal_Bool
) const
171 return LANGUAGE_SYSTEM
;
174 static ::com::sun::star::uno::Reference
<
175 ::com::sun::star::lang::XMultiServiceFactory
>& GetProcessFact()
177 static ::com::sun::star::uno::Reference
<
178 ::com::sun::star::lang::XMultiServiceFactory
> xMSF
=
179 ::comphelper::getProcessServiceFactory();
183 static sal_uInt16
GetAppLang()
185 return Application::GetSettings().GetLanguage();
187 static LocaleDataWrapper
& GetLocaleDataWrapper( sal_uInt16 nLang
)
189 static LocaleDataWrapper
aLclDtWrp( GetProcessFact(),
190 SvxCreateLocale( GetAppLang() ) );
191 ::com::sun::star::lang::Locale
aLcl( SvxCreateLocale( nLang
));
192 const ::com::sun::star::lang::Locale
& rLcl
= aLclDtWrp
.getLoadedLocale();
193 if( aLcl
.Language
!= rLcl
.Language
||
194 aLcl
.Country
!= rLcl
.Country
||
195 aLcl
.Variant
!= rLcl
.Variant
)
196 aLclDtWrp
.setLocale( aLcl
);
199 static TransliterationWrapper
& GetIgnoreTranslWrapper()
201 static int bIsInit
= 0;
202 static TransliterationWrapper
aWrp( GetProcessFact(),
203 ::com::sun::star::i18n::TransliterationModules_IGNORE_KANA
|
204 ::com::sun::star::i18n::TransliterationModules_IGNORE_WIDTH
);
207 aWrp
.loadModuleIfNeeded( GetAppLang() );
212 static CollatorWrapper
& GetCollatorWrapper()
214 static int bIsInit
= 0;
215 static CollatorWrapper
aCollWrp( GetProcessFact() );
218 aCollWrp
.loadDefaultCollator( SvxCreateLocale( GetAppLang() ), 0 );
225 void SvxAutocorrWordList::DeleteAndDestroy( sal_uInt16 nP
, sal_uInt16 nL
)
229 OSL_ENSURE( nP
< nA
&& nP
+ nL
<= nA
, "ERR_VAR_DEL" );
230 for( sal_uInt16 n
=nP
; n
< nP
+ nL
; n
++ )
231 delete *((SvxAutocorrWordPtr
*)pData
+n
);
232 SvPtrarr::Remove( nP
, nL
);
237 // Keep the list sorted ...
238 sal_Bool
SvxAutocorrWordList::Seek_Entry( const SvxAutocorrWordPtr aE
, sal_uInt16
* pP
) const
240 register sal_uInt16 nO
= SvxAutocorrWordList_SAR::Count(),
246 CollatorWrapper
& rCmp
= ::GetCollatorWrapper();
249 // quick check of the end of the list
250 if (rCmp
.compareString( aE
->GetShort(),
251 (*((SvxAutocorrWordPtr
*)pData
+ nO
))->GetShort() ) > 0)
253 if( pP
) *pP
= nO
+ 1;
257 // Incredibly crude sort algorithm, should use some partitioning search.
260 nM
= nU
+ ( nO
- nU
) / 2;
261 long nCmp
= rCmp
.compareString( aE
->GetShort(),
262 (*((SvxAutocorrWordPtr
*)pData
+ nM
))->GetShort() );
283 static void lcl_ClearTable(boost::ptr_map
<LanguageType
, SvxAutoCorrectLanguageLists
>& rLangTable
)
288 sal_Bool
SvxAutoCorrect::IsAutoCorrectChar( sal_Unicode cChar
)
290 return cChar
== '\0' || cChar
== '\t' || cChar
== 0x0a ||
291 cChar
== ' ' || cChar
== '\'' || cChar
== '\"' ||
292 cChar
== '*' || cChar
== '_' || cChar
== '%' ||
293 cChar
== '.' || cChar
== ',' || cChar
== ';' ||
294 cChar
== ':' || cChar
== '?' || cChar
== '!' || cChar
== '/';
297 sal_Bool
SvxAutoCorrect::NeedsHardspaceAutocorr( sal_Unicode cChar
)
299 return cChar
== '%' || cChar
== ';' || cChar
== ':' || cChar
== '?' || cChar
== '!' ||
300 cChar
== '/' /*case for the urls exception*/;
303 long SvxAutoCorrect::GetDefaultFlags()
305 long nRet
= Autocorrect
317 LanguageType eLang
= GetAppLang();
320 case LANGUAGE_ENGLISH
:
321 case LANGUAGE_ENGLISH_US
:
322 case LANGUAGE_ENGLISH_UK
:
323 case LANGUAGE_ENGLISH_AUS
:
324 case LANGUAGE_ENGLISH_CAN
:
325 case LANGUAGE_ENGLISH_NZ
:
326 case LANGUAGE_ENGLISH_EIRE
:
327 case LANGUAGE_ENGLISH_SAFRICA
:
328 case LANGUAGE_ENGLISH_JAMAICA
:
329 case LANGUAGE_ENGLISH_CARRIBEAN
:
330 nRet
&= ~(ChgQuotes
|ChgSglQuotes
);
337 SvxAutoCorrect::SvxAutoCorrect( const String
& rShareAutocorrFile
,
338 const String
& rUserAutocorrFile
)
339 : sShareAutoCorrFile( rShareAutocorrFile
),
340 sUserAutoCorrFile( rUserAutocorrFile
),
341 pLangTable( new boost::ptr_map
<LanguageType
, SvxAutoCorrectLanguageLists
> ),
342 pCharClass( 0 ), bRunNext( false ),
343 cStartDQuote( 0 ), cEndDQuote( 0 ), cStartSQuote( 0 ), cEndSQuote( 0 )
345 nFlags
= SvxAutoCorrect::GetDefaultFlags();
351 SvxAutoCorrect::SvxAutoCorrect( const SvxAutoCorrect
& rCpy
)
352 : sShareAutoCorrFile( rCpy
.sShareAutoCorrFile
),
353 sUserAutoCorrFile( rCpy
.sUserAutoCorrFile
),
355 aSwFlags( rCpy
.aSwFlags
),
357 pLangTable( new boost::ptr_map
<LanguageType
, SvxAutoCorrectLanguageLists
> ),
358 pCharClass( 0 ), bRunNext( false ),
360 nFlags( rCpy
.nFlags
& ~(ChgWordLstLoad
|CplSttLstLoad
|WrdSttLstLoad
)),
361 cStartDQuote( rCpy
.cStartDQuote
), cEndDQuote( rCpy
.cEndDQuote
),
362 cStartSQuote( rCpy
.cStartSQuote
), cEndSQuote( rCpy
.cEndSQuote
),
363 cEmDash( rCpy
.cEmDash
), cEnDash( rCpy
.cEnDash
)
368 SvxAutoCorrect::~SvxAutoCorrect()
370 lcl_ClearTable(*pLangTable
);
375 void SvxAutoCorrect::_GetCharClass( LanguageType eLang
)
378 pCharClass
= new CharClass( SvxCreateLocale( eLang
));
379 eCharClassLang
= eLang
;
382 void SvxAutoCorrect::SetAutoCorrFlag( long nFlag
, sal_Bool bOn
)
385 nFlags
= bOn
? nFlags
| nFlag
390 if( (nOld
& CptlSttSntnc
) != (nFlags
& CptlSttSntnc
) )
391 nFlags
&= ~CplSttLstLoad
;
392 if( (nOld
& CptlSttWrd
) != (nFlags
& CptlSttWrd
) )
393 nFlags
&= ~WrdSttLstLoad
;
394 if( (nOld
& Autocorrect
) != (nFlags
& Autocorrect
) )
395 nFlags
&= ~ChgWordLstLoad
;
400 // Two capital letters at the beginning of word?
401 sal_Bool
SvxAutoCorrect::FnCptlSttWrd( SvxAutoCorrDoc
& rDoc
, const String
& rTxt
,
402 xub_StrLen nSttPos
, xub_StrLen nEndPos
,
405 sal_Bool bRet
= sal_False
;
406 CharClass
& rCC
= GetCharClass( eLang
);
408 // Delete all non alphanumeric. Test the characters at the beginning/end of
409 // the word ( recognizes: "(min.", "/min.", and so on.)
410 for( ; nSttPos
< nEndPos
; ++nSttPos
)
411 if( rCC
.isLetterNumeric( rTxt
, nSttPos
))
413 for( ; nSttPos
< nEndPos
; --nEndPos
)
414 if( rCC
.isLetterNumeric( rTxt
, nEndPos
- 1 ))
417 // Two capital letters at the beginning of word?
418 if( nSttPos
+2 < nEndPos
&&
419 IsUpperLetter( rCC
.getCharacterType( rTxt
, nSttPos
)) &&
420 IsUpperLetter( rCC
.getCharacterType( rTxt
, ++nSttPos
)) &&
421 // Is the third character a lower case
422 IsLowerLetter( rCC
.getCharacterType( rTxt
, nSttPos
+1 )) &&
423 // Do not replace special attributes
424 0x1 != rTxt
.GetChar( nSttPos
) && 0x2 != rTxt
.GetChar( nSttPos
))
426 // test if the word is in an exception list
427 String
sWord( rTxt
.Copy( nSttPos
- 1, nEndPos
- nSttPos
+ 1 ));
428 if( !FindInWrdSttExceptList(eLang
, sWord
) )
430 // Check that word isn't correctly spelled before correcting:
431 ::com::sun::star::uno::Reference
<
432 ::com::sun::star::linguistic2::XSpellChecker1
> xSpeller
=
433 SvxGetSpellChecker();
434 if( xSpeller
->hasLanguage(eLang
) )
436 Sequence
< ::com::sun::star::beans::PropertyValue
> aEmptySeq
;
437 if (!xSpeller
->spell(sWord
, eLang
, aEmptySeq
).is())
442 sal_Unicode cSave
= rTxt
.GetChar( nSttPos
);
443 String
sChar( cSave
);
444 sChar
= rCC
.lowercase( sChar
);
445 if( sChar
.GetChar(0) != cSave
&& rDoc
.ReplaceRange( nSttPos
, 1, sChar
))
447 if( SaveWordWrdSttLst
& nFlags
)
448 rDoc
.SaveCpltSttWord( CptlSttWrd
, nSttPos
, sWord
, cSave
);
457 sal_Bool
SvxAutoCorrect::FnChgOrdinalNumber(
458 SvxAutoCorrDoc
& rDoc
, const String
& rTxt
,
459 xub_StrLen nSttPos
, xub_StrLen nEndPos
,
462 // 1st, 2nd, 3rd, 4 - 0th
465 CharClass
& rCC
= GetCharClass( eLang
);
466 sal_Bool bChg
= sal_False
;
468 for( ; nSttPos
< nEndPos
; ++nSttPos
)
469 if( !lcl_IsInAsciiArr( sImplSttSkipChars
, rTxt
.GetChar( nSttPos
) ))
471 for( ; nSttPos
< nEndPos
; --nEndPos
)
472 if( !lcl_IsInAsciiArr( sImplEndSkipChars
, rTxt
.GetChar( nEndPos
- 1 ) ))
476 // Get the last number in the string to check
477 xub_StrLen nNumEnd
= nEndPos
;
478 bool foundEnd
= false;
479 bool validNumber
= true;
480 xub_StrLen i
= nEndPos
;
482 while ( i
> nSttPos
)
485 bool isDigit
= rCC
.isDigit( rTxt
, i
);
487 validNumber
|= isDigit
;
489 if ( isDigit
&& !foundEnd
)
496 if ( foundEnd
&& validNumber
) {
497 sal_Int32 nNum
= rTxt
.Copy( nSttPos
, nNumEnd
- nSttPos
+ 1 ).ToInt32( );
499 // Check if the characters after that number correspond to the ordinal suffix
500 rtl::OUString
sServiceName("com.sun.star.i18n.OrdinalSuffix");
501 uno::Reference
< i18n::XOrdinalSuffix
> xOrdSuffix(
502 comphelper::createProcessComponent( sServiceName
),
505 if ( xOrdSuffix
.is( ) )
507 uno::Sequence
< rtl::OUString
> aSuffixes
= xOrdSuffix
->getOrdinalSuffix( nNum
, rCC
.getLocale( ) );
508 for ( sal_Int32 nSuff
= 0; nSuff
< aSuffixes
.getLength(); nSuff
++ )
510 String
sSuffix( aSuffixes
[ nSuff
] );
511 String sEnd
= rTxt
.Copy( nNumEnd
+ 1, nEndPos
- nNumEnd
- 1 );
513 if ( sSuffix
== sEnd
)
515 // Check if the ordinal suffix has to be set as super script
516 if ( rCC
.isLetter( sSuffix
) )
519 SvxEscapementItem
aSvxEscapementItem( DFLT_ESC_AUTO_SUPER
,
520 DFLT_ESC_PROP
, SID_ATTR_CHAR_ESCAPEMENT
);
521 rDoc
.SetAttr( nNumEnd
+ 1 , nEndPos
,
522 SID_ATTR_CHAR_ESCAPEMENT
,
534 sal_Bool
SvxAutoCorrect::FnChgToEnEmDash(
535 SvxAutoCorrDoc
& rDoc
, const String
& rTxt
,
536 xub_StrLen nSttPos
, xub_StrLen nEndPos
,
539 sal_Bool bRet
= sal_False
;
540 CharClass
& rCC
= GetCharClass( eLang
);
541 if (eLang
== LANGUAGE_SYSTEM
)
542 eLang
= GetAppLang();
543 bool bAlwaysUseEmDash
= (cEmDash
&& (eLang
== LANGUAGE_RUSSIAN
|| eLang
== LANGUAGE_UKRAINIAN
));
545 // replace " - " or " --" with "enDash"
546 if( cEnDash
&& 1 < nSttPos
&& 1 <= nEndPos
- nSttPos
)
548 sal_Unicode cCh
= rTxt
.GetChar( nSttPos
);
551 if( ' ' == rTxt
.GetChar( nSttPos
-1 ) &&
552 '-' == rTxt
.GetChar( nSttPos
+1 ))
555 for( n
= nSttPos
+2; n
< nEndPos
&& lcl_IsInAsciiArr(
556 sImplSttSkipChars
,(cCh
= rTxt
.GetChar( n
)));
560 // found: " --[<AnySttChars>][A-z0-9]
561 if( rCC
.isLetterNumeric( cCh
) )
563 for( n
= nSttPos
-1; n
&& lcl_IsInAsciiArr(
564 sImplEndSkipChars
,(cCh
= rTxt
.GetChar( --n
))); )
567 // found: "[A-z0-9][<AnyEndChars>] --[<AnySttChars>][A-z0-9]
568 if( rCC
.isLetterNumeric( cCh
))
570 rDoc
.Delete( nSttPos
, nSttPos
+ 2 );
571 rDoc
.Insert( nSttPos
, bAlwaysUseEmDash
? cEmDash
: cEnDash
);
577 else if( 3 < nSttPos
&&
578 ' ' == rTxt
.GetChar( nSttPos
-1 ) &&
579 '-' == rTxt
.GetChar( nSttPos
-2 ))
581 xub_StrLen n
, nLen
= 1, nTmpPos
= nSttPos
- 2;
582 if( '-' == ( cCh
= rTxt
.GetChar( nTmpPos
-1 )) )
586 cCh
= rTxt
.GetChar( nTmpPos
-1 );
590 for( n
= nSttPos
; n
< nEndPos
&& lcl_IsInAsciiArr(
591 sImplSttSkipChars
,(cCh
= rTxt
.GetChar( n
)));
595 // found: " - [<AnySttChars>][A-z0-9]
596 if( rCC
.isLetterNumeric( cCh
) )
599 for( n
= nTmpPos
-1; n
&& lcl_IsInAsciiArr(
600 sImplEndSkipChars
,(cCh
= rTxt
.GetChar( --n
))); )
602 // found: "[A-z0-9][<AnyEndChars>] - [<AnySttChars>][A-z0-9]
603 if( rCC
.isLetterNumeric( cCh
))
605 rDoc
.Delete( nTmpPos
, nTmpPos
+ nLen
);
606 rDoc
.Insert( nTmpPos
, bAlwaysUseEmDash
? cEmDash
: cEnDash
);
614 // Replace [A-z0-9]--[A-z0-9] double dash with "emDash" or "enDash".
615 // Finnish and Hungarian use enDash instead of emDash.
616 bool bEnDash
= (eLang
== LANGUAGE_HUNGARIAN
|| eLang
== LANGUAGE_FINNISH
);
617 if( ((cEmDash
&& !bEnDash
) || (cEnDash
&& bEnDash
)) && 4 <= nEndPos
- nSttPos
)
619 String
sTmp( rTxt
.Copy( nSttPos
, nEndPos
- nSttPos
) );
620 xub_StrLen nFndPos
= sTmp
.SearchAscii( "--" );
621 if( STRING_NOTFOUND
!= nFndPos
&& nFndPos
&&
622 nFndPos
+ 2 < sTmp
.Len() &&
623 ( rCC
.isLetterNumeric( sTmp
, nFndPos
- 1 ) ||
624 lcl_IsInAsciiArr( sImplEndSkipChars
, rTxt
.GetChar( nFndPos
- 1 ) )) &&
625 ( rCC
.isLetterNumeric( sTmp
, nFndPos
+ 2 ) ||
626 lcl_IsInAsciiArr( sImplSttSkipChars
, rTxt
.GetChar( nFndPos
+ 2 ) )))
628 nSttPos
= nSttPos
+ nFndPos
;
629 rDoc
.Delete( nSttPos
, nSttPos
+ 2 );
630 rDoc
.Insert( nSttPos
, (bEnDash
? cEnDash
: cEmDash
) );
638 #pragma warning(push)
639 #pragma warning(disable: 4706) // assignment within conditional expression
642 sal_Bool
SvxAutoCorrect::FnAddNonBrkSpace(
643 SvxAutoCorrDoc
& rDoc
, const String
& rTxt
,
644 xub_StrLen
, xub_StrLen nEndPos
,
649 CharClass
& rCC
= GetCharClass( eLang
);
650 const lang::Locale rLocale
= rCC
.getLocale( );
652 if ( rLocale
.Language
== OUString( "fr" ) )
654 bool bFrCA
= rLocale
.Country
== OUString( "CA" );
655 OUString allChars
= OUString( ":;?!%" );
656 OUString
chars( allChars
);
658 chars
= OUString( ":" );
660 sal_Unicode cChar
= rTxt
.GetChar( nEndPos
);
661 bool bHasSpace
= chars
.indexOf( cChar
) != -1;
662 bool bIsSpecial
= allChars
.indexOf( cChar
) != -1;
665 // Get the last word delimiter position
666 xub_StrLen nSttWdPos
= nEndPos
;
667 bool bWasWordDelim
= false;
668 while( nSttWdPos
&& !(bWasWordDelim
= IsWordDelim( rTxt
.GetChar( --nSttWdPos
))))
671 if(INetURLObject::CompareProtocolScheme(rTxt
.Copy(nSttWdPos
+ (bWasWordDelim
? 1 : 0), nEndPos
- nSttWdPos
+ 1)) != INET_PROT_NOT_VALID
) {
676 // Check the presence of "://" in the word
677 xub_StrLen nStrPos
= rTxt
.Search( String::CreateFromAscii( "://" ), nSttWdPos
+ 1 );
678 if ( STRING_NOTFOUND
== nStrPos
&& nEndPos
> 0 )
680 // Check the previous char
681 sal_Unicode cPrevChar
= rTxt
.GetChar( nEndPos
- 1 );
682 if ( ( chars
.indexOf( cPrevChar
) == -1 ) && cPrevChar
!= '\t' )
684 // Remove any previous normal space
685 xub_StrLen nPos
= nEndPos
- 1;
686 while ( cPrevChar
== ' ' || cPrevChar
== CHAR_HARDBLANK
)
688 if ( nPos
== 0 ) break;
690 cPrevChar
= rTxt
.GetChar( nPos
);
694 if ( nEndPos
- nPos
> 0 )
695 rDoc
.Delete( nPos
, nEndPos
);
697 // Add the non-breaking space at the end pos
699 rDoc
.Insert( nPos
, CHAR_HARDBLANK
);
703 else if ( chars
.indexOf( cPrevChar
) != -1 )
707 else if ( cChar
== '/' && nEndPos
> 1 && rTxt
.Len() > (nEndPos
- 1) )
709 // Remove the hardspace right before to avoid formatting URLs
710 sal_Unicode cPrevChar
= rTxt
.GetChar( nEndPos
- 1 );
711 sal_Unicode cMaybeSpaceChar
= rTxt
.GetChar( nEndPos
- 2 );
712 if ( cPrevChar
== ':' && cMaybeSpaceChar
== CHAR_HARDBLANK
)
714 rDoc
.Delete( nEndPos
- 2, nEndPos
- 1 );
727 sal_Bool
SvxAutoCorrect::FnSetINetAttr( SvxAutoCorrDoc
& rDoc
, const String
& rTxt
,
728 xub_StrLen nSttPos
, xub_StrLen nEndPos
,
731 String
sURL( URIHelper::FindFirstURLInText( rTxt
, nSttPos
, nEndPos
,
732 GetCharClass( eLang
) ));
733 sal_Bool bRet
= 0 != sURL
.Len();
734 if( bRet
) // also Attribut setzen:
735 rDoc
.SetINetAttr( nSttPos
, nEndPos
, sURL
);
740 sal_Bool
SvxAutoCorrect::FnChgWeightUnderl( SvxAutoCorrDoc
& rDoc
, const String
& rTxt
,
741 xub_StrLen
, xub_StrLen nEndPos
,
745 // at the beginning: _ or * after Space with the folloeing !Space
746 // at the end: _ or * before Space (word delimiter?)
748 sal_Unicode c
, cInsChar
= rTxt
.GetChar( nEndPos
); // underline or bold
749 if( ++nEndPos
!= rTxt
.Len() &&
750 !IsWordDelim( rTxt
.GetChar( nEndPos
) ) )
755 sal_Bool bAlphaNum
= sal_False
;
756 xub_StrLen nPos
= nEndPos
, nFndPos
= STRING_NOTFOUND
;
757 CharClass
& rCC
= GetCharClass( eLang
);
761 switch( c
= rTxt
.GetChar( --nPos
) )
767 if( bAlphaNum
&& nPos
+1 < nEndPos
&& ( !nPos
||
768 IsWordDelim( rTxt
.GetChar( nPos
-1 ))) &&
769 !IsWordDelim( rTxt
.GetChar( nPos
+1 )))
772 // Condition is not satisfied, so cancel
773 nFndPos
= STRING_NOTFOUND
;
779 bAlphaNum
= rCC
.isLetterNumeric( rTxt
, nPos
);
783 if( STRING_NOTFOUND
!= nFndPos
)
785 // Span the Attribute over the area and delete the Character found at
787 if( '*' == cInsChar
) // Bold
789 SvxWeightItem
aSvxWeightItem( WEIGHT_BOLD
, SID_ATTR_CHAR_WEIGHT
);
790 rDoc
.SetAttr( nFndPos
+ 1, nEndPos
,
791 SID_ATTR_CHAR_WEIGHT
,
796 SvxUnderlineItem
aSvxUnderlineItem( UNDERLINE_SINGLE
, SID_ATTR_CHAR_UNDERLINE
);
797 rDoc
.SetAttr( nFndPos
+ 1, nEndPos
,
798 SID_ATTR_CHAR_UNDERLINE
,
801 rDoc
.Delete( nEndPos
, nEndPos
+ 1 );
802 rDoc
.Delete( nFndPos
, nFndPos
+ 1 );
805 return STRING_NOTFOUND
!= nFndPos
;
809 sal_Bool
SvxAutoCorrect::FnCptlSttSntnc( SvxAutoCorrDoc
& rDoc
,
810 const String
& rTxt
, sal_Bool bNormalPos
,
811 xub_StrLen nSttPos
, xub_StrLen nEndPos
,
815 if( !rTxt
.Len() || nEndPos
<= nSttPos
)
818 CharClass
& rCC
= GetCharClass( eLang
);
819 String
aText( rTxt
);
820 const sal_Unicode
*pStart
= aText
.GetBuffer(),
821 *pStr
= pStart
+ nEndPos
,
825 sal_Bool bAtStart
= sal_False
;
829 aText
, sal::static_int_cast
< xub_StrLen
>( pStr
- pStart
) ) )
838 sal::static_int_cast
< xub_StrLen
>( pStr
- pStart
) ) )
840 if( lcl_IsInAsciiArr( sImplWordChars
, *pStr
) &&
841 pWordStt
- 1 == pStr
&&
842 // Installation at beginning of paragraph. Replaced < by <= (#i38971#)
843 (long)(pStart
+ 1) <= (long)pStr
&&
846 sal::static_int_cast
< xub_StrLen
>( pStr
-1 - pStart
) ) )
851 } while( 0 == ( bAtStart
= (pStart
== pStr
)) );
855 aText
, sal::static_int_cast
< xub_StrLen
>( pStr
- pStart
) ) ||
857 rCC
.getCharacterType(
859 sal::static_int_cast
< xub_StrLen
>( pWordStt
- pStart
) ) ) ||
860 INetURLObject::CompareProtocolScheme(rTxt
.Copy(pWordStt
- pStart
, pDelim
- pWordStt
+ 1)) != INET_PROT_NOT_VALID
||
861 0x1 == *pWordStt
|| 0x2 == *pWordStt
)
862 return sal_False
; // no character to be replaced, or already ok
864 if( *pDelim
&& 2 >= pDelim
- pWordStt
&&
865 lcl_IsInAsciiArr( ".-)>", *pDelim
) )
868 if( !bAtStart
) // Still no beginning of a paragraph?
870 if ( IsWordDelim( *pStr
) )
872 while( 0 == ( bAtStart
= (pStart
== pStr
--) ) && IsWordDelim( *pStr
))
875 // Asian full stop, full width full stop, full width exclamation mark
876 // and full width question marks are treated as word delimiters
877 else if ( 0x3002 != *pStr
&& 0xFF0E != *pStr
&& 0xFF01 != *pStr
&&
879 return sal_False
; // no valid separator -> no replacement
882 if( bAtStart
) // at the beginning of a paragraph?
884 // Check out the previous paragraph, if it exists.
885 // If so, then check to paragraph separator at the end.
886 const String
* pPrevPara
= rDoc
.GetPrevPara( bNormalPos
);
889 // valid separator -> replace
890 String
sChar( *pWordStt
);
891 sChar
= rCC
.titlecase( sChar
); //see fdo#56740
892 return sChar
!= *pWordStt
&&
893 rDoc
.ReplaceRange( xub_StrLen( pWordStt
- pStart
), 1, sChar
);
897 bAtStart
= sal_False
;
898 pStart
= aText
.GetBuffer();
899 pStr
= pStart
+ aText
.Len();
901 do { // overwrite all blanks
903 if( !IsWordDelim( *pStr
))
905 } while( 0 == ( bAtStart
= (pStart
== pStr
)) );
908 return sal_False
; // no valid separator -> no replacement
911 // Found [ \t]+[A-Z0-9]+ until here. Test now on the paragraph separator.
912 // all three can happen, but not more than once!
913 const sal_Unicode
* pExceptStt
= 0;
916 sal_Bool bWeiter
= sal_True
;
921 // Western and Asian full stop
926 if( nFlag
& C_FULL_STOP
)
927 return sal_False
; // no valid separator -> no replacement
928 nFlag
|= C_FULL_STOP
;
935 if( nFlag
& C_EXCLAMATION_MARK
)
936 return sal_False
; // no valid separator -> no replacement
937 nFlag
|= C_EXCLAMATION_MARK
;
943 if( nFlag
& C_QUESTION_MARK
)
944 return sal_False
; // no valid separator -> no replacement
945 nFlag
|= C_QUESTION_MARK
;
950 return sal_False
; // no valid separator -> no replacement
956 if( bWeiter
&& pStr
-- == pStart
)
958 return sal_False
; // no valid separator -> no replacement
961 if( C_FULL_STOP
!= nFlag
)
965 if( 2 > ( pStr
- pStart
) )
968 if( !rCC
.isLetterNumeric(
969 aText
, sal::static_int_cast
< xub_StrLen
>( pStr
-- - pStart
) ) )
971 sal_Bool bValid
= sal_False
, bAlphaFnd
= sal_False
;
972 const sal_Unicode
* pTmpStr
= pStr
;
977 sal::static_int_cast
< xub_StrLen
>( pTmpStr
- pStart
) ) )
982 else if( rCC
.isLetter(
984 sal::static_int_cast
< xub_StrLen
>(
985 pTmpStr
- pStart
) ) )
993 bAlphaFnd
= sal_True
;
995 else if( bAlphaFnd
|| IsWordDelim( *pTmpStr
) )
998 if( pTmpStr
== pStart
)
1005 return sal_False
; // no valid separator -> no replacement
1008 sal_Bool bNumericOnly
= '0' <= *(pStr
+1) && *(pStr
+1) <= '9';
1010 // Search for the beginning of the word
1011 while( !IsWordDelim( *pStr
))
1015 aText
, sal::static_int_cast
< xub_StrLen
>( pStr
- pStart
) ) )
1016 bNumericOnly
= sal_False
;
1018 if( pStart
== pStr
)
1024 if( bNumericOnly
) // consists of only numbers, then not
1027 if( IsWordDelim( *pStr
))
1032 // check on the basis of the exception list
1036 pStr
, sal::static_int_cast
< xub_StrLen
>( pExceptStt
- pStr
+ 1 ) );
1037 if( FindInCplSttExceptList(eLang
, sWord
) )
1040 // Delete all non alphanumeric. Test the characters at the
1041 // beginning/end of the word ( recognizes: "(min.", "/min.", and so on.)
1042 String
sTmp( sWord
);
1043 while( sTmp
.Len() &&
1044 !rCC
.isLetterNumeric( sTmp
, 0 ) )
1047 // Remove all non alphanumeric characters towards the end up until
1049 xub_StrLen nLen
= sTmp
.Len();
1050 while( nLen
&& !rCC
.isLetterNumeric( sTmp
, nLen
-1 ) )
1052 if( nLen
+ 1 < sTmp
.Len() )
1053 sTmp
.Erase( nLen
+ 1 );
1055 if( sTmp
.Len() && sTmp
.Len() != sWord
.Len() &&
1056 FindInCplSttExceptList(eLang
, sTmp
))
1059 if(FindInCplSttExceptList(eLang
, sWord
, sal_True
))
1064 sal_Unicode cSave
= *pWordStt
;
1065 nSttPos
= sal::static_int_cast
< xub_StrLen
>( pWordStt
- rTxt
.GetBuffer() );
1066 String
sChar( cSave
);
1067 sChar
= rCC
.titlecase( sChar
); //see fdo#56740
1068 sal_Bool bRet
= sChar
.GetChar(0) != cSave
&& rDoc
.ReplaceRange( nSttPos
, 1, sChar
);
1070 // Parahaps someone wants to have the word
1071 if( bRet
&& SaveWordCplSttLst
& nFlags
)
1072 rDoc
.SaveCpltSttWord( CptlSttSntnc
, nSttPos
, sWord
, cSave
);
1077 bool SvxAutoCorrect::FnCorrectCapsLock( SvxAutoCorrDoc
& rDoc
, const String
& rTxt
,
1078 xub_StrLen nSttPos
, xub_StrLen nEndPos
,
1079 LanguageType eLang
)
1081 if (nEndPos
- nSttPos
< 2)
1082 // string must be at least 2-character long.
1085 CharClass
& rCC
= GetCharClass( eLang
);
1087 // Check the first 2 letters.
1088 if ( !IsLowerLetter(rCC
.getCharacterType(rTxt
, nSttPos
)) )
1091 if ( !IsUpperLetter(rCC
.getCharacterType(rTxt
, nSttPos
+1)) )
1095 aConverted
.Append( rCC
.uppercase(rtl::OUString(rTxt
.GetChar(nSttPos
))) );
1096 aConverted
.Append( rCC
.lowercase(rtl::OUString(rTxt
.GetChar(nSttPos
+1))) );
1098 for (xub_StrLen i
= nSttPos
+2; i
< nEndPos
; ++i
)
1100 if ( IsLowerLetter(rCC
.getCharacterType(rTxt
, i
)) )
1101 // A lowercase letter disqualifies the whole text.
1104 if ( IsUpperLetter(rCC
.getCharacterType(rTxt
, i
)) )
1105 // Another uppercase letter. Convert it.
1106 aConverted
.Append( rCC
.lowercase(String(rTxt
.GetChar(i
))) );
1108 // This is not an alphabetic letter. Leave it as-is.
1109 aConverted
.Append(rTxt
.GetChar(i
));
1112 // Replace the word.
1113 rDoc
.Delete(nSttPos
, nEndPos
);
1114 rDoc
.Insert(nSttPos
, aConverted
);
1120 sal_Unicode
SvxAutoCorrect::GetQuote( sal_Unicode cInsChar
, sal_Bool bSttQuote
,
1121 LanguageType eLang
) const
1123 sal_Unicode cRet
= bSttQuote
? ( '\"' == cInsChar
1124 ? GetStartDoubleQuote()
1125 : GetStartSingleQuote() )
1126 : ( '\"' == cInsChar
1127 ? GetEndDoubleQuote()
1128 : GetEndSingleQuote() );
1131 // then through the Language find the right character
1132 if( LANGUAGE_NONE
== eLang
)
1136 LocaleDataWrapper
& rLcl
= GetLocaleDataWrapper( eLang
);
1137 String
sRet( bSttQuote
1138 ? ( '\"' == cInsChar
1139 ? rLcl
.getDoubleQuotationMarkStart()
1140 : rLcl
.getQuotationMarkStart() )
1141 : ( '\"' == cInsChar
1142 ? rLcl
.getDoubleQuotationMarkEnd()
1143 : rLcl
.getQuotationMarkEnd() ));
1144 cRet
= sRet
.Len() ? sRet
.GetChar( 0 ) : cInsChar
;
1150 void SvxAutoCorrect::InsertQuote( SvxAutoCorrDoc
& rDoc
, xub_StrLen nInsPos
,
1151 sal_Unicode cInsChar
, sal_Bool bSttQuote
,
1154 LanguageType eLang
= rDoc
.GetLanguage( nInsPos
, sal_False
);
1155 sal_Unicode cRet
= GetQuote( cInsChar
, bSttQuote
, eLang
);
1157 String
sChg( cInsChar
);
1159 rDoc
.Insert( nInsPos
, sChg
);
1161 rDoc
.Replace( nInsPos
, sChg
);
1165 if( '\"' == cInsChar
)
1167 if( LANGUAGE_SYSTEM
== eLang
)
1168 eLang
= GetAppLang();
1171 case LANGUAGE_FRENCH
:
1172 case LANGUAGE_FRENCH_BELGIAN
:
1173 case LANGUAGE_FRENCH_CANADIAN
:
1174 case LANGUAGE_FRENCH_SWISS
:
1175 case LANGUAGE_FRENCH_LUXEMBOURG
:
1177 String
s( static_cast< sal_Unicode
>(0xA0) );
1178 // UNICODE code for no break space
1179 if( rDoc
.Insert( bSttQuote
? nInsPos
+1 : nInsPos
, s
))
1189 rDoc
.Replace( nInsPos
, sChg
);
1192 String
SvxAutoCorrect::GetQuote( SvxAutoCorrDoc
& rDoc
, xub_StrLen nInsPos
,
1193 sal_Unicode cInsChar
, sal_Bool bSttQuote
)
1195 LanguageType eLang
= rDoc
.GetLanguage( nInsPos
, sal_False
);
1196 sal_Unicode cRet
= GetQuote( cInsChar
, bSttQuote
, eLang
);
1198 String
sRet( cRet
);
1200 if( '\"' == cInsChar
)
1202 if( LANGUAGE_SYSTEM
== eLang
)
1203 eLang
= GetAppLang();
1206 case LANGUAGE_FRENCH
:
1207 case LANGUAGE_FRENCH_BELGIAN
:
1208 case LANGUAGE_FRENCH_CANADIAN
:
1209 case LANGUAGE_FRENCH_SWISS
:
1210 case LANGUAGE_FRENCH_LUXEMBOURG
:
1214 sRet
.Insert( ' ', 0 );
1221 sal_uLong
SvxAutoCorrect::AutoCorrect( SvxAutoCorrDoc
& rDoc
, const String
& rTxt
,
1222 xub_StrLen nInsPos
, sal_Unicode cChar
,
1223 sal_Bool bInsert
, Window
* pFrameWin
)
1226 bool bIsNextRun
= bRunNext
;
1227 bRunNext
= false; // if it was set, then it has to be turned off
1229 do{ // only for middle check loop !!
1232 // Prevent double space
1233 if( nInsPos
&& ' ' == cChar
&&
1234 IsAutoCorrFlag( IgnoreDoubleSpace
) &&
1235 ' ' == rTxt
.GetChar( nInsPos
- 1 ) )
1237 nRet
= IgnoreDoubleSpace
;
1241 sal_Bool bSingle
= '\'' == cChar
;
1242 sal_Bool bIsReplaceQuote
=
1243 (IsAutoCorrFlag( ChgQuotes
) && ('\"' == cChar
)) ||
1244 (IsAutoCorrFlag( ChgSglQuotes
) && bSingle
);
1245 if( bIsReplaceQuote
)
1248 sal_Bool bSttQuote
= !nInsPos
||
1249 IsWordDelim( ( cPrev
= rTxt
.GetChar( nInsPos
-1 ))) ||
1250 lcl_IsInAsciiArr( "([{", cPrev
) ||
1251 ( cEmDash
&& cEmDash
== cPrev
) ||
1252 ( cEnDash
&& cEnDash
== cPrev
);
1254 InsertQuote( rDoc
, nInsPos
, cChar
, bSttQuote
, bInsert
);
1255 nRet
= bSingle
? ChgSglQuotes
: ChgQuotes
;
1260 rDoc
.Insert( nInsPos
, cChar
);
1262 rDoc
.Replace( nInsPos
, cChar
);
1264 // Hardspaces autocorrection
1265 if ( IsAutoCorrFlag( AddNonBrkSpace
) )
1267 if ( NeedsHardspaceAutocorr( cChar
) &&
1268 FnAddNonBrkSpace( rDoc
, rTxt
, 0, nInsPos
, rDoc
.GetLanguage( nInsPos
, sal_False
) ) )
1270 nRet
= AddNonBrkSpace
;
1272 else if ( bIsNextRun
&& !IsAutoCorrectChar( cChar
) )
1274 // Remove the NBSP if it wasn't an autocorrection
1275 if ( nInsPos
!= 0 && NeedsHardspaceAutocorr( rTxt
.GetChar( nInsPos
- 1 ) ) &&
1276 cChar
!= ' ' && cChar
!= '\t' && cChar
!= CHAR_HARDBLANK
)
1278 // Look for the last HARD_SPACE
1279 xub_StrLen nPos
= nInsPos
- 1;
1280 bool bContinue
= true;
1283 const sal_Unicode cTmpChar
= rTxt
.GetChar( nPos
);
1284 if ( cTmpChar
== CHAR_HARDBLANK
)
1286 rDoc
.Delete( nPos
, nPos
+ 1 );
1287 nRet
= AddNonBrkSpace
;
1290 else if ( !NeedsHardspaceAutocorr( cTmpChar
) || nPos
== 0 )
1302 xub_StrLen nPos
= nInsPos
- 1;
1304 if( IsWordDelim( rTxt
.GetChar( nPos
)))
1307 // Set bold or underline automatically?
1308 if( '*' == cChar
|| '_' == cChar
)
1310 if( IsAutoCorrFlag( ChgWeightUnderl
) &&
1311 FnChgWeightUnderl( rDoc
, rTxt
, 0, nPos
+1 ) )
1312 nRet
= ChgWeightUnderl
;
1316 while( nPos
&& !IsWordDelim( rTxt
.GetChar( --nPos
)))
1319 // Found a Paragraph-start or a Blank, search for the word shortcut in
1321 xub_StrLen nCapLttrPos
= nPos
+1; // on the 1st Character
1322 if( !nPos
&& !IsWordDelim( rTxt
.GetChar( 0 )))
1323 --nCapLttrPos
; // Absatz Anfang und kein Blank !
1325 LanguageType eLang
= rDoc
.GetLanguage( nCapLttrPos
, sal_False
);
1326 if( LANGUAGE_SYSTEM
== eLang
)
1327 eLang
= MsLangId::getSystemLanguage();
1328 CharClass
& rCC
= GetCharClass( eLang
);
1330 // no symbol characters
1331 if( lcl_IsSymbolChar( rCC
, rTxt
, nCapLttrPos
, nInsPos
))
1334 if( IsAutoCorrFlag( Autocorrect
) )
1336 const String
* pPara
= 0;
1337 const String
** ppPara
= IsAutoCorrFlag(CptlSttSntnc
) ? &pPara
: 0;
1339 sal_Bool bChgWord
= rDoc
.ChgAutoCorrWord( nCapLttrPos
, nInsPos
,
1343 xub_StrLen nCapLttrPos1
= nCapLttrPos
, nInsPos1
= nInsPos
;
1344 while( nCapLttrPos1
< nInsPos
&&
1345 lcl_IsInAsciiArr( sImplSttSkipChars
, rTxt
.GetChar( nCapLttrPos1
) )
1348 while( nCapLttrPos1
< nInsPos1
&& nInsPos1
&&
1349 lcl_IsInAsciiArr( sImplEndSkipChars
, rTxt
.GetChar( nInsPos1
-1 ) )
1353 if( (nCapLttrPos1
!= nCapLttrPos
|| nInsPos1
!= nInsPos
) &&
1354 nCapLttrPos1
< nInsPos1
&&
1355 rDoc
.ChgAutoCorrWord( nCapLttrPos1
, nInsPos1
, *this, ppPara
))
1357 bChgWord
= sal_True
;
1358 nCapLttrPos
= nCapLttrPos1
;
1367 xub_StrLen nEnd
= nCapLttrPos
;
1368 while( nEnd
< pPara
->Len() &&
1369 !IsWordDelim( pPara
->GetChar( nEnd
)))
1372 // Capital letter at beginning of paragraph?
1373 if( IsAutoCorrFlag( CptlSttSntnc
) &&
1374 FnCptlSttSntnc( rDoc
, *pPara
, sal_False
,
1375 nCapLttrPos
, nEnd
, eLang
) )
1376 nRet
|= CptlSttSntnc
;
1378 if( IsAutoCorrFlag( ChgToEnEmDash
) &&
1379 FnChgToEnEmDash( rDoc
, rTxt
, nCapLttrPos
, nEnd
, eLang
) )
1380 nRet
|= ChgToEnEmDash
;
1386 if( ( IsAutoCorrFlag( nRet
= ChgOrdinalNumber
) &&
1387 FnChgOrdinalNumber( rDoc
, rTxt
, nCapLttrPos
, nInsPos
, eLang
) ) ||
1388 ( IsAutoCorrFlag( nRet
= SetINetAttr
) &&
1389 ( ' ' == cChar
|| '\t' == cChar
|| 0x0a == cChar
|| !cChar
) &&
1390 FnSetINetAttr( rDoc
, rTxt
, nCapLttrPos
, nInsPos
, eLang
) ) )
1394 bool bLockKeyOn
= pFrameWin
&& (pFrameWin
->GetIndicatorState() & INDICATOR_CAPSLOCK
);
1397 if ( bLockKeyOn
&& IsAutoCorrFlag( CorrectCapsLock
) &&
1398 FnCorrectCapsLock( rDoc
, rTxt
, nCapLttrPos
, nInsPos
, eLang
) )
1400 // Correct accidental use of cAPS LOCK key (do this only when
1401 // the caps or shift lock key is pressed). Turn off the caps
1403 nRet
|= CorrectCapsLock
;
1404 pFrameWin
->SimulateKeyPress( KEY_CAPSLOCK
);
1407 // Capital letter at beginning of paragraph ?
1408 if( IsAutoCorrFlag( CptlSttSntnc
) &&
1409 FnCptlSttSntnc( rDoc
, rTxt
, sal_True
, nCapLttrPos
, nInsPos
, eLang
) )
1410 nRet
|= CptlSttSntnc
;
1412 // Two capital letters at beginning of word ??
1413 if( IsAutoCorrFlag( CptlSttWrd
) &&
1414 FnCptlSttWrd( rDoc
, rTxt
, nCapLttrPos
, nInsPos
, eLang
) )
1417 if( IsAutoCorrFlag( ChgToEnEmDash
) &&
1418 FnChgToEnEmDash( rDoc
, rTxt
, nCapLttrPos
, nInsPos
, eLang
) )
1419 nRet
|= ChgToEnEmDash
;
1422 } while( sal_False
);
1426 const char* aHelpIds
[] =
1428 HID_AUTOCORR_HELP_WORD
,
1429 HID_AUTOCORR_HELP_SENT
,
1430 HID_AUTOCORR_HELP_SENTWORD
,
1431 HID_AUTOCORR_HELP_ACORWORD
,
1433 HID_AUTOCORR_HELP_ACORSENTWORD
,
1435 HID_AUTOCORR_HELP_CHGTOENEMDASH
,
1436 HID_AUTOCORR_HELP_WORDENEMDASH
,
1437 HID_AUTOCORR_HELP_SENTENEMDASH
,
1438 HID_AUTOCORR_HELP_SENTWORDENEMDASH
,
1439 HID_AUTOCORR_HELP_ACORWORDENEMDASH
,
1441 HID_AUTOCORR_HELP_ACORSENTWORDENEMDASH
,
1443 HID_AUTOCORR_HELP_CHGQUOTES
,
1444 HID_AUTOCORR_HELP_CHGSGLQUOTES
,
1445 HID_AUTOCORR_HELP_SETINETATTR
,
1446 HID_AUTOCORR_HELP_INGNOREDOUBLESPACE
,
1447 HID_AUTOCORR_HELP_CHGWEIGHTUNDERL
,
1448 HID_AUTOCORR_HELP_CHGFRACTIONSYMBOL
,
1449 HID_AUTOCORR_HELP_CHGORDINALNUMBER
1452 sal_uLong nHelpId
= 0;
1453 if( nRet
& ( Autocorrect
|CptlSttSntnc
|CptlSttWrd
|ChgToEnEmDash
) )
1456 if( nRet
& ChgToEnEmDash
)
1458 if( nRet
& Autocorrect
)
1460 if( nRet
& CptlSttSntnc
)
1462 if( nRet
& CptlSttWrd
)
1467 if( nRet
& ChgQuotes
) nHelpId
= 16;
1468 else if( nRet
& ChgSglQuotes
) nHelpId
= 17;
1469 else if( nRet
& SetINetAttr
) nHelpId
= 18;
1470 else if( nRet
& IgnoreDoubleSpace
) nHelpId
= 19;
1471 else if( nRet
& ChgWeightUnderl
) nHelpId
= 20;
1472 else if( nRet
& AddNonBrkSpace
) nHelpId
= 21;
1473 else if( nRet
& ChgOrdinalNumber
) nHelpId
= 22;
1479 Application::GetHelp()->OpenHelpAgent( aHelpIds
[nHelpId
] );
1487 SvxAutoCorrectLanguageLists
& SvxAutoCorrect::_GetLanguageList(
1488 LanguageType eLang
)
1490 if(pLangTable
->find(eLang
) == pLangTable
->end())
1491 CreateLanguageFile(eLang
, sal_True
);
1492 return *(pLangTable
->find(eLang
)->second
);
1495 void SvxAutoCorrect::SaveCplSttExceptList( LanguageType eLang
)
1497 boost::ptr_map
<LanguageType
, SvxAutoCorrectLanguageLists
>::iterator nTmpVal
= pLangTable
->find(eLang
);
1498 if(nTmpVal
!= pLangTable
->end() && nTmpVal
->second
)
1499 nTmpVal
->second
->SaveCplSttExceptList();
1503 OSL_FAIL("Save an empty list? ");
1508 void SvxAutoCorrect::SaveWrdSttExceptList(LanguageType eLang
)
1510 boost::ptr_map
<LanguageType
, SvxAutoCorrectLanguageLists
>::iterator nTmpVal
= pLangTable
->find(eLang
);
1511 if(nTmpVal
!= pLangTable
->end() && nTmpVal
->second
)
1512 nTmpVal
->second
->SaveWrdSttExceptList();
1516 OSL_FAIL("Save an empty list? ");
1521 // Adds a single word. The list will immediately be written to the file!
1522 sal_Bool
SvxAutoCorrect::AddCplSttException( const String
& rNew
,
1523 LanguageType eLang
)
1525 SvxAutoCorrectLanguageLists
* pLists
= 0;
1526 // either the right language is present or it will be this in the general list
1527 boost::ptr_map
<LanguageType
, SvxAutoCorrectLanguageLists
>::iterator nTmpVal
= pLangTable
->find(eLang
);
1528 if(nTmpVal
!= pLangTable
->end())
1529 pLists
= nTmpVal
->second
;
1532 nTmpVal
= pLangTable
->find(LANGUAGE_DONTKNOW
);
1533 if(nTmpVal
!= pLangTable
->end())
1534 pLists
= nTmpVal
->second
;
1535 else if(CreateLanguageFile(LANGUAGE_DONTKNOW
, sal_True
))
1536 pLists
= pLangTable
->find(LANGUAGE_DONTKNOW
)->second
;
1538 OSL_ENSURE(pLists
, "No auto correction data");
1539 return pLists
->AddToCplSttExceptList(rNew
);
1542 // Adds a single word. The list will immediately be written to the file!
1543 sal_Bool
SvxAutoCorrect::AddWrtSttException( const String
& rNew
,
1544 LanguageType eLang
)
1546 SvxAutoCorrectLanguageLists
* pLists
= 0;
1547 //either the right language is present or it is set in the general list
1548 boost::ptr_map
<LanguageType
, SvxAutoCorrectLanguageLists
>::iterator nTmpVal
= pLangTable
->find(eLang
);
1549 if(nTmpVal
!= pLangTable
->end())
1550 pLists
= nTmpVal
->second
;
1553 nTmpVal
= pLangTable
->find(LANGUAGE_DONTKNOW
);
1554 if(nTmpVal
!= pLangTable
->end())
1555 pLists
= nTmpVal
->second
;
1556 else if(CreateLanguageFile(LANGUAGE_DONTKNOW
, sal_True
))
1557 pLists
= pLangTable
->find(LANGUAGE_DONTKNOW
)->second
;
1559 OSL_ENSURE(pLists
, "keine Autokorrekturdatei");
1560 return pLists
->AddToWrdSttExceptList(rNew
);
1563 sal_Bool
SvxAutoCorrect::GetPrevAutoCorrWord( SvxAutoCorrDoc
& rDoc
,
1564 const String
& rTxt
, xub_StrLen nPos
,
1565 String
& rWord
) const
1570 xub_StrLen nEnde
= nPos
;
1572 // it must be followed by a blank or tab!
1573 if( ( nPos
< rTxt
.Len() &&
1574 !IsWordDelim( rTxt
.GetChar( nPos
))) ||
1575 IsWordDelim( rTxt
.GetChar( --nPos
)))
1578 while( nPos
&& !IsWordDelim( rTxt
.GetChar( --nPos
)))
1581 // Found a Paragraph-start or a Blank, search for the word shortcut in
1583 xub_StrLen nCapLttrPos
= nPos
+1; // on the 1st Character
1584 if( !nPos
&& !IsWordDelim( rTxt
.GetChar( 0 )))
1585 --nCapLttrPos
; // Beginning of pargraph and no Blank!
1587 while( lcl_IsInAsciiArr( sImplSttSkipChars
, rTxt
.GetChar( nCapLttrPos
)) )
1588 if( ++nCapLttrPos
>= nEnde
)
1591 if( 3 > nEnde
- nCapLttrPos
)
1594 LanguageType eLang
= rDoc
.GetLanguage( nCapLttrPos
, sal_False
);
1595 if( LANGUAGE_SYSTEM
== eLang
)
1596 eLang
= MsLangId::getSystemLanguage();
1598 SvxAutoCorrect
* pThis
= (SvxAutoCorrect
*)this;
1599 CharClass
& rCC
= pThis
->GetCharClass( eLang
);
1601 if( lcl_IsSymbolChar( rCC
, rTxt
, nCapLttrPos
, nEnde
))
1604 rWord
= rTxt
.Copy( nCapLttrPos
, nEnde
- nCapLttrPos
);
1608 sal_Bool
SvxAutoCorrect::CreateLanguageFile( LanguageType eLang
, sal_Bool bNewFile
)
1610 OSL_ENSURE(pLangTable
->find(eLang
) == pLangTable
->end(), "Language already exists ");
1612 String
sUserDirFile( GetAutoCorrFileName( eLang
, sal_True
, sal_False
)),
1613 sShareDirFile( sUserDirFile
);
1614 SvxAutoCorrectLanguageListsPtr pLists
= 0;
1616 Time
nMinTime( 0, 2 ), nAktTime( Time::SYSTEM
), nLastCheckTime( Time::EMPTY
);
1618 std::map
<LanguageType
, long>::iterator nFndPos
= aLastFileTable
.find(eLang
);
1619 if(nFndPos
!= aLastFileTable
.end() &&
1620 (nLastCheckTime
.SetTime(nFndPos
->second
), nLastCheckTime
< nAktTime
) &&
1621 nAktTime
- nLastCheckTime
< nMinTime
)
1623 // no need to test the file, because the last check is not older then
1627 sShareDirFile
= sUserDirFile
;
1628 pLists
= new SvxAutoCorrectLanguageLists( *this, sShareDirFile
,
1629 sUserDirFile
, eLang
);
1630 pLangTable
->insert(eLang
, pLists
);
1631 aLastFileTable
.erase(nFndPos
);
1634 else if( ( FStatHelper::IsDocument( sUserDirFile
) ||
1635 FStatHelper::IsDocument( sShareDirFile
=
1636 GetAutoCorrFileName( eLang
, sal_False
, sal_False
) ) ) ||
1637 ( sShareDirFile
= sUserDirFile
, bNewFile
))
1639 pLists
= new SvxAutoCorrectLanguageLists( *this, sShareDirFile
,
1640 sUserDirFile
, eLang
);
1641 pLangTable
->insert(eLang
, pLists
);
1642 if (nFndPos
!= aLastFileTable
.end())
1643 aLastFileTable
.erase(nFndPos
);
1645 else if( !bNewFile
)
1647 aLastFileTable
[eLang
] = nAktTime
.GetTime();
1652 sal_Bool
SvxAutoCorrect::PutText( const String
& rShort
, const String
& rLong
,
1653 LanguageType eLang
)
1655 boost::ptr_map
<LanguageType
, SvxAutoCorrectLanguageLists
>::iterator nTmpVal
= pLangTable
->find(eLang
);
1656 if(nTmpVal
!= pLangTable
->end())
1657 return nTmpVal
->second
->PutText(rShort
, rLong
);
1658 if(CreateLanguageFile(eLang
))
1659 return pLangTable
->find(eLang
)->second
->PutText(rShort
, rLong
);
1663 // - Delete an entry
1664 sal_Bool
SvxAutoCorrect::DeleteText( const String
& rShort
, LanguageType eLang
)
1666 boost::ptr_map
<LanguageType
, SvxAutoCorrectLanguageLists
>::iterator nTmpVal
= pLangTable
->find(eLang
);
1667 if(nTmpVal
!= pLangTable
->end())
1668 return nTmpVal
->second
->DeleteText(rShort
);
1672 // - return the replacement text (only for SWG-Format, all other
1673 // can be taken from the word list!)
1674 sal_Bool
SvxAutoCorrect::GetLongText( const com::sun::star::uno::Reference
< com::sun::star::embed::XStorage
>&, const String
&, const String
& , String
& )
1679 // Text with attribution (only the SWG - SWG format!)
1680 sal_Bool
SvxAutoCorrect::PutText( const com::sun::star::uno::Reference
< com::sun::star::embed::XStorage
>&, const String
&, const String
&, SfxObjectShell
&,
1686 void EncryptBlockName_Imp( String
& rName
)
1688 xub_StrLen nLen
, nPos
= 1;
1689 rName
.Insert( '#', 0 );
1690 sal_Unicode
* pName
= rName
.GetBufferAccess();
1691 for ( nLen
= rName
.Len(), ++pName
; nPos
< nLen
; ++nPos
, ++pName
)
1693 if( lcl_IsInAsciiArr( "!/:.\\", *pName
))
1698 /* This code is copied from SwXMLTextBlocks::GeneratePackageName */
1699 static void GeneratePackageName ( const String
& rShort
, String
& rPackageName
)
1701 rPackageName
= rShort
;
1702 xub_StrLen nPos
= 0;
1703 sal_Unicode pDelims
[] = { '!', '/', ':', '.', '\\', 0 };
1704 rtl::OString
sByte(rtl::OUStringToOString(rPackageName
, RTL_TEXTENCODING_UTF7
));
1705 rPackageName
= rtl::OStringToOUString(sByte
, RTL_TEXTENCODING_ASCII_US
);
1706 while( STRING_NOTFOUND
!= ( nPos
= rPackageName
.SearchChar( pDelims
, nPos
)))
1708 rPackageName
.SetChar( nPos
, '_' );
1713 static const SvxAutocorrWord
* lcl_SearchWordsInList(
1714 SvxAutoCorrectLanguageListsPtr pList
, const String
& rTxt
,
1715 xub_StrLen
& rStt
, xub_StrLen nEndPos
, SvxAutoCorrDoc
& )
1717 const SvxAutocorrWordList
* pAutoCorrWordList
= pList
->GetAutocorrWordList();
1718 TransliterationWrapper
& rCmp
= GetIgnoreTranslWrapper();
1719 for( xub_StrLen nPos
= 0; nPos
< pAutoCorrWordList
->Count(); ++nPos
)
1721 const SvxAutocorrWord
* pFnd
= (*pAutoCorrWordList
)[ nPos
];
1722 const String
& rChk
= pFnd
->GetShort();
1723 if( nEndPos
>= rChk
.Len() )
1725 xub_StrLen nCalcStt
= nEndPos
- rChk
.Len();
1726 if( ( !nCalcStt
|| nCalcStt
== rStt
||
1727 ( nCalcStt
< rStt
&&
1728 IsWordDelim( rTxt
.GetChar(nCalcStt
- 1 ) ))) )
1730 String
sWord( rTxt
.GetBuffer() + nCalcStt
, rChk
.Len() );
1731 if( rCmp
.isEqual( rChk
, sWord
))
1743 // the search or the words in the substitution table
1744 const SvxAutocorrWord
* SvxAutoCorrect::SearchWordsInList(
1745 const String
& rTxt
, xub_StrLen
& rStt
, xub_StrLen nEndPos
,
1746 SvxAutoCorrDoc
& rDoc
, LanguageType
& rLang
)
1748 LanguageType eLang
= rLang
;
1749 const SvxAutocorrWord
* pRet
= 0;
1750 if( LANGUAGE_SYSTEM
== eLang
)
1751 eLang
= MsLangId::getSystemLanguage();
1753 // First search for eLang, then US-English -> English
1754 // and last in LANGUAGE_DONTKNOW
1755 if(pLangTable
->find(eLang
) != pLangTable
->end() || CreateLanguageFile(eLang
, sal_False
))
1757 //the language is available - so bring it on
1758 SvxAutoCorrectLanguageLists
* pList
= pLangTable
->find(eLang
)->second
;
1759 pRet
= lcl_SearchWordsInList( pList
, rTxt
, rStt
, nEndPos
, rDoc
);
1767 // If it still could not be found here, then keep on searching
1769 LanguageType nTmpKey1
= eLang
& 0x7ff, // the main language in many cases DE
1770 nTmpKey2
= eLang
& 0x3ff; // otherwise for example EN
1771 if(nTmpKey1
!= eLang
&& (pLangTable
->find(nTmpKey1
) != pLangTable
->end() || CreateLanguageFile(nTmpKey1
, sal_False
)))
1773 //the language is available - so bring it on
1774 SvxAutoCorrectLanguageLists
* pList
= pLangTable
->find(nTmpKey1
)->second
;
1775 pRet
= lcl_SearchWordsInList( pList
, rTxt
, rStt
, nEndPos
, rDoc
);
1783 if(nTmpKey2
!= eLang
&& (pLangTable
->find(nTmpKey2
) != pLangTable
->end() || CreateLanguageFile(nTmpKey2
, sal_False
)))
1785 //the language is available - so bring it on
1786 SvxAutoCorrectLanguageLists
* pList
= pLangTable
->find(nTmpKey2
)->second
;
1787 pRet
= lcl_SearchWordsInList( pList
, rTxt
, rStt
, nEndPos
, rDoc
);
1795 if(pLangTable
->find(LANGUAGE_DONTKNOW
) != pLangTable
->end() || CreateLanguageFile(LANGUAGE_DONTKNOW
, sal_False
))
1797 //the language is available - so bring it on
1798 SvxAutoCorrectLanguageLists
* pList
= pLangTable
->find(LANGUAGE_DONTKNOW
)->second
;
1799 pRet
= lcl_SearchWordsInList( pList
, rTxt
, rStt
, nEndPos
, rDoc
);
1802 rLang
= LANGUAGE_DONTKNOW
;
1809 sal_Bool
SvxAutoCorrect::FindInWrdSttExceptList( LanguageType eLang
,
1810 const String
& sWord
)
1812 // First search for eLang, then US-English -> English
1813 // and last in LANGUAGE_DONTKNOW
1814 LanguageType nTmpKey1
= eLang
& 0x7ff, // the main language in many cases DE
1815 nTmpKey2
= eLang
& 0x3ff; // otherwise for example EN
1816 String
sTemp(sWord
);
1818 if(pLangTable
->find(eLang
) != pLangTable
->end() || CreateLanguageFile(eLang
, sal_False
))
1820 //the language is available - so bring it on
1821 SvxAutoCorrectLanguageLists
* pList
= pLangTable
->find(eLang
)->second
;
1822 String
_sTemp(sWord
);
1823 if(pList
->GetWrdSttExceptList()->Seek_Entry(&_sTemp
))
1827 // If it still could not be found here, then keep on searching
1828 if(nTmpKey1
!= eLang
&& (pLangTable
->find(nTmpKey1
) != pLangTable
->end() || CreateLanguageFile(nTmpKey1
, sal_False
)))
1830 //the language is available - so bring it on
1831 SvxAutoCorrectLanguageLists
* pList
= pLangTable
->find(nTmpKey1
)->second
;
1832 if(pList
->GetWrdSttExceptList()->Seek_Entry(&sTemp
))
1836 if(nTmpKey2
!= eLang
&& (pLangTable
->find(nTmpKey2
) != pLangTable
->end() || CreateLanguageFile(nTmpKey2
, sal_False
)))
1838 //the language is available - so bring it on
1839 SvxAutoCorrectLanguageLists
* pList
= pLangTable
->find(nTmpKey2
)->second
;
1840 if(pList
->GetWrdSttExceptList()->Seek_Entry(&sTemp
))
1844 if(pLangTable
->find(LANGUAGE_DONTKNOW
) != pLangTable
->end() || CreateLanguageFile(LANGUAGE_DONTKNOW
, sal_False
))
1846 //the language is available - so bring it on
1847 SvxAutoCorrectLanguageLists
* pList
= pLangTable
->find(LANGUAGE_DONTKNOW
)->second
;
1848 if(pList
->GetWrdSttExceptList()->Seek_Entry(&sTemp
))
1854 static sal_Bool
lcl_FindAbbreviation( const SvStringsISortDtor
* pList
, const String
& sWord
)
1858 pList
->Seek_Entry( &sAbk
, &nPos
);
1859 if( nPos
< pList
->Count() )
1861 String
sLowerWord( sWord
); sLowerWord
.ToLowerAscii();
1863 for( sal_uInt16 n
= nPos
;
1864 n
< pList
->Count() &&
1865 '~' == ( pAbk
= (*pList
)[ n
])->GetChar( 0 );
1868 // ~ and ~. are not allowed!
1869 if( 2 < pAbk
->Len() && pAbk
->Len() - 1 <= sWord
.Len() )
1871 String
sLowerAbk( *pAbk
); sLowerAbk
.ToLowerAscii();
1872 for( xub_StrLen i
= sLowerAbk
.Len(), ii
= sLowerWord
.Len(); i
; )
1874 if( !--i
) // agrees
1877 if( sLowerAbk
.GetChar( i
) != sLowerWord
.GetChar( --ii
))
1883 OSL_ENSURE( !(nPos
&& '~' == (*pList
)[ --nPos
]->GetChar( 0 ) ),
1884 "Wrongly sorted exception list?" );
1888 sal_Bool
SvxAutoCorrect::FindInCplSttExceptList(LanguageType eLang
,
1889 const String
& sWord
, sal_Bool bAbbreviation
)
1891 // First search for eLang, then US-English -> English
1892 // and last in LANGUAGE_DONTKNOW
1893 LanguageType nTmpKey1
= eLang
& 0x7ff, // the main language in many cases DE
1894 nTmpKey2
= eLang
& 0x3ff; // otherwise for example EN
1895 String
sTemp( sWord
);
1897 if(pLangTable
->find(eLang
) != pLangTable
->end() || CreateLanguageFile(eLang
, sal_False
))
1899 //the language is available - so bring it on
1900 const SvStringsISortDtor
* pList
= pLangTable
->find(eLang
)->second
->GetCplSttExceptList();
1901 if(bAbbreviation
? lcl_FindAbbreviation(pList
, sWord
) : pList
->Seek_Entry(&sTemp
))
1905 // If it still could not be found here, then keep on searching
1906 if(nTmpKey1
!= eLang
&& (pLangTable
->find(nTmpKey1
) != pLangTable
->end() || CreateLanguageFile(nTmpKey1
, sal_False
)))
1908 const SvStringsISortDtor
* pList
= pLangTable
->find(nTmpKey1
)->second
->GetCplSttExceptList();
1909 if(bAbbreviation
? lcl_FindAbbreviation(pList
, sWord
) : pList
->Seek_Entry(&sTemp
))
1913 if(nTmpKey2
!= eLang
&& (pLangTable
->find(nTmpKey2
) != pLangTable
->end() || CreateLanguageFile(nTmpKey2
, sal_False
)))
1915 //the language is available - so bring it on
1916 const SvStringsISortDtor
* pList
= pLangTable
->find(nTmpKey2
)->second
->GetCplSttExceptList();
1917 if(bAbbreviation
? lcl_FindAbbreviation(pList
, sWord
) : pList
->Seek_Entry(&sTemp
))
1921 if(pLangTable
->find(LANGUAGE_DONTKNOW
) != pLangTable
->end() || CreateLanguageFile(LANGUAGE_DONTKNOW
, sal_False
))
1923 //the language is available - so bring it on
1924 const SvStringsISortDtor
* pList
= pLangTable
->find(LANGUAGE_DONTKNOW
)->second
->GetCplSttExceptList();
1925 if(bAbbreviation
? lcl_FindAbbreviation(pList
, sWord
) : pList
->Seek_Entry(&sTemp
))
1931 String
SvxAutoCorrect::GetAutoCorrFileName( LanguageType eLang
,
1932 sal_Bool bNewFile
, sal_Bool bTst
) const
1934 String sRet
, sExt( MsLangId::convertLanguageToIsoString( eLang
) );
1935 sExt
.Insert('_', 0);
1936 sExt
.AppendAscii( ".dat" );
1938 ( sRet
= sUserAutoCorrFile
) += sExt
;
1940 ( sRet
= sShareAutoCorrFile
) += sExt
;
1943 // test first in the user directory - if not exist, then
1944 ( sRet
= sUserAutoCorrFile
) += sExt
;
1945 if( !FStatHelper::IsDocument( sRet
))
1946 ( sRet
= sShareAutoCorrFile
) += sExt
;
1951 SvxAutoCorrectLanguageLists::SvxAutoCorrectLanguageLists(
1952 SvxAutoCorrect
& rParent
,
1953 const String
& rShareAutoCorrectFile
,
1954 const String
& rUserAutoCorrectFile
,
1956 : sShareAutoCorrFile( rShareAutoCorrectFile
),
1957 sUserAutoCorrFile( rUserAutoCorrectFile
),
1958 aModifiedDate( Date::EMPTY
),
1959 aModifiedTime( Time::EMPTY
),
1960 aLastCheckTime( Time::EMPTY
),
1962 pCplStt_ExcptLst( 0 ),
1963 pWrdStt_ExcptLst( 0 ),
1964 pAutocorr_List( 0 ),
1965 rAutoCorrect(rParent
),
1970 SvxAutoCorrectLanguageLists::~SvxAutoCorrectLanguageLists()
1972 delete pCplStt_ExcptLst
;
1973 delete pWrdStt_ExcptLst
;
1974 delete pAutocorr_List
;
1977 sal_Bool
SvxAutoCorrectLanguageLists::IsFileChanged_Imp()
1979 // Access the file system only every 2 minutes to check the date stamp
1980 sal_Bool bRet
= sal_False
;
1982 Time
nMinTime( 0, 2 );
1983 Time
nAktTime( Time::SYSTEM
);
1984 if( aLastCheckTime
> nAktTime
|| // overflow?
1985 ( nAktTime
-= aLastCheckTime
) > nMinTime
) // min time past
1987 Date
aTstDate( Date::EMPTY
); Time
aTstTime( Time::EMPTY
);
1988 if( FStatHelper::GetModifiedDateTimeOfFile( sShareAutoCorrFile
,
1989 &aTstDate
, &aTstTime
) &&
1990 ( aModifiedDate
!= aTstDate
|| aModifiedTime
!= aTstTime
))
1993 // then remove all the lists fast!
1994 if( CplSttLstLoad
& nFlags
&& pCplStt_ExcptLst
)
1995 delete pCplStt_ExcptLst
, pCplStt_ExcptLst
= 0;
1996 if( WrdSttLstLoad
& nFlags
&& pWrdStt_ExcptLst
)
1997 delete pWrdStt_ExcptLst
, pWrdStt_ExcptLst
= 0;
1998 if( ChgWordLstLoad
& nFlags
&& pAutocorr_List
)
1999 delete pAutocorr_List
, pAutocorr_List
= 0;
2000 nFlags
&= ~(CplSttLstLoad
| WrdSttLstLoad
| ChgWordLstLoad
);
2002 aLastCheckTime
= Time( Time::SYSTEM
);
2007 void SvxAutoCorrectLanguageLists::LoadXMLExceptList_Imp(
2008 SvStringsISortDtor
*& rpLst
,
2009 const sal_Char
* pStrmName
,
2010 SotStorageRef
& rStg
)
2013 rpLst
->DeleteAndDestroy( 0, rpLst
->Count() );
2015 rpLst
= new SvStringsISortDtor( 16 );
2018 String
sStrmName( pStrmName
, RTL_TEXTENCODING_MS_1252
);
2019 String
sTmp( sStrmName
);
2021 if( rStg
.Is() && rStg
->IsStream( sStrmName
) )
2023 SvStorageStreamRef xStrm
= rStg
->OpenSotStream( sTmp
,
2024 ( STREAM_READ
| STREAM_SHARE_DENYWRITE
| STREAM_NOCREATE
) );
2025 if( SVSTREAM_OK
!= xStrm
->GetError())
2029 RemoveStream_Imp( sStrmName
);
2033 uno::Reference
< lang::XMultiServiceFactory
> xServiceFactory
=
2034 comphelper::getProcessServiceFactory();
2035 OSL_ENSURE( xServiceFactory
.is(),
2036 "XMLReader::Read: got no service manager" );
2037 if( !xServiceFactory
.is() )
2039 // Throw an exception ?
2042 xml::sax::InputSource aParserInput
;
2043 aParserInput
.sSystemId
= sStrmName
;
2046 xStrm
->SetBufferSize( 8 * 1024 );
2047 aParserInput
.aInputStream
= new utl::OInputStreamWrapper( *xStrm
);
2050 uno::Reference
< XInterface
> xXMLParser
= xServiceFactory
->createInstance(
2051 OUString("com.sun.star.xml.sax.Parser") );
2052 OSL_ENSURE( xXMLParser
.is(),
2053 "XMLReader::Read: com.sun.star.xml.sax.Parser service missing" );
2054 if( !xXMLParser
.is() )
2056 // Maybe throw an exception?
2060 uno::Reference
< xml::sax::XDocumentHandler
> xFilter
= new SvXMLExceptionListImport ( xServiceFactory
, *rpLst
);
2062 // connect parser and filter
2063 uno::Reference
< xml::sax::XParser
> xParser( xXMLParser
, UNO_QUERY
);
2064 xParser
->setDocumentHandler( xFilter
);
2069 xParser
->parseStream( aParserInput
);
2071 catch( const xml::sax::SAXParseException
& )
2075 catch( const xml::sax::SAXException
& )
2079 catch( const io::IOException
& )
2087 FStatHelper::GetModifiedDateTimeOfFile( sShareAutoCorrFile
,
2088 &aModifiedDate
, &aModifiedTime
);
2089 aLastCheckTime
= Time( Time::SYSTEM
);
2094 void SvxAutoCorrectLanguageLists::SaveExceptList_Imp(
2095 const SvStringsISortDtor
& rLst
,
2096 const sal_Char
* pStrmName
,
2097 SotStorageRef
&rStg
,
2102 String
sStrmName( pStrmName
, RTL_TEXTENCODING_MS_1252
);
2105 rStg
->Remove( sStrmName
);
2110 SotStorageStreamRef xStrm
= rStg
->OpenSotStream( sStrmName
,
2111 ( STREAM_READ
| STREAM_WRITE
| STREAM_SHARE_DENYWRITE
) );
2114 xStrm
->SetSize( 0 );
2115 xStrm
->SetBufferSize( 8192 );
2116 String
aPropName( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM("MediaType") ) );
2117 OUString
aMime( "text/xml" );
2120 xStrm
->SetProperty( aPropName
, aAny
);
2123 uno::Reference
< lang::XMultiServiceFactory
> xServiceFactory
=
2124 comphelper::getProcessServiceFactory();
2125 OSL_ENSURE( xServiceFactory
.is(),
2126 "XMLReader::Read: got no service manager" );
2127 if( !xServiceFactory
.is() )
2129 // Throw an exception ?
2132 uno::Reference
< XInterface
> xWriter (xServiceFactory
->createInstance(
2133 OUString("com.sun.star.xml.sax.Writer")));
2134 OSL_ENSURE(xWriter
.is(),"com.sun.star.xml.sax.Writer service missing");
2135 uno::Reference
< io::XOutputStream
> xOut
= new utl::OOutputStreamWrapper( *xStrm
);
2136 uno::Reference
<io::XActiveDataSource
> xSrc(xWriter
, uno::UNO_QUERY
);
2137 xSrc
->setOutputStream(xOut
);
2139 uno::Reference
<xml::sax::XDocumentHandler
> xHandler(xWriter
, uno::UNO_QUERY
);
2141 SvXMLExceptionListExport
aExp( xServiceFactory
, rLst
, sStrmName
, xHandler
);
2143 aExp
.exportDoc( XML_BLOCK_LIST
);
2146 if( xStrm
->GetError() == SVSTREAM_OK
)
2152 if( SVSTREAM_OK
!= rStg
->GetError() )
2154 rStg
->Remove( sStrmName
);
2164 SvxAutocorrWordList
* SvxAutoCorrectLanguageLists::LoadAutocorrWordList()
2166 if( pAutocorr_List
)
2167 pAutocorr_List
->DeleteAndDestroy( 0, pAutocorr_List
->Count() );
2169 pAutocorr_List
= new SvxAutocorrWordList( 16 );
2173 uno::Reference
< embed::XStorage
> xStg
= comphelper::OStorageHelper::GetStorageFromURL( sShareAutoCorrFile
, embed::ElementModes::READ
);
2174 String
aXMLWordListName( pXMLImplAutocorr_ListStr
, RTL_TEXTENCODING_MS_1252
);
2175 uno::Reference
< io::XStream
> xStrm
= xStg
->openStreamElement( aXMLWordListName
, embed::ElementModes::READ
);
2176 uno::Reference
< lang::XMultiServiceFactory
> xServiceFactory
= comphelper::getProcessServiceFactory();
2178 xml::sax::InputSource aParserInput
;
2179 aParserInput
.sSystemId
= aXMLWordListName
;
2180 aParserInput
.aInputStream
= xStrm
->getInputStream();
2183 uno::Reference
< XInterface
> xXMLParser
= xServiceFactory
->createInstance( OUString("com.sun.star.xml.sax.Parser") );
2184 OSL_ENSURE( xXMLParser
.is(), "XMLReader::Read: com.sun.star.xml.sax.Parser service missing" );
2185 if( xXMLParser
.is() )
2187 RTL_LOGFILE_PRODUCT_CONTEXT( aLog
, "AutoCorrect Import" );
2188 uno::Reference
< xml::sax::XDocumentHandler
> xFilter
= new SvXMLAutoCorrectImport( xServiceFactory
, pAutocorr_List
, rAutoCorrect
, xStg
);
2190 // connect parser and filter
2191 uno::Reference
< xml::sax::XParser
> xParser( xXMLParser
, UNO_QUERY
);
2192 xParser
->setDocumentHandler( xFilter
);
2195 xParser
->parseStream( aParserInput
);
2198 catch ( const uno::Exception
& )
2203 FStatHelper::GetModifiedDateTimeOfFile( sShareAutoCorrFile
,
2204 &aModifiedDate
, &aModifiedTime
);
2205 aLastCheckTime
= Time( Time::SYSTEM
);
2207 return pAutocorr_List
;
2210 void SvxAutoCorrectLanguageLists::SetAutocorrWordList( SvxAutocorrWordList
* pList
)
2212 if( pAutocorr_List
&& pList
!= pAutocorr_List
)
2213 delete pAutocorr_List
;
2214 pAutocorr_List
= pList
;
2215 if( !pAutocorr_List
)
2217 OSL_ENSURE( !this, "No valid list" );
2218 pAutocorr_List
= new SvxAutocorrWordList( 16 );
2220 nFlags
|= ChgWordLstLoad
;
2223 const SvxAutocorrWordList
* SvxAutoCorrectLanguageLists::GetAutocorrWordList()
2225 if( !( ChgWordLstLoad
& nFlags
) || IsFileChanged_Imp() )
2226 SetAutocorrWordList( LoadAutocorrWordList() );
2227 return pAutocorr_List
;
2230 SvStringsISortDtor
* SvxAutoCorrectLanguageLists::GetCplSttExceptList()
2232 if( !( CplSttLstLoad
& nFlags
) || IsFileChanged_Imp() )
2233 SetCplSttExceptList( LoadCplSttExceptList() );
2234 return pCplStt_ExcptLst
;
2237 sal_Bool
SvxAutoCorrectLanguageLists::AddToCplSttExceptList(const String
& rNew
)
2239 String
* pNew
= new String( rNew
);
2240 if( rNew
.Len() && GetCplSttExceptList()->Insert( pNew
) )
2242 MakeUserStorage_Impl();
2243 SotStorageRef xStg
= new SotStorage( sUserAutoCorrFile
, STREAM_READWRITE
, sal_True
);
2245 SaveExceptList_Imp( *pCplStt_ExcptLst
, pXMLImplCplStt_ExcptLstStr
, xStg
);
2249 FStatHelper::GetModifiedDateTimeOfFile( sUserAutoCorrFile
,
2250 &aModifiedDate
, &aModifiedTime
);
2251 aLastCheckTime
= Time( Time::SYSTEM
);
2254 delete pNew
, pNew
= 0;
2258 sal_Bool
SvxAutoCorrectLanguageLists::AddToWrdSttExceptList(const String
& rNew
)
2260 String
* pNew
= new String( rNew
);
2261 SvStringsISortDtor
* pExceptList
= LoadWrdSttExceptList();
2262 if( rNew
.Len() && pExceptList
&& pExceptList
->Insert( pNew
) )
2264 MakeUserStorage_Impl();
2265 SotStorageRef xStg
= new SotStorage( sUserAutoCorrFile
, STREAM_READWRITE
, sal_True
);
2267 SaveExceptList_Imp( *pWrdStt_ExcptLst
, pXMLImplWrdStt_ExcptLstStr
, xStg
);
2271 FStatHelper::GetModifiedDateTimeOfFile( sUserAutoCorrFile
,
2272 &aModifiedDate
, &aModifiedTime
);
2273 aLastCheckTime
= Time( Time::SYSTEM
);
2276 delete pNew
, pNew
= 0;
2280 SvStringsISortDtor
* SvxAutoCorrectLanguageLists::LoadCplSttExceptList()
2282 SotStorageRef xStg
= new SotStorage( sShareAutoCorrFile
, STREAM_READ
| STREAM_SHARE_DENYNONE
, sal_True
);
2283 String
sTemp ( RTL_CONSTASCII_USTRINGPARAM ( pXMLImplCplStt_ExcptLstStr
) );
2284 if( xStg
.Is() && xStg
->IsContained( sTemp
) )
2285 LoadXMLExceptList_Imp( pCplStt_ExcptLst
, pXMLImplCplStt_ExcptLstStr
, xStg
);
2287 return pCplStt_ExcptLst
;
2290 void SvxAutoCorrectLanguageLists::SaveCplSttExceptList()
2292 MakeUserStorage_Impl();
2293 SotStorageRef xStg
= new SotStorage( sUserAutoCorrFile
, STREAM_READWRITE
, sal_True
);
2295 SaveExceptList_Imp( *pCplStt_ExcptLst
, pXMLImplCplStt_ExcptLstStr
, xStg
);
2300 FStatHelper::GetModifiedDateTimeOfFile( sUserAutoCorrFile
,
2301 &aModifiedDate
, &aModifiedTime
);
2302 aLastCheckTime
= Time( Time::SYSTEM
);
2305 void SvxAutoCorrectLanguageLists::SetCplSttExceptList( SvStringsISortDtor
* pList
)
2307 if( pCplStt_ExcptLst
&& pList
!= pCplStt_ExcptLst
)
2308 delete pCplStt_ExcptLst
;
2310 pCplStt_ExcptLst
= pList
;
2311 if( !pCplStt_ExcptLst
)
2313 OSL_ENSURE( !this, "No valid list" );
2314 pCplStt_ExcptLst
= new SvStringsISortDtor( 16 );
2316 nFlags
|= CplSttLstLoad
;
2319 SvStringsISortDtor
* SvxAutoCorrectLanguageLists::LoadWrdSttExceptList()
2321 SotStorageRef xStg
= new SotStorage( sShareAutoCorrFile
, STREAM_READ
| STREAM_SHARE_DENYNONE
, sal_True
);
2322 String
sTemp ( RTL_CONSTASCII_USTRINGPARAM ( pXMLImplWrdStt_ExcptLstStr
) );
2323 if( xStg
.Is() && xStg
->IsContained( sTemp
) )
2324 LoadXMLExceptList_Imp( pWrdStt_ExcptLst
, pXMLImplWrdStt_ExcptLstStr
, xStg
);
2325 return pWrdStt_ExcptLst
;
2328 void SvxAutoCorrectLanguageLists::SaveWrdSttExceptList()
2330 MakeUserStorage_Impl();
2331 SotStorageRef xStg
= new SotStorage( sUserAutoCorrFile
, STREAM_READWRITE
, sal_True
);
2333 SaveExceptList_Imp( *pWrdStt_ExcptLst
, pXMLImplWrdStt_ExcptLstStr
, xStg
);
2337 FStatHelper::GetModifiedDateTimeOfFile( sUserAutoCorrFile
,
2338 &aModifiedDate
, &aModifiedTime
);
2339 aLastCheckTime
= Time( Time::SYSTEM
);
2342 void SvxAutoCorrectLanguageLists::SetWrdSttExceptList( SvStringsISortDtor
* pList
)
2344 if( pWrdStt_ExcptLst
&& pList
!= pWrdStt_ExcptLst
)
2345 delete pWrdStt_ExcptLst
;
2346 pWrdStt_ExcptLst
= pList
;
2347 if( !pWrdStt_ExcptLst
)
2349 OSL_ENSURE( !this, "No valid list" );
2350 pWrdStt_ExcptLst
= new SvStringsISortDtor( 16 );
2352 nFlags
|= WrdSttLstLoad
;
2355 SvStringsISortDtor
* SvxAutoCorrectLanguageLists::GetWrdSttExceptList()
2357 if( !( WrdSttLstLoad
& nFlags
) || IsFileChanged_Imp() )
2358 SetWrdSttExceptList( LoadWrdSttExceptList() );
2359 return pWrdStt_ExcptLst
;
2362 void SvxAutoCorrectLanguageLists::RemoveStream_Imp( const String
& rName
)
2364 if( sShareAutoCorrFile
!= sUserAutoCorrFile
)
2366 SotStorageRef xStg
= new SotStorage( sUserAutoCorrFile
, STREAM_READWRITE
, sal_True
);
2367 if( xStg
.Is() && SVSTREAM_OK
== xStg
->GetError() &&
2368 xStg
->IsStream( rName
) )
2370 xStg
->Remove( rName
);
2378 void SvxAutoCorrectLanguageLists::MakeUserStorage_Impl()
2380 // The conversion needs to happen if the file is already in the user
2381 // directory and is in the old format. Additionally it needs to
2382 // happen when the file is being copied from share to user.
2384 sal_Bool bError
= sal_False
, bConvert
= sal_False
, bCopy
= sal_False
;
2385 INetURLObject aDest
;
2386 INetURLObject aSource
;
2388 if (sUserAutoCorrFile
!= sShareAutoCorrFile
)
2390 aSource
= INetURLObject ( sShareAutoCorrFile
);
2391 aDest
= INetURLObject ( sUserAutoCorrFile
);
2392 if ( SotStorage::IsOLEStorage ( sShareAutoCorrFile
) )
2394 aDest
.SetExtension ( String::CreateFromAscii ( "bak" ) );
2395 bConvert
= sal_True
;
2399 else if ( SotStorage::IsOLEStorage ( sUserAutoCorrFile
) )
2401 aSource
= INetURLObject ( sUserAutoCorrFile
);
2402 aDest
= INetURLObject ( sUserAutoCorrFile
);
2403 aDest
.SetExtension ( String::CreateFromAscii ( "bak" ) );
2404 bCopy
= bConvert
= sal_True
;
2410 String
sMain(aDest
.GetMainURL( INetURLObject::DECODE_TO_IURI
));
2411 sal_Unicode cSlash
= '/';
2412 xub_StrLen nSlashPos
= sMain
.SearchBackward(cSlash
);
2413 sMain
.Erase(nSlashPos
);
2414 ::ucbhelper::Content
aNewContent( sMain
, uno::Reference
< XCommandEnvironment
> ());
2417 aInfo
.NameClash
= NameClash::OVERWRITE
;
2418 aInfo
.NewTitle
= aDest
.GetName();
2419 aInfo
.SourceURL
= aSource
.GetMainURL( INetURLObject::DECODE_TO_IURI
);
2420 aInfo
.MoveData
= sal_False
;
2422 aNewContent
.executeCommand( OUString ( "transfer" ), aAny
);
2429 if (bConvert
&& !bError
)
2431 SotStorageRef xSrcStg
= new SotStorage( aDest
.GetMainURL( INetURLObject::DECODE_TO_IURI
), STREAM_READ
, sal_True
);
2432 SotStorageRef xDstStg
= new SotStorage( sUserAutoCorrFile
, STREAM_WRITE
, sal_True
);
2434 if( xSrcStg
.Is() && xDstStg
.Is() )
2436 String
sWord ( RTL_CONSTASCII_USTRINGPARAM ( pImplWrdStt_ExcptLstStr
) );
2437 String
sSentence ( RTL_CONSTASCII_USTRINGPARAM ( pImplCplStt_ExcptLstStr
) );
2438 String
sXMLWord ( RTL_CONSTASCII_USTRINGPARAM ( pXMLImplWrdStt_ExcptLstStr
) );
2439 String
sXMLSentence ( RTL_CONSTASCII_USTRINGPARAM ( pXMLImplCplStt_ExcptLstStr
) );
2440 SvStringsISortDtor
*pTmpWordList
= NULL
;
2442 if (xSrcStg
->IsContained( sXMLWord
) )
2443 LoadXMLExceptList_Imp( pTmpWordList
, pXMLImplWrdStt_ExcptLstStr
, xSrcStg
);
2447 SaveExceptList_Imp( *pTmpWordList
, pXMLImplWrdStt_ExcptLstStr
, xDstStg
, sal_True
);
2448 pTmpWordList
->DeleteAndDestroy( 0, pTmpWordList
->Count() );
2449 pTmpWordList
= NULL
;
2453 if (xSrcStg
->IsContained( sXMLSentence
) )
2454 LoadXMLExceptList_Imp( pTmpWordList
, pXMLImplCplStt_ExcptLstStr
, xSrcStg
);
2458 SaveExceptList_Imp( *pTmpWordList
, pXMLImplCplStt_ExcptLstStr
, xDstStg
, sal_True
);
2459 pTmpWordList
->DeleteAndDestroy( 0, pTmpWordList
->Count() );
2462 GetAutocorrWordList();
2463 MakeBlocklist_Imp( *xDstStg
);
2464 sShareAutoCorrFile
= sUserAutoCorrFile
;
2468 ::ucbhelper::Content
aContent ( aDest
.GetMainURL( INetURLObject::DECODE_TO_IURI
), uno::Reference
< XCommandEnvironment
> ());
2469 aContent
.executeCommand ( OUString ( RTL_CONSTASCII_USTRINGPARAM ( "delete" ) ), makeAny ( sal_Bool (sal_True
) ) );
2476 else if( bCopy
&& !bError
)
2477 sShareAutoCorrFile
= sUserAutoCorrFile
;
2480 sal_Bool
SvxAutoCorrectLanguageLists::MakeBlocklist_Imp( SvStorage
& rStg
)
2482 String
sStrmName( pXMLImplAutocorr_ListStr
, RTL_TEXTENCODING_MS_1252
);
2483 sal_Bool bRet
= sal_True
, bRemove
= !pAutocorr_List
|| !pAutocorr_List
->Count();
2486 SvStorageStreamRef refList
= rStg
.OpenSotStream( sStrmName
,
2487 ( STREAM_READ
| STREAM_WRITE
| STREAM_SHARE_DENYWRITE
) );
2490 refList
->SetSize( 0 );
2491 refList
->SetBufferSize( 8192 );
2492 String
aPropName( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM("MediaType") ) );
2493 OUString
aMime( "text/xml" );
2496 refList
->SetProperty( aPropName
, aAny
);
2498 uno::Reference
< lang::XMultiServiceFactory
> xServiceFactory
=
2499 comphelper::getProcessServiceFactory();
2500 OSL_ENSURE( xServiceFactory
.is(),
2501 "XMLReader::Read: got no service manager" );
2502 if( !xServiceFactory
.is() )
2504 // Throw an exception ?
2507 uno::Reference
< XInterface
> xWriter (xServiceFactory
->createInstance(
2508 OUString("com.sun.star.xml.sax.Writer")));
2509 OSL_ENSURE(xWriter
.is(),"com.sun.star.xml.sax.Writer service missing");
2510 uno::Reference
< io::XOutputStream
> xOut
= new utl::OOutputStreamWrapper( *refList
);
2511 uno::Reference
<io::XActiveDataSource
> xSrc(xWriter
, uno::UNO_QUERY
);
2512 xSrc
->setOutputStream(xOut
);
2514 uno::Reference
<xml::sax::XDocumentHandler
> xHandler(xWriter
, uno::UNO_QUERY
);
2516 SvXMLAutoCorrectExport
aExp( xServiceFactory
, pAutocorr_List
, sStrmName
, xHandler
);
2518 aExp
.exportDoc( XML_BLOCK_LIST
);
2521 bRet
= SVSTREAM_OK
== refList
->GetError();
2526 if( SVSTREAM_OK
!= rStg
.GetError() )
2539 rStg
.Remove( sStrmName
);
2546 sal_Bool
SvxAutoCorrectLanguageLists::PutText( const String
& rShort
,
2547 const String
& rLong
)
2549 // First get the current list!
2550 GetAutocorrWordList();
2552 MakeUserStorage_Impl();
2553 SotStorageRef xStg
= new SotStorage( sUserAutoCorrFile
, STREAM_READWRITE
, sal_True
);
2555 sal_Bool bRet
= xStg
.Is() && SVSTREAM_OK
== xStg
->GetError();
2557 // Update the word list
2561 SvxAutocorrWord
* pNew
= new SvxAutocorrWord( rShort
, rLong
, sal_True
);
2562 if( pAutocorr_List
->Seek_Entry( pNew
, &nPos
) )
2564 if( !(*pAutocorr_List
)[ nPos
]->IsTextOnly() )
2566 // Still have to remove the Storage
2567 String
sStgNm( rShort
);
2568 if (xStg
->IsOLEStorage())
2569 EncryptBlockName_Imp( sStgNm
);
2571 GeneratePackageName ( rShort
, sStgNm
);
2573 if( xStg
->IsContained( sStgNm
) )
2574 xStg
->Remove( sStgNm
);
2576 pAutocorr_List
->DeleteAndDestroy( nPos
);
2579 if( pAutocorr_List
->Insert( pNew
) )
2581 bRet
= MakeBlocklist_Imp( *xStg
);
2593 sal_Bool
SvxAutoCorrectLanguageLists::PutText( const String
& rShort
,
2594 SfxObjectShell
& rShell
)
2596 // First get the current list!
2597 GetAutocorrWordList();
2599 MakeUserStorage_Impl();
2601 sal_Bool bRet
= sal_False
;
2605 uno::Reference
< embed::XStorage
> xStg
= comphelper::OStorageHelper::GetStorageFromURL( sUserAutoCorrFile
, embed::ElementModes::READWRITE
);
2606 bRet
= rAutoCorrect
.PutText( xStg
, sUserAutoCorrFile
, rShort
, rShell
, sLong
);
2609 // Update the word list
2612 SvxAutocorrWord
* pNew
= new SvxAutocorrWord( rShort
, sLong
, sal_False
);
2613 if( pAutocorr_List
->Insert( pNew
) )
2615 SotStorageRef xStor
= new SotStorage( sUserAutoCorrFile
, STREAM_READWRITE
, sal_True
);
2616 MakeBlocklist_Imp( *xStor
);
2622 catch ( const uno::Exception
& )
2630 sal_Bool
SvxAutoCorrectLanguageLists::DeleteText( const String
& rShort
)
2632 // First get the current list!
2633 GetAutocorrWordList();
2635 MakeUserStorage_Impl();
2637 SotStorageRef xStg
= new SotStorage( sUserAutoCorrFile
, STREAM_READWRITE
, sal_True
);
2638 sal_Bool bRet
= xStg
.Is() && SVSTREAM_OK
== xStg
->GetError();
2642 SvxAutocorrWord
aTmp( rShort
, rShort
);
2643 if( pAutocorr_List
->Seek_Entry( &aTmp
, &nPos
) )
2645 SvxAutocorrWord
* pFnd
= (*pAutocorr_List
)[ nPos
];
2646 if( !pFnd
->IsTextOnly() )
2648 String
aName( rShort
);
2649 if (xStg
->IsOLEStorage())
2650 EncryptBlockName_Imp( aName
);
2652 GeneratePackageName ( rShort
, aName
);
2653 if( xStg
->IsContained( aName
) )
2655 xStg
->Remove( aName
);
2656 bRet
= xStg
->Commit();
2660 // Update the word list
2661 pAutocorr_List
->DeleteAndDestroy( nPos
);
2662 MakeBlocklist_Imp( *xStg
);
2671 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */