merge the formfield patch from ooo-build
[ooovba.git] / svx / source / editeng / unolingu.cxx
blobd6a2d2d96e2d11ad4cdb3aeffaefcfeb23554964
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: unolingu.cxx,v $
10 * $Revision: 1.39 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svx.hxx"
34 #include <map>
35 #include <set>
36 #include <vector>
37 #include <slist>
38 #include <memory>
39 #include <unolingu.hxx>
40 #include <tools/debug.hxx>
41 #include <tools/urlobj.hxx>
42 #include <rtl/logfile.hxx>
43 #include <svtools/pathoptions.hxx>
44 #include <com/sun/star/frame/XModel.hpp>
45 #include <com/sun/star/frame/XStorable.hpp>
46 #include <com/sun/star/lang/XEventListener.hpp>
47 #include <com/sun/star/linguistic2/XAvailableLocales.hpp>
48 #include <com/sun/star/ucb/XAnyCompareFactory.hpp>
49 #include <com/sun/star/ucb/XContentAccess.hpp>
50 #include <com/sun/star/ucb/XSortedDynamicResultSetFactory.hpp>
51 #include <com/sun/star/ucb/NumberedSortingInfo.hpp>
52 #include <com/sun/star/ucb/XContentAccess.hpp>
53 #include <com/sun/star/sdbc/XResultSet.hpp>
54 #include <com/sun/star/sdbc/XRow.hpp>
55 #include <com/sun/star/util/DateTime.hpp>
57 #include <comphelper/processfactory.hxx>
58 #include <cppuhelper/implbase1.hxx> // helper for implementations
59 #include <i18npool/mslangid.hxx>
60 #include <svtools/lingucfg.hxx>
61 #include <unotools/ucbhelper.hxx>
62 #include <unotools/localfilehelper.hxx>
63 #include <ucbhelper/commandenvironment.hxx>
64 #include <ucbhelper/content.hxx>
65 #include <comphelper/processfactory.hxx>
66 #include <vcl/msgbox.hxx>
67 #include <tools/shl.hxx>
68 #include <linguistic/misc.hxx>
69 #include <svx/dialmgr.hxx>
70 #include <svx/dialogs.hrc>
72 using namespace ::rtl;
73 using namespace ::comphelper;
74 using namespace ::linguistic;
75 using namespace ::com::sun::star;
76 using namespace ::com::sun::star::util;
77 using namespace ::com::sun::star::uno;
78 using namespace ::com::sun::star::lang;
79 using namespace ::com::sun::star::beans;
80 using namespace ::com::sun::star::frame;
81 using namespace ::com::sun::star::linguistic2;
83 #define CSS com::sun::star
85 ///////////////////////////////////////////////////////////////////////////
88 static uno::Reference< XLinguServiceManager > GetLngSvcMgr_Impl()
90 uno::Reference< XLinguServiceManager > xRes;
91 uno::Reference< XMultiServiceFactory > xMgr = getProcessServiceFactory();
92 if (xMgr.is())
94 xRes = uno::Reference< XLinguServiceManager > ( xMgr->createInstance(
95 OUString( RTL_CONSTASCII_USTRINGPARAM(
96 "com.sun.star.linguistic2.LinguServiceManager" ) ) ), UNO_QUERY ) ;
98 return xRes;
101 ///////////////////////////////////////////////////////////////////////////
103 BOOL lcl_FindEntry( const OUString &rEntry, const Sequence< OUString > &rCfgSvcs )
105 INT32 nRes = -1;
106 INT32 nEntries = rCfgSvcs.getLength();
107 const OUString *pEntry = rCfgSvcs.getConstArray();
108 for (INT32 i = 0; i < nEntries && nRes == -1; ++i)
110 if (rEntry == pEntry[i])
111 nRes = i;
113 return nRes != -1;
117 Sequence< OUString > lcl_RemoveMissingEntries(
118 const Sequence< OUString > &rCfgSvcs,
119 const Sequence< OUString > &rAvailSvcs )
121 Sequence< OUString > aRes( rCfgSvcs.getLength() );
122 OUString *pRes = aRes.getArray();
123 INT32 nCnt = 0;
125 INT32 nEntries = rCfgSvcs.getLength();
126 const OUString *pEntry = rCfgSvcs.getConstArray();
127 for (INT32 i = 0; i < nEntries; ++i)
129 if (pEntry[i].getLength() && lcl_FindEntry( pEntry[i], rAvailSvcs ))
130 pRes[ nCnt++ ] = pEntry[i];
133 aRes.realloc( nCnt );
134 return aRes;
138 Sequence< OUString > lcl_GetLastFoundSvcs(
139 SvtLinguConfig &rCfg,
140 const OUString &rLastFoundList ,
141 const Locale &rAvailLocale )
143 Sequence< OUString > aRes;
145 OUString aCfgLocaleStr( MsLangId::convertLanguageToIsoString(
146 SvxLocaleToLanguage( rAvailLocale ) ) );
148 Sequence< OUString > aNodeNames( rCfg.GetNodeNames(rLastFoundList) );
149 BOOL bFound = lcl_FindEntry( aCfgLocaleStr, aNodeNames);
151 if (bFound)
153 Sequence< OUString > aNames(1);
154 OUString &rNodeName = aNames.getArray()[0];
155 rNodeName = rLastFoundList;
156 rNodeName += OUString::valueOf( (sal_Unicode)'/' );
157 rNodeName += aCfgLocaleStr;
158 Sequence< Any > aValues( rCfg.GetProperties( aNames ) );
159 #if OSL_DEBUG_LEVEL > 1
160 const Any *pValue;
161 pValue = aValues.getConstArray();
162 #endif
163 if (aValues.getLength())
165 DBG_ASSERT( aValues.getLength() == 1, "unexpected length of sequence" );
166 Sequence< OUString > aSvcImplNames;
167 if (aValues.getConstArray()[0] >>= aSvcImplNames)
168 aRes = aSvcImplNames;
169 else
171 DBG_ERROR( "type mismatch" );
176 return aRes;
180 Sequence< OUString > lcl_GetNewEntries(
181 const Sequence< OUString > &rLastFoundSvcs,
182 const Sequence< OUString > &rAvailSvcs )
184 INT32 nLen = rAvailSvcs.getLength();
185 Sequence< OUString > aRes( nLen );
186 OUString *pRes = aRes.getArray();
187 INT32 nCnt = 0;
189 const OUString *pEntry = rAvailSvcs.getConstArray();
190 for (INT32 i = 0; i < nLen; ++i)
192 if (pEntry[i].getLength() && !lcl_FindEntry( pEntry[i], rLastFoundSvcs ))
193 pRes[ nCnt++ ] = pEntry[i];
196 aRes.realloc( nCnt );
197 return aRes;
201 Sequence< OUString > lcl_MergeSeq(
202 const Sequence< OUString > &rCfgSvcs,
203 const Sequence< OUString > &rNewSvcs )
205 Sequence< OUString > aRes( rCfgSvcs.getLength() + rNewSvcs.getLength() );
206 OUString *pRes = aRes.getArray();
207 INT32 nCnt = 0;
209 for (INT32 k = 0; k < 2; ++k)
211 // add previously configuerd service first and append
212 // new found services at the end
213 const Sequence< OUString > &rSeq = k == 0 ? rCfgSvcs : rNewSvcs;
215 INT32 nLen = rSeq.getLength();
216 const OUString *pEntry = rSeq.getConstArray();
217 for (INT32 i = 0; i < nLen; ++i)
219 if (pEntry[i].getLength() && !lcl_FindEntry( pEntry[i], aRes ))
220 pRes[ nCnt++ ] = pEntry[i];
224 aRes.realloc( nCnt );
225 return aRes;
228 ///////////////////////////////////////////////////////////////////////////
230 // static member initialization
231 INT16 SvxLinguConfigUpdate::nNeedUpdating = -1;
232 INT32 SvxLinguConfigUpdate::nCurrentDataFilesChangedCheckValue = -1;
234 void SvxLinguConfigUpdate::UpdateAll( sal_Bool bForceCheck )
236 RTL_LOGFILE_CONTEXT( aLog, "svx: SvxLinguConfigUpdate::UpdateAll" );
238 if (IsNeedUpdateAll( bForceCheck ))
240 typedef OUString OUstring_t;
241 typedef Sequence< OUString > Sequence_OUString_t;
242 typedef std::vector< OUstring_t > OUString_vector_t;
243 typedef std::set< OUstring_t > OUString_set_t;
244 std::vector< OUString_vector_t > aVector;
245 typedef std::map< OUstring_t, Sequence_OUString_t > list_entry_map_t;
247 RTL_LOGFILE_CONTEXT( aLog, "svx: SvxLinguConfigUpdate::UpdateAll - updating..." );
249 DBG_ASSERT( nNeedUpdating == 1, "SvxLinguConfigUpdate::UpdateAll already updated!" );
251 uno::Reference< XLinguServiceManager > xLngSvcMgr( GetLngSvcMgr_Impl() );
252 DBG_ASSERT( xLngSvcMgr.is(), "service manager missing");
253 if (!xLngSvcMgr.is())
254 return;
256 SvtLinguConfig aCfg;
258 const int nNumServices = 4;
259 const sal_Char * apServices[nNumServices] = { SN_SPELLCHECKER, SN_GRAMMARCHECKER, SN_HYPHENATOR, SN_THESAURUS };
260 const sal_Char * apCurLists[nNumServices] = { "ServiceManager/SpellCheckerList", "ServiceManager/GrammarCheckerList", "ServiceManager/HyphenatorList", "ServiceManager/ThesaurusList" };
261 const sal_Char * apLastFoundLists[nNumServices] = { "ServiceManager/LastFoundSpellCheckers", "ServiceManager/LastFoundGrammarCheckers", "ServiceManager/LastFoundHyphenators", "ServiceManager/LastFoundThesauri" };
263 // usage of indices as above: 0 = spell checker, 1 = grammar checker, 2 = hyphenator, 3 = thesaurus
264 std::vector< list_entry_map_t > aLastFoundSvcs(nNumServices);
265 std::vector< list_entry_map_t > aCurSvcs(nNumServices);
267 for (int k = 0; k < nNumServices; ++k)
269 OUString aService( A2OU( apServices[k] ) );
270 OUString aActiveList( A2OU( apCurLists[k] ) );
271 OUString aLastFoundList( A2OU( apLastFoundLists[k] ) );
272 INT32 i;
275 // remove configured but not available language/services entries
277 Sequence< OUString > aNodeNames( aCfg.GetNodeNames( aActiveList ) ); // list of configured locales
278 INT32 nNodeNames = aNodeNames.getLength();
279 const OUString *pNodeName = aNodeNames.getConstArray();
280 for (i = 0; i < nNodeNames; ++i)
282 Locale aLocale( SvxCreateLocale( MsLangId::convertIsoStringToLanguage(pNodeName[i]) ) );
283 Sequence< OUString > aCfgSvcs(
284 xLngSvcMgr->getConfiguredServices( aService, aLocale ));
285 Sequence< OUString > aAvailSvcs(
286 xLngSvcMgr->getAvailableServices( aService, aLocale ));
287 #if OSL_DEBUG_LEVEL > 1
288 const OUString * pCfgSvcs = aCfgSvcs.getConstArray();;
289 const OUString * pAvailSvcs = aAvailSvcs.getConstArray();;
290 (void) pCfgSvcs;
291 (void) pAvailSvcs;
292 #endif
293 aCfgSvcs = lcl_RemoveMissingEntries( aCfgSvcs, aAvailSvcs );
295 aCurSvcs[k][ pNodeName[i] ] = aCfgSvcs;
299 // add new available language/servcice entries
301 uno::Reference< XAvailableLocales > xAvail( xLngSvcMgr, UNO_QUERY );
302 Sequence< Locale > aAvailLocales( xAvail->getAvailableLocales(aService) );
303 INT32 nAvailLocales = aAvailLocales.getLength();
304 const Locale *pAvailLocale = aAvailLocales.getConstArray();
305 for (i = 0; i < nAvailLocales; ++i)
307 Sequence< OUString > aAvailSvcs(
308 xLngSvcMgr->getAvailableServices( aService, pAvailLocale[i] ));
309 Sequence< OUString > aLastSvcs(
310 lcl_GetLastFoundSvcs( aCfg, aLastFoundList , pAvailLocale[i] ));
311 Sequence< OUString > aNewSvcs =
312 lcl_GetNewEntries( aLastSvcs, aAvailSvcs );
313 #if OSL_DEBUG_LEVEL > 1
314 const OUString * pAvailSvcs = aAvailSvcs.getConstArray();
315 const OUString * pLastSvcs = aLastSvcs.getConstArray();
316 const OUString * pNewSvcs = aNewSvcs.getConstArray();
317 (void) pAvailSvcs;
318 (void) pLastSvcs;
319 (void) pNewSvcs;
320 #endif
322 OUString aCfgLocaleStr( MsLangId::convertLanguageToIsoString(
323 SvxLocaleToLanguage( pAvailLocale[i] ) ) );
324 Sequence< OUString > aCfgSvcs( aCurSvcs[k][ aCfgLocaleStr ] );
326 // merge services list (previously configured to be listed first).
327 aCfgSvcs = lcl_MergeSeq( aCfgSvcs, aNewSvcs );
330 // there is at most one Hyphenator per language allowed
331 // to be configured, thus we only use the first one found.
332 if (k == 2 && aCfgSvcs.getLength() > 1)
333 aCfgSvcs.realloc(1);
335 aCurSvcs[k][ aCfgLocaleStr ] = aCfgSvcs;
339 // set last found services to currently available ones
341 for (i = 0; i < nAvailLocales; ++i)
343 Sequence< OUString > aSvcImplNames(
344 xLngSvcMgr->getAvailableServices( aService, pAvailLocale[i] ) );
346 #if OSL_DEBUG_LEVEL > 1
347 INT32 nSvcs = aSvcImplNames.getLength();
348 const OUString *pSvcImplName = aSvcImplNames.getConstArray();
349 for (INT32 j = 0; j < nSvcs; ++j)
351 OUString aImplName( pSvcImplName[j] );
353 #endif
355 OUString aCfgLocaleStr( MsLangId::convertLanguageToIsoString(
356 SvxLocaleToLanguage( pAvailLocale[i] ) ) );
357 aLastFoundSvcs[k][ aCfgLocaleStr ] = aSvcImplNames;
362 // write new data back to configuration
364 for (int k = 0; k < nNumServices; ++k)
366 for (int i = 0; i < 2; ++i)
368 const sal_Char *pSubNodeName = (i == 0) ? apCurLists[k] : apLastFoundLists[k];
369 OUString aSubNodeName( A2OU(pSubNodeName) );
371 list_entry_map_t &rCurMap = (i == 0) ? aCurSvcs[k] : aLastFoundSvcs[k];
372 list_entry_map_t::const_iterator aIt( rCurMap.begin() );
373 sal_Int32 nVals = static_cast< sal_Int32 >( rCurMap.size() );
374 Sequence< PropertyValue > aNewValues( nVals );
375 PropertyValue *pNewValue = aNewValues.getArray();
376 while (aIt != rCurMap.end())
378 OUString aCfgEntryName( aSubNodeName );
379 aCfgEntryName += OUString::valueOf( (sal_Unicode) '/' );
380 aCfgEntryName += (*aIt).first;
382 #if OSL_DEBUG_LEVEL > 1
383 Sequence< OUString > aSvcImplNames( (*aIt).second );
384 INT32 nSvcs = aSvcImplNames.getLength();
385 const OUString *pSvcImplName = aSvcImplNames.getConstArray();
386 for (INT32 j = 0; j < nSvcs; ++j)
388 OUString aImplName( pSvcImplName[j] );
390 #endif
391 pNewValue->Name = aCfgEntryName;
392 pNewValue->Value <<= (*aIt).second;
393 ++pNewValue;
394 ++aIt;
396 DBG_ASSERT( pNewValue - aNewValues.getArray() == nVals,
397 "possible mismatch of sequence size and property number" );
400 RTL_LOGFILE_CONTEXT( aLog, "svx: SvxLinguConfigUpdate::UpdateAll - ReplaceSetProperties" );
401 // add new or replace existing entries.
402 BOOL bRes = aCfg.ReplaceSetProperties( aSubNodeName, aNewValues );
403 if (!bRes)
405 #if OSL_DEBUG_LEVEL > 1
406 DBG_ERROR( "failed to set new configuration values" );
407 #endif
412 DBG_ASSERT( nCurrentDataFilesChangedCheckValue != -1, "SvxLinguConfigUpdate::UpdateAll DataFilesChangedCheckValue not yet calculated!" );
413 Any aAny;
415 // for the time being (developer builds until OOo 3.0)
416 // we should always check for everything available
417 // otherwise we may miss a new installed extension dicitonary
418 // just because e.g. the spellchecker is not asked what
419 // languages it does support currently...
420 // Since the check is on-demand occuring and executed once it should
421 // not be too troublesome.
422 // In OOo 3.0 we will not need the respective code anymore at all.
423 // aAny <<= nCurrentDataFilesChangedCheckValue;
424 aAny <<= (INT32) -1; // keep the value set to 'need to check'
426 aCfg.SetProperty( A2OU( "DataFilesChangedCheckValue" ), aAny );
428 //! Note 1: the new values are commited when the 'aCfg' object
429 //! gets destroyed.
430 //! Note 2: the new settings in the configuration get applied
431 //! because the 'LngSvcMgr' (in linguistic/source/lngsvcmgr.hxx)
432 //! listens to the configuration for changes of the relevant
433 //! properties and then applies the new settings.
435 // nothing needs to be done anymore
436 nNeedUpdating = 0;
441 INT32 SvxLinguConfigUpdate::CalcDataFilesChangedCheckValue()
443 RTL_LOGFILE_CONTEXT( aLog, "svx: SvxLinguConfigUpdate::CalcDataFilesChangedCheckValue" );
445 INT32 nHashVal = 0;
446 // nothing to be checked anymore since those old directory paths are gone by now
447 return nHashVal;
451 BOOL SvxLinguConfigUpdate::IsNeedUpdateAll( sal_Bool bForceCheck )
453 RTL_LOGFILE_CONTEXT( aLog, "svx: SvxLinguConfigUpdate::IsNeedUpdateAll" );
454 if (nNeedUpdating == -1 || bForceCheck ) // need to check if updating is necessary
456 // calculate hash value for current data files
457 nCurrentDataFilesChangedCheckValue = CalcDataFilesChangedCheckValue();
459 // compare hash value and check value to see if anything has changed
460 // and thus the configuration needs to be updated
461 SvtLinguOptions aLinguOpt;
462 SvtLinguConfig aCfg;
463 aCfg.GetOptions( aLinguOpt );
464 nNeedUpdating = (nCurrentDataFilesChangedCheckValue == aLinguOpt.nDataFilesChangedCheckValue) ? 0 : 1;
466 DBG_ASSERT( nNeedUpdating != -1,
467 "need for linguistic configuration update should have been already checked." );
469 return nNeedUpdating == 1;
472 ///////////////////////////////////////////////////////////////////////////
475 //! Dummy implementation in order to avoid loading of lingu DLL
476 //! when only the XSupportedLocales interface is used.
477 //! The dummy accesses the real implementation (and thus loading the DLL)
478 //! when "real" work needs to be done only.
479 class ThesDummy_Impl :
480 public cppu::WeakImplHelper1< XThesaurus >
482 uno::Reference< XThesaurus > xThes; // the real one...
483 Sequence< Locale > *pLocaleSeq;
485 void GetCfgLocales();
487 void GetThes_Impl();
489 public:
490 ThesDummy_Impl() : pLocaleSeq(0) {}
491 ~ThesDummy_Impl();
493 // XSupportedLocales
494 virtual ::com::sun::star::uno::Sequence<
495 ::com::sun::star::lang::Locale > SAL_CALL
496 getLocales()
497 throw(::com::sun::star::uno::RuntimeException);
498 virtual sal_Bool SAL_CALL
499 hasLocale( const ::com::sun::star::lang::Locale& rLocale )
500 throw(::com::sun::star::uno::RuntimeException);
502 // XThesaurus
503 virtual ::com::sun::star::uno::Sequence<
504 ::com::sun::star::uno::Reference<
505 ::com::sun::star::linguistic2::XMeaning > > SAL_CALL
506 queryMeanings( const ::rtl::OUString& rTerm,
507 const ::com::sun::star::lang::Locale& rLocale,
508 const ::com::sun::star::beans::PropertyValues& rProperties )
509 throw(::com::sun::star::lang::IllegalArgumentException,
510 ::com::sun::star::uno::RuntimeException);
514 ThesDummy_Impl::~ThesDummy_Impl()
516 delete pLocaleSeq;
520 void ThesDummy_Impl::GetCfgLocales()
522 if (!pLocaleSeq)
524 SvtLinguConfig aCfg;
525 String aNode( A2OU( "ServiceManager/ThesaurusList" ) );
526 Sequence < OUString > aNodeNames( aCfg.GetNodeNames( aNode ) );
527 const OUString *pNodeNames = aNodeNames.getConstArray();
528 INT32 nLen = aNodeNames.getLength();
529 pLocaleSeq = new Sequence< Locale >( nLen );
530 Locale *pLocale = pLocaleSeq->getArray();
531 for (INT32 i = 0; i < nLen; ++i)
533 pLocale[i] = SvxCreateLocale(
534 MsLangId::convertIsoStringToLanguage( pNodeNames[i] ) );
540 void ThesDummy_Impl::GetThes_Impl()
542 // update configuration before accessing the service
543 if (SvxLinguConfigUpdate::IsNeedUpdateAll())
544 SvxLinguConfigUpdate::UpdateAll();
546 if (!xThes.is())
548 uno::Reference< XLinguServiceManager > xLngSvcMgr( GetLngSvcMgr_Impl() );
549 if (xLngSvcMgr.is())
550 xThes = xLngSvcMgr->getThesaurus();
552 if (xThes.is())
554 // no longer needed...
555 delete pLocaleSeq; pLocaleSeq = 0;
561 uno::Sequence< lang::Locale > SAL_CALL
562 ThesDummy_Impl::getLocales()
563 throw(uno::RuntimeException)
565 if (!SvxLinguConfigUpdate::IsNeedUpdateAll()) // configuration already update and thus lingu DLL's already loaded ?
566 GetThes_Impl();
567 if (xThes.is())
568 return xThes->getLocales();
569 else if (!pLocaleSeq) // if not already loaded save startup time by avoiding loading them now
570 GetCfgLocales();
571 return *pLocaleSeq;
575 sal_Bool SAL_CALL
576 ThesDummy_Impl::hasLocale( const lang::Locale& rLocale )
577 throw(uno::RuntimeException)
579 if (!SvxLinguConfigUpdate::IsNeedUpdateAll()) // configuration already update and thus lingu DLL's already loaded ?
580 GetThes_Impl();
581 if (xThes.is())
582 return xThes->hasLocale( rLocale );
583 else if (!pLocaleSeq) // if not already loaded save startup time by avoiding loading them now
584 GetCfgLocales();
585 GetCfgLocales();
586 BOOL bFound = FALSE;
587 INT32 nLen = pLocaleSeq->getLength();
588 const Locale *pLocale = pLocaleSeq->getConstArray();
589 const Locale *pEnd = pLocale + nLen;
590 for ( ; pLocale < pEnd && !bFound; ++pLocale)
592 bFound = pLocale->Language == rLocale.Language &&
593 pLocale->Country == rLocale.Country &&
594 pLocale->Variant == rLocale.Variant;
596 return bFound;
600 uno::Sequence< uno::Reference< linguistic2::XMeaning > > SAL_CALL
601 ThesDummy_Impl::queryMeanings(
602 const rtl::OUString& rTerm,
603 const lang::Locale& rLocale,
604 const beans::PropertyValues& rProperties )
605 throw(lang::IllegalArgumentException,
606 uno::RuntimeException)
608 GetThes_Impl();
609 uno::Sequence< uno::Reference< linguistic2::XMeaning > > aRes;
610 DBG_ASSERT( xThes.is(), "Thesaurus missing" );
611 if (xThes.is())
612 aRes = xThes->queryMeanings( rTerm, rLocale, rProperties );
613 return aRes;
617 ///////////////////////////////////////////////////////////////////////////
620 //! Dummy implementation in order to avoid loading of lingu DLL.
621 //! The dummy accesses the real implementation (and thus loading the DLL)
622 //! when it needs to be done only.
623 class SpellDummy_Impl :
624 public cppu::WeakImplHelper1< XSpellChecker1 >
626 uno::Reference< XSpellChecker1 > xSpell; // the real one...
628 void GetSpell_Impl();
630 public:
632 // XSupportedLanguages (for XSpellChecker1)
633 virtual ::com::sun::star::uno::Sequence< sal_Int16 > SAL_CALL
634 getLanguages()
635 throw(::com::sun::star::uno::RuntimeException);
636 virtual sal_Bool SAL_CALL
637 hasLanguage( sal_Int16 nLanguage )
638 throw(::com::sun::star::uno::RuntimeException);
640 // XSpellChecker1 (same as XSpellChecker but sal_Int16 for language)
641 virtual sal_Bool SAL_CALL
642 isValid( const ::rtl::OUString& rWord, sal_Int16 nLanguage,
643 const ::com::sun::star::beans::PropertyValues& rProperties )
644 throw(::com::sun::star::lang::IllegalArgumentException,
645 ::com::sun::star::uno::RuntimeException);
646 virtual ::com::sun::star::uno::Reference<
647 ::com::sun::star::linguistic2::XSpellAlternatives > SAL_CALL
648 spell( const ::rtl::OUString& rWord, sal_Int16 nLanguage,
649 const ::com::sun::star::beans::PropertyValues& rProperties )
650 throw(::com::sun::star::lang::IllegalArgumentException,
651 ::com::sun::star::uno::RuntimeException);
655 void SpellDummy_Impl::GetSpell_Impl()
657 // update configuration before accessing the service
658 if (SvxLinguConfigUpdate::IsNeedUpdateAll())
659 SvxLinguConfigUpdate::UpdateAll();
661 if (!xSpell.is())
663 uno::Reference< XLinguServiceManager > xLngSvcMgr( GetLngSvcMgr_Impl() );
664 if (xLngSvcMgr.is())
665 xSpell = uno::Reference< XSpellChecker1 >( xLngSvcMgr->getSpellChecker(), UNO_QUERY );
670 uno::Sequence< sal_Int16 > SAL_CALL
671 SpellDummy_Impl::getLanguages()
672 throw(uno::RuntimeException)
674 GetSpell_Impl();
675 if (xSpell.is())
676 return xSpell->getLanguages();
677 else
678 return uno::Sequence< sal_Int16 >();
682 sal_Bool SAL_CALL
683 SpellDummy_Impl::hasLanguage( sal_Int16 nLanguage )
684 throw(uno::RuntimeException)
686 GetSpell_Impl();
687 BOOL bRes = FALSE;
688 if (xSpell.is())
689 bRes = xSpell->hasLanguage( nLanguage );
690 return bRes;
694 sal_Bool SAL_CALL
695 SpellDummy_Impl::isValid( const rtl::OUString& rWord, sal_Int16 nLanguage,
696 const beans::PropertyValues& rProperties )
697 throw(lang::IllegalArgumentException,
698 uno::RuntimeException)
700 GetSpell_Impl();
701 BOOL bRes = TRUE;
702 if (xSpell.is())
703 bRes = xSpell->isValid( rWord, nLanguage, rProperties );
704 return bRes;
708 uno::Reference< linguistic2::XSpellAlternatives > SAL_CALL
709 SpellDummy_Impl::spell( const rtl::OUString& rWord, sal_Int16 nLanguage,
710 const beans::PropertyValues& rProperties )
711 throw(lang::IllegalArgumentException,
712 uno::RuntimeException)
714 GetSpell_Impl();
715 uno::Reference< linguistic2::XSpellAlternatives > xRes;
716 if (xSpell.is())
717 xRes = xSpell->spell( rWord, nLanguage, rProperties );
718 return xRes;
722 ///////////////////////////////////////////////////////////////////////////
725 //! Dummy implementation in order to avoid loading of lingu DLL.
726 //! The dummy accesses the real implementation (and thus loading the DLL)
727 //! when it needs to be done only.
728 class HyphDummy_Impl :
729 public cppu::WeakImplHelper1< XHyphenator >
731 uno::Reference< XHyphenator > xHyph; // the real one...
733 void GetHyph_Impl();
735 public:
737 // XSupportedLocales
738 virtual ::com::sun::star::uno::Sequence<
739 ::com::sun::star::lang::Locale > SAL_CALL
740 getLocales()
741 throw(::com::sun::star::uno::RuntimeException);
742 virtual sal_Bool SAL_CALL
743 hasLocale( const ::com::sun::star::lang::Locale& rLocale )
744 throw(::com::sun::star::uno::RuntimeException);
746 // XHyphenator
747 virtual ::com::sun::star::uno::Reference<
748 ::com::sun::star::linguistic2::XHyphenatedWord > SAL_CALL
749 hyphenate( const ::rtl::OUString& rWord,
750 const ::com::sun::star::lang::Locale& rLocale,
751 sal_Int16 nMaxLeading,
752 const ::com::sun::star::beans::PropertyValues& rProperties )
753 throw(::com::sun::star::lang::IllegalArgumentException,
754 ::com::sun::star::uno::RuntimeException);
755 virtual ::com::sun::star::uno::Reference<
756 ::com::sun::star::linguistic2::XHyphenatedWord > SAL_CALL
757 queryAlternativeSpelling( const ::rtl::OUString& rWord,
758 const ::com::sun::star::lang::Locale& rLocale,
759 sal_Int16 nIndex,
760 const ::com::sun::star::beans::PropertyValues& rProperties )
761 throw(::com::sun::star::lang::IllegalArgumentException,
762 ::com::sun::star::uno::RuntimeException);
763 virtual ::com::sun::star::uno::Reference<
764 ::com::sun::star::linguistic2::XPossibleHyphens > SAL_CALL
765 createPossibleHyphens(
766 const ::rtl::OUString& rWord,
767 const ::com::sun::star::lang::Locale& rLocale,
768 const ::com::sun::star::beans::PropertyValues& rProperties )
769 throw(::com::sun::star::lang::IllegalArgumentException,
770 ::com::sun::star::uno::RuntimeException);
774 void HyphDummy_Impl::GetHyph_Impl()
776 // update configuration before accessing the service
777 if (SvxLinguConfigUpdate::IsNeedUpdateAll())
778 SvxLinguConfigUpdate::UpdateAll();
780 if (!xHyph.is())
782 uno::Reference< XLinguServiceManager > xLngSvcMgr( GetLngSvcMgr_Impl() );
783 if (xLngSvcMgr.is())
784 xHyph = xLngSvcMgr->getHyphenator();
789 uno::Sequence< lang::Locale > SAL_CALL
790 HyphDummy_Impl::getLocales()
791 throw(uno::RuntimeException)
793 GetHyph_Impl();
794 if (xHyph.is())
795 return xHyph->getLocales();
796 else
797 return uno::Sequence< lang::Locale >();
801 sal_Bool SAL_CALL
802 HyphDummy_Impl::hasLocale( const lang::Locale& rLocale )
803 throw(uno::RuntimeException)
805 GetHyph_Impl();
806 BOOL bRes = FALSE;
807 if (xHyph.is())
808 bRes = xHyph->hasLocale( rLocale );
809 return bRes;
813 uno::Reference< linguistic2::XHyphenatedWord > SAL_CALL
814 HyphDummy_Impl::hyphenate(
815 const rtl::OUString& rWord,
816 const lang::Locale& rLocale,
817 sal_Int16 nMaxLeading,
818 const beans::PropertyValues& rProperties )
819 throw(lang::IllegalArgumentException,
820 uno::RuntimeException)
822 GetHyph_Impl();
823 uno::Reference< linguistic2::XHyphenatedWord > xRes;
824 if (xHyph.is())
825 xRes = xHyph->hyphenate( rWord, rLocale, nMaxLeading, rProperties );
826 return xRes;
830 uno::Reference< linguistic2::XHyphenatedWord > SAL_CALL
831 HyphDummy_Impl::queryAlternativeSpelling(
832 const rtl::OUString& rWord,
833 const lang::Locale& rLocale,
834 sal_Int16 nIndex,
835 const PropertyValues& rProperties )
836 throw(lang::IllegalArgumentException,
837 uno::RuntimeException)
839 GetHyph_Impl();
840 uno::Reference< linguistic2::XHyphenatedWord > xRes;
841 if (xHyph.is())
842 xRes = xHyph->queryAlternativeSpelling( rWord, rLocale, nIndex, rProperties );
843 return xRes;
847 uno::Reference< linguistic2::XPossibleHyphens > SAL_CALL
848 HyphDummy_Impl::createPossibleHyphens(
849 const rtl::OUString& rWord,
850 const lang::Locale& rLocale,
851 const beans::PropertyValues& rProperties )
852 throw(lang::IllegalArgumentException,
853 uno::RuntimeException)
855 GetHyph_Impl();
856 uno::Reference< linguistic2::XPossibleHyphens > xRes;
857 if (xHyph.is())
858 xRes = xHyph->createPossibleHyphens( rWord, rLocale, rProperties );
859 return xRes;
863 ///////////////////////////////////////////////////////////////////////////
866 typedef cppu::WeakImplHelper1 < XEventListener > LinguMgrAppExitLstnrBaseClass;
868 class LinguMgrAppExitLstnr : public LinguMgrAppExitLstnrBaseClass
870 uno::Reference< XComponent > xDesktop;
872 public:
873 LinguMgrAppExitLstnr();
874 virtual ~LinguMgrAppExitLstnr();
876 virtual void AtExit() = 0;
879 // lang::XEventListener
880 virtual void SAL_CALL disposing(const EventObject& rSource)
881 throw( RuntimeException );
884 LinguMgrAppExitLstnr::LinguMgrAppExitLstnr()
886 // add object to frame::Desktop EventListeners in order to properly call
887 // the AtExit function at appliction exit.
889 uno::Reference< XMultiServiceFactory > xMgr = getProcessServiceFactory();
890 if ( xMgr.is() )
892 xDesktop = uno::Reference< XComponent > ( xMgr->createInstance(
893 OUString( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.frame.Desktop" ) ) ), UNO_QUERY ) ;
894 if (xDesktop.is())
895 xDesktop->addEventListener( this );
899 LinguMgrAppExitLstnr::~LinguMgrAppExitLstnr()
901 if (xDesktop.is())
903 xDesktop->removeEventListener( this );
904 xDesktop = NULL; //! release reference to desktop
906 DBG_ASSERT(!xDesktop.is(), "reference to desktop should be realeased");
909 void LinguMgrAppExitLstnr::disposing(const EventObject& rSource)
910 throw( RuntimeException )
912 if (xDesktop.is() && rSource.Source == xDesktop)
914 xDesktop->removeEventListener( this );
915 xDesktop = NULL; //! release reference to desktop
917 AtExit();
921 ///////////////////////////////////////////////////////////////////////////
923 class LinguMgrExitLstnr : public LinguMgrAppExitLstnr
925 public:
926 virtual void AtExit();
929 void LinguMgrExitLstnr::AtExit()
931 // release references
932 LinguMgr::xLngSvcMgr = 0;
933 LinguMgr::xSpell = 0;
934 LinguMgr::xHyph = 0;
935 LinguMgr::xThes = 0;
936 LinguMgr::xDicList = 0;
937 LinguMgr::xProp = 0;
938 LinguMgr::xIgnoreAll = 0;
939 LinguMgr::xChangeAll = 0;
941 LinguMgr::bExiting = sal_True;
943 //TL:TODO: MBA fragen wie ich ohne Absturz hier meinen Speicher
944 // wieder freibekomme...
945 //delete LinguMgr::pExitLstnr;
946 LinguMgr::pExitLstnr = 0;
949 ///////////////////////////////////////////////////////////////////////////
952 // static member initialization
953 LinguMgrExitLstnr * LinguMgr::pExitLstnr = 0;
954 sal_Bool LinguMgr::bExiting = sal_False;
955 uno::Reference< XLinguServiceManager > LinguMgr::xLngSvcMgr = 0;
956 uno::Reference< XSpellChecker1 > LinguMgr::xSpell = 0;
957 uno::Reference< XHyphenator > LinguMgr::xHyph = 0;
958 uno::Reference< XThesaurus > LinguMgr::xThes = 0;
959 uno::Reference< XDictionaryList > LinguMgr::xDicList = 0;
960 uno::Reference< XPropertySet > LinguMgr::xProp = 0;
961 uno::Reference< XDictionary > LinguMgr::xIgnoreAll = 0;
962 uno::Reference< XDictionary > LinguMgr::xChangeAll = 0;
965 uno::Reference< XLinguServiceManager > LinguMgr::GetLngSvcMgr()
967 if (bExiting)
968 return 0;
970 if (!pExitLstnr)
971 pExitLstnr = new LinguMgrExitLstnr;
973 if (!xLngSvcMgr.is())
974 xLngSvcMgr = GetLngSvcMgr_Impl();
976 return xLngSvcMgr;
980 uno::Reference< XSpellChecker1 > LinguMgr::GetSpellChecker()
982 return xSpell.is() ? xSpell : GetSpell();
985 uno::Reference< XHyphenator > LinguMgr::GetHyphenator()
987 return xHyph.is() ? xHyph : GetHyph();
990 uno::Reference< XThesaurus > LinguMgr::GetThesaurus()
992 return xThes.is() ? xThes : GetThes();
995 uno::Reference< XDictionaryList > LinguMgr::GetDictionaryList()
997 return xDicList.is() ? xDicList : GetDicList();
1000 uno::Reference< XPropertySet > LinguMgr::GetLinguPropertySet()
1002 return xProp.is() ? xProp : GetProp();
1005 uno::Reference< XDictionary > LinguMgr::GetStandardDic()
1007 //! don't hold reference to this
1008 //! (it may be removed from dictionary list and needs to be
1009 //! created empty if accessed again)
1010 return GetStandard();
1013 uno::Reference< XDictionary > LinguMgr::GetIgnoreAllList()
1015 return xIgnoreAll.is() ? xIgnoreAll : GetIgnoreAll();
1018 uno::Reference< XDictionary > LinguMgr::GetChangeAllList()
1020 return xChangeAll.is() ? xChangeAll : GetChangeAll();
1023 uno::Reference< XSpellChecker1 > LinguMgr::GetSpell()
1025 if (bExiting)
1026 return 0;
1028 if (!pExitLstnr)
1029 pExitLstnr = new LinguMgrExitLstnr;
1031 //! use dummy implementation in order to avoid loading of lingu DLL
1032 xSpell = new SpellDummy_Impl;
1034 /* if (!xLngSvcMgr.is())
1035 xLngSvcMgr = GetLngSvcMgr_Impl();
1037 if (xLngSvcMgr.is())
1039 xSpell = uno::Reference< XSpellChecker1 > (
1040 xLngSvcMgr->getSpellChecker(), UNO_QUERY );
1043 return xSpell;
1046 uno::Reference< XHyphenator > LinguMgr::GetHyph()
1048 if (bExiting)
1049 return 0;
1051 if (!pExitLstnr)
1052 pExitLstnr = new LinguMgrExitLstnr;
1054 //! use dummy implementation in order to avoid loading of lingu DLL
1055 xHyph = new HyphDummy_Impl;
1058 if (!xLngSvcMgr.is())
1059 xLngSvcMgr = GetLngSvcMgr_Impl();
1061 if (xLngSvcMgr.is())
1063 xHyph = xLngSvcMgr->getHyphenator();
1066 return xHyph;
1069 uno::Reference< XThesaurus > LinguMgr::GetThes()
1071 if (bExiting)
1072 return 0;
1074 if (!pExitLstnr)
1075 pExitLstnr = new LinguMgrExitLstnr;
1077 //! use dummy implementation in order to avoid loading of lingu DLL
1078 //! when only the XSupportedLocales interface is used.
1079 //! The dummy accesses the real implementation (and thus loading the DLL)
1080 //! when "real" work needs to be done only.
1081 xThes = new ThesDummy_Impl;
1083 if (!xLngSvcMgr.is())
1084 xLngSvcMgr = GetLngSvcMgr_Impl();
1086 if (xLngSvcMgr.is())
1088 xThes = xLngSvcMgr->getThesaurus();
1091 return xThes;
1095 void LinguMgr::UpdateAll()
1100 uno::Reference< XDictionaryList > LinguMgr::GetDicList()
1102 if (bExiting)
1103 return 0;
1105 if (!pExitLstnr)
1106 pExitLstnr = new LinguMgrExitLstnr;
1108 uno::Reference< XMultiServiceFactory > xMgr( getProcessServiceFactory() );
1109 if (xMgr.is())
1111 xDicList = uno::Reference< XDictionaryList > ( xMgr->createInstance(
1112 A2OU("com.sun.star.linguistic2.DictionaryList") ), UNO_QUERY );
1114 return xDicList;
1117 uno::Reference< XPropertySet > LinguMgr::GetProp()
1119 if (bExiting)
1120 return 0;
1122 if (!pExitLstnr)
1123 pExitLstnr = new LinguMgrExitLstnr;
1125 uno::Reference< XMultiServiceFactory > xMgr( getProcessServiceFactory() );
1126 if (xMgr.is())
1128 xProp = uno::Reference< XPropertySet > ( xMgr->createInstance(
1129 A2OU("com.sun.star.linguistic2.LinguProperties") ), UNO_QUERY );
1131 return xProp;
1134 uno::Reference< XDictionary > LinguMgr::GetIgnoreAll()
1136 if (bExiting)
1137 return 0;
1139 if (!pExitLstnr)
1140 pExitLstnr = new LinguMgrExitLstnr;
1142 uno::Reference< XDictionaryList > xTmpDicList( GetDictionaryList() );
1143 if (xTmpDicList.is())
1145 xIgnoreAll = uno::Reference< XDictionary > ( xTmpDicList->getDictionaryByName(
1146 A2OU("IgnoreAllList") ), UNO_QUERY );
1148 return xIgnoreAll;
1151 uno::Reference< XDictionary > LinguMgr::GetChangeAll()
1153 if (bExiting)
1154 return 0;
1156 if (!pExitLstnr)
1157 pExitLstnr = new LinguMgrExitLstnr;
1159 uno::Reference< XDictionaryList > _xDicList( GetDictionaryList() , UNO_QUERY );
1160 if (_xDicList.is())
1162 xChangeAll = uno::Reference< XDictionary > (
1163 _xDicList->createDictionary(
1164 A2OU("ChangeAllList"),
1165 SvxCreateLocale( LANGUAGE_NONE ),
1166 DictionaryType_NEGATIVE, String() ), UNO_QUERY );
1168 return xChangeAll;
1171 uno::Reference< XDictionary > LinguMgr::GetStandard()
1173 // Tries to return a dictionary which may hold positive entries is
1174 // persistent and not read-only.
1176 if (bExiting)
1177 return 0;
1179 uno::Reference< XDictionaryList > xTmpDicList( GetDictionaryList() );
1180 if (!xTmpDicList.is())
1181 return NULL;
1183 const OUString aDicName( RTL_CONSTASCII_USTRINGPARAM( "standard.dic" ) );
1184 uno::Reference< XDictionary > xDic( xTmpDicList->getDictionaryByName( aDicName ),
1185 UNO_QUERY );
1186 if (!xDic.is())
1188 // try to create standard dictionary
1189 uno::Reference< XDictionary > xTmp;
1192 xTmp = xTmpDicList->createDictionary( aDicName,
1193 SvxCreateLocale( LANGUAGE_NONE ),
1194 DictionaryType_POSITIVE,
1195 linguistic::GetWritableDictionaryURL( aDicName ) );
1197 catch(com::sun::star::uno::Exception &)
1201 // add new dictionary to list
1202 if (xTmp.is())
1203 xTmpDicList->addDictionary( xTmp );
1204 xDic = uno::Reference< XDictionary > ( xTmp, UNO_QUERY );
1206 #if OSL_DEBUG_LEVEL > 1
1207 uno::Reference< XStorable > xStor( xDic, UNO_QUERY );
1208 DBG_ASSERT( xDic.is() && xDic->getDictionaryType() == DictionaryType_POSITIVE,
1209 "wrong dictionary type");
1210 DBG_ASSERT( xDic.is() && SvxLocaleToLanguage( xDic->getLocale() ) == LANGUAGE_NONE,
1211 "wrong dictionary language");
1212 DBG_ASSERT( !xStor.is() || (xStor->hasLocation() && !xStor->isReadonly()),
1213 "dictionary not editable" );
1214 #endif
1216 return xDic;
1219 ///////////////////////////////////////////////////////////////////////////
1221 uno::Reference< XSpellChecker1 > SvxGetSpellChecker()
1223 return LinguMgr::GetSpellChecker();
1226 uno::Reference< XHyphenator > SvxGetHyphenator()
1228 return LinguMgr::GetHyphenator();
1231 uno::Reference< XThesaurus > SvxGetThesaurus()
1233 return LinguMgr::GetThesaurus();
1236 uno::Reference< XDictionaryList > SvxGetDictionaryList()
1238 return LinguMgr::GetDictionaryList();
1241 uno::Reference< XPropertySet > SvxGetLinguPropertySet()
1243 return LinguMgr::GetLinguPropertySet();
1246 //TL:TODO: remove argument or provide SvxGetIgnoreAllList with the same one
1247 uno::Reference< XDictionary > SvxGetOrCreatePosDic(
1248 uno::Reference< XDictionaryList > /* xDicList */ )
1250 return LinguMgr::GetStandardDic();
1253 uno::Reference< XDictionary > SvxGetIgnoreAllList()
1255 return LinguMgr::GetIgnoreAllList();
1258 uno::Reference< XDictionary > SvxGetChangeAllList()
1260 return LinguMgr::GetChangeAllList();
1263 ///////////////////////////////////////////////////////////////////////////
1266 #include <com/sun/star/linguistic2/XHyphenatedWord.hpp>
1268 SvxAlternativeSpelling SvxGetAltSpelling(
1269 const ::com::sun::star::uno::Reference<
1270 ::com::sun::star::linguistic2::XHyphenatedWord > & rHyphWord )
1272 SvxAlternativeSpelling aRes;
1273 if (rHyphWord.is() && rHyphWord->isAlternativeSpelling())
1275 OUString aWord( rHyphWord->getWord() ),
1276 aAltWord( rHyphWord->getHyphenatedWord() );
1277 INT16 nHyphenationPos = rHyphWord->getHyphenationPos(),
1278 nHyphenPos = rHyphWord->getHyphenPos();
1279 INT16 nLen = (INT16)aWord.getLength();
1280 INT16 nAltLen = (INT16)aAltWord.getLength();
1281 const sal_Unicode *pWord = aWord.getStr(),
1282 *pAltWord = aAltWord.getStr();
1284 // count number of chars from the left to the
1285 // hyphenation pos / hyphen pos that are equal
1286 INT16 nL = 0;
1287 while (nL <= nHyphenationPos && nL <= nHyphenPos
1288 && pWord[ nL ] == pAltWord[ nL ])
1289 ++nL;
1290 // count number of chars from the right to the
1291 // hyphenation pos / hyphen pos that are equal
1292 INT16 nR = 0;
1293 INT32 nIdx = nLen - 1;
1294 INT32 nAltIdx = nAltLen - 1;
1295 while (nIdx > nHyphenationPos && nAltIdx > nHyphenPos
1296 && pWord[ nIdx-- ] == pAltWord[ nAltIdx-- ])
1297 ++nR;
1299 aRes.aReplacement = OUString( aAltWord.copy( nL, nAltLen - nL - nR ) );
1300 aRes.nChangedPos = (INT16) nL;
1301 aRes.nChangedLength = nLen - nL - nR;
1302 aRes.bIsAltSpelling = TRUE;
1303 aRes.xHyphWord = rHyphWord;
1305 return aRes;
1309 ///////////////////////////////////////////////////////////////////////////
1311 SvxDicListChgClamp::SvxDicListChgClamp( uno::Reference< XDictionaryList > &rxDicList ) :
1312 xDicList ( rxDicList )
1314 if (xDicList.is())
1316 xDicList->beginCollectEvents();
1320 SvxDicListChgClamp::~SvxDicListChgClamp()
1322 if (xDicList.is())
1324 xDicList->endCollectEvents();
1328 ///////////////////////////////////////////////////////////////////////////
1330 short SvxDicError( Window *pParent, sal_Int16 nError )
1332 short nRes = 0;
1333 if (DIC_ERR_NONE != nError)
1335 int nRid;
1336 switch (nError)
1338 case DIC_ERR_FULL : nRid = RID_SVXSTR_DIC_ERR_FULL; break;
1339 case DIC_ERR_READONLY : nRid = RID_SVXSTR_DIC_ERR_READONLY; break;
1340 default:
1341 nRid = RID_SVXSTR_DIC_ERR_UNKNOWN;
1342 DBG_ASSERT(0, "unexpected case");
1344 nRes = InfoBox( pParent, SVX_RESSTR( nRid ) ).Execute();
1346 return nRes;
1349 LanguageType SvxLocaleToLanguage( const Locale& rLocale )
1351 // empty Locale -> LANGUAGE_NONE
1352 if ( rLocale.Language.getLength() == 0 )
1353 return LANGUAGE_NONE;
1355 return MsLangId::convertLocaleToLanguage( rLocale );
1358 Locale& SvxLanguageToLocale( Locale& rLocale, LanguageType eLang )
1360 if ( eLang != LANGUAGE_NONE /* && eLang != LANGUAGE_SYSTEM */)
1361 MsLangId::convertLanguageToLocale( eLang, rLocale );
1362 else
1363 rLocale = Locale();
1365 return rLocale;
1368 Locale SvxCreateLocale( LanguageType eLang )
1370 Locale aLocale;
1371 if ( eLang != LANGUAGE_NONE /* && eLang != LANGUAGE_SYSTEM */)
1372 MsLangId::convertLanguageToLocale( eLang, aLocale );
1374 return aLocale;