diff --git a/README.md b/README.md index 0c1833a..916e186 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ Requirements: * pdf2svg -## Software libre no gratis. +## Free Software, not gratis software This extension have a cost of maintenance of 5 euros every year. diff --git a/conf.py b/conf.py index 01db5ec..534a986 100644 --- a/conf.py +++ b/conf.py @@ -117,6 +117,14 @@ MENUS = ( 'toolbar': False, 'shortcut': '', }, + { + 'title': {'en': 'Insert...', 'es': 'Insertar...'}, + 'argument': 'dlg', + 'context': 'calc,writer,draw,impress', + 'icon': 'icon1', + 'toolbar': False, + 'shortcut': '', + }, { 'title': {'en': 'Validate applications', 'es': 'Validar aplicaciones'}, 'argument': 'app', diff --git a/files/ZAZLaTex2SVG_v0.1.0.oxt b/files/ZAZLaTex2SVG_v0.1.0.oxt index 092f1c2..e77179a 100644 Binary files a/files/ZAZLaTex2SVG_v0.1.0.oxt and b/files/ZAZLaTex2SVG_v0.1.0.oxt differ diff --git a/source/Addons.xcu b/source/Addons.xcu index 4de1c72..b025717 100644 --- a/source/Addons.xcu +++ b/source/Addons.xcu @@ -30,6 +30,24 @@ + + Insert... + Insertar... + + + com.sun.star.sheet.SpreadsheetDocument,com.sun.star.text.TextDocument,com.sun.star.drawing.DrawingDocument,com.sun.star.presentation.PresentationDocument + + + service:net.elmau.zaz.latex2svg?dlg + + + _self + + + %origin%/images/icon1 + + + Validate applications Validar aplicaciones diff --git a/source/ZAZLaTex2SVG.py b/source/ZAZLaTex2SVG.py index 442884c..fe0a446 100644 --- a/source/ZAZLaTex2SVG.py +++ b/source/ZAZLaTex2SVG.py @@ -6,74 +6,182 @@ import easymacro2 as app ID_EXTENSION = 'net.elmau.zaz.latex2svg' SERVICE = ('com.sun.star.task.Job',) +TITLE = 'ZAZ Latex2SVG' + + +_ = app.install_locales(__file__) + + +TEMPLATE = """\documentclass{{article}} +\\usepackage[a5paper, landscape]{{geometry}} +\\usepackage{{xcolor}} +\\usepackage{{amssymb}} +\\usepackage{{amsmath}} +\pagestyle{{empty}} +\\begin{{document}} + +\[ {} \] + +\end{{document}} +""" + + +class Controllers(object): + + def __init__(self, dlg): + self.d = dlg + + def cmd_preview_action(self, event): + data = self.d.text.value + if not data: + msg = _('Write some code') + app.errorbox(msg) + return + + app.msgbox(data) + return class ZAZLaTex2SVG(unohelper.Base, XJobExecutor): + NAME = 'temp' + _msg1 = _('Not found') + _msg2 = _('Found') def __init__(self, ctx): self.ctx = ctx - def trigger(self, args='pyUNO'): + def trigger(self, args=''): if args == 'app': self._app() return + if args == 'dlg': + self._dlg() + return + self._from_selection() return def _app(self): - result = 'No encontrado' + result = self._msg1 if app.paths.exists_app('pdflatex'): - result = 'Encontrado' + result = self._msg2 msg = f'pdflatex = {result}\n' - result = 'No encontrado' + result = self._msg1 if app.paths.exists_app('pdfcrop'): - result = 'Encontrado' + result = self._msg2 msg += f'pdfcrop = {result}\n' - result = 'No encontrado' + result = self._msg1 if app.paths.exists_app('pdf2svg'): - result = 'Encontrado' + result = self._msg2 msg += f'pdf2svg = {result}\n\n' - msg += 'No continues hasta tener las tres aplicaciones detectadas' + msg += _('Not used, if not found some application.') app.msgbox(msg) return @app.catch_exception + def _dlg(self): + dlg = self._create_dialog() + dlg.open() + return + + def _create_dialog(self): + args = { + 'Name': 'dialog', + 'Title': TITLE, + 'Width': 270, + 'Height': 250, + } + dlg = app.create_dialog(args) + dlg.id = ID_EXTENSION + dlg.events = Controllers + + args = { + 'Type': 'Label', + 'Name': 'lbl_code', + 'Label': _('Latex code'), + 'Width': 70, + 'Height': 15, + 'X': 10, + 'Y': 5, + 'VerticalAlign': 1, + } + dlg.add_control(args) + + args = { + 'Type': 'Text', + 'Name': 'text', + 'Width': 250, + 'Height': 75, + 'MultiLine': True, + 'VScroll': True, + } + dlg.add_control(args) + + args = { + 'Type': 'Button', + 'Name': 'cmd_preview', + 'Label': _('Preview'), + 'Width': 70, + 'Height': 15, + 'ImageURL': 'view.png', + 'ImagePosition': 1, + } + dlg.add_control(args) + + args = { + 'Type': 'Button', + 'Name': 'cmd_insert', + 'Label': _('Insert'), + 'Width': 70, + 'Height': 15, + 'ImageURL': 'insert.png', + 'ImagePosition': 1, + } + dlg.add_control(args) + args = { + 'Type': 'Button', + 'Name': 'cmd_close', + 'Label': _('Close'), + 'Width': 70, + 'Height': 15, + 'ImageURL': 'close.png', + 'ImagePosition': 1, + } + dlg.add_control(args) + + dlg.text.move(dlg.lbl_code) + dlg.cmd_preview.move(dlg.text, center=True) + dlg.cmd_insert.move(dlg.cmd_preview) + dlg.cmd_close.move(dlg.cmd_preview) + controls = (dlg.cmd_insert, dlg.cmd_close) + dlg.center(controls) + + return dlg + def _from_selection(self): - template = """\documentclass{{article}} - \\usepackage[a5paper, landscape]{{geometry}} - \\usepackage{{xcolor}} - \\usepackage{{amssymb}} - \\usepackage{{amsmath}} - \pagestyle{{empty}} - \\begin{{document}} - - \[ {} \] - - \end{{document}} - """ doc = app.active sel = doc.selection if doc.type == 'writer': sel = sel[0] data = sel.value - data = template.format(data) - path_tmp = '/tmp' - path_tex = '/tmp/test.tex' - path_pdf = '/tmp/test.pdf' - path_svg = '/tmp/test.svg' + data = TEMPLATE.format(data) + dt = app.paths.dir_tmp() + path_tex = app._P.join(dt.name, f'{self.NAME}.tex') + path_pdf = app._P.join(dt.name, f'{self.NAME}.pdf') + path_svg = app._P.join(dt.name, f'{self.NAME}.svg') app.paths.save(path_tex, data) - cmd = f'pdflatex --interaction=batchmode -output-directory={path_tmp} {path_tex}' + cmd = f'pdflatex --interaction=batchmode -output-directory="{dt.name}" "{path_tex}"' app.run(cmd) - cmd = f'pdfcrop {path_pdf} {path_pdf}' + cmd = f'pdfcrop "{path_pdf}" "{path_pdf}"' app.run(cmd) - cmd = f'pdf2svg {path_pdf} {path_svg}' + cmd = f'pdf2svg "{path_pdf}" "{path_svg}"' app.run(cmd) sel = sel.offset() @@ -82,6 +190,7 @@ class ZAZLaTex2SVG(unohelper.Base, XJobExecutor): args = {'Width': 5000, 'Height': 2000} sel.insert_image(path_svg, args) + dt.cleanup() return diff --git a/source/locales/en/LC_MESSAGES/base.po b/source/locales/en/LC_MESSAGES/base.po new file mode 100644 index 0000000..3b984cd --- /dev/null +++ b/source/locales/en/LC_MESSAGES/base.po @@ -0,0 +1,30 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR ORGANIZATION +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: \n" +"POT-Creation-Date: 2020-10-30 12:59-0600\n" +"PO-Revision-Date: 2020-10-30 13:03-0600\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: pygettext.py 1.5\n" +"X-Generator: Poedit 2.4.1\n" +"Last-Translator: \n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"Language: en\n" + +#: source/ZAZLaTex2SVG.py:15 +msgid "Not found" +msgstr "" + +#: source/ZAZLaTex2SVG.py:16 +msgid "Found" +msgstr "" + +#: source/ZAZLaTex2SVG.py:45 +msgid "Not used, if not found some application." +msgstr "" diff --git a/source/locales/es/LC_MESSAGES/base.po b/source/locales/es/LC_MESSAGES/base.po new file mode 100644 index 0000000..dfe7951 --- /dev/null +++ b/source/locales/es/LC_MESSAGES/base.po @@ -0,0 +1,32 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR ORGANIZATION +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: \n" +"POT-Creation-Date: 2020-10-30 12:59-0600\n" +"PO-Revision-Date: 2020-10-30 13:01-0600\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: pygettext.py 1.5\n" +"X-Generator: Poedit 2.4.1\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: source/ZAZLaTex2SVG.py:15 +msgid "Not found" +msgstr "No encontrado" + +#: source/ZAZLaTex2SVG.py:16 +msgid "Found" +msgstr "Encontrado" + +#: source/ZAZLaTex2SVG.py:45 +#, fuzzy +#| msgid "Not used, if not found some application" +msgid "Not used, if not found some application." +msgstr "No use, si no se encuentra alguna aplicaciĆ³n." diff --git a/source/locales/es/LC_MESSAGES/es.po~ b/source/locales/es/LC_MESSAGES/es.po~ new file mode 100644 index 0000000..c14f498 --- /dev/null +++ b/source/locales/es/LC_MESSAGES/es.po~ @@ -0,0 +1,30 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR ORGANIZATION +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: \n" +"POT-Creation-Date: 2020-10-30 12:34-0600\n" +"PO-Revision-Date: 2020-10-30 12:58-0600\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: pygettext.py 1.5\n" +"X-Generator: Poedit 2.4.1\n" +"Last-Translator: \n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"Language: es\n" + +#: source/ZAZLaTex2SVG.py:15 +msgid "Not found" +msgstr "No encontrado" + +#: source/ZAZLaTex2SVG.py:16 +msgid "Found" +msgstr "Encontrado" + +#: source/ZAZLaTex2SVG.py:45 +msgid "Not used, if not found some application" +msgstr "No use, si no se encuentra alguna aplicaciĆ³n." diff --git a/source/pythonpath/easymacro2.py b/source/pythonpath/easymacro2.py index df892ef..8777491 100644 --- a/source/pythonpath/easymacro2.py +++ b/source/pythonpath/easymacro2.py @@ -33,6 +33,7 @@ import shutil import socket import subprocess import sys +import tempfile import threading import time @@ -2618,6 +2619,7 @@ UNO_CLASSES = { class LODialog(object): + SEPARATION = 5 MODELS = { 'label': 'com.sun.star.awt.UnoControlFixedTextModel', 'link': 'com.sun.star.awt.UnoControlFixedHyperlinkModel', @@ -2642,6 +2644,8 @@ class LODialog(object): self._modal = True self._controls = {} self._color_on_focus = COLOR_ON_FOCUS + self._id = '' + self._path = '' def _create(self, args): service = 'com.sun.star.awt.DialogProvider' @@ -2688,6 +2692,28 @@ class LODialog(object): def controls(self): return self._controls + @property + def id(self): + return self._id + @id.setter + def id(self, value): + self._id = value + self._path = _P.from_id(value) + + @property + def height(self): + return self.model.Height + @height.setter + def height(self, value): + self.model.Height = value + + @property + def width(self): + return self.model.Width + @width.setter + def width(self, value): + self.model.Width = value + @property def visible(self): return self.obj.Visible @@ -2715,6 +2741,13 @@ class LODialog(object): _add_listeners(self.events, control, control.Model.Name) return + def _set_image_url(self, image): + if _P.exists(image): + return _P.to_url(image) + + path = _P.join(self._path, DIR['images'], image) + return _P.to_url(path) + def _special_properties(self, tipo, args): columns = args.pop('Columns', ()) @@ -2764,6 +2797,32 @@ class LODialog(object): self._controls[name] = control return control + def center(self, control, x=0, y=0): + w = self.width + h = self.height + + if isinstance(control, tuple): + wt = self.SEPARATION * -1 + for c in control: + wt += c.width + self.SEPARATION + x = w / 2 - wt / 2 + for c in control: + c.x = x + x = c.x + c.width + self.SEPARATION + return + + if x < 0: + x = w + x - control.width + elif x == 0: + x = w / 2 - control.width / 2 + if y < 0: + y = h + y - control.height + elif y == 0: + y = h / 2 - control.height / 2 + control.x = x + control.y = y + return + def open(self, modal=True): self._modal = modal if modal: @@ -3078,6 +3137,35 @@ class Paths(object): def home(self): return str(Path.home()) + @classproperty + def temp_dir(self): + return tempfile.gettempdir() + + @classmethod + def dir_tmp(self, only_name=False): + dt = tempfile.TemporaryDirectory() + if only_name: + dt = dt.name + return dt + + @classmethod + def tmp(cls, ext=''): + tmp = tempfile.NamedTemporaryFile(suffix=ext) + return tmp.name + + @classproperty + def python(self): + return sys.executable + + @classmethod + def config(cls, name='Work'): + """ + Return de path name in config + http://api.libreoffice.org/docs/idl/ref/interfacecom_1_1sun_1_1star_1_1util_1_1XPathSettings.html + """ + path = create_instance('com.sun.star.util.PathSettings') + return cls.to_system(getattr(path, name)) + @classmethod def replace_ext(cls, path, new_ext): p = Paths(path) @@ -3109,6 +3197,10 @@ class Paths(object): def is_dir(cls, path): return Path(path).is_dir() + @classmethod + def is_file(cls, path): + return Path(path).is_file() + @classmethod def join(cls, *paths): return str(Path(paths[0]).joinpath(*paths[1:])) @@ -3135,6 +3227,22 @@ class Paths(object): path = str(Path(uno.fileUrlToSystemPath(path)).resolve()) return path + @classmethod + def kill(cls, path): + result = True + p = Path(path) + + try: + if p.is_file(): + p.unlink() + elif p.is_dir(): + shutil.rmtree(path) + except OSError as e: + log.error(e) + result = False + + return result + @classmethod def walk(cls, path, filters=''): paths = [] @@ -3148,6 +3256,12 @@ class Paths(object): paths += files return paths + @classmethod + def from_id(cls, id_ext): + pip = CTX.getValueByName('/singletons/com.sun.star.deployment.PackageInformationProvider') + path = _P.to_system(pip.getPackageLocation(id_ext)) + return path + @classmethod def copy(cls, source, target='', name=''): p, f, n, e = _P(source).info