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 <utility>
21#include <vcl/settings.hxx>
22#include <vcl/weld.hxx>
25#include <o3tl/safeint.hxx>
26#include <officecfg/Office/Security.hxx>
27#include <unotools/lingucfg.hxx>
29#include <editeng/unolingu.hxx>
30#include <linguistic/misc.hxx>
31#include <sfx2/sfxsids.hrc>
32#include <tools/debug.hxx>
33#include <tools/urlobj.hxx>
34#include <tools/diagnose_ex.h>
37#include <com/sun/star/linguistic2/LinguServiceManager.hpp>
38#include <com/sun/star/linguistic2/XSearchableDictionaryList.hpp>
39#include <com/sun/star/linguistic2/XSpellChecker.hpp>
40#include <com/sun/star/linguistic2/XProofreader.hpp>
41#include <com/sun/star/linguistic2/XHyphenator.hpp>
42#include <com/sun/star/linguistic2/XThesaurus.hpp>
43#include <com/sun/star/linguistic2/XDictionary.hpp>
44#include <com/sun/star/linguistic2/XDictionaryList.hpp>
45#include <com/sun/star/linguistic2/XLinguProperties.hpp>
46#include <com/sun/star/lang/XServiceDisplayName.hpp>
47#include <com/sun/star/frame/XStorable.hpp>
49#include <svl/eitem.hxx>
50#include <vcl/svapp.hxx>
51#include <sal/log.hxx>
52#include <osl/diagnose.h>
53
54#include <svx/svxdlg.hxx>
55#include <editeng/optitems.hxx>
56#include <optlingu.hxx>
57#include <dialmgr.hxx>
58#include <strings.hrc>
59
60#include <ucbhelper/content.hxx>
61
62#include <vector>
63#include <map>
64
65using namespace ::ucbhelper;
66using namespace ::com::sun::star;
67using namespace css::lang;
68using namespace css::uno;
69using namespace css::linguistic2;
70using namespace css::beans;
71
72constexpr OUStringLiteral cSpell(SN_SPELLCHECKER);
73constexpr OUStringLiteral cGrammar(SN_GRAMMARCHECKER);
74constexpr OUStringLiteral cHyph(SN_HYPHENATOR);
75constexpr OUStringLiteral cThes(SN_THESAURUS);
76
77// static ----------------------------------------------------------------
78
79static sal_Int32 lcl_SeqGetEntryPos(
80 const Sequence< OUString > &rSeq, std::u16string_view rEntry )
81{
82 sal_Int32 i;
83 sal_Int32 nLen = rSeq.getLength();
84 const OUString *pItem = rSeq.getConstArray();
85 for (i = 0; i < nLen; ++i)
86 {
87 if (rEntry == pItem[i])
88 break;
89 }
90 return i < nLen ? i : -1;
91}
92
93static bool KillFile_Impl( const OUString& rURL )
94{
95 bool bRet = true;
96 try
97 {
99 aCnt.executeCommand( "delete", Any( true ) );
100 }
101 catch( ... )
102 {
103 TOOLS_WARN_EXCEPTION( "cui.options", "KillFile" );
104 bRet = false;
105 }
106
107 return bRet;
108}
109
110// 0x 0p 0t 0c nn
111// p: 1 -> parent
112// t: 1 -> spell, 2 -> hyph, 3 -> thes, 4 -> grammar
113// c: 1 -> checked 0 -> unchecked
114// n: index
115
116#define TYPE_SPELL sal_uInt8(1)
117#define TYPE_GRAMMAR sal_uInt8(2)
118#define TYPE_HYPH sal_uInt8(3)
119#define TYPE_THES sal_uInt8(4)
120
121namespace {
122
123class ModuleUserData_Impl
124{
125 bool bParent;
126 bool bIsChecked;
129 OUString sImplName;
130
131public:
132 ModuleUserData_Impl( OUString sImpName, bool bIsParent, bool bChecked, sal_uInt8 nSetType, sal_uInt8 nSetIndex ) :
133 bParent(bIsParent),
134 bIsChecked(bChecked),
135 nType(nSetType),
136 nIndex(nSetIndex),
137 sImplName(std::move(sImpName))
138 {
139 }
140 bool IsParent() const {return bParent;}
141 sal_uInt8 GetType() const {return nType;}
142 bool IsChecked() const {return bIsChecked;}
143 sal_uInt8 GetIndex() const {return nIndex;}
144 const OUString& GetImplName() const {return sImplName;}
145
146};
147
148
149// User for user-dictionaries (XDictionary interface)
150
151class DicUserData
152{
153 sal_uInt32 nVal;
154
155public:
156 explicit DicUserData(sal_uInt32 nUserData) : nVal( nUserData ) {}
157 DicUserData( sal_uInt16 nEID,
158 bool bChecked, bool bEditable, bool bDeletable );
159
160 sal_uInt32 GetUserData() const { return nVal; }
161 sal_uInt16 GetEntryId() const { return static_cast<sal_uInt16>(nVal >> 16); }
162 bool IsChecked() const { return static_cast<bool>((nVal >> 8) & 0x01); }
163 bool IsDeletable() const { return static_cast<bool>((nVal >> 10) & 0x01); }
164};
165
166}
167
168DicUserData::DicUserData(
169 sal_uInt16 nEID,
170 bool bChecked, bool bEditable, bool bDeletable )
171{
172 DBG_ASSERT( nEID < 65000, "Entry Id out of range" );
173 nVal = (static_cast<sal_uInt32>(0xFFFF & nEID) << 16) |
174 (static_cast<sal_uInt32>(bChecked ? 1 : 0) << 8) |
175 (static_cast<sal_uInt32>(bEditable ? 1 : 0) << 9) |
176 (static_cast<sal_uInt32>(bDeletable ? 1 : 0) << 10);
177}
178
179/*--------------------------------------------------
180 Entry IDs for options listbox of dialog
181--------------------------------------------------*/
182
183namespace {
184
185enum EID_OPTIONS
186{
187 EID_SPELL_AUTO,
188 EID_GRAMMAR_AUTO,
189 EID_CAPITAL_WORDS,
190 EID_WORDS_WITH_DIGITS,
191 EID_SPELL_SPECIAL,
192 EID_NUM_MIN_WORDLEN,
193 EID_NUM_PRE_BREAK,
194 EID_NUM_POST_BREAK,
195 EID_HYPH_AUTO,
196 EID_HYPH_SPECIAL
197};
198
199}
200
201static OUString lcl_GetPropertyName( EID_OPTIONS eEntryId )
202{
203 switch (eEntryId)
204 {
205 case EID_SPELL_AUTO: return UPN_IS_SPELL_AUTO;
206 case EID_GRAMMAR_AUTO: return UPN_IS_GRAMMAR_AUTO;
207 case EID_CAPITAL_WORDS: return UPN_IS_SPELL_UPPER_CASE;
208 case EID_WORDS_WITH_DIGITS: return UPN_IS_SPELL_WITH_DIGITS;
209 case EID_SPELL_SPECIAL: return UPN_IS_SPELL_SPECIAL;
210 case EID_NUM_MIN_WORDLEN: return UPN_HYPH_MIN_WORD_LENGTH;
211 case EID_NUM_PRE_BREAK: return UPN_HYPH_MIN_LEADING;
212 case EID_NUM_POST_BREAK: return UPN_HYPH_MIN_TRAILING;
213 case EID_HYPH_AUTO: return UPN_IS_HYPH_AUTO;
214 case EID_HYPH_SPECIAL: return UPN_IS_HYPH_SPECIAL;
215 default: assert (false); abort();
216 }
217}
218
219namespace {
220
221class 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
228public:
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
262class OptionsUserData
263{
264 sal_uInt32 nVal;
265
266public:
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
284OptionsUserData::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
297void 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
309namespace {
310
311struct ServiceInfo_Impl
312{
313 OUString sDisplayName;
314 OUString sSpellImplName;
315 OUString sHyphImplName;
316 OUString sThesImplName;
317 OUString sGrammarImplName;
322 bool bConfigured;
323
324 ServiceInfo_Impl() : bConfigured(false) {}
325};
326
327}
328
329typedef std::vector< ServiceInfo_Impl > ServiceInfoArr;
330typedef std::map< LanguageType, Sequence< OUString > > LangImplNameTable;
331
332
333// SvxLinguData_Impl ----------------------------------------------------
334
336{
337 //contains services and implementation names sorted by implementation names
340
341 Sequence< Locale > aAllServiceLocales;
347
348
349 static bool AddRemove( Sequence< OUString > &rConfigured,
350 const OUString &rImplName, bool bAdd );
351
352public:
354
356
357 void SetChecked( const Sequence< OUString > &rConfiguredServices );
358 void Reconfigure( std::u16string_view rDisplayName, bool bEnable );
359
360 const Sequence<Locale> & GetAllSupportedLocales() const { return aAllServiceLocales; }
361
366
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.
380
381 ServiceInfo_Impl * GetInfoByImplName( std::u16string_view rSvcImplName );
382};
383
384
385static sal_Int32 lcl_SeqGetIndex( const Sequence< OUString > &rSeq, std::u16string_view 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( nDisplayServices >= o3tl::make_unsigned(nIdx), "size mismatch" );
419 aRes.realloc( nDisplayServices );
420 OUString *pRes = aRes.getArray();
421
422 // add not configured services
423 for (sal_uInt32 i = 0; i < 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
450ServiceInfo_Impl * SvxLinguData_Impl::GetInfoByImplName( std::u16string_view 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
467static 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
679void 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
731void SvxLinguData_Impl::Reconfigure( std::u16string_view rDisplayName, bool bEnable )
732{
733 DBG_ASSERT( !rDisplayName.empty(), "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 {
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 {
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 {
797 if (!aCfgHyphTable.count( nLang ) && bEnable)
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 {
814 if (!aCfgThesTable.count( nLang ) && bEnable)
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_CUISTR_CAPITAL_WORDS))
827 , sWordsWithDigits(CuiResId(RID_CUISTR_WORDS_WITH_DIGITS))
828 , sSpellSpecial (CuiResId(RID_CUISTR_SPELL_SPECIAL))
829 , sSpellAuto (CuiResId(RID_CUISTR_SPELL_AUTO))
830 , sGrammarAuto (CuiResId(RID_CUISTR_GRAMMAR_AUTO))
831 , sNumMinWordlen (CuiResId(RID_CUISTR_NUM_MIN_WORDLEN))
832 , sNumPreBreak (CuiResId(RID_CUISTR_NUM_PRE_BREAK))
833 , sNumPostBreak (CuiResId(RID_CUISTR_NUM_POST_BREAK))
834 , sHyphAuto (CuiResId(RID_CUISTR_HYPH_AUTO))
835 , sHyphSpecial (CuiResId(RID_CUISTR_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{
853 m_xLinguDicsCLB->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 m_xMoreDictsLink->connect_activate_link(LINK(this, SvxLinguTabPage, OnLinkClick));
874 if (officecfg::Office::Security::Hyperlinks::Open::get() == SvtExtendedSecurityOptions::OPEN_NEVER)
875 m_xMoreDictsLink->hide();
876
879 if (xDicList.is())
880 {
881 // keep references to all **currently** available dictionaries,
882 // since the diclist may get changed meanwhile (e.g. through the API).
883 // We want the dialog to operate on the same set of dictionaries it
884 // was started with.
885 // Also we have to take care to not lose the last reference when
886 // someone else removes a dictionary from the list.
887 // removed dics will be replaced by NULL new entries be added to the end
888 // Thus we may use indices as consistent references.
889 aDics = xDicList->getDictionaries();
890
892 }
893 else
894 {
895 m_xLinguDicsFT->set_sensitive(false);
896 m_xLinguDicsCLB->set_sensitive(false);
897 m_xLinguDicsNewPB->set_sensitive(false);
898 m_xLinguDicsEditPB->set_sensitive(false);
899 m_xLinguDicsDelPB->set_sensitive(false);
900 }
901}
902
904{
906 {
908 m_nDlbClickEventId = nullptr;
909 }
910 pLinguData.reset();
911}
912
913std::unique_ptr<SfxTabPage> SvxLinguTabPage::Create( weld::Container* pPage, weld::DialogController* pController,
914 const SfxItemSet* rAttrSet )
915{
916 return std::make_unique<SvxLinguTabPage>( pPage, pController, *rAttrSet );
917}
918
920{
921 bool bModified = true; // !!!!
922
923 // if not HideGroups was called with GROUP_MODULES...
924 if (m_xLinguModulesCLB->get_visible())
925 {
926 DBG_ASSERT( pLinguData, "pLinguData not yet initialized" );
927 if (!pLinguData)
928 pLinguData.reset( new SvxLinguData_Impl );
929
930 // update spellchecker configuration entries
931 const LangImplNameTable *pTable = &pLinguData->GetSpellTable();
932 for (auto const& elem : *pTable)
933 {
934 LanguageType nLang = elem.first;
935 const Sequence< OUString > aImplNames(elem.second);
937 Locale aLocale( LanguageTag::convertToLocale(nLang) );
938 if (xMgr.is())
939 xMgr->setConfiguredServices( cSpell, aLocale, aImplNames );
940 }
941
942 // update grammar checker configuration entries
943 pTable = &pLinguData->GetGrammarTable();
944 for (auto const& elem : *pTable)
945 {
946 LanguageType nLang = elem.first;
947 const Sequence< OUString > aImplNames(elem.second);
949 Locale aLocale( LanguageTag::convertToLocale(nLang) );
950 if (xMgr.is())
951 xMgr->setConfiguredServices( cGrammar, aLocale, aImplNames );
952 }
953
954 // update hyphenator configuration entries
955 pTable = &pLinguData->GetHyphTable();
956 for (auto const& elem : *pTable)
957 {
958 LanguageType nLang = elem.first;
959 const Sequence< OUString > aImplNames(elem.second);
961 Locale aLocale( LanguageTag::convertToLocale(nLang) );
962 if (xMgr.is())
963 xMgr->setConfiguredServices( cHyph, aLocale, aImplNames );
964 }
965
966 // update thesaurus configuration entries
967 pTable = &pLinguData->GetThesTable();
968 for (auto const& elem : *pTable)
969 {
970 LanguageType nLang = elem.first;
971 const Sequence< OUString > aImplNames(elem.second);
973 Locale aLocale( LanguageTag::convertToLocale(nLang) );
974 if (xMgr.is())
975 xMgr->setConfiguredServices( cThes, aLocale, aImplNames );
976 }
977 }
978
979
980 // activate dictionaries according to checkbox state
981
982 Sequence< OUString > aActiveDics;
983 sal_Int32 nActiveDics = 0;
984 int nEntries = m_xLinguDicsCLB->n_children();
985 for (int i = 0; i < nEntries; ++i)
986 {
987 sal_Int32 nDics = aDics.getLength();
988
989 aActiveDics.realloc( nDics );
990 OUString *pActiveDic = aActiveDics.getArray();
991
992 DicUserData aData(m_xLinguDicsCLB->get_id(i).toUInt32());
993 if (aData.GetEntryId() < nDics)
994 {
995 bool bChecked = m_xLinguDicsCLB->get_toggle(i) == TRISTATE_TRUE;
996 uno::Reference< XDictionary > xDic( aDics.getConstArray()[ i ] );
997 if (xDic.is())
998 {
999 if (LinguMgr::GetIgnoreAllList() == xDic)
1000 bChecked = true;
1001 xDic->setActive( bChecked );
1002
1003 if (bChecked)
1004 {
1005 OUString aDicName( xDic->getName() );
1006 pActiveDic[ nActiveDics++ ] = aDicName;
1007 }
1008 }
1009 }
1010 }
1011
1012 aActiveDics.realloc( nActiveDics );
1013 Any aTmp;
1014 aTmp <<= aActiveDics;
1015 SvtLinguConfig aLngCfg;
1016 aLngCfg.SetProperty( UPH_ACTIVE_DICTIONARIES, aTmp );
1017
1018
1019 nEntries = m_xLinguOptionsCLB->n_children();
1020 for (int j = 0; j < nEntries; ++j)
1021 {
1022 OptionsUserData aData(m_xLinguOptionsCLB->get_id(j).toUInt32());
1023 OUString aPropName( lcl_GetPropertyName( static_cast<EID_OPTIONS>(aData.GetEntryId()) ) );
1024
1025 Any aAny;
1026 if (aData.IsCheckable())
1027 {
1028 bool bChecked = m_xLinguOptionsCLB->get_toggle(j) == TRISTATE_TRUE;
1029 aAny <<= bChecked;
1030 }
1031 else if (aData.HasNumericValue())
1032 {
1033 sal_Int16 nVal = aData.GetNumericValue();
1034 aAny <<= nVal;
1035 }
1036
1037 if (xProp.is())
1038 xProp->setPropertyValue( aPropName, aAny );
1039 aLngCfg.SetProperty( aPropName, aAny );
1040 }
1041
1042 OptionsUserData aPreBreakData(m_xLinguOptionsCLB->get_id(EID_NUM_PRE_BREAK).toUInt32());
1043 OptionsUserData aPostBreakData(m_xLinguOptionsCLB->get_id(EID_NUM_POST_BREAK).toUInt32());
1044 if ( aPreBreakData.IsModified() || aPostBreakData.IsModified() )
1045 {
1046 SfxHyphenRegionItem aHyp( SID_ATTR_HYPHENREGION );
1047 aHyp.GetMinLead() = static_cast<sal_uInt8>(aPreBreakData.GetNumericValue());
1048 aHyp.GetMinTrail() = static_cast<sal_uInt8>(aPostBreakData.GetNumericValue());
1049 rCoreSet->Put( aHyp );
1050 }
1051
1052 // automatic spell checking
1053 bool bNewAutoCheck = m_xLinguOptionsCLB->get_toggle(EID_SPELL_AUTO) == TRISTATE_TRUE;
1054 const SfxPoolItem* pOld = GetOldItem( *rCoreSet, SID_AUTOSPELL_CHECK );
1055 if ( !pOld || static_cast<const SfxBoolItem*>(pOld)->GetValue() != bNewAutoCheck )
1056 {
1057 rCoreSet->Put( SfxBoolItem( SID_AUTOSPELL_CHECK, bNewAutoCheck ) );
1058 bModified = true;
1059 }
1060
1061 return bModified;
1062}
1063
1064sal_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, weld::toId(&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));
1227
1228 const SfxHyphenRegionItem *pHyp = nullptr;
1229 if ( rSet->GetItemState( SID_ATTR_HYPHENREGION, false ) == SfxItemState::SET )
1230 pHyp = & rSet->Get( SID_ATTR_HYPHENREGION );
1231
1232 m_xLinguOptionsCLB->append();
1233 ++nEntry;
1234
1235 aLngCfg.GetProperty( UPN_HYPH_MIN_LEADING ) >>= nVal;
1236 if (pHyp)
1237 nVal = static_cast<sal_Int16>(pHyp->GetMinLead());
1238 nUserData = OptionsUserData( EID_NUM_PRE_BREAK, true, static_cast<sal_uInt16>(nVal), false, false).GetUserData();
1239 m_xLinguOptionsCLB->set_text(nEntry, sNumPreBreak + " " + OUString::number(nVal), 0);
1240 m_xLinguOptionsCLB->set_id(nEntry, OUString::number(nUserData));
1241 nUPN_HYPH_MIN_LEADING = nEntry;
1242
1243 m_xLinguOptionsCLB->append();
1244 ++nEntry;
1245
1246 aLngCfg.GetProperty( UPN_HYPH_MIN_TRAILING ) >>= nVal;
1247 if (pHyp)
1248 nVal = static_cast<sal_Int16>(pHyp->GetMinTrail());
1249 nUserData = OptionsUserData( EID_NUM_POST_BREAK, true, static_cast<sal_uInt16>(nVal), false, false).GetUserData();
1250 m_xLinguOptionsCLB->set_text(nEntry, sNumPostBreak + " " + OUString::number(nVal), 0);
1251 m_xLinguOptionsCLB->set_id(nEntry, OUString::number(nUserData));
1252 nUPN_HYPH_MIN_TRAILING = nEntry;
1253
1254 m_xLinguOptionsCLB->append();
1255 ++nEntry;
1256
1257 aLngCfg.GetProperty( UPN_IS_HYPH_AUTO ) >>= bVal;
1258 nUserData = OptionsUserData( EID_HYPH_AUTO, false, 0, true, bVal).GetUserData();
1259 m_xLinguOptionsCLB->set_toggle(nEntry, bVal ? TRISTATE_TRUE : TRISTATE_FALSE);
1260 m_xLinguOptionsCLB->set_text(nEntry, sHyphAuto, 0);
1261 m_xLinguOptionsCLB->set_id(nEntry, OUString::number(nUserData));
1262
1263 m_xLinguOptionsCLB->append();
1264 ++nEntry;
1265
1266 aLngCfg.GetProperty( UPN_IS_HYPH_SPECIAL ) >>= bVal;
1267 nUserData = OptionsUserData( EID_HYPH_SPECIAL, false, 0, true, bVal).GetUserData();
1268 m_xLinguOptionsCLB->set_toggle(nEntry, bVal ? TRISTATE_TRUE : TRISTATE_FALSE);
1269 m_xLinguOptionsCLB->set_text(nEntry, sHyphSpecial, 0);
1270 m_xLinguOptionsCLB->set_id(nEntry, OUString::number(nUserData));
1271
1272 m_xLinguOptionsCLB->thaw();
1273
1274 m_xLinguOptionsCLB->select(0);
1275 SelectHdl_Impl(*m_xLinguOptionsCLB);
1276
1277 m_xLinguModulesCLB->set_size_request(m_xLinguModulesCLB->get_preferred_size().Width(),
1278 m_xLinguModulesCLB->get_height_rows(3));
1279 m_xLinguDicsCLB->set_size_request(m_xLinguDicsCLB->get_preferred_size().Width(),
1280 m_xLinguDicsCLB->get_height_rows(5));
1281 m_xLinguOptionsCLB->set_size_request(m_xLinguOptionsCLB->get_preferred_size().Width(),
1282 m_xLinguOptionsCLB->get_height_rows(5));
1283}
1284
1285IMPL_LINK(SvxLinguTabPage, BoxDoubleClickHdl_Impl, weld::TreeView&, rBox, bool)
1286{
1287 if (&rBox == m_xLinguModulesCLB.get() && !m_nDlbClickEventId)
1288 {
1292 m_nDlbClickEventId = Application::PostUserEvent(LINK(this, SvxLinguTabPage, PostDblClickHdl_Impl));
1293 }
1294 else if (&rBox == m_xLinguOptionsCLB.get())
1295 {
1296 ClickHdl_Impl(*m_xLinguOptionsEditPB);
1297 }
1298 return true;
1299}
1300
1301IMPL_LINK_NOARG(SvxLinguTabPage, PostDblClickHdl_Impl, void*, void)
1302{
1303 m_nDlbClickEventId = nullptr;
1304 ClickHdl_Impl(*m_xLinguModulesEditPB);
1305}
1306
1307IMPL_LINK(SvxLinguTabPage, ModulesBoxCheckButtonHdl_Impl, const weld::TreeView::iter_col&, rRowCol, void)
1308{
1309 if (!pLinguData)
1310 return;
1311 pLinguData->Reconfigure(m_xLinguModulesCLB->get_text(rRowCol.first),
1312 m_xLinguModulesCLB->get_toggle(rRowCol.first) == TRISTATE_TRUE);
1313}
1314
1315IMPL_LINK(SvxLinguTabPage, DicsBoxCheckButtonHdl_Impl, const weld::TreeView::iter_col&, rRowCol, void)
1316{
1317 const uno::Reference<XDictionary> &rDic = aDics.getConstArray()[m_xLinguDicsCLB->get_iter_index_in_parent(rRowCol.first)];
1318 if (LinguMgr::GetIgnoreAllList() == rDic)
1319 m_xLinguDicsCLB->set_toggle(rRowCol.first, TRISTATE_TRUE);
1320}
1321
1322IMPL_LINK(SvxLinguTabPage, ClickHdl_Impl, weld::Button&, rBtn, void)
1323{
1324 if (m_xLinguModulesEditPB.get() == &rBtn)
1325 {
1326 if (!pLinguData)
1327 pLinguData.reset( new SvxLinguData_Impl );
1328
1329 SvxLinguData_Impl aOldLinguData( *pLinguData );
1330 SvxEditModulesDlg aDlg(GetFrameWeld(), *pLinguData);
1331 if (aDlg.run() != RET_OK)
1332 *pLinguData = aOldLinguData;
1333
1334 // evaluate new status of 'bConfigured' flag
1335 sal_uInt32 nLen = pLinguData->GetDisplayServiceCount();
1336 for (sal_uInt32 i = 0; i < nLen; ++i)
1337 pLinguData->GetDisplayServiceArray()[i].bConfigured = false;
1338 const Locale* pAllLocales = pLinguData->GetAllSupportedLocales().getConstArray();
1339 sal_Int32 nLocales = pLinguData->GetAllSupportedLocales().getLength();
1340 for (sal_Int32 k = 0; k < nLocales; ++k)
1341 {
1342 LanguageType nLang = LanguageTag::convertToLanguageType( pAllLocales[k] );
1343 if (pLinguData->GetSpellTable().count( nLang ))
1344 pLinguData->SetChecked( pLinguData->GetSpellTable()[ nLang ] );
1345 if (pLinguData->GetGrammarTable().count( nLang ))
1346 pLinguData->SetChecked( pLinguData->GetGrammarTable()[ nLang ] );
1347 if (pLinguData->GetHyphTable().count( nLang ))
1348 pLinguData->SetChecked( pLinguData->GetHyphTable()[ nLang ] );
1349 if (pLinguData->GetThesTable().count( nLang ))
1350 pLinguData->SetChecked( pLinguData->GetThesTable()[ nLang ] );
1351 }
1352
1353 // show new status of modules
1354 UpdateModulesBox_Impl();
1355 }
1356 else if (m_xLinguDicsNewPB.get() == &rBtn)
1357 {
1361 if ( aDlg->Execute() == RET_OK )
1362 xNewDic = aDlg->GetNewDictionary();
1363 if ( xNewDic.is() )
1364 {
1365 // add new dics to the end
1366 sal_Int32 nLen = aDics.getLength();
1367 aDics.realloc( nLen + 1 );
1368
1369 aDics.getArray()[ nLen ] = xNewDic;
1370
1371 AddDicBoxEntry( xNewDic, static_cast<sal_uInt16>(nLen) );
1372 }
1373 }
1374 else if (m_xLinguDicsEditPB.get() == &rBtn)
1375 {
1376 int nEntry = m_xLinguDicsCLB->get_selected_index();
1377 if (nEntry != -1)
1378 {
1379 DicUserData aData(m_xLinguDicsCLB->get_id(nEntry).toUInt32());
1380 sal_uInt16 nDicPos = aData.GetEntryId();
1381 sal_Int32 nDics = aDics.getLength();
1382 if (nDicPos < nDics)
1383 {
1384 uno::Reference< XDictionary > xDic = aDics.getConstArray()[ nDicPos ];
1385 if (xDic.is())
1386 {
1389 aDlg->Execute();
1390 }
1391 }
1392 }
1393 }
1394 else if (m_xLinguDicsDelPB.get() == &rBtn)
1395 {
1396 std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/querydeletedictionarydialog.ui"));
1397 std::unique_ptr<weld::MessageDialog> xQuery(xBuilder->weld_message_dialog("QueryDeleteDictionaryDialog"));
1398 if (RET_NO == xQuery->run())
1399 return;
1400
1401 int nEntry = m_xLinguDicsCLB->get_selected_index();
1402 if (nEntry != -1)
1403 {
1404 DicUserData aData(m_xLinguDicsCLB->get_id(nEntry).toUInt32());
1405 sal_uInt16 nDicPos = aData.GetEntryId();
1406 sal_Int32 nDics = aDics.getLength();
1407 if (nDicPos < nDics)
1408 {
1409 uno::Reference< XDictionary > xDic = aDics.getConstArray()[ nDicPos ];
1410 if (xDic.is())
1411 {
1412 if (LinguMgr::GetIgnoreAllList() == xDic)
1413 xDic->clear();
1414 else
1415 {
1416 if (xDicList.is())
1417 xDicList->removeDictionary( xDic );
1418
1419 uno::Reference< frame::XStorable > xStor( xDic, UNO_QUERY );
1420 if ( xStor->hasLocation() && !xStor->isReadonly() )
1421 {
1422 OUString sURL = xStor->getLocation();
1423 INetURLObject aObj(sURL);
1424 DBG_ASSERT( aObj.GetProtocol() == INetProtocol::File,
1425 "non-file URLs cannot be deleted" );
1426 if ( aObj.GetProtocol() == INetProtocol::File )
1427 {
1429 }
1430 }
1431
1432 aDics.getArray()[ nDicPos ] = nullptr;
1433
1434 // remove entry from checklistbox
1435 int nCnt = m_xLinguDicsCLB->n_children();
1436 for (int i = 0; i < nCnt; ++i)
1437 {
1438 DicUserData aDicData(m_xLinguDicsCLB->get_id(i).toUInt32());
1439 if (aDicData.GetEntryId() == nDicPos )
1440 {
1441 m_xLinguDicsCLB->remove(i);
1442 break;
1443 }
1444 }
1445 DBG_ASSERT( nCnt > m_xLinguDicsCLB->n_children(),
1446 "remove failed ?");
1447 }
1448 }
1449 }
1450 }
1451 }
1452 else if (m_xLinguOptionsEditPB.get() == &rBtn)
1453 {
1454 int nEntry = m_xLinguOptionsCLB->get_selected_index();
1455 DBG_ASSERT(nEntry != -1, "no entry selected");
1456 if (nEntry != -1)
1457 {
1458 OptionsUserData aData(m_xLinguOptionsCLB->get_id(nEntry).toUInt32());
1459 if (aData.HasNumericValue())
1460 {
1461 sal_uInt16 nRID = aData.GetEntryId();
1462 OptionsBreakSet aDlg(GetFrameWeld(), nRID);
1463 aDlg.GetNumericFld().set_value(aData.GetNumericValue());
1464 if (RET_OK == aDlg.run())
1465 {
1466 int nVal = aDlg.GetNumericFld().get_value();
1467 if (-1 != nVal && aData.GetNumericValue() != nVal)
1468 {
1469 aData.SetNumericValue( static_cast<sal_uInt8>(nVal) );
1470 m_xLinguOptionsCLB->set_id(nEntry, OUString::number(aData.GetUserData()));
1471 if (nEntry == nUPN_HYPH_MIN_WORD_LENGTH)
1472 m_xLinguOptionsCLB->set_text(nEntry, sNumMinWordlen + " " + OUString::number(nVal), 0);
1473 else if (nEntry == nUPN_HYPH_MIN_LEADING)
1474 m_xLinguOptionsCLB->set_text(nEntry, sNumPreBreak + " " + OUString::number(nVal), 0);
1475 else if (nEntry == nUPN_HYPH_MIN_TRAILING)
1476 m_xLinguOptionsCLB->set_text(nEntry, sNumPostBreak + " " + OUString::number(nVal), 0);
1477 m_xLinguOptionsCLB->set_id(nEntry, OUString::number(aData.GetUserData()));
1478 }
1479 }
1480 }
1481 }
1482 }
1483 else
1484 {
1485 OSL_FAIL( "rBtn unexpected value" );
1486 }
1487}
1488
1489IMPL_LINK(SvxLinguTabPage, SelectHdl_Impl, weld::TreeView&, rBox, void)
1490{
1491 if (m_xLinguModulesCLB.get() == &rBox)
1492 {
1493 }
1494 else if (m_xLinguDicsCLB.get() == &rBox)
1495 {
1496 int nEntry = rBox.get_selected_index();
1497 if (nEntry != -1)
1498 {
1499 DicUserData aData(rBox.get_id(nEntry).toUInt32());
1500
1501 // always allow to edit (i.e. at least view the content of the dictionary)
1502 m_xLinguDicsEditPB->set_sensitive( true );
1503 m_xLinguDicsDelPB->set_sensitive( aData.IsDeletable() );
1504 }
1505 }
1506 else if (m_xLinguOptionsCLB.get() == &rBox)
1507 {
1508 int nEntry = rBox.get_selected_index();
1509 if (nEntry != -1)
1510 {
1511 OptionsUserData aData(rBox.get_id(nEntry).toUInt32());
1512 m_xLinguOptionsEditPB->set_sensitive( aData.HasNumericValue() );
1513 }
1514 }
1515 else
1516 {
1517 OSL_FAIL( "rBox unexpected value" );
1518 }
1519}
1520
1521void SvxLinguTabPage::HideGroups( sal_uInt16 nGrp )
1522{
1523 if ( 0 != ( GROUP_MODULES & nGrp ) )
1524 {
1525 m_xLinguModulesFT->hide();
1526 m_xLinguModulesCLB->hide();
1527 m_xLinguModulesEditPB->hide();
1528
1529 if (officecfg::Office::Security::Hyperlinks::Open::get() != SvtExtendedSecurityOptions::OPEN_NEVER)
1530 {
1531 m_xMoreDictsLink->show();
1532 }
1533 }
1534}
1535
1537{
1538 comphelper::dispatchCommand(".uno:MoreDictionaries", {});
1539 return true;
1540}
1541
1543 : GenericDialogController(pParent, "cui/ui/editmodulesdialog.ui", "EditModulesDialog")
1544 , sSpell(CuiResId(RID_CUISTR_SPELL))
1545 , sHyph(CuiResId(RID_CUISTR_HYPH))
1546 , sThes(CuiResId(RID_CUISTR_THES))
1547 , sGrammar(CuiResId(RID_CUISTR_GRAMMAR))
1548 , rLinguData(rData)
1549 , m_xModulesCLB(m_xBuilder->weld_tree_view("lingudicts"))
1550 , m_xPrioUpPB(m_xBuilder->weld_button("up"))
1551 , m_xPrioDownPB(m_xBuilder->weld_button("down"))
1552 , m_xBackPB(m_xBuilder->weld_button("back"))
1553 , m_xMoreDictsLink(m_xBuilder->weld_link_button("moredictslink"))
1554 , m_xClosePB(m_xBuilder->weld_button("close"))
1555 , m_xLanguageLB(new SvxLanguageBox(m_xBuilder->weld_combo_box("language")))
1556{
1557 m_xModulesCLB->set_size_request(m_xModulesCLB->get_approximate_digit_width() * 40,
1558 m_xModulesCLB->get_height_rows(12));
1559
1560 m_xModulesCLB->enable_toggle_buttons(weld::ColumnToggleType::Check);
1561
1563
1564 m_xModulesCLB->connect_changed( LINK( this, SvxEditModulesDlg, SelectHdl_Impl ));
1565 m_xModulesCLB->connect_toggled(LINK(this, SvxEditModulesDlg, BoxCheckButtonHdl_Impl));
1566
1567 m_xClosePB->connect_clicked( LINK( this, SvxEditModulesDlg, ClickHdl_Impl ));
1568 m_xPrioUpPB->connect_clicked( LINK( this, SvxEditModulesDlg, UpDownHdl_Impl ));
1569 m_xPrioDownPB->connect_clicked( LINK( this, SvxEditModulesDlg, UpDownHdl_Impl ));
1570 m_xBackPB->connect_clicked( LINK( this, SvxEditModulesDlg, BackHdl_Impl ));
1571 // in case of not installed language modules
1572 m_xPrioUpPB->set_sensitive( false );
1573 m_xPrioDownPB->set_sensitive( false );
1574
1575 m_xMoreDictsLink->connect_activate_link(LINK(this, SvxEditModulesDlg, OnLinkClick));
1576 if (officecfg::Office::Security::Hyperlinks::Open::get() == SvtExtendedSecurityOptions::OPEN_NEVER)
1577 m_xMoreDictsLink->hide();
1578
1579 // set that we want the checkbox shown if spellchecking is available
1580 m_xLanguageLB->SetLanguageList(SvxLanguageListFlags::EMPTY, false, false, true);
1581
1582 //fill language box
1583 const Sequence< Locale >& rLoc = rLinguData.GetAllSupportedLocales();
1584 for (Locale const & locale : rLoc)
1585 {
1587 m_xLanguageLB->InsertLanguage(nLang);
1588 }
1590 m_xLanguageLB->set_active_id( eSysLang );
1591 if (m_xLanguageLB->get_active_id() != eSysLang)
1592 m_xLanguageLB->set_active(0);
1593
1594 m_xLanguageLB->connect_changed( LINK( this, SvxEditModulesDlg, LangSelectListBoxHdl_Impl ));
1596}
1597
1599{
1600 for (int i = 0, nEntryCount = m_xModulesCLB->n_children(); i < nEntryCount; ++i)
1601 delete weld::fromId<ModuleUserData_Impl*>(m_xModulesCLB->get_id(i));
1602}
1603
1604IMPL_LINK( SvxEditModulesDlg, SelectHdl_Impl, weld::TreeView&, rBox, void )
1605{
1606 int nCurPos = rBox.get_selected_index();
1607 if (nCurPos == -1)
1608 return;
1609
1610 bool bDisableUp = true;
1611 bool bDisableDown = true;
1612 ModuleUserData_Impl* pData = weld::fromId<ModuleUserData_Impl*>(rBox.get_id(nCurPos));
1613 if (!pData->IsParent() && pData->GetType() != TYPE_HYPH)
1614 {
1615 if (nCurPos < rBox.n_children() - 1)
1616 {
1617 bDisableDown = weld::fromId<ModuleUserData_Impl*>(rBox.get_id(nCurPos + 1))->IsParent();
1618 }
1619 if (nCurPos > 1)
1620 {
1621 bDisableUp = weld::fromId<ModuleUserData_Impl*>(rBox.get_id(nCurPos - 1))->IsParent();
1622 }
1623 }
1624 m_xPrioUpPB->set_sensitive(!bDisableUp);
1625 m_xPrioDownPB->set_sensitive(!bDisableDown);
1626}
1627
1628IMPL_LINK( SvxEditModulesDlg, BoxCheckButtonHdl_Impl, const weld::TreeView::iter_col&, rRowCol, void )
1629{
1630 ModuleUserData_Impl* pData = weld::fromId<ModuleUserData_Impl*>(m_xModulesCLB->get_id(rRowCol.first));
1631 if (pData->IsParent() || pData->GetType() != TYPE_HYPH)
1632 return;
1633
1634 // make hyphenator checkboxes function as radio-buttons
1635 // (at most one box may be checked)
1636 auto nPos = m_xModulesCLB->get_iter_index_in_parent(rRowCol.first);
1637 for (int i = 0, nEntryCount = m_xModulesCLB->n_children(); i < nEntryCount; ++i)
1638 {
1639 pData = weld::fromId<ModuleUserData_Impl*>(m_xModulesCLB->get_id(i));
1640 if (!pData->IsParent() && pData->GetType() == TYPE_HYPH && i != nPos)
1641 {
1642 m_xModulesCLB->set_toggle(i, TRISTATE_FALSE);
1643 }
1644 }
1645}
1646
1647IMPL_LINK_NOARG(SvxEditModulesDlg, LangSelectListBoxHdl_Impl, weld::ComboBox&, void)
1648{
1649 LangSelectHdl_Impl(m_xLanguageLB.get());
1650}
1651
1653{
1654 LanguageType eCurLanguage = m_xLanguageLB->get_active_id();
1655 static Locale aLastLocale;
1656 Locale aCurLocale( LanguageTag::convertToLocale( eCurLanguage));
1657
1658 if (pBox)
1659 {
1660 // save old probably changed settings
1661 // before switching to new language entries
1662
1663 LanguageType nLang = LanguageTag::convertToLanguageType( aLastLocale );
1664
1665 sal_Int32 nStart = 0, nLocalIndex = 0;
1666 Sequence< OUString > aChange;
1667 bool bChanged = false;
1668 for (int i = 0, nEntryCount = m_xModulesCLB->n_children(); i < nEntryCount; ++i)
1669 {
1670 ModuleUserData_Impl* pData = weld::fromId<ModuleUserData_Impl*>(m_xModulesCLB->get_id(i));
1671 if (pData->IsParent())
1672 {
1673 if (bChanged)
1674 {
1675 LangImplNameTable *pTable = nullptr;
1676 sal_uInt8 nType = pData->GetType();
1677 switch (nType - 1)
1678 {
1679 case TYPE_SPELL : pTable = &rLinguData.GetSpellTable(); break;
1680 case TYPE_GRAMMAR : pTable = &rLinguData.GetGrammarTable(); break;
1681 case TYPE_HYPH : pTable = &rLinguData.GetHyphTable(); break;
1682 case TYPE_THES : pTable = &rLinguData.GetThesTable(); break;
1683 }
1684 if (pTable)
1685 {
1686 aChange.realloc(nStart);
1687 (*pTable)[ nLang ] = aChange;
1688 }
1689 }
1690 nLocalIndex = nStart = 0;
1691 aChange.realloc(nEntryCount);
1692 bChanged = false;
1693 }
1694 else
1695 {
1696 OUString* pChange = aChange.getArray();
1697 pChange[nStart] = pData->GetImplName();
1698 bChanged |= pData->GetIndex() != nLocalIndex ||
1699 static_cast<TriState>(pData->IsChecked()) != m_xModulesCLB->get_toggle(i);
1700 if (m_xModulesCLB->get_toggle(i))
1701 nStart++;
1702 ++nLocalIndex;
1703 }
1704 }
1705 if(bChanged)
1706 {
1707 aChange.realloc(nStart);
1708 rLinguData.GetThesTable()[ nLang ] = aChange;
1709 }
1710 }
1711
1712 for (int i = 0, nEntryCount = m_xModulesCLB->n_children(); i < nEntryCount; ++i)
1713 delete weld::fromId<ModuleUserData_Impl*>(m_xModulesCLB->get_id(i));
1714 m_xModulesCLB->clear();
1715
1716 // display entries for new selected language
1717
1718 if (LANGUAGE_DONTKNOW != eCurLanguage)
1719 {
1720 sal_Int32 n;
1721 ServiceInfo_Impl* pInfo;
1722
1723 int nRow = 0;
1724 // spellchecker entries
1725
1726 ModuleUserData_Impl* pUserData = new ModuleUserData_Impl(
1727 OUString(), true, false, TYPE_SPELL, 0 );
1728 OUString sId(weld::toId(pUserData));
1729 m_xModulesCLB->append(nullptr);
1730 m_xModulesCLB->set_id(nRow, sId);
1731 m_xModulesCLB->set_text(nRow, sSpell, 0);
1732 m_xModulesCLB->set_text_emphasis(nRow, true, 0);
1733 ++nRow;
1734
1736 const OUString *pName = aNames.getConstArray();
1737 sal_Int32 nNames = aNames.getLength();
1738 sal_Int32 nLocalIndex = 0; // index relative to parent
1739 for (n = 0; n < nNames; ++n)
1740 {
1741 OUString aImplName;
1742 bool bIsSuppLang = false;
1743
1744 pInfo = rLinguData.GetInfoByImplName( pName[n] );
1745 if (pInfo)
1746 {
1747 bIsSuppLang = pInfo->xSpell.is() &&
1748 pInfo->xSpell->hasLocale( aCurLocale );
1749 aImplName = pInfo->sSpellImplName;
1750 }
1751 if (!aImplName.isEmpty() && bIsSuppLang)
1752 {
1753 OUString aTxt( pInfo->sDisplayName );
1754
1756 const bool bHasLang = rTable.count( eCurLanguage );
1757 if (!bHasLang)
1758 {
1759 SAL_INFO( "cui.options", "language entry missing" ); // only relevant if all languages found should be supported
1760 }
1761 const bool bCheck = bHasLang && lcl_SeqGetEntryPos( rTable[ eCurLanguage ], aImplName ) >= 0;
1762 pUserData = new ModuleUserData_Impl( aImplName, false,
1763 bCheck, TYPE_SPELL, static_cast<sal_uInt8>(nLocalIndex++) );
1764 sId = weld::toId(pUserData);
1765
1766 m_xModulesCLB->append(nullptr);
1767 m_xModulesCLB->set_id(nRow, sId);
1768 m_xModulesCLB->set_toggle(nRow, bCheck ? TRISTATE_TRUE : TRISTATE_FALSE);
1769 m_xModulesCLB->set_text(nRow, aTxt, 0);
1770 m_xModulesCLB->set_text_emphasis(nRow, false, 0);
1771 ++nRow;
1772 }
1773 }
1774
1775 // grammar checker entries
1776
1777 pUserData = new ModuleUserData_Impl( OUString(), true, false, TYPE_GRAMMAR, 0 );
1778 sId = weld::toId(pUserData);
1779 m_xModulesCLB->append(nullptr);
1780 m_xModulesCLB->set_id(nRow, sId);
1781 m_xModulesCLB->set_text(nRow, sGrammar, 0);
1782 m_xModulesCLB->set_text_emphasis(nRow, true, 0);
1783 ++nRow;
1784
1785 aNames = rLinguData.GetSortedImplNames( eCurLanguage, TYPE_GRAMMAR );
1786 pName = aNames.getConstArray();
1787 nNames = aNames.getLength();
1788 nLocalIndex = 0;
1789 for (n = 0; n < nNames; ++n)
1790 {
1791 OUString aImplName;
1792 bool bIsSuppLang = false;
1793
1794 pInfo = rLinguData.GetInfoByImplName( pName[n] );
1795 if (pInfo)
1796 {
1797 bIsSuppLang = pInfo->xGrammar.is() &&
1798 pInfo->xGrammar->hasLocale( aCurLocale );
1799 aImplName = pInfo->sGrammarImplName;
1800 }
1801 if (!aImplName.isEmpty() && bIsSuppLang)
1802 {
1803 OUString aTxt( pInfo->sDisplayName );
1804
1806 const bool bHasLang = rTable.count( eCurLanguage );
1807 if (!bHasLang)
1808 {
1809 SAL_INFO( "cui.options", "language entry missing" ); // only relevant if all languages found should be supported
1810 }
1811 const bool bCheck = bHasLang && lcl_SeqGetEntryPos( rTable[ eCurLanguage ], aImplName ) >= 0;
1812 pUserData = new ModuleUserData_Impl( aImplName, false,
1813 bCheck, TYPE_GRAMMAR, static_cast<sal_uInt8>(nLocalIndex++) );
1814
1815 sId = weld::toId(pUserData);
1816
1817 m_xModulesCLB->append(nullptr);
1818 m_xModulesCLB->set_id(nRow, sId);
1819 m_xModulesCLB->set_toggle(nRow, bCheck ? TRISTATE_TRUE : TRISTATE_FALSE);
1820 m_xModulesCLB->set_text(nRow, aTxt, 0);
1821 m_xModulesCLB->set_text_emphasis(nRow, false, 0);
1822 ++nRow;
1823 }
1824 }
1825
1826 // hyphenator entries
1827
1828 pUserData = new ModuleUserData_Impl( OUString(), true, false, TYPE_HYPH, 0 );
1829 sId = weld::toId(pUserData);
1830 m_xModulesCLB->append(nullptr);
1831 m_xModulesCLB->set_id(nRow, sId);
1832 m_xModulesCLB->set_text(nRow, sHyph, 0);
1833 m_xModulesCLB->set_text_emphasis(nRow, true, 0);
1834 ++nRow;
1835
1836 aNames = rLinguData.GetSortedImplNames( eCurLanguage, TYPE_HYPH );
1837 pName = aNames.getConstArray();
1838 nNames = aNames.getLength();
1839 nLocalIndex = 0;
1840 for (n = 0; n < nNames; ++n)
1841 {
1842 OUString aImplName;
1843 bool bIsSuppLang = false;
1844
1845 pInfo = rLinguData.GetInfoByImplName( pName[n] );
1846 if (pInfo)
1847 {
1848 bIsSuppLang = pInfo->xHyph.is() &&
1849 pInfo->xHyph->hasLocale( aCurLocale );
1850 aImplName = pInfo->sHyphImplName;
1851 }
1852 if (!aImplName.isEmpty() && bIsSuppLang)
1853 {
1854 OUString aTxt( pInfo->sDisplayName );
1855
1857 const bool bHasLang = rTable.count( eCurLanguage );
1858 if (!bHasLang)
1859 {
1860 SAL_INFO( "cui.options", "language entry missing" ); // only relevant if all languages found should be supported
1861 }
1862 const bool bCheck = bHasLang && lcl_SeqGetEntryPos( rTable[ eCurLanguage ], aImplName ) >= 0;
1863 pUserData = new ModuleUserData_Impl( aImplName, false,
1864 bCheck, TYPE_HYPH, static_cast<sal_uInt8>(nLocalIndex++) );
1865 sId = weld::toId(pUserData);
1866
1867 m_xModulesCLB->append(nullptr);
1868 m_xModulesCLB->set_id(nRow, sId);
1869 m_xModulesCLB->set_toggle(nRow, bCheck ? TRISTATE_TRUE : TRISTATE_FALSE);
1870 m_xModulesCLB->set_text(nRow, aTxt, 0);
1871 m_xModulesCLB->set_text_emphasis(nRow, false, 0);
1872 ++nRow;
1873 }
1874 }
1875
1876 // thesaurus entries
1877
1878 pUserData = new ModuleUserData_Impl( OUString(), true, false, TYPE_THES, 0 );
1879 sId = weld::toId(pUserData);
1880 m_xModulesCLB->append(nullptr);
1881 m_xModulesCLB->set_id(nRow, sId);
1882 m_xModulesCLB->set_text(nRow, sThes, 0);
1883 m_xModulesCLB->set_text_emphasis(nRow, true, 0);
1884 ++nRow;
1885
1886 aNames = rLinguData.GetSortedImplNames( eCurLanguage, TYPE_THES );
1887 pName = aNames.getConstArray();
1888 nNames = aNames.getLength();
1889 nLocalIndex = 0;
1890 for (n = 0; n < nNames; ++n)
1891 {
1892 OUString aImplName;
1893 bool bIsSuppLang = false;
1894
1895 pInfo = rLinguData.GetInfoByImplName( pName[n] );
1896 if (pInfo)
1897 {
1898 bIsSuppLang = pInfo->xThes.is() &&
1899 pInfo->xThes->hasLocale( aCurLocale );
1900 aImplName = pInfo->sThesImplName;
1901 }
1902 if (!aImplName.isEmpty() && bIsSuppLang)
1903 {
1904 OUString aTxt( pInfo->sDisplayName );
1905
1907 const bool bHasLang = rTable.count( eCurLanguage );
1908 if (!bHasLang)
1909 {
1910 SAL_INFO( "cui.options", "language entry missing" ); // only relevant if all languages found should be supported
1911 }
1912 const bool bCheck = bHasLang && lcl_SeqGetEntryPos( rTable[ eCurLanguage ], aImplName ) >= 0;
1913 pUserData = new ModuleUserData_Impl( aImplName, false,
1914 bCheck, TYPE_THES, static_cast<sal_uInt8>(nLocalIndex++) );
1915 sId = weld::toId(pUserData);
1916
1917 m_xModulesCLB->append(nullptr);
1918 m_xModulesCLB->set_id(nRow, sId);
1919 m_xModulesCLB->set_toggle(nRow, bCheck ? TRISTATE_TRUE : TRISTATE_FALSE);
1920 m_xModulesCLB->set_text(nRow, aTxt, 0);
1921 m_xModulesCLB->set_text_emphasis(nRow, false, 0);
1922 ++nRow;
1923 }
1924 }
1925 }
1926 aLastLocale = aCurLocale;
1927}
1928
1929IMPL_LINK( SvxEditModulesDlg, UpDownHdl_Impl, weld::Button&, rBtn, void )
1930{
1931 bool bUp = m_xPrioUpPB.get() == &rBtn;
1932 int nCurPos = m_xModulesCLB->get_selected_index();
1933 if (nCurPos == -1)
1934 return;
1935
1936 m_xModulesCLB->freeze();
1937
1938 OUString sId(m_xModulesCLB->get_id(nCurPos));
1939 OUString sStr(m_xModulesCLB->get_text(nCurPos));
1940 bool bIsChecked = m_xModulesCLB->get_toggle(nCurPos);
1941
1942 m_xModulesCLB->remove(nCurPos);
1943
1944 int nDestPos = bUp ? nCurPos - 1 : nCurPos + 1;
1945
1946 m_xModulesCLB->insert_text(nDestPos, sStr);
1947 m_xModulesCLB->set_id(nDestPos, sId);
1948 m_xModulesCLB->set_toggle(nDestPos, bIsChecked ? TRISTATE_TRUE : TRISTATE_FALSE);
1949
1950 m_xModulesCLB->thaw();
1951
1952 m_xModulesCLB->select(nDestPos);
1953 SelectHdl_Impl(*m_xModulesCLB);
1954}
1955
1957{
1958 // store language config
1959 LangSelectHdl_Impl(m_xLanguageLB.get());
1960 m_xDialog->response(RET_OK);
1961}
1962
1964{
1965 rLinguData = *pDefaultLinguData;
1966 LangSelectHdl_Impl(nullptr);
1967}
1968
1970{
1971 comphelper::dispatchCommand(".uno:MoreDictionaries", {});
1972 return true;
1973}
1974
1975/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
const char * pName
Reference< XExecutableDialog > m_xDialog
const LanguageTag & GetLanguageTag() const
static const AllSettings & GetSettings()
static ImplSVEvent * PostUserEvent(const Link< void *, void > &rLink, void *pCaller=nullptr, bool bReferenceLink=false)
static std::unique_ptr< weld::Builder > CreateBuilder(weld::Widget *pParent, const OUString &rUIFile, bool bMobile=false, sal_uInt64 nLOKWindowId=0)
static void RemoveUserEvent(ImplSVEvent *nUserEvent)
OUString GetMainURL(DecodeMechanism eMechanism, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
INetProtocol GetProtocol() const
LanguageType getLanguageType(bool bResolveSystem=true) const
const css::lang::Locale & getLocale(bool bResolveSystem=true) const
static css::lang::Locale convertToLocale(LanguageType nLangID, bool bResolveSystem=true)
static LanguageType convertToLanguageType(const css::lang::Locale &rLocale, bool bResolveSystem=true)
static css::uno::Reference< css::linguistic2::XSearchableDictionaryList > GetDictionaryList()
static css::uno::Reference< css::linguistic2::XDictionary > GetIgnoreAllList()
static css::uno::Reference< css::linguistic2::XLinguProperties > GetLinguPropertySet()
static LanguageType getConfiguredSystemLanguage()
sal_uInt8 & GetMinTrail()
sal_uInt8 & GetMinLead()
SfxItemState GetItemState(sal_uInt16 nWhich, bool bSrchInParent=true, const SfxPoolItem **ppItem=nullptr) const
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
const SfxPoolItem & Get(sal_uInt16 nWhich, bool bSrchInParent=true) const
static const SfxPoolItem * GetItem(const SfxItemSet &rSet, sal_uInt16 nSlot, bool bDeep=true)
const SfxPoolItem * GetOldItem(const SfxItemSet &rSet, sal_uInt16 nSlot, bool bDeep=true)
css::uno::Any GetProperty(std::u16string_view rPropertyName) const
bool SetProperty(std::u16string_view rPropertyName, const css::uno::Any &rValue)
virtual VclPtr< VclAbstractDialog > CreateSvxEditDictionaryDialog(weld::Window *pParent, const OUString &rName)=0
virtual VclPtr< AbstractSvxNewDictionaryDialog > CreateSvxNewDictionaryDialog(weld::Window *pParent)=0
static SvxAbstractDialogFactory * Create()
std::unique_ptr< weld::Button > m_xClosePB
Definition: optlingu.hxx:60
OUString sThes
Definition: optlingu.hxx:49
std::unique_ptr< weld::Button > m_xBackPB
Definition: optlingu.hxx:58
OUString sGrammar
Definition: optlingu.hxx:50
std::unique_ptr< SvxLanguageBox > m_xLanguageLB
Definition: optlingu.hxx:61
SvxLinguData_Impl & rLinguData
Definition: optlingu.hxx:53
std::unique_ptr< weld::Button > m_xPrioUpPB
Definition: optlingu.hxx:56
std::unique_ptr< weld::Button > m_xPrioDownPB
Definition: optlingu.hxx:57
std::unique_ptr< weld::LinkButton > m_xMoreDictsLink
Definition: optlingu.hxx:59
OUString sSpell
Definition: optlingu.hxx:47
std::unique_ptr< weld::TreeView > m_xModulesCLB
Definition: optlingu.hxx:55
void LangSelectHdl_Impl(const SvxLanguageBox *pBox)
Definition: optlingu.cxx:1652
SvxEditModulesDlg(weld::Window *pParent, SvxLinguData_Impl &rData)
Definition: optlingu.cxx:1542
OUString sHyph
Definition: optlingu.hxx:48
virtual ~SvxEditModulesDlg() override
Definition: optlingu.cxx:1598
std::unique_ptr< SvxLinguData_Impl > pDefaultLinguData
Definition: optlingu.hxx:52
LangImplNameTable aCfgSpellTable
Definition: optlingu.cxx:342
LangImplNameTable aCfgHyphTable
Definition: optlingu.cxx:343
ServiceInfo_Impl * GetInfoByImplName(std::u16string_view rSvcImplName)
Definition: optlingu.cxx:450
uno::Reference< XLinguServiceManager2 > & GetManager()
Definition: optlingu.cxx:355
ServiceInfoArr & GetDisplayServiceArray()
Definition: optlingu.cxx:367
LangImplNameTable & GetSpellTable()
Definition: optlingu.cxx:362
const sal_uInt32 & GetDisplayServiceCount() const
Definition: optlingu.cxx:369
LangImplNameTable & GetHyphTable()
Definition: optlingu.cxx:363
ServiceInfoArr aDisplayServiceArr
Definition: optlingu.cxx:338
static bool AddRemove(Sequence< OUString > &rConfigured, const OUString &rImplName, bool bAdd)
Definition: optlingu.cxx:703
void Reconfigure(std::u16string_view rDisplayName, bool bEnable)
Definition: optlingu.cxx:731
uno::Reference< XLinguServiceManager2 > xLinguSrvcMgr
Definition: optlingu.cxx:346
sal_uInt32 nDisplayServices
Definition: optlingu.cxx:339
LangImplNameTable & GetGrammarTable()
Definition: optlingu.cxx:365
LangImplNameTable aCfgThesTable
Definition: optlingu.cxx:344
void SetDisplayServiceCount(sal_uInt32 nVal)
Definition: optlingu.cxx:370
LangImplNameTable aCfgGrammarTable
Definition: optlingu.cxx:345
Sequence< Locale > aAllServiceLocales
Definition: optlingu.cxx:341
const Sequence< Locale > & GetAllSupportedLocales() const
Definition: optlingu.cxx:360
LangImplNameTable & GetThesTable()
Definition: optlingu.cxx:364
void SetChecked(const Sequence< OUString > &rConfiguredServices)
Definition: optlingu.cxx:679
Sequence< OUString > GetSortedImplNames(LanguageType nLang, sal_uInt8 nType)
Definition: optlingu.cxx:399
std::unique_ptr< weld::TreeView > m_xLinguOptionsCLB
Definition: optlingu.hxx:119
std::unique_ptr< weld::Label > m_xLinguDicsFT
Definition: optlingu.hxx:114
int nUPN_HYPH_MIN_TRAILING
Definition: optlingu.hxx:96
int nUPN_HYPH_MIN_WORD_LENGTH
Definition: optlingu.hxx:94
std::unique_ptr< weld::TreeView > m_xLinguDicsCLB
Definition: optlingu.hxx:115
OUString sWordsWithDigits
Definition: optlingu.hxx:84
std::unique_ptr< weld::Label > m_xLinguModulesFT
Definition: optlingu.hxx:111
OUString sNumMinWordlen
Definition: optlingu.hxx:88
std::unique_ptr< weld::Button > m_xLinguDicsNewPB
Definition: optlingu.hxx:116
std::unique_ptr< weld::LinkButton > m_xMoreDictsLink
Definition: optlingu.hxx:121
std::unique_ptr< weld::Button > m_xLinguModulesEditPB
Definition: optlingu.hxx:113
css::uno::Reference< css::linguistic2::XLinguProperties > xProp
Definition: optlingu.hxx:101
std::unique_ptr< weld::Button > m_xLinguDicsEditPB
Definition: optlingu.hxx:117
void UpdateDicBox_Impl()
Definition: optlingu.cxx:1102
OUString sNumPostBreak
Definition: optlingu.hxx:90
OUString sNumPreBreak
Definition: optlingu.hxx:89
css::uno::Sequence< css::uno::Reference< css::linguistic2::XDictionary > > aDics
Definition: optlingu.hxx:107
static std::unique_ptr< SfxTabPage > Create(weld::Container *pPage, weld::DialogController *pController, const SfxItemSet *rSet)
Definition: optlingu.cxx:913
SvxLinguTabPage(weld::Container *pPage, weld::DialogController *pController, const SfxItemSet &rCoreSet)
Definition: optlingu.cxx:824
std::unique_ptr< weld::TreeView > m_xLinguModulesCLB
Definition: optlingu.hxx:112
css::uno::Reference< css::linguistic2::XDictionaryList > xDicList
Definition: optlingu.hxx:104
OUString sHyphAuto
Definition: optlingu.hxx:91
static sal_uInt32 GetDicUserData(const css::uno::Reference< css::linguistic2::XDictionary > &rxDic, sal_uInt16 nIdx)
Definition: optlingu.cxx:1064
std::unique_ptr< weld::Button > m_xLinguOptionsEditPB
Definition: optlingu.hxx:120
ImplSVEvent * m_nDlbClickEventId
Definition: optlingu.hxx:98
int nUPN_HYPH_MIN_LEADING
Definition: optlingu.hxx:95
virtual bool FillItemSet(SfxItemSet *rSet) override
Definition: optlingu.cxx:919
std::unique_ptr< weld::Button > m_xLinguDicsDelPB
Definition: optlingu.hxx:118
OUString sSpellAuto
Definition: optlingu.hxx:86
void HideGroups(sal_uInt16 nGrp)
Definition: optlingu.cxx:1521
OUString sCapitalWords
Definition: optlingu.hxx:83
virtual void Reset(const SfxItemSet *rSet) override
Definition: optlingu.cxx:1150
void UpdateModulesBox_Impl()
Definition: optlingu.cxx:1124
std::unique_ptr< SvxLinguData_Impl > pLinguData
Definition: optlingu.hxx:109
OUString sHyphSpecial
Definition: optlingu.hxx:92
void AddDicBoxEntry(const css::uno::Reference< css::linguistic2::XDictionary > &rxDic, sal_uInt16 nIdx)
Definition: optlingu.cxx:1083
virtual ~SvxLinguTabPage() override
Definition: optlingu.cxx:903
OUString sGrammarAuto
Definition: optlingu.hxx:87
OUString sSpellSpecial
Definition: optlingu.hxx:85
virtual short run()
std::pair< const TreeIter &, int > iter_col
OUString CuiResId(TranslateId aKey)
Definition: cuiresmgr.cxx:23
#define DBG_ASSERT(sCon, aError)
#define TOOLS_WARN_EXCEPTION(area, stream)
weld::Window * GetFrameWeld(const SfxFrame *pFrame)
virtual tools::Long GetValue() const override
TriState
TRISTATE_FALSE
TRISTATE_TRUE
OUString sDisplayName
sal_Int32 nIndex
sal_Int64 n
#define LANGUAGE_DONTKNOW
constexpr OUStringLiteral UPN_IS_GRAMMAR_AUTO
#define UPH_ACTIVE_DICTIONARIES
constexpr OUStringLiteral UPN_IS_SPELL_AUTO
constexpr OUStringLiteral UPN_IS_HYPH_AUTO
constexpr OUStringLiteral UPN_IS_SPELL_UPPER_CASE
constexpr OUStringLiteral UPN_HYPH_MIN_WORD_LENGTH
constexpr OUStringLiteral UPN_HYPH_MIN_LEADING
constexpr OUStringLiteral UPN_IS_SPELL_WITH_DIGITS
constexpr OUStringLiteral UPN_IS_HYPH_SPECIAL
constexpr OUStringLiteral UPN_HYPH_MIN_TRAILING
constexpr OUStringLiteral UPN_IS_SPELL_SPECIAL
sal_uInt16 nPos
const char * pLocale
#define SAL_WARN(area, stream)
#define SAL_INFO(area, stream)
std::unique_ptr< sal_Int32[]> pData
const ContentProperties & rData
constexpr OUStringLiteral aData
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)
Reference< XComponentContext > getProcessComponentContext()
int i
OUString aPropName
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
OUString toId(const void *pValue)
IMPL_STATIC_LINK_NOARG(SvxLinguTabPage, OnLinkClick, weld::LinkButton &, bool)
Definition: optlingu.cxx:1536
#define TYPE_SPELL
Definition: optlingu.cxx:116
#define TYPE_GRAMMAR
Definition: optlingu.cxx:117
static void lcl_MergeDisplayArray(SvxLinguData_Impl &rData, const ServiceInfo_Impl &rToAdd)
Definition: optlingu.cxx:497
constexpr OUStringLiteral cHyph(SN_HYPHENATOR)
constexpr OUStringLiteral cGrammar(SN_GRAMMARCHECKER)
static sal_Int32 lcl_SeqGetIndex(const Sequence< OUString > &rSeq, std::u16string_view rTxt)
Definition: optlingu.cxx:385
std::vector< ServiceInfo_Impl > ServiceInfoArr
Definition: optlingu.cxx:329
IMPL_LINK_NOARG(SvxLinguTabPage, PostDblClickHdl_Impl, void *, void)
Definition: optlingu.cxx:1301
static bool KillFile_Impl(const OUString &rURL)
Definition: optlingu.cxx:93
static void lcl_MergeLocales(Sequence< Locale > &aAllLocales, const Sequence< Locale > &rAdd)
Definition: optlingu.cxx:467
#define TYPE_THES
Definition: optlingu.cxx:119
IMPL_LINK(SvxLinguTabPage, BoxDoubleClickHdl_Impl, weld::TreeView &, rBox, bool)
Definition: optlingu.cxx:1285
static OUString lcl_GetPropertyName(EID_OPTIONS eEntryId)
Definition: optlingu.cxx:201
#define TYPE_HYPH
Definition: optlingu.cxx:118
constexpr OUStringLiteral cSpell(SN_SPELLCHECKER)
constexpr OUStringLiteral cThes(SN_THESAURUS)
static sal_Int32 lcl_SeqGetEntryPos(const Sequence< OUString > &rSeq, std::u16string_view rEntry)
Definition: optlingu.cxx:79
std::map< LanguageType, Sequence< OUString > > LangImplNameTable
Definition: optlingu.cxx:330
#define GROUP_MODULES
Definition: optlingu.hxx:41
QPRO_FUNC_TYPE nType
static SfxItemSet & rSet
unsigned char sal_uInt8
OUString sId
RET_OK
RET_NO
sal_Int32 nLength