24#if OSL_DEBUG_LEVEL > 0
29#include <com/sun/star/beans/XPropertySet.hpp>
30#include <com/sun/star/uno/XComponentContext.hpp>
31#include <com/sun/star/linguistic2/XLinguProperties.hpp>
32#include <com/sun/star/linguistic2/XLinguServiceEventBroadcaster.hpp>
33#include <rtl/ustrbuf.hxx>
40#include <osl/mutex.hxx>
76 const OUString& rOrigWord,
86 OUString aText( xEntry->getDictionaryWord() );
87 sal_Int32 nTextLen = aText.getLength();
90 if (nTextLen > 0 && aText[ nTextLen - 1 ] !=
'=' && aText[ nTextLen - 1 ] !=
'[')
92 sal_Int16 nHyphenationPos = -1;
93 sal_Int16 nOrigHyphPos = -1;
95 OUStringBuffer aTmp( nTextLen );
98 sal_Int32 nHyphIdx = -1;
99 sal_Int32 nLeading = 0;
100 for (sal_Int32
i = 0;
i < nTextLen;
i++)
103 if (cTmp ==
'[' || cTmp ==
']')
105 if (cTmp !=
'=' && !bSkip2 && cTmp !=
']')
114 if (!bSkip && nHyphIdx >= 0)
116 if (nLeading <= nMaxLeading) {
117 nHyphenationPos =
static_cast<sal_Int16
>(nHyphIdx);
125 if (nHyphenationPos > 0)
127#if OSL_DEBUG_LEVEL > 0
129 if (std::u16string_view(aTmp) != rOrigWord)
133 std::u16string_view aShorter(aTmp), aLonger(rOrigWord);
134 if (aTmp.getLength() > rOrigWord.getLength())
135 std::swap(aShorter, aLonger);
136 sal_Int32 nS = aShorter.size();
137 sal_Int32 nL = aLonger.size();
138 if (nS > 0 && nL > 0)
140 assert( ((nS + 1 == nL) && aLonger[nL-1] ==
'.') &&
"HyphenatorDispatcher::buildHyphWord: unexpected difference between words!" );
145 sal_Int32 nHyphenPos = -1;
146 if (aText[ nOrigHyphPos ] ==
'[')
150 sal_Int32 endhyphpat = aText.indexOf(
']', nOrigHyphPos );
151 if (
'0' <= c && c <=
'9')
158 OUStringBuffer aTmp2 ( aTmp.copy(0, std::max (nHyphenationPos + 1 -
split, 0) ) );
159 aTmp2.append( aText.subView( nOrigHyphPos + 1, endhyphpat - nOrigHyphPos - 1) );
160 nHyphenPos = aTmp2.getLength();
161 aTmp2.append( aTmp.subView( nHyphenationPos + 1 ) );
163 if (rOrigWord[ rOrigWord.getLength() - 1 ] ==
'.')
165 aText = aTmp2.makeStringAndClear();
168 if (nHyphenPos == -1)
172 aText, (nHyphenPos > -1) ? nHyphenPos - 1 : nHyphenationPos);
191 OUString aText( xEntry->getDictionaryWord() );
192 sal_Int32 nTextLen = aText.getLength();
195 if (nTextLen > 0 && aText[ nTextLen - 1 ] !=
'=' && aText[ nTextLen - 1 ] !=
'[')
199 sal_Int16 *pPos = aHyphPos.getArray();
200 sal_Int32 nHyphCount = 0;
202 OUStringBuffer aTmp( nTextLen );
205 sal_Int32 nHyphIdx = -1;
206 for (sal_Int32
i = 0;
i < nTextLen;
i++)
209 if (cTmp ==
'[' || cTmp ==
']')
211 if (cTmp !=
'=' && !bSkip2 && cTmp !=
']')
219 if (!bSkip && nHyphIdx >= 0)
220 pPos[ nHyphCount++ ] =
static_cast<sal_Int16
>(nHyphIdx);
226 if (bSkip && nHyphIdx >= 0)
230 DBG_ASSERT( nHyphCount >= 0,
"lng : invalid hyphenation count");
234 aHyphPos.realloc( nHyphCount );
249 std::vector<Locale> aLocales;
250 aLocales.reserve(
aSvcMap.size());
252 std::transform(
aSvcMap.begin(),
aSvcMap.end(), std::back_inserter(aLocales),
253 [](HyphSvcByLangMap_t::const_reference elem) { return LanguageTag::convertToLocale(elem.first); });
269 const OUString& rWord,
const Locale& rLocale, sal_Int16 nMaxLeading,
270 const css::uno::Sequence< ::css::beans::PropertyValue >& rProperties )
276 sal_Int32 nWordLen = rWord.getLength();
279 nMaxLeading == 0 || nMaxLeading == nWordLen)
283 HyphSvcByLangMap_t::iterator aIt(
aSvcMap.find( nLanguage ) );
286 bool bWordModified =
false;
287 if (!pEntry || (nMaxLeading < 0 || nMaxLeading > nWordLen))
293 OUString aChkWord( rWord );
297 DBG_ASSERT( 1 == aSingleQuote.getLength(),
"unexpected length of quotation mark" );
298 if (!aSingleQuote.isEmpty())
299 aChkWord = aChkWord.replace( aSingleQuote[0],
'\'' );
304 sal_Int16 nChkMaxLeading =
static_cast<sal_Int16
>(
GetPosInWordToCheck( rWord, nMaxLeading ));
311 xEntry =
GetDicList()->queryDictionaryEntry( aChkWord, rLocale,
322 xRes =
buildHyphWord( rWord, xEntry, nLanguage, nChkMaxLeading );
326 sal_Int32 nLen = pEntry->
aSvcImplNames.hasElements() ? 1 : 0;
328 "lng : index out of range");
336 if (i <= pEntry->nLastTriedSvcIndex)
338 if (xHyph.is() && xHyph->hasLocale( rLocale ))
339 xRes = xHyph->hyphenate( aChkWord, rLocale, nChkMaxLeading,
359 xContext->getServiceManager()->createInstanceWithArgumentsAndContext(
363 catch (uno::Exception &)
365 SAL_WARN(
"linguistic",
"createInstanceWithArguments failed" );
370 xBroadcaster( xHyph, UNO_QUERY );
371 if (xBroadcaster.is())
374 if (xHyph.is() && xHyph->hasLocale( rLocale ))
375 xRes = xHyph->hyphenate( aChkWord, rLocale, nChkMaxLeading,
383 if (xHyph.is() && !xHyph->hasLocale( rLocale ))
389 if (bWordModified && xRes.is())
392 if (xRes.is() && xRes->getWord() != rWord)
394 xRes =
new HyphenatedWord( rWord, nLanguage, xRes->getHyphenationPos(),
395 xRes->getHyphenatedWord(),
396 xRes->getHyphenPos() );
405 const OUString& rWord,
const Locale& rLocale, sal_Int16 nIndex,
406 const css::uno::Sequence< ::css::beans::PropertyValue >& rProperties )
412 sal_Int32 nWordLen = rWord.getLength();
418 HyphSvcByLangMap_t::iterator aIt(
aSvcMap.find( nLanguage ) );
421 bool bWordModified =
false;
428 OUString aChkWord( rWord );
432 DBG_ASSERT( 1 == aSingleQuote.getLength(),
"unexpected length of quotation mark" );
433 if (!aSingleQuote.isEmpty())
434 aChkWord = aChkWord.replace( aSingleQuote[0],
'\'' );
446 xEntry =
GetDicList()->queryDictionaryEntry( aChkWord, rLocale,
453 if (xRes.is() && xRes->isAlternativeSpelling() && xRes->getHyphenationPos() ==
nIndex)
458 sal_Int32 nLen = pEntry->
aSvcImplNames.hasElements() ? 1 : 0;
460 "lng : index out of range");
468 if (i <= pEntry->nLastTriedSvcIndex)
470 if (xHyph.is() && xHyph->hasLocale( rLocale ))
471 xRes = xHyph->queryAlternativeSpelling( aChkWord, rLocale,
472 nChkIndex, rProperties );
491 xContext->getServiceManager()->createInstanceWithArgumentsAndContext(
494 catch (uno::Exception &)
496 SAL_WARN(
"linguistic",
"createInstanceWithArguments failed" );
501 xBroadcaster( xHyph, UNO_QUERY );
502 if (xBroadcaster.is())
505 if (xHyph.is() && xHyph->hasLocale( rLocale ))
506 xRes = xHyph->queryAlternativeSpelling( aChkWord, rLocale,
507 nChkIndex, rProperties );
514 if (xHyph.is() && !xHyph->hasLocale( rLocale ))
520 if (bWordModified && xRes.is())
523 if (xRes.is() && xRes->getWord() != rWord)
525 xRes =
new HyphenatedWord( rWord, nLanguage, xRes->getHyphenationPos(),
526 xRes->getHyphenatedWord(),
527 xRes->getHyphenPos() );
536 const OUString& rWord,
const Locale& rLocale,
537 const css::uno::Sequence< ::css::beans::PropertyValue >& rProperties )
548 HyphSvcByLangMap_t::iterator aIt(
aSvcMap.find( nLanguage ) );
553 OUString aChkWord( rWord );
557 DBG_ASSERT( 1 == aSingleQuote.getLength(),
"unexpected length of quotation mark" );
558 if (!aSingleQuote.isEmpty())
559 aChkWord = aChkWord.replace( aSingleQuote[0],
'\'' );
570 xEntry =
GetDicList()->queryDictionaryEntry( aChkWord, rLocale,
580 sal_Int32 nLen = pEntry->
aSvcImplNames.hasElements() ? 1 : 0;
582 "lng : index out of range");
590 if (i <= pEntry->nLastTriedSvcIndex)
592 if (xHyph.is() && xHyph->hasLocale( rLocale ))
593 xRes = xHyph->createPossibleHyphens( aChkWord, rLocale,
612 xHyph.set( xContext->getServiceManager()->createInstanceWithArgumentsAndContext(
616 catch (uno::Exception &)
618 SAL_WARN(
"linguistic",
"createWithArguments failed" );
623 xBroadcaster( xHyph, UNO_QUERY );
624 if (xBroadcaster.is())
627 if (xHyph.is() && xHyph->hasLocale( rLocale ))
628 xRes = xHyph->createPossibleHyphens( aChkWord, rLocale, rProperties );
635 if (xHyph.is() && !xHyph->hasLocale( rLocale ))
641 if (xRes.is() && xRes->getWord() != rWord)
644 xRes->getPossibleHyphens(),
645 xRes->getHyphenationPositions() );
659 if (!rSvcImplNames.hasElements())
675 auto pTmpEntry = std::make_shared<LangSvcEntries_Hyph>( rSvcImplNames[0] );
677 aSvcMap[ nLanguage ] = pTmpEntry;
692 const HyphSvcByLangMap_t::const_iterator aIt(
aSvcMap.find( nLanguage ) );
697 if (aRes.hasElements())
virtual css::uno::Sequence< OUString > GetServiceList(const css::lang::Locale &rLocale) const override
virtual ~HyphenatorDispatcher() override
virtual css::uno::Reference< css::linguistic2::XPossibleHyphens > SAL_CALL createPossibleHyphens(const OUString &aWord, const css::lang::Locale &aLocale, const css::uno::Sequence< ::css::beans::PropertyValue > &aProperties) override
const css::uno::Reference< css::linguistic2::XSearchableDictionaryList > & GetDicList()
virtual css::uno::Reference< css::linguistic2::XHyphenatedWord > SAL_CALL hyphenate(const OUString &aWord, const css::lang::Locale &aLocale, sal_Int16 nMaxLeading, const css::uno::Sequence< ::css::beans::PropertyValue > &aProperties) override
std::map< LanguageType, LangSvcEntries_Hyph_Ptr_t > HyphSvcByLangMap_t
static css::uno::Reference< css::linguistic2::XHyphenatedWord > buildHyphWord(const OUString &rOrigWord, const css::uno::Reference< css::linguistic2::XDictionaryEntry > &xEntry, LanguageType nLang, sal_Int16 nMaxLeading)
HyphenatorDispatcher(const HyphenatorDispatcher &)=delete
virtual void SetServiceList(const css::lang::Locale &rLocale, const css::uno::Sequence< OUString > &rSvcImplNames) override
const css::uno::Reference< css::linguistic2::XLinguProperties > & GetPropSet()
virtual css::uno::Reference< css::linguistic2::XHyphenatedWord > SAL_CALL queryAlternativeSpelling(const OUString &aWord, const css::lang::Locale &aLocale, sal_Int16 nIndex, const css::uno::Sequence< ::css::beans::PropertyValue > &aProperties) override
virtual css::uno::Sequence< css::lang::Locale > SAL_CALL getLocales() override
HyphSvcByLangMap_t aSvcMap
virtual sal_Bool SAL_CALL hasLocale(const css::lang::Locale &aLocale) override
static css::uno::Reference< css::linguistic2::XPossibleHyphens > buildPossHyphens(const css::uno::Reference< css::linguistic2::XDictionaryEntry > &xEntry, LanguageType nLanguage)
bool AddLngSvcEvtBroadcaster(const css::uno::Reference< css::linguistic2::XLinguServiceEventBroadcaster > &rxBroadcaster)
#define DBG_ASSERT(sCon, aError)
#define SAL_WARN(area, stream)
std::vector< OUString > split(std::u16string_view rStr, sal_Unicode cSeparator)
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
Reference< XComponentContext > getProcessComponentContext()
bool LinguIsUnspecified(LanguageType nLanguage)
Checks if a LanguageType is one of the values that denote absence of language or undetermined languag...
bool RemoveHyphens(OUString &rTxt)
bool RemoveControlChars(OUString &rTxt)
uno::Reference< XHyphenatedWord > RebuildHyphensAndControlChars(const OUString &rOrigWord, uno::Reference< XHyphenatedWord > const &rxHyphWord)
sal_Int32 GetPosInWordToCheck(std::u16string_view rTxt, sal_Int32 nPos)
osl::Mutex & GetLinguMutex()
! multi-thread safe mutex for all platforms !!
bool IsIgnoreControlChars(const PropertyValues &rProperties, const uno::Reference< XPropertySet > &rxProp)
const LocaleDataWrapper & GetLocaleDataWrapper(LanguageType nLang)
LanguageType LinguLocaleToLanguage(const css::lang::Locale &rLocale)
Convert Locale to LanguageType for legacy handling.
bool IsUseDicList(const PropertyValues &rProperties, const uno::Reference< XPropertySet > &rxProp)
css::uno::Sequence< css::uno::Reference< css::linguistic2::XHyphenator > > aSvcRefs
css::uno::Sequence< OUString > aSvcImplNames
sal_Int16 nLastTriedSvcIndex