sw/source/ui/misc/translatelangselect.cxx   |   11 ++++++-----
 sw/source/uibase/shells/textsh1.cxx         |   14 ++++++++++----
 sw/source/uibase/shells/translatehelper.cxx |   10 +++++++++-
 3 files changed, 25 insertions(+), 10 deletions(-)

New commits:
commit 334c520742ed38ba5c57df09e2f5bcfc94380cf9
Author:     Mike Kaganski <[email protected]>
AuthorDate: Tue Dec 23 15:58:21 2025 +0500
Commit:     Xisco Fauli <[email protected]>
CommitDate: Mon Dec 29 15:44:41 2025 +0100

    tdf#152706: Trim the stored API URL before appending query
    
    There already was a call to trim, obviously aimed to handle accidental
    spaces entered by user. But the call only happened after the original
    URL string was concatenated with a query string; so the trailing space
    would not be trimmed.
    
    Fix it here.
    
    Change-Id: Ice6bd7bed2742b44fef52fcd6edd8f6739a2ca46
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/196255
    Tested-by: Jenkins
    Reviewed-by: Mike Kaganski <[email protected]>
    Signed-off-by: Xisco Fauli <[email protected]>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/196282

diff --git a/sw/source/ui/misc/translatelangselect.cxx 
b/sw/source/ui/misc/translatelangselect.cxx
index 061d0662e1dd..15a2a406ad3f 100644
--- a/sw/source/ui/misc/translatelangselect.cxx
+++ b/sw/source/ui/misc/translatelangselect.cxx
@@ -27,6 +27,7 @@
 #include <translatelangselect.hxx>
 #include <pagedesc.hxx>
 #include <poolfmt.hxx>
+#include <o3tl/string_view.hxx>
 #include <sal/log.hxx>
 #include <ndtxt.hxx>
 #include <shellio.hxx>
