Add support for locales

This commit is contained in:
Mauricio Baeza 2019-09-14 17:40:07 -05:00
parent 118395df71
commit 1a5c2031f3
17 changed files with 1812 additions and 12 deletions

View File

@ -1,3 +1,7 @@
v 0.4.0 [14-sep-2019]
---------------------
- Add support for locales
v 0.3.0 [10-sep-2019]
---------------------
- Add support for dialogs

View File

@ -3,3 +3,4 @@
* Configuration
* Option panel
* Sub-menus
* Panel lateral

View File

@ -1 +1 @@
0.3.0
0.4.0

View File

@ -34,6 +34,12 @@ NAME = 'TestMacro'
# ~ Should be unique, used URL inverse
ID = 'org.myextension.test'
# ~ If you extension will be multilanguage set: True
# ~ This feature used gettext, set pythonpath and easymacro in True
USE_LOCALES = True
DOMAIN = 'base'
PATH_LOCALES = 'locales'
PUBLISHER = {
'en': {'text': 'El Mau', 'link': 'https://elmau.net'},
'es': {'text': 'El Mau', 'link': 'https://elmau.net'},
@ -131,11 +137,12 @@ EXTENSION = {
'name': NAME,
'id': ID,
'icon': (ICON, ICON_EXT),
'languages': tuple(INFO.keys())
}
# ~ If used more libraries set python path in True and copy inside
# ~ If used easymacro pythonpath always is True
# ~ If used easymacro pythonpath always is True, recommended
DIRS = {
'meta': 'META-INF',
'source': 'source',
@ -143,7 +150,8 @@ DIRS = {
'images': 'images',
'registration': 'registration',
'files': 'files',
'pythonpath': False,
'pythonpath': True,
'locales': PATH_LOCALES,
}
@ -335,6 +343,8 @@ if PARENT == 'OfficeMenuBar':
def _get_context(args):
if not args:
return ''
c = []
for v in args.split(','):
c.append(CONTEXT[v])

View File

@ -18,7 +18,8 @@
# ~ along with ZAZ. If not, see <https://www.gnu.org/licenses/>.
import ctypes
import datetime
import errno
import getpass
import logging
@ -45,6 +46,7 @@ from com.sun.star.awt import MessageBoxButtons as MSG_BUTTONS
from com.sun.star.awt.MessageBoxResults import YES
from com.sun.star.awt.PosSize import POSSIZE, SIZE
from com.sun.star.awt import Size, Point
from com.sun.star.datatransfer import XTransferable, DataFlavor
from com.sun.star.table.CellContentType import EMPTY, VALUE, TEXT, FORMULA
from com.sun.star.text.TextContentAnchorType import AS_CHARACTER
@ -79,9 +81,12 @@ log = logging.getLogger(__name__)
OS = platform.system()
USER = getpass.getuser()
PC = platform.node()
DESKTOP = os.environ.get('DESKTOP_SESSION', '')
INFO_DEBUG = '{}\n\n{}\n\n{}'.format(sys.version, platform.platform(), '\n'.join(sys.path))
IS_WIN = OS == 'Windows'
LOG_NAME = 'ZAZ'
CLIPBOARD_FORMAT_TEXT = 'text/plain;charset=utf-16'
CALC = 'calc'
WRITER = 'writer'
@ -119,10 +124,9 @@ def _get_config(key, node_name):
LANGUAGE = _get_config('ooLocale', 'org.openoffice.Setup/L10N/')
LANG = LANGUAGE.split('-')[0]
NAME = TITLE = _get_config('ooName', 'org.openoffice.Setup/Product')
VERSION = _get_config('ooSetupVersion', 'org.openoffice.Setup/Product')
INFO_DEBUG = '{}\n\n{}\n\n{}'.format(
sys.version, platform.platform(), '\n'.join(sys.path))
def mri(obj):
@ -238,6 +242,10 @@ def get_desktop():
return create_instance('com.sun.star.frame.Desktop', True)
def get_dispatch():
return create_instance('com.sun.star.frame.DispatchHelper')
def get_temp_file():
return tempfile.NamedTemporaryFile()
@ -315,6 +323,10 @@ class LODocument(object):
def title(self):
return self.obj.getTitle()
@property
def frame(self):
return self._cc.getFrame()
@property
def is_saved(self):
return self.obj.hasLocation()
@ -368,6 +380,12 @@ class LODocument(object):
w.setFocus()
return
def paste(self):
sc = create_instance('com.sun.star.datatransfer.clipboard.SystemClipboard')
transferable = sc.getContents()
self._cc.insertTransferable(transferable)
return self.obj.getCurrentSelection()
class LOCalc(LODocument):
@ -400,9 +418,14 @@ class LOCalc(LODocument):
cell = LOCellRange(self.active[index].obj, self)
return cell
# ~ def create_instance(self, name):
# ~ obj = self.obj.createInstance(name)
# ~ return obj
def select(self, rango):
r = rango
if hasattr(rango, 'obj'):
r = rango.obj
elif isinstance(rango, str):
r = self.get_cell(rango).obj
self._cc.select(r)
return
class LOCalcSheet(object):
@ -551,6 +574,11 @@ class LOBasicIde(LODocument):
def __init__(self, obj):
super().__init__(obj)
@property
def selection(self):
sel = self._cc.getSelection()
return sel
class LOCellRange(object):
@ -674,6 +702,10 @@ class LOCellRange(object):
img.setSize(Size(w, h))
return
def select(self):
self.doc._cc.select(self.obj)
return
class EventsListenerBase(unohelper.Base, XEventListener):
@ -1198,6 +1230,9 @@ def open_doc(path, **kwargs):
Password: super_secret
MacroExecutionMode: 4 = Activate macros
Preview: True or False
http://api.libreoffice.org/docs/idl/ref/interfacecom_1_1sun_1_1star_1_1frame_1_1XComponentLoader.html
http://api.libreoffice.org/docs/idl/ref/servicecom_1_1sun_1_1star_1_1document_1_1MediaDescriptor.html
"""
path = _path_url(path)
opt = _properties(kwargs)
@ -1252,12 +1287,13 @@ def run(command, wait=False):
# ~ debug(shlex.split(command))
try:
if wait:
p = subprocess.Popen(shlex.split(command), stdout=subprocess.PIPE)
p.wait()
# ~ p = subprocess.Popen(shlex.split(command), stdout=subprocess.PIPE)
# ~ p.wait()
result = subprocess.check_output(command, shell=True)
else:
p = subprocess.Popen(shlex.split(command), stdin=None,
stdout=None, stderr=None, close_fds=True)
result, er = p.communicate()
result, er = p.communicate()
except subprocess.CalledProcessError as e:
msg = ("run [ERROR]: output = %s, error code = %s\n"
% (e.output, e.returncode))
@ -1366,3 +1402,93 @@ def merge_zip(target, zips):
return True
def kill(path):
p = Path(path)
if p.is_file():
try:
p.unlink()
except:
pass
elif p.is_dir():
p.rmdir()
return
def get_size_screen():
if IS_WIN:
user32 = ctypes.windll.user32
res = '{}x{}'.format(user32.GetSystemMetrics(0), user32.GetSystemMetrics(1))
else:
args = 'xrandr | grep "*" | cut -d " " -f4'
res = run(args, True)
return res.strip()
def get_clipboard():
df = None
text = ''
sc = create_instance('com.sun.star.datatransfer.clipboard.SystemClipboard')
transferable = sc.getContents()
data = transferable.getTransferDataFlavors()
for df in data:
if df.MimeType == CLIPBOARD_FORMAT_TEXT:
break
if df:
text = transferable.getTransferData(df)
return text
class TextTransferable(unohelper.Base, XTransferable):
"""Keep clipboard data and provide them."""
def __init__(self, text):
df = DataFlavor()
df.MimeType = CLIPBOARD_FORMAT_TEXT
df.HumanPresentableName = "encoded text utf-16"
self.flavors = [df]
self.data = [text]
def getTransferData(self, flavor):
if not flavor:
return
for i, f in enumerate(self.flavors):
if flavor.MimeType == f.MimeType:
return self.data[i]
return
def getTransferDataFlavors(self):
return tuple(self.flavors)
def isDataFlavorSupported(self, flavor):
if not flavor:
return False
mtype = flavor.MimeType
for f in self.flavors:
if mtype == f.MimeType:
return True
return False
def set_clipboard(text):
ts = TextTransferable(text)
sc = create_instance('com.sun.star.datatransfer.clipboard.SystemClipboard')
sc.setContents(ts, None)
return
def copy(doc=None):
if doc is None:
doc = get_document()
if hasattr(doc, 'frame'):
frame = doc.frame
else:
frame = doc.getCurrentController().getFrame()
dispatch = get_dispatch()
dispatch.executeDispatch(frame, '.uno:Copy', '', 0, ())
return
def get_epoch():
now = datetime.datetime.now()
return int(time.mktime(now.timetuple()))

58
source/source/Addons.xcu Normal file
View File

@ -0,0 +1,58 @@
<?xml version='1.0' encoding='UTF-8'?>
<oor:component-data xmlns:oor="http://openoffice.org/2001/registry" xmlns:xs="http://www.w3.org/2001/XMLSchema" oor:name="Addons" oor:package="org.openoffice.Office">
<node oor:name="AddonUI">
<node oor:name="OfficeMenuBar">
<node oor:name="org.myextension.test" oor:op="replace">
<prop oor:name="Title" oor:type="xs:string">
<value xml:lang="en">My Extension</value>
<value xml:lang="es">Mi Extensión</value>
</prop>
<prop oor:name="Target" oor:type="xs:string">
<value>_self</value>
</prop>
<node oor:name="Submenu">
<node oor:name="org.myextension.test.101" oor:op="replace">
<prop oor:name="Title" oor:type="xs:string">
<value xml:lang="en">Option 1</value>
<value xml:lang="es">Opción 1</value>
</prop>
<prop oor:name="URL" oor:type="xs:string">
<value>service:org.myextension.test?option1</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.sheet.SpreadsheetDocument,com.sun.star.text.TextDocument</value>
</prop>
<prop oor:name="ImageIdentifier" oor:type="xs:string">
<value>%origin%/images/icon</value>
</prop>
</node>
</node>
</node>
</node>
<node oor:name="OfficeToolBar">
<node oor:name="org.myextension.test" oor:op="replace">
<node oor:name="org.myextension.test.t1" oor:op="replace">
<prop oor:name="Title" oor:type="xs:string">
<value xml:lang="en">Option 1</value>
<value xml:lang="es">Opción 1</value>
</prop>
<prop oor:name="URL" oor:type="xs:string">
<value>service:org.myextension.test?option1</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.sheet.SpreadsheetDocument,com.sun.star.text.TextDocument</value>
</prop>
<prop oor:name="ImageIdentifier" oor:type="xs:string">
<value>%origin%/images/icon</value>
</prop>
</node>
</node>
</node>
</node>
</oor:component-data>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<manifest:manifest>
<manifest:file-entry manifest:full-path="TestMacro.py" manifest:media-type="application/vnd.sun.star.uno-component;type=Python"/>
<manifest:file-entry manifest:full-path="Addons.xcu" manifest:media-type="application/vnd.sun.star.configuration-data"/>
</manifest:manifest>

View File

@ -0,0 +1,33 @@
import gettext
import uno
import unohelper
from com.sun.star.task import XJobExecutor
import easymacro as app
ID_EXTENSION = 'org.myextension.test'
SERVICE = ('com.sun.star.task.Job',)
p, *_ = app.get_info_path(__file__)
path_locales = app.join(p, 'locales')
try:
lang = gettext.translation('base', path_locales, languages=[app.LANG])
lang.install()
_ = lang.gettext
except Exception as e:
app.error(e)
class TestMacro(unohelper.Base, XJobExecutor):
def __init__(self, ctx):
self.ctx = ctx
def trigger(self, args='pyUNO'):
print('Hello World', args)
return
g_ImplementationHelper = unohelper.ImplementationHelper()
g_ImplementationHelper.addImplementation(TestMacro, ID_EXTENSION, SERVICE)

View File

@ -0,0 +1,26 @@
<?xml version='1.0' encoding='UTF-8'?>
<description xmlns="http://openoffice.org/extensions/description/2006" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:d="http://openoffice.org/extensions/description/2006">
<identifier value="org.myextension.test" />
<version value="0.1.0" />
<display-name>
<name lang="en">Test Macro</name>
<name lang="es">Macro de Prueba</name>
</display-name>
<extension-description>
<src lang="en" xlink:href="description/desc_en.txt" />
<src lang="es" xlink:href="description/desc_es.txt" />
</extension-description>
<icon>
<default xlink:href="images/testmacro.png" />
</icon>
<publisher>
<name xlink:href="https://elmau.net" lang="en">El Mau</name>
<name xlink:href="https://elmau.net" lang="es">El Mau</name>
</publisher>
<registration>
<simple-license accept-by="user" suppress-on-update="true" >
<license-text xlink:href="registration/license_en.txt" lang="en" />
<license-text xlink:href="registration/license_es.txt" lang="es" />
</simple-license>
</registration>
</description>

View File

@ -0,0 +1 @@
My great extension

View File

@ -0,0 +1 @@
Mi gran extensión

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,14 @@
This file is part of TestMacro.
TestMacro is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
TestMacro is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with TestMacro. If not, see <https://www.gnu.org/licenses/>.

View File

@ -0,0 +1,14 @@
This file is part of TestMacro.
TestMacro is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
TestMacro is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with TestMacro. If not, see <https://www.gnu.org/licenses/>.

View File

@ -20,6 +20,7 @@
import argparse
import os
import sys
from pathlib import Path
from shutil import copyfile
from subprocess import call
import zipfile
@ -32,6 +33,7 @@ from conf import (
INFO,
PATHS,
TYPE_EXTENSION,
USE_LOCALES,
log)
@ -74,6 +76,10 @@ def _compress_oxt():
z.write(fullpath, file_name, zipfile.ZIP_DEFLATED)
z.close()
if DATA['update']:
path_xml = _join(path, FILES['update'])
_save(path_xml, DATA['update'])
log.info('Extension OXT created sucesfully...')
return
@ -227,6 +233,13 @@ def _update_files():
path = _join(path_source, FILES['addin'])
_save(path, DATA['addin'])
if USE_LOCALES:
msg = "Don't forget generate DOMAIN.pot for locales"
log.info(msg)
for lang in EXTENSION['languages']:
path = _join(path_source, DIRS['locales'], lang, 'LC_MESSAGES')
Path(path).mkdir(parents=True, exist_ok=True)
_compile_idl()
return