23#include <com/sun/star/deployment/DeploymentException.hpp>
24#include <com/sun/star/deployment/ExtensionManager.hpp>
25#include <com/sun/star/container/XContentEnumerationAccess.hpp>
26#include <com/sun/star/container/XEnumeration.hpp>
27#include <com/sun/star/lang/XSingleComponentFactory.hpp>
28#include <com/sun/star/lang/XSingleServiceFactory.hpp>
29#include <com/sun/star/linguistic2/XSupportedLocales.hpp>
30#include <com/sun/star/linguistic2/DictionaryListEventFlags.hpp>
31#include <com/sun/star/linguistic2/LinguServiceEventFlags.hpp>
32#include <com/sun/star/linguistic2/ProofreadingIterator.hpp>
61static bool lcl_SeqHasString(
const uno::Sequence< OUString > &rSeq,
const OUString &rText )
63 return !rText.isEmpty()
69 const uno::Sequence< OUString > &rSvcImplNames )
71 uno::Sequence< lang::Locale > aRes;
74 if( rSvcImplNames.hasElements() )
76 std::set< LanguageType > aLanguages;
79 uno::Sequence< uno::Any > aArgs(2);
85 for (
const OUString& rImplName : rSvcImplNames)
87 uno::Reference< linguistic2::XSupportedLocales > xSuppLoc;
90 xSuppLoc.set( xContext->getServiceManager()->createInstanceWithArgumentsAndContext(
91 rImplName, aArgs, xContext ),
94 catch (uno::Exception &)
96 SAL_WARN(
"linguistic",
"createInstanceWithArguments failed" );
101 const uno::Sequence< lang::Locale > aLoc( xSuppLoc->getLocales() );
102 for (
const lang::Locale& rLoc : aLoc)
107 aLanguages.insert( nLang );
112 SAL_WARN(
"linguistic",
"interface not supported by service" );
117 std::vector<lang::Locale> aVec;
118 aVec.reserve(aLanguages.size());
120 std::transform(aLanguages.begin(), aLanguages.end(), std::back_inserter(aVec),
121 [](
const LanguageType& rLang) -> lang::Locale { return LanguageTag::convertToLocale(rLang); });
136 std::vector< LanguageType >&& rSuppLanguages ) :
157 public cppu::WeakImplHelper
159 linguistic2::XLinguServiceEventListener,
160 linguistic2::XDictionaryListEventListener
167 uno::Reference< linguistic2::XSearchableDictionaryList >
xDicList;
177 uno::Reference< linguistic2::XSearchableDictionaryList >
xDicList );
183 virtual void SAL_CALL
184 disposing(
const lang::EventObject& rSource )
override;
187 virtual void SAL_CALL
191 virtual void SAL_CALL
193 const linguistic2::DictionaryListEvent& rDicListEvent )
override;
196 const uno::Reference< lang::XEventListener >& rxListener );
198 const uno::Reference< lang::XEventListener >& rxListener );
201 const uno::Reference< linguistic2::XLinguServiceEventBroadcaster > &rxBroadcaster );
203 const uno::Reference< linguistic2::XLinguServiceEventBroadcaster > &rxBroadcaster );
211 uno::Reference< linguistic2::XSearchableDictionaryList > xDicList_ ) :
212 rMyManager ( rLngSvcMgr ),
215 xDicList (
std::move( xDicList_ ))
219 xDicList->addDictionaryListEventListener(
220 static_cast<linguistic2::XDictionaryListEventListener *
>(
this),
false );
231 uno::Reference< uno::XInterface > xRef( rSource.Source );
249 linguistic2::LinguServiceEvent aEvtObj(
271 const linguistic2::LinguServiceEvent& rLngSvcEvent )
280 const linguistic2::DictionaryListEvent& rDicListEvent )
284 sal_Int16 nDlEvt = rDicListEvent.nCondensedEvent;
294 sal_Int16 nLngSvcEvt = 0;
295 sal_Int16
const nSpellCorrectFlags =
296 linguistic2::DictionaryListEventFlags::ADD_NEG_ENTRY |
297 linguistic2::DictionaryListEventFlags::DEL_POS_ENTRY |
298 linguistic2::DictionaryListEventFlags::ACTIVATE_NEG_DIC |
299 linguistic2::DictionaryListEventFlags::DEACTIVATE_POS_DIC;
300 if (0 != (nDlEvt & nSpellCorrectFlags))
301 nLngSvcEvt |= linguistic2::LinguServiceEventFlags::SPELL_CORRECT_WORDS_AGAIN;
303 sal_Int16
const nSpellWrongFlags =
304 linguistic2::DictionaryListEventFlags::ADD_POS_ENTRY |
305 linguistic2::DictionaryListEventFlags::DEL_NEG_ENTRY |
306 linguistic2::DictionaryListEventFlags::ACTIVATE_POS_DIC |
307 linguistic2::DictionaryListEventFlags::DEACTIVATE_NEG_DIC;
308 if (0 != (nDlEvt & nSpellWrongFlags))
309 nLngSvcEvt |= linguistic2::LinguServiceEventFlags::SPELL_WRONG_WORDS_AGAIN;
311 sal_Int16
const nHyphenateFlags =
312 linguistic2::DictionaryListEventFlags::ADD_POS_ENTRY |
313 linguistic2::DictionaryListEventFlags::DEL_POS_ENTRY |
314 linguistic2::DictionaryListEventFlags::ACTIVATE_POS_DIC |
315 linguistic2::DictionaryListEventFlags::ACTIVATE_NEG_DIC;
316 if (0 != (nDlEvt & nHyphenateFlags))
317 nLngSvcEvt |= linguistic2::LinguServiceEventFlags::HYPHENATE_AGAIN;
328 linguistic2::LinguServiceEvent aEvt(
329 static_cast<css::linguistic2::XLinguServiceManager*
>(&
rMyManager), nLngSvcEvtFlags );
337 const uno::Reference< lang::XEventListener >& rxListener )
344 const uno::Reference< lang::XEventListener >& rxListener )
359 uno::Reference< linguistic2::XLinguServiceEventBroadcaster > xRef( aIt.
next(), uno::UNO_QUERY );
367 xDicList->removeDictionaryListEventListener(
368 static_cast<linguistic2::XDictionaryListEventListener *
>(
this) );
375 const uno::Reference< linguistic2::XLinguServiceEventBroadcaster > &rxBroadcaster )
377 if (rxBroadcaster.is())
380 rxBroadcaster->addLinguServiceEventListener(
381 static_cast<linguistic2::XLinguServiceEventListener *
>(
this) );
387 const uno::Reference< linguistic2::XLinguServiceEventBroadcaster > &rxBroadcaster )
389 if (rxBroadcaster.is())
392 rxBroadcaster->removeLinguServiceEventListener(
393 static_cast<linguistic2::XLinguServiceEventListener *
>(
this) );
399 :
utl::ConfigItem(
"Office.Linguistic")
401 , aUpdateIdle(
"LngSvcMgr aUpdateIdle")
406 uno::Sequence< OUString > aNames{
407 "ServiceManager/SpellCheckerList",
408 "ServiceManager/GrammarCheckerList",
409 "ServiceManager/HyphenatorList",
410 "ServiceManager/ThesaurusList"
422 uno::Reference<deployment::XExtensionManager> xExtensionManager;
424 xExtensionManager = deployment::ExtensionManager::get(xContext);
425 }
catch (
const uno::DeploymentException & ) {
426 SAL_WARN(
"linguistic",
"no extension manager - should fire on mobile only" );
427 }
catch (
const deployment::DeploymentException & ) {
428 SAL_WARN(
"linguistic",
"no extension manager - should fire on mobile only" );
430 if (xExtensionManager.is())
432 xMB.set(xExtensionManager, uno::UNO_QUERY_THROW);
434 uno::Reference<util::XModifyListener> xListener(
this);
435 xMB->addModifyListener( xListener );
465 if (mxListenerHelper.is())
467 mxListenerHelper->AddLngSvcEvt(
468 linguistic2::LinguServiceEventFlags::SPELL_CORRECT_WORDS_AGAIN |
469 linguistic2::LinguServiceEventFlags::SPELL_WRONG_WORDS_AGAIN |
470 linguistic2::LinguServiceEventFlags::PROOFREAD_AGAIN |
471 linguistic2::LinguServiceEventFlags::HYPHENATE_AGAIN );
484 uno::Reference<util::XModifyListener> xListener(
this);
485 xMB->removeModifyListener(xListener);
487 catch (
const uno::Exception&)
519 bool lcl_FindEntry(
const OUString &rEntry,
const Sequence< OUString > &rCfgSvcs )
524 bool lcl_FindEntry(
const OUString &rEntry,
const std::vector< OUString > &rCfgSvcs )
526 return std::find(rCfgSvcs.begin(), rCfgSvcs.end(), rEntry) != rCfgSvcs.end();
529 Sequence< OUString > lcl_GetLastFoundSvcs(
531 const OUString &rLastFoundList ,
532 const OUString& rCfgLocaleStr )
534 Sequence< OUString > aRes;
536 Sequence< OUString > aNodeNames( rCfg.
GetNodeNames(rLastFoundList) );
537 bool bFound = lcl_FindEntry( rCfgLocaleStr, aNodeNames);
541 Sequence< OUString > aNames { rLastFoundList +
"/" + rCfgLocaleStr };
543 if (aValues.hasElements())
545 SAL_WARN_IF( aValues.getLength() != 1,
"linguistic",
"unexpected length of sequence" );
546 Sequence< OUString > aSvcImplNames;
547 if (aValues.getConstArray()[0] >>= aSvcImplNames)
548 aRes = aSvcImplNames;
551 SAL_WARN(
"linguistic",
"type mismatch" );
559 Sequence< OUString > lcl_RemoveMissingEntries(
560 const Sequence< OUString > &rCfgSvcs,
561 const Sequence< OUString > &rAvailSvcs )
563 std::vector<OUString> aRes;
564 aRes.reserve(rCfgSvcs.getLength());
566 std::copy_if(rCfgSvcs.begin(), rCfgSvcs.end(), std::back_inserter(aRes),
567 [&rAvailSvcs](
const OUString& entry) { return lcl_SeqHasString(rAvailSvcs, entry); });
572 Sequence< OUString > lcl_GetNewEntries(
573 const Sequence< OUString > &rLastFoundSvcs,
574 const Sequence< OUString > &rAvailSvcs )
576 std::vector<OUString> aRes;
577 aRes.reserve(rAvailSvcs.getLength());
579 std::copy_if(rAvailSvcs.begin(), rAvailSvcs.end(), std::back_inserter(aRes),
580 [&rLastFoundSvcs](
const OUString& rEntry) {
581 return !rEntry.isEmpty() && !lcl_FindEntry( rEntry, rLastFoundSvcs ); });
586 Sequence< OUString > lcl_MergeSeq(
587 const Sequence< OUString > &rCfgSvcs,
588 const Sequence< OUString > &rNewSvcs )
590 std::vector<OUString> aRes;
591 aRes.reserve(rCfgSvcs.getLength() + rNewSvcs.getLength());
593 auto lVecNotHasString = [&aRes](
const OUString& rEntry)
594 {
return !rEntry.isEmpty() && !lcl_FindEntry(rEntry, aRes); };
598 for (
const Sequence< OUString > &rSeq : { rCfgSvcs, rNewSvcs })
600 std::copy_if(rSeq.begin(), rSeq.end(), std::back_inserter(aRes), lVecNotHasString);
609 using beans::PropertyValue;
613 typedef std::map< OUString, Sequence< OUString > > list_entry_map_t;
617 const int nNumServices = 4;
619 const char *
const apCurLists[nNumServices] = {
"ServiceManager/SpellCheckerList",
"ServiceManager/GrammarCheckerList",
"ServiceManager/HyphenatorList",
"ServiceManager/ThesaurusList" };
620 const char *
const apLastFoundLists[nNumServices] = {
"ServiceManager/LastFoundSpellCheckers",
"ServiceManager/LastFoundGrammarCheckers",
"ServiceManager/LastFoundHyphenators",
"ServiceManager/LastFoundThesauri" };
623 std::vector< list_entry_map_t > aLastFoundSvcs(nNumServices);
624 std::vector< list_entry_map_t > aCurSvcs(nNumServices);
626 for (
int k = 0; k < nNumServices; ++k)
628 OUString aService( apServices[k] );
629 OUString aActiveList( OUString::createFromAscii( apCurLists[k] ) );
630 OUString aLastFoundList( OUString::createFromAscii( apLastFoundLists[k] ) );
635 const Sequence< OUString > aNodeNames( aCfg.
GetNodeNames( aActiveList ) );
636 for (
const OUString& rNodeName : aNodeNames)
642 aCfgSvcs = lcl_RemoveMissingEntries( aCfgSvcs, aAvailSvcs );
644 aCurSvcs[k][ rNodeName ] = aCfgSvcs;
653 for (
const Locale& rAvailLocale : aAvailLocales)
659 aLastFoundSvcs[k][ aCfgLocaleStr ] = aAvailSvcs;
661 Sequence< OUString > aLastSvcs(
662 lcl_GetLastFoundSvcs( aCfg, aLastFoundList , aCfgLocaleStr ));
663 Sequence< OUString > aNewSvcs =
664 lcl_GetNewEntries( aLastSvcs, aAvailSvcs );
666 Sequence< OUString > aCfgSvcs( aCurSvcs[k][ aCfgLocaleStr ] );
669 aCfgSvcs = lcl_MergeSeq( aCfgSvcs, aNewSvcs );
671 aCurSvcs[k][ aCfgLocaleStr ] = aCfgSvcs;
678 for (
int k = 0; k < nNumServices; ++k)
680 for (
int i = 0;
i < 2; ++
i)
682 const char *pSubNodeName = (
i == 0) ? apCurLists[k] : apLastFoundLists[k];
683 OUString aSubNodeName( OUString::createFromAscii(pSubNodeName) );
685 list_entry_map_t &rCurMap = (
i == 0) ? aCurSvcs[k] : aLastFoundSvcs[k];
686 sal_Int32 nVals =
static_cast< sal_Int32
>( rCurMap.size() );
687 Sequence< PropertyValue > aNewValues( nVals );
688 PropertyValue *pNewValue = aNewValues.getArray();
689 for (
auto const& elem : rCurMap)
691 pNewValue->Name = aSubNodeName +
"/" + elem.first;
692 pNewValue->Value <<= elem.second;
695 OSL_ENSURE( pNewValue - aNewValues.getConstArray() == nVals,
696 "possible mismatch of sequence size and property number" );
701 SAL_WARN_IF(!bRes,
"linguistic",
"failed to set new configuration values");
713 static constexpr OUStringLiteral aSpellCheckerList(
u"ServiceManager/SpellCheckerList" );
714 static constexpr OUStringLiteral aGrammarCheckerList(
u"ServiceManager/GrammarCheckerList" );
715 static constexpr OUStringLiteral aHyphenatorList(
u"ServiceManager/HyphenatorList" );
716 static constexpr OUStringLiteral aThesaurusList(
u"ServiceManager/ThesaurusList" );
718 const uno::Sequence< OUString > aSpellCheckerListEntries(
GetNodeNames( aSpellCheckerList ) );
719 const uno::Sequence< OUString > aGrammarCheckerListEntries(
GetNodeNames( aGrammarCheckerList ) );
720 const uno::Sequence< OUString > aHyphenatorListEntries(
GetNodeNames( aHyphenatorList ) );
721 const uno::Sequence< OUString > aThesaurusListEntries(
GetNodeNames( aThesaurusList ) );
723 uno::Sequence< uno::Any > aValues;
724 uno::Sequence< OUString > aNames( 1 );
725 OUString *pNames = aNames.getArray();
727 for (
const OUString& rName : rPropertyNames)
733 nKeyStart = rName.lastIndexOf(
'/' );
736 aKeyText = rName.copy( nKeyStart + 1 );
737 SAL_WARN_IF( aKeyText.isEmpty(),
"linguistic",
"unexpected key (lang::Locale) string" );
738 if (rName.startsWith( aSpellCheckerList ))
747 pNames[0] = aSpellCheckerList +
"/" + aKeyText;
749 uno::Sequence< OUString > aSvcImplNames;
750 if (aValues.hasElements())
754 if (!aKeyText.isEmpty())
761 else if (rName.startsWith( aGrammarCheckerList ))
770 pNames[0] = aGrammarCheckerList +
"/" + aKeyText;
772 uno::Sequence< OUString > aSvcImplNames;
773 if (aValues.hasElements())
774 aSvcImplNames =
GetLangSvc( aValues.getConstArray()[0] );
777 if (!aKeyText.isEmpty())
787 else if (rName.startsWith( aHyphenatorList ))
796 pNames[0] = aHyphenatorList +
"/" + aKeyText;
798 uno::Sequence< OUString > aSvcImplNames;
799 if (aValues.hasElements())
800 aSvcImplNames =
GetLangSvc( aValues.getConstArray()[0] );
803 if (!aKeyText.isEmpty())
810 else if (rName.startsWith( aThesaurusList ))
819 pNames[0] = aThesaurusList +
"/" + aKeyText;
821 uno::Sequence< OUString > aSvcImplNames;
822 if (aValues.hasElements())
826 if (!aKeyText.isEmpty())
835 SAL_WARN(
"linguistic",
"notified for unexpected property" );
876 uno::Reference< linguistic2::XProofreadingIterator > xGCI;
881 catch (
const uno::Exception &)
884 SAL_WARN_IF( !xGCI.is(),
"linguistic",
"instantiating grammar checking iterator failed" );
927 uno::Reference< container::XContentEnumerationAccess > xEnumAccess( xContext->getServiceManager(), uno::UNO_QUERY );
928 uno::Reference< container::XEnumeration > xEnum;
929 if (xEnumAccess.is())
935 while (xEnum->hasMoreElements())
937 uno::Any aCurrent = xEnum->nextElement();
938 uno::Reference< lang::XSingleComponentFactory > xCompFactory;
939 uno::Reference< lang::XSingleServiceFactory >
xFactory;
941 xCompFactory.set(aCurrent, css::uno::UNO_QUERY);
942 if (!xCompFactory.is())
944 xFactory.set(aCurrent, css::uno::UNO_QUERY);
946 if ( xCompFactory.is() ||
xFactory.is() )
950 uno::Reference< linguistic2::XSpellChecker > xSvc( ( xCompFactory.is() ? xCompFactory->createInstanceWithContext( xContext ) :
xFactory->createInstance() ), uno::UNO_QUERY_THROW );
953 std::vector< LanguageType > aLanguages;
954 uno::Reference< XServiceInfo > xInfo( xSvc, uno::UNO_QUERY );
956 aImplName = xInfo->getImplementationName();
957 SAL_WARN_IF( aImplName.isEmpty(),
"linguistic",
"empty implementation name" );
958 uno::Sequence<lang::Locale> aLocaleSequence(xSvc->getLocales());
963 catch (
const uno::Exception &)
965 SAL_WARN(
"linguistic",
"createInstance failed" );
981 uno::Reference< container::XContentEnumerationAccess > xEnumAccess( xContext->getServiceManager(), uno::UNO_QUERY );
982 uno::Reference< container::XEnumeration > xEnum;
983 if (xEnumAccess.is())
989 while (xEnum->hasMoreElements())
991 uno::Any aCurrent = xEnum->nextElement();
992 uno::Reference< lang::XSingleComponentFactory > xCompFactory;
993 uno::Reference< lang::XSingleServiceFactory >
xFactory;
995 xCompFactory.set(aCurrent, css::uno::UNO_QUERY);
996 if (!xCompFactory.is())
998 xFactory.set(aCurrent, css::uno::UNO_QUERY);
1000 if ( xCompFactory.is() ||
xFactory.is() )
1004 uno::Reference< linguistic2::XProofreader > xSvc(
1006 ? xCompFactory->createInstanceWithContext(xContext)
1008 uno::UNO_QUERY_THROW);
1011 std::vector< LanguageType > aLanguages;
1012 uno::Reference< XServiceInfo > xInfo( xSvc, uno::UNO_QUERY );
1014 aImplName = xInfo->getImplementationName();
1015 SAL_WARN_IF( aImplName.isEmpty(),
"linguistic",
"empty implementation name" );
1016 uno::Sequence<lang::Locale> aLocaleSequence(xSvc->getLocales());
1021 catch (
const uno::Exception &)
1023 SAL_WARN(
"linguistic",
"createInstance failed" );
1039 uno::Reference< container::XContentEnumerationAccess > xEnumAccess( xContext->getServiceManager(), uno::UNO_QUERY );
1040 uno::Reference< container::XEnumeration > xEnum;
1041 if (xEnumAccess.is())
1042 xEnum = xEnumAccess->createContentEnumeration(
SN_HYPHENATOR );
1047 while (xEnum->hasMoreElements())
1049 uno::Any aCurrent = xEnum->nextElement();
1050 uno::Reference< lang::XSingleComponentFactory > xCompFactory;
1051 uno::Reference< lang::XSingleServiceFactory >
xFactory;
1053 xCompFactory.set(aCurrent, css::uno::UNO_QUERY);
1054 if (!xCompFactory.is())
1056 xFactory.set(aCurrent, css::uno::UNO_QUERY);
1058 if ( xCompFactory.is() ||
xFactory.is() )
1062 uno::Reference< linguistic2::XHyphenator > xSvc( ( xCompFactory.is() ? xCompFactory->createInstanceWithContext( xContext ) :
xFactory->createInstance() ), uno::UNO_QUERY_THROW );
1064 std::vector< LanguageType > aLanguages;
1065 uno::Reference< XServiceInfo > xInfo( xSvc, uno::UNO_QUERY );
1067 aImplName = xInfo->getImplementationName();
1068 SAL_WARN_IF( aImplName.isEmpty(),
"linguistic",
"empty implementation name" );
1069 uno::Sequence<lang::Locale> aLocaleSequence(xSvc->getLocales());
1073 catch (
const uno::Exception &)
1075 SAL_WARN(
"linguistic",
"createInstance failed" );
1091 uno::Reference< container::XContentEnumerationAccess > xEnumAccess( xContext->getServiceManager(), uno::UNO_QUERY );
1092 uno::Reference< container::XEnumeration > xEnum;
1093 if (xEnumAccess.is())
1094 xEnum = xEnumAccess->createContentEnumeration(
SN_THESAURUS );
1099 while (xEnum->hasMoreElements())
1101 uno::Any aCurrent = xEnum->nextElement();
1102 uno::Reference< lang::XSingleComponentFactory > xCompFactory;
1103 uno::Reference< lang::XSingleServiceFactory >
xFactory;
1105 xCompFactory.set(aCurrent, css::uno::UNO_QUERY);
1106 if (!xCompFactory.is())
1108 xFactory.set(aCurrent, css::uno::UNO_QUERY);
1110 if ( xCompFactory.is() ||
xFactory.is() )
1114 uno::Reference< linguistic2::XThesaurus > xSvc( ( xCompFactory.is() ? xCompFactory->createInstanceWithContext( xContext ) :
xFactory->createInstance() ), uno::UNO_QUERY_THROW );
1117 std::vector< LanguageType > aLanguages;
1118 uno::Reference< XServiceInfo > xInfo( xSvc, uno::UNO_QUERY );
1120 aImplName = xInfo->getImplementationName();
1121 SAL_WARN_IF( aImplName.isEmpty(),
"linguistic",
"empty implementation name" );
1122 uno::Sequence<lang::Locale> aLocaleSequence(xSvc->getLocales());
1127 catch (
const uno::Exception &)
1129 SAL_WARN(
"linguistic",
"createInstance failed" );
1138 SAL_INFO(
"linguistic",
"linguistic: LngSvcMgr::SetCfgServiceLists - Spell" );
1140 OUString aNode(
"ServiceManager/SpellCheckerList");
1141 uno::Sequence< OUString > aNames(
GetNodeNames( aNode ) );
1144 OUString aPrefix = aNode +
"/";
1145 for (OUString &
name : asNonConstRange(aNames))
1150 const uno::Sequence< uno::Any > aValues(
GetProperties( aNames ) );
1151 if (!(aNames.hasElements() && aNames.getLength() == aValues.getLength()))
1154 const OUString *pNames = aNames.getConstArray();
1155 for (
const uno::Any& rValue : aValues)
1157 uno::Sequence< OUString > aSvcImplNames;
1158 if (rValue >>= aSvcImplNames)
1160 OUString aLocaleStr( *pNames++ );
1161 sal_Int32 nSeparatorPos = aLocaleStr.lastIndexOf(
'/' );
1162 aLocaleStr = aLocaleStr.copy( nSeparatorPos + 1 );
1171 SAL_INFO(
"linguistic",
"linguistic: LngSvcMgr::SetCfgServiceLists - Grammar" );
1173 OUString aNode(
"ServiceManager/GrammarCheckerList");
1174 uno::Sequence< OUString > aNames(
GetNodeNames( aNode ) );
1177 OUString aPrefix = aNode +
"/";
1178 for (OUString &
name : asNonConstRange(aNames))
1183 const uno::Sequence< uno::Any > aValues(
GetProperties( aNames ) );
1184 if (!(aNames.hasElements() && aNames.getLength() == aValues.getLength()))
1187 const OUString *pNames = aNames.getConstArray();
1188 for (
const uno::Any& rValue : aValues)
1190 uno::Sequence< OUString > aSvcImplNames;
1191 if (rValue >>= aSvcImplNames)
1194 if (aSvcImplNames.getLength() > 1)
1195 aSvcImplNames.realloc(1);
1197 OUString aLocaleStr( *pNames++ );
1198 sal_Int32 nSeparatorPos = aLocaleStr.lastIndexOf(
'/' );
1199 aLocaleStr = aLocaleStr.copy( nSeparatorPos + 1 );
1208 SAL_INFO(
"linguistic",
"linguistic: LngSvcMgr::SetCfgServiceLists - Hyph" );
1210 OUString aNode(
"ServiceManager/HyphenatorList");
1211 uno::Sequence< OUString > aNames(
GetNodeNames( aNode ) );
1214 OUString aPrefix = aNode +
"/";
1215 for (OUString &
name : asNonConstRange(aNames))
1220 const uno::Sequence< uno::Any > aValues(
GetProperties( aNames ) );
1221 if (!(aNames.hasElements() && aNames.getLength() == aValues.getLength()))
1224 const OUString *pNames = aNames.getConstArray();
1225 for (
const uno::Any& rValue : aValues)
1227 uno::Sequence< OUString > aSvcImplNames;
1228 if (rValue >>= aSvcImplNames)
1231 if (aSvcImplNames.getLength() > 1)
1232 aSvcImplNames.realloc(1);
1234 OUString aLocaleStr( *pNames++ );
1235 sal_Int32 nSeparatorPos = aLocaleStr.lastIndexOf(
'/' );
1236 aLocaleStr = aLocaleStr.copy( nSeparatorPos + 1 );
1245 SAL_INFO(
"linguistic",
"linguistic: LngSvcMgr::SetCfgServiceLists - Thes" );
1247 OUString aNode(
"ServiceManager/ThesaurusList");
1248 uno::Sequence< OUString > aNames(
GetNodeNames( aNode ) );
1251 OUString aPrefix = aNode +
"/";
1252 for (OUString &
name : asNonConstRange(aNames))
1257 const uno::Sequence< uno::Any > aValues(
GetProperties( aNames ) );
1258 if (!(aNames.hasElements() && aNames.getLength() == aValues.getLength()))
1261 const OUString *pNames = aNames.getConstArray();
1262 for (
const uno::Any& rValue : aValues)
1264 uno::Sequence< OUString > aSvcImplNames;
1265 if (rValue >>= aSvcImplNames)
1267 OUString aLocaleStr( *pNames++ );
1268 sal_Int32 nSeparatorPos = aLocaleStr.lastIndexOf(
'/' );
1269 aLocaleStr = aLocaleStr.copy( nSeparatorPos + 1 );
1276uno::Reference< linguistic2::XSpellChecker > SAL_CALL
1280#if OSL_DEBUG_LEVEL > 0
1284 uno::Reference< linguistic2::XSpellChecker > xRes;
1295uno::Reference< linguistic2::XHyphenator > SAL_CALL
1299#if OSL_DEBUG_LEVEL > 0
1302 uno::Reference< linguistic2::XHyphenator > xRes;
1313uno::Reference< linguistic2::XThesaurus > SAL_CALL
1317#if OSL_DEBUG_LEVEL > 0
1320 uno::Reference< linguistic2::XThesaurus > xRes;
1333 const uno::Reference< lang::XEventListener >& xListener )
1349 const uno::Reference< lang::XEventListener >& xListener )
1364uno::Sequence< OUString > SAL_CALL
1366 const OUString& rServiceName,
1367 const lang::Locale& rLocale )
1371 uno::Sequence< OUString > aRes;
1397 std::vector<OUString> aVec;
1398 aVec.reserve(pInfoArray->size());
1401 for (
const auto& rInfo : *pInfoArray)
1404 || rInfo.HasLanguage( nLanguage ))
1406 aVec.push_back(rInfo.aSvcImplName);
1417uno::Sequence< lang::Locale > SAL_CALL
1419 const OUString& rServiceName )
1423 uno::Sequence< lang::Locale > aRes;
1425 uno::Sequence< lang::Locale > *pAvailLocales =
nullptr;
1441 aRes = *pAvailLocales;
1448 const uno::Sequence< OUString > &rList2 )
1451 return rList1.getLength() == rList2.getLength()
1452 && std::equal(rList1.begin(), rList1.end(), rList2.begin(), rList2.end());
1458 const OUString& rServiceName,
1459 const lang::Locale& rLocale,
1460 const uno::Sequence< OUString >& rServiceImplNames )
1462 SAL_INFO(
"linguistic",
"linguistic: LngSvcMgr::setConfiguredServices" );
1478 mxSpellDsp->SetServiceList( rLocale, rServiceImplNames );
1483 linguistic2::LinguServiceEventFlags::SPELL_CORRECT_WORDS_AGAIN |
1484 linguistic2::LinguServiceEventFlags::SPELL_WRONG_WORDS_AGAIN );
1497 mxGrammarDsp->SetServiceList( rLocale, rServiceImplNames );
1502 linguistic2::LinguServiceEventFlags::PROOFREAD_AGAIN );
1513 mxHyphDsp->SetServiceList( rLocale, rServiceImplNames );
1518 linguistic2::LinguServiceEventFlags::HYPHENATE_AGAIN );
1529 mxThesDsp->SetServiceList( rLocale, rServiceImplNames );
1538 SAL_INFO(
"linguistic",
"linguistic: LngSvcMgr::SaveCfgSvcs" );
1543 uno::Sequence< lang::Locale > aLocales;
1574 if (pDsp && aLocales.hasElements())
1576 uno::Sequence< beans::PropertyValue > aValues( aLocales.getLength() );
1577 beans::PropertyValue *pValue = aValues.getArray();
1580 const char *pNodeName =
nullptr;
1582 pNodeName =
"ServiceManager/SpellCheckerList";
1584 pNodeName =
"ServiceManager/GrammarCheckerList";
1586 pNodeName =
"ServiceManager/HyphenatorList";
1588 pNodeName =
"ServiceManager/ThesaurusList";
1591 SAL_WARN(
"linguistic",
"node name missing" );
1593 OUString aNodeName( OUString::createFromAscii(pNodeName) );
1595 for (
const lang::Locale& rLocale : std::as_const(aLocales))
1597 uno::Sequence< OUString > aSvcImplNames = pDsp->
GetServiceList( rLocale );
1602 aSvcImplNames.realloc(1);
1603 aCfgAny <<= aSvcImplNames;
1607 pValue->Value = aCfgAny;
1608 pValue->Name = aNodeName +
"/" + aCfgLocaleStr;
1612 SAL_INFO(
"linguistic",
"linguistic: LngSvcMgr::SaveCfgSvcs - ReplaceSetProperties" );
1624 uno::Sequence< OUString > aRes;
1629#if OSL_DEBUG_LEVEL > 0
1630 for (
const OUString& rSvcName : std::as_const(aRes))
1632 SAL_WARN_IF( rSvcName.isEmpty(),
"linguistic",
"service impl-name missing" );
1643 uno::Sequence< OUString > aRes;
1654 if (aRes.getLength() > 1)
1660 if ((rVal >>= aImplName) && !aImplName.isEmpty())
1663 aRes.getArray()[0] = aImplName;
1667 SAL_WARN(
"linguistic",
"GetLangSvc: unexpected type encountered" );
1675uno::Sequence< OUString > SAL_CALL
1677 const OUString& rServiceName,
1678 const lang::Locale& rLocale )
1682 uno::Sequence< OUString > aSvcImplNames;
1686 uno::Sequence< uno::Any > aValues;
1687 uno::Sequence< OUString > aNames( 1 );
1688 OUString *pNames = aNames.getArray();
1691 OUString aNode(
"ServiceManager/SpellCheckerList");
1692 const uno::Sequence< OUString > aNodeEntries(
GetNodeNames( aNode ) );
1695 pNames[0] = aNode +
"/" + aCfgLocale;
1697 if (aValues.hasElements())
1703 OUString aNode(
"ServiceManager/GrammarCheckerList");
1704 const uno::Sequence< OUString > aNodeEntries(
GetNodeNames( aNode ) );
1707 pNames[0] = aNode +
"/" + aCfgLocale;
1709 if (aValues.hasElements())
1710 aSvcImplNames =
GetLangSvc( aValues.getConstArray()[0] );
1715 OUString aNode(
"ServiceManager/HyphenatorList");
1716 const uno::Sequence< OUString > aNodeEntries(
GetNodeNames( aNode ) );
1719 pNames[0] = aNode +
"/" + aCfgLocale;
1721 if (aValues.hasElements())
1722 aSvcImplNames =
GetLangSvc( aValues.getConstArray()[0] );
1727 OUString aNode(
"ServiceManager/ThesaurusList");
1728 const uno::Sequence< OUString > aNodeEntries(
GetNodeNames( aNode ) );
1731 pNames[0] = aNode +
"/" + aCfgLocale;
1733 if (aValues.hasElements())
1738 return aSvcImplNames;
1752 lang::EventObject aEvtObj(
static_cast<XLinguServiceManager*
>(
this) );
1763 const uno::Reference< lang::XEventListener >& xListener )
1776 const uno::Reference< lang::XEventListener >& xListener )
1788 const uno::Reference< linguistic2::XLinguServiceEventBroadcaster > &rxBroadcaster )
1790 if (!rxBroadcaster.is())
1802 return "com.sun.star.lingu2.LngSvcMgr";
1813uno::Sequence< OUString > SAL_CALL
1816 return {
"com.sun.star.linguistic2.LinguServiceManager" };
1819extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
1821 css::uno::XComponentContext* , css::uno::Sequence<css::uno::Any>
const&)
virtual void SetServiceList(const css::lang::Locale &rLocale, const css::uno::Sequence< OUString > &rSvcImplNames) override
virtual void SetServiceList(const css::lang::Locale &rLocale, const css::uno::Sequence< OUString > &rSvcImplNames) override
virtual void Start(bool bStartTimer=true) override
static css::lang::Locale convertToLocale(LanguageType nLangID, bool bResolveSystem=true)
static OUString convertToBcp47(LanguageType nLangID)
static LanguageType convertToLanguageType(const css::lang::Locale &rLocale, bool bResolveSystem=true)
virtual css::uno::Sequence< OUString > GetServiceList(const css::lang::Locale &rLocale) const =0
void AddLngSvcEvt(sal_Int16 nLngSvcEvt)
::comphelper::OInterfaceContainerHelper2 aLngSvcMgrListeners
void RemoveLngSvcMgrListener(const uno::Reference< lang::XEventListener > &rxListener)
uno::Reference< linguistic2::XSearchableDictionaryList > xDicList
sal_Int16 nCombinedLngSvcEvt
virtual void SAL_CALL processDictionaryListEvent(const linguistic2::DictionaryListEvent &rDicListEvent) override
void AddLngSvcMgrListener(const uno::Reference< lang::XEventListener > &rxListener)
void DisposeAndClear(const lang::EventObject &rEvtObj)
LngSvcMgrListenerHelper & operator=(const LngSvcMgrListenerHelper &)=delete
LngSvcMgrListenerHelper(const LngSvcMgrListenerHelper &)=delete
virtual void SAL_CALL disposing(const lang::EventObject &rSource) override
void LaunchEvent(sal_Int16 nLngSvcEvtFlags)
void AddLngSvcEvtBroadcaster(const uno::Reference< linguistic2::XLinguServiceEventBroadcaster > &rxBroadcaster)
void RemoveLngSvcEvtBroadcaster(const uno::Reference< linguistic2::XLinguServiceEventBroadcaster > &rxBroadcaster)
::comphelper::OInterfaceContainerHelper2 aLngSvcEvtBroadcasters
virtual void SAL_CALL processLinguServiceEvent(const linguistic2::LinguServiceEvent &aLngSvcEvent) override
LngSvcMgrListenerHelper(LngSvcMgr &rLngSvcMgr, uno::Reference< linguistic2::XSearchableDictionaryList > xDicList)
std::optional< SvcInfoArray > pAvailHyphSvcs
virtual css::uno::Reference< css::linguistic2::XHyphenator > SAL_CALL getHyphenator() override
virtual css::uno::Sequence< OUString > SAL_CALL getAvailableServices(const OUString &aServiceName, const css::lang::Locale &aLocale) override
virtual void Notify(const css::uno::Sequence< OUString > &rPropertyNames) override
virtual void SAL_CALL setConfiguredServices(const OUString &aServiceName, const css::lang::Locale &aLocale, const css::uno::Sequence< OUString > &aServiceImplNames) override
void GetAvailableSpellSvcs_Impl()
bool AddLngSvcEvtBroadcaster(const css::uno::Reference< css::linguistic2::XLinguServiceEventBroadcaster > &rxBroadcaster)
void GetAvailableHyphSvcs_Impl()
css::uno::Sequence< css::lang::Locale > aAvailGrammarLocales
virtual void SAL_CALL addEventListener(const css::uno::Reference< css::lang::XEventListener > &xListener) override
virtual void SAL_CALL modified(const css::lang::EventObject &rEvent) override
virtual void SAL_CALL removeEventListener(const css::uno::Reference< css::lang::XEventListener > &aListener) override
virtual css::uno::Reference< css::linguistic2::XThesaurus > SAL_CALL getThesaurus() override
css::uno::Sequence< css::lang::Locale > aAvailThesLocales
void GetAvailableGrammarSvcs_Impl()
virtual css::uno::Reference< css::linguistic2::XSpellChecker > SAL_CALL getSpellChecker() override
virtual css::uno::Sequence< OUString > SAL_CALL getConfiguredServices(const OUString &aServiceName, const css::lang::Locale &aLocale) override
rtl::Reference< ThesaurusDispatcher > mxThesDsp
virtual sal_Bool SAL_CALL removeLinguServiceManagerListener(const css::uno::Reference< css::lang::XEventListener > &xListener) override
void GetThesaurusDsp_Impl(bool bSetSvcList=true)
std::optional< SvcInfoArray > pAvailGrammarSvcs
bool SaveCfgSvcs(std::u16string_view rServiceName)
void GetHyphenatorDsp_Impl(bool bSetSvcList=true)
virtual css::uno::Sequence< css::lang::Locale > SAL_CALL getAvailableLocales(const OUString &aServiceName) override
virtual ~LngSvcMgr() override
rtl::Reference< LngSvcMgrListenerHelper > mxListenerHelper
::comphelper::OInterfaceContainerHelper3< css::lang::XEventListener > aEvtListeners
virtual sal_Bool SAL_CALL addLinguServiceManagerListener(const css::uno::Reference< css::lang::XEventListener > &xListener) override
css::uno::Sequence< css::lang::Locale > aAvailSpellLocales
virtual void SAL_CALL dispose() override
friend class LngSvcMgrListenerHelper
void GetGrammarCheckerDsp_Impl(bool bSetSvcList=true)
css::uno::Sequence< css::lang::Locale > aAvailHyphLocales
rtl::Reference< HyphenatorDispatcher > mxHyphDsp
void SetCfgServiceLists(SpellCheckerDispatcher &rSpellDsp)
virtual sal_Bool SAL_CALL supportsService(const OUString &ServiceName) override
std::optional< SvcInfoArray > pAvailSpellSvcs
virtual void SAL_CALL disposing(const css::lang::EventObject &rSource) override
rtl::Reference< SpellCheckerDispatcher > mxSpellDsp
void GetListenerHelper_Impl()
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
css::uno::Reference< css::util::XModifyBroadcaster > xMB
std::vector< SvcInfo > SvcInfoArray
rtl::Reference< GrammarCheckingIterator > mxGrammarDsp
void GetSpellCheckerDsp_Impl(bool bSetSvcList=true)
void GetAvailableThesSvcs_Impl()
virtual void ImplCommit() override
virtual OUString SAL_CALL getImplementationName() override
std::optional< SvcInfoArray > pAvailThesSvcs
virtual void SetServiceList(const css::lang::Locale &rLocale, const css::uno::Sequence< OUString > &rSvcImplNames) override
css::uno::Sequence< OUString > GetNodeNames(const OUString &rNode) const
css::uno::Sequence< css::uno::Any > GetProperties(const css::uno::Sequence< OUString > &rNames) const
bool ReplaceSetProperties(const OUString &rNode, const css::uno::Sequence< css::beans::PropertyValue > &rValues)
void SetPriority(TaskPriority ePriority)
virtual void SetServiceList(const css::lang::Locale &rLocale, const css::uno::Sequence< OUString > &rSvcImplNames) override
void SetInvokeHandler(const Link< Timer *, void > &rLink)
void notifyEach(void(SAL_CALL ListenerT::*NotificationMethod)(const EventT &), const EventT &Event)
void disposeAndClear(const css::lang::EventObject &rEvt)
sal_Int32 removeInterface(const css::uno::Reference< css::uno::XInterface > &rxIFace)
sal_Int32 addInterface(const css::uno::Reference< css::uno::XInterface > &rxIFace)
sal_Int32 addInterface(const css::uno::Reference< ListenerT > &rxIFace)
void disposeAndClear(const css::lang::EventObject &rEvt)
sal_Int32 removeInterface(const css::uno::Reference< ListenerT > &rxIFace)
css::uno::XInterface * next()
bool hasMoreElements() const
bool EnableNotification(const css::uno::Sequence< OUString > &rNames, bool bEnableInternalNotification=false)
static css::uno::Sequence< css::uno::Any > GetProperties(css::uno::Reference< css::container::XHierarchicalNameAccess > const &xHierarchyAccess, const css::uno::Sequence< OUString > &rNames, bool bAllLocales)
static bool ReplaceSetProperties(css::uno::Reference< css::container::XHierarchicalNameAccess > const &xHierarchyAccess, const OUString &rNode, const css::uno::Sequence< css::beans::PropertyValue > &rValues, bool bAllLocales)
static css::uno::Sequence< OUString > GetNodeNames(css::uno::Reference< css::container::XHierarchicalNameAccess > const &xHierarchyAccess, const OUString &rNode, ConfigNameFormat eFormat)
#define DBG_ASSERT(sCon, aError)
Reference< XSingleServiceFactory > xFactory
#define LINK(Instance, Class, Member)
static bool lcl_SeqHasString(const uno::Sequence< OUString > &rSeq, const OUString &rText)
static uno::Sequence< OUString > GetLangSvcList(const uno::Any &rVal)
static uno::Sequence< OUString > GetLangSvc(const uno::Any &rVal)
static uno::Sequence< lang::Locale > GetAvailLocales(const uno::Sequence< OUString > &rSvcImplNames)
IMPL_LINK_NOARG(LngSvcMgr, updateAndBroadcast, Timer *, void)
static bool IsEqSvcList(const uno::Sequence< OUString > &rList1, const uno::Sequence< OUString > &rList2)
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * linguistic_LngSvcMgr_get_implementation(css::uno::XComponentContext *, css::uno::Sequence< css::uno::Any > const &)
#define SAL_WARN_IF(condition, area, stream)
#define SAL_WARN(area, stream)
#define SAL_INFO(area, stream)
constexpr OUStringLiteral SN_SPELLCHECKER
constexpr OUStringLiteral SN_HYPHENATOR
constexpr OUStringLiteral SN_GRAMMARCHECKER
constexpr OUStringLiteral SN_THESAURUS
sal_Int32 findValue(const css::uno::Sequence< T1 > &_rList, const T2 &_rValue)
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
Reference< XComponentContext > getProcessComponentContext()
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
std::vector< LanguageType > LocaleSeqToLangVec(uno::Sequence< Locale > const &rLocaleSeq)
bool LinguIsUnspecified(LanguageType nLanguage)
Checks if a LanguageType is one of the values that denote absence of language or undetermined languag...
uno::Reference< XSearchableDictionaryList > GetDictionaryList()
uno::Reference< XLinguProperties > GetLinguProperties()
osl::Mutex & GetLinguMutex()
! multi-thread safe mutex for all platforms !!
LanguageType LinguLocaleToLanguage(const css::lang::Locale &rLocale)
Convert Locale to LanguageType for legacy handling.
bool HasLanguage(LanguageType nLanguage) const
const OUString aSvcImplName
SvcInfo(OUString aSvcImplName_, std::vector< LanguageType > &&rSuppLanguages)
const std::vector< LanguageType > aSuppLanguages