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

⌈⌋ branch:  PageTranslate


Check-in [93f1a54882]

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

Overview
Comment:Transform OptionsPageURL= into code; switching to our dialog still non-functional.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 93f1a5488266db55936e4ed2bdcea091f62a6040
User & Date: mario 2021-05-15 16:21:49
Context
2021-05-15
16:26
Introduce 🏴 button configuration to change default language/behaviour. check-in: 57703cade1 user: mario tags: trunk
16:21
Transform OptionsPageURL= into code; switching to our dialog still non-functional. check-in: 93f1a54882 user: mario tags: trunk
05:42
Add PONS Text Translation backend. check-in: 4620700b36 user: mario tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to Addons.xcu.

725
726
727
728
729
730
731



732
733
734
735
736
737
738
739
740
741
                </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 oor:name="M5Z-CONFIG" oor:op="replace">
                  <prop oor:name="Context" oor:type="xs:string"><value/></prop>                      <!--vnd.sun.star.extension://vnd.include-once.pagetranslate/OptionsDialog.xdl-->
                  <prop oor:name="URL" oor:type="xs:string"><value>.uno:OptionsTreeDialog?OptionsPageURL=%origin%/OptionsDialog.xdl</value></prop>
                  <prop oor:name="Title" oor:type="xs:string"><value/><value xml:lang="en-US">Settings→Language→...</value></prop>
                  <prop oor:name="Target" oor:type="xs:string"><value>_self</value></prop>
                </node>
              </node>
            </node>
          </node>
        </node>







>
>
>
|
|
|







725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
                </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 oor:name="M6A" oor:op="replace">
                  <prop oor:name="URL" oor:type="xs:string"><value>private:separator</value></prop>
                </node>
                <node oor:name="M6CONFIG" 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?settings</value></prop>
                  <prop oor:name="Title" oor:type="xs:string"><value/><value xml:lang="en-US">Settings→Language→...</value></prop>
                  <prop oor:name="Target" oor:type="xs:string"><value>_self</value></prop>
                </node>
              </node>
            </node>
          </node>
        </node>
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
              <prop oor:name="ImageIdentifier" oor:type="xs:string"><value></value></prop>
              <prop oor:name="Target" oor:type="xs:string"><value>_self</value></prop>
              <prop oor:name="Context" oor:type="xs:string"><value>com.sun.star.text.TextDocument,com.sun.star.drawing.DrawingDocument,com.sun.star.presentation.PresentationDocument</value></prop>
              <prop oor:name="ControlType" oor:type="xs:string"><value>ImageButton</value></prop>
              <prop oor:name="Title" oor:type="xs:string"><value>T→🇬🇧</value></prop>
            </node>
            <node oor:name="T4" oor:op="replace">
              <prop oor:name="URL" oor:type="xs:string"><value>service:org.openoffice.comp.pyuno.pagetranslate?page&amp;lang=locale</value></prop>
              <prop oor:name="ImageIdentifier" oor:type="xs:string"><value></value></prop>
              <prop oor:name="Target" oor:type="xs:string"><value>_self</value></prop>
              <prop oor:name="Context" oor:type="xs:string"><value>com.sun.star.text.TextDocument,com.sun.star.drawing.DrawingDocument,com.sun.star.presentation.PresentationDocument</value></prop>
              <prop oor:name="ControlType" oor:type="xs:string"><value>Checkbutton</value></prop>
              <prop oor:name="Title" oor:type="xs:string"><value xml:lang="en-US">🏴</value></prop>
            </node>
            <node oor:name="T5" oor:op="replace">







|







762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
              <prop oor:name="ImageIdentifier" oor:type="xs:string"><value></value></prop>
              <prop oor:name="Target" oor:type="xs:string"><value>_self</value></prop>
              <prop oor:name="Context" oor:type="xs:string"><value>com.sun.star.text.TextDocument,com.sun.star.drawing.DrawingDocument,com.sun.star.presentation.PresentationDocument</value></prop>
              <prop oor:name="ControlType" oor:type="xs:string"><value>ImageButton</value></prop>
              <prop oor:name="Title" oor:type="xs:string"><value>T→🇬🇧</value></prop>
            </node>
            <node oor:name="T4" oor:op="replace">
              <prop oor:name="URL" oor:type="xs:string"><value>service:org.openoffice.comp.pyuno.pagetranslate?page&amp;lang=flag</value></prop>
              <prop oor:name="ImageIdentifier" oor:type="xs:string"><value></value></prop>
              <prop oor:name="Target" oor:type="xs:string"><value>_self</value></prop>
              <prop oor:name="Context" oor:type="xs:string"><value>com.sun.star.text.TextDocument,com.sun.star.drawing.DrawingDocument,com.sun.star.presentation.PresentationDocument</value></prop>
              <prop oor:name="ControlType" oor:type="xs:string"><value>Checkbutton</value></prop>
              <prop oor:name="Title" oor:type="xs:string"><value xml:lang="en-US">🏴</value></prop>
            </node>
            <node oor:name="T5" oor:op="replace">

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.8.1
# 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.8.33
# 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)
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
        quick = 0,          # use temporary newline placeholders, or split/iterate over text sections
        slow = 0,           # further split over paragraph segments/formatting (super slow mode)
        debug = 1,          # logging level
        backend = "Google", # backend to use, (string name replaces old flags)
        api_key = "",       # API key
        email = "",         # MyMemory email
        cmd = "translate-cli -o -f auto -t {lang} {text}",  # cli tool

    )
    t = None   #= translationbackends.google(self.params)


    # gets instantiated as XJobExecutor by LibreOffice
    def __init__(self, ctx):
        log.info("init")
        self.ctx = ctx
        desktop = self.ctx.ServiceManager.createInstanceWithContext( "com.sun.star.frame.Desktop", self.ctx )
        self.document = desktop.getCurrentComponent()
        #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["from"] = "auto"
            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.get("lang") == "select" or self.params.get("from") == "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))







