1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #ifndef INCLUDED_EDITENG_SVXACORR_HXX
21 #define INCLUDED_EDITENG_SVXACORR_HXX
23 #include <com/sun/star/embed/XStorage.hpp>
25 #include <o3tl/sorted_vector.hxx>
26 #include <tools/ref.hxx>
27 #include <i18nlangtag/languagetag.hxx>
28 #include <tools/time.hxx>
29 #include <tools/date.hxx>
30 #include <editeng/swafopt.hxx>
31 #include <editeng/editengdllapi.h>
41 namespace vcl
{ class Window
; }
43 struct CompareSvStringsISortDtor
45 bool operator()( OUString
const& lhs
, OUString
const& rhs
) const
47 return lhs
.compareToIgnoreAsciiCase( rhs
) < 0;
51 class SvStringsISortDtor
52 : public o3tl::sorted_vector
<OUString
, CompareSvStringsISortDtor
>
57 const long CapitalStartSentence
= 0x00000001; // Capital letters at the beginning of a sentence
58 const long CapitalStartWord
= 0x00000002; // not two Capital letters at the beginning of a word
59 const long AddNonBrkSpace
= 0x00000004; // Add non breaking space before :;?!%
60 const long ChgOrdinalNumber
= 0x00000008; // Ordinal-Number 1st, 2nd,..
61 const long ChgToEnEmDash
= 0x00000010; // - -> Endash/Emdash
62 const long ChgWeightUnderl
= 0x00000020; // * -> Bold, _ -> Underscore
63 const long SetINetAttr
= 0x00000040; // Set INetAttribut
64 const long Autocorrect
= 0x00000080; // Call AutoCorrect
65 const long ChgQuotes
= 0x00000100; // replace double quotes
66 const long SaveWordCplSttLst
= 0x00000200; // Save Auto correction of Capital letter at beginning of sentence.
67 const long SaveWordWrdSttLst
= 0x00000400; // Save Auto correction of 2 Capital letter at beginning of word.
68 const long IgnoreDoubleSpace
= 0x00000800; // Ignore 2 Spaces
69 const long ChgSglQuotes
= 0x00001000; // Replace simple quotes
70 const long CorrectCapsLock
= 0x00002000; // Correct accidental use of cAPS LOCK key
72 const long ChgWordLstLoad
= 0x20000000; // Replacement list loaded
73 const long CplSttLstLoad
= 0x40000000; // Exception list for Capital letters Start loaded
74 const long WrdSttLstLoad
= 0x80000000; // Exception list for Word Start loaded
76 // TODO: handle code points > U+FFFF and check users of this class
78 // only a mapping class
79 class EDITENG_DLLPUBLIC SvxAutoCorrDoc
83 virtual ~SvxAutoCorrDoc();
85 virtual bool Delete( sal_Int32 nStt
, sal_Int32 nEnd
) = 0;
86 virtual bool Insert( sal_Int32 nPos
, const OUString
& rTxt
) = 0;
87 virtual bool Replace( sal_Int32 nPos
, const OUString
& rTxt
) = 0;
88 virtual bool ReplaceRange( sal_Int32 nPos
, sal_Int32 nLen
, const OUString
& rTxt
) = 0;
90 virtual void SetAttr( sal_Int32 nStt
, sal_Int32 nEnd
, sal_uInt16 nSlotId
,
93 virtual bool SetINetAttr( sal_Int32 nStt
, sal_Int32 nEnd
, const OUString
& rURL
) = 0;
95 // Return the text of a previous paragraph.
96 // If no paragraph exits or just an empty one, then return an empty string.
97 // The flag indicates:
98 // TRUE: before the normal insertion position (TRUE)
99 // FALSE: in which the corrected word was inserted.
100 // (Does not to have to be the same paragraph !!!!)
101 virtual OUString
const* GetPrevPara(bool bAtNormalPos
) = 0;
103 virtual bool ChgAutoCorrWord( sal_Int32
& rSttPos
, sal_Int32 nEndPos
,
104 SvxAutoCorrect
& rACorrect
,
105 OUString
* pPara
) = 0;
106 // Is called after the change of the signs by the functions
107 // - FnCapitalStartWord
108 // - FnCapitalStartSentence
109 // As an option, the words can then be inserted into the exception lists.
110 virtual void SaveCpltSttWord( sal_uLong nFlag
, sal_Int32 nPos
,
111 const OUString
& rExceptWord
,
114 // which language at the position?
115 virtual LanguageType
GetLanguage( sal_Int32 nPos
) const;
119 class EDITENG_DLLPUBLIC SvxAutocorrWord
121 OUString sShort
, sLong
;
122 bool bIsTxtOnly
; // Is pure ASCII - Text
124 SvxAutocorrWord( const OUString
& rS
, const OUString
& rL
, bool bFlag
= true )
125 : sShort( rS
), sLong( rL
), bIsTxtOnly( bFlag
)
128 const OUString
& GetShort() const { return sShort
; }
129 const OUString
& GetLong() const { return sLong
; }
130 bool IsTextOnly() const { return bIsTxtOnly
; }
133 class EDITENG_DLLPUBLIC SvxAutocorrWordList
136 std::unique_ptr
<Impl
> mpImpl
;
138 SvxAutocorrWordList( const SvxAutocorrWordList
& ) = delete;
139 const SvxAutocorrWordList
& operator= ( const SvxAutocorrWordList
& ) = delete;
141 const SvxAutocorrWord
* WordMatches(const SvxAutocorrWord
*pFnd
,
142 const OUString
&rTxt
,
144 sal_Int32 nEndPos
) const;
146 SvxAutocorrWordList();
147 // free any objects still in the set
148 ~SvxAutocorrWordList();
149 void DeleteAndDestroyAll();
150 bool Insert(SvxAutocorrWord
*pWord
) const;
151 SvxAutocorrWord
* FindAndRemove(SvxAutocorrWord
*pWord
);
152 void LoadEntry(const OUString
& sWrong
, const OUString
& sRight
, bool bOnlyTxt
);
155 typedef std::vector
<SvxAutocorrWord
*> Content
;
156 Content
getSortedContent() const;
158 const SvxAutocorrWord
* SearchWordsInList(const OUString
& rTxt
, sal_Int32
& rStt
, sal_Int32 nEndPos
) const;
161 class EDITENG_DLLPUBLIC SvxAutoCorrectLanguageLists
163 OUString sShareAutoCorrFile
, sUserAutoCorrFile
;
164 // If the AutoCorr file is newer
166 tools::Time aModifiedTime
, aLastCheckTime
;
168 SvStringsISortDtor
* pCplStt_ExcptLst
;
169 SvStringsISortDtor
* pWrdStt_ExcptLst
;
170 SvxAutocorrWordList
* pAutocorr_List
;
171 SvxAutoCorrect
& rAutoCorrect
;
175 bool IsFileChanged_Imp();
176 void LoadXMLExceptList_Imp( SvStringsISortDtor
*& rpLst
,
177 const sal_Char
* pStrmName
,
178 tools::SvRef
<SotStorage
>& rStg
);
179 static void SaveExceptList_Imp( const SvStringsISortDtor
& rLst
,
180 const sal_Char
* pStrmName
,
181 tools::SvRef
<SotStorage
>& rStg
,
182 bool bConvert
= false);
184 bool MakeBlocklist_Imp( SotStorage
& rStg
);
185 void RemoveStream_Imp( const OUString
& rName
);
186 void MakeUserStorage_Impl();
189 SvxAutoCorrectLanguageLists( SvxAutoCorrect
& rParent
,
190 const OUString
& rShareAutoCorrectFile
,
191 const OUString
& rUserAutoCorrectFile
);
192 ~SvxAutoCorrectLanguageLists();
194 // Load, Set, Get - the replacement list
195 SvxAutocorrWordList
* LoadAutocorrWordList();
196 void SetAutocorrWordList( SvxAutocorrWordList
* pList
);
197 const SvxAutocorrWordList
* GetAutocorrWordList();
199 // Load, Set, Get - the exception list for Capital letter at the
200 // beginning of a sentence
201 SvStringsISortDtor
* LoadCplSttExceptList();
202 void SaveCplSttExceptList();
203 void SetCplSttExceptList( SvStringsISortDtor
* pList
);
204 SvStringsISortDtor
* GetCplSttExceptList();
205 bool AddToCplSttExceptList(const OUString
& rNew
);
207 // Load, Set, Get the exception list for 2 Capital letters at the
208 // beginning of a word.
209 SvStringsISortDtor
* LoadWrdSttExceptList();
210 void SaveWrdSttExceptList();
211 void SetWrdSttExceptList( SvStringsISortDtor
* pList
);
212 SvStringsISortDtor
* GetWrdSttExceptList();
213 bool AddToWrdSttExceptList(const OUString
& rNew
);
215 // Save word substitutions:
216 // Store these directly in the storage. The word list is updated
219 bool PutText( const OUString
& rShort
, const OUString
& rLong
);
220 // - Text with attribution (only the SWG - SWG format!)
221 bool PutText( const OUString
& rShort
, SfxObjectShell
& );
222 // - Make combined changes in one pass
223 bool MakeCombinedChanges( std::vector
<SvxAutocorrWord
>& aNewEntries
, std::vector
<SvxAutocorrWord
>& aDeleteEntries
);
226 class EDITENG_DLLPUBLIC SvxAutoCorrect
228 friend class SvxAutoCorrectLanguageLists
;
230 OUString sShareAutoCorrFile
, sUserAutoCorrFile
;
232 SvxSwAutoFormatFlags aSwFlags
; // StarWriter AutoFormat Flags
234 // all languages in a table
235 std::map
<LanguageTag
, std::unique_ptr
<SvxAutoCorrectLanguageLists
>> m_aLangTable
;
236 std::map
<LanguageTag
, sal_Int64
> aLastFileTable
;
237 std::unique_ptr
<CharClass
> pCharClass
;
239 LanguageType eCharClassLang
;
242 sal_Unicode cStartDQuote
, cEndDQuote
, cStartSQuote
, cEndSQuote
,
247 SvxAutoCorrectLanguageLists
& GetLanguageList_( LanguageType eLang
);
249 void GetCharClass_( LanguageType eLang
);
252 // - Text with attribution (only the SWG - SWG format!)
253 // rShort is the stream name - encrypted!
254 virtual bool PutText( const css::uno::Reference
< css::embed::XStorage
>& rStg
,
255 const OUString
& rFileName
, const OUString
& rShort
, SfxObjectShell
&, OUString
& );
257 // required language in the table add if possible only when the file exists
258 bool CreateLanguageFile(const LanguageTag
& rLanguageTag
, bool bNewFile
= true);
259 // - Return the replacement text (only for SWG format, all others can be
260 // taken from the word list!)
261 // rShort is the stream name - encrypted!
264 sal_Unicode
GetQuote( sal_Unicode cInsChar
, bool bSttQuote
,
265 LanguageType eLang
) const;
266 virtual bool GetLongText( const OUString
& rShort
, OUString
& rLong
);
268 virtual void refreshBlockList( const css::uno::Reference
< css::embed::XStorage
>& rStg
);
270 SvxAutoCorrect( const OUString
& rShareAutocorrFile
,
271 const OUString
& rUserAutocorrFile
);
272 SvxAutoCorrect( const SvxAutoCorrect
& );
273 virtual ~SvxAutoCorrect();
275 /** Execute an AutoCorrect.
276 Returns what has been executed, according to the above auto correct flags.
277 @param io_bNbspRunNext
278 Remembers if a NO-BREAK SPACE was added (eg. in "fr" language)
279 (set to <TRUE/>) at the last character input that may have to
280 be removed again depending on what character is following.
282 // FIXME: this has the horrible flaw that the rTxt must be a reference
283 // to the actual SwTxtNode/EditNode string because it inserts the character
284 // in rDoc and expects that to side-effect rTxt
285 void DoAutoCorrect( SvxAutoCorrDoc
& rDoc
, const OUString
& rTxt
,
286 sal_Int32 nPos
, sal_Unicode cInsChar
, bool bInsert
, bool& io_bNbspRunNext
,
287 vcl::Window
* pFrameWin
= nullptr );
289 // Return for the autotext expansion the previous word,
290 // AutoCorrect - corresponding algorithm
291 bool GetPrevAutoCorrWord( SvxAutoCorrDoc
& rDoc
, const OUString
& rTxt
,
292 sal_Int32 nPos
, OUString
& rWord
) const;
294 // Search for the words in the replacement table.
295 // rText - check in this text the words of the list
296 // rStt - the detected starting position
297 // nEnd - to check position - as of this item forward
298 // rLang - Input: in which language is searched
299 // Output: in which "language list" was it found
300 const SvxAutocorrWord
* SearchWordsInList( const OUString
& rTxt
,
301 sal_Int32
& rStt
, sal_Int32 nEndPos
,
302 SvxAutoCorrDoc
& rDoc
,
303 LanguageTag
& rLang
);
305 // Query/Set the Character for the Quote substitution
306 sal_Unicode
GetStartSingleQuote() const { return cStartSQuote
; }
307 sal_Unicode
GetEndSingleQuote() const { return cEndSQuote
; }
308 sal_Unicode
GetStartDoubleQuote() const { return cStartDQuote
; }
309 sal_Unicode
GetEndDoubleQuote() const { return cEndDQuote
; }
311 void SetStartSingleQuote( const sal_Unicode cStart
) { cStartSQuote
= cStart
; }
312 void SetEndSingleQuote( const sal_Unicode cEnd
) { cEndSQuote
= cEnd
; }
313 void SetStartDoubleQuote( const sal_Unicode cStart
) { cStartDQuote
= cStart
; }
314 void SetEndDoubleQuote( const sal_Unicode cEnd
) { cEndDQuote
= cEnd
; }
316 OUString
GetQuote( SvxAutoCorrDoc
& rDoc
, sal_Int32 nInsPos
,
317 sal_Unicode cInsChar
, bool bSttQuote
);
318 void InsertQuote( SvxAutoCorrDoc
& rDoc
, sal_Int32 nInsPos
,
319 sal_Unicode cInsChar
, bool bSttQuote
, bool bIns
);
321 // Query/Set the name of the AutoCorrect file
322 // the default is "autocorr.dat"
323 OUString
GetAutoCorrFileName( const LanguageTag
& rLanguageTag
/* = LANGUAGE_SYSTEM */ ,
324 bool bNewFile
= false,
325 bool bTstUserExist
= false,
326 bool bUnlocalized
= false ) const;
328 // Query/Set the current settings of AutoCorrect
329 long GetFlags() const { return nFlags
; }
330 SvxSwAutoFormatFlags
& GetSwFlags() { return aSwFlags
;}
331 bool IsAutoCorrFlag( long nFlag
) const
332 { return (nFlags
& nFlag
) != 0; }
333 void SetAutoCorrFlag( long nFlag
, bool bOn
= true );
335 // Load, Set, Get - the replacement list
336 SvxAutocorrWordList
* LoadAutocorrWordList( LanguageType eLang
)
337 { return GetLanguageList_( eLang
).LoadAutocorrWordList(); }
339 // Save word substitutions:
340 // Save these directly in the storage. The word list is updated
343 bool PutText( const OUString
& rShort
, const OUString
& rLong
, LanguageType eLang
);
344 // - Text with attribution (only in the SWG - SWG format!)
345 void PutText( const OUString
& rShort
, SfxObjectShell
& rShell
, LanguageType eLang
)
346 { GetLanguageList_( eLang
).PutText(rShort
, rShell
); }
348 void MakeCombinedChanges( std::vector
<SvxAutocorrWord
>& aNewEntries
,
349 std::vector
<SvxAutocorrWord
>& aDeleteEntries
,
350 LanguageType eLang
);
352 // Load, Set, Get - the exception list for capital letters at the
353 // beginning of a sentence
354 void SaveCplSttExceptList( LanguageType eLang
);
355 SvStringsISortDtor
* LoadCplSttExceptList(LanguageType eLang
)
356 { return GetLanguageList_( eLang
).LoadCplSttExceptList(); }
357 const SvStringsISortDtor
* GetCplSttExceptList( LanguageType eLang
)
358 { return GetLanguageList_( eLang
).GetCplSttExceptList(); }
360 // Adds a single word. The list will be immediately written to the file!
361 bool AddCplSttException( const OUString
& rNew
, LanguageType eLang
);
363 // Load, Set, Get the exception list for 2 Capital letters at the
364 // beginning of a word.
365 void SaveWrdSttExceptList( LanguageType eLang
);
366 SvStringsISortDtor
* LoadWrdSttExceptList( LanguageType eLang
)
367 { return GetLanguageList_( eLang
).LoadWrdSttExceptList(); }
368 const SvStringsISortDtor
* GetWrdSttExceptList( LanguageType eLang
)
369 { return GetLanguageList_( eLang
).GetWrdSttExceptList(); }
370 // Adds a single word. The list will be immediately written to the file!
371 bool AddWrtSttException( const OUString
& rNew
, LanguageType eLang
);
373 // Search through the Languages for the entry
374 bool FindInWrdSttExceptList( LanguageType eLang
, const OUString
& sWord
);
375 bool FindInCplSttExceptList( LanguageType eLang
, const OUString
& sWord
,
376 bool bAbbreviation
= false);
378 // Methods for the auto-correction
379 bool FnCapitalStartWord( SvxAutoCorrDoc
&, const OUString
&,
380 sal_Int32 nSttPos
, sal_Int32 nEndPos
,
381 LanguageType eLang
);
382 bool FnChgOrdinalNumber( SvxAutoCorrDoc
&, const OUString
&,
383 sal_Int32 nSttPos
, sal_Int32 nEndPos
,
384 LanguageType eLang
);
385 bool FnChgToEnEmDash( SvxAutoCorrDoc
&, const OUString
&,
386 sal_Int32 nSttPos
, sal_Int32 nEndPos
,
387 LanguageType eLang
);
388 bool FnAddNonBrkSpace( SvxAutoCorrDoc
&, const OUString
&,
390 LanguageType eLang
, bool& io_bNbspRunNext
);
391 bool FnSetINetAttr( SvxAutoCorrDoc
&, const OUString
&,
392 sal_Int32 nSttPos
, sal_Int32 nEndPos
,
393 LanguageType eLang
);
394 bool FnChgWeightUnderl( SvxAutoCorrDoc
&, const OUString
&,
396 bool FnCapitalStartSentence( SvxAutoCorrDoc
&, const OUString
&, bool bNormalPos
,
397 sal_Int32 nSttPos
, sal_Int32 nEndPos
,
399 bool FnCorrectCapsLock( SvxAutoCorrDoc
&, const OUString
&,
400 sal_Int32 nSttPos
, sal_Int32 nEndPos
,
401 LanguageType eLang
);
403 static long GetDefaultFlags();
405 // returns sal_True for characters where the function
406 // 'SvxAutoCorrect::AutoCorrect' should be called.
407 // (used to avoid occasional 'collisions' with (Thai) input-sequence-checking)
408 static bool IsAutoCorrectChar( sal_Unicode cChar
);
410 static bool NeedsHardspaceAutocorr( sal_Unicode cChar
);
412 CharClass
& GetCharClass( LanguageType eLang
)
414 if( !pCharClass
|| eLang
!= eCharClassLang
)
415 GetCharClass_( eLang
);
422 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */