LibreOffice plugin to pipe whole Writer documents through Google Translate, that ought to keep most of the page formatting.

⌈⌋ branch:  PageTranslate


Check-in [ab2252ef7a]

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Prettier error/esxception dialog, and From→To language selection mode now available per menu entry. (Only used by MyMemory for now.)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: ab2252ef7a15c3bd0600b4c5c93d69d3cafb62d5
User & Date: mario 2021-02-08 16:00:47
Context
2021-02-09
16:26
More error notes and changed MyMemory behaviour. check-in: 76510a454a user: mario tags: trunk
2021-02-08
16:00
Prettier error/esxception dialog, and From→To language selection mode now available per menu entry. (Only used by MyMemory for now.) check-in: ab2252ef7a user: mario tags: trunk
05:57
Minor reshuffling in config dialog (and get rid of parenthesis) check-in: 1bb59b3af8 user: mario tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to Addons.xcu.

719
720
721
722
723
724
725






726
727
728
729
730
731
732
                </node>
                <node oor:name="M5PARA2" oor:op="replace">
                  <prop oor:name="Context" oor:type="xs:string"><value/></prop>
                  <prop oor:name="URL" oor:type="xs:string"><value>service:org.openoffice.comp.pyuno.pagetranslate?tradutor&amp;lang=en</value></prop>
                  <prop oor:name="Title" oor:type="xs:string"><value/><value xml:lang="en-US">→Paragraph langinfo</value></prop>
                  <prop oor:name="Target" oor:type="xs:string"><value>_self</value></prop>
                </node>






              </node>
            </node>
          </node>
        </node>
      </node>
    </node>








>
>
>
>
>
>







719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
                </node>
                <node oor:name="M5PARA2" oor:op="replace">
                  <prop oor:name="Context" oor:type="xs:string"><value/></prop>
                  <prop oor:name="URL" oor:type="xs:string"><value>service:org.openoffice.comp.pyuno.pagetranslate?tradutor&amp;lang=en</value></prop>
                  <prop oor:name="Title" oor:type="xs:string"><value/><value xml:lang="en-US">→Paragraph langinfo</value></prop>
                  <prop oor:name="Target" oor:type="xs:string"><value>_self</value></prop>
                </node>
                <node oor:name="M5SELECT" oor:op="replace">
                  <prop oor:name="Context" oor:type="xs:string"><value/></prop>
                  <prop oor:name="URL" oor:type="xs:string"><value>service:org.openoffice.comp.pyuno.pagetranslate?trigger&amp;from=select&amp;lang=select</value></prop>
                  <prop oor:name="Title" oor:type="xs:string"><value/><value xml:lang="en-US">From🏳 ➜ To🏳</value></prop>
                  <prop oor:name="Target" oor:type="xs:string"><value>_self</value></prop>
                </node>
              </node>
            </node>
          </node>
        </node>
      </node>
    </node>

Changes to off/exceptions.xdl.

1
2
3
4
5

6
7
8
9
10
11


12
13
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dlg:window PUBLIC "-//OpenOffice.org//DTD OfficeDocument 1.0//EN" "dialog.dtd">
<dlg:window xmlns:dlg="http://openoffice.org/2000/dialog" xmlns:script="http://openoffice.org/2000/script" dlg:id="exceptions" dlg:left="135" dlg:top="91" dlg:width="164" dlg:height="123" dlg:closeable="true" dlg:moveable="true">
 <dlg:styles>
  <dlg:style dlg:style-id="0" dlg:font-name="Sans" dlg:font-stylename="Bold" dlg:font-family="swiss" dlg:font-weight="150"/>

 </dlg:styles>
 <dlg:bulletinboard>
  <dlg:text dlg:style-id="0" dlg:id="message" dlg:tab-index="0" dlg:left="5" dlg:top="3" dlg:width="153" dlg:height="22" dlg:help-url="vnd.sun.star.help://help/vnd.include-once.pagetranslate/errors.xhp?Language=en&amp;amp;System=UNIX&amp;amp;UseDB=no"/>
  <dlg:formattedfield dlg:id="exception" dlg:tab-index="1" dlg:left="4" dlg:top="28" dlg:width="154" dlg:height="65"/>
  <dlg:button dlg:id="Close" dlg:tab-index="2" dlg:left="103" dlg:top="102" dlg:width="54" dlg:height="13" dlg:value="OK"/>
  <dlg:linklabel dlg:id="help" dlg:tab-index="3" dlg:left="4" dlg:top="99" dlg:width="65" dlg:height="17" dlg:help-url="vnd.sun.star.help://help/vnd.include-once.pagetranslate/errors.xhp?Language=en&amp;amp;System=UNIX&amp;amp;UseDB=no" dlg:value="see help section on common errors" dlg:multiline="true"/>


 </dlg:bulletinboard>
</dlg:window>


|


>


|
<
|
|
>
>


1
2
3
4
5
6
7
8
9

10
11
12
13
14
15
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dlg:window PUBLIC "-//OpenOffice.org//DTD OfficeDocument 1.0//EN" "dialog.dtd">
<dlg:window xmlns:dlg="http://openoffice.org/2000/dialog" xmlns:script="http://openoffice.org/2000/script" dlg:id="exceptions" dlg:left="135" dlg:top="91" dlg:width="243" dlg:height="173" dlg:closeable="true" dlg:moveable="true">
 <dlg:styles>
  <dlg:style dlg:style-id="0" dlg:font-name="Sans" dlg:font-stylename="Bold" dlg:font-family="swiss" dlg:font-weight="150"/>
  <dlg:style dlg:style-id="1" dlg:border="simple"/>
 </dlg:styles>
 <dlg:bulletinboard>
  <dlg:text dlg:style-id="0" dlg:id="message" dlg:tab-index="0" dlg:left="5" dlg:top="13" dlg:width="233" dlg:height="20" dlg:help-url="vnd.sun.star.help://help/vnd.include-once.pagetranslate/errors.xhp?Language=en&amp;amp;System=UNIX&amp;amp;UseDB=no" dlg:value="msg/err"/>

  <dlg:button dlg:id="Close" dlg:tab-index="1" dlg:left="182" dlg:top="154" dlg:width="54" dlg:height="13" dlg:value="OK"/>
  <dlg:linklabel dlg:id="help" dlg:tab-index="2" dlg:left="4" dlg:top="149" dlg:width="65" dlg:height="17" dlg:help-url="vnd.sun.star.help://help/vnd.include-once.pagetranslate/errors.xhp?Language=en&amp;amp;System=UNIX&amp;amp;UseDB=no" dlg:value="see help section on common errors" dlg:multiline="true"/>
  <dlg:text dlg:id="Label1" dlg:tab-index="4" dlg:left="5" dlg:top="2" dlg:width="139" dlg:height="8" dlg:value="⚠ So, we ran into a problem here:"/>
  <dlg:textfield dlg:style-id="1" dlg:id="exception" dlg:tab-index="3" dlg:left="5" dlg:top="36" dlg:width="233" dlg:height="108" dlg:hscroll="true" dlg:vscroll="true" dlg:multiline="true" dlg:value="exc/trc"/>
 </dlg:bulletinboard>
</dlg:window>

Changes to pagetranslate.py.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/usr/bin/python
# encoding: utf-8
# api: uno
# type: callback
# category: language
# title: PageTranslate
# description: Action button to get whole Writer document translated
# version: 1.6.46
# state: beta
# author: mario
# url: https://fossil.include-once.org/pagetranslate/
# depends: python:requests (>= 2.5), python:uno
# pack: *.py, pythonpath/*.py, META-INF/*, pkg-desc, *.x*, icons/*
# license: GNU LGPL 2.1
# forked-from: TradutorLibreText (Claudemir de Almeida Rosa)







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/usr/bin/python
# encoding: utf-8
# api: uno
# type: callback
# category: language
# title: PageTranslate
# description: Action button to get whole Writer document translated
# version: 1.6.78
# state: beta
# author: mario
# url: https://fossil.include-once.org/pagetranslate/
# depends: python:requests (>= 2.5), python:uno
# pack: *.py, pythonpath/*.py, META-INF/*, pkg-desc, *.x*, icons/*
# license: GNU LGPL 2.1
# forked-from: TradutorLibreText (Claudemir de Almeida Rosa)
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112



113
114
115
116
117
118
119
        #self.dispatcher = self.ctx.ServiceManager.createInstanceWithContext("com.sun.star.frame.DispatchHelper", self.ctx)


    # invoked from toolbar button
    def trigger(self, args):
        log.info(".trigger(args=%s) invoked" % repr(args))
        try:
            #import pt_dialogs, langselect
            #langselect.Run_MyApp()
            #pt_dialogs.Run_MyApp()
            
            # merge defaults from registry + params from args
            self.params.update(settings(self.ctx).read())
            self.params.update(self.argparse(args))
            if self.params.get("debug"):
                log.root.handlers[0].setLevel(log.DEBUG)



            log.info(repr(self.params))

            # Draw/Impress?
            log.debug(dir(self.document))
            if self.document.supportsService("com.sun.star.drawing.DrawingDocument") or self.document.supportsService("com.sun.star.presentation.PresentationDocument"):
                self.assign_t()
                self.drawtranslate(self.document.getDrawPages())







<
<
<
<





>
>
>







97
98
99
100
101
102
103




104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
        #self.dispatcher = self.ctx.ServiceManager.createInstanceWithContext("com.sun.star.frame.DispatchHelper", self.ctx)


    # invoked from toolbar button
    def trigger(self, args):
        log.info(".trigger(args=%s) invoked" % repr(args))
        try:




            # merge defaults from registry + params from args
            self.params.update(settings(self.ctx).read())
            self.params.update(self.argparse(args))
            if self.params.get("debug"):
                log.root.handlers[0].setLevel(log.DEBUG)
            if self.params["lang"] == "select":
                import pt_dialogs
                self.params["from"], self.params["lang"] = pt_dialogs.langselect()
            log.info(repr(self.params))

            # Draw/Impress?
            log.debug(dir(self.document))
            if self.document.supportsService("com.sun.star.drawing.DrawingDocument") or self.document.supportsService("com.sun.star.presentation.PresentationDocument"):
                self.assign_t()
                self.drawtranslate(self.document.getDrawPages())
130
131
132
133
134
135
136
137



138
139
140
141
142
143
144
145
            tree = self.document.getText().createEnumeration()
            self.traverse(tree, slow=self.params.get("slow"))
            if self.params.get("frames"):
            	self.traverse(XNamedAsEnumeration(self.document.getTextFrames()))

        except Exception as exc:
            log.error(format_exc())
            



            self.MessageBox(format_exc(), MsgType=ERRORBOX)
        log.info("----")

    # map self.t.translate() implementation according to settings
    def assign_t(self):
        self.t = translationbackends.assign_service(self.params)
        log.info(self.t)
    







|
>
>
>
|







129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
            tree = self.document.getText().createEnumeration()
            self.traverse(tree, slow=self.params.get("slow"))
            if self.params.get("frames"):
            	self.traverse(XNamedAsEnumeration(self.document.getTextFrames()))

        except Exception as exc:
            log.error(format_exc())
            try:
                import pt_dialogs
                pt_dialogs.exception(err=str(exc), exc=format_exc())
            except:
                self.MessageBox(format_exc(), MsgType=ERRORBOX)
        log.info("----")

    # map self.t.translate() implementation according to settings
    def assign_t(self):
        self.t = translationbackends.assign_service(self.params)
        log.info(self.t)
    

Changes to pythonpath/pt_dialogs.py.

17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83









84
85
86
87
88
89
90
91
92
93
94
95
96

97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128

129

130
131
132


















133
134
135
136
137
138
139
import unohelper
from com.sun.star.awt import XActionListener
from com.sun.star.task import XJobExecutor

from com.sun.star.awt.MessageBoxButtons import BUTTONS_OK, BUTTONS_OK_CANCEL, BUTTONS_YES_NO, BUTTONS_YES_NO_CANCEL, BUTTONS_RETRY_CANCEL, BUTTONS_ABORT_IGNORE_RETRY
from com.sun.star.awt.MessageBoxButtons import DEFAULT_BUTTON_OK, DEFAULT_BUTTON_CANCEL, DEFAULT_BUTTON_RETRY, DEFAULT_BUTTON_YES, DEFAULT_BUTTON_NO, DEFAULT_BUTTON_IGNORE
from com.sun.star.awt.MessageBoxType import MESSAGEBOX, INFOBOX, WARNINGBOX, ERRORBOX, QUERYBOX

# -------------------------------------
# HELPERS FOR MRI AND  XRAY
# -------------------------------------

# Uncomment for MRI
# def mri(ctx, target):
#     mri = ctx.ServiceManager.createInstanceWithContext("mytools.Mri", ctx)
#     mri.inspect(target)

# Uncomment for Xray
# def xray(myObject):
#     try:
#         sm = uno.getComponentContext().ServiceManager
#         mspf = sm.createInstanceWithContext("com.sun.star.script.provider.MasterScriptProviderFactory", uno.getComponentContext())
#         scriptPro = mspf.createScriptProvider("")
#         xScript = scriptPro.getScript("vnd.sun.star.script:XrayTool._Main.Xray?language=Basic&location=application")
#         xScript.invoke((myObject,), (), ())
#         return
#     except:
#         raise _rtex("\nBasic library Xray is not installed", uno.getComponentContext())
# -------------------------------------------------------------------


class MyApp(unohelper.Base, XActionListener, XJobExecutor):
    """
    Class documentation...
    """
    def __init__(self, ctx=uno.getComponentContext()):
        self.LocalContext = ctx
        self.ServiceManager = self.LocalContext.ServiceManager
        self.Toolkit = self.ServiceManager.createInstanceWithContext("com.sun.star.awt.ExtToolkit", self.LocalContext)

        # -----------------------------------------------------------
        #               Create dialog and insert controls
        # -----------------------------------------------------------

        # --------------create dialog container and set model and properties
        self.DialogContainer = self.ServiceManager.createInstanceWithContext("com.sun.star.awt.UnoControlDialog", self.LocalContext)
        self.DialogModel = self.ServiceManager.createInstance("com.sun.star.awt.UnoControlDialogModel")
        self.DialogContainer.setModel(self.DialogModel)
        self.DialogModel.Name = "exceptions"
        self.DialogModel.PositionX = "135"
        self.DialogModel.PositionY = "91"
        self.DialogModel.Width = 164
        self.DialogModel.Height = 123
        self.DialogModel.Closeable = True
        self.DialogModel.Moveable = True

        
        # --------- create an instance of FixedText control, set properties ---
        self.message = self.DialogModel.createInstance("com.sun.star.awt.UnoControlFixedTextModel")

        self.message.Name = "message"
        self.message.TabIndex = 0
        self.message.PositionX = "5"
        self.message.PositionY = "3"
        self.message.Width = 153
        self.message.Height = 22
        self.message.HelpURL = "vnd.sun.star.help://help/vnd.include-once.pagetranslate/errors.xhp?Language=en&amp;System=UNIX&amp;UseDB=no"










        # inserts the control model into the dialog model
        self.DialogModel.insertByName("message", self.message)

        # --------- create an instance of FormattedField control, set properties ---
        self.exception = self.DialogModel.createInstance("com.sun.star.awt.UnoControlFormattedFieldModel")

        self.exception.Name = "exception"
        self.exception.TabIndex = 1
        self.exception.PositionX = "4"
        self.exception.PositionY = "28"
        self.exception.Width = 154
        self.exception.Height = 65


        # inserts the control model into the dialog model
        self.DialogModel.insertByName("exception", self.exception)

        # --------- create an instance of Button control, set properties ---
        self.Close = self.DialogModel.createInstance("com.sun.star.awt.UnoControlButtonModel")

        self.Close.Name = "Close"
        self.Close.TabIndex = 2
        self.Close.PositionX = "103"
        self.Close.PositionY = "102"
        self.Close.Width = 54
        self.Close.Height = 13
        self.Close.Label = "OK"

        # inserts the control model into the dialog model
        self.DialogModel.insertByName("Close", self.Close)

        # add the action listener
        self.DialogContainer.getControl('Close').addActionListener(self)
        self.DialogContainer.getControl('Close').setActionCommand('Close_OnClick')

        # --------- create an instance of FixedHyperlink control, set properties ---
        self.help = self.DialogModel.createInstance("com.sun.star.awt.UnoControlFixedHyperlinkModel")

        self.help.Name = "help"
        self.help.TabIndex = 3
        self.help.PositionX = "4"
        self.help.PositionY = "99"
        self.help.Width = 65
        self.help.Height = 17
        self.help.HelpURL = "vnd.sun.star.help://help/vnd.include-once.pagetranslate/errors.xhp?Language=en&amp;System=UNIX&amp;UseDB=no"

        self.help.Label = "see help section on common errors"


        # inserts the control model into the dialog model
        self.DialogModel.insertByName("help", self.help)



















    def showDialog(self):
        self.DialogContainer.setVisible(True)
        self.DialogContainer.createPeer(self.Toolkit, None)
        self.DialogContainer.execute()

    # --------- functions -----------------------







