Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #ifndef INCLUDED_EDITENG_SVXACORR_HXX
21 : #define INCLUDED_EDITENG_SVXACORR_HXX
22 :
23 : #include <com/sun/star/embed/XStorage.hpp>
24 :
25 : #include <o3tl/sorted_vector.hxx>
26 : #include <sot/storage.hxx>
27 : #include <tools/rtti.hxx>
28 : #include <i18nlangtag/languagetag.hxx>
29 : #include <tools/time.hxx>
30 : #include <tools/date.hxx>
31 : #include <editeng/swafopt.hxx>
32 : #include <editeng/editengdllapi.h>
33 :
34 : #include <map>
35 : #include <set>
36 : #include <boost/unordered_map.hpp>
37 : #include <boost/ptr_container/ptr_map.hpp>
38 :
39 : class CharClass;
40 : class SfxPoolItem;
41 : class SvxAutoCorrect;
42 : class SfxObjectShell;
43 : namespace vcl { class Window; }
44 :
45 : struct CompareSvStringsISortDtor
46 : {
47 0 : bool operator()( OUString const& lhs, OUString const& rhs ) const
48 : {
49 0 : return lhs.compareToIgnoreAsciiCase( rhs ) < 0;
50 : }
51 : };
52 :
53 0 : class SvStringsISortDtor
54 : : public o3tl::sorted_vector<OUString, CompareSvStringsISortDtor>
55 : {
56 : };
57 :
58 : // Auto correct flags
59 : const long CptlSttSntnc = 0x00000001; // Capital letters at the beginning of a sentence
60 : const long CptlSttWrd = 0x00000002; // not two Capital letters at the beginning of a word
61 : const long AddNonBrkSpace = 0x00000004; // Add non breaking space before :;?!%
62 : const long ChgOrdinalNumber = 0x00000008; // Ordinal-Number 1st, 2nd,..
63 : const long ChgToEnEmDash = 0x00000010; // - -> Endash/Emdash
64 : const long ChgWeightUnderl = 0x00000020; // * -> Bold, _ -> Underscore
65 : const long SetINetAttr = 0x00000040; // Set INetAttribut
66 : const long Autocorrect = 0x00000080; // Call AutoCorrect
67 : const long ChgQuotes = 0x00000100; // replace double quotes
68 : const long SaveWordCplSttLst= 0x00000200; // Save Auto correction of Capital letter at beginning of sentence.
69 : const long SaveWordWrdSttLst= 0x00000400; // Save Auto correction of 2 Capital letter at beginning of word.
70 : const long IgnoreDoubleSpace= 0x00000800; // Ignore 2 Spaces
71 : const long ChgSglQuotes = 0x00001000; // Replace simple quotes
72 : const long CorrectCapsLock = 0x00002000; // Correct accidental use of cAPS LOCK key
73 :
74 : const long ChgWordLstLoad = 0x20000000; // Replacement list loaded
75 : const long CplSttLstLoad = 0x40000000; // Exception list for Capital letters Start loaded
76 : const long WrdSttLstLoad = 0x80000000; // Exception list for Word Start loaded
77 :
78 : // TODO: handle unicodes > U+FFFF and check users of this class
79 :
80 : // only a mapping class
81 : class EDITENG_DLLPUBLIC SvxAutoCorrDoc
82 : {
83 : public:
84 6 : SvxAutoCorrDoc() {}
85 : virtual ~SvxAutoCorrDoc();
86 :
87 : virtual bool Delete( sal_Int32 nStt, sal_Int32 nEnd ) = 0;
88 : virtual bool Insert( sal_Int32 nPos, const OUString& rTxt ) = 0;
89 : virtual bool Replace( sal_Int32 nPos, const OUString& rTxt ) = 0;
90 : virtual bool ReplaceRange( sal_Int32 nPos, sal_Int32 nLen, const OUString& rTxt ) = 0;
91 :
92 : virtual bool SetAttr( sal_Int32 nStt, sal_Int32 nEnd, sal_uInt16 nSlotId,
93 : SfxPoolItem& ) = 0;
94 :
95 : virtual bool SetINetAttr( sal_Int32 nStt, sal_Int32 nEnd, const OUString& rURL ) = 0;
96 :
97 : // Return the text of a previous paragraph.
98 : // If no paragraph exits or just an empty one, then return an empty string.
99 : // The flag indicates:
100 : // TRUE: before the normal insertion position (TRUE)
101 : // FALSE: in which the corrected word was inserted.
102 : // (Does not to have to be the same paragraph !!!!)
103 : virtual OUString const* GetPrevPara(bool bAtNormalPos) = 0;
104 :
105 : virtual bool ChgAutoCorrWord( sal_Int32& rSttPos, sal_Int32 nEndPos,
106 : SvxAutoCorrect& rACorrect,
107 : OUString* pPara ) = 0;
108 : // Is called after the change of the signs by the functions
109 : // - FnCptlSttWrd
110 : // - FnCptlSttSntnc
111 : // As an option, the words can then be inserted into the exception lists.
112 : virtual void SaveCpltSttWord( sal_uLong nFlag, sal_Int32 nPos,
113 : const OUString& rExceptWord,
114 : sal_Unicode cChar );
115 :
116 : // which language at the position?
117 : virtual LanguageType GetLanguage( sal_Int32 nPos, bool bPrevPara = false ) const;
118 : };
119 :
120 :
121 0 : class EDITENG_DLLPUBLIC SvxAutocorrWord
122 : {
123 : OUString sShort, sLong;
124 : bool bIsTxtOnly; // Is pure ASCII - Text
125 : public:
126 0 : SvxAutocorrWord( const OUString& rS, const OUString& rL, bool bFlag = true )
127 0 : : sShort( rS ), sLong( rL ), bIsTxtOnly( bFlag )
128 0 : {}
129 :
130 0 : const OUString& GetShort() const { return sShort; }
131 0 : const OUString& GetLong() const { return sLong; }
132 0 : bool IsTextOnly() const { return bIsTxtOnly; }
133 : };
134 :
135 : struct CompareSvxAutocorrWordList
136 : {
137 : bool operator()( SvxAutocorrWord* const& lhs, SvxAutocorrWord* const& rhs ) const;
138 : };
139 :
140 : typedef std::set<SvxAutocorrWord*, CompareSvxAutocorrWordList> SvxAutocorrWordList_Set;
141 : typedef ::boost::unordered_map< OUString, SvxAutocorrWord *,
142 : OUStringHash > SvxAutocorrWordList_Hash;
143 :
144 0 : class EDITENG_DLLPUBLIC SvxAutocorrWordList
145 : {
146 : // only one of these contains the data
147 : mutable SvxAutocorrWordList_Set maSet;
148 : mutable SvxAutocorrWordList_Hash maHash; // key is 'Short'
149 :
150 : const SvxAutocorrWord* WordMatches(const SvxAutocorrWord *pFnd,
151 : const OUString &rTxt,
152 : sal_Int32 &rStt,
153 : sal_Int32 nEndPos) const;
154 : public:
155 : // free any objects still in the set
156 : ~SvxAutocorrWordList();
157 : void DeleteAndDestroyAll();
158 : bool Insert(SvxAutocorrWord *pWord) const;
159 : SvxAutocorrWord* FindAndRemove(SvxAutocorrWord *pWord);
160 : void LoadEntry(const OUString& sWrong, const OUString& sRight, bool bOnlyTxt);
161 : bool empty() const;
162 :
163 : typedef std::vector<SvxAutocorrWord *> Content;
164 : Content getSortedContent() const;
165 :
166 : const SvxAutocorrWord* SearchWordsInList(const OUString& rTxt, sal_Int32& rStt, sal_Int32 nEndPos) const;
167 : };
168 :
169 : class EDITENG_DLLPUBLIC SvxAutoCorrectLanguageLists
170 : {
171 : OUString sShareAutoCorrFile, sUserAutoCorrFile;
172 : // If the AutoCorr file is newer
173 : Date aModifiedDate;
174 : tools::Time aModifiedTime, aLastCheckTime;
175 :
176 : SvStringsISortDtor* pCplStt_ExcptLst;
177 : SvStringsISortDtor* pWrdStt_ExcptLst;
178 : SvxAutocorrWordList* pAutocorr_List;
179 : SvxAutoCorrect& rAutoCorrect;
180 :
181 : long nFlags;
182 :
183 : bool IsFileChanged_Imp();
184 : void LoadXMLExceptList_Imp( SvStringsISortDtor*& rpLst,
185 : const sal_Char* pStrmName,
186 : SotStorageRef& rStg);
187 : void SaveExceptList_Imp( const SvStringsISortDtor& rLst,
188 : const sal_Char* pStrmName,
189 : SotStorageRef& rStg,
190 : bool bConvert = false);
191 :
192 : bool MakeBlocklist_Imp( SotStorage& rStg );
193 : void RemoveStream_Imp( const OUString& rName );
194 : void MakeUserStorage_Impl();
195 :
196 : public:
197 : SvxAutoCorrectLanguageLists( SvxAutoCorrect& rParent,
198 : const OUString& rShareAutoCorrectFile,
199 : const OUString& rUserAutoCorrectFile);
200 : ~SvxAutoCorrectLanguageLists();
201 :
202 : // Load, Set, Get - the replacement list
203 : SvxAutocorrWordList* LoadAutocorrWordList();
204 : void SetAutocorrWordList( SvxAutocorrWordList* pList );
205 : const SvxAutocorrWordList* GetAutocorrWordList();
206 :
207 : // Load, Set, Get - the exception list for Capital letter at the
208 : // beginning of a sentence
209 : SvStringsISortDtor* LoadCplSttExceptList();
210 : void SaveCplSttExceptList();
211 : void SetCplSttExceptList( SvStringsISortDtor* pList );
212 : SvStringsISortDtor* GetCplSttExceptList();
213 : bool AddToCplSttExceptList(const OUString& rNew);
214 :
215 : // Load, Set, Get the exception list for 2 Capital letters at the
216 : // beginning of a word.
217 : SvStringsISortDtor* LoadWrdSttExceptList();
218 : void SaveWrdSttExceptList();
219 : void SetWrdSttExceptList( SvStringsISortDtor* pList );
220 : SvStringsISortDtor* GetWrdSttExceptList();
221 : bool AddToWrdSttExceptList(const OUString& rNew);
222 :
223 : // Save word substitutions:
224 : // Store these directly in the storage. The word list is updated
225 : // accordingly!
226 : // - pure Text
227 : bool PutText( const OUString& rShort, const OUString& rLong );
228 : // - Text with attribution (only the SWG - SWG format!)
229 : bool PutText( const OUString& rShort, SfxObjectShell& );
230 : // - Deleting an entry
231 : bool DeleteText( const OUString& rShort );
232 : // - Make combined changes in one pass
233 : bool MakeCombinedChanges( std::vector<SvxAutocorrWord>& aNewEntries, std::vector<SvxAutocorrWord>& aDeleteEntries );
234 : };
235 :
236 : class EDITENG_DLLPUBLIC SvxAutoCorrect
237 : {
238 : friend class SvxAutoCorrectLanguageLists;
239 :
240 : OUString sShareAutoCorrFile, sUserAutoCorrFile;
241 :
242 : SvxSwAutoFmtFlags aSwFlags; // StarWriter AutoFormat Flags
243 :
244 : // all languages in a table
245 : boost::ptr_map<LanguageTag, SvxAutoCorrectLanguageLists>* pLangTable;
246 : std::map<LanguageTag, long> aLastFileTable;
247 : CharClass* pCharClass;
248 :
249 : bool bRunNext;
250 :
251 : LanguageType eCharClassLang;
252 :
253 : long nFlags;
254 : sal_Unicode cStartDQuote, cEndDQuote, cStartSQuote, cEndSQuote,
255 : cEmDash, cEnDash;
256 :
257 :
258 : // private methods
259 : SvxAutoCorrectLanguageLists& _GetLanguageList( LanguageType eLang );
260 :
261 : void _GetCharClass( LanguageType eLang );
262 :
263 : protected:
264 : // - Text with attribution (only the SWG - SWG format!)
265 : // rShort is the stream name - encrypted!
266 : virtual bool PutText( const com::sun::star::uno::Reference < com::sun::star::embed::XStorage >& rStg,
267 : const OUString& rFileName, const OUString& rShort, SfxObjectShell&, OUString& );
268 :
269 : // required language in the table add if possible only when the file exists
270 : bool CreateLanguageFile(const LanguageTag& rLanguageTag, bool bNewFile = true);
271 : // - Return the replacement text (only for SWG format, all others can be
272 : // taken from the word list!)
273 : // rShort is the stream name - encrypted!
274 : public:
275 :
276 : sal_Unicode GetQuote( sal_Unicode cInsChar, bool bSttQuote,
277 : LanguageType eLang ) const;
278 : virtual bool GetLongText( const com::sun::star::uno::Reference < com::sun::star::embed::XStorage >& rStg,
279 : const OUString& rShort, OUString& rLong );
280 :
281 : TYPEINFO();
282 :
283 : SvxAutoCorrect( const OUString& rShareAutocorrFile,
284 : const OUString& rUserAutocorrFile );
285 : SvxAutoCorrect( const SvxAutoCorrect& );
286 : virtual ~SvxAutoCorrect();
287 :
288 : // Execute an AutoCorrect.
289 : // Returns what has been executed, according to the above flags
290 : // FIXME: this has the horrible flaw that the rTxt must be a reference
291 : // to the actual SwTxtNode/EditNode string because it inserts the character
292 : // in rDoc and expects that to side-effect rTxt
293 : sal_uLong DoAutoCorrect( SvxAutoCorrDoc& rDoc, const OUString& rTxt,
294 : sal_Int32 nPos, sal_Unicode cInsChar, bool bInsert, vcl::Window* pFrameWin = NULL );
295 :
296 : // Return for the autotext expansion the previous word,
297 : // AutoCorrect - corresponding algorithm
298 : bool GetPrevAutoCorrWord( SvxAutoCorrDoc& rDoc, const OUString& rTxt,
299 : sal_Int32 nPos, OUString& rWord ) const;
300 :
301 : // Search for or or the words in the replacement table.
302 : // rText - check in this text the words of the list
303 : // rStt - the detected starting position
304 : // nEnd - to check position - as of this item forward
305 : // rLang - Input: in which language is searched
306 : // Output: in which "language list" was it found
307 : const SvxAutocorrWord* SearchWordsInList( const OUString& rTxt,
308 : sal_Int32& rStt, sal_Int32 nEndPos,
309 : SvxAutoCorrDoc& rDoc,
310 : LanguageTag& rLang );
311 :
312 : // Query/Set the Character for the Quote substitution
313 0 : sal_Unicode GetStartSingleQuote() const { return cStartSQuote; }
314 0 : sal_Unicode GetEndSingleQuote() const { return cEndSQuote; }
315 0 : sal_Unicode GetStartDoubleQuote() const { return cStartDQuote; }
316 0 : sal_Unicode GetEndDoubleQuote() const { return cEndDQuote; }
317 :
318 0 : void SetStartSingleQuote( const sal_Unicode cStart ) { cStartSQuote = cStart; }
319 0 : void SetEndSingleQuote( const sal_Unicode cEnd ) { cEndSQuote = cEnd; }
320 0 : void SetStartDoubleQuote( const sal_Unicode cStart ) { cStartDQuote = cStart; }
321 0 : void SetEndDoubleQuote( const sal_Unicode cEnd ) { cEndDQuote = cEnd; }
322 :
323 : OUString GetQuote( SvxAutoCorrDoc& rDoc, sal_Int32 nInsPos,
324 : sal_Unicode cInsChar, bool bSttQuote );
325 : void InsertQuote( SvxAutoCorrDoc& rDoc, sal_Int32 nInsPos,
326 : sal_Unicode cInsChar, bool bSttQuote, bool bIns );
327 :
328 : // Query/Set the name of the AutoCorrect file
329 : // the default is "autocorr.dat"
330 : OUString GetAutoCorrFileName( const LanguageTag& rLanguageTag /* = LANGUAGE_SYSTEM */ ,
331 : bool bNewFile = false,
332 : bool bTstUserExist = false,
333 : bool bUnlocalized = false ) const;
334 :
335 : // Query/Set the current settings of AutoCorrect
336 176 : long GetFlags() const { return nFlags; }
337 2671 : inline SvxSwAutoFmtFlags& GetSwFlags() { return aSwFlags;}
338 52 : bool IsAutoCorrFlag( long nFlag ) const
339 52 : { return nFlags & nFlag ? sal_True : sal_False; }
340 : void SetAutoCorrFlag( long nFlag, bool bOn = true );
341 :
342 : // Load, Set, Get - the replacement list
343 0 : SvxAutocorrWordList* LoadAutocorrWordList(
344 : LanguageType eLang = LANGUAGE_SYSTEM )
345 0 : { return _GetLanguageList( eLang ).LoadAutocorrWordList(); }
346 : const SvxAutocorrWordList* GetAutocorrWordList(
347 : LanguageType eLang = LANGUAGE_SYSTEM )
348 : { return _GetLanguageList( eLang ).GetAutocorrWordList(); }
349 :
350 : // Save word substitutions:
351 : // Save these directly in the storage. The word list is updated
352 : // accordingly!
353 : // - pure Text
354 : bool PutText( const OUString& rShort, const OUString& rLong, LanguageType eLang = LANGUAGE_SYSTEM );
355 : // - Text with attribution (only in the SWG - SWG format!)
356 0 : bool PutText( const OUString& rShort, SfxObjectShell& rShell,
357 : LanguageType eLang = LANGUAGE_SYSTEM )
358 0 : { return _GetLanguageList( eLang ).PutText(rShort, rShell ); }
359 :
360 : bool MakeCombinedChanges( std::vector<SvxAutocorrWord>& aNewEntries,
361 : std::vector<SvxAutocorrWord>& aDeleteEntries,
362 : LanguageType eLang = LANGUAGE_SYSTEM );
363 :
364 : // Load, Set, Get - the exception list for capital letters at the
365 : // beginning of a sentence
366 : void SaveCplSttExceptList( LanguageType eLang = LANGUAGE_SYSTEM );
367 0 : SvStringsISortDtor* LoadCplSttExceptList(
368 : LanguageType eLang = LANGUAGE_SYSTEM)
369 0 : { return _GetLanguageList( eLang ).LoadCplSttExceptList(); }
370 0 : const SvStringsISortDtor* GetCplSttExceptList(
371 : LanguageType eLang = LANGUAGE_SYSTEM )
372 0 : { return _GetLanguageList( eLang ).GetCplSttExceptList(); }
373 :
374 : // Adds a single word. The list will be immediately written to the file!
375 : bool AddCplSttException( const OUString& rNew,
376 : LanguageType eLang = LANGUAGE_SYSTEM );
377 :
378 : // Load, Set, Get the exception list for 2 Capital letters at the
379 : // beginning of a word.
380 : void SaveWrdSttExceptList( LanguageType eLang = LANGUAGE_SYSTEM );
381 0 : SvStringsISortDtor* LoadWrdSttExceptList(
382 : LanguageType eLang = LANGUAGE_SYSTEM )
383 0 : { return _GetLanguageList( eLang ).LoadWrdSttExceptList(); }
384 0 : const SvStringsISortDtor* GetWrdSttExceptList(
385 : LanguageType eLang = LANGUAGE_SYSTEM )
386 0 : { return _GetLanguageList( eLang ).GetWrdSttExceptList(); }
387 : // Adds a single word. The list will be immediately written to the file!
388 : bool AddWrtSttException( const OUString& rNew, LanguageType eLang = LANGUAGE_SYSTEM);
389 :
390 : // Search through the Languages for the entry
391 : bool FindInWrdSttExceptList( LanguageType eLang, const OUString& sWord );
392 : bool FindInCplSttExceptList( LanguageType eLang, const OUString& sWord,
393 : bool bAbbreviation = false);
394 :
395 : // Methods for the auto-correction
396 : bool FnCptlSttWrd( SvxAutoCorrDoc&, const OUString&,
397 : sal_Int32 nSttPos, sal_Int32 nEndPos,
398 : LanguageType eLang = LANGUAGE_SYSTEM );
399 : bool FnChgOrdinalNumber( SvxAutoCorrDoc&, const OUString&,
400 : sal_Int32 nSttPos, sal_Int32 nEndPos,
401 : LanguageType eLang = LANGUAGE_SYSTEM );
402 : bool FnChgToEnEmDash( SvxAutoCorrDoc&, const OUString&,
403 : sal_Int32 nSttPos, sal_Int32 nEndPos,
404 : LanguageType eLang = LANGUAGE_SYSTEM );
405 : bool FnAddNonBrkSpace( SvxAutoCorrDoc&, const OUString&,
406 : sal_Int32 nSttPos, sal_Int32 nEndPos,
407 : LanguageType eLang = LANGUAGE_SYSTEM );
408 : bool FnSetINetAttr( SvxAutoCorrDoc&, const OUString&,
409 : sal_Int32 nSttPos, sal_Int32 nEndPos,
410 : LanguageType eLang = LANGUAGE_SYSTEM );
411 : bool FnChgWeightUnderl( SvxAutoCorrDoc&, const OUString&,
412 : sal_Int32 nSttPos, sal_Int32 nEndPos,
413 : LanguageType eLang = LANGUAGE_SYSTEM );
414 : bool FnCptlSttSntnc( SvxAutoCorrDoc&, const OUString&, bool bNormalPos,
415 : sal_Int32 nSttPos, sal_Int32 nEndPos,
416 : LanguageType eLang = LANGUAGE_SYSTEM);
417 : bool FnCorrectCapsLock( SvxAutoCorrDoc&, const OUString&,
418 : sal_Int32 nSttPos, sal_Int32 nEndPos,
419 : LanguageType eLang = LANGUAGE_SYSTEM );
420 :
421 0 : bool HasRunNext() { return bRunNext; }
422 :
423 : static long GetDefaultFlags();
424 :
425 : // returns sal_True for characters where the function
426 : // 'SvxAutoCorrect::AutoCorrect' should be called.
427 : // (used to avoid occasional 'collisions' with (Thai) input-sequence-checking)
428 : static bool IsAutoCorrectChar( sal_Unicode cChar );
429 :
430 : bool NeedsHardspaceAutocorr( sal_Unicode cChar );
431 :
432 26 : CharClass& GetCharClass( LanguageType eLang )
433 : {
434 26 : if( !pCharClass || eLang != eCharClassLang )
435 4 : _GetCharClass( eLang );
436 26 : return *pCharClass;
437 : }
438 : };
439 :
440 : #endif
441 :
442 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|