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