|
<
<
<

<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<

<
|



|















|
|










|
|
|

>
>
>
>
>
>
>
>
>




|
|

|
|
|
|
|
|
>


|





|
|
|















|

|



>

>



>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







17
18
19
20
21
22
23
24



25




26












27

28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
import unohelper
from com.sun.star.awt import XActionListener
from com.sun.star.task import XJobExecutor

from com.sun.star.awt.MessageBoxButtons import BUTTONS_OK, BUTTONS_OK_CANCEL, BUTTONS_YES_NO, BUTTONS_YES_NO_CANCEL, BUTTONS_RETRY_CANCEL, BUTTONS_ABORT_IGNORE_RETRY
from com.sun.star.awt.MessageBoxButtons import DEFAULT_BUTTON_OK, DEFAULT_BUTTON_CANCEL, DEFAULT_BUTTON_RETRY, DEFAULT_BUTTON_YES, DEFAULT_BUTTON_NO, DEFAULT_BUTTON_IGNORE
from com.sun.star.awt.MessageBoxType import MESSAGEBOX, INFOBOX, WARNINGBOX, ERRORBOX, QUERYBOX
from com.sun.star.awt import FontDescriptor








langs = ("acf", "af", "aig", "am", "ar", "az", "bah", "be", "bem", "bg", "bi", "bjs", "bn", "bod", "br", "bs", "ca", "cb", "cha", "cop", "crs", "cs", "cy", "da", "de", "de", "div", "dzo", "el", "en", "eo", "es", "et", "eu", "fa", "fi", "fn", "fo", "fr", "ga", "gcl", "gd", "gl", "grc", "gu", "gv", "gyn", "ha", "haw", "he", "hi", "hr", "ht", "hu", "hy", "id", "is", "it", "ja", "jam", "jv", "ka", "kab", "kal", "kea", "kk", "km", "kn", "ko", "ku", "ku", "ky", "la", "lb", "lo", "lt", "lv", "men", "mfe", "mg", "mh", "mi", "mk", "mn", "ms", "mt", "my", "ne", "niu", "nl", "no", "nso", "ny", "pa", "pap", "pau", "pis", "pl", "pot", "pov", "ppk", "ps", "pt", "qu", "rm", "ro", "ru", "run", "rw", "sg", "si", "sk", "sl", "smo", "sna", "so", "sq", "sr", "srn", "sv", "svc", "sw", "syc", "ta", "te", "tet", "tg", "th", "ti", "tk", "tkl", "tl", "tmh", "tn", "ton", "tpi", "tr", "tvl", "uk", "ur", "uz", "vi", "vic", "wls", "wo", "xh", "yi", "zdj", "zh-CN", "zh-TW", "zu")