@@ -139,7 +140,9 @@ IMPL_LINK_NOARG(SwTranslateLangSelectDlg, 
LangSelectTranslateHdl, weld::Button&,
         = officecfg::Office::Linguistic::Translation::Deepl::ApiURL::get();
     std::optional<OUString> oDeeplKey
         = officecfg::Office::Linguistic::Translation::Deepl::AuthKey::get();
-    if (!oDeeplAPIUrl || oDeeplAPIUrl->isEmpty() || !oDeeplKey || 
oDeeplKey->isEmpty())
+    auto sApiUrlTrimmed = oDeeplAPIUrl ? o3tl::trim(*oDeeplAPIUrl) : 
std::u16string_view();
+    auto sKeyTrimmed = oDeeplKey ? o3tl::trim(*oDeeplKey) : 
std::u16string_view();
+    if (sApiUrlTrimmed.empty() || sKeyTrimmed.empty())
     {
         SAL_WARN("sw.ui", "SwTranslateLangSelectDlg: API options are not set");
         m_xDialog->response(RET_CANCEL);
@@ -147,10 +150,8 @@ IMPL_LINK_NOARG(SwTranslateLangSelectDlg, 
LangSelectTranslateHdl, weld::Button&,
     }
 
     const OString aAPIUrl
-        = OUStringToOString(rtl::Concat2View(*oDeeplAPIUrl + 
"?tag_handling=html"),
-                            RTL_TEXTENCODING_UTF8)
-              .trim();
-    const OString aAuthKey = OUStringToOString(*oDeeplKey, 
RTL_TEXTENCODING_UTF8).trim();
+        = OUStringToOString(sApiUrlTrimmed, RTL_TEXTENCODING_UTF8) + 
"?tag_handling=html";
+    const OString aAuthKey = OUStringToOString(sKeyTrimmed, 
RTL_TEXTENCODING_UTF8);
     const auto aTargetLang
         = 
getLanguageVec().at(SwTranslateLangSelectDlg::selectedLangIdx).getLanguage();
 
diff --git a/sw/source/uibase/shells/textsh1.cxx 
b/sw/source/uibase/shells/textsh1.cxx
index 08178e04ab73..cd26bb553ead 100644
--- a/sw/source/uibase/shells/textsh1.cxx
+++ b/sw/source/uibase/shells/textsh1.cxx
@@ -2305,13 +2305,16 @@ void SwTextShell::Execute(SfxRequest &rReq)
         {
             std::optional<OUString> oDeeplAPIUrl = 
officecfg::Office::Linguistic::Translation::Deepl::ApiURL::get();
             std::optional<OUString> oDeeplKey = 
officecfg::Office::Linguistic::Translation::Deepl::AuthKey::get();
-            if (!oDeeplAPIUrl || oDeeplAPIUrl->isEmpty() || !oDeeplKey || 
oDeeplKey->isEmpty())
+            auto sApiUrlTrimmed = oDeeplAPIUrl ? o3tl::trim(*oDeeplAPIUrl) : 
std::u16string_view();
+            auto sKeyTrimmed = oDeeplKey ? o3tl::trim(*oDeeplKey) : 
std::u16string_view();
+            if (sApiUrlTrimmed.empty() || sKeyTrimmed.empty())
             {
                 SAL_WARN("sw.ui", "SID_FM_TRANSLATE: API options are not set");
                 break;
             }
-            const OString aAPIUrl = 
OUStringToOString(rtl::Concat2View(*oDeeplAPIUrl + "?tag_handling=html"), 
RTL_TEXTENCODING_UTF8).trim();
-            const OString aAuthKey = OUStringToOString(*oDeeplKey, 
RTL_TEXTENCODING_UTF8).trim();
+            const OString aAPIUrl
+                = OUStringToOString(sApiUrlTrimmed, RTL_TEXTENCODING_UTF8) + 
"?tag_handling=html";
+            const OString aAuthKey = OUStringToOString(sKeyTrimmed, 
RTL_TEXTENCODING_UTF8);
             OString aTargetLang = OUStringToOString(static_cast<const 
SfxStringItem*>(pTargetLangStringItem)->GetValue(), RTL_TEXTENCODING_UTF8);
             SwTranslateHelper::TranslateAPIConfig aConfig({aAPIUrl, aAuthKey, 
aTargetLang});
             SwTranslateHelper::TranslateDocument(rWrtSh, aConfig);
@@ -3966,7 +3969,10 @@ void SwTextShell::GetState( SfxItemSet &rSet )
                     }
                     std::optional<OUString> oDeeplAPIUrl = 
officecfg::Office::Linguistic::Translation::Deepl::ApiURL::get();
                     std::optional<OUString> oDeeplKey = 
officecfg::Office::Linguistic::Translation::Deepl::AuthKey::get();
-                    if (!oDeeplAPIUrl || oDeeplAPIUrl->isEmpty() || !oDeeplKey 
|| oDeeplKey->isEmpty())
+                    auto sApiUrlTrimmed
+                        = oDeeplAPIUrl ? o3tl::trim(*oDeeplAPIUrl) : 
std::u16string_view();
+                    auto sKeyTrimmed = oDeeplKey ? o3tl::trim(*oDeeplKey) : 
std::u16string_view();
+                    if (sApiUrlTrimmed.empty() || sKeyTrimmed.empty())
                     {
                         rSet.DisableItem(nWhich);
                     }
commit 57feee7a7e31d0ca2566452a1183ab9d45deaad5
Author:     Mike Kaganski <[email protected]>
AuthorDate: Tue Dec 23 15:51:47 2025 +0500
Commit:     Xisco Fauli <[email protected]>
CommitDate: Mon Dec 29 15:44:33 2025 +0100

    tdf#152706: don't overwrite source on translation failure
    
    linguistic::Translate returns an empty string, when any error occurs
    (it may be a malformed URL, or wrong key, or a server error). Then
    PasteHTMLToPaM would replace the selection with nothing, and after
    that, show a "Requested clipboard format is not available" message.
    
    This change checks the returned string, to avoid the replacement. It
    doesn't show a message itself (TODO in a follow-up).
    
    Change-Id: Ia92b0d0a609386bf3988fc9ef7e01da84311ab38
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/196253
    Reviewed-by: Mike Kaganski <[email protected]>
    Tested-by: Jenkins
    Signed-off-by: Xisco Fauli <[email protected]>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/196280

diff --git a/sw/source/uibase/shells/translatehelper.cxx 
b/sw/source/uibase/shells/translatehelper.cxx
index fefa2fac5d14..190357c29ee6 100644
--- a/sw/source/uibase/shells/translatehelper.cxx
+++ b/sw/source/uibase/shells/translatehelper.cxx
@@ -191,7 +191,15 @@ void TranslateDocumentCancellable(SwWrtShell& rWrtSh, 
const TranslateAPIConfig&
             const auto aOut = SwTranslateHelper::ExportPaMToHTML(cursor.get());
             const auto aTranslatedOut = linguistic::Translate(
                 rConfig.m_xTargetLanguage, rConfig.m_xAPIUrl, 
rConfig.m_xAuthKey, aOut);
-            SwTranslateHelper::PasteHTMLToPaM(rWrtSh, cursor.get(), 
aTranslatedOut);
+            if (!aTranslatedOut.isEmpty())
+            {
+                SwTranslateHelper::PasteHTMLToPaM(rWrtSh, cursor.get(), 
aTranslatedOut);
+            }
+            else
+            {
+                // TODO: show error?
+                break;
+            }
 
             if (xStatusIndicator.is() && nCount)
                 xStatusIndicator->setValue((100 * ++nProgress) / nCount);

Reply via email to