LibreOffice Module lingucomponent (master) 1
sspellimp.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include <com/sun/star/uno/Reference.h>
21
22#include <com/sun/star/linguistic2/SpellFailure.hpp>
23#include <com/sun/star/linguistic2/XLinguProperties.hpp>
24#include <comphelper/lok.hxx>
27#include <cppuhelper/weak.hxx>
28#include <com/sun/star/lang/XMultiServiceFactory.hpp>
29#include <tools/debug.hxx>
30#include <osl/mutex.hxx>
31#include <osl/thread.h>
32#include <com/sun/star/ucb/XSimpleFileAccess.hpp>
33
34#include <lingutil.hxx>
35#include <hunspell.hxx>
36#include "sspellimp.hxx"
37
38#include <linguistic/misc.hxx>
41#include <svtools/strings.hrc>
42#include <unotools/lingucfg.hxx>
43#include <unotools/resmgr.hxx>
44#include <osl/file.hxx>
45#include <rtl/ustrbuf.hxx>
46#include <rtl/textenc.h>
47#include <sal/log.hxx>
48
49#include <numeric>
50#include <utility>
51#include <vector>
52#include <set>
53#include <string.h>
54
55using namespace utl;
56using namespace osl;
57using namespace com::sun::star;
58using namespace com::sun::star::beans;
59using namespace com::sun::star::lang;
60using namespace com::sun::star::uno;
61using namespace com::sun::star::linguistic2;
62using namespace linguistic;
63
64// XML-header of SPELLML queries
65#if !defined SPELL_XML
66constexpr OUStringLiteral SPELL_XML = u"<?xml?>";
67#endif
68
69// only available in hunspell >= 1.5
70#if !defined MAXWORDLEN
71#define MAXWORDLEN 176
72#endif
73
75 m_aEvtListeners(GetLinguMutex()),
76 m_bDisposing(false)
77{
78}
79
80SpellChecker::DictItem::DictItem(OUString i_DName, Locale i_DLoc, rtl_TextEncoding i_DEnc)
81 : m_aDName(std::move(i_DName))
82 , m_aDLoc(std::move(i_DLoc))
83 , m_aDEnc(i_DEnc)
84{
85}
86
88{
89 if (m_pPropHelper)
90 {
91 m_pPropHelper->RemoveAsPropListener();
92 }
93}
94
95PropertyHelper_Spelling & SpellChecker::GetPropHelper_Impl()
96{
97 if (!m_pPropHelper)
98 {
100
101 m_pPropHelper.reset( new PropertyHelper_Spelling( static_cast<XSpellChecker *>(this), xPropSet ) );
102 m_pPropHelper->AddAsPropListener();
103 }
104 return *m_pPropHelper;
105}
106
108{
109 MutexGuard aGuard( GetLinguMutex() );
110
111 // this routine should return the locales supported by the installed
112 // dictionaries.
113 if (m_DictItems.empty())
114 {
115 SvtLinguConfig aLinguCfg;
116
117 // get list of extension dictionaries-to-use
118 // (or better speaking: the list of dictionaries using the
119 // new configuration entries).
120 std::vector< SvtLinguConfigDictionaryEntry > aDics;
121 uno::Sequence< OUString > aFormatList;
122 aLinguCfg.GetSupportedDictionaryFormatsFor( "SpellCheckers",
123 "org.openoffice.lingu.MySpellSpellChecker", aFormatList );
124 for (auto const& format : std::as_const(aFormatList))
125 {
126 std::vector< SvtLinguConfigDictionaryEntry > aTmpDic(
127 aLinguCfg.GetActiveDictionariesByFormat(format) );
128 aDics.insert( aDics.end(), aTmpDic.begin(), aTmpDic.end() );
129 }
130
134 std::vector< SvtLinguConfigDictionaryEntry > aOldStyleDics(
135 GetOldStyleDics( "DICT" ) );
136
137 // to prefer dictionaries with configuration entries we will only
138 // use those old style dictionaries that add a language that
139 // is not yet supported by the list of new style dictionaries
140 MergeNewStyleDicsAndOldStyleDics( aDics, aOldStyleDics );
141
142 if (!aDics.empty())
143 {
144 uno::Reference< lang::XMultiServiceFactory > xServiceFactory(comphelper::getProcessServiceFactory());
145 uno::Reference< ucb::XSimpleFileAccess > xAccess(xServiceFactory->createInstance("com.sun.star.ucb.SimpleFileAccess"), uno::UNO_QUERY);
146 // get supported locales from the dictionaries-to-use...
147 std::set<OUString> aLocaleNamesSet;
148 for (auto const& dict : aDics)
149 {
150 const uno::Sequence< OUString > aLocaleNames( dict.aLocaleNames );
151 uno::Sequence< OUString > aLocations( dict.aLocations );
153 aLocaleNames.hasElements() && !aLocations.hasElements(),
154 "lingucomponent", "no locations");
155 if (aLocations.hasElements())
156 {
157 if (xAccess.is() && xAccess->exists(aLocations[0]))
158 {
159 for (auto const& locale : aLocaleNames)
160 {
162 continue;
163
164 aLocaleNamesSet.insert(locale);
165 }
166 }
167 else
168 {
169 SAL_WARN(
170 "lingucomponent",
171 "missing <" << aLocations[0] << ">");
172 }
173 }
174 }
175 // ... and add them to the resulting sequence
176 m_aSuppLocales.realloc( aLocaleNamesSet.size() );
177 std::transform(
178 aLocaleNamesSet.begin(), aLocaleNamesSet.end(), m_aSuppLocales.getArray(),
179 [](auto const& localeName) { return LanguageTag::convertToLocale(localeName); });
180
186 sal_uInt32 nDictSize = std::accumulate(aDics.begin(), aDics.end(), sal_uInt32(0),
187 [](const sal_uInt32 nSum, const SvtLinguConfigDictionaryEntry& dict) {
188 return nSum + dict.aLocaleNames.getLength(); });
189
190 // add dictionary information
191 m_DictItems.reserve(nDictSize);
192 for (auto const& dict : aDics)
193 {
194 if (dict.aLocaleNames.hasElements() &&
195 dict.aLocations.hasElements())
196 {
197 const uno::Sequence< OUString > aLocaleNames( dict.aLocaleNames );
198
199 // currently only one language per dictionary is supported in the actual implementation...
200 // Thus here we work-around this by adding the same dictionary several times.
201 // Once for each of its supported locales.
202 for (auto const& localeName : aLocaleNames)
203 {
204 // also both files have to be in the same directory and the
205 // file names must only differ in the extension (.aff/.dic).
206 // Thus we use the first location only and strip the extension part.
207 OUString aLocation = dict.aLocations[0];
208 sal_Int32 nPos = aLocation.lastIndexOf( '.' );
209 aLocation = aLocation.copy( 0, nPos );
210
211 m_DictItems.emplace_back(aLocation, LanguageTag::convertToLocale(localeName), RTL_TEXTENCODING_DONTKNOW);
212 }
213 }
214 }
215 DBG_ASSERT( nDictSize == m_DictItems.size(), "index mismatch?" );
216 }
217 else
218 {
219 // no dictionary found so register no dictionaries
220 m_aSuppLocales.realloc(0);
221 }
222 }
223
224 return m_aSuppLocales;
225}
226
227sal_Bool SAL_CALL SpellChecker::hasLocale(const Locale& rLocale)
228{
229 MutexGuard aGuard( GetLinguMutex() );
230
231 bool bRes = false;
232 if (!m_aSuppLocales.hasElements())
233 getLocales();
234
235 for (auto const& suppLocale : std::as_const(m_aSuppLocales))
236 {
237 if (rLocale == suppLocale)
238 {
239 bRes = true;
240 break;
241 }
242 }
243 return bRes;
244}
245
246sal_Int16 SpellChecker::GetSpellFailure(const OUString &rWord, const Locale &rLocale, int& rInfo)
247{
248 if (rWord.getLength() > MAXWORDLEN)
249 return -1;
250
251 Hunspell * pMS = nullptr;
252 rtl_TextEncoding eEnc = RTL_TEXTENCODING_DONTKNOW;
253
254 // initialize a myspell object for each dictionary once
255 // (note: mutex is held higher up in isValid)
256
257 sal_Int16 nRes = -1;
258
259 // first handle smart quotes both single and double
260 OUStringBuffer rBuf(rWord);
261 sal_Int32 n = rBuf.getLength();
262 sal_Unicode c;
263 sal_Int32 extrachar = 0;
264
265 for (sal_Int32 ix=0; ix < n; ix++)
266 {
267 c = rBuf[ix];
268 if ((c == 0x201C) || (c == 0x201D))
269 rBuf[ix] = u'"';
270 else if ((c == 0x2018) || (c == 0x2019))
271 rBuf[ix] = u'\'';
272
273 // recognize words with Unicode ligatures and ZWNJ/ZWJ characters (only
274 // with 8-bit encoded dictionaries. For UTF-8 encoded dictionaries
275 // set ICONV and IGNORE aff file options, if needed.)
276 else if ((c == 0x200C) || (c == 0x200D) ||
277 ((c >= 0xFB00) && (c <= 0xFB04)))
278 extrachar = 1;
279 }
280 OUString nWord(rBuf.makeStringAndClear());
281
282 if (n)
283 {
284 for (auto& currDict : m_DictItems)
285 {
286 pMS = nullptr;
287 eEnc = RTL_TEXTENCODING_DONTKNOW;
288
289 if (rLocale == currDict.m_aDLoc)
290 {
291 if (!currDict.m_pDict)
292 {
293 OUString dicpath = currDict.m_aDName + ".dic";
294 OUString affpath = currDict.m_aDName + ".aff";
295 OUString dict;
296 OUString aff;
297 osl::FileBase::getSystemPathFromFileURL(dicpath,dict);
298 osl::FileBase::getSystemPathFromFileURL(affpath,aff);
299#if defined(_WIN32)
300 // workaround for Windows specific problem that the
301 // path length in calls to 'fopen' is limited to somewhat
302 // about 120+ characters which will usually be exceed when
303 // using dictionaries as extensions. (Hunspell waits UTF-8 encoded
304 // path with \\?\ long path prefix.)
305 OString aTmpaff = Win_AddLongPathPrefix(OUStringToOString(aff, RTL_TEXTENCODING_UTF8));
306 OString aTmpdict = Win_AddLongPathPrefix(OUStringToOString(dict, RTL_TEXTENCODING_UTF8));
307#else
308 OString aTmpaff(OU2ENC(aff,osl_getThreadTextEncoding()));
309 OString aTmpdict(OU2ENC(dict,osl_getThreadTextEncoding()));
310#endif
311
312 currDict.m_pDict = std::make_unique<Hunspell>(aTmpaff.getStr(),aTmpdict.getStr());
313#if defined(H_DEPRECATED)
314 currDict.m_aDEnc = getTextEncodingFromCharset(currDict.m_pDict->get_dict_encoding().c_str());
315#else
316 currDict.m_aDEnc = getTextEncodingFromCharset(currDict.m_pDict->get_dic_encoding());
317#endif
318 }
319 pMS = currDict.m_pDict.get();
320 eEnc = currDict.m_aDEnc;
321 }
322
323 if (pMS)
324 {
325 // we don't want to work with a default text encoding since following incorrect
326 // results may occur only for specific text and thus may be hard to notice.
327 // Thus better always make a clean exit here if the text encoding is in question.
328 // Hopefully something not working at all will raise proper attention quickly. ;-)
329 DBG_ASSERT( eEnc != RTL_TEXTENCODING_DONTKNOW, "failed to get text encoding! (maybe incorrect encoding string in file)" );
330 if (eEnc == RTL_TEXTENCODING_DONTKNOW)
331 return -1;
332
333 OString aWrd(OU2ENC(nWord,eEnc));
334#if defined(H_DEPRECATED)
335 bool bVal = pMS->spell(std::string(aWrd), &rInfo);
336#else
337 bool bVal = pMS->spell(aWrd.getStr(), &rInfo) != 0;
338#endif
339 if (!bVal) {
340 if (extrachar && (eEnc != RTL_TEXTENCODING_UTF8)) {
341 OUStringBuffer aBuf(nWord);
342 n = aBuf.getLength();
343 for (sal_Int32 ix=n-1; ix >= 0; ix--)
344 {
345 switch (aBuf[ix]) {
346 case 0xFB00: aBuf.remove(ix, 1); aBuf.insert(ix, "ff"); break;
347 case 0xFB01: aBuf.remove(ix, 1); aBuf.insert(ix, "fi"); break;
348 case 0xFB02: aBuf.remove(ix, 1); aBuf.insert(ix, "fl"); break;
349 case 0xFB03: aBuf.remove(ix, 1); aBuf.insert(ix, "ffi"); break;
350 case 0xFB04: aBuf.remove(ix, 1); aBuf.insert(ix, "ffl"); break;
351 case 0x200C:
352 case 0x200D: aBuf.remove(ix, 1); break;
353 }
354 }
355 OUString aWord(aBuf.makeStringAndClear());
356 OString bWrd(OU2ENC(aWord, eEnc));
357#if defined(H_DEPRECATED)
358 bVal = pMS->spell(std::string(bWrd), &rInfo);
359#else
360 bVal = pMS->spell(bWrd.getStr(), &rInfo) != 0;
361#endif
362 if (bVal) return -1;
363 }
364 nRes = SpellFailure::SPELLING_ERROR;
365 } else {
366 return -1;
367 }
368 pMS = nullptr;
369 }
370 }
371 }
372
373 return nRes;
374}
375
376sal_Bool SAL_CALL SpellChecker::isValid( const OUString& rWord, const Locale& rLocale,
377 const css::uno::Sequence< css::beans::PropertyValue >& rProperties )
378{
379 MutexGuard aGuard( GetLinguMutex() );
380
381 if (rLocale == Locale() || rWord.isEmpty())
382 return true;
383
384 if (!hasLocale( rLocale ))
385 return true;
386
387 // return sal_False to process SPELLML requests (they are longer than the header)
388 if (rWord.match(SPELL_XML, 0) && (rWord.getLength() > 10)) return false;
389
390 // Get property values to be used.
391 // These are be the default values set in the SN_LINGU_PROPERTIES
392 // PropertySet which are overridden by the supplied ones from the
393 // last argument.
394 // You'll probably like to use a simpler solution than the provided
395 // one using the PropertyHelper_Spell.
396 PropertyHelper_Spelling& rHelper = GetPropHelper();
397 rHelper.SetTmpPropVals( rProperties );
398
399 int nInfo = 0;
400 sal_Int16 nFailure = GetSpellFailure( rWord, rLocale, nInfo );
401 if (nFailure != -1 && !rWord.match(SPELL_XML, 0))
402 {
403 LanguageType nLang = LinguLocaleToLanguage( rLocale );
404 // postprocess result for errors that should be ignored
405 const bool bIgnoreError =
406 (!rHelper.IsSpellUpperCase() && IsUpper( rWord, nLang )) ||
407 (!rHelper.IsSpellWithDigits() && HasDigits( rWord )) ||
408 (!rHelper.IsSpellCapitalization() && nFailure == SpellFailure::CAPTION_ERROR);
409 if (bIgnoreError)
410 nFailure = -1;
411 }
412//#define SPELL_COMPOUND 1 << 0
413
414 // valid word, but it's a rule-based compound word
415 if ( nFailure == -1 && (nInfo & SPELL_COMPOUND) )
416 {
417 bool bHasHyphen = rWord.indexOf('-') > -1;
418 if ( (bHasHyphen && !rHelper.IsSpellHyphenatedCompound()) ||
419 (!bHasHyphen && !rHelper.IsSpellClosedCompound()) )
420 {
421 return false;
422 }
423 }
424
425 return (nFailure == -1);
426}
427
429 SpellChecker::GetProposals( const OUString &rWord, const Locale &rLocale )
430{
431 // Retrieves the return values for the 'spell' function call in case
432 // of a misspelled word.
433 // Especially it may give a list of suggested (correct) words:
435 // note: mutex is held by higher up by spell which covers both
436
437 Hunspell* pMS = nullptr;
438 rtl_TextEncoding eEnc = RTL_TEXTENCODING_DONTKNOW;
439
440 // first handle smart quotes (single and double)
441 OUStringBuffer rBuf(rWord);
442 sal_Int32 n = rBuf.getLength();
443 sal_Unicode c;
444 for (sal_Int32 ix=0; ix < n; ix++)
445 {
446 c = rBuf[ix];
447 if ((c == 0x201C) || (c == 0x201D))
448 rBuf[ix] = u'"';
449 if ((c == 0x2018) || (c == 0x2019))
450 rBuf[ix] = u'\'';
451 }
452 OUString nWord(rBuf.makeStringAndClear());
453
454 if (n)
455 {
456 LanguageType nLang = LinguLocaleToLanguage( rLocale );
457 int numsug = 0;
458
460 for (const auto& currDict : m_DictItems)
461 {
462 pMS = nullptr;
463 eEnc = RTL_TEXTENCODING_DONTKNOW;
464
465 if (rLocale == currDict.m_aDLoc)
466 {
467 pMS = currDict.m_pDict.get();
468 eEnc = currDict.m_aDEnc;
469 }
470
471 if (pMS)
472 {
473 OString aWrd(OU2ENC(nWord,eEnc));
474#if defined(H_DEPRECATED)
475 std::vector<std::string> suglst = pMS->suggest(std::string(aWrd));
476 if (!suglst.empty())
477 {
478 aStr.realloc(numsug + suglst.size());
479 OUString *pStr = aStr.getArray();
480 for (size_t ii = 0; ii < suglst.size(); ++ii)
481 {
482 OUString cvtwrd(suglst[ii].c_str(), suglst[ii].size(), eEnc);
483 pStr[numsug + ii] = cvtwrd;
484 }
485 numsug += suglst.size();
486 }
487#else
488 char ** suglst = nullptr;
489 int count = pMS->suggest(&suglst, aWrd.getStr());
490 if (count)
491 {
492 aStr.realloc( numsug + count );
493 OUString *pStr = aStr.getArray();
494 for (int ii=0; ii < count; ++ii)
495 {
496 OUString cvtwrd(suglst[ii],strlen(suglst[ii]),eEnc);
497 pStr[numsug + ii] = cvtwrd;
498 }
499 numsug += count;
500 }
501 pMS->free_list(&suglst, count);
502#endif
503 }
504 }
505
506 // now return an empty alternative for no suggestions or the list of alternatives if some found
507 xRes = SpellAlternatives::CreateSpellAlternatives( rWord, nLang, SpellFailure::SPELLING_ERROR, aStr );
508 return xRes;
509 }
510 return xRes;
511}
512
514 const OUString& rWord, const Locale& rLocale,
515 const css::uno::Sequence< css::beans::PropertyValue >& rProperties )
516{
517 MutexGuard aGuard( GetLinguMutex() );
518
519 if (rLocale == Locale() || rWord.isEmpty())
520 return nullptr;
521
522 if (!hasLocale( rLocale ))
523 return nullptr;
524
526 if (!isValid( rWord, rLocale, rProperties ))
527 {
528 xAlt = GetProposals( rWord, rLocale );
529 }
530 return xAlt;
531}
532
535{
536 MutexGuard aGuard( GetLinguMutex() );
537
538 bool bRes = false;
539 if (!m_bDisposing && rxLstnr.is())
540 {
541 bRes = GetPropHelper().addLinguServiceEventListener( rxLstnr );
542 }
543 return bRes;
544}
545
548{
549 MutexGuard aGuard( GetLinguMutex() );
550
551 bool bRes = false;
552 if (!m_bDisposing && rxLstnr.is())
553 {
554 bRes = GetPropHelper().removeLinguServiceEventListener( rxLstnr );
555 }
556 return bRes;
557}
558
559OUString SAL_CALL SpellChecker::getServiceDisplayName(const Locale& rLocale)
560{
561 std::locale loc(Translate::Create("svt", LanguageTag(rLocale)));
562 return Translate::get(STR_DESCRIPTION_HUNSPELL, loc);
563}
564
565void SAL_CALL SpellChecker::initialize( const Sequence< Any >& rArguments )
566{
567 MutexGuard aGuard( GetLinguMutex() );
568
569 if (m_pPropHelper)
570 return;
571
572 sal_Int32 nLen = rArguments.getLength();
573 if (2 == nLen)
574 {
576 rArguments.getConstArray()[0] >>= xPropSet;
577 // rArguments.getConstArray()[1] >>= xDicList;
578
583 m_pPropHelper.reset( new PropertyHelper_Spelling( static_cast<XSpellChecker *>(this), xPropSet ) );
584 m_pPropHelper->AddAsPropListener();
585 }
586 else {
587 OSL_FAIL( "wrong number of arguments in sequence" );
588 }
589}
590
592{
593 MutexGuard aGuard( GetLinguMutex() );
594
595 if (!m_bDisposing)
596 {
597 m_bDisposing = true;
598 EventObject aEvtObj( static_cast<XSpellChecker *>(this) );
600 if (m_pPropHelper)
601 {
602 m_pPropHelper->RemoveAsPropListener();
603 m_pPropHelper.reset();
604 }
605 }
606}
607
609{
610 MutexGuard aGuard( GetLinguMutex() );
611
612 if (!m_bDisposing && rxListener.is())
613 m_aEvtListeners.addInterface( rxListener );
614}
615
617{
618 MutexGuard aGuard( GetLinguMutex() );
619
620 if (!m_bDisposing && rxListener.is())
621 m_aEvtListeners.removeInterface( rxListener );
622}
623
624// Service specific part
626{
627 return "org.openoffice.lingu.MySpellSpellChecker";
628}
629
630sal_Bool SAL_CALL SpellChecker::supportsService( const OUString& ServiceName )
631{
633}
634
636{
637 return { SN_SPELLCHECKER };
638}
639
640extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
642 css::uno::XComponentContext* , css::uno::Sequence<css::uno::Any> const&)
643{
644 return cppu::acquire(new SpellChecker());
645}
646
647
648/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static css::lang::Locale convertToLocale(LanguageType nLangID, bool bResolveSystem=true)
bool m_bDisposing
Definition: sspellimp.hxx:71
linguistic::PropertyHelper_Spelling & GetPropHelper_Impl()
Definition: sspellimp.cxx:95
virtual ~SpellChecker() override
Definition: sspellimp.cxx:87
virtual sal_Bool SAL_CALL addLinguServiceEventListener(const Reference< XLinguServiceEventListener > &rxLstnr) override
Definition: sspellimp.cxx:533
virtual Sequence< Locale > SAL_CALL getLocales() override
Definition: sspellimp.cxx:107
virtual void SAL_CALL initialize(const Sequence< Any > &rArguments) override
Definition: sspellimp.cxx:565
::comphelper::OInterfaceContainerHelper3< XEventListener > m_aEvtListeners
Definition: sspellimp.hxx:69
virtual sal_Bool SAL_CALL isValid(const OUString &rWord, const Locale &rLocale, const css::uno::Sequence< css::beans::PropertyValue > &rProperties) override
Definition: sspellimp.cxx:376
virtual void SAL_CALL addEventListener(const Reference< XEventListener > &rxListener) override
Definition: sspellimp.cxx:608
Reference< XSpellAlternatives > GetProposals(const OUString &rWord, const Locale &rLocale)
Definition: sspellimp.cxx:429
linguistic::PropertyHelper_Spelling & GetPropHelper()
Definition: sspellimp.hxx:77
virtual OUString SAL_CALL getServiceDisplayName(const Locale &rLocale) override
Definition: sspellimp.cxx:559
virtual sal_Bool SAL_CALL hasLocale(const Locale &rLocale) override
Definition: sspellimp.cxx:227
std::unique_ptr< linguistic::PropertyHelper_Spelling > m_pPropHelper
Definition: sspellimp.hxx:70
Sequence< Locale > m_aSuppLocales
Definition: sspellimp.hxx:67
virtual sal_Bool SAL_CALL supportsService(const OUString &rServiceName) override
Definition: sspellimp.cxx:630
virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() override
Definition: sspellimp.cxx:635
virtual OUString SAL_CALL getImplementationName() override
Definition: sspellimp.cxx:625
virtual Reference< XSpellAlternatives > SAL_CALL spell(const OUString &rWord, const Locale &rLocale, const css::uno::Sequence< css::beans::PropertyValue > &rProperties) override
Definition: sspellimp.cxx:513
virtual void SAL_CALL dispose() override
Definition: sspellimp.cxx:591
virtual void SAL_CALL removeEventListener(const Reference< XEventListener > &rxListener) override
Definition: sspellimp.cxx:616
std::vector< DictItem > m_DictItems
Definition: sspellimp.hxx:65
sal_Int16 GetSpellFailure(const OUString &rWord, const Locale &rLocale, int &rInfo)
Definition: sspellimp.cxx:246
virtual sal_Bool SAL_CALL removeLinguServiceEventListener(const Reference< XLinguServiceEventListener > &rxLstnr) override
Definition: sspellimp.cxx:546
std::vector< SvtLinguConfigDictionaryEntry > GetActiveDictionariesByFormat(std::u16string_view rFormatName) const
bool GetSupportedDictionaryFormatsFor(const OUString &rSetName, const OUString &rSetEntry, css::uno::Sequence< OUString > &rFormatList) const
sal_Int32 addInterface(const css::uno::Reference< ListenerT > &rxIFace)
void disposeAndClear(const css::lang::EventObject &rEvt)
sal_Int32 removeInterface(const css::uno::Reference< ListenerT > &rxIFace)
#define DBG_ASSERT(sCon, aError)
float u
sal_Int64 n
std::vector< SvtLinguConfigDictionaryEntry > GetOldStyleDics(const char *pDicType)
Definition: lingutil.cxx:146
void MergeNewStyleDicsAndOldStyleDics(std::vector< SvtLinguConfigDictionaryEntry > &rNewStyleDics, const std::vector< SvtLinguConfigDictionaryEntry > &rOldStyleDics)
Definition: lingutil.cxx:252
rtl_TextEncoding getTextEncodingFromCharset(const char *pCharset)
Definition: lingutil.cxx:295
#define OU2ENC(rtlOUString, rtlEncoding)
Definition: lingutil.hxx:27
sal_uInt16 nPos
#define SAL_WARN_IF(condition, area, stream)
#define SAL_WARN(area, stream)
aStr
aBuf
constexpr OUStringLiteral SN_SPELLCHECKER
std::locale Create(std::string_view aPrefixName, const LanguageTag &rLocale)
OUString get(TranslateId sContextAndId, const std::locale &loc)
size
bool isAllowlistedLanguage(const OUString &lang)
Reference< XMultiServiceFactory > getProcessServiceFactory()
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
uno::Reference< XLinguProperties > GetLinguProperties()
osl::Mutex & GetLinguMutex()
bool IsUpper(const OUString &rText, sal_Int32 nPos, sal_Int32 nLen, LanguageType nLanguage)
bool HasDigits(const OUString &rText)
LanguageType LinguLocaleToLanguage(const css::lang::Locale &rLocale)
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
#define MAXWORDLEN
Definition: sspellimp.cxx:71
constexpr OUStringLiteral SPELL_XML
Definition: sspellimp.cxx:66
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * lingucomponent_SpellChecker_get_implementation(css::uno::XComponentContext *, css::uno::Sequence< css::uno::Any > const &)
Definition: sspellimp.cxx:641
DictItem(OUString i_DName, Locale i_DLoc, rtl_TextEncoding i_DEnc)
Definition: sspellimp.cxx:80
css::uno::Sequence< OUString > aLocaleNames
css::uno::Sequence< OUString > aLocations
unsigned char sal_Bool
sal_uInt16 sal_Unicode