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