include/svtools/strings.hrc                                       |    3 
 lingucomponent/source/spellcheck/languagetool/languagetoolimp.cxx |   38 
++++++----
 sw/source/core/edit/edlingu.cxx                                   |    3 
 3 files changed, 31 insertions(+), 13 deletions(-)

New commits:
commit 6ba79643803085782a97a8ce4214061270d5eefe
Author:     Mike Kaganski <[email protected]>
AuthorDate: Wed Oct 16 17:12:12 2024 +0500
Commit:     Andras Timar <[email protected]>
CommitDate: Thu Oct 17 00:00:46 2024 +0200

    tdf#160127: Improve grammar check popups from Duden
    
    When there is a grammar check error that it has no suggestions for, Duden
    may return a JSON without suggestions, but still informing about the type
    of the error, like
    
      ...
      {
          "offset": 468,
          "length": 8,
          "errorcode": 21,
          "type": "orth",
          "proposals": []
      },
      ...
    
    Before the change, we underlined the error, but right-clicking it would
    only bring the normal Writer's context menu, as if there were no error.
    This was made in commit 7697ef9d8fbbed7afba10c00ff9f5362d0540cdd (Proof
    reading suggestions:, 2023-11-28); before that change, the context menu
    was shown, but since it had no suggestions, and no explanation text, it
    was considered better to just not show the grammar check results. But
    no menu for an underlined word is no better; so let's instead show the
    explanation, based on the type of the error reported by Duden - that is
    stored in SingleProofreadingError::aShortComment. Also set aFullComment,
    which is used in the grammar check dialog.
    
    Incidentally, it even improves popups with suggestions, because it now
    has the explanation as well, where previously only was an icon without
    any text.
    
    It may be further improved in a follow-up, because there is "errorcode"
    in the message, which we may use to add more details to the explanation.
    
    tdf#160127 should be fixed with this, too; but if there are cases when
    there are neither suggestions, nor explanation available, it will need
    further work.
    
    Change-Id: I62cde204e0142d6226c9c9486f1cdb5ffc20dca8
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/175017
    Reviewed-by: Mike Kaganski <[email protected]>
    Tested-by: Jenkins
    (cherry picked from commit 3233383b2631788e7cfb0dd0b92d879322561616)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/174959
    Tested-by: Jenkins CollaboraOffice <[email protected]>
    Reviewed-by: Andras Timar <[email protected]>

diff --git a/include/svtools/strings.hrc b/include/svtools/strings.hrc
index ab18119242b3..faa3e7cd4b2a 100644
--- a/include/svtools/strings.hrc
+++ b/include/svtools/strings.hrc
@@ -350,5 +350,8 @@
 #define STR_DESCRIPTION_MYTHES                  NC_("STR_DESCRIPTION_MYTHES", 
"MyThes Thesaurus")
 #define STR_DESCRIPTION_IGNOREALLLIST           
NC_("STR_DESCRIPTION_IGNOREALLLIST", "List of Ignored Words")
 #define STR_DESCRIPTION_LANGUAGETOOL            
NC_("STR_DESCRIPTION_LANGUAGETOOL", "LanguageTool Remote Grammar Checker")
+#define STR_DESCRIPTION_SPELLING_ERROR          
NC_("STR_DESCRIPTION_SPELLING_ERROR", "Spelling error")
+#define STR_DESCRIPTION_GRAMMAR_ERROR           
NC_("STR_DESCRIPTION_GRAMMAR_ERROR_LONG", "Grammar error")
+#define STR_DESCRIPTION_STYLE_ERROR             
NC_("STR_DESCRIPTION_STYLE_ERROR", "Bad style")
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/lingucomponent/source/spellcheck/languagetool/languagetoolimp.cxx 
b/lingucomponent/source/spellcheck/languagetool/languagetoolimp.cxx
index e0a9fd8a718d..00dccc9b2db2 100644
--- a/lingucomponent/source/spellcheck/languagetool/languagetoolimp.cxx
+++ b/lingucomponent/source/spellcheck/languagetool/languagetoolimp.cxx
@@ -235,28 +235,42 @@ uno::Sequence<SingleProofreadingError> 
parseJson(std::string&& json, std::string
     return {};
 }
 
