Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / include / editeng / svxacorr.hxx
bloba5e43032a78fbc3a2be0573a4484650e0f978a4b
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 <o3tl/sorted_vector.hxx>
24 #include <o3tl/typed_flags_set.hxx>
25 #include <o3tl/string_view.hxx>
26 #include <i18nlangtag/languagetag.hxx>
27 #include <tools/time.hxx>
28 #include <tools/date.hxx>
29 #include <editeng/swafopt.hxx>
30 #include <editeng/editengdllapi.h>
31 #include <unotools/charclass.hxx>
33 #include <optional>
34 #include <map>
35 #include <memory>
36 #include <string_view>
37 #include <utility>
39 class SfxPoolItem;
40 class SotStorage;
41 class SvxAutoCorrect;
42 class SfxObjectShell;
43 namespace vcl { class Window; }
44 namespace com::sun::star::embed { class XStorage; }
45 namespace tools { template <typename T> class SvRef; }
47 struct CompareSvStringsISortDtor
49 bool operator()( std::u16string_view lhs, std::u16string_view rhs ) const
51 return o3tl::compareToIgnoreAsciiCase( lhs, rhs ) < 0;
55 class SvStringsISortDtor
56 : public o3tl::sorted_vector<OUString, CompareSvStringsISortDtor>
60 // Auto correct flags
61 enum class ACFlags : sal_uInt32 {
62 NONE = 0x00000000,
63 CapitalStartSentence = 0x00000001, // Capital letters at the beginning of a sentence
64 CapitalStartWord = 0x00000002, // not two Capital letters at the beginning of a word
65 AddNonBrkSpace = 0x00000004, // Add non breaking space before :,?!%
66 ChgOrdinalNumber = 0x00000008, // Ordinal-Number 1st, 2nd,..
67 ChgToEnEmDash = 0x00000010, // - -> Endash/Emdash
68 ChgWeightUnderl = 0x00000020, // * -> Bold, _ -> Underscore
69 SetINetAttr = 0x00000040, // Set INetAttribut
70 Autocorrect = 0x00000080, // Call AutoCorrect
71 ChgQuotes = 0x00000100, // replace double quotes
72 SaveWordCplSttLst = 0x00000200, // Save Auto correction of Capital letter at beginning of sentence.
73 SaveWordWordStartLst = 0x00000400, // Save Auto correction of TWo INitial CApitals or sMALL iNITIAL.
74 IgnoreDoubleSpace = 0x00000800, // Ignore 2 Spaces
75 ChgSglQuotes = 0x00001000, // Replace simple quotes
76 CorrectCapsLock = 0x00002000, // Correct accidental use of cAPS LOCK key
77 TransliterateRTL = 0x00004000, // Transliterate RTL text
78 ChgAngleQuotes = 0x00008000, // >>, << -> angle quotes in some languages
79 SetDOIAttr = 0x00010000, // Set DOIAttribute
81 ChgWordLstLoad = 0x20000000, // Replacement list loaded
82 CplSttLstLoad = 0x40000000, // Exception list for Capital letters Start loaded
83 WordStartLstLoad = 0x80000000, // Exception list for Word Start loaded
85 namespace o3tl {
86 template<> struct typed_flags<ACFlags> : is_typed_flags<ACFlags, 0xe001ffff> {};
89 enum class ACQuotes
91 NONE,
92 NonBreakingSpace,
93 CapitalizeIAm,
94 DoubleAngleQuote,
95 UseApostrophe,
98 // TODO: handle code points > U+FFFF and check users of this class
100 // only a mapping class
101 class EDITENG_DLLPUBLIC SvxAutoCorrDoc
103 public:
104 virtual ~SvxAutoCorrDoc();
106 virtual bool Delete( sal_Int32 nStt, sal_Int32 nEnd ) = 0;
107 virtual bool Insert( sal_Int32 nPos, const OUString& rTxt ) = 0;
108 virtual bool Replace( sal_Int32 nPos, const OUString& rTxt ) = 0;
109 virtual bool ReplaceRange( sal_Int32 nPos, sal_Int32 nLen, const OUString& rTxt ) = 0;
111 virtual void SetAttr( sal_Int32 nStt, sal_Int32 nEnd, sal_uInt16 nSlotId,
112 SfxPoolItem& ) = 0;
114 virtual bool SetINetAttr( sal_Int32 nStt, sal_Int32 nEnd, const OUString& rURL ) = 0;
116 // Return the text of a previous paragraph.
117 // If no paragraph exits or just an empty one, then return an empty string.
118 // The flag indicates:
119 // TRUE: before the normal insertion position (TRUE)
120 // FALSE: in which the corrected word was inserted.
121 // (Does not to have to be the same paragraph !!!!)
122 virtual OUString const* GetPrevPara(bool bAtNormalPos) = 0;
124 virtual bool ChgAutoCorrWord( sal_Int32& rSttPos, sal_Int32 nEndPos,
125 SvxAutoCorrect& rACorrect,
126 OUString* pPara ) = 0;
127 virtual bool TransliterateRTLWord( sal_Int32& rSttPos, sal_Int32 nEndPos,
128 bool bApply = false ) = 0;
130 // Is called after the change of the signs by the functions
131 // - FnCapitalStartWord
132 // - FnCapitalStartSentence
133 // As an option, the words can then be inserted into the exception lists.
134 virtual void SaveCpltSttWord( ACFlags nFlag, sal_Int32 nPos,
135 const OUString& rExceptWord,
136 sal_Unicode cChar );
138 // which language at the position?
139 virtual LanguageType GetLanguage( sal_Int32 nPos ) const;
143 class EDITENG_DLLPUBLIC SvxAutocorrWord
145 OUString sShort, sLong;
146 bool bIsTxtOnly; // Is pure ASCII - Text
147 public:
148 SvxAutocorrWord( OUString aS, OUString aL, bool bFlag = true )
149 : sShort(std::move( aS )), sLong(std::move( aL )), bIsTxtOnly( bFlag )
152 const OUString& GetShort() const { return sShort; }
153 const OUString& GetLong() const { return sLong; }
154 bool IsTextOnly() const { return bIsTxtOnly; }
157 class EDITENG_DLLPUBLIC SvxAutocorrWordList
159 struct Impl;
160 std::unique_ptr<Impl> mpImpl;
162 SvxAutocorrWordList( const SvxAutocorrWordList& ) = delete;
163 const SvxAutocorrWordList& operator= ( const SvxAutocorrWordList& ) = delete;
165 const SvxAutocorrWord* WordMatches(const SvxAutocorrWord *pFnd,
166 std::u16string_view rTxt,
167 sal_Int32 &rStt,
168 sal_Int32 nEndPos) const;
169 public:
170 SvxAutocorrWordList();
171 // free any objects still in the set
172 ~SvxAutocorrWordList();
173 void DeleteAndDestroyAll();
174 const SvxAutocorrWord* Insert(SvxAutocorrWord aWord) const;
175 std::optional<SvxAutocorrWord> FindAndRemove(const SvxAutocorrWord *pWord);
176 void LoadEntry(const OUString& sWrong, const OUString& sRight, bool bOnlyTxt);
177 bool empty() const;
179 struct CompareSvxAutocorrWordList;
180 typedef std::vector<SvxAutocorrWord> AutocorrWordSetType;
181 const AutocorrWordSetType & getSortedContent() const;
183 const SvxAutocorrWord* SearchWordsInList(std::u16string_view rTxt, sal_Int32& rStt, sal_Int32 nEndPos) const;
186 class EDITENG_DLLPUBLIC SvxAutoCorrectLanguageLists
188 OUString sShareAutoCorrFile, sUserAutoCorrFile;
189 // If the AutoCorr file is newer
190 Date aModifiedDate;
191 tools::Time aModifiedTime, aLastCheckTime;
193 std::unique_ptr<SvStringsISortDtor> pCplStt_ExcptLst;
194 std::unique_ptr<SvStringsISortDtor> pWordStart_ExcptLst;
195 std::unique_ptr<SvxAutocorrWordList> pAutocorr_List;
196 SvxAutoCorrect& rAutoCorrect;
198 ACFlags nFlags;
200 bool IsFileChanged_Imp();
201 void LoadXMLExceptList_Imp( std::unique_ptr<SvStringsISortDtor>& rpLst,
202 const OUString& sStrmName,
203 tools::SvRef<SotStorage>& rStg);
204 static void SaveExceptList_Imp( const SvStringsISortDtor& rLst,
205 const OUString& sStrmName,
206 tools::SvRef<SotStorage> const & rStg,
207 bool bConvert = false);
209 bool MakeBlocklist_Imp( SotStorage& rStg );
210 void RemoveStream_Imp( const OUString& rName );
211 void MakeUserStorage_Impl();
213 public:
214 SvxAutoCorrectLanguageLists( SvxAutoCorrect& rParent,
215 OUString aShareAutoCorrectFile,
216 OUString aUserAutoCorrectFile);
217 ~SvxAutoCorrectLanguageLists();
219 // Load, Set, Get - the replacement list
220 SvxAutocorrWordList* LoadAutocorrWordList();
221 const SvxAutocorrWordList* GetAutocorrWordList();
223 // Load, Set, Get - the exception list for Capital letter at the
224 // beginning of a sentence
225 SvStringsISortDtor* LoadCplSttExceptList();
226 void SaveCplSttExceptList();
227 SvStringsISortDtor* GetCplSttExceptList();
228 bool AddToCplSttExceptList(const OUString& rNew);
230 // Load, Set, Get the exception list for TWo INitial CApitals or sMALL iNITIAL
231 SvStringsISortDtor* LoadWordStartExceptList();
232 void SaveWordStartExceptList();
233 SvStringsISortDtor* GetWordStartExceptList();
234 bool AddToWordStartExceptList(const OUString& rNew);
236 // Save word substitutions:
237 // Store these directly in the storage. The word list is updated
238 // accordingly!
239 // - pure Text
240 bool PutText( const OUString& rShort, const OUString& rLong );
241 // - Text with attribution (only the SWG - SWG format!)
242 void PutText( const OUString& rShort, SfxObjectShell& );
243 // - Make combined changes in one pass
244 bool MakeCombinedChanges( std::vector<SvxAutocorrWord>& aNewEntries, std::vector<SvxAutocorrWord>& aDeleteEntries );
247 class EDITENG_DLLPUBLIC SvxAutoCorrect
249 friend class SvxAutoCorrectLanguageLists;
251 OUString sShareAutoCorrFile, sUserAutoCorrFile;
253 SvxSwAutoFormatFlags aSwFlags; // StarWriter AutoFormat Flags
255 // all languages in a table
256 std::map<LanguageTag, SvxAutoCorrectLanguageLists> m_aLangTable;
257 std::map<LanguageTag, sal_Int64> aLastFileTable;
258 std::optional<CharClass> moCharClass;
260 LanguageType eCharClassLang;
262 ACFlags nFlags;
263 sal_Unicode cStartDQuote, cEndDQuote, cStartSQuote, cEndSQuote;
266 // private methods
267 SvxAutoCorrectLanguageLists& GetLanguageList_( LanguageType eLang );
269 void GetCharClass_( LanguageType eLang );
271 protected:
272 // - Text with attribution (only the SWG - SWG format!)
273 // rShort is the stream name - encrypted!
274 virtual bool PutText( const css::uno::Reference < css::embed::XStorage >& rStg,
275 const OUString& rFileName, const OUString& rShort, SfxObjectShell&, OUString& );
277 // required language in the table add if possible only when the file exists
278 bool CreateLanguageFile(const LanguageTag& rLanguageTag, bool bNewFile = true);
279 // - Return the replacement text (only for SWG format, all others can be
280 // taken from the word list!)
281 // rShort is the stream name - encrypted!
282 public:
284 sal_Unicode GetQuote( sal_Unicode cInsChar, bool bSttQuote,
285 LanguageType eLang ) const;
286 virtual bool GetLongText( const OUString& rShort, OUString& rLong );
288 virtual void refreshBlockList( const css::uno::Reference < css::embed::XStorage >& rStg);
290 SvxAutoCorrect( OUString aShareAutocorrFile,
291 OUString aUserAutocorrFile );
292 SvxAutoCorrect( const SvxAutoCorrect& );
293 virtual ~SvxAutoCorrect();
295 /** Execute an AutoCorrect.
296 Returns what has been executed, according to the above auto correct flags.
297 @param io_bNbspRunNext
298 Remembers if a NO-BREAK SPACE was added (eg. in "fr" language)
299 (set to <TRUE/>) at the last character input that may have to
300 be removed again depending on what character is following.
302 // FIXME: this has the horrible flaw that the rTxt must be a reference
303 // to the actual SwTxtNode/EditNode string because it inserts the character
304 // in rDoc and expects that to side-effect rTxt
305 void DoAutoCorrect( SvxAutoCorrDoc& rDoc, const OUString& rTxt,
306 sal_Int32 nPos, sal_Unicode cInsChar, bool bInsert, bool& io_bNbspRunNext,
307 vcl::Window const * pFrameWin = nullptr );
309 // Return for the autotext expansion the previous word,
310 // AutoCorrect - corresponding algorithm
311 OUString GetPrevAutoCorrWord(SvxAutoCorrDoc const& rDoc, const OUString& rTxt, sal_Int32 nPos);
313 // Returns vector candidates for AutoText name match, starting with the longest string between
314 // 3 and 9 characters long, that is a chunk of text starting with a whitespace or with a word's
315 // first character, and ending at the current cursor position or empty string if no such string
316 // exists
317 static std::vector<OUString> GetChunkForAutoText(std::u16string_view rTxt, sal_Int32 nPos);
319 // Search for the words in the replacement table.
320 // rText - check in this text the words of the list
321 // rStt - the detected starting position
322 // nEnd - to check position - as of this item forward
323 // rLang - Input: in which language is searched
324 // Output: in which "language list" was it found
325 const SvxAutocorrWord* SearchWordsInList( std::u16string_view rTxt,
326 sal_Int32& rStt, sal_Int32 nEndPos,
327 SvxAutoCorrDoc& rDoc,
328 LanguageTag& rLang );
330 // Query/Set the Character for the Quote substitution
331 sal_Unicode GetStartSingleQuote() const { return cStartSQuote; }
332 sal_Unicode GetEndSingleQuote() const { return cEndSQuote; }
333 sal_Unicode GetStartDoubleQuote() const { return cStartDQuote; }
334 sal_Unicode GetEndDoubleQuote() const { return cEndDQuote; }
336 void SetStartSingleQuote( const sal_Unicode cStart ) { cStartSQuote = cStart; }
337 void SetEndSingleQuote( const sal_Unicode cEnd ) { cEndSQuote = cEnd; }
338 void SetStartDoubleQuote( const sal_Unicode cStart ) { cStartDQuote = cStart; }
339 void SetEndDoubleQuote( const sal_Unicode cEnd ) { cEndDQuote = cEnd; }
341 OUString GetQuote( SvxAutoCorrDoc const & rDoc, sal_Int32 nInsPos,
342 sal_Unicode cInsChar, bool bSttQuote );
343 void InsertQuote( SvxAutoCorrDoc& rDoc, sal_Int32 nInsPos,
344 sal_Unicode cInsChar, bool bSttQuote, bool bIns,
345 LanguageType eLang, ACQuotes eType ) const;
347 // Query/Set the name of the AutoCorrect file
348 // the default is "autocorr.dat"
349 OUString GetAutoCorrFileName( const LanguageTag& rLanguageTag /* = LANGUAGE_SYSTEM */ ,
350 bool bNewFile = false,
351 bool bTstUserExist = false,
352 bool bUnlocalized = false ) const;
354 // Query/Set the current settings of AutoCorrect
355 ACFlags GetFlags() const { return nFlags; }
356 SvxSwAutoFormatFlags& GetSwFlags() { return aSwFlags;}
357 const SvxSwAutoFormatFlags& GetSwFlags() const { return aSwFlags; }
358 bool IsAutoCorrFlag( ACFlags nFlag ) const
359 { return bool(nFlags & nFlag); }
360 void SetAutoCorrFlag( ACFlags nFlag, bool bOn = true );
362 // Load, Set, Get - the replacement list
363 SvxAutocorrWordList* LoadAutocorrWordList( LanguageType eLang )
364 { return GetLanguageList_( eLang ).LoadAutocorrWordList(); }
366 // Save word substitutions:
367 // Save these directly in the storage. The word list is updated
368 // accordingly!
369 // - pure Text
370 bool PutText( const OUString& rShort, const OUString& rLong, LanguageType eLang );
371 // - Text with attribution (only in the SWG - SWG format!)
372 void PutText( const OUString& rShort, SfxObjectShell& rShell, LanguageType eLang )
373 { GetLanguageList_( eLang ).PutText(rShort, rShell ); }
375 void MakeCombinedChanges( std::vector<SvxAutocorrWord>& aNewEntries,
376 std::vector<SvxAutocorrWord>& aDeleteEntries,
377 LanguageType eLang );
379 // Load, Set, Get - the exception list for capital letters at the
380 // beginning of a sentence
381 void SaveCplSttExceptList( LanguageType eLang );
382 SvStringsISortDtor* LoadCplSttExceptList(LanguageType eLang)
383 { return GetLanguageList_( eLang ).LoadCplSttExceptList(); }
384 const SvStringsISortDtor* GetCplSttExceptList( LanguageType eLang )
385 { return GetLanguageList_( eLang ).GetCplSttExceptList(); }
387 // Adds a single word. The list will be immediately written to the file!
388 bool AddCplSttException( const OUString& rNew, LanguageType eLang );
390 // Load, Set, Get the exception list for TWo INitial CApitals or sMALL iNITIAL
391 void SaveWordStartExceptList( LanguageType eLang );
392 SvStringsISortDtor* LoadWordStartExceptList( LanguageType eLang )
393 { return GetLanguageList_( eLang ).LoadWordStartExceptList(); }
394 const SvStringsISortDtor* GetWordStartExceptList( LanguageType eLang )
395 { return GetLanguageList_( eLang ).GetWordStartExceptList(); }
396 // Adds a single word. The list will be immediately written to the file!
397 bool AddWordStartException( const OUString& rNew, LanguageType eLang);
399 // Search through the Languages for the entry
400 bool FindInWordStartExceptList( LanguageType eLang, const OUString& sWord );
401 bool FindInCplSttExceptList( LanguageType eLang, const OUString& sWord,
402 bool bAbbreviation = false);
404 // Methods for the auto-correction
405 void FnCapitalStartWord( SvxAutoCorrDoc&, const OUString&,
406 sal_Int32 nSttPos, sal_Int32 nEndPos,
407 LanguageType eLang );
408 bool FnChgOrdinalNumber( SvxAutoCorrDoc&, const OUString&,
409 sal_Int32 nSttPos, sal_Int32 nEndPos,
410 LanguageType eLang );
411 bool FnChgToEnEmDash( SvxAutoCorrDoc&, const OUString&,
412 sal_Int32 nSttPos, sal_Int32 nEndPos,
413 LanguageType eLang );
414 bool FnAddNonBrkSpace( SvxAutoCorrDoc&, std::u16string_view,
415 sal_Int32 nEndPos,
416 LanguageType eLang, bool& io_bNbspRunNext );
417 bool FnSetINetAttr( SvxAutoCorrDoc&, const OUString&,
418 sal_Int32 nSttPos, sal_Int32 nEndPos,
419 LanguageType eLang );
420 bool FnSetDOIAttr( SvxAutoCorrDoc&, const OUString&,
421 sal_Int32 nSttPos, sal_Int32 nEndPos,
422 LanguageType eLang );
423 bool FnChgWeightUnderl( SvxAutoCorrDoc&, const OUString&,
424 sal_Int32 nEndPos );
425 void FnCapitalStartSentence( SvxAutoCorrDoc&, const OUString&, bool bNormalPos,
426 sal_Int32 nSttPos, sal_Int32 nEndPos,
427 LanguageType eLang);
428 bool FnCorrectCapsLock( SvxAutoCorrDoc&, const OUString&,
429 sal_Int32 nSttPos, sal_Int32 nEndPos,
430 LanguageType eLang );
432 static ACFlags GetDefaultFlags();
434 // returns sal_True for characters where the function
435 // 'SvxAutoCorrect::AutoCorrect' should be called.
436 // (used to avoid occasional 'collisions' with (Thai) input-sequence-checking)
437 static bool IsAutoCorrectChar( sal_Unicode cChar );
439 static bool NeedsHardspaceAutocorr( sal_Unicode cChar );
441 CharClass& GetCharClass( LanguageType eLang )
443 if( !moCharClass || eLang != eCharClassLang )
444 GetCharClass_( eLang );
445 return *moCharClass;
449 #endif
451 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */