desktop/source/lib/init.cxx                                        |  195 
+++++++---
 include/unotools/lingucfg.hxx                                      |    2 
 lingucomponent/config/Linguistic-lingucomponent-grammarchecker.xcu |   30 -
 lingucomponent/source/spellcheck/languagetool/languagetoolimp.cxx  |   59 +--
 postprocess/CustomTarget_registry.mk                               |    1 
 unotools/source/config/lingucfg.cxx                                |   21 -
 6 files changed, 186 insertions(+), 122 deletions(-)

New commits:
commit 94e6049b6467d9bc1e52a1a80c7cf1a5f138e82d
Author:     Xisco Fauli <xiscofa...@libreoffice.org>
AuthorDate: Wed Jul 12 07:03:15 2023 +0200
Commit:     Xisco Fauli <xiscofa...@libreoffice.org>
CommitDate: Wed Jul 12 08:57:41 2023 +0200

    Revert recent LanguageTool commits
    
    Reason for revert: See discussion in 
https://gerrit.libreoffice.org/c/core/+/154302
    - it's causing CppunitTest_sw_layoutwriter2 to fail on Windows.
    - it's causing CppunitTest_sw_layoutwriter to fail on Linux.
    - Probably other recent CI failures are also related.
    - A similar commit was reverted one year ago for similar reasons -> 
https://gerrit.libreoffice.org/c/core/+/135859
    
    This commit contains the following commits:
    
    Revert "lok: remove old hack for LanguageTool locales"
    
    This reverts commit 9a5329a266bd74abc4794f1fcbae3db07582dbde.
    
    Revert "lok: LanguageTool provides list of languages"
    
    This reverts commit 21d0489a5efa970e975ce1a70dfda2fd9e2c186d.
    
    Revert "lok: remove duplicated locales for LanguageTool"
    
    This reverts commit a0865169ab62508a7b933ed4634defa57b25f7b7.
    
    Revert "Load the locales from config file for languagetool"
    
    This reverts commit 81b0d9a951c9b15f4f1a76d45d0bd955b4dfc95b.
    
    Change-Id: I3dc48097615f510e33e233e868b6b10704d81e67
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/154342
    Tested-by: Jenkins
    Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org>

diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index 4f1b5287130f..dbd236858ce8 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -117,7 +117,6 @@
 #include <com/sun/star/linguistic2/LanguageGuessing.hpp>
 #include <com/sun/star/linguistic2/LinguServiceManager.hpp>
 #include <com/sun/star/linguistic2/XSpellChecker.hpp>
-#include <com/sun/star/linguistic2/XProofreader.hpp>
 #include <com/sun/star/i18n/LocaleCalendar2.hpp>
 #include <com/sun/star/i18n/ScriptType.hpp>
 #include <com/sun/star/lang/DisposedException.hpp>
@@ -228,8 +227,6 @@ using namespace vcl;
 using namespace desktop;
 using namespace utl;
 
-using LanguageToolCfg = 
officecfg::Office::Linguistic::GrammarChecking::LanguageTool;
-
 static LibLibreOffice_Impl *gImpl = nullptr;
 static bool lok_preinit_2_called = false;
 static std::weak_ptr< LibreOfficeKitClass > gOfficeClass;
@@ -5620,6 +5617,132 @@ static void 
doc_setGraphicSelection(LibreOfficeKitDocument* pThis, int nType, in
     pDoc->setGraphicSelection(nType, nX, nY);
 }
 
