Kaydet (Commit) 95d9f596 authored tarafından László Németh's avatar László Németh

tdf#113739 add "Grammar By" feature to user dictionaries

Language-specific user dictionaries (en-US, de-DE, etc.)
have got a new "Grammar By" field to specify
optional automatic affixation and compounding of the
new words by adding an example dictionary word.

Test example:

Create an en-US user dictionary. Add the new word
"crowdfund" to it, also an example, the Hunspell
en-US dictionary word "fund" in the optional
"Grammar By" field.

This way, the word "crowdfund" will be recognized
by the spell checker with suffixes of the word "fund",
too: crowdfund’s, crowdfunds, crowdfunder, crowdfunders
and crowdfunding.

Hunspell dictionaries with compound flag usage (German,
Hungarian, etc.) can support automatic compounding of
the new words, too.

Change-Id: Id70dbee4544643967153f730ae64938e5cee0c82
Reviewed-on: https://gerrit.libreoffice.org/44562Tested-by: 's avatarJenkins <ci@libreoffice.org>
Reviewed-by: 's avatarLászló Németh <nemeth@numbertext.org>
üst a7ec9946
......@@ -268,6 +268,7 @@
#define RID_SVXSTR_CHG_SMARTART NC_("RID_SVXSTR_CHG_SMARTART", "SmartArt to %PRODUCTNAME shapes or reverse")
#define RID_SVXSTR_OPT_DOUBLE_DICTS NC_("RID_SVXSTR_OPT_DOUBLE_DICTS", "The specified name already exists.\nPlease enter a new name.")
#define RID_SVXSTR_OPT_GRAMMAR_BY NC_("RID_SVXSTR_OPT_GRAMMAR_BY", "~Grammar By")
#define STR_MODIFY NC_("STR_MODIFY", "~Replace")
#define RID_SVXSTR_CONFIRM_SET_LANGUAGE NC_("RID_SVXSTR_CONFIRM_SET_LANGUAGE", "Do you want to change the '%1' dictionary language?")
......
......@@ -109,6 +109,7 @@ private:
OUString sModify;
OUString sNew;
OUString sReplaceFT_Text;
css::uno::Sequence<
css::uno::Reference<
......
......@@ -227,6 +227,7 @@ SvxEditDictionaryDialog::SvxEditDictionaryDialog(
get(pWordED,"word");
get(pReplaceFT,"replace_label");
sReplaceFT_Text = pReplaceFT->GetText();
get(pReplaceED,"replace");
get(pWordsLB,"words");
pWordsLB->set_height_request(pWordsLB->GetTextHeight() * 8);
......@@ -484,7 +485,22 @@ void SvxEditDictionaryDialog::ShowWords_Impl( sal_uInt16 nId )
pWordED->SetText(aStr);
pReplaceED->SetText(aStr);
if(xDic->getDictionaryType() != DictionaryType_POSITIVE)
bool bIsNegative = xDic->getDictionaryType() != DictionaryType_POSITIVE;
bool bLangNone = LanguageTag(
xDic->getLocale() ).getLanguageType() == LANGUAGE_NONE;
// The label is "Replace By" only in negative dictionaries (forbidden
// words), otherwise "Grammar By" in language-specific dictionaries
// (where the optional second word is the sample word for
// the Hunspell based affixation/compounding of the new dictionary word)
if (bIsNegative)
{
pReplaceFT->SetText(sReplaceFT_Text);
} else if (!bLangNone) {
pReplaceFT->SetText(CuiResId(RID_SVXSTR_OPT_GRAMMAR_BY));
}
if(bIsNegative || !bLangNone)
{
nStaticTabs[0]=2;
......@@ -525,7 +541,7 @@ void SvxEditDictionaryDialog::ShowWords_Impl( sal_uInt16 nId )
{
aStr = pEntry[i]->getDictionaryWord();
sal_uLong nPos = GetLBInsertPos( aStr );
if(pEntry[i]->isNegative())
if(!pEntry[i]->getReplacementText().isEmpty())
{
aStr += "\t" + pEntry[i]->getReplacementText();
}
......@@ -608,11 +624,10 @@ bool SvxEditDictionaryDialog::NewDelHdl(void const * pBtn)
{
// make changes in dic
//! ...IsVisible should reflect whether the dictionary is a negativ
//! or not (hopefully...)
bool bIsNegEntry = pReplaceFT->IsVisible();
bool bIsNegEntry = xDic->getDictionaryType() == DictionaryType_NEGATIVE;
OUString aRplcText;
if(bIsNegEntry)
if(!aReplaceStr.isEmpty())
aRplcText = aReplaceStr;
if (_pEntry) // entry selected in pWordsLB ie action = modify entry
......@@ -635,7 +650,7 @@ bool SvxEditDictionaryDialog::NewDelHdl(void const * pBtn)
pWordsLB->SetUpdateMode(false);
sal_uLong _nPos = TREELIST_ENTRY_NOTFOUND;
if(pReplaceFT->IsVisible())
if(!aReplaceStr.isEmpty())
{
sEntry += "\t" + aReplaceStr;
}
......
......@@ -40,6 +40,9 @@
#include <com/sun/star/io/XInputStream.hpp>
#include <com/sun/star/io/XOutputStream.hpp>
#include <com/sun/star/linguistic2/LinguServiceManager.hpp>
#include <com/sun/star/linguistic2/XSpellChecker1.hpp>
#include "defs.hxx"
#include <algorithm>
......@@ -59,6 +62,9 @@ using namespace linguistic;
#define MAX_HEADER_LENGTH 16
// XML-header to query SPELLML support
#define SPELLML_SUPPORT "<?xml?>"
static const sal_Char* const pVerStr2 = "WBSWG2";
static const sal_Char* const pVerStr5 = "WBSWG5";
static const sal_Char* const pVerStr6 = "WBSWG6";
......@@ -70,6 +76,13 @@ static const sal_Int16 DIC_VERSION_5 = 5;
static const sal_Int16 DIC_VERSION_6 = 6;
static const sal_Int16 DIC_VERSION_7 = 7;
static uno::Reference< XLinguServiceManager2 > GetLngSvcMgr_Impl()
{
uno::Reference< XComponentContext > xContext( comphelper::getProcessComponentContext() );
uno::Reference< XLinguServiceManager2 > xRes = LinguServiceManager::create( xContext ) ;
return xRes;
}
static bool getTag(const OString &rLine, const sal_Char *pTagName,
OString &rTagValue)
{
......@@ -359,7 +372,7 @@ static OString formatForSave(const uno::Reference< XDictionaryEntry > &xEntry,
{
OStringBuffer aStr(OUStringToOString(xEntry->getDictionaryWord(), eEnc));
if (xEntry->isNegative())
if (xEntry->isNegative() || !xEntry->getReplacementText().isEmpty())
{
aStr.append("==");
aStr.append(OUStringToOString(xEntry->getReplacementText(), eEnc));
......@@ -672,6 +685,27 @@ bool DictionaryNeo::addEntry_Impl(const uno::Reference< XDictionaryEntry >& xDic
}
}
// add word to the Hunspell dictionary using a sample word for affixation/compounding
if (xDicEntry.is() && !xDicEntry->isNegative() && !xDicEntry->getReplacementText().isEmpty()) {
uno::Reference< XLinguServiceManager2 > xLngSvcMgr( GetLngSvcMgr_Impl() );
uno::Reference< XSpellChecker1 > xSpell;
Reference< XSpellAlternatives > xTmpRes;
xSpell.set( xLngSvcMgr->getSpellChecker(), UNO_QUERY );
Sequence< css::beans::PropertyValue > aEmptySeq;
if (xSpell.is() && (xSpell->isValid( SPELLML_SUPPORT, (sal_uInt16)nLanguage, aEmptySeq )))
{
// "Grammar By" sample word is a Hunspell dictionary word?
if (xSpell->isValid( xDicEntry->getReplacementText(), (sal_uInt16)nLanguage, aEmptySeq ))
{
xTmpRes = xSpell->spell( "<?xml?><query type='add'><word>" +
xDicEntry->getDictionaryWord() + "</word><word>" + xDicEntry->getReplacementText() +
"</word></query>", (sal_uInt16)nLanguage, aEmptySeq );
bRes = true;
} else
bRes = false;
}
}
return bRes;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment