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