+OUString DudenTypeToComment(const std::string& type, const Locale& rLocale)
+{
+    // TODO: consider also "errorcode", some values of which are explained
+    // at https://main.dks.epc.de/doc/Relnotes.html
+    TranslateId id = STR_DESCRIPTION_SPELLING_ERROR; // matches both "orth" 
and "term"
+    if (type == "gram")
+        id = STR_DESCRIPTION_GRAMMAR_ERROR;
+    else if (type == "style")
+        id = STR_DESCRIPTION_STYLE_ERROR;
+    std::locale loc(Translate::Create("svt", LanguageTag(rLocale)));
+    return Translate::get(id, loc);
+}
+
 void parseDudenResponse(ProofreadingResult& rResult, std::string&& aJSONBody)
 {
     rResult.aErrors = parseJson(
         std::move(aJSONBody), "check-positions",
-        [](const boost::property_tree::ptree& rPos, SingleProofreadingError& 
rError) {
+        [& locale = rResult.aLocale](const boost::property_tree::ptree& rPos,
+                                     SingleProofreadingError& rError) {
             rError.nErrorStart = rPos.get<int>("offset", 0);
             rError.nErrorLength = rPos.get<int>("length", 0);
             rError.nErrorType = text::TextMarkupType::PROOFREADING;
-            //rError.aShortComment = ??
-            //rError.aFullComment = ??
             const std::string sType = rPos.get<std::string>("type", {});
+            rError.aShortComment = DudenTypeToComment(sType, locale);
+            rError.aFullComment = rError.aShortComment;
             rError.aProperties = { lcl_GetLineColorPropertyFromErrorId(sType) 
};
 
-            const auto proposals = rPos.get_child_optional("proposals");
-            if (!proposals)
-                return;
-            rError.aSuggestions.realloc(std::min(proposals->size(), 
MAX_SUGGESTIONS_SIZE));
-            auto itProp = proposals->begin();
-            for (auto& rSuggestion : asNonConstRange(rError.aSuggestions))
+            if (const auto proposals = rPos.get_child_optional("proposals"))
             {
-                rSuggestion = OStringToOUString(itProp->second.data(), 
RTL_TEXTENCODING_UTF8);
-                itProp++;
+                rError.aSuggestions.realloc(std::min(proposals->size(), 
MAX_SUGGESTIONS_SIZE));
+                auto itProp = proposals->begin();
+                for (auto& rSuggestion : asNonConstRange(rError.aSuggestions))
+                {
+                    rSuggestion = OStringToOUString(itProp->second.data(), 
RTL_TEXTENCODING_UTF8);
+                    itProp++;
+                }
             }
         });
 }
diff --git a/sw/source/core/edit/edlingu.cxx b/sw/source/core/edit/edlingu.cxx
index 5731d2b2be49..17c93ed4ece3 100644
--- a/sw/source/core/edit/edlingu.cxx
+++ b/sw/source/core/edit/edlingu.cxx
@@ -1032,7 +1032,7 @@ bool SwEditShell::GetGrammarCorrection(
                     [rErrorPosInText, nLen](const 
linguistic2::SingleProofreadingError &rError) {
                         return rError.nErrorStart <= rErrorPosInText
                             && rErrorPosInText + nLen <= rError.nErrorStart + 
rError.nErrorLength
-                            && rError.aSuggestions.size() > 0; });
+                            && (rError.aSuggestions.hasElements() || 
!rError.aShortComment.isEmpty()); });
                 if (pError != std::cend(rResult.aErrors))
                 {
                     rSuggestions = pError->aSuggestions;
commit 1f1822442cf0ccdfa0cc01a2dd80cb67f2fbd94d
Author:     Mike Kaganski <[email protected]>
AuthorDate: Wed Oct 16 17:56:28 2024 +0500
Commit:     Andras Timar <[email protected]>
CommitDate: Thu Oct 17 00:00:46 2024 +0200

    Revert "tdf#160127: revert 7697ef9d8fbbed7afba10c00ff9f5362d0540cdd"
    
    This reverts commit d9890cc6b9bb5e94fe42ba0216dd5b7e92d11b13.
    The restored change will be amended in a follow-up fix to tdf#160127.
    
    Change-Id: I10eeeb5ccf02969e76e72a46f0705a5ff8909da7
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/175022
    Tested-by: Jenkins CollaboraOffice <[email protected]>
    Reviewed-by: Andras Timar <[email protected]>

diff --git a/sw/source/core/edit/edlingu.cxx b/sw/source/core/edit/edlingu.cxx
index e1f6d631139d..5731d2b2be49 100644
--- a/sw/source/core/edit/edlingu.cxx
+++ b/sw/source/core/edit/edlingu.cxx
@@ -1031,7 +1031,8 @@ bool SwEditShell::GetGrammarCorrection(
                 auto pError = std::find_if(std::cbegin(rResult.aErrors), 
std::cend(rResult.aErrors),
                     [rErrorPosInText, nLen](const 
linguistic2::SingleProofreadingError &rError) {
                         return rError.nErrorStart <= rErrorPosInText
-                            && rErrorPosInText + nLen <= rError.nErrorStart + 
rError.nErrorLength; });
+                            && rErrorPosInText + nLen <= rError.nErrorStart + 
rError.nErrorLength
+                            && rError.aSuggestions.size() > 0; });
                 if (pError != std::cend(rResult.aErrors))
                 {
                     rSuggestions = pError->aSuggestions;
commit a5eb61d98754c163f88e3fbb32b39deb8015de43
Author:     Mike Kaganski <[email protected]>
AuthorDate: Wed Oct 16 17:50:38 2024 +0500
Commit:     Andras Timar <[email protected]>
CommitDate: Thu Oct 17 00:00:46 2024 +0200

    Revert "Return earlier if there are no proposals from Duden checker."
    
    This reverts commit bf980c7b7c8197724cbebd1ed16dfe4401b97392.
    The reason is: the change caused empty entries in the ProofreadingResult's
    aErrors; those didn't even have nErrorType set, and it was 0. Later, in
    SwXTextMarkup::commitMultiTextMarkup, the value of the type was checked,
    and when it was neither SENTENCE nor PROOFREADING, the application of the
    result to the paragraph was aborted. Thus, any paragraph with a spelling
    error without a suggestion wasn't marked as a whole.
    
    A better fix is in works.
    
    Change-Id: Ic5a2c75bb3896f34e60589d5fcbc8e9048dcda9b
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/175021
    Tested-by: Jenkins CollaboraOffice <[email protected]>
    Reviewed-by: Andras Timar <[email protected]>

diff --git a/lingucomponent/source/spellcheck/languagetool/languagetoolimp.cxx 
b/lingucomponent/source/spellcheck/languagetool/languagetoolimp.cxx
index c1f26d5c9992..e0a9fd8a718d 100644
--- a/lingucomponent/source/spellcheck/languagetool/languagetoolimp.cxx
+++ b/lingucomponent/source/spellcheck/languagetool/languagetoolimp.cxx
@@ -240,10 +240,6 @@ void parseDudenResponse(ProofreadingResult& rResult, 
std::string&& aJSONBody)
     rResult.aErrors = parseJson(
         std::move(aJSONBody), "check-positions",
         [](const boost::property_tree::ptree& rPos, SingleProofreadingError& 
rError) {
-            const auto proposals = rPos.get_child_optional("proposals");
-            if (!proposals || proposals->empty())
-                return;
-
             rError.nErrorStart = rPos.get<int>("offset", 0);
             rError.nErrorLength = rPos.get<int>("length", 0);
             rError.nErrorType = text::TextMarkupType::PROOFREADING;
@@ -251,6 +247,10 @@ void parseDudenResponse(ProofreadingResult& rResult, 
std::string&& aJSONBody)
             //rError.aFullComment = ??
             const std::string sType = rPos.get<std::string>("type", {});
             rError.aProperties = { lcl_GetLineColorPropertyFromErrorId(sType) 
};
+
+            const auto proposals = rPos.get_child_optional("proposals");
+            if (!proposals)
+                return;
             rError.aSuggestions.realloc(std::min(proposals->size(), 
MAX_SUGGESTIONS_SIZE));
             auto itProp = proposals->begin();
             for (auto& rSuggestion : asNonConstRange(rError.aSuggestions))

Reply via email to