[Libreoffice-commits] core.git: cui/inc cui/source linguistic/source

László Németh nemeth at numbertext.org
Fri Nov 17 16:33:24 UTC 2017


 cui/inc/strings.hrc            |    1 +
 cui/source/inc/optdict.hxx     |    1 +
 cui/source/options/optdict.cxx |   29 ++++++++++++++++++++++-------
 linguistic/source/dicimp.cxx   |   36 +++++++++++++++++++++++++++++++++++-
 4 files changed, 59 insertions(+), 8 deletions(-)

New commits:
commit 95d9f596336ebf19dc367f618b3788a4ce0ba542
Author: László Németh <nemeth at numbertext.org>
Date:   Thu Nov 9 16:03:21 2017 +0100

    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/44562
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: László Németh <nemeth at numbertext.org>

diff --git a/cui/inc/strings.hrc b/cui/inc/strings.hrc
index 40270de92037..5909ef647c74 100644
--- a/cui/inc/strings.hrc
+++ b/cui/inc/strings.hrc
@@ -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?")
 
diff --git a/cui/source/inc/optdict.hxx b/cui/source/inc/optdict.hxx
index fb8cd6deb364..e2dc53bf9e6e 100644
--- a/cui/source/inc/optdict.hxx
+++ b/cui/source/inc/optdict.hxx
@@ -109,6 +109,7 @@ private:
 
     OUString                sModify;
     OUString                sNew;
+    OUString                sReplaceFT_Text;
 
     css::uno::Sequence<
         css::uno::Reference<
diff --git a/cui/source/options/optdict.cxx b/cui/source/options/optdict.cxx
index c04584f08bb4..8b23f40c5445 100644
--- a/cui/source/options/optdict.cxx
+++ b/cui/source/options/optdict.cxx
@@ -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;
             }
diff --git a/linguistic/source/dicimp.cxx b/linguistic/source/dicimp.cxx
index 1c985503c9f9..b5b1e840e94c 100644
--- a/linguistic/source/dicimp.cxx
+++ b/linguistic/source/dicimp.cxx
@@ -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;
 }
 


More information about the Libreoffice-commits mailing list