cui/inc/strings.hrc                                            |    2 
 cui/source/inc/optlingu.hxx                                    |    2 
 cui/source/options/optlingu.cxx                                |   26 +++++-
 include/linguistic/lngprophelp.hxx                             |    8 +
 include/unotools/lingucfg.hxx                                  |    8 +
 include/unotools/linguprops.hxx                                |    8 -
 lingucomponent/source/spellcheck/spell/sspellimp.cxx           |   25 ++++-
 lingucomponent/source/spellcheck/spell/sspellimp.hxx           |    2 
 linguistic/source/iprcache.cxx                                 |    6 -
 linguistic/source/lngopt.cxx                                   |    8 +
 linguistic/source/lngopt.hxx                                   |    8 +
 linguistic/source/lngprophelp.cxx                              |   42 
++++++++++
 linguistic/workben/sprophelp.cxx                               |   35 ++++++++
 offapi/com/sun/star/linguistic2/XLinguProperties.idl           |   14 +++
 offapi/type_reference/offapi.idl                               |    2 
 officecfg/registry/schema/org/openoffice/Office/Linguistic.xcs |   16 +++
 unotools/source/config/lingucfg.cxx                            |   19 ++++
 17 files changed, 211 insertions(+), 20 deletions(-)

New commits:
commit 57d79744c77eef96b4c2bd3b16e0a04317ffcf9e
Author:     László Németh <nem...@numbertext.org>
AuthorDate: Fri Dec 30 10:26:07 2022 +0100
Commit:     László Németh <nem...@numbertext.org>
CommitDate: Fri Dec 30 11:03:39 2022 +0000

    tdf#136306 offapi linguistic: add options to disable rule-based compounding
    
    Add two new spell checking options to disable rule-based closed
    and hyphenated compound word recognition with Hunspell dictionaries:
    
    com::sun::star::linguistic2::XLinguProperties::IsSpellClosedCompound
    com::sun::star::linguistic2::XLinguProperties::IsSpellHyphenatedCompound
    
    For professional proofreaders, it can be more important to avoid
    of the mistakes of the rule-based compound word recognition, than
    to speed up proofreading. Disabling the following two new options
    will report all rule-based closed compound words (default in
    Dutch, German, Hungarian etc. dictionaries) and rule-based
    hyphenated compound words (all languages with BREAK usage in
    their Hunspell dictionaries):
    
    - "Accept possible closed compound words"
    
    - "Accept possible hyphenated compound words"
    
    For example, disabling the second one, dictionary word "scot-free"
    will be still correct word in English spell checking, but not
    the previously accepted compound "arbitrary-word-with-hyphen".
    
    Note: the second option works with the update to Hunspell 1.7.2.
    
    Change-Id: Id879610927d5e8269fda5ad207c1c2fe1f57a0b6
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/144875
    Tested-by: Jenkins
    Reviewed-by: László Németh <nem...@numbertext.org>

diff --git a/cui/inc/strings.hrc b/cui/inc/strings.hrc
index 1d4fe526dabd..0d311518ad53 100644
--- a/cui/inc/strings.hrc
+++ b/cui/inc/strings.hrc
@@ -293,6 +293,8 @@
 #define RID_CUISTR_CAPITAL_WORDS                    
NC_("RID_SVXSTR_CAPITAL_WORDS", "Check uppercase words")
 #define RID_CUISTR_WORDS_WITH_DIGITS                
NC_("RID_SVXSTR_WORDS_WITH_DIGITS", "Check words with numbers ")
 #define RID_CUISTR_SPELL_SPECIAL                    
NC_("RID_SVXSTR_SPELL_SPECIAL", "Check special regions")
+#define RID_CUISTR_SPELL_CLOSED_COMPOUND            
NC_("RID_SVXSTR_SPELL_CLOSED_COMPOUND", "Accept possible closed compound words")
+#define RID_CUISTR_SPELL_HYPHENATED_COMPOUND        
NC_("RID_SVXSTR_SPELL_HYPHENATED_COMPOUND", "Accept possible hyphenated 
compound words")
 #define RID_CUISTR_SPELL_AUTO                       
NC_("RID_SVXSTR_SPELL_AUTO", "Check spelling as you type")
 #define RID_CUISTR_GRAMMAR_AUTO                     
NC_("RID_SVXSTR_GRAMMAR_AUTO", "Check grammar as you type")
 #define RID_CUISTR_NUM_MIN_WORDLEN                  
NC_("RID_SVXSTR_NUM_MIN_WORDLEN", "Minimal number of characters for 
hyphenation: ")
diff --git a/cui/source/inc/optlingu.hxx b/cui/source/inc/optlingu.hxx
index 365acfbbb0fb..29adee861417 100644
--- a/cui/source/inc/optlingu.hxx
+++ b/cui/source/inc/optlingu.hxx
@@ -84,6 +84,8 @@ private:
     OUString            sWordsWithDigits;
     OUString            sSpellSpecial;
     OUString            sSpellAuto;
+    OUString            sSpellClosedCompound;
+    OUString            sSpellHyphenatedCompound;
     OUString            sGrammarAuto;
     OUString            sNumMinWordlen;
     OUString            sNumPreBreak;
diff --git a/cui/source/options/optlingu.cxx b/cui/source/options/optlingu.cxx
index 6db7634159b1..b80343657f22 100644
--- a/cui/source/options/optlingu.cxx
+++ b/cui/source/options/optlingu.cxx
@@ -193,7 +193,9 @@ enum EID_OPTIONS
     EID_NUM_PRE_BREAK,
     EID_NUM_POST_BREAK,
     EID_HYPH_AUTO,
-    EID_HYPH_SPECIAL
+    EID_HYPH_SPECIAL,
+    EID_SPELL_CLOSED_COMPOUND,
+    EID_SPELL_HYPHENATED_COMPOUND
 };
 
 }
