desktop/source/lib/init.cxx | 190 ++-------- lingucomponent/config/Linguistic-lingucomponent-grammarchecker.xcu | 2 lingucomponent/source/spellcheck/languagetool/languagetoolimp.cxx | 50 +- 3 files changed, 76 insertions(+), 166 deletions(-)
New commits: commit 7fb089be113f3f95d9a13e3aafafc64107301d1d Author: Szymon Kłos <szymon.k...@collabora.com> AuthorDate: Fri Feb 10 14:56:06 2023 +0100 Commit: Andras Timar <andras.ti...@collabora.com> CommitDate: Fri Feb 10 21:55:58 2023 +0000 lok: remove old hack for LanguageTool locales Change-Id: I1098c51f03b4cdd4f21a635f7b6aae8e90fd9f9f Reviewed-on: https://gerrit.libreoffice.org/c/core/+/146779 Reviewed-by: Henry Castro <hcas...@collabora.com> Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx index 2d79b7e57d3a..8c3e82ff0896 100644 --- a/desktop/source/lib/init.cxx +++ b/desktop/source/lib/init.cxx @@ -5396,132 +5396,6 @@ static void doc_setGraphicSelection(LibreOfficeKitDocument* pThis, int nType, in pDoc->setGraphicSelection(nType, nX, nY); } -static uno::Any getDocLanguages(LibreOfficeKitDocument* pThis) -{ - SfxViewFrame* pViewFrame = SfxViewFrame::Current(); - if (!pViewFrame) - return uno::makeAny(Sequence<lang::Locale>()); - - SfxDispatcher* pDispatcher = pViewFrame->GetBindings().GetDispatcher(); - if (!pDispatcher) - return uno::makeAny(Sequence<lang::Locale>()); - - 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); - } - - return uno::makeAny(aLocales); -} - static void doc_resetSelection(LibreOfficeKitDocument* pThis) { comphelper::ProfileZone aZone("doc_resetSelection"); @@ -5579,16 +5453,6 @@ static char* getLanguages(LibreOfficeKitDocument* pThis, const char* pCommand) uno::Reference< linguistic2::XSupportedLocales > xSuppLoc( xGC, uno::UNO_QUERY_THROW ); aGrammarLocales = xSuppLoc->getLocales(); } - - // Fallback - - /* 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()) - { - getDocLanguages(pThis) >>= aLocales; - } } boost::property_tree::ptree aTree; commit b39caa7f6570126441a52c9dfdf224178f001e22 Author: Szymon Kłos <szymon.k...@collabora.com> AuthorDate: Fri Feb 10 14:40:33 2023 +0100 Commit: Andras Timar <andras.ti...@collabora.com> CommitDate: Fri Feb 10 21:55:50 2023 +0000 lok: remove duplicated locales for LanguageTool Change-Id: I8fd1632f36a6c2c2d61331d6ce5dbd3cce83e2a0 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/146776 Reviewed-by: Henry Castro <hcas...@collabora.com> Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> diff --git a/lingucomponent/config/Linguistic-lingucomponent-grammarchecker.xcu b/lingucomponent/config/Linguistic-lingucomponent-grammarchecker.xcu index ce3d6033d0c2..6fa455d969b8 100644 --- a/lingucomponent/config/Linguistic-lingucomponent-grammarchecker.xcu +++ b/lingucomponent/config/Linguistic-lingucomponent-grammarchecker.xcu @@ -21,7 +21,7 @@ <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-CA en-GB en-NZ en-ZA en-US fr gl-ES de de-AT de-DE 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> + <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> commit 6d76656a2858a792a0ff59fda5708145c500eae7 Author: Szymon Kłos <szymon.k...@collabora.com> AuthorDate: Wed Feb 8 11:10:58 2023 +0100 Commit: Andras Timar <andras.ti...@collabora.com> CommitDate: Fri Feb 10 21:55:43 2023 +0000 lok: LanguageTool provides list of languages - it sends supported list to the LOK client - disables Spell Checker for locales supported by LanguageTool - duden protocol supports only german - initialize language tool config before usage to fetch correct list of supported languages Change-Id: Id9de8519303774163721def8661fa408da449348 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/146665 Reviewed-by: Henry Castro <hcas...@collabora.com> Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx index ec7b82ef086f..2d79b7e57d3a 100644 --- a/desktop/source/lib/init.cxx +++ b/desktop/source/lib/init.cxx @@ -104,6 +104,7 @@ #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> @@ -5538,12 +5539,28 @@ 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(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()) { @@ -5552,6 +5569,19 @@ static char* getLanguages(LibreOfficeKitDocument* pThis, const char* pCommand) aLocales = xSpell->getLocales(); } + // LanguageTool + SvxLanguageToolOptions& rLanguageOpts = SvxLanguageToolOptions::Get(); + if (rLanguageOpts.getEnabled()) + { + 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(); + } + + // Fallback + /* 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 */ @@ -5564,19 +5594,10 @@ static char* getLanguages(LibreOfficeKitDocument* pThis, const char* pCommand) boost::property_tree::ptree aTree; aTree.put("commandName", pCommand); boost::property_tree::ptree aValues; - 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)); - } + 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); aTree.add_child("commandValues", aValues); std::stringstream aStream; boost::property_tree::write_json(aStream, aTree); @@ -6999,6 +7020,8 @@ static void lo_status_indicator_callback(void *data, comphelper::LibreOfficeKit: } } +void setLanguageToolConfig(); + /// Used only by LibreOfficeKit when used by Online to pre-initialize static void preloadData() { @@ -7017,6 +7040,9 @@ 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()); @@ -7202,12 +7228,19 @@ void setLanguageToolConfig() if (xSpell.is()) { Sequence<OUString> aEmpty; - constexpr OUStringLiteral cSpell(SN_SPELLCHECKER); + 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++) { - xLangSrv->setConfiguredServices(cSpell, aLocales[itLocale], aEmpty); + // turn off spell checker if LanguageTool supports the locale already + if (xSuppLoc->hasLocale(aLocales[itLocale])) + xLangSrv->setConfiguredServices(cSpell, aLocales[itLocale], aEmpty); } } } @@ -7562,7 +7595,6 @@ static int lo_initialize(LibreOfficeKit* pThis, const char* pAppPath, const char #endif setCertificateDir(); - setLanguageToolConfig(); setDeeplConfig(); if (bNotebookbar) diff --git a/lingucomponent/source/spellcheck/languagetool/languagetoolimp.cxx b/lingucomponent/source/spellcheck/languagetool/languagetoolimp.cxx index 6cae9f78378a..c53f4bbd4fce 100644 --- a/lingucomponent/source/spellcheck/languagetool/languagetoolimp.cxx +++ b/lingucomponent/source/spellcheck/languagetool/languagetoolimp.cxx @@ -112,15 +112,25 @@ sal_Bool SAL_CALL LanguageToolGrammarChecker::hasLocale(const Locale& rLocale) Sequence<Locale> SAL_CALL LanguageToolGrammarChecker::getLocales() { - MutexGuard aGuard( GetLinguMutex() ); + MutexGuard aGuard(GetLinguMutex()); if (m_aSuppLocales.hasElements()) return m_aSuppLocales; SvtLinguConfig aLinguCfg; - uno::Sequence< OUString > aLocaleList; - aLinguCfg.GetLocaleListFor( "GrammarCheckers", - "org.openoffice.lingu.LanguageToolGrammarChecker", aLocaleList ); + uno::Sequence<OUString> aLocaleList; + + SvxLanguageToolOptions& rLanguageOpts = SvxLanguageToolOptions::Get(); + if (rLanguageOpts.getRestProtocol() == sDuden) + { + aLocaleList.realloc(3); + aLocaleList.getArray()[0] = "de-DE"; + aLocaleList.getArray()[1] = "en-US"; + aLocaleList.getArray()[2] = "en-GB"; + } + else + aLinguCfg.GetLocaleListFor("GrammarCheckers", + "org.openoffice.lingu.LanguageToolGrammarChecker", aLocaleList); auto nLength = aLocaleList.getLength(); m_aSuppLocales.realloc(nLength); @@ -235,8 +245,9 @@ ProofreadingResult SAL_CALL LanguageToolGrammarChecker::doProofreading( } else { - OString postData(OUStringToOString( - OUStringConcatenation("text=" + aText + "&language=" + langTag), RTL_TEXTENCODING_UTF8)); + OString postData( + OUStringToOString(OUStringConcatenation("text=" + aText + "&language=" + langTag), + RTL_TEXTENCODING_UTF8)); response_body = makeHttpRequest(checkerURL, HTTP_METHOD::HTTP_POST, postData, http_code); } @@ -273,7 +284,8 @@ void LanguageToolGrammarChecker::parseDudenResponse(ProofreadingResult& rResult, std::stringstream aStream(aJSONBody.data()); boost::property_tree::read_json(aStream, aRoot); - const boost::optional<boost::property_tree::ptree&> aPositions = aRoot.get_child_optional("check-positions"); + const boost::optional<boost::property_tree::ptree&> aPositions + = aRoot.get_child_optional("check-positions"); if (!aPositions || !(nSize = aPositions.get().size())) { return; @@ -286,7 +298,7 @@ void LanguageToolGrammarChecker::parseDudenResponse(ProofreadingResult& rResult, while (itPos != aPositions.get().end()) { const boost::property_tree::ptree& rTree = itPos->second; - const std::string sType= rTree.get<std::string>("type", ""); + const std::string sType = rTree.get<std::string>("type", ""); const int nOffset = rTree.get<int>("offset", 0); const int nLength = rTree.get<int>("length", 0); @@ -297,8 +309,8 @@ void LanguageToolGrammarChecker::parseDudenResponse(ProofreadingResult& rResult, //pChecks[nIndex1].aFullComment = ?? pChecks[nIndex1].aProperties = lcl_GetLineColorPropertyFromErrorId(sType); - const boost::optional<const boost::property_tree::ptree&> aProposals = - rTree.get_child_optional("proposals"); + const boost::optional<const boost::property_tree::ptree&> aProposals + = rTree.get_child_optional("proposals"); if (aProposals && (nProposalSize = aProposals.get().size())) { pChecks[nIndex1].aSuggestions.realloc(std::min(nProposalSize, MAX_SUGGESTIONS_SIZE)); @@ -308,8 +320,8 @@ void LanguageToolGrammarChecker::parseDudenResponse(ProofreadingResult& rResult, auto pSuggestions = pChecks[nIndex1].aSuggestions.getArray(); while (itProp != aProposals.get().end() && nIndex2 < MAX_SUGGESTIONS_SIZE) { - pSuggestions[nIndex2++] = - OStringToOUString(itProp->second.data(), RTL_TEXTENCODING_UTF8); + pSuggestions[nIndex2++] + = OStringToOUString(itProp->second.data(), RTL_TEXTENCODING_UTF8); itProp++; } } @@ -389,7 +401,8 @@ void LanguageToolGrammarChecker::parseProofreadingJSONResponse(ProofreadingResul rResult.aErrors = aErrors; } -std::string LanguageToolGrammarChecker::makeDudenHttpRequest(std::string_view aURL, HTTP_METHOD method, +std::string LanguageToolGrammarChecker::makeDudenHttpRequest(std::string_view aURL, + HTTP_METHOD method, const OString& aData, tools::Long& nCode) { @@ -401,8 +414,8 @@ std::string LanguageToolGrammarChecker::makeDudenHttpRequest(std::string_view aU std::string sResponseBody; struct curl_slist* pList = nullptr; SvxLanguageToolOptions& rLanguageOpts = SvxLanguageToolOptions::Get(); - OString sAccessToken = OString("access_token: ") + - OUStringToOString(rLanguageOpts.getApiKey(), RTL_TEXTENCODING_UTF8); + OString sAccessToken = OString("access_token: ") + + OUStringToOString(rLanguageOpts.getApiKey(), RTL_TEXTENCODING_UTF8); pList = curl_slist_append(pList, "Cache-Control: no-cache"); pList = curl_slist_append(pList, "Content-Type: application/json"); @@ -432,12 +445,12 @@ std::string LanguageToolGrammarChecker::makeDudenHttpRequest(std::string_view aU CURLcode cc = curl_easy_perform(curl.get()); if (cc != CURLE_OK) { - SAL_WARN("languagetool", "CURL request returned with error: " << static_cast<sal_Int32>(cc)); + SAL_WARN("languagetool", + "CURL request returned with error: " << static_cast<sal_Int32>(cc)); } curl_easy_getinfo(curl.get(), CURLINFO_RESPONSE_CODE, &nCode); return sResponseBody; - } std::string LanguageToolGrammarChecker::makeHttpRequest(std::string_view aURL, HTTP_METHOD method, @@ -492,7 +505,8 @@ std::string LanguageToolGrammarChecker::makeHttpRequest(std::string_view aURL, H CURLcode cc = curl_easy_perform(curl.get()); if (cc != CURLE_OK) { - SAL_WARN("languagetool", "CURL request returned with error: " << static_cast<sal_Int32>(cc)); + SAL_WARN("languagetool", + "CURL request returned with error: " << static_cast<sal_Int32>(cc)); } curl_easy_getinfo(curl.get(), CURLINFO_RESPONSE_CODE, &nStatusCode); return response_body;