LibreOffice Module cui (master)  1
optlingu.cxx
Go to the documentation of this file.
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 #include <vcl/settings.hxx>
21 #include <vcl/weld.hxx>
23 #include <i18nlangtag/mslangid.hxx>
24 #include <officecfg/Office/Security.hxx>
25 #include <unotools/lingucfg.hxx>
26 #include <unotools/linguprops.hxx>
27 #include <editeng/unolingu.hxx>
28 #include <linguistic/misc.hxx>
29 #include <sfx2/sfxsids.hrc>
30 #include <tools/debug.hxx>
31 #include <tools/urlobj.hxx>
32 #include <tools/diagnose_ex.h>
35 #include <com/sun/star/linguistic2/LinguServiceManager.hpp>
36 #include <com/sun/star/linguistic2/XSearchableDictionaryList.hpp>
37 #include <com/sun/star/linguistic2/XSpellChecker.hpp>
38 #include <com/sun/star/linguistic2/XProofreader.hpp>
39 #include <com/sun/star/linguistic2/XHyphenator.hpp>
40 #include <com/sun/star/linguistic2/XThesaurus.hpp>
41 #include <com/sun/star/linguistic2/XDictionary.hpp>
42 #include <com/sun/star/linguistic2/XDictionaryList.hpp>
43 #include <com/sun/star/linguistic2/XLinguProperties.hpp>
44 #include <com/sun/star/lang/XServiceDisplayName.hpp>
45 #include <com/sun/star/frame/XStorable.hpp>
47 #include <svl/eitem.hxx>
48 #include <vcl/svapp.hxx>
49 #include <sal/log.hxx>
50 #include <osl/diagnose.h>
51 
52 #include <svx/svxdlg.hxx>
53 #include <editeng/optitems.hxx>
54 #include <optlingu.hxx>
55 #include <dialmgr.hxx>
56 #include <strings.hrc>
57 
58 #include <ucbhelper/content.hxx>
59 
60 #include <vector>
61 #include <map>
62 
63 using namespace ::ucbhelper;
64 using namespace ::com::sun::star;
65 using namespace css::lang;
66 using namespace css::uno;
67 using namespace css::linguistic2;
68 using namespace css::beans;
69 
70 constexpr OUStringLiteral cSpell(SN_SPELLCHECKER);
71 constexpr OUStringLiteral cGrammar(SN_GRAMMARCHECKER);
72 constexpr OUStringLiteral cHyph(SN_HYPHENATOR);
73 constexpr OUStringLiteral cThes(SN_THESAURUS);
74 
75 // static ----------------------------------------------------------------
76 
77 static sal_Int32 lcl_SeqGetEntryPos(
78  const Sequence< OUString > &rSeq, std::u16string_view rEntry )
79 {
80  sal_Int32 i;
81  sal_Int32 nLen = rSeq.getLength();
82  const OUString *pItem = rSeq.getConstArray();
83  for (i = 0; i < nLen; ++i)
84  {
85  if (rEntry == pItem[i])
86  break;
87  }
88  return i < nLen ? i : -1;
89 }
90 
91 static bool KillFile_Impl( const OUString& rURL )
92 {
93  bool bRet = true;
94  try
95  {
96  Content aCnt( rURL, uno::Reference< css::ucb::XCommandEnvironment >(), comphelper::getProcessComponentContext() );
97  aCnt.executeCommand( "delete", Any( true ) );
98  }
99  catch( ... )
100  {
101  TOOLS_WARN_EXCEPTION( "cui.options", "KillFile" );
102  bRet = false;
103  }
104 
105  return bRet;
106 }
107 
108 // 0x 0p 0t 0c nn
109 // p: 1 -> parent
110 // t: 1 -> spell, 2 -> hyph, 3 -> thes, 4 -> grammar
111 // c: 1 -> checked 0 -> unchecked
112 // n: index
113 
114 #define TYPE_SPELL sal_uInt8(1)
115 #define TYPE_GRAMMAR sal_uInt8(2)
116 #define TYPE_HYPH sal_uInt8(3)
117 #define TYPE_THES sal_uInt8(4)
118 
119 namespace {
120 
121 class ModuleUserData_Impl
122 {
123  bool bParent;
124  bool bIsChecked;
127  OUString sImplName;
128 
129 public:
130  ModuleUserData_Impl( const OUString& sImpName, bool bIsParent, bool bChecked, sal_uInt8 nSetType, sal_uInt8 nSetIndex ) :
131  bParent(bIsParent),
132  bIsChecked(bChecked),
133  nType(nSetType),
134  nIndex(nSetIndex),
135  sImplName(sImpName)
136  {
137  }
138  bool IsParent() const {return bParent;}
139  sal_uInt8 GetType() const {return nType;}
140  bool IsChecked() const {return bIsChecked;}
141  sal_uInt8 GetIndex() const {return nIndex;}
142  const OUString& GetImplName() const {return sImplName;}
143 
144 };
145 
146 
147 // User for user-dictionaries (XDictionary interface)
148 
149 class DicUserData
150 {
151  sal_uInt32 nVal;
152 
153 public:
154  explicit DicUserData(sal_uInt32 nUserData) : nVal( nUserData ) {}
155  DicUserData( sal_uInt16 nEID,
156  bool bChecked, bool bEditable, bool bDeletable );
157 
158  sal_uInt32 GetUserData() const { return nVal; }
159  sal_uInt16 GetEntryId() const { return static_cast<sal_uInt16>(nVal >> 16); }
160  bool IsChecked() const { return static_cast<bool>((nVal >> 8) & 0x01); }
161  bool IsDeletable() const { return static_cast<bool>((nVal >> 10) & 0x01); }
162 };
163 
164 }
165 
166 DicUserData::DicUserData(
167  sal_uInt16 nEID,
168  bool bChecked, bool bEditable, bool bDeletable )
169 {
170  DBG_ASSERT( nEID < 65000, "Entry Id out of range" );
171  nVal = (static_cast<sal_uInt32>(0xFFFF & nEID) << 16) |
172  (static_cast<sal_uInt32>(bChecked ? 1 : 0) << 8) |
173  (static_cast<sal_uInt32>(bEditable ? 1 : 0) << 9) |
174  (static_cast<sal_uInt32>(bDeletable ? 1 : 0) << 10);
175 }
176 
177 /*--------------------------------------------------
178  Entry IDs for options listbox of dialog
179 --------------------------------------------------*/
180 
181 namespace {
182 
184 {
185  EID_SPELL_AUTO,
186  EID_GRAMMAR_AUTO,
187  EID_CAPITAL_WORDS,
188  EID_WORDS_WITH_DIGITS,
189  EID_SPELL_SPECIAL,
190  EID_NUM_MIN_WORDLEN,
191  EID_NUM_PRE_BREAK,
192  EID_NUM_POST_BREAK,
193  EID_HYPH_AUTO,
194  EID_HYPH_SPECIAL
195 };
196 
197 }
198 
199 static OUString lcl_GetPropertyName( EID_OPTIONS eEntryId )
200 {
201  switch (eEntryId)
202  {
203  case EID_SPELL_AUTO: return UPN_IS_SPELL_AUTO;
204  case EID_GRAMMAR_AUTO: return UPN_IS_GRAMMAR_AUTO;
205  case EID_CAPITAL_WORDS: return UPN_IS_SPELL_UPPER_CASE;
206  case EID_WORDS_WITH_DIGITS: return UPN_IS_SPELL_WITH_DIGITS;
207  case EID_SPELL_SPECIAL: return UPN_IS_SPELL_SPECIAL;
208  case EID_NUM_MIN_WORDLEN: return UPN_HYPH_MIN_WORD_LENGTH;
209  case EID_NUM_PRE_BREAK: return UPN_HYPH_MIN_LEADING;
210  case EID_NUM_POST_BREAK: return UPN_HYPH_MIN_TRAILING;
211  case EID_HYPH_AUTO: return UPN_IS_HYPH_AUTO;
212  case EID_HYPH_SPECIAL: return UPN_IS_HYPH_SPECIAL;
213  default: assert (false); abort();
214  }
215 }
216 
217 namespace {
218 
219 class OptionsBreakSet : public weld::GenericDialogController
220 {
221  std::unique_ptr<weld::Widget> m_xBeforeFrame;
222  std::unique_ptr<weld::Widget> m_xAfterFrame;
223  std::unique_ptr<weld::Widget> m_xMinimalFrame;
224  std::unique_ptr<weld::SpinButton> m_xBreakNF;
225 
226 public:
227  OptionsBreakSet(weld::Window* pParent, sal_uInt16 nRID)
228  : GenericDialogController(pParent, "cui/ui/breaknumberoption.ui", "BreakNumberOption")
229  , m_xBeforeFrame(m_xBuilder->weld_widget("beforeframe"))
230  , m_xAfterFrame(m_xBuilder->weld_widget("afterframe"))
231  , m_xMinimalFrame(m_xBuilder->weld_widget("miniframe"))
232  {
233  assert(EID_NUM_PRE_BREAK == nRID || EID_NUM_POST_BREAK == nRID || EID_NUM_MIN_WORDLEN == nRID); //unexpected ID
234 
235  if (nRID == EID_NUM_PRE_BREAK)
236  {
237  m_xBeforeFrame->show();
238  m_xBreakNF = m_xBuilder->weld_spin_button("beforebreak");
239  }
240  else if(nRID == EID_NUM_POST_BREAK)
241  {
242  m_xAfterFrame->show();
243  m_xBreakNF = m_xBuilder->weld_spin_button("afterbreak");
244  }
245  else if(nRID == EID_NUM_MIN_WORDLEN)
246  {
247  m_xMinimalFrame->show();
248  m_xBreakNF = m_xBuilder->weld_spin_button("wordlength");
249  }
250  }
251 
252  weld::SpinButton& GetNumericFld()
253  {
254  return *m_xBreakNF;
255  }
256 };
257 
258 // class OptionsUserData -------------------------------------------------
259 
260 class OptionsUserData
261 {
262  sal_uInt32 nVal;
263 
264 public:
265  explicit OptionsUserData( sal_uInt32 nUserData ) : nVal( nUserData ) {}
266  OptionsUserData( sal_uInt16 nEID,
267  bool bHasNV, sal_uInt16 nNumVal,
268  bool bCheckable, bool bChecked );
269 
270  sal_uInt32 GetUserData() const { return nVal; }
271  sal_uInt16 GetEntryId() const { return static_cast<sal_uInt16>(nVal >> 16); }
272  bool HasNumericValue() const { return static_cast<bool>((nVal >> 10) & 0x01); }
273  sal_uInt16 GetNumericValue() const { return static_cast<sal_uInt16>(nVal & 0xFF); }
274  bool IsCheckable() const { return static_cast<bool>((nVal >> 9) & 0x01); }
275  bool IsModified() const { return static_cast<bool>((nVal >> 11) & 0x01); }
276 
277  void SetNumericValue( sal_uInt8 nNumVal );
278 };
279 
280 }
281 
282 OptionsUserData::OptionsUserData( sal_uInt16 nEID,
283  bool bHasNV, sal_uInt16 nNumVal,
284  bool bCheckable, bool bChecked )
285 {
286  DBG_ASSERT( nEID < 65000, "Entry Id out of range" );
287  DBG_ASSERT( nNumVal < 256, "value out of range" );
288  nVal = (static_cast<sal_uInt32>(0xFFFF & nEID) << 16) |
289  (static_cast<sal_uInt32>(bHasNV ? 1 : 0) << 10) |
290  (static_cast<sal_uInt32>(bCheckable ? 1 : 0) << 9) |
291  (static_cast<sal_uInt32>(bChecked ? 1 : 0) << 8) |
292  static_cast<sal_uInt32>(0xFF & nNumVal);
293 }
294 
295 void OptionsUserData::SetNumericValue( sal_uInt8 nNumVal )
296 {
297  if (HasNumericValue() && (GetNumericValue() != nNumVal))
298  {
299  nVal &= 0xffffff00;
300  nVal |= nNumVal;
301  nVal |= sal_uInt32(1) << 11; // mark as modified
302  }
303 }
304 
305 // ServiceInfo_Impl ----------------------------------------------------
306 
307 namespace {
308 
309 struct ServiceInfo_Impl
310 {
311  OUString sDisplayName;
312  OUString sSpellImplName;
313  OUString sHyphImplName;
314  OUString sThesImplName;
315  OUString sGrammarImplName;
316  uno::Reference< XSpellChecker > xSpell;
317  uno::Reference< XHyphenator > xHyph;
318  uno::Reference< XThesaurus > xThes;
319  uno::Reference< XProofreader > xGrammar;
320  bool bConfigured;
321 
322  ServiceInfo_Impl() : bConfigured(false) {}
323 };
324 
325 }
326 
327 typedef std::vector< ServiceInfo_Impl > ServiceInfoArr;
328 typedef std::map< LanguageType, Sequence< OUString > > LangImplNameTable;
329 
330 
331 // SvxLinguData_Impl ----------------------------------------------------
332 
334 {
335  //contains services and implementation names sorted by implementation names
336  ServiceInfoArr aDisplayServiceArr;
337  sal_uInt32 nDisplayServices;
338 
339  Sequence< Locale > aAllServiceLocales;
340  LangImplNameTable aCfgSpellTable;
341  LangImplNameTable aCfgHyphTable;
342  LangImplNameTable aCfgThesTable;
343  LangImplNameTable aCfgGrammarTable;
344  uno::Reference< XLinguServiceManager2 > xLinguSrvcMgr;
345 
346 
347  static bool AddRemove( Sequence< OUString > &rConfigured,
348  const OUString &rImplName, bool bAdd );
349 
350 public:
352 
353  uno::Reference<XLinguServiceManager2> & GetManager() { return xLinguSrvcMgr; }
354 
355  void SetChecked( const Sequence< OUString > &rConfiguredServices );
356  void Reconfigure( std::u16string_view rDisplayName, bool bEnable );
357 
358  const Sequence<Locale> & GetAllSupportedLocales() const { return aAllServiceLocales; }
359 
360  LangImplNameTable & GetSpellTable() { return aCfgSpellTable; }
361  LangImplNameTable & GetHyphTable() { return aCfgHyphTable; }
362  LangImplNameTable & GetThesTable() { return aCfgThesTable; }
363  LangImplNameTable & GetGrammarTable() { return aCfgGrammarTable; }
364 
365  ServiceInfoArr & GetDisplayServiceArray() { return aDisplayServiceArr; }
366 
367  const sal_uInt32 & GetDisplayServiceCount() const { return nDisplayServices; }
368  void SetDisplayServiceCount( sal_uInt32 nVal ) { nDisplayServices = nVal; }
369 
370  // returns the list of service implementation names for the specified
371  // language and service (TYPE_SPELL, TYPE_HYPH, TYPE_THES) sorted in
372  // the proper order for the SvxEditModulesDlg (the ones from the
373  // configuration (keeping that order!) first and then the other ones.
374  // I.e. the ones available but not configured in arbitrary order).
375  // They available ones may contain names that do not(!) support that
376  // language.
377  Sequence< OUString > GetSortedImplNames( LanguageType nLang, sal_uInt8 nType );
378 
379  ServiceInfo_Impl * GetInfoByImplName( std::u16string_view rSvcImplName );
380 };
381 
382 
383 static sal_Int32 lcl_SeqGetIndex( const Sequence< OUString > &rSeq, std::u16string_view rTxt )
384 {
385  sal_Int32 nRes = -1;
386  sal_Int32 nLen = rSeq.getLength();
387  const OUString *pString = rSeq.getConstArray();
388  for (sal_Int32 i = 0; i < nLen && nRes == -1; ++i)
389  {
390  if (pString[i] == rTxt)
391  nRes = i;
392  }
393  return nRes;
394 }
395 
396 
398 {
399  LangImplNameTable *pTable = nullptr;
400  switch (nType)
401  {
402  case TYPE_SPELL : pTable = &aCfgSpellTable; break;
403  case TYPE_HYPH : pTable = &aCfgHyphTable; break;
404  case TYPE_THES : pTable = &aCfgThesTable; break;
405  case TYPE_GRAMMAR : pTable = &aCfgGrammarTable; break;
406  }
408  if (!pTable)
409  {
410  SAL_WARN( "cui.options", "unknown linguistic type" );
411  return aRes;
412  }
413  if (pTable->count( nLang ))
414  aRes = (*pTable)[ nLang ]; // add configured services
415  sal_Int32 nIdx = aRes.getLength();
416  DBG_ASSERT( static_cast<sal_Int32>(nDisplayServices) >= nIdx, "size mismatch" );
417  aRes.realloc( nDisplayServices );
418  OUString *pRes = aRes.getArray();
419 
420  // add not configured services
421  for (sal_Int32 i = 0; i < static_cast<sal_Int32>(nDisplayServices); ++i)
422  {
423  const ServiceInfo_Impl &rInfo = aDisplayServiceArr[ i ];
424  OUString aImplName;
425  switch (nType)
426  {
427  case TYPE_SPELL : aImplName = rInfo.sSpellImplName; break;
428  case TYPE_HYPH : aImplName = rInfo.sHyphImplName; break;
429  case TYPE_THES : aImplName = rInfo.sThesImplName; break;
430  case TYPE_GRAMMAR : aImplName = rInfo.sGrammarImplName; break;
431  }
432 
433  if (!aImplName.isEmpty() && (lcl_SeqGetIndex( aRes, aImplName) == -1)) // name not yet added
434  {
435  DBG_ASSERT( nIdx < aRes.getLength(), "index out of range" );
436  if (nIdx < aRes.getLength())
437  pRes[ nIdx++ ] = aImplName;
438  }
439  }
440  // don't forget to put aRes back to its actual size just in case you allocated too much
441  // since all of the names may have already been added
442  // otherwise you get duplicate entries in the edit dialog
443  aRes.realloc( nIdx );
444  return aRes;
445 }
446 
447 
448 ServiceInfo_Impl * SvxLinguData_Impl::GetInfoByImplName( std::u16string_view rSvcImplName )
449 {
450  for (sal_uInt32 i = 0; i < nDisplayServices; ++i)
451  {
452  ServiceInfo_Impl &rTmp = aDisplayServiceArr[ i ];
453  if (rTmp.sSpellImplName == rSvcImplName ||
454  rTmp.sHyphImplName == rSvcImplName ||
455  rTmp.sThesImplName == rSvcImplName ||
456  rTmp.sGrammarImplName == rSvcImplName)
457  {
458  return &rTmp;
459  }
460  }
461  return nullptr;
462 }
463 
464 
465 static void lcl_MergeLocales(Sequence< Locale >& aAllLocales, const Sequence< Locale >& rAdd)
466 {
467  Sequence<Locale> aLocToAdd(rAdd.getLength());
468  Locale* pLocToAdd = aLocToAdd.getArray();
469  sal_Int32 nFound = 0;
470  for(const Locale& i : rAdd)
471  {
472  bool bFound = false;
473  for(const Locale& j : std::as_const(aAllLocales))
474  {
475  if (i.Language == j.Language &&
476  i.Country == j.Country &&
477  i.Variant == j.Variant)
478  {
479  bFound = true;
480  break;
481  }
482  }
483  if(!bFound)
484  {
485  pLocToAdd[nFound++] = i;
486  }
487  }
488  sal_Int32 nLength = aAllLocales.getLength();
489  aAllLocales.realloc( nLength + nFound);
490  Locale* pAllLocales2 = aAllLocales.getArray();
491  for(sal_Int32 i = 0; i < nFound; i++)
492  pAllLocales2[nLength++] = pLocToAdd[i];
493 }
494 
496  SvxLinguData_Impl &rData,
497  const ServiceInfo_Impl &rToAdd )
498 {
499  sal_uInt32 nCnt = 0;
500 
501  ServiceInfoArr &rSvcInfoArr = rData.GetDisplayServiceArray();
502  sal_uInt32 nEntries = rData.GetDisplayServiceCount();
503 
504  for (sal_uInt32 i = 0; i < nEntries; ++i)
505  {
506  ServiceInfo_Impl& rEntry = rSvcInfoArr[i];
507  if (rEntry.sDisplayName == rToAdd.sDisplayName)
508  {
509  if(rToAdd.xSpell.is())
510  {
511  DBG_ASSERT( !rEntry.xSpell.is() &&
512  rEntry.sSpellImplName.isEmpty(),
513  "merge conflict" );
514  rEntry.sSpellImplName = rToAdd.sSpellImplName;
515  rEntry.xSpell = rToAdd.xSpell;
516  }
517  if(rToAdd.xGrammar.is())
518  {
519  DBG_ASSERT( !rEntry.xGrammar.is() &&
520  rEntry.sGrammarImplName.isEmpty(),
521  "merge conflict" );
522  rEntry.sGrammarImplName = rToAdd.sGrammarImplName;
523  rEntry.xGrammar = rToAdd.xGrammar;
524  }
525  if(rToAdd.xHyph.is())
526  {
527  DBG_ASSERT( !rEntry.xHyph.is() &&
528  rEntry.sHyphImplName.isEmpty(),
529  "merge conflict" );
530  rEntry.sHyphImplName = rToAdd.sHyphImplName;
531  rEntry.xHyph = rToAdd.xHyph;
532  }
533  if(rToAdd.xThes.is())
534  {
535  DBG_ASSERT( !rEntry.xThes.is() &&
536  rEntry.sThesImplName.isEmpty(),
537  "merge conflict" );
538  rEntry.sThesImplName = rToAdd.sThesImplName;
539  rEntry.xThes = rToAdd.xThes;
540  }
541  return ;
542  }
543  ++nCnt;
544  }
545  rData.GetDisplayServiceArray().push_back( rToAdd );
546  rData.SetDisplayServiceCount( nCnt + 1 );
547 }
548 
550  nDisplayServices (0)
551 {
552  uno::Reference< XComponentContext > xContext = ::comphelper::getProcessComponentContext();
553  xLinguSrvcMgr = LinguServiceManager::create(xContext);
554 
555  const Locale& rCurrentLocale = Application::GetSettings().GetLanguageTag().getLocale();
556  Sequence<Any> aArgs(2);//second arguments has to be empty!
557  aArgs.getArray()[0] <<= LinguMgr::GetLinguPropertySet();
558 
559  //read spell checker
560  const Sequence< OUString > aSpellNames = xLinguSrvcMgr->getAvailableServices(
561  cSpell, Locale() );
562 
563  for(const OUString& spellName : aSpellNames)
564  {
565  ServiceInfo_Impl aInfo;
566  aInfo.sSpellImplName = spellName;
567  aInfo.xSpell.set(
568  xContext->getServiceManager()->createInstanceWithArgumentsAndContext(aInfo.sSpellImplName, aArgs, xContext), UNO_QUERY);
569 
570  uno::Reference<XServiceDisplayName> xDispName(aInfo.xSpell, UNO_QUERY);
571  if(xDispName.is())
572  aInfo.sDisplayName = xDispName->getServiceDisplayName( rCurrentLocale );
573 
574  const Sequence< Locale > aLocales( aInfo.xSpell->getLocales() );
576  if (aLocales.hasElements())
577  {
579  lcl_MergeDisplayArray( *this, aInfo );
580  }
581  }
582 
583  //read grammar checker
584  const Sequence< OUString > aGrammarNames = xLinguSrvcMgr->getAvailableServices(
585  cGrammar, Locale() );
586  for(const OUString& grammarName : aGrammarNames)
587  {
588  ServiceInfo_Impl aInfo;
589  aInfo.sGrammarImplName = grammarName;
590  aInfo.xGrammar.set(
591  xContext->getServiceManager()->createInstanceWithArgumentsAndContext(aInfo.sGrammarImplName, aArgs, xContext), UNO_QUERY);
592 
593  uno::Reference<XServiceDisplayName> xDispName(aInfo.xGrammar, UNO_QUERY);
594  if(xDispName.is())
595  aInfo.sDisplayName = xDispName->getServiceDisplayName( rCurrentLocale );
596 
597  const Sequence< Locale > aLocales( aInfo.xGrammar->getLocales() );
599  if (aLocales.hasElements())
600  {
602  lcl_MergeDisplayArray( *this, aInfo );
603  }
604  }
605 
606  //read hyphenator
607  const Sequence< OUString > aHyphNames = xLinguSrvcMgr->getAvailableServices(
608  cHyph, Locale() );
609  for(const OUString& hyphName : aHyphNames)
610  {
611  ServiceInfo_Impl aInfo;
612  aInfo.sHyphImplName = hyphName;
613  aInfo.xHyph.set( xContext->getServiceManager()->createInstanceWithArgumentsAndContext(aInfo.sHyphImplName, aArgs, xContext), UNO_QUERY);
614 
615  uno::Reference<XServiceDisplayName> xDispName(aInfo.xHyph, UNO_QUERY);
616  if(xDispName.is())
617  aInfo.sDisplayName = xDispName->getServiceDisplayName( rCurrentLocale );
618 
619  const Sequence< Locale > aLocales( aInfo.xHyph->getLocales() );
621  if (aLocales.hasElements())
622  {
624  lcl_MergeDisplayArray( *this, aInfo );
625  }
626  }
627 
628  //read thesauri
629  const Sequence< OUString > aThesNames = xLinguSrvcMgr->getAvailableServices(
630  cThes, Locale() );
631  for(const OUString& thesName : aThesNames)
632  {
633  ServiceInfo_Impl aInfo;
634  aInfo.sThesImplName = thesName;
635  aInfo.xThes.set( xContext->getServiceManager()->createInstanceWithArgumentsAndContext(aInfo.sThesImplName, aArgs, xContext), UNO_QUERY);
636 
637  uno::Reference<XServiceDisplayName> xDispName(aInfo.xThes, UNO_QUERY);
638  if(xDispName.is())
639  aInfo.sDisplayName = xDispName->getServiceDisplayName( rCurrentLocale );
640 
641  const Sequence< Locale > aLocales( aInfo.xThes->getLocales() );
643  if (aLocales.hasElements())
644  {
646  lcl_MergeDisplayArray( *this, aInfo );
647  }
648  }
649 
650  Sequence< OUString > aCfgSvcs;
651  for(auto const & locale : std::as_const(aAllServiceLocales))
652  {
654 
655  aCfgSvcs = xLinguSrvcMgr->getConfiguredServices(cSpell, locale);
656  SetChecked( aCfgSvcs );
657  if (aCfgSvcs.hasElements())
658  aCfgSpellTable[ nLang ] = aCfgSvcs;
659 
660  aCfgSvcs = xLinguSrvcMgr->getConfiguredServices(cGrammar, locale);
661  SetChecked( aCfgSvcs );
662  if (aCfgSvcs.hasElements())
663  aCfgGrammarTable[ nLang ] = aCfgSvcs;
664 
665  aCfgSvcs = xLinguSrvcMgr->getConfiguredServices(cHyph, locale);
666  SetChecked( aCfgSvcs );
667  if (aCfgSvcs.hasElements())
668  aCfgHyphTable[ nLang ] = aCfgSvcs;
669 
670  aCfgSvcs = xLinguSrvcMgr->getConfiguredServices(cThes, locale);
671  SetChecked( aCfgSvcs );
672  if (aCfgSvcs.hasElements())
673  aCfgThesTable[ nLang ] = aCfgSvcs;
674  }
675 }
676 
677 void SvxLinguData_Impl::SetChecked(const Sequence<OUString>& rConfiguredServices)
678 {
679  for(OUString const & configService : rConfiguredServices)
680  {
681  for (sal_uInt32 i = 0; i < nDisplayServices; ++i)
682  {
683  ServiceInfo_Impl& rEntry = aDisplayServiceArr[i];
684  if (!rEntry.bConfigured)
685  {
686  const OUString &rSrvcImplName = configService;
687  if (!rSrvcImplName.isEmpty() &&
688  (rEntry.sSpellImplName == rSrvcImplName ||
689  rEntry.sGrammarImplName == rSrvcImplName ||
690  rEntry.sHyphImplName == rSrvcImplName ||
691  rEntry.sThesImplName == rSrvcImplName))
692  {
693  rEntry.bConfigured = true;
694  break;
695  }
696  }
697  }
698  }
699 }
700 
702  Sequence< OUString > &rConfigured,
703  const OUString &rImplName, bool bAdd )
704 {
705  bool bRet = false; // modified?
706 
707  sal_Int32 nEntries = rConfigured.getLength();
708  sal_Int32 nPos = lcl_SeqGetEntryPos(rConfigured, rImplName);
709  if (bAdd && nPos < 0) // add new entry
710  {
711  rConfigured.realloc( ++nEntries );
712  OUString *pConfigured = rConfigured.getArray();
713  pConfigured[nEntries - 1] = rImplName;
714  bRet = true;
715  }
716  else if (!bAdd && nPos >= 0) // remove existing entry
717  {
718  OUString *pConfigured = rConfigured.getArray();
719  for (sal_Int32 i = nPos; i < nEntries - 1; ++i)
720  pConfigured[i] = pConfigured[i + 1];
721  rConfigured.realloc(--nEntries);
722  bRet = true;
723  }
724 
725  return bRet;
726 }
727 
728 
729 void SvxLinguData_Impl::Reconfigure( std::u16string_view rDisplayName, bool bEnable )
730 {
731  DBG_ASSERT( !rDisplayName.empty(), "empty DisplayName" );
732 
733  ServiceInfo_Impl *pInfo = nullptr;
734  for (sal_uInt32 i = 0; i < nDisplayServices; ++i)
735  {
736  ServiceInfo_Impl& rTmp = aDisplayServiceArr[i];
737  if (rTmp.sDisplayName == rDisplayName)
738  {
739  pInfo = &rTmp;
740  break;
741  }
742  }
743  DBG_ASSERT( pInfo, "DisplayName entry not found" );
744  if (!pInfo)
745  return;
746 
747  pInfo->bConfigured = bEnable;
748 
749  Sequence< Locale > aLocales;
750  const Locale *pLocale = nullptr;
751  sal_Int32 nLocales = 0;
752  sal_Int32 i;
753 
754  // update configured spellchecker entries
755  if (pInfo->xSpell.is())
756  {
757  aLocales = pInfo->xSpell->getLocales();
758  pLocale = aLocales.getConstArray();
759  nLocales = aLocales.getLength();
760  for (i = 0; i < nLocales; ++i)
761  {
762  LanguageType nLang = LanguageTag::convertToLanguageType( pLocale[i] );
763  if (!aCfgSpellTable.count( nLang ) && bEnable)
765  if (aCfgSpellTable.count( nLang ))
766  AddRemove( aCfgSpellTable[ nLang ], pInfo->sSpellImplName, bEnable );
767  }
768  }
769 
770  // update configured grammar checker entries
771  if (pInfo->xGrammar.is())
772  {
773  aLocales = pInfo->xGrammar->getLocales();
774  pLocale = aLocales.getConstArray();
775  nLocales = aLocales.getLength();
776  for (i = 0; i < nLocales; ++i)
777  {
778  LanguageType nLang = LanguageTag::convertToLanguageType( pLocale[i] );
779  if (!aCfgGrammarTable.count( nLang ) && bEnable)
781  if (aCfgGrammarTable.count( nLang ))
782  AddRemove( aCfgGrammarTable[ nLang ], pInfo->sGrammarImplName, bEnable );
783  }
784  }
785 
786  // update configured hyphenator entries
787  if (pInfo->xHyph.is())
788  {
789  aLocales = pInfo->xHyph->getLocales();
790  pLocale = aLocales.getConstArray();
791  nLocales = aLocales.getLength();
792  for (i = 0; i < nLocales; ++i)
793  {
794  LanguageType nLang = LanguageTag::convertToLanguageType( pLocale[i] );
795  if (!aCfgHyphTable.count( nLang ) && bEnable)
796  aCfgHyphTable[ nLang ] = Sequence< OUString >();
797  if (aCfgHyphTable.count( nLang ))
798  AddRemove( aCfgHyphTable[ nLang ], pInfo->sHyphImplName, bEnable );
799  }
800  }
801 
802  // update configured spellchecker entries
803  if (!pInfo->xThes.is())
804  return;
805 
806  aLocales = pInfo->xThes->getLocales();
807  pLocale = aLocales.getConstArray();
808  nLocales = aLocales.getLength();
809  for (i = 0; i < nLocales; ++i)
810  {
811  LanguageType nLang = LanguageTag::convertToLanguageType( pLocale[i] );
812  if (!aCfgThesTable.count( nLang ) && bEnable)
813  aCfgThesTable[ nLang ] = Sequence< OUString >();
814  if (aCfgThesTable.count( nLang ))
815  AddRemove( aCfgThesTable[ nLang ], pInfo->sThesImplName, bEnable );
816  }
817 }
818 
819 
820 // class SvxLinguTabPage -------------------------------------------------
821 
823  : SfxTabPage(pPage, pController, "cui/ui/optlingupage.ui", "OptLinguPage", &rSet)
824  , sCapitalWords (CuiResId(RID_CUISTR_CAPITAL_WORDS))
825  , sWordsWithDigits(CuiResId(RID_CUISTR_WORDS_WITH_DIGITS))
826  , sSpellSpecial (CuiResId(RID_CUISTR_SPELL_SPECIAL))
827  , sSpellAuto (CuiResId(RID_CUISTR_SPELL_AUTO))
828  , sGrammarAuto (CuiResId(RID_CUISTR_GRAMMAR_AUTO))
829  , sNumMinWordlen (CuiResId(RID_CUISTR_NUM_MIN_WORDLEN))
830  , sNumPreBreak (CuiResId(RID_CUISTR_NUM_PRE_BREAK))
831  , sNumPostBreak (CuiResId(RID_CUISTR_NUM_POST_BREAK))
832  , sHyphAuto (CuiResId(RID_CUISTR_HYPH_AUTO))
833  , sHyphSpecial (CuiResId(RID_CUISTR_HYPH_SPECIAL))
834  , nUPN_HYPH_MIN_WORD_LENGTH(-1)
835  , nUPN_HYPH_MIN_LEADING(-1)
836  , nUPN_HYPH_MIN_TRAILING(-1)
837  , m_nDlbClickEventId(nullptr)
838  , m_xLinguModulesFT(m_xBuilder->weld_label("lingumodulesft"))
839  , m_xLinguModulesCLB(m_xBuilder->weld_tree_view("lingumodules"))
840  , m_xLinguModulesEditPB(m_xBuilder->weld_button("lingumodulesedit"))
841  , m_xLinguDicsFT(m_xBuilder->weld_label("lingudictsft"))
842  , m_xLinguDicsCLB(m_xBuilder->weld_tree_view("lingudicts"))
843  , m_xLinguDicsNewPB(m_xBuilder->weld_button("lingudictsnew"))
844  , m_xLinguDicsEditPB(m_xBuilder->weld_button("lingudictsedit"))
845  , m_xLinguDicsDelPB(m_xBuilder->weld_button("lingudictsdelete"))
846  , m_xLinguOptionsCLB(m_xBuilder->weld_tree_view("linguoptions"))
847  , m_xLinguOptionsEditPB(m_xBuilder->weld_button("linguoptionsedit"))
848  , m_xMoreDictsLink(m_xBuilder->weld_link_button("moredictslink"))
849 {
850  m_xLinguModulesCLB->enable_toggle_buttons(weld::ColumnToggleType::Check);
851  m_xLinguDicsCLB->enable_toggle_buttons(weld::ColumnToggleType::Check);
852  m_xLinguOptionsCLB->enable_toggle_buttons(weld::ColumnToggleType::Check);
853 
854  m_xLinguModulesCLB->connect_changed( LINK( this, SvxLinguTabPage, SelectHdl_Impl ));
855  m_xLinguModulesCLB->connect_row_activated(LINK(this, SvxLinguTabPage, BoxDoubleClickHdl_Impl));
856  m_xLinguModulesCLB->connect_toggled(LINK(this, SvxLinguTabPage, ModulesBoxCheckButtonHdl_Impl));
857 
858  m_xLinguModulesEditPB->connect_clicked( LINK( this, SvxLinguTabPage, ClickHdl_Impl ));
859  m_xLinguOptionsEditPB->connect_clicked( LINK( this, SvxLinguTabPage, ClickHdl_Impl ));
860 
861  m_xLinguDicsCLB->connect_changed( LINK( this, SvxLinguTabPage, SelectHdl_Impl ));
862  m_xLinguDicsCLB->connect_toggled(LINK(this, SvxLinguTabPage, DicsBoxCheckButtonHdl_Impl));
863 
864  m_xLinguDicsNewPB->connect_clicked( LINK( this, SvxLinguTabPage, ClickHdl_Impl ));
865  m_xLinguDicsEditPB->connect_clicked( LINK( this, SvxLinguTabPage, ClickHdl_Impl ));
866  m_xLinguDicsDelPB->connect_clicked( LINK( this, SvxLinguTabPage, ClickHdl_Impl ));
867 
868  m_xLinguOptionsCLB->connect_changed( LINK( this, SvxLinguTabPage, SelectHdl_Impl ));
869  m_xLinguOptionsCLB->connect_row_activated(LINK(this, SvxLinguTabPage, BoxDoubleClickHdl_Impl));
870 
871  m_xMoreDictsLink->connect_activate_link(LINK(this, SvxLinguTabPage, OnLinkClick));
872  if (officecfg::Office::Security::Hyperlinks::Open::get() == SvtExtendedSecurityOptions::OPEN_NEVER)
873  m_xMoreDictsLink->hide();
874 
877  if (xDicList.is())
878  {
879  // keep references to all **currently** available dictionaries,
880  // since the diclist may get changed meanwhile (e.g. through the API).
881  // We want the dialog to operate on the same set of dictionaries it
882  // was started with.
883  // Also we have to take care to not lose the last reference when
884  // someone else removes a dictionary from the list.
885  // removed dics will be replaced by NULL new entries be added to the end
886  // Thus we may use indices as consistent references.
887  aDics = xDicList->getDictionaries();
888 
890  }
891  else
892  {
893  m_xLinguDicsFT->set_sensitive(false);
894  m_xLinguDicsCLB->set_sensitive(false);
895  m_xLinguDicsNewPB->set_sensitive(false);
896  m_xLinguDicsEditPB->set_sensitive(false);
897  m_xLinguDicsDelPB->set_sensitive(false);
898  }
899 }
900 
902 {
903  if (m_nDlbClickEventId)
904  {
906  m_nDlbClickEventId = nullptr;
907  }
908  pLinguData.reset();
909 }
910 
911 std::unique_ptr<SfxTabPage> SvxLinguTabPage::Create( weld::Container* pPage, weld::DialogController* pController,
912  const SfxItemSet* rAttrSet )
913 {
914  return std::make_unique<SvxLinguTabPage>( pPage, pController, *rAttrSet );
915 }
916 
918 {
919  bool bModified = true; // !!!!
920 
921  // if not HideGroups was called with GROUP_MODULES...
922  if (m_xLinguModulesCLB->get_visible())
923  {
924  DBG_ASSERT( pLinguData, "pLinguData not yet initialized" );
925  if (!pLinguData)
926  pLinguData.reset( new SvxLinguData_Impl );
927 
928  // update spellchecker configuration entries
929  const LangImplNameTable *pTable = &pLinguData->GetSpellTable();
930  for (auto const& elem : *pTable)
931  {
932  LanguageType nLang = elem.first;
933  const Sequence< OUString > aImplNames(elem.second);
934  uno::Reference< XLinguServiceManager2 > xMgr( pLinguData->GetManager() );
935  Locale aLocale( LanguageTag::convertToLocale(nLang) );
936  if (xMgr.is())
937  xMgr->setConfiguredServices( cSpell, aLocale, aImplNames );
938  }
939 
940  // update grammar checker configuration entries
941  pTable = &pLinguData->GetGrammarTable();
942  for (auto const& elem : *pTable)
943  {
944  LanguageType nLang = elem.first;
945  const Sequence< OUString > aImplNames(elem.second);
946  uno::Reference< XLinguServiceManager2 > xMgr( pLinguData->GetManager() );
947  Locale aLocale( LanguageTag::convertToLocale(nLang) );
948  if (xMgr.is())
949  xMgr->setConfiguredServices( cGrammar, aLocale, aImplNames );
950  }
951 
952  // update hyphenator configuration entries
953  pTable = &pLinguData->GetHyphTable();
954  for (auto const& elem : *pTable)
955  {
956  LanguageType nLang = elem.first;
957  const Sequence< OUString > aImplNames(elem.second);
958  uno::Reference< XLinguServiceManager2 > xMgr( pLinguData->GetManager() );
959  Locale aLocale( LanguageTag::convertToLocale(nLang) );
960  if (xMgr.is())
961  xMgr->setConfiguredServices( cHyph, aLocale, aImplNames );
962  }
963 
964  // update thesaurus configuration entries
965  pTable = &pLinguData->GetThesTable();
966  for (auto const& elem : *pTable)
967  {
968  LanguageType nLang = elem.first;
969  const Sequence< OUString > aImplNames(elem.second);
970  uno::Reference< XLinguServiceManager2 > xMgr( pLinguData->GetManager() );
971  Locale aLocale( LanguageTag::convertToLocale(nLang) );
972  if (xMgr.is())
973  xMgr->setConfiguredServices( cThes, aLocale, aImplNames );
974  }
975  }
976 
977 
978  // activate dictionaries according to checkbox state
979 
980  Sequence< OUString > aActiveDics;
981  sal_Int32 nActiveDics = 0;
982  int nEntries = m_xLinguDicsCLB->n_children();
983  for (int i = 0; i < nEntries; ++i)
984  {
985  sal_Int32 nDics = aDics.getLength();
986 
987  aActiveDics.realloc( nDics );
988  OUString *pActiveDic = aActiveDics.getArray();
989 
990  DicUserData aData(m_xLinguDicsCLB->get_id(i).toUInt32());
991  if (aData.GetEntryId() < nDics)
992  {
993  bool bChecked = m_xLinguDicsCLB->get_toggle(i) == TRISTATE_TRUE;
994  uno::Reference< XDictionary > xDic( aDics.getConstArray()[ i ] );
995  if (xDic.is())
996  {
997  if (LinguMgr::GetIgnoreAllList() == xDic)
998  bChecked = true;
999  xDic->setActive( bChecked );
1000 
1001  if (bChecked)
1002  {
1003  OUString aDicName( xDic->getName() );
1004  pActiveDic[ nActiveDics++ ] = aDicName;
1005  }
1006  }
1007  }
1008  }
1009 
1010  aActiveDics.realloc( nActiveDics );
1011  Any aTmp;
1012  aTmp <<= aActiveDics;
1013  SvtLinguConfig aLngCfg;
1014  aLngCfg.SetProperty( UPH_ACTIVE_DICTIONARIES, aTmp );
1015 
1016 
1017  nEntries = m_xLinguOptionsCLB->n_children();
1018  for (int j = 0; j < nEntries; ++j)
1019  {
1020  OptionsUserData aData(m_xLinguOptionsCLB->get_id(j).toUInt32());
1021  OUString aPropName( lcl_GetPropertyName( static_cast<EID_OPTIONS>(aData.GetEntryId()) ) );
1022 
1023  Any aAny;
1024  if (aData.IsCheckable())
1025  {
1026  bool bChecked = m_xLinguOptionsCLB->get_toggle(j) == TRISTATE_TRUE;
1027  aAny <<= bChecked;
1028  }
1029  else if (aData.HasNumericValue())
1030  {
1031  sal_Int16 nVal = aData.GetNumericValue();
1032  aAny <<= nVal;
1033  }
1034 
1035  if (xProp.is())
1036  xProp->setPropertyValue( aPropName, aAny );
1037  aLngCfg.SetProperty( aPropName, aAny );
1038  }
1039 
1040  OptionsUserData aPreBreakData(m_xLinguOptionsCLB->get_id(EID_NUM_PRE_BREAK).toUInt32());
1041  OptionsUserData aPostBreakData(m_xLinguOptionsCLB->get_id(EID_NUM_POST_BREAK).toUInt32());
1042  if ( aPreBreakData.IsModified() || aPostBreakData.IsModified() )
1043  {
1044  SfxHyphenRegionItem aHyp( GetWhich( SID_ATTR_HYPHENREGION ) );
1045  aHyp.GetMinLead() = static_cast<sal_uInt8>(aPreBreakData.GetNumericValue());
1046  aHyp.GetMinTrail() = static_cast<sal_uInt8>(aPostBreakData.GetNumericValue());
1047  rCoreSet->Put( aHyp );
1048  }
1049 
1050  // automatic spell checking
1051  bool bNewAutoCheck = m_xLinguOptionsCLB->get_toggle(EID_SPELL_AUTO) == TRISTATE_TRUE;
1052  const SfxPoolItem* pOld = GetOldItem( *rCoreSet, SID_AUTOSPELL_CHECK );
1053  if ( !pOld || static_cast<const SfxBoolItem*>(pOld)->GetValue() != bNewAutoCheck )
1054  {
1055  rCoreSet->Put( SfxBoolItem( GetWhich( SID_AUTOSPELL_CHECK ),
1056  bNewAutoCheck ) );
1057  bModified = true;
1058  }
1059 
1060  return bModified;
1061 }
1062 
1063 sal_uInt32 SvxLinguTabPage::GetDicUserData( const uno::Reference< XDictionary > &rxDic, sal_uInt16 nIdx )
1064 {
1065  sal_uInt32 nRes = 0;
1066  DBG_ASSERT( rxDic.is(), "dictionary not supplied" );
1067  if (rxDic.is())
1068  {
1069  uno::Reference< frame::XStorable > xStor( rxDic, UNO_QUERY );
1070 
1071  bool bChecked = rxDic->isActive();
1072  bool bEditable = !xStor.is() || !xStor->isReadonly();
1073  bool bDeletable = bEditable;
1074 
1075  nRes = DicUserData( nIdx,
1076  bChecked, bEditable, bDeletable ).GetUserData();
1077  }
1078  return nRes;
1079 }
1080 
1081 
1083  const uno::Reference< XDictionary > &rxDic,
1084  sal_uInt16 nIdx )
1085 {
1086  m_xLinguDicsCLB->freeze();
1087 
1088  OUString aTxt( ::GetDicInfoStr( rxDic->getName(),
1089  LanguageTag( rxDic->getLocale() ).getLanguageType(),
1090  DictionaryType_NEGATIVE == rxDic->getDictionaryType() ) );
1091  m_xLinguDicsCLB->append(); // append at end
1092  int nEntry = m_xLinguDicsCLB->n_children() - 1;
1093  DicUserData aData( GetDicUserData( rxDic, nIdx ) );
1094  m_xLinguDicsCLB->set_id(nEntry, OUString::number(aData.GetUserData()));
1095  m_xLinguDicsCLB->set_toggle(nEntry, aData.IsChecked() ? TRISTATE_TRUE : TRISTATE_FALSE);
1096  m_xLinguDicsCLB->set_text(nEntry, aTxt, 0); // append at end
1097 
1098  m_xLinguDicsCLB->thaw();
1099 }
1100 
1102 {
1103  m_xLinguDicsCLB->freeze();
1104  m_xLinguDicsCLB->clear();
1105 
1106  sal_Int32 nDics = aDics.getLength();
1107  const uno::Reference< XDictionary > *pDic = aDics.getConstArray();
1108  for (sal_Int32 i = 0; i < nDics; ++i)
1109  {
1110  const uno::Reference< XDictionary > &rDic = pDic[i];
1111  if (rDic.is())
1112  AddDicBoxEntry( rDic, static_cast<sal_uInt16>(i) );
1113  }
1114 
1115  m_xLinguDicsCLB->thaw();
1116  if (m_xLinguDicsCLB->n_children())
1117  {
1118  m_xLinguDicsCLB->select(0);
1119  SelectHdl_Impl(*m_xLinguDicsCLB);
1120  }
1121 }
1122 
1124 {
1125  if (!pLinguData)
1126  return;
1127 
1128  const ServiceInfoArr &rAllDispSrvcArr = pLinguData->GetDisplayServiceArray();
1129  const sal_uInt32 nDispSrvcCount = pLinguData->GetDisplayServiceCount();
1130 
1131  m_xLinguModulesCLB->clear();
1132 
1133  for (sal_uInt32 i = 0; i < nDispSrvcCount; ++i)
1134  {
1135  const ServiceInfo_Impl &rInfo = rAllDispSrvcArr[i];
1136  m_xLinguModulesCLB->append();
1137  m_xLinguModulesCLB->set_id(i, OUString::number(reinterpret_cast<sal_Int64>(&rInfo)));
1138  m_xLinguModulesCLB->set_toggle(i, rInfo.bConfigured ? TRISTATE_TRUE : TRISTATE_FALSE);
1139  m_xLinguModulesCLB->set_text(i, rInfo.sDisplayName, 0);
1140  }
1141  if (nDispSrvcCount)
1142  {
1143  m_xLinguModulesCLB->select(0);
1144  SelectHdl_Impl(*m_xLinguModulesCLB);
1145  }
1146  m_xLinguModulesEditPB->set_sensitive( nDispSrvcCount > 0 );
1147 }
1148 
1150 {
1151  // if not HideGroups was called with GROUP_MODULES...
1152  if (m_xLinguModulesCLB->get_visible())
1153  {
1154  if (!pLinguData)
1155  pLinguData.reset( new SvxLinguData_Impl );
1157  }
1158 
1159 
1160  // get data from configuration
1161  SvtLinguConfig aLngCfg;
1162 
1163  m_xLinguOptionsCLB->freeze();
1164  m_xLinguOptionsCLB->clear();
1165 
1166  sal_Int16 nVal = 0;
1167  bool bVal = false;
1168  sal_uInt32 nUserData = 0;
1169 
1170  m_xLinguOptionsCLB->append();
1171  int nEntry = 0;
1172 
1173  aLngCfg.GetProperty( UPN_IS_SPELL_AUTO ) >>= bVal;
1174  const SfxPoolItem* pItem = GetItem( *rSet, SID_AUTOSPELL_CHECK );
1175  if (pItem)
1176  bVal = static_cast<const SfxBoolItem *>(pItem)->GetValue();
1177  nUserData = OptionsUserData( EID_SPELL_AUTO, false, 0, true, bVal).GetUserData();
1178  m_xLinguOptionsCLB->set_toggle(nEntry, bVal ? TRISTATE_TRUE : TRISTATE_FALSE);
1179  m_xLinguOptionsCLB->set_text(nEntry, sSpellAuto, 0);
1180  m_xLinguOptionsCLB->set_id(nEntry, OUString::number(nUserData));
1181 
1182  m_xLinguOptionsCLB->append();
1183  ++nEntry;
1184 
1185  aLngCfg.GetProperty( UPN_IS_GRAMMAR_AUTO ) >>= bVal;
1186  nUserData = OptionsUserData( EID_GRAMMAR_AUTO, false, 0, true, bVal).GetUserData();
1187  m_xLinguOptionsCLB->set_toggle(nEntry, bVal ? TRISTATE_TRUE : TRISTATE_FALSE);
1188  m_xLinguOptionsCLB->set_text(nEntry, sGrammarAuto, 0);
1189  m_xLinguOptionsCLB->set_id(nEntry, OUString::number(nUserData));
1190 
1191  m_xLinguOptionsCLB->append();
1192  ++nEntry;
1193 
1194  aLngCfg.GetProperty( UPN_IS_SPELL_UPPER_CASE ) >>= bVal;
1195  nUserData = OptionsUserData( EID_CAPITAL_WORDS, false, 0, true, bVal).GetUserData();
1196  m_xLinguOptionsCLB->set_toggle(nEntry, bVal ? TRISTATE_TRUE : TRISTATE_FALSE);
1197  m_xLinguOptionsCLB->set_text(nEntry, sCapitalWords, 0);
1198  m_xLinguOptionsCLB->set_id(nEntry, OUString::number(nUserData));
1199 
1200  m_xLinguOptionsCLB->append();
1201  ++nEntry;
1202 
1203  aLngCfg.GetProperty( UPN_IS_SPELL_WITH_DIGITS ) >>= bVal;
1204  nUserData = OptionsUserData( EID_WORDS_WITH_DIGITS, false, 0, true, bVal).GetUserData();
1205  m_xLinguOptionsCLB->set_toggle(nEntry, bVal ? TRISTATE_TRUE : TRISTATE_FALSE);
1206  m_xLinguOptionsCLB->set_text(nEntry, sWordsWithDigits, 0);
1207  m_xLinguOptionsCLB->set_id(nEntry, OUString::number(nUserData));
1208 
1209  m_xLinguOptionsCLB->append();
1210  ++nEntry;
1211 
1212  aLngCfg.GetProperty( UPN_IS_SPELL_SPECIAL ) >>= bVal;
1213  nUserData = OptionsUserData( EID_SPELL_SPECIAL, false, 0, true, bVal).GetUserData();
1214  m_xLinguOptionsCLB->set_toggle(nEntry, bVal ? TRISTATE_TRUE : TRISTATE_FALSE);
1215  m_xLinguOptionsCLB->set_text(nEntry, sSpellSpecial, 0);
1216  m_xLinguOptionsCLB->set_id(nEntry, OUString::number(nUserData));
1217 
1218  m_xLinguOptionsCLB->append();
1219  ++nEntry;
1220 
1221  aLngCfg.GetProperty( UPN_HYPH_MIN_WORD_LENGTH ) >>= nVal;
1222  nUserData = OptionsUserData( EID_NUM_MIN_WORDLEN, true, static_cast<sal_uInt16>(nVal), false, false).GetUserData();
1223  m_xLinguOptionsCLB->set_text(nEntry, sNumMinWordlen + " " + OUString::number(nVal), 0);
1224  m_xLinguOptionsCLB->set_id(nEntry, OUString::number(nUserData));
1225  nUPN_HYPH_MIN_WORD_LENGTH = nEntry;
1226 
1227  const SfxHyphenRegionItem *pHyp = nullptr;
1228  sal_uInt16 nWhich = GetWhich( SID_ATTR_HYPHENREGION );
1229  if ( rSet->GetItemState( nWhich, false ) == SfxItemState::SET )
1230  pHyp = &static_cast<const SfxHyphenRegionItem &>( rSet->Get( nWhich ) );
1231 
1232  m_xLinguOptionsCLB->append();
1233  ++nEntry;
1234 
1235  aLngCfg.GetProperty( UPN_HYPH_MIN_LEADING ) >>= nVal;
1236  if (pHyp)
1237  nVal = static_cast<sal_Int16>(pHyp->GetMinLead());
1238  nUserData = OptionsUserData( EID_NUM_PRE_BREAK, true, static_cast<sal_uInt16>(nVal), false, false).GetUserData();
1239  m_xLinguOptionsCLB->set_text(nEntry, sNumPreBreak + " " + OUString::number(nVal), 0);
1240  m_xLinguOptionsCLB->set_id(nEntry, OUString::number(nUserData));
1241  nUPN_HYPH_MIN_LEADING = nEntry;
1242 
1243  m_xLinguOptionsCLB->append();
1244  ++nEntry;
1245 
1246  aLngCfg.GetProperty( UPN_HYPH_MIN_TRAILING ) >>= nVal;
1247  if (pHyp)
1248  nVal = static_cast<sal_Int16>(pHyp->GetMinTrail());
1249  nUserData = OptionsUserData( EID_NUM_POST_BREAK, true, static_cast<sal_uInt16>(nVal), false, false).GetUserData();
1250  m_xLinguOptionsCLB->set_text(nEntry, sNumPostBreak + " " + OUString::number(nVal), 0);
1251  m_xLinguOptionsCLB->set_id(nEntry, OUString::number(nUserData));
1252  nUPN_HYPH_MIN_TRAILING = nEntry;
1253 
1254  m_xLinguOptionsCLB->append();
1255  ++nEntry;
1256 
1257  aLngCfg.GetProperty( UPN_IS_HYPH_AUTO ) >>= bVal;
1258  nUserData = OptionsUserData( EID_HYPH_AUTO, false, 0, true, bVal).GetUserData();
1259  m_xLinguOptionsCLB->set_toggle(nEntry, bVal ? TRISTATE_TRUE : TRISTATE_FALSE);
1260  m_xLinguOptionsCLB->set_text(nEntry, sHyphAuto, 0);
1261  m_xLinguOptionsCLB->set_id(nEntry, OUString::number(nUserData));
1262 
1263  m_xLinguOptionsCLB->append();
1264  ++nEntry;
1265 
1266  aLngCfg.GetProperty( UPN_IS_HYPH_SPECIAL ) >>= bVal;
1267  nUserData = OptionsUserData( EID_HYPH_SPECIAL, false, 0, true, bVal).GetUserData();
1268  m_xLinguOptionsCLB->set_toggle(nEntry, bVal ? TRISTATE_TRUE : TRISTATE_FALSE);
1269  m_xLinguOptionsCLB->set_text(nEntry, sHyphSpecial, 0);
1270  m_xLinguOptionsCLB->set_id(nEntry, OUString::number(nUserData));
1271 
1272  m_xLinguOptionsCLB->thaw();
1273 
1274  m_xLinguOptionsCLB->select(0);
1275  SelectHdl_Impl(*m_xLinguOptionsCLB);
1276 
1277  m_xLinguModulesCLB->set_size_request(m_xLinguModulesCLB->get_preferred_size().Width(),
1278  m_xLinguModulesCLB->get_height_rows(3));
1279  m_xLinguDicsCLB->set_size_request(m_xLinguDicsCLB->get_preferred_size().Width(),
1280  m_xLinguDicsCLB->get_height_rows(5));
1281  m_xLinguOptionsCLB->set_size_request(m_xLinguOptionsCLB->get_preferred_size().Width(),
1282  m_xLinguOptionsCLB->get_height_rows(5));
1283 }
1284 
1285 IMPL_LINK(SvxLinguTabPage, BoxDoubleClickHdl_Impl, weld::TreeView&, rBox, bool)
1286 {
1287  if (&rBox == m_xLinguModulesCLB.get() && !m_nDlbClickEventId)
1288  {
1292  m_nDlbClickEventId = Application::PostUserEvent(LINK(this, SvxLinguTabPage, PostDblClickHdl_Impl));
1293  }
1294  else if (&rBox == m_xLinguOptionsCLB.get())
1295  {
1296  ClickHdl_Impl(*m_xLinguOptionsEditPB);
1297  }
1298  return true;
1299 }
1300 
1301 IMPL_LINK_NOARG(SvxLinguTabPage, PostDblClickHdl_Impl, void*, void)
1302 {
1303  m_nDlbClickEventId = nullptr;
1304  ClickHdl_Impl(*m_xLinguModulesEditPB);
1305 }
1306 
1307 IMPL_LINK(SvxLinguTabPage, ModulesBoxCheckButtonHdl_Impl, const weld::TreeView::iter_col&, rRowCol, void)
1308 {
1309  if (!pLinguData)
1310  return;
1311  pLinguData->Reconfigure(m_xLinguModulesCLB->get_text(rRowCol.first),
1312  m_xLinguModulesCLB->get_toggle(rRowCol.first) == TRISTATE_TRUE);
1313 }
1314 
1315 IMPL_LINK(SvxLinguTabPage, DicsBoxCheckButtonHdl_Impl, const weld::TreeView::iter_col&, rRowCol, void)
1316 {
1317  const uno::Reference<XDictionary> &rDic = aDics.getConstArray()[m_xLinguDicsCLB->get_iter_index_in_parent(rRowCol.first)];
1318  if (LinguMgr::GetIgnoreAllList() == rDic)
1319  m_xLinguDicsCLB->set_toggle(rRowCol.first, TRISTATE_TRUE);
1320 }
1321 
1322 IMPL_LINK(SvxLinguTabPage, ClickHdl_Impl, weld::Button&, rBtn, void)
1323 {
1324  if (m_xLinguModulesEditPB.get() == &rBtn)
1325  {
1326  if (!pLinguData)
1327  pLinguData.reset( new SvxLinguData_Impl );
1328 
1329  SvxLinguData_Impl aOldLinguData( *pLinguData );
1330  SvxEditModulesDlg aDlg(GetFrameWeld(), *pLinguData);
1331  if (aDlg.run() != RET_OK)
1332  *pLinguData = aOldLinguData;
1333 
1334  // evaluate new status of 'bConfigured' flag
1335  sal_uInt32 nLen = pLinguData->GetDisplayServiceCount();
1336  for (sal_uInt32 i = 0; i < nLen; ++i)
1337  pLinguData->GetDisplayServiceArray()[i].bConfigured = false;
1338  const Locale* pAllLocales = pLinguData->GetAllSupportedLocales().getConstArray();
1339  sal_Int32 nLocales = pLinguData->GetAllSupportedLocales().getLength();
1340  for (sal_Int32 k = 0; k < nLocales; ++k)
1341  {
1342  LanguageType nLang = LanguageTag::convertToLanguageType( pAllLocales[k] );
1343  if (pLinguData->GetSpellTable().count( nLang ))
1344  pLinguData->SetChecked( pLinguData->GetSpellTable()[ nLang ] );
1345  if (pLinguData->GetGrammarTable().count( nLang ))
1346  pLinguData->SetChecked( pLinguData->GetGrammarTable()[ nLang ] );
1347  if (pLinguData->GetHyphTable().count( nLang ))
1348  pLinguData->SetChecked( pLinguData->GetHyphTable()[ nLang ] );
1349  if (pLinguData->GetThesTable().count( nLang ))
1350  pLinguData->SetChecked( pLinguData->GetThesTable()[ nLang ] );
1351  }
1352 
1353  // show new status of modules
1354  UpdateModulesBox_Impl();
1355  }
1356  else if (m_xLinguDicsNewPB.get() == &rBtn)
1357  {
1360  uno::Reference< XDictionary > xNewDic;
1361  if ( aDlg->Execute() == RET_OK )
1362  xNewDic = aDlg->GetNewDictionary();
1363  if ( xNewDic.is() )
1364  {
1365  // add new dics to the end
1366  sal_Int32 nLen = aDics.getLength();
1367  aDics.realloc( nLen + 1 );
1368 
1369  aDics.getArray()[ nLen ] = xNewDic;
1370 
1371  AddDicBoxEntry( xNewDic, static_cast<sal_uInt16>(nLen) );
1372  }
1373  }
1374  else if (m_xLinguDicsEditPB.get() == &rBtn)
1375  {
1376  int nEntry = m_xLinguDicsCLB->get_selected_index();
1377  if (nEntry != -1)
1378  {
1379  DicUserData aData(m_xLinguDicsCLB->get_id(nEntry).toUInt32());
1380  sal_uInt16 nDicPos = aData.GetEntryId();
1381  sal_Int32 nDics = aDics.getLength();
1382  if (nDicPos < nDics)
1383  {
1384  uno::Reference< XDictionary > xDic = aDics.getConstArray()[ nDicPos ];
1385  if (xDic.is())
1386  {
1389  aDlg->Execute();
1390  }
1391  }
1392  }
1393  }
1394  else if (m_xLinguDicsDelPB.get() == &rBtn)
1395  {
1396  std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/querydeletedictionarydialog.ui"));
1397  std::unique_ptr<weld::MessageDialog> xQuery(xBuilder->weld_message_dialog("QueryDeleteDictionaryDialog"));
1398  if (RET_NO == xQuery->run())
1399  return;
1400 
1401  int nEntry = m_xLinguDicsCLB->get_selected_index();
1402  if (nEntry != -1)
1403  {
1404  DicUserData aData(m_xLinguDicsCLB->get_id(nEntry).toUInt32());
1405  sal_uInt16 nDicPos = aData.GetEntryId();
1406  sal_Int32 nDics = aDics.getLength();
1407  if (nDicPos < nDics)
1408  {
1409  uno::Reference< XDictionary > xDic = aDics.getConstArray()[ nDicPos ];
1410  if (xDic.is())
1411  {
1412  if (LinguMgr::GetIgnoreAllList() == xDic)
1413  xDic->clear();
1414  else
1415  {
1416  if (xDicList.is())
1417  xDicList->removeDictionary( xDic );
1418 
1419  uno::Reference< frame::XStorable > xStor( xDic, UNO_QUERY );
1420  if ( xStor->hasLocation() && !xStor->isReadonly() )
1421  {
1422  OUString sURL = xStor->getLocation();
1423  INetURLObject aObj(sURL);
1424  DBG_ASSERT( aObj.GetProtocol() == INetProtocol::File,
1425  "non-file URLs cannot be deleted" );
1426  if ( aObj.GetProtocol() == INetProtocol::File )
1427  {
1429  }
1430  }
1431 
1432  aDics.getArray()[ nDicPos ] = nullptr;
1433 
1434  // remove entry from checklistbox
1435  int nCnt = m_xLinguDicsCLB->n_children();
1436  for (int i = 0; i < nCnt; ++i)
1437  {
1438  DicUserData aDicData(m_xLinguDicsCLB->get_id(i).toUInt32());
1439  if (aDicData.GetEntryId() == nDicPos )
1440  {
1441  m_xLinguDicsCLB->remove(i);
1442  break;
1443  }
1444  }
1445  DBG_ASSERT( nCnt > m_xLinguDicsCLB->n_children(),
1446  "remove failed ?");
1447  }
1448  }
1449  }
1450  }
1451  }
1452  else if (m_xLinguOptionsEditPB.get() == &rBtn)
1453  {
1454  int nEntry = m_xLinguOptionsCLB->get_selected_index();
1455  DBG_ASSERT(nEntry != -1, "no entry selected");
1456  if (nEntry != -1)
1457  {
1458  OptionsUserData aData(m_xLinguOptionsCLB->get_id(nEntry).toUInt32());
1459  if (aData.HasNumericValue())
1460  {
1461  sal_uInt16 nRID = aData.GetEntryId();
1462  OptionsBreakSet aDlg(GetFrameWeld(), nRID);
1463  aDlg.GetNumericFld().set_value(aData.GetNumericValue());
1464  if (RET_OK == aDlg.run())
1465  {
1466  int nVal = aDlg.GetNumericFld().get_value();
1467  if (-1 != nVal && aData.GetNumericValue() != nVal)
1468  {
1469  aData.SetNumericValue( static_cast<sal_uInt8>(nVal) );
1470  m_xLinguOptionsCLB->set_id(nEntry, OUString::number(aData.GetUserData()));
1471  if (nEntry == nUPN_HYPH_MIN_WORD_LENGTH)
1472  m_xLinguOptionsCLB->set_text(nEntry, sNumMinWordlen + " " + OUString::number(nVal), 0);
1473  else if (nEntry == nUPN_HYPH_MIN_LEADING)
1474  m_xLinguOptionsCLB->set_text(nEntry, sNumPreBreak + " " + OUString::number(nVal), 0);
1475  else if (nEntry == nUPN_HYPH_MIN_TRAILING)
1476  m_xLinguOptionsCLB->set_text(nEntry, sNumPostBreak + " " + OUString::number(nVal), 0);
1477  m_xLinguOptionsCLB->set_id(nEntry, OUString::number(aData.GetUserData()));
1478  }
1479  }
1480  }
1481  }
1482  }
1483  else
1484  {
1485  OSL_FAIL( "rBtn unexpected value" );
1486  }
1487 }
1488 
1489 IMPL_LINK(SvxLinguTabPage, SelectHdl_Impl, weld::TreeView&, rBox, void)
1490 {
1491  if (m_xLinguModulesCLB.get() == &rBox)
1492  {
1493  }
1494  else if (m_xLinguDicsCLB.get() == &rBox)
1495  {
1496  int nEntry = rBox.get_selected_index();
1497  if (nEntry != -1)
1498  {
1499  DicUserData aData(rBox.get_id(nEntry).toUInt32());
1500 
1501  // always allow to edit (i.e. at least view the content of the dictionary)
1502  m_xLinguDicsEditPB->set_sensitive( true );
1503  m_xLinguDicsDelPB->set_sensitive( aData.IsDeletable() );
1504  }
1505  }
1506  else if (m_xLinguOptionsCLB.get() == &rBox)
1507  {
1508  int nEntry = rBox.get_selected_index();
1509  if (nEntry != -1)
1510  {
1511  OptionsUserData aData(rBox.get_id(nEntry).toUInt32());
1512  m_xLinguOptionsEditPB->set_sensitive( aData.HasNumericValue() );
1513  }
1514  }
1515  else
1516  {
1517  OSL_FAIL( "rBox unexpected value" );
1518  }
1519 }
1520 
1521 void SvxLinguTabPage::HideGroups( sal_uInt16 nGrp )
1522 {
1523  if ( 0 != ( GROUP_MODULES & nGrp ) )
1524  {
1525  m_xLinguModulesFT->hide();
1526  m_xLinguModulesCLB->hide();
1527  m_xLinguModulesEditPB->hide();
1528 
1529  if (officecfg::Office::Security::Hyperlinks::Open::get() != SvtExtendedSecurityOptions::OPEN_NEVER)
1530  {
1531  m_xMoreDictsLink->show();
1532  }
1533  }
1534 }
1535 
1537 {
1538  comphelper::dispatchCommand(".uno:MoreDictionaries", {});
1539  return true;
1540 }
1541 
1543  : GenericDialogController(pParent, "cui/ui/editmodulesdialog.ui", "EditModulesDialog")
1544  , sSpell(CuiResId(RID_CUISTR_SPELL))
1545  , sHyph(CuiResId(RID_CUISTR_HYPH))
1546  , sThes(CuiResId(RID_CUISTR_THES))
1547  , sGrammar(CuiResId(RID_CUISTR_GRAMMAR))
1548  , rLinguData(rData)
1549  , m_xModulesCLB(m_xBuilder->weld_tree_view("lingudicts"))
1550  , m_xPrioUpPB(m_xBuilder->weld_button("up"))
1551  , m_xPrioDownPB(m_xBuilder->weld_button("down"))
1552  , m_xBackPB(m_xBuilder->weld_button("back"))
1553  , m_xMoreDictsLink(m_xBuilder->weld_link_button("moredictslink"))
1554  , m_xClosePB(m_xBuilder->weld_button("close"))
1555  , m_xLanguageLB(new SvxLanguageBox(m_xBuilder->weld_combo_box("language")))
1556 {
1557  m_xModulesCLB->set_size_request(m_xModulesCLB->get_approximate_digit_width() * 40,
1558  m_xModulesCLB->get_height_rows(12));
1559 
1560  m_xModulesCLB->enable_toggle_buttons(weld::ColumnToggleType::Check);
1561 
1563 
1564  m_xModulesCLB->connect_changed( LINK( this, SvxEditModulesDlg, SelectHdl_Impl ));
1565  m_xModulesCLB->connect_toggled(LINK(this, SvxEditModulesDlg, BoxCheckButtonHdl_Impl));
1566 
1567  m_xClosePB->connect_clicked( LINK( this, SvxEditModulesDlg, ClickHdl_Impl ));
1568  m_xPrioUpPB->connect_clicked( LINK( this, SvxEditModulesDlg, UpDownHdl_Impl ));
1569  m_xPrioDownPB->connect_clicked( LINK( this, SvxEditModulesDlg, UpDownHdl_Impl ));
1570  m_xBackPB->connect_clicked( LINK( this, SvxEditModulesDlg, BackHdl_Impl ));
1571  // in case of not installed language modules
1572  m_xPrioUpPB->set_sensitive( false );
1573  m_xPrioDownPB->set_sensitive( false );
1574 
1575  m_xMoreDictsLink->connect_activate_link(LINK(this, SvxEditModulesDlg, OnLinkClick));
1576  if (officecfg::Office::Security::Hyperlinks::Open::get() == SvtExtendedSecurityOptions::OPEN_NEVER)
1577  m_xMoreDictsLink->hide();
1578 
1579  // set that we want the checkbox shown if spellchecking is available
1580  m_xLanguageLB->SetLanguageList(SvxLanguageListFlags::EMPTY, false, false, true);
1581 
1582  //fill language box
1583  const Sequence< Locale >& rLoc = rLinguData.GetAllSupportedLocales();
1584  for (Locale const & locale : rLoc)
1585  {
1587  m_xLanguageLB->InsertLanguage(nLang);
1588  }
1590  m_xLanguageLB->set_active_id( eSysLang );
1591  if (m_xLanguageLB->get_active_id() != eSysLang)
1592  m_xLanguageLB->set_active(0);
1593 
1594  m_xLanguageLB->connect_changed( LINK( this, SvxEditModulesDlg, LangSelectListBoxHdl_Impl ));
1596 }
1597 
1599 {
1600  for (int i = 0, nEntryCount = m_xModulesCLB->n_children(); i < nEntryCount; ++i)
1601  delete reinterpret_cast<ModuleUserData_Impl*>(m_xModulesCLB->get_id(i).toInt64());
1602 }
1603 
1604 IMPL_LINK( SvxEditModulesDlg, SelectHdl_Impl, weld::TreeView&, rBox, void )
1605 {
1606  int nCurPos = rBox.get_selected_index();
1607  if (nCurPos == -1)
1608  return;
1609 
1610  bool bDisableUp = true;
1611  bool bDisableDown = true;
1612  ModuleUserData_Impl* pData = reinterpret_cast<ModuleUserData_Impl*>(rBox.get_id(nCurPos).toInt64());
1613  if (!pData->IsParent() && pData->GetType() != TYPE_HYPH)
1614  {
1615  if (nCurPos < rBox.n_children() - 1)
1616  {
1617  bDisableDown = reinterpret_cast<ModuleUserData_Impl*>(rBox.get_id(nCurPos + 1).toInt64())->IsParent();
1618  }
1619  if (nCurPos > 1)
1620  {
1621  bDisableUp = reinterpret_cast<ModuleUserData_Impl*>(rBox.get_id(nCurPos - 1).toInt64())->IsParent();
1622  }
1623  }
1624  m_xPrioUpPB->set_sensitive(!bDisableUp);
1625  m_xPrioDownPB->set_sensitive(!bDisableDown);
1626 }
1627 
1628 IMPL_LINK( SvxEditModulesDlg, BoxCheckButtonHdl_Impl, const weld::TreeView::iter_col&, rRowCol, void )
1629 {
1630  ModuleUserData_Impl* pData = reinterpret_cast<ModuleUserData_Impl*>(m_xModulesCLB->get_id(rRowCol.first).toInt64());
1631  if (pData->IsParent() || pData->GetType() != TYPE_HYPH)
1632  return;
1633 
1634  // make hyphenator checkboxes function as radio-buttons
1635  // (at most one box may be checked)
1636  auto nPos = m_xModulesCLB->get_iter_index_in_parent(rRowCol.first);
1637  for (int i = 0, nEntryCount = m_xModulesCLB->n_children(); i < nEntryCount; ++i)
1638  {
1639  pData = reinterpret_cast<ModuleUserData_Impl*>(m_xModulesCLB->get_id(i).toInt64());
1640  if (!pData->IsParent() && pData->GetType() == TYPE_HYPH && i != nPos)
1641  {
1642  m_xModulesCLB->set_toggle(i, TRISTATE_FALSE);
1643  }
1644  }
1645 }
1646 
1647 IMPL_LINK_NOARG(SvxEditModulesDlg, LangSelectListBoxHdl_Impl, weld::ComboBox&, void)
1648 {
1649  LangSelectHdl_Impl(m_xLanguageLB.get());
1650 }
1651 
1653 {
1654  LanguageType eCurLanguage = m_xLanguageLB->get_active_id();
1655  static Locale aLastLocale;
1656  Locale aCurLocale( LanguageTag::convertToLocale( eCurLanguage));
1657 
1658  if (pBox)
1659  {
1660  // save old probably changed settings
1661  // before switching to new language entries
1662 
1663  LanguageType nLang = LanguageTag::convertToLanguageType( aLastLocale );
1664 
1665  sal_Int32 nStart = 0, nLocalIndex = 0;
1666  Sequence< OUString > aChange;
1667  bool bChanged = false;
1668  for (int i = 0, nEntryCount = m_xModulesCLB->n_children(); i < nEntryCount; ++i)
1669  {
1670  ModuleUserData_Impl* pData = reinterpret_cast<ModuleUserData_Impl*>(m_xModulesCLB->get_id(i).toInt64());
1671  if (pData->IsParent())
1672  {
1673  if (bChanged)
1674  {
1675  LangImplNameTable *pTable = nullptr;
1676  sal_uInt8 nType = pData->GetType();
1677  switch (nType - 1)
1678  {
1679  case TYPE_SPELL : pTable = &rLinguData.GetSpellTable(); break;
1680  case TYPE_GRAMMAR : pTable = &rLinguData.GetGrammarTable(); break;
1681  case TYPE_HYPH : pTable = &rLinguData.GetHyphTable(); break;
1682  case TYPE_THES : pTable = &rLinguData.GetThesTable(); break;
1683  }
1684  if (pTable)
1685  {
1686  aChange.realloc(nStart);
1687  (*pTable)[ nLang ] = aChange;
1688  }
1689  }
1690  nLocalIndex = nStart = 0;
1691  aChange.realloc(nEntryCount);
1692  bChanged = false;
1693  }
1694  else
1695  {
1696  OUString* pChange = aChange.getArray();
1697  pChange[nStart] = pData->GetImplName();
1698  bChanged |= pData->GetIndex() != nLocalIndex ||
1699  static_cast<TriState>(pData->IsChecked()) != m_xModulesCLB->get_toggle(i);
1700  if (m_xModulesCLB->get_toggle(i))
1701  nStart++;
1702  ++nLocalIndex;
1703  }
1704  }
1705  if(bChanged)
1706  {
1707  aChange.realloc(nStart);
1708  rLinguData.GetThesTable()[ nLang ] = aChange;
1709  }
1710  }
1711 
1712  for (int i = 0, nEntryCount = m_xModulesCLB->n_children(); i < nEntryCount; ++i)
1713  delete reinterpret_cast<ModuleUserData_Impl*>(m_xModulesCLB->get_id(i).toInt64());
1714  m_xModulesCLB->clear();
1715 
1716  // display entries for new selected language
1717 
1718  if (LANGUAGE_DONTKNOW != eCurLanguage)
1719  {
1720  sal_Int32 n;
1721  ServiceInfo_Impl* pInfo;
1722 
1723  int nRow = 0;
1724  // spellchecker entries
1725 
1726  ModuleUserData_Impl* pUserData = new ModuleUserData_Impl(
1727  OUString(), true, false, TYPE_SPELL, 0 );
1728  OUString sId(OUString::number(reinterpret_cast<sal_Int64>(pUserData)));
1729  m_xModulesCLB->append(nullptr);
1730  m_xModulesCLB->set_id(nRow, sId);
1731  m_xModulesCLB->set_text(nRow, sSpell, 0);
1732  m_xModulesCLB->set_text_emphasis(nRow, true, 0);
1733  ++nRow;
1734 
1735  Sequence< OUString > aNames( rLinguData.GetSortedImplNames( eCurLanguage, TYPE_SPELL ) );
1736  const OUString *pName = aNames.getConstArray();
1737  sal_Int32 nNames = aNames.getLength();
1738  sal_Int32 nLocalIndex = 0; // index relative to parent
1739  for (n = 0; n < nNames; ++n)
1740  {
1741  OUString aImplName;
1742  bool bIsSuppLang = false;
1743 
1744  pInfo = rLinguData.GetInfoByImplName( pName[n] );
1745  if (pInfo)
1746  {
1747  bIsSuppLang = pInfo->xSpell.is() &&
1748  pInfo->xSpell->hasLocale( aCurLocale );
1749  aImplName = pInfo->sSpellImplName;
1750  }
1751  if (!aImplName.isEmpty() && bIsSuppLang)
1752  {
1753  OUString aTxt( pInfo->sDisplayName );
1754 
1755  LangImplNameTable &rTable = rLinguData.GetSpellTable();
1756  const bool bHasLang = rTable.count( eCurLanguage );
1757  if (!bHasLang)
1758  {
1759  SAL_INFO( "cui.options", "language entry missing" ); // only relevant if all languages found should be supported
1760  }
1761  const bool bCheck = bHasLang && lcl_SeqGetEntryPos( rTable[ eCurLanguage ], aImplName ) >= 0;
1762  pUserData = new ModuleUserData_Impl( aImplName, false,
1763  bCheck, TYPE_SPELL, static_cast<sal_uInt8>(nLocalIndex++) );
1764  sId = OUString::number(reinterpret_cast<sal_Int64>(pUserData));
1765 
1766  m_xModulesCLB->append(nullptr);
1767  m_xModulesCLB->set_id(nRow, sId);
1768  m_xModulesCLB->set_toggle(nRow, bCheck ? TRISTATE_TRUE : TRISTATE_FALSE);
1769  m_xModulesCLB->set_text(nRow, aTxt, 0);
1770  m_xModulesCLB->set_text_emphasis(nRow, false, 0);
1771  ++nRow;
1772  }
1773  }
1774 
1775  // grammar checker entries
1776 
1777  pUserData = new ModuleUserData_Impl( OUString(), true, false, TYPE_GRAMMAR, 0 );
1778  sId = OUString::number(reinterpret_cast<sal_Int64>(pUserData));
1779  m_xModulesCLB->append(nullptr);
1780  m_xModulesCLB->set_id(nRow, sId);
1781  m_xModulesCLB->set_text(nRow, sGrammar, 0);
1782  m_xModulesCLB->set_text_emphasis(nRow, true, 0);
1783  ++nRow;
1784 
1785  aNames = rLinguData.GetSortedImplNames( eCurLanguage, TYPE_GRAMMAR );
1786  pName = aNames.getConstArray();
1787  nNames = aNames.getLength();
1788  nLocalIndex = 0;
1789  for (n = 0; n < nNames; ++n)
1790  {
1791  OUString aImplName;
1792  bool bIsSuppLang = false;
1793 
1794  pInfo = rLinguData.GetInfoByImplName( pName[n] );
1795  if (pInfo)
1796  {
1797  bIsSuppLang = pInfo->xGrammar.is() &&
1798  pInfo->xGrammar->hasLocale( aCurLocale );
1799  aImplName = pInfo->sGrammarImplName;
1800  }
1801  if (!aImplName.isEmpty() && bIsSuppLang)
1802  {
1803  OUString aTxt( pInfo->sDisplayName );
1804 
1805  LangImplNameTable &rTable = rLinguData.GetGrammarTable();
1806  const bool bHasLang = rTable.count( eCurLanguage );
1807  if (!bHasLang)
1808  {
1809  SAL_INFO( "cui.options", "language entry missing" ); // only relevant if all languages found should be supported
1810  }
1811  const bool bCheck = bHasLang && lcl_SeqGetEntryPos( rTable[ eCurLanguage ], aImplName ) >= 0;
1812  pUserData = new ModuleUserData_Impl( aImplName, false,
1813  bCheck, TYPE_GRAMMAR, static_cast<sal_uInt8>(nLocalIndex++) );
1814 
1815  sId = OUString::number(reinterpret_cast<sal_Int64>(pUserData));
1816 
1817  m_xModulesCLB->append(nullptr);
1818  m_xModulesCLB->set_id(nRow, sId);
1819  m_xModulesCLB->set_toggle(nRow, bCheck ? TRISTATE_TRUE : TRISTATE_FALSE);
1820  m_xModulesCLB->set_text(nRow, aTxt, 0);
1821  m_xModulesCLB->set_text_emphasis(nRow, false, 0);
1822  ++nRow;
1823  }
1824  }
1825 
1826  // hyphenator entries
1827 
1828  pUserData = new ModuleUserData_Impl( OUString(), true, false, TYPE_HYPH, 0 );
1829  sId = OUString::number(reinterpret_cast<sal_Int64>(pUserData));
1830  m_xModulesCLB->append(nullptr);
1831  m_xModulesCLB->set_id(nRow, sId);
1832  m_xModulesCLB->set_text(nRow, sHyph, 0);
1833  m_xModulesCLB->set_text_emphasis(nRow, true, 0);
1834  ++nRow;
1835 
1836  aNames = rLinguData.GetSortedImplNames( eCurLanguage, TYPE_HYPH );
1837  pName = aNames.getConstArray();
1838  nNames = aNames.getLength();
1839  nLocalIndex = 0;
1840  for (n = 0; n < nNames; ++n)
1841  {
1842  OUString aImplName;
1843  bool bIsSuppLang = false;
1844 
1845  pInfo = rLinguData.GetInfoByImplName( pName[n] );
1846  if (pInfo)
1847  {
1848  bIsSuppLang = pInfo->xHyph.is() &&
1849  pInfo->xHyph->hasLocale( aCurLocale );
1850  aImplName = pInfo->sHyphImplName;
1851  }
1852  if (!aImplName.isEmpty() && bIsSuppLang)
1853  {
1854  OUString aTxt( pInfo->sDisplayName );
1855 
1856  LangImplNameTable &rTable = rLinguData.GetHyphTable();
1857  const bool bHasLang = rTable.count( eCurLanguage );
1858  if (!bHasLang)
1859  {
1860  SAL_INFO( "cui.options", "language entry missing" ); // only relevant if all languages found should be supported
1861  }
1862  const bool bCheck = bHasLang && lcl_SeqGetEntryPos( rTable[ eCurLanguage ], aImplName ) >= 0;
1863  pUserData = new ModuleUserData_Impl( aImplName, false,
1864  bCheck, TYPE_HYPH, static_cast<sal_uInt8>(nLocalIndex++) );
1865  sId = OUString::number(reinterpret_cast<sal_Int64>(pUserData));
1866 
1867  m_xModulesCLB->append(nullptr);
1868  m_xModulesCLB->set_id(nRow, sId);
1869  m_xModulesCLB->set_toggle(nRow, bCheck ? TRISTATE_TRUE : TRISTATE_FALSE);
1870  m_xModulesCLB->set_text(nRow, aTxt, 0);
1871  m_xModulesCLB->set_text_emphasis(nRow, false, 0);
1872  ++nRow;
1873  }
1874  }
1875 
1876  // thesaurus entries
1877 
1878  pUserData = new ModuleUserData_Impl( OUString(), true, false, TYPE_THES, 0 );
1879  sId = OUString::number(reinterpret_cast<sal_Int64>(pUserData));
1880  m_xModulesCLB->append(nullptr);
1881  m_xModulesCLB->set_id(nRow, sId);
1882  m_xModulesCLB->set_text(nRow, sThes, 0);
1883  m_xModulesCLB->set_text_emphasis(nRow, true, 0);
1884  ++nRow;
1885 
1886  aNames = rLinguData.GetSortedImplNames( eCurLanguage, TYPE_THES );
1887  pName = aNames.getConstArray();
1888  nNames = aNames.getLength();
1889  nLocalIndex = 0;
1890  for (n = 0; n < nNames; ++n)
1891  {
1892  OUString aImplName;
1893  bool bIsSuppLang = false;
1894 
1895  pInfo = rLinguData.GetInfoByImplName( pName[n] );
1896  if (pInfo)
1897  {
1898  bIsSuppLang = pInfo->xThes.is() &&
1899  pInfo->xThes->hasLocale( aCurLocale );
1900  aImplName = pInfo->sThesImplName;
1901  }
1902  if (!aImplName.isEmpty() && bIsSuppLang)
1903  {
1904  OUString aTxt( pInfo->sDisplayName );
1905 
1906  LangImplNameTable &rTable = rLinguData.GetThesTable();
1907  const bool bHasLang = rTable.count( eCurLanguage );
1908  if (!bHasLang)
1909  {
1910  SAL_INFO( "cui.options", "language entry missing" ); // only relevant if all languages found should be supported
1911  }
1912  const bool bCheck = bHasLang && lcl_SeqGetEntryPos( rTable[ eCurLanguage ], aImplName ) >= 0;
1913  pUserData = new ModuleUserData_Impl( aImplName, false,
1914  bCheck, TYPE_THES, static_cast<sal_uInt8>(nLocalIndex++) );
1915  sId = OUString::number(reinterpret_cast<sal_Int64>(pUserData));
1916 
1917  m_xModulesCLB->append(nullptr);
1918  m_xModulesCLB->set_id(nRow, sId);
1919  m_xModulesCLB->set_toggle(nRow, bCheck ? TRISTATE_TRUE : TRISTATE_FALSE);
1920  m_xModulesCLB->set_text(nRow, aTxt, 0);
1921  m_xModulesCLB->set_text_emphasis(nRow, false, 0);
1922  ++nRow;
1923  }
1924  }
1925  }
1926  aLastLocale = aCurLocale;
1927 }
1928 
1929 IMPL_LINK( SvxEditModulesDlg, UpDownHdl_Impl, weld::Button&, rBtn, void )
1930 {
1931  bool bUp = m_xPrioUpPB.get() == &rBtn;
1932  int nCurPos = m_xModulesCLB->get_selected_index();
1933  if (nCurPos == -1)
1934  return;
1935 
1936  m_xModulesCLB->freeze();
1937 
1938  OUString sId(m_xModulesCLB->get_id(nCurPos));
1939  OUString sStr(m_xModulesCLB->get_text(nCurPos));
1940  bool bIsChecked = m_xModulesCLB->get_toggle(nCurPos);
1941 
1942  m_xModulesCLB->remove(nCurPos);
1943 
1944  int nDestPos = bUp ? nCurPos - 1 : nCurPos + 1;
1945 
1946  m_xModulesCLB->insert_text(nDestPos, sStr);
1947  m_xModulesCLB->set_id(nDestPos, sId);
1948  m_xModulesCLB->set_toggle(nDestPos, bIsChecked ? TRISTATE_TRUE : TRISTATE_FALSE);
1949 
1950  m_xModulesCLB->thaw();
1951 
1952  m_xModulesCLB->select(nDestPos);
1953  SelectHdl_Impl(*m_xModulesCLB);
1954 }
1955 
1957 {
1958  // store language config
1959  LangSelectHdl_Impl(m_xLanguageLB.get());
1960  m_xDialog->response(RET_OK);
1961 }
1962 
1964 {
1965  rLinguData = *pDefaultLinguData;
1966  LangSelectHdl_Impl(nullptr);
1967 }
1968 
1970 {
1971  comphelper::dispatchCommand(".uno:MoreDictionaries", {});
1972  return true;
1973 }
1974 
1975 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static sal_Int32 lcl_SeqGetEntryPos(const Sequence< OUString > &rSeq, std::u16string_view rEntry)
Definition: optlingu.cxx:77
virtual VclPtr< AbstractSvxNewDictionaryDialog > CreateSvxNewDictionaryDialog(weld::Window *pParent)=0
SvxEditModulesDlg(weld::Window *pParent, SvxLinguData_Impl &rData)
Definition: optlingu.cxx:1542
static bool KillFile_Impl(const OUString &rURL)
Definition: optlingu.cxx:91
std::unique_ptr< weld::Button > m_xLinguDicsDelPB
Definition: optlingu.hxx:118
sal_Int32 nIndex
OUString sHyphSpecial
Definition: optlingu.hxx:92
constexpr OUStringLiteral cThes(SN_THESAURUS)
void UpdateDicBox_Impl()
Definition: optlingu.cxx:1101
SvxLinguData_Impl & rLinguData
Definition: optlingu.hxx:53
uno::Reference< XLinguServiceManager2 > xLinguSrvcMgr
Definition: optlingu.cxx:344
#define TYPE_HYPH
Definition: optlingu.cxx:116
Sequence< OUString > GetSortedImplNames(LanguageType nLang, sal_uInt8 nType)
Definition: optlingu.cxx:397
OUString sNumMinWordlen
Definition: optlingu.hxx:88
std::unique_ptr< SvxLanguageBox > m_xLanguageLB
Definition: optlingu.hxx:61
const char * pLocale
constexpr OUStringLiteral cHyph(SN_HYPHENATOR)
std::unique_ptr< weld::LinkButton > m_xMoreDictsLink
Definition: optlingu.hxx:121
sal_uInt32 nDisplayServices
Definition: optlingu.cxx:337
std::unique_ptr< weld::Label > m_xLinguModulesFT
Definition: optlingu.hxx:111
ServiceInfoArr aDisplayServiceArr
Definition: optlingu.cxx:336
std::unique_ptr< weld::Label > m_xLinguDicsFT
Definition: optlingu.hxx:114
std::unique_ptr< sal_Int32[]> pData
sal_uInt8 & GetMinTrail()
static sal_Int32 lcl_SeqGetIndex(const Sequence< OUString > &rSeq, std::u16string_view rTxt)
Definition: optlingu.cxx:383
static bool AddRemove(Sequence< OUString > &rConfigured, const OUString &rImplName, bool bAdd)
Definition: optlingu.cxx:701
std::unique_ptr< SvxLinguData_Impl > pLinguData
Definition: optlingu.hxx:109
static LanguageType convertToLanguageType(const css::lang::Locale &rLocale, bool bResolveSystem=true)
void HideGroups(sal_uInt16 nGrp)
Definition: optlingu.cxx:1521
static SvxAbstractDialogFactory * Create()
static const AllSettings & GetSettings()
static std::unique_ptr< SfxTabPage > Create(weld::Container *pPage, weld::DialogController *pController, const SfxItemSet *rSet)
Definition: optlingu.cxx:911
sal_Int64 n
constexpr OUStringLiteral UPN_IS_SPELL_UPPER_CASE
std::unique_ptr< weld::Button > m_xPrioUpPB
Definition: optlingu.hxx:56
#define TYPE_THES
Definition: optlingu.cxx:117
static ImplSVEvent * PostUserEvent(const Link< void *, void > &rLink, void *pCaller=nullptr, bool bReferenceLink=false)
constexpr OUStringLiteral UPN_HYPH_MIN_TRAILING
virtual short Execute()=0
TRISTATE_TRUE
std::unique_ptr< SvxLinguData_Impl > pDefaultLinguData
Definition: optlingu.hxx:52
static const SfxPoolItem * GetItem(const SfxItemSet &rSet, sal_uInt16 nSlot, bool bDeep=true)
const css::lang::Locale & getLocale(bool bResolveSystem=true) const
constexpr OUStringLiteral UPN_IS_HYPH_SPECIAL
static css::uno::Reference< css::linguistic2::XLinguProperties > GetLinguPropertySet()
void LangSelectHdl_Impl(const SvxLanguageBox *pBox)
Definition: optlingu.cxx:1652
RET_NO
LangImplNameTable & GetThesTable()
Definition: optlingu.cxx:362
virtual ~SvxLinguTabPage() override
Definition: optlingu.cxx:901
sal_uInt8 & GetMinLead()
void UpdateModulesBox_Impl()
Definition: optlingu.cxx:1123
bool dispatchCommand(const OUString &rCommand, const uno::Reference< css::frame::XFrame > &rFrame, const css::uno::Sequence< css::beans::PropertyValue > &rArguments, const uno::Reference< css::frame::XDispatchResultListener > &rListener)
std::pair< const TreeIter &, int > iter_col
virtual VclPtr< VclAbstractDialog > CreateSvxEditDictionaryDialog(weld::Window *pParent, const OUString &rName)=0
static css::uno::Reference< css::linguistic2::XSearchableDictionaryList > GetDictionaryList()
std::unique_ptr< weld::TreeView > m_xModulesCLB
Definition: optlingu.hxx:55
OUString sHyphAuto
Definition: optlingu.hxx:91
std::map< LanguageType, Sequence< OUString > > LangImplNameTable
Definition: optlingu.cxx:328
std::unique_ptr< weld::Button > m_xLinguDicsNewPB
Definition: optlingu.hxx:116
std::unique_ptr< weld::Button > m_xClosePB
Definition: optlingu.hxx:60
std::unique_ptr< weld::TreeView > m_xLinguModulesCLB
Definition: optlingu.hxx:112
#define TYPE_GRAMMAR
Definition: optlingu.cxx:115
std::unique_ptr< weld::LinkButton > m_xMoreDictsLink
Definition: optlingu.hxx:59
std::unique_ptr< weld::Button > m_xLinguOptionsEditPB
Definition: optlingu.hxx:120
constexpr OUStringLiteral UPN_IS_SPELL_SPECIAL
OUString sThes
Definition: optlingu.hxx:49
static css::uno::Reference< css::linguistic2::XDictionary > GetIgnoreAllList()
constexpr OUStringLiteral UPN_IS_GRAMMAR_AUTO
OUString GetDicInfoStr(const OUString &rName, const LanguageType nLang, bool bNeg)
IMPL_STATIC_LINK_NOARG(SvxLinguTabPage, OnLinkClick, weld::LinkButton &, bool)
Definition: optlingu.cxx:1536
std::unique_ptr< weld::Button > m_xPrioDownPB
Definition: optlingu.hxx:57
const LanguageTag & GetLanguageTag() const
ImplSVEvent * m_nDlbClickEventId
Definition: optlingu.hxx:98
constexpr OUStringLiteral aData
constexpr OUStringLiteral UPN_IS_SPELL_WITH_DIGITS
virtual tools::Long GetValue() const override
static void lcl_MergeLocales(Sequence< Locale > &aAllLocales, const Sequence< Locale > &rAdd)
Definition: optlingu.cxx:465
static void RemoveUserEvent(ImplSVEvent *nUserEvent)
constexpr OUStringLiteral cGrammar(SN_GRAMMARCHECKER)
int nUPN_HYPH_MIN_LEADING
Definition: optlingu.hxx:95
LangImplNameTable & GetSpellTable()
Definition: optlingu.cxx:360
OUString CuiResId(TranslateId aKey)
Definition: cuiresmgr.cxx:23
OUString sGrammarAuto
Definition: optlingu.hxx:87
const SfxPoolItem * GetOldItem(const SfxItemSet &rSet, sal_uInt16 nSlot, bool bDeep=true)
sal_uInt16 char * pName
void SetDisplayServiceCount(sal_uInt32 nVal)
Definition: optlingu.cxx:368
#define TOOLS_WARN_EXCEPTION(area, stream)
SvxLinguTabPage(weld::Container *pPage, weld::DialogController *pController, const SfxItemSet &rCoreSet)
Definition: optlingu.cxx:822
constexpr OUStringLiteral UPN_HYPH_MIN_WORD_LENGTH
OUString sSpellAuto
Definition: optlingu.hxx:86
#define GROUP_MODULES
Definition: optlingu.hxx:41
SfxItemState GetItemState(sal_uInt16 nWhich, bool bSrchInParent=true, const SfxPoolItem **ppItem=nullptr) const
#define DBG_ASSERT(sCon, aError)
OUString sSpellSpecial
Definition: optlingu.hxx:85
int i
ServiceInfoArr & GetDisplayServiceArray()
Definition: optlingu.cxx:365
constexpr OUStringLiteral UPN_IS_HYPH_AUTO
std::vector< ServiceInfo_Impl > ServiceInfoArr
Definition: optlingu.cxx:327
TRISTATE_FALSE
std::unique_ptr< weld::TreeView > m_xLinguOptionsCLB
Definition: optlingu.hxx:119
std::unique_ptr< weld::TreeView > m_xLinguDicsCLB
Definition: optlingu.hxx:115
constexpr OUStringLiteral UPN_HYPH_MIN_LEADING
#define LANGUAGE_DONTKNOW
OUString aPropName
css::uno::Reference< css::linguistic2::XDictionaryList > xDicList
Definition: optlingu.hxx:104
LangImplNameTable aCfgGrammarTable
Definition: optlingu.cxx:343
std::unique_ptr< weld::Button > m_xBackPB
Definition: optlingu.hxx:58
#define UPH_ACTIVE_DICTIONARIES
void Reconfigure(std::u16string_view rDisplayName, bool bEnable)
Definition: optlingu.cxx:729
OUString sSpell
Definition: optlingu.hxx:47
int nUPN_HYPH_MIN_TRAILING
Definition: optlingu.hxx:96
IMPL_LINK_NOARG(SvxLinguTabPage, PostDblClickHdl_Impl, void *, void)
Definition: optlingu.cxx:1301
OUString GetMainURL(DecodeMechanism eMechanism, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
OUString sGrammar
Definition: optlingu.hxx:50
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
constexpr OUStringLiteral cSpell(SN_SPELLCHECKER)
LangImplNameTable aCfgHyphTable
Definition: optlingu.cxx:341
OUString sWordsWithDigits
Definition: optlingu.hxx:84
const sal_uInt32 & GetDisplayServiceCount() const
Definition: optlingu.cxx:367
LangImplNameTable aCfgThesTable
Definition: optlingu.cxx:342
const SfxPoolItem & Get(sal_uInt16 nWhich, bool bSrchInParent=true) const
OUString sCapitalWords
Definition: optlingu.hxx:83
unsigned char sal_uInt8
const Sequence< Locale > & GetAllSupportedLocales() const
Definition: optlingu.cxx:358
static sal_uInt32 GetDicUserData(const css::uno::Reference< css::linguistic2::XDictionary > &rxDic, sal_uInt16 nIdx)
Definition: optlingu.cxx:1063
#define SAL_INFO(area, stream)
static LanguageType getConfiguredSystemLanguage()
EID_OPTIONS
Definition: optlingu.cxx:183
INetProtocol GetProtocol() const
Sequence< Locale > aAllServiceLocales
Definition: optlingu.cxx:339
RET_OK
OUString sHyph
Definition: optlingu.hxx:48
Reference< XExecutableDialog > m_xDialog
bool SetProperty(const OUString &rPropertyName, const css::uno::Any &rValue)
std::unique_ptr< weld::Button > m_xLinguModulesEditPB
Definition: optlingu.hxx:113
constexpr OUStringLiteral UPN_IS_SPELL_AUTO
virtual short run()
Reference< XComponentContext > getProcessComponentContext()
QPRO_FUNC_TYPE nType
static void lcl_MergeDisplayArray(SvxLinguData_Impl &rData, const ServiceInfo_Impl &rToAdd)
Definition: optlingu.cxx:495
int nUPN_HYPH_MIN_WORD_LENGTH
Definition: optlingu.hxx:94
css::uno::Sequence< css::uno::Reference< css::linguistic2::XDictionary > > aDics
Definition: optlingu.hxx:107
virtual css::uno::Reference< css::linguistic2::XDictionary > GetNewDictionary()=0
static OUString lcl_GetPropertyName(EID_OPTIONS eEntryId)
Definition: optlingu.cxx:199
LangImplNameTable & GetHyphTable()
Definition: optlingu.cxx:361
virtual bool FillItemSet(SfxItemSet *rSet) override
Definition: optlingu.cxx:917
#define SAL_WARN(area, stream)
OUString sNumPostBreak
Definition: optlingu.hxx:90
css::uno::Any GetProperty(const OUString &rPropertyName) const
virtual void Reset(const SfxItemSet *rSet) override
Definition: optlingu.cxx:1149
sal_Int32 nLength
virtual ~SvxEditModulesDlg() override
Definition: optlingu.cxx:1598
std::unique_ptr< weld::Button > m_xLinguDicsEditPB
Definition: optlingu.hxx:117
void AddDicBoxEntry(const css::uno::Reference< css::linguistic2::XDictionary > &rxDic, sal_uInt16 nIdx)
Definition: optlingu.cxx:1082
void SetChecked(const Sequence< OUString > &rConfiguredServices)
Definition: optlingu.cxx:677
LangImplNameTable aCfgSpellTable
Definition: optlingu.cxx:340
uno::Reference< XLinguServiceManager2 > & GetManager()
Definition: optlingu.cxx:353
TriState
weld::Window * GetFrameWeld(const SfxFrame *pFrame)
ServiceInfo_Impl * GetInfoByImplName(std::u16string_view rSvcImplName)
Definition: optlingu.cxx:448
#define TYPE_SPELL
Definition: optlingu.cxx:114
css::uno::Reference< css::linguistic2::XLinguProperties > xProp
Definition: optlingu.hxx:101
OUString sNumPreBreak
Definition: optlingu.hxx:89
sal_uInt16 nPos
sal_uInt16 GetWhich(sal_uInt16 nSlot, bool bDeep=true) const
static std::unique_ptr< weld::Builder > CreateBuilder(weld::Widget *pParent, const OUString &rUIFile, bool bMobile=false, sal_uInt64 nLOKWindowId=0)
IMPL_LINK(SvxLinguTabPage, BoxDoubleClickHdl_Impl, weld::TreeView &, rBox, bool)
Definition: optlingu.cxx:1285
static css::lang::Locale convertToLocale(LanguageType nLangID, bool bResolveSystem=true)
OUString sDisplayName
LangImplNameTable & GetGrammarTable()
Definition: optlingu.cxx:363
OUString sId