sw/inc/strings.hrc | 1 + sw/source/ui/misc/translatelangselect.cxx | 11 ++++++----- sw/source/uibase/shells/textsh1.cxx | 14 ++++++++++---- sw/source/uibase/shells/translatehelper.cxx | 13 ++++++++++++- 4 files changed, 29 insertions(+), 10 deletions(-)
New commits: commit 2bfe6dcbda3e29adc7495bb74173683abce1d461 Author: Mike Kaganski <[email protected]> AuthorDate: Tue Dec 23 15:58:21 2025 +0500 Commit: Mike Kaganski <[email protected]> CommitDate: Sun Dec 28 12:09:38 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]> 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 497ecc8c6d86..78b90721acb9 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 329b88bd2abc2ee09a371a29c0bbb85fd7b6e1f7 Author: Mike Kaganski <[email protected]> AuthorDate: Tue Dec 23 15:56:32 2025 +0500 Commit: Mike Kaganski <[email protected]> CommitDate: Sun Dec 28 12:09:32 2025 +0100 tdf#152706: Show an error message on translation error I don't know if this may be called in a headless way; if it may, then a proper interaction handler should be passed to TranslateDocumentCancellable. Change-Id: I4a0f9170ebece54d6debcd36e495d33e97e57980 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/196254 Tested-by: Jenkins Reviewed-by: Mike Kaganski <[email protected]> diff --git a/sw/inc/strings.hrc b/sw/inc/strings.hrc index 7fb72a1d2840..0dc4bc9bd2df 100644 --- a/sw/inc/strings.hrc +++ b/sw/inc/strings.hrc @@ -301,6 +301,7 @@ #define STR_HIDE_NOTE_AUTHOR NC_("STR_HIDE_NOTE_AUTHOR", "H~ide All Comments by $1") #define STR_OUTLINE_NUMBERING NC_("STR_OUTLINE_NUMBERING", "Heading Numbering") #define STR_STATSTR_SWTRANSLATE NC_("STR_STATSTR_SWTRANSLATE", "Translating document...") +#define STR_SWTRANSLATE_ERROR NC_("STR_SWTRANSLATE_ERROR", "Error translating document.") /* To translators: $1 == will be replaced by STR_WORDCOUNT_WORDARG, and $2 by STR_WORDCOUNT_COLARG e.g. Selected: 1 word, 2 characters */ #define STR_WORDCOUNT NC_("STR_WORDCOUNT", "Selected: $1, $2") diff --git a/sw/source/uibase/shells/translatehelper.cxx b/sw/source/uibase/shells/translatehelper.cxx index ae2461481e36..bc2a1eaef785 100644 --- a/sw/source/uibase/shells/translatehelper.cxx +++ b/sw/source/uibase/shells/translatehelper.cxx @@ -196,7 +196,10 @@ void TranslateDocumentCancellable(SwWrtShell& rWrtSh, const TranslateAPIConfig& } else { - // TODO: show error? + std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog( + nullptr, VclMessageType::Error, VclButtonsType::Ok, + SwResId(STR_SWTRANSLATE_ERROR))); + xBox->run(); break; } commit 3cfc00a638dfaffc48019242bcbd66f98bfb9318 Author: Mike Kaganski <[email protected]> AuthorDate: Tue Dec 23 15:51:47 2025 +0500 Commit: Mike Kaganski <[email protected]> CommitDate: Sun Dec 28 12:09:26 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 diff --git a/sw/source/uibase/shells/translatehelper.cxx b/sw/source/uibase/shells/translatehelper.cxx index 10b2976f5b2e..ae2461481e36 100644 --- a/sw/source/uibase/shells/translatehelper.cxx +++ b/sw/source/uibase/shells/translatehelper.cxx @@ -190,7 +190,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);