@@ -205,6 +207,8 @@ static OUString lcl_GetPropertyName( EID_OPTIONS eEntryId )
         case EID_SPELL_AUTO: return UPN_IS_SPELL_AUTO;
         case EID_GRAMMAR_AUTO: return UPN_IS_GRAMMAR_AUTO;
         case EID_CAPITAL_WORDS: return UPN_IS_SPELL_UPPER_CASE;
+        case EID_SPELL_CLOSED_COMPOUND: return UPN_IS_SPELL_CLOSED_COMPOUND;
+        case EID_SPELL_HYPHENATED_COMPOUND: return 
UPN_IS_SPELL_HYPHENATED_COMPOUND;
         case EID_WORDS_WITH_DIGITS: return UPN_IS_SPELL_WITH_DIGITS;
         case EID_SPELL_SPECIAL: return UPN_IS_SPELL_SPECIAL;
         case EID_NUM_MIN_WORDLEN: return UPN_HYPH_MIN_WORD_LENGTH;
@@ -827,6 +831,8 @@ SvxLinguTabPage::SvxLinguTabPage(weld::Container* pPage, 
weld::DialogController*
     , sWordsWithDigits(CuiResId(RID_CUISTR_WORDS_WITH_DIGITS))
     , sSpellSpecial   (CuiResId(RID_CUISTR_SPELL_SPECIAL))
     , sSpellAuto      (CuiResId(RID_CUISTR_SPELL_AUTO))
+    , sSpellClosedCompound (CuiResId(RID_CUISTR_SPELL_CLOSED_COMPOUND))
+    , sSpellHyphenatedCompound (CuiResId(RID_CUISTR_SPELL_HYPHENATED_COMPOUND))
     , sGrammarAuto    (CuiResId(RID_CUISTR_GRAMMAR_AUTO))
     , sNumMinWordlen  (CuiResId(RID_CUISTR_NUM_MIN_WORDLEN))
     , sNumPreBreak    (CuiResId(RID_CUISTR_NUM_PRE_BREAK))
@@ -1210,6 +1216,24 @@ void SvxLinguTabPage::Reset( const SfxItemSet* rSet )
     m_xLinguOptionsCLB->append();
     ++nEntry;
 
+    aLngCfg.GetProperty( UPN_IS_SPELL_CLOSED_COMPOUND ) >>= bVal;
+    nUserData = OptionsUserData( EID_SPELL_CLOSED_COMPOUND, false, 0, true, 
bVal).GetUserData();
+    m_xLinguOptionsCLB->set_toggle(nEntry, bVal ? TRISTATE_TRUE : 
TRISTATE_FALSE);
+    m_xLinguOptionsCLB->set_text(nEntry, sSpellClosedCompound, 0);
+    m_xLinguOptionsCLB->set_id(nEntry, OUString::number(nUserData));
+
+    m_xLinguOptionsCLB->append();
+    ++nEntry;
+
+    aLngCfg.GetProperty( UPN_IS_SPELL_HYPHENATED_COMPOUND ) >>= bVal;
+    nUserData = OptionsUserData( EID_SPELL_HYPHENATED_COMPOUND, false, 0, 
true, bVal).GetUserData();
+    m_xLinguOptionsCLB->set_toggle(nEntry, bVal ? TRISTATE_TRUE : 
TRISTATE_FALSE);
+    m_xLinguOptionsCLB->set_text(nEntry, sSpellHyphenatedCompound, 0);
+    m_xLinguOptionsCLB->set_id(nEntry, OUString::number(nUserData));
+
+    m_xLinguOptionsCLB->append();
+    ++nEntry;
+
     aLngCfg.GetProperty( UPN_IS_SPELL_SPECIAL ) >>= bVal;
     nUserData = OptionsUserData( EID_SPELL_SPECIAL, false, 0, true, 
bVal).GetUserData();
     m_xLinguOptionsCLB->set_toggle(nEntry, bVal ? TRISTATE_TRUE : 
TRISTATE_FALSE);
diff --git a/include/linguistic/lngprophelp.hxx 
b/include/linguistic/lngprophelp.hxx
index 18dfaa60d2e2..85b32b7cec3e 100644
--- a/include/linguistic/lngprophelp.hxx
+++ b/include/linguistic/lngprophelp.hxx
@@ -166,11 +166,15 @@ class UNLESS_MERGELIBS(LNG_DLLPUBLIC) 
PropertyHelper_Spell final :
     bool        bIsSpellUpperCase;
     bool        bIsSpellWithDigits;
     bool        bIsSpellCapitalization;
+    bool        bIsSpellClosedCompound;
+    bool        bIsSpellHyphenatedCompound;
 
     // return values, will be set to default value or current temporary value
     bool        bResIsSpellUpperCase;
     bool        bResIsSpellWithDigits;
     bool        bResIsSpellCapitalization;
+    bool        bResIsSpellClosedCompound;
+    bool        bResIsSpellHyphenatedCompound;
 
     PropertyHelper_Spell( const PropertyHelper_Spell & ) = delete;
     PropertyHelper_Spell & operator = ( const PropertyHelper_Spell & ) = 
delete;
@@ -196,6 +200,8 @@ public:
     bool        IsSpellUpperCase() const            { return 
bResIsSpellUpperCase; }
     bool        IsSpellWithDigits() const           { return 
bResIsSpellWithDigits; }
     bool        IsSpellCapitalization() const       { return 
bResIsSpellCapitalization; }
+    bool        IsSpellClosedCompound() const       { return 
bResIsSpellClosedCompound; }
+    bool        IsSpellHyphenatedCompound() const   { return 
bResIsSpellHyphenatedCompound; }
 };
 
 
@@ -219,6 +225,8 @@ public:
     bool    IsSpellUpperCase() const;
     bool    IsSpellWithDigits() const;
     bool    IsSpellCapitalization() const;
