26#include <officecfg/Office/Security.hxx>
31#include <sfx2/sfxsids.hrc>
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>
53#include <osl/diagnose.h>
69using namespace css::lang;
70using namespace css::uno;
71using namespace css::linguistic2;
72using namespace css::beans;
74constexpr OUStringLiteral
cSpell(SN_SPELLCHECKER);
75constexpr OUStringLiteral
cGrammar(SN_GRAMMARCHECKER);
76constexpr OUStringLiteral
cHyph(SN_HYPHENATOR);
77constexpr OUStringLiteral
cThes(SN_THESAURUS);
85 sal_Int32 nLen = rSeq.getLength();
86 const OUString *pItem = rSeq.getConstArray();
87 for (
i = 0;
i < nLen; ++
i)
89 if (rEntry == pItem[
i])
92 return i < nLen ?
i : -1;
101 aCnt.executeCommand(
"delete",
Any(
true ) );
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)
125class ModuleUserData_Impl
134 ModuleUserData_Impl( OUString sImpName,
bool bIsParent,
bool bChecked,
sal_uInt8 nSetType,
sal_uInt8 nSetIndex ) :
136 bIsChecked(bChecked),
139 sImplName(std::move(sImpName))
142 bool IsParent()
const {
return bParent;}
144 bool IsChecked()
const {
return bIsChecked;}
146 const OUString& GetImplName()
const {
return sImplName;}
158 explicit DicUserData(sal_uInt32 nUserData) : nVal( nUserData ) {}
159 DicUserData( sal_uInt16 nEID,
160 bool bChecked,
bool bEditable,
bool bDeletable );
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); }
170DicUserData::DicUserData(
172 bool bChecked,
bool bEditable,
bool bDeletable )
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);
192 EID_WORDS_WITH_DIGITS,
199 EID_SPELL_CLOSED_COMPOUND,
200 EID_SPELL_HYPHENATED_COMPOUND
221 default: assert (
false); abort();
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;
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"))
241 assert(EID_NUM_PRE_BREAK == nRID || EID_NUM_POST_BREAK == nRID || EID_NUM_MIN_WORDLEN == nRID);
243 if (nRID == EID_NUM_PRE_BREAK)
245 m_xBeforeFrame->show();
246 m_xBreakNF = m_xBuilder->weld_spin_button(
"beforebreak");
248 else if(nRID == EID_NUM_POST_BREAK)
250 m_xAfterFrame->show();
251 m_xBreakNF = m_xBuilder->weld_spin_button(
"afterbreak");
253 else if(nRID == EID_NUM_MIN_WORDLEN)
255 m_xMinimalFrame->show();
256 m_xBreakNF = m_xBuilder->weld_spin_button(
"wordlength");
273 explicit OptionsUserData( sal_uInt32 nUserData ) : nVal( nUserData ) {}
274 OptionsUserData( sal_uInt16 nEID,
275 bool bHasNV, sal_uInt16 nNumVal,
276 bool bCheckable,
bool bChecked );
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); }
285 void SetNumericValue(
sal_uInt8 nNumVal );
290OptionsUserData::OptionsUserData( sal_uInt16 nEID,
291 bool bHasNV, sal_uInt16 nNumVal,
292 bool bCheckable,
bool bChecked )
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);
303void OptionsUserData::SetNumericValue(
sal_uInt8 nNumVal )
305 if (HasNumericValue() && (GetNumericValue() != nNumVal))
309 nVal |= sal_uInt32(1) << 11;
317struct ServiceInfo_Impl
320 OUString sSpellImplName;
321 OUString sHyphImplName;
322 OUString sThesImplName;
323 OUString sGrammarImplName;
330 ServiceInfo_Impl() : bConfigured(false) {}
335 bool operator()(
const css::lang::Locale& lhs,
const css::lang::Locale& rhs)
const
337 if (lhs.Language < rhs.Language)
339 if (lhs.Language > rhs.Language)
341 if (lhs.Country < rhs.Country)
343 if (lhs.Country > rhs.Country)
345 return lhs.Variant < rhs.Variant;
372 const OUString &rImplName,
bool bAdd );
380 void Reconfigure( std::u16string_view rDisplayName,
bool bEnable );
410 sal_Int32 nLen = rSeq.getLength();
411 const OUString *pString = rSeq.getConstArray();
412 for (sal_Int32
i = 0;
i < nLen && nRes == -1; ++
i)
414 if (pString[
i] == rTxt)
434 SAL_WARN(
"cui.options",
"unknown linguistic type" );
437 if (pTable->count( nLang ))
438 aRes = (*pTable)[ nLang ];
439 sal_Int32 nIdx = aRes.getLength();
442 OUString *pRes = aRes.getArray();
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;
459 DBG_ASSERT( nIdx < aRes.getLength(),
"index out of range" );
460 if (nIdx < aRes.getLength())
461 pRes[ nIdx++ ] = aImplName;
467 aRes.realloc( nIdx );
477 if (rTmp.sSpellImplName == rSvcImplName ||
478 rTmp.sHyphImplName == rSvcImplName ||
479 rTmp.sThesImplName == rSvcImplName ||
480 rTmp.sGrammarImplName == rSvcImplName)
490 const ServiceInfo_Impl &rToAdd )
497 for (sal_uInt32
i = 0;
i < nEntries; ++
i)
499 ServiceInfo_Impl& rEntry = rSvcInfoArr[
i];
500 if (rEntry.sDisplayName == rToAdd.sDisplayName)
502 if(rToAdd.xSpell.is())
505 rEntry.sSpellImplName.isEmpty(),
507 rEntry.sSpellImplName = rToAdd.sSpellImplName;
508 rEntry.xSpell = rToAdd.xSpell;
510 if(rToAdd.xGrammar.is())
513 rEntry.sGrammarImplName.isEmpty(),
515 rEntry.sGrammarImplName = rToAdd.sGrammarImplName;
516 rEntry.xGrammar = rToAdd.xGrammar;
518 if(rToAdd.xHyph.is())
521 rEntry.sHyphImplName.isEmpty(),
523 rEntry.sHyphImplName = rToAdd.sHyphImplName;
524 rEntry.xHyph = rToAdd.xHyph;
526 if(rToAdd.xThes.is())
529 rEntry.sThesImplName.isEmpty(),
531 rEntry.sThesImplName = rToAdd.sThesImplName;
532 rEntry.xThes = rToAdd.xThes;
559 for(
const OUString& spellName : aSpellNames)
561 ServiceInfo_Impl aInfo;
562 aInfo.sSpellImplName = spellName;
564 xContext->getServiceManager()->createInstanceWithArgumentsAndContext(aInfo.sSpellImplName, aArgs, xContext), UNO_QUERY);
568 aInfo.sDisplayName = xDispName->getServiceDisplayName( rCurrentLocale );
570 const Sequence< Locale > aLocales( aInfo.xSpell->getLocales() );
572 if (aLocales.hasElements())
582 for(
const OUString& grammarName : aGrammarNames)
584 ServiceInfo_Impl aInfo;
585 aInfo.sGrammarImplName = grammarName;
587 xContext->getServiceManager()->createInstanceWithArgumentsAndContext(aInfo.sGrammarImplName, aArgs, xContext), UNO_QUERY);
591 aInfo.sDisplayName = xDispName->getServiceDisplayName( rCurrentLocale );
593 const Sequence< Locale > aLocales( aInfo.xGrammar->getLocales() );
595 if (aLocales.hasElements())
605 for(
const OUString& hyphName : aHyphNames)
607 ServiceInfo_Impl aInfo;
608 aInfo.sHyphImplName = hyphName;
609 aInfo.xHyph.set( xContext->getServiceManager()->createInstanceWithArgumentsAndContext(aInfo.sHyphImplName, aArgs, xContext), UNO_QUERY);
613 aInfo.sDisplayName = xDispName->getServiceDisplayName( rCurrentLocale );
615 const Sequence< Locale > aLocales( aInfo.xHyph->getLocales() );
617 if (aLocales.hasElements())
627 for(
const OUString& thesName : aThesNames)
629 ServiceInfo_Impl aInfo;
630 aInfo.sThesImplName = thesName;
631 aInfo.xThes.set( xContext->getServiceManager()->createInstanceWithArgumentsAndContext(aInfo.sThesImplName, aArgs, xContext), UNO_QUERY);
635 aInfo.sDisplayName = xDispName->getServiceDisplayName( rCurrentLocale );
637 const Sequence< Locale > aLocales( aInfo.xThes->getLocales() );
639 if (aLocales.hasElements())
653 if (aCfgSvcs.hasElements())
658 if (aCfgSvcs.hasElements())
663 if (aCfgSvcs.hasElements())
668 if (aCfgSvcs.hasElements())
675 for(OUString
const & configService : rConfiguredServices)
680 if (!rEntry.bConfigured)
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))
689 rEntry.bConfigured =
true;
699 const OUString &rImplName,
bool bAdd )
703 sal_Int32 nEntries = rConfigured.getLength();
705 if (bAdd &&
nPos < 0)
707 rConfigured.realloc( ++nEntries );
708 OUString *pConfigured = rConfigured.getArray();
709 pConfigured[nEntries - 1] = rImplName;
712 else if (!bAdd &&
nPos >= 0)
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);
727 DBG_ASSERT( !rDisplayName.empty(),
"empty DisplayName" );
729 ServiceInfo_Impl *pInfo =
nullptr;
733 if (rTmp.sDisplayName == rDisplayName)
739 DBG_ASSERT( pInfo,
"DisplayName entry not found" );
743 pInfo->bConfigured = bEnable;
745 Sequence< Locale > aLocales;
747 sal_Int32 nLocales = 0;
751 if (pInfo->xSpell.is())
753 aLocales = pInfo->xSpell->getLocales();
754 pLocale = aLocales.getConstArray();
755 nLocales = aLocales.getLength();
756 for (
i = 0;
i < nLocales; ++
i)
767 if (pInfo->xGrammar.is())
769 aLocales = pInfo->xGrammar->getLocales();
770 pLocale = aLocales.getConstArray();
771 nLocales = aLocales.getLength();
772 for (
i = 0;
i < nLocales; ++
i)
783 if (pInfo->xHyph.is())
785 aLocales = pInfo->xHyph->getLocales();
786 pLocale = aLocales.getConstArray();
787 nLocales = aLocales.getLength();
788 for (
i = 0;
i < nLocales; ++
i)
799 if (!pInfo->xThes.is())
802 aLocales = pInfo->xThes->getLocales();
803 pLocale = aLocales.getConstArray();
804 nLocales = aLocales.getLength();
805 for (
i = 0;
i < nLocales; ++
i)
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"))
877 m_xBuilder->weld_frame(
"dictsframe")->hide();
921 return std::make_unique<SvxLinguTabPage>( pPage, pController, *rAttrSet );
926 bool bModified =
true;
937 for (
auto const& elem : *pTable)
944 xMgr->setConfiguredServices(
cSpell, aLocale, aImplNames );
949 for (
auto const& elem : *pTable)
956 xMgr->setConfiguredServices(
cGrammar, aLocale, aImplNames );
961 for (
auto const& elem : *pTable)
968 xMgr->setConfiguredServices(
cHyph, aLocale, aImplNames );
973 for (
auto const& elem : *pTable)
980 xMgr->setConfiguredServices(
cThes, aLocale, aImplNames );
988 sal_Int32 nActiveDics = 0;
990 for (
int i = 0;
i < nEntries; ++
i)
992 sal_Int32 nDics =
aDics.getLength();
994 aActiveDics.realloc( nDics );
995 OUString *pActiveDic = aActiveDics.getArray();
998 if (
aData.GetEntryId() < nDics)
1006 xDic->setActive( bChecked );
1010 OUString aDicName( xDic->getName() );
1011 pActiveDic[ nActiveDics++ ] = aDicName;
1017 aActiveDics.realloc( nActiveDics );
1019 aTmp <<= aActiveDics;
1025 for (
int j = 0; j < nEntries; ++j)
1031 if (
aData.IsCheckable())
1036 else if (
aData.HasNumericValue())
1038 sal_Int16 nVal =
aData.GetNumericValue();
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() )
1054 rCoreSet->
Put( aHyp );
1062 rCoreSet->
Put(
SfxBoolItem( SID_AUTOSPELL_CHECK, bNewAutoCheck ) );
1071 sal_uInt32 nRes = 0;
1072 DBG_ASSERT( rxDic.is(),
"dictionary not supplied" );
1077 bool bChecked = rxDic->isActive();
1078 bool bEditable = !xStor.is() || !xStor->isReadonly();
1079 bool bDeletable = bEditable;
1081 nRes = DicUserData( nIdx,
1082 bChecked, bEditable, bDeletable ).GetUserData();
1094 OUString aTxt( ::GetDicInfoStr( rxDic->getName(),
1096 DictionaryType_NEGATIVE == rxDic->getDictionaryType() ) );
1112 sal_Int32 nDics =
aDics.getLength();
1114 for (sal_Int32
i = 0;
i < nDics; ++
i)
1135 const sal_uInt32 nDispSrvcCount =
pLinguData->GetDisplayServiceCount();
1139 for (sal_uInt32
i = 0;
i < nDispSrvcCount; ++
i)
1141 const ServiceInfo_Impl &rInfo = rAllDispSrvcArr[
i];
1174 sal_uInt32 nUserData = 0;
1183 nUserData = OptionsUserData( EID_SPELL_AUTO,
false, 0,
true, bVal).GetUserData();
1192 nUserData = OptionsUserData( EID_GRAMMAR_AUTO,
false, 0,
true, bVal).GetUserData();
1201 nUserData = OptionsUserData( EID_CAPITAL_WORDS,
false, 0,
true, bVal).GetUserData();
1210 nUserData = OptionsUserData( EID_WORDS_WITH_DIGITS,
false, 0,
true, bVal).GetUserData();
1219 nUserData = OptionsUserData( EID_SPELL_CLOSED_COMPOUND,
false, 0,
true, bVal).GetUserData();
1228 nUserData = OptionsUserData( EID_SPELL_HYPHENATED_COMPOUND,
false, 0,
true, bVal).GetUserData();
1237 nUserData = OptionsUserData( EID_SPELL_SPECIAL,
false, 0,
true, bVal).GetUserData();
1246 nUserData = OptionsUserData( EID_NUM_MIN_WORDLEN,
true,
static_cast<sal_uInt16
>(nVal),
false,
false).GetUserData();
1252 if (
rSet->
GetItemState( SID_ATTR_HYPHENREGION,
false ) == SfxItemState::SET )
1253 pHyp = &
rSet->
Get( SID_ATTR_HYPHENREGION );
1260 nVal =
static_cast<sal_Int16
>(pHyp->
GetMinLead());
1261 nUserData = OptionsUserData( EID_NUM_PRE_BREAK,
true,
static_cast<sal_uInt16
>(nVal),
false,
false).GetUserData();
1271 nVal =
static_cast<sal_Int16
>(pHyp->
GetMinTrail());
1272 nUserData = OptionsUserData( EID_NUM_POST_BREAK,
true,
static_cast<sal_uInt16
>(nVal),
false,
false).GetUserData();
1281 nUserData = OptionsUserData( EID_HYPH_AUTO,
false, 0,
true, bVal).GetUserData();
1290 nUserData = OptionsUserData( EID_HYPH_SPECIAL,
false, 0,
true, bVal).GetUserData();
1310 if (&rBox == m_xLinguModulesCLB.get() && !m_nDlbClickEventId)
1317 else if (&rBox == m_xLinguOptionsCLB.get())
1319 ClickHdl_Impl(*m_xLinguOptionsEditPB);
1326 m_nDlbClickEventId =
nullptr;
1327 ClickHdl_Impl(*m_xLinguModulesEditPB);
1334 pLinguData->Reconfigure(m_xLinguModulesCLB->get_text(rRowCol.first),
1335 m_xLinguModulesCLB->get_toggle(rRowCol.first) ==
TRISTATE_TRUE);
1347 if (m_xLinguModulesEditPB.get() == &rBtn)
1355 *pLinguData = aOldLinguData;
1359 for (sal_uInt32
i = 0;
i < nLen; ++
i)
1360 pLinguData->GetDisplayServiceArray()[
i].bConfigured =
false;
1361 for (
const auto& locale : pLinguData->GetAllSupportedLocales())
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 ] );
1375 UpdateModulesBox_Impl();
1377 else if (m_xLinguDicsNewPB.get() == &rBtn)
1382 if ( aDlg->Execute() ==
RET_OK )
1383 xNewDic = aDlg->GetNewDictionary();
1387 sal_Int32 nLen = aDics.getLength();
1388 aDics.realloc( nLen + 1 );
1390 aDics.getArray()[ nLen ] = xNewDic;
1392 AddDicBoxEntry( xNewDic,
static_cast<sal_uInt16
>(nLen) );
1395 else if (m_xLinguDicsEditPB.get() == &rBtn)
1397 int nEntry = m_xLinguDicsCLB->get_selected_index();
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)
1415 else if (m_xLinguDicsDelPB.get() == &rBtn)
1418 std::unique_ptr<weld::MessageDialog> xQuery(xBuilder->weld_message_dialog(
"QueryDeleteDictionaryDialog"));
1419 if (
RET_NO == xQuery->run())
1422 int nEntry = m_xLinguDicsCLB->get_selected_index();
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)
1438 xDicList->removeDictionary( xDic );
1441 if ( xStor->hasLocation() && !xStor->isReadonly() )
1443 OUString sURL = xStor->getLocation();
1446 "non-file URLs cannot be deleted" );
1453 aDics.getArray()[ nDicPos ] =
nullptr;
1456 int nCnt = m_xLinguDicsCLB->n_children();
1457 for (
int i = 0;
i < nCnt; ++
i)
1459 DicUserData aDicData(m_xLinguDicsCLB->get_id(
i).toUInt32());
1460 if (aDicData.GetEntryId() == nDicPos )
1462 m_xLinguDicsCLB->remove(
i);
1466 DBG_ASSERT( nCnt > m_xLinguDicsCLB->n_children(),
1473 else if (m_xLinguOptionsEditPB.get() == &rBtn)
1475 int nEntry = m_xLinguOptionsCLB->get_selected_index();
1476 DBG_ASSERT(nEntry != -1,
"no entry selected");
1479 OptionsUserData
aData(m_xLinguOptionsCLB->get_id(nEntry).toUInt32());
1480 if (
aData.HasNumericValue())
1482 sal_uInt16 nRID =
aData.GetEntryId();
1484 aDlg.GetNumericFld().set_value(
aData.GetNumericValue());
1485 if (
RET_OK == aDlg.run())
1487 int nVal = aDlg.GetNumericFld().get_value();
1488 if (-1 != nVal &&
aData.GetNumericValue() != 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()));
1506 SAL_WARN(
"cui.options",
"rBtn unexpected value");
1512 if (m_xLinguModulesCLB.get() == &rBox)
1515 else if (m_xLinguDicsCLB.get() == &rBox)
1517 int nEntry = rBox.get_selected_index();
1520 DicUserData
aData(rBox.get_id(nEntry).toUInt32());
1523 m_xLinguDicsEditPB->set_sensitive(
true );
1524 m_xLinguDicsDelPB->set_sensitive(
aData.IsDeletable() );
1527 else if (m_xLinguOptionsCLB.get() == &rBox)
1529 int nEntry = rBox.get_selected_index();
1532 OptionsUserData
aData(rBox.get_id(nEntry).toUInt32());
1533 m_xLinguOptionsEditPB->set_sensitive(
aData.HasNumericValue() );
1538 SAL_WARN(
"cui.options",
"rBtn unexpected value");
1565 : GenericDialogController(pParent,
"cui/ui/editmodulesdialog.ui",
"EditModulesDialog")
1566 , sSpell(
CuiResId(RID_CUISTR_SPELL))
1569 , sGrammar(
CuiResId(RID_CUISTR_GRAMMAR))
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")))
1602 m_xLanguageLB->SetLanguageList(SvxLanguageListFlags::EMPTY,
false,
false,
true);
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); });
1622 for (
int i = 0, nEntryCount =
m_xModulesCLB->n_children();
i < nEntryCount; ++
i)
1623 delete weld::fromId<ModuleUserData_Impl*>(
m_xModulesCLB->get_id(
i));
1628 int nCurPos = rBox.get_selected_index();
1632 bool bDisableUp =
true;
1633 bool bDisableDown =
true;
1634 ModuleUserData_Impl*
pData = weld::fromId<ModuleUserData_Impl*>(rBox.get_id(nCurPos));
1637 if (nCurPos < rBox.n_children() - 1)
1639 bDisableDown = weld::fromId<ModuleUserData_Impl*>(rBox.get_id(nCurPos + 1))->IsParent();
1643 bDisableUp = weld::fromId<ModuleUserData_Impl*>(rBox.get_id(nCurPos - 1))->IsParent();
1646 m_xPrioUpPB->set_sensitive(!bDisableUp);
1647 m_xPrioDownPB->set_sensitive(!bDisableDown);
1652 ModuleUserData_Impl*
pData = weld::fromId<ModuleUserData_Impl*>(m_xModulesCLB->get_id(rRowCol.first));
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)
1661 pData = weld::fromId<ModuleUserData_Impl*>(m_xModulesCLB->get_id(
i));
1671 LangSelectHdl_Impl(m_xLanguageLB.get());
1677 static Locale aLastLocale;
1687 sal_Int32 nStart = 0, nLocalIndex = 0;
1689 bool bChanged =
false;
1690 for (
int i = 0, nEntryCount =
m_xModulesCLB->n_children();
i < nEntryCount; ++
i)
1692 ModuleUserData_Impl*
pData = weld::fromId<ModuleUserData_Impl*>(
m_xModulesCLB->get_id(
i));
1693 if (
pData->IsParent())
1708 aChange.realloc(nStart);
1709 (*pTable)[ nLang ] = aChange;
1712 nLocalIndex = nStart = 0;
1713 aChange.realloc(nEntryCount);
1718 OUString* pChange = aChange.getArray();
1719 pChange[nStart] =
pData->GetImplName();
1720 bChanged |=
pData->GetIndex() != nLocalIndex ||
1729 aChange.realloc(nStart);
1734 for (
int i = 0, nEntryCount =
m_xModulesCLB->n_children();
i < nEntryCount; ++
i)
1735 delete weld::fromId<ModuleUserData_Impl*>(
m_xModulesCLB->get_id(
i));
1743 ServiceInfo_Impl* pInfo;
1748 ModuleUserData_Impl* pUserData =
new ModuleUserData_Impl(
1758 const OUString *
pName = aNames.getConstArray();
1759 sal_Int32 nNames = aNames.getLength();
1760 sal_Int32 nLocalIndex = 0;
1761 for (
n = 0;
n < nNames; ++
n)
1764 bool bIsSuppLang =
false;
1769 bIsSuppLang = pInfo->xSpell.is() &&
1770 pInfo->xSpell->hasLocale( aCurLocale );
1771 aImplName = pInfo->sSpellImplName;
1773 if (!aImplName.isEmpty() && bIsSuppLang)
1775 OUString aTxt( pInfo->sDisplayName );
1778 const bool bHasLang = rTable.count( eCurLanguage );
1781 SAL_INFO(
"cui.options",
"language entry missing" );
1783 const bool bCheck = bHasLang &&
lcl_SeqGetEntryPos( rTable[ eCurLanguage ], aImplName ) >= 0;
1784 pUserData =
new ModuleUserData_Impl( aImplName,
false,
1799 pUserData =
new ModuleUserData_Impl( OUString(),
true,
false,
TYPE_GRAMMAR, 0 );
1808 pName = aNames.getConstArray();
1809 nNames = aNames.getLength();
1811 for (
n = 0;
n < nNames; ++
n)
1814 bool bIsSuppLang =
false;
1819 bIsSuppLang = pInfo->xGrammar.is() &&
1820 pInfo->xGrammar->hasLocale( aCurLocale );
1821 aImplName = pInfo->sGrammarImplName;
1823 if (!aImplName.isEmpty() && bIsSuppLang)
1825 OUString aTxt( pInfo->sDisplayName );
1828 const bool bHasLang = rTable.count( eCurLanguage );
1831 SAL_INFO(
"cui.options",
"language entry missing" );
1833 const bool bCheck = bHasLang &&
lcl_SeqGetEntryPos( rTable[ eCurLanguage ], aImplName ) >= 0;
1834 pUserData =
new ModuleUserData_Impl( aImplName,
false,
1850 pUserData =
new ModuleUserData_Impl( OUString(),
true,
false,
TYPE_HYPH, 0 );
1859 pName = aNames.getConstArray();
1860 nNames = aNames.getLength();
1862 for (
n = 0;
n < nNames; ++
n)
1865 bool bIsSuppLang =
false;
1870 bIsSuppLang = pInfo->xHyph.is() &&
1871 pInfo->xHyph->hasLocale( aCurLocale );
1872 aImplName = pInfo->sHyphImplName;
1874 if (!aImplName.isEmpty() && bIsSuppLang)
1876 OUString aTxt( pInfo->sDisplayName );
1879 const bool bHasLang = rTable.count( eCurLanguage );
1882 SAL_INFO(
"cui.options",
"language entry missing" );
1884 const bool bCheck = bHasLang &&
lcl_SeqGetEntryPos( rTable[ eCurLanguage ], aImplName ) >= 0;
1885 pUserData =
new ModuleUserData_Impl( aImplName,
false,
1900 pUserData =
new ModuleUserData_Impl( OUString(),
true,
false,
TYPE_THES, 0 );
1909 pName = aNames.getConstArray();
1910 nNames = aNames.getLength();
1912 for (
n = 0;
n < nNames; ++
n)
1915 bool bIsSuppLang =
false;
1920 bIsSuppLang = pInfo->xThes.is() &&
1921 pInfo->xThes->hasLocale( aCurLocale );
1922 aImplName = pInfo->sThesImplName;
1924 if (!aImplName.isEmpty() && bIsSuppLang)
1926 OUString aTxt( pInfo->sDisplayName );
1929 const bool bHasLang = rTable.count( eCurLanguage );
1932 SAL_INFO(
"cui.options",
"language entry missing" );
1934 const bool bCheck = bHasLang &&
lcl_SeqGetEntryPos( rTable[ eCurLanguage ], aImplName ) >= 0;
1935 pUserData =
new ModuleUserData_Impl( aImplName,
false,
1948 aLastLocale = aCurLocale;
1953 bool bUp = m_xPrioUpPB.get() == &rBtn;
1954 int nCurPos = m_xModulesCLB->get_selected_index();
1958 m_xModulesCLB->freeze();
1960 OUString
sId(m_xModulesCLB->get_id(nCurPos));
1961 OUString sStr(m_xModulesCLB->get_text(nCurPos));
1962 bool bIsChecked = m_xModulesCLB->get_toggle(nCurPos);
1964 m_xModulesCLB->remove(nCurPos);
1966 int nDestPos = bUp ? nCurPos - 1 : nCurPos + 1;
1968 m_xModulesCLB->insert_text(nDestPos, sStr);
1969 m_xModulesCLB->set_id(nDestPos,
sId);
1972 m_xModulesCLB->thaw();
1974 m_xModulesCLB->select(nDestPos);
1975 SelectHdl_Impl(*m_xModulesCLB);
1981 LangSelectHdl_Impl(m_xLanguageLB.get());
1987 rLinguData = *pDefaultLinguData;
1988 LangSelectHdl_Impl(
nullptr);
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()
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
std::unique_ptr< weld::Button > m_xBackPB
std::unique_ptr< SvxLanguageBox > m_xLanguageLB
SvxLinguData_Impl & rLinguData
std::unique_ptr< weld::Button > m_xPrioUpPB
std::unique_ptr< weld::Button > m_xPrioDownPB
std::unique_ptr< weld::LinkButton > m_xMoreDictsLink
std::unique_ptr< weld::TreeView > m_xModulesCLB
void LangSelectHdl_Impl(const SvxLanguageBox *pBox)
SvxEditModulesDlg(weld::Window *pParent, SvxLinguData_Impl &rData)
virtual ~SvxEditModulesDlg() override
std::unique_ptr< SvxLinguData_Impl > pDefaultLinguData
LangImplNameTable aCfgSpellTable
LangImplNameTable aCfgHyphTable
ServiceInfo_Impl * GetInfoByImplName(std::u16string_view rSvcImplName)
const auto & GetAllSupportedLocales() const
uno::Reference< XLinguServiceManager2 > & GetManager()
ServiceInfoArr & GetDisplayServiceArray()
LangImplNameTable & GetSpellTable()
const sal_uInt32 & GetDisplayServiceCount() const
LangImplNameTable & GetHyphTable()
ServiceInfoArr aDisplayServiceArr
static bool AddRemove(Sequence< OUString > &rConfigured, const OUString &rImplName, bool bAdd)
void Reconfigure(std::u16string_view rDisplayName, bool bEnable)
uno::Reference< XLinguServiceManager2 > xLinguSrvcMgr
sal_uInt32 nDisplayServices
LangImplNameTable & GetGrammarTable()
LangImplNameTable aCfgThesTable
void SetDisplayServiceCount(sal_uInt32 nVal)
LangImplNameTable aCfgGrammarTable
LangImplNameTable & GetThesTable()
void SetChecked(const Sequence< OUString > &rConfiguredServices)
std::set< Locale, Locale_less > aAllServiceLocales
Sequence< OUString > GetSortedImplNames(LanguageType nLang, sal_uInt8 nType)
std::unique_ptr< weld::TreeView > m_xLinguOptionsCLB
std::unique_ptr< weld::Label > m_xLinguDicsFT
int nUPN_HYPH_MIN_TRAILING
int nUPN_HYPH_MIN_WORD_LENGTH
std::unique_ptr< weld::TreeView > m_xLinguDicsCLB
OUString sWordsWithDigits
std::unique_ptr< weld::Label > m_xLinguModulesFT
OUString sSpellClosedCompound
std::unique_ptr< weld::Button > m_xLinguDicsNewPB
std::unique_ptr< weld::LinkButton > m_xMoreDictsLink
std::unique_ptr< weld::Button > m_xLinguModulesEditPB
css::uno::Reference< css::linguistic2::XLinguProperties > xProp
std::unique_ptr< weld::Button > m_xLinguDicsEditPB
std::unique_ptr< weld::Box > m_xMoreDictsBox
css::uno::Sequence< css::uno::Reference< css::linguistic2::XDictionary > > aDics
static std::unique_ptr< SfxTabPage > Create(weld::Container *pPage, weld::DialogController *pController, const SfxItemSet *rSet)
SvxLinguTabPage(weld::Container *pPage, weld::DialogController *pController, const SfxItemSet &rCoreSet)
OUString sSpellHyphenatedCompound
std::unique_ptr< weld::TreeView > m_xLinguModulesCLB
css::uno::Reference< css::linguistic2::XDictionaryList > xDicList
static sal_uInt32 GetDicUserData(const css::uno::Reference< css::linguistic2::XDictionary > &rxDic, sal_uInt16 nIdx)
std::unique_ptr< weld::Button > m_xLinguOptionsEditPB
ImplSVEvent * m_nDlbClickEventId
int nUPN_HYPH_MIN_LEADING
virtual bool FillItemSet(SfxItemSet *rSet) override
std::unique_ptr< weld::Button > m_xLinguDicsDelPB
void HideGroups(sal_uInt16 nGrp)
virtual void Reset(const SfxItemSet *rSet) override
void UpdateModulesBox_Impl()
std::unique_ptr< SvxLinguData_Impl > pLinguData
void AddDicBoxEntry(const css::uno::Reference< css::linguistic2::XDictionary > &rxDic, sal_uInt16 nIdx)
virtual ~SvxLinguTabPage() override
std::pair< const TreeIter &, int > iter_col
OUString CuiResId(TranslateId aKey)
#define DBG_ASSERT(sCon, aError)
#define TOOLS_WARN_EXCEPTION(area, stream)
weld::Window * GetFrameWeld(const SfxFrame *pFrame)
virtual tools::Long GetValue() const override
#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
#define LINK(Instance, Class, Member)
#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()
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)
static void lcl_MergeDisplayArray(SvxLinguData_Impl &rData, const ServiceInfo_Impl &rToAdd)
constexpr OUStringLiteral cHyph(SN_HYPHENATOR)
constexpr OUStringLiteral cGrammar(SN_GRAMMARCHECKER)
static sal_Int32 lcl_SeqGetIndex(const Sequence< OUString > &rSeq, std::u16string_view rTxt)
std::vector< ServiceInfo_Impl > ServiceInfoArr
IMPL_LINK_NOARG(SvxLinguTabPage, PostDblClickHdl_Impl, void *, void)
static bool KillFile_Impl(const OUString &rURL)
IMPL_LINK(SvxLinguTabPage, BoxDoubleClickHdl_Impl, weld::TreeView &, rBox, bool)
static OUString lcl_GetPropertyName(EID_OPTIONS eEntryId)
constexpr OUStringLiteral cSpell(SN_SPELLCHECKER)
constexpr OUStringLiteral cThes(SN_THESAURUS)
static sal_Int32 lcl_SeqGetEntryPos(const Sequence< OUString > &rSeq, std::u16string_view rEntry)
std::map< LanguageType, Sequence< OUString > > LangImplNameTable