class ExcApp(unohelper.Base, XActionListener, XJobExecutor):
    """
    Class documentation...
    """
    def __init__(self, ctx=uno.getComponentContext(), err="error msg", exc="exception/traceback"):
        self.LocalContext = ctx
        self.ServiceManager = self.LocalContext.ServiceManager
        self.Toolkit = self.ServiceManager.createInstanceWithContext("com.sun.star.awt.ExtToolkit", self.LocalContext)

        # -----------------------------------------------------------
        #               Create dialog and insert controls
        # -----------------------------------------------------------

        # --------------create dialog container and set model and properties
        self.DialogContainer = self.ServiceManager.createInstanceWithContext("com.sun.star.awt.UnoControlDialog", self.LocalContext)
        self.DialogModel = self.ServiceManager.createInstance("com.sun.star.awt.UnoControlDialogModel")
        self.DialogContainer.setModel(self.DialogModel)
        self.DialogModel.Name = "exceptions"
        self.DialogModel.PositionX = "135"
        self.DialogModel.PositionY = "91"
        self.DialogModel.Width = 243
        self.DialogModel.Height = 173
        self.DialogModel.Closeable = True
        self.DialogModel.Moveable = True

        
        # --------- create an instance of FixedText control, set properties ---
        self.message = self.DialogModel.createInstance("com.sun.star.awt.UnoControlFixedTextModel")

        self.message.Name = "message"
        self.message.TabIndex = 0
        self.message.PositionX = "5"
        self.message.PositionY = "13"
        self.message.Width = 233
        self.message.Height = 20
        self.message.HelpURL = "vnd.sun.star.help://help/vnd.include-once.pagetranslate/errors.xhp?Language=en&amp;System=UNIX&amp;UseDB=no"
        self.message.Label = err
        self.message.MultiLine = True
        self.message.BackgroundColor = 0xFFDDCC
        self.message.FontDescriptor = FontDescriptor()
        self.message.FontDescriptor.Name = "Liberation Sans"
        self.message.FontDescriptor.StyleName = "Bold"
        self.message.FontDescriptor.Weight = 150.0
        #self.message.FontDescriptor.Family = "swiss"
        print(vars(self.message.FontDescriptor))

        # inserts the control model into the dialog model
        self.DialogModel.insertByName("message", self.message)

        # --------- create an instance of FixedText control, set properties ---
        self.Label1 = self.DialogModel.createInstance("com.sun.star.awt.UnoControlFixedTextModel")

        self.Label1.Name = "Label1"
        self.Label1.TabIndex = 4
        self.Label1.PositionX = "5"
        self.Label1.PositionY = "2"
        self.Label1.Width = 139
        self.Label1.Height = 8
        self.Label1.Label = "⚠ So, we ran into a problem here:"

        # inserts the control model into the dialog model
        self.DialogModel.insertByName("Label1", self.Label1)

        # --------- create an instance of Button control, set properties ---
        self.Close = self.DialogModel.createInstance("com.sun.star.awt.UnoControlButtonModel")

        self.Close.Name = "Close"
        self.Close.TabIndex = 1
        self.Close.PositionX = "182"
        self.Close.PositionY = "154"
        self.Close.Width = 54
        self.Close.Height = 13
        self.Close.Label = "OK"

        # inserts the control model into the dialog model
        self.DialogModel.insertByName("Close", self.Close)

        # add the action listener
        self.DialogContainer.getControl('Close').addActionListener(self)
        self.DialogContainer.getControl('Close').setActionCommand('Close_OnClick')

        # --------- create an instance of FixedHyperlink control, set properties ---
        self.help = self.DialogModel.createInstance("com.sun.star.awt.UnoControlFixedHyperlinkModel")

        self.help.Name = "help"
        self.help.TabIndex = 2
        self.help.PositionX = "4"
        self.help.PositionY = "149"
        self.help.Width = 65
        self.help.Height = 17
        self.help.HelpURL = "vnd.sun.star.help://help/vnd.include-once.pagetranslate/errors.xhp?Language=en&amp;System=UNIX&amp;UseDB=no"
        self.help.URL = "https://fossil.include-once.org/pagetranslate/file/help/en/vnd.include-once.pagetranslate/errors.duck"
        self.help.Label = "see help section on common errors"
        self.help.MultiLine = True

        # inserts the control model into the dialog model
        self.DialogModel.insertByName("help", self.help)

        # --------- create an instance of Edit control, set properties ---
        self.exception = self.DialogModel.createInstance("com.sun.star.awt.UnoControlEditModel")

        self.exception.Name = "exception"
        self.exception.Border = 0
        self.exception.HScroll = True
        self.exception.VScroll = True
        self.exception.TabIndex = 3
        self.exception.PositionX = "5"
        self.exception.PositionY = "36"
        self.exception.Width = 233
        self.exception.Height = 108
        self.exception.Text = exc
        self.exception.MultiLine = True

        # inserts the control model into the dialog model
        self.DialogModel.insertByName("exception", self.exception)

    def showDialog(self):
        self.DialogContainer.setVisible(True)
        self.DialogContainer.createPeer(self.Toolkit, None)
        self.DialogContainer.execute()

    # --------- functions -----------------------
157
158
159
160
161
162
163













































164
165











































































166























167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
    def actionPerformed(self, oActionEvent):
    
        if oActionEvent.ActionCommand == 'Close_OnClick':
            self.Close_OnClick()

    
    def Close_OnClick(self):













































        self.DialogModel.Title = "It's Alive! - Close"
        self.messageBox("It's Alive! - Close", "Event: OnClick", INFOBOX)











































































        # TODO: not implemented























        self.DialogContainer.dispose();


