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