xref: /AOO41X/main/editeng/source/misc/unolingu.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_editeng.hxx"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir #include <map>
32*cdf0e10cSrcweir #include <set>
33*cdf0e10cSrcweir #include <vector>
34*cdf0e10cSrcweir #include <slist>
35*cdf0e10cSrcweir #include <memory>
36*cdf0e10cSrcweir #include <editeng/unolingu.hxx>
37*cdf0e10cSrcweir #include <tools/debug.hxx>
38*cdf0e10cSrcweir #include <tools/urlobj.hxx>
39*cdf0e10cSrcweir #include <rtl/logfile.hxx>
40*cdf0e10cSrcweir #include <unotools/pathoptions.hxx>
41*cdf0e10cSrcweir #include <com/sun/star/frame/XModel.hpp>
42*cdf0e10cSrcweir #include <com/sun/star/frame/XStorable.hpp>
43*cdf0e10cSrcweir #include <com/sun/star/lang/XEventListener.hpp>
44*cdf0e10cSrcweir #include <com/sun/star/linguistic2/XAvailableLocales.hpp>
45*cdf0e10cSrcweir #include <com/sun/star/ucb/XAnyCompareFactory.hpp>
46*cdf0e10cSrcweir #include <com/sun/star/ucb/XContentAccess.hpp>
47*cdf0e10cSrcweir #include <com/sun/star/ucb/XSortedDynamicResultSetFactory.hpp>
48*cdf0e10cSrcweir #include <com/sun/star/ucb/NumberedSortingInfo.hpp>
49*cdf0e10cSrcweir #include <com/sun/star/ucb/XContentAccess.hpp>
50*cdf0e10cSrcweir #include <com/sun/star/sdbc/XResultSet.hpp>
51*cdf0e10cSrcweir #include <com/sun/star/sdbc/XRow.hpp>
52*cdf0e10cSrcweir #include <com/sun/star/util/DateTime.hpp>
53*cdf0e10cSrcweir 
54*cdf0e10cSrcweir #include <comphelper/processfactory.hxx>
55*cdf0e10cSrcweir #include <cppuhelper/implbase1.hxx>	// helper for implementations
56*cdf0e10cSrcweir #include <i18npool/mslangid.hxx>
57*cdf0e10cSrcweir #include <unotools/lingucfg.hxx>
58*cdf0e10cSrcweir #include <unotools/ucbhelper.hxx>
59*cdf0e10cSrcweir #include <unotools/localfilehelper.hxx>
60*cdf0e10cSrcweir #include <ucbhelper/commandenvironment.hxx>
61*cdf0e10cSrcweir #include <ucbhelper/content.hxx>
62*cdf0e10cSrcweir #include <comphelper/processfactory.hxx>
63*cdf0e10cSrcweir #include <vcl/msgbox.hxx>
64*cdf0e10cSrcweir #include <tools/shl.hxx>
65*cdf0e10cSrcweir #include <linguistic/misc.hxx>
66*cdf0e10cSrcweir #include <editeng/eerdll.hxx>
67*cdf0e10cSrcweir #include <editeng/editrids.hrc>
68*cdf0e10cSrcweir 
69*cdf0e10cSrcweir using namespace ::rtl;
70*cdf0e10cSrcweir using namespace ::comphelper;
71*cdf0e10cSrcweir using namespace ::linguistic;
72*cdf0e10cSrcweir using namespace ::com::sun::star;
73*cdf0e10cSrcweir using namespace ::com::sun::star::util;
74*cdf0e10cSrcweir using namespace ::com::sun::star::uno;
75*cdf0e10cSrcweir using namespace ::com::sun::star::lang;
76*cdf0e10cSrcweir using namespace ::com::sun::star::beans;
77*cdf0e10cSrcweir using namespace ::com::sun::star::frame;
78*cdf0e10cSrcweir using namespace ::com::sun::star::linguistic2;
79*cdf0e10cSrcweir 
80*cdf0e10cSrcweir #define CSS com::sun::star
81*cdf0e10cSrcweir 
82*cdf0e10cSrcweir ///////////////////////////////////////////////////////////////////////////
83*cdf0e10cSrcweir 
84*cdf0e10cSrcweir 
85*cdf0e10cSrcweir static uno::Reference< XLinguServiceManager > GetLngSvcMgr_Impl()
86*cdf0e10cSrcweir {
87*cdf0e10cSrcweir 	uno::Reference< XLinguServiceManager > xRes;
88*cdf0e10cSrcweir 	uno::Reference< XMultiServiceFactory >  xMgr = getProcessServiceFactory();
89*cdf0e10cSrcweir 	if (xMgr.is())
90*cdf0e10cSrcweir 	{
91*cdf0e10cSrcweir 		xRes = uno::Reference< XLinguServiceManager > ( xMgr->createInstance(
92*cdf0e10cSrcweir 				OUString( RTL_CONSTASCII_USTRINGPARAM(
93*cdf0e10cSrcweir 					"com.sun.star.linguistic2.LinguServiceManager" ) ) ), UNO_QUERY ) ;
94*cdf0e10cSrcweir 	}
95*cdf0e10cSrcweir 	return xRes;
96*cdf0e10cSrcweir }
97*cdf0e10cSrcweir 
98*cdf0e10cSrcweir ///////////////////////////////////////////////////////////////////////////
99*cdf0e10cSrcweir 
100*cdf0e10cSrcweir sal_Bool lcl_FindEntry( const OUString &rEntry, const Sequence< OUString > &rCfgSvcs )
101*cdf0e10cSrcweir {
102*cdf0e10cSrcweir     sal_Int32 nRes = -1;
103*cdf0e10cSrcweir     sal_Int32 nEntries = rCfgSvcs.getLength();
104*cdf0e10cSrcweir     const OUString *pEntry = rCfgSvcs.getConstArray();
105*cdf0e10cSrcweir     for (sal_Int32 i = 0;  i < nEntries && nRes == -1;  ++i)
106*cdf0e10cSrcweir     {
107*cdf0e10cSrcweir         if (rEntry == pEntry[i])
108*cdf0e10cSrcweir             nRes = i;
109*cdf0e10cSrcweir     }
110*cdf0e10cSrcweir     return nRes != -1;
111*cdf0e10cSrcweir }
112*cdf0e10cSrcweir 
113*cdf0e10cSrcweir 
114*cdf0e10cSrcweir Sequence< OUString > lcl_RemoveMissingEntries(
115*cdf0e10cSrcweir         const Sequence< OUString > &rCfgSvcs,
116*cdf0e10cSrcweir         const Sequence< OUString > &rAvailSvcs )
117*cdf0e10cSrcweir {
118*cdf0e10cSrcweir     Sequence< OUString > aRes( rCfgSvcs.getLength() );
119*cdf0e10cSrcweir     OUString *pRes = aRes.getArray();
120*cdf0e10cSrcweir     sal_Int32 nCnt = 0;
121*cdf0e10cSrcweir 
122*cdf0e10cSrcweir     sal_Int32 nEntries = rCfgSvcs.getLength();
123*cdf0e10cSrcweir     const OUString *pEntry = rCfgSvcs.getConstArray();
124*cdf0e10cSrcweir     for (sal_Int32 i = 0;  i < nEntries;  ++i)
125*cdf0e10cSrcweir     {
126*cdf0e10cSrcweir         if (pEntry[i].getLength() && lcl_FindEntry( pEntry[i], rAvailSvcs ))
127*cdf0e10cSrcweir             pRes[ nCnt++ ] = pEntry[i];
128*cdf0e10cSrcweir     }
129*cdf0e10cSrcweir 
130*cdf0e10cSrcweir     aRes.realloc( nCnt );
131*cdf0e10cSrcweir     return aRes;
132*cdf0e10cSrcweir }
133*cdf0e10cSrcweir 
134*cdf0e10cSrcweir 
135*cdf0e10cSrcweir Sequence< OUString > lcl_GetLastFoundSvcs(
136*cdf0e10cSrcweir         SvtLinguConfig &rCfg,
137*cdf0e10cSrcweir         const OUString &rLastFoundList ,
138*cdf0e10cSrcweir         const Locale &rAvailLocale )
139*cdf0e10cSrcweir {
140*cdf0e10cSrcweir     Sequence< OUString > aRes;
141*cdf0e10cSrcweir 
142*cdf0e10cSrcweir     OUString aCfgLocaleStr( MsLangId::convertLanguageToIsoString(
143*cdf0e10cSrcweir                                 SvxLocaleToLanguage( rAvailLocale ) ) );
144*cdf0e10cSrcweir 
145*cdf0e10cSrcweir     Sequence< OUString > aNodeNames( rCfg.GetNodeNames(rLastFoundList) );
146*cdf0e10cSrcweir     sal_Bool bFound = lcl_FindEntry( aCfgLocaleStr, aNodeNames);
147*cdf0e10cSrcweir 
148*cdf0e10cSrcweir     if (bFound)
149*cdf0e10cSrcweir     {
150*cdf0e10cSrcweir         Sequence< OUString > aNames(1);
151*cdf0e10cSrcweir         OUString &rNodeName = aNames.getArray()[0];
152*cdf0e10cSrcweir         rNodeName = rLastFoundList;
153*cdf0e10cSrcweir         rNodeName += OUString::valueOf( (sal_Unicode)'/' );
154*cdf0e10cSrcweir         rNodeName += aCfgLocaleStr;
155*cdf0e10cSrcweir         Sequence< Any > aValues( rCfg.GetProperties( aNames ) );
156*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
157*cdf0e10cSrcweir         const Any *pValue;
158*cdf0e10cSrcweir         pValue = aValues.getConstArray();
159*cdf0e10cSrcweir #endif
160*cdf0e10cSrcweir         if (aValues.getLength())
161*cdf0e10cSrcweir         {
162*cdf0e10cSrcweir             DBG_ASSERT( aValues.getLength() == 1, "unexpected length of sequence" );
163*cdf0e10cSrcweir             Sequence< OUString > aSvcImplNames;
164*cdf0e10cSrcweir             if (aValues.getConstArray()[0] >>= aSvcImplNames)
165*cdf0e10cSrcweir                 aRes = aSvcImplNames;
166*cdf0e10cSrcweir             else
167*cdf0e10cSrcweir             {
168*cdf0e10cSrcweir                 DBG_ERROR( "type mismatch" );
169*cdf0e10cSrcweir             }
170*cdf0e10cSrcweir         }
171*cdf0e10cSrcweir     }
172*cdf0e10cSrcweir 
173*cdf0e10cSrcweir     return aRes;
174*cdf0e10cSrcweir }
175*cdf0e10cSrcweir 
176*cdf0e10cSrcweir 
177*cdf0e10cSrcweir Sequence< OUString > lcl_GetNewEntries(
178*cdf0e10cSrcweir         const Sequence< OUString > &rLastFoundSvcs,
179*cdf0e10cSrcweir         const Sequence< OUString > &rAvailSvcs )
180*cdf0e10cSrcweir {
181*cdf0e10cSrcweir     sal_Int32 nLen = rAvailSvcs.getLength();
182*cdf0e10cSrcweir     Sequence< OUString > aRes( nLen );
183*cdf0e10cSrcweir     OUString *pRes = aRes.getArray();
184*cdf0e10cSrcweir     sal_Int32 nCnt = 0;
185*cdf0e10cSrcweir 
186*cdf0e10cSrcweir     const OUString *pEntry = rAvailSvcs.getConstArray();
187*cdf0e10cSrcweir     for (sal_Int32 i = 0;  i < nLen;  ++i)
188*cdf0e10cSrcweir     {
189*cdf0e10cSrcweir         if (pEntry[i].getLength() && !lcl_FindEntry( pEntry[i], rLastFoundSvcs ))
190*cdf0e10cSrcweir             pRes[ nCnt++ ] = pEntry[i];
191*cdf0e10cSrcweir     }
192*cdf0e10cSrcweir 
193*cdf0e10cSrcweir     aRes.realloc( nCnt );
194*cdf0e10cSrcweir     return aRes;
195*cdf0e10cSrcweir }
196*cdf0e10cSrcweir 
197*cdf0e10cSrcweir 
198*cdf0e10cSrcweir Sequence< OUString > lcl_MergeSeq(
199*cdf0e10cSrcweir         const Sequence< OUString > &rCfgSvcs,
200*cdf0e10cSrcweir         const Sequence< OUString > &rNewSvcs )
201*cdf0e10cSrcweir {
202*cdf0e10cSrcweir     Sequence< OUString > aRes( rCfgSvcs.getLength() + rNewSvcs.getLength() );
203*cdf0e10cSrcweir     OUString *pRes = aRes.getArray();
204*cdf0e10cSrcweir     sal_Int32 nCnt = 0;
205*cdf0e10cSrcweir 
206*cdf0e10cSrcweir     for (sal_Int32 k = 0;  k < 2;  ++k)
207*cdf0e10cSrcweir     {
208*cdf0e10cSrcweir 		// add previously configuerd service first and append
209*cdf0e10cSrcweir 		// new found services at the end
210*cdf0e10cSrcweir         const Sequence< OUString > &rSeq = k == 0 ? rCfgSvcs : rNewSvcs;
211*cdf0e10cSrcweir 
212*cdf0e10cSrcweir 		sal_Int32 nLen = rSeq.getLength();
213*cdf0e10cSrcweir         const OUString *pEntry = rSeq.getConstArray();
214*cdf0e10cSrcweir         for (sal_Int32 i = 0;  i < nLen;  ++i)
215*cdf0e10cSrcweir         {
216*cdf0e10cSrcweir             if (pEntry[i].getLength() && !lcl_FindEntry( pEntry[i], aRes ))
217*cdf0e10cSrcweir                 pRes[ nCnt++ ] = pEntry[i];
218*cdf0e10cSrcweir         }
219*cdf0e10cSrcweir     }
220*cdf0e10cSrcweir 
221*cdf0e10cSrcweir     aRes.realloc( nCnt );
222*cdf0e10cSrcweir     return aRes;
223*cdf0e10cSrcweir }
224*cdf0e10cSrcweir 
225*cdf0e10cSrcweir ///////////////////////////////////////////////////////////////////////////
226*cdf0e10cSrcweir 
227*cdf0e10cSrcweir // static member initialization
228*cdf0e10cSrcweir sal_Int16 SvxLinguConfigUpdate::nNeedUpdating = -1;
229*cdf0e10cSrcweir sal_Int32 SvxLinguConfigUpdate::nCurrentDataFilesChangedCheckValue = -1;
230*cdf0e10cSrcweir 
231*cdf0e10cSrcweir void SvxLinguConfigUpdate::UpdateAll( sal_Bool bForceCheck )
232*cdf0e10cSrcweir {
233*cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT( aLog, "svx: SvxLinguConfigUpdate::UpdateAll" );
234*cdf0e10cSrcweir 
235*cdf0e10cSrcweir     if (IsNeedUpdateAll( bForceCheck ))
236*cdf0e10cSrcweir     {
237*cdf0e10cSrcweir         typedef OUString OUstring_t;
238*cdf0e10cSrcweir         typedef Sequence< OUString > Sequence_OUString_t;
239*cdf0e10cSrcweir         typedef std::vector< OUstring_t > OUString_vector_t;
240*cdf0e10cSrcweir         typedef std::set< OUstring_t > OUString_set_t;
241*cdf0e10cSrcweir         std::vector< OUString_vector_t > aVector;
242*cdf0e10cSrcweir         typedef std::map< OUstring_t, Sequence_OUString_t > list_entry_map_t;
243*cdf0e10cSrcweir 
244*cdf0e10cSrcweir         RTL_LOGFILE_CONTEXT( aLog, "svx: SvxLinguConfigUpdate::UpdateAll - updating..." );
245*cdf0e10cSrcweir 
246*cdf0e10cSrcweir         DBG_ASSERT( nNeedUpdating == 1, "SvxLinguConfigUpdate::UpdateAll already updated!" );
247*cdf0e10cSrcweir 
248*cdf0e10cSrcweir         uno::Reference< XLinguServiceManager > xLngSvcMgr( GetLngSvcMgr_Impl() );
249*cdf0e10cSrcweir         DBG_ASSERT( xLngSvcMgr.is(), "service manager missing");
250*cdf0e10cSrcweir         if (!xLngSvcMgr.is())
251*cdf0e10cSrcweir             return;
252*cdf0e10cSrcweir 
253*cdf0e10cSrcweir         SvtLinguConfig aCfg;
254*cdf0e10cSrcweir 
255*cdf0e10cSrcweir 		const int nNumServices = 4;
256*cdf0e10cSrcweir         const sal_Char * apServices[nNumServices]       =  { SN_SPELLCHECKER, SN_GRAMMARCHECKER, SN_HYPHENATOR, SN_THESAURUS };
257*cdf0e10cSrcweir         const sal_Char * apCurLists[nNumServices]       =  { "ServiceManager/SpellCheckerList",       "ServiceManager/GrammarCheckerList",       "ServiceManager/HyphenatorList",       "ServiceManager/ThesaurusList" };
258*cdf0e10cSrcweir         const sal_Char * apLastFoundLists[nNumServices] =  { "ServiceManager/LastFoundSpellCheckers", "ServiceManager/LastFoundGrammarCheckers", "ServiceManager/LastFoundHyphenators", "ServiceManager/LastFoundThesauri" };
259*cdf0e10cSrcweir 
260*cdf0e10cSrcweir         // usage of indices as above: 0 = spell checker, 1 = grammar checker, 2 = hyphenator, 3 = thesaurus
261*cdf0e10cSrcweir         std::vector< list_entry_map_t > aLastFoundSvcs(nNumServices);
262*cdf0e10cSrcweir         std::vector< list_entry_map_t > aCurSvcs(nNumServices);
263*cdf0e10cSrcweir 
264*cdf0e10cSrcweir         for (int k = 0;  k < nNumServices;  ++k)
265*cdf0e10cSrcweir         {
266*cdf0e10cSrcweir             OUString aService( A2OU( apServices[k] ) );
267*cdf0e10cSrcweir             OUString aActiveList( A2OU( apCurLists[k] ) );
268*cdf0e10cSrcweir             OUString aLastFoundList( A2OU( apLastFoundLists[k] ) );
269*cdf0e10cSrcweir             sal_Int32 i;
270*cdf0e10cSrcweir 
271*cdf0e10cSrcweir             //
272*cdf0e10cSrcweir             // remove configured but not available language/services entries
273*cdf0e10cSrcweir             //
274*cdf0e10cSrcweir             Sequence< OUString > aNodeNames( aCfg.GetNodeNames( aActiveList ) );   // list of configured locales
275*cdf0e10cSrcweir             sal_Int32 nNodeNames = aNodeNames.getLength();
276*cdf0e10cSrcweir             const OUString *pNodeName = aNodeNames.getConstArray();
277*cdf0e10cSrcweir             for (i = 0;  i < nNodeNames;  ++i)
278*cdf0e10cSrcweir             {
279*cdf0e10cSrcweir                 Locale aLocale( SvxCreateLocale( MsLangId::convertIsoStringToLanguage(pNodeName[i]) ) );
280*cdf0e10cSrcweir                 Sequence< OUString > aCfgSvcs(
281*cdf0e10cSrcweir                         xLngSvcMgr->getConfiguredServices( aService, aLocale ));
282*cdf0e10cSrcweir                 Sequence< OUString > aAvailSvcs(
283*cdf0e10cSrcweir                         xLngSvcMgr->getAvailableServices( aService, aLocale ));
284*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
285*cdf0e10cSrcweir                 const OUString * pCfgSvcs   = aCfgSvcs.getConstArray();;
286*cdf0e10cSrcweir                 const OUString * pAvailSvcs = aAvailSvcs.getConstArray();;
287*cdf0e10cSrcweir                 (void) pCfgSvcs;
288*cdf0e10cSrcweir                 (void) pAvailSvcs;
289*cdf0e10cSrcweir #endif
290*cdf0e10cSrcweir                 aCfgSvcs = lcl_RemoveMissingEntries( aCfgSvcs, aAvailSvcs );
291*cdf0e10cSrcweir 
292*cdf0e10cSrcweir                 aCurSvcs[k][ pNodeName[i] ] = aCfgSvcs;
293*cdf0e10cSrcweir             }
294*cdf0e10cSrcweir 
295*cdf0e10cSrcweir             //
296*cdf0e10cSrcweir             // add new available language/servcice entries
297*cdf0e10cSrcweir             //
298*cdf0e10cSrcweir             uno::Reference< XAvailableLocales > xAvail( xLngSvcMgr, UNO_QUERY );
299*cdf0e10cSrcweir             Sequence< Locale > aAvailLocales( xAvail->getAvailableLocales(aService) );
300*cdf0e10cSrcweir             sal_Int32 nAvailLocales = aAvailLocales.getLength();
301*cdf0e10cSrcweir             const Locale *pAvailLocale = aAvailLocales.getConstArray();
302*cdf0e10cSrcweir             for (i = 0;  i < nAvailLocales;  ++i)
303*cdf0e10cSrcweir             {
304*cdf0e10cSrcweir                 Sequence< OUString > aAvailSvcs(
305*cdf0e10cSrcweir                         xLngSvcMgr->getAvailableServices( aService, pAvailLocale[i] ));
306*cdf0e10cSrcweir                 Sequence< OUString > aLastSvcs(
307*cdf0e10cSrcweir                         lcl_GetLastFoundSvcs( aCfg, aLastFoundList , pAvailLocale[i] ));
308*cdf0e10cSrcweir                 Sequence< OUString > aNewSvcs =
309*cdf0e10cSrcweir                         lcl_GetNewEntries( aLastSvcs, aAvailSvcs );
310*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
311*cdf0e10cSrcweir                 const OUString * pAvailSvcs = aAvailSvcs.getConstArray();
312*cdf0e10cSrcweir                 const OUString * pLastSvcs  = aLastSvcs.getConstArray();
313*cdf0e10cSrcweir                 const OUString * pNewSvcs   = aNewSvcs.getConstArray();
314*cdf0e10cSrcweir                 (void) pAvailSvcs;
315*cdf0e10cSrcweir                 (void) pLastSvcs;
316*cdf0e10cSrcweir                 (void) pNewSvcs;
317*cdf0e10cSrcweir #endif
318*cdf0e10cSrcweir 
319*cdf0e10cSrcweir                 OUString aCfgLocaleStr( MsLangId::convertLanguageToIsoString(
320*cdf0e10cSrcweir                                             SvxLocaleToLanguage( pAvailLocale[i] ) ) );
321*cdf0e10cSrcweir                 Sequence< OUString > aCfgSvcs( aCurSvcs[k][ aCfgLocaleStr ] );
322*cdf0e10cSrcweir 
323*cdf0e10cSrcweir                 // merge services list (previously configured to be listed first).
324*cdf0e10cSrcweir 				aCfgSvcs = lcl_MergeSeq( aCfgSvcs, aNewSvcs );
325*cdf0e10cSrcweir 
326*cdf0e10cSrcweir /*
327*cdf0e10cSrcweir 				// there is at most one Hyphenator per language allowed
328*cdf0e10cSrcweir 				// to be configured, thus we only use the first one found.
329*cdf0e10cSrcweir 				if (k == 2 && aCfgSvcs.getLength() > 1)
330*cdf0e10cSrcweir 					aCfgSvcs.realloc(1);
331*cdf0e10cSrcweir */
332*cdf0e10cSrcweir                 aCurSvcs[k][ aCfgLocaleStr ] = aCfgSvcs;
333*cdf0e10cSrcweir             }
334*cdf0e10cSrcweir 
335*cdf0e10cSrcweir             //
336*cdf0e10cSrcweir             // set last found services to currently available ones
337*cdf0e10cSrcweir             //
338*cdf0e10cSrcweir             for (i = 0;  i < nAvailLocales;  ++i)
339*cdf0e10cSrcweir             {
340*cdf0e10cSrcweir                 Sequence< OUString > aSvcImplNames(
341*cdf0e10cSrcweir                         xLngSvcMgr->getAvailableServices( aService, pAvailLocale[i] ) );
342*cdf0e10cSrcweir 
343*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
344*cdf0e10cSrcweir                 sal_Int32 nSvcs = aSvcImplNames.getLength();
345*cdf0e10cSrcweir                 const OUString *pSvcImplName = aSvcImplNames.getConstArray();
346*cdf0e10cSrcweir                 for (sal_Int32 j = 0;  j < nSvcs;  ++j)
347*cdf0e10cSrcweir                 {
348*cdf0e10cSrcweir                     OUString aImplName( pSvcImplName[j] );
349*cdf0e10cSrcweir                 }
350*cdf0e10cSrcweir #endif
351*cdf0e10cSrcweir 
352*cdf0e10cSrcweir                 OUString aCfgLocaleStr( MsLangId::convertLanguageToIsoString(
353*cdf0e10cSrcweir                                             SvxLocaleToLanguage( pAvailLocale[i] ) ) );
354*cdf0e10cSrcweir 				aLastFoundSvcs[k][ aCfgLocaleStr ] = aSvcImplNames;
355*cdf0e10cSrcweir             }
356*cdf0e10cSrcweir         }
357*cdf0e10cSrcweir 
358*cdf0e10cSrcweir         //
359*cdf0e10cSrcweir         // write new data back to configuration
360*cdf0e10cSrcweir         //
361*cdf0e10cSrcweir         for (int k = 0;  k < nNumServices;  ++k)
362*cdf0e10cSrcweir         {
363*cdf0e10cSrcweir             for (int i = 0;  i < 2;  ++i)
364*cdf0e10cSrcweir             {
365*cdf0e10cSrcweir                 const sal_Char *pSubNodeName = (i == 0) ? apCurLists[k] : apLastFoundLists[k];
366*cdf0e10cSrcweir                 OUString aSubNodeName( A2OU(pSubNodeName) );
367*cdf0e10cSrcweir 
368*cdf0e10cSrcweir 				list_entry_map_t &rCurMap = (i == 0) ? aCurSvcs[k] : aLastFoundSvcs[k];
369*cdf0e10cSrcweir                 list_entry_map_t::const_iterator aIt( rCurMap.begin() );
370*cdf0e10cSrcweir                 sal_Int32 nVals = static_cast< sal_Int32 >( rCurMap.size() );
371*cdf0e10cSrcweir                 Sequence< PropertyValue > aNewValues( nVals );
372*cdf0e10cSrcweir                 PropertyValue *pNewValue = aNewValues.getArray();
373*cdf0e10cSrcweir                 while (aIt != rCurMap.end())
374*cdf0e10cSrcweir                 {
375*cdf0e10cSrcweir 					OUString aCfgEntryName( aSubNodeName );
376*cdf0e10cSrcweir 	                aCfgEntryName += OUString::valueOf( (sal_Unicode) '/' );
377*cdf0e10cSrcweir 					aCfgEntryName += (*aIt).first;
378*cdf0e10cSrcweir 
379*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
380*cdf0e10cSrcweir                     Sequence< OUString > aSvcImplNames( (*aIt).second );
381*cdf0e10cSrcweir                     sal_Int32 nSvcs = aSvcImplNames.getLength();
382*cdf0e10cSrcweir                     const OUString *pSvcImplName = aSvcImplNames.getConstArray();
383*cdf0e10cSrcweir                     for (sal_Int32 j = 0;  j < nSvcs;  ++j)
384*cdf0e10cSrcweir                     {
385*cdf0e10cSrcweir                         OUString aImplName( pSvcImplName[j] );
386*cdf0e10cSrcweir                     }
387*cdf0e10cSrcweir #endif
388*cdf0e10cSrcweir                     pNewValue->Name  = aCfgEntryName;
389*cdf0e10cSrcweir                     pNewValue->Value <<= (*aIt).second;
390*cdf0e10cSrcweir                     ++pNewValue;
391*cdf0e10cSrcweir                     ++aIt;
392*cdf0e10cSrcweir                 }
393*cdf0e10cSrcweir                 DBG_ASSERT( pNewValue - aNewValues.getArray() == nVals,
394*cdf0e10cSrcweir                         "possible mismatch of sequence size and property number" );
395*cdf0e10cSrcweir 
396*cdf0e10cSrcweir                 {
397*cdf0e10cSrcweir                     RTL_LOGFILE_CONTEXT( aLog, "svx: SvxLinguConfigUpdate::UpdateAll - ReplaceSetProperties" );
398*cdf0e10cSrcweir                     // add new or replace existing entries.
399*cdf0e10cSrcweir                     sal_Bool bRes = aCfg.ReplaceSetProperties( aSubNodeName, aNewValues );
400*cdf0e10cSrcweir                     if (!bRes)
401*cdf0e10cSrcweir                     {
402*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
403*cdf0e10cSrcweir                         DBG_ERROR( "failed to set new configuration values" );
404*cdf0e10cSrcweir #endif
405*cdf0e10cSrcweir                     }
406*cdf0e10cSrcweir                 }
407*cdf0e10cSrcweir             }
408*cdf0e10cSrcweir         }
409*cdf0e10cSrcweir 		DBG_ASSERT( nCurrentDataFilesChangedCheckValue != -1, "SvxLinguConfigUpdate::UpdateAll DataFilesChangedCheckValue not yet calculated!" );
410*cdf0e10cSrcweir 		Any aAny;
411*cdf0e10cSrcweir 
412*cdf0e10cSrcweir 		// for the time being (developer builds until OOo 3.0)
413*cdf0e10cSrcweir 		// we should always check for everything available
414*cdf0e10cSrcweir 		// otherwise we may miss a new installed extension dicitonary
415*cdf0e10cSrcweir 		// just because e.g. the spellchecker is not asked what
416*cdf0e10cSrcweir 		// languages it does support currently...
417*cdf0e10cSrcweir 		// Since the check is on-demand occuring and executed once it should
418*cdf0e10cSrcweir 		// not be too troublesome.
419*cdf0e10cSrcweir 		// In OOo 3.0 we will not need the respective code anymore at all.
420*cdf0e10cSrcweir //		aAny <<= nCurrentDataFilesChangedCheckValue;
421*cdf0e10cSrcweir 		aAny <<= (sal_Int32) -1;	// keep the value set to 'need to check'
422*cdf0e10cSrcweir 
423*cdf0e10cSrcweir 		aCfg.SetProperty( A2OU( "DataFilesChangedCheckValue" ), aAny );
424*cdf0e10cSrcweir 
425*cdf0e10cSrcweir 		//! Note 1: the new values are commited when the 'aCfg' object
426*cdf0e10cSrcweir 		//!		gets destroyed.
427*cdf0e10cSrcweir 		//! Note 2: the new settings in the configuration get applied
428*cdf0e10cSrcweir 		//!		because the 'LngSvcMgr' (in linguistic/source/lngsvcmgr.hxx)
429*cdf0e10cSrcweir 		//!		listens to the configuration for changes of the relevant
430*cdf0e10cSrcweir 		//!		properties and then applies the new settings.
431*cdf0e10cSrcweir 
432*cdf0e10cSrcweir 		// nothing needs to be done anymore
433*cdf0e10cSrcweir         nNeedUpdating = 0;
434*cdf0e10cSrcweir     }
435*cdf0e10cSrcweir }
436*cdf0e10cSrcweir 
437*cdf0e10cSrcweir 
438*cdf0e10cSrcweir sal_Int32 SvxLinguConfigUpdate::CalcDataFilesChangedCheckValue()
439*cdf0e10cSrcweir {
440*cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT( aLog, "svx: SvxLinguConfigUpdate::CalcDataFilesChangedCheckValue" );
441*cdf0e10cSrcweir 
442*cdf0e10cSrcweir     sal_Int32 nHashVal = 0;
443*cdf0e10cSrcweir     // nothing to be checked anymore since those old directory paths are gone by now
444*cdf0e10cSrcweir     return nHashVal;
445*cdf0e10cSrcweir }
446*cdf0e10cSrcweir 
447*cdf0e10cSrcweir 
448*cdf0e10cSrcweir sal_Bool SvxLinguConfigUpdate::IsNeedUpdateAll( sal_Bool bForceCheck )
449*cdf0e10cSrcweir {
450*cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT( aLog, "svx: SvxLinguConfigUpdate::IsNeedUpdateAll" );
451*cdf0e10cSrcweir     if (nNeedUpdating == -1 || bForceCheck )    // need to check if updating is necessary
452*cdf0e10cSrcweir     {
453*cdf0e10cSrcweir         // calculate hash value for current data files
454*cdf0e10cSrcweir         nCurrentDataFilesChangedCheckValue = CalcDataFilesChangedCheckValue();
455*cdf0e10cSrcweir 
456*cdf0e10cSrcweir         // compare hash value and check value to see if anything has changed
457*cdf0e10cSrcweir         // and thus the configuration needs to be updated
458*cdf0e10cSrcweir         SvtLinguOptions aLinguOpt;
459*cdf0e10cSrcweir         SvtLinguConfig aCfg;
460*cdf0e10cSrcweir         aCfg.GetOptions( aLinguOpt );
461*cdf0e10cSrcweir         nNeedUpdating = (nCurrentDataFilesChangedCheckValue == aLinguOpt.nDataFilesChangedCheckValue) ? 0 : 1;
462*cdf0e10cSrcweir     }
463*cdf0e10cSrcweir     DBG_ASSERT( nNeedUpdating != -1,
464*cdf0e10cSrcweir             "need for linguistic configuration update should have been already checked." );
465*cdf0e10cSrcweir 
466*cdf0e10cSrcweir     return nNeedUpdating == 1;
467*cdf0e10cSrcweir }
468*cdf0e10cSrcweir 
469*cdf0e10cSrcweir ///////////////////////////////////////////////////////////////////////////
470*cdf0e10cSrcweir 
471*cdf0e10cSrcweir 
472*cdf0e10cSrcweir //! Dummy implementation in order to avoid loading of lingu DLL
473*cdf0e10cSrcweir //! when only the XSupportedLocales interface is used.
474*cdf0e10cSrcweir //! The dummy accesses the real implementation (and thus loading the DLL)
475*cdf0e10cSrcweir //! when "real" work needs to be done only.
476*cdf0e10cSrcweir class ThesDummy_Impl :
477*cdf0e10cSrcweir     public cppu::WeakImplHelper1< XThesaurus >
478*cdf0e10cSrcweir {
479*cdf0e10cSrcweir     uno::Reference< XThesaurus >     xThes;      // the real one...
480*cdf0e10cSrcweir     Sequence< Locale >         *pLocaleSeq;
481*cdf0e10cSrcweir 
482*cdf0e10cSrcweir     void GetCfgLocales();
483*cdf0e10cSrcweir 
484*cdf0e10cSrcweir     void GetThes_Impl();
485*cdf0e10cSrcweir 
486*cdf0e10cSrcweir public:
487*cdf0e10cSrcweir     ThesDummy_Impl() : pLocaleSeq(0)  {}
488*cdf0e10cSrcweir     ~ThesDummy_Impl();
489*cdf0e10cSrcweir 
490*cdf0e10cSrcweir     // XSupportedLocales
491*cdf0e10cSrcweir     virtual ::com::sun::star::uno::Sequence<
492*cdf0e10cSrcweir 			::com::sun::star::lang::Locale > SAL_CALL
493*cdf0e10cSrcweir 		getLocales()
494*cdf0e10cSrcweir 			throw(::com::sun::star::uno::RuntimeException);
495*cdf0e10cSrcweir     virtual sal_Bool SAL_CALL
496*cdf0e10cSrcweir         hasLocale( const ::com::sun::star::lang::Locale& rLocale )
497*cdf0e10cSrcweir 			throw(::com::sun::star::uno::RuntimeException);
498*cdf0e10cSrcweir 
499*cdf0e10cSrcweir 	// XThesaurus
500*cdf0e10cSrcweir     virtual ::com::sun::star::uno::Sequence<
501*cdf0e10cSrcweir 			::com::sun::star::uno::Reference<
502*cdf0e10cSrcweir 				::com::sun::star::linguistic2::XMeaning > > SAL_CALL
503*cdf0e10cSrcweir         queryMeanings( const ::rtl::OUString& rTerm,
504*cdf0e10cSrcweir                 const ::com::sun::star::lang::Locale& rLocale,
505*cdf0e10cSrcweir                 const ::com::sun::star::beans::PropertyValues& rProperties )
506*cdf0e10cSrcweir 			throw(::com::sun::star::lang::IllegalArgumentException,
507*cdf0e10cSrcweir 				  ::com::sun::star::uno::RuntimeException);
508*cdf0e10cSrcweir };
509*cdf0e10cSrcweir 
510*cdf0e10cSrcweir 
511*cdf0e10cSrcweir ThesDummy_Impl::~ThesDummy_Impl()
512*cdf0e10cSrcweir {
513*cdf0e10cSrcweir     delete pLocaleSeq;
514*cdf0e10cSrcweir }
515*cdf0e10cSrcweir 
516*cdf0e10cSrcweir 
517*cdf0e10cSrcweir void ThesDummy_Impl::GetCfgLocales()
518*cdf0e10cSrcweir {
519*cdf0e10cSrcweir     if (!pLocaleSeq)
520*cdf0e10cSrcweir     {
521*cdf0e10cSrcweir         SvtLinguConfig aCfg;
522*cdf0e10cSrcweir         String  aNode( A2OU( "ServiceManager/ThesaurusList" ) );
523*cdf0e10cSrcweir         Sequence < OUString > aNodeNames( aCfg.GetNodeNames( aNode ) );
524*cdf0e10cSrcweir         const OUString *pNodeNames = aNodeNames.getConstArray();
525*cdf0e10cSrcweir         sal_Int32 nLen = aNodeNames.getLength();
526*cdf0e10cSrcweir         pLocaleSeq = new Sequence< Locale >( nLen );
527*cdf0e10cSrcweir         Locale *pLocale = pLocaleSeq->getArray();
528*cdf0e10cSrcweir         for (sal_Int32 i = 0;  i < nLen;  ++i)
529*cdf0e10cSrcweir         {
530*cdf0e10cSrcweir             pLocale[i] = SvxCreateLocale(
531*cdf0e10cSrcweir                             MsLangId::convertIsoStringToLanguage( pNodeNames[i] ) );
532*cdf0e10cSrcweir         }
533*cdf0e10cSrcweir     }
534*cdf0e10cSrcweir }
535*cdf0e10cSrcweir 
536*cdf0e10cSrcweir 
537*cdf0e10cSrcweir void ThesDummy_Impl::GetThes_Impl()
538*cdf0e10cSrcweir {
539*cdf0e10cSrcweir     // update configuration before accessing the service
540*cdf0e10cSrcweir     if (SvxLinguConfigUpdate::IsNeedUpdateAll())
541*cdf0e10cSrcweir         SvxLinguConfigUpdate::UpdateAll();
542*cdf0e10cSrcweir 
543*cdf0e10cSrcweir     if (!xThes.is())
544*cdf0e10cSrcweir     {
545*cdf0e10cSrcweir         uno::Reference< XLinguServiceManager > xLngSvcMgr( GetLngSvcMgr_Impl() );
546*cdf0e10cSrcweir         if (xLngSvcMgr.is())
547*cdf0e10cSrcweir             xThes = xLngSvcMgr->getThesaurus();
548*cdf0e10cSrcweir 
549*cdf0e10cSrcweir         if (xThes.is())
550*cdf0e10cSrcweir         {
551*cdf0e10cSrcweir             // no longer needed...
552*cdf0e10cSrcweir             delete pLocaleSeq;    pLocaleSeq = 0;
553*cdf0e10cSrcweir         }
554*cdf0e10cSrcweir     }
555*cdf0e10cSrcweir }
556*cdf0e10cSrcweir 
557*cdf0e10cSrcweir 
558*cdf0e10cSrcweir uno::Sequence< lang::Locale > SAL_CALL
559*cdf0e10cSrcweir         ThesDummy_Impl::getLocales()
560*cdf0e10cSrcweir             throw(uno::RuntimeException)
561*cdf0e10cSrcweir {
562*cdf0e10cSrcweir     if (!SvxLinguConfigUpdate::IsNeedUpdateAll())   // configuration already update and thus lingu DLL's already loaded ?
563*cdf0e10cSrcweir         GetThes_Impl();
564*cdf0e10cSrcweir     if (xThes.is())
565*cdf0e10cSrcweir         return xThes->getLocales();
566*cdf0e10cSrcweir     else if (!pLocaleSeq)       // if not already loaded save startup time by avoiding loading them now
567*cdf0e10cSrcweir         GetCfgLocales();
568*cdf0e10cSrcweir     return *pLocaleSeq;
569*cdf0e10cSrcweir }
570*cdf0e10cSrcweir 
571*cdf0e10cSrcweir 
572*cdf0e10cSrcweir sal_Bool SAL_CALL
573*cdf0e10cSrcweir         ThesDummy_Impl::hasLocale( const lang::Locale& rLocale )
574*cdf0e10cSrcweir             throw(uno::RuntimeException)
575*cdf0e10cSrcweir {
576*cdf0e10cSrcweir     if (!SvxLinguConfigUpdate::IsNeedUpdateAll())   // configuration already update and thus lingu DLL's already loaded ?
577*cdf0e10cSrcweir         GetThes_Impl();
578*cdf0e10cSrcweir     if (xThes.is())
579*cdf0e10cSrcweir         return xThes->hasLocale( rLocale );
580*cdf0e10cSrcweir     else if (!pLocaleSeq)       // if not already loaded save startup time by avoiding loading them now
581*cdf0e10cSrcweir         GetCfgLocales();
582*cdf0e10cSrcweir         GetCfgLocales();
583*cdf0e10cSrcweir     sal_Bool bFound = sal_False;
584*cdf0e10cSrcweir     sal_Int32 nLen = pLocaleSeq->getLength();
585*cdf0e10cSrcweir     const Locale *pLocale = pLocaleSeq->getConstArray();
586*cdf0e10cSrcweir     const Locale *pEnd = pLocale + nLen;
587*cdf0e10cSrcweir     for ( ;  pLocale < pEnd  &&  !bFound;  ++pLocale)
588*cdf0e10cSrcweir     {
589*cdf0e10cSrcweir         bFound = pLocale->Language == rLocale.Language  &&
590*cdf0e10cSrcweir                  pLocale->Country  == rLocale.Country   &&
591*cdf0e10cSrcweir                  pLocale->Variant  == rLocale.Variant;
592*cdf0e10cSrcweir     }
593*cdf0e10cSrcweir     return bFound;
594*cdf0e10cSrcweir }
595*cdf0e10cSrcweir 
596*cdf0e10cSrcweir 
597*cdf0e10cSrcweir uno::Sequence< uno::Reference< linguistic2::XMeaning > > SAL_CALL
598*cdf0e10cSrcweir         ThesDummy_Impl::queryMeanings(
599*cdf0e10cSrcweir                 const rtl::OUString& rTerm,
600*cdf0e10cSrcweir                 const lang::Locale& rLocale,
601*cdf0e10cSrcweir                 const beans::PropertyValues& rProperties )
602*cdf0e10cSrcweir             throw(lang::IllegalArgumentException,
603*cdf0e10cSrcweir                   uno::RuntimeException)
604*cdf0e10cSrcweir {
605*cdf0e10cSrcweir     GetThes_Impl();
606*cdf0e10cSrcweir     uno::Sequence< uno::Reference< linguistic2::XMeaning > > aRes;
607*cdf0e10cSrcweir     DBG_ASSERT( xThes.is(), "Thesaurus missing" );
608*cdf0e10cSrcweir     if (xThes.is())
609*cdf0e10cSrcweir         aRes = xThes->queryMeanings( rTerm, rLocale, rProperties );
610*cdf0e10cSrcweir     return aRes;
611*cdf0e10cSrcweir }
612*cdf0e10cSrcweir 
613*cdf0e10cSrcweir 
614*cdf0e10cSrcweir ///////////////////////////////////////////////////////////////////////////
615*cdf0e10cSrcweir 
616*cdf0e10cSrcweir 
617*cdf0e10cSrcweir //! Dummy implementation in order to avoid loading of lingu DLL.
618*cdf0e10cSrcweir //! The dummy accesses the real implementation (and thus loading the DLL)
619*cdf0e10cSrcweir //! when it needs to be done only.
620*cdf0e10cSrcweir class SpellDummy_Impl :
621*cdf0e10cSrcweir     public cppu::WeakImplHelper1< XSpellChecker1 >
622*cdf0e10cSrcweir {
623*cdf0e10cSrcweir     uno::Reference< XSpellChecker1 >     xSpell;      // the real one...
624*cdf0e10cSrcweir 
625*cdf0e10cSrcweir     void    GetSpell_Impl();
626*cdf0e10cSrcweir 
627*cdf0e10cSrcweir public:
628*cdf0e10cSrcweir 
629*cdf0e10cSrcweir 	// XSupportedLanguages (for XSpellChecker1)
630*cdf0e10cSrcweir     virtual ::com::sun::star::uno::Sequence< sal_Int16 > SAL_CALL
631*cdf0e10cSrcweir 		getLanguages()
632*cdf0e10cSrcweir 			throw(::com::sun::star::uno::RuntimeException);
633*cdf0e10cSrcweir     virtual sal_Bool SAL_CALL
634*cdf0e10cSrcweir 		hasLanguage( sal_Int16 nLanguage )
635*cdf0e10cSrcweir 			throw(::com::sun::star::uno::RuntimeException);
636*cdf0e10cSrcweir 
637*cdf0e10cSrcweir 	// XSpellChecker1 (same as XSpellChecker but sal_Int16 for language)
638*cdf0e10cSrcweir 	virtual sal_Bool SAL_CALL
639*cdf0e10cSrcweir         isValid( const ::rtl::OUString& rWord, sal_Int16 nLanguage,
640*cdf0e10cSrcweir                 const ::com::sun::star::beans::PropertyValues& rProperties )
641*cdf0e10cSrcweir 			throw(::com::sun::star::lang::IllegalArgumentException,
642*cdf0e10cSrcweir 				  ::com::sun::star::uno::RuntimeException);
643*cdf0e10cSrcweir 	virtual ::com::sun::star::uno::Reference<
644*cdf0e10cSrcweir 			::com::sun::star::linguistic2::XSpellAlternatives > SAL_CALL
645*cdf0e10cSrcweir         spell( const ::rtl::OUString& rWord, sal_Int16 nLanguage,
646*cdf0e10cSrcweir                 const ::com::sun::star::beans::PropertyValues& rProperties )
647*cdf0e10cSrcweir 			throw(::com::sun::star::lang::IllegalArgumentException,
648*cdf0e10cSrcweir 				  ::com::sun::star::uno::RuntimeException);
649*cdf0e10cSrcweir };
650*cdf0e10cSrcweir 
651*cdf0e10cSrcweir 
652*cdf0e10cSrcweir void SpellDummy_Impl::GetSpell_Impl()
653*cdf0e10cSrcweir {
654*cdf0e10cSrcweir     // update configuration before accessing the service
655*cdf0e10cSrcweir     if (SvxLinguConfigUpdate::IsNeedUpdateAll())
656*cdf0e10cSrcweir         SvxLinguConfigUpdate::UpdateAll();
657*cdf0e10cSrcweir 
658*cdf0e10cSrcweir     if (!xSpell.is())
659*cdf0e10cSrcweir     {
660*cdf0e10cSrcweir         uno::Reference< XLinguServiceManager > xLngSvcMgr( GetLngSvcMgr_Impl() );
661*cdf0e10cSrcweir         if (xLngSvcMgr.is())
662*cdf0e10cSrcweir             xSpell = uno::Reference< XSpellChecker1 >( xLngSvcMgr->getSpellChecker(), UNO_QUERY );
663*cdf0e10cSrcweir     }
664*cdf0e10cSrcweir }
665*cdf0e10cSrcweir 
666*cdf0e10cSrcweir 
667*cdf0e10cSrcweir uno::Sequence< sal_Int16 > SAL_CALL
668*cdf0e10cSrcweir     SpellDummy_Impl::getLanguages()
669*cdf0e10cSrcweir         throw(uno::RuntimeException)
670*cdf0e10cSrcweir {
671*cdf0e10cSrcweir     GetSpell_Impl();
672*cdf0e10cSrcweir     if (xSpell.is())
673*cdf0e10cSrcweir         return xSpell->getLanguages();
674*cdf0e10cSrcweir     else
675*cdf0e10cSrcweir         return uno::Sequence< sal_Int16 >();
676*cdf0e10cSrcweir }
677*cdf0e10cSrcweir 
678*cdf0e10cSrcweir 
679*cdf0e10cSrcweir sal_Bool SAL_CALL
680*cdf0e10cSrcweir     SpellDummy_Impl::hasLanguage( sal_Int16 nLanguage )
681*cdf0e10cSrcweir         throw(uno::RuntimeException)
682*cdf0e10cSrcweir {
683*cdf0e10cSrcweir     GetSpell_Impl();
684*cdf0e10cSrcweir     sal_Bool bRes = sal_False;
685*cdf0e10cSrcweir     if (xSpell.is())
686*cdf0e10cSrcweir         bRes = xSpell->hasLanguage( nLanguage );
687*cdf0e10cSrcweir     return bRes;
688*cdf0e10cSrcweir }
689*cdf0e10cSrcweir 
690*cdf0e10cSrcweir 
691*cdf0e10cSrcweir sal_Bool SAL_CALL
692*cdf0e10cSrcweir     SpellDummy_Impl::isValid( const rtl::OUString& rWord, sal_Int16 nLanguage,
693*cdf0e10cSrcweir             const beans::PropertyValues& rProperties )
694*cdf0e10cSrcweir         throw(lang::IllegalArgumentException,
695*cdf0e10cSrcweir               uno::RuntimeException)
696*cdf0e10cSrcweir {
697*cdf0e10cSrcweir     GetSpell_Impl();
698*cdf0e10cSrcweir     sal_Bool bRes = sal_True;
699*cdf0e10cSrcweir     if (xSpell.is())
700*cdf0e10cSrcweir         bRes = xSpell->isValid( rWord, nLanguage, rProperties );
701*cdf0e10cSrcweir     return bRes;
702*cdf0e10cSrcweir }
703*cdf0e10cSrcweir 
704*cdf0e10cSrcweir 
705*cdf0e10cSrcweir uno::Reference< linguistic2::XSpellAlternatives > SAL_CALL
706*cdf0e10cSrcweir     SpellDummy_Impl::spell( const rtl::OUString& rWord, sal_Int16 nLanguage,
707*cdf0e10cSrcweir             const beans::PropertyValues& rProperties )
708*cdf0e10cSrcweir         throw(lang::IllegalArgumentException,
709*cdf0e10cSrcweir               uno::RuntimeException)
710*cdf0e10cSrcweir {
711*cdf0e10cSrcweir     GetSpell_Impl();
712*cdf0e10cSrcweir     uno::Reference< linguistic2::XSpellAlternatives > xRes;
713*cdf0e10cSrcweir     if (xSpell.is())
714*cdf0e10cSrcweir         xRes = xSpell->spell( rWord, nLanguage, rProperties );
715*cdf0e10cSrcweir     return xRes;
716*cdf0e10cSrcweir }
717*cdf0e10cSrcweir 
718*cdf0e10cSrcweir 
719*cdf0e10cSrcweir ///////////////////////////////////////////////////////////////////////////
720*cdf0e10cSrcweir 
721*cdf0e10cSrcweir 
722*cdf0e10cSrcweir //! Dummy implementation in order to avoid loading of lingu DLL.
723*cdf0e10cSrcweir //! The dummy accesses the real implementation (and thus loading the DLL)
724*cdf0e10cSrcweir //! when it needs to be done only.
725*cdf0e10cSrcweir class HyphDummy_Impl :
726*cdf0e10cSrcweir     public cppu::WeakImplHelper1< XHyphenator >
727*cdf0e10cSrcweir {
728*cdf0e10cSrcweir     uno::Reference< XHyphenator >     xHyph;      // the real one...
729*cdf0e10cSrcweir 
730*cdf0e10cSrcweir     void    GetHyph_Impl();
731*cdf0e10cSrcweir 
732*cdf0e10cSrcweir public:
733*cdf0e10cSrcweir 
734*cdf0e10cSrcweir     // XSupportedLocales
735*cdf0e10cSrcweir     virtual ::com::sun::star::uno::Sequence<
736*cdf0e10cSrcweir 			::com::sun::star::lang::Locale > SAL_CALL
737*cdf0e10cSrcweir 		getLocales()
738*cdf0e10cSrcweir 			throw(::com::sun::star::uno::RuntimeException);
739*cdf0e10cSrcweir     virtual sal_Bool SAL_CALL
740*cdf0e10cSrcweir         hasLocale( const ::com::sun::star::lang::Locale& rLocale )
741*cdf0e10cSrcweir 			throw(::com::sun::star::uno::RuntimeException);
742*cdf0e10cSrcweir 
743*cdf0e10cSrcweir     // XHyphenator
744*cdf0e10cSrcweir     virtual ::com::sun::star::uno::Reference<
745*cdf0e10cSrcweir 			::com::sun::star::linguistic2::XHyphenatedWord > SAL_CALL
746*cdf0e10cSrcweir         hyphenate( const ::rtl::OUString& rWord,
747*cdf0e10cSrcweir                 const ::com::sun::star::lang::Locale& rLocale,
748*cdf0e10cSrcweir 				sal_Int16 nMaxLeading,
749*cdf0e10cSrcweir                 const ::com::sun::star::beans::PropertyValues& rProperties )
750*cdf0e10cSrcweir 			throw(::com::sun::star::lang::IllegalArgumentException,
751*cdf0e10cSrcweir 				  ::com::sun::star::uno::RuntimeException);
752*cdf0e10cSrcweir     virtual ::com::sun::star::uno::Reference<
753*cdf0e10cSrcweir 			::com::sun::star::linguistic2::XHyphenatedWord > SAL_CALL
754*cdf0e10cSrcweir         queryAlternativeSpelling( const ::rtl::OUString& rWord,
755*cdf0e10cSrcweir                 const ::com::sun::star::lang::Locale& rLocale,
756*cdf0e10cSrcweir 				sal_Int16 nIndex,
757*cdf0e10cSrcweir                 const ::com::sun::star::beans::PropertyValues& rProperties )
758*cdf0e10cSrcweir 			throw(::com::sun::star::lang::IllegalArgumentException,
759*cdf0e10cSrcweir 				  ::com::sun::star::uno::RuntimeException);
760*cdf0e10cSrcweir     virtual ::com::sun::star::uno::Reference<
761*cdf0e10cSrcweir 			::com::sun::star::linguistic2::XPossibleHyphens > SAL_CALL
762*cdf0e10cSrcweir 		createPossibleHyphens(
763*cdf0e10cSrcweir                 const ::rtl::OUString& rWord,
764*cdf0e10cSrcweir                 const ::com::sun::star::lang::Locale& rLocale,
765*cdf0e10cSrcweir                 const ::com::sun::star::beans::PropertyValues& rProperties )
766*cdf0e10cSrcweir 			throw(::com::sun::star::lang::IllegalArgumentException,
767*cdf0e10cSrcweir 				  ::com::sun::star::uno::RuntimeException);
768*cdf0e10cSrcweir };
769*cdf0e10cSrcweir 
770*cdf0e10cSrcweir 
771*cdf0e10cSrcweir void HyphDummy_Impl::GetHyph_Impl()
772*cdf0e10cSrcweir {
773*cdf0e10cSrcweir     // update configuration before accessing the service
774*cdf0e10cSrcweir     if (SvxLinguConfigUpdate::IsNeedUpdateAll())
775*cdf0e10cSrcweir         SvxLinguConfigUpdate::UpdateAll();
776*cdf0e10cSrcweir 
777*cdf0e10cSrcweir     if (!xHyph.is())
778*cdf0e10cSrcweir     {
779*cdf0e10cSrcweir         uno::Reference< XLinguServiceManager > xLngSvcMgr( GetLngSvcMgr_Impl() );
780*cdf0e10cSrcweir         if (xLngSvcMgr.is())
781*cdf0e10cSrcweir             xHyph = xLngSvcMgr->getHyphenator();
782*cdf0e10cSrcweir     }
783*cdf0e10cSrcweir }
784*cdf0e10cSrcweir 
785*cdf0e10cSrcweir 
786*cdf0e10cSrcweir uno::Sequence< lang::Locale > SAL_CALL
787*cdf0e10cSrcweir     HyphDummy_Impl::getLocales()
788*cdf0e10cSrcweir         throw(uno::RuntimeException)
789*cdf0e10cSrcweir {
790*cdf0e10cSrcweir     GetHyph_Impl();
791*cdf0e10cSrcweir     if (xHyph.is())
792*cdf0e10cSrcweir         return xHyph->getLocales();
793*cdf0e10cSrcweir     else
794*cdf0e10cSrcweir         return uno::Sequence< lang::Locale >();
795*cdf0e10cSrcweir }
796*cdf0e10cSrcweir 
797*cdf0e10cSrcweir 
798*cdf0e10cSrcweir sal_Bool SAL_CALL
799*cdf0e10cSrcweir     HyphDummy_Impl::hasLocale( const lang::Locale& rLocale )
800*cdf0e10cSrcweir         throw(uno::RuntimeException)
801*cdf0e10cSrcweir {
802*cdf0e10cSrcweir     GetHyph_Impl();
803*cdf0e10cSrcweir     sal_Bool bRes = sal_False;
804*cdf0e10cSrcweir     if (xHyph.is())
805*cdf0e10cSrcweir         bRes = xHyph->hasLocale( rLocale );
806*cdf0e10cSrcweir     return bRes;
807*cdf0e10cSrcweir }
808*cdf0e10cSrcweir 
809*cdf0e10cSrcweir 
810*cdf0e10cSrcweir uno::Reference< linguistic2::XHyphenatedWord > SAL_CALL
811*cdf0e10cSrcweir     HyphDummy_Impl::hyphenate(
812*cdf0e10cSrcweir             const rtl::OUString& rWord,
813*cdf0e10cSrcweir             const lang::Locale& rLocale,
814*cdf0e10cSrcweir             sal_Int16 nMaxLeading,
815*cdf0e10cSrcweir             const beans::PropertyValues& rProperties )
816*cdf0e10cSrcweir         throw(lang::IllegalArgumentException,
817*cdf0e10cSrcweir               uno::RuntimeException)
818*cdf0e10cSrcweir {
819*cdf0e10cSrcweir     GetHyph_Impl();
820*cdf0e10cSrcweir     uno::Reference< linguistic2::XHyphenatedWord > xRes;
821*cdf0e10cSrcweir     if (xHyph.is())
822*cdf0e10cSrcweir         xRes = xHyph->hyphenate( rWord, rLocale, nMaxLeading, rProperties );
823*cdf0e10cSrcweir     return xRes;
824*cdf0e10cSrcweir }
825*cdf0e10cSrcweir 
826*cdf0e10cSrcweir 
827*cdf0e10cSrcweir uno::Reference< linguistic2::XHyphenatedWord > SAL_CALL
828*cdf0e10cSrcweir     HyphDummy_Impl::queryAlternativeSpelling(
829*cdf0e10cSrcweir             const rtl::OUString& rWord,
830*cdf0e10cSrcweir             const lang::Locale& rLocale,
831*cdf0e10cSrcweir             sal_Int16 nIndex,
832*cdf0e10cSrcweir             const PropertyValues& rProperties )
833*cdf0e10cSrcweir         throw(lang::IllegalArgumentException,
834*cdf0e10cSrcweir               uno::RuntimeException)
835*cdf0e10cSrcweir {
836*cdf0e10cSrcweir     GetHyph_Impl();
837*cdf0e10cSrcweir     uno::Reference< linguistic2::XHyphenatedWord > xRes;
838*cdf0e10cSrcweir     if (xHyph.is())
839*cdf0e10cSrcweir         xRes = xHyph->queryAlternativeSpelling( rWord, rLocale, nIndex, rProperties );
840*cdf0e10cSrcweir     return xRes;
841*cdf0e10cSrcweir }
842*cdf0e10cSrcweir 
843*cdf0e10cSrcweir 
844*cdf0e10cSrcweir uno::Reference< linguistic2::XPossibleHyphens > SAL_CALL
845*cdf0e10cSrcweir     HyphDummy_Impl::createPossibleHyphens(
846*cdf0e10cSrcweir             const rtl::OUString& rWord,
847*cdf0e10cSrcweir             const lang::Locale& rLocale,
848*cdf0e10cSrcweir             const beans::PropertyValues& rProperties )
849*cdf0e10cSrcweir         throw(lang::IllegalArgumentException,
850*cdf0e10cSrcweir               uno::RuntimeException)
851*cdf0e10cSrcweir {
852*cdf0e10cSrcweir     GetHyph_Impl();
853*cdf0e10cSrcweir     uno::Reference< linguistic2::XPossibleHyphens > xRes;
854*cdf0e10cSrcweir     if (xHyph.is())
855*cdf0e10cSrcweir         xRes = xHyph->createPossibleHyphens( rWord, rLocale, rProperties );
856*cdf0e10cSrcweir     return xRes;
857*cdf0e10cSrcweir }
858*cdf0e10cSrcweir 
859*cdf0e10cSrcweir 
860*cdf0e10cSrcweir ///////////////////////////////////////////////////////////////////////////
861*cdf0e10cSrcweir 
862*cdf0e10cSrcweir 
863*cdf0e10cSrcweir typedef cppu::WeakImplHelper1 < XEventListener > LinguMgrAppExitLstnrBaseClass;
864*cdf0e10cSrcweir 
865*cdf0e10cSrcweir class LinguMgrAppExitLstnr : public LinguMgrAppExitLstnrBaseClass
866*cdf0e10cSrcweir {
867*cdf0e10cSrcweir 	uno::Reference< XComponent > 		xDesktop;
868*cdf0e10cSrcweir 
869*cdf0e10cSrcweir public:
870*cdf0e10cSrcweir 	LinguMgrAppExitLstnr();
871*cdf0e10cSrcweir 	virtual ~LinguMgrAppExitLstnr();
872*cdf0e10cSrcweir 
873*cdf0e10cSrcweir 	virtual	void	AtExit() = 0;
874*cdf0e10cSrcweir 
875*cdf0e10cSrcweir 
876*cdf0e10cSrcweir 	// lang::XEventListener
877*cdf0e10cSrcweir     virtual void 	SAL_CALL disposing(const EventObject& rSource)
878*cdf0e10cSrcweir 			throw( RuntimeException );
879*cdf0e10cSrcweir };
880*cdf0e10cSrcweir 
881*cdf0e10cSrcweir LinguMgrAppExitLstnr::LinguMgrAppExitLstnr()
882*cdf0e10cSrcweir {
883*cdf0e10cSrcweir 	// add object to frame::Desktop EventListeners in order to properly call
884*cdf0e10cSrcweir 	// the AtExit function at appliction exit.
885*cdf0e10cSrcweir 
886*cdf0e10cSrcweir 	uno::Reference< XMultiServiceFactory >  xMgr = getProcessServiceFactory();
887*cdf0e10cSrcweir 	if ( xMgr.is() )
888*cdf0e10cSrcweir 	{
889*cdf0e10cSrcweir 		xDesktop = uno::Reference< XComponent > ( xMgr->createInstance(
890*cdf0e10cSrcweir 				OUString( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.frame.Desktop" ) ) ), UNO_QUERY ) ;
891*cdf0e10cSrcweir 		if (xDesktop.is())
892*cdf0e10cSrcweir 			xDesktop->addEventListener( this );
893*cdf0e10cSrcweir 	}
894*cdf0e10cSrcweir }
895*cdf0e10cSrcweir 
896*cdf0e10cSrcweir LinguMgrAppExitLstnr::~LinguMgrAppExitLstnr()
897*cdf0e10cSrcweir {
898*cdf0e10cSrcweir 	if (xDesktop.is())
899*cdf0e10cSrcweir 	{
900*cdf0e10cSrcweir 		xDesktop->removeEventListener( this );
901*cdf0e10cSrcweir 		xDesktop = NULL;	//! release reference to desktop
902*cdf0e10cSrcweir 	}
903*cdf0e10cSrcweir 	DBG_ASSERT(!xDesktop.is(), "reference to desktop should be realeased");
904*cdf0e10cSrcweir }
905*cdf0e10cSrcweir 
906*cdf0e10cSrcweir void LinguMgrAppExitLstnr::disposing(const EventObject& rSource)
907*cdf0e10cSrcweir 		throw( RuntimeException )
908*cdf0e10cSrcweir {
909*cdf0e10cSrcweir 	if (xDesktop.is()  &&  rSource.Source == xDesktop)
910*cdf0e10cSrcweir 	{
911*cdf0e10cSrcweir 		xDesktop->removeEventListener( this );
912*cdf0e10cSrcweir 		xDesktop = NULL;	//! release reference to desktop
913*cdf0e10cSrcweir 
914*cdf0e10cSrcweir 		AtExit();
915*cdf0e10cSrcweir 	}
916*cdf0e10cSrcweir }
917*cdf0e10cSrcweir 
918*cdf0e10cSrcweir ///////////////////////////////////////////////////////////////////////////
919*cdf0e10cSrcweir 
920*cdf0e10cSrcweir class LinguMgrExitLstnr : public LinguMgrAppExitLstnr
921*cdf0e10cSrcweir {
922*cdf0e10cSrcweir public:
923*cdf0e10cSrcweir 	virtual	void	AtExit();
924*cdf0e10cSrcweir };
925*cdf0e10cSrcweir 
926*cdf0e10cSrcweir void LinguMgrExitLstnr::AtExit()
927*cdf0e10cSrcweir {
928*cdf0e10cSrcweir 	// release references
929*cdf0e10cSrcweir 	LinguMgr::xLngSvcMgr	= 0;
930*cdf0e10cSrcweir 	LinguMgr::xSpell		= 0;
931*cdf0e10cSrcweir 	LinguMgr::xHyph			= 0;
932*cdf0e10cSrcweir 	LinguMgr::xThes			= 0;
933*cdf0e10cSrcweir 	LinguMgr::xDicList		= 0;
934*cdf0e10cSrcweir 	LinguMgr::xProp			= 0;
935*cdf0e10cSrcweir 	LinguMgr::xIgnoreAll	= 0;
936*cdf0e10cSrcweir 	LinguMgr::xChangeAll	= 0;
937*cdf0e10cSrcweir 
938*cdf0e10cSrcweir 	LinguMgr::bExiting		= sal_True;
939*cdf0e10cSrcweir 
940*cdf0e10cSrcweir 	//TL:TODO: MBA fragen wie ich ohne Absturz hier meinen Speicher
941*cdf0e10cSrcweir 	//  wieder freibekomme...
942*cdf0e10cSrcweir 	//delete LinguMgr::pExitLstnr;
943*cdf0e10cSrcweir 	LinguMgr::pExitLstnr	= 0;
944*cdf0e10cSrcweir }
945*cdf0e10cSrcweir 
946*cdf0e10cSrcweir ///////////////////////////////////////////////////////////////////////////
947*cdf0e10cSrcweir 
948*cdf0e10cSrcweir 
949*cdf0e10cSrcweir // static member initialization
950*cdf0e10cSrcweir LinguMgrExitLstnr * 			LinguMgr::pExitLstnr	= 0;
951*cdf0e10cSrcweir sal_Bool						LinguMgr::bExiting		= sal_False;
952*cdf0e10cSrcweir uno::Reference< XLinguServiceManager >	LinguMgr::xLngSvcMgr	= 0;
953*cdf0e10cSrcweir uno::Reference< XSpellChecker1 > 	LinguMgr::xSpell		= 0;
954*cdf0e10cSrcweir uno::Reference< XHyphenator > 		LinguMgr::xHyph			= 0;
955*cdf0e10cSrcweir uno::Reference< XThesaurus > 		LinguMgr::xThes			= 0;
956*cdf0e10cSrcweir uno::Reference< XDictionaryList > 	LinguMgr::xDicList		= 0;
957*cdf0e10cSrcweir uno::Reference< XPropertySet > 		LinguMgr::xProp			= 0;
958*cdf0e10cSrcweir uno::Reference< XDictionary >       LinguMgr::xIgnoreAll    = 0;
959*cdf0e10cSrcweir uno::Reference< XDictionary >       LinguMgr::xChangeAll    = 0;
960*cdf0e10cSrcweir 
961*cdf0e10cSrcweir 
962*cdf0e10cSrcweir uno::Reference< XLinguServiceManager > LinguMgr::GetLngSvcMgr()
963*cdf0e10cSrcweir {
964*cdf0e10cSrcweir 	if (bExiting)
965*cdf0e10cSrcweir 		return 0;
966*cdf0e10cSrcweir 
967*cdf0e10cSrcweir 	if (!pExitLstnr)
968*cdf0e10cSrcweir 		pExitLstnr = new LinguMgrExitLstnr;
969*cdf0e10cSrcweir 
970*cdf0e10cSrcweir 	if (!xLngSvcMgr.is())
971*cdf0e10cSrcweir 		xLngSvcMgr = GetLngSvcMgr_Impl();
972*cdf0e10cSrcweir 
973*cdf0e10cSrcweir 	return xLngSvcMgr;
974*cdf0e10cSrcweir }
975*cdf0e10cSrcweir 
976*cdf0e10cSrcweir 
977*cdf0e10cSrcweir uno::Reference< XSpellChecker1 > LinguMgr::GetSpellChecker()
978*cdf0e10cSrcweir {
979*cdf0e10cSrcweir 	return xSpell.is() ? xSpell : GetSpell();
980*cdf0e10cSrcweir }
981*cdf0e10cSrcweir 
982*cdf0e10cSrcweir uno::Reference< XHyphenator > LinguMgr::GetHyphenator()
983*cdf0e10cSrcweir {
984*cdf0e10cSrcweir 	return xHyph.is() ? xHyph : GetHyph();
985*cdf0e10cSrcweir }
986*cdf0e10cSrcweir 
987*cdf0e10cSrcweir uno::Reference< XThesaurus > LinguMgr::GetThesaurus()
988*cdf0e10cSrcweir {
989*cdf0e10cSrcweir 	return xThes.is() ? xThes : GetThes();
990*cdf0e10cSrcweir }
991*cdf0e10cSrcweir 
992*cdf0e10cSrcweir uno::Reference< XDictionaryList > LinguMgr::GetDictionaryList()
993*cdf0e10cSrcweir {
994*cdf0e10cSrcweir 	return xDicList.is() ? xDicList : GetDicList();
995*cdf0e10cSrcweir }
996*cdf0e10cSrcweir 
997*cdf0e10cSrcweir uno::Reference< XPropertySet > LinguMgr::GetLinguPropertySet()
998*cdf0e10cSrcweir {
999*cdf0e10cSrcweir 	return xProp.is() ? xProp : GetProp();
1000*cdf0e10cSrcweir }
1001*cdf0e10cSrcweir 
1002*cdf0e10cSrcweir uno::Reference< XDictionary > LinguMgr::GetStandardDic()
1003*cdf0e10cSrcweir {
1004*cdf0e10cSrcweir 	//! don't hold reference to this
1005*cdf0e10cSrcweir 	//! (it may be removed from dictionary list and needs to be
1006*cdf0e10cSrcweir 	//! created empty if accessed again)
1007*cdf0e10cSrcweir 	return GetStandard();
1008*cdf0e10cSrcweir }
1009*cdf0e10cSrcweir 
1010*cdf0e10cSrcweir uno::Reference< XDictionary > LinguMgr::GetIgnoreAllList()
1011*cdf0e10cSrcweir {
1012*cdf0e10cSrcweir 	return xIgnoreAll.is() ? xIgnoreAll : GetIgnoreAll();
1013*cdf0e10cSrcweir }
1014*cdf0e10cSrcweir 
1015*cdf0e10cSrcweir uno::Reference< XDictionary > LinguMgr::GetChangeAllList()
1016*cdf0e10cSrcweir {
1017*cdf0e10cSrcweir 	return xChangeAll.is() ? xChangeAll : GetChangeAll();
1018*cdf0e10cSrcweir }
1019*cdf0e10cSrcweir 
1020*cdf0e10cSrcweir uno::Reference< XSpellChecker1 > LinguMgr::GetSpell()
1021*cdf0e10cSrcweir {
1022*cdf0e10cSrcweir 	if (bExiting)
1023*cdf0e10cSrcweir 		return 0;
1024*cdf0e10cSrcweir 
1025*cdf0e10cSrcweir 	if (!pExitLstnr)
1026*cdf0e10cSrcweir 		pExitLstnr = new LinguMgrExitLstnr;
1027*cdf0e10cSrcweir 
1028*cdf0e10cSrcweir     //! use dummy implementation in order to avoid loading of lingu DLL
1029*cdf0e10cSrcweir     xSpell = new SpellDummy_Impl;
1030*cdf0e10cSrcweir 
1031*cdf0e10cSrcweir /*    if (!xLngSvcMgr.is())
1032*cdf0e10cSrcweir 		xLngSvcMgr = GetLngSvcMgr_Impl();
1033*cdf0e10cSrcweir 
1034*cdf0e10cSrcweir 	if (xLngSvcMgr.is())
1035*cdf0e10cSrcweir 	{
1036*cdf0e10cSrcweir 		xSpell = uno::Reference< XSpellChecker1 > (
1037*cdf0e10cSrcweir 						xLngSvcMgr->getSpellChecker(), UNO_QUERY );
1038*cdf0e10cSrcweir 	}
1039*cdf0e10cSrcweir */
1040*cdf0e10cSrcweir 	return xSpell;
1041*cdf0e10cSrcweir }
1042*cdf0e10cSrcweir 
1043*cdf0e10cSrcweir uno::Reference< XHyphenator > LinguMgr::GetHyph()
1044*cdf0e10cSrcweir {
1045*cdf0e10cSrcweir 	if (bExiting)
1046*cdf0e10cSrcweir 		return 0;
1047*cdf0e10cSrcweir 
1048*cdf0e10cSrcweir 	if (!pExitLstnr)
1049*cdf0e10cSrcweir 		pExitLstnr = new LinguMgrExitLstnr;
1050*cdf0e10cSrcweir 
1051*cdf0e10cSrcweir     //! use dummy implementation in order to avoid loading of lingu DLL
1052*cdf0e10cSrcweir     xHyph = new HyphDummy_Impl;
1053*cdf0e10cSrcweir 
1054*cdf0e10cSrcweir /*
1055*cdf0e10cSrcweir 	if (!xLngSvcMgr.is())
1056*cdf0e10cSrcweir 		xLngSvcMgr = GetLngSvcMgr_Impl();
1057*cdf0e10cSrcweir 
1058*cdf0e10cSrcweir 	if (xLngSvcMgr.is())
1059*cdf0e10cSrcweir 	{
1060*cdf0e10cSrcweir 		xHyph = xLngSvcMgr->getHyphenator();
1061*cdf0e10cSrcweir 	}
1062*cdf0e10cSrcweir */
1063*cdf0e10cSrcweir 	return xHyph;
1064*cdf0e10cSrcweir }
1065*cdf0e10cSrcweir 
1066*cdf0e10cSrcweir uno::Reference< XThesaurus > LinguMgr::GetThes()
1067*cdf0e10cSrcweir {
1068*cdf0e10cSrcweir 	if (bExiting)
1069*cdf0e10cSrcweir 		return 0;
1070*cdf0e10cSrcweir 
1071*cdf0e10cSrcweir 	if (!pExitLstnr)
1072*cdf0e10cSrcweir 		pExitLstnr = new LinguMgrExitLstnr;
1073*cdf0e10cSrcweir 
1074*cdf0e10cSrcweir     //! use dummy implementation in order to avoid loading of lingu DLL
1075*cdf0e10cSrcweir     //! when only the XSupportedLocales interface is used.
1076*cdf0e10cSrcweir     //! The dummy accesses the real implementation (and thus loading the DLL)
1077*cdf0e10cSrcweir     //! when "real" work needs to be done only.
1078*cdf0e10cSrcweir     xThes = new ThesDummy_Impl;
1079*cdf0e10cSrcweir /*
1080*cdf0e10cSrcweir 	if (!xLngSvcMgr.is())
1081*cdf0e10cSrcweir 		xLngSvcMgr = GetLngSvcMgr_Impl();
1082*cdf0e10cSrcweir 
1083*cdf0e10cSrcweir 	if (xLngSvcMgr.is())
1084*cdf0e10cSrcweir 	{
1085*cdf0e10cSrcweir 		xThes = xLngSvcMgr->getThesaurus();
1086*cdf0e10cSrcweir 	}
1087*cdf0e10cSrcweir */
1088*cdf0e10cSrcweir 	return xThes;
1089*cdf0e10cSrcweir }
1090*cdf0e10cSrcweir 
1091*cdf0e10cSrcweir 
1092*cdf0e10cSrcweir void LinguMgr::UpdateAll()
1093*cdf0e10cSrcweir {
1094*cdf0e10cSrcweir }
1095*cdf0e10cSrcweir 
1096*cdf0e10cSrcweir 
1097*cdf0e10cSrcweir uno::Reference< XDictionaryList > LinguMgr::GetDicList()
1098*cdf0e10cSrcweir {
1099*cdf0e10cSrcweir 	if (bExiting)
1100*cdf0e10cSrcweir 		return 0;
1101*cdf0e10cSrcweir 
1102*cdf0e10cSrcweir 	if (!pExitLstnr)
1103*cdf0e10cSrcweir 		pExitLstnr = new LinguMgrExitLstnr;
1104*cdf0e10cSrcweir 
1105*cdf0e10cSrcweir 	uno::Reference< XMultiServiceFactory >  xMgr( getProcessServiceFactory() );
1106*cdf0e10cSrcweir 	if (xMgr.is())
1107*cdf0e10cSrcweir 	{
1108*cdf0e10cSrcweir 		xDicList = uno::Reference< XDictionaryList > ( xMgr->createInstance(
1109*cdf0e10cSrcweir                     A2OU("com.sun.star.linguistic2.DictionaryList") ), UNO_QUERY );
1110*cdf0e10cSrcweir 	}
1111*cdf0e10cSrcweir 	return xDicList;
1112*cdf0e10cSrcweir }
1113*cdf0e10cSrcweir 
1114*cdf0e10cSrcweir uno::Reference< XPropertySet > LinguMgr::GetProp()
1115*cdf0e10cSrcweir {
1116*cdf0e10cSrcweir 	if (bExiting)
1117*cdf0e10cSrcweir 		return 0;
1118*cdf0e10cSrcweir 
1119*cdf0e10cSrcweir 	if (!pExitLstnr)
1120*cdf0e10cSrcweir 		pExitLstnr = new LinguMgrExitLstnr;
1121*cdf0e10cSrcweir 
1122*cdf0e10cSrcweir 	uno::Reference< XMultiServiceFactory >  xMgr( getProcessServiceFactory() );
1123*cdf0e10cSrcweir 	if (xMgr.is())
1124*cdf0e10cSrcweir 	{
1125*cdf0e10cSrcweir 		xProp = uno::Reference< XPropertySet > ( xMgr->createInstance(
1126*cdf0e10cSrcweir                     A2OU("com.sun.star.linguistic2.LinguProperties") ), UNO_QUERY );
1127*cdf0e10cSrcweir 	}
1128*cdf0e10cSrcweir 	return xProp;
1129*cdf0e10cSrcweir }
1130*cdf0e10cSrcweir 
1131*cdf0e10cSrcweir uno::Reference< XDictionary > LinguMgr::GetIgnoreAll()
1132*cdf0e10cSrcweir {
1133*cdf0e10cSrcweir 	if (bExiting)
1134*cdf0e10cSrcweir 		return 0;
1135*cdf0e10cSrcweir 
1136*cdf0e10cSrcweir 	if (!pExitLstnr)
1137*cdf0e10cSrcweir 		pExitLstnr = new LinguMgrExitLstnr;
1138*cdf0e10cSrcweir 
1139*cdf0e10cSrcweir 	uno::Reference< XDictionaryList >  xTmpDicList( GetDictionaryList() );
1140*cdf0e10cSrcweir 	if (xTmpDicList.is())
1141*cdf0e10cSrcweir 	{
1142*cdf0e10cSrcweir         xIgnoreAll = uno::Reference< XDictionary > ( xTmpDicList->getDictionaryByName(
1143*cdf0e10cSrcweir                     A2OU("IgnoreAllList") ), UNO_QUERY );
1144*cdf0e10cSrcweir 	}
1145*cdf0e10cSrcweir 	return xIgnoreAll;
1146*cdf0e10cSrcweir }
1147*cdf0e10cSrcweir 
1148*cdf0e10cSrcweir uno::Reference< XDictionary > LinguMgr::GetChangeAll()
1149*cdf0e10cSrcweir {
1150*cdf0e10cSrcweir 	if (bExiting)
1151*cdf0e10cSrcweir 		return 0;
1152*cdf0e10cSrcweir 
1153*cdf0e10cSrcweir 	if (!pExitLstnr)
1154*cdf0e10cSrcweir 		pExitLstnr = new LinguMgrExitLstnr;
1155*cdf0e10cSrcweir 
1156*cdf0e10cSrcweir 	uno::Reference< XDictionaryList > _xDicList( GetDictionaryList() , UNO_QUERY );
1157*cdf0e10cSrcweir 	if (_xDicList.is())
1158*cdf0e10cSrcweir 	{
1159*cdf0e10cSrcweir         xChangeAll = uno::Reference< XDictionary > (
1160*cdf0e10cSrcweir 						_xDicList->createDictionary(
1161*cdf0e10cSrcweir                             A2OU("ChangeAllList"),
1162*cdf0e10cSrcweir 							SvxCreateLocale( LANGUAGE_NONE ),
1163*cdf0e10cSrcweir 							DictionaryType_NEGATIVE, String() ), UNO_QUERY );
1164*cdf0e10cSrcweir 	}
1165*cdf0e10cSrcweir 	return xChangeAll;
1166*cdf0e10cSrcweir }
1167*cdf0e10cSrcweir 
1168*cdf0e10cSrcweir uno::Reference< XDictionary > LinguMgr::GetStandard()
1169*cdf0e10cSrcweir {
1170*cdf0e10cSrcweir 	// Tries to return a dictionary which may hold positive entries is
1171*cdf0e10cSrcweir 	// persistent and not read-only.
1172*cdf0e10cSrcweir 
1173*cdf0e10cSrcweir 	if (bExiting)
1174*cdf0e10cSrcweir 		return 0;
1175*cdf0e10cSrcweir 
1176*cdf0e10cSrcweir 	uno::Reference< XDictionaryList >  xTmpDicList( GetDictionaryList() );
1177*cdf0e10cSrcweir 	if (!xTmpDicList.is())
1178*cdf0e10cSrcweir 		return NULL;
1179*cdf0e10cSrcweir 
1180*cdf0e10cSrcweir 	const OUString aDicName( RTL_CONSTASCII_USTRINGPARAM( "standard.dic" ) );
1181*cdf0e10cSrcweir     uno::Reference< XDictionary >   xDic( xTmpDicList->getDictionaryByName( aDicName ),
1182*cdf0e10cSrcweir 									  UNO_QUERY );
1183*cdf0e10cSrcweir     if (!xDic.is())
1184*cdf0e10cSrcweir     {
1185*cdf0e10cSrcweir         // try to create standard dictionary
1186*cdf0e10cSrcweir         uno::Reference< XDictionary >    xTmp;
1187*cdf0e10cSrcweir         try
1188*cdf0e10cSrcweir         {
1189*cdf0e10cSrcweir             xTmp =  xTmpDicList->createDictionary( aDicName,
1190*cdf0e10cSrcweir                         SvxCreateLocale( LANGUAGE_NONE ),
1191*cdf0e10cSrcweir                         DictionaryType_POSITIVE,
1192*cdf0e10cSrcweir                         linguistic::GetWritableDictionaryURL( aDicName ) );
1193*cdf0e10cSrcweir         }
1194*cdf0e10cSrcweir         catch(com::sun::star::uno::Exception &)
1195*cdf0e10cSrcweir         {
1196*cdf0e10cSrcweir         }
1197*cdf0e10cSrcweir 
1198*cdf0e10cSrcweir         // add new dictionary to list
1199*cdf0e10cSrcweir         if (xTmp.is())
1200*cdf0e10cSrcweir         {
1201*cdf0e10cSrcweir             xTmpDicList->addDictionary( xTmp );
1202*cdf0e10cSrcweir             xTmp->setActive( sal_True );
1203*cdf0e10cSrcweir         }
1204*cdf0e10cSrcweir         xDic = uno::Reference< XDictionary > ( xTmp, UNO_QUERY );
1205*cdf0e10cSrcweir     }
1206*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
1207*cdf0e10cSrcweir     uno::Reference< XStorable >      xStor( xDic, UNO_QUERY );
1208*cdf0e10cSrcweir     DBG_ASSERT( xDic.is() && xDic->getDictionaryType() == DictionaryType_POSITIVE,
1209*cdf0e10cSrcweir             "wrong dictionary type");
1210*cdf0e10cSrcweir     DBG_ASSERT( xDic.is() && SvxLocaleToLanguage( xDic->getLocale() ) == LANGUAGE_NONE,
1211*cdf0e10cSrcweir             "wrong dictionary language");
1212*cdf0e10cSrcweir     DBG_ASSERT( !xStor.is() || (xStor->hasLocation() && !xStor->isReadonly()),
1213*cdf0e10cSrcweir             "dictionary not editable" );
1214*cdf0e10cSrcweir #endif
1215*cdf0e10cSrcweir 
1216*cdf0e10cSrcweir 	return xDic;
1217*cdf0e10cSrcweir }
1218*cdf0e10cSrcweir 
1219*cdf0e10cSrcweir ///////////////////////////////////////////////////////////////////////////
1220*cdf0e10cSrcweir 
1221*cdf0e10cSrcweir uno::Reference< XSpellChecker1 >  SvxGetSpellChecker()
1222*cdf0e10cSrcweir {
1223*cdf0e10cSrcweir 	return LinguMgr::GetSpellChecker();
1224*cdf0e10cSrcweir }
1225*cdf0e10cSrcweir 
1226*cdf0e10cSrcweir uno::Reference< XHyphenator >  SvxGetHyphenator()
1227*cdf0e10cSrcweir {
1228*cdf0e10cSrcweir 	return LinguMgr::GetHyphenator();
1229*cdf0e10cSrcweir }
1230*cdf0e10cSrcweir 
1231*cdf0e10cSrcweir uno::Reference< XThesaurus >  SvxGetThesaurus()
1232*cdf0e10cSrcweir {
1233*cdf0e10cSrcweir 	return LinguMgr::GetThesaurus();
1234*cdf0e10cSrcweir }
1235*cdf0e10cSrcweir 
1236*cdf0e10cSrcweir uno::Reference< XDictionaryList >  SvxGetDictionaryList()
1237*cdf0e10cSrcweir {
1238*cdf0e10cSrcweir 	return LinguMgr::GetDictionaryList();
1239*cdf0e10cSrcweir }
1240*cdf0e10cSrcweir 
1241*cdf0e10cSrcweir uno::Reference< XPropertySet > 	SvxGetLinguPropertySet()
1242*cdf0e10cSrcweir {
1243*cdf0e10cSrcweir 	return LinguMgr::GetLinguPropertySet();
1244*cdf0e10cSrcweir }
1245*cdf0e10cSrcweir 
1246*cdf0e10cSrcweir //TL:TODO: remove argument or provide SvxGetIgnoreAllList with the same one
1247*cdf0e10cSrcweir uno::Reference< XDictionary >  SvxGetOrCreatePosDic(
1248*cdf0e10cSrcweir 		uno::Reference< XDictionaryList >  /* xDicList */ )
1249*cdf0e10cSrcweir {
1250*cdf0e10cSrcweir 	return LinguMgr::GetStandardDic();
1251*cdf0e10cSrcweir }
1252*cdf0e10cSrcweir 
1253*cdf0e10cSrcweir uno::Reference< XDictionary >  SvxGetIgnoreAllList()
1254*cdf0e10cSrcweir {
1255*cdf0e10cSrcweir 	return LinguMgr::GetIgnoreAllList();
1256*cdf0e10cSrcweir }
1257*cdf0e10cSrcweir 
1258*cdf0e10cSrcweir uno::Reference< XDictionary >  SvxGetChangeAllList()
1259*cdf0e10cSrcweir {
1260*cdf0e10cSrcweir 	return LinguMgr::GetChangeAllList();
1261*cdf0e10cSrcweir }
1262*cdf0e10cSrcweir 
1263*cdf0e10cSrcweir ///////////////////////////////////////////////////////////////////////////
1264*cdf0e10cSrcweir 
1265*cdf0e10cSrcweir 
1266*cdf0e10cSrcweir #include <com/sun/star/linguistic2/XHyphenatedWord.hpp>
1267*cdf0e10cSrcweir 
1268*cdf0e10cSrcweir SvxAlternativeSpelling SvxGetAltSpelling(
1269*cdf0e10cSrcweir 		const ::com::sun::star::uno::Reference<
1270*cdf0e10cSrcweir 			::com::sun::star::linguistic2::XHyphenatedWord > & rHyphWord )
1271*cdf0e10cSrcweir {
1272*cdf0e10cSrcweir 	SvxAlternativeSpelling aRes;
1273*cdf0e10cSrcweir 	if (rHyphWord.is() && rHyphWord->isAlternativeSpelling())
1274*cdf0e10cSrcweir 	{
1275*cdf0e10cSrcweir 		OUString aWord( rHyphWord->getWord() ),
1276*cdf0e10cSrcweir                  aAltWord( rHyphWord->getHyphenatedWord() );
1277*cdf0e10cSrcweir 		sal_Int16	nHyphenationPos		= rHyphWord->getHyphenationPos(),
1278*cdf0e10cSrcweir 				nHyphenPos			= rHyphWord->getHyphenPos();
1279*cdf0e10cSrcweir         sal_Int16   nLen    = (sal_Int16)aWord.getLength();
1280*cdf0e10cSrcweir         sal_Int16   nAltLen = (sal_Int16)aAltWord.getLength();
1281*cdf0e10cSrcweir 		const sal_Unicode *pWord	= aWord.getStr(),
1282*cdf0e10cSrcweir                           *pAltWord = aAltWord.getStr();
1283*cdf0e10cSrcweir 
1284*cdf0e10cSrcweir         // count number of chars from the left to the
1285*cdf0e10cSrcweir         // hyphenation pos / hyphen pos that are equal
1286*cdf0e10cSrcweir         sal_Int16 nL = 0;
1287*cdf0e10cSrcweir         while (nL <= nHyphenationPos && nL <= nHyphenPos
1288*cdf0e10cSrcweir                && pWord[ nL ] == pAltWord[ nL ])
1289*cdf0e10cSrcweir             ++nL;
1290*cdf0e10cSrcweir         // count number of chars from the right to the
1291*cdf0e10cSrcweir         // hyphenation pos / hyphen pos that are equal
1292*cdf0e10cSrcweir         sal_Int16 nR = 0;
1293*cdf0e10cSrcweir         sal_Int32 nIdx    = nLen - 1;
1294*cdf0e10cSrcweir         sal_Int32 nAltIdx = nAltLen - 1;
1295*cdf0e10cSrcweir         while (nIdx > nHyphenationPos && nAltIdx > nHyphenPos
1296*cdf0e10cSrcweir                && pWord[ nIdx-- ] == pAltWord[ nAltIdx-- ])
1297*cdf0e10cSrcweir             ++nR;
1298*cdf0e10cSrcweir 
1299*cdf0e10cSrcweir         aRes.aReplacement       = OUString( aAltWord.copy( nL, nAltLen - nL - nR ) );
1300*cdf0e10cSrcweir         aRes.nChangedPos        = (sal_Int16) nL;
1301*cdf0e10cSrcweir         aRes.nChangedLength     = nLen - nL - nR;
1302*cdf0e10cSrcweir 		aRes.bIsAltSpelling		= sal_True;
1303*cdf0e10cSrcweir 		aRes.xHyphWord			= rHyphWord;
1304*cdf0e10cSrcweir 	}
1305*cdf0e10cSrcweir 	return aRes;
1306*cdf0e10cSrcweir }
1307*cdf0e10cSrcweir 
1308*cdf0e10cSrcweir 
1309*cdf0e10cSrcweir ///////////////////////////////////////////////////////////////////////////
1310*cdf0e10cSrcweir 
1311*cdf0e10cSrcweir SvxDicListChgClamp::SvxDicListChgClamp( uno::Reference< XDictionaryList >  &rxDicList ) :
1312*cdf0e10cSrcweir 	xDicList	( rxDicList )
1313*cdf0e10cSrcweir {
1314*cdf0e10cSrcweir 	if (xDicList.is())
1315*cdf0e10cSrcweir 	{
1316*cdf0e10cSrcweir 		xDicList->beginCollectEvents();
1317*cdf0e10cSrcweir 	}
1318*cdf0e10cSrcweir }
1319*cdf0e10cSrcweir 
1320*cdf0e10cSrcweir SvxDicListChgClamp::~SvxDicListChgClamp()
1321*cdf0e10cSrcweir {
1322*cdf0e10cSrcweir 	if (xDicList.is())
1323*cdf0e10cSrcweir 	{
1324*cdf0e10cSrcweir 		xDicList->endCollectEvents();
1325*cdf0e10cSrcweir 	}
1326*cdf0e10cSrcweir }
1327*cdf0e10cSrcweir 
1328*cdf0e10cSrcweir ///////////////////////////////////////////////////////////////////////////
1329*cdf0e10cSrcweir 
1330*cdf0e10cSrcweir short SvxDicError( Window *pParent, sal_Int16 nError )
1331*cdf0e10cSrcweir {
1332*cdf0e10cSrcweir 	short nRes = 0;
1333*cdf0e10cSrcweir 	if (DIC_ERR_NONE != nError)
1334*cdf0e10cSrcweir 	{
1335*cdf0e10cSrcweir 		int nRid;
1336*cdf0e10cSrcweir 		switch (nError)
1337*cdf0e10cSrcweir 		{
1338*cdf0e10cSrcweir 			case DIC_ERR_FULL	  : nRid = RID_SVXSTR_DIC_ERR_FULL;  break;
1339*cdf0e10cSrcweir 			case DIC_ERR_READONLY : nRid = RID_SVXSTR_DIC_ERR_READONLY;  break;
1340*cdf0e10cSrcweir 			default:
1341*cdf0e10cSrcweir 				nRid = RID_SVXSTR_DIC_ERR_UNKNOWN;
1342*cdf0e10cSrcweir 				DBG_ASSERT(0, "unexpected case");
1343*cdf0e10cSrcweir 		}
1344*cdf0e10cSrcweir 		nRes = InfoBox( pParent, EE_RESSTR( nRid ) ).Execute();
1345*cdf0e10cSrcweir 	}
1346*cdf0e10cSrcweir 	return nRes;
1347*cdf0e10cSrcweir }
1348*cdf0e10cSrcweir 
1349*cdf0e10cSrcweir LanguageType SvxLocaleToLanguage( const Locale& rLocale )
1350*cdf0e10cSrcweir {
1351*cdf0e10cSrcweir 	//	empty Locale -> LANGUAGE_NONE
1352*cdf0e10cSrcweir 	if ( rLocale.Language.getLength() == 0 )
1353*cdf0e10cSrcweir 		return LANGUAGE_NONE;
1354*cdf0e10cSrcweir 
1355*cdf0e10cSrcweir 	return MsLangId::convertLocaleToLanguage( rLocale );
1356*cdf0e10cSrcweir }
1357*cdf0e10cSrcweir 
1358*cdf0e10cSrcweir Locale& SvxLanguageToLocale( Locale& rLocale, LanguageType eLang )
1359*cdf0e10cSrcweir {
1360*cdf0e10cSrcweir 	if ( eLang != LANGUAGE_NONE	/* &&  eLang != LANGUAGE_SYSTEM */)
1361*cdf0e10cSrcweir 		MsLangId::convertLanguageToLocale( eLang, rLocale );
1362*cdf0e10cSrcweir     else
1363*cdf0e10cSrcweir         rLocale = Locale();
1364*cdf0e10cSrcweir 
1365*cdf0e10cSrcweir 	return rLocale;
1366*cdf0e10cSrcweir }
1367*cdf0e10cSrcweir 
1368*cdf0e10cSrcweir Locale SvxCreateLocale( LanguageType eLang )
1369*cdf0e10cSrcweir {
1370*cdf0e10cSrcweir 	Locale aLocale;
1371*cdf0e10cSrcweir 	if ( eLang != LANGUAGE_NONE /* &&  eLang != LANGUAGE_SYSTEM */)
1372*cdf0e10cSrcweir 		MsLangId::convertLanguageToLocale( eLang, aLocale );
1373*cdf0e10cSrcweir 
1374*cdf0e10cSrcweir 	return aLocale;
1375*cdf0e10cSrcweir }
1376*cdf0e10cSrcweir 
1377*cdf0e10cSrcweir 
1378