def Run_MyApp(*args):

    try:
        ctx = remote_ctx                    # IDE
    except:
        ctx = uno.getComponentContext()     # UI

    # get desktop
    desktop = ctx.getByName("/singletons/com.sun.star.frame.theDesktop")

    # get document
    document = desktop.getCurrentComponent()

    app = MyApp(ctx=ctx)
    app.showDialog()


# Execute macro from LibreOffice UI (Tools - Macro)
g_exportedScripts = Run_MyApp,

# -------------------------------------
# HELPER FOR AN IDE
# -------------------------------------

if __name__ == "__main__":
    """ Connect to LibreOffice proccess.
    1) Start the office in shell with command:
    soffice "--accept=socket,host=127.0.0.1,port=2002,tcpNoDelay=1;urp;StarOffice.ComponentContext" --norestore
    2) Run script
    """
    import os
    import sys

    sys.path.append(os.path.join(os.path.dirname(__file__), 'pythonpath'))

    local_ctx = uno.getComponentContext()
    resolver = local_ctx.ServiceManager.createInstance("com.sun.star.bridge.UnoUrlResolver")
    try:
        remote_ctx = resolver.resolve("uno:socket,"
                                        "host=127.0.0.1,"
                                        "port=2002,"
                                        "tcpNoDelay=1;"
                                        "urp;"
                                        "StarOffice.ComponentContext")
    except Exception as err:
        print(err)

    Run_MyApp()







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|


|












|

|

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339































    def actionPerformed(self, oActionEvent):
    
        if oActionEvent.ActionCommand == 'Close_OnClick':
            self.Close_OnClick()

    
    def Close_OnClick(self):
        self.DialogContainer.endDialog(1);


def exception(err, exc, *args):

    try:
        ctx = remote_ctx                    # IDE
    except:
        ctx = uno.getComponentContext()     # UI

    # get desktop
    desktop = ctx.getByName("/singletons/com.sun.star.frame.theDesktop")

    # get document
    document = desktop.getCurrentComponent()

    app = ExcApp(ctx=ctx, err=err, exc=exc)
    app.showDialog()



