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