| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_editeng.hxx" |
| |
| #include <map> |
| #include <set> |
| #include <vector> |
| #include <slist> |
| #include <memory> |
| #include <editeng/unolingu.hxx> |
| #include <tools/debug.hxx> |
| #include <tools/urlobj.hxx> |
| #include <rtl/logfile.hxx> |
| #include <unotools/pathoptions.hxx> |
| #include <com/sun/star/frame/XModel.hpp> |
| #include <com/sun/star/frame/XStorable.hpp> |
| #include <com/sun/star/lang/XEventListener.hpp> |
| #include <com/sun/star/linguistic2/XAvailableLocales.hpp> |
| #include <com/sun/star/ucb/XAnyCompareFactory.hpp> |
| #include <com/sun/star/ucb/XContentAccess.hpp> |
| #include <com/sun/star/ucb/XSortedDynamicResultSetFactory.hpp> |
| #include <com/sun/star/ucb/NumberedSortingInfo.hpp> |
| #include <com/sun/star/ucb/XContentAccess.hpp> |
| #include <com/sun/star/sdbc/XResultSet.hpp> |
| #include <com/sun/star/sdbc/XRow.hpp> |
| #include <com/sun/star/util/DateTime.hpp> |
| |
| #include <comphelper/processfactory.hxx> |
| #include <cppuhelper/implbase1.hxx> // helper for implementations |
| #include <i18npool/mslangid.hxx> |
| #include <unotools/lingucfg.hxx> |
| #include <unotools/ucbhelper.hxx> |
| #include <unotools/localfilehelper.hxx> |
| #include <ucbhelper/commandenvironment.hxx> |
| #include <ucbhelper/content.hxx> |
| #include <comphelper/processfactory.hxx> |
| #include <vcl/msgbox.hxx> |
| #include <tools/shl.hxx> |
| #include <linguistic/misc.hxx> |
| #include <editeng/eerdll.hxx> |
| #include <editeng/editrids.hrc> |
| |
| using namespace ::rtl; |
| using namespace ::comphelper; |
| using namespace ::linguistic; |
| using namespace ::com::sun::star; |
| using namespace ::com::sun::star::util; |
| using namespace ::com::sun::star::uno; |
| using namespace ::com::sun::star::lang; |
| using namespace ::com::sun::star::beans; |
| using namespace ::com::sun::star::frame; |
| using namespace ::com::sun::star::linguistic2; |
| |
| #define CSS com::sun::star |
| |
| /////////////////////////////////////////////////////////////////////////// |
| |
| |
| static uno::Reference< XLinguServiceManager > GetLngSvcMgr_Impl() |
| { |
| uno::Reference< XLinguServiceManager > xRes; |
| uno::Reference< XMultiServiceFactory > xMgr = getProcessServiceFactory(); |
| if (xMgr.is()) |
| { |
| xRes = uno::Reference< XLinguServiceManager > ( xMgr->createInstance( |
| OUString( RTL_CONSTASCII_USTRINGPARAM( |
| "com.sun.star.linguistic2.LinguServiceManager" ) ) ), UNO_QUERY ) ; |
| } |
| return xRes; |
| } |
| |
| /////////////////////////////////////////////////////////////////////////// |
| |
| sal_Bool lcl_FindEntry( const OUString &rEntry, const Sequence< OUString > &rCfgSvcs ) |
| { |
| sal_Int32 nRes = -1; |
| sal_Int32 nEntries = rCfgSvcs.getLength(); |
| const OUString *pEntry = rCfgSvcs.getConstArray(); |
| for (sal_Int32 i = 0; i < nEntries && nRes == -1; ++i) |
| { |
| if (rEntry == pEntry[i]) |
| nRes = i; |
| } |
| return nRes != -1; |
| } |
| |
| |
| Sequence< OUString > lcl_RemoveMissingEntries( |
| const Sequence< OUString > &rCfgSvcs, |
| const Sequence< OUString > &rAvailSvcs ) |
| { |
| Sequence< OUString > aRes( rCfgSvcs.getLength() ); |
| OUString *pRes = aRes.getArray(); |
| sal_Int32 nCnt = 0; |
| |
| sal_Int32 nEntries = rCfgSvcs.getLength(); |
| const OUString *pEntry = rCfgSvcs.getConstArray(); |
| for (sal_Int32 i = 0; i < nEntries; ++i) |
| { |
| if (pEntry[i].getLength() && lcl_FindEntry( pEntry[i], rAvailSvcs )) |
| pRes[ nCnt++ ] = pEntry[i]; |
| } |
| |
| aRes.realloc( nCnt ); |
| return aRes; |
| } |
| |
| |
| Sequence< OUString > lcl_GetLastFoundSvcs( |
| SvtLinguConfig &rCfg, |
| const OUString &rLastFoundList , |
| const Locale &rAvailLocale ) |
| { |
| Sequence< OUString > aRes; |
| |
| OUString aCfgLocaleStr( MsLangId::convertLanguageToIsoString( |
| SvxLocaleToLanguage( rAvailLocale ) ) ); |
| |
| Sequence< OUString > aNodeNames( rCfg.GetNodeNames(rLastFoundList) ); |
| sal_Bool bFound = lcl_FindEntry( aCfgLocaleStr, aNodeNames); |
| |
| if (bFound) |
| { |
| Sequence< OUString > aNames(1); |
| OUString &rNodeName = aNames.getArray()[0]; |
| rNodeName = rLastFoundList; |
| rNodeName += OUString::valueOf( (sal_Unicode)'/' ); |
| rNodeName += aCfgLocaleStr; |
| Sequence< Any > aValues( rCfg.GetProperties( aNames ) ); |
| #if OSL_DEBUG_LEVEL > 1 |
| const Any *pValue; |
| pValue = aValues.getConstArray(); |
| #endif |
| if (aValues.getLength()) |
| { |
| DBG_ASSERT( aValues.getLength() == 1, "unexpected length of sequence" ); |
| Sequence< OUString > aSvcImplNames; |
| if (aValues.getConstArray()[0] >>= aSvcImplNames) |
| aRes = aSvcImplNames; |
| else |
| { |
| DBG_ERROR( "type mismatch" ); |
| } |
| } |
| } |
| |
| return aRes; |
| } |
| |
| |
| Sequence< OUString > lcl_GetNewEntries( |
| const Sequence< OUString > &rLastFoundSvcs, |
| const Sequence< OUString > &rAvailSvcs ) |
| { |
| sal_Int32 nLen = rAvailSvcs.getLength(); |
| Sequence< OUString > aRes( nLen ); |
| OUString *pRes = aRes.getArray(); |
| sal_Int32 nCnt = 0; |
| |
| const OUString *pEntry = rAvailSvcs.getConstArray(); |
| for (sal_Int32 i = 0; i < nLen; ++i) |
| { |
| if (pEntry[i].getLength() && !lcl_FindEntry( pEntry[i], rLastFoundSvcs )) |
| pRes[ nCnt++ ] = pEntry[i]; |
| } |
| |
| aRes.realloc( nCnt ); |
| return aRes; |
| } |
| |
| |
| Sequence< OUString > lcl_MergeSeq( |
| const Sequence< OUString > &rCfgSvcs, |
| const Sequence< OUString > &rNewSvcs ) |
| { |
| Sequence< OUString > aRes( rCfgSvcs.getLength() + rNewSvcs.getLength() ); |
| OUString *pRes = aRes.getArray(); |
| sal_Int32 nCnt = 0; |
| |
| for (sal_Int32 k = 0; k < 2; ++k) |
| { |
| // add previously configuerd service first and append |
| // new found services at the end |
| const Sequence< OUString > &rSeq = k == 0 ? rCfgSvcs : rNewSvcs; |
| |
| sal_Int32 nLen = rSeq.getLength(); |
| const OUString *pEntry = rSeq.getConstArray(); |
| for (sal_Int32 i = 0; i < nLen; ++i) |
| { |
| if (pEntry[i].getLength() && !lcl_FindEntry( pEntry[i], aRes )) |
| pRes[ nCnt++ ] = pEntry[i]; |
| } |
| } |
| |
| aRes.realloc( nCnt ); |
| return aRes; |
| } |
| |
| /////////////////////////////////////////////////////////////////////////// |
| |
| // static member initialization |
| sal_Int16 SvxLinguConfigUpdate::nNeedUpdating = -1; |
| sal_Int32 SvxLinguConfigUpdate::nCurrentDataFilesChangedCheckValue = -1; |
| |
| void SvxLinguConfigUpdate::UpdateAll( sal_Bool bForceCheck ) |
| { |
| RTL_LOGFILE_CONTEXT( aLog, "svx: SvxLinguConfigUpdate::UpdateAll" ); |
| |
| if (IsNeedUpdateAll( bForceCheck )) |
| { |
| typedef OUString OUstring_t; |
| typedef Sequence< OUString > Sequence_OUString_t; |
| typedef std::vector< OUstring_t > OUString_vector_t; |
| typedef std::set< OUstring_t > OUString_set_t; |
| std::vector< OUString_vector_t > aVector; |
| typedef std::map< OUstring_t, Sequence_OUString_t > list_entry_map_t; |
| |
| RTL_LOGFILE_CONTEXT( aLog, "svx: SvxLinguConfigUpdate::UpdateAll - updating..." ); |
| |
| DBG_ASSERT( nNeedUpdating == 1, "SvxLinguConfigUpdate::UpdateAll already updated!" ); |
| |
| uno::Reference< XLinguServiceManager > xLngSvcMgr( GetLngSvcMgr_Impl() ); |
| DBG_ASSERT( xLngSvcMgr.is(), "service manager missing"); |
| if (!xLngSvcMgr.is()) |
| return; |
| |
| SvtLinguConfig aCfg; |
| |
| const int nNumServices = 4; |
| const sal_Char * apServices[nNumServices] = { SN_SPELLCHECKER, SN_GRAMMARCHECKER, SN_HYPHENATOR, SN_THESAURUS }; |
| const sal_Char * apCurLists[nNumServices] = { "ServiceManager/SpellCheckerList", "ServiceManager/GrammarCheckerList", "ServiceManager/HyphenatorList", "ServiceManager/ThesaurusList" }; |
| const sal_Char * apLastFoundLists[nNumServices] = { "ServiceManager/LastFoundSpellCheckers", "ServiceManager/LastFoundGrammarCheckers", "ServiceManager/LastFoundHyphenators", "ServiceManager/LastFoundThesauri" }; |
| |
| // usage of indices as above: 0 = spell checker, 1 = grammar checker, 2 = hyphenator, 3 = thesaurus |
| std::vector< list_entry_map_t > aLastFoundSvcs(nNumServices); |
| std::vector< list_entry_map_t > aCurSvcs(nNumServices); |
| |
| for (int k = 0; k < nNumServices; ++k) |
| { |
| OUString aService( A2OU( apServices[k] ) ); |
| OUString aActiveList( A2OU( apCurLists[k] ) ); |
| OUString aLastFoundList( A2OU( apLastFoundLists[k] ) ); |
| sal_Int32 i; |
| |
| // |
| // remove configured but not available language/services entries |
| // |
| Sequence< OUString > aNodeNames( aCfg.GetNodeNames( aActiveList ) ); // list of configured locales |
| sal_Int32 nNodeNames = aNodeNames.getLength(); |
| const OUString *pNodeName = aNodeNames.getConstArray(); |
| for (i = 0; i < nNodeNames; ++i) |
| { |
| Locale aLocale( SvxCreateLocale( MsLangId::convertIsoStringToLanguage(pNodeName[i]) ) ); |
| Sequence< OUString > aCfgSvcs( |
| xLngSvcMgr->getConfiguredServices( aService, aLocale )); |
| Sequence< OUString > aAvailSvcs( |
| xLngSvcMgr->getAvailableServices( aService, aLocale )); |
| #if OSL_DEBUG_LEVEL > 1 |
| const OUString * pCfgSvcs = aCfgSvcs.getConstArray();; |
| const OUString * pAvailSvcs = aAvailSvcs.getConstArray();; |
| (void) pCfgSvcs; |
| (void) pAvailSvcs; |
| #endif |
| aCfgSvcs = lcl_RemoveMissingEntries( aCfgSvcs, aAvailSvcs ); |
| |
| aCurSvcs[k][ pNodeName[i] ] = aCfgSvcs; |
| } |
| |
| // |
| // add new available language/servcice entries |
| // |
| uno::Reference< XAvailableLocales > xAvail( xLngSvcMgr, UNO_QUERY ); |
| Sequence< Locale > aAvailLocales( xAvail->getAvailableLocales(aService) ); |
| sal_Int32 nAvailLocales = aAvailLocales.getLength(); |
| const Locale *pAvailLocale = aAvailLocales.getConstArray(); |
| for (i = 0; i < nAvailLocales; ++i) |
| { |
| Sequence< OUString > aAvailSvcs( |
| xLngSvcMgr->getAvailableServices( aService, pAvailLocale[i] )); |
| Sequence< OUString > aLastSvcs( |
| lcl_GetLastFoundSvcs( aCfg, aLastFoundList , pAvailLocale[i] )); |
| Sequence< OUString > aNewSvcs = |
| lcl_GetNewEntries( aLastSvcs, aAvailSvcs ); |
| #if OSL_DEBUG_LEVEL > 1 |
| const OUString * pAvailSvcs = aAvailSvcs.getConstArray(); |
| const OUString * pLastSvcs = aLastSvcs.getConstArray(); |
| const OUString * pNewSvcs = aNewSvcs.getConstArray(); |
| (void) pAvailSvcs; |
| (void) pLastSvcs; |
| (void) pNewSvcs; |
| #endif |
| |
| OUString aCfgLocaleStr( MsLangId::convertLanguageToIsoString( |
| SvxLocaleToLanguage( pAvailLocale[i] ) ) ); |
| Sequence< OUString > aCfgSvcs( aCurSvcs[k][ aCfgLocaleStr ] ); |
| |
| // merge services list (previously configured to be listed first). |
| aCfgSvcs = lcl_MergeSeq( aCfgSvcs, aNewSvcs ); |
| |
| /* |
| // there is at most one Hyphenator per language allowed |
| // to be configured, thus we only use the first one found. |
| if (k == 2 && aCfgSvcs.getLength() > 1) |
| aCfgSvcs.realloc(1); |
| */ |
| aCurSvcs[k][ aCfgLocaleStr ] = aCfgSvcs; |
| } |
| |
| // |
| // set last found services to currently available ones |
| // |
| for (i = 0; i < nAvailLocales; ++i) |
| { |
| Sequence< OUString > aSvcImplNames( |
| xLngSvcMgr->getAvailableServices( aService, pAvailLocale[i] ) ); |
| |
| #if OSL_DEBUG_LEVEL > 1 |
| sal_Int32 nSvcs = aSvcImplNames.getLength(); |
| const OUString *pSvcImplName = aSvcImplNames.getConstArray(); |
| for (sal_Int32 j = 0; j < nSvcs; ++j) |
| { |
| OUString aImplName( pSvcImplName[j] ); |
| } |
| #endif |
| |
| OUString aCfgLocaleStr( MsLangId::convertLanguageToIsoString( |
| SvxLocaleToLanguage( pAvailLocale[i] ) ) ); |
| aLastFoundSvcs[k][ aCfgLocaleStr ] = aSvcImplNames; |
| } |
| } |
| |
| // |
| // write new data back to configuration |
| // |
| for (int k = 0; k < nNumServices; ++k) |
| { |
| for (int i = 0; i < 2; ++i) |
| { |
| const sal_Char *pSubNodeName = (i == 0) ? apCurLists[k] : apLastFoundLists[k]; |
| OUString aSubNodeName( A2OU(pSubNodeName) ); |
| |
| list_entry_map_t &rCurMap = (i == 0) ? aCurSvcs[k] : aLastFoundSvcs[k]; |
| list_entry_map_t::const_iterator aIt( rCurMap.begin() ); |
| sal_Int32 nVals = static_cast< sal_Int32 >( rCurMap.size() ); |
| Sequence< PropertyValue > aNewValues( nVals ); |
| PropertyValue *pNewValue = aNewValues.getArray(); |
| while (aIt != rCurMap.end()) |
| { |
| OUString aCfgEntryName( aSubNodeName ); |
| aCfgEntryName += OUString::valueOf( (sal_Unicode) '/' ); |
| aCfgEntryName += (*aIt).first; |
| |
| #if OSL_DEBUG_LEVEL > 1 |
| Sequence< OUString > aSvcImplNames( (*aIt).second ); |
| sal_Int32 nSvcs = aSvcImplNames.getLength(); |
| const OUString *pSvcImplName = aSvcImplNames.getConstArray(); |
| for (sal_Int32 j = 0; j < nSvcs; ++j) |
| { |
| OUString aImplName( pSvcImplName[j] ); |
| } |
| #endif |
| pNewValue->Name = aCfgEntryName; |
| pNewValue->Value <<= (*aIt).second; |
| ++pNewValue; |
| ++aIt; |
| } |
| DBG_ASSERT( pNewValue - aNewValues.getArray() == nVals, |
| "possible mismatch of sequence size and property number" ); |
| |
| { |
| RTL_LOGFILE_CONTEXT( aLog, "svx: SvxLinguConfigUpdate::UpdateAll - ReplaceSetProperties" ); |
| // add new or replace existing entries. |
| sal_Bool bRes = aCfg.ReplaceSetProperties( aSubNodeName, aNewValues ); |
| if (!bRes) |
| { |
| #if OSL_DEBUG_LEVEL > 1 |
| DBG_ERROR( "failed to set new configuration values" ); |
| #endif |
| } |
| } |
| } |
| } |
| DBG_ASSERT( nCurrentDataFilesChangedCheckValue != -1, "SvxLinguConfigUpdate::UpdateAll DataFilesChangedCheckValue not yet calculated!" ); |
| Any aAny; |
| |
| // for the time being (developer builds until OOo 3.0) |
| // we should always check for everything available |
| // otherwise we may miss a new installed extension dicitonary |
| // just because e.g. the spellchecker is not asked what |
| // languages it does support currently... |
| // Since the check is on-demand occuring and executed once it should |
| // not be too troublesome. |
| // In OOo 3.0 we will not need the respective code anymore at all. |
| // aAny <<= nCurrentDataFilesChangedCheckValue; |
| aAny <<= (sal_Int32) -1; // keep the value set to 'need to check' |
| |
| aCfg.SetProperty( A2OU( "DataFilesChangedCheckValue" ), aAny ); |
| |
| //! Note 1: the new values are commited when the 'aCfg' object |
| //! gets destroyed. |
| //! Note 2: the new settings in the configuration get applied |
| //! because the 'LngSvcMgr' (in linguistic/source/lngsvcmgr.hxx) |
| //! listens to the configuration for changes of the relevant |
| //! properties and then applies the new settings. |
| |
| // nothing needs to be done anymore |
| nNeedUpdating = 0; |
| } |
| } |
| |
| |
| sal_Int32 SvxLinguConfigUpdate::CalcDataFilesChangedCheckValue() |
| { |
| RTL_LOGFILE_CONTEXT( aLog, "svx: SvxLinguConfigUpdate::CalcDataFilesChangedCheckValue" ); |
| |
| sal_Int32 nHashVal = 0; |
| // nothing to be checked anymore since those old directory paths are gone by now |
| return nHashVal; |
| } |
| |
| |
| sal_Bool SvxLinguConfigUpdate::IsNeedUpdateAll( sal_Bool bForceCheck ) |
| { |
| RTL_LOGFILE_CONTEXT( aLog, "svx: SvxLinguConfigUpdate::IsNeedUpdateAll" ); |
| if (nNeedUpdating == -1 || bForceCheck ) // need to check if updating is necessary |
| { |
| // calculate hash value for current data files |
| nCurrentDataFilesChangedCheckValue = CalcDataFilesChangedCheckValue(); |
| |
| // compare hash value and check value to see if anything has changed |
| // and thus the configuration needs to be updated |
| SvtLinguOptions aLinguOpt; |
| SvtLinguConfig aCfg; |
| aCfg.GetOptions( aLinguOpt ); |
| nNeedUpdating = (nCurrentDataFilesChangedCheckValue == aLinguOpt.nDataFilesChangedCheckValue) ? 0 : 1; |
| } |
| DBG_ASSERT( nNeedUpdating != -1, |
| "need for linguistic configuration update should have been already checked." ); |
| |
| return nNeedUpdating == 1; |
| } |
| |
| /////////////////////////////////////////////////////////////////////////// |
| |
| |
| //! Dummy implementation in order to avoid loading of lingu DLL |
| //! when only the XSupportedLocales interface is used. |
| //! The dummy accesses the real implementation (and thus loading the DLL) |
| //! when "real" work needs to be done only. |
| class ThesDummy_Impl : |
| public cppu::WeakImplHelper1< XThesaurus > |
| { |
| uno::Reference< XThesaurus > xThes; // the real one... |
| Sequence< Locale > *pLocaleSeq; |
| |
| void GetCfgLocales(); |
| |
| void GetThes_Impl(); |
| |
| public: |
| ThesDummy_Impl() : pLocaleSeq(0) {} |
| ~ThesDummy_Impl(); |
| |
| // XSupportedLocales |
| virtual ::com::sun::star::uno::Sequence< |
| ::com::sun::star::lang::Locale > SAL_CALL |
| getLocales() |
| throw(::com::sun::star::uno::RuntimeException); |
| virtual sal_Bool SAL_CALL |
| hasLocale( const ::com::sun::star::lang::Locale& rLocale ) |
| throw(::com::sun::star::uno::RuntimeException); |
| |
| // XThesaurus |
| virtual ::com::sun::star::uno::Sequence< |
| ::com::sun::star::uno::Reference< |
| ::com::sun::star::linguistic2::XMeaning > > SAL_CALL |
| queryMeanings( const ::rtl::OUString& rTerm, |
| const ::com::sun::star::lang::Locale& rLocale, |
| const ::com::sun::star::beans::PropertyValues& rProperties ) |
| throw(::com::sun::star::lang::IllegalArgumentException, |
| ::com::sun::star::uno::RuntimeException); |
| }; |
| |
| |
| ThesDummy_Impl::~ThesDummy_Impl() |
| { |
| delete pLocaleSeq; |
| } |
| |
| |
| void ThesDummy_Impl::GetCfgLocales() |
| { |
| if (!pLocaleSeq) |
| { |
| SvtLinguConfig aCfg; |
| String aNode( A2OU( "ServiceManager/ThesaurusList" ) ); |
| Sequence < OUString > aNodeNames( aCfg.GetNodeNames( aNode ) ); |
| const OUString *pNodeNames = aNodeNames.getConstArray(); |
| sal_Int32 nLen = aNodeNames.getLength(); |
| pLocaleSeq = new Sequence< Locale >( nLen ); |
| Locale *pLocale = pLocaleSeq->getArray(); |
| for (sal_Int32 i = 0; i < nLen; ++i) |
| { |
| pLocale[i] = SvxCreateLocale( |
| MsLangId::convertIsoStringToLanguage( pNodeNames[i] ) ); |
| } |
| } |
| } |
| |
| |
| void ThesDummy_Impl::GetThes_Impl() |
| { |
| // update configuration before accessing the service |
| if (SvxLinguConfigUpdate::IsNeedUpdateAll()) |
| SvxLinguConfigUpdate::UpdateAll(); |
| |
| if (!xThes.is()) |
| { |
| uno::Reference< XLinguServiceManager > xLngSvcMgr( GetLngSvcMgr_Impl() ); |
| if (xLngSvcMgr.is()) |
| xThes = xLngSvcMgr->getThesaurus(); |
| |
| if (xThes.is()) |
| { |
| // no longer needed... |
| delete pLocaleSeq; pLocaleSeq = 0; |
| } |
| } |
| } |
| |
| |
| uno::Sequence< lang::Locale > SAL_CALL |
| ThesDummy_Impl::getLocales() |
| throw(uno::RuntimeException) |
| { |
| if (!SvxLinguConfigUpdate::IsNeedUpdateAll()) // configuration already update and thus lingu DLL's already loaded ? |
| GetThes_Impl(); |
| if (xThes.is()) |
| return xThes->getLocales(); |
| else if (!pLocaleSeq) // if not already loaded save startup time by avoiding loading them now |
| GetCfgLocales(); |
| return *pLocaleSeq; |
| } |
| |
| |
| sal_Bool SAL_CALL |
| ThesDummy_Impl::hasLocale( const lang::Locale& rLocale ) |
| throw(uno::RuntimeException) |
| { |
| if (!SvxLinguConfigUpdate::IsNeedUpdateAll()) // configuration already update and thus lingu DLL's already loaded ? |
| GetThes_Impl(); |
| if (xThes.is()) |
| return xThes->hasLocale( rLocale ); |
| else if (!pLocaleSeq) // if not already loaded save startup time by avoiding loading them now |
| GetCfgLocales(); |
| GetCfgLocales(); |
| sal_Bool bFound = sal_False; |
| sal_Int32 nLen = pLocaleSeq->getLength(); |
| const Locale *pLocale = pLocaleSeq->getConstArray(); |
| const Locale *pEnd = pLocale + nLen; |
| for ( ; pLocale < pEnd && !bFound; ++pLocale) |
| { |
| bFound = pLocale->Language == rLocale.Language && |
| pLocale->Country == rLocale.Country && |
| pLocale->Variant == rLocale.Variant; |
| } |
| return bFound; |
| } |
| |
| |
| uno::Sequence< uno::Reference< linguistic2::XMeaning > > SAL_CALL |
| ThesDummy_Impl::queryMeanings( |
| const rtl::OUString& rTerm, |
| const lang::Locale& rLocale, |
| const beans::PropertyValues& rProperties ) |
| throw(lang::IllegalArgumentException, |
| uno::RuntimeException) |
| { |
| GetThes_Impl(); |
| uno::Sequence< uno::Reference< linguistic2::XMeaning > > aRes; |
| DBG_ASSERT( xThes.is(), "Thesaurus missing" ); |
| if (xThes.is()) |
| aRes = xThes->queryMeanings( rTerm, rLocale, rProperties ); |
| return aRes; |
| } |
| |
| |
| /////////////////////////////////////////////////////////////////////////// |
| |
| |
| //! Dummy implementation in order to avoid loading of lingu DLL. |
| //! The dummy accesses the real implementation (and thus loading the DLL) |
| //! when it needs to be done only. |
| class SpellDummy_Impl : |
| public cppu::WeakImplHelper1< XSpellChecker1 > |
| { |
| uno::Reference< XSpellChecker1 > xSpell; // the real one... |
| |
| void GetSpell_Impl(); |
| |
| public: |
| |
| // XSupportedLanguages (for XSpellChecker1) |
| virtual ::com::sun::star::uno::Sequence< sal_Int16 > SAL_CALL |
| getLanguages() |
| throw(::com::sun::star::uno::RuntimeException); |
| virtual sal_Bool SAL_CALL |
| hasLanguage( sal_Int16 nLanguage ) |
| throw(::com::sun::star::uno::RuntimeException); |
| |
| // XSpellChecker1 (same as XSpellChecker but sal_Int16 for language) |
| virtual sal_Bool SAL_CALL |
| isValid( const ::rtl::OUString& rWord, sal_Int16 nLanguage, |
| const ::com::sun::star::beans::PropertyValues& rProperties ) |
| throw(::com::sun::star::lang::IllegalArgumentException, |
| ::com::sun::star::uno::RuntimeException); |
| virtual ::com::sun::star::uno::Reference< |
| ::com::sun::star::linguistic2::XSpellAlternatives > SAL_CALL |
| spell( const ::rtl::OUString& rWord, sal_Int16 nLanguage, |
| const ::com::sun::star::beans::PropertyValues& rProperties ) |
| throw(::com::sun::star::lang::IllegalArgumentException, |
| ::com::sun::star::uno::RuntimeException); |
| }; |
| |
| |
| void SpellDummy_Impl::GetSpell_Impl() |
| { |
| // update configuration before accessing the service |
| if (SvxLinguConfigUpdate::IsNeedUpdateAll()) |
| SvxLinguConfigUpdate::UpdateAll(); |
| |
| if (!xSpell.is()) |
| { |
| uno::Reference< XLinguServiceManager > xLngSvcMgr( GetLngSvcMgr_Impl() ); |
| if (xLngSvcMgr.is()) |
| xSpell = uno::Reference< XSpellChecker1 >( xLngSvcMgr->getSpellChecker(), UNO_QUERY ); |
| } |
| } |
| |
| |
| uno::Sequence< sal_Int16 > SAL_CALL |
| SpellDummy_Impl::getLanguages() |
| throw(uno::RuntimeException) |
| { |
| GetSpell_Impl(); |
| if (xSpell.is()) |
| return xSpell->getLanguages(); |
| else |
| return uno::Sequence< sal_Int16 >(); |
| } |
| |
| |
| sal_Bool SAL_CALL |
| SpellDummy_Impl::hasLanguage( sal_Int16 nLanguage ) |
| throw(uno::RuntimeException) |
| { |
| GetSpell_Impl(); |
| sal_Bool bRes = sal_False; |
| if (xSpell.is()) |
| bRes = xSpell->hasLanguage( nLanguage ); |
| return bRes; |
| } |
| |
| |
| sal_Bool SAL_CALL |
| SpellDummy_Impl::isValid( const rtl::OUString& rWord, sal_Int16 nLanguage, |
| const beans::PropertyValues& rProperties ) |
| throw(lang::IllegalArgumentException, |
| uno::RuntimeException) |
| { |
| GetSpell_Impl(); |
| sal_Bool bRes = sal_True; |
| if (xSpell.is()) |
| bRes = xSpell->isValid( rWord, nLanguage, rProperties ); |
| return bRes; |
| } |
| |
| |
| uno::Reference< linguistic2::XSpellAlternatives > SAL_CALL |
| SpellDummy_Impl::spell( const rtl::OUString& rWord, sal_Int16 nLanguage, |
| const beans::PropertyValues& rProperties ) |
| throw(lang::IllegalArgumentException, |
| uno::RuntimeException) |
| { |
| GetSpell_Impl(); |
| uno::Reference< linguistic2::XSpellAlternatives > xRes; |
| if (xSpell.is()) |
| xRes = xSpell->spell( rWord, nLanguage, rProperties ); |
| return xRes; |
| } |
| |
| |
| /////////////////////////////////////////////////////////////////////////// |
| |
| |
| //! Dummy implementation in order to avoid loading of lingu DLL. |
| //! The dummy accesses the real implementation (and thus loading the DLL) |
| //! when it needs to be done only. |
| class HyphDummy_Impl : |
| public cppu::WeakImplHelper1< XHyphenator > |
| { |
| uno::Reference< XHyphenator > xHyph; // the real one... |
| |
| void GetHyph_Impl(); |
| |
| public: |
| |
| // XSupportedLocales |
| virtual ::com::sun::star::uno::Sequence< |
| ::com::sun::star::lang::Locale > SAL_CALL |
| getLocales() |
| throw(::com::sun::star::uno::RuntimeException); |
| virtual sal_Bool SAL_CALL |
| hasLocale( const ::com::sun::star::lang::Locale& rLocale ) |
| throw(::com::sun::star::uno::RuntimeException); |
| |
| // XHyphenator |
| virtual ::com::sun::star::uno::Reference< |
| ::com::sun::star::linguistic2::XHyphenatedWord > SAL_CALL |
| hyphenate( const ::rtl::OUString& rWord, |
| const ::com::sun::star::lang::Locale& rLocale, |
| sal_Int16 nMaxLeading, |
| const ::com::sun::star::beans::PropertyValues& rProperties ) |
| throw(::com::sun::star::lang::IllegalArgumentException, |
| ::com::sun::star::uno::RuntimeException); |
| virtual ::com::sun::star::uno::Reference< |
| ::com::sun::star::linguistic2::XHyphenatedWord > SAL_CALL |
| queryAlternativeSpelling( const ::rtl::OUString& rWord, |
| const ::com::sun::star::lang::Locale& rLocale, |
| sal_Int16 nIndex, |
| const ::com::sun::star::beans::PropertyValues& rProperties ) |
| throw(::com::sun::star::lang::IllegalArgumentException, |
| ::com::sun::star::uno::RuntimeException); |
| virtual ::com::sun::star::uno::Reference< |
| ::com::sun::star::linguistic2::XPossibleHyphens > SAL_CALL |
| createPossibleHyphens( |
| const ::rtl::OUString& rWord, |
| const ::com::sun::star::lang::Locale& rLocale, |
| const ::com::sun::star::beans::PropertyValues& rProperties ) |
| throw(::com::sun::star::lang::IllegalArgumentException, |
| ::com::sun::star::uno::RuntimeException); |
| }; |
| |
| |
| void HyphDummy_Impl::GetHyph_Impl() |
| { |
| // update configuration before accessing the service |
| if (SvxLinguConfigUpdate::IsNeedUpdateAll()) |
| SvxLinguConfigUpdate::UpdateAll(); |
| |
| if (!xHyph.is()) |
| { |
| uno::Reference< XLinguServiceManager > xLngSvcMgr( GetLngSvcMgr_Impl() ); |
| if (xLngSvcMgr.is()) |
| xHyph = xLngSvcMgr->getHyphenator(); |
| } |
| } |
| |
| |
| uno::Sequence< lang::Locale > SAL_CALL |
| HyphDummy_Impl::getLocales() |
| throw(uno::RuntimeException) |
| { |
| GetHyph_Impl(); |
| if (xHyph.is()) |
| return xHyph->getLocales(); |
| else |
| return uno::Sequence< lang::Locale >(); |
| } |
| |
| |
| sal_Bool SAL_CALL |
| HyphDummy_Impl::hasLocale( const lang::Locale& rLocale ) |
| throw(uno::RuntimeException) |
| { |
| GetHyph_Impl(); |
| sal_Bool bRes = sal_False; |
| if (xHyph.is()) |
| bRes = xHyph->hasLocale( rLocale ); |
| return bRes; |
| } |
| |
| |
| uno::Reference< linguistic2::XHyphenatedWord > SAL_CALL |
| HyphDummy_Impl::hyphenate( |
| const rtl::OUString& rWord, |
| const lang::Locale& rLocale, |
| sal_Int16 nMaxLeading, |
| const beans::PropertyValues& rProperties ) |
| throw(lang::IllegalArgumentException, |
| uno::RuntimeException) |
| { |
| GetHyph_Impl(); |
| uno::Reference< linguistic2::XHyphenatedWord > xRes; |
| if (xHyph.is()) |
| xRes = xHyph->hyphenate( rWord, rLocale, nMaxLeading, rProperties ); |
| return xRes; |
| } |
| |
| |
| uno::Reference< linguistic2::XHyphenatedWord > SAL_CALL |
| HyphDummy_Impl::queryAlternativeSpelling( |
| const rtl::OUString& rWord, |
| const lang::Locale& rLocale, |
| sal_Int16 nIndex, |
| const PropertyValues& rProperties ) |
| throw(lang::IllegalArgumentException, |
| uno::RuntimeException) |
| { |
| GetHyph_Impl(); |
| uno::Reference< linguistic2::XHyphenatedWord > xRes; |
| if (xHyph.is()) |
| xRes = xHyph->queryAlternativeSpelling( rWord, rLocale, nIndex, rProperties ); |
| return xRes; |
| } |
| |
| |
| uno::Reference< linguistic2::XPossibleHyphens > SAL_CALL |
| HyphDummy_Impl::createPossibleHyphens( |
| const rtl::OUString& rWord, |
| const lang::Locale& rLocale, |
| const beans::PropertyValues& rProperties ) |
| throw(lang::IllegalArgumentException, |
| uno::RuntimeException) |
| { |
| GetHyph_Impl(); |
| uno::Reference< linguistic2::XPossibleHyphens > xRes; |
| if (xHyph.is()) |
| xRes = xHyph->createPossibleHyphens( rWord, rLocale, rProperties ); |
| return xRes; |
| } |
| |
| |
| /////////////////////////////////////////////////////////////////////////// |
| |
| |
| typedef cppu::WeakImplHelper1 < XEventListener > LinguMgrAppExitLstnrBaseClass; |
| |
| class LinguMgrAppExitLstnr : public LinguMgrAppExitLstnrBaseClass |
| { |
| uno::Reference< XComponent > xDesktop; |
| |
| public: |
| LinguMgrAppExitLstnr(); |
| virtual ~LinguMgrAppExitLstnr(); |
| |
| virtual void AtExit() = 0; |
| |
| |
| // lang::XEventListener |
| virtual void SAL_CALL disposing(const EventObject& rSource) |
| throw( RuntimeException ); |
| }; |
| |
| LinguMgrAppExitLstnr::LinguMgrAppExitLstnr() |
| { |
| // add object to frame::Desktop EventListeners in order to properly call |
| // the AtExit function at appliction exit. |
| |
| uno::Reference< XMultiServiceFactory > xMgr = getProcessServiceFactory(); |
| if ( xMgr.is() ) |
| { |
| xDesktop = uno::Reference< XComponent > ( xMgr->createInstance( |
| OUString( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.frame.Desktop" ) ) ), UNO_QUERY ) ; |
| if (xDesktop.is()) |
| xDesktop->addEventListener( this ); |
| } |
| } |
| |
| LinguMgrAppExitLstnr::~LinguMgrAppExitLstnr() |
| { |
| if (xDesktop.is()) |
| { |
| xDesktop->removeEventListener( this ); |
| xDesktop = NULL; //! release reference to desktop |
| } |
| DBG_ASSERT(!xDesktop.is(), "reference to desktop should be realeased"); |
| } |
| |
| void LinguMgrAppExitLstnr::disposing(const EventObject& rSource) |
| throw( RuntimeException ) |
| { |
| if (xDesktop.is() && rSource.Source == xDesktop) |
| { |
| xDesktop->removeEventListener( this ); |
| xDesktop = NULL; //! release reference to desktop |
| |
| AtExit(); |
| } |
| } |
| |
| /////////////////////////////////////////////////////////////////////////// |
| |
| class LinguMgrExitLstnr : public LinguMgrAppExitLstnr |
| { |
| public: |
| virtual void AtExit(); |
| }; |
| |
| void LinguMgrExitLstnr::AtExit() |
| { |
| // release references |
| LinguMgr::xLngSvcMgr = 0; |
| LinguMgr::xSpell = 0; |
| LinguMgr::xHyph = 0; |
| LinguMgr::xThes = 0; |
| LinguMgr::xDicList = 0; |
| LinguMgr::xProp = 0; |
| LinguMgr::xIgnoreAll = 0; |
| LinguMgr::xChangeAll = 0; |
| |
| LinguMgr::bExiting = sal_True; |
| |
| //TL:TODO: MBA fragen wie ich ohne Absturz hier meinen Speicher |
| // wieder freibekomme... |
| //delete LinguMgr::pExitLstnr; |
| LinguMgr::pExitLstnr = 0; |
| } |
| |
| /////////////////////////////////////////////////////////////////////////// |
| |
| |
| // static member initialization |
| LinguMgrExitLstnr * LinguMgr::pExitLstnr = 0; |
| sal_Bool LinguMgr::bExiting = sal_False; |
| uno::Reference< XLinguServiceManager > LinguMgr::xLngSvcMgr = 0; |
| uno::Reference< XSpellChecker1 > LinguMgr::xSpell = 0; |
| uno::Reference< XHyphenator > LinguMgr::xHyph = 0; |
| uno::Reference< XThesaurus > LinguMgr::xThes = 0; |
| uno::Reference< XDictionaryList > LinguMgr::xDicList = 0; |
| uno::Reference< XPropertySet > LinguMgr::xProp = 0; |
| uno::Reference< XDictionary > LinguMgr::xIgnoreAll = 0; |
| uno::Reference< XDictionary > LinguMgr::xChangeAll = 0; |
| |
| |
| uno::Reference< XLinguServiceManager > LinguMgr::GetLngSvcMgr() |
| { |
| if (bExiting) |
| return 0; |
| |
| if (!pExitLstnr) |
| pExitLstnr = new LinguMgrExitLstnr; |
| |
| if (!xLngSvcMgr.is()) |
| xLngSvcMgr = GetLngSvcMgr_Impl(); |
| |
| return xLngSvcMgr; |
| } |
| |
| |
| uno::Reference< XSpellChecker1 > LinguMgr::GetSpellChecker() |
| { |
| return xSpell.is() ? xSpell : GetSpell(); |
| } |
| |
| uno::Reference< XHyphenator > LinguMgr::GetHyphenator() |
| { |
| return xHyph.is() ? xHyph : GetHyph(); |
| } |
| |
| uno::Reference< XThesaurus > LinguMgr::GetThesaurus() |
| { |
| return xThes.is() ? xThes : GetThes(); |
| } |
| |
| uno::Reference< XDictionaryList > LinguMgr::GetDictionaryList() |
| { |
| return xDicList.is() ? xDicList : GetDicList(); |
| } |
| |
| uno::Reference< XPropertySet > LinguMgr::GetLinguPropertySet() |
| { |
| return xProp.is() ? xProp : GetProp(); |
| } |
| |
| uno::Reference< XDictionary > LinguMgr::GetStandardDic() |
| { |
| //! don't hold reference to this |
| //! (it may be removed from dictionary list and needs to be |
| //! created empty if accessed again) |
| return GetStandard(); |
| } |
| |
| uno::Reference< XDictionary > LinguMgr::GetIgnoreAllList() |
| { |
| return xIgnoreAll.is() ? xIgnoreAll : GetIgnoreAll(); |
| } |
| |
| uno::Reference< XDictionary > LinguMgr::GetChangeAllList() |
| { |
| return xChangeAll.is() ? xChangeAll : GetChangeAll(); |
| } |
| |
| uno::Reference< XSpellChecker1 > LinguMgr::GetSpell() |
| { |
| if (bExiting) |
| return 0; |
| |
| if (!pExitLstnr) |
| pExitLstnr = new LinguMgrExitLstnr; |
| |
| //! use dummy implementation in order to avoid loading of lingu DLL |
| xSpell = new SpellDummy_Impl; |
| |
| /* if (!xLngSvcMgr.is()) |
| xLngSvcMgr = GetLngSvcMgr_Impl(); |
| |
| if (xLngSvcMgr.is()) |
| { |
| xSpell = uno::Reference< XSpellChecker1 > ( |
| xLngSvcMgr->getSpellChecker(), UNO_QUERY ); |
| } |
| */ |
| return xSpell; |
| } |
| |
| uno::Reference< XHyphenator > LinguMgr::GetHyph() |
| { |
| if (bExiting) |
| return 0; |
| |
| if (!pExitLstnr) |
| pExitLstnr = new LinguMgrExitLstnr; |
| |
| //! use dummy implementation in order to avoid loading of lingu DLL |
| xHyph = new HyphDummy_Impl; |
| |
| /* |
| if (!xLngSvcMgr.is()) |
| xLngSvcMgr = GetLngSvcMgr_Impl(); |
| |
| if (xLngSvcMgr.is()) |
| { |
| xHyph = xLngSvcMgr->getHyphenator(); |
| } |
| */ |
| return xHyph; |
| } |
| |
| uno::Reference< XThesaurus > LinguMgr::GetThes() |
| { |
| if (bExiting) |
| return 0; |
| |
| if (!pExitLstnr) |
| pExitLstnr = new LinguMgrExitLstnr; |
| |
| //! use dummy implementation in order to avoid loading of lingu DLL |
| //! when only the XSupportedLocales interface is used. |
| //! The dummy accesses the real implementation (and thus loading the DLL) |
| //! when "real" work needs to be done only. |
| xThes = new ThesDummy_Impl; |
| /* |
| if (!xLngSvcMgr.is()) |
| xLngSvcMgr = GetLngSvcMgr_Impl(); |
| |
| if (xLngSvcMgr.is()) |
| { |
| xThes = xLngSvcMgr->getThesaurus(); |
| } |
| */ |
| return xThes; |
| } |
| |
| |
| void LinguMgr::UpdateAll() |
| { |
| } |
| |
| |
| uno::Reference< XDictionaryList > LinguMgr::GetDicList() |
| { |
| if (bExiting) |
| return 0; |
| |
| if (!pExitLstnr) |
| pExitLstnr = new LinguMgrExitLstnr; |
| |
| uno::Reference< XMultiServiceFactory > xMgr( getProcessServiceFactory() ); |
| if (xMgr.is()) |
| { |
| xDicList = uno::Reference< XDictionaryList > ( xMgr->createInstance( |
| A2OU("com.sun.star.linguistic2.DictionaryList") ), UNO_QUERY ); |
| } |
| return xDicList; |
| } |
| |
| uno::Reference< XPropertySet > LinguMgr::GetProp() |
| { |
| if (bExiting) |
| return 0; |
| |
| if (!pExitLstnr) |
| pExitLstnr = new LinguMgrExitLstnr; |
| |
| uno::Reference< XMultiServiceFactory > xMgr( getProcessServiceFactory() ); |
| if (xMgr.is()) |
| { |
| xProp = uno::Reference< XPropertySet > ( xMgr->createInstance( |
| A2OU("com.sun.star.linguistic2.LinguProperties") ), UNO_QUERY ); |
| } |
| return xProp; |
| } |
| |
| uno::Reference< XDictionary > LinguMgr::GetIgnoreAll() |
| { |
| if (bExiting) |
| return 0; |
| |
| if (!pExitLstnr) |
| pExitLstnr = new LinguMgrExitLstnr; |
| |
| uno::Reference< XDictionaryList > xTmpDicList( GetDictionaryList() ); |
| if (xTmpDicList.is()) |
| { |
| xIgnoreAll = uno::Reference< XDictionary > ( xTmpDicList->getDictionaryByName( |
| A2OU("IgnoreAllList") ), UNO_QUERY ); |
| } |
| return xIgnoreAll; |
| } |
| |
| uno::Reference< XDictionary > LinguMgr::GetChangeAll() |
| { |
| if (bExiting) |
| return 0; |
| |
| if (!pExitLstnr) |
| pExitLstnr = new LinguMgrExitLstnr; |
| |
| uno::Reference< XDictionaryList > _xDicList( GetDictionaryList() , UNO_QUERY ); |
| if (_xDicList.is()) |
| { |
| xChangeAll = uno::Reference< XDictionary > ( |
| _xDicList->createDictionary( |
| A2OU("ChangeAllList"), |
| SvxCreateLocale( LANGUAGE_NONE ), |
| DictionaryType_NEGATIVE, String() ), UNO_QUERY ); |
| } |
| return xChangeAll; |
| } |
| |
| uno::Reference< XDictionary > LinguMgr::GetStandard() |
| { |
| // Tries to return a dictionary which may hold positive entries is |
| // persistent and not read-only. |
| |
| if (bExiting) |
| return 0; |
| |
| uno::Reference< XDictionaryList > xTmpDicList( GetDictionaryList() ); |
| if (!xTmpDicList.is()) |
| return NULL; |
| |
| const OUString aDicName( RTL_CONSTASCII_USTRINGPARAM( "standard.dic" ) ); |
| uno::Reference< XDictionary > xDic( xTmpDicList->getDictionaryByName( aDicName ), |
| UNO_QUERY ); |
| if (!xDic.is()) |
| { |
| // try to create standard dictionary |
| uno::Reference< XDictionary > xTmp; |
| try |
| { |
| xTmp = xTmpDicList->createDictionary( aDicName, |
| SvxCreateLocale( LANGUAGE_NONE ), |
| DictionaryType_POSITIVE, |
| linguistic::GetWritableDictionaryURL( aDicName ) ); |
| } |
| catch(com::sun::star::uno::Exception &) |
| { |
| } |
| |
| // add new dictionary to list |
| if (xTmp.is()) |
| { |
| xTmpDicList->addDictionary( xTmp ); |
| xTmp->setActive( sal_True ); |
| } |
| xDic = uno::Reference< XDictionary > ( xTmp, UNO_QUERY ); |
| } |
| #if OSL_DEBUG_LEVEL > 1 |
| uno::Reference< XStorable > xStor( xDic, UNO_QUERY ); |
| DBG_ASSERT( xDic.is() && xDic->getDictionaryType() == DictionaryType_POSITIVE, |
| "wrong dictionary type"); |
| DBG_ASSERT( xDic.is() && SvxLocaleToLanguage( xDic->getLocale() ) == LANGUAGE_NONE, |
| "wrong dictionary language"); |
| DBG_ASSERT( !xStor.is() || (xStor->hasLocation() && !xStor->isReadonly()), |
| "dictionary not editable" ); |
| #endif |
| |
| return xDic; |
| } |
| |
| /////////////////////////////////////////////////////////////////////////// |
| |
| uno::Reference< XSpellChecker1 > SvxGetSpellChecker() |
| { |
| return LinguMgr::GetSpellChecker(); |
| } |
| |
| uno::Reference< XHyphenator > SvxGetHyphenator() |
| { |
| return LinguMgr::GetHyphenator(); |
| } |
| |
| uno::Reference< XThesaurus > SvxGetThesaurus() |
| { |
| return LinguMgr::GetThesaurus(); |
| } |
| |
| uno::Reference< XDictionaryList > SvxGetDictionaryList() |
| { |
| return LinguMgr::GetDictionaryList(); |
| } |
| |
| uno::Reference< XPropertySet > SvxGetLinguPropertySet() |
| { |
| return LinguMgr::GetLinguPropertySet(); |
| } |
| |
| //TL:TODO: remove argument or provide SvxGetIgnoreAllList with the same one |
| uno::Reference< XDictionary > SvxGetOrCreatePosDic( |
| uno::Reference< XDictionaryList > /* xDicList */ ) |
| { |
| return LinguMgr::GetStandardDic(); |
| } |
| |
| uno::Reference< XDictionary > SvxGetIgnoreAllList() |
| { |
| return LinguMgr::GetIgnoreAllList(); |
| } |
| |
| uno::Reference< XDictionary > SvxGetChangeAllList() |
| { |
| return LinguMgr::GetChangeAllList(); |
| } |
| |
| /////////////////////////////////////////////////////////////////////////// |
| |
| |
| #include <com/sun/star/linguistic2/XHyphenatedWord.hpp> |
| |
| SvxAlternativeSpelling SvxGetAltSpelling( |
| const ::com::sun::star::uno::Reference< |
| ::com::sun::star::linguistic2::XHyphenatedWord > & rHyphWord ) |
| { |
| SvxAlternativeSpelling aRes; |
| if (rHyphWord.is() && rHyphWord->isAlternativeSpelling()) |
| { |
| OUString aWord( rHyphWord->getWord() ), |
| aAltWord( rHyphWord->getHyphenatedWord() ); |
| sal_Int16 nHyphenationPos = rHyphWord->getHyphenationPos(), |
| nHyphenPos = rHyphWord->getHyphenPos(); |
| sal_Int16 nLen = (sal_Int16)aWord.getLength(); |
| sal_Int16 nAltLen = (sal_Int16)aAltWord.getLength(); |
| const sal_Unicode *pWord = aWord.getStr(), |
| *pAltWord = aAltWord.getStr(); |
| |
| // count number of chars from the left to the |
| // hyphenation pos / hyphen pos that are equal |
| sal_Int16 nL = 0; |
| while (nL <= nHyphenationPos && nL <= nHyphenPos |
| && pWord[ nL ] == pAltWord[ nL ]) |
| ++nL; |
| // count number of chars from the right to the |
| // hyphenation pos / hyphen pos that are equal |
| sal_Int16 nR = 0; |
| sal_Int32 nIdx = nLen - 1; |
| sal_Int32 nAltIdx = nAltLen - 1; |
| while (nIdx > nHyphenationPos && nAltIdx > nHyphenPos |
| && pWord[ nIdx-- ] == pAltWord[ nAltIdx-- ]) |
| ++nR; |
| |
| aRes.aReplacement = OUString( aAltWord.copy( nL, nAltLen - nL - nR ) ); |
| aRes.nChangedPos = (sal_Int16) nL; |
| aRes.nChangedLength = nLen - nL - nR; |
| aRes.bIsAltSpelling = sal_True; |
| aRes.xHyphWord = rHyphWord; |
| } |
| return aRes; |
| } |
| |
| |
| /////////////////////////////////////////////////////////////////////////// |
| |
| SvxDicListChgClamp::SvxDicListChgClamp( uno::Reference< XDictionaryList > &rxDicList ) : |
| xDicList ( rxDicList ) |
| { |
| if (xDicList.is()) |
| { |
| xDicList->beginCollectEvents(); |
| } |
| } |
| |
| SvxDicListChgClamp::~SvxDicListChgClamp() |
| { |
| if (xDicList.is()) |
| { |
| xDicList->endCollectEvents(); |
| } |
| } |
| |
| /////////////////////////////////////////////////////////////////////////// |
| |
| short SvxDicError( Window *pParent, sal_Int16 nError ) |
| { |
| short nRes = 0; |
| if (DIC_ERR_NONE != nError) |
| { |
| int nRid; |
| switch (nError) |
| { |
| case DIC_ERR_FULL : nRid = RID_SVXSTR_DIC_ERR_FULL; break; |
| case DIC_ERR_READONLY : nRid = RID_SVXSTR_DIC_ERR_READONLY; break; |
| default: |
| nRid = RID_SVXSTR_DIC_ERR_UNKNOWN; |
| DBG_ASSERT(0, "unexpected case"); |
| } |
| nRes = InfoBox( pParent, EE_RESSTR( nRid ) ).Execute(); |
| } |
| return nRes; |
| } |
| |
| LanguageType SvxLocaleToLanguage( const Locale& rLocale ) |
| { |
| // empty Locale -> LANGUAGE_NONE |
| if ( rLocale.Language.getLength() == 0 ) |
| return LANGUAGE_NONE; |
| |
| return MsLangId::convertLocaleToLanguage( rLocale ); |
| } |
| |
| Locale& SvxLanguageToLocale( Locale& rLocale, LanguageType eLang ) |
| { |
| if ( eLang != LANGUAGE_NONE /* && eLang != LANGUAGE_SYSTEM */) |
| MsLangId::convertLanguageToLocale( eLang, rLocale ); |
| else |
| rLocale = Locale(); |
| |
| return rLocale; |
| } |
| |
| Locale SvxCreateLocale( LanguageType eLang ) |
| { |
| Locale aLocale; |
| if ( eLang != LANGUAGE_NONE /* && eLang != LANGUAGE_SYSTEM */) |
| MsLangId::convertLanguageToLocale( eLang, aLocale ); |
| |
| return aLocale; |
| } |
| |
| |