diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 05:54:39 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 05:54:39 +0000 |
commit | 267c6f2ac71f92999e969232431ba04678e7437e (patch) | |
tree | 358c9467650e1d0a1d7227a21dac2e3d08b622b2 /editeng/source/misc/unolingu.cxx | |
parent | Initial commit. (diff) | |
download | libreoffice-267c6f2ac71f92999e969232431ba04678e7437e.tar.xz libreoffice-267c6f2ac71f92999e969232431ba04678e7437e.zip |
Adding upstream version 4:24.2.0.upstream/4%24.2.0
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'editeng/source/misc/unolingu.cxx')
-rw-r--r-- | editeng/source/misc/unolingu.cxx | 754 |
1 files changed, 754 insertions, 0 deletions
diff --git a/editeng/source/misc/unolingu.cxx b/editeng/source/misc/unolingu.cxx new file mode 100644 index 0000000000..1e7b69a25f --- /dev/null +++ b/editeng/source/misc/unolingu.cxx @@ -0,0 +1,754 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + + +#include <memory> +#include <editeng/unolingu.hxx> +#include <com/sun/star/frame/Desktop.hpp> +#include <com/sun/star/frame/XStorable.hpp> +#include <com/sun/star/lang/XEventListener.hpp> +#include <com/sun/star/linguistic2/XHyphenatedWord.hpp> +#include <com/sun/star/linguistic2/DictionaryList.hpp> +#include <com/sun/star/linguistic2/LinguServiceManager.hpp> +#include <com/sun/star/linguistic2/LinguProperties.hpp> +#include <com/sun/star/linguistic2/XSpellChecker1.hpp> + +#include <comphelper/processfactory.hxx> +#include <cppuhelper/implbase.hxx> +#include <i18nlangtag/languagetag.hxx> +#include <unotools/lingucfg.hxx> +#include <utility> +#include <vcl/svapp.hxx> +#include <vcl/weld.hxx> +#include <linguistic/misc.hxx> +#include <editeng/eerdll.hxx> +#include <editeng/editrids.hrc> +#include <svtools/strings.hrc> +#include <unotools/resmgr.hxx> +#include <sal/log.hxx> +#include <osl/diagnose.h> + +using namespace ::comphelper; +using namespace ::linguistic; +using namespace ::com::sun::star; +using namespace ::com::sun::star::util; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::frame; +using namespace ::com::sun::star::linguistic2; + +static uno::Reference< XLinguServiceManager2 > GetLngSvcMgr_Impl() +{ + uno::Reference< XComponentContext > xContext = comphelper::getProcessComponentContext(); + uno::Reference< XLinguServiceManager2 > xRes = LinguServiceManager::create(xContext); + return xRes; +} + +namespace { + +//! Dummy implementation in order to avoid loading of lingu DLL +//! when only the XSupportedLocales interface is used. +//! The dummy accesses the real implementation (and thus loading the DLL) +//! when "real" work needs to be done only. +class ThesDummy_Impl : + public cppu::WeakImplHelper< XThesaurus > +{ + uno::Reference< XThesaurus > xThes; // the real one... + std::unique_ptr<Sequence< lang::Locale >> pLocaleSeq; + + void GetCfgLocales(); + + void GetThes_Impl(); + +public: + ThesDummy_Impl() {} + + // XSupportedLocales + virtual css::uno::Sequence< css::lang::Locale > SAL_CALL + getLocales() override; + virtual sal_Bool SAL_CALL + hasLocale( const css::lang::Locale& rLocale ) override; + + // XThesaurus + virtual css::uno::Sequence< + css::uno::Reference< css::linguistic2::XMeaning > > SAL_CALL + queryMeanings( const OUString& rTerm, + const css::lang::Locale& rLocale, + const css::uno::Sequence< css::beans::PropertyValue >& rProperties ) override; +}; + +} + +void ThesDummy_Impl::GetCfgLocales() +{ + if (pLocaleSeq) + return; + + SvtLinguConfig aCfg; + Sequence < OUString > aNodeNames( aCfg.GetNodeNames( "ServiceManager/ThesaurusList" ) ); + const OUString *pNodeNames = aNodeNames.getConstArray(); + sal_Int32 nLen = aNodeNames.getLength(); + pLocaleSeq.reset( new Sequence< lang::Locale >( nLen ) ); + lang::Locale *pLocale = pLocaleSeq->getArray(); + for (sal_Int32 i = 0; i < nLen; ++i) + { + pLocale[i] = LanguageTag::convertToLocaleWithFallback( pNodeNames[i] ); + } +} + + +void ThesDummy_Impl::GetThes_Impl() +{ + if (!xThes.is()) + { + uno::Reference< XLinguServiceManager2 > xLngSvcMgr( GetLngSvcMgr_Impl() ); + xThes = xLngSvcMgr->getThesaurus(); + + if (xThes.is()) + { + // no longer needed... + pLocaleSeq.reset(); + } + } +} + + +uno::Sequence< lang::Locale > SAL_CALL + ThesDummy_Impl::getLocales() +{ + GetThes_Impl(); + if (xThes.is()) + return xThes->getLocales(); + else if (!pLocaleSeq) // if not already loaded save startup time by avoiding loading them now + GetCfgLocales(); + return *pLocaleSeq; +} + + +sal_Bool SAL_CALL + ThesDummy_Impl::hasLocale( const lang::Locale& rLocale ) +{ + GetThes_Impl(); + if (xThes.is()) + return xThes->hasLocale( rLocale ); + else if (!pLocaleSeq) // if not already loaded save startup time by avoiding loading them now + GetCfgLocales(); + bool bFound = false; + sal_Int32 nLen = pLocaleSeq->getLength(); + const lang::Locale *pLocale = pLocaleSeq->getConstArray(); + const lang::Locale *pEnd = pLocale + nLen; + for ( ; pLocale < pEnd && !bFound; ++pLocale) + { + bFound = pLocale->Language == rLocale.Language && + pLocale->Country == rLocale.Country && + pLocale->Variant == rLocale.Variant; + } + return bFound; +} + + +uno::Sequence< uno::Reference< linguistic2::XMeaning > > SAL_CALL + ThesDummy_Impl::queryMeanings( + const OUString& rTerm, + const lang::Locale& rLocale, + const css::uno::Sequence< css::beans::PropertyValue >& rProperties ) +{ + GetThes_Impl(); + uno::Sequence< uno::Reference< linguistic2::XMeaning > > aRes; + OSL_ENSURE( xThes.is(), "Thesaurus missing" ); + if (xThes.is()) + aRes = xThes->queryMeanings( rTerm, rLocale, rProperties ); + return aRes; +} + +namespace { + +//! Dummy implementation in order to avoid loading of lingu DLL. +//! The dummy accesses the real implementation (and thus loading the DLL) +//! when it needs to be done only. +class SpellDummy_Impl : + public cppu::WeakImplHelper< XSpellChecker1 > +{ + uno::Reference< XSpellChecker1 > xSpell; // the real one... + + void GetSpell_Impl(); + +public: + + // XSupportedLanguages (for XSpellChecker1) + virtual css::uno::Sequence< sal_Int16 > SAL_CALL + getLanguages() override; + virtual sal_Bool SAL_CALL + hasLanguage( sal_Int16 nLanguage ) override; + + // XSpellChecker1 (same as XSpellChecker but sal_Int16 for language) + virtual sal_Bool SAL_CALL + isValid( const OUString& rWord, sal_Int16 nLanguage, + const css::uno::Sequence< css::beans::PropertyValue >& rProperties ) override; + virtual css::uno::Reference< css::linguistic2::XSpellAlternatives > SAL_CALL + spell( const OUString& rWord, sal_Int16 nLanguage, + const css::uno::Sequence< css::beans::PropertyValue >& rProperties ) override; +}; + +} + +void SpellDummy_Impl::GetSpell_Impl() +{ + if (!xSpell.is()) + { + uno::Reference< XLinguServiceManager2 > xLngSvcMgr( GetLngSvcMgr_Impl() ); + xSpell.set( xLngSvcMgr->getSpellChecker(), UNO_QUERY ); + } +} + + +uno::Sequence< sal_Int16 > SAL_CALL + SpellDummy_Impl::getLanguages() +{ + GetSpell_Impl(); + if (xSpell.is()) + return xSpell->getLanguages(); + else + return uno::Sequence< sal_Int16 >(); +} + + +sal_Bool SAL_CALL + SpellDummy_Impl::hasLanguage( sal_Int16 nLanguage ) +{ + GetSpell_Impl(); + bool bRes = false; + if (xSpell.is()) + bRes = xSpell->hasLanguage( nLanguage ); + return bRes; +} + + +sal_Bool SAL_CALL + SpellDummy_Impl::isValid( const OUString& rWord, sal_Int16 nLanguage, + const css::uno::Sequence< css::beans::PropertyValue >& rProperties ) +{ + GetSpell_Impl(); + bool bRes = true; + if (xSpell.is()) + bRes = xSpell->isValid( rWord, nLanguage, rProperties ); + return bRes; +} + + +uno::Reference< linguistic2::XSpellAlternatives > SAL_CALL + SpellDummy_Impl::spell( const OUString& rWord, sal_Int16 nLanguage, + const css::uno::Sequence< css::beans::PropertyValue >& rProperties ) +{ + GetSpell_Impl(); + uno::Reference< linguistic2::XSpellAlternatives > xRes; + if (xSpell.is()) + xRes = xSpell->spell( rWord, nLanguage, rProperties ); + return xRes; +} + +namespace { + +//! Dummy implementation in order to avoid loading of lingu DLL. +//! The dummy accesses the real implementation (and thus loading the DLL) +//! when it needs to be done only. +class HyphDummy_Impl : + public cppu::WeakImplHelper< XHyphenator > +{ + uno::Reference< XHyphenator > xHyph; // the real one... + + void GetHyph_Impl(); + +public: + + // XSupportedLocales + virtual css::uno::Sequence< + css::lang::Locale > SAL_CALL + getLocales() override; + virtual sal_Bool SAL_CALL + hasLocale( const css::lang::Locale& rLocale ) override; + + // XHyphenator + virtual css::uno::Reference< + css::linguistic2::XHyphenatedWord > SAL_CALL + hyphenate( const OUString& rWord, + const css::lang::Locale& rLocale, + sal_Int16 nMaxLeading, + const css::uno::Sequence< css::beans::PropertyValue >& rProperties ) override; + virtual css::uno::Reference< + css::linguistic2::XHyphenatedWord > SAL_CALL + queryAlternativeSpelling( const OUString& rWord, + const css::lang::Locale& rLocale, + sal_Int16 nIndex, + const css::uno::Sequence< css::beans::PropertyValue >& rProperties ) override; + virtual css::uno::Reference< + css::linguistic2::XPossibleHyphens > SAL_CALL + createPossibleHyphens( + const OUString& rWord, + const css::lang::Locale& rLocale, + const css::uno::Sequence< css::beans::PropertyValue >& rProperties ) override; +}; + +} + +void HyphDummy_Impl::GetHyph_Impl() +{ + if (!xHyph.is()) + { + uno::Reference< XLinguServiceManager2 > xLngSvcMgr( GetLngSvcMgr_Impl() ); + xHyph = xLngSvcMgr->getHyphenator(); + } +} + + +uno::Sequence< lang::Locale > SAL_CALL + HyphDummy_Impl::getLocales() +{ + GetHyph_Impl(); + if (xHyph.is()) + return xHyph->getLocales(); + else + return uno::Sequence< lang::Locale >(); +} + + +sal_Bool SAL_CALL + HyphDummy_Impl::hasLocale( const lang::Locale& rLocale ) +{ + GetHyph_Impl(); + bool bRes = false; + if (xHyph.is()) + bRes = xHyph->hasLocale( rLocale ); + return bRes; +} + + +uno::Reference< linguistic2::XHyphenatedWord > SAL_CALL + HyphDummy_Impl::hyphenate( + const OUString& rWord, + const lang::Locale& rLocale, + sal_Int16 nMaxLeading, + const css::uno::Sequence< css::beans::PropertyValue >& rProperties ) +{ + GetHyph_Impl(); + uno::Reference< linguistic2::XHyphenatedWord > xRes; + if (xHyph.is()) + xRes = xHyph->hyphenate( rWord, rLocale, nMaxLeading, rProperties ); + return xRes; +} + + +uno::Reference< linguistic2::XHyphenatedWord > SAL_CALL + HyphDummy_Impl::queryAlternativeSpelling( + const OUString& rWord, + const lang::Locale& rLocale, + sal_Int16 nIndex, + const css::uno::Sequence< css::beans::PropertyValue >& rProperties ) +{ + GetHyph_Impl(); + uno::Reference< linguistic2::XHyphenatedWord > xRes; + if (xHyph.is()) + xRes = xHyph->queryAlternativeSpelling( rWord, rLocale, nIndex, rProperties ); + return xRes; +} + + +uno::Reference< linguistic2::XPossibleHyphens > SAL_CALL + HyphDummy_Impl::createPossibleHyphens( + const OUString& rWord, + const lang::Locale& rLocale, + const css::uno::Sequence< css::beans::PropertyValue >& rProperties ) +{ + GetHyph_Impl(); + uno::Reference< linguistic2::XPossibleHyphens > xRes; + if (xHyph.is()) + xRes = xHyph->createPossibleHyphens( rWord, rLocale, rProperties ); + return xRes; +} + +class LinguMgrExitLstnr : public cppu::WeakImplHelper<XEventListener> +{ + uno::Reference< XDesktop2 > xDesktop; + + static void AtExit(); + +public: + LinguMgrExitLstnr(); + virtual ~LinguMgrExitLstnr() override; + + // lang::XEventListener + virtual void SAL_CALL disposing(const EventObject& rSource) override; +}; + +LinguMgrExitLstnr::LinguMgrExitLstnr() +{ + // add object to frame::Desktop EventListeners in order to properly call + // the AtExit function at application exit. + + uno::Reference< XComponentContext > xContext = getProcessComponentContext(); + xDesktop = Desktop::create( xContext ); + xDesktop->addEventListener( this ); +} + +LinguMgrExitLstnr::~LinguMgrExitLstnr() +{ + if (xDesktop.is()) + { + xDesktop->removeEventListener( this ); + xDesktop = nullptr; //! release reference to desktop + } + OSL_ENSURE(!xDesktop.is(), "reference to desktop should be released"); +} + +void LinguMgrExitLstnr::disposing(const EventObject& rSource) +{ + if (xDesktop.is() && rSource.Source == xDesktop) + { + xDesktop->removeEventListener( this ); + xDesktop = nullptr; //! release reference to desktop + + AtExit(); + } +} + +void LinguMgrExitLstnr::AtExit() +{ + SolarMutexGuard g; + + // release references + LinguMgr::xLngSvcMgr = nullptr; + LinguMgr::xSpell = nullptr; + LinguMgr::xHyph = nullptr; + LinguMgr::xThes = nullptr; + LinguMgr::xDicList = nullptr; + LinguMgr::xProp = nullptr; + LinguMgr::xIgnoreAll = nullptr; + LinguMgr::xChangeAll = nullptr; + + LinguMgr::bExiting = true; + + LinguMgr::pExitLstnr = nullptr; +} + + +rtl::Reference<LinguMgrExitLstnr> LinguMgr::pExitLstnr; +bool LinguMgr::bExiting = false; +uno::Reference< XLinguServiceManager2 > LinguMgr::xLngSvcMgr; +uno::Reference< XSpellChecker1 > LinguMgr::xSpell; +uno::Reference< XHyphenator > LinguMgr::xHyph; +uno::Reference< XThesaurus > LinguMgr::xThes; +uno::Reference< XSearchableDictionaryList > LinguMgr::xDicList; +uno::Reference< XLinguProperties > LinguMgr::xProp; +uno::Reference< XDictionary > LinguMgr::xIgnoreAll; +uno::Reference< XDictionary > LinguMgr::xChangeAll; + + +uno::Reference< XLinguServiceManager2 > LinguMgr::GetLngSvcMgr() +{ + if (bExiting) + return nullptr; + + if (!pExitLstnr) + pExitLstnr = new LinguMgrExitLstnr; + + if (!xLngSvcMgr.is()) + xLngSvcMgr = GetLngSvcMgr_Impl(); + + return xLngSvcMgr; +} + + +uno::Reference< XSpellChecker1 > LinguMgr::GetSpellChecker() +{ + return xSpell.is() ? xSpell : GetSpell(); +} + +uno::Reference< XHyphenator > LinguMgr::GetHyphenator() +{ + return xHyph.is() ? xHyph : GetHyph(); +} + +uno::Reference< XThesaurus > LinguMgr::GetThesaurus() +{ + return xThes.is() ? xThes : GetThes(); +} + +uno::Reference< XSearchableDictionaryList > LinguMgr::GetDictionaryList() +{ + return xDicList.is() ? xDicList : GetDicList(); +} + +uno::Reference< linguistic2::XLinguProperties > LinguMgr::GetLinguPropertySet() +{ + return xProp.is() ? xProp : GetProp(); +} + +uno::Reference< XDictionary > LinguMgr::GetStandardDic() +{ + //! don't hold reference to this + //! (it may be removed from dictionary list and needs to be + //! created empty if accessed again) + return GetStandard(); +} + +uno::Reference< XDictionary > LinguMgr::GetIgnoreAllList() +{ + return xIgnoreAll.is() ? xIgnoreAll : GetIgnoreAll(); +} + +uno::Reference< XDictionary > LinguMgr::GetChangeAllList() +{ + return xChangeAll.is() ? xChangeAll : GetChangeAll(); +} + +uno::Reference< XSpellChecker1 > LinguMgr::GetSpell() +{ + if (bExiting) + return nullptr; + + if (!pExitLstnr) + pExitLstnr = new LinguMgrExitLstnr; + + //! use dummy implementation in order to avoid loading of lingu DLL + xSpell = new SpellDummy_Impl; + return xSpell; +} + +uno::Reference< XHyphenator > LinguMgr::GetHyph() +{ + if (bExiting) + return nullptr; + + if (!pExitLstnr) + pExitLstnr = new LinguMgrExitLstnr; + + //! use dummy implementation in order to avoid loading of lingu DLL + xHyph = new HyphDummy_Impl; + return xHyph; +} + +uno::Reference< XThesaurus > LinguMgr::GetThes() +{ + if (bExiting) + return nullptr; + + if (!pExitLstnr) + pExitLstnr = new LinguMgrExitLstnr; + + //! use dummy implementation in order to avoid loading of lingu DLL + //! when only the XSupportedLocales interface is used. + //! The dummy accesses the real implementation (and thus loading the DLL) + //! when "real" work needs to be done only. + xThes = new ThesDummy_Impl; + return xThes; +} + +uno::Reference< XSearchableDictionaryList > LinguMgr::GetDicList() +{ + if (bExiting) + return nullptr; + + if (!pExitLstnr) + pExitLstnr = new LinguMgrExitLstnr; + + xDicList = linguistic2::DictionaryList::create( getProcessComponentContext() ); + return xDicList; +} + +uno::Reference< linguistic2::XLinguProperties > LinguMgr::GetProp() +{ + if (bExiting) + return nullptr; + + if (!pExitLstnr) + pExitLstnr = new LinguMgrExitLstnr; + + xProp = linguistic2::LinguProperties::create( getProcessComponentContext() ); + return xProp; +} + +uno::Reference< XDictionary > LinguMgr::GetIgnoreAll() +{ + if (bExiting) + return nullptr; + + if (!pExitLstnr) + pExitLstnr = new LinguMgrExitLstnr; + + uno::Reference< XSearchableDictionaryList > xTmpDicList( GetDictionaryList() ); + if (xTmpDicList.is()) + { + std::locale loc(Translate::Create("svt")); + xIgnoreAll = xTmpDicList->getDictionaryByName( + Translate::get(STR_DESCRIPTION_IGNOREALLLIST, loc) ); + } + return xIgnoreAll; +} + +uno::Reference< XDictionary > LinguMgr::GetChangeAll() +{ + if (bExiting) + return nullptr; + + if (!pExitLstnr) + pExitLstnr = new LinguMgrExitLstnr; + + uno::Reference< XSearchableDictionaryList > _xDicList = GetDictionaryList(); + if (_xDicList.is()) + { + xChangeAll = _xDicList->createDictionary( + "ChangeAllList", + LanguageTag::convertToLocale( LANGUAGE_NONE ), + DictionaryType_NEGATIVE, OUString() ); + } + return xChangeAll; +} + +uno::Reference< XDictionary > LinguMgr::GetStandard() +{ + // Tries to return a dictionary which may hold positive entries is + // persistent and not read-only. + + if (bExiting) + return nullptr; + + uno::Reference< XSearchableDictionaryList > xTmpDicList( GetDictionaryList() ); + if (!xTmpDicList.is()) + return nullptr; + + static constexpr OUString aDicName( u"standard.dic"_ustr ); + uno::Reference< XDictionary > xDic = xTmpDicList->getDictionaryByName( aDicName ); + if (!xDic.is()) + { + // try to create standard dictionary + uno::Reference< XDictionary > xTmp; + try + { + xTmp = xTmpDicList->createDictionary( aDicName, + LanguageTag::convertToLocale( LANGUAGE_NONE ), + DictionaryType_POSITIVE, + linguistic::GetWritableDictionaryURL( aDicName ) ); + } + catch(const css::uno::Exception &) + { + } + + // add new dictionary to list + if (xTmp.is()) + { + xTmpDicList->addDictionary( xTmp ); + xTmp->setActive( true ); + } + xDic = xTmp; + } +#if OSL_DEBUG_LEVEL > 1 + uno::Reference< XStorable > xStor( xDic, UNO_QUERY ); + OSL_ENSURE( xDic.is() && xDic->getDictionaryType() == DictionaryType_POSITIVE, + "wrong dictionary type"); + OSL_ENSURE( xDic.is() && LanguageTag( xDic->getLocale() ).getLanguageType() == LANGUAGE_NONE, + "wrong dictionary language"); + OSL_ENSURE( !xStor.is() || (xStor->hasLocation() && !xStor->isReadonly()), + "dictionary not editable" ); +#endif + + return xDic; +} + +SvxAlternativeSpelling SvxGetAltSpelling( + const css::uno::Reference< css::linguistic2::XHyphenatedWord > & rHyphWord ) +{ + SvxAlternativeSpelling aRes; + if (rHyphWord.is() && rHyphWord->isAlternativeSpelling()) + { + OUString aWord( rHyphWord->getWord() ), + aAltWord( rHyphWord->getHyphenatedWord() ); + sal_Int16 nHyphenationPos = rHyphWord->getHyphenationPos(), + nHyphenPos = rHyphWord->getHyphenPos(); + sal_Int16 nLen = static_cast<sal_Int16>(aWord.getLength()); + sal_Int16 nAltLen = static_cast<sal_Int16>(aAltWord.getLength()); + const sal_Unicode *pWord = aWord.getStr(), + *pAltWord = aAltWord.getStr(); + + // count number of chars from the left to the + // hyphenation pos / hyphen pos that are equal + sal_Int16 nL = 0; + while (nL <= nHyphenationPos && nL <= nHyphenPos + && pWord[ nL ] == pAltWord[ nL ]) + ++nL; + // count number of chars from the right to the + // hyphenation pos / hyphen pos that are equal + sal_Int16 nR = 0; + sal_Int32 nIdx = nLen - 1; + sal_Int32 nAltIdx = nAltLen - 1; + while (nIdx > nHyphenationPos && nAltIdx > nHyphenPos + && pWord[ nIdx-- ] == pAltWord[ nAltIdx-- ]) + ++nR; + + aRes.aReplacement = aAltWord.copy( nL, nAltLen - nL - nR ); + aRes.nChangedPos = nL; + aRes.nChangedLength = nLen - nL - nR; + aRes.bIsAltSpelling = true; + } + return aRes; +} + + +SvxDicListChgClamp::SvxDicListChgClamp( uno::Reference< XSearchableDictionaryList > _xDicList ) : + xDicList (std::move( _xDicList )) +{ + if (xDicList.is()) + { + xDicList->beginCollectEvents(); + } +} + +SvxDicListChgClamp::~SvxDicListChgClamp() +{ + if (xDicList.is()) + { + xDicList->endCollectEvents(); + } +} + +short SvxDicError(weld::Window *pParent, linguistic::DictionaryError nError) +{ + short nRes = 0; + if (linguistic::DictionaryError::NONE != nError) + { + TranslateId pRid; + switch (nError) + { + case linguistic::DictionaryError::FULL : pRid = RID_SVXSTR_DIC_ERR_FULL; break; + case linguistic::DictionaryError::READONLY : pRid = RID_SVXSTR_DIC_ERR_READONLY; break; + default: + pRid = RID_SVXSTR_DIC_ERR_UNKNOWN; + SAL_WARN("editeng", "unexpected case"); + } + std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(pParent, + VclMessageType::Info, VclButtonsType::Ok, + EditResId(pRid))); + nRes = xInfoBox->run(); + + } + return nRes; +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |