summaryrefslogtreecommitdiff
path: root/linguistic/source/lngsvcmgr.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'linguistic/source/lngsvcmgr.cxx')
-rw-r--r--linguistic/source/lngsvcmgr.cxx1078
1 files changed, 1078 insertions, 0 deletions
diff --git a/linguistic/source/lngsvcmgr.cxx b/linguistic/source/lngsvcmgr.cxx
new file mode 100644
index 000000000000..b6b0fa0db761
--- /dev/null
+++ b/linguistic/source/lngsvcmgr.cxx
@@ -0,0 +1,1078 @@
+/*************************************************************************
+ *
+ * $RCSfile: lngsvcmgr.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-11-17 12:37:40 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _SOLAR_H
+#include <tools/solar.h>
+#endif
+
+#include <cppuhelper/factory.hxx> // helper for factories
+#include <com/sun/star/registry/XRegistryKey.hpp>
+#ifndef _COM_SUN_STAR_CONTAINER_XCONTENTENUMERATIONACCESS_HPP_
+#include <com/sun/star/container/XContentEnumerationAccess.hpp>
+#endif
+#ifndef _COM_SUN_STAR_CONTAINER_XENUMERATION_HPP_
+#include <com/sun/star/container/XEnumeration.hpp>
+#endif
+#ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP_
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#endif
+#ifndef _COM_SUN_STAR_LINGUISTIC2_XSUPPORTEDLOCALES_HPP_
+#include <com/sun/star/linguistic2/XSupportedLocales.hpp>
+#endif
+
+#include <com/sun/star/linguistic2/DictionaryListEventFlags.hpp>
+#include <com/sun/star/linguistic2/LinguServiceEventFlags.hpp>
+
+#include "lngsvcmgr.hxx"
+#include "misc.hxx"
+#include "spelldsp.hxx"
+#include "hyphdsp.hxx"
+#include "thesdsp.hxx"
+
+#include <cppuhelper/extract.hxx>
+#ifndef _UNOTOOLS_PROCESSFACTORY_HXX_
+#include <unotools/processfactory.hxx>
+#endif
+#ifndef _SVARRAY_HXX
+#include <svtools/svarray.hxx>
+#endif
+
+
+using namespace utl;
+using namespace osl;
+using namespace rtl;
+using namespace com::sun::star;
+using namespace com::sun::star::container;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::linguistic2;
+using namespace linguistic;
+
+
+SV_DECL_VARARR_SORT( SortedINT16Array, INT16, 32, 32);
+SV_IMPL_VARARR_SORT( SortedINT16Array, INT16 );
+
+///////////////////////////////////////////////////////////////////////////
+
+
+struct SvcInfo
+{
+ const ::rtl::OUString aSvcImplName;
+ const ::com::sun::star::uno::Sequence< INT16 > aSuppLanguages;
+
+ SvcInfo( const ::rtl::OUString &rSvcImplName,
+ const ::com::sun::star::uno::Sequence< INT16 > &rSuppLanguages ) :
+ aSvcImplName (rSvcImplName),
+ aSuppLanguages (rSuppLanguages)
+ {
+ }
+
+ BOOL HasLanguage( INT16 nLanguage ) const;
+};
+
+
+BOOL SvcInfo::HasLanguage( INT16 nLanguage ) const
+{
+ INT32 nCnt = aSuppLanguages.getLength();
+ const INT16 *pLang = aSuppLanguages.getConstArray();
+ for (INT32 i = 0; i < nCnt; ++i)
+ {
+ if (nLanguage == pLang[i])
+ break;
+ }
+ return i < nCnt;
+}
+
+
+typedef SvcInfo * PTR_SVCINFO;
+SV_DECL_PTRARR_DEL( SvcInfoArray, PTR_SVCINFO, 16, 16 );
+SV_IMPL_PTRARR( SvcInfoArray, PTR_SVCINFO * );
+
+
+///////////////////////////////////////////////////////////////////////////
+
+
+void SetAvailableServiceLists( const SvcInfoArray &rInfoArray,
+ LinguDispatcher &rDispatcher )
+{
+ USHORT nSvcs = rInfoArray.Count();
+
+ // build list of all available languages
+ SortedINT16Array aLanguages;
+ USHORT i;
+ for (i = 0; i < nSvcs; ++i)
+ {
+ const Sequence< INT16 > &rSuppLang = rInfoArray[i]->aSuppLanguages;
+ INT32 nLang = rSuppLang.getLength();
+ const INT16 *pSuppLang = rSuppLang.getConstArray();
+ for (INT32 j = 0; j < nLang; ++j)
+ {
+ // language not already added?
+ if (!aLanguages.Seek_Entry( pSuppLang[j] ))
+ aLanguages.Insert( pSuppLang[j] );
+ }
+ }
+
+ // set service list per language to all available services supporting
+ // that language
+ INT16 nLanguages = aLanguages.Count();
+ for (i = 0; i < nLanguages; ++i)
+ {
+ INT16 nActLang = aLanguages[i];
+ Sequence< OUString > aSvcImplNames( nSvcs );
+ OUString *pSvcImplName = aSvcImplNames.getArray();
+ INT32 nSeqCnt = 0;
+ for (USHORT j = 0; j < nSvcs; ++j)
+ {
+ const SvcInfo &rSvcInfo = *rInfoArray[j];
+ if (rSvcInfo.HasLanguage( nActLang ))
+ pSvcImplName[ nSeqCnt++ ] = rSvcInfo.aSvcImplName;
+ }
+ aSvcImplNames.realloc( nSeqCnt );
+
+ rDispatcher.SetServiceList( CreateLocale( nActLang ), aSvcImplNames );
+ }
+}
+
+
+///////////////////////////////////////////////////////////////////////////
+
+
+class LngSvcMgrListenerHelper :
+ public cppu::WeakImplHelper2
+ <
+ XLinguServiceEventListener,
+ XDictionaryListEventListener
+ >
+{
+ //cppu::OMultiTypeInterfaceContainerHelper aListeners;
+ ::cppu::OInterfaceContainerHelper aLngSvcMgrListeners;
+ ::cppu::OInterfaceContainerHelper aLngSvcEvtBroadcasters;
+ Reference< XDictionaryList > xDicList;
+ Reference< XInterface > xMyEvtObj;
+
+ // disallow copy-constructor and assignment-operator for now
+ LngSvcMgrListenerHelper(const LngSvcMgrListenerHelper &);
+ LngSvcMgrListenerHelper & operator = (const LngSvcMgrListenerHelper &);
+
+ void LaunchEvent( INT16 nLngSvcEvtFlags );
+
+public:
+ LngSvcMgrListenerHelper( const Reference< XInterface > &rxSource,
+ const Reference< XDictionaryList > &rxDicList );
+
+ // XEventListener
+ virtual void SAL_CALL
+ disposing( const EventObject& rSource )
+ throw(RuntimeException);
+
+ // XLinguServiceEventListener
+ virtual void SAL_CALL
+ processLinguServiceEvent( const LinguServiceEvent& aLngSvcEvent )
+ throw(RuntimeException);
+
+ // XDictionaryListEventListener
+ virtual void SAL_CALL
+ processDictionaryListEvent(
+ const DictionaryListEvent& rDicListEvent )
+ throw(RuntimeException);
+
+ inline BOOL AddLngSvcMgrListener(
+ const Reference< XEventListener >& rxListener );
+ inline BOOL RemoveLngSvcMgrListener(
+ const Reference< XEventListener >& rxListener );
+ void DisposeAndClear( const EventObject &rEvtObj );
+ BOOL AddLngSvcEvtBroadcaster(
+ const Reference< XLinguServiceEventBroadcaster > &rxBroadcaster );
+ BOOL RemoveLngSvcEvtBroadcaster(
+ const Reference< XLinguServiceEventBroadcaster > &rxBroadcaster );
+};
+
+
+LngSvcMgrListenerHelper::LngSvcMgrListenerHelper(
+ const Reference< XInterface > &rxSource,
+ const Reference< XDictionaryList > &rxDicList ) :
+ aLngSvcMgrListeners ( GetLinguMutex() ),
+ aLngSvcEvtBroadcasters ( GetLinguMutex() ),
+ xDicList ( rxDicList ),
+ xMyEvtObj ( rxSource )
+{
+ if (xDicList.is())
+ {
+ xDicList->addDictionaryListEventListener(
+ (XDictionaryListEventListener *) this, FALSE );
+ }
+}
+
+
+void SAL_CALL LngSvcMgrListenerHelper::disposing( const EventObject& rSource )
+ throw(RuntimeException)
+{
+ MutexGuard aGuard( GetLinguMutex() );
+
+ Reference< XInterface > xRef( rSource.Source );
+ if ( xRef.is() )
+ {
+ aLngSvcMgrListeners .removeInterface( xRef );
+ aLngSvcEvtBroadcasters.removeInterface( xRef );
+ if (xDicList == xRef)
+ xDicList = 0;
+ }
+}
+
+
+void SAL_CALL
+ LngSvcMgrListenerHelper::processLinguServiceEvent(
+ const LinguServiceEvent& rLngSvcEvent )
+ throw(RuntimeException)
+{
+ MutexGuard aGuard( GetLinguMutex() );
+
+ // change event source to LinguServiceManager since the listeners
+ // probably do not know (and need not to know) about the specific
+ // SpellChecker's or Hyphenator's.
+ LinguServiceEvent aEvtObj( rLngSvcEvent );
+ aEvtObj.Source = xMyEvtObj;
+
+ // pass event on to XLinguServiceEventListener's
+ cppu::OInterfaceIteratorHelper aIt( aLngSvcMgrListeners );
+ while (aIt.hasMoreElements())
+ {
+ Reference< XLinguServiceEventListener > xRef( aIt.next(), UNO_QUERY );
+ if (xRef.is())
+ xRef->processLinguServiceEvent( aEvtObj );
+ }
+}
+
+
+void SAL_CALL
+ LngSvcMgrListenerHelper::processDictionaryListEvent(
+ const DictionaryListEvent& rDicListEvent )
+ throw(RuntimeException)
+{
+ MutexGuard aGuard( GetLinguMutex() );
+
+ // we do keep the original event source here though...
+
+ // pass event on to XDictionaryListEventListener's
+ cppu::OInterfaceIteratorHelper aIt( aLngSvcMgrListeners );
+ while (aIt.hasMoreElements())
+ {
+ Reference< XDictionaryListEventListener > xRef( aIt.next(), UNO_QUERY );
+ if (xRef.is())
+ xRef->processDictionaryListEvent( rDicListEvent );
+ }
+
+ // "translate" DictionaryList event into LinguServiceEvent
+ INT16 nLngSvcEvt = 0;
+ INT16 nDlEvt = rDicListEvent.nCondensedEvent;
+ if ( (nDlEvt & DictionaryListEventFlags::ADD_NEG_ENTRY) ||
+ (nDlEvt & DictionaryListEventFlags::DEL_POS_ENTRY) ||
+ (nDlEvt & DictionaryListEventFlags::ACTIVATE_NEG_DIC) ||
+ (nDlEvt & DictionaryListEventFlags::DEACTIVATE_POS_DIC) )
+ nLngSvcEvt |= LinguServiceEventFlags::SPELL_CORRECT_WORDS_AGAIN;
+ if ( (nDlEvt & DictionaryListEventFlags::ADD_POS_ENTRY) ||
+ (nDlEvt & DictionaryListEventFlags::DEL_NEG_ENTRY) ||
+ (nDlEvt & DictionaryListEventFlags::ACTIVATE_POS_DIC) ||
+ (nDlEvt & DictionaryListEventFlags::DEACTIVATE_NEG_DIC) )
+ nLngSvcEvt |= LinguServiceEventFlags::SPELL_WRONG_WORDS_AGAIN;
+ if ( (nDlEvt & DictionaryListEventFlags::ADD_POS_ENTRY) ||
+ (nDlEvt & DictionaryListEventFlags::DEL_POS_ENTRY) ||
+ (nDlEvt & DictionaryListEventFlags::ACTIVATE_POS_DIC) ||
+ (nDlEvt & DictionaryListEventFlags::ACTIVATE_NEG_DIC) )
+ nLngSvcEvt |= LinguServiceEventFlags::HYPHENATE_AGAIN;
+ if (nLngSvcEvt)
+ LaunchEvent( nLngSvcEvt );
+}
+
+
+void LngSvcMgrListenerHelper::LaunchEvent( INT16 nLngSvcEvtFlags )
+{
+ LinguServiceEvent aEvt( xMyEvtObj, nLngSvcEvtFlags );
+
+ // pass event on to XLinguServiceEventListener's
+ cppu::OInterfaceIteratorHelper aIt( aLngSvcMgrListeners );
+ while (aIt.hasMoreElements())
+ {
+ Reference< XLinguServiceEventListener > xRef( aIt.next(), UNO_QUERY );
+ if (xRef.is())
+ xRef->processLinguServiceEvent( aEvt );
+ }
+}
+
+
+inline BOOL LngSvcMgrListenerHelper::AddLngSvcMgrListener(
+ const Reference< XEventListener >& rxListener )
+{
+ aLngSvcMgrListeners.addInterface(
+ /*::getCppuType((const ::com::sun::star::uno::Reference<
+ ::com::sun::star::lang::XEventListener >*)0), */
+ rxListener );
+ return TRUE;
+}
+
+
+inline BOOL LngSvcMgrListenerHelper::RemoveLngSvcMgrListener(
+ const Reference< XEventListener >& rxListener )
+{
+ aLngSvcMgrListeners.removeInterface(
+ /*::getCppuType((const ::com::sun::star::uno::Reference<
+ ::com::sun::star::lang::XEventListener >*)0), */
+ rxListener );
+ return TRUE;
+}
+
+
+void LngSvcMgrListenerHelper::DisposeAndClear( const EventObject &rEvtObj )
+{
+ // call "disposing" for all listeners and clear list
+ aLngSvcMgrListeners .disposeAndClear( rEvtObj );
+
+ // remove references to this object hold by the broadcasters
+ cppu::OInterfaceIteratorHelper aIt( aLngSvcEvtBroadcasters );
+ while (aIt.hasMoreElements())
+ {
+ Reference< XLinguServiceEventBroadcaster > xRef( aIt.next(), UNO_QUERY );
+ if (xRef.is())
+ RemoveLngSvcEvtBroadcaster( xRef );
+ }
+
+ // remove refernce to this object hold by the dictionary-list
+ if (xDicList.is())
+ {
+ xDicList->removeDictionaryListEventListener(
+ (XDictionaryListEventListener *) this );
+ xDicList = 0;
+ }
+}
+
+
+BOOL LngSvcMgrListenerHelper::AddLngSvcEvtBroadcaster(
+ const Reference< XLinguServiceEventBroadcaster > &rxBroadcaster )
+{
+ BOOL bRes = FALSE;
+ if (rxBroadcaster.is())
+ {
+ aLngSvcEvtBroadcasters.addInterface( rxBroadcaster );
+ rxBroadcaster->addLinguServiceEventListener(
+ (XLinguServiceEventListener *) this );
+ }
+ return bRes;
+}
+
+
+BOOL LngSvcMgrListenerHelper::RemoveLngSvcEvtBroadcaster(
+ const Reference< XLinguServiceEventBroadcaster > &rxBroadcaster )
+{
+ BOOL bRes = FALSE;
+ if (rxBroadcaster.is())
+ {
+ aLngSvcEvtBroadcasters.removeInterface( rxBroadcaster );
+ rxBroadcaster->removeLinguServiceEventListener(
+ (XLinguServiceEventListener *) this );
+ }
+ return bRes;
+}
+
+
+///////////////////////////////////////////////////////////////////////////
+
+
+LngSvcMgr::LngSvcMgr() :
+ aEvtListeners ( GetLinguMutex() )
+{
+ bDisposing = FALSE;
+
+ pSpellDsp = 0;
+ pHyphDsp = 0;
+ pThesDsp = 0;
+
+ pSpellSvcs = 0;
+ pHyphSvcs = 0;
+ pThesSvcs = 0;
+ pListenerHelper = 0;
+}
+
+
+LngSvcMgr::~LngSvcMgr()
+{
+ // memory for pSpellDsp, pHyphDsp, pThesDsp, pListenerHelper
+ // will be freed in the destructor of the respective Reference's
+ // xSpellDsp, xHyphDsp, xThesDsp
+
+ delete pSpellSvcs;
+ delete pHyphSvcs;
+ delete pThesSvcs;
+}
+
+
+void LngSvcMgr::GetListenerHelper_Impl()
+{
+ if (!pListenerHelper)
+ {
+ pListenerHelper = new LngSvcMgrListenerHelper(
+ (XLinguServiceManager *) this, linguistic::GetDictionaryList() );
+ xListenerHelper = (XLinguServiceEventListener *) pListenerHelper;
+ }
+}
+
+
+void LngSvcMgr::GetSpellCheckerDsp_Impl()
+{
+ if (!pSpellDsp)
+ {
+ pSpellDsp = new SpellCheckerDispatcher( *this );
+ xSpellDsp = pSpellDsp;
+ SetCfgServiceLists( *pSpellDsp );
+ }
+}
+
+
+void LngSvcMgr::GetHyphenatorDsp_Impl()
+{
+ if (!pHyphDsp)
+ {
+ pHyphDsp = new HyphenatorDispatcher( *this );
+ xHyphDsp = pHyphDsp;
+ SetCfgServiceLists( *pHyphDsp );
+ }
+}
+
+
+void LngSvcMgr::GetThesaurusDsp_Impl()
+{
+ if (!pThesDsp)
+ {
+ pThesDsp = new ThesaurusDispatcher;
+ xThesDsp = pThesDsp;
+ SetCfgServiceLists( *pThesDsp );
+ }
+}
+
+
+void LngSvcMgr::GetAvailableSpellSvcs_Impl()
+{
+ if (!pSpellSvcs)
+ {
+ pSpellSvcs = new SvcInfoArray;
+
+ Reference< XMultiServiceFactory > xFac( getProcessServiceFactory() );
+ if (xFac.is())
+ {
+ Reference< XContentEnumerationAccess > xEnumAccess( xFac, UNO_QUERY );
+ Reference< XEnumeration > xEnum;
+ if (xEnumAccess.is())
+ xEnum = xEnumAccess->createContentEnumeration(
+ A2OU( SN_SPELLCHECKER ) );
+
+ if (xEnum.is())
+ {
+ while (xEnum->hasMoreElements())
+ {
+ Any aCurrent = xEnum->nextElement();
+ Reference< XSingleServiceFactory > xFactory;
+
+ if (!::cppu::extractInterface( xFactory, aCurrent ))
+ continue;
+
+ Reference< XSpellChecker > xSvc( xFactory->createInstance(),
+ UNO_QUERY );
+ if (xSvc.is())
+ {
+ OUString aImplName;
+ Sequence< INT16 > aLanguages;
+ Reference< XServiceInfo > xInfo( xSvc, UNO_QUERY );
+ if (xInfo.is())
+ aImplName = xInfo->getImplementationName();
+ DBG_ASSERT( aImplName.getLength(),
+ "empty implementation name" );
+ Reference< XSupportedLocales > xSuppLoc( xSvc, UNO_QUERY );
+ DBG_ASSERT( xSuppLoc.is(), "interfaces not supported" );
+ if (xSuppLoc.is())
+ aLanguages = LocaleSeqToLangSeq( xSuppLoc->getLocales() );
+
+ pSpellSvcs->Insert( new SvcInfo( aImplName, aLanguages ),
+ pSpellSvcs->Count() );
+
+ // TL_TODO:
+ // when HRO has the functionality provided to unload
+ // the DLLs it should be done here!
+ }
+ }
+ }
+ }
+ }
+}
+
+
+void LngSvcMgr::GetAvailableHyphSvcs_Impl()
+{
+ if (!pHyphSvcs)
+ {
+ pHyphSvcs = new SvcInfoArray;
+
+ Reference< XMultiServiceFactory > xFac( getProcessServiceFactory() );
+ if (xFac.is())
+ {
+ Reference< XContentEnumerationAccess > xEnumAccess( xFac, UNO_QUERY );
+ Reference< XEnumeration > xEnum;
+ if (xEnumAccess.is())
+ xEnum = xEnumAccess->createContentEnumeration(
+ A2OU( SN_HYPHENATOR ) );
+
+ if (xEnum.is())
+ {
+ while (xEnum->hasMoreElements())
+ {
+ Any aCurrent = xEnum->nextElement();
+ Reference< XSingleServiceFactory > xFactory;
+
+ if (!::cppu::extractInterface( xFactory, aCurrent ))
+ continue;
+
+ Reference< XHyphenator > xSvc( xFactory->createInstance(),
+ UNO_QUERY );
+ if (xSvc.is())
+ {
+ OUString aImplName;
+ Sequence< INT16 > aLanguages;
+ Reference< XServiceInfo > xInfo( xSvc, UNO_QUERY );
+ if (xInfo.is())
+ aImplName = xInfo->getImplementationName();
+ DBG_ASSERT( aImplName.getLength(),
+ "empty implementation name" );
+ Reference< XSupportedLocales > xSuppLoc( xSvc, UNO_QUERY );
+ DBG_ASSERT( xSuppLoc.is(), "interfaces not supported" );
+ if (xSuppLoc.is())
+ aLanguages = LocaleSeqToLangSeq( xSuppLoc->getLocales() );
+
+ pHyphSvcs->Insert( new SvcInfo( aImplName, aLanguages ),
+ pHyphSvcs->Count() );
+
+ // TL_TODO:
+ // when HRO has the functionality provided to unload
+ // the DLLs it should be done here!
+ }
+ }
+ }
+ }
+ }
+}
+
+
+void LngSvcMgr::GetAvailableThesSvcs_Impl()
+{
+ if (!pThesSvcs)
+ {
+ pThesSvcs = new SvcInfoArray;
+
+ Reference< XMultiServiceFactory > xFac( getProcessServiceFactory() );
+ if (xFac.is())
+ {
+ Reference< XContentEnumerationAccess > xEnumAccess( xFac, UNO_QUERY );
+ Reference< XEnumeration > xEnum;
+ if (xEnumAccess.is())
+ xEnum = xEnumAccess->createContentEnumeration(
+ A2OU( SN_THESAURUS ) );
+
+ if (xEnum.is())
+ {
+ while (xEnum->hasMoreElements())
+ {
+ Any aCurrent = xEnum->nextElement();
+ Reference< XSingleServiceFactory > xFactory;
+
+ if (!::cppu::extractInterface( xFactory, aCurrent ))
+ continue;
+
+ Reference< XThesaurus > xSvc( xFactory->createInstance(),
+ UNO_QUERY );
+ if (xSvc.is())
+ {
+ OUString aImplName;
+ Sequence< INT16 > aLanguages;
+ Reference< XServiceInfo > xInfo( xSvc, UNO_QUERY );
+ if (xInfo.is())
+ aImplName = xInfo->getImplementationName();
+ DBG_ASSERT( aImplName.getLength(),
+ "empty implementation name" );
+ Reference< XSupportedLocales > xSuppLoc( xSvc, UNO_QUERY );
+ DBG_ASSERT( xSuppLoc.is(), "interfaces not supported" );
+ if (xSuppLoc.is())
+ aLanguages = LocaleSeqToLangSeq( xSuppLoc->getLocales() );
+
+ pThesSvcs->Insert( new SvcInfo( aImplName, aLanguages ),
+ pThesSvcs->Count() );
+
+ // TL_TODO:
+ // when HRO has the functionality provided to unload
+ // the DLLs it should be done here!
+ }
+ }
+ }
+ }
+ }
+}
+
+
+void LngSvcMgr::SetCfgServiceLists( SpellCheckerDispatcher &rSpellDsp )
+{
+ // TL_TODO:
+ // the services obtained from the configuration should be set here
+
+ if (!pSpellSvcs)
+ GetAvailableSpellSvcs_Impl();
+ SetAvailableServiceLists( *pSpellSvcs, rSpellDsp );
+}
+
+
+void LngSvcMgr::SetCfgServiceLists( HyphenatorDispatcher &rHyphDsp )
+{
+ // TL_TODO:
+ // the services obtained from the configuration should be set here
+
+ if (!pHyphSvcs)
+ GetAvailableHyphSvcs_Impl();
+ SetAvailableServiceLists( *pHyphSvcs, rHyphDsp );
+}
+
+
+void LngSvcMgr::SetCfgServiceLists( ThesaurusDispatcher &rThesDsp )
+{
+ // TL_TODO:
+ // the services obtained from the configuration should be set here
+
+ if (!pThesSvcs)
+ GetAvailableThesSvcs_Impl();
+ SetAvailableServiceLists( *pThesSvcs, rThesDsp );
+}
+
+
+Reference< XSpellChecker > SAL_CALL
+ LngSvcMgr::getSpellChecker()
+ throw(RuntimeException)
+{
+ MutexGuard aGuard( GetLinguMutex() );
+
+ Reference< XSpellChecker > xRes;
+ if (!bDisposing)
+ {
+ if (!xSpellDsp.is())
+ GetSpellCheckerDsp_Impl();
+ xRes = xSpellDsp;
+ }
+ return xRes;
+}
+
+
+Reference< XHyphenator > SAL_CALL
+ LngSvcMgr::getHyphenator()
+ throw(RuntimeException)
+{
+ MutexGuard aGuard( GetLinguMutex() );
+
+ Reference< XHyphenator > xRes;
+ if (!bDisposing)
+ {
+ if (!xHyphDsp.is())
+ GetHyphenatorDsp_Impl();
+ xRes = xHyphDsp;
+ }
+ return xRes;
+}
+
+
+Reference< XThesaurus > SAL_CALL
+ LngSvcMgr::getThesaurus()
+ throw(RuntimeException)
+{
+ MutexGuard aGuard( GetLinguMutex() );
+
+ Reference< XThesaurus > xRes;
+ if (!bDisposing)
+ {
+ if (!xThesDsp.is())
+ GetThesaurusDsp_Impl();
+ xRes = xThesDsp;
+ }
+ return xRes;
+}
+
+
+sal_Bool SAL_CALL
+ LngSvcMgr::addLinguServiceManagerListener(
+ const Reference< XEventListener >& xListener )
+ throw(RuntimeException)
+{
+ MutexGuard aGuard( GetLinguMutex() );
+
+ BOOL bRes = FALSE;
+ if (!bDisposing && xListener.is())
+ {
+ if (!pListenerHelper)
+ GetListenerHelper_Impl();
+ bRes = pListenerHelper->AddLngSvcMgrListener( xListener );
+ }
+ return bRes;
+}
+
+
+sal_Bool SAL_CALL
+ LngSvcMgr::removeLinguServiceManagerListener(
+ const Reference< XEventListener >& xListener )
+ throw(RuntimeException)
+{
+ MutexGuard aGuard( GetLinguMutex() );
+
+ BOOL bRes = FALSE;
+ if (!bDisposing && xListener.is())
+ {
+ DBG_ASSERT( pListenerHelper, "listener removed without being added" );
+ if (!pListenerHelper)
+ GetListenerHelper_Impl();
+ bRes = pListenerHelper->RemoveLngSvcMgrListener( xListener );
+ }
+ return bRes;
+}
+
+
+Sequence< OUString > SAL_CALL
+ LngSvcMgr::getAvailableServices(
+ const OUString& rServiceName,
+ const Locale& rLocale )
+ throw(RuntimeException)
+{
+ MutexGuard aGuard( GetLinguMutex() );
+
+ Sequence< OUString > aRes;
+ const SvcInfoArray *pInfoArray = 0;
+
+ if (0 == rServiceName.compareToAscii( SN_SPELLCHECKER ))
+ {
+ if (!pSpellSvcs)
+ GetAvailableSpellSvcs_Impl();
+ pInfoArray = pSpellSvcs;
+ }
+ else if (0 == rServiceName.compareToAscii( SN_HYPHENATOR ))
+ {
+ if (!pHyphSvcs)
+ GetAvailableHyphSvcs_Impl();
+ pInfoArray = pHyphSvcs;
+ }
+ else if (0 == rServiceName.compareToAscii( SN_THESAURUS ))
+ {
+ if (!pThesSvcs)
+ GetAvailableThesSvcs_Impl();
+ pInfoArray = pThesSvcs;
+ }
+
+ if (pInfoArray)
+ {
+ // resize to max number of entries
+ INT32 nMaxCnt = pInfoArray->Count();
+ aRes.realloc( nMaxCnt );
+ OUString *pImplName = aRes.getArray();
+
+ INT32 nCnt = 0;
+ INT16 nLanguage = LocaleToLanguage( rLocale );
+ for (INT32 i = 0; i < nMaxCnt; ++i)
+ {
+ const SvcInfo *pInfo = pInfoArray->GetObject(i);
+ if (LANGUAGE_NONE == nLanguage
+ || (pInfo && pInfo->HasLanguage( nLanguage )))
+ {
+ pImplName[ nCnt++ ] = pInfo->aSvcImplName;
+ }
+ }
+
+ // resize to actual number of entries
+ if (nCnt && nCnt != nMaxCnt)
+ aRes.realloc( nCnt );
+ }
+
+ return aRes;
+}
+
+
+void SAL_CALL
+ LngSvcMgr::setConfiguredServices(
+ const OUString& rServiceName,
+ const Locale& rLocale,
+ const Sequence< OUString >& rServiceImplNames )
+ throw(RuntimeException)
+{
+ MutexGuard aGuard( GetLinguMutex() );
+
+ // TL_TODO:
+ // write code to access the configuration and set the following
+ // variable accordingly
+ BOOL bCfgChgSuccess = TRUE;
+ INT16 nLanguage = LocaleToLanguage( rLocale );
+
+ if (bCfgChgSuccess && LANGUAGE_NONE != nLanguage)
+ {
+ if (0 == rServiceName.compareToAscii( SN_SPELLCHECKER ))
+ pSpellDsp->SetServiceList( rLocale, rServiceImplNames );
+ else if (0 == rServiceName.compareToAscii( SN_HYPHENATOR ))
+ pHyphDsp->SetServiceList( rLocale, rServiceImplNames );
+ else if (0 == rServiceName.compareToAscii( SN_THESAURUS ))
+ pThesDsp->SetServiceList( rLocale, rServiceImplNames );
+ }
+}
+
+
+Sequence< OUString > SAL_CALL
+ LngSvcMgr::getConfiguredServices(
+ const OUString& rServiceName,
+ const Locale& rLocale )
+ throw(RuntimeException)
+{
+ MutexGuard aGuard( GetLinguMutex() );
+ return Sequence< OUString > ();
+}
+
+
+void SAL_CALL
+ LngSvcMgr::dispose()
+ throw(RuntimeException)
+{
+ MutexGuard aGuard( GetLinguMutex() );
+
+ if (!bDisposing)
+ {
+ bDisposing = TRUE;
+
+ // require listeners to release this object
+ EventObject aEvtObj( (XLinguServiceManager *) this );
+ aEvtListeners.disposeAndClear( aEvtObj );
+
+ if (pListenerHelper)
+ pListenerHelper->DisposeAndClear( aEvtObj );
+ }
+}
+
+
+void SAL_CALL
+ LngSvcMgr::addEventListener(
+ const Reference< XEventListener >& xListener )
+ throw(RuntimeException)
+{
+ MutexGuard aGuard( GetLinguMutex() );
+
+ if (!bDisposing && xListener.is())
+ {
+ aEvtListeners.addInterface(
+ /*::getCppuType((const ::com::sun::star::uno::Reference<
+ ::com::sun::star::lang::XEventListener >*)0), */
+ xListener );
+ }
+}
+
+
+void SAL_CALL
+ LngSvcMgr::removeEventListener(
+ const Reference< XEventListener >& xListener )
+ throw(RuntimeException)
+{
+ MutexGuard aGuard( GetLinguMutex() );
+
+ if (xListener.is())
+ {
+ aEvtListeners.removeInterface(
+ /*::getCppuType((const ::com::sun::star::uno::Reference<
+ ::com::sun::star::lang::XEventListener >*)0), */
+ xListener );
+ }
+}
+
+
+BOOL LngSvcMgr::AddLngSvcEvtBroadcaster(
+ const Reference< XLinguServiceEventBroadcaster > &rxBroadcaster )
+{
+ BOOL bRes = FALSE;
+ if (rxBroadcaster.is())
+ {
+ if (!pListenerHelper)
+ GetListenerHelper_Impl();
+ bRes = pListenerHelper->AddLngSvcEvtBroadcaster( rxBroadcaster );
+ }
+ return bRes;
+}
+
+
+BOOL LngSvcMgr::RemoveLngSvcEvtBroadcaster(
+ const Reference< XLinguServiceEventBroadcaster > &rxBroadcaster )
+{
+ BOOL bRes = FALSE;
+ if (rxBroadcaster.is())
+ {
+ DBG_ASSERT( pListenerHelper, "pListenerHelper non existent" );
+ if (!pListenerHelper)
+ GetListenerHelper_Impl();
+ bRes = pListenerHelper->RemoveLngSvcEvtBroadcaster( rxBroadcaster );
+ }
+ return bRes;
+}
+
+
+OUString SAL_CALL
+ LngSvcMgr::getImplementationName()
+ throw(RuntimeException)
+{
+ MutexGuard aGuard( GetLinguMutex() );
+ return getImplementationName_Static();
+}
+
+
+sal_Bool SAL_CALL
+ LngSvcMgr::supportsService( const OUString& ServiceName )
+ throw(RuntimeException)
+{
+ MutexGuard aGuard( GetLinguMutex() );
+
+ uno::Sequence< OUString > aSNL = getSupportedServiceNames();
+ const OUString * pArray = aSNL.getConstArray();
+ for( INT32 i = 0; i < aSNL.getLength(); i++ )
+ if( pArray[i] == ServiceName )
+ return TRUE;
+ return FALSE;
+}
+
+
+Sequence< OUString > SAL_CALL
+ LngSvcMgr::getSupportedServiceNames()
+ throw(RuntimeException)
+{
+ MutexGuard aGuard( GetLinguMutex() );
+ return getSupportedServiceNames_Static();
+}
+
+
+uno::Sequence< OUString > LngSvcMgr::getSupportedServiceNames_Static()
+ throw()
+{
+ MutexGuard aGuard( GetLinguMutex() );
+
+ uno::Sequence< OUString > aSNS( 1 ); // auch mehr als 1 Service moeglich
+ aSNS.getArray()[0] = A2OU( SN_LINGU_SERVCICE_MANAGER );
+ return aSNS;
+}
+
+
+Reference< XInterface > SAL_CALL LngSvcMgr_CreateInstance(
+ const Reference< XMultiServiceFactory > & rSMgr )
+ throw(Exception)
+{
+ Reference< XInterface > xService = (cppu::OWeakObject*) new LngSvcMgr;
+ return xService;
+}
+
+
+
+sal_Bool SAL_CALL LngSvcMgr_writeInfo(
+ void * /*pServiceManager*/,
+ registry::XRegistryKey * pRegistryKey )
+{
+ try
+ {
+ String aImpl( '/' );
+ aImpl += LngSvcMgr::getImplementationName_Static().getStr();
+ aImpl.AppendAscii( "/UNO/SERVICES" );
+ Reference< registry::XRegistryKey > xNewKey =
+ pRegistryKey->createKey( aImpl );
+ uno::Sequence< OUString > aServices = LngSvcMgr::getSupportedServiceNames_Static();
+ for( INT32 i = 0; i < aServices.getLength(); i++ )
+ xNewKey->createKey( aServices.getConstArray()[i] );
+
+ return sal_True;
+ }
+ catch(Exception &)
+ {
+ return sal_False;
+ }
+}
+
+void * SAL_CALL LngSvcMgr_getFactory(
+ const sal_Char * pImplName,
+ XMultiServiceFactory * pServiceManager,
+ void * /*pRegistryKey*/ )
+{
+
+ void * pRet = 0;
+ if ( !LngSvcMgr::getImplementationName_Static().compareToAscii( pImplName ) )
+ {
+ Reference< XSingleServiceFactory > xFactory =
+ cppu::createOneInstanceFactory(
+ pServiceManager,
+ LngSvcMgr::getImplementationName_Static(),
+ LngSvcMgr_CreateInstance,
+ LngSvcMgr::getSupportedServiceNames_Static());
+ // acquire, because we return an interface pointer instead of a reference
+ xFactory->acquire();
+ pRet = xFactory.get();
+ }
+ return pRet;
+}
+
+
+///////////////////////////////////////////////////////////////////////////
+