linguistic/source/spelldsp.cxx  |   12 ++++++++++++
 sw/qa/extras/layout/layout2.cxx |   25 +++++++++++++++++++++++++
 2 files changed, 37 insertions(+)

New commits:
commit 5348f86429c420825a25a42494e5bb52e700723d
Author:     László Németh <[email protected]>
AuthorDate: Sun Dec 28 22:02:45 2025 +0100
Commit:     Xisco Fauli <[email protected]>
CommitDate: Mon Dec 29 17:25:01 2025 +0100

    tdf#40277 linguistic: recognize compounds from custom dictionary words
    
    Accept compounds separated by hyphens, when some (or all) constituents
    of the compound come from the custom dictionaries.
    
    For example, when "CustomWord" added by the user to one of the custom
    dictionaries, now "CustomWord-based", "CustomWord-CustomWord",
    "CustomWord-based-CustomWord-like" etc. compounds are accepted.
    
    Note: the recursion used by the algorithm is limited by the maximum
    allowed word length during spell checking (100 characters).
    
    Change-Id: Ie2e19714ad10b3c7436a442ca8c8775e673da579
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/196271
    Reviewed-by: László Németh <[email protected]>
    Tested-by: Jenkins
    Signed-off-by: Xisco Fauli <[email protected]>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/196285

diff --git a/linguistic/source/spelldsp.cxx b/linguistic/source/spelldsp.cxx
index e917c32f7c0b..3728bf2f1734 100644
--- a/linguistic/source/spelldsp.cxx
+++ b/linguistic/source/spelldsp.cxx
@@ -204,6 +204,18 @@ sal_Bool SAL_CALL
         // fallback: convert the apostrophes
         bRet = isValid_Impl( rWord, LinguLocaleToLanguage( rLocale ), 
rProperties, bConvert );
     }
+    if (!bRet)
+    {
+        // accept compounds combined from custom and default dictionary words
+        // separated by a hyphen
+        sal_Int32 nHyphenPos = rWord.indexOf("-");
+        if (nHyphenPos > -1)
+        {
+            return isValid(rWord.copy(0, nHyphenPos), rLocale, rProperties) &&
+                isValid(rWord.copy(nHyphenPos + 1, rWord.getLength() - 
nHyphenPos - 1),
+                                rLocale, rProperties);
+        }
+    }
     return bRet;
 }
 
diff --git a/sw/qa/extras/layout/layout2.cxx b/sw/qa/extras/layout/layout2.cxx
index b288a036359d..5a7cbd6873a7 100644
--- a/sw/qa/extras/layout/layout2.cxx
+++ b/sw/qa/extras/layout/layout2.cxx
@@ -1295,6 +1295,31 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter2, testTdf170140)
     CPPUNIT_ASSERT(!xSpell->isValid(sWord2, static_cast<sal_uInt16>(eLang), 
aProperties));
 }
 
+// TODO: move this test to the linguistic project
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter2, testTdf40277)
+{
+    uno::Reference<linguistic2::XSpellChecker1> xSpell = 
LinguMgr::GetSpellChecker();
+    auto aLocale = lang::Locale(u"en"_ustr, u"US"_ustr, OUString());
+    LanguageType eLang = LanguageTag::convertToLanguageType(aLocale);
+    if (!xSpell.is() || !xSpell->hasLanguage(static_cast<sal_uInt16>(eLang)))
+        return;
+
+    uno::Sequence<beans::PropertyValue> aProperties;
+
+    // check Hunspell dictionary
+    OUString sWord(u"based"_ustr);
+    CPPUNIT_ASSERT(xSpell->isValid(sWord, static_cast<sal_uInt16>(eLang), 
aProperties));
+
+    // check custom dictionary support (a word which is stored only in 
technical.dic)
+    OUString sWord2(u"SunHSI"_ustr);
+    CPPUNIT_ASSERT(xSpell->isValid(sWord2, static_cast<sal_uInt16>(eLang), 
aProperties));
+
+    OUString sWord3(u"SunHSI-based"_ustr);
+    // This was false (missing recognition of compounds formed from Hunspell
+    // dictionary words and custom dictionary words)
+    CPPUNIT_ASSERT(xSpell->isValid(sWord3, static_cast<sal_uInt16>(eLang), 
aProperties));
+}
+
 CPPUNIT_TEST_FIXTURE(SwLayoutWriter2, testRedlineNumberInFootnote)
 {
     createSwDoc("tdf85610.fodt");

Reply via email to