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