+    bool    IsSpellClosedCompound() const;
+    bool    IsSpellHyphenatedCompound() const;
     /// @throws css::uno::RuntimeException
     bool addLinguServiceEventListener(
                 const css::uno::Reference< 
css::linguistic2::XLinguServiceEventListener >& rxListener );
diff --git a/include/unotools/lingucfg.hxx b/include/unotools/lingucfg.hxx
index b4a0b824e127..40797a372f33 100644
--- a/include/unotools/lingucfg.hxx
+++ b/include/unotools/lingucfg.hxx
@@ -85,11 +85,15 @@ struct UNOTOOLS_DLLPUBLIC SvtLinguOptions
     // SpellChecker service specific options
     bool    bIsSpellWithDigits,
             bIsSpellUpperCase,
-            bIsSpellCapitalization;
+            bIsSpellCapitalization,
+            bIsSpellClosedCompound,
+            bIsSpellHyphenatedCompound;
 
     bool    bROIsSpellWithDigits,
             bROIsSpellUpperCase,
-            bROIsSpellCapitalization;
+            bROIsSpellCapitalization,
+            bROIsSpellClosedCompound,
+            bROIsSpellHyphenatedCompound;
 
     // text conversion specific options
     bool    bIsIgnorePostPositionalWord;
diff --git a/include/unotools/linguprops.hxx b/include/unotools/linguprops.hxx
index 971c0280444c..7f55a9e74042 100644
--- a/include/unotools/linguprops.hxx
+++ b/include/unotools/linguprops.hxx
@@ -54,8 +54,8 @@ inline constexpr OUStringLiteral UPN_DEFAULT_LOCALE_CTL       
       = u"Default
 inline constexpr OUStringLiteral UPN_IS_HYPH_AUTO                    = 
u"IsHyphAuto";
 inline constexpr OUStringLiteral UPN_IS_HYPH_SPECIAL                 = 
u"IsHyphSpecial";
 inline constexpr OUStringLiteral UPN_IS_SPELL_AUTO                   = 
u"IsSpellAuto";
-inline constexpr OUStringLiteral UPN_IS_SPELL_HIDE                   = 
u"IsSpellHide";           /*! deprecated #i91949 !*/
-inline constexpr OUStringLiteral UPN_IS_SPELL_IN_ALL_LANGUAGES       = 
u"IsSpellInAllLanguages"; /*! deprecated #i91949 !*/
+inline constexpr OUStringLiteral UPN_IS_SPELL_CLOSED_COMPOUND        = 
u"IsSpellClosedCompound";
+inline constexpr OUStringLiteral UPN_IS_SPELL_HYPHENATED_COMPOUND    = 
u"IsSpellHyphenatedCompound";
 inline constexpr OUStringLiteral UPN_IS_SPELL_SPECIAL                = 
u"IsSpellSpecial";
 inline constexpr OUStringLiteral UPN_IS_WRAP_REVERSE                 = 
u"IsWrapReverse";
 inline constexpr OUStringLiteral UPN_DATA_FILES_CHANGED_CHECK_VALUE  = 
u"DataFilesChangedCheckValue";
@@ -86,8 +86,8 @@ inline constexpr OUStringLiteral UPN_IS_GRAMMAR_INTERACTIVE   
       = u"IsInter
 #define UPH_HYPH_MIN_WORD_LENGTH             8
 #define UPH_DEFAULT_LOCALE                   9
 #define UPH_IS_SPELL_AUTO                   10
-#define UPH_IS_SPELL_HIDE                   11
-#define UPH_IS_SPELL_IN_ALL_LANGUAGES       12
+#define UPH_IS_SPELL_CLOSED_COMPOUND        11
+#define UPH_IS_SPELL_HYPHENATED_COMPOUND    12
 #define UPH_IS_SPELL_SPECIAL                13
 #define UPH_IS_HYPH_AUTO                    14
 #define UPH_IS_HYPH_SPECIAL                 15
diff --git a/lingucomponent/source/spellcheck/spell/sspellimp.cxx 
b/lingucomponent/source/spellcheck/spell/sspellimp.cxx
index 95b264157533..506d2c9dd014 100644
--- a/lingucomponent/source/spellcheck/spell/sspellimp.cxx
+++ b/lingucomponent/source/spellcheck/spell/sspellimp.cxx
@@ -243,7 +243,7 @@ sal_Bool SAL_CALL SpellChecker::hasLocale(const Locale& 
rLocale)
     return bRes;
 }
 
-sal_Int16 SpellChecker::GetSpellFailure(const OUString &rWord, const Locale 
&rLocale)
+sal_Int16 SpellChecker::GetSpellFailure(const OUString &rWord, const Locale 
&rLocale, int& rInfo)
 {
     if (rWord.getLength() > MAXWORDLEN)
         return -1;
@@ -332,9 +332,9 @@ sal_Int16 SpellChecker::GetSpellFailure(const OUString 
&rWord, const Locale &rLo
 
                 OString aWrd(OU2ENC(nWord,eEnc));
 #if defined(H_DEPRECATED)
-                bool bVal = pMS->spell(std::string(aWrd.getStr()));
+                bool bVal = pMS->spell(std::string(aWrd.getStr()), &rInfo);
 #else
-                bool bVal = pMS->spell(aWrd.getStr()) != 0;
+                bool bVal = pMS->spell(aWrd.getStr(), &rInfo) != 0;
 #endif
                 if (!bVal) {
                     if (extrachar && (eEnc != RTL_TEXTENCODING_UTF8)) {
@@ -355,9 +355,9 @@ sal_Int16 SpellChecker::GetSpellFailure(const OUString 
&rWord, const Locale &rLo
                         OUString aWord(aBuf.makeStringAndClear());
                         OString bWrd(OU2ENC(aWord, eEnc));
 #if defined(H_DEPRECATED)
-                        bVal = pMS->spell(std::string(bWrd.getStr()));
+                        bVal = pMS->spell(std::string(bWrd.getStr()), &rInfo);
 #else
-                        bVal = pMS->spell(bWrd.getStr()) != 0;
+                        bVal = pMS->spell(bWrd.getStr(), &rInfo) != 0;
 #endif
                         if (bVal) return -1;
                     }
@@ -396,7 +396,8 @@ sal_Bool SAL_CALL SpellChecker::isValid( const OUString& 
rWord, const Locale& rL
     PropertyHelper_Spelling& rHelper = GetPropHelper();
     rHelper.SetTmpPropVals( rProperties );
 
-    sal_Int16 nFailure = GetSpellFailure( rWord, rLocale );
+    int nInfo = 0;
+    sal_Int16 nFailure = GetSpellFailure( rWord, rLocale, nInfo );
     if (nFailure != -1 && !rWord.match(SPELL_XML, 0))
     {
         LanguageType nLang = LinguLocaleToLanguage( rLocale );
@@ -408,6 +409,18 @@ sal_Bool SAL_CALL SpellChecker::isValid( const OUString& 
rWord, const Locale& rL
         if (bIgnoreError)
             nFailure = -1;
     }
+//#define SPELL_COMPOUND 1 << 0
+
+    // valid word, but it's a rule-based compound word
+    if ( nFailure == -1 && (nInfo & SPELL_COMPOUND) )
+    {
+        bool bHasHyphen = rWord.indexOf('-') > -1;
+        if ( (bHasHyphen && !rHelper.IsSpellHyphenatedCompound()) ||
+             (!bHasHyphen && !rHelper.IsSpellClosedCompound()) )
+        {
+            return false;
+        }
+    }
 
     return (nFailure == -1);
 }
diff --git a/lingucomponent/source/spellcheck/spell/sspellimp.hxx 
b/lingucomponent/source/spellcheck/spell/sspellimp.hxx
index 000f1756f5bc..68ddc69b3c56 100644
--- a/lingucomponent/source/spellcheck/spell/sspellimp.hxx
+++ b/lingucomponent/source/spellcheck/spell/sspellimp.hxx
@@ -79,7 +79,7 @@ class SpellChecker :
         return m_pPropHelper ? *m_pPropHelper : GetPropHelper_Impl();
     }
 
-    sal_Int16   GetSpellFailure( const OUString &rWord, const Locale &rLocale 
);
+    sal_Int16   GetSpellFailure( const OUString &rWord, const Locale &rLocale, 
int& rInfo );
     Reference< XSpellAlternatives > GetProposals( const OUString &rWord, const 
Locale &rLocale );
 
 public:
diff --git a/linguistic/source/iprcache.cxx b/linguistic/source/iprcache.cxx
index 2b82e5684d83..5dc0031cb139 100644
--- a/linguistic/source/iprcache.cxx
+++ b/linguistic/source/iprcache.cxx
@@ -37,7 +37,7 @@ namespace linguistic
 {
 
 
-#define NUM_FLUSH_PROPS     6
+#define NUM_FLUSH_PROPS     8
 
 const struct
 {
@@ -49,7 +49,9 @@ const struct
     { UPN_IS_IGNORE_CONTROL_CHARACTERS,   UPH_IS_IGNORE_CONTROL_CHARACTERS },
     { UPN_IS_SPELL_UPPER_CASE,            UPH_IS_SPELL_UPPER_CASE },
     { UPN_IS_SPELL_WITH_DIGITS,           UPH_IS_SPELL_WITH_DIGITS },
-    { UPN_IS_SPELL_CAPITALIZATION,        UPH_IS_SPELL_CAPITALIZATION }
+    { UPN_IS_SPELL_CAPITALIZATION,        UPH_IS_SPELL_CAPITALIZATION },
+    { UPN_IS_SPELL_CLOSED_COMPOUND,       UPH_IS_SPELL_CLOSED_COMPOUND },
+    { UPN_IS_SPELL_HYPHENATED_COMPOUND,   UPH_IS_SPELL_HYPHENATED_COMPOUND }
 };
 
 
diff --git a/linguistic/source/lngopt.cxx b/linguistic/source/lngopt.cxx
index f1cd69636a42..d46dfbb52bbd 100644
--- a/linguistic/source/lngopt.cxx
+++ b/linguistic/source/lngopt.cxx
@@ -115,7 +115,9 @@ WID_Name const aWID_Name[] =
     { 0,                                  "" },
     { UPH_DEFAULT_LANGUAGE,               UPN_DEFAULT_LANGUAGE },
     { UPH_DEFAULT_LOCALE_CJK,             UPN_DEFAULT_LOCALE_CJK },
-    { UPH_DEFAULT_LOCALE_CTL,             UPN_DEFAULT_LOCALE_CTL }
+    { UPH_DEFAULT_LOCALE_CTL,             UPN_DEFAULT_LOCALE_CTL },
+    { UPH_IS_SPELL_CLOSED_COMPOUND,       UPN_IS_SPELL_CLOSED_COMPOUND },
+    { UPH_IS_SPELL_HYPHENATED_COMPOUND,   UPN_IS_SPELL_HYPHENATED_COMPOUND }
 };
 
 
@@ -166,9 +168,9 @@ static o3tl::span<const SfxItemPropertyMapEntry> 
lcl_GetLinguProps()
                 cppu::UnoType<bool>::get(),            0, 0 },
         { UPN_IS_SPELL_CAPITALIZATION,    UPH_IS_SPELL_CAPITALIZATION,
                 cppu::UnoType<bool>::get(),            0, 0 },
-        { UPN_IS_SPELL_HIDE,              UPH_IS_SPELL_HIDE,              /*! 
deprecated !*/
+        { UPN_IS_SPELL_CLOSED_COMPOUND,   UPH_IS_SPELL_CLOSED_COMPOUND,
                 cppu::UnoType<bool>::get(),            0, 0 },
-        { UPN_IS_SPELL_IN_ALL_LANGUAGES,  UPH_IS_SPELL_IN_ALL_LANGUAGES,  /*! 
deprecated !*/
+        { UPN_IS_SPELL_HYPHENATED_COMPOUND,   UPH_IS_SPELL_HYPHENATED_COMPOUND,
                 cppu::UnoType<bool>::get(),            0, 0 },
         { UPN_IS_SPELL_SPECIAL,           UPH_IS_SPELL_SPECIAL,
                 cppu::UnoType<bool>::get(),            0, 0 },
diff --git a/linguistic/source/lngopt.hxx b/linguistic/source/lngopt.hxx
index 896e345edb74..08dde49e117c 100644
--- a/linguistic/source/lngopt.hxx
+++ b/linguistic/source/lngopt.hxx
@@ -124,6 +124,14 @@ public:
         { return getPropertyBool(UPN_IS_SPELL_CAPITALIZATION); }
     virtual void SAL_CALL setIsSpellCapitalization(sal_Bool p1) override
         { setProperty(UPN_IS_SPELL_CAPITALIZATION, static_cast<bool>(p1)); }
+    virtual sal_Bool SAL_CALL getIsSpellClosedCompound() override
+        { return getPropertyBool(UPN_IS_SPELL_CLOSED_COMPOUND); }
+    virtual void SAL_CALL setIsSpellClosedCompound(sal_Bool p1) override
+        { setProperty(UPN_IS_SPELL_CLOSED_COMPOUND, static_cast<bool>(p1)); }
+    virtual sal_Bool SAL_CALL getIsSpellHyphenatedCompound() override
+        { return getPropertyBool(UPN_IS_SPELL_HYPHENATED_COMPOUND); }
+    virtual void SAL_CALL setIsSpellHyphenatedCompound(sal_Bool p1) override
+        { setProperty(UPN_IS_SPELL_HYPHENATED_COMPOUND, 
static_cast<bool>(p1)); }
     virtual sal_Int16 SAL_CALL getHyphMinLeading() override
         { return getPropertyInt16(UPN_HYPH_MIN_LEADING); }
     virtual void SAL_CALL setHyphMinLeading(sal_Int16 p1) override
diff --git a/linguistic/source/lngprophelp.cxx 
b/linguistic/source/lngprophelp.cxx
index a14c96c9501e..543685dc33c4 100644
--- a/linguistic/source/lngprophelp.cxx
+++ b/linguistic/source/lngprophelp.cxx
@@ -292,6 +292,8 @@ PropertyHelper_Spell::PropertyHelper_Spell(
     rPropNames.push_back(UPN_IS_SPELL_UPPER_CASE);
     rPropNames.push_back(UPN_IS_SPELL_WITH_DIGITS);
     rPropNames.push_back(UPN_IS_SPELL_CAPITALIZATION);
+    rPropNames.push_back(UPN_IS_SPELL_CLOSED_COMPOUND);
+    rPropNames.push_back(UPN_IS_SPELL_HYPHENATED_COMPOUND);
     SetDefaultValues();
     GetCurrentValues();
 }
@@ -309,6 +311,8 @@ void PropertyHelper_Spell::SetDefaultValues()
     bResIsSpellUpperCase        = bIsSpellUpperCase         = false;
     bResIsSpellWithDigits       = bIsSpellWithDigits        = false;
     bResIsSpellCapitalization   = bIsSpellCapitalization    = true;
+    bResIsSpellClosedCompound   = bIsSpellClosedCompound    = true;
+    bResIsSpellHyphenatedCompound = bIsSpellHyphenatedCompound = true;
 }
 
 
@@ -340,6 +344,16 @@ void PropertyHelper_Spell::GetCurrentValues()
             pbVal    = &bIsSpellCapitalization;
             pbResVal = &bResIsSpellCapitalization;
         }
+        else if ( rPropName == UPN_IS_SPELL_CLOSED_COMPOUND )
+        {
+            pbVal    = &bIsSpellClosedCompound;
+            pbResVal = &bResIsSpellClosedCompound;
+        }
+        else if ( rPropName == UPN_IS_SPELL_HYPHENATED_COMPOUND )
+        {
+            pbVal    = &bIsSpellHyphenatedCompound;
+            pbResVal = &bResIsSpellHyphenatedCompound;
+        }
 
         if (pbVal && pbResVal)
         {
@@ -383,6 +397,20 @@ bool PropertyHelper_Spell::propertyChange_Impl( const 
PropertyChangeEvent& rEvt
                 bSWWA = !bSCWA;             // sal_True->sal_False change?
                 break;
             }
+            case UPH_IS_SPELL_CLOSED_COMPOUND     :
+            {
+                pbVal = &bIsSpellClosedCompound;
+                bSCWA = ! *pbVal;    // sal_False->sal_True change?
+                bSWWA = !bSCWA;             // sal_True->sal_False change?
+                break;
+            }
+            case UPH_IS_SPELL_HYPHENATED_COMPOUND :
+            {
+                pbVal = &bIsSpellHyphenatedCompound;
+                bSCWA = ! *pbVal;    // sal_False->sal_True change?
+                bSWWA = !bSCWA;             // sal_True->sal_False change?
+                break;
+            }
             default:
                 SAL_WARN( "linguistic", "unknown property" );
         }
@@ -425,6 +453,8 @@ void PropertyHelper_Spell::SetTmpPropVals( const 
PropertyValues &rPropVals )
     // temporary value
     bResIsSpellWithDigits       = bIsSpellWithDigits;
     bResIsSpellCapitalization   = bIsSpellCapitalization;
+    bResIsSpellClosedCompound   = bIsSpellClosedCompound;
+    bResIsSpellHyphenatedCompound = bIsSpellHyphenatedCompound;
     bResIsSpellUpperCase        = bIsSpellUpperCase;
 
     for (const PropertyValue& rVal : rPropVals)
@@ -441,6 +471,8 @@ void PropertyHelper_Spell::SetTmpPropVals( const 
PropertyValues &rPropVals )
                 case UPH_IS_SPELL_UPPER_CASE     : pbResVal = 
&bResIsSpellUpperCase; break;
                 case UPH_IS_SPELL_WITH_DIGITS    : pbResVal = 
&bResIsSpellWithDigits; break;
                 case UPH_IS_SPELL_CAPITALIZATION : pbResVal = 
&bResIsSpellCapitalization; break;
+                case UPH_IS_SPELL_CLOSED_COMPOUND : pbResVal = 
&bResIsSpellClosedCompound; break;
+                case UPH_IS_SPELL_HYPHENATED_COMPOUND : pbResVal = 
&bResIsSpellHyphenatedCompound; break;
                 default:
                     SAL_WARN( "linguistic", "unknown property" );
             }
@@ -731,6 +763,16 @@ bool PropertyHelper_Spelling::IsSpellCapitalization() const
     return mxPropHelper->IsSpellCapitalization();
 }
 
+bool PropertyHelper_Spelling::IsSpellClosedCompound() const
+{
+    return mxPropHelper->IsSpellClosedCompound();
+}
+
+bool PropertyHelper_Spelling::IsSpellHyphenatedCompound() const
+{
+    return mxPropHelper->IsSpellHyphenatedCompound();
+}
+
 bool PropertyHelper_Spelling::addLinguServiceEventListener(
                 const css::uno::Reference<
                     css::linguistic2::XLinguServiceEventListener >& rxListener 
)
diff --git a/linguistic/workben/sprophelp.cxx b/linguistic/workben/sprophelp.cxx
index 41542fec155f..9da626319a72 100644
--- a/linguistic/workben/sprophelp.cxx
+++ b/linguistic/workben/sprophelp.cxx
@@ -167,7 +167,9 @@ static const char *aSP[] =
     UPN_IS_USE_DICTIONARY_LIST,
     UPN_IS_SPELL_UPPER_CASE,
     UPN_IS_SPELL_WITH_DIGITS,
-    UPN_IS_SPELL_CAPITALIZATION
+    UPN_IS_SPELL_CAPITALIZATION,
+    UPN_IS_SPELL_CLOSED_COMPOUND,
+    UPN_IS_SPELL_HYPHENATED_COMPOUND
 };
 
 
@@ -216,6 +218,16 @@ PropertyHelper_Spell::PropertyHelper_Spell(
                 pbVal    = &bIsSpellCapitalization;
                 pbResVal = &bResIsSpellCapitalization;
             }
+            else if (OUString( UPN_IS_SPELL_CLOSED_COMPOUND ) == pPropName[i])
+            {
+                pbVal    = &bIsSpellClosedCompound;
+                pbResVal = &bResIsSpellClosedCompound;
+            }
+            else if (OUString( UPN_IS_SPELL_HYPHENATED_COMPOUND ) == 
pPropName[i])
+            {
+                pbVal    = &bIsSpellHyphenatedCompound;
+                pbResVal = &bResIsSpellHyphenatedCompound;
+            }
 
             if (pbVal && pbResVal)
             {
@@ -240,6 +252,8 @@ void PropertyHelper_Spell::SetDefault()
     bResIsSpellUpperCase            = bIsSpellUpperCase             = 
sal_False;
     bResIsSpellWithDigits           = bIsSpellWithDigits            = 
sal_False;
     bResIsSpellCapitalization       = bIsSpellCapitalization        = sal_True;
+    bResIsSpellClosedCompound       = bIsSpellClosedCompound        = sal_True;
+    bResIsSpellHyphenatedCompound   = bIsSpellHyphenatedCompound    = sal_True;
 }
 
 
