fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / lingucomponent / source / languageguessing / guesslang.cxx
blobcde93636194f82dec9dfe2958dcaacbfe778e485
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 <iostream>
22 #include <boost/noncopyable.hpp>
23 #include <tools/debug.hxx>
25 #include <sal/config.h>
26 #include <cppuhelper/factory.hxx>
27 #include <cppuhelper/implementationentry.hxx>
28 #include <cppuhelper/implbase2.hxx>
29 #include <cppuhelper/supportsservice.hxx>
31 #include <simpleguesser.hxx>
32 #include <guess.hxx>
34 #include <com/sun/star/lang/XServiceInfo.hpp>
35 #include <com/sun/star/linguistic2/XLanguageGuessing.hpp>
36 #include <unotools/pathoptions.hxx>
37 #include <unotools/localfilehelper.hxx>
38 #include <osl/thread.h>
40 #include <sal/macros.h>
42 #ifdef SYSTEM_LIBEXTTEXTCAT
43 #include <libexttextcat/textcat.h>
44 #else
45 #include <textcat.h>
46 #endif
48 using namespace ::osl;
49 using namespace ::cppu;
50 using namespace ::com::sun::star;
51 using namespace ::com::sun::star::uno;
52 using namespace ::com::sun::star::lang;
53 using namespace ::com::sun::star::linguistic2;
55 #define SERVICENAME "com.sun.star.linguistic2.LanguageGuessing"
56 #define IMPLNAME "com.sun.star.lingu2.LanguageGuessing"
58 static Sequence< OUString > getSupportedServiceNames_LangGuess_Impl()
60 Sequence<OUString> names(1);
61 names[0] = SERVICENAME;
62 return names;
65 static OUString getImplementationName_LangGuess_Impl()
67 return OUString( IMPLNAME );
70 static osl::Mutex & GetLangGuessMutex()
72 static osl::Mutex aMutex;
73 return aMutex;
76 class LangGuess_Impl :
77 public ::cppu::WeakImplHelper2<
78 XLanguageGuessing,
79 XServiceInfo >,
80 private boost::noncopyable
82 SimpleGuesser m_aGuesser;
83 bool m_bInitialized;
84 css::uno::Reference< css::uno::XComponentContext > m_xContext;
86 virtual ~LangGuess_Impl() {}
87 void EnsureInitialized();
89 public:
90 explicit LangGuess_Impl(css::uno::Reference< css::uno::XComponentContext > const & rxContext);
92 // XServiceInfo implementation
93 virtual OUString SAL_CALL getImplementationName( ) throw(RuntimeException, std::exception) SAL_OVERRIDE;
94 virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) throw(RuntimeException, std::exception) SAL_OVERRIDE;
95 virtual Sequence< OUString > SAL_CALL getSupportedServiceNames( ) throw(RuntimeException, std::exception) SAL_OVERRIDE;
96 static Sequence< OUString > SAL_CALL getSupportedServiceNames_Static( );
98 // XLanguageGuessing implementation
99 virtual ::com::sun::star::lang::Locale SAL_CALL guessPrimaryLanguage( const OUString& aText, ::sal_Int32 nStartPos, ::sal_Int32 nLen ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
100 virtual void SAL_CALL disableLanguages( const ::com::sun::star::uno::Sequence< ::com::sun::star::lang::Locale >& aLanguages ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
101 virtual void SAL_CALL enableLanguages( const ::com::sun::star::uno::Sequence< ::com::sun::star::lang::Locale >& aLanguages ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
102 virtual ::com::sun::star::uno::Sequence< ::com::sun::star::lang::Locale > SAL_CALL getAvailableLanguages( ) throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
103 virtual ::com::sun::star::uno::Sequence< ::com::sun::star::lang::Locale > SAL_CALL getEnabledLanguages( ) throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
104 virtual ::com::sun::star::uno::Sequence< ::com::sun::star::lang::Locale > SAL_CALL getDisabledLanguages( ) throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
106 // implementation specific
107 void SetFingerPrintsDB( const OUString &fileName ) throw (RuntimeException);
110 LangGuess_Impl::LangGuess_Impl(css::uno::Reference< css::uno::XComponentContext > const & rxContext) :
111 m_bInitialized( false ),
112 m_xContext( rxContext )
116 void LangGuess_Impl::EnsureInitialized()
118 if (!m_bInitialized)
120 // set this to true at the very start to prevent loops because of
121 // implicitly called functions below
122 m_bInitialized = true;
124 // set default fingerprint path to where those get installed
125 OUString aPhysPath;
126 OUString aURL( SvtPathOptions().GetFingerprintPath() );
127 utl::LocalFileHelper::ConvertURLToPhysicalName( aURL, aPhysPath );
128 #ifdef WNT
129 aPhysPath += "\\";
130 #else
131 aPhysPath += "/";
132 #endif
134 SetFingerPrintsDB( aPhysPath );
136 #if !defined(EXTTEXTCAT_VERSION_MAJOR)
138 // disable currently not functional languages...
139 struct LangCountry
141 const char *pLang;
142 const char *pCountry;
144 LangCountry aDisable[] =
146 // not functional in modified libtextcat, but fixed in >= libexttextcat 3.1.0
147 // which is the first with EXTTEXTCAT_VERSION_MAJOR defined
148 {"sco", ""}, {"zh", "CN"}, {"zh", "TW"}, {"ja", ""}, {"ko", ""},
149 {"ka", ""}, {"hi", ""}, {"mr", ""}, {"ne", ""}, {"sa", ""},
150 {"ta", ""}, {"th", ""}, {"qu", ""}, {"yi", ""}
152 sal_Int32 nNum = SAL_N_ELEMENTS(aDisable);
153 Sequence< Locale > aDisableSeq( nNum );
154 Locale *pDisableSeq = aDisableSeq.getArray();
155 for (sal_Int32 i = 0; i < nNum; ++i)
157 Locale aLocale;
158 aLocale.Language = OUString::createFromAscii( aDisable[i].pLang );
159 aLocale.Country = OUString::createFromAscii( aDisable[i].pCountry );
160 pDisableSeq[i] = aLocale;
162 disableLanguages( aDisableSeq );
163 DBG_ASSERT( nNum == getDisabledLanguages().getLength(), "size mismatch" );
164 #endif
168 Locale SAL_CALL LangGuess_Impl::guessPrimaryLanguage(
169 const OUString& rText,
170 ::sal_Int32 nStartPos,
171 ::sal_Int32 nLen )
172 throw (lang::IllegalArgumentException, uno::RuntimeException, std::exception)
174 osl::MutexGuard aGuard( GetLangGuessMutex() );
176 EnsureInitialized();
178 lang::Locale aRes;
179 if (nStartPos >=0 && nLen >= 0 && nStartPos + nLen <= rText.getLength())
181 OString o( OUStringToOString( rText.copy(nStartPos, nLen), RTL_TEXTENCODING_UTF8 ) );
182 Guess g = m_aGuesser.GuessPrimaryLanguage(o.getStr());
183 aRes.Language = OUString::createFromAscii( g.GetLanguage().c_str() );
184 aRes.Country = OUString::createFromAscii( g.GetCountry().c_str() );
186 else
187 throw lang::IllegalArgumentException();
189 return aRes;
192 #define DEFAULT_CONF_FILE_NAME "fpdb.conf"
194 void LangGuess_Impl::SetFingerPrintsDB(
195 const OUString &filePath )
196 throw (RuntimeException)
198 //! text encoding for file name / path needs to be in the same encoding the OS uses
199 OString path = OUStringToOString( filePath, osl_getThreadTextEncoding() );
200 OString conf_file_name( DEFAULT_CONF_FILE_NAME );
201 OString conf_file_path(path);
202 conf_file_path += conf_file_name;
204 m_aGuesser.SetDBPath((const char*)conf_file_path.getStr(), (const char*)path.getStr());
207 uno::Sequence< Locale > SAL_CALL LangGuess_Impl::getAvailableLanguages( )
208 throw (uno::RuntimeException, std::exception)
210 osl::MutexGuard aGuard( GetLangGuessMutex() );
212 EnsureInitialized();
214 Sequence< com::sun::star::lang::Locale > aRes;
215 vector<Guess> gs = m_aGuesser.GetAllManagedLanguages();
216 aRes.realloc(gs.size());
218 com::sun::star::lang::Locale *pRes = aRes.getArray();
220 for(size_t i = 0; i < gs.size() ; i++ ){
221 com::sun::star::lang::Locale current_aRes;
222 current_aRes.Language = OUString::createFromAscii( gs[i].GetLanguage().c_str() );
223 current_aRes.Country = OUString::createFromAscii( gs[i].GetCountry().c_str() );
224 pRes[i] = current_aRes;
227 return aRes;
230 uno::Sequence< Locale > SAL_CALL LangGuess_Impl::getEnabledLanguages( )
231 throw (uno::RuntimeException, std::exception)
233 osl::MutexGuard aGuard( GetLangGuessMutex() );
235 EnsureInitialized();
237 Sequence< com::sun::star::lang::Locale > aRes;
238 vector<Guess> gs = m_aGuesser.GetAvailableLanguages();
239 aRes.realloc(gs.size());
241 com::sun::star::lang::Locale *pRes = aRes.getArray();
243 for(size_t i = 0; i < gs.size() ; i++ ){
244 com::sun::star::lang::Locale current_aRes;
245 current_aRes.Language = OUString::createFromAscii( gs[i].GetLanguage().c_str() );
246 current_aRes.Country = OUString::createFromAscii( gs[i].GetCountry().c_str() );
247 pRes[i] = current_aRes;
250 return aRes;
253 uno::Sequence< Locale > SAL_CALL LangGuess_Impl::getDisabledLanguages( )
254 throw (uno::RuntimeException, std::exception)
256 osl::MutexGuard aGuard( GetLangGuessMutex() );
258 EnsureInitialized();
260 Sequence< com::sun::star::lang::Locale > aRes;
261 vector<Guess> gs = m_aGuesser.GetUnavailableLanguages();
262 aRes.realloc(gs.size());
264 com::sun::star::lang::Locale *pRes = aRes.getArray();
266 for(size_t i = 0; i < gs.size() ; i++ ){
267 com::sun::star::lang::Locale current_aRes;
268 current_aRes.Language = OUString::createFromAscii( gs[i].GetLanguage().c_str() );
269 current_aRes.Country = OUString::createFromAscii( gs[i].GetCountry().c_str() );
270 pRes[i] = current_aRes;
273 return aRes;
276 void SAL_CALL LangGuess_Impl::disableLanguages(
277 const uno::Sequence< Locale >& rLanguages )
278 throw (lang::IllegalArgumentException, uno::RuntimeException, std::exception)
280 osl::MutexGuard aGuard( GetLangGuessMutex() );
282 EnsureInitialized();
284 sal_Int32 nLanguages = rLanguages.getLength();
285 const Locale *pLanguages = rLanguages.getConstArray();
287 for (sal_Int32 i = 0; i < nLanguages; ++i)
289 string language;
291 OString l = OUStringToOString( pLanguages[i].Language, RTL_TEXTENCODING_ASCII_US );
292 OString c = OUStringToOString( pLanguages[i].Country, RTL_TEXTENCODING_ASCII_US );
294 language += l.getStr();
295 language += "-";
296 language += c.getStr();
297 m_aGuesser.DisableLanguage(language);
301 void SAL_CALL LangGuess_Impl::enableLanguages(
302 const uno::Sequence< Locale >& rLanguages )
303 throw (lang::IllegalArgumentException, uno::RuntimeException, std::exception)
305 osl::MutexGuard aGuard( GetLangGuessMutex() );
307 EnsureInitialized();
309 sal_Int32 nLanguages = rLanguages.getLength();
310 const Locale *pLanguages = rLanguages.getConstArray();
312 for (sal_Int32 i = 0; i < nLanguages; ++i)
314 string language;
316 OString l = OUStringToOString( pLanguages[i].Language, RTL_TEXTENCODING_ASCII_US );
317 OString c = OUStringToOString( pLanguages[i].Country, RTL_TEXTENCODING_ASCII_US );
319 language += l.getStr();
320 language += "-";
321 language += c.getStr();
322 m_aGuesser.EnableLanguage(language);
326 OUString SAL_CALL LangGuess_Impl::getImplementationName( )
327 throw(RuntimeException, std::exception)
329 osl::MutexGuard aGuard( GetLangGuessMutex() );
330 return OUString( IMPLNAME );
333 sal_Bool SAL_CALL LangGuess_Impl::supportsService( const OUString& ServiceName )
334 throw(RuntimeException, std::exception)
336 return cppu::supportsService(this, ServiceName);
339 Sequence<OUString> SAL_CALL LangGuess_Impl::getSupportedServiceNames( )
340 throw(RuntimeException, std::exception)
342 osl::MutexGuard aGuard( GetLangGuessMutex() );
343 return getSupportedServiceNames_Static();
346 Sequence<OUString> SAL_CALL LangGuess_Impl::getSupportedServiceNames_Static( )
348 OUString aName( SERVICENAME );
349 return Sequence< OUString >( &aName, 1 );
353 * Function to create a new component instance; is needed by factory helper implementation.
354 * @param xMgr service manager to if the components needs other component instances
356 Reference< XInterface > SAL_CALL LangGuess_Impl_create(
357 Reference< XComponentContext > const & xContext )
359 return static_cast< ::cppu::OWeakObject * >( new LangGuess_Impl(xContext) );
362 //#### EXPORTED ### functions to allow for registration and creation of the UNO component
363 static const struct ::cppu::ImplementationEntry s_component_entries [] =
366 LangGuess_Impl_create, getImplementationName_LangGuess_Impl,
367 getSupportedServiceNames_LangGuess_Impl,
368 ::cppu::createSingleComponentFactory,
369 0, 0
371 { 0, 0, 0, 0, 0, 0 }
374 extern "C"
377 SAL_DLLPUBLIC_EXPORT void * SAL_CALL guesslang_component_getFactory(
378 sal_Char const * implName, void * xMgr,
379 void * xRegistry )
381 return ::cppu::component_getFactoryHelper(
382 implName, xMgr, xRegistry, s_component_entries );
387 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */