Rebased ref, commits from common ancestor:
commit cc0a4ed042b1ce484250dbb101d0a5f48f640153
Author: Mert Tumer <[email protected]>
AuthorDate: Tue Jul 5 12:03:27 2022 +0300
Commit: Mert Tumer <[email protected]>
CommitDate: Wed Jul 13 22:58:43 2022 +0300
wip translate
Signed-off-by: Mert Tumer <[email protected]>
diff --git a/cui/Library_cui.mk b/cui/Library_cui.mk
index d455a64ab266..c4c0a52b2ef4 100644
--- a/cui/Library_cui.mk
+++ b/cui/Library_cui.mk
@@ -181,6 +181,7 @@ $(eval $(call gb_Library_add_exception_objects,cui,\
cui/source/options/optgenrl \
cui/source/options/opthtml \
cui/source/options/optlanguagetool \
+ cui/source/options/optdeepl \
cui/source/options/optinet2 \
cui/source/options/optjava \
cui/source/options/optjsearch \
diff --git a/cui/UIConfig_cui.mk b/cui/UIConfig_cui.mk
index 806779daaa9d..0ed879e2b228 100644
--- a/cui/UIConfig_cui.mk
+++ b/cui/UIConfig_cui.mk
@@ -139,6 +139,7 @@ $(eval $(call gb_UIConfig_add_uifiles,cui,\
cui/uiconfig/ui/optgeneralpage \
cui/uiconfig/ui/opthtmlpage \
cui/uiconfig/ui/langtoolconfigpage \
+ cui/uiconfig/ui/deepltabpage \
cui/uiconfig/ui/optionsdialog \
cui/uiconfig/ui/optjsearchpage \
cui/uiconfig/ui/optlanguagespage \
diff --git a/cui/inc/treeopt.hrc b/cui/inc/treeopt.hrc
index 952b79ea92d4..6d5bc4004a53 100644
--- a/cui/inc/treeopt.hrc
+++ b/cui/inc/treeopt.hrc
@@ -55,7 +55,8 @@ const std::pair<TranslateId, sal_uInt16>
SID_LANGUAGE_OPTIONS_RES[] =
{ NC_("SID_LANGUAGE_OPTIONS_RES", "Searching in Japanese"),
RID_SVXPAGE_JSEARCH_OPTIONS },
{ NC_("SID_LANGUAGE_OPTIONS_RES", "Asian Layout"),
RID_SVXPAGE_ASIAN_LAYOUT },
{ NC_("SID_LANGUAGE_OPTIONS_RES", "Complex Text Layout"),
RID_SVXPAGE_OPTIONS_CTL },
- { NC_("SID_LANGUAGE_OPTIONS_RES", "LanguageTool Server Settings"),
RID_SVXPAGE_LANGTOOL_OPTIONS }
+ { NC_("SID_LANGUAGE_OPTIONS_RES", "LanguageTool Server Settings"),
RID_SVXPAGE_LANGTOOL_OPTIONS },
+ { NC_("SID_LANGUAGE_OPTIONS_RES", "DeepL Server Settings"),
RID_SVXPAGE_DEEPL_OPTIONS }
};
const std::pair<TranslateId, sal_uInt16> SID_INET_DLG_RES[] =
diff --git a/cui/source/options/optdeepl.cxx b/cui/source/options/optdeepl.cxx
new file mode 100644
index 000000000000..5b3538530cce
--- /dev/null
+++ b/cui/source/options/optdeepl.cxx
@@ -0,0 +1,48 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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 .
+ */
+
+#include "optdeepl.hxx"
+#include <svtools/languagetoolcfg.hxx>
+#include <sal/log.hxx>
+
+OptDeeplTabPage::OptDeeplTabPage(weld::Container* pPage,
+ weld::DialogController*
pController,
+ const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/deepltabpage.ui", "OptDeeplPage",
&rSet)
+{
+
+}
+
+OptDeeplTabPage::~OptDeeplTabPage() {}
+
+void OptDeeplTabPage::Reset(const SfxItemSet*)
+{
+}
+
+bool OptDeeplTabPage::FillItemSet(SfxItemSet*)
+{
+ return false;
+}
+
+std::unique_ptr<SfxTabPage> OptDeeplTabPage::Create(weld::Container* pPage,
+
weld::DialogController* pController,
+ const SfxItemSet*
rAttrSet)
+{
+ return std::make_unique<OptDeeplTabPage>(pPage, pController, *rAttrSet);
+}
diff --git a/cui/source/options/optdeepl.hxx b/cui/source/options/optdeepl.hxx
new file mode 100644
index 000000000000..15d80b007647
--- /dev/null
+++ b/cui/source/options/optdeepl.hxx
@@ -0,0 +1,33 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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 .
+ */
+#pragma once
+#include <sfx2/tabdlg.hxx>
+
+class OptDeeplTabPage : public SfxTabPage
+{
+public:
+ OptDeeplTabPage(weld::Container* pPage, weld::DialogController*
pController,
+ const SfxItemSet& rSet);
+ virtual ~OptDeeplTabPage() override;
+ static std::unique_ptr<SfxTabPage>
+ Create(weld::Container* pPage, weld::DialogController* pController, const
SfxItemSet* rAttrSet);
+
+ virtual bool FillItemSet(SfxItemSet* rSet) override;
+ virtual void Reset(const SfxItemSet* rSet) override;
+};
\ No newline at end of file
diff --git a/cui/source/options/treeopt.cxx b/cui/source/options/treeopt.cxx
index e3029ca45eaf..1ab88a7e5381 100644
--- a/cui/source/options/treeopt.cxx
+++ b/cui/source/options/treeopt.cxx
@@ -64,6 +64,7 @@
#include <treeopt.hxx>
#include "optbasic.hxx"
#include "optlanguagetool.hxx"
+#include "optdeepl.hxx"
#include <com/sun/star/awt/XContainerWindowEventHandler.hpp>
#include <com/sun/star/awt/ContainerWindowProvider.hpp>
@@ -299,6 +300,7 @@ static std::unique_ptr<SfxTabPage>
CreateGeneralTabPage(sal_uInt16 nId, weld::Co
case RID_SVXPAGE_ACCESSIBILITYCONFIG: fnCreate =
&SvxAccessibilityOptionsTabPage::Create; break;
case RID_SVXPAGE_OPTIONS_CTL: fnCreate =
&SvxCTLOptionsPage::Create ; break;
case RID_SVXPAGE_LANGTOOL_OPTIONS: fnCreate =
&OptLanguageToolTabPage::Create ; break;
+ case RID_SVXPAGE_DEEPL_OPTIONS: fnCreate =
&OptDeeplTabPage::Create ; break;
case RID_SVXPAGE_OPTIONS_JAVA: fnCreate =
&SvxJavaOptionsPage::Create ; break;
#if HAVE_FEATURE_OPENCL
case RID_SVXPAGE_OPENCL: fnCreate =
&SvxOpenCLTabPage::Create ; break;
diff --git a/cui/uiconfig/ui/deepltabpage.ui b/cui/uiconfig/ui/deepltabpage.ui
new file mode 100644
index 000000000000..5479a498354f
--- /dev/null
+++ b/cui/uiconfig/ui/deepltabpage.ui
@@ -0,0 +1,122 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.22.2 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkBox" id="OptDeeplPage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="column_homogeneous">True</property>
+ <child>
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="xpad">5</property>
+ <property name="ypad">5</property>
+ <property name="label" translatable="yes"
context="deepltabpage|label1">DeepL API Options</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">grid1</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLinkButton" id="privacy">
+ <property name="label" translatable="yes"
context="deepltabpage|privacy">Please read the privacy policy</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="halign">start</property>
+ <property name="relief">none</property>
+ <property name="uri">https://www.deepl.com/privacy/</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkGrid" id="grid2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin_left">5</property>
+ <property name="margin_right">5</property>
+ <property name="margin_top">5</property>
+ <property name="margin_bottom">5</property>
+ <property name="row_spacing">5</property>
+ <property name="column_spacing">5</property>
+ <child>
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes"
context="deepltabpage|privacy">API URL:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">apiurl</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes"
context="deepltabpage|label3">Auth Key:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">authkey</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="apiurl">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="authkey">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+</interface>
diff --git a/include/sfx2/pageids.hxx b/include/sfx2/pageids.hxx
index 9371848b784a..1464ec40c55a 100644
--- a/include/sfx2/pageids.hxx
+++ b/include/sfx2/pageids.hxx
@@ -57,6 +57,7 @@
#define RID_SVXPAGE_COLORCONFIG (RID_SVX_START + 249)
#define RID_SVXPAGE_BASICIDE_OPTIONS (RID_SVX_START + 209)
#define RID_SVXPAGE_LANGTOOL_OPTIONS (RID_SVX_START + 210)
+#define RID_SVXPAGE_DEEPL_OPTIONS (RID_SVX_START + 211)
// Resource-Id's ------------------------------------------------------------
diff --git a/include/sfx2/sfxsids.hrc b/include/sfx2/sfxsids.hrc
index 39a3ec5bf9d6..1937368ba2b9 100644
--- a/include/sfx2/sfxsids.hrc
+++ b/include/sfx2/sfxsids.hrc
@@ -208,6 +208,7 @@ class SvxSearchItem;
#define SID_VIEW_DATA_SOURCE_BROWSER (SID_SFX_START + 1660)
#define SID_UNPACK (SID_SFX_START + 1662)
// (SID_SFX_START + 1663) used further down
+#define SID_ATTR_TARGETLANG_STR (SID_SFX_START + 1664)
// FREE
#define SID_OUTPUTSTREAM (SID_SFX_START + 1666)
#define SID_IMAGE_ORIENTATION (SID_SFX_START + 1667)
diff --git a/include/svx/svxids.hrc b/include/svx/svxids.hrc
index 573f036128c8..f8e162a973a6 100644
--- a/include/svx/svxids.hrc
+++ b/include/svx/svxids.hrc
@@ -570,7 +570,7 @@ class SdrAngleItem;
#define SID_FM_FILECONTROL ( SID_SVX_START + 605 )
//( SID_SVX_START + 606 ) is used by SID_DRAWTBX_REDACTED_EXPORT
#define SID_FM_NAVIGATIONBAR ( SID_SVX_START + 607 )
-//FREE
+#define SID_FM_TRANSLATE ( SID_SVX_START + 608 )
//FREE
#define SID_FM_DELETEROWS ( SID_SVX_START + 610 )
//FREE
diff --git a/include/vcl/unohelp3.hxx b/include/vcl/unohelp3.hxx
new file mode 100644
index 000000000000..2d3bfb4e5f28
--- /dev/null
+++ b/include/vcl/unohelp3.hxx
@@ -0,0 +1,53 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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 .
+ */
+
+#pragma once
+
+#include <com/sun/star/datatransfer/XTransferable.hpp>
+#include <cppuhelper/weak.hxx>
+#include <rtl/ustring.hxx>
+#include <osl/mutex.hxx>
+#include <vcl/dllapi.h>
+#include <vcl/IDialogRenderable.hxx>
+
+namespace vcl::unohelper {
+
+ class VCL_DLLPUBLIC HtmlTransferable final :
+ public css::datatransfer::XTransferable,
+ public ::cppu::OWeakObject
+ {
+ private:
+ OString data;
+
+ public:
+ HtmlTransferable( OString sData );
+ virtual ~HtmlTransferable() override;
+
+ // css::uno::XInterface
+ css::uno::Any SAL_CALL queryInterface( const css::uno::Type & rType )
override;
+ void SAL_CALL acquire() noexcept override {
OWeakObject::acquire(); }
+ void SAL_CALL release() noexcept override {
OWeakObject::release(); }
+
+ // css::datatransfer::XTransferable
+ css::uno::Any SAL_CALL getTransferData( const
css::datatransfer::DataFlavor& aFlavor ) override;
+ css::uno::Sequence< css::datatransfer::DataFlavor > SAL_CALL
getTransferDataFlavors( ) override;
+ sal_Bool SAL_CALL isDataFlavorSupported( const
css::datatransfer::DataFlavor& aFlavor ) override;
+ };
+
+} // namespace vcl::unohelper
diff --git
a/officecfg/registry/data/org/openoffice/Office/UI/WriterCommands.xcu
b/officecfg/registry/data/org/openoffice/Office/UI/WriterCommands.xcu
index 37996759a90d..2f82b9f1711f 100644
--- a/officecfg/registry/data/org/openoffice/Office/UI/WriterCommands.xcu
+++ b/officecfg/registry/data/org/openoffice/Office/UI/WriterCommands.xcu
@@ -1333,6 +1333,14 @@
<value>1</value>
</prop>
</node>
+ <node oor:name=".uno:Translate" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="en-US">Translate Page...</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
<node oor:name=".uno:FormatColumns" oor:op="replace">
<prop oor:name="Label" oor:type="xs:string">
<value xml:lang="en-US">Co~lumns...</value>
diff --git a/svx/sdi/svx.sdi b/svx/sdi/svx.sdi
index 9ab00de7e881..ac886aaa0cd4 100644
--- a/svx/sdi/svx.sdi
+++ b/svx/sdi/svx.sdi
@@ -1596,6 +1596,23 @@ SfxBoolItem NavigationBar SID_FM_NAVIGATIONBAR
GroupId = SfxGroupId::Controls;
]
+SfxBoolItem Translate SID_FM_TRANSLATE
+(SfxStringItem TargetLang SID_ATTR_TARGETLANG_STR)
+[
+ AutoUpdate = FALSE,
+ FastCall = TRUE,
+ ReadOnlyDoc = FALSE,
+ Toggle = FALSE,
+ Container = FALSE,
+ RecordAbsolute = FALSE,
+ RecordPerSet;
+
+ AccelConfig = FALSE,
+ MenuConfig = FALSE,
+ ToolBoxConfig = FALSE,
+ GroupId = SfxGroupId::Format;
+]
+
SfxBoolItem Combobox SID_INSERT_COMBOBOX
diff --git a/sw/Library_sw.mk b/sw/Library_sw.mk
index a49d53d0509f..5408e28b867a 100644
--- a/sw/Library_sw.mk
+++ b/sw/Library_sw.mk
@@ -91,6 +91,7 @@ $(eval $(call gb_Library_use_externals,sw,\
icuuc \
icu_headers \
libxml2 \
+ curl \
))
$(eval $(call gb_Library_add_exception_objects,sw,\
diff --git a/sw/Library_swui.mk b/sw/Library_swui.mk
index 4c1d9614f56c..f4cd9cbf5432 100644
--- a/sw/Library_swui.mk
+++ b/sw/Library_swui.mk
@@ -150,6 +150,7 @@ $(eval $(call gb_Library_add_exception_objects,swui,\
sw/source/ui/misc/pgfnote \
sw/source/ui/misc/pggrid \
sw/source/ui/misc/srtdlg \
+ sw/source/ui/misc/translatelangselect \
sw/source/ui/misc/swmodalredlineacceptdlg \
sw/source/ui/misc/titlepage \
sw/source/ui/table/colwd \
diff --git a/sw/UIConfig_swriter.mk b/sw/UIConfig_swriter.mk
index 73abd66dee9b..7d2fc662ae22 100644
--- a/sw/UIConfig_swriter.mk
+++ b/sw/UIConfig_swriter.mk
@@ -178,6 +178,7 @@ $(eval $(call gb_UIConfig_add_uifiles,modules/swriter,\
sw/uiconfig/swriter/ui/insertautotextdialog \
sw/uiconfig/swriter/ui/insertbookmark \
sw/uiconfig/swriter/ui/insertbreak \
+ sw/uiconfig/swriter/ui/translationdialog \
sw/uiconfig/swriter/ui/insertcaption \
sw/uiconfig/swriter/ui/insertdbcolumnsdialog \
sw/uiconfig/swriter/ui/insertfootnote \
diff --git a/sw/inc/swabstdlg.hxx b/sw/inc/swabstdlg.hxx
index 0963de35da21..19d12a736e66 100644
--- a/sw/inc/swabstdlg.hxx
+++ b/sw/inc/swabstdlg.hxx
@@ -375,6 +375,18 @@ public:
virtual sal_uInt16 GetRestartPage() const = 0;
};
+class SwLanguageListItem;
+
+class AbstractSwTranslateLangSelectDlg
+{
+protected:
+ virtual ~AbstractSwTranslateLangSelectDlg() = default;
+public:
+ virtual std::shared_ptr<weld::DialogController> getDialogController() = 0;
+ virtual std::optional<SwLanguageListItem> GetSelectedLanguage() = 0;
+};
+
+
class SwAbstractDialogFactory
{
public:
@@ -398,6 +410,7 @@ public:
CreateSwContentControlListItemDlg(weld::Window* pParent,
SwContentControlListItem& rItem) = 0;
virtual std::shared_ptr<AbstractSwBreakDlg> CreateSwBreakDlg(weld::Window
*pParent, SwWrtShell &rSh) = 0;
+ virtual std::shared_ptr<AbstractSwTranslateLangSelectDlg>
CreateSwTranslateLangSelectDlg(weld::Window *pParent) = 0;
virtual VclPtr<VclAbstractDialog> CreateSwChangeDBDlg(SwView& rVw) = 0;
virtual VclPtr<SfxAbstractTabDialog> CreateSwCharDlg(weld::Window*
pParent, SwView& pVw, const SfxItemSet& rCoreSet,
SwCharDlgMode nDialogMode, const OUString* pFormatStr = nullptr) = 0;
diff --git a/sw/sdi/_textsh.sdi b/sw/sdi/_textsh.sdi
index 84750b937715..128591f1673d 100644
--- a/sw/sdi/_textsh.sdi
+++ b/sw/sdi/_textsh.sdi
@@ -1796,5 +1796,11 @@ interface BaseText
StateMethod = GetState ;
]
+ SID_FM_TRANSLATE
+ [
+ ExecMethod = Execute ;
+ StateMethod = GetState ;
+ ]
+
} // end of interface text
diff --git a/sw/source/ui/dialog/swdlgfact.cxx
b/sw/source/ui/dialog/swdlgfact.cxx
index 17f0ed1d3a03..b89321133188 100644
--- a/sw/source/ui/dialog/swdlgfact.cxx
+++ b/sw/source/ui/dialog/swdlgfact.cxx
@@ -90,6 +90,7 @@
#include <uiborder.hxx>
#include <mmresultdialogs.hxx>
#include <formatlinebreak.hxx>
+#include <translatelangselect.hxx>
using namespace ::com::sun::star;
using namespace css::frame;
@@ -802,6 +803,12 @@ sal_uInt16 AbstractMailMergeWizard_Impl::GetRestartPage()
const
return m_xDlg->GetRestartPage();
}
+std::optional<SwLanguageListItem>
AbstractSwTranslateLangSelectDlg_Impl::GetSelectedLanguage()
+{
+ SwTranslateLangSelectDlg* pDlg =
dynamic_cast<SwTranslateLangSelectDlg*>(m_xDlg.get());
+ return pDlg->GetSelectedLanguage();
+}
+
VclPtr<AbstractSwInsertAbstractDlg>
SwAbstractDialogFactory_Impl::CreateSwInsertAbstractDlg(weld::Window* pParent)
{
return
VclPtr<AbstractSwInsertAbstractDlg_Impl>::Create(std::make_unique<SwInsertAbstractDlg>(pParent));
@@ -861,6 +868,11 @@ std::shared_ptr<AbstractSwBreakDlg>
SwAbstractDialogFactory_Impl::CreateSwBreakD
return
std::make_shared<AbstractSwBreakDlg_Impl>(std::make_unique<SwBreakDlg>(pParent,
rSh));
}
+std::shared_ptr<AbstractSwTranslateLangSelectDlg>
SwAbstractDialogFactory_Impl::CreateSwTranslateLangSelectDlg(weld::Window*
pParent)
+{
+ return
std::make_shared<AbstractSwTranslateLangSelectDlg_Impl>(std::make_unique<SwTranslateLangSelectDlg>(pParent));
+}
+
VclPtr<VclAbstractDialog>
SwAbstractDialogFactory_Impl::CreateSwChangeDBDlg(SwView& rVw)
{
#if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
diff --git a/sw/source/ui/dialog/swdlgfact.hxx
b/sw/source/ui/dialog/swdlgfact.hxx
index 8690d9db8129..7e7615ef9220 100644
--- a/sw/source/ui/dialog/swdlgfact.hxx
+++ b/sw/source/ui/dialog/swdlgfact.hxx
@@ -187,6 +187,19 @@ public:
virtual std::shared_ptr<weld::DialogController> getDialogController()
override { return m_xDlg; }
};
+class AbstractSwTranslateLangSelectDlg_Impl : public
AbstractSwTranslateLangSelectDlg
+{
+ std::shared_ptr<weld::DialogController> m_xDlg;
+public:
+ explicit
AbstractSwTranslateLangSelectDlg_Impl(std::shared_ptr<weld::DialogController> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+
+ virtual std::shared_ptr<weld::DialogController> getDialogController()
override { return m_xDlg; }
+ virtual std::optional<SwLanguageListItem> GetSelectedLanguage() override;
+};
+
class AbstractSwTableWidthDlg_Impl : public VclAbstractDialog
{
std::unique_ptr<SwTableWidthDlg> m_xDlg;
@@ -684,6 +697,7 @@ public:
SwContentControlListItem& rItem)
override;
virtual std::shared_ptr<AbstractSwBreakDlg> CreateSwBreakDlg(weld::Window
*pParent, SwWrtShell &rSh) override;
+ virtual std::shared_ptr<AbstractSwTranslateLangSelectDlg>
CreateSwTranslateLangSelectDlg(weld::Window *pParent) override;
virtual VclPtr<VclAbstractDialog> CreateSwChangeDBDlg(SwView& rVw)
override;
virtual VclPtr<SfxAbstractTabDialog> CreateSwCharDlg(weld::Window*
pParent, SwView& pVw, const SfxItemSet& rCoreSet,
SwCharDlgMode nDialogMode, const OUString* pFormatStr = nullptr)
override;
diff --git a/sw/source/ui/misc/translatelangselect.cxx
b/sw/source/ui/misc/translatelangselect.cxx
new file mode 100644
index 000000000000..9a05e6c738f3
--- /dev/null
+++ b/sw/source/ui/misc/translatelangselect.cxx
@@ -0,0 +1,110 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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 .
+ */
+
+#include <vcl/svapp.hxx>
+#include <osl/diagnose.h>
+
+#include <uitool.hxx>
+#include <swtypes.hxx>
+#include <wrtsh.hxx>
+#include <view.hxx>
+#include <viewopt.hxx>
+#include <translatelangselect.hxx>
+#include <pagedesc.hxx>
+#include <poolfmt.hxx>
+#include <sal/log.hxx>
+
+int SwTranslateLangSelectDlg::selectedLangIdx = -1;
+SwTranslateLangSelectDlg::SwTranslateLangSelectDlg(weld::Window *pParent)
+ : GenericDialogController(pParent,
"modules/swriter/ui/translationdialog.ui", "LanguageSelectDialog")
+ , m_xLanguageListBox(m_xBuilder->weld_combo_box("combobox1"))
+ , m_xBtnCancel(m_xBuilder->weld_button("cancel"))
+ , m_xBtnTranslate(m_xBuilder->weld_button("translate"))
+ , m_xLanguageVec(
+ {
+ SwLanguageListItem("BG", "Bulgarian"),
+ SwLanguageListItem("CS", "Czech"),
+ SwLanguageListItem("DA", "Danish"),
+ SwLanguageListItem("DE", "German"),
+ SwLanguageListItem("EL", "Greek"),
+ SwLanguageListItem("EN-GB", "English (British)"),
+ SwLanguageListItem("EN-US", "English (American)"),
+ SwLanguageListItem("ET", "Estonian"),
+ SwLanguageListItem("FI", "Finnish"),
+ SwLanguageListItem("FR", "French"),
+ SwLanguageListItem("HU", "Hungarian"),
+ SwLanguageListItem("ID", "Indonesian"),
+ SwLanguageListItem("IT", "Italian"),
+ SwLanguageListItem("JA", "Japanese"),
+ SwLanguageListItem("LT", "Lithuanian"),
+ SwLanguageListItem("LV", "Dutch"),
+ SwLanguageListItem("PL", "Polish"),
+ SwLanguageListItem("PT-BR", "Portuguese (Brazilian)"),
+ SwLanguageListItem("PT-PT", "Portuguese (European)"),
+ SwLanguageListItem("RO", "Romanian"),
+ SwLanguageListItem("RU", "Russian"),
+ SwLanguageListItem("SK", "Slovak"),
+ SwLanguageListItem("SL", "Slovenian"),
+ SwLanguageListItem("SV", "Swedish"),
+ SwLanguageListItem("TR", "Turkish"),
+ SwLanguageListItem("ZH", "Chinese (simplified)"),
+ })
+{
+ m_xLanguageListBox->connect_changed(LINK(this, SwTranslateLangSelectDlg,
LangSelectHdl));
+ m_xBtnCancel->connect_clicked(LINK(this, SwTranslateLangSelectDlg,
LangSelectCancelHdl));
+ m_xBtnTranslate->connect_clicked(LINK(this, SwTranslateLangSelectDlg,
LangSelectTranslateHdl));
+ for (const auto& item : m_xLanguageVec)
+ {
+ m_xLanguageListBox->append_text(OStringToOUString(item.getName(),
RTL_TEXTENCODING_UTF8));
+ }
+
+ if (SwTranslateLangSelectDlg::selectedLangIdx != -1)
+ {
+
m_xLanguageListBox->set_active(SwTranslateLangSelectDlg::selectedLangIdx);
+ }
+}
+
+std::optional<SwLanguageListItem>
SwTranslateLangSelectDlg::GetSelectedLanguage()
+{
+ if (SwTranslateLangSelectDlg::selectedLangIdx != -1)
+ {
+ return m_xLanguageVec.at(SwTranslateLangSelectDlg::selectedLangIdx);
+ }
+
+ return {};
+}
+
+
+IMPL_LINK(SwTranslateLangSelectDlg, LangSelectHdl, weld::ComboBox&, rBox, void)
+{
+ const auto selected = m_xLanguageListBox->get_active();
+ SwTranslateLangSelectDlg::selectedLangIdx = selected;
+}
+
+IMPL_LINK(SwTranslateLangSelectDlg, LangSelectCancelHdl, weld::Button&,
rButton, void)
+{
+ m_xDialog->response(RET_CANCEL);
+}
+
+IMPL_LINK(SwTranslateLangSelectDlg, LangSelectTranslateHdl, weld::Button&,
rButton, void)
+{
+ m_xDialog->response(RET_OK);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/inc/translatelangselect.hxx
b/sw/source/uibase/inc/translatelangselect.hxx
new file mode 100644
index 000000000000..84e5669b7fcb
--- /dev/null
+++ b/sw/source/uibase/inc/translatelangselect.hxx
@@ -0,0 +1,58 @@
+
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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 .
+ */
+#pragma once
+#include <vcl/weld.hxx>
+#include <rtl/string.h>
+#include <vector>
+#include <optional>
+//class SwWrtShell;
+
+class SwLanguageListItem final
+{
+public:
+ SwLanguageListItem(const OString& sLanguage, const OString& sName) :
m_sLanguage(sLanguage), m_sName(sName) {}
+ const OString& getLanguage() const { return m_sLanguage; }
+ const OString& getName() const { return m_sName; }
+
+private:
+ const OString m_sLanguage;
+ const OString m_sName;
+};
+
+class SwTranslateLangSelectDlg final : public weld::GenericDialogController
+{
+public:
+ static int selectedLangIdx;
+ SwTranslateLangSelectDlg(weld::Window* pParent/*, SwWrtShell& rSh*/);
+ std::optional<SwLanguageListItem> GetSelectedLanguage();
+
+private:
+ std::unique_ptr<weld::ComboBox> m_xLanguageListBox;
+ std::unique_ptr<weld::Button> m_xBtnCancel;
+ std::unique_ptr<weld::Button> m_xBtnTranslate;
+ std::vector<SwLanguageListItem> m_xLanguageVec;
+
+ DECL_LINK(LangSelectHdl, weld::ComboBox&, void );
+ DECL_LINK(LangSelectCancelHdl, weld::Button&, void );
+ DECL_LINK(LangSelectTranslateHdl, weld::Button&, void );
+};
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/shells/textsh1.cxx
b/sw/source/uibase/shells/textsh1.cxx
index 8d7c07e104ca..b88705ba244a 100644
--- a/sw/source/uibase/shells/textsh1.cxx
+++ b/sw/source/uibase/shells/textsh1.cxx
@@ -35,6 +35,7 @@
#include <sfx2/bindings.hxx>
#include <sfx2/viewfrm.hxx>
#include <vcl/unohelp2.hxx>
+#include <vcl/unohelp3.hxx>
#include <vcl/weld.hxx>
#include <sfx2/request.hxx>
#include <svl/eitem.hxx>
@@ -78,6 +79,8 @@
#include <editeng/acorrcfg.hxx>
#include <swabstdlg.hxx>
#include <sfx2/sfxdlg.hxx>
+#include <com/sun/star/text/XTextContent.hpp>
+#include <com/sun/star/datatransfer/clipboard/XFlushableClipboard.hpp>
#include <com/sun/star/container/XNameContainer.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
@@ -103,6 +106,14 @@
#include <bookmark.hxx>
#include <linguistic/misc.hxx>
#include <authfld.hxx>
+#include <unoparagraph.hxx>
+#include <ndtxt.hxx>
+#include <shellio.hxx>
+#include <curl/curl.h>
+#include <boost/property_tree/ptree.hpp>
+#include <boost/property_tree/json_parser.hpp>
+#include <translatelangselect.hxx>
+#include <swwait.hxx>
using namespace ::com::sun::star;
using namespace com::sun::star::beans;
@@ -1503,6 +1514,161 @@ void SwTextShell::Execute(SfxRequest &rReq)
}
}
break;
+ case SID_FM_TRANSLATE:
+ {
+ // TODO
+ // get url and auth_key from config
+ // move htmltransferable to sw/
+ // progressbar etc
+ SwPaM *pPaM = nullptr;
+ if (rWrtSh.HasSelection())
+ {
+ pPaM = rWrtSh.GetCursor();
+ }
+ auto replacePara = [&rWrtSh](const OString& res, const OString&
targetLang, SwPaM *pCursor, bool isSelection = false) {
+ // curl deepl
+ std::unique_ptr<CURL, std::function<void(CURL*)>>
curl(curl_easy_init(),
+ [](CURL* p) {
curl_easy_cleanup(p); });
+ curl_easy_setopt(curl.get(), CURLOPT_URL,
"https://api-free.deepl.com/v2/translate?tag_handling=html");
+ curl_easy_setopt(curl.get(), CURLOPT_FAILONERROR, 1L);
+ std::string response_body;
+ curl_easy_setopt(curl.get(), CURLOPT_WRITEFUNCTION, +[](void
*buffer, size_t size, size_t nmemb, void *userp) -> size_t
+ {
+ if (!userp)
+ return 0;
+ std::string* response = static_cast<std::string*>(userp);
+ size_t real_size = size * nmemb;
+ response->append(static_cast<char*>(buffer), real_size);
+ return real_size;
+ });
+ curl_easy_setopt(curl.get(), CURLOPT_WRITEDATA,
static_cast<void*>(&response_body));
+ OString aPostData("auth_key=&target_lang="+targetLang+"&text=" +
OString(curl_easy_escape(curl.get(), res.getStr(), res.getLength())));
+ curl_easy_setopt(curl.get(), CURLOPT_POSTFIELDS,
aPostData.getStr());
+ CURLcode cc = curl_easy_perform(curl.get());
+ if (cc != CURLE_OK)
+ {
+ SAL_WARN("deepl", "CURL request returned with error: " <<
static_cast<sal_Int32>(cc));
+ return;
+ }
+ tools::Long nStatusCode;
+ curl_easy_getinfo(curl.get(), CURLINFO_RESPONSE_CODE,
&nStatusCode);
+ if (nStatusCode != 200)
+ {
+ SAL_WARN("deepl", "CURL request returned with status code: "
<< nStatusCode);
+ return;
+ }
+ // parse the response
+ boost::property_tree::ptree root;
+ std::stringstream aStream(response_body.data());
+ boost::property_tree::read_json(aStream, root);
+ boost::property_tree::ptree& translations =
root.get_child("translations");
+ size_t size = translations.size();
+ if (size <= 0)
+ {
+ SAL_WARN("deepl", "request returned no translations");
+ }
+ // take the first one
+ const boost::property_tree::ptree& translation =
translations.begin()->second;
+ const std::string text = translation.get<std::string>("text");
+ OString translatedData(text);
+ rtl::Reference<vcl::unohelper::HtmlTransferable> pHtmlTransferable
= new vcl::unohelper::HtmlTransferable( translatedData );
+ if ( pHtmlTransferable.is() )
+ {
+ TransferableDataHelper aDataHelper( pHtmlTransferable );
+ if( aDataHelper.GetXTransferable().is() &&
SwTransferable::IsPasteSpecial( rWrtSh, aDataHelper ) )
+ {
+ if (isSelection != true)
+ {
+ rWrtSh.SetSelection(*pCursor);
+ }
+ SwTransferable::Paste(rWrtSh, aDataHelper);
+ rWrtSh.KillSelection(nullptr, false);
+ }
+ }
+ };
+ auto exportAndReplace = [&rWrtSh, replacePara] (const OString&
targetLang, SwPaM *pCursor)
+ {
+ // freeze everything
+ SwWait aWait( *rWrtSh.GetView().GetDocShell(), true );
+ OString aResult;
+ auto const& pNodes = rWrtSh.GetNodes();
+ WriterRef xWrt;
+ GetHTMLWriter( OUString("NoLineLimit,SkipHeaderFooter"),
OUString(), xWrt );
+ SwNode* pNode = nullptr;
+ if (pCursor != nullptr)
+ {
+ SvMemoryStream aMemoryStream;
+ SwWriter aWriter(aMemoryStream, *pCursor);
+ ErrCode nError = aWriter.Write(xWrt);
+ if (nError.IsError())
+ {
+ SAL_WARN("deepl", "failed to export selection to HTML");
+ return;
+ }
+ aResult = OString(static_cast<const
char*>(aMemoryStream.GetData()), aMemoryStream.GetSize());
+ replacePara(aResult, targetLang, pCursor, true);
+ return;
+ }
+ for (SwNodeOffset n(0); ; ++n)
+ {
+ if (n >= rWrtSh.GetNodes().Count())
+ break;
+
+ if (!pNodes[n])
+ break;
+
+ pNode = pNodes[n];
+ if (pNode->IsTextNode())
+ {
+ if (pNode->GetTextNode()->GetText() == "")
+ continue;
+ auto cursor = Writer::NewUnoCursor(*rWrtSh.GetDoc(),
pNode->GetIndex(), pNode->GetIndex());
+ SvMemoryStream aMemoryStream;
+ SwWriter aWriter(aMemoryStream, *cursor);
+ ErrCode nError = aWriter.Write(xWrt);
+ if (nError.IsError())
+ {
+ SAL_WARN("deepl", "failed to export the paragraph to
HTML");
+ continue;
+ }
+ aResult = OString(static_cast<const
char*>(aMemoryStream.GetData()), aMemoryStream.GetSize());
+ // replace <p> with <scan> to avoid newlines on paste,
hacky but no other option
+ aResult = aResult.replaceAll("<p", "<span");
+ aResult = aResult.replaceAll("</p>", "</span>");
+ replacePara(aResult, targetLang, cursor.get());
+ }
+ }
+ };
+
+ const SfxPoolItem* pTargetLangStringItem = nullptr;
+ if (pArgs && SfxItemState::SET ==
pArgs->GetItemState(SID_ATTR_TARGETLANG_STR, false, &pTargetLangStringItem))
+ {
+ OString targetLang = OUStringToOString(static_cast<const
SfxStringItem*>(pTargetLangStringItem)->GetValue(), RTL_TEXTENCODING_UTF8);
+ exportAndReplace(targetLang, pPaM);
+ }
+ else
+ {
+ SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
+ std::shared_ptr<AbstractSwTranslateLangSelectDlg>
pAbstractDialog(pFact->CreateSwTranslateLangSelectDlg(GetView().GetFrameWeld()));
+ std::shared_ptr<weld::DialogController>
pDialogController(pAbstractDialog->getDialogController());
+ weld::DialogController::runAsync(pDialogController,
[exportAndReplace, pAbstractDialog, pPaM] (sal_Int32 nResult)
+ {
+ if (nResult != RET_OK)
+ {
+ return;
+ }
+ auto languageItem = pAbstractDialog->GetSelectedLanguage();
+ if (!languageItem.has_value())
+ {
+ return;
+ }
+ const OString targetLang = languageItem->getLanguage();
+ exportAndReplace(targetLang, pPaM);
+ });
+ }
+
+ }
+ break;
case SID_SPELLCHECK_IGNORE:
{
SwPaM *pPaM = rWrtSh.GetCursor();
diff --git a/sw/uiconfig/sglobal/menubar/menubar.xml
b/sw/uiconfig/sglobal/menubar/menubar.xml
index 38f6708c1a55..709c492df4f3 100644
--- a/sw/uiconfig/sglobal/menubar/menubar.xml
+++ b/sw/uiconfig/sglobal/menubar/menubar.xml
@@ -446,6 +446,7 @@
<menu:menuseparator/>
<menu:menuitem menu:id=".uno:PageDialog"/>
<menu:menuitem menu:id=".uno:TitlePageDialog" menu:style="text"/>
+ <menu:menuitem menu:id=".uno:Translate" menu:style="text"/>
<menu:menuitem menu:id=".uno:FormatAllNotes" menu:style="text"/>
<menu:menuitem menu:id=".uno:RubyDialog" menu:style="text"/>
<menu:menuitem menu:id=".uno:FormatColumns" menu:style="text"/>
diff --git a/sw/uiconfig/swform/menubar/menubar.xml
b/sw/uiconfig/swform/menubar/menubar.xml
index 0969d09e6ef6..861cded1a732 100644
--- a/sw/uiconfig/swform/menubar/menubar.xml
+++ b/sw/uiconfig/swform/menubar/menubar.xml
@@ -396,6 +396,7 @@
<menu:menuseparator/>
<menu:menuitem menu:id=".uno:PageDialog"/>
<menu:menuitem menu:id=".uno:TitlePageDialog" menu:style="text"/>
+ <menu:menuitem menu:id=".uno:Translate" menu:style="text"/>
<menu:menuitem menu:id=".uno:FormatAllNotes" menu:style="text"/>
<menu:menuitem menu:id=".uno:RubyDialog" menu:style="text"/>
<menu:menuitem menu:id=".uno:FormatColumns" menu:style="text"/>
diff --git a/sw/uiconfig/swriter/menubar/menubar.xml
b/sw/uiconfig/swriter/menubar/menubar.xml
index 3f257b9f0ebf..4658564da415 100644
--- a/sw/uiconfig/swriter/menubar/menubar.xml
+++ b/sw/uiconfig/swriter/menubar/menubar.xml
@@ -457,6 +457,7 @@
<menu:menuseparator/>
<menu:menuitem menu:id=".uno:PageDialog"/>
<menu:menuitem menu:id=".uno:TitlePageDialog"/>
+ <menu:menuitem menu:id=".uno:Translate"/>
<menu:menuitem menu:id=".uno:FormatAllNotes" menu:style="text"/>
<menu:menuitem menu:id=".uno:RubyDialog" menu:style="text"/>
<menu:menuitem menu:id=".uno:FormatColumns"/>
diff --git a/sw/uiconfig/swriter/ui/translationdialog.ui
b/sw/uiconfig/swriter/ui/translationdialog.ui
new file mode 100644
index 000000000000..70a594201e60
--- /dev/null
+++ b/sw/uiconfig/swriter/ui/translationdialog.ui
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.22.2 -->
+<interface domain="sw">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkDialog" id="LanguageSelectDialog">
+ <property name="can_focus">False</property>
+ <property name="title" translatable="yes">Language Selection</property>
+ <property name="type_hint">dialog</property>
+ <child type="titlebar">
+ <placeholder/>
+ </child>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="box1">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">2</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="action-area1">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label">gtk-cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_stock">True</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="translate">
+ <property name="label">gtk-apply</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_stock">True</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_homogeneous">True</property>
+ <property name="column_homogeneous">True</property>
+ <child>
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Select language to
translate</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">combobox1</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="combobox1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk
index 90d432ee559b..8f3e41c57d81 100644
--- a/vcl/Library_vcl.mk
+++ b/vcl/Library_vcl.mk
@@ -408,6 +408,7 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\
vcl/source/app/svmain \
vcl/source/app/timer \
vcl/source/app/unohelp2 \
+ vcl/source/app/unohelp3 \
vcl/source/app/unohelp \
vcl/source/app/vclevent \
vcl/source/app/watchdog \
diff --git a/vcl/source/app/unohelp3.cxx b/vcl/source/app/unohelp3.cxx
new file mode 100644
index 000000000000..0910de84e64d
--- /dev/null
+++ b/vcl/source/app/unohelp3.cxx
@@ -0,0 +1,80 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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 .
+ */
+
+#include <sal/log.hxx>
+#include <vcl/unohelp3.hxx>
+#include <sot/exchange.hxx>
+#include <sot/formats.hxx>
+#include <vcl/svapp.hxx>
+#include <com/sun/star/datatransfer/UnsupportedFlavorException.hpp>
+#include <com/sun/star/datatransfer/clipboard/XClipboard.hpp>
+#include <com/sun/star/datatransfer/clipboard/XFlushableClipboard.hpp>
+#include <cppuhelper/queryinterface.hxx>
+#include <boost/property_tree/json_parser.hpp>
+
+using namespace ::com::sun::star;
+
+namespace vcl::unohelper {
+
+ HtmlTransferable::HtmlTransferable( OString sData ) : data( sData )
+ {
+ }
+
+ HtmlTransferable::~HtmlTransferable()
+ {
+ }
+
+ // css::uno::XInterface
+ uno::Any HtmlTransferable::queryInterface( const uno::Type & rType )
+ {
+ uno::Any aRet = ::cppu::queryInterface( rType, static_cast<
datatransfer::XTransferable* >(this) );
+ return (aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType ));
+ }
+
+ // css::datatransfer::XTransferable
+ uno::Any HtmlTransferable::getTransferData( const
datatransfer::DataFlavor& rFlavor )
+ {
+ SotClipboardFormatId nT = SotExchange::GetFormat( rFlavor );
+ if ( nT != SotClipboardFormatId::HTML )
+ {
+ throw datatransfer::UnsupportedFlavorException();
+ }
+ size_t size = data.getLength();
+ uno::Sequence<sal_Int8> sData(size);
+ std::memcpy(sData.getArray(), data.getStr(), size);
+ return uno::Any(sData);
+ }
+
+ uno::Sequence< datatransfer::DataFlavor >
HtmlTransferable::getTransferDataFlavors( )
+ {
+ uno::Sequence< datatransfer::DataFlavor > aDataFlavors(1);
+ auto ref = aDataFlavors.getArray()[0];
+ ref.MimeType = "text/html";
+ ref.DataType = cppu::UnoType< uno::Sequence<sal_Int8> >::get();
+ SotExchange::GetFormatDataFlavor( SotClipboardFormatId::HTML,
aDataFlavors.getArray()[0] );
+ return aDataFlavors;
+ }
+
+ sal_Bool HtmlTransferable::isDataFlavorSupported( const
datatransfer::DataFlavor& rFlavor )
+ {
+ SotClipboardFormatId nT = SotExchange::GetFormat( rFlavor );
+ return ( nT == SotClipboardFormatId::HTML );
+ }
+
+} // namespace vcl::unohelper