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