@@ -296,6 +310,21 @@ void SAL_CALL
                 bSWWA = !bSCWA;             // sal_True->sal_False change?
                 break;
             }
+            case UPH_IS_SPELL_CLOSED_COMPOUND     :
+            {
+                pbVal = &bIsSpellClosedCompound;
+                bSCWA = sal_False == *pbVal;    // sal_False->sal_True change?
+                bSWWA = !bSCWA;             // sal_True->sal_False change?
+                break;
+            }
+            case UPH_IS_SPELL_HYPHENATED_COMPOUND     :
+            {
+                pbVal = &bIsSpellHyphenatedCompound;
+                bSCWA = sal_False == *pbVal;    // sal_False->sal_True change?
+                bSWWA = !bSCWA;             // sal_True->sal_False change?
+                break;
+            }
+
             default:
                 OSL_FAIL( "unknown property" );
         }
@@ -325,6 +354,8 @@ void PropertyHelper_Spell::SetTmpPropVals( const 
PropertyValues &rPropVals )
     bResIsSpellUpperCase            = bIsSpellUpperCase;
     bResIsSpellWithDigits           = bIsSpellWithDigits;
     bResIsSpellCapitalization       = bIsSpellCapitalization;
+    bResIsSpellClosedCompound       = bIsSpellClosedCompound;
+    bResIsSpellHyphenatedCompound   = bIsSpellHyphenatedCompound;
 
     sal_Int32 nLen = rPropVals.getLength();
     if (nLen)
@@ -341,6 +372,8 @@ void PropertyHelper_Spell::SetTmpPropVals( const 
PropertyValues &rPropVals )
                 case UPH_IS_SPELL_UPPER_CASE          : pbResVal = 
&bResIsSpellUpperCase; break;
                 case UPH_IS_SPELL_WITH_DIGITS         : pbResVal = 
&bResIsSpellWithDigits; break;
                 case UPH_IS_SPELL_CAPITALIZATION      : pbResVal = 