+static void getDocLanguages(LibreOfficeKitDocument* pThis, 
uno::Sequence<lang::Locale>& rSeq)
+{
+    SfxViewFrame* pViewFrame = SfxViewFrame::Current();
+    if (!pViewFrame)
+        return;
+
+    SfxDispatcher* pDispatcher = pViewFrame->GetBindings().GetDispatcher();
+    if (!pDispatcher)
+        return;
+
+    css::uno::Any aLangStatus;
+    pDispatcher->QueryState(SID_LANGUAGE_STATUS, aLangStatus);
+
+    OUString sCurrent;
+    OUString sKeyboard;
+    OUString sGuessText;
+    SvtScriptType eScriptType = SvtScriptType::LATIN | SvtScriptType::ASIAN
+        | SvtScriptType::COMPLEX;
+
+    Sequence<OUString> aSeqLang;
+    if (aLangStatus >>= aSeqLang)
+    {
+        if (aSeqLang.getLength() == 4)
+        {
+            sCurrent = aSeqLang[0];
+            eScriptType = static_cast<SvtScriptType>(aSeqLang[1].toInt32());
+            sKeyboard = aSeqLang[1];
+            sGuessText = aSeqLang[2];
+        }
+    }
+    else
+    {
+        aLangStatus >>= sCurrent;
+    }
+
+    LanguageType nLangType;
+    std::set<LanguageType> aLangItems;
+
+    if (!sCurrent.isEmpty())
+    {
+        nLangType = SvtLanguageTable::GetLanguageType(sCurrent);
+        if (nLangType != LANGUAGE_DONTKNOW)
+        {
+            aLangItems.insert(nLangType);
+        }
+    }
+
+    const AllSettings& rAllSettings = Application::GetSettings();
+    nLangType = rAllSettings.GetLanguageTag().getLanguageType();
+    if (nLangType != LANGUAGE_DONTKNOW &&
+        (eScriptType & SvtLanguageOptions::GetScriptTypeOfLanguage(nLangType)))
+    {
+        aLangItems.insert(nLangType);
+    }
+
+    nLangType = rAllSettings.GetUILanguageTag().getLanguageType();
+    if (nLangType != LANGUAGE_DONTKNOW &&
+        (eScriptType & SvtLanguageOptions::GetScriptTypeOfLanguage(nLangType)))
+    {
+        aLangItems.insert(nLangType);
+    }
+
+    if (!sKeyboard.isEmpty())
+    {
+        nLangType = SvtLanguageTable::GetLanguageType(sKeyboard);
+        if (nLangType != LANGUAGE_DONTKNOW &&
+            (eScriptType & 
SvtLanguageOptions::GetScriptTypeOfLanguage(nLangType)))
+        {
+            aLangItems.insert(nLangType);
+        }
+    }
+
+    if (!sGuessText.isEmpty())
+    {
+        Reference<linguistic2::XLanguageGuessing> xLangGuesser;
+        try
+        {
+            xLangGuesser = linguistic2::LanguageGuessing::create(xContext);
+        }
+        catch(...)
+        {
+        }
+
+        if (xLangGuesser.is())
+        {
+            lang::Locale aLocale = 
xLangGuesser->guessPrimaryLanguage(sGuessText, 0,
+                                                                      
sGuessText.getLength());
+            LanguageTag aLanguageTag(aLocale);
+            nLangType = aLanguageTag.getLanguageType(false);
+            if (nLangType != LANGUAGE_DONTKNOW &&
+                (eScriptType & 
SvtLanguageOptions::GetScriptTypeOfLanguage(nLangType)))
+            {
+                aLangItems.insert(nLangType);
+            }
+        }
+    }
+
+    LibLODocument_Impl* pDocument = static_cast<LibLODocument_Impl*>(pThis);
+    Reference<document::XDocumentLanguages> 
xDocumentLanguages(pDocument->mxComponent, UNO_QUERY);
+    if (xDocumentLanguages.is())
+    {
+        const Sequence<lang::Locale> 
aLocales(xDocumentLanguages->getDocumentLanguages(
+                                                  
static_cast<sal_Int16>(eScriptType), 64));
+
+        for (const lang::Locale& aLocale : aLocales)
+        {
+            nLangType = SvtLanguageTable::GetLanguageType(aLocale.Language);
+            if (nLangType != LANGUAGE_DONTKNOW &&
+                (eScriptType & 
SvtLanguageOptions::GetScriptTypeOfLanguage(nLangType)))
+            {
+                aLangItems.insert(nLangType);
+            }
+        }
+    }
+
+    int nLocale = 0;
+    Sequence<lang::Locale> aLocales(aLangItems.size());
+    auto pLocales = aLocales.getArray();
+    for (const LanguageType& itLang : aLangItems)
+    {
+        pLocales[nLocale++] = LanguageTag::convertToLocale(itLang);
+    }
+
+    rSeq = aLocales;
+}
+
 static void doc_resetSelection(LibreOfficeKitDocument* pThis)
 {
     comphelper::ProfileZone aZone("doc_resetSelection");
@@ -5637,28 +5760,12 @@ static void doc_resetSelection(LibreOfficeKitDocument* 
pThis)
     pDoc->resetSelection();
 }
 
-static void addLocale(boost::property_tree::ptree& rValues, css::lang::Locale 
const & rLocale)
-{
-    boost::property_tree::ptree aChild;
-    OUString sLanguage;
-    const LanguageTag aLanguageTag( rLocale );
-    sLanguage = 
SvtLanguageTable::GetLanguageString(aLanguageTag.getLanguageType());
-    if (sLanguage.endsWith("}"))
-        return;
-
-    sLanguage += ";" + aLanguageTag.getBcp47(false);
-    aChild.put("", sLanguage.toUtf8());
-    rValues.push_back(std::make_pair("", aChild));
-}
-
-static char* getLanguages(const char* pCommand)
+static char* getLanguages(LibreOfficeKitDocument* pThis, const char* pCommand)
 {
     css::uno::Sequence< css::lang::Locale > aLocales;
-    css::uno::Sequence< css::lang::Locale > aGrammarLocales;
 
     if (xContext.is())
     {
-        // SpellChecker
         css::uno::Reference<css::linguistic2::XLinguServiceManager2> xLangSrv 
= css::linguistic2::LinguServiceManager::create(xContext);
         if (xLangSrv.is())
         {
@@ -5667,24 +5774,33 @@ static char* getLanguages(const char* pCommand)
                 aLocales = xSpell->getLocales();
         }
 
-        // LanguageTool
-        if (LanguageToolCfg::IsEnabled::get())
+        /* FIXME: To obtain the document languages the spell checker can be 
disabled,
+           so a future re-work of the getLanguages function is needed in favor 
to use
+           getDocLanguages */
+        if (!aLocales.hasElements())
         {
-            uno::Reference< linguistic2::XProofreader > xGC(
-                    
xContext->getServiceManager()->createInstanceWithContext("org.openoffice.lingu.LanguageToolGrammarChecker",
 xContext),
-                    uno::UNO_QUERY_THROW );
-            uno::Reference< linguistic2::XSupportedLocales > xSuppLoc( xGC, 
uno::UNO_QUERY_THROW );
-            aGrammarLocales = xSuppLoc->getLocales();
+            uno::Sequence< css::lang::Locale > aSeq;
+            getDocLanguages(pThis, aSeq);
+            aLocales = aSeq;
         }
     }
 
     boost::property_tree::ptree aTree;
     aTree.put("commandName", pCommand);
     boost::property_tree::ptree aValues;
-    for ( css::lang::Locale const & rLocale : std::as_const(aLocales) )
-        addLocale(aValues, rLocale);
-    for ( css::lang::Locale const & rLocale : std::as_const(aGrammarLocales) )
-        addLocale(aValues, rLocale);
+    boost::property_tree::ptree aChild;
+    OUString sLanguage;
+    for ( css::lang::Locale const & locale : std::as_const(aLocales) )
+    {
+        const LanguageTag aLanguageTag( locale );
+        sLanguage = 
SvtLanguageTable::GetLanguageString(aLanguageTag.getLanguageType());
+        if (sLanguage.startsWith("{") && sLanguage.endsWith("}"))
+            continue;
+
+        sLanguage += ";" + aLanguageTag.getBcp47(false);
+        aChild.put("", sLanguage.toUtf8());
+        aValues.push_back(std::make_pair("", aChild));
+    }
     aTree.add_child("commandValues", aValues);
     std::stringstream aStream;
     boost::property_tree::write_json(aStream, aTree);
@@ -6023,7 +6139,7 @@ static char* doc_getCommandValues(LibreOfficeKitDocument* 
pThis, const char* pCo
 
     if (!strcmp(pCommand, ".uno:LanguageStatus"))
     {
-        return getLanguages(pCommand);
+        return getLanguages(pThis, pCommand);
     }
     else if (!strcmp(pCommand, ".uno:CharFontName"))
     {
@@ -7160,8 +7276,6 @@ static void preLoadShortCutAccelerators()
     batch->commit();
 }
 
-void setLanguageToolConfig();
-
 /// Used only by LibreOfficeKit when used by Online to pre-initialize
 static void preloadData()
 {
@@ -7180,9 +7294,6 @@ static void preloadData()
     if(bAbort)
         std::cerr << "CheckExtensionDependencies failed" << std::endl;
 
-    // setup LanguageTool config before spell checking init
-    setLanguageToolConfig();
-
     // preload all available dictionaries
     css::uno::Reference<css::linguistic2::XLinguServiceManager> xLngSvcMgr =
         
css::linguistic2::LinguServiceManager::create(comphelper::getProcessComponentContext());
@@ -7402,19 +7513,11 @@ void setLanguageToolConfig()
                 if (xSpell.is())
                 {
                     Sequence<OUString> aEmpty;
-                    static constexpr OUStringLiteral cSpell(SN_SPELLCHECKER);
                     Sequence<css::lang::Locale> aLocales = 
xSpell->getLocales();
 
-                    uno::Reference<linguistic2::XProofreader> xGC(
-                        
xContext->getServiceManager()->createInstanceWithContext("org.openoffice.lingu.LanguageToolGrammarChecker",
 xContext),
-                        uno::UNO_QUERY_THROW);
-                    uno::Reference<linguistic2::XSupportedLocales> 
xSuppLoc(xGC, uno::UNO_QUERY_THROW);
-
                     for (int itLocale = 0; itLocale < aLocales.getLength(); 
itLocale++)
                     {
-                        // turn off spell checker if LanguageTool supports the 
locale already
-                        if (xSuppLoc->hasLocale(aLocales[itLocale]))
-                            xLangSrv->setConfiguredServices(cSpell, 
aLocales[itLocale], aEmpty);
+                        xLangSrv->setConfiguredServices(SN_SPELLCHECKER, 
aLocales[itLocale], aEmpty);
                     }
                 }
             }
diff --git a/include/unotools/lingucfg.hxx b/include/unotools/lingucfg.hxx
index c924d7898764..40797a372f33 100644
--- a/include/unotools/lingucfg.hxx
+++ b/include/unotools/lingucfg.hxx
@@ -196,8 +196,6 @@ public:
 
     bool GetDictionaryEntry( const OUString &rNodeName, 
SvtLinguConfigDictionaryEntry &rDicEntry ) const;
 
-    bool GetLocaleListFor( const OUString &rSetName, const OUString 
&rSetEntry, css::uno::Sequence< OUString > &rLocaleList ) const;
-
     css::uno::Sequence< OUString > GetDisabledDictionaries() const;
 
     std::vector< SvtLinguConfigDictionaryEntry > 
GetActiveDictionariesByFormat( std::u16string_view rFormatName ) const;
diff --git a/lingucomponent/config/Linguistic-lingucomponent-grammarchecker.xcu 
b/lingucomponent/config/Linguistic-lingucomponent-grammarchecker.xcu
deleted file mode 100644
index 6fa455d969b8..000000000000
--- a/lingucomponent/config/Linguistic-lingucomponent-grammarchecker.xcu
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version='1.0' encoding='UTF-8'?>
-<!--
- * This file is part of the LibreOffice project.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * This file incorporates work covered by the following license notice:
- *
- *   Licensed to the Apache Software Foundation (ASF) under one or more
- *   contributor license agreements. See the NOTICE file distributed
- *   with this work for additional information regarding copyright
- *   ownership. The ASF licenses this file to you under the Apache
- *   License, Version 2.0 (the "License"); you may not use this file
- *   except in compliance with the License. You may obtain a copy of
- *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
--->
-<oor:component-data oor:name="Linguistic" oor:package="org.openoffice.Office" 
xmlns:install="http://openoffice.org/2004/installation"; 
xmlns:oor="http://openoffice.org/2001/registry"; 
xmlns:xs="http://www.w3.org/2001/XMLSchema"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";>
-    <node oor:name="ServiceManager">
-        <node oor:name="GrammarCheckers">
-            <node oor:name="org.openoffice.lingu.LanguageToolGrammarChecker" 
oor:op="fuse">
-                <prop oor:name="Locales" oor:type="oor:string-list">
-                    <value>ar ast-ES be-BY br-FR ca-ES ca-ES-valencia zh-CN 
da-DK nl nl-BE en en-AU en-CA en-GB en-NZ en-ZA en-US fr gl-ES de de-AT de-DE 
de-CH el-GR ga-IE it ja-JP km-KH nb no fa pl-PL pt pt-AO pt-BR pt-MZ pt-PT 
ro-RO ru-RU de-DE-x-simple-language sk-SK sl-SI es es-AR sv tl-PH ta-IN 
uk-UA</value>
-                </prop>
-            </node>
-        </node>
-    </node>
-</oor:component-data>
-
diff --git a/lingucomponent/source/spellcheck/languagetool/languagetoolimp.cxx 
b/lingucomponent/source/spellcheck/languagetool/languagetoolimp.cxx
index fb115f582f30..7152a6ff0880 100644
--- a/lingucomponent/source/spellcheck/languagetool/languagetoolimp.cxx
+++ b/lingucomponent/source/spellcheck/languagetool/languagetoolimp.cxx
@@ -56,8 +56,6 @@ using namespace com::sun::star::beans;
 using namespace com::sun::star::lang;
 using namespace com::sun::star::linguistic2;
 
-constexpr OUStringLiteral sDuden = u"duden";
-
 namespace
 {
 constexpr size_t MAX_SUGGESTIONS_SIZE = 10;
@@ -297,6 +295,14 @@ void parseProofreadingJSONResponse(ProofreadingResult& 
rResult, std::string&& aJ
         });
 }
 
+OUString getLocaleListURL()
+{
+    if (auto oURL = LanguageToolCfg::BaseURL::get())
+        if (!oURL->isEmpty())
+            return *oURL + "/languages";
+    return {};
+}
+
 OUString getCheckerURL()
 {
     if (auto oURL = LanguageToolCfg::BaseURL::get())
@@ -330,35 +336,44 @@ sal_Bool SAL_CALL 
LanguageToolGrammarChecker::hasLocale(const Locale& rLocale)
 
 uno::Sequence<Locale> SAL_CALL LanguageToolGrammarChecker::getLocales()
 {
-    osl::MutexGuard aGuard(linguistic::GetLinguMutex());
-
     if (m_aSuppLocales.hasElements())
         return m_aSuppLocales;
+    if (!LanguageToolCfg::IsEnabled::get())
+    {
+        return m_aSuppLocales;
+    }
 
-    SvtLinguConfig aLinguCfg;
-    uno::Sequence<OUString> aLocaleList;
-
-    if (LanguageToolCfg::RestProtocol::get().value_or("") == sDuden)
+    OUString localeUrl = getLocaleListURL();
+    if (localeUrl.isEmpty())
     {
-        aLocaleList.realloc(3);
-        aLocaleList.getArray()[0] = "de-DE";
-        aLocaleList.getArray()[1] = "en-US";
-        aLocaleList.getArray()[2] = "en-GB";
+        return m_aSuppLocales;
     }
-    else
-        aLinguCfg.GetLocaleListFor("GrammarCheckers",
-                                   
"org.openoffice.lingu.LanguageToolGrammarChecker", aLocaleList);
+    tools::Long statusCode = 0;
+    std::string response = makeHttpRequest(localeUrl, HTTP_METHOD::HTTP_GET, 
OString(), statusCode);
+    if (statusCode != 200)
+    {
+        return m_aSuppLocales;
+    }
+    if (response.empty())
+    {
+        return m_aSuppLocales;
+    }
+    boost::property_tree::ptree root;
+    std::stringstream aStream(response);
+    boost::property_tree::read_json(aStream, root);
 
-    auto nLength = aLocaleList.getLength();
-    m_aSuppLocales.realloc(nLength);
+    size_t length = root.size();
+    m_aSuppLocales.realloc(length);
     auto pArray = m_aSuppLocales.getArray();
-    auto pLocaleList = aLocaleList.getArray();
-
-    for (auto i = 0; i < nLength; i++)
+    int i = 0;
+    for (auto it = root.begin(); it != root.end(); it++, i++)
     {
-        pArray[i] = LanguageTag::convertToLocale(pLocaleList[i]);
+        boost::property_tree::ptree& localeItem = it->second;
+        const std::string longCode = localeItem.get<std::string>("longCode");
+        Locale aLocale = LanguageTag::convertToLocale(
+            OUString(longCode.c_str(), longCode.length(), 
RTL_TEXTENCODING_UTF8));
+        pArray[i] = aLocale;
     }
-
     return m_aSuppLocales;
 }
 
diff --git a/postprocess/CustomTarget_registry.mk 
b/postprocess/CustomTarget_registry.mk
index 9e235f098b25..b0bc7a4320f2 100644
--- a/postprocess/CustomTarget_registry.mk
+++ b/postprocess/CustomTarget_registry.mk
@@ -116,7 +116,6 @@ postprocess_DEPS_lingucomponent := main
 postprocess_FILES_lingucomponent := \
        
$(SRCDIR)/lingucomponent/config/Linguistic-lingucomponent-hyphenator.xcu \
        
$(SRCDIR)/lingucomponent/config/Linguistic-lingucomponent-spellchecker.xcu \
-       
$(SRCDIR)/lingucomponent/config/Linguistic-lingucomponent-grammarchecker.xcu \
        $(SRCDIR)/lingucomponent/config/Linguistic-lingucomponent-thesaurus.xcu 
\
 
 postprocess_FILES_main := \
diff --git a/unotools/source/config/lingucfg.cxx 
b/unotools/source/config/lingucfg.cxx
index af1eaee4aa9d..0b39db9172ef 100644
--- a/unotools/source/config/lingucfg.cxx
+++ b/unotools/source/config/lingucfg.cxx
@@ -941,27 +941,6 @@ bool SvtLinguConfig::GetSupportedDictionaryFormatsFor(
     return bSuccess;
 }
 
-bool SvtLinguConfig::GetLocaleListFor( const OUString &rSetName, const 
OUString &rSetEntry, css::uno::Sequence< OUString > &rLocaleList ) const
-{
-    if (rSetName.isEmpty() || rSetEntry.isEmpty())
-        return false;
-    bool bSuccess = false;
-    try
-    {
-        uno::Reference< container::XNameAccess > xNA( GetMainUpdateAccess(), 
uno::UNO_QUERY_THROW );
-        xNA.set( xNA->getByName("ServiceManager"), uno::UNO_QUERY_THROW );
-        xNA.set( xNA->getByName( rSetName ), uno::UNO_QUERY_THROW );
-        xNA.set( xNA->getByName( rSetEntry ), uno::UNO_QUERY_THROW );
-        if (xNA->getByName( "Locales" ) >>= rLocaleList)
-            bSuccess = true;
-        DBG_ASSERT( rLocaleList.hasElements(), "Locale list is empty" );
-    }
-    catch (uno::Exception &)
-    {
-    }
-    return bSuccess;
-}
-
 static bool lcl_GetFileUrlFromOrigin(
     OUString /*out*/ &rFileUrl,
     const OUString &rOrigin )

Reply via email to