>








|
|











>


>
>
>
>







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
        quick = 0,          # use temporary newline placeholders, or split/iterate over text sections
        slow = 0,           # further split over paragraph segments/formatting (super slow mode)
        debug = 1,          # logging level
        backend = "Google", # backend to use, (string name replaces old flags)
        api_key = "",       # API key
        email = "",         # MyMemory email
        cmd = "translate-cli -o -f auto -t {lang} {text}",  # cli tool
        flag = "locale",    # default lang for secondary 🏴 button
    )
    t = None   #= translationbackends.google(self.params)


    # gets instantiated as XJobExecutor by LibreOffice
    def __init__(self, ctx):
        log.info("init")
        self.ctx = ctx
        self.desktop = self.ctx.ServiceManager.createInstanceWithContext( "com.sun.star.frame.Desktop", self.ctx )
        self.document = self.desktop.getCurrentComponent()
        #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["from"] = "auto"
            self.params.update(settings(self.ctx).read())
            self.params.update(self.argparse(args))
            log.info(repr(self.params))
            if self.params.get("debug"):
                log.root.handlers[0].setLevel(log.DEBUG)
            if self.params.get("mode") == "settings":
                return settings.dispatch_dialog(self.ctx, self.desktop)
            if self.params.get("lang") == "flag":
                self.params["lang"] = self.params.get("flag", "locale")
            if self.params.get("lang") == "select" or self.params.get("from") == "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))
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314




















315
316
317
318
319
320
        elif hasattr(c, "getSelectedItem"): return str(c.getSelectedItem())
    def setControlValue(self, c, value):
        if hasattr(c, "State"): c.State = int(value if value else 0)
        elif hasattr(c, "Text"): c.Text = str(value if value else "")
        elif hasattr(c, "selectItem"): c.selectItem(str(value if value else ""), True)
        #else: log.debug([c, dir(c)])
   

    # XContainerWindowEventHandler
    def getSupportedMethodNames(self): return ("external_event",)
    # XServiceInfo
    def supportsService(self, name): return (name == self.impl_id)
    def getImplementationName(self): return self.impl_id
    def getSupportedServiceNames(self): return (self.impl_id,)
    def getServiceNames(self): return (self.impl_id,)























# register with LibreOffice
g_ImplementationHelper = unohelper.ImplementationHelper()
g_ImplementationHelper.addImplementation( pagetranslate, "org.openoffice.comp.pyuno.pagetranslate", ("com.sun.star.task.Job",), )
g_ImplementationHelper.addImplementation( settings, settings.impl_id, () )







<








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






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
340
341
342
343
344
345
        elif hasattr(c, "getSelectedItem"): return str(c.getSelectedItem())
    def setControlValue(self, c, value):
        if hasattr(c, "State"): c.State = int(value if value else 0)
        elif hasattr(c, "Text"): c.Text = str(value if value else "")
        elif hasattr(c, "selectItem"): c.selectItem(str(value if value else ""), True)
        #else: log.debug([c, dir(c)])
   

    # XContainerWindowEventHandler
    def getSupportedMethodNames(self): return ("external_event",)
    # XServiceInfo
    def supportsService(self, name): return (name == self.impl_id)
    def getImplementationName(self): return self.impl_id
    def getSupportedServiceNames(self): return (self.impl_id,)
    def getServiceNames(self): return (self.impl_id,)

    # open OptionsTreeDialog with our dialog directly / https://forum.openoffice.org/en/forum/viewtopic.php?p=222540
    @staticmethod
    def dispatch_dialog(ctx, desktop):
        dispatcher = ctx.ServiceManager.createInstanceWithContext("com.sun.star.frame.DispatchHelper", ctx)
        fn = re.sub("^(.+)/uno_packages/", "vnd.sun.star.expand:$UNO_USER_PACKAGES_CACHE/uno_packages/", __file__)
        fn = re.sub("/[\w.]+$", "/OptionsDialog.xdl", fn) #"file://"+__file__)
        #fn = "vnd.sun.star.extension://vnd.include-once.pagetranslate/OptionsDialog.xdl"
        #fn = "./OptionsDialog.xdl"
        log.info(fn)
        # "OptionsPageURL" defined in https://github.com/LibreOffice/core/blob/master/sfx2/source/appl/appuno.cxx
        # "SID_OPTIONS_PAGEURL" in https://github.com/LibreOffice/core/blob/master/sfx2/source/appl/appserv.cxx
        # "xDlg->ActivatePage()" might take numeric argument however
        arg = PropertyValue(Name="OptionsPageURL", Value=fn)
        dispatcher.executeDispatch(
            desktop.getCurrentFrame(),
            ".uno:OptionsTreeDialog",
            "",
            0,
            (arg,),  # neither URL format seems to resonate with handler
        )


# register with LibreOffice
g_ImplementationHelper = unohelper.ImplementationHelper()
g_ImplementationHelper.addImplementation( pagetranslate, "org.openoffice.comp.pyuno.pagetranslate", ("com.sun.star.task.Job",), )
g_ImplementationHelper.addImplementation( settings, settings.impl_id, () )