Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
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.
15 : : *
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).
21 : : *
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.
26 : : *
27 : : ************************************************************************/
28 : :
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/fstathelper.hxx>
36 : : #include <svtools/helpopt.hxx>
37 : : #include <svl/urihelper.hxx>
38 : : #include <unotools/charclass.hxx>
39 : : #include <com/sun/star/i18n/UnicodeType.hpp>
40 : : #include <unotools/collatorwrapper.hxx>
41 : : #include <com/sun/star/i18n/CollatorOptions.hpp>
42 : : #include <com/sun/star/i18n/UnicodeScript.hpp>
43 : : #include <com/sun/star/i18n/XOrdinalSuffix.hpp>
44 : : #include <unotools/localedatawrapper.hxx>
45 : : #include <unotools/transliterationwrapper.hxx>
46 : : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
47 : : #include <com/sun/star/io/XActiveDataSource.hpp>
48 : : #include <comphelper/processfactory.hxx>
49 : : #include <comphelper/storagehelper.hxx>
50 : : #include <comphelper/string.hxx>
51 : : #include <editeng/editids.hrc>
52 : : #include <sot/storage.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"
59 : : #include <helpid.hrc>
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>
72 : :
73 : : #define CHAR_HARDBLANK ((sal_Unicode)0x00A0)
74 : :
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;
81 : :
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;
86 : :
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";
93 : :
94 : : static const sal_Char
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";
99 : :
100 : : // These characters are allowed in words: (for FnCptlSttSntnc)
101 : : static const sal_Char sImplWordChars[] = "-'";
102 : :
103 : : void EncryptBlockName_Imp( String& rName );
104 : :
105 [ # # ]: 0 : TYPEINIT0(SvxAutoCorrect)
106 : :
107 : : typedef SvxAutoCorrectLanguageLists* SvxAutoCorrectLanguageListsPtr;
108 : :
109 : 0 : static inline int IsWordDelim( const sal_Unicode c )
110 : : {
111 : : return ' ' == c || '\t' == c || 0x0a == c ||
112 [ # # ][ # # ]: 0 : 0xA0 == c || 0x2011 == c || 0x1 == c;
[ # # ][ # # ]
[ # # ][ # # ]
113 : : }
114 : :
115 : 0 : static inline int IsLowerLetter( sal_Int32 nCharType )
116 : : {
117 : 0 : return CharClass::isLetterType( nCharType ) &&
118 [ # # ][ # # ]: 0 : 0 == ( ::com::sun::star::i18n::KCharacterType::UPPER & nCharType);
119 : : }
120 : :
121 : 0 : static inline int IsUpperLetter( sal_Int32 nCharType )
122 : : {
123 : 0 : return CharClass::isLetterType( nCharType ) &&
124 [ # # ][ # # ]: 0 : 0 == ( ::com::sun::star::i18n::KCharacterType::LOWER & nCharType);
125 : : }
126 : :
127 : 0 : static sal_Bool lcl_IsSymbolChar( CharClass& rCC, const String& rTxt,
128 : : xub_StrLen nStt, xub_StrLen nEnd )
129 : : {
130 [ # # ]: 0 : for( ; nStt < nEnd; ++nStt )
131 : : {
132 [ # # ]: 0 : if( ::com::sun::star::i18n::UnicodeType::PRIVATE_USE ==
133 : 0 : rCC.getType( rTxt, nStt ))
134 : 0 : return sal_True;
135 : : }
136 : 0 : return sal_False;
137 : : }
138 : :
139 : 0 : static sal_Bool lcl_IsInAsciiArr( const sal_Char* pArr, const sal_Unicode c )
140 : : {
141 : 0 : sal_Bool bRet = sal_False;
142 [ # # ]: 0 : for( ; *pArr; ++pArr )
143 [ # # ]: 0 : if( *pArr == c )
144 : : {
145 : 0 : bRet = sal_True;
146 : 0 : break;
147 : : }
148 : 0 : return bRet;
149 : : }
150 : :
151 : 0 : SvxAutoCorrDoc::~SvxAutoCorrDoc()
152 : : {
153 [ # # ]: 0 : }
154 : : // Is called by the functions:
155 : : // - FnCptlSttWrd
156 : : // - FnCptlSttSntnc
157 : : // after the exchange of characters. then the words can maybe be inserted
158 : : // into the exception list.
159 : 0 : void SvxAutoCorrDoc::SaveCpltSttWord( sal_uLong, xub_StrLen, const String&,
160 : : sal_Unicode )
161 : : {
162 : 0 : }
163 : :
164 : 0 : LanguageType SvxAutoCorrDoc::GetLanguage( xub_StrLen , sal_Bool ) const
165 : : {
166 : 0 : return LANGUAGE_SYSTEM;
167 : : }
168 : :
169 : : static ::com::sun::star::uno::Reference<
170 : 0 : ::com::sun::star::lang::XMultiServiceFactory >& GetProcessFact()
171 : : {
172 : : static ::com::sun::star::uno::Reference<
173 : : ::com::sun::star::lang::XMultiServiceFactory > xMSF =
174 [ # # ][ # # ]: 0 : ::comphelper::getProcessServiceFactory();
[ # # ][ # # ]
175 : 0 : return xMSF;
176 : : }
177 : :
178 : 73 : static sal_uInt16 GetAppLang()
179 : : {
180 : 73 : return Application::GetSettings().GetLanguage();
181 : : }
182 : 0 : static LocaleDataWrapper& GetLocaleDataWrapper( sal_uInt16 nLang )
183 : : {
184 [ # # ]: 0 : static LocaleDataWrapper aLclDtWrp( GetProcessFact(),
185 [ # # ][ # # ]: 0 : SvxCreateLocale( GetAppLang() ) );
[ # # ][ # # ]
[ # # ][ # # ]
186 [ # # ]: 0 : ::com::sun::star::lang::Locale aLcl( SvxCreateLocale( nLang ));
187 [ # # ]: 0 : const ::com::sun::star::lang::Locale& rLcl = aLclDtWrp.getLoadedLocale();
188 [ # # # # : 0 : if( aLcl.Language != rLcl.Language ||
# # ][ # # ]
189 : 0 : aLcl.Country != rLcl.Country ||
190 : 0 : aLcl.Variant != rLcl.Variant )
191 [ # # ]: 0 : aLclDtWrp.setLocale( aLcl );
192 : 0 : return aLclDtWrp;
193 : : }
194 : 0 : static TransliterationWrapper& GetIgnoreTranslWrapper()
195 : : {
196 : : static int bIsInit = 0;
197 [ # # ]: 0 : static TransliterationWrapper aWrp( GetProcessFact(),
198 : : ::com::sun::star::i18n::TransliterationModules_IGNORE_KANA |
199 [ # # ][ # # ]: 0 : ::com::sun::star::i18n::TransliterationModules_IGNORE_WIDTH );
[ # # ][ # # ]
200 [ # # ]: 0 : if( !bIsInit )
201 : : {
202 : 0 : aWrp.loadModuleIfNeeded( GetAppLang() );
203 : 0 : bIsInit = 1;
204 : : }
205 : 0 : return aWrp;
206 : : }
207 : 0 : static CollatorWrapper& GetCollatorWrapper()
208 : : {
209 : : static int bIsInit = 0;
210 [ # # ][ # # ]: 0 : static CollatorWrapper aCollWrp( GetProcessFact() );
[ # # ][ # # ]
[ # # ]
211 [ # # ]: 0 : if( !bIsInit )
212 : : {
213 [ # # ]: 0 : aCollWrp.loadDefaultCollator( SvxCreateLocale( GetAppLang() ), 0 );
214 : 0 : bIsInit = 1;
215 : : }
216 : 0 : return aCollWrp;
217 : : }
218 : :
219 : :
220 : : // Keep the list sorted ...
221 : 0 : bool CompareSvxAutocorrWordList::operator()( SvxAutocorrWord* const& lhs, SvxAutocorrWord* const& rhs ) const
222 : : {
223 : 0 : CollatorWrapper& rCmp = ::GetCollatorWrapper();
224 [ # # ][ # # ]: 0 : return rCmp.compareString( lhs->GetShort(), rhs->GetShort() ) < 0;
225 : : }
226 : :
227 : 146 : static void lcl_ClearTable(boost::ptr_map<LanguageType, SvxAutoCorrectLanguageLists>& rLangTable)
228 : : {
229 : 146 : rLangTable.clear();
230 : 146 : }
231 : :
232 : 0 : sal_Bool SvxAutoCorrect::IsAutoCorrectChar( sal_Unicode cChar )
233 : : {
234 : : return cChar == '\0' || cChar == '\t' || cChar == 0x0a ||
235 : : cChar == ' ' || cChar == '\'' || cChar == '\"' ||
236 : : cChar == '*' || cChar == '_' || cChar == '%' ||
237 : : cChar == '.' || cChar == ',' || cChar == ';' ||
238 [ # # ][ # # ]: 0 : cChar == ':' || cChar == '?' || cChar == '!' || cChar == '/';
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
239 : : }
240 : :
241 : 0 : sal_Bool SvxAutoCorrect::NeedsHardspaceAutocorr( sal_Unicode cChar )
242 : : {
243 : : return cChar == '%' || cChar == ';' || cChar == ':' || cChar == '?' || cChar == '!' ||
244 [ # # ][ # # ]: 0 : cChar == '/' /*case for the urls exception*/;
[ # # ][ # # ]
[ # # ][ # # ]
245 : : }
246 : :
247 : 73 : long SvxAutoCorrect::GetDefaultFlags()
248 : : {
249 : : long nRet = Autocorrect
250 : : | CptlSttSntnc
251 : : | CptlSttWrd
252 : : | ChgOrdinalNumber
253 : : | ChgToEnEmDash
254 : : | AddNonBrkSpace
255 : : | ChgWeightUnderl
256 : : | SetINetAttr
257 : : | ChgQuotes
258 : : | SaveWordCplSttLst
259 : : | SaveWordWrdSttLst
260 : 73 : | CorrectCapsLock;
261 : 73 : LanguageType eLang = GetAppLang();
262 [ + - ]: 73 : switch( eLang )
263 : : {
264 : : case LANGUAGE_ENGLISH:
265 : : case LANGUAGE_ENGLISH_US:
266 : : case LANGUAGE_ENGLISH_UK:
267 : : case LANGUAGE_ENGLISH_AUS:
268 : : case LANGUAGE_ENGLISH_CAN:
269 : : case LANGUAGE_ENGLISH_NZ:
270 : : case LANGUAGE_ENGLISH_EIRE:
271 : : case LANGUAGE_ENGLISH_SAFRICA:
272 : : case LANGUAGE_ENGLISH_JAMAICA:
273 : : case LANGUAGE_ENGLISH_CARRIBEAN:
274 : 73 : nRet &= ~(ChgQuotes|ChgSglQuotes);
275 : 73 : break;
276 : : }
277 : 73 : return nRet;
278 : : }
279 : :
280 : :
281 : 73 : SvxAutoCorrect::SvxAutoCorrect( const String& rShareAutocorrFile,
282 : : const String& rUserAutocorrFile )
283 : : : sShareAutoCorrFile( rShareAutocorrFile ),
284 : : sUserAutoCorrFile( rUserAutocorrFile ),
285 [ + - ]: 73 : pLangTable( new boost::ptr_map<LanguageType, SvxAutoCorrectLanguageLists> ),
286 : : pCharClass( 0 ), bRunNext( false ),
287 [ + - ][ + - ]: 146 : cStartDQuote( 0 ), cEndDQuote( 0 ), cStartSQuote( 0 ), cEndSQuote( 0 )
[ + - ][ + - ]
288 : : {
289 [ + - ]: 73 : nFlags = SvxAutoCorrect::GetDefaultFlags();
290 : :
291 : 73 : cEmDash = 0x2014;
292 : 73 : cEnDash = 0x2013;
293 : 73 : }
294 : :
295 : 73 : SvxAutoCorrect::SvxAutoCorrect( const SvxAutoCorrect& rCpy )
296 : : : sShareAutoCorrFile( rCpy.sShareAutoCorrFile ),
297 : : sUserAutoCorrFile( rCpy.sUserAutoCorrFile ),
298 : :
299 : : aSwFlags( rCpy.aSwFlags ),
300 : :
301 [ + - ]: 73 : pLangTable( new boost::ptr_map<LanguageType, SvxAutoCorrectLanguageLists> ),
302 : : pCharClass( 0 ), bRunNext( false ),
303 : :
304 : : nFlags( rCpy.nFlags & ~(ChgWordLstLoad|CplSttLstLoad|WrdSttLstLoad)),
305 : : cStartDQuote( rCpy.cStartDQuote ), cEndDQuote( rCpy.cEndDQuote ),
306 : : cStartSQuote( rCpy.cStartSQuote ), cEndSQuote( rCpy.cEndSQuote ),
307 [ + - ][ + - ]: 146 : cEmDash( rCpy.cEmDash ), cEnDash( rCpy.cEnDash )
[ + - ][ + - ]
308 : : {
309 : 73 : }
310 : :
311 : :
312 [ + - ][ + - ]: 146 : SvxAutoCorrect::~SvxAutoCorrect()
313 : : {
314 [ + - ]: 146 : lcl_ClearTable(*pLangTable);
315 [ + - ][ + - ]: 146 : delete pLangTable;
316 [ - + ][ # # ]: 146 : delete pCharClass;
317 [ - + ]: 219 : }
318 : :
319 : 0 : void SvxAutoCorrect::_GetCharClass( LanguageType eLang )
320 : : {
321 [ # # ]: 0 : delete pCharClass;
322 [ # # ][ # # ]: 0 : pCharClass = new CharClass( SvxCreateLocale( eLang ));
323 : 0 : eCharClassLang = eLang;
324 : 0 : }
325 : :
326 : 146 : void SvxAutoCorrect::SetAutoCorrFlag( long nFlag, sal_Bool bOn )
327 : : {
328 : 146 : long nOld = nFlags;
329 : : nFlags = bOn ? nFlags | nFlag
330 [ + + ]: 146 : : nFlags & ~nFlag;
331 : :
332 [ + + ]: 146 : if( !bOn )
333 : : {
334 [ - + ]: 73 : if( (nOld & CptlSttSntnc) != (nFlags & CptlSttSntnc) )
335 : 0 : nFlags &= ~CplSttLstLoad;
336 [ - + ]: 73 : if( (nOld & CptlSttWrd) != (nFlags & CptlSttWrd) )
337 : 0 : nFlags &= ~WrdSttLstLoad;
338 [ - + ]: 73 : if( (nOld & Autocorrect) != (nFlags & Autocorrect) )
339 : 0 : nFlags &= ~ChgWordLstLoad;
340 : : }
341 : 146 : }
342 : :
343 : :
344 : : // Two capital letters at the beginning of word?
345 : 0 : sal_Bool SvxAutoCorrect::FnCptlSttWrd( SvxAutoCorrDoc& rDoc, const String& rTxt,
346 : : xub_StrLen nSttPos, xub_StrLen nEndPos,
347 : : LanguageType eLang )
348 : : {
349 : 0 : sal_Bool bRet = sal_False;
350 : 0 : CharClass& rCC = GetCharClass( eLang );
351 : :
352 : : // Delete all non alphanumeric. Test the characters at the beginning/end of
353 : : // the word ( recognizes: "(min.", "/min.", and so on.)
354 [ # # ]: 0 : for( ; nSttPos < nEndPos; ++nSttPos )
355 [ # # ]: 0 : if( rCC.isLetterNumeric( rTxt, nSttPos ))
356 : 0 : break;
357 [ # # ]: 0 : for( ; nSttPos < nEndPos; --nEndPos )
358 [ # # ]: 0 : if( rCC.isLetterNumeric( rTxt, nEndPos - 1 ))
359 : 0 : break;
360 : :
361 : : // Two capital letters at the beginning of word?
362 [ # # # # : 0 : if( nSttPos+2 < nEndPos &&
# # # # #
# # # ]
[ # # ]
363 : 0 : IsUpperLetter( rCC.getCharacterType( rTxt, nSttPos )) &&
364 : 0 : IsUpperLetter( rCC.getCharacterType( rTxt, ++nSttPos )) &&
365 : : // Is the third character a lower case
366 : 0 : IsLowerLetter( rCC.getCharacterType( rTxt, nSttPos +1 )) &&
367 : : // Do not replace special attributes
368 : 0 : 0x1 != rTxt.GetChar( nSttPos ) && 0x2 != rTxt.GetChar( nSttPos ))
369 : : {
370 : : // test if the word is in an exception list
371 [ # # ]: 0 : String sWord( rTxt.Copy( nSttPos - 1, nEndPos - nSttPos + 1 ));
372 [ # # ][ # # ]: 0 : if( !FindInWrdSttExceptList(eLang, sWord) )
373 : : {
374 : : // Check that word isn't correctly spelled before correcting:
375 : : ::com::sun::star::uno::Reference<
376 : : ::com::sun::star::linguistic2::XSpellChecker1 > xSpeller =
377 [ # # ]: 0 : SvxGetSpellChecker();
378 [ # # ][ # # ]: 0 : if( xSpeller->hasLanguage(eLang) )
[ # # ]
379 : : {
380 [ # # ]: 0 : Sequence< ::com::sun::star::beans::PropertyValue > aEmptySeq;
381 [ # # ][ # # ]: 0 : if (!xSpeller->spell(sWord, eLang, aEmptySeq).is())
[ # # ][ # # ]
382 : : {
383 : 0 : return false;
384 [ # # ][ # # ]: 0 : }
385 : : }
386 : 0 : sal_Unicode cSave = rTxt.GetChar( nSttPos );
387 : 0 : rtl::OUString sChar( cSave );
388 [ # # ]: 0 : sChar = rCC.lowercase( sChar );
389 [ # # ][ # # ]: 0 : if( sChar[0] != cSave && rDoc.ReplaceRange( nSttPos, 1, sChar ))
[ # # ][ # # ]
[ # # ]
[ # # # # ]
[ # # ]
390 : : {
391 [ # # ]: 0 : if( SaveWordWrdSttLst & nFlags )
392 [ # # ]: 0 : rDoc.SaveCpltSttWord( CptlSttWrd, nSttPos, sWord, cSave );
393 : 0 : bRet = sal_True;
394 [ # # ]: 0 : }
395 [ # # ][ # # ]: 0 : }
396 : : }
397 : 0 : return bRet;
398 : : }
399 : :
400 : :
401 : 0 : sal_Bool SvxAutoCorrect::FnChgOrdinalNumber(
402 : : SvxAutoCorrDoc& rDoc, const String& rTxt,
403 : : xub_StrLen nSttPos, xub_StrLen nEndPos,
404 : : LanguageType eLang )
405 : : {
406 : : // 1st, 2nd, 3rd, 4 - 0th
407 : : // 201th or 201st
408 : : // 12th or 12nd
409 : 0 : CharClass& rCC = GetCharClass( eLang );
410 : 0 : sal_Bool bChg = sal_False;
411 : :
412 [ # # ]: 0 : for( ; nSttPos < nEndPos; ++nSttPos )
413 [ # # ]: 0 : if( !lcl_IsInAsciiArr( sImplSttSkipChars, rTxt.GetChar( nSttPos ) ))
414 : 0 : break;
415 [ # # ]: 0 : for( ; nSttPos < nEndPos; --nEndPos )
416 [ # # ]: 0 : if( !lcl_IsInAsciiArr( sImplEndSkipChars, rTxt.GetChar( nEndPos - 1 ) ))
417 : 0 : break;
418 : :
419 : :
420 : : // Get the last number in the string to check
421 : 0 : xub_StrLen nNumEnd = nEndPos;
422 : 0 : bool foundEnd = false;
423 : 0 : bool validNumber = true;
424 : 0 : xub_StrLen i = nEndPos;
425 : :
426 [ # # ]: 0 : while ( i > nSttPos )
427 : : {
428 : 0 : i--;
429 : 0 : bool isDigit = rCC.isDigit( rTxt, i );
430 [ # # ]: 0 : if ( foundEnd )
431 : 0 : validNumber |= isDigit;
432 : :
433 [ # # ][ # # ]: 0 : if ( isDigit && !foundEnd )
434 : : {
435 : 0 : foundEnd = true;
436 : 0 : nNumEnd = i;
437 : : }
438 : : }
439 : :
440 [ # # ][ # # ]: 0 : if ( foundEnd && validNumber ) {
441 [ # # ][ # # ]: 0 : sal_Int32 nNum = rTxt.Copy( nSttPos, nNumEnd - nSttPos + 1 ).ToInt32( );
[ # # ]
442 : :
443 : : // Check if the characters after that number correspond to the ordinal suffix
444 : 0 : rtl::OUString sServiceName("com.sun.star.i18n.OrdinalSuffix");
445 : : uno::Reference< i18n::XOrdinalSuffix > xOrdSuffix(
446 : : comphelper::createProcessComponent( sServiceName ),
447 [ # # ][ # # ]: 0 : uno::UNO_QUERY );
448 : :
449 [ # # ]: 0 : if ( xOrdSuffix.is( ) )
450 : : {
451 [ # # ][ # # ]: 0 : uno::Sequence< rtl::OUString > aSuffixes = xOrdSuffix->getOrdinalSuffix( nNum, rCC.getLocale( ) );
[ # # ]
452 [ # # ]: 0 : for ( sal_Int32 nSuff = 0; nSuff < aSuffixes.getLength(); nSuff++ )
453 : : {
454 [ # # ][ # # ]: 0 : String sSuffix( aSuffixes[ nSuff ] );
455 [ # # ]: 0 : String sEnd = rTxt.Copy( nNumEnd + 1, nEndPos - nNumEnd - 1 );
456 : :
457 [ # # ][ # # ]: 0 : if ( sSuffix == sEnd )
458 : : {
459 : : // Check if the ordinal suffix has to be set as super script
460 [ # # ][ # # ]: 0 : if ( rCC.isLetter( sSuffix ) )
461 : : {
462 : : // Do the change
463 : : SvxEscapementItem aSvxEscapementItem( DFLT_ESC_AUTO_SUPER,
464 [ # # ]: 0 : DFLT_ESC_PROP, SID_ATTR_CHAR_ESCAPEMENT );
465 : : rDoc.SetAttr( nNumEnd + 1 , nEndPos,
466 : : SID_ATTR_CHAR_ESCAPEMENT,
467 [ # # ][ # # ]: 0 : aSvxEscapementItem);
468 : : }
469 : : }
470 [ # # ][ # # ]: 0 : }
[ # # ]
471 : 0 : }
472 : :
473 : : }
474 : 0 : return bChg;
475 : : }
476 : :
477 : :
478 : 0 : sal_Bool SvxAutoCorrect::FnChgToEnEmDash(
479 : : SvxAutoCorrDoc& rDoc, const String& rTxt,
480 : : xub_StrLen nSttPos, xub_StrLen nEndPos,
481 : : LanguageType eLang )
482 : : {
483 : 0 : sal_Bool bRet = sal_False;
484 : 0 : CharClass& rCC = GetCharClass( eLang );
485 [ # # ]: 0 : if (eLang == LANGUAGE_SYSTEM)
486 : 0 : eLang = GetAppLang();
487 [ # # ][ # # ]: 0 : bool bAlwaysUseEmDash = (cEmDash && (eLang == LANGUAGE_RUSSIAN || eLang == LANGUAGE_UKRAINIAN));
[ # # ]
488 : :
489 : : // replace " - " or " --" with "enDash"
490 [ # # ][ # # ]: 0 : if( cEnDash && 1 < nSttPos && 1 <= nEndPos - nSttPos )
[ # # ]
491 : : {
492 : 0 : sal_Unicode cCh = rTxt.GetChar( nSttPos );
493 [ # # ]: 0 : if( '-' == cCh )
494 : : {
495 [ # # # # ]: 0 : if( ' ' == rTxt.GetChar( nSttPos-1 ) &&
[ # # ]
496 : 0 : '-' == rTxt.GetChar( nSttPos+1 ))
497 : : {
498 : : xub_StrLen n;
499 [ # # ][ # # ]: 0 : for( n = nSttPos+2; n < nEndPos && lcl_IsInAsciiArr(
[ # # ]
500 : 0 : sImplSttSkipChars,(cCh = rTxt.GetChar( n )));
501 : : ++n )
502 : : ;
503 : :
504 : : // found: " --[<AnySttChars>][A-z0-9]
505 [ # # ][ # # ]: 0 : if( rCC.isLetterNumeric( rtl::OUString(cCh) ) )
[ # # ][ # # ]
506 : : {
507 [ # # ][ # # ]: 0 : for( n = nSttPos-1; n && lcl_IsInAsciiArr(
[ # # ]
508 : 0 : sImplEndSkipChars,(cCh = rTxt.GetChar( --n ))); )
509 : : ;
510 : :
511 : : // found: "[A-z0-9][<AnyEndChars>] --[<AnySttChars>][A-z0-9]
512 [ # # ][ # # ]: 0 : if( rCC.isLetterNumeric( rtl::OUString(cCh) ))
[ # # ][ # # ]
513 : : {
514 : 0 : rDoc.Delete( nSttPos, nSttPos + 2 );
515 [ # # ][ # # ]: 0 : rDoc.Insert( nSttPos, bAlwaysUseEmDash ? rtl::OUString(cEmDash) : rtl::OUString(cEnDash) );
[ # # ][ # # ]
516 : 0 : bRet = sal_True;
517 : : }
518 : : }
519 : : }
520 : : }
521 [ # # # # : 0 : else if( 3 < nSttPos &&
# # ][ # # ]
522 : 0 : ' ' == rTxt.GetChar( nSttPos-1 ) &&
523 : 0 : '-' == rTxt.GetChar( nSttPos-2 ))
524 : : {
525 : 0 : xub_StrLen n, nLen = 1, nTmpPos = nSttPos - 2;
526 [ # # ]: 0 : if( '-' == ( cCh = rTxt.GetChar( nTmpPos-1 )) )
527 : : {
528 : 0 : --nTmpPos;
529 : 0 : ++nLen;
530 : 0 : cCh = rTxt.GetChar( nTmpPos-1 );
531 : : }
532 [ # # ]: 0 : if( ' ' == cCh )
533 : : {
534 [ # # ][ # # ]: 0 : for( n = nSttPos; n < nEndPos && lcl_IsInAsciiArr(
[ # # ]
535 : 0 : sImplSttSkipChars,(cCh = rTxt.GetChar( n )));
536 : : ++n )
537 : : ;
538 : :
539 : : // found: " - [<AnySttChars>][A-z0-9]
540 [ # # ][ # # ]: 0 : if( rCC.isLetterNumeric( rtl::OUString(cCh) ) )
[ # # ][ # # ]
541 : : {
542 : 0 : cCh = ' ';
543 [ # # ][ # # ]: 0 : for( n = nTmpPos-1; n && lcl_IsInAsciiArr(
[ # # ]
544 : 0 : sImplEndSkipChars,(cCh = rTxt.GetChar( --n ))); )
545 : : ;
546 : : // found: "[A-z0-9][<AnyEndChars>] - [<AnySttChars>][A-z0-9]
547 [ # # ][ # # ]: 0 : if( rCC.isLetterNumeric( rtl::OUString(cCh) ))
[ # # ][ # # ]
548 : : {
549 : 0 : rDoc.Delete( nTmpPos, nTmpPos + nLen );
550 [ # # ][ # # ]: 0 : rDoc.Insert( nTmpPos, bAlwaysUseEmDash ? rtl::OUString(cEmDash) : rtl::OUString(cEnDash) );
[ # # ][ # # ]
551 : 0 : bRet = sal_True;
552 : : }
553 : : }
554 : : }
555 : : }
556 : : }
557 : :
558 : : // Replace [A-z0-9]--[A-z0-9] double dash with "emDash" or "enDash".
559 : : // Finnish and Hungarian use enDash instead of emDash.
560 [ # # ][ # # ]: 0 : bool bEnDash = (eLang == LANGUAGE_HUNGARIAN || eLang == LANGUAGE_FINNISH);
561 [ # # ][ # # ]: 0 : if( ((cEmDash && !bEnDash) || (cEnDash && bEnDash)) && 4 <= nEndPos - nSttPos )
[ # # ][ # # ]
[ # # ]
562 : : {
563 [ # # ]: 0 : String sTmp( rTxt.Copy( nSttPos, nEndPos - nSttPos ) );
564 [ # # ]: 0 : xub_StrLen nFndPos = sTmp.SearchAscii( "--" );
565 [ # # ]: 0 : if( STRING_NOTFOUND != nFndPos && nFndPos &&
[ # # # # ]
[ # # # # ]
[ # # # # ]
[ # # ]
566 : 0 : nFndPos + 2 < sTmp.Len() &&
567 [ # # ]: 0 : ( rCC.isLetterNumeric( sTmp, nFndPos - 1 ) ||
568 : 0 : lcl_IsInAsciiArr( sImplEndSkipChars, rTxt.GetChar( nFndPos - 1 ) )) &&
569 [ # # ]: 0 : ( rCC.isLetterNumeric( sTmp, nFndPos + 2 ) ||
570 : 0 : lcl_IsInAsciiArr( sImplSttSkipChars, rTxt.GetChar( nFndPos + 2 ) )))
571 : : {
572 : 0 : nSttPos = nSttPos + nFndPos;
573 [ # # ]: 0 : rDoc.Delete( nSttPos, nSttPos + 2 );
574 [ # # ][ # # ]: 0 : rDoc.Insert( nSttPos, (bEnDash ? rtl::OUString(cEnDash) : rtl::OUString(cEmDash)) );
[ # # ][ # # ]
575 : 0 : bRet = sal_True;
576 [ # # ]: 0 : }
577 : : }
578 : 0 : return bRet;
579 : : }
580 : :
581 : : #ifdef _MSC_VER
582 : : #pragma warning(push)
583 : : #pragma warning(disable: 4706) // assignment within conditional expression
584 : : #endif
585 : :
586 : 0 : sal_Bool SvxAutoCorrect::FnAddNonBrkSpace(
587 : : SvxAutoCorrDoc& rDoc, const String& rTxt,
588 : : xub_StrLen, xub_StrLen nEndPos,
589 : : LanguageType eLang )
590 : : {
591 : 0 : bool bRet = false;
592 : :
593 [ # # ]: 0 : CharClass& rCC = GetCharClass( eLang );
594 [ # # ]: 0 : const lang::Locale rLocale = rCC.getLocale( );
595 : :
596 [ # # ]: 0 : if ( rLocale.Language == OUString( "fr" ) )
597 : : {
598 : 0 : bool bFrCA = rLocale.Country == OUString( "CA" );
599 : 0 : OUString allChars = OUString( ":;?!%" );
600 : 0 : OUString chars( allChars );
601 [ # # ]: 0 : if ( bFrCA )
602 : 0 : chars = OUString( ":" );
603 : :
604 : 0 : sal_Unicode cChar = rTxt.GetChar( nEndPos );
605 : 0 : bool bHasSpace = chars.indexOf( cChar ) != -1;
606 : 0 : bool bIsSpecial = allChars.indexOf( cChar ) != -1;
607 [ # # ]: 0 : if ( bIsSpecial )
608 : : {
609 : : // Get the last word delimiter position
610 : 0 : xub_StrLen nSttWdPos = nEndPos;
611 : 0 : bool bWasWordDelim = false;
612 [ # # ][ # # ]: 0 : while( nSttWdPos && !(bWasWordDelim = IsWordDelim( rTxt.GetChar( --nSttWdPos ))))
[ # # ]
613 : : ;
614 : :
615 [ # # ][ # # ]: 0 : if(INetURLObject::CompareProtocolScheme(rTxt.Copy(nSttWdPos + (bWasWordDelim ? 1 : 0), nEndPos - nSttWdPos + 1)) != INET_PROT_NOT_VALID) {
[ # # ][ # # ]
[ # # ][ # # ]
616 : 0 : return sal_False;
617 : : }
618 : :
619 : :
620 : : // Check the presence of "://" in the word
621 [ # # ][ # # ]: 0 : xub_StrLen nStrPos = rTxt.Search( rtl::OUString( "://" ), nSttWdPos + 1 );
[ # # ]
622 [ # # ][ # # ]: 0 : if ( STRING_NOTFOUND == nStrPos && nEndPos > 0 )
623 : : {
624 : : // Check the previous char
625 : 0 : sal_Unicode cPrevChar = rTxt.GetChar( nEndPos - 1 );
626 [ # # ][ # # ]: 0 : if ( ( chars.indexOf( cPrevChar ) == -1 ) && cPrevChar != '\t' )
[ # # ]
627 : : {
628 : : // Remove any previous normal space
629 : 0 : xub_StrLen nPos = nEndPos - 1;
630 [ # # ][ # # ]: 0 : while ( cPrevChar == ' ' || cPrevChar == CHAR_HARDBLANK )
[ # # ]
631 : : {
632 [ # # ]: 0 : if ( nPos == 0 ) break;
633 : 0 : nPos--;
634 : 0 : cPrevChar = rTxt.GetChar( nPos );
635 : : }
636 : :
637 : 0 : nPos++;
638 [ # # ]: 0 : if ( nEndPos - nPos > 0 )
639 [ # # ]: 0 : rDoc.Delete( nPos, nEndPos );
640 : :
641 : : // Add the non-breaking space at the end pos
642 [ # # ]: 0 : if ( bHasSpace )
643 [ # # ][ # # ]: 0 : rDoc.Insert( nPos, rtl::OUString(CHAR_HARDBLANK) );
[ # # ]
644 : 0 : bRunNext = true;
645 : 0 : bRet = true;
646 : : }
647 [ # # ]: 0 : else if ( chars.indexOf( cPrevChar ) != -1 )
648 : 0 : bRunNext = true;
649 : : }
650 : : }
651 [ # # ][ # # ]: 0 : else if ( cChar == '/' && nEndPos > 1 && rTxt.Len() > (nEndPos - 1) )
[ # # ][ # # ]
652 : : {
653 : : // Remove the hardspace right before to avoid formatting URLs
654 : 0 : sal_Unicode cPrevChar = rTxt.GetChar( nEndPos - 1 );
655 : 0 : sal_Unicode cMaybeSpaceChar = rTxt.GetChar( nEndPos - 2 );
656 [ # # ][ # # ]: 0 : if ( cPrevChar == ':' && cMaybeSpaceChar == CHAR_HARDBLANK )
657 : : {
658 [ # # ]: 0 : rDoc.Delete( nEndPos - 2, nEndPos - 1 );
659 : 0 : bRet = true;
660 : : }
661 [ # # ][ # # ]: 0 : }
662 : : }
663 : :
664 : 0 : return bRet;
665 : : }
666 : :
667 : : #ifdef _MSC_VER
668 : : #pragma warning(pop)
669 : : #endif
670 : :
671 : 0 : sal_Bool SvxAutoCorrect::FnSetINetAttr( SvxAutoCorrDoc& rDoc, const String& rTxt,
672 : : xub_StrLen nSttPos, xub_StrLen nEndPos,
673 : : LanguageType eLang )
674 : : {
675 : : String sURL( URIHelper::FindFirstURLInText( rTxt, nSttPos, nEndPos,
676 [ # # ][ # # ]: 0 : GetCharClass( eLang ) ));
[ # # ][ # # ]
677 : 0 : sal_Bool bRet = 0 != sURL.Len();
678 [ # # ]: 0 : if( bRet ) // also Attribut setzen:
679 [ # # ]: 0 : rDoc.SetINetAttr( nSttPos, nEndPos, sURL );
680 [ # # ]: 0 : return bRet;
681 : : }
682 : :
683 : :
684 : 0 : sal_Bool SvxAutoCorrect::FnChgWeightUnderl( SvxAutoCorrDoc& rDoc, const String& rTxt,
685 : : xub_StrLen, xub_StrLen nEndPos,
686 : : LanguageType eLang )
687 : : {
688 : : // Condition:
689 : : // at the beginning: _ or * after Space with the folloeing !Space
690 : : // at the end: _ or * before Space (word delimiter?)
691 : :
692 : 0 : sal_Unicode c, cInsChar = rTxt.GetChar( nEndPos ); // underline or bold
693 [ # # ]: 0 : if( ++nEndPos != rTxt.Len() &&
[ # # # # ]
694 : 0 : !IsWordDelim( rTxt.GetChar( nEndPos ) ) )
695 : 0 : return sal_False;
696 : :
697 : 0 : --nEndPos;
698 : :
699 : 0 : sal_Bool bAlphaNum = sal_False;
700 : 0 : xub_StrLen nPos = nEndPos, nFndPos = STRING_NOTFOUND;
701 : 0 : CharClass& rCC = GetCharClass( eLang );
702 : :
703 [ # # ]: 0 : while( nPos )
704 : : {
705 [ # # ]: 0 : switch( c = rTxt.GetChar( --nPos ) )
706 : : {
707 : : case '_':
708 : : case '*':
709 [ # # ]: 0 : if( c == cInsChar )
710 : : {
711 [ # # ][ # # ]: 0 : if( bAlphaNum && nPos+1 < nEndPos && ( !nPos ||
[ # # # #
# # ][ # # ]
712 : 0 : IsWordDelim( rTxt.GetChar( nPos-1 ))) &&
713 : 0 : !IsWordDelim( rTxt.GetChar( nPos+1 )))
714 : 0 : nFndPos = nPos;
715 : : else
716 : : // Condition is not satisfied, so cancel
717 : 0 : nFndPos = STRING_NOTFOUND;
718 : 0 : nPos = 0;
719 : : }
720 : 0 : break;
721 : : default:
722 [ # # ]: 0 : if( !bAlphaNum )
723 : 0 : bAlphaNum = rCC.isLetterNumeric( rTxt, nPos );
724 : : }
725 : : }
726 : :
727 [ # # ]: 0 : if( STRING_NOTFOUND != nFndPos )
728 : : {
729 : : // Span the Attribute over the area and delete the Character found at
730 : : // the end.
731 [ # # ]: 0 : if( '*' == cInsChar ) // Bold
732 : : {
733 [ # # ]: 0 : SvxWeightItem aSvxWeightItem( WEIGHT_BOLD, SID_ATTR_CHAR_WEIGHT );
734 : : rDoc.SetAttr( nFndPos + 1, nEndPos,
735 : : SID_ATTR_CHAR_WEIGHT,
736 [ # # ][ # # ]: 0 : aSvxWeightItem);
737 : : }
738 : : else // underline
739 : : {
740 [ # # ]: 0 : SvxUnderlineItem aSvxUnderlineItem( UNDERLINE_SINGLE, SID_ATTR_CHAR_UNDERLINE );
741 : : rDoc.SetAttr( nFndPos + 1, nEndPos,
742 : : SID_ATTR_CHAR_UNDERLINE,
743 [ # # ][ # # ]: 0 : aSvxUnderlineItem);
744 : : }
745 : 0 : rDoc.Delete( nEndPos, nEndPos + 1 );
746 : 0 : rDoc.Delete( nFndPos, nFndPos + 1 );
747 : : }
748 : :
749 : 0 : return STRING_NOTFOUND != nFndPos;
750 : : }
751 : :
752 : :
753 : 0 : sal_Bool SvxAutoCorrect::FnCptlSttSntnc( SvxAutoCorrDoc& rDoc,
754 : : const String& rTxt, sal_Bool bNormalPos,
755 : : xub_StrLen nSttPos, xub_StrLen nEndPos,
756 : : LanguageType eLang )
757 : : {
758 : :
759 [ # # ][ # # ]: 0 : if( !rTxt.Len() || nEndPos <= nSttPos )
[ # # ]
760 : 0 : return sal_False;
761 : :
762 [ # # ]: 0 : CharClass& rCC = GetCharClass( eLang );
763 [ # # ]: 0 : String aText( rTxt );
764 : 0 : const sal_Unicode *pStart = aText.GetBuffer(),
765 : 0 : *pStr = pStart + nEndPos,
766 : 0 : *pWordStt = 0,
767 : 0 : *pDelim = 0;
768 : :
769 : 0 : sal_Bool bAtStart = sal_False;
770 [ # # ]: 0 : do {
771 : 0 : --pStr;
772 [ # # ]: 0 : if( rCC.isLetter(
773 [ # # ]: 0 : aText, sal::static_int_cast< xub_StrLen >( pStr - pStart ) ) )
774 : : {
775 [ # # ]: 0 : if( !pWordStt )
776 : 0 : pDelim = pStr+1;
777 : 0 : pWordStt = pStr;
778 : : }
779 [ # # ][ # # ]: 0 : else if( pWordStt &&
[ # # ]
780 : : !rCC.isDigit(
781 : : aText,
782 [ # # ]: 0 : sal::static_int_cast< xub_StrLen >( pStr - pStart ) ) )
783 : : {
784 [ # # ][ # # ]: 0 : if( lcl_IsInAsciiArr( sImplWordChars, *pStr ) &&
[ # # ][ # # ]
[ # # ]
785 : 0 : pWordStt - 1 == pStr &&
786 : : // Installation at beginning of paragraph. Replaced < by <= (#i38971#)
787 : 0 : (long)(pStart + 1) <= (long)pStr &&
788 : : rCC.isLetter(
789 : : aText,
790 [ # # ]: 0 : sal::static_int_cast< xub_StrLen >( pStr-1 - pStart ) ) )
791 : 0 : pWordStt = --pStr;
792 : : else
793 : 0 : break;
794 : : }
795 : : } while( 0 == ( bAtStart = (pStart == pStr)) );
796 : :
797 [ # # ]: 0 : if( !pWordStt ||
[ # # # # ]
[ # # ][ # # ]
[ # # ][ # # ]
798 : : rCC.isDigit(
799 [ # # ]: 0 : aText, sal::static_int_cast< xub_StrLen >( pStr - pStart ) ) ||
800 : : IsUpperLetter(
801 : : rCC.getCharacterType(
802 : : aText,
803 [ # # ]: 0 : sal::static_int_cast< xub_StrLen >( pWordStt - pStart ) ) ) ||
804 [ # # ][ # # ]: 0 : INetURLObject::CompareProtocolScheme(rTxt.Copy(pWordStt - pStart, pDelim - pWordStt + 1)) != INET_PROT_NOT_VALID ||
[ # # ][ # # ]
[ # # ][ # # ]
[ # # # # ]
805 : : 0x1 == *pWordStt || 0x2 == *pWordStt )
806 : 0 : return sal_False; // no character to be replaced, or already ok
807 : :
808 [ # # ]: 0 : if( *pDelim && 2 >= pDelim - pWordStt &&
[ # # # # ]
[ # # ]
809 : 0 : lcl_IsInAsciiArr( ".-)>", *pDelim ) )
810 : 0 : return sal_False;
811 : :
812 [ # # ]: 0 : if( !bAtStart ) // Still no beginning of a paragraph?
813 : : {
814 [ # # ]: 0 : if ( IsWordDelim( *pStr ) )
815 : : {
816 [ # # ][ # # ]: 0 : while( 0 == ( bAtStart = (pStart == pStr--) ) && IsWordDelim( *pStr ))
[ # # ]
817 : : ;
818 : : }
819 : : // Asian full stop, full width full stop, full width exclamation mark
820 : : // and full width question marks are treated as word delimiters
821 [ # # ][ # # ]: 0 : else if ( 0x3002 != *pStr && 0xFF0E != *pStr && 0xFF01 != *pStr &&
[ # # ][ # # ]
822 : : 0xFF1F != *pStr )
823 : 0 : return sal_False; // no valid separator -> no replacement
824 : : }
825 : :
826 [ # # ]: 0 : if( bAtStart ) // at the beginning of a paragraph?
827 : : {
828 : : // Check out the previous paragraph, if it exists.
829 : : // If so, then check to paragraph separator at the end.
830 [ # # ]: 0 : const String* pPrevPara = rDoc.GetPrevPara( bNormalPos );
831 [ # # ]: 0 : if( !pPrevPara )
832 : : {
833 : : // valid separator -> replace
834 : 0 : rtl::OUString sChar( *pWordStt );
835 [ # # ]: 0 : sChar = rCC.uppercase( sChar );
836 : 0 : return !comphelper::string::equals(sChar, *pWordStt) &&
837 [ # # ][ # # ]: 0 : rDoc.ReplaceRange( xub_StrLen( pWordStt - pStart ), 1, sChar );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
838 : : }
839 : :
840 [ # # ]: 0 : aText = *pPrevPara;
841 : 0 : bAtStart = sal_False;
842 : 0 : pStart = aText.GetBuffer();
843 : 0 : pStr = pStart + aText.Len();
844 : :
845 [ # # ]: 0 : do { // overwrite all blanks
846 : 0 : --pStr;
847 [ # # ]: 0 : if( !IsWordDelim( *pStr ))
848 : 0 : break;
849 : : } while( 0 == ( bAtStart = (pStart == pStr)) );
850 : :
851 [ # # ]: 0 : if( bAtStart )
852 : 0 : return sal_False; // no valid separator -> no replacement
853 : : }
854 : :
855 : : // Found [ \t]+[A-Z0-9]+ until here. Test now on the paragraph separator.
856 : : // all three can happen, but not more than once!
857 : 0 : const sal_Unicode* pExceptStt = 0;
858 [ # # ]: 0 : if( !bAtStart )
859 : : {
860 : 0 : sal_Bool bWeiter = sal_True;
861 : 0 : int nFlag = C_NONE;
862 [ # # ]: 0 : do {
863 [ # # # # ]: 0 : switch( *pStr )
864 : : {
865 : : // Western and Asian full stop
866 : : case '.':
867 : : case 0x3002 :
868 : : case 0xFF0E :
869 : : {
870 [ # # ]: 0 : if( nFlag & C_FULL_STOP )
871 : 0 : return sal_False; // no valid separator -> no replacement
872 : 0 : nFlag |= C_FULL_STOP;
873 : 0 : pExceptStt = pStr;
874 : : }
875 : 0 : break;
876 : : case '!':
877 : : case 0xFF01 :
878 : : {
879 [ # # ]: 0 : if( nFlag & C_EXCLAMATION_MARK )
880 : 0 : return sal_False; // no valid separator -> no replacement
881 : 0 : nFlag |= C_EXCLAMATION_MARK;
882 : : }
883 : 0 : break;
884 : : case '?':
885 : : case 0xFF1F :
886 : : {
887 [ # # ]: 0 : if( nFlag & C_QUESTION_MARK)
888 : 0 : return sal_False; // no valid separator -> no replacement
889 : 0 : nFlag |= C_QUESTION_MARK;
890 : : }
891 : 0 : break;
892 : : default:
893 [ # # ]: 0 : if( !nFlag )
894 : 0 : return sal_False; // no valid separator -> no replacement
895 : : else
896 : 0 : bWeiter = sal_False;
897 : 0 : break;
898 : : }
899 : :
900 [ # # ][ # # ]: 0 : if( bWeiter && pStr-- == pStart )
[ # # ]
901 : : {
902 : 0 : return sal_False; // no valid separator -> no replacement
903 : : }
904 : : } while( bWeiter );
905 [ # # ]: 0 : if( C_FULL_STOP != nFlag )
906 : 0 : pExceptStt = 0;
907 : : }
908 : :
909 [ # # ]: 0 : if( 2 > ( pStr - pStart ) )
910 : 0 : return sal_False;
911 : :
912 [ # # ]: 0 : if( !rCC.isLetterNumeric(
913 [ # # ]: 0 : aText, sal::static_int_cast< xub_StrLen >( pStr-- - pStart ) ) )
914 : : {
915 : 0 : sal_Bool bValid = sal_False, bAlphaFnd = sal_False;
916 : 0 : const sal_Unicode* pTmpStr = pStr;
917 [ # # ]: 0 : while( !bValid )
918 : : {
919 [ # # ]: 0 : if( rCC.isDigit(
920 : : aText,
921 [ # # ]: 0 : sal::static_int_cast< xub_StrLen >( pTmpStr - pStart ) ) )
922 : : {
923 : 0 : bValid = sal_True;
924 : 0 : pStr = pTmpStr - 1;
925 : : }
926 [ # # ]: 0 : else if( rCC.isLetter(
927 : : aText,
928 : : sal::static_int_cast< xub_StrLen >(
929 [ # # ]: 0 : pTmpStr - pStart ) ) )
930 : : {
931 [ # # ]: 0 : if( bAlphaFnd )
932 : : {
933 : 0 : bValid = sal_True;
934 : 0 : pStr = pTmpStr;
935 : : }
936 : : else
937 : 0 : bAlphaFnd = sal_True;
938 : : }
939 [ # # ][ # # ]: 0 : else if( bAlphaFnd || IsWordDelim( *pTmpStr ) )
[ # # ]
940 : 0 : break;
941 : :
942 [ # # ]: 0 : if( pTmpStr == pStart )
943 : 0 : break;
944 : :
945 : 0 : --pTmpStr;
946 : : }
947 : :
948 [ # # ]: 0 : if( !bValid )
949 : 0 : return sal_False; // no valid separator -> no replacement
950 : : }
951 : :
952 [ # # ][ # # ]: 0 : sal_Bool bNumericOnly = '0' <= *(pStr+1) && *(pStr+1) <= '9';
953 : :
954 : : // Search for the beginning of the word
955 [ # # ]: 0 : while( !IsWordDelim( *pStr ))
956 : : {
957 [ # # ][ # # ]: 0 : if( bNumericOnly &&
[ # # ]
958 : : rCC.isLetter(
959 [ # # ]: 0 : aText, sal::static_int_cast< xub_StrLen >( pStr - pStart ) ) )
960 : 0 : bNumericOnly = sal_False;
961 : :
962 [ # # ]: 0 : if( pStart == pStr )
963 : 0 : break;
964 : :
965 : 0 : --pStr;
966 : : }
967 : :
968 [ # # ]: 0 : if( bNumericOnly ) // consists of only numbers, then not
969 : 0 : return sal_False;
970 : :
971 [ # # ]: 0 : if( IsWordDelim( *pStr ))
972 : 0 : ++pStr;
973 : :
974 [ # # ]: 0 : String sWord;
975 : :
976 : : // check on the basis of the exception list
977 [ # # ]: 0 : if( pExceptStt )
978 : : {
979 [ # # ]: 0 : sWord = rtl::OUString(pStr, pExceptStt - pStr + 1);
980 [ # # ][ # # ]: 0 : if( FindInCplSttExceptList(eLang, sWord) )
981 : 0 : return sal_False;
982 : :
983 : : // Delete all non alphanumeric. Test the characters at the
984 : : // beginning/end of the word ( recognizes: "(min.", "/min.", and so on.)
985 [ # # ]: 0 : String sTmp( sWord );
986 [ # # ][ # # ]: 0 : while( sTmp.Len() &&
[ # # ]
987 [ # # ]: 0 : !rCC.isLetterNumeric( sTmp, 0 ) )
988 [ # # ]: 0 : sTmp.Erase( 0, 1 );
989 : :
990 : : // Remove all non alphanumeric characters towards the end up until
991 : : // the last one.
992 : 0 : xub_StrLen nLen = sTmp.Len();
993 [ # # ][ # # ]: 0 : while( nLen && !rCC.isLetterNumeric( sTmp, nLen-1 ) )
[ # # ][ # # ]
994 : 0 : --nLen;
995 [ # # ]: 0 : if( nLen + 1 < sTmp.Len() )
996 [ # # ]: 0 : sTmp.Erase( nLen + 1 );
997 : :
998 [ # # ][ # # ]: 0 : if( sTmp.Len() && sTmp.Len() != sWord.Len() &&
[ # # ][ # # ]
999 [ # # ]: 0 : FindInCplSttExceptList(eLang, sTmp))
1000 : 0 : return sal_False;
1001 : :
1002 [ # # ][ # # ]: 0 : if(FindInCplSttExceptList(eLang, sWord, sal_True))
1003 [ # # ][ # # ]: 0 : return sal_False;
1004 : : }
1005 : :
1006 : : // Ok, then replace
1007 : 0 : sal_Unicode cSave = *pWordStt;
1008 : 0 : nSttPos = sal::static_int_cast< xub_StrLen >( pWordStt - rTxt.GetBuffer() );
1009 : 0 : rtl::OUString sChar( cSave );
1010 [ # # ]: 0 : sChar = rCC.uppercase( sChar );
1011 [ # # ][ # # ]: 0 : sal_Bool bRet = sChar[0] != cSave && rDoc.ReplaceRange( nSttPos, 1, sChar );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1012 : :
1013 : : // Parahaps someone wants to have the word
1014 [ # # ][ # # ]: 0 : if( bRet && SaveWordCplSttLst & nFlags )
1015 [ # # ]: 0 : rDoc.SaveCpltSttWord( CptlSttSntnc, nSttPos, sWord, cSave );
1016 : :
1017 [ # # ][ # # ]: 0 : return bRet;
1018 : : }
1019 : :
1020 : 0 : bool SvxAutoCorrect::FnCorrectCapsLock( SvxAutoCorrDoc& rDoc, const String& rTxt,
1021 : : xub_StrLen nSttPos, xub_StrLen nEndPos,
1022 : : LanguageType eLang )
1023 : : {
1024 [ # # ]: 0 : if (nEndPos - nSttPos < 2)
1025 : : // string must be at least 2-character long.
1026 : 0 : return false;
1027 : :
1028 [ # # ]: 0 : CharClass& rCC = GetCharClass( eLang );
1029 : :
1030 : : // Check the first 2 letters.
1031 [ # # ][ # # ]: 0 : if ( !IsLowerLetter(rCC.getCharacterType(rTxt, nSttPos)) )
1032 : 0 : return false;
1033 : :
1034 [ # # ][ # # ]: 0 : if ( !IsUpperLetter(rCC.getCharacterType(rTxt, nSttPos+1)) )
1035 : 0 : return false;
1036 : :
1037 [ # # ]: 0 : String aConverted;
1038 [ # # ][ # # ]: 0 : aConverted.Append( rCC.uppercase(rtl::OUString(rTxt.GetChar(nSttPos))) );
[ # # ][ # # ]
1039 [ # # ][ # # ]: 0 : aConverted.Append( rCC.lowercase(rtl::OUString(rTxt.GetChar(nSttPos+1))) );
[ # # ][ # # ]
1040 : :
1041 [ # # ]: 0 : for (xub_StrLen i = nSttPos+2; i < nEndPos; ++i)
1042 : : {
1043 [ # # ][ # # ]: 0 : if ( IsLowerLetter(rCC.getCharacterType(rTxt, i)) )
1044 : : // A lowercase letter disqualifies the whole text.
1045 : 0 : return false;
1046 : :
1047 [ # # ][ # # ]: 0 : if ( IsUpperLetter(rCC.getCharacterType(rTxt, i)) )
1048 : : // Another uppercase letter. Convert it.
1049 [ # # ][ # # ]: 0 : aConverted.Append(rCC.lowercase(rtl::OUString(rTxt.GetChar(i))));
[ # # ][ # # ]
1050 : : else
1051 : : // This is not an alphabetic letter. Leave it as-is.
1052 [ # # ]: 0 : aConverted.Append(rTxt.GetChar(i));
1053 : : }
1054 : :
1055 : : // Replace the word.
1056 [ # # ]: 0 : rDoc.Delete(nSttPos, nEndPos);
1057 [ # # ]: 0 : rDoc.Insert(nSttPos, aConverted);
1058 : :
1059 [ # # ]: 0 : return true;
1060 : : }
1061 : :
1062 : :
1063 : 0 : sal_Unicode SvxAutoCorrect::GetQuote( sal_Unicode cInsChar, sal_Bool bSttQuote,
1064 : : LanguageType eLang ) const
1065 : : {
1066 : : sal_Unicode cRet = bSttQuote ? ( '\"' == cInsChar
1067 : : ? GetStartDoubleQuote()
1068 : : : GetStartSingleQuote() )
1069 : : : ( '\"' == cInsChar
1070 : : ? GetEndDoubleQuote()
1071 [ # # ][ # # ]: 0 : : GetEndSingleQuote() );
[ # # ]
1072 [ # # ]: 0 : if( !cRet )
1073 : : {
1074 : : // then through the Language find the right character
1075 [ # # ]: 0 : if( LANGUAGE_NONE == eLang )
1076 : 0 : cRet = cInsChar;
1077 : : else
1078 : : {
1079 [ # # ]: 0 : LocaleDataWrapper& rLcl = GetLocaleDataWrapper( eLang );
1080 : : String sRet( bSttQuote
1081 : : ? ( '\"' == cInsChar
1082 : : ? rLcl.getDoubleQuotationMarkStart()
1083 : : : rLcl.getQuotationMarkStart() )
1084 : : : ( '\"' == cInsChar
1085 : : ? rLcl.getDoubleQuotationMarkEnd()
1086 [ # # ][ # # ]: 0 : : rLcl.getQuotationMarkEnd() ));
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
1087 [ # # ][ # # ]: 0 : cRet = sRet.Len() ? sRet.GetChar( 0 ) : cInsChar;
1088 : : }
1089 : : }
1090 : 0 : return cRet;
1091 : : }
1092 : :
1093 : 0 : void SvxAutoCorrect::InsertQuote( SvxAutoCorrDoc& rDoc, xub_StrLen nInsPos,
1094 : : sal_Unicode cInsChar, sal_Bool bSttQuote,
1095 : : sal_Bool bIns )
1096 : : {
1097 [ # # ]: 0 : LanguageType eLang = rDoc.GetLanguage( nInsPos, sal_False );
1098 [ # # ]: 0 : sal_Unicode cRet = GetQuote( cInsChar, bSttQuote, eLang );
1099 : :
1100 : 0 : rtl::OUString sChg( cInsChar );
1101 [ # # ]: 0 : if( bIns )
1102 [ # # ][ # # ]: 0 : rDoc.Insert( nInsPos, sChg );
[ # # ]
1103 : : else
1104 [ # # ][ # # ]: 0 : rDoc.Replace( nInsPos, sChg );
[ # # ]
1105 : :
1106 : 0 : sChg = rtl::OUString(cRet);
1107 : :
1108 [ # # ]: 0 : if( '\"' == cInsChar )
1109 : : {
1110 [ # # ]: 0 : if( LANGUAGE_SYSTEM == eLang )
1111 [ # # ]: 0 : eLang = GetAppLang();
1112 [ # # ]: 0 : switch( eLang )
1113 : : {
1114 : : case LANGUAGE_FRENCH:
1115 : : case LANGUAGE_FRENCH_BELGIAN:
1116 : : case LANGUAGE_FRENCH_CANADIAN:
1117 : : case LANGUAGE_FRENCH_SWISS:
1118 : : case LANGUAGE_FRENCH_LUXEMBOURG:
1119 : : {
1120 : 0 : rtl::OUString s( static_cast< sal_Unicode >(0xA0) );
1121 : : // UNICODE code for no break space
1122 [ # # ][ # # ]: 0 : if( rDoc.Insert( bSttQuote ? nInsPos+1 : nInsPos, s ))
[ # # ][ # # ]
[ # # ]
1123 : : {
1124 [ # # ]: 0 : if( !bSttQuote )
1125 : 0 : ++nInsPos;
1126 : 0 : }
1127 : : }
1128 : 0 : break;
1129 : : }
1130 : : }
1131 : :
1132 [ # # ][ # # ]: 0 : rDoc.Replace( nInsPos, sChg );
[ # # ]
1133 : 0 : }
1134 : :
1135 : 0 : String SvxAutoCorrect::GetQuote( SvxAutoCorrDoc& rDoc, xub_StrLen nInsPos,
1136 : : sal_Unicode cInsChar, sal_Bool bSttQuote )
1137 : : {
1138 : 0 : LanguageType eLang = rDoc.GetLanguage( nInsPos, sal_False );
1139 : 0 : sal_Unicode cRet = GetQuote( cInsChar, bSttQuote, eLang );
1140 : :
1141 [ # # ]: 0 : String sRet = rtl::OUString(cRet);
1142 : :
1143 [ # # ]: 0 : if( '\"' == cInsChar )
1144 : : {
1145 [ # # ]: 0 : if( LANGUAGE_SYSTEM == eLang )
1146 [ # # ]: 0 : eLang = GetAppLang();
1147 [ # # ]: 0 : switch( eLang )
1148 : : {
1149 : : case LANGUAGE_FRENCH:
1150 : : case LANGUAGE_FRENCH_BELGIAN:
1151 : : case LANGUAGE_FRENCH_CANADIAN:
1152 : : case LANGUAGE_FRENCH_SWISS:
1153 : : case LANGUAGE_FRENCH_LUXEMBOURG:
1154 [ # # ]: 0 : if( bSttQuote )
1155 [ # # ]: 0 : sRet += ' ';
1156 : : else
1157 [ # # ]: 0 : sRet.Insert( ' ', 0 );
1158 : 0 : break;
1159 : : }
1160 : : }
1161 : 0 : return sRet;
1162 : : }
1163 : :
1164 : 0 : sal_uLong SvxAutoCorrect::AutoCorrect( SvxAutoCorrDoc& rDoc, const String& rTxt,
1165 : : xub_StrLen nInsPos, sal_Unicode cChar,
1166 : : sal_Bool bInsert, Window* pFrameWin )
1167 : : {
1168 : 0 : sal_uLong nRet = 0;
1169 : 0 : bool bIsNextRun = bRunNext;
1170 : 0 : bRunNext = false; // if it was set, then it has to be turned off
1171 : :
1172 : : do{ // only for middle check loop !!
1173 [ # # ]: 0 : if( cChar )
1174 : : {
1175 : : // Prevent double space
1176 [ # # ][ # # : 0 : if( nInsPos && ' ' == cChar &&
# # # # ]
[ # # ]
1177 : 0 : IsAutoCorrFlag( IgnoreDoubleSpace ) &&
1178 : 0 : ' ' == rTxt.GetChar( nInsPos - 1 ) )
1179 : : {
1180 : 0 : nRet = IgnoreDoubleSpace;
1181 : : break;
1182 : : }
1183 : :
1184 : 0 : sal_Bool bSingle = '\'' == cChar;
1185 : : sal_Bool bIsReplaceQuote =
1186 : 0 : (IsAutoCorrFlag( ChgQuotes ) && ('\"' == cChar )) ||
1187 [ # # ][ # # ]: 0 : (IsAutoCorrFlag( ChgSglQuotes ) && bSingle );
[ # # ][ # # ]
1188 [ # # ]: 0 : if( bIsReplaceQuote )
1189 : : {
1190 : : sal_Unicode cPrev;
1191 : : sal_Bool bSttQuote = !nInsPos ||
1192 : 0 : IsWordDelim( ( cPrev = rTxt.GetChar( nInsPos-1 ))) ||
1193 : 0 : lcl_IsInAsciiArr( "([{", cPrev ) ||
1194 : : ( cEmDash && cEmDash == cPrev ) ||
1195 [ # # ]: 0 : ( cEnDash && cEnDash == cPrev );
[ # # # # ]
[ # # ][ # # ]
[ # # ][ # # ]
1196 : :
1197 [ # # ]: 0 : InsertQuote( rDoc, nInsPos, cChar, bSttQuote, bInsert );
1198 [ # # ]: 0 : nRet = bSingle ? ChgSglQuotes : ChgQuotes;
1199 : : break;
1200 : : }
1201 : :
1202 [ # # ]: 0 : if( bInsert )
1203 [ # # ][ # # ]: 0 : rDoc.Insert( nInsPos, rtl::OUString(cChar) );
[ # # ]
1204 : : else
1205 [ # # ][ # # ]: 0 : rDoc.Replace( nInsPos, rtl::OUString(cChar) );
[ # # ]
1206 : :
1207 : : // Hardspaces autocorrection
1208 [ # # ]: 0 : if ( IsAutoCorrFlag( AddNonBrkSpace ) )
1209 : : {
1210 [ # # ][ # # ]: 0 : if ( NeedsHardspaceAutocorr( cChar ) &&
[ # # ][ # # ]
1211 [ # # ][ # # ]: 0 : FnAddNonBrkSpace( rDoc, rTxt, 0, nInsPos, rDoc.GetLanguage( nInsPos, sal_False ) ) )
1212 : : {
1213 : 0 : nRet = AddNonBrkSpace;
1214 : : }
1215 [ # # ][ # # ]: 0 : else if ( bIsNextRun && !IsAutoCorrectChar( cChar ) )
[ # # ][ # # ]
1216 : : {
1217 : : // Remove the NBSP if it wasn't an autocorrection
1218 [ # # ][ # # ]: 0 : if ( nInsPos != 0 && NeedsHardspaceAutocorr( rTxt.GetChar( nInsPos - 1 ) ) &&
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1219 : : cChar != ' ' && cChar != '\t' && cChar != CHAR_HARDBLANK )
1220 : : {
1221 : : // Look for the last HARD_SPACE
1222 : 0 : xub_StrLen nPos = nInsPos - 1;
1223 : 0 : bool bContinue = true;
1224 [ # # ]: 0 : while ( bContinue )
1225 : : {
1226 : 0 : const sal_Unicode cTmpChar = rTxt.GetChar( nPos );
1227 [ # # ]: 0 : if ( cTmpChar == CHAR_HARDBLANK )
1228 : : {
1229 [ # # ]: 0 : rDoc.Delete( nPos, nPos + 1 );
1230 : 0 : nRet = AddNonBrkSpace;
1231 : 0 : bContinue = false;
1232 : : }
1233 [ # # ][ # # ]: 0 : else if ( !NeedsHardspaceAutocorr( cTmpChar ) || nPos == 0 )
[ # # ][ # # ]
1234 : 0 : bContinue = false;
1235 : 0 : nPos--;
1236 : : }
1237 : : }
1238 : : }
1239 : : }
1240 : : }
1241 : :
1242 [ # # ]: 0 : if( !nInsPos )
1243 : : break;
1244 : :
1245 : 0 : xub_StrLen nPos = nInsPos - 1;
1246 : :
1247 [ # # ]: 0 : if( IsWordDelim( rTxt.GetChar( nPos )))
1248 : : break;
1249 : :
1250 : : // Set bold or underline automatically?
1251 [ # # ][ # # ]: 0 : if( '*' == cChar || '_' == cChar )
1252 : : {
1253 [ # # ][ # # ]: 0 : if( IsAutoCorrFlag( ChgWeightUnderl ) &&
[ # # ]
1254 [ # # ]: 0 : FnChgWeightUnderl( rDoc, rTxt, 0, nPos+1 ) )
1255 : 0 : nRet = ChgWeightUnderl;
1256 : : break;
1257 : : }
1258 : :
1259 [ # # ][ # # ]: 0 : while( nPos && !IsWordDelim( rTxt.GetChar( --nPos )))
[ # # ]
1260 : : ;
1261 : :
1262 : : // Found a Paragraph-start or a Blank, search for the word shortcut in
1263 : : // auto.
1264 : 0 : xub_StrLen nCapLttrPos = nPos+1; // on the 1st Character
1265 [ # # ][ # # ]: 0 : if( !nPos && !IsWordDelim( rTxt.GetChar( 0 )))
[ # # ]
1266 : 0 : --nCapLttrPos; // Absatz Anfang und kein Blank !
1267 : :
1268 [ # # ]: 0 : LanguageType eLang = rDoc.GetLanguage( nCapLttrPos, sal_False );
1269 [ # # ]: 0 : if( LANGUAGE_SYSTEM == eLang )
1270 [ # # ]: 0 : eLang = MsLangId::getSystemLanguage();
1271 [ # # ]: 0 : CharClass& rCC = GetCharClass( eLang );
1272 : :
1273 : : // no symbol characters
1274 [ # # ][ # # ]: 0 : if( lcl_IsSymbolChar( rCC, rTxt, nCapLttrPos, nInsPos ))
1275 : : break;
1276 : :
1277 [ # # ]: 0 : if( IsAutoCorrFlag( Autocorrect ) )
1278 : : {
1279 : 0 : const String* pPara = 0;
1280 [ # # ]: 0 : const String** ppPara = IsAutoCorrFlag(CptlSttSntnc) ? &pPara : 0;
1281 : :
1282 : : sal_Bool bChgWord = rDoc.ChgAutoCorrWord( nCapLttrPos, nInsPos,
1283 [ # # ]: 0 : *this, ppPara );
1284 [ # # ]: 0 : if( !bChgWord )
1285 : : {
1286 : 0 : xub_StrLen nCapLttrPos1 = nCapLttrPos, nInsPos1 = nInsPos;
1287 [ # # # # ]: 0 : while( nCapLttrPos1 < nInsPos &&
[ # # ]
1288 : 0 : lcl_IsInAsciiArr( sImplSttSkipChars, rTxt.GetChar( nCapLttrPos1 ) )
1289 : : )
1290 : 0 : ++nCapLttrPos1;
1291 [ # # ]: 0 : while( nCapLttrPos1 < nInsPos1 && nInsPos1 &&
[ # # # # ]
[ # # ]
1292 : 0 : lcl_IsInAsciiArr( sImplEndSkipChars, rTxt.GetChar( nInsPos1-1 ) )
1293 : : )
1294 : 0 : --nInsPos1;
1295 : :
1296 [ # # ][ # # ]: 0 : if( (nCapLttrPos1 != nCapLttrPos || nInsPos1 != nInsPos ) &&
[ # # ][ # # ]
[ # # ]
1297 : : nCapLttrPos1 < nInsPos1 &&
1298 [ # # ]: 0 : rDoc.ChgAutoCorrWord( nCapLttrPos1, nInsPos1, *this, ppPara ))
1299 : : {
1300 : 0 : bChgWord = sal_True;
1301 : 0 : nCapLttrPos = nCapLttrPos1;
1302 : : }
1303 : : }
1304 : :
1305 [ # # ]: 0 : if( bChgWord )
1306 : : {
1307 : 0 : nRet = Autocorrect;
1308 [ # # ]: 0 : if( pPara )
1309 : : {
1310 : 0 : xub_StrLen nEnd = nCapLttrPos;
1311 [ # # # # ]: 0 : while( nEnd < pPara->Len() &&
[ # # ]
1312 : 0 : !IsWordDelim( pPara->GetChar( nEnd )))
1313 : 0 : ++nEnd;
1314 : :
1315 : : // Capital letter at beginning of paragraph?
1316 [ # # ][ # # ]: 0 : if( IsAutoCorrFlag( CptlSttSntnc ) &&
[ # # ]
1317 : : FnCptlSttSntnc( rDoc, *pPara, sal_False,
1318 [ # # ]: 0 : nCapLttrPos, nEnd, eLang ) )
1319 : 0 : nRet |= CptlSttSntnc;
1320 : :
1321 [ # # ][ # # ]: 0 : if( IsAutoCorrFlag( ChgToEnEmDash ) &&
[ # # ]
1322 [ # # ]: 0 : FnChgToEnEmDash( rDoc, rTxt, nCapLttrPos, nEnd, eLang ) )
1323 : 0 : nRet |= ChgToEnEmDash;
1324 : : }
1325 : : break;
1326 : : }
1327 : : }
1328 : :
1329 [ # # ]: 0 : if( ( IsAutoCorrFlag( nRet = ChgOrdinalNumber ) &&
[ # # # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
1330 [ # # ]: 0 : FnChgOrdinalNumber( rDoc, rTxt, nCapLttrPos, nInsPos, eLang ) ) ||
1331 : 0 : ( IsAutoCorrFlag( nRet = SetINetAttr ) &&
1332 : : ( ' ' == cChar || '\t' == cChar || 0x0a == cChar || !cChar ) &&
1333 [ # # ]: 0 : FnSetINetAttr( rDoc, rTxt, nCapLttrPos, nInsPos, eLang ) ) )
1334 : : ;
1335 : : else
1336 : : {
1337 [ # # ][ # # ]: 0 : bool bLockKeyOn = pFrameWin && (pFrameWin->GetIndicatorState() & INDICATOR_CAPSLOCK);
[ # # ]
1338 : :
1339 : 0 : nRet = 0;
1340 [ # # ][ # # ]: 0 : if ( bLockKeyOn && IsAutoCorrFlag( CorrectCapsLock ) &&
[ # # ][ # # ]
1341 [ # # ]: 0 : FnCorrectCapsLock( rDoc, rTxt, nCapLttrPos, nInsPos, eLang ) )
1342 : : {
1343 : : // Correct accidental use of cAPS LOCK key (do this only when
1344 : : // the caps or shift lock key is pressed). Turn off the caps
1345 : : // lock afterwords.
1346 : 0 : nRet |= CorrectCapsLock;
1347 [ # # ]: 0 : pFrameWin->SimulateKeyPress( KEY_CAPSLOCK );
1348 : : }
1349 : :
1350 : : // Capital letter at beginning of paragraph ?
1351 [ # # ][ # # ]: 0 : if( IsAutoCorrFlag( CptlSttSntnc ) &&
[ # # ]
1352 [ # # ]: 0 : FnCptlSttSntnc( rDoc, rTxt, sal_True, nCapLttrPos, nInsPos, eLang ) )
1353 : 0 : nRet |= CptlSttSntnc;
1354 : :
1355 : : // Two capital letters at beginning of word ??
1356 [ # # ][ # # ]: 0 : if( IsAutoCorrFlag( CptlSttWrd ) &&
[ # # ]
1357 [ # # ]: 0 : FnCptlSttWrd( rDoc, rTxt, nCapLttrPos, nInsPos, eLang ) )
1358 : 0 : nRet |= CptlSttWrd;
1359 : :
1360 [ # # ][ # # ]: 0 : if( IsAutoCorrFlag( ChgToEnEmDash ) &&
[ # # ]
1361 [ # # ]: 0 : FnChgToEnEmDash( rDoc, rTxt, nCapLttrPos, nInsPos, eLang ) )
1362 : 0 : nRet |= ChgToEnEmDash;
1363 : : }
1364 : :
1365 : : } while( sal_False );
1366 : :
1367 [ # # ]: 0 : if( nRet )
1368 : : {
1369 : : const char* aHelpIds[] =
1370 : : {
1371 : : HID_AUTOCORR_HELP_WORD,
1372 : : HID_AUTOCORR_HELP_SENT,
1373 : : HID_AUTOCORR_HELP_SENTWORD,
1374 : : HID_AUTOCORR_HELP_ACORWORD,
1375 : : "",
1376 : : HID_AUTOCORR_HELP_ACORSENTWORD,
1377 : : "",
1378 : : HID_AUTOCORR_HELP_CHGTOENEMDASH,
1379 : : HID_AUTOCORR_HELP_WORDENEMDASH,
1380 : : HID_AUTOCORR_HELP_SENTENEMDASH,
1381 : : HID_AUTOCORR_HELP_SENTWORDENEMDASH,
1382 : : HID_AUTOCORR_HELP_ACORWORDENEMDASH,
1383 : : "",
1384 : : HID_AUTOCORR_HELP_ACORSENTWORDENEMDASH,
1385 : : "",
1386 : : HID_AUTOCORR_HELP_CHGQUOTES,
1387 : : HID_AUTOCORR_HELP_CHGSGLQUOTES,
1388 : : HID_AUTOCORR_HELP_SETINETATTR,
1389 : : HID_AUTOCORR_HELP_INGNOREDOUBLESPACE,
1390 : : HID_AUTOCORR_HELP_CHGWEIGHTUNDERL,
1391 : : HID_AUTOCORR_HELP_CHGFRACTIONSYMBOL,
1392 : : HID_AUTOCORR_HELP_CHGORDINALNUMBER
1393 : 0 : };
1394 : :
1395 : 0 : sal_uLong nHelpId = 0;
1396 [ # # ]: 0 : if( nRet & ( Autocorrect|CptlSttSntnc|CptlSttWrd|ChgToEnEmDash ) )
1397 : : {
1398 : : // from 0 - 15
1399 [ # # ]: 0 : if( nRet & ChgToEnEmDash )
1400 : 0 : nHelpId += 8;
1401 [ # # ]: 0 : if( nRet & Autocorrect )
1402 : 0 : nHelpId += 4;
1403 [ # # ]: 0 : if( nRet & CptlSttSntnc )
1404 : 0 : nHelpId += 2;
1405 [ # # ]: 0 : if( nRet & CptlSttWrd )
1406 : 0 : nHelpId += 1;
1407 : : }
1408 : : else
1409 : : {
1410 [ # # ]: 0 : if( nRet & ChgQuotes) nHelpId = 16;
1411 [ # # ]: 0 : else if( nRet & ChgSglQuotes) nHelpId = 17;
1412 [ # # ]: 0 : else if( nRet & SetINetAttr) nHelpId = 18;
1413 [ # # ]: 0 : else if( nRet & IgnoreDoubleSpace) nHelpId = 19;
1414 [ # # ]: 0 : else if( nRet & ChgWeightUnderl) nHelpId = 20;
1415 [ # # ]: 0 : else if( nRet & AddNonBrkSpace) nHelpId = 21;
1416 [ # # ]: 0 : else if( nRet & ChgOrdinalNumber) nHelpId = 22;
1417 : : }
1418 : :
1419 [ # # ]: 0 : if( nHelpId )
1420 : : {
1421 : 0 : nHelpId -= 1;
1422 [ # # ][ # # ]: 0 : Application::GetHelp()->OpenHelpAgent( aHelpIds[nHelpId] );
1423 : : }
1424 : : }
1425 : :
1426 : :
1427 : 0 : return nRet;
1428 : : }
1429 : :
1430 : 0 : SvxAutoCorrectLanguageLists& SvxAutoCorrect::_GetLanguageList(
1431 : : LanguageType eLang )
1432 : : {
1433 [ # # ][ # # ]: 0 : if(pLangTable->find(eLang) == pLangTable->end())
[ # # ]
1434 : 0 : CreateLanguageFile(eLang, sal_True);
1435 [ # # ]: 0 : return *(pLangTable->find(eLang)->second);
1436 : : }
1437 : :
1438 : 0 : void SvxAutoCorrect::SaveCplSttExceptList( LanguageType eLang )
1439 : : {
1440 [ # # ]: 0 : boost::ptr_map<LanguageType, SvxAutoCorrectLanguageLists>::iterator nTmpVal = pLangTable->find(eLang);
1441 [ # # ][ # # ]: 0 : if(nTmpVal != pLangTable->end() && nTmpVal->second)
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # #
# # # # ]
1442 [ # # ][ # # ]: 0 : nTmpVal->second->SaveCplSttExceptList();
1443 : : #ifdef DBG_UTIL
1444 : : else
1445 : : {
1446 : : OSL_FAIL("Save an empty list? ");
1447 : : }
1448 : : #endif
1449 : 0 : }
1450 : :
1451 : 0 : void SvxAutoCorrect::SaveWrdSttExceptList(LanguageType eLang)
1452 : : {
1453 [ # # ]: 0 : boost::ptr_map<LanguageType, SvxAutoCorrectLanguageLists>::iterator nTmpVal = pLangTable->find(eLang);
1454 [ # # ][ # # ]: 0 : if(nTmpVal != pLangTable->end() && nTmpVal->second)
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # #
# # # # ]
1455 [ # # ][ # # ]: 0 : nTmpVal->second->SaveWrdSttExceptList();
1456 : : #ifdef DBG_UTIL
1457 : : else
1458 : : {
1459 : : OSL_FAIL("Save an empty list? ");
1460 : : }
1461 : : #endif
1462 : 0 : }
1463 : :
1464 : : // Adds a single word. The list will immediately be written to the file!
1465 : 0 : sal_Bool SvxAutoCorrect::AddCplSttException( const String& rNew,
1466 : : LanguageType eLang )
1467 : : {
1468 : 0 : SvxAutoCorrectLanguageLists* pLists = 0;
1469 : : // either the right language is present or it will be this in the general list
1470 [ # # ]: 0 : boost::ptr_map<LanguageType, SvxAutoCorrectLanguageLists>::iterator nTmpVal = pLangTable->find(eLang);
1471 [ # # ][ # # ]: 0 : if(nTmpVal != pLangTable->end())
[ # # ]
1472 [ # # ]: 0 : pLists = nTmpVal->second;
1473 : : else
1474 : : {
1475 [ # # ]: 0 : nTmpVal = pLangTable->find(LANGUAGE_DONTKNOW);
1476 [ # # ][ # # ]: 0 : if(nTmpVal != pLangTable->end())
[ # # ]
1477 [ # # ]: 0 : pLists = nTmpVal->second;
1478 [ # # ][ # # ]: 0 : else if(CreateLanguageFile(LANGUAGE_DONTKNOW, sal_True))
1479 [ # # ][ # # ]: 0 : pLists = pLangTable->find(LANGUAGE_DONTKNOW)->second;
1480 : : }
1481 : : OSL_ENSURE(pLists, "No auto correction data");
1482 [ # # ]: 0 : return pLists->AddToCplSttExceptList(rNew);
1483 : : }
1484 : :
1485 : : // Adds a single word. The list will immediately be written to the file!
1486 : 0 : sal_Bool SvxAutoCorrect::AddWrtSttException( const String& rNew,
1487 : : LanguageType eLang )
1488 : : {
1489 : 0 : SvxAutoCorrectLanguageLists* pLists = 0;
1490 : : //either the right language is present or it is set in the general list
1491 [ # # ]: 0 : boost::ptr_map<LanguageType, SvxAutoCorrectLanguageLists>::iterator nTmpVal = pLangTable->find(eLang);
1492 [ # # ][ # # ]: 0 : if(nTmpVal != pLangTable->end())
[ # # ]
1493 [ # # ]: 0 : pLists = nTmpVal->second;
1494 : : else
1495 : : {
1496 [ # # ]: 0 : nTmpVal = pLangTable->find(LANGUAGE_DONTKNOW);
1497 [ # # ][ # # ]: 0 : if(nTmpVal != pLangTable->end())
[ # # ]
1498 [ # # ]: 0 : pLists = nTmpVal->second;
1499 [ # # ][ # # ]: 0 : else if(CreateLanguageFile(LANGUAGE_DONTKNOW, sal_True))
1500 [ # # ][ # # ]: 0 : pLists = pLangTable->find(LANGUAGE_DONTKNOW)->second;
1501 : : }
1502 : : OSL_ENSURE(pLists, "keine Autokorrekturdatei");
1503 [ # # ]: 0 : return pLists->AddToWrdSttExceptList(rNew);
1504 : : }
1505 : :
1506 : 0 : sal_Bool SvxAutoCorrect::GetPrevAutoCorrWord( SvxAutoCorrDoc& rDoc,
1507 : : const String& rTxt, xub_StrLen nPos,
1508 : : String& rWord ) const
1509 : : {
1510 [ # # ]: 0 : if( !nPos )
1511 : 0 : return sal_False;
1512 : :
1513 : 0 : xub_StrLen nEnde = nPos;
1514 : :
1515 : : // it must be followed by a blank or tab!
1516 [ # # # # : 0 : if( ( nPos < rTxt.Len() &&
# # ][ # # ]
1517 : 0 : !IsWordDelim( rTxt.GetChar( nPos ))) ||
1518 : 0 : IsWordDelim( rTxt.GetChar( --nPos )))
1519 : 0 : return sal_False;
1520 : :
1521 [ # # ][ # # ]: 0 : while( nPos && !IsWordDelim( rTxt.GetChar( --nPos )))
[ # # ]
1522 : : ;
1523 : :
1524 : : // Found a Paragraph-start or a Blank, search for the word shortcut in
1525 : : // auto.
1526 : 0 : xub_StrLen nCapLttrPos = nPos+1; // on the 1st Character
1527 [ # # ][ # # ]: 0 : if( !nPos && !IsWordDelim( rTxt.GetChar( 0 )))
[ # # ]
1528 : 0 : --nCapLttrPos; // Beginning of pargraph and no Blank!
1529 : :
1530 [ # # ]: 0 : while( lcl_IsInAsciiArr( sImplSttSkipChars, rTxt.GetChar( nCapLttrPos )) )
1531 [ # # ]: 0 : if( ++nCapLttrPos >= nEnde )
1532 : 0 : return sal_False;
1533 : :
1534 [ # # ]: 0 : if( 3 > nEnde - nCapLttrPos )
1535 : 0 : return sal_False;
1536 : :
1537 : 0 : LanguageType eLang = rDoc.GetLanguage( nCapLttrPos, sal_False );
1538 [ # # ]: 0 : if( LANGUAGE_SYSTEM == eLang )
1539 : 0 : eLang = MsLangId::getSystemLanguage();
1540 : :
1541 : 0 : SvxAutoCorrect* pThis = (SvxAutoCorrect*)this;
1542 : 0 : CharClass& rCC = pThis->GetCharClass( eLang );
1543 : :
1544 [ # # ]: 0 : if( lcl_IsSymbolChar( rCC, rTxt, nCapLttrPos, nEnde ))
1545 : 0 : return sal_False;
1546 : :
1547 [ # # ]: 0 : rWord = rTxt.Copy( nCapLttrPos, nEnde - nCapLttrPos );
1548 : 0 : return sal_True;
1549 : : }
1550 : :
1551 : 0 : sal_Bool SvxAutoCorrect::CreateLanguageFile( LanguageType eLang, sal_Bool bNewFile )
1552 : : {
1553 : : OSL_ENSURE(pLangTable->find(eLang) == pLangTable->end(), "Language already exists ");
1554 : :
1555 [ # # ]: 0 : String sUserDirFile( GetAutoCorrFileName( eLang, sal_True, sal_False )),
1556 [ # # ]: 0 : sShareDirFile( sUserDirFile );
1557 : 0 : SvxAutoCorrectLanguageListsPtr pLists = 0;
1558 : :
1559 [ # # ][ # # ]: 0 : Time nMinTime( 0, 2 ), nAktTime( Time::SYSTEM ), nLastCheckTime( Time::EMPTY );
1560 : :
1561 [ # # ]: 0 : std::map<LanguageType, long>::iterator nFndPos = aLastFileTable.find(eLang);
1562 [ # # ][ # # : 0 : if(nFndPos != aLastFileTable.end() &&
# # # # ]
[ # # ]
[ # # # # ]
1563 [ # # ]: 0 : (nLastCheckTime.SetTime(nFndPos->second), nLastCheckTime < nAktTime) &&
1564 [ # # ][ # # ]: 0 : nAktTime - nLastCheckTime < nMinTime)
[ # # ]
1565 : : {
1566 : : // no need to test the file, because the last check is not older then
1567 : : // 2 minutes.
1568 [ # # ]: 0 : if( bNewFile )
1569 : : {
1570 [ # # ]: 0 : sShareDirFile = sUserDirFile;
1571 : : pLists = new SvxAutoCorrectLanguageLists( *this, sShareDirFile,
1572 [ # # ][ # # ]: 0 : sUserDirFile );
1573 [ # # ]: 0 : pLangTable->insert(eLang, pLists);
1574 [ # # ]: 0 : aLastFileTable.erase(nFndPos);
1575 : : }
1576 : : }
1577 [ # # ][ # # ]: 0 : else if( ( FStatHelper::IsDocument( sUserDirFile ) ||
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
[ # # # # ]
1578 : : FStatHelper::IsDocument( sShareDirFile =
1579 [ # # ][ # # ]: 0 : GetAutoCorrFileName( eLang, sal_False, sal_False ) ) ) ||
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
[ # # # # ]
1580 : : ( sShareDirFile = sUserDirFile, bNewFile ))
1581 : : {
1582 : : pLists = new SvxAutoCorrectLanguageLists( *this, sShareDirFile,
1583 [ # # ][ # # ]: 0 : sUserDirFile );
1584 [ # # ]: 0 : pLangTable->insert(eLang, pLists);
1585 [ # # ][ # # ]: 0 : if (nFndPos != aLastFileTable.end())
1586 [ # # ]: 0 : aLastFileTable.erase(nFndPos);
1587 : : }
1588 [ # # ]: 0 : else if( !bNewFile )
1589 : : {
1590 [ # # ]: 0 : aLastFileTable[eLang] = nAktTime.GetTime();
1591 : : }
1592 [ # # ][ # # ]: 0 : return pLists != 0;
1593 : : }
1594 : :
1595 : 0 : sal_Bool SvxAutoCorrect::PutText( const String& rShort, const String& rLong,
1596 : : LanguageType eLang )
1597 : : {
1598 [ # # ]: 0 : boost::ptr_map<LanguageType, SvxAutoCorrectLanguageLists>::iterator nTmpVal = pLangTable->find(eLang);
1599 [ # # ][ # # ]: 0 : if(nTmpVal != pLangTable->end())
[ # # ]
1600 [ # # ][ # # ]: 0 : return nTmpVal->second->PutText(rShort, rLong);
1601 [ # # ][ # # ]: 0 : if(CreateLanguageFile(eLang))
1602 [ # # ][ # # ]: 0 : return pLangTable->find(eLang)->second->PutText(rShort, rLong);
[ # # ]
1603 : 0 : return sal_False;
1604 : : }
1605 : :
1606 : : // - Delete an entry
1607 : 0 : sal_Bool SvxAutoCorrect::DeleteText( const String& rShort, LanguageType eLang )
1608 : : {
1609 [ # # ]: 0 : boost::ptr_map<LanguageType, SvxAutoCorrectLanguageLists>::iterator nTmpVal = pLangTable->find(eLang);
1610 [ # # ][ # # ]: 0 : if(nTmpVal != pLangTable->end())
[ # # ]
1611 [ # # ][ # # ]: 0 : return nTmpVal->second->DeleteText(rShort);
1612 : 0 : return sal_False;
1613 : : }
1614 : :
1615 : : // - return the replacement text (only for SWG-Format, all other
1616 : : // can be taken from the word list!)
1617 : 0 : sal_Bool SvxAutoCorrect::GetLongText( const com::sun::star::uno::Reference < com::sun::star::embed::XStorage >&, const String&, const String& , String& )
1618 : : {
1619 : 0 : return sal_False;
1620 : : }
1621 : :
1622 : : // Text with attribution (only the SWG - SWG format!)
1623 : 0 : sal_Bool SvxAutoCorrect::PutText( const com::sun::star::uno::Reference < com::sun::star::embed::XStorage >&, const String&, const String&, SfxObjectShell&,
1624 : : String& )
1625 : : {
1626 : 0 : return sal_False;
1627 : : }
1628 : :
1629 : 0 : void EncryptBlockName_Imp( String& rName )
1630 : : {
1631 : 0 : xub_StrLen nLen, nPos = 1;
1632 : 0 : rName.Insert( '#', 0 );
1633 : 0 : sal_Unicode* pName = rName.GetBufferAccess();
1634 [ # # ]: 0 : for ( nLen = rName.Len(), ++pName; nPos < nLen; ++nPos, ++pName )
1635 : : {
1636 [ # # ]: 0 : if( lcl_IsInAsciiArr( "!/:.\\", *pName ))
1637 : 0 : *pName &= 0x0f;
1638 : : }
1639 : 0 : }
1640 : :
1641 : : /* This code is copied from SwXMLTextBlocks::GeneratePackageName */
1642 : 0 : static void GeneratePackageName ( const String& rShort, String& rPackageName )
1643 : : {
1644 [ # # ]: 0 : rPackageName = rShort;
1645 : 0 : xub_StrLen nPos = 0;
1646 : 0 : sal_Unicode pDelims[] = { '!', '/', ':', '.', '\\', 0 };
1647 [ # # ][ # # ]: 0 : rtl::OString sByte(rtl::OUStringToOString(rPackageName, RTL_TEXTENCODING_UTF7));
1648 [ # # ][ # # ]: 0 : rPackageName = rtl::OStringToOUString(sByte, RTL_TEXTENCODING_ASCII_US);
1649 [ # # ][ # # ]: 0 : while( STRING_NOTFOUND != ( nPos = rPackageName.SearchChar( pDelims, nPos )))
1650 : : {
1651 [ # # ]: 0 : rPackageName.SetChar( nPos, '_' );
1652 : 0 : ++nPos;
1653 : 0 : }
1654 : 0 : }
1655 : :
1656 : 0 : static const SvxAutocorrWord* lcl_SearchWordsInList(
1657 : : SvxAutoCorrectLanguageListsPtr pList, const String& rTxt,
1658 : : xub_StrLen& rStt, xub_StrLen nEndPos, SvxAutoCorrDoc& )
1659 : : {
1660 : 0 : const SvxAutocorrWordList* pAutoCorrWordList = pList->GetAutocorrWordList();
1661 : 0 : TransliterationWrapper& rCmp = GetIgnoreTranslWrapper();
1662 [ # # ][ # # ]: 0 : for( SvxAutocorrWordList::const_iterator it = pAutoCorrWordList->begin(); it != pAutoCorrWordList->end(); ++it )
[ # # ]
1663 : : {
1664 [ # # ]: 0 : const SvxAutocorrWord* pFnd = *it;
1665 : 0 : const String& rChk = pFnd->GetShort();
1666 [ # # ]: 0 : if( nEndPos >= rChk.Len() )
1667 : : {
1668 : 0 : xub_StrLen nCalcStt = nEndPos - rChk.Len();
1669 [ # # ]: 0 : if( ( !nCalcStt || nCalcStt == rStt ||
[ # # # # ]
[ # # ][ # # ]
1670 : : ( nCalcStt < rStt &&
1671 : 0 : IsWordDelim( rTxt.GetChar(nCalcStt - 1 ) ))) )
1672 : : {
1673 : 0 : rtl::OUString sWord(rTxt.GetBuffer() + nCalcStt, rChk.Len());
1674 [ # # ][ # # ]: 0 : if( rCmp.isEqual( rChk, sWord ))
[ # # ][ # # ]
1675 : : {
1676 : 0 : rStt = nCalcStt;
1677 : 0 : return pFnd;
1678 [ # # ]: 0 : }
1679 : : }
1680 : : }
1681 : : }
1682 : 0 : return 0;
1683 : : }
1684 : :
1685 : :
1686 : : // the search or the words in the substitution table
1687 : 0 : const SvxAutocorrWord* SvxAutoCorrect::SearchWordsInList(
1688 : : const String& rTxt, xub_StrLen& rStt, xub_StrLen nEndPos,
1689 : : SvxAutoCorrDoc& rDoc, LanguageType& rLang )
1690 : : {
1691 : 0 : LanguageType eLang = rLang;
1692 : 0 : const SvxAutocorrWord* pRet = 0;
1693 [ # # ]: 0 : if( LANGUAGE_SYSTEM == eLang )
1694 [ # # ]: 0 : eLang = MsLangId::getSystemLanguage();
1695 : :
1696 : : // First search for eLang, then US-English -> English
1697 : : // and last in LANGUAGE_DONTKNOW
1698 [ # # ][ # # ]: 0 : if(pLangTable->find(eLang) != pLangTable->end() || CreateLanguageFile(eLang, sal_False))
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # # #
# # ]
1699 : : {
1700 : : //the language is available - so bring it on
1701 [ # # ][ # # ]: 0 : SvxAutoCorrectLanguageLists* pList = pLangTable->find(eLang)->second;
1702 [ # # ]: 0 : pRet = lcl_SearchWordsInList( pList, rTxt, rStt, nEndPos, rDoc );
1703 [ # # ]: 0 : if( pRet )
1704 : : {
1705 : 0 : rLang = eLang;
1706 : 0 : return pRet;
1707 : : }
1708 : : }
1709 : :
1710 : : // If it still could not be found here, then keep on searching
1711 : :
1712 : 0 : LanguageType nTmpKey1 = eLang & 0x7ff, // the main language in many cases DE
1713 : 0 : nTmpKey2 = eLang & 0x3ff; // otherwise for example EN
1714 [ # # ][ # # ]: 0 : if(nTmpKey1 != eLang && (pLangTable->find(nTmpKey1) != pLangTable->end() || CreateLanguageFile(nTmpKey1, sal_False)))
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # #
# # # # ]
1715 : : {
1716 : : //the language is available - so bring it on
1717 [ # # ][ # # ]: 0 : SvxAutoCorrectLanguageLists* pList = pLangTable->find(nTmpKey1)->second;
1718 [ # # ]: 0 : pRet = lcl_SearchWordsInList( pList, rTxt, rStt, nEndPos, rDoc);
1719 [ # # ]: 0 : if( pRet )
1720 : : {
1721 : 0 : rLang = nTmpKey1;
1722 : 0 : return pRet;
1723 : : }
1724 : : }
1725 : :
1726 [ # # ][ # # ]: 0 : if(nTmpKey2 != eLang && (pLangTable->find(nTmpKey2) != pLangTable->end() || CreateLanguageFile(nTmpKey2, sal_False)))
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # #
# # # # ]
1727 : : {
1728 : : //the language is available - so bring it on
1729 [ # # ][ # # ]: 0 : SvxAutoCorrectLanguageLists* pList = pLangTable->find(nTmpKey2)->second;
1730 [ # # ]: 0 : pRet = lcl_SearchWordsInList( pList, rTxt, rStt, nEndPos, rDoc);
1731 [ # # ]: 0 : if( pRet )
1732 : : {
1733 : 0 : rLang = nTmpKey2;
1734 : 0 : return pRet;
1735 : : }
1736 : : }
1737 : :
1738 [ # # ][ # # ]: 0 : if(pLangTable->find(LANGUAGE_DONTKNOW) != pLangTable->end() || CreateLanguageFile(LANGUAGE_DONTKNOW, sal_False))
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # #
# # # # #
# ]
1739 : : {
1740 : : //the language is available - so bring it on
1741 [ # # ][ # # ]: 0 : SvxAutoCorrectLanguageLists* pList = pLangTable->find(LANGUAGE_DONTKNOW)->second;
1742 [ # # ]: 0 : pRet = lcl_SearchWordsInList( pList, rTxt, rStt, nEndPos, rDoc);
1743 [ # # ]: 0 : if( pRet )
1744 : : {
1745 : 0 : rLang = LANGUAGE_DONTKNOW;
1746 : 0 : return pRet;
1747 : : }
1748 : : }
1749 : 0 : return 0;
1750 : : }
1751 : :
1752 : 0 : sal_Bool SvxAutoCorrect::FindInWrdSttExceptList( LanguageType eLang,
1753 : : const String& sWord )
1754 : : {
1755 : : // First search for eLang, then US-English -> English
1756 : : // and last in LANGUAGE_DONTKNOW
1757 : 0 : LanguageType nTmpKey1 = eLang & 0x7ff, // the main language in many cases DE
1758 : 0 : nTmpKey2 = eLang & 0x3ff; // otherwise for example EN
1759 [ # # ]: 0 : String sTemp(sWord);
1760 : :
1761 [ # # ][ # # ]: 0 : if(pLangTable->find(eLang) != pLangTable->end() || CreateLanguageFile(eLang, sal_False))
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # # #
# # ]
1762 : : {
1763 : : //the language is available - so bring it on
1764 [ # # ][ # # ]: 0 : SvxAutoCorrectLanguageLists* pList = pLangTable->find(eLang)->second;
1765 [ # # ]: 0 : String _sTemp(sWord);
1766 [ # # ][ # # ]: 0 : if(pList->GetWrdSttExceptList()->find(&_sTemp) != pList->GetWrdSttExceptList()->end() )
[ # # ][ # # ]
[ # # ]
1767 [ # # ][ # # ]: 0 : return sal_True;
1768 : : }
1769 : :
1770 : : // If it still could not be found here, then keep on searching
1771 [ # # ][ # # ]: 0 : if(nTmpKey1 != eLang && (pLangTable->find(nTmpKey1) != pLangTable->end() || CreateLanguageFile(nTmpKey1, sal_False)))
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # #
# # # # ]
1772 : : {
1773 : : //the language is available - so bring it on
1774 [ # # ][ # # ]: 0 : SvxAutoCorrectLanguageLists* pList = pLangTable->find(nTmpKey1)->second;
1775 [ # # ][ # # ]: 0 : if(pList->GetWrdSttExceptList()->find(&sTemp) != pList->GetWrdSttExceptList()->end() )
[ # # ][ # # ]
[ # # ]
1776 : 0 : return sal_True;
1777 : : }
1778 : :
1779 [ # # ][ # # ]: 0 : if(nTmpKey2 != eLang && (pLangTable->find(nTmpKey2) != pLangTable->end() || CreateLanguageFile(nTmpKey2, sal_False)))
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # #
# # # # ]
1780 : : {
1781 : : //the language is available - so bring it on
1782 [ # # ][ # # ]: 0 : SvxAutoCorrectLanguageLists* pList = pLangTable->find(nTmpKey2)->second;
1783 [ # # ][ # # ]: 0 : if(pList->GetWrdSttExceptList()->find(&sTemp) != pList->GetWrdSttExceptList()->end() )
[ # # ][ # # ]
[ # # ]
1784 : 0 : return sal_True;
1785 : : }
1786 : :
1787 [ # # ][ # # ]: 0 : if(pLangTable->find(LANGUAGE_DONTKNOW) != pLangTable->end() || CreateLanguageFile(LANGUAGE_DONTKNOW, sal_False))
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # #
# # # # #
# ]
1788 : : {
1789 : : //the language is available - so bring it on
1790 [ # # ][ # # ]: 0 : SvxAutoCorrectLanguageLists* pList = pLangTable->find(LANGUAGE_DONTKNOW)->second;
1791 [ # # ][ # # ]: 0 : if(pList->GetWrdSttExceptList()->find(&sTemp) != pList->GetWrdSttExceptList()->end() )
[ # # ][ # # ]
[ # # ]
1792 : 0 : return sal_True;
1793 : : }
1794 [ # # ]: 0 : return sal_False;
1795 : : }
1796 : :
1797 : 0 : static sal_Bool lcl_FindAbbreviation( const SvStringsISortDtor* pList, const String& sWord)
1798 : : {
1799 [ # # ]: 0 : String sAbk(rtl::OUString('~'));
1800 [ # # ]: 0 : SvStringsISortDtor::const_iterator it = pList->find( &sAbk );
1801 [ # # ]: 0 : sal_uInt16 nPos = it - pList->begin();
1802 [ # # ]: 0 : if( nPos < pList->size() )
1803 : : {
1804 [ # # ][ # # ]: 0 : String sLowerWord( sWord ); sLowerWord.ToLowerAscii();
1805 : : const String* pAbk;
1806 [ # # # # ]: 0 : for( sal_uInt16 n = nPos;
[ # # ]
1807 : 0 : n < pList->size() &&
1808 [ # # ]: 0 : '~' == ( pAbk = (*pList)[ n ])->GetChar( 0 );
1809 : : ++n )
1810 : : {
1811 : : // ~ and ~. are not allowed!
1812 [ # # ][ # # ]: 0 : if( 2 < pAbk->Len() && pAbk->Len() - 1 <= sWord.Len() )
[ # # ]
1813 : : {
1814 [ # # ][ # # ]: 0 : String sLowerAbk( *pAbk ); sLowerAbk.ToLowerAscii();
1815 [ # # ]: 0 : for( xub_StrLen i = sLowerAbk.Len(), ii = sLowerWord.Len(); i; )
1816 : : {
1817 [ # # ]: 0 : if( !--i ) // agrees
1818 : 0 : return sal_True;
1819 : :
1820 [ # # ]: 0 : if( sLowerAbk.GetChar( i ) != sLowerWord.GetChar( --ii ))
1821 : 0 : break;
1822 [ # # ][ # # ]: 0 : }
1823 : : }
1824 [ # # ][ # # ]: 0 : }
1825 : : }
1826 : : OSL_ENSURE( !(nPos && '~' == (*pList)[ --nPos ]->GetChar( 0 ) ),
1827 : : "Wrongly sorted exception list?" );
1828 [ # # ]: 0 : return sal_False;
1829 : : }
1830 : :
1831 : 0 : sal_Bool SvxAutoCorrect::FindInCplSttExceptList(LanguageType eLang,
1832 : : const String& sWord, sal_Bool bAbbreviation)
1833 : : {
1834 : : // First search for eLang, then US-English -> English
1835 : : // and last in LANGUAGE_DONTKNOW
1836 : 0 : LanguageType nTmpKey1 = eLang & 0x7ff, // the main language in many cases DE
1837 : 0 : nTmpKey2 = eLang & 0x3ff; // otherwise for example EN
1838 [ # # ]: 0 : String sTemp( sWord );
1839 : :
1840 [ # # ][ # # ]: 0 : if(pLangTable->find(eLang) != pLangTable->end() || CreateLanguageFile(eLang, sal_False))
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # # #
# # ]
1841 : : {
1842 : : //the language is available - so bring it on
1843 [ # # ][ # # ]: 0 : const SvStringsISortDtor* pList = pLangTable->find(eLang)->second->GetCplSttExceptList();
[ # # ]
1844 [ # # ][ # # ]: 0 : if(bAbbreviation ? lcl_FindAbbreviation(pList, sWord) : pList->find(&sTemp) != pList->end() )
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # #
# # # # #
# ]
1845 : 0 : return sal_True;
1846 : : }
1847 : :
1848 : : // If it still could not be found here, then keep on searching
1849 [ # # ][ # # ]: 0 : if(nTmpKey1 != eLang && (pLangTable->find(nTmpKey1) != pLangTable->end() || CreateLanguageFile(nTmpKey1, sal_False)))
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # #
# # # # ]
1850 : : {
1851 [ # # ][ # # ]: 0 : const SvStringsISortDtor* pList = pLangTable->find(nTmpKey1)->second->GetCplSttExceptList();
[ # # ]
1852 [ # # ][ # # ]: 0 : if(bAbbreviation ? lcl_FindAbbreviation(pList, sWord) : pList->find(&sTemp) != pList->end() )
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # #
# # # # #
# ]
1853 : 0 : return sal_True;
1854 : : }
1855 : :
1856 [ # # ][ # # ]: 0 : if(nTmpKey2 != eLang && (pLangTable->find(nTmpKey2) != pLangTable->end() || CreateLanguageFile(nTmpKey2, sal_False)))
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # #
# # # # ]
1857 : : {
1858 : : //the language is available - so bring it on
1859 [ # # ][ # # ]: 0 : const SvStringsISortDtor* pList = pLangTable->find(nTmpKey2)->second->GetCplSttExceptList();
[ # # ]
1860 [ # # ][ # # ]: 0 : if(bAbbreviation ? lcl_FindAbbreviation(pList, sWord) : pList->find(&sTemp) != pList->end() )
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # #
# # # # #
# ]
1861 : 0 : return sal_True;
1862 : : }
1863 : :
1864 [ # # ][ # # ]: 0 : if(pLangTable->find(LANGUAGE_DONTKNOW) != pLangTable->end() || CreateLanguageFile(LANGUAGE_DONTKNOW, sal_False))
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # #
# # # # #
# ]
1865 : : {
1866 : : //the language is available - so bring it on
1867 [ # # ][ # # ]: 0 : const SvStringsISortDtor* pList = pLangTable->find(LANGUAGE_DONTKNOW)->second->GetCplSttExceptList();
[ # # ]
1868 [ # # ][ # # ]: 0 : if(bAbbreviation ? lcl_FindAbbreviation(pList, sWord) : pList->find(&sTemp) != pList->end() )
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # #
# # # # #
# ]
1869 : 0 : return sal_True;
1870 : : }
1871 [ # # ]: 0 : return sal_False;
1872 : : }
1873 : :
1874 : 0 : String SvxAutoCorrect::GetAutoCorrFileName( LanguageType eLang,
1875 : : sal_Bool bNewFile, sal_Bool bTst ) const
1876 : : {
1877 [ # # ][ # # ]: 0 : String sRet, sExt( MsLangId::convertLanguageToIsoString( eLang ) );
[ # # ]
1878 [ # # ]: 0 : sExt.Insert('_', 0);
1879 [ # # ]: 0 : sExt.AppendAscii( ".dat" );
1880 [ # # ]: 0 : if( bNewFile )
1881 [ # # ][ # # ]: 0 : ( sRet = sUserAutoCorrFile ) += sExt;
1882 [ # # ]: 0 : else if( !bTst )
1883 [ # # ][ # # ]: 0 : ( sRet = sShareAutoCorrFile ) += sExt;
1884 : : else
1885 : : {
1886 : : // test first in the user directory - if not exist, then
1887 [ # # ][ # # ]: 0 : ( sRet = sUserAutoCorrFile ) += sExt;
1888 [ # # ][ # # ]: 0 : if( !FStatHelper::IsDocument( sRet ))
[ # # ]
1889 [ # # ][ # # ]: 0 : ( sRet = sShareAutoCorrFile ) += sExt;
1890 : : }
1891 [ # # ]: 0 : return sRet;
1892 : : }
1893 : :
1894 : 0 : SvxAutoCorrectLanguageLists::SvxAutoCorrectLanguageLists(
1895 : : SvxAutoCorrect& rParent,
1896 : : const String& rShareAutoCorrectFile,
1897 : : const String& rUserAutoCorrectFile)
1898 : : : sShareAutoCorrFile( rShareAutoCorrectFile ),
1899 : : sUserAutoCorrFile( rUserAutoCorrectFile ),
1900 : : aModifiedDate( Date::EMPTY ),
1901 : : aModifiedTime( Time::EMPTY ),
1902 : : aLastCheckTime( Time::EMPTY ),
1903 : : pCplStt_ExcptLst( 0 ),
1904 : : pWrdStt_ExcptLst( 0 ),
1905 : : pAutocorr_List( 0 ),
1906 : : rAutoCorrect(rParent),
1907 [ # # ]: 0 : nFlags(0)
1908 : : {
1909 : 0 : }
1910 : :
1911 [ # # ]: 0 : SvxAutoCorrectLanguageLists::~SvxAutoCorrectLanguageLists()
1912 : : {
1913 [ # # ][ # # ]: 0 : delete pCplStt_ExcptLst;
1914 [ # # ][ # # ]: 0 : delete pWrdStt_ExcptLst;
1915 [ # # ][ # # ]: 0 : delete pAutocorr_List;
1916 : 0 : }
1917 : :
1918 : 0 : sal_Bool SvxAutoCorrectLanguageLists::IsFileChanged_Imp()
1919 : : {
1920 : : // Access the file system only every 2 minutes to check the date stamp
1921 : 0 : sal_Bool bRet = sal_False;
1922 : :
1923 [ # # ]: 0 : Time nMinTime( 0, 2 );
1924 [ # # ]: 0 : Time nAktTime( Time::SYSTEM );
1925 [ # # # # ]: 0 : if( aLastCheckTime > nAktTime || // overflow?
[ # # ]
1926 [ # # ]: 0 : ( nAktTime -= aLastCheckTime ) > nMinTime ) // min time past
1927 : : {
1928 : 0 : Date aTstDate( Date::EMPTY ); Time aTstTime( Time::EMPTY );
1929 [ # # # # : 0 : if( FStatHelper::GetModifiedDateTimeOfFile( sShareAutoCorrFile,
# # ][ # # ]
1930 [ # # ][ # # ]: 0 : &aTstDate, &aTstTime ) &&
[ # # ][ # # ]
1931 : 0 : ( aModifiedDate != aTstDate || aModifiedTime != aTstTime ))
1932 : : {
1933 : 0 : bRet = sal_True;
1934 : : // then remove all the lists fast!
1935 [ # # ][ # # ]: 0 : if( CplSttLstLoad & nFlags && pCplStt_ExcptLst )
1936 [ # # ][ # # ]: 0 : delete pCplStt_ExcptLst, pCplStt_ExcptLst = 0;
1937 [ # # ][ # # ]: 0 : if( WrdSttLstLoad & nFlags && pWrdStt_ExcptLst )
1938 [ # # ][ # # ]: 0 : delete pWrdStt_ExcptLst, pWrdStt_ExcptLst = 0;
1939 [ # # ][ # # ]: 0 : if( ChgWordLstLoad & nFlags && pAutocorr_List )
1940 [ # # ][ # # ]: 0 : delete pAutocorr_List, pAutocorr_List = 0;
1941 : 0 : nFlags &= ~(CplSttLstLoad | WrdSttLstLoad | ChgWordLstLoad );
1942 : : }
1943 [ # # ][ # # ]: 0 : aLastCheckTime = Time( Time::SYSTEM );
1944 : : }
1945 : 0 : return bRet;
1946 : : }
1947 : :
1948 : 0 : void SvxAutoCorrectLanguageLists::LoadXMLExceptList_Imp(
1949 : : SvStringsISortDtor*& rpLst,
1950 : : const sal_Char* pStrmName,
1951 : : SotStorageRef& rStg)
1952 : : {
1953 [ # # ]: 0 : if( rpLst )
1954 : 0 : rpLst->DeleteAndDestroyAll();
1955 : : else
1956 [ # # ]: 0 : rpLst = new SvStringsISortDtor;
1957 : :
1958 : : {
1959 [ # # ]: 0 : String sStrmName( pStrmName, RTL_TEXTENCODING_MS_1252 );
1960 [ # # ]: 0 : String sTmp( sStrmName );
1961 : :
1962 [ # # ][ # # ]: 0 : if( rStg.Is() && rStg->IsStream( sStrmName ) )
[ # # ][ # # ]
1963 : : {
1964 : : SvStorageStreamRef xStrm = rStg->OpenSotStream( sTmp,
1965 [ # # ]: 0 : ( STREAM_READ | STREAM_SHARE_DENYWRITE | STREAM_NOCREATE ) );
1966 [ # # ]: 0 : if( SVSTREAM_OK != xStrm->GetError())
1967 : : {
1968 [ # # ]: 0 : xStrm.Clear();
1969 [ # # ]: 0 : rStg.Clear();
1970 [ # # ]: 0 : RemoveStream_Imp( sStrmName );
1971 : : }
1972 : : else
1973 : : {
1974 : : uno::Reference< lang::XMultiServiceFactory > xServiceFactory =
1975 [ # # ]: 0 : comphelper::getProcessServiceFactory();
1976 : : OSL_ENSURE( xServiceFactory.is(),
1977 : : "XMLReader::Read: got no service manager" );
1978 : 0 : if( !xServiceFactory.is() )
1979 : : {
1980 : : // Throw an exception ?
1981 : : }
1982 : :
1983 [ # # ]: 0 : xml::sax::InputSource aParserInput;
1984 [ # # ]: 0 : aParserInput.sSystemId = sStrmName;
1985 : :
1986 [ # # ]: 0 : xStrm->Seek( 0L );
1987 [ # # ]: 0 : xStrm->SetBufferSize( 8 * 1024 );
1988 [ # # ][ # # ]: 0 : aParserInput.aInputStream = new utl::OInputStreamWrapper( *xStrm );
[ # # ]
1989 : :
1990 : : // get parser
1991 [ # # ]: 0 : uno::Reference< XInterface > xXMLParser = xServiceFactory->createInstance(
1992 [ # # ]: 0 : OUString("com.sun.star.xml.sax.Parser") );
1993 : : OSL_ENSURE( xXMLParser.is(),
1994 : : "XMLReader::Read: com.sun.star.xml.sax.Parser service missing" );
1995 : 0 : if( !xXMLParser.is() )
1996 : : {
1997 : : // Maybe throw an exception?
1998 : : }
1999 : :
2000 : : // get filter
2001 [ # # ][ # # ]: 0 : uno::Reference< xml::sax::XDocumentHandler > xFilter = new SvXMLExceptionListImport ( xServiceFactory, *rpLst );
[ # # # # ]
[ # # ]
2002 : :
2003 : : // connect parser and filter
2004 [ # # ]: 0 : uno::Reference< xml::sax::XParser > xParser( xXMLParser, UNO_QUERY );
2005 [ # # ][ # # ]: 0 : xParser->setDocumentHandler( xFilter );
2006 : :
2007 : : // parse
2008 : : try
2009 : : {
2010 [ # # ][ # # ]: 0 : xParser->parseStream( aParserInput );
2011 : : }
2012 [ # # ]: 0 : catch( const xml::sax::SAXParseException& )
2013 : : {
2014 : : // re throw ?
2015 : : }
2016 [ # # ]: 0 : catch( const xml::sax::SAXException& )
2017 : : {
2018 : : // re throw ?
2019 : : }
2020 [ # # ]: 0 : catch( const io::IOException& )
2021 : : {
2022 : : // re throw ?
2023 [ # # ]: 0 : }
2024 [ # # ]: 0 : }
2025 : : }
2026 : :
2027 : : // Set time stamp
2028 : : FStatHelper::GetModifiedDateTimeOfFile( sShareAutoCorrFile,
2029 [ # # ][ # # ]: 0 : &aModifiedDate, &aModifiedTime );
2030 [ # # ][ # # ]: 0 : aLastCheckTime = Time( Time::SYSTEM );
[ # # ][ # # ]
2031 : : }
2032 : :
2033 : 0 : }
2034 : :
2035 : 0 : void SvxAutoCorrectLanguageLists::SaveExceptList_Imp(
2036 : : const SvStringsISortDtor& rLst,
2037 : : const sal_Char* pStrmName,
2038 : : SotStorageRef &rStg,
2039 : : sal_Bool bConvert )
2040 : : {
2041 [ # # ]: 0 : if( rStg.Is() )
2042 : : {
2043 [ # # ]: 0 : String sStrmName( pStrmName, RTL_TEXTENCODING_MS_1252 );
2044 [ # # ]: 0 : if( rLst.empty() )
2045 : : {
2046 [ # # ]: 0 : rStg->Remove( sStrmName );
2047 [ # # ]: 0 : rStg->Commit();
2048 : : }
2049 : : else
2050 : : {
2051 : : SotStorageStreamRef xStrm = rStg->OpenSotStream( sStrmName,
2052 [ # # ]: 0 : ( STREAM_READ | STREAM_WRITE | STREAM_SHARE_DENYWRITE ) );
2053 [ # # ]: 0 : if( xStrm.Is() )
2054 : : {
2055 [ # # ]: 0 : xStrm->SetSize( 0 );
2056 [ # # ]: 0 : xStrm->SetBufferSize( 8192 );
2057 : 0 : OUString aMime( "text/xml" );
2058 : 0 : uno::Any aAny;
2059 [ # # ]: 0 : aAny <<= aMime;
2060 [ # # ][ # # ]: 0 : xStrm->SetProperty( rtl::OUString("MediaType"), aAny );
[ # # ]
2061 : :
2062 : :
2063 : : uno::Reference< lang::XMultiServiceFactory > xServiceFactory =
2064 [ # # ]: 0 : comphelper::getProcessServiceFactory();
2065 : : OSL_ENSURE( xServiceFactory.is(),
2066 : : "XMLReader::Read: got no service manager" );
2067 : 0 : if( !xServiceFactory.is() )
2068 : : {
2069 : : // Throw an exception ?
2070 : : }
2071 : :
2072 [ # # ]: 0 : uno::Reference < XInterface > xWriter (xServiceFactory->createInstance(
2073 [ # # ]: 0 : OUString("com.sun.star.xml.sax.Writer")));
2074 : : OSL_ENSURE(xWriter.is(),"com.sun.star.xml.sax.Writer service missing");
2075 [ # # ][ # # ]: 0 : uno::Reference < io::XOutputStream> xOut = new utl::OOutputStreamWrapper( *xStrm );
[ # # ]
2076 [ # # ]: 0 : uno::Reference<io::XActiveDataSource> xSrc(xWriter, uno::UNO_QUERY);
2077 [ # # ][ # # ]: 0 : xSrc->setOutputStream(xOut);
2078 : :
2079 [ # # ]: 0 : uno::Reference<xml::sax::XDocumentHandler> xHandler(xWriter, uno::UNO_QUERY);
2080 : :
2081 [ # # ][ # # ]: 0 : SvXMLExceptionListExport aExp( xServiceFactory, rLst, sStrmName, xHandler );
2082 : :
2083 [ # # ]: 0 : aExp.exportDoc( XML_BLOCK_LIST );
2084 : :
2085 [ # # ]: 0 : xStrm->Commit();
2086 [ # # ]: 0 : if( xStrm->GetError() == SVSTREAM_OK )
2087 : : {
2088 [ # # ]: 0 : xStrm.Clear();
2089 [ # # ]: 0 : if (!bConvert)
2090 : : {
2091 [ # # ]: 0 : rStg->Commit();
2092 [ # # ]: 0 : if( SVSTREAM_OK != rStg->GetError() )
2093 : : {
2094 [ # # ]: 0 : rStg->Remove( sStrmName );
2095 [ # # ]: 0 : rStg->Commit();
2096 : : }
2097 : : }
2098 [ # # ]: 0 : }
2099 [ # # ]: 0 : }
2100 [ # # ]: 0 : }
2101 : : }
2102 : 0 : }
2103 : :
2104 : 0 : SvxAutocorrWordList* SvxAutoCorrectLanguageLists::LoadAutocorrWordList()
2105 : : {
2106 [ # # ]: 0 : if( pAutocorr_List )
2107 : 0 : pAutocorr_List->DeleteAndDestroyAll();
2108 : : else
2109 [ # # ]: 0 : pAutocorr_List = new SvxAutocorrWordList();
2110 : :
2111 : : try
2112 : : {
2113 [ # # ][ # # ]: 0 : uno::Reference < embed::XStorage > xStg = comphelper::OStorageHelper::GetStorageFromURL( sShareAutoCorrFile, embed::ElementModes::READ );
2114 [ # # ]: 0 : String aXMLWordListName( pXMLImplAutocorr_ListStr, RTL_TEXTENCODING_MS_1252 );
2115 [ # # ][ # # ]: 0 : uno::Reference < io::XStream > xStrm = xStg->openStreamElement( aXMLWordListName, embed::ElementModes::READ );
[ # # ]
2116 [ # # ]: 0 : uno::Reference< lang::XMultiServiceFactory > xServiceFactory = comphelper::getProcessServiceFactory();
2117 : :
2118 [ # # ]: 0 : xml::sax::InputSource aParserInput;
2119 [ # # ]: 0 : aParserInput.sSystemId = aXMLWordListName;
2120 [ # # ][ # # ]: 0 : aParserInput.aInputStream = xStrm->getInputStream();
[ # # ]
2121 : :
2122 : : // get parser
2123 [ # # ][ # # ]: 0 : uno::Reference< XInterface > xXMLParser = xServiceFactory->createInstance( OUString("com.sun.star.xml.sax.Parser") );
2124 : : OSL_ENSURE( xXMLParser.is(), "XMLReader::Read: com.sun.star.xml.sax.Parser service missing" );
2125 [ # # ]: 0 : if( xXMLParser.is() )
2126 : : {
2127 [ # # ]: 0 : RTL_LOGFILE_PRODUCT_CONTEXT( aLog, "AutoCorrect Import" );
2128 [ # # ][ # # ]: 0 : uno::Reference< xml::sax::XDocumentHandler > xFilter = new SvXMLAutoCorrectImport( xServiceFactory, pAutocorr_List, rAutoCorrect, xStg );
[ # # ]
2129 : :
2130 : : // connect parser and filter
2131 [ # # ]: 0 : uno::Reference< xml::sax::XParser > xParser( xXMLParser, UNO_QUERY );
2132 [ # # ][ # # ]: 0 : xParser->setDocumentHandler( xFilter );
2133 : :
2134 : : // parse
2135 [ # # ][ # # ]: 0 : xParser->parseStream( aParserInput );
[ # # ]
2136 [ # # ][ # # ]: 0 : }
[ # # ]
2137 : : }
2138 : 0 : catch ( const uno::Exception& )
2139 : : {
2140 : : }
2141 : :
2142 : : // Set time stamp
2143 : : FStatHelper::GetModifiedDateTimeOfFile( sShareAutoCorrFile,
2144 [ # # ]: 0 : &aModifiedDate, &aModifiedTime );
2145 [ # # ]: 0 : aLastCheckTime = Time( Time::SYSTEM );
2146 : :
2147 : 0 : return pAutocorr_List;
2148 : : }
2149 : :
2150 : 0 : void SvxAutoCorrectLanguageLists::SetAutocorrWordList( SvxAutocorrWordList* pList )
2151 : : {
2152 [ # # ][ # # ]: 0 : if( pAutocorr_List && pList != pAutocorr_List )
2153 [ # # ]: 0 : delete pAutocorr_List;
2154 : 0 : pAutocorr_List = pList;
2155 [ # # ]: 0 : if( !pAutocorr_List )
2156 : : {
2157 : : OSL_ENSURE( !this, "No valid list" );
2158 [ # # ]: 0 : pAutocorr_List = new SvxAutocorrWordList();
2159 : : }
2160 : 0 : nFlags |= ChgWordLstLoad;
2161 : 0 : }
2162 : :
2163 : 0 : const SvxAutocorrWordList* SvxAutoCorrectLanguageLists::GetAutocorrWordList()
2164 : : {
2165 [ # # ][ # # ]: 0 : if( !( ChgWordLstLoad & nFlags ) || IsFileChanged_Imp() )
[ # # ]
2166 : 0 : SetAutocorrWordList( LoadAutocorrWordList() );
2167 : 0 : return pAutocorr_List;
2168 : : }
2169 : :
2170 : 0 : SvStringsISortDtor* SvxAutoCorrectLanguageLists::GetCplSttExceptList()
2171 : : {
2172 [ # # ][ # # ]: 0 : if( !( CplSttLstLoad & nFlags ) || IsFileChanged_Imp() )
[ # # ]
2173 : 0 : SetCplSttExceptList( LoadCplSttExceptList() );
2174 : 0 : return pCplStt_ExcptLst;
2175 : : }
2176 : :
2177 : 0 : sal_Bool SvxAutoCorrectLanguageLists::AddToCplSttExceptList(const String& rNew)
2178 : : {
2179 [ # # ][ # # ]: 0 : String* pNew = new String( rNew );
2180 [ # # ][ # # ]: 0 : if( rNew.Len() && GetCplSttExceptList()->insert( pNew ).second )
[ # # ][ # # ]
[ # # ]
[ # # # # ]
2181 : : {
2182 [ # # ]: 0 : MakeUserStorage_Impl();
2183 [ # # ][ # # ]: 0 : SotStorageRef xStg = new SotStorage( sUserAutoCorrFile, STREAM_READWRITE, sal_True );
2184 : :
2185 [ # # ]: 0 : SaveExceptList_Imp( *pCplStt_ExcptLst, pXMLImplCplStt_ExcptLstStr, xStg );
2186 : :
2187 [ # # ]: 0 : xStg = 0;
2188 : : // Set time stamp
2189 : : FStatHelper::GetModifiedDateTimeOfFile( sUserAutoCorrFile,
2190 [ # # ][ # # ]: 0 : &aModifiedDate, &aModifiedTime );
2191 [ # # ][ # # ]: 0 : aLastCheckTime = Time( Time::SYSTEM );
[ # # ]
2192 : : }
2193 : : else
2194 [ # # ][ # # ]: 0 : delete pNew, pNew = 0;
2195 : 0 : return 0 != pNew;
2196 : : }
2197 : :
2198 : 0 : sal_Bool SvxAutoCorrectLanguageLists::AddToWrdSttExceptList(const String& rNew)
2199 : : {
2200 [ # # ][ # # ]: 0 : String* pNew = new String( rNew );
2201 [ # # ]: 0 : SvStringsISortDtor* pExceptList = LoadWrdSttExceptList();
2202 [ # # ][ # # ]: 0 : if( rNew.Len() && pExceptList && pExceptList->insert( pNew ).second )
[ # # ][ # # ]
[ # # ]
[ # # # # ]
2203 : : {
2204 [ # # ]: 0 : MakeUserStorage_Impl();
2205 [ # # ][ # # ]: 0 : SotStorageRef xStg = new SotStorage( sUserAutoCorrFile, STREAM_READWRITE, sal_True );
2206 : :
2207 [ # # ]: 0 : SaveExceptList_Imp( *pWrdStt_ExcptLst, pXMLImplWrdStt_ExcptLstStr, xStg );
2208 : :
2209 [ # # ]: 0 : xStg = 0;
2210 : : // Set time stamp
2211 : : FStatHelper::GetModifiedDateTimeOfFile( sUserAutoCorrFile,
2212 [ # # ][ # # ]: 0 : &aModifiedDate, &aModifiedTime );
2213 [ # # ][ # # ]: 0 : aLastCheckTime = Time( Time::SYSTEM );
[ # # ]
2214 : : }
2215 : : else
2216 [ # # ][ # # ]: 0 : delete pNew, pNew = 0;
2217 : 0 : return 0 != pNew;
2218 : : }
2219 : :
2220 : 0 : SvStringsISortDtor* SvxAutoCorrectLanguageLists::LoadCplSttExceptList()
2221 : : {
2222 [ # # ][ # # ]: 0 : SotStorageRef xStg = new SotStorage( sShareAutoCorrFile, STREAM_READ | STREAM_SHARE_DENYNONE, sal_True );
2223 [ # # ]: 0 : String sTemp ( RTL_CONSTASCII_USTRINGPARAM ( pXMLImplCplStt_ExcptLstStr ) );
2224 [ # # ][ # # ]: 0 : if( xStg.Is() && xStg->IsContained( sTemp ) )
[ # # ][ # # ]
2225 [ # # ]: 0 : LoadXMLExceptList_Imp( pCplStt_ExcptLst, pXMLImplCplStt_ExcptLstStr, xStg );
2226 : :
2227 [ # # ][ # # ]: 0 : return pCplStt_ExcptLst;
2228 : : }
2229 : :
2230 : 0 : void SvxAutoCorrectLanguageLists::SaveCplSttExceptList()
2231 : : {
2232 [ # # ]: 0 : MakeUserStorage_Impl();
2233 [ # # ][ # # ]: 0 : SotStorageRef xStg = new SotStorage( sUserAutoCorrFile, STREAM_READWRITE, sal_True );
2234 : :
2235 [ # # ]: 0 : SaveExceptList_Imp( *pCplStt_ExcptLst, pXMLImplCplStt_ExcptLstStr, xStg );
2236 : :
2237 [ # # ]: 0 : xStg = 0;
2238 : :
2239 : : // Set time stamp
2240 : : FStatHelper::GetModifiedDateTimeOfFile( sUserAutoCorrFile,
2241 [ # # ][ # # ]: 0 : &aModifiedDate, &aModifiedTime );
2242 [ # # ][ # # ]: 0 : aLastCheckTime = Time( Time::SYSTEM );
[ # # ]
2243 : 0 : }
2244 : :
2245 : 0 : void SvxAutoCorrectLanguageLists::SetCplSttExceptList( SvStringsISortDtor* pList )
2246 : : {
2247 [ # # ][ # # ]: 0 : if( pCplStt_ExcptLst && pList != pCplStt_ExcptLst )
2248 [ # # ]: 0 : delete pCplStt_ExcptLst;
2249 : :
2250 : 0 : pCplStt_ExcptLst = pList;
2251 [ # # ]: 0 : if( !pCplStt_ExcptLst )
2252 : : {
2253 : : OSL_ENSURE( !this, "No valid list" );
2254 [ # # ]: 0 : pCplStt_ExcptLst = new SvStringsISortDtor;
2255 : : }
2256 : 0 : nFlags |= CplSttLstLoad;
2257 : 0 : }
2258 : :
2259 : 0 : SvStringsISortDtor* SvxAutoCorrectLanguageLists::LoadWrdSttExceptList()
2260 : : {
2261 [ # # ][ # # ]: 0 : SotStorageRef xStg = new SotStorage( sShareAutoCorrFile, STREAM_READ | STREAM_SHARE_DENYNONE, sal_True );
2262 [ # # ]: 0 : String sTemp ( RTL_CONSTASCII_USTRINGPARAM ( pXMLImplWrdStt_ExcptLstStr ) );
2263 [ # # ][ # # ]: 0 : if( xStg.Is() && xStg->IsContained( sTemp ) )
[ # # ][ # # ]
2264 [ # # ]: 0 : LoadXMLExceptList_Imp( pWrdStt_ExcptLst, pXMLImplWrdStt_ExcptLstStr, xStg );
2265 [ # # ][ # # ]: 0 : return pWrdStt_ExcptLst;
2266 : : }
2267 : :
2268 : 0 : void SvxAutoCorrectLanguageLists::SaveWrdSttExceptList()
2269 : : {
2270 [ # # ]: 0 : MakeUserStorage_Impl();
2271 [ # # ][ # # ]: 0 : SotStorageRef xStg = new SotStorage( sUserAutoCorrFile, STREAM_READWRITE, sal_True );
2272 : :
2273 [ # # ]: 0 : SaveExceptList_Imp( *pWrdStt_ExcptLst, pXMLImplWrdStt_ExcptLstStr, xStg );
2274 : :
2275 [ # # ]: 0 : xStg = 0;
2276 : : // Set time stamp
2277 : : FStatHelper::GetModifiedDateTimeOfFile( sUserAutoCorrFile,
2278 [ # # ][ # # ]: 0 : &aModifiedDate, &aModifiedTime );
2279 [ # # ][ # # ]: 0 : aLastCheckTime = Time( Time::SYSTEM );
[ # # ]
2280 : 0 : }
2281 : :
2282 : 0 : void SvxAutoCorrectLanguageLists::SetWrdSttExceptList( SvStringsISortDtor* pList )
2283 : : {
2284 [ # # ][ # # ]: 0 : if( pWrdStt_ExcptLst && pList != pWrdStt_ExcptLst )
2285 [ # # ]: 0 : delete pWrdStt_ExcptLst;
2286 : 0 : pWrdStt_ExcptLst = pList;
2287 [ # # ]: 0 : if( !pWrdStt_ExcptLst )
2288 : : {
2289 : : OSL_ENSURE( !this, "No valid list" );
2290 [ # # ]: 0 : pWrdStt_ExcptLst = new SvStringsISortDtor;
2291 : : }
2292 : 0 : nFlags |= WrdSttLstLoad;
2293 : 0 : }
2294 : :
2295 : 0 : SvStringsISortDtor* SvxAutoCorrectLanguageLists::GetWrdSttExceptList()
2296 : : {
2297 [ # # ][ # # ]: 0 : if( !( WrdSttLstLoad & nFlags ) || IsFileChanged_Imp() )
[ # # ]
2298 : 0 : SetWrdSttExceptList( LoadWrdSttExceptList() );
2299 : 0 : return pWrdStt_ExcptLst;
2300 : : }
2301 : :
2302 : 0 : void SvxAutoCorrectLanguageLists::RemoveStream_Imp( const String& rName )
2303 : : {
2304 [ # # ]: 0 : if( sShareAutoCorrFile != sUserAutoCorrFile )
2305 : : {
2306 [ # # ][ # # ]: 0 : SotStorageRef xStg = new SotStorage( sUserAutoCorrFile, STREAM_READWRITE, sal_True );
2307 [ # # ][ # # ]: 0 : if( xStg.Is() && SVSTREAM_OK == xStg->GetError() &&
[ # # ][ # # ]
2308 [ # # ]: 0 : xStg->IsStream( rName ) )
2309 : : {
2310 [ # # ]: 0 : xStg->Remove( rName );
2311 [ # # ]: 0 : xStg->Commit();
2312 : :
2313 [ # # ]: 0 : xStg = 0;
2314 [ # # ]: 0 : }
2315 : : }
2316 : 0 : }
2317 : :
2318 : 0 : void SvxAutoCorrectLanguageLists::MakeUserStorage_Impl()
2319 : : {
2320 : : // The conversion needs to happen if the file is already in the user
2321 : : // directory and is in the old format. Additionally it needs to
2322 : : // happen when the file is being copied from share to user.
2323 : :
2324 : 0 : sal_Bool bError = sal_False, bConvert = sal_False, bCopy = sal_False;
2325 [ # # ]: 0 : INetURLObject aDest;
2326 [ # # ]: 0 : INetURLObject aSource;
2327 : :
2328 [ # # ][ # # ]: 0 : if (sUserAutoCorrFile != sShareAutoCorrFile )
2329 : : {
2330 [ # # ][ # # ]: 0 : aSource = INetURLObject ( sShareAutoCorrFile );
[ # # ][ # # ]
2331 [ # # ][ # # ]: 0 : aDest = INetURLObject ( sUserAutoCorrFile );
[ # # ][ # # ]
2332 [ # # ][ # # ]: 0 : if ( SotStorage::IsOLEStorage ( sShareAutoCorrFile ) )
2333 : : {
2334 [ # # ]: 0 : aDest.SetExtension ( rtl::OUString("bak") );
2335 : 0 : bConvert = sal_True;
2336 : : }
2337 : 0 : bCopy = sal_True;
2338 : : }
2339 [ # # ][ # # ]: 0 : else if ( SotStorage::IsOLEStorage ( sUserAutoCorrFile ) )
2340 : : {
2341 [ # # ][ # # ]: 0 : aSource = INetURLObject ( sUserAutoCorrFile );
[ # # ][ # # ]
2342 [ # # ][ # # ]: 0 : aDest = INetURLObject ( sUserAutoCorrFile );
[ # # ][ # # ]
2343 [ # # ]: 0 : aDest.SetExtension ( rtl::OUString("bak") );
2344 : 0 : bCopy = bConvert = sal_True;
2345 : : }
2346 [ # # ]: 0 : if (bCopy)
2347 : : {
2348 : : try
2349 : : {
2350 [ # # ][ # # ]: 0 : String sMain(aDest.GetMainURL( INetURLObject::DECODE_TO_IURI ));
2351 : 0 : sal_Unicode cSlash = '/';
2352 [ # # ]: 0 : xub_StrLen nSlashPos = sMain.SearchBackward(cSlash);
2353 [ # # ]: 0 : sMain.Erase(nSlashPos);
2354 [ # # ][ # # ]: 0 : ::ucbhelper::Content aNewContent( sMain, uno::Reference< XCommandEnvironment > ());
2355 : 0 : Any aAny;
2356 : 0 : TransferInfo aInfo;
2357 : 0 : aInfo.NameClash = NameClash::OVERWRITE;
2358 [ # # ]: 0 : aInfo.NewTitle = aDest.GetName();
2359 [ # # ]: 0 : aInfo.SourceURL = aSource.GetMainURL( INetURLObject::DECODE_TO_IURI );
2360 : 0 : aInfo.MoveData = sal_False;
2361 [ # # ]: 0 : aAny <<= aInfo;
2362 [ # # ][ # # ]: 0 : aNewContent.executeCommand( OUString ( "transfer" ), aAny);
[ # # ]
2363 : : }
2364 [ # # ]: 0 : catch (...)
2365 : : {
2366 : 0 : bError = sal_True;
2367 : : }
2368 : : }
2369 [ # # ][ # # ]: 0 : if (bConvert && !bError)
2370 : : {
2371 [ # # ][ # # ]: 0 : SotStorageRef xSrcStg = new SotStorage( aDest.GetMainURL( INetURLObject::DECODE_TO_IURI ), STREAM_READ, sal_True );
[ # # ][ # # ]
[ # # ]
2372 [ # # ][ # # ]: 0 : SotStorageRef xDstStg = new SotStorage( sUserAutoCorrFile, STREAM_WRITE, sal_True );
2373 : :
2374 [ # # ][ # # ]: 0 : if( xSrcStg.Is() && xDstStg.Is() )
[ # # ]
2375 : : {
2376 [ # # ]: 0 : String sWord ( RTL_CONSTASCII_USTRINGPARAM ( pImplWrdStt_ExcptLstStr ) );
2377 [ # # ]: 0 : String sSentence ( RTL_CONSTASCII_USTRINGPARAM ( pImplCplStt_ExcptLstStr ) );
2378 [ # # ]: 0 : String sXMLWord ( RTL_CONSTASCII_USTRINGPARAM ( pXMLImplWrdStt_ExcptLstStr ) );
2379 [ # # ]: 0 : String sXMLSentence ( RTL_CONSTASCII_USTRINGPARAM ( pXMLImplCplStt_ExcptLstStr ) );
2380 : 0 : SvStringsISortDtor *pTmpWordList = NULL;
2381 : :
2382 [ # # ][ # # ]: 0 : if (xSrcStg->IsContained( sXMLWord ) )
2383 [ # # ]: 0 : LoadXMLExceptList_Imp( pTmpWordList, pXMLImplWrdStt_ExcptLstStr, xSrcStg );
2384 : :
2385 [ # # ]: 0 : if (pTmpWordList)
2386 : : {
2387 [ # # ]: 0 : SaveExceptList_Imp( *pTmpWordList, pXMLImplWrdStt_ExcptLstStr, xDstStg, sal_True );
2388 [ # # ]: 0 : pTmpWordList->DeleteAndDestroyAll();
2389 : 0 : pTmpWordList = NULL;
2390 : : }
2391 : :
2392 : :
2393 [ # # ][ # # ]: 0 : if (xSrcStg->IsContained( sXMLSentence ) )
2394 [ # # ]: 0 : LoadXMLExceptList_Imp( pTmpWordList, pXMLImplCplStt_ExcptLstStr, xSrcStg );
2395 : :
2396 [ # # ]: 0 : if (pTmpWordList)
2397 : : {
2398 [ # # ]: 0 : SaveExceptList_Imp( *pTmpWordList, pXMLImplCplStt_ExcptLstStr, xDstStg, sal_True );
2399 [ # # ]: 0 : pTmpWordList->DeleteAndDestroyAll();
2400 : : }
2401 : :
2402 [ # # ]: 0 : GetAutocorrWordList();
2403 [ # # ]: 0 : MakeBlocklist_Imp( *xDstStg );
2404 [ # # ]: 0 : sShareAutoCorrFile = sUserAutoCorrFile;
2405 [ # # ]: 0 : xDstStg = 0;
2406 : : try
2407 : : {
2408 [ # # ][ # # ]: 0 : ::ucbhelper::Content aContent ( aDest.GetMainURL( INetURLObject::DECODE_TO_IURI ), uno::Reference < XCommandEnvironment > ());
2409 [ # # ][ # # ]: 0 : aContent.executeCommand ( OUString ( RTL_CONSTASCII_USTRINGPARAM ( "delete" ) ), makeAny ( sal_Bool (sal_True ) ) );
[ # # ][ # # ]
2410 : : }
2411 [ # # ]: 0 : catch (...)
2412 : : {
2413 [ # # ][ # # ]: 0 : }
[ # # ][ # # ]
2414 [ # # ][ # # ]: 0 : }
2415 : : }
2416 [ # # ][ # # ]: 0 : else if( bCopy && !bError )
2417 [ # # ][ # # ]: 0 : sShareAutoCorrFile = sUserAutoCorrFile;
[ # # ]
2418 : 0 : }
2419 : :
2420 : 0 : sal_Bool SvxAutoCorrectLanguageLists::MakeBlocklist_Imp( SvStorage& rStg )
2421 : : {
2422 [ # # ]: 0 : String sStrmName( pXMLImplAutocorr_ListStr, RTL_TEXTENCODING_MS_1252 );
2423 [ # # ][ # # ]: 0 : sal_Bool bRet = sal_True, bRemove = !pAutocorr_List || pAutocorr_List->empty();
2424 [ # # ]: 0 : if( !bRemove )
2425 : : {
2426 : : SvStorageStreamRef refList = rStg.OpenSotStream( sStrmName,
2427 [ # # ]: 0 : ( STREAM_READ | STREAM_WRITE | STREAM_SHARE_DENYWRITE ) );
2428 [ # # ]: 0 : if( refList.Is() )
2429 : : {
2430 [ # # ]: 0 : refList->SetSize( 0 );
2431 [ # # ]: 0 : refList->SetBufferSize( 8192 );
2432 [ # # ]: 0 : String aPropName( rtl::OUString( "MediaType" ) );
2433 : 0 : OUString aMime( "text/xml" );
2434 : 0 : uno::Any aAny;
2435 [ # # ]: 0 : aAny <<= aMime;
2436 [ # # ]: 0 : refList->SetProperty( aPropName, aAny );
2437 : :
2438 : : uno::Reference< lang::XMultiServiceFactory > xServiceFactory =
2439 [ # # ]: 0 : comphelper::getProcessServiceFactory();
2440 : : OSL_ENSURE( xServiceFactory.is(),
2441 : : "XMLReader::Read: got no service manager" );
2442 : 0 : if( !xServiceFactory.is() )
2443 : : {
2444 : : // Throw an exception ?
2445 : : }
2446 : :
2447 [ # # ]: 0 : uno::Reference < XInterface > xWriter (xServiceFactory->createInstance(
2448 [ # # ]: 0 : OUString("com.sun.star.xml.sax.Writer")));
2449 : : OSL_ENSURE(xWriter.is(),"com.sun.star.xml.sax.Writer service missing");
2450 [ # # ][ # # ]: 0 : uno::Reference < io::XOutputStream> xOut = new utl::OOutputStreamWrapper( *refList );
[ # # ]
2451 [ # # ]: 0 : uno::Reference<io::XActiveDataSource> xSrc(xWriter, uno::UNO_QUERY);
2452 [ # # ][ # # ]: 0 : xSrc->setOutputStream(xOut);
2453 : :
2454 [ # # ]: 0 : uno::Reference<xml::sax::XDocumentHandler> xHandler(xWriter, uno::UNO_QUERY);
2455 : :
2456 [ # # ][ # # ]: 0 : SvXMLAutoCorrectExport aExp( xServiceFactory, pAutocorr_List, sStrmName, xHandler );
2457 : :
2458 [ # # ]: 0 : aExp.exportDoc( XML_BLOCK_LIST );
2459 : :
2460 [ # # ]: 0 : refList->Commit();
2461 : 0 : bRet = SVSTREAM_OK == refList->GetError();
2462 [ # # ]: 0 : if( bRet )
2463 : : {
2464 [ # # ]: 0 : refList.Clear();
2465 [ # # ]: 0 : rStg.Commit();
2466 [ # # ]: 0 : if( SVSTREAM_OK != rStg.GetError() )
2467 : : {
2468 : 0 : bRemove = sal_True;
2469 : 0 : bRet = sal_False;
2470 : : }
2471 [ # # ][ # # ]: 0 : }
2472 : : }
2473 : : else
2474 [ # # ]: 0 : bRet = sal_False;
2475 : : }
2476 : :
2477 [ # # ]: 0 : if( bRemove )
2478 : : {
2479 [ # # ]: 0 : rStg.Remove( sStrmName );
2480 [ # # ]: 0 : rStg.Commit();
2481 : : }
2482 : :
2483 [ # # ]: 0 : return bRet;
2484 : : }
2485 : :
2486 : 0 : sal_Bool SvxAutoCorrectLanguageLists::PutText( const String& rShort,
2487 : : const String& rLong )
2488 : : {
2489 : : // First get the current list!
2490 [ # # ]: 0 : GetAutocorrWordList();
2491 : :
2492 [ # # ]: 0 : MakeUserStorage_Impl();
2493 [ # # ][ # # ]: 0 : SotStorageRef xStg = new SotStorage( sUserAutoCorrFile, STREAM_READWRITE, sal_True );
2494 : :
2495 [ # # ][ # # ]: 0 : sal_Bool bRet = xStg.Is() && SVSTREAM_OK == xStg->GetError();
2496 : :
2497 : : // Update the word list
2498 [ # # ]: 0 : if( bRet )
2499 : : {
2500 [ # # ][ # # ]: 0 : SvxAutocorrWord* pNew = new SvxAutocorrWord( rShort, rLong, sal_True );
2501 [ # # ]: 0 : SvxAutocorrWordList::iterator it = pAutocorr_List->find( pNew );
2502 [ # # ][ # # ]: 0 : if( it != pAutocorr_List->end() )
2503 : : {
2504 [ # # ][ # # ]: 0 : if( !(*it)->IsTextOnly() )
2505 : : {
2506 : : // Still have to remove the Storage
2507 [ # # ]: 0 : String sStgNm( rShort );
2508 [ # # ][ # # ]: 0 : if (xStg->IsOLEStorage())
2509 [ # # ]: 0 : EncryptBlockName_Imp( sStgNm );
2510 : : else
2511 [ # # ]: 0 : GeneratePackageName ( rShort, sStgNm);
2512 : :
2513 [ # # ][ # # ]: 0 : if( xStg->IsContained( sStgNm ) )
2514 [ # # ][ # # ]: 0 : xStg->Remove( sStgNm );
2515 : : }
2516 [ # # ][ # # ]: 0 : delete *it;
[ # # ]
2517 [ # # ]: 0 : pAutocorr_List->erase( it );
2518 : : }
2519 : :
2520 [ # # ][ # # ]: 0 : if( pAutocorr_List->insert( pNew ).second )
2521 : : {
2522 [ # # ]: 0 : bRet = MakeBlocklist_Imp( *xStg );
2523 [ # # ]: 0 : xStg = 0;
2524 : : }
2525 : : else
2526 : : {
2527 [ # # ][ # # ]: 0 : delete pNew;
2528 : 0 : bRet = sal_False;
2529 : : }
2530 : : }
2531 [ # # ]: 0 : return bRet;
2532 : : }
2533 : :
2534 : 0 : sal_Bool SvxAutoCorrectLanguageLists::PutText( const String& rShort,
2535 : : SfxObjectShell& rShell )
2536 : : {
2537 : : // First get the current list!
2538 [ # # ]: 0 : GetAutocorrWordList();
2539 : :
2540 [ # # ]: 0 : MakeUserStorage_Impl();
2541 : :
2542 : 0 : sal_Bool bRet = sal_False;
2543 [ # # ]: 0 : String sLong;
2544 : : try
2545 : : {
2546 [ # # ][ # # ]: 0 : uno::Reference < embed::XStorage > xStg = comphelper::OStorageHelper::GetStorageFromURL( sUserAutoCorrFile, embed::ElementModes::READWRITE );
2547 [ # # ]: 0 : bRet = rAutoCorrect.PutText( xStg, sUserAutoCorrFile, rShort, rShell, sLong );
2548 [ # # ]: 0 : xStg = 0;
2549 : :
2550 : : // Update the word list
2551 [ # # ]: 0 : if( bRet )
2552 : : {
2553 [ # # ][ # # ]: 0 : SvxAutocorrWord* pNew = new SvxAutocorrWord( rShort, sLong, sal_False );
2554 [ # # ][ # # ]: 0 : if( pAutocorr_List->insert( pNew ).second )
2555 : : {
2556 [ # # ][ # # ]: 0 : SotStorageRef xStor = new SotStorage( sUserAutoCorrFile, STREAM_READWRITE, sal_True );
2557 [ # # ][ # # ]: 0 : MakeBlocklist_Imp( *xStor );
2558 : : }
2559 : : else
2560 [ # # ][ # # ]: 0 : delete pNew;
2561 [ # # ]: 0 : }
2562 : : }
2563 [ # # ]: 0 : catch ( const uno::Exception& )
2564 : : {
2565 : : }
2566 : :
2567 [ # # ]: 0 : return bRet;
2568 : : }
2569 : :
2570 : : // Delete an entry
2571 : 0 : sal_Bool SvxAutoCorrectLanguageLists::DeleteText( const String& rShort )
2572 : : {
2573 : : // First get the current list!
2574 [ # # ]: 0 : GetAutocorrWordList();
2575 : :
2576 [ # # ]: 0 : MakeUserStorage_Impl();
2577 : :
2578 [ # # ][ # # ]: 0 : SotStorageRef xStg = new SotStorage( sUserAutoCorrFile, STREAM_READWRITE, sal_True );
2579 [ # # ][ # # ]: 0 : sal_Bool bRet = xStg.Is() && SVSTREAM_OK == xStg->GetError();
2580 [ # # ]: 0 : if( bRet )
2581 : : {
2582 [ # # ]: 0 : SvxAutocorrWord aTmp( rShort, rShort );
2583 [ # # ]: 0 : SvxAutocorrWordList::iterator it = pAutocorr_List->find( &aTmp );
2584 [ # # ][ # # ]: 0 : if( it != pAutocorr_List->end() )
2585 : : {
2586 [ # # ]: 0 : SvxAutocorrWord* pFnd = *it;
2587 [ # # ]: 0 : if( !pFnd->IsTextOnly() )
2588 : : {
2589 [ # # ]: 0 : String aName( rShort );
2590 [ # # ][ # # ]: 0 : if (xStg->IsOLEStorage())
2591 [ # # ]: 0 : EncryptBlockName_Imp( aName );
2592 : : else
2593 [ # # ]: 0 : GeneratePackageName ( rShort, aName );
2594 [ # # ][ # # ]: 0 : if( xStg->IsContained( aName ) )
2595 : : {
2596 [ # # ]: 0 : xStg->Remove( aName );
2597 [ # # ]: 0 : bRet = xStg->Commit();
2598 [ # # ]: 0 : }
2599 : :
2600 : : }
2601 : : // Update the word list
2602 [ # # ][ # # ]: 0 : delete pFnd;
2603 [ # # ]: 0 : pAutocorr_List->erase( it );
2604 [ # # ]: 0 : MakeBlocklist_Imp( *xStg );
2605 [ # # ]: 0 : xStg = 0;
2606 : : }
2607 : : else
2608 [ # # ]: 0 : bRet = sal_False;
2609 : : }
2610 [ # # ]: 0 : return bRet;
2611 : : }
2612 : :
2613 : 0 : SvxAutocorrWordList::~SvxAutocorrWordList()
2614 : : {
2615 [ # # ]: 0 : DeleteAndDestroyAll();
2616 : 0 : }
2617 : :
2618 : 0 : void SvxAutocorrWordList::DeleteAndDestroyAll()
2619 : : {
2620 [ # # ][ # # ]: 0 : for( const_iterator it = begin(); it != end(); ++it )
[ # # ]
2621 [ # # ][ # # ]: 0 : delete *it;
[ # # ]
2622 : 0 : clear();
2623 : 0 : }
2624 : :
2625 : :
2626 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|