tdf#156769 - Escape the question mark in the storage name
[LibreOffice.git] / editeng / source / misc / unolingu.cxx
blobbd1fae50654e7209ca3f9572a1d046576e49140a
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 .
21 #include <memory>
22 #include <editeng/unolingu.hxx>
23 #include <com/sun/star/frame/Desktop.hpp>
24 #include <com/sun/star/frame/XStorable.hpp>
25 #include <com/sun/star/lang/XEventListener.hpp>
26 #include <com/sun/star/linguistic2/XHyphenatedWord.hpp>
27 #include <com/sun/star/linguistic2/DictionaryList.hpp>
28 #include <com/sun/star/linguistic2/LinguServiceManager.hpp>
29 #include <com/sun/star/linguistic2/LinguProperties.hpp>
30 #include <com/sun/star/linguistic2/XSpellChecker1.hpp>
32 #include <comphelper/lok.hxx>
33 #include <comphelper/processfactory.hxx>
34 #include <cppuhelper/implbase.hxx>
35 #include <i18nlangtag/languagetag.hxx>
36 #include <unotools/lingucfg.hxx>
37 #include <utility>
38 #include <vcl/svapp.hxx>
39 #include <vcl/weld.hxx>
40 #include <linguistic/misc.hxx>
41 #include <editeng/eerdll.hxx>
42 #include <editeng/editrids.hrc>
43 #include <svtools/strings.hrc>
44 #include <unotools/resmgr.hxx>
45 #include <sal/log.hxx>
46 #include <osl/diagnose.h>
48 using namespace ::comphelper;
49 using namespace ::linguistic;
50 using namespace ::com::sun::star;
51 using namespace ::com::sun::star::util;
52 using namespace ::com::sun::star::uno;
53 using namespace ::com::sun::star::lang;
54 using namespace ::com::sun::star::beans;
55 using namespace ::com::sun::star::frame;
56 using namespace ::com::sun::star::linguistic2;
58 static uno::Reference< XLinguServiceManager2 > GetLngSvcMgr_Impl()
60 uno::Reference< XComponentContext > xContext = comphelper::getProcessComponentContext();
61 uno::Reference< XLinguServiceManager2 > xRes = LinguServiceManager::create(xContext);
62 return xRes;
65 namespace {
67 //! Dummy implementation in order to avoid loading of lingu DLL
68 //! when only the XSupportedLocales interface is used.
69 //! The dummy accesses the real implementation (and thus loading the DLL)
70 //! when "real" work needs to be done only.
71 class ThesDummy_Impl :
72 public cppu::WeakImplHelper< XThesaurus >
74 uno::Reference< XThesaurus > xThes; // the real one...
75 std::unique_ptr<Sequence< lang::Locale >> pLocaleSeq;
77 void GetCfgLocales();
79 void GetThes_Impl();
81 public:
82 ThesDummy_Impl() {}
84 // XSupportedLocales
85 virtual css::uno::Sequence< css::lang::Locale > SAL_CALL
86 getLocales() override;
87 virtual sal_Bool SAL_CALL
88 hasLocale( const css::lang::Locale& rLocale ) override;
90 // XThesaurus
91 virtual css::uno::Sequence<
92 css::uno::Reference< css::linguistic2::XMeaning > > SAL_CALL
93 queryMeanings( const OUString& rTerm,
94 const css::lang::Locale& rLocale,
95 const css::uno::Sequence< css::beans::PropertyValue >& rProperties ) override;
100 void ThesDummy_Impl::GetCfgLocales()
102 if (pLocaleSeq)
103 return;
105 SvtLinguConfig aCfg;
106 Sequence < OUString > aNodeNames( aCfg.GetNodeNames( "ServiceManager/ThesaurusList" ) );
107 const OUString *pNodeNames = aNodeNames.getConstArray();
108 sal_Int32 nLen = aNodeNames.getLength();
109 pLocaleSeq.reset( new Sequence< lang::Locale >( nLen ) );
110 lang::Locale *pLocale = pLocaleSeq->getArray();
111 for (sal_Int32 i = 0; i < nLen; ++i)
113 pLocale[i] = LanguageTag::convertToLocaleWithFallback( pNodeNames[i] );
118 void ThesDummy_Impl::GetThes_Impl()
120 if (!xThes.is())
122 uno::Reference< XLinguServiceManager2 > xLngSvcMgr( GetLngSvcMgr_Impl() );
123 xThes = xLngSvcMgr->getThesaurus();
125 if (xThes.is())
127 // no longer needed...
128 pLocaleSeq.reset();
134 uno::Sequence< lang::Locale > SAL_CALL
135 ThesDummy_Impl::getLocales()
137 GetThes_Impl();
138 if (xThes.is())
139 return xThes->getLocales();
140 else if (!pLocaleSeq) // if not already loaded save startup time by avoiding loading them now
141 GetCfgLocales();
142 return *pLocaleSeq;
146 sal_Bool SAL_CALL
147 ThesDummy_Impl::hasLocale( const lang::Locale& rLocale )
149 GetThes_Impl();
150 if (xThes.is())
151 return xThes->hasLocale( rLocale );
152 else if (!pLocaleSeq) // if not already loaded save startup time by avoiding loading them now
153 GetCfgLocales();
154 bool bFound = false;
155 sal_Int32 nLen = pLocaleSeq->getLength();
156 const lang::Locale *pLocale = pLocaleSeq->getConstArray();
157 const lang::Locale *pEnd = pLocale + nLen;
158 for ( ; pLocale < pEnd && !bFound; ++pLocale)
160 bFound = pLocale->Language == rLocale.Language &&
161 pLocale->Country == rLocale.Country &&
162 pLocale->Variant == rLocale.Variant;
164 return bFound;
168 uno::Sequence< uno::Reference< linguistic2::XMeaning > > SAL_CALL
169 ThesDummy_Impl::queryMeanings(
170 const OUString& rTerm,
171 const lang::Locale& rLocale,
172 const css::uno::Sequence< css::beans::PropertyValue >& rProperties )
174 GetThes_Impl();
175 uno::Sequence< uno::Reference< linguistic2::XMeaning > > aRes;
176 OSL_ENSURE( xThes.is(), "Thesaurus missing" );
177 if (xThes.is())
178 aRes = xThes->queryMeanings( rTerm, rLocale, rProperties );
179 return aRes;
182 namespace {
184 //! Dummy implementation in order to avoid loading of lingu DLL.
185 //! The dummy accesses the real implementation (and thus loading the DLL)
186 //! when it needs to be done only.
187 class SpellDummy_Impl :
188 public cppu::WeakImplHelper< XSpellChecker1 >
190 uno::Reference< XSpellChecker1 > xSpell; // the real one...
192 void GetSpell_Impl();
194 public:
196 // XSupportedLanguages (for XSpellChecker1)
197 virtual css::uno::Sequence< sal_Int16 > SAL_CALL
198 getLanguages() override;
199 virtual sal_Bool SAL_CALL
200 hasLanguage( sal_Int16 nLanguage ) override;
202 // XSpellChecker1 (same as XSpellChecker but sal_Int16 for language)
203 virtual sal_Bool SAL_CALL
204 isValid( const OUString& rWord, sal_Int16 nLanguage,
205 const css::uno::Sequence< css::beans::PropertyValue >& rProperties ) override;
206 virtual css::uno::Reference< css::linguistic2::XSpellAlternatives > SAL_CALL
207 spell( const OUString& rWord, sal_Int16 nLanguage,
208 const css::uno::Sequence< css::beans::PropertyValue >& rProperties ) override;
213 void SpellDummy_Impl::GetSpell_Impl()
215 if (!xSpell.is())
217 uno::Reference< XLinguServiceManager2 > xLngSvcMgr( GetLngSvcMgr_Impl() );
218 xSpell.set( xLngSvcMgr->getSpellChecker(), UNO_QUERY );
223 uno::Sequence< sal_Int16 > SAL_CALL
224 SpellDummy_Impl::getLanguages()
226 GetSpell_Impl();
227 if (xSpell.is())
228 return xSpell->getLanguages();
229 else
230 return uno::Sequence< sal_Int16 >();
234 sal_Bool SAL_CALL
235 SpellDummy_Impl::hasLanguage( sal_Int16 nLanguage )
237 GetSpell_Impl();
238 bool bRes = false;
239 if (xSpell.is())
240 bRes = xSpell->hasLanguage( nLanguage );
241 return bRes;
245 sal_Bool SAL_CALL
246 SpellDummy_Impl::isValid( const OUString& rWord, sal_Int16 nLanguage,
247 const css::uno::Sequence< css::beans::PropertyValue >& rProperties )
249 GetSpell_Impl();
250 bool bRes = true;
251 if (xSpell.is())
252 bRes = xSpell->isValid( rWord, nLanguage, rProperties );
253 return bRes;
257 uno::Reference< linguistic2::XSpellAlternatives > SAL_CALL
258 SpellDummy_Impl::spell( const OUString& rWord, sal_Int16 nLanguage,
259 const css::uno::Sequence< css::beans::PropertyValue >& rProperties )
261 GetSpell_Impl();
262 uno::Reference< linguistic2::XSpellAlternatives > xRes;
263 if (xSpell.is())
264 xRes = xSpell->spell( rWord, nLanguage, rProperties );
265 return xRes;
268 namespace {
270 //! Dummy implementation in order to avoid loading of lingu DLL.
271 //! The dummy accesses the real implementation (and thus loading the DLL)
272 //! when it needs to be done only.
273 class HyphDummy_Impl :
274 public cppu::WeakImplHelper< XHyphenator >
276 uno::Reference< XHyphenator > xHyph; // the real one...
278 void GetHyph_Impl();
280 public:
282 // XSupportedLocales
283 virtual css::uno::Sequence<
284 css::lang::Locale > SAL_CALL
285 getLocales() override;
286 virtual sal_Bool SAL_CALL
287 hasLocale( const css::lang::Locale& rLocale ) override;
289 // XHyphenator
290 virtual css::uno::Reference<
291 css::linguistic2::XHyphenatedWord > SAL_CALL
292 hyphenate( const OUString& rWord,
293 const css::lang::Locale& rLocale,
294 sal_Int16 nMaxLeading,
295 const css::uno::Sequence< css::beans::PropertyValue >& rProperties ) override;
296 virtual css::uno::Reference<
297 css::linguistic2::XHyphenatedWord > SAL_CALL
298 queryAlternativeSpelling( const OUString& rWord,
299 const css::lang::Locale& rLocale,
300 sal_Int16 nIndex,
301 const css::uno::Sequence< css::beans::PropertyValue >& rProperties ) override;
302 virtual css::uno::Reference<
303 css::linguistic2::XPossibleHyphens > SAL_CALL
304 createPossibleHyphens(
305 const OUString& rWord,
306 const css::lang::Locale& rLocale,
307 const css::uno::Sequence< css::beans::PropertyValue >& rProperties ) override;
312 void HyphDummy_Impl::GetHyph_Impl()
314 if (!xHyph.is())
316 uno::Reference< XLinguServiceManager2 > xLngSvcMgr( GetLngSvcMgr_Impl() );
317 xHyph = xLngSvcMgr->getHyphenator();
322 uno::Sequence< lang::Locale > SAL_CALL
323 HyphDummy_Impl::getLocales()
325 GetHyph_Impl();
326 if (xHyph.is())
327 return xHyph->getLocales();
328 else
329 return uno::Sequence< lang::Locale >();
333 sal_Bool SAL_CALL
334 HyphDummy_Impl::hasLocale( const lang::Locale& rLocale )
336 GetHyph_Impl();
337 bool bRes = false;
338 if (xHyph.is())
339 bRes = xHyph->hasLocale( rLocale );
340 return bRes;
344 uno::Reference< linguistic2::XHyphenatedWord > SAL_CALL
345 HyphDummy_Impl::hyphenate(
346 const OUString& rWord,
347 const lang::Locale& rLocale,
348 sal_Int16 nMaxLeading,
349 const css::uno::Sequence< css::beans::PropertyValue >& rProperties )
351 GetHyph_Impl();
352 uno::Reference< linguistic2::XHyphenatedWord > xRes;
353 if (xHyph.is())
354 xRes = xHyph->hyphenate( rWord, rLocale, nMaxLeading, rProperties );
355 return xRes;
359 uno::Reference< linguistic2::XHyphenatedWord > SAL_CALL
360 HyphDummy_Impl::queryAlternativeSpelling(
361 const OUString& rWord,
362 const lang::Locale& rLocale,
363 sal_Int16 nIndex,
364 const css::uno::Sequence< css::beans::PropertyValue >& rProperties )
366 GetHyph_Impl();
367 uno::Reference< linguistic2::XHyphenatedWord > xRes;
368 if (xHyph.is())
369 xRes = xHyph->queryAlternativeSpelling( rWord, rLocale, nIndex, rProperties );
370 return xRes;
374 uno::Reference< linguistic2::XPossibleHyphens > SAL_CALL
375 HyphDummy_Impl::createPossibleHyphens(
376 const OUString& rWord,
377 const lang::Locale& rLocale,
378 const css::uno::Sequence< css::beans::PropertyValue >& rProperties )
380 GetHyph_Impl();
381 uno::Reference< linguistic2::XPossibleHyphens > xRes;
382 if (xHyph.is())
383 xRes = xHyph->createPossibleHyphens( rWord, rLocale, rProperties );
384 return xRes;
387 class LinguMgrExitLstnr : public cppu::WeakImplHelper<XEventListener>
389 uno::Reference< XDesktop2 > xDesktop;
391 static void AtExit();
393 public:
394 LinguMgrExitLstnr();
395 virtual ~LinguMgrExitLstnr() override;
397 // lang::XEventListener
398 virtual void SAL_CALL disposing(const EventObject& rSource) override;
401 LinguMgrExitLstnr::LinguMgrExitLstnr()
403 // add object to frame::Desktop EventListeners in order to properly call
404 // the AtExit function at application exit.
406 uno::Reference< XComponentContext > xContext = getProcessComponentContext();
407 xDesktop = Desktop::create( xContext );
408 xDesktop->addEventListener( this );
411 LinguMgrExitLstnr::~LinguMgrExitLstnr()
413 if (xDesktop.is())
415 xDesktop->removeEventListener( this );
416 xDesktop = nullptr; //! release reference to desktop
418 OSL_ENSURE(!xDesktop.is(), "reference to desktop should be released");
421 void LinguMgrExitLstnr::disposing(const EventObject& rSource)
423 if (xDesktop.is() && rSource.Source == xDesktop)
425 xDesktop->removeEventListener( this );
426 xDesktop = nullptr; //! release reference to desktop
428 AtExit();
432 void LinguMgrExitLstnr::AtExit()
434 SolarMutexGuard g;
436 // release references
437 LinguMgr::xLngSvcMgr = nullptr;
438 LinguMgr::xSpell = nullptr;
439 LinguMgr::xHyph = nullptr;
440 LinguMgr::xThes = nullptr;
441 LinguMgr::xDicList = nullptr;
442 LinguMgr::xProp = nullptr;
443 LinguMgr::xIgnoreAll = nullptr;
444 LinguMgr::xChangeAll = nullptr;
446 LinguMgr::bExiting = true;
448 LinguMgr::pExitLstnr = nullptr;
452 rtl::Reference<LinguMgrExitLstnr> LinguMgr::pExitLstnr;
453 bool LinguMgr::bExiting = false;
454 uno::Reference< XLinguServiceManager2 > LinguMgr::xLngSvcMgr;
455 uno::Reference< XSpellChecker1 > LinguMgr::xSpell;
456 uno::Reference< XHyphenator > LinguMgr::xHyph;
457 uno::Reference< XThesaurus > LinguMgr::xThes;
458 uno::Reference< XSearchableDictionaryList > LinguMgr::xDicList;
459 uno::Reference< XLinguProperties > LinguMgr::xProp;
460 uno::Reference< XDictionary > LinguMgr::xIgnoreAll;
461 uno::Reference< XDictionary > LinguMgr::xChangeAll;
464 uno::Reference< XLinguServiceManager2 > LinguMgr::GetLngSvcMgr()
466 if (bExiting)
467 return nullptr;
469 if (!pExitLstnr)
470 pExitLstnr = new LinguMgrExitLstnr;
472 if (!xLngSvcMgr.is())
473 xLngSvcMgr = GetLngSvcMgr_Impl();
475 return xLngSvcMgr;
479 uno::Reference< XSpellChecker1 > LinguMgr::GetSpellChecker()
481 return xSpell.is() ? xSpell : GetSpell();
484 uno::Reference< XHyphenator > LinguMgr::GetHyphenator()
486 return xHyph.is() ? xHyph : GetHyph();
489 uno::Reference< XThesaurus > LinguMgr::GetThesaurus()
491 return xThes.is() ? xThes : GetThes();
494 uno::Reference< XSearchableDictionaryList > LinguMgr::GetDictionaryList()
496 return xDicList.is() ? xDicList : GetDicList();
499 uno::Reference< linguistic2::XLinguProperties > LinguMgr::GetLinguPropertySet()
501 return xProp.is() ? xProp : GetProp();
504 uno::Reference< XDictionary > LinguMgr::GetStandardDic()
506 //! don't hold reference to this
507 //! (it may be removed from dictionary list and needs to be
508 //! created empty if accessed again)
509 return GetStandard();
512 uno::Reference< XDictionary > LinguMgr::GetIgnoreAllList()
514 return xIgnoreAll.is() ? xIgnoreAll : GetIgnoreAll();
517 uno::Reference< XDictionary > LinguMgr::GetChangeAllList()
519 return xChangeAll.is() ? xChangeAll : GetChangeAll();
522 uno::Reference< XSpellChecker1 > LinguMgr::GetSpell()
524 if (bExiting)
525 return nullptr;
527 if (!pExitLstnr)
528 pExitLstnr = new LinguMgrExitLstnr;
530 //! use dummy implementation in order to avoid loading of lingu DLL
531 xSpell = new SpellDummy_Impl;
532 return xSpell;
535 uno::Reference< XHyphenator > LinguMgr::GetHyph()
537 if (bExiting)
538 return nullptr;
540 if (!pExitLstnr)
541 pExitLstnr = new LinguMgrExitLstnr;
543 //! use dummy implementation in order to avoid loading of lingu DLL
544 xHyph = new HyphDummy_Impl;
545 return xHyph;
548 uno::Reference< XThesaurus > LinguMgr::GetThes()
550 if (bExiting)
551 return nullptr;
553 if (!pExitLstnr)
554 pExitLstnr = new LinguMgrExitLstnr;
556 //! use dummy implementation in order to avoid loading of lingu DLL
557 //! when only the XSupportedLocales interface is used.
558 //! The dummy accesses the real implementation (and thus loading the DLL)
559 //! when "real" work needs to be done only.
560 xThes = new ThesDummy_Impl;
561 return xThes;
564 uno::Reference< XSearchableDictionaryList > LinguMgr::GetDicList()
566 if (bExiting)
567 return nullptr;
569 if (!pExitLstnr)
570 pExitLstnr = new LinguMgrExitLstnr;
572 xDicList = linguistic2::DictionaryList::create( getProcessComponentContext() );
573 return xDicList;
576 uno::Reference< linguistic2::XLinguProperties > LinguMgr::GetProp()
578 if (bExiting)
579 return nullptr;
581 if (!pExitLstnr)
582 pExitLstnr = new LinguMgrExitLstnr;
584 xProp = linguistic2::LinguProperties::create( getProcessComponentContext() );
585 return xProp;
588 uno::Reference< XDictionary > LinguMgr::GetIgnoreAll()
590 if (bExiting)
591 return nullptr;
593 if (!pExitLstnr)
594 pExitLstnr = new LinguMgrExitLstnr;
596 uno::Reference< XSearchableDictionaryList > xTmpDicList( GetDictionaryList() );
597 if (xTmpDicList.is())
599 const LanguageTag tag = comphelper::LibreOfficeKit::isActive()
600 ? LanguageTag("en-US")
601 : SvtSysLocale().GetUILanguageTag();
602 std::locale loc(Translate::Create("svt", tag));
603 xIgnoreAll = xTmpDicList->getDictionaryByName(
604 Translate::get(STR_DESCRIPTION_IGNOREALLLIST, loc) );
606 return xIgnoreAll;
609 uno::Reference< XDictionary > LinguMgr::GetChangeAll()
611 if (bExiting)
612 return nullptr;
614 if (!pExitLstnr)
615 pExitLstnr = new LinguMgrExitLstnr;
617 uno::Reference< XSearchableDictionaryList > _xDicList = GetDictionaryList();
618 if (_xDicList.is())
620 xChangeAll = _xDicList->createDictionary(
621 "ChangeAllList",
622 LanguageTag::convertToLocale( LANGUAGE_NONE ),
623 DictionaryType_NEGATIVE, OUString() );
625 return xChangeAll;
628 uno::Reference< XDictionary > LinguMgr::GetStandard()
630 // Tries to return a dictionary which may hold positive entries is
631 // persistent and not read-only.
633 if (bExiting)
634 return nullptr;
636 uno::Reference< XSearchableDictionaryList > xTmpDicList( GetDictionaryList() );
637 if (!xTmpDicList.is())
638 return nullptr;
640 static constexpr OUString aDicName( u"standard.dic"_ustr );
641 uno::Reference< XDictionary > xDic = xTmpDicList->getDictionaryByName( aDicName );
642 if (!xDic.is())
644 // try to create standard dictionary
645 uno::Reference< XDictionary > xTmp;
648 xTmp = xTmpDicList->createDictionary( aDicName,
649 LanguageTag::convertToLocale( LANGUAGE_NONE ),
650 DictionaryType_POSITIVE,
651 linguistic::GetWritableDictionaryURL( aDicName ) );
653 catch(const css::uno::Exception &)
657 // add new dictionary to list
658 if (xTmp.is())
660 xTmpDicList->addDictionary( xTmp );
661 xTmp->setActive( true );
663 xDic = xTmp;
665 #if OSL_DEBUG_LEVEL > 1
666 uno::Reference< XStorable > xStor( xDic, UNO_QUERY );
667 OSL_ENSURE( xDic.is() && xDic->getDictionaryType() == DictionaryType_POSITIVE,
668 "wrong dictionary type");
669 OSL_ENSURE( xDic.is() && LanguageTag( xDic->getLocale() ).getLanguageType() == LANGUAGE_NONE,
670 "wrong dictionary language");
671 OSL_ENSURE( !xStor.is() || (xStor->hasLocation() && !xStor->isReadonly()),
672 "dictionary not editable" );
673 #endif
675 return xDic;
678 SvxAlternativeSpelling SvxGetAltSpelling(
679 const css::uno::Reference< css::linguistic2::XHyphenatedWord > & rHyphWord )
681 SvxAlternativeSpelling aRes;
682 if (rHyphWord.is() && rHyphWord->isAlternativeSpelling())
684 OUString aWord( rHyphWord->getWord() ),
685 aAltWord( rHyphWord->getHyphenatedWord() );
686 sal_Int16 nHyphenationPos = rHyphWord->getHyphenationPos(),
687 nHyphenPos = rHyphWord->getHyphenPos();
688 sal_Int16 nLen = static_cast<sal_Int16>(aWord.getLength());
689 sal_Int16 nAltLen = static_cast<sal_Int16>(aAltWord.getLength());
690 const sal_Unicode *pWord = aWord.getStr(),
691 *pAltWord = aAltWord.getStr();
693 // count number of chars from the left to the
694 // hyphenation pos / hyphen pos that are equal
695 sal_Int16 nL = 0;
696 while (nL <= nHyphenationPos && nL <= nHyphenPos
697 && pWord[ nL ] == pAltWord[ nL ])
698 ++nL;
699 // count number of chars from the right to the
700 // hyphenation pos / hyphen pos that are equal
701 sal_Int16 nR = 0;
702 sal_Int32 nIdx = nLen - 1;
703 sal_Int32 nAltIdx = nAltLen - 1;
704 while (nIdx > nHyphenationPos && nAltIdx > nHyphenPos
705 && pWord[ nIdx-- ] == pAltWord[ nAltIdx-- ])
706 ++nR;
708 aRes.aReplacement = aAltWord.copy( nL, nAltLen - nL - nR );
709 aRes.nChangedPos = nL;
710 aRes.nChangedLength = nLen - nL - nR;
711 aRes.bIsAltSpelling = true;
713 return aRes;
717 SvxDicListChgClamp::SvxDicListChgClamp( uno::Reference< XSearchableDictionaryList > _xDicList ) :
718 xDicList (std::move( _xDicList ))
720 if (xDicList.is())
722 xDicList->beginCollectEvents();
726 SvxDicListChgClamp::~SvxDicListChgClamp()
728 if (xDicList.is())
730 xDicList->endCollectEvents();
734 short SvxDicError(weld::Window *pParent, linguistic::DictionaryError nError)
736 short nRes = 0;
737 if (linguistic::DictionaryError::NONE != nError)
739 TranslateId pRid;
740 switch (nError)
742 case linguistic::DictionaryError::FULL : pRid = RID_SVXSTR_DIC_ERR_FULL; break;
743 case linguistic::DictionaryError::READONLY : pRid = RID_SVXSTR_DIC_ERR_READONLY; break;
744 default:
745 pRid = RID_SVXSTR_DIC_ERR_UNKNOWN;
746 SAL_WARN("editeng", "unexpected case");
748 std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(pParent,
749 VclMessageType::Info, VclButtonsType::Ok,
750 EditResId(pRid)));
751 nRes = xInfoBox->run();
754 return nRes;
758 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */