update emoji autocorrect entries from po-files
[LibreOffice.git] / linguistic / source / thesdsp.cxx
blob4386f400c9856d236bd5965f8711565352f5c23c
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <i18nlangtag/lang.h>
21 #include <tools/debug.hxx>
22 #include <svl/lngmisc.hxx>
24 #include <cppuhelper/factory.hxx>
25 #include <com/sun/star/registry/XRegistryKey.hpp>
26 #include <com/sun/star/beans/XPropertySet.hpp>
27 #include <comphelper/processfactory.hxx>
28 #include <osl/mutex.hxx>
30 #include "thesdsp.hxx"
31 #include "linguistic/lngprops.hxx"
33 using namespace osl;
34 using namespace com::sun::star;
35 using namespace com::sun::star::beans;
36 using namespace com::sun::star::lang;
37 using namespace com::sun::star::uno;
38 using namespace com::sun::star::linguistic2;
39 using namespace linguistic;
43 static bool SvcListHasLanguage(
44 const Sequence< Reference< XThesaurus > > &rRefs,
45 const Locale &rLocale )
47 bool bHasLanguage = false;
49 const Reference< XThesaurus > *pRef = rRefs.getConstArray();
50 sal_Int32 nLen = rRefs.getLength();
51 for (sal_Int32 k = 0; k < nLen && !bHasLanguage; ++k)
53 if (pRef[k].is())
54 bHasLanguage = pRef[k]->hasLocale( rLocale );
57 return bHasLanguage;
62 ThesaurusDispatcher::ThesaurusDispatcher()
67 ThesaurusDispatcher::~ThesaurusDispatcher()
69 ClearSvcList();
73 void ThesaurusDispatcher::ClearSvcList()
75 // release memory for each table entry
76 ThesSvcByLangMap_t aTmp;
77 aSvcMap.swap( aTmp );
81 Sequence< Locale > SAL_CALL
82 ThesaurusDispatcher::getLocales()
83 throw(RuntimeException, std::exception)
85 MutexGuard aGuard( GetLinguMutex() );
87 Sequence< Locale > aLocales( static_cast< sal_Int32 >(aSvcMap.size()) );
88 Locale *pLocales = aLocales.getArray();
89 ThesSvcByLangMap_t::const_iterator aIt;
90 for (aIt = aSvcMap.begin(); aIt != aSvcMap.end(); ++aIt)
92 *pLocales++ = LanguageTag::convertToLocale( aIt->first );
94 return aLocales;
98 sal_Bool SAL_CALL
99 ThesaurusDispatcher::hasLocale( const Locale& rLocale )
100 throw(RuntimeException, std::exception)
102 MutexGuard aGuard( GetLinguMutex() );
103 ThesSvcByLangMap_t::const_iterator aIt( aSvcMap.find( LinguLocaleToLanguage( rLocale ) ) );
104 return aIt != aSvcMap.end();
108 Sequence< Reference< XMeaning > > SAL_CALL
109 ThesaurusDispatcher::queryMeanings(
110 const OUString& rTerm, const Locale& rLocale,
111 const PropertyValues& rProperties )
112 throw(IllegalArgumentException, RuntimeException, std::exception)
114 MutexGuard aGuard( GetLinguMutex() );
116 Sequence< Reference< XMeaning > > aMeanings;
118 sal_Int16 nLanguage = LinguLocaleToLanguage( rLocale );
119 if (LinguIsUnspecified( nLanguage) || rTerm.isEmpty())
120 return aMeanings;
122 // search for entry with that language
123 ThesSvcByLangMap_t::iterator aIt( aSvcMap.find( nLanguage ) );
124 LangSvcEntries_Thes *pEntry = aIt != aSvcMap.end() ? aIt->second.get() : NULL;
126 if (pEntry)
128 OUString aChkWord( rTerm );
129 aChkWord = aChkWord.replace( SVT_HARD_SPACE, ' ' );
130 RemoveHyphens( aChkWord );
131 if (IsIgnoreControlChars( rProperties, GetPropSet() ))
132 RemoveControlChars( aChkWord );
134 sal_Int32 nLen = pEntry->aSvcRefs.getLength();
135 DBG_ASSERT( nLen == pEntry->aSvcImplNames.getLength(),
136 "lng : sequence length mismatch");
137 DBG_ASSERT( pEntry->nLastTriedSvcIndex < nLen,
138 "lng : index out of range");
140 sal_Int32 i = 0;
142 // try already instantiated services first
144 const Reference< XThesaurus > *pRef = pEntry->aSvcRefs.getConstArray();
145 while (i <= pEntry->nLastTriedSvcIndex
146 && aMeanings.getLength() == 0)
148 if (pRef[i].is() && pRef[i]->hasLocale( rLocale ))
149 aMeanings = pRef[i]->queryMeanings( aChkWord, rLocale, rProperties );
150 ++i;
154 // if still no result instantiate new services and try those
155 if (aMeanings.getLength() == 0
156 && pEntry->nLastTriedSvcIndex < nLen - 1)
158 const OUString *pImplNames = pEntry->aSvcImplNames.getConstArray();
159 Reference< XThesaurus > *pRef = pEntry->aSvcRefs.getArray();
161 Reference< XComponentContext > xContext(
162 comphelper::getProcessComponentContext() );
164 // build service initialization argument
165 Sequence< Any > aArgs(1);
166 aArgs.getArray()[0] <<= GetPropSet();
168 while (i < nLen && aMeanings.getLength() == 0)
170 // create specific service via it's implementation name
171 Reference< XThesaurus > xThes;
174 xThes = Reference< XThesaurus >(
175 xContext->getServiceManager()->createInstanceWithArgumentsAndContext(
176 pImplNames[i], aArgs, xContext ),
177 UNO_QUERY );
179 catch (uno::Exception &)
181 DBG_ASSERT( false, "createInstanceWithArguments failed" );
183 pRef[i] = xThes;
185 if (xThes.is() && xThes->hasLocale( rLocale ))
186 aMeanings = xThes->queryMeanings( aChkWord, rLocale, rProperties );
188 pEntry->nLastTriedSvcIndex = (sal_Int16) i;
189 ++i;
192 // if language is not supported by any of the services
193 // remove it from the list.
194 if (i == nLen && aMeanings.getLength() == 0)
196 if (!SvcListHasLanguage( pEntry->aSvcRefs, rLocale ))
197 aSvcMap.erase( nLanguage );
202 return aMeanings;
206 void ThesaurusDispatcher::SetServiceList( const Locale &rLocale,
207 const Sequence< OUString > &rSvcImplNames )
209 MutexGuard aGuard( GetLinguMutex() );
211 sal_Int16 nLanguage = LinguLocaleToLanguage( rLocale );
213 sal_Int32 nLen = rSvcImplNames.getLength();
214 if (0 == nLen)
215 // remove entry
216 aSvcMap.erase( nLanguage );
217 else
219 // modify/add entry
220 LangSvcEntries_Thes *pEntry = aSvcMap[ nLanguage ].get();
221 if (pEntry)
223 pEntry->Clear();
224 pEntry->aSvcImplNames = rSvcImplNames;
225 pEntry->aSvcRefs = Sequence< Reference < XThesaurus > >( nLen );
227 else
229 boost::shared_ptr< LangSvcEntries_Thes > pTmpEntry( new LangSvcEntries_Thes( rSvcImplNames ) );
230 pTmpEntry->aSvcRefs = Sequence< Reference < XThesaurus > >( nLen );
231 aSvcMap[ nLanguage ] = pTmpEntry;
237 Sequence< OUString >
238 ThesaurusDispatcher::GetServiceList( const Locale &rLocale ) const
240 MutexGuard aGuard( GetLinguMutex() );
242 Sequence< OUString > aRes;
244 // search for entry with that language and use data from that
245 sal_Int16 nLanguage = LinguLocaleToLanguage( rLocale );
246 const ThesSvcByLangMap_t::const_iterator aIt( aSvcMap.find( nLanguage ) );
247 const LangSvcEntries_Thes *pEntry = aIt != aSvcMap.end() ? aIt->second.get() : NULL;
248 if (pEntry)
249 aRes = pEntry->aSvcImplNames;
251 return aRes;
255 LinguDispatcher::DspType ThesaurusDispatcher::GetDspType() const
257 return DSP_THES;
262 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */