Fix error in main

This commit is contained in:
Mauricio Baeza 2019-10-23 22:10:23 -05:00
parent 611bd77a89
commit a600b12dc4
8 changed files with 1068 additions and 124 deletions

View File

@ -1,3 +1,7 @@
v 0.4.0 [23-oct-2019]
- Fix error in main
v 0.3.0 [15-oct-2019]
---------------------
- Add menus in start application.

View File

@ -1,2 +1,2 @@
0.3.0
0.4.0

View File

@ -26,7 +26,7 @@ import logging
TYPE_EXTENSION = 1
# ~ https://semver.org/
VERSION = '0.3.0'
VERSION = '0.4.0'
# ~ Your great extension name, not used spaces
NAME = 'ZAZFavorites'

View File

@ -22,6 +22,7 @@ import csv
import ctypes
import datetime
import errno
import gettext
import getpass
import hashlib
import json
@ -40,12 +41,15 @@ import time
import traceback
import zipfile
from collections import OrderedDict
from collections.abc import MutableMapping
# ~ from collections import OrderedDict
# ~ from collections.abc import MutableMapping
from functools import wraps
from operator import itemgetter
from pathlib import Path, PurePath
from pprint import pprint
from enum import IntEnum
from urllib.request import Request, urlopen
from urllib.error import URLError, HTTPError
from string import Template
from subprocess import PIPE
@ -75,6 +79,7 @@ from com.sun.star.table.CellContentType import EMPTY, VALUE, TEXT, FORMULA
from com.sun.star.text.ControlCharacter import PARAGRAPH_BREAK
from com.sun.star.text.TextContentAnchorType import AS_CHARACTER
from com.sun.star.script import ScriptEventDescriptor
from com.sun.star.lang import XEventListener
from com.sun.star.awt import XActionListener
from com.sun.star.awt import XMouseListener
@ -87,6 +92,13 @@ from com.sun.star.awt import XKeyListener
from com.sun.star.awt import XItemListener
from com.sun.star.awt import XFocusListener
class FontSlant(IntEnum):
NONE = 0
OBLIQUE = 1
ITALIC = 2
DONTKNOW = 3
REVERSE_OBLIQUE = 4
REVERSE_ITALIC = 5
try:
from fernet import Fernet, InvalidToken
@ -94,6 +106,20 @@ except ImportError:
pass
ID_EXTENSION = ''
DIR = {
'images': 'images',
'locales': 'locales',
}
KEY = {
'enter': 1280,
}
SEPARATION = 5
MSG_LANG = {
'es': {
'OK': 'Aceptar',
@ -117,6 +143,9 @@ LOG_NAME = 'ZAZ'
CLIPBOARD_FORMAT_TEXT = 'text/plain;charset=utf-16'
PYTHON = 'python'
if IS_WIN:
PYTHON = 'python.exe'
CALC = 'calc'
WRITER = 'writer'
OBJ_CELL = 'ScCellObj'
@ -281,16 +310,17 @@ def info(data):
return
def debug(info):
def debug(*info):
if IS_WIN:
doc = get_document(FILE_NAME_DEBUG)
if doc is None:
return
doc = LogWin(doc.obj)
doc.write(info)
doc.write(str(info))
return
log.debug(str(info))
data = [str(d) for d in info]
log.debug('\t'.join(data))
return
@ -314,18 +344,17 @@ def run_in_thread(fn):
return run
def now():
return datetime.datetime.now()
def now(only_time=False):
now = datetime.datetime.now()
if only_time:
return now.time()
return now
def today():
return datetime.date.today()
def time():
return datetime.datetime.now().time()
def get_date(year, month, day, hour=-1, minute=-1, second=-1):
if hour > -1 or minute > -1 or second > -1:
h = hour
@ -578,9 +607,6 @@ class LODocument(object):
def _init_values(self):
self._type_doc = get_type_doc(self.obj)
# ~ if self._type_doc == 'base':
# ~ self._cc = self.obj.DatabaseDocument.getCurrentController()
# ~ else:
self._cc = self.obj.getCurrentController()
return
@ -701,10 +727,117 @@ class LODocument(object):
return path_pdf
class FormControlBase(object):
EVENTS = {
'action': 'actionPerformed',
'click': 'mousePressed',
}
TYPES = {
'actionPerformed': 'XActionListener',
'mousePressed': 'XMouseListener',
}
def __init__(self, obj):
self._obj = obj
self._index = -1
self._rules = {}
@property
def obj(self):
return self._obj
@property
def name(self):
return self.obj.Name
@property
def form(self):
return self.obj.getParent()
@property
def index(self):
return self._index
@index.setter
def index(self, value):
self._index = value
@property
def events(self):
return self.form.getScriptEvents(self.index)
def remove_event(self, name=''):
for ev in self.events:
if name and \
ev.EventMethod == self.EVENTS[name] and \
ev.ListenerType == self.TYPES[ev.EventMethod]:
self.form.revokeScriptEvent(self.index,
ev.ListenerType, ev.EventMethod, ev.AddListenerParam)
break
else:
self.form.revokeScriptEvent(self.index,
ev.ListenerType, ev.EventMethod, ev.AddListenerParam)
return
def add_event(self, name, macro):
if not 'name' in macro:
macro['name'] = '{}_{}'.format(self.name, name)
event = ScriptEventDescriptor()
event.AddListenerParam = ''
event.EventMethod = self.EVENTS[name]
event.ListenerType = self.TYPES[event.EventMethod]
event.ScriptCode = _get_url_script(macro)
event.ScriptType = 'Script'
for ev in self.events:
if ev.EventMethod == event.EventMethod and \
ev.ListenerType == event.ListenerType:
self.form.revokeScriptEvent(self.index,
event.ListenerType, event.EventMethod, event.AddListenerParam)
break
self.form.registerScriptEvent(self.index, event)
return
class FormButton(FormControlBase):
def __init__(self, obj):
super().__init__(obj)
class LOForm(ObjectBase):
def __init__(self, obj):
super().__init__(obj)
self._init_controls()
def __getitem__(self, index):
if isinstance(index, int):
return self._controls[index]
else:
return getattr(self, index)
def _get_type_control(self, name):
types = {
# ~ 'stardiv.Toolkit.UnoFixedTextControl': 'label',
'com.sun.star.form.OButtonModel': 'formbutton',
# ~ 'stardiv.Toolkit.UnoEditControl': 'text',
# ~ 'stardiv.Toolkit.UnoRoadmapControl': 'roadmap',
# ~ 'stardiv.Toolkit.UnoFixedHyperlinkControl': 'link',
# ~ 'stardiv.Toolkit.UnoListBoxControl': 'listbox',
}
return types[name]
def _init_controls(self):
self._controls = []
for i, c in enumerate(self.obj.ControlModels):
tipo = self._get_type_control(c.ImplementationName)
control = get_custom_class(tipo, c)
control.index = i
self._controls.append(control)
setattr(self, c.Name, control)
@property
def name(self):
@ -1235,6 +1368,42 @@ class LOWriter(LODocument):
self._cc.select(text)
return
def search(self, options):
descriptor = self.obj.createSearchDescriptor()
descriptor.setSearchString(options.get('Search', ''))
descriptor.SearchCaseSensitive = options.get('CaseSensitive', False)
descriptor.SearchWords = options.get('Words', False)
if 'Attributes' in options:
attr = dict_to_property(options['Attributes'])
descriptor.setSearchAttributes(attr)
if hasattr(descriptor, 'SearchRegularExpression'):
descriptor.SearchRegularExpression = options.get('RegularExpression', False)
if hasattr(descriptor, 'SearchType') and 'Type' in options:
descriptor.SearchType = options['Type']
if options.get('First', False):
found = self.obj.findFirst(descriptor)
else:
found = self.obj.findAll(descriptor)
return found
def replace(self, options):
descriptor = self.obj.createReplaceDescriptor()
descriptor.setSearchString(options['Search'])
descriptor.setReplaceString(options['Replace'])
descriptor.SearchCaseSensitive = options.get('CaseSensitive', False)
descriptor.SearchWords = options.get('Words', False)
if 'Attributes' in options:
attr = dict_to_property(options['Attributes'])
descriptor.setSearchAttributes(attr)
if hasattr(descriptor, 'SearchRegularExpression'):
descriptor.SearchRegularExpression = options.get('RegularExpression', False)
if hasattr(descriptor, 'SearchType') and 'Type' in options:
descriptor.SearchType = options['Type']
found = self.obj.replaceAll(descriptor)
return found
class LOTextRange(object):
@ -1779,6 +1948,36 @@ class LOCellRange(object):
chart.cell = self
return chart
def search(self, options):
descriptor = self.obj.Spreadsheet.createSearchDescriptor()
descriptor.setSearchString(options.get('Search', ''))
descriptor.SearchCaseSensitive = options.get('CaseSensitive', False)
descriptor.SearchWords = options.get('Words', False)
if hasattr(descriptor, 'SearchRegularExpression'):
descriptor.SearchRegularExpression = options.get('RegularExpression', False)
if hasattr(descriptor, 'SearchType') and 'Type' in options:
descriptor.SearchType = options['Type']
if options.get('First', False):
found = self.obj.findFirst(descriptor)
else:
found = self.obj.findAll(descriptor)
return found
def replace(self, options):
descriptor = self.obj.Spreadsheet.createReplaceDescriptor()
descriptor.setSearchString(options['Search'])
descriptor.setReplaceString(options['Replace'])
descriptor.SearchCaseSensitive = options.get('CaseSensitive', False)
descriptor.SearchWords = options.get('Words', False)
if hasattr(descriptor, 'SearchRegularExpression'):
descriptor.SearchRegularExpression = options.get('RegularExpression', False)
if hasattr(descriptor, 'SearchType') and 'Type' in options:
descriptor.SearchType = options['Type']
found = self.obj.replaceAll(descriptor)
return found
class EventsListenerBase(unohelper.Base, XEventListener):
@ -1813,7 +2012,7 @@ class EventsMouse(EventsListenerBase, XMouseListener, XMouseMotionListener):
def mousePressed(self, event):
event_name = '{}_click'.format(self._name)
if event.ClickCount == 2:
event_name = '{}_double_click'.format(name)
event_name = '{}_double_click'.format(self._name)
if hasattr(self._controller, event_name):
getattr(self._controller, event_name)(event)
return
@ -1914,6 +2113,9 @@ class EventsFocus(EventsListenerBase, XFocusListener):
super().__init__(controller, name)
def focusGained(self, event):
service = event.Source.Model.ImplementationName
if service == 'stardiv.Toolkit.UnoControlListBoxModel':
return
obj = event.Source.Model
obj.BackgroundColor = COLOR_ON_FOCUS
@ -1930,6 +2132,27 @@ class EventsKey(EventsListenerBase, XKeyListener):
event.Modifiers
"""
def __init__(self, controller, name):
super().__init__(controller, name)
def keyPressed(self, event):
pass
def keyReleased(self, event):
event_name = '{}_key_released'.format(self._name)
if hasattr(self._controller, event_name):
getattr(self._controller, event_name)(event)
return
class EventsKeyWindow(EventsListenerBase, XKeyListener):
"""
event.KeyChar
event.KeyCode
event.KeyFunc
event.Modifiers
"""
def __init__(self, cls):
super().__init__(cls.events, cls.name)
self._cls = cls
@ -2023,7 +2246,6 @@ class EventsMenu(EventsListenerBase, XMenuListener):
def itemHighlighted(self, event):
pass
@catch_exception
def itemSelected(self, event):
name = event.Source.getCommand(event.MenuId)
if name.startswith('menu'):
@ -2122,6 +2344,20 @@ class UnoBaseObject(object):
def tag(self, value):
self.model.Tag = value
@property
def visible(self):
return self.obj.Visible
@visible.setter
def visible(self, value):
self.obj.setVisible(value)
@property
def enabled(self):
return self.model.Enabled
@enabled.setter
def enabled(self, value):
self.model.Enabled = value
@property
def step(self):
return self.model.Step
@ -2160,16 +2396,17 @@ class UnoBaseObject(object):
return
def move(self, origin, x=0, y=5):
w = 0
h = 0
if x:
w = origin.width
self.x = origin.x + origin.width + x
if y:
h = origin.height
x = origin.x + x + w
y = origin.y + y + h
self.x = x
self.y = y
self.y = origin.y + origin.height + y
return
def possize(self, origin):
self.x = origin.x
self.y = origin.y
self.width = origin.width
self.height = origin.height
return
@ -2242,7 +2479,6 @@ class UnoListBox(UnoBaseObject):
def __init__(self, obj):
super().__init__(obj)
self._data = []
@property
def type(self):
@ -2250,15 +2486,55 @@ class UnoListBox(UnoBaseObject):
@property
def value(self):
return self.obj.SelectedItem
return self.obj.getSelectedItem()
@property
def count(self):
return len(self.data)
@property
def data(self):
return self._data
return self.model.StringItemList
@data.setter
def data(self, values):
self._data = list(sorted(values))
self.model.StringItemList = self.data
self.model.StringItemList = list(sorted(values))
return
def unselect(self):
self.obj.selectItem(self.value, False)
return
def select(self, pos=0):
if isinstance(pos, str):
self.obj.selectItem(pos, True)
else:
self.obj.selectItemPos(pos, True)
return
def clear(self):
self.model.removeAllItems()
return
def _set_image_url(self, image):
if exists_path(image):
return _path_url(image)
if not ID_EXTENSION:
return ''
path = get_path_extension(ID_EXTENSION)
path = join(path, DIR['images'], image)
return _path_url(path)
def insert(self, value, path='', pos=-1, show=True):
if pos < 0:
pos = self.count
if path:
self.model.insertItem(pos, value, self._set_image_url(path))
else:
self.model.insertItemText(pos, value)
if show:
self.select(pos)
return
@ -2393,11 +2669,75 @@ class UnoRoadmap(UnoBaseObject):
self.model.insertByIndex(i, opt)
return
@property
def enabled(self):
return True
@enabled.setter
def enabled(self, value):
for m in self.model:
m.Enabled = value
return
def set_enabled(self, index, value):
self.model.getByIndex(index).Enabled = value
return
class UnoTree(UnoBaseObject):
@catch_exception
def __init__(self, obj, ):
super().__init__(obj)
self._tdm = None
self._data = []
@property
def selection(self):
return self.obj.Selection
@property
def root(self):
if self._tdm is None:
return ''
return self._tdm.Root.DisplayValue
@root.setter
def root(self, value):
self._add_data_model(value)
def _add_data_model(self, name):
tdm = create_instance('com.sun.star.awt.tree.MutableTreeDataModel')
root = tdm.createNode(name, True)
root.DataValue = 0
tdm.setRoot(root)
self.model.DataModel = tdm
self._tdm = self.model.DataModel
self._add_data()
return
@property
def data(self):
return self._data
@data.setter
def data(self, values):
self._data = list(values)
self._add_data()
def _add_data(self):
if not self.data:
return
parents = {}
for node in self.data:
parent = parents.get(node[1], self._tdm.Root)
child = self._tdm.createNode(node[2], False)
child.DataValue = node[0]
parent.appendChild(child)
parents[node[0]] = child
self.obj.expandNode(self._tdm.Root)
return
def get_custom_class(tipo, obj):
classes = {
'label': UnoLabel,
@ -2407,11 +2747,12 @@ def get_custom_class(tipo, obj):
'grid': UnoGrid,
'link': UnoLabelLink,
'roadmap': UnoRoadmap,
'tree': UnoTree,
# ~ 'tab': UnoTab,
# ~ 'image': UnoImage,
# ~ 'radio': UnoRadio,
# ~ 'groupbox': UnoGroupBox,
# ~ 'tree': UnoTree,
'formbutton': FormButton,
}
return classes[tipo](obj)
@ -2422,6 +2763,7 @@ def add_listeners(events, control, name=''):
'addMouseListener': EventsMouse,
'addItemListener': EventsItem,
'addFocusListener': EventsFocus,
'addKeyListener': EventsKey,
}
if hasattr(control, 'obj'):
control = contro.obj
@ -2441,6 +2783,7 @@ def add_listeners(events, control, name=''):
if is_roadmap and key == 'addItemListener':
control.addItemListener(EventsItemRoadmap(events, name))
continue
getattr(control, key)(listeners[key](events, name))
return
@ -2893,6 +3236,8 @@ class LODialog(object):
self._init_controls()
self._events = None
self._color_on_focus = -1
self._id_extension = ''
self._images = 'images'
return
def _create(self, properties):
@ -2928,10 +3273,11 @@ class LODialog(object):
def _get_type_control(self, name):
types = {
'stardiv.Toolkit.UnoFixedTextControl': 'label',
'stardiv.Toolkit.UnoButtonControl': 'button',
'stardiv.Toolkit.UnoEditControl': 'text',
'stardiv.Toolkit.UnoRoadmapControl': 'roadmap',
'stardiv.Toolkit.UnoFixedHyperlinkControl': 'link',
'stardiv.Toolkit.UnoEditControl': 'text',
'stardiv.Toolkit.UnoButtonControl': 'button',
'stardiv.Toolkit.UnoListBoxControl': 'listbox',
'stardiv.Toolkit.UnoRoadmapControl': 'roadmap',
}
return types[name]
@ -2951,6 +3297,22 @@ class LODialog(object):
def model(self):
return self._model
@property
def id_extension(self):
return self._id_extension
@id_extension.setter
def id_extension(self, value):
global ID_EXTENSION
ID_EXTENSION = value
self._id_extension = value
@property
def images(self):
return self._images
@images.setter
def images(self, value):
self._images = value
@property
def height(self):
return self.model.Height
@ -2958,6 +3320,13 @@ class LODialog(object):
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 color_on_focus(self):
return self._color_on_focus
@ -2995,17 +3364,17 @@ class LODialog(object):
def _get_control_model(self, control):
services = {
'button': 'com.sun.star.awt.UnoControlButtonModel',
'grid': 'com.sun.star.awt.grid.UnoControlGridModel',
'groupbox': 'com.sun.star.awt.UnoControlGroupBoxModel',
'image': 'com.sun.star.awt.UnoControlImageControlModel',
'label': 'com.sun.star.awt.UnoControlFixedTextModel',
'link': 'com.sun.star.awt.UnoControlFixedHyperlinkModel',
'listbox': 'com.sun.star.awt.UnoControlListBoxModel',
'radio': 'com.sun.star.awt.UnoControlRadioButtonModel',
'roadmap': 'com.sun.star.awt.UnoControlRoadmapModel',
'text': 'com.sun.star.awt.UnoControlEditModel',
'listbox': 'com.sun.star.awt.UnoControlListBoxModel',
'button': 'com.sun.star.awt.UnoControlButtonModel',
'roadmap': 'com.sun.star.awt.UnoControlRoadmapModel',
'grid': 'com.sun.star.awt.grid.UnoControlGridModel',
'tree': 'com.sun.star.awt.tree.TreeControlModel',
'groupbox': 'com.sun.star.awt.UnoControlGroupBoxModel',
'image': 'com.sun.star.awt.UnoControlImageControlModel',
'radio': 'com.sun.star.awt.UnoControlRadioButtonModel',
}
return services[control]
@ -3019,10 +3388,16 @@ class LODialog(object):
column_model.addColumn(grid_column)
return column_model
def _set_image_url(self, path):
if exists_path(path):
return _path_url(path)
return ''
def _set_image_url(self, image):
if exists_path(image):
return _path_url(image)
if not self.id_extension:
return ''
path = get_path_extension(self.id_extension)
path = join(path, self.images, image)
return _path_url(path)
def _special_properties(self, tipo, properties):
columns = properties.pop('Columns', ())
@ -3030,12 +3405,17 @@ class LODialog(object):
properties['ColumnModel'] = self._set_column_model(columns)
elif tipo == 'button' and 'ImageURL' in properties:
properties['ImageURL'] = self._set_image_url(properties['ImageURL'])
elif tipo == 'roadmap' and not 'Height' in properties:
properties['Height'] = self.height
elif tipo == 'roadmap':
if not 'Height' in properties:
properties['Height'] = self.height
if 'Title' in properties:
properties['Text'] = properties.pop('Title')
return properties
def add_control(self, properties):
tipo = properties.pop('Type').lower()
root = properties.pop('Root', '')
properties = self._special_properties(tipo, properties)
model = self.model.createInstance(self._get_control_model(tipo))
set_properties(model, properties)
@ -3044,9 +3424,39 @@ class LODialog(object):
control = self.obj.getControl(name)
add_listeners(self.events, control, name)
control = get_custom_class(tipo, control)
if tipo == 'tree' and root:
control.root = root
setattr(self, name, control)
return
def center(self, control, x=0, y=0):
w = self.width
h = self.height
if isinstance(control, tuple):
wt = SEPARATION * -1
for c in control:
wt += c.width + SEPARATION
x = w / 2 - wt / 2
for c in control:
c.x = x
x = c.x + c.width + 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
class LOWindow(object):
@ -3175,7 +3585,7 @@ class LOWindow(object):
controller = EventsWindow(self)
self._window.addTopWindowListener(controller)
self._window.addWindowListener(controller)
self._container.addKeyListener(EventsKey(self))
self._container.addKeyListener(EventsKeyWindow(self))
return
@property
@ -3236,7 +3646,7 @@ def get_document(title=''):
return doc
for d in desktop.getComponents():
if d.Title == title:
if hasattr(d, 'Title') and d.Title == title:
doc = d
break
@ -3294,6 +3704,11 @@ def get_config_path(name='Work'):
return _path_system(getattr(path, name))
def get_path_python():
path = get_config_path('Module')
return join(path, PYTHON)
# ~ Export ok
def get_file(init_dir='', multiple=False, filters=()):
"""
@ -3424,6 +3839,10 @@ def get_path_extension(id):
return path
def get_home():
return Path.home()
# ~ Export ok
def inputbox(message, default='', title=TITLE, echochar=''):
@ -3602,13 +4021,39 @@ def zip_content(path):
return names
def popen(command, stdin=None):
try:
proc = subprocess.Popen(shlex.split(command), shell=IS_WIN,
stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
for line in proc.stdout:
yield line.decode().rstrip()
except Exception as e:
error(e)
yield (e.errno, e.strerror)
def url_open(url, options={}, json=False):
data = ''
req = Request(url)
try:
response = urlopen(req)
# ~ response.info()
except HTTPError as e:
error(e)
except URLError as e:
error(e.reason)
else:
if json:
data = json_loads(response.read())
else:
data = response.read()
return data
def run(command, wait=False):
# ~ debug(command)
# ~ debug(shlex.split(command))
try:
if 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,
@ -4223,6 +4668,24 @@ def format(template, data):
return result
def _get_url_script(macro):
macro['language'] = macro.get('language', 'Python')
macro['location'] = macro.get('location', 'user')
data = macro.copy()
if data['language'] == 'Python':
data['module'] = '.py$'
elif data['language'] == 'Basic':
data['module'] = '.{}.'.format(macro['module'])
if macro['location'] == 'user':
data['location'] = 'application'
else:
data['module'] = '.'
url = 'vnd.sun.star.script:{library}{module}{name}?language={language}&location={location}'
path = url.format(**data)
return path
def _call_macro(macro):
#~ https://wiki.openoffice.org/wiki/Documentation/DevGuide/Scripting/Scripting_Framework_URI_Specification
name = 'com.sun.star.script.provider.MasterScriptProviderFactory'
@ -4243,6 +4706,7 @@ def _call_macro(macro):
args = macro.get('args', ())
url = 'vnd.sun.star.script:{library}{module}{name}?language={language}&location={location}'
path = url.format(**data)
script = factory.createScriptProvider('').getScript(path)
return script.invoke(args, None, None)[0]
@ -4469,6 +4933,7 @@ def import_csv(path, **kwargs):
rows = tuple(csv.reader(f, **kwargs))
return rows
def export_csv(path, data, **kwargs):
with open(path, 'w') as f:
writer = csv.writer(f, **kwargs)
@ -4476,6 +4941,19 @@ def export_csv(path, data, **kwargs):
return
def install_locales(path, domain='base', dir_locales=DIR['locales']):
p, *_ = get_info_path(path)
path_locales = join(p, dir_locales)
try:
lang = gettext.translation(domain, path_locales, languages=[LANG])
lang.install()
_ = lang.gettext
except Exception as e:
from gettext import gettext as _
error(e)
return _
class LIBOServer(object):
HOST = 'localhost'
PORT = '8100'
@ -4555,12 +5033,9 @@ class LIBOServer(object):
# ~ 'CurrencyField': 'com.sun.star.awt.UnoControlCurrencyFieldModel',
# ~ 'DateField': 'com.sun.star.awt.UnoControlDateFieldModel',
# ~ 'FileControl': 'com.sun.star.awt.UnoControlFileControlModel',
# ~ 'FixedLine': 'com.sun.star.awt.UnoControlFixedLineModel',
# ~ 'FixedText': 'com.sun.star.awt.UnoControlFixedTextModel',
# ~ 'FormattedField': 'com.sun.star.awt.UnoControlFormattedFieldModel',
# ~ 'GroupBox': 'com.sun.star.awt.UnoControlGroupBoxModel',
# ~ 'ImageControl': 'com.sun.star.awt.UnoControlImageControlModel',
# ~ 'ListBox': 'com.sun.star.awt.UnoControlListBoxModel',
# ~ 'NumericField': 'com.sun.star.awt.UnoControlNumericFieldModel',
# ~ 'PatternField': 'com.sun.star.awt.UnoControlPatternFieldModel',
# ~ 'ProgressBar': 'com.sun.star.awt.UnoControlProgressBarModel',

Binary file not shown.

View File

@ -1,4 +1,3 @@
import gettext
import uno
import unohelper
from com.sun.star.task import XJobExecutor
@ -9,16 +8,7 @@ ID_EXTENSION = 'net.elmau.zaz.Favorites'
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:
from gettext import gettext as _
app.error(e)
app.debug(app.LANGUAGE)
_ = app.install_locales(__file__)
class Controllers(object):

View File

@ -1,7 +1,7 @@
<?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="net.elmau.zaz.Favorites" />
<version value="0.3.0" />
<version value="0.4.0" />
<display-name>
<name lang="en">Favorites files</name>
<name lang="es">Archivos favoritos</name>

View File

@ -22,6 +22,7 @@ import csv
import ctypes
import datetime
import errno
import gettext
import getpass
import hashlib
import json
@ -40,12 +41,15 @@ import time
import traceback
import zipfile
from collections import OrderedDict
from collections.abc import MutableMapping
# ~ from collections import OrderedDict
# ~ from collections.abc import MutableMapping
from functools import wraps
from operator import itemgetter
from pathlib import Path, PurePath
from pprint import pprint
from enum import IntEnum
from urllib.request import Request, urlopen
from urllib.error import URLError, HTTPError
from string import Template
from subprocess import PIPE
@ -75,6 +79,7 @@ from com.sun.star.table.CellContentType import EMPTY, VALUE, TEXT, FORMULA
from com.sun.star.text.ControlCharacter import PARAGRAPH_BREAK
from com.sun.star.text.TextContentAnchorType import AS_CHARACTER
from com.sun.star.script import ScriptEventDescriptor
from com.sun.star.lang import XEventListener
from com.sun.star.awt import XActionListener
from com.sun.star.awt import XMouseListener
@ -87,6 +92,13 @@ from com.sun.star.awt import XKeyListener
from com.sun.star.awt import XItemListener
from com.sun.star.awt import XFocusListener
class FontSlant(IntEnum):
NONE = 0
OBLIQUE = 1
ITALIC = 2
DONTKNOW = 3
REVERSE_OBLIQUE = 4
REVERSE_ITALIC = 5
try:
from fernet import Fernet, InvalidToken
@ -94,6 +106,20 @@ except ImportError:
pass
ID_EXTENSION = ''
DIR = {
'images': 'images',
'locales': 'locales',
}
KEY = {
'enter': 1280,
}
SEPARATION = 5
MSG_LANG = {
'es': {
'OK': 'Aceptar',
@ -117,6 +143,9 @@ LOG_NAME = 'ZAZ'
CLIPBOARD_FORMAT_TEXT = 'text/plain;charset=utf-16'
PYTHON = 'python'
if IS_WIN:
PYTHON = 'python.exe'
CALC = 'calc'
WRITER = 'writer'
OBJ_CELL = 'ScCellObj'
@ -281,16 +310,17 @@ def info(data):
return
def debug(info):
def debug(*info):
if IS_WIN:
doc = get_document(FILE_NAME_DEBUG)
if doc is None:
return
doc = LogWin(doc.obj)
doc.write(info)
doc.write(str(info))
return
log.debug(str(info))
data = [str(d) for d in info]
log.debug('\t'.join(data))
return
@ -314,18 +344,17 @@ def run_in_thread(fn):
return run
def now():
return datetime.datetime.now()
def now(only_time=False):
now = datetime.datetime.now()
if only_time:
return now.time()
return now
def today():
return datetime.date.today()
def time():
return datetime.datetime.now().time()
def get_date(year, month, day, hour=-1, minute=-1, second=-1):
if hour > -1 or minute > -1 or second > -1:
h = hour
@ -578,9 +607,6 @@ class LODocument(object):
def _init_values(self):
self._type_doc = get_type_doc(self.obj)
# ~ if self._type_doc == 'base':
# ~ self._cc = self.obj.DatabaseDocument.getCurrentController()
# ~ else:
self._cc = self.obj.getCurrentController()
return
@ -701,10 +727,117 @@ class LODocument(object):
return path_pdf
class FormControlBase(object):
EVENTS = {
'action': 'actionPerformed',
'click': 'mousePressed',
}
TYPES = {
'actionPerformed': 'XActionListener',
'mousePressed': 'XMouseListener',
}
def __init__(self, obj):
self._obj = obj
self._index = -1
self._rules = {}
@property
def obj(self):
return self._obj
@property
def name(self):
return self.obj.Name
@property
def form(self):
return self.obj.getParent()
@property
def index(self):
return self._index
@index.setter
def index(self, value):
self._index = value
@property
def events(self):
return self.form.getScriptEvents(self.index)
def remove_event(self, name=''):
for ev in self.events:
if name and \
ev.EventMethod == self.EVENTS[name] and \
ev.ListenerType == self.TYPES[ev.EventMethod]:
self.form.revokeScriptEvent(self.index,
ev.ListenerType, ev.EventMethod, ev.AddListenerParam)
break
else:
self.form.revokeScriptEvent(self.index,
ev.ListenerType, ev.EventMethod, ev.AddListenerParam)
return
def add_event(self, name, macro):
if not 'name' in macro:
macro['name'] = '{}_{}'.format(self.name, name)
event = ScriptEventDescriptor()
event.AddListenerParam = ''
event.EventMethod = self.EVENTS[name]
event.ListenerType = self.TYPES[event.EventMethod]
event.ScriptCode = _get_url_script(macro)
event.ScriptType = 'Script'
for ev in self.events:
if ev.EventMethod == event.EventMethod and \
ev.ListenerType == event.ListenerType:
self.form.revokeScriptEvent(self.index,
event.ListenerType, event.EventMethod, event.AddListenerParam)
break
self.form.registerScriptEvent(self.index, event)
return
class FormButton(FormControlBase):
def __init__(self, obj):
super().__init__(obj)
class LOForm(ObjectBase):
def __init__(self, obj):
super().__init__(obj)
self._init_controls()
def __getitem__(self, index):
if isinstance(index, int):
return self._controls[index]
else:
return getattr(self, index)
def _get_type_control(self, name):
types = {
# ~ 'stardiv.Toolkit.UnoFixedTextControl': 'label',
'com.sun.star.form.OButtonModel': 'formbutton',
# ~ 'stardiv.Toolkit.UnoEditControl': 'text',
# ~ 'stardiv.Toolkit.UnoRoadmapControl': 'roadmap',
# ~ 'stardiv.Toolkit.UnoFixedHyperlinkControl': 'link',
# ~ 'stardiv.Toolkit.UnoListBoxControl': 'listbox',
}
return types[name]
def _init_controls(self):
self._controls = []
for i, c in enumerate(self.obj.ControlModels):
tipo = self._get_type_control(c.ImplementationName)
control = get_custom_class(tipo, c)
control.index = i
self._controls.append(control)
setattr(self, c.Name, control)
@property
def name(self):
@ -1235,6 +1368,42 @@ class LOWriter(LODocument):
self._cc.select(text)
return
def search(self, options):
descriptor = self.obj.createSearchDescriptor()
descriptor.setSearchString(options.get('Search', ''))
descriptor.SearchCaseSensitive = options.get('CaseSensitive', False)
descriptor.SearchWords = options.get('Words', False)
if 'Attributes' in options:
attr = dict_to_property(options['Attributes'])
descriptor.setSearchAttributes(attr)
if hasattr(descriptor, 'SearchRegularExpression'):
descriptor.SearchRegularExpression = options.get('RegularExpression', False)
if hasattr(descriptor, 'SearchType') and 'Type' in options:
descriptor.SearchType = options['Type']
if options.get('First', False):
found = self.obj.findFirst(descriptor)
else:
found = self.obj.findAll(descriptor)
return found
def replace(self, options):
descriptor = self.obj.createReplaceDescriptor()
descriptor.setSearchString(options['Search'])
descriptor.setReplaceString(options['Replace'])
descriptor.SearchCaseSensitive = options.get('CaseSensitive', False)
descriptor.SearchWords = options.get('Words', False)
if 'Attributes' in options:
attr = dict_to_property(options['Attributes'])
descriptor.setSearchAttributes(attr)
if hasattr(descriptor, 'SearchRegularExpression'):
descriptor.SearchRegularExpression = options.get('RegularExpression', False)
if hasattr(descriptor, 'SearchType') and 'Type' in options:
descriptor.SearchType = options['Type']
found = self.obj.replaceAll(descriptor)
return found
class LOTextRange(object):
@ -1779,6 +1948,36 @@ class LOCellRange(object):
chart.cell = self
return chart
def search(self, options):
descriptor = self.obj.Spreadsheet.createSearchDescriptor()
descriptor.setSearchString(options.get('Search', ''))
descriptor.SearchCaseSensitive = options.get('CaseSensitive', False)
descriptor.SearchWords = options.get('Words', False)
if hasattr(descriptor, 'SearchRegularExpression'):
descriptor.SearchRegularExpression = options.get('RegularExpression', False)
if hasattr(descriptor, 'SearchType') and 'Type' in options:
descriptor.SearchType = options['Type']
if options.get('First', False):
found = self.obj.findFirst(descriptor)
else:
found = self.obj.findAll(descriptor)
return found
def replace(self, options):
descriptor = self.obj.Spreadsheet.createReplaceDescriptor()
descriptor.setSearchString(options['Search'])
descriptor.setReplaceString(options['Replace'])
descriptor.SearchCaseSensitive = options.get('CaseSensitive', False)
descriptor.SearchWords = options.get('Words', False)
if hasattr(descriptor, 'SearchRegularExpression'):
descriptor.SearchRegularExpression = options.get('RegularExpression', False)
if hasattr(descriptor, 'SearchType') and 'Type' in options:
descriptor.SearchType = options['Type']
found = self.obj.replaceAll(descriptor)
return found
class EventsListenerBase(unohelper.Base, XEventListener):
@ -1813,7 +2012,7 @@ class EventsMouse(EventsListenerBase, XMouseListener, XMouseMotionListener):
def mousePressed(self, event):
event_name = '{}_click'.format(self._name)
if event.ClickCount == 2:
event_name = '{}_double_click'.format(name)
event_name = '{}_double_click'.format(self._name)
if hasattr(self._controller, event_name):
getattr(self._controller, event_name)(event)
return
@ -1914,6 +2113,9 @@ class EventsFocus(EventsListenerBase, XFocusListener):
super().__init__(controller, name)
def focusGained(self, event):
service = event.Source.Model.ImplementationName
if service == 'stardiv.Toolkit.UnoControlListBoxModel':
return
obj = event.Source.Model
obj.BackgroundColor = COLOR_ON_FOCUS
@ -1930,6 +2132,27 @@ class EventsKey(EventsListenerBase, XKeyListener):
event.Modifiers
"""
def __init__(self, controller, name):
super().__init__(controller, name)
def keyPressed(self, event):
pass
def keyReleased(self, event):
event_name = '{}_key_released'.format(self._name)
if hasattr(self._controller, event_name):
getattr(self._controller, event_name)(event)
return
class EventsKeyWindow(EventsListenerBase, XKeyListener):
"""
event.KeyChar
event.KeyCode
event.KeyFunc
event.Modifiers
"""
def __init__(self, cls):
super().__init__(cls.events, cls.name)
self._cls = cls
@ -2023,7 +2246,6 @@ class EventsMenu(EventsListenerBase, XMenuListener):
def itemHighlighted(self, event):
pass
@catch_exception
def itemSelected(self, event):
name = event.Source.getCommand(event.MenuId)
if name.startswith('menu'):
@ -2122,6 +2344,20 @@ class UnoBaseObject(object):
def tag(self, value):
self.model.Tag = value
@property
def visible(self):
return self.obj.Visible
@visible.setter
def visible(self, value):
self.obj.setVisible(value)
@property
def enabled(self):
return self.model.Enabled
@enabled.setter
def enabled(self, value):
self.model.Enabled = value
@property
def step(self):
return self.model.Step
@ -2160,16 +2396,17 @@ class UnoBaseObject(object):
return
def move(self, origin, x=0, y=5):
w = 0
h = 0
if x:
w = origin.width
self.x = origin.x + origin.width + x
if y:
h = origin.height
x = origin.x + x + w
y = origin.y + y + h
self.x = x
self.y = y
self.y = origin.y + origin.height + y
return
def possize(self, origin):
self.x = origin.x
self.y = origin.y
self.width = origin.width
self.height = origin.height
return
@ -2242,7 +2479,6 @@ class UnoListBox(UnoBaseObject):
def __init__(self, obj):
super().__init__(obj)
self._data = []
@property
def type(self):
@ -2250,15 +2486,55 @@ class UnoListBox(UnoBaseObject):
@property
def value(self):
return self.obj.SelectedItem
return self.obj.getSelectedItem()
@property
def count(self):
return len(self.data)
@property
def data(self):
return self._data
return self.model.StringItemList
@data.setter
def data(self, values):
self._data = list(sorted(values))
self.model.StringItemList = self.data
self.model.StringItemList = list(sorted(values))
return
def unselect(self):
self.obj.selectItem(self.value, False)
return
def select(self, pos=0):
if isinstance(pos, str):
self.obj.selectItem(pos, True)
else:
self.obj.selectItemPos(pos, True)
return
def clear(self):
self.model.removeAllItems()
return
def _set_image_url(self, image):
if exists_path(image):
return _path_url(image)
if not ID_EXTENSION:
return ''
path = get_path_extension(ID_EXTENSION)
path = join(path, DIR['images'], image)
return _path_url(path)
def insert(self, value, path='', pos=-1, show=True):
if pos < 0:
pos = self.count
if path:
self.model.insertItem(pos, value, self._set_image_url(path))
else:
self.model.insertItemText(pos, value)
if show:
self.select(pos)
return
@ -2393,11 +2669,75 @@ class UnoRoadmap(UnoBaseObject):
self.model.insertByIndex(i, opt)
return
@property
def enabled(self):
return True
@enabled.setter
def enabled(self, value):
for m in self.model:
m.Enabled = value
return
def set_enabled(self, index, value):
self.model.getByIndex(index).Enabled = value
return
class UnoTree(UnoBaseObject):
@catch_exception
def __init__(self, obj, ):
super().__init__(obj)
self._tdm = None
self._data = []
@property
def selection(self):
return self.obj.Selection
@property
def root(self):
if self._tdm is None:
return ''
return self._tdm.Root.DisplayValue
@root.setter
def root(self, value):
self._add_data_model(value)
def _add_data_model(self, name):
tdm = create_instance('com.sun.star.awt.tree.MutableTreeDataModel')
root = tdm.createNode(name, True)
root.DataValue = 0
tdm.setRoot(root)
self.model.DataModel = tdm
self._tdm = self.model.DataModel
self._add_data()
return
@property
def data(self):
return self._data
@data.setter
def data(self, values):
self._data = list(values)
self._add_data()
def _add_data(self):
if not self.data:
return
parents = {}
for node in self.data:
parent = parents.get(node[1], self._tdm.Root)
child = self._tdm.createNode(node[2], False)
child.DataValue = node[0]
parent.appendChild(child)
parents[node[0]] = child
self.obj.expandNode(self._tdm.Root)
return
def get_custom_class(tipo, obj):
classes = {
'label': UnoLabel,
@ -2407,11 +2747,12 @@ def get_custom_class(tipo, obj):
'grid': UnoGrid,
'link': UnoLabelLink,
'roadmap': UnoRoadmap,
'tree': UnoTree,
# ~ 'tab': UnoTab,
# ~ 'image': UnoImage,
# ~ 'radio': UnoRadio,
# ~ 'groupbox': UnoGroupBox,
# ~ 'tree': UnoTree,
'formbutton': FormButton,
}
return classes[tipo](obj)
@ -2422,6 +2763,7 @@ def add_listeners(events, control, name=''):
'addMouseListener': EventsMouse,
'addItemListener': EventsItem,
'addFocusListener': EventsFocus,
'addKeyListener': EventsKey,
}
if hasattr(control, 'obj'):
control = contro.obj
@ -2441,6 +2783,7 @@ def add_listeners(events, control, name=''):
if is_roadmap and key == 'addItemListener':
control.addItemListener(EventsItemRoadmap(events, name))
continue
getattr(control, key)(listeners[key](events, name))
return
@ -2893,6 +3236,8 @@ class LODialog(object):
self._init_controls()
self._events = None
self._color_on_focus = -1
self._id_extension = ''
self._images = 'images'
return
def _create(self, properties):
@ -2928,10 +3273,11 @@ class LODialog(object):
def _get_type_control(self, name):
types = {
'stardiv.Toolkit.UnoFixedTextControl': 'label',
'stardiv.Toolkit.UnoButtonControl': 'button',
'stardiv.Toolkit.UnoEditControl': 'text',
'stardiv.Toolkit.UnoRoadmapControl': 'roadmap',
'stardiv.Toolkit.UnoFixedHyperlinkControl': 'link',
'stardiv.Toolkit.UnoEditControl': 'text',
'stardiv.Toolkit.UnoButtonControl': 'button',
'stardiv.Toolkit.UnoListBoxControl': 'listbox',
'stardiv.Toolkit.UnoRoadmapControl': 'roadmap',
}
return types[name]
@ -2951,6 +3297,22 @@ class LODialog(object):
def model(self):
return self._model
@property
def id_extension(self):
return self._id_extension
@id_extension.setter
def id_extension(self, value):
global ID_EXTENSION
ID_EXTENSION = value
self._id_extension = value
@property
def images(self):
return self._images
@images.setter
def images(self, value):
self._images = value
@property
def height(self):
return self.model.Height
@ -2958,6 +3320,13 @@ class LODialog(object):
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 color_on_focus(self):
return self._color_on_focus
@ -2995,17 +3364,17 @@ class LODialog(object):
def _get_control_model(self, control):
services = {
'button': 'com.sun.star.awt.UnoControlButtonModel',
'grid': 'com.sun.star.awt.grid.UnoControlGridModel',
'groupbox': 'com.sun.star.awt.UnoControlGroupBoxModel',
'image': 'com.sun.star.awt.UnoControlImageControlModel',
'label': 'com.sun.star.awt.UnoControlFixedTextModel',
'link': 'com.sun.star.awt.UnoControlFixedHyperlinkModel',
'listbox': 'com.sun.star.awt.UnoControlListBoxModel',
'radio': 'com.sun.star.awt.UnoControlRadioButtonModel',
'roadmap': 'com.sun.star.awt.UnoControlRoadmapModel',
'text': 'com.sun.star.awt.UnoControlEditModel',
'listbox': 'com.sun.star.awt.UnoControlListBoxModel',
'button': 'com.sun.star.awt.UnoControlButtonModel',
'roadmap': 'com.sun.star.awt.UnoControlRoadmapModel',
'grid': 'com.sun.star.awt.grid.UnoControlGridModel',
'tree': 'com.sun.star.awt.tree.TreeControlModel',
'groupbox': 'com.sun.star.awt.UnoControlGroupBoxModel',
'image': 'com.sun.star.awt.UnoControlImageControlModel',
'radio': 'com.sun.star.awt.UnoControlRadioButtonModel',
}
return services[control]
@ -3019,10 +3388,16 @@ class LODialog(object):
column_model.addColumn(grid_column)
return column_model
def _set_image_url(self, path):
if exists_path(path):
return _path_url(path)
return ''
def _set_image_url(self, image):
if exists_path(image):
return _path_url(image)
if not self.id_extension:
return ''
path = get_path_extension(self.id_extension)
path = join(path, self.images, image)
return _path_url(path)
def _special_properties(self, tipo, properties):
columns = properties.pop('Columns', ())
@ -3030,12 +3405,17 @@ class LODialog(object):
properties['ColumnModel'] = self._set_column_model(columns)
elif tipo == 'button' and 'ImageURL' in properties:
properties['ImageURL'] = self._set_image_url(properties['ImageURL'])
elif tipo == 'roadmap' and not 'Height' in properties:
properties['Height'] = self.height
elif tipo == 'roadmap':
if not 'Height' in properties:
properties['Height'] = self.height
if 'Title' in properties:
properties['Text'] = properties.pop('Title')
return properties
def add_control(self, properties):
tipo = properties.pop('Type').lower()
root = properties.pop('Root', '')
properties = self._special_properties(tipo, properties)
model = self.model.createInstance(self._get_control_model(tipo))
set_properties(model, properties)
@ -3044,9 +3424,39 @@ class LODialog(object):
control = self.obj.getControl(name)
add_listeners(self.events, control, name)
control = get_custom_class(tipo, control)
if tipo == 'tree' and root:
control.root = root
setattr(self, name, control)
return
def center(self, control, x=0, y=0):
w = self.width
h = self.height
if isinstance(control, tuple):
wt = SEPARATION * -1
for c in control:
wt += c.width + SEPARATION
x = w / 2 - wt / 2
for c in control:
c.x = x
x = c.x + c.width + 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
class LOWindow(object):
@ -3175,7 +3585,7 @@ class LOWindow(object):
controller = EventsWindow(self)
self._window.addTopWindowListener(controller)
self._window.addWindowListener(controller)
self._container.addKeyListener(EventsKey(self))
self._container.addKeyListener(EventsKeyWindow(self))
return
@property
@ -3236,7 +3646,7 @@ def get_document(title=''):
return doc
for d in desktop.getComponents():
if d.Title == title:
if hasattr(d, 'Title') and d.Title == title:
doc = d
break
@ -3294,6 +3704,11 @@ def get_config_path(name='Work'):
return _path_system(getattr(path, name))
def get_path_python():
path = get_config_path('Module')
return join(path, PYTHON)
# ~ Export ok
def get_file(init_dir='', multiple=False, filters=()):
"""
@ -3424,6 +3839,10 @@ def get_path_extension(id):
return path
def get_home():
return Path.home()
# ~ Export ok
def inputbox(message, default='', title=TITLE, echochar=''):
@ -3602,13 +4021,39 @@ def zip_content(path):
return names
def popen(command, stdin=None):
try:
proc = subprocess.Popen(shlex.split(command), shell=IS_WIN,
stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
for line in proc.stdout:
yield line.decode().rstrip()
except Exception as e:
error(e)
yield (e.errno, e.strerror)
def url_open(url, options={}, json=False):
data = ''
req = Request(url)
try:
response = urlopen(req)
# ~ response.info()
except HTTPError as e:
error(e)
except URLError as e:
error(e.reason)
else:
if json:
data = json_loads(response.read())
else:
data = response.read()
return data
def run(command, wait=False):
# ~ debug(command)
# ~ debug(shlex.split(command))
try:
if 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,
@ -4223,6 +4668,24 @@ def format(template, data):
return result
def _get_url_script(macro):
macro['language'] = macro.get('language', 'Python')
macro['location'] = macro.get('location', 'user')
data = macro.copy()
if data['language'] == 'Python':
data['module'] = '.py$'
elif data['language'] == 'Basic':
data['module'] = '.{}.'.format(macro['module'])
if macro['location'] == 'user':
data['location'] = 'application'
else:
data['module'] = '.'
url = 'vnd.sun.star.script:{library}{module}{name}?language={language}&location={location}'
path = url.format(**data)
return path
def _call_macro(macro):
#~ https://wiki.openoffice.org/wiki/Documentation/DevGuide/Scripting/Scripting_Framework_URI_Specification
name = 'com.sun.star.script.provider.MasterScriptProviderFactory'
@ -4243,6 +4706,7 @@ def _call_macro(macro):
args = macro.get('args', ())
url = 'vnd.sun.star.script:{library}{module}{name}?language={language}&location={location}'
path = url.format(**data)
script = factory.createScriptProvider('').getScript(path)
return script.invoke(args, None, None)[0]
@ -4469,6 +4933,7 @@ def import_csv(path, **kwargs):
rows = tuple(csv.reader(f, **kwargs))
return rows
def export_csv(path, data, **kwargs):
with open(path, 'w') as f:
writer = csv.writer(f, **kwargs)
@ -4476,6 +4941,19 @@ def export_csv(path, data, **kwargs):
return
def install_locales(path, domain='base', dir_locales=DIR['locales']):
p, *_ = get_info_path(path)
path_locales = join(p, dir_locales)
try:
lang = gettext.translation(domain, path_locales, languages=[LANG])
lang.install()
_ = lang.gettext
except Exception as e:
from gettext import gettext as _
error(e)
return _
class LIBOServer(object):
HOST = 'localhost'
PORT = '8100'
@ -4555,12 +5033,9 @@ class LIBOServer(object):
# ~ 'CurrencyField': 'com.sun.star.awt.UnoControlCurrencyFieldModel',
# ~ 'DateField': 'com.sun.star.awt.UnoControlDateFieldModel',
# ~ 'FileControl': 'com.sun.star.awt.UnoControlFileControlModel',
# ~ 'FixedLine': 'com.sun.star.awt.UnoControlFixedLineModel',
# ~ 'FixedText': 'com.sun.star.awt.UnoControlFixedTextModel',
# ~ 'FormattedField': 'com.sun.star.awt.UnoControlFormattedFieldModel',
# ~ 'GroupBox': 'com.sun.star.awt.UnoControlGroupBoxModel',
# ~ 'ImageControl': 'com.sun.star.awt.UnoControlImageControlModel',
# ~ 'ListBox': 'com.sun.star.awt.UnoControlListBoxModel',
# ~ 'NumericField': 'com.sun.star.awt.UnoControlNumericFieldModel',
# ~ 'PatternField': 'com.sun.star.awt.UnoControlPatternFieldModel',
# ~ 'ProgressBar': 'com.sun.star.awt.UnoControlProgressBarModel',