&bResIsSpellCapitalization; break;
+                case UPH_IS_SPELL_CLOSED_COMPOUND     : pbResVal = 
&bResIsSpellClosedCompound; break;
+                case UPH_IS_SPELL_HYPHENATED_COMPOUND : pbResVal = 
&bResIsSpellHyphenatedCompound; break;
                 default:
                     OSL_FAIL( "unknown property" );
             }
diff --git a/offapi/com/sun/star/linguistic2/XLinguProperties.idl 
b/offapi/com/sun/star/linguistic2/XLinguProperties.idl
index 0d0e78d67192..c35047879c29 100644
--- a/offapi/com/sun/star/linguistic2/XLinguProperties.idl
+++ b/offapi/com/sun/star/linguistic2/XLinguProperties.idl
@@ -106,6 +106,20 @@ published interface XLinguProperties
     */
     [attribute] com::sun::star::lang::Locale DefaultLocale_CTL;
 
+    /** defines whether spell checking should be accept rule-based
+         closed compounding of dictionary words.
+
+        @since LibreOffice 7.6
+    */
+    [attribute] boolean IsSpellClosedCompound;
+
+    /** defines whether spell checking should be accept rule-based
+         hyphenated compounding of dictionary words.
+
+        @since LibreOffice 7.6
+    */
+    [attribute] boolean IsSpellHyphenatedCompound;
+
 };
 
 
diff --git a/offapi/type_reference/offapi.idl b/offapi/type_reference/offapi.idl
index fad96110fffa..3a54a0ebe134 100644
--- a/offapi/type_reference/offapi.idl
+++ b/offapi/type_reference/offapi.idl
@@ -8968,6 +8968,8 @@ module com {
      [attribute] boolean IsWrapReverse;
      [attribute] ::com::sun::star::lang::Locale DefaultLocale_CJK;
      [attribute] ::com::sun::star::lang::Locale DefaultLocale_CTL;
+     [attribute] boolean IsSpellClosedCompound;
+     [attribute] boolean IsSpellHyphenatedCompound;
     };
     published service LinguProperties: 