class LangApp(unohelper.Base, XActionListener, XJobExecutor):
    """
    Class documentation...
    """
    def __init__(self, ctx=uno.getComponentContext()):
        self.LocalContext = ctx
        self.ServiceManager = self.LocalContext.ServiceManager
        self.Toolkit = self.ServiceManager.createInstanceWithContext("com.sun.star.awt.ExtToolkit", self.LocalContext)

        # -----------------------------------------------------------
        #               Create dialog and insert controls
        # -----------------------------------------------------------

        # --------------create dialog container and set model and properties
        self.DialogContainer = self.ServiceManager.createInstanceWithContext("com.sun.star.awt.UnoControlDialog", self.LocalContext)
        self.DialogModel = self.ServiceManager.createInstance("com.sun.star.awt.UnoControlDialogModel")
        self.DialogContainer.setModel(self.DialogModel)
        self.DialogModel.Name = "langselect"
        self.DialogModel.PositionX = "135"
        self.DialogModel.PositionY = "91"
        self.DialogModel.Width = 208
        self.DialogModel.Height = 40
        self.DialogModel.Closeable = True
        self.DialogModel.Moveable = True
        self.DialogModel.Title = "Select translation languages"

        
        # --------- create an instance of ListBox control, set properties ---
        self.fr = self.DialogModel.createInstance("com.sun.star.awt.UnoControlListBoxModel")

        self.fr.Name = "from"
        self.fr.TabIndex = 0
        self.fr.PositionX = "15"
        self.fr.PositionY = "10"
        self.fr.Width = 44
        self.fr.Height = 15
        self.fr.Dropdown = True
        self.fr.LineCount= 15
        self.fr.StringItemList = langs
        self.fr.SelectedItems = (29, )

        # inserts the control model into the dialog model
        self.DialogModel.insertByName("from", self.fr)

        # --------- create an instance of ListBox control, set properties ---
        self.lang = self.DialogModel.createInstance("com.sun.star.awt.UnoControlListBoxModel")

        self.lang.Name = "lang"
        self.lang.TabIndex = 2
        self.lang.PositionX = "90"
        self.lang.PositionY = "10"
        self.lang.Width = 44
        self.lang.Height = 15
        self.lang.Dropdown = True
        self.lang.LineCount = 15
        self.lang.StringItemList = langs
        self.lang.SelectedItems = (31, )

        # inserts the control model into the dialog model
        self.DialogModel.insertByName("lang", self.lang)

        # --------- create an instance of FixedText control, set properties ---
        self.Label1 = self.DialogModel.createInstance("com.sun.star.awt.UnoControlFixedTextModel")

        self.Label1.Name = "Label1"
        self.Label1.TabIndex = 1
        self.Label1.PositionX = "70"
        self.Label1.PositionY = "11"
        self.Label1.Width = 13
        self.Label1.Height = 13
        self.Label1.Label = "➜"

        # inserts the control model into the dialog model
        self.DialogModel.insertByName("Label1", self.Label1)

        # --------- create an instance of Button control, set properties ---
        self.ok = self.DialogModel.createInstance("com.sun.star.awt.UnoControlButtonModel")

        self.ok.Name = "ok"
        self.ok.TabIndex = 3
        self.ok.PositionX = "160"
        self.ok.PositionY = "10"
        self.ok.Width = 35
        self.ok.Height = 17
        self.ok.Label = "OK"

        # inserts the control model into the dialog model
        self.DialogModel.insertByName("ok", self.ok)

        # add the action listener
        self.DialogContainer.getControl('ok').addActionListener(self)
        self.DialogContainer.getControl('ok').setActionCommand('ok_OnClick')

    def showDialog(self):
        self.DialogContainer.setVisible(True)
        self.DialogContainer.createPeer(self.Toolkit, None)
        self.DialogContainer.execute()

    # --------- functions -----------------------

    def myFunction(self):
        # TODO: not implemented
        pass

    # --------- helpers -------------------------

    def messageBox(self, MsgText, MsgTitle, MsgType=MESSAGEBOX, MsgButtons=BUTTONS_OK):
        sm = self.LocalContext.ServiceManager
        si = sm.createInstanceWithContext("com.sun.star.awt.Toolkit", self.LocalContext)
        mBox = si.createMessageBox(self.Toolkit, MsgType, MsgButtons, MsgTitle, MsgText)
        mBox.execute()

    # -----------------------------------------------------------
    #               Action events
    # -----------------------------------------------------------

    def actionPerformed(self, oActionEvent):
    
        if oActionEvent.ActionCommand == 'ok_OnClick':
            self.ok_OnClick()

    
    def ok_OnClick(self):
        self.fr = langs[self.fr.SelectedItems[0]]
        self.to = langs[self.lang.SelectedItems[0]]
        self.DialogContainer.endDialog(1)


def langselect(*args):

    try:
        ctx = remote_ctx                    # IDE
    except:
        ctx = uno.getComponentContext()     # UI

    # get desktop
    desktop = ctx.getByName("/singletons/com.sun.star.frame.theDesktop")

    # get document
    document = desktop.getCurrentComponent()

    app = LangApp(ctx=ctx)
    app.showDialog()
    return app.fr, app.to
































Changes to pythonpath/translationbackends.py.

328
329
330
331
332
333
334

335
336
337
338
339
340
341
342
343
            import langdetect
            self.lang = langdatect.detect
        except:
            log.warning("`pip install langdetect` for best results")

    # API    
    def fetch(self, text, lang="en"):

        url = "https://api.mymemory.translated.net/get?q=%s&langpair=%s|%s&of=json&mt=1" % (
            quote_plus(text.encode("utf-8")), self.lang(text), lang
        )
        if self.params.get("email"):
            url = url + "&de=" + self.params["email"]
        # any exceptions are covered in main
        j = http.get(url).content.decode("utf-8")
        print(j)
        j = json.loads(j)







>

|







328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
            import langdetect
            self.lang = langdatect.detect
        except:
            log.warning("`pip install langdetect` for best results")

    # API    
    def fetch(self, text, lang="en"):
        source_lang = self.params.get("from") or self.lang(text)
        url = "https://api.mymemory.translated.net/get?q=%s&langpair=%s|%s&of=json&mt=1" % (
            quote_plus(text.encode("utf-8")), source_lang, lang
        )
        if self.params.get("email"):
            url = url + "&de=" + self.params["email"]
        # any exceptions are covered in main
        j = http.get(url).content.decode("utf-8")
        print(j)
        j = json.loads(j)