use more concrete UNO classes in linguistic
Change-Id: Iae9dc3c7dadc21e3d92192a197f42c55e590fab1 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/182434 Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk> Tested-by: Jenkins
This commit is contained in:
parent
835fcbca7a
commit
9865922ff1
@ -29,6 +29,7 @@
|
||||
#include <cppuhelper/implbase.hxx>
|
||||
#include <i18nlangtag/lang.h>
|
||||
#include <rtl/ustring.hxx>
|
||||
#include <rtl/ref.hxx>
|
||||
#include <linguistic/lngdllapi.h>
|
||||
|
||||
#include <vector>
|
||||
@ -45,7 +46,6 @@ namespace osl { class Mutex; }
|
||||
class CharClass;
|
||||
class LocaleDataWrapper;
|
||||
|
||||
|
||||
inline constexpr OUString SN_GRAMMARCHECKER = u"com.sun.star.linguistic2.Proofreader"_ustr;
|
||||
inline constexpr OUString SN_SPELLCHECKER = u"com.sun.star.linguistic2.SpellChecker"_ustr;
|
||||
inline constexpr OUString SN_HYPHENATOR = u"com.sun.star.linguistic2.Hyphenator"_ustr;
|
||||
@ -54,6 +54,7 @@ inline constexpr OUString SN_THESAURUS = u"com.sun.star.linguistic2.Thesaurus"_u
|
||||
|
||||
namespace linguistic
|
||||
{
|
||||
class HyphenatedWord;
|
||||
|
||||
|
||||
// AddEntryToDic return values
|
||||
@ -122,7 +123,7 @@ LNG_DLLPUBLIC OUString GetWritableDictionaryURL( std::u16string_view rDicName )
|
||||
|
||||
LNG_DLLPUBLIC sal_Int32 GetPosInWordToCheck( std::u16string_view rTxt, sal_Int32 nPos );
|
||||
|
||||
css::uno::Reference< css::linguistic2::XHyphenatedWord >
|
||||
rtl::Reference< HyphenatedWord >
|
||||
RebuildHyphensAndControlChars(
|
||||
const OUString &rOrigWord,
|
||||
css::uno::Reference< css::linguistic2::XHyphenatedWord > const &rxHyphWord );
|
||||
|
@ -72,172 +72,169 @@ void HyphenatorDispatcher::ClearSvcList()
|
||||
}
|
||||
|
||||
|
||||
Reference<XHyphenatedWord> HyphenatorDispatcher::buildHyphWord(
|
||||
rtl::Reference< HyphenatedWord > HyphenatorDispatcher::buildHyphWord(
|
||||
const OUString& rOrigWord,
|
||||
const Reference<XDictionaryEntry> &xEntry,
|
||||
LanguageType nLang, sal_Int16 nMaxLeading )
|
||||
{
|
||||
MutexGuard aGuard( GetLinguMutex() );
|
||||
|
||||
Reference< XHyphenatedWord > xRes;
|
||||
if (!xEntry.is())
|
||||
return nullptr;
|
||||
|
||||
if (xEntry.is())
|
||||
OUString aText( xEntry->getDictionaryWord() );
|
||||
sal_Int32 nTextLen = aText.getLength();
|
||||
|
||||
// trailing '=' means "hyphenation should not be possible"
|
||||
if (nTextLen <= 0 || aText[ nTextLen - 1 ] == '=' || aText[ nTextLen - 1 ] == '[')
|
||||
return nullptr;
|
||||
|
||||
sal_Int16 nHyphenationPos = -1;
|
||||
sal_Int16 nOrigHyphPos = -1;
|
||||
|
||||
OUStringBuffer aTmp( nTextLen );
|
||||
bool bSkip = false;
|
||||
bool bSkip2 = false;
|
||||
sal_Int32 nHyphIdx = -1;
|
||||
sal_Int32 nLeading = 0;
|
||||
for (sal_Int32 i = 0; i < nTextLen; i++)
|
||||
{
|
||||
OUString aText( xEntry->getDictionaryWord() );
|
||||
sal_Int32 nTextLen = aText.getLength();
|
||||
|
||||
// trailing '=' means "hyphenation should not be possible"
|
||||
if (nTextLen > 0 && aText[ nTextLen - 1 ] != '=' && aText[ nTextLen - 1 ] != '[')
|
||||
sal_Unicode cTmp = aText[i];
|
||||
if (cTmp == '[' || cTmp == ']')
|
||||
bSkip2 = !bSkip2;
|
||||
if (cTmp != '=' && !bSkip2 && cTmp != ']')
|
||||
{
|
||||
sal_Int16 nHyphenationPos = -1;
|
||||
sal_Int16 nOrigHyphPos = -1;
|
||||
|
||||
OUStringBuffer aTmp( nTextLen );
|
||||
bool bSkip = false;
|
||||
bool bSkip2 = false;
|
||||
sal_Int32 nHyphIdx = -1;
|
||||
sal_Int32 nLeading = 0;
|
||||
for (sal_Int32 i = 0; i < nTextLen; i++)
|
||||
aTmp.append( cTmp );
|
||||
nLeading++;
|
||||
bSkip = false;
|
||||
nHyphIdx++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!bSkip && nHyphIdx >= 0)
|
||||
{
|
||||
sal_Unicode cTmp = aText[i];
|
||||
if (cTmp == '[' || cTmp == ']')
|
||||
bSkip2 = !bSkip2;
|
||||
if (cTmp != '=' && !bSkip2 && cTmp != ']')
|
||||
{
|
||||
aTmp.append( cTmp );
|
||||
nLeading++;
|
||||
bSkip = false;
|
||||
nHyphIdx++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!bSkip && nHyphIdx >= 0)
|
||||
{
|
||||
if (nLeading <= nMaxLeading) {
|
||||
nHyphenationPos = static_cast<sal_Int16>(nHyphIdx);
|
||||
nOrigHyphPos = i;
|
||||
}
|
||||
}
|
||||
bSkip = true; //! multiple '=' should count as one only
|
||||
if (nLeading <= nMaxLeading) {
|
||||
nHyphenationPos = static_cast<sal_Int16>(nHyphIdx);
|
||||
nOrigHyphPos = i;
|
||||
}
|
||||
}
|
||||
bSkip = true; //! multiple '=' should count as one only
|
||||
}
|
||||
}
|
||||
|
||||
if (nHyphenationPos <= 0)
|
||||
return nullptr;
|
||||
|
||||
if (nHyphenationPos > 0)
|
||||
{
|
||||
#if OSL_DEBUG_LEVEL > 0
|
||||
{
|
||||
if (std::u16string_view(aTmp) != rOrigWord)
|
||||
{
|
||||
// both words should only differ by a having a trailing '.'
|
||||
// character or not...
|
||||
std::u16string_view aShorter(aTmp), aLonger(rOrigWord);
|
||||
if (aTmp.getLength() > rOrigWord.getLength())
|
||||
std::swap(aShorter, aLonger);
|
||||
sal_Int32 nS = aShorter.size();
|
||||
sal_Int32 nL = aLonger.size();
|
||||
if (nS > 0 && nL > 0)
|
||||
{
|
||||
assert( ((nS + 1 == nL) && aLonger[nL-1] == '.') && "HyphenatorDispatcher::buildHyphWord: unexpected difference between words!" );
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
sal_Int32 nHyphenPos = -1;
|
||||
if (aText[ nOrigHyphPos ] == '[') // alternative hyphenation
|
||||
{
|
||||
sal_Int16 split = 0;
|
||||
sal_Unicode c = aText [ nOrigHyphPos + 1 ];
|
||||
sal_Int32 endhyphpat = aText.indexOf( ']', nOrigHyphPos );
|
||||
if ('0' <= c && c <= '9')
|
||||
{
|
||||
split = c - '0';
|
||||
nOrigHyphPos++;
|
||||
}
|
||||
if (endhyphpat > -1)
|
||||
{
|
||||
OUStringBuffer aTmp2 ( aTmp.copy(0, std::max (nHyphenationPos + 1 - split, 0) ) );
|
||||
aTmp2.append( aText.subView( nOrigHyphPos + 1, endhyphpat - nOrigHyphPos - 1) );
|
||||
nHyphenPos = aTmp2.getLength();
|
||||
aTmp2.append( aTmp.subView( nHyphenationPos + 1 ) );
|
||||
//! take care of #i22591#
|
||||
if (rOrigWord[ rOrigWord.getLength() - 1 ] == '.')
|
||||
aTmp2.append( '.' );
|
||||
aText = aTmp2.makeStringAndClear();
|
||||
}
|
||||
}
|
||||
if (nHyphenPos == -1)
|
||||
aText = rOrigWord;
|
||||
|
||||
xRes = new HyphenatedWord( rOrigWord, nLang, nHyphenationPos,
|
||||
aText, (nHyphenPos > -1) ? nHyphenPos - 1 : nHyphenationPos);
|
||||
{
|
||||
if (std::u16string_view(aTmp) != rOrigWord)
|
||||
{
|
||||
// both words should only differ by a having a trailing '.'
|
||||
// character or not...
|
||||
std::u16string_view aShorter(aTmp), aLonger(rOrigWord);
|
||||
if (aTmp.getLength() > rOrigWord.getLength())
|
||||
std::swap(aShorter, aLonger);
|
||||
sal_Int32 nS = aShorter.size();
|
||||
sal_Int32 nL = aLonger.size();
|
||||
if (nS > 0 && nL > 0)
|
||||
{
|
||||
assert( ((nS + 1 == nL) && aLonger[nL-1] == '.') && "HyphenatorDispatcher::buildHyphWord: unexpected difference between words!" );
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
sal_Int32 nHyphenPos = -1;
|
||||
if (aText[ nOrigHyphPos ] == '[') // alternative hyphenation
|
||||
{
|
||||
sal_Int16 split = 0;
|
||||
sal_Unicode c = aText [ nOrigHyphPos + 1 ];
|
||||
sal_Int32 endhyphpat = aText.indexOf( ']', nOrigHyphPos );
|
||||
if ('0' <= c && c <= '9')
|
||||
{
|
||||
split = c - '0';
|
||||
nOrigHyphPos++;
|
||||
}
|
||||
if (endhyphpat > -1)
|
||||
{
|
||||
OUStringBuffer aTmp2 ( aTmp.copy(0, std::max (nHyphenationPos + 1 - split, 0) ) );
|
||||
aTmp2.append( aText.subView( nOrigHyphPos + 1, endhyphpat - nOrigHyphPos - 1) );
|
||||
nHyphenPos = aTmp2.getLength();
|
||||
aTmp2.append( aTmp.subView( nHyphenationPos + 1 ) );
|
||||
//! take care of #i22591#
|
||||
if (rOrigWord[ rOrigWord.getLength() - 1 ] == '.')
|
||||
aTmp2.append( '.' );
|
||||
aText = aTmp2.makeStringAndClear();
|
||||
}
|
||||
}
|
||||
if (nHyphenPos == -1)
|
||||
aText = rOrigWord;
|
||||
|
||||
rtl::Reference< HyphenatedWord > xRes = new HyphenatedWord( rOrigWord, nLang, nHyphenationPos,
|
||||
aText, (nHyphenPos > -1) ? nHyphenPos - 1 : nHyphenationPos);
|
||||
|
||||
|
||||
return xRes;
|
||||
}
|
||||
|
||||
|
||||
Reference< XPossibleHyphens > HyphenatorDispatcher::buildPossHyphens(
|
||||
rtl::Reference<PossibleHyphens> HyphenatorDispatcher::buildPossHyphens(
|
||||
const Reference< XDictionaryEntry > &xEntry, LanguageType nLanguage )
|
||||
{
|
||||
MutexGuard aGuard( GetLinguMutex() );
|
||||
|
||||
Reference<XPossibleHyphens> xRes;
|
||||
if (!xEntry.is())
|
||||
return nullptr;
|
||||
|
||||
if (xEntry.is())
|
||||
// text with hyphenation info
|
||||
OUString aText( xEntry->getDictionaryWord() );
|
||||
sal_Int32 nTextLen = aText.getLength();
|
||||
|
||||
// trailing '=' means "hyphenation should not be possible"
|
||||
if (nTextLen <= 0 || aText[ nTextLen - 1 ] == '=' || aText[ nTextLen - 1 ] == '[')
|
||||
return nullptr;
|
||||
|
||||
// sequence to hold hyphenation positions
|
||||
Sequence< sal_Int16 > aHyphPos( nTextLen );
|
||||
sal_Int16 *pPos = aHyphPos.getArray();
|
||||
sal_Int32 nHyphCount = 0;
|
||||
|
||||
OUStringBuffer aTmp( nTextLen );
|
||||
bool bSkip = false;
|
||||
bool bSkip2 = false;
|
||||
sal_Int32 nHyphIdx = -1;
|
||||
for (sal_Int32 i = 0; i < nTextLen; i++)
|
||||
{
|
||||
// text with hyphenation info
|
||||
OUString aText( xEntry->getDictionaryWord() );
|
||||
sal_Int32 nTextLen = aText.getLength();
|
||||
|
||||
// trailing '=' means "hyphenation should not be possible"
|
||||
if (nTextLen > 0 && aText[ nTextLen - 1 ] != '=' && aText[ nTextLen - 1 ] != '[')
|
||||
sal_Unicode cTmp = aText[i];
|
||||
if (cTmp == '[' || cTmp == ']')
|
||||
bSkip2 = !bSkip2;
|
||||
if (cTmp != '=' && !bSkip2 && cTmp != ']')
|
||||
{
|
||||
// sequence to hold hyphenation positions
|
||||
Sequence< sal_Int16 > aHyphPos( nTextLen );
|
||||
sal_Int16 *pPos = aHyphPos.getArray();
|
||||
sal_Int32 nHyphCount = 0;
|
||||
|
||||
OUStringBuffer aTmp( nTextLen );
|
||||
bool bSkip = false;
|
||||
bool bSkip2 = false;
|
||||
sal_Int32 nHyphIdx = -1;
|
||||
for (sal_Int32 i = 0; i < nTextLen; i++)
|
||||
{
|
||||
sal_Unicode cTmp = aText[i];
|
||||
if (cTmp == '[' || cTmp == ']')
|
||||
bSkip2 = !bSkip2;
|
||||
if (cTmp != '=' && !bSkip2 && cTmp != ']')
|
||||
{
|
||||
aTmp.append( cTmp );
|
||||
bSkip = false;
|
||||
nHyphIdx++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!bSkip && nHyphIdx >= 0)
|
||||
pPos[ nHyphCount++ ] = static_cast<sal_Int16>(nHyphIdx);
|
||||
bSkip = true; //! multiple '=' should count as one only
|
||||
}
|
||||
}
|
||||
|
||||
// ignore (multiple) trailing '='
|
||||
if (bSkip && nHyphIdx >= 0)
|
||||
{
|
||||
nHyphCount--;
|
||||
}
|
||||
DBG_ASSERT( nHyphCount >= 0, "lng : invalid hyphenation count");
|
||||
|
||||
if (nHyphCount > 0)
|
||||
{
|
||||
aHyphPos.realloc( nHyphCount );
|
||||
xRes = new PossibleHyphens( aTmp.makeStringAndClear(), nLanguage,
|
||||
aText, aHyphPos );
|
||||
}
|
||||
aTmp.append( cTmp );
|
||||
bSkip = false;
|
||||
nHyphIdx++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!bSkip && nHyphIdx >= 0)
|
||||
pPos[ nHyphCount++ ] = static_cast<sal_Int16>(nHyphIdx);
|
||||
bSkip = true; //! multiple '=' should count as one only
|
||||
}
|
||||
}
|
||||
|
||||
// ignore (multiple) trailing '='
|
||||
if (bSkip && nHyphIdx >= 0)
|
||||
{
|
||||
nHyphCount--;
|
||||
}
|
||||
DBG_ASSERT( nHyphCount >= 0, "lng : invalid hyphenation count");
|
||||
|
||||
if (nHyphCount <= 0)
|
||||
return nullptr;
|
||||
|
||||
aHyphPos.realloc( nHyphCount );
|
||||
rtl::Reference<PossibleHyphens> xRes = new PossibleHyphens( aTmp.makeStringAndClear(), nLanguage,
|
||||
aText, aHyphPos );
|
||||
|
||||
return xRes;
|
||||
}
|
||||
|
||||
|
@ -32,7 +32,7 @@
|
||||
#include "defs.hxx"
|
||||
|
||||
class LngSvcMgr;
|
||||
|
||||
namespace linguistic { class HyphenatedWord; class PossibleHyphens; }
|
||||
|
||||
class HyphenatorDispatcher :
|
||||
public cppu::WeakImplHelper
|
||||
@ -60,12 +60,12 @@ class HyphenatorDispatcher :
|
||||
|
||||
void ClearSvcList();
|
||||
|
||||
static css::uno::Reference< css::linguistic2::XHyphenatedWord>
|
||||
static rtl::Reference< linguistic::HyphenatedWord >
|
||||
buildHyphWord( const OUString& rOrigWord,
|
||||
const css::uno::Reference< css::linguistic2::XDictionaryEntry> &xEntry,
|
||||
LanguageType nLang, sal_Int16 nMaxLeading );
|
||||
|
||||
static css::uno::Reference< css::linguistic2::XPossibleHyphens >
|
||||
static rtl::Reference< linguistic::PossibleHyphens >
|
||||
buildPossHyphens( const css::uno::Reference< css::linguistic2::XDictionaryEntry > &xEntry,
|
||||
LanguageType nLanguage );
|
||||
|
||||
|
@ -498,63 +498,60 @@ sal_Int32 GetPosInWordToCheck( std::u16string_view rTxt, sal_Int32 nPos )
|
||||
return nRes;
|
||||
}
|
||||
|
||||
uno::Reference< XHyphenatedWord > RebuildHyphensAndControlChars(
|
||||
rtl::Reference< HyphenatedWord > RebuildHyphensAndControlChars(
|
||||
const OUString &rOrigWord,
|
||||
uno::Reference< XHyphenatedWord > const &rxHyphWord )
|
||||
{
|
||||
uno::Reference< XHyphenatedWord > xRes;
|
||||
if (!rOrigWord.isEmpty() && rxHyphWord.is())
|
||||
if (rOrigWord.isEmpty() || !rxHyphWord.is())
|
||||
return nullptr;
|
||||
|
||||
sal_Int16 nChgPos = 0,
|
||||
nChgLen = 0;
|
||||
OUString aRplc;
|
||||
bool bAltSpelling = GetAltSpelling( nChgPos, nChgLen, aRplc, rxHyphWord );
|
||||
|
||||
OUString aOrigHyphenatedWord;
|
||||
sal_Int16 nOrigHyphenPos = -1;
|
||||
sal_Int16 nOrigHyphenationPos = -1;
|
||||
if (!bAltSpelling)
|
||||
{
|
||||
sal_Int16 nChgPos = 0,
|
||||
nChgLen = 0;
|
||||
OUString aRplc;
|
||||
bool bAltSpelling = GetAltSpelling( nChgPos, nChgLen, aRplc, rxHyphWord );
|
||||
|
||||
OUString aOrigHyphenatedWord;
|
||||
sal_Int16 nOrigHyphenPos = -1;
|
||||
sal_Int16 nOrigHyphenationPos = -1;
|
||||
if (!bAltSpelling)
|
||||
{
|
||||
aOrigHyphenatedWord = rOrigWord;
|
||||
nOrigHyphenPos = GetOrigWordPos( rOrigWord, rxHyphWord->getHyphenPos() );
|
||||
nOrigHyphenationPos = GetOrigWordPos( rOrigWord, rxHyphWord->getHyphenationPos() );
|
||||
}
|
||||
else
|
||||
{
|
||||
//! should at least work with the German words
|
||||
//! B-"u-c-k-er and Sc-hif-fah-rt
|
||||
|
||||
sal_Int16 nPos = GetOrigWordPos( rOrigWord, nChgPos );
|
||||
|
||||
// get words like Sc-hif-fah-rt to work correct
|
||||
sal_Int16 nHyphenationPos = rxHyphWord->getHyphenationPos();
|
||||
if (nChgPos > nHyphenationPos)
|
||||
--nPos;
|
||||
|
||||
std::u16string_view aLeft = rOrigWord.subView( 0, nPos );
|
||||
std::u16string_view aRight = rOrigWord.subView( nPos ); // FIXME: changes at the right side
|
||||
|
||||
aOrigHyphenatedWord = aLeft + aRplc + aRight;
|
||||
|
||||
nOrigHyphenPos = sal::static_int_cast< sal_Int16 >(aLeft.size() +
|
||||
rxHyphWord->getHyphenPos() - nChgPos);
|
||||
nOrigHyphenationPos = GetOrigWordPos( rOrigWord, nHyphenationPos );
|
||||
}
|
||||
|
||||
if (nOrigHyphenPos == -1 || nOrigHyphenationPos == -1)
|
||||
{
|
||||
SAL_WARN( "linguistic", "failed to get nOrigHyphenPos or nOrigHyphenationPos" );
|
||||
}
|
||||
else
|
||||
{
|
||||
LanguageType nLang = LinguLocaleToLanguage( rxHyphWord->getLocale() );
|
||||
xRes = new HyphenatedWord(
|
||||
rOrigWord, nLang, nOrigHyphenationPos,
|
||||
aOrigHyphenatedWord, nOrigHyphenPos );
|
||||
}
|
||||
|
||||
aOrigHyphenatedWord = rOrigWord;
|
||||
nOrigHyphenPos = GetOrigWordPos( rOrigWord, rxHyphWord->getHyphenPos() );
|
||||
nOrigHyphenationPos = GetOrigWordPos( rOrigWord, rxHyphWord->getHyphenationPos() );
|
||||
}
|
||||
return xRes;
|
||||
else
|
||||
{
|
||||
//! should at least work with the German words
|
||||
//! B-"u-c-k-er and Sc-hif-fah-rt
|
||||
|
||||
sal_Int16 nPos = GetOrigWordPos( rOrigWord, nChgPos );
|
||||
|
||||
// get words like Sc-hif-fah-rt to work correct
|
||||
sal_Int16 nHyphenationPos = rxHyphWord->getHyphenationPos();
|
||||
if (nChgPos > nHyphenationPos)
|
||||
--nPos;
|
||||
|
||||
std::u16string_view aLeft = rOrigWord.subView( 0, nPos );
|
||||
std::u16string_view aRight = rOrigWord.subView( nPos ); // FIXME: changes at the right side
|
||||
|
||||
aOrigHyphenatedWord = aLeft + aRplc + aRight;
|
||||
|
||||
nOrigHyphenPos = sal::static_int_cast< sal_Int16 >(aLeft.size() +
|
||||
rxHyphWord->getHyphenPos() - nChgPos);
|
||||
nOrigHyphenationPos = GetOrigWordPos( rOrigWord, nHyphenationPos );
|
||||
}
|
||||
|
||||
if (nOrigHyphenPos != -1 && nOrigHyphenationPos != -1)
|
||||
{
|
||||
SAL_WARN( "linguistic", "failed to get nOrigHyphenPos or nOrigHyphenationPos" );
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
LanguageType nLang = LinguLocaleToLanguage( rxHyphWord->getLocale() );
|
||||
return new HyphenatedWord(
|
||||
rOrigWord, nLang, nOrigHyphenationPos,
|
||||
aOrigHyphenatedWord, nOrigHyphenPos );
|
||||
|
||||
}
|
||||
|
||||
bool IsUpper( const OUString &rText, sal_Int32 nPos, sal_Int32 nLen, LanguageType nLanguage )
|
||||
|
@ -424,299 +424,299 @@ Reference< XSpellAlternatives > SpellCheckerDispatcher::spell_Impl(
|
||||
{
|
||||
MutexGuard aGuard( GetLinguMutex() );
|
||||
|
||||
Reference< XSpellAlternatives > xRes;
|
||||
|
||||
if (LinguIsUnspecified( nLanguage) || rWord.isEmpty())
|
||||
return xRes;
|
||||
return nullptr;
|
||||
|
||||
// search for entry with that language
|
||||
SpellSvcByLangMap_t::iterator aIt( m_aSvcMap.find( nLanguage ) );
|
||||
LangSvcEntries_Spell *pEntry = aIt != m_aSvcMap.end() ? aIt->second.get() : nullptr;
|
||||
|
||||
if (pEntry)
|
||||
if (!pEntry)
|
||||
return nullptr;
|
||||
|
||||
Reference< XSpellAlternatives > xRes;
|
||||
|
||||
OUString aChkWord( rWord );
|
||||
Locale aLocale( LanguageTag::convertToLocale( nLanguage ) );
|
||||
|
||||
// replace typographical apostroph by ascii apostroph
|
||||
OUString aSingleQuote( GetLocaleDataWrapper( nLanguage ).getQuotationMarkEnd() );
|
||||
DBG_ASSERT( 1 == aSingleQuote.getLength(), "unexpected length of quotation mark" );
|
||||
if (!aSingleQuote.isEmpty())
|
||||
aChkWord = aChkWord.replace( aSingleQuote[0], '\'' );
|
||||
|
||||
RemoveHyphens( aChkWord );
|
||||
if (IsIgnoreControlChars( rProperties, GetPropSet() ))
|
||||
RemoveControlChars( aChkWord );
|
||||
|
||||
sal_Int32 nLen = pEntry->aSvcRefs.getLength();
|
||||
DBG_ASSERT( nLen == pEntry->aSvcImplNames.getLength(),
|
||||
"lng : sequence length mismatch");
|
||||
DBG_ASSERT( pEntry->nLastTriedSvcIndex < nLen,
|
||||
"lng : index out of range");
|
||||
|
||||
sal_Int32 i = 0;
|
||||
Reference< XSpellAlternatives > xTmpRes;
|
||||
bool bTmpResValid = false;
|
||||
|
||||
// try already instantiated services first
|
||||
{
|
||||
OUString aChkWord( rWord );
|
||||
Locale aLocale( LanguageTag::convertToLocale( nLanguage ) );
|
||||
|
||||
// replace typographical apostroph by ascii apostroph
|
||||
OUString aSingleQuote( GetLocaleDataWrapper( nLanguage ).getQuotationMarkEnd() );
|
||||
DBG_ASSERT( 1 == aSingleQuote.getLength(), "unexpected length of quotation mark" );
|
||||
if (!aSingleQuote.isEmpty())
|
||||
aChkWord = aChkWord.replace( aSingleQuote[0], '\'' );
|
||||
|
||||
RemoveHyphens( aChkWord );
|
||||
if (IsIgnoreControlChars( rProperties, GetPropSet() ))
|
||||
RemoveControlChars( aChkWord );
|
||||
|
||||
sal_Int32 nLen = pEntry->aSvcRefs.getLength();
|
||||
DBG_ASSERT( nLen == pEntry->aSvcImplNames.getLength(),
|
||||
"lng : sequence length mismatch");
|
||||
DBG_ASSERT( pEntry->nLastTriedSvcIndex < nLen,
|
||||
"lng : index out of range");
|
||||
|
||||
sal_Int32 i = 0;
|
||||
Reference< XSpellAlternatives > xTmpRes;
|
||||
bool bTmpResValid = false;
|
||||
|
||||
// try already instantiated services first
|
||||
const Reference< XSpellChecker > *pRef = pEntry->aSvcRefs.getConstArray();
|
||||
sal_Int32 nNumSuggestions = -1;
|
||||
while (i <= pEntry->nLastTriedSvcIndex
|
||||
&& (!bTmpResValid || xTmpRes.is()) )
|
||||
{
|
||||
const Reference< XSpellChecker > *pRef = pEntry->aSvcRefs.getConstArray();
|
||||
sal_Int32 nNumSuggestions = -1;
|
||||
while (i <= pEntry->nLastTriedSvcIndex
|
||||
&& (!bTmpResValid || xTmpRes.is()) )
|
||||
bTmpResValid = true;
|
||||
if (pRef[i].is() && pRef[i]->hasLocale( aLocale ))
|
||||
{
|
||||
bTmpResValid = true;
|
||||
if (pRef[i].is() && pRef[i]->hasLocale( aLocale ))
|
||||
{
|
||||
bool bOK = GetCache().CheckWord( aChkWord, nLanguage );
|
||||
if (bOK)
|
||||
xTmpRes = nullptr;
|
||||
else
|
||||
{
|
||||
xTmpRes = pRef[i]->spell( aChkWord, aLocale, rProperties );
|
||||
|
||||
// Add correct words to the cache.
|
||||
// But not those that are correct only because of
|
||||
// the temporary supplied settings.
|
||||
if (!xTmpRes.is() && !rProperties.hasElements())
|
||||
GetCache().AddWord( aChkWord, nLanguage );
|
||||
}
|
||||
}
|
||||
bool bOK = GetCache().CheckWord( aChkWord, nLanguage );
|
||||
if (bOK)
|
||||
xTmpRes = nullptr;
|
||||
else
|
||||
bTmpResValid = false;
|
||||
|
||||
// return first found result if the word is not known by any checker.
|
||||
// But if that result has no suggestions use the first one that does
|
||||
// provide suggestions for the misspelled word.
|
||||
if (!xRes.is() && bTmpResValid)
|
||||
{
|
||||
xRes = xTmpRes;
|
||||
nNumSuggestions = 0;
|
||||
if (xRes.is())
|
||||
nNumSuggestions = xRes->getAlternatives().getLength();
|
||||
}
|
||||
sal_Int32 nTmpNumSuggestions = 0;
|
||||
if (xTmpRes.is() && bTmpResValid)
|
||||
nTmpNumSuggestions = xTmpRes->getAlternatives().getLength();
|
||||
if (xRes.is() && nNumSuggestions == 0 && nTmpNumSuggestions > 0)
|
||||
{
|
||||
xRes = xTmpRes;
|
||||
nNumSuggestions = nTmpNumSuggestions;
|
||||
}
|
||||
xTmpRes = pRef[i]->spell( aChkWord, aLocale, rProperties );
|
||||
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
// if still no result instantiate new services and try those
|
||||
if ((!bTmpResValid || xTmpRes.is())
|
||||
&& pEntry->nLastTriedSvcIndex < nLen - 1)
|
||||
{
|
||||
const OUString *pImplNames = pEntry->aSvcImplNames.getConstArray();
|
||||
Reference< XSpellChecker > *pRef = pEntry->aSvcRefs .getArray();
|
||||
|
||||
const Reference< XComponentContext >& xContext(
|
||||
comphelper::getProcessComponentContext() );
|
||||
|
||||
// build service initialization argument
|
||||
Sequence< Any > aArgs(2);
|
||||
aArgs.getArray()[0] <<= GetPropSet();
|
||||
|
||||
sal_Int32 nNumSuggestions = -1;
|
||||
while (i < nLen && (!bTmpResValid || xTmpRes.is()))
|
||||
{
|
||||
// create specific service via it's implementation name
|
||||
Reference< XSpellChecker > xSpell;
|
||||
try
|
||||
{
|
||||
xSpell.set( xContext->getServiceManager()->createInstanceWithArgumentsAndContext(
|
||||
pImplNames[i], aArgs, xContext ),
|
||||
UNO_QUERY );
|
||||
}
|
||||
catch (uno::Exception &)
|
||||
{
|
||||
SAL_WARN( "linguistic", "createInstanceWithArguments failed" );
|
||||
}
|
||||
pRef [i] = xSpell;
|
||||
|
||||
Reference< XLinguServiceEventBroadcaster >
|
||||
xBroadcaster( xSpell, UNO_QUERY );
|
||||
if (xBroadcaster.is())
|
||||
m_rMgr.AddLngSvcEvtBroadcaster( xBroadcaster );
|
||||
|
||||
bTmpResValid = true;
|
||||
if (xSpell.is() && xSpell->hasLocale( aLocale ))
|
||||
{
|
||||
bool bOK = GetCache().CheckWord( aChkWord, nLanguage );
|
||||
if (bOK)
|
||||
xTmpRes = nullptr;
|
||||
else
|
||||
{
|
||||
xTmpRes = xSpell->spell( aChkWord, aLocale, rProperties );
|
||||
|
||||
// Add correct words to the cache.
|
||||
// But not those that are correct only because of
|
||||
// the temporary supplied settings.
|
||||
if (!xTmpRes.is() && !rProperties.hasElements())
|
||||
GetCache().AddWord( aChkWord, nLanguage );
|
||||
}
|
||||
}
|
||||
else
|
||||
bTmpResValid = false;
|
||||
|
||||
// return first found result if the word is not known by any checker.
|
||||
// But if that result has no suggestions use the first one that does
|
||||
// provide suggestions for the misspelled word.
|
||||
if (!xRes.is() && bTmpResValid)
|
||||
{
|
||||
xRes = xTmpRes;
|
||||
nNumSuggestions = 0;
|
||||
if (xRes.is())
|
||||
nNumSuggestions = xRes->getAlternatives().getLength();
|
||||
}
|
||||
sal_Int32 nTmpNumSuggestions = 0;
|
||||
if (xTmpRes.is() && bTmpResValid)
|
||||
nTmpNumSuggestions = xTmpRes->getAlternatives().getLength();
|
||||
if (xRes.is() && nNumSuggestions == 0 && nTmpNumSuggestions > 0)
|
||||
{
|
||||
xRes = xTmpRes;
|
||||
nNumSuggestions = nTmpNumSuggestions;
|
||||
}
|
||||
|
||||
pEntry->nLastTriedSvcIndex = static_cast<sal_Int16>(i);
|
||||
++i;
|
||||
}
|
||||
|
||||
// if language is not supported by any of the services
|
||||
// remove it from the list.
|
||||
if (i == nLen)
|
||||
{
|
||||
if (!SvcListHasLanguage( *pEntry, nLanguage ))
|
||||
m_aSvcMap.erase( nLanguage );
|
||||
}
|
||||
}
|
||||
|
||||
// if word is finally found to be correct
|
||||
// clear previously remembered alternatives
|
||||
if (bTmpResValid && !xTmpRes.is())
|
||||
xRes = nullptr;
|
||||
|
||||
// list of proposals found (to be checked against entries of
|
||||
// negative dictionaries)
|
||||
ProposalList aProposalList;
|
||||
sal_Int16 eFailureType = -1; // no failure
|
||||
if (xRes.is())
|
||||
{
|
||||
aProposalList.Append( xRes->getAlternatives() );
|
||||
eFailureType = xRes->getFailureType();
|
||||
}
|
||||
Reference< XSearchableDictionaryList > xDList;
|
||||
if (GetDicList().is() && IsUseDicList( rProperties, GetPropSet() ))
|
||||
xDList = GetDicList();
|
||||
|
||||
// cross-check against results from user-dictionaries which have precedence!
|
||||
if (xDList.is())
|
||||
{
|
||||
Reference< XDictionaryEntry > xTmp( lcl_GetRulingDictionaryEntry( aChkWord, nLanguage ) );
|
||||
if (xTmp.is())
|
||||
{
|
||||
if (xTmp->isNegative()) // negative entry found
|
||||
{
|
||||
eFailureType = SpellFailure::IS_NEGATIVE_WORD;
|
||||
|
||||
// replacement text to be added to suggestions, if not empty
|
||||
OUString aAddRplcTxt( xTmp->getReplacementText() );
|
||||
|
||||
// replacement text must not be in negative dictionary itself
|
||||
if (!aAddRplcTxt.isEmpty() &&
|
||||
!SearchDicList( xDList, aAddRplcTxt, nLanguage, false, true ).is())
|
||||
{
|
||||
aProposalList.Prepend( aAddRplcTxt );
|
||||
}
|
||||
}
|
||||
else // positive entry found
|
||||
{
|
||||
xRes = nullptr;
|
||||
eFailureType = -1; // no failure
|
||||
// Add correct words to the cache.
|
||||
// But not those that are correct only because of
|
||||
// the temporary supplied settings.
|
||||
if (!xTmpRes.is() && !rProperties.hasElements())
|
||||
GetCache().AddWord( aChkWord, nLanguage );
|
||||
}
|
||||
}
|
||||
else
|
||||
bTmpResValid = false;
|
||||
|
||||
// return first found result if the word is not known by any checker.
|
||||
// But if that result has no suggestions use the first one that does
|
||||
// provide suggestions for the misspelled word.
|
||||
if (!xRes.is() && bTmpResValid)
|
||||
{
|
||||
setCharClass(LanguageTag(nLanguage));
|
||||
CapType ct = capitalType(aChkWord, m_oCharClass ? &*m_oCharClass : nullptr);
|
||||
if (ct == CapType::INITCAP || ct == CapType::ALLCAP)
|
||||
xRes = xTmpRes;
|
||||
nNumSuggestions = 0;
|
||||
if (xRes.is())
|
||||
nNumSuggestions = xRes->getAlternatives().getLength();
|
||||
}
|
||||
sal_Int32 nTmpNumSuggestions = 0;
|
||||
if (xTmpRes.is() && bTmpResValid)
|
||||
nTmpNumSuggestions = xTmpRes->getAlternatives().getLength();
|
||||
if (xRes.is() && nNumSuggestions == 0 && nTmpNumSuggestions > 0)
|
||||
{
|
||||
xRes = xTmpRes;
|
||||
nNumSuggestions = nTmpNumSuggestions;
|
||||
}
|
||||
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
// if still no result instantiate new services and try those
|
||||
if ((!bTmpResValid || xTmpRes.is())
|
||||
&& pEntry->nLastTriedSvcIndex < nLen - 1)
|
||||
{
|
||||
const OUString *pImplNames = pEntry->aSvcImplNames.getConstArray();
|
||||
Reference< XSpellChecker > *pRef = pEntry->aSvcRefs .getArray();
|
||||
|
||||
const Reference< XComponentContext >& xContext(
|
||||
comphelper::getProcessComponentContext() );
|
||||
|
||||
// build service initialization argument
|
||||
Sequence< Any > aArgs(2);
|
||||
aArgs.getArray()[0] <<= GetPropSet();
|
||||
|
||||
sal_Int32 nNumSuggestions = -1;
|
||||
while (i < nLen && (!bTmpResValid || xTmpRes.is()))
|
||||
{
|
||||
// create specific service via it's implementation name
|
||||
Reference< XSpellChecker > xSpell;
|
||||
try
|
||||
{
|
||||
xSpell.set( xContext->getServiceManager()->createInstanceWithArgumentsAndContext(
|
||||
pImplNames[i], aArgs, xContext ),
|
||||
UNO_QUERY );
|
||||
}
|
||||
catch (uno::Exception &)
|
||||
{
|
||||
SAL_WARN( "linguistic", "createInstanceWithArguments failed" );
|
||||
}
|
||||
pRef [i] = xSpell;
|
||||
|
||||
Reference< XLinguServiceEventBroadcaster >
|
||||
xBroadcaster( xSpell, UNO_QUERY );
|
||||
if (xBroadcaster.is())
|
||||
m_rMgr.AddLngSvcEvtBroadcaster( xBroadcaster );
|
||||
|
||||
bTmpResValid = true;
|
||||
if (xSpell.is() && xSpell->hasLocale( aLocale ))
|
||||
{
|
||||
bool bOK = GetCache().CheckWord( aChkWord, nLanguage );
|
||||
if (bOK)
|
||||
xTmpRes = nullptr;
|
||||
else
|
||||
{
|
||||
Reference< XDictionaryEntry > xTmp2( lcl_GetRulingDictionaryEntry( makeLowerCase(aChkWord, m_oCharClass), nLanguage ) );
|
||||
if (xTmp2.is())
|
||||
xTmpRes = xSpell->spell( aChkWord, aLocale, rProperties );
|
||||
|
||||
// Add correct words to the cache.
|
||||
// But not those that are correct only because of
|
||||
// the temporary supplied settings.
|
||||
if (!xTmpRes.is() && !rProperties.hasElements())
|
||||
GetCache().AddWord( aChkWord, nLanguage );
|
||||
}
|
||||
}
|
||||
else
|
||||
bTmpResValid = false;
|
||||
|
||||
// return first found result if the word is not known by any checker.
|
||||
// But if that result has no suggestions use the first one that does
|
||||
// provide suggestions for the misspelled word.
|
||||
if (!xRes.is() && bTmpResValid)
|
||||
{
|
||||
xRes = xTmpRes;
|
||||
nNumSuggestions = 0;
|
||||
if (xRes.is())
|
||||
nNumSuggestions = xRes->getAlternatives().getLength();
|
||||
}
|
||||
sal_Int32 nTmpNumSuggestions = 0;
|
||||
if (xTmpRes.is() && bTmpResValid)
|
||||
nTmpNumSuggestions = xTmpRes->getAlternatives().getLength();
|
||||
if (xRes.is() && nNumSuggestions == 0 && nTmpNumSuggestions > 0)
|
||||
{
|
||||
xRes = xTmpRes;
|
||||
nNumSuggestions = nTmpNumSuggestions;
|
||||
}
|
||||
|
||||
pEntry->nLastTriedSvcIndex = static_cast<sal_Int16>(i);
|
||||
++i;
|
||||
}
|
||||
|
||||
// if language is not supported by any of the services
|
||||
// remove it from the list.
|
||||
if (i == nLen)
|
||||
{
|
||||
if (!SvcListHasLanguage( *pEntry, nLanguage ))
|
||||
m_aSvcMap.erase( nLanguage );
|
||||
}
|
||||
}
|
||||
|
||||
// if word is finally found to be correct
|
||||
// clear previously remembered alternatives
|
||||
if (bTmpResValid && !xTmpRes.is())
|
||||
xRes = nullptr;
|
||||
|
||||
// list of proposals found (to be checked against entries of
|
||||
// negative dictionaries)
|
||||
ProposalList aProposalList;
|
||||
sal_Int16 eFailureType = -1; // no failure
|
||||
if (xRes.is())
|
||||
{
|
||||
aProposalList.Append( xRes->getAlternatives() );
|
||||
eFailureType = xRes->getFailureType();
|
||||
}
|
||||
Reference< XSearchableDictionaryList > xDList;
|
||||
if (GetDicList().is() && IsUseDicList( rProperties, GetPropSet() ))
|
||||
xDList = GetDicList();
|
||||
|
||||
// cross-check against results from user-dictionaries which have precedence!
|
||||
if (xDList.is())
|
||||
{
|
||||
Reference< XDictionaryEntry > xTmp( lcl_GetRulingDictionaryEntry( aChkWord, nLanguage ) );
|
||||
if (xTmp.is())
|
||||
{
|
||||
if (xTmp->isNegative()) // negative entry found
|
||||
{
|
||||
eFailureType = SpellFailure::IS_NEGATIVE_WORD;
|
||||
|
||||
// replacement text to be added to suggestions, if not empty
|
||||
OUString aAddRplcTxt( xTmp->getReplacementText() );
|
||||
|
||||
// replacement text must not be in negative dictionary itself
|
||||
if (!aAddRplcTxt.isEmpty() &&
|
||||
!SearchDicList( xDList, aAddRplcTxt, nLanguage, false, true ).is())
|
||||
{
|
||||
aProposalList.Prepend( aAddRplcTxt );
|
||||
}
|
||||
}
|
||||
else // positive entry found
|
||||
{
|
||||
xRes = nullptr;
|
||||
eFailureType = -1; // no failure
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
setCharClass(LanguageTag(nLanguage));
|
||||
CapType ct = capitalType(aChkWord, m_oCharClass ? &*m_oCharClass : nullptr);
|
||||
if (ct == CapType::INITCAP || ct == CapType::ALLCAP)
|
||||
{
|
||||
Reference< XDictionaryEntry > xTmp2( lcl_GetRulingDictionaryEntry( makeLowerCase(aChkWord, m_oCharClass), nLanguage ) );
|
||||
if (xTmp2.is())
|
||||
{
|
||||
if (xTmp2->isNegative()) // negative entry found
|
||||
{
|
||||
if (xTmp2->isNegative()) // negative entry found
|
||||
eFailureType = SpellFailure::IS_NEGATIVE_WORD;
|
||||
|
||||
// replacement text to be added to suggestions, if not empty
|
||||
OUString aAddRplcTxt( xTmp2->getReplacementText() );
|
||||
|
||||
// replacement text must not be in negative dictionary itself
|
||||
if (!aAddRplcTxt.isEmpty() &&
|
||||
!SearchDicList( xDList, aAddRplcTxt, nLanguage, false, true ).is())
|
||||
{
|
||||
eFailureType = SpellFailure::IS_NEGATIVE_WORD;
|
||||
|
||||
// replacement text to be added to suggestions, if not empty
|
||||
OUString aAddRplcTxt( xTmp2->getReplacementText() );
|
||||
|
||||
// replacement text must not be in negative dictionary itself
|
||||
if (!aAddRplcTxt.isEmpty() &&
|
||||
!SearchDicList( xDList, aAddRplcTxt, nLanguage, false, true ).is())
|
||||
switch ( ct )
|
||||
{
|
||||
switch ( ct )
|
||||
{
|
||||
case CapType::INITCAP:
|
||||
aProposalList.Prepend( m_oCharClass->titlecase(aAddRplcTxt) );
|
||||
break;
|
||||
case CapType::ALLCAP:
|
||||
aProposalList.Prepend( m_oCharClass->uppercase(aAddRplcTxt) );
|
||||
break;
|
||||
default:
|
||||
/* can't happen because of if ct == above */
|
||||
break;
|
||||
}
|
||||
case CapType::INITCAP:
|
||||
aProposalList.Prepend( m_oCharClass->titlecase(aAddRplcTxt) );
|
||||
break;
|
||||
case CapType::ALLCAP:
|
||||
aProposalList.Prepend( m_oCharClass->uppercase(aAddRplcTxt) );
|
||||
break;
|
||||
default:
|
||||
/* can't happen because of if ct == above */
|
||||
break;
|
||||
}
|
||||
}
|
||||
else // positive entry found
|
||||
{
|
||||
xRes = nullptr;
|
||||
eFailureType = -1; // no failure
|
||||
}
|
||||
}
|
||||
else // positive entry found
|
||||
{
|
||||
xRes = nullptr;
|
||||
eFailureType = -1; // no failure
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (eFailureType != -1) // word misspelled or found in negative user-dictionary
|
||||
if (eFailureType != -1) // word misspelled or found in negative user-dictionary
|
||||
{
|
||||
// search suitable user-dictionaries for suggestions that are
|
||||
// similar to the misspelled word
|
||||
std::vector< OUString > aDicListProps; // list of proposals from user-dictionaries
|
||||
SearchSimilarText( aChkWord, nLanguage, xDList, aDicListProps );
|
||||
aProposalList.Append( aDicListProps );
|
||||
std::vector< OUString > aProposals = aProposalList.GetVector();
|
||||
|
||||
// remove entries listed in negative dictionaries
|
||||
// (we don't want to display suggestions that will be regarded as misspelled later on)
|
||||
if (xDList.is())
|
||||
SeqRemoveNegEntries( aProposals, xDList, nLanguage );
|
||||
|
||||
uno::Reference< linguistic2::XSetSpellAlternatives > xSetAlt( xRes, uno::UNO_QUERY );
|
||||
if (xSetAlt.is())
|
||||
{
|
||||
// search suitable user-dictionaries for suggestions that are
|
||||
// similar to the misspelled word
|
||||
std::vector< OUString > aDicListProps; // list of proposals from user-dictionaries
|
||||
SearchSimilarText( aChkWord, nLanguage, xDList, aDicListProps );
|
||||
aProposalList.Append( aDicListProps );
|
||||
std::vector< OUString > aProposals = aProposalList.GetVector();
|
||||
|
||||
// remove entries listed in negative dictionaries
|
||||
// (we don't want to display suggestions that will be regarded as misspelled later on)
|
||||
if (xDList.is())
|
||||
SeqRemoveNegEntries( aProposals, xDList, nLanguage );
|
||||
|
||||
uno::Reference< linguistic2::XSetSpellAlternatives > xSetAlt( xRes, uno::UNO_QUERY );
|
||||
if (xSetAlt.is())
|
||||
xSetAlt->setAlternatives( comphelper::containerToSequence(aProposals) );
|
||||
xSetAlt->setFailureType( eFailureType );
|
||||
}
|
||||
else
|
||||
{
|
||||
if (xRes.is())
|
||||
{
|
||||
xSetAlt->setAlternatives( comphelper::containerToSequence(aProposals) );
|
||||
xSetAlt->setFailureType( eFailureType );
|
||||
SAL_WARN( "linguistic", "XSetSpellAlternatives not implemented!" );
|
||||
}
|
||||
else
|
||||
else if (!aProposals.empty())
|
||||
{
|
||||
if (xRes.is())
|
||||
{
|
||||
SAL_WARN( "linguistic", "XSetSpellAlternatives not implemented!" );
|
||||
}
|
||||
else if (!aProposals.empty())
|
||||
{
|
||||
// no xRes but Proposals found from the user-dictionaries.
|
||||
// Thus we need to create an xRes...
|
||||
xRes = new linguistic::SpellAlternatives( rWord, nLanguage,
|
||||
comphelper::containerToSequence(aProposals) );
|
||||
}
|
||||
// no xRes but Proposals found from the user-dictionaries.
|
||||
// Thus we need to create an xRes...
|
||||
xRes = new linguistic::SpellAlternatives( rWord, nLanguage,
|
||||
comphelper::containerToSequence(aProposals) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user