::com::sun::star::linguistic2::XLinguProperties;
     published struct LinguServiceEvent: ::com::sun::star::lang::EventObject {
diff --git a/officecfg/registry/schema/org/openoffice/Office/Linguistic.xcs 
b/officecfg/registry/schema/org/openoffice/Office/Linguistic.xcs
index 2ecc4ae34804..95c9297d5a86 100644
--- a/officecfg/registry/schema/org/openoffice/Office/Linguistic.xcs
+++ b/officecfg/registry/schema/org/openoffice/Office/Linguistic.xcs
@@ -349,6 +349,22 @@
         </info>
         <value>true</value>
       </prop>
+      <prop oor:name="IsSpellClosedCompound" oor:type="xs:boolean" 
oor:nillable="false">
+        <!-- UIHints: Tools - Options - General - Language -->
+        <info>
+          <desc>Allows rule-based closed compounding of dictionary words</desc>
+          <label>Accept possible closed compound words</label>
+        </info>
+        <value>true</value>
+      </prop>
+      <prop oor:name="IsSpellHyphenatedCompound" oor:type="xs:boolean" 
oor:nillable="false">
+        <!-- UIHints: Tools - Options - General - Language -->
+        <info>
+          <desc>Allows rule-based hyphenated compounding of dictionary 
words</desc>
+          <label>Accept possible hyphenated compound words</label>
+        </info>
+        <value>true</value>
+      </prop>
       <prop oor:name="IsReverseDirection" oor:type="xs:boolean" 
oor:nillable="false">
         <!-- UIHints: Tools - Options - General - Language -->
         <info>
diff --git a/unotools/source/config/lingucfg.cxx 
b/unotools/source/config/lingucfg.cxx
index 03969c3d1ffe..0b39db9172ef 100644
--- a/unotools/source/config/lingucfg.cxx
+++ b/unotools/source/config/lingucfg.cxx
@@ -117,9 +117,13 @@ SvtLinguOptions::SvtLinguOptions()
     , bIsSpellWithDigits(false)
     , bIsSpellUpperCase(false)
     , bIsSpellCapitalization(true)
+    , bIsSpellClosedCompound(true)
+    , bIsSpellHyphenatedCompound(true)
     , bROIsSpellWithDigits(false)
     , bROIsSpellUpperCase(false)
     , bROIsSpellCapitalization(false)
+    , bROIsSpellClosedCompound(false)
+    , bROIsSpellHyphenatedCompound(false)
     , bIsIgnorePostPositionalWord(true)
     , bIsAutoCloseDialog(false)
     , bIsShowEntriesRecentlyUsedFirst(false)
@@ -238,6 +242,8 @@ NamesToHdl const aNamesToHdl[] =
 {/*  9 */    "SpellChecking/IsSpellCapitalization",           
UPN_IS_SPELL_CAPITALIZATION,           UPH_IS_SPELL_CAPITALIZATION},
 {/* 10 */    "SpellChecking/IsSpellAuto",                     
UPN_IS_SPELL_AUTO,                     UPH_IS_SPELL_AUTO},
 {/* 11 */    "SpellChecking/IsSpellSpecial",                  
UPN_IS_SPELL_SPECIAL,                  UPH_IS_SPELL_SPECIAL},
+{/* 12 */    "SpellChecking/IsSpellClosedCompound",           
UPN_IS_SPELL_CLOSED_COMPOUND,          UPH_IS_SPELL_CLOSED_COMPOUND},
+{/* 13 */    "SpellChecking/IsSpellHyphenatedCompound",       
UPN_IS_SPELL_HYPHENATED_COMPOUND,      UPH_IS_SPELL_HYPHENATED_COMPOUND},
 {/* 14 */    "SpellChecking/IsReverseDirection",              
UPN_IS_WRAP_REVERSE,                   UPH_IS_WRAP_REVERSE},
 
 {/* 15 */    "Hyphenation/MinLeading",                        
UPN_HYPH_MIN_LEADING,                  UPH_HYPH_MIN_LEADING},
@@ -348,6 +354,8 @@ uno::Any SvtLinguConfigItem::GetProperty( sal_Int32 
nPropertyHandle ) const
         case UPH_IS_WRAP_REVERSE :          pbVal = &rOpt.bIsSpellReverse;  
break;
         case UPH_DEFAULT_LANGUAGE :         plVal = &rOpt.nDefaultLanguage; 
break;
         case UPH_IS_SPELL_CAPITALIZATION :  pbVal = 
&rOpt.bIsSpellCapitalization;       break;
+        case UPH_IS_SPELL_CLOSED_COMPOUND:  pbVal = 
&rOpt.bIsSpellClosedCompound;       break;
+        case UPH_IS_SPELL_HYPHENATED_COMPOUND:  pbVal = 
&rOpt.bIsSpellHyphenatedCompound;    break;
         case UPH_IS_SPELL_WITH_DIGITS :     pbVal = &rOpt.bIsSpellWithDigits;  
 break;
         case UPH_IS_SPELL_UPPER_CASE :      pbVal = &rOpt.bIsSpellUpperCase;   
     break;
         case UPH_HYPH_MIN_LEADING :         pnVal = &rOpt.nHyphMinLeading;     
 break;
@@ -443,6 +451,8 @@ bool SvtLinguConfigItem::SetProperty( sal_Int32 
nPropertyHandle, const uno::Any
         case UPH_IS_WRAP_REVERSE :          pbVal = &rOpt.bIsSpellReverse; 
break;
         case UPH_DEFAULT_LANGUAGE :         plVal = &rOpt.nDefaultLanguage;    
break;
         case UPH_IS_SPELL_CAPITALIZATION :  pbVal = 
&rOpt.bIsSpellCapitalization;      break;
+        case UPH_IS_SPELL_CLOSED_COMPOUND:  pbVal = 
&rOpt.bIsSpellClosedCompound;      break;
+        case UPH_IS_SPELL_HYPHENATED_COMPOUND:  pbVal = 
&rOpt.bIsSpellHyphenatedCompound;    break;
         case UPH_IS_SPELL_WITH_DIGITS :     pbVal = &rOpt.bIsSpellWithDigits;  
break;
         case UPH_IS_SPELL_UPPER_CASE :      pbVal = &rOpt.bIsSpellUpperCase;   
    break;
         case UPH_HYPH_MIN_LEADING :         pnVal = &rOpt.nHyphMinLeading;     
break;
@@ -603,6 +613,11 @@ void SvtLinguConfigItem::LoadOptions( const uno::Sequence< 
OUString > &rProperyN
                     { rOpt.bROIsSpellWithDigits = pROStates[i]; rVal >>= 
rOpt.bIsSpellWithDigits;    } break;
                 case UPH_IS_SPELL_CAPITALIZATION :
                     { rOpt.bROIsSpellCapitalization = pROStates[i]; rVal >>= 
rOpt.bIsSpellCapitalization;    } break;
+                case UPH_IS_SPELL_CLOSED_COMPOUND :
+                    { rOpt.bROIsSpellClosedCompound = pROStates[i]; rVal >>= 
rOpt.bIsSpellClosedCompound;    } break;
+                case UPH_IS_SPELL_HYPHENATED_COMPOUND :
+                    { rOpt.bROIsSpellHyphenatedCompound = pROStates[i]; rVal 
>>= rOpt.bIsSpellHyphenatedCompound;    } break;
+
                 case UPH_IS_SPELL_AUTO :
                     { rOpt.bROIsSpellAuto = pROStates[i]; rVal >>= 
rOpt.bIsSpellAuto;  } break;
                 case UPH_IS_SPELL_SPECIAL :
@@ -707,6 +722,8 @@ bool SvtLinguConfigItem::SaveOptions( const uno::Sequence< 
OUString > &rProperyN
         *pValue++ <<= rOpt.bIsSpellCapitalization;     //   9
         *pValue++ <<= rOpt.bIsSpellAuto;               //  10
         *pValue++ <<= rOpt.bIsSpellSpecial;            //  11
+        *pValue++ <<= rOpt.bIsSpellClosedCompound;     //  12
+        *pValue++ <<= rOpt.bIsSpellHyphenatedCompound; //  13
         *pValue++ <<= rOpt.bIsSpellReverse;            //  14
 
         *pValue++ <<= rOpt.nHyphMinLeading;            //  15
@@ -767,6 +784,8 @@ bool SvtLinguConfigItem::IsReadOnly( sal_Int32 
nPropertyHandle ) const
         case UPH_IS_WRAP_REVERSE                : bReadOnly = 
rOpt.bROIsSpellReverse; break;
         case UPH_DEFAULT_LANGUAGE               : bReadOnly = 
rOpt.bRODefaultLanguage; break;
         case UPH_IS_SPELL_CAPITALIZATION        : bReadOnly = 
rOpt.bROIsSpellCapitalization; break;
+        case UPH_IS_SPELL_CLOSED_COMPOUND       : bReadOnly = 
rOpt.bROIsSpellClosedCompound; break;
+        case UPH_IS_SPELL_HYPHENATED_COMPOUND   : bReadOnly = 
rOpt.bROIsSpellHyphenatedCompound; break;
         case UPH_IS_SPELL_WITH_DIGITS           : bReadOnly = 
rOpt.bROIsSpellWithDigits; break;
         case UPH_IS_SPELL_UPPER_CASE            : bReadOnly = 
rOpt.bROIsSpellUpperCase; break;
         case UPH_HYPH_MIN_LEADING               : bReadOnly = 
rOpt.bROHyphMinLeading; break;

Reply via email to