commit
1f323820b0
|
@ -1,3 +1,6 @@
|
||||||
|
v 0.3.0 [18-sep-2019]
|
||||||
|
- Add support for generate barcode by code
|
||||||
|
|
||||||
v 0.2.1 [16-sep-2019]
|
v 0.2.1 [16-sep-2019]
|
||||||
- Fix #1
|
- Fix #1
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,9 @@ https://github.com/WhyNotHugo/python-barcode
|
||||||
https://github.com/lincolnloop/python-qrcode
|
https://github.com/lincolnloop/python-qrcode
|
||||||
|
|
||||||
|
|
||||||
|
### Software libre, no gratis
|
||||||
|
|
||||||
|
|
||||||
This extension have a cost of maintenance of 1 euro every year.
|
This extension have a cost of maintenance of 1 euro every year.
|
||||||
|
|
||||||
BCH: `1RPLWHJW34p7pMQV1ft4x7eWhAYw69Dsb`
|
BCH: `1RPLWHJW34p7pMQV1ft4x7eWhAYw69Dsb`
|
||||||
|
@ -40,3 +43,8 @@ BTC: `3Fe4JuADrAK8Qs7GDAxbSXR8E54avwZJLW`
|
||||||
|
|
||||||
* [See the wiki](https://gitlab.com/mauriciobaeza/zaz-barcode/wikis/home)
|
* [See the wiki](https://gitlab.com/mauriciobaeza/zaz-barcode/wikis/home)
|
||||||
* [Mira la wiki](https://gitlab.com/mauriciobaeza/zaz-barcode/wikis/home_es)
|
* [Mira la wiki](https://gitlab.com/mauriciobaeza/zaz-barcode/wikis/home_es)
|
||||||
|
|
||||||
|
|
||||||
|
Thanks for translations:
|
||||||
|
|
||||||
|
Esperanto: [Guillermo Molleda](https://gitlab.com/gmolleda)
|
||||||
|
|
3
conf.py
3
conf.py
|
@ -26,7 +26,7 @@ import logging
|
||||||
TYPE_EXTENSION = 1
|
TYPE_EXTENSION = 1
|
||||||
|
|
||||||
# ~ https://semver.org/
|
# ~ https://semver.org/
|
||||||
VERSION = '0.2.1'
|
VERSION = '0.3.0'
|
||||||
|
|
||||||
# ~ Your great extension name, not used spaces
|
# ~ Your great extension name, not used spaces
|
||||||
NAME = 'ZAZBarCode'
|
NAME = 'ZAZBarCode'
|
||||||
|
@ -697,7 +697,6 @@ NODE_SHORTCUT = """ {0}<node oor:name="{1}" oor:op="fuse">
|
||||||
{0}</node>
|
{0}</node>
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
NODE_SHORTCUTS = ''
|
NODE_SHORTCUTS = ''
|
||||||
if TYPE_EXTENSION == 1:
|
if TYPE_EXTENSION == 1:
|
||||||
node_global = []
|
node_global = []
|
||||||
|
|
385
easymacro.py
385
easymacro.py
|
@ -22,10 +22,13 @@ import ctypes
|
||||||
import datetime
|
import datetime
|
||||||
import errno
|
import errno
|
||||||
import getpass
|
import getpass
|
||||||
|
import json
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import platform
|
import platform
|
||||||
|
import re
|
||||||
import shlex
|
import shlex
|
||||||
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
|
@ -33,6 +36,8 @@ import threading
|
||||||
import time
|
import time
|
||||||
import zipfile
|
import zipfile
|
||||||
|
|
||||||
|
from collections import OrderedDict
|
||||||
|
from collections.abc import MutableMapping
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
from pathlib import Path, PurePath
|
from pathlib import Path, PurePath
|
||||||
|
@ -65,26 +70,18 @@ MSG_LANG = {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
FILE_NAME_DEBUG = 'zaz-debug.log'
|
|
||||||
LOG_FORMAT = '%(asctime)s - %(levelname)s - %(message)s'
|
|
||||||
LOG_DATE = '%d/%m/%Y %H:%M:%S'
|
|
||||||
logging.addLevelName(logging.ERROR, '\033[1;41mERROR\033[1;0m')
|
|
||||||
logging.addLevelName(logging.DEBUG, '\x1b[33mDEBUG\033[1;0m')
|
|
||||||
logging.addLevelName(logging.INFO, '\x1b[32mINFO\033[1;0m')
|
|
||||||
logging.basicConfig(level=logging.DEBUG, format=LOG_FORMAT, datefmt=LOG_DATE)
|
|
||||||
log = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
OS = platform.system()
|
OS = platform.system()
|
||||||
USER = getpass.getuser()
|
USER = getpass.getuser()
|
||||||
PC = platform.node()
|
PC = platform.node()
|
||||||
DESKTOP = os.environ.get('DESKTOP_SESSION', '')
|
DESKTOP = os.environ.get('DESKTOP_SESSION', '')
|
||||||
INFO_DEBUG = '{}\n\n{}\n\n{}'.format(sys.version, platform.platform(), '\n'.join(sys.path))
|
INFO_DEBUG = '{}\n\n{}\n\n{}'.format(sys.version, platform.platform(), '\n'.join(sys.path))
|
||||||
|
|
||||||
|
|
||||||
IS_WIN = OS == 'Windows'
|
IS_WIN = OS == 'Windows'
|
||||||
LOG_NAME = 'ZAZ'
|
LOG_NAME = 'ZAZ'
|
||||||
CLIPBOARD_FORMAT_TEXT = 'text/plain;charset=utf-16'
|
CLIPBOARD_FORMAT_TEXT = 'text/plain;charset=utf-16'
|
||||||
|
|
||||||
|
|
||||||
CALC = 'calc'
|
CALC = 'calc'
|
||||||
WRITER = 'writer'
|
WRITER = 'writer'
|
||||||
OBJ_CELL = 'ScCellObj'
|
OBJ_CELL = 'ScCellObj'
|
||||||
|
@ -92,6 +89,46 @@ OBJ_RANGE = 'ScCellRangeObj'
|
||||||
OBJ_RANGES = 'ScCellRangesObj'
|
OBJ_RANGES = 'ScCellRangesObj'
|
||||||
OBJ_TYPE_RANGES = (OBJ_CELL, OBJ_RANGE, OBJ_RANGES)
|
OBJ_TYPE_RANGES = (OBJ_CELL, OBJ_RANGE, OBJ_RANGES)
|
||||||
|
|
||||||
|
TYPE_DOC = {
|
||||||
|
'calc': 'com.sun.star.sheet.SpreadsheetDocument',
|
||||||
|
'writer': 'com.sun.star.text.TextDocument',
|
||||||
|
'impress': 'com.sun.star.presentation.PresentationDocument',
|
||||||
|
'draw': 'com.sun.star.drawing.DrawingDocument',
|
||||||
|
'base': 'com.sun.star.sdb.OfficeDatabaseDocument',
|
||||||
|
'math': 'com.sun.star.formula.FormulaProperties',
|
||||||
|
'basic': 'com.sun.star.script.BasicIDE',
|
||||||
|
}
|
||||||
|
|
||||||
|
NODE_MENUBAR = 'private:resource/menubar/menubar'
|
||||||
|
MENUS_CALC = {
|
||||||
|
'file': '.uno:PickList',
|
||||||
|
'edit': '.uno:EditMenu',
|
||||||
|
'view': '.uno:ViewMenu',
|
||||||
|
'insert': '.uno:InsertMenu',
|
||||||
|
'format': '.uno:FormatMenu',
|
||||||
|
'styles': '.uno:FormatStylesMenu',
|
||||||
|
'sheet': '.uno:SheetMenu',
|
||||||
|
'data': '.uno:DataMenu',
|
||||||
|
'tools': '.uno:ToolsMenu',
|
||||||
|
'windows': '.uno:WindowList',
|
||||||
|
'help': '.uno:HelpMenu',
|
||||||
|
}
|
||||||
|
|
||||||
|
MENUS_APP = {
|
||||||
|
'calc': MENUS_CALC,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FILE_NAME_DEBUG = 'zaz-debug.log'
|
||||||
|
FILE_NAME_CONFIG = 'zaz-config.json'
|
||||||
|
LOG_FORMAT = '%(asctime)s - %(levelname)s - %(message)s'
|
||||||
|
LOG_DATE = '%d/%m/%Y %H:%M:%S'
|
||||||
|
logging.addLevelName(logging.ERROR, '\033[1;41mERROR\033[1;0m')
|
||||||
|
logging.addLevelName(logging.DEBUG, '\x1b[33mDEBUG\033[1;0m')
|
||||||
|
logging.addLevelName(logging.INFO, '\x1b[32mINFO\033[1;0m')
|
||||||
|
logging.basicConfig(level=logging.DEBUG, format=LOG_FORMAT, datefmt=LOG_DATE)
|
||||||
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
CTX = uno.getComponentContext()
|
CTX = uno.getComponentContext()
|
||||||
SM = CTX.getServiceManager()
|
SM = CTX.getServiceManager()
|
||||||
|
@ -105,7 +142,7 @@ def create_instance(name, with_context=False):
|
||||||
return instance
|
return instance
|
||||||
|
|
||||||
|
|
||||||
def _get_config(key, node_name):
|
def _get_app_config(key, node_name):
|
||||||
name = 'com.sun.star.configuration.ConfigurationProvider'
|
name = 'com.sun.star.configuration.ConfigurationProvider'
|
||||||
service = 'com.sun.star.configuration.ConfigurationAccess'
|
service = 'com.sun.star.configuration.ConfigurationAccess'
|
||||||
cp = create_instance(name, True)
|
cp = create_instance(name, True)
|
||||||
|
@ -120,10 +157,10 @@ def _get_config(key, node_name):
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
|
|
||||||
LANGUAGE = _get_config('ooLocale', 'org.openoffice.Setup/L10N/')
|
LANGUAGE = _get_app_config('ooLocale', 'org.openoffice.Setup/L10N/')
|
||||||
LANG = LANGUAGE.split('-')[0]
|
LANG = LANGUAGE.split('-')[0]
|
||||||
NAME = TITLE = _get_config('ooName', 'org.openoffice.Setup/Product')
|
NAME = TITLE = _get_app_config('ooName', 'org.openoffice.Setup/Product')
|
||||||
VERSION = _get_config('ooSetupVersion', 'org.openoffice.Setup/Product')
|
VERSION = _get_app_config('ooSetupVersion', 'org.openoffice.Setup/Product')
|
||||||
|
|
||||||
|
|
||||||
def mri(obj):
|
def mri(obj):
|
||||||
|
@ -202,8 +239,34 @@ def run_in_thread(fn):
|
||||||
return run
|
return run
|
||||||
|
|
||||||
|
|
||||||
def sleep(sec):
|
def get_config(key=''):
|
||||||
time.sleep(sec)
|
values = {}
|
||||||
|
path = join(get_config_path('UserConfig'), FILE_NAME_CONFIG)
|
||||||
|
if not exists_path(path):
|
||||||
|
return values
|
||||||
|
|
||||||
|
with open(path, 'r', encoding='utf-8') as fh:
|
||||||
|
data = fh.read()
|
||||||
|
if data:
|
||||||
|
values = json.loads(data)
|
||||||
|
|
||||||
|
if key:
|
||||||
|
return values.get(key, None)
|
||||||
|
|
||||||
|
return values
|
||||||
|
|
||||||
|
|
||||||
|
def set_config(key, value):
|
||||||
|
path = join(get_config_path('UserConfig'), FILE_NAME_CONFIG)
|
||||||
|
values = get_config()
|
||||||
|
values[key] = value
|
||||||
|
with open(path, 'w', encoding='utf-8') as fh:
|
||||||
|
json.dump(values, fh, ensure_ascii=False, sort_keys=True, indent=4)
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def sleep(seconds):
|
||||||
|
time.sleep(seconds)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
|
@ -278,30 +341,116 @@ def exists_app(name):
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
# ~ Delete
|
||||||
def exists(path):
|
def exists(path):
|
||||||
return Path(path).exists()
|
return Path(path).exists()
|
||||||
|
def exists_path(path):
|
||||||
|
return Path(path).exists()
|
||||||
|
|
||||||
|
|
||||||
def get_type_doc(obj):
|
def get_type_doc(obj):
|
||||||
services = {
|
# ~ services = {
|
||||||
'calc': 'com.sun.star.sheet.SpreadsheetDocument',
|
# ~ 'calc': 'com.sun.star.sheet.SpreadsheetDocument',
|
||||||
'writer': 'com.sun.star.text.TextDocument',
|
# ~ 'writer': 'com.sun.star.text.TextDocument',
|
||||||
'impress': 'com.sun.star.presentation.PresentationDocument',
|
# ~ 'impress': 'com.sun.star.presentation.PresentationDocument',
|
||||||
'draw': 'com.sun.star.drawing.DrawingDocument',
|
# ~ 'draw': 'com.sun.star.drawing.DrawingDocument',
|
||||||
'base': 'com.sun.star.sdb.OfficeDatabaseDocument',
|
# ~ 'base': 'com.sun.star.sdb.OfficeDatabaseDocument',
|
||||||
'math': 'com.sun.star.formula.FormulaProperties',
|
# ~ 'math': 'com.sun.star.formula.FormulaProperties',
|
||||||
'basic': 'com.sun.star.script.BasicIDE',
|
# ~ 'basic': 'com.sun.star.script.BasicIDE',
|
||||||
}
|
# ~ }
|
||||||
for k, v in services.items():
|
for k, v in TYPE_DOC.items():
|
||||||
if obj.supportsService(v):
|
if obj.supportsService(v):
|
||||||
return k
|
return k
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
|
|
||||||
def _properties(values):
|
# ~ def _properties(values):
|
||||||
p = [PropertyValue(Name=n, Value=v) for n, v in values.items()]
|
# ~ p = [PropertyValue(Name=n, Value=v) for n, v in values.items()]
|
||||||
return tuple(p)
|
# ~ return tuple(p)
|
||||||
|
|
||||||
|
def dict_to_property(values, uno_any=False):
|
||||||
|
ps = tuple([PropertyValue(Name=n, Value=v) for n, v in values.items()])
|
||||||
|
if uno_any:
|
||||||
|
ps = uno.Any('[]com.sun.star.beans.PropertyValue', ps)
|
||||||
|
return ps
|
||||||
|
|
||||||
|
|
||||||
|
def property_to_dict(values):
|
||||||
|
d = {i.Name: i.Value for i in values}
|
||||||
|
return d
|
||||||
|
|
||||||
|
|
||||||
|
# ~ Third classes
|
||||||
|
|
||||||
|
|
||||||
|
# ~ https://github.com/psf/requests/blob/v2.22.0/requests/structures.py
|
||||||
|
class CaseInsensitiveDict(MutableMapping):
|
||||||
|
"""A case-insensitive ``dict``-like object.
|
||||||
|
Implements all methods and operations of
|
||||||
|
``MutableMapping`` as well as dict's ``copy``. Also
|
||||||
|
provides ``lower_items``.
|
||||||
|
All keys are expected to be strings. The structure remembers the
|
||||||
|
case of the last key to be set, and ``iter(instance)``,
|
||||||
|
``keys()``, ``items()``, ``iterkeys()``, and ``iteritems()``
|
||||||
|
will contain case-sensitive keys. However, querying and contains
|
||||||
|
testing is case insensitive::
|
||||||
|
cid = CaseInsensitiveDict()
|
||||||
|
cid['Accept'] = 'application/json'
|
||||||
|
cid['aCCEPT'] == 'application/json' # True
|
||||||
|
list(cid) == ['Accept'] # True
|
||||||
|
For example, ``headers['content-encoding']`` will return the
|
||||||
|
value of a ``'Content-Encoding'`` response header, regardless
|
||||||
|
of how the header name was originally stored.
|
||||||
|
If the constructor, ``.update``, or equality comparison
|
||||||
|
operations are given keys that have equal ``.lower()``s, the
|
||||||
|
behavior is undefined.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, data=None, **kwargs):
|
||||||
|
self._store = OrderedDict()
|
||||||
|
if data is None:
|
||||||
|
data = {}
|
||||||
|
self.update(data, **kwargs)
|
||||||
|
|
||||||
|
def __setitem__(self, key, value):
|
||||||
|
# Use the lowercased key for lookups, but store the actual
|
||||||
|
# key alongside the value.
|
||||||
|
self._store[key.lower()] = (key, value)
|
||||||
|
|
||||||
|
def __getitem__(self, key):
|
||||||
|
return self._store[key.lower()][1]
|
||||||
|
|
||||||
|
def __delitem__(self, key):
|
||||||
|
del self._store[key.lower()]
|
||||||
|
|
||||||
|
def __iter__(self):
|
||||||
|
return (casedkey for casedkey, mappedvalue in self._store.values())
|
||||||
|
|
||||||
|
def __len__(self):
|
||||||
|
return len(self._store)
|
||||||
|
|
||||||
|
def lower_items(self):
|
||||||
|
"""Like iteritems(), but with all lowercase keys."""
|
||||||
|
return (
|
||||||
|
(lowerkey, keyval[1])
|
||||||
|
for (lowerkey, keyval)
|
||||||
|
in self._store.items()
|
||||||
|
)
|
||||||
|
|
||||||
|
def __eq__(self, other):
|
||||||
|
if isinstance(other, Mapping):
|
||||||
|
other = CaseInsensitiveDict(other)
|
||||||
|
else:
|
||||||
|
return NotImplemented
|
||||||
|
# Compare insensitively
|
||||||
|
return dict(self.lower_items()) == dict(other.lower_items())
|
||||||
|
|
||||||
|
# Copy is required
|
||||||
|
def copy(self):
|
||||||
|
return CaseInsensitiveDict(self._store.values())
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return str(dict(self.items()))
|
||||||
|
|
||||||
|
|
||||||
# ~ Custom classes
|
# ~ Custom classes
|
||||||
|
@ -371,7 +520,8 @@ class LODocument(object):
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
def save(self, path='', **kwargs):
|
def save(self, path='', **kwargs):
|
||||||
opt = _properties(kwargs)
|
# ~ opt = _properties(kwargs)
|
||||||
|
opt = dict_to_property(kwargs)
|
||||||
if path:
|
if path:
|
||||||
self._obj.storeAsURL(_path_url(path), opt)
|
self._obj.storeAsURL(_path_url(path), opt)
|
||||||
else:
|
else:
|
||||||
|
@ -1127,9 +1277,30 @@ def set_properties(model, properties):
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
def get_file(filters=(), multiple=False):
|
def get_config_path(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 _path_system(getattr(path, name))
|
||||||
|
|
||||||
|
|
||||||
|
def get_file(init_dir='', multiple=False, filters=()):
|
||||||
|
"""
|
||||||
|
init_folder: folder default open
|
||||||
|
multiple: True for multiple selected
|
||||||
|
filters: Example
|
||||||
|
(
|
||||||
|
('XML', '*.xml'),
|
||||||
|
('TXT', '*.txt'),
|
||||||
|
)
|
||||||
|
"""
|
||||||
|
if not init_dir:
|
||||||
|
init_dir = get_config_path()
|
||||||
file_picker = create_instance('com.sun.star.ui.dialogs.FilePicker')
|
file_picker = create_instance('com.sun.star.ui.dialogs.FilePicker')
|
||||||
file_picker.setTitle(_('Select file'))
|
file_picker.setTitle(_('Select file'))
|
||||||
|
file_picker.setDisplayDirectory(init_dir)
|
||||||
file_picker.setMultiSelectionMode(multiple)
|
file_picker.setMultiSelectionMode(multiple)
|
||||||
|
|
||||||
if filters:
|
if filters:
|
||||||
|
@ -1242,7 +1413,8 @@ def open_doc(path, **kwargs):
|
||||||
http://api.libreoffice.org/docs/idl/ref/servicecom_1_1sun_1_1star_1_1document_1_1MediaDescriptor.html
|
http://api.libreoffice.org/docs/idl/ref/servicecom_1_1sun_1_1star_1_1document_1_1MediaDescriptor.html
|
||||||
"""
|
"""
|
||||||
path = _path_url(path)
|
path = _path_url(path)
|
||||||
opt = _properties(kwargs)
|
# ~ opt = _properties(kwargs)
|
||||||
|
opt = dict_to_property(kwargs)
|
||||||
doc = get_desktop().loadComponentFromURL(path, '_blank', 0, opt)
|
doc = get_desktop().loadComponentFromURL(path, '_blank', 0, opt)
|
||||||
if doc is None:
|
if doc is None:
|
||||||
return
|
return
|
||||||
|
@ -1278,9 +1450,9 @@ def is_created(path):
|
||||||
return is_file(path) and bool(get_file_size(path))
|
return is_file(path) and bool(get_file_size(path))
|
||||||
|
|
||||||
|
|
||||||
def replace_ext(path, ext):
|
def replace_ext(path, extension):
|
||||||
path, _, name, _ = get_info_path(path)
|
path, _, name, _ = get_info_path(path)
|
||||||
return '{}/{}.{}'.format(path, name, ext)
|
return '{}/{}.{}'.format(path, name, extension)
|
||||||
|
|
||||||
|
|
||||||
def zip_names(path):
|
def zip_names(path):
|
||||||
|
@ -1477,8 +1649,8 @@ class TextTransferable(unohelper.Base, XTransferable):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def set_clipboard(text):
|
def set_clipboard(value):
|
||||||
ts = TextTransferable(text)
|
ts = TextTransferable(value)
|
||||||
sc = create_instance('com.sun.star.datatransfer.clipboard.SystemClipboard')
|
sc = create_instance('com.sun.star.datatransfer.clipboard.SystemClipboard')
|
||||||
sc.setContents(ts, None)
|
sc.setContents(ts, None)
|
||||||
return
|
return
|
||||||
|
@ -1499,3 +1671,142 @@ def copy(doc=None):
|
||||||
def get_epoch():
|
def get_epoch():
|
||||||
now = datetime.datetime.now()
|
now = datetime.datetime.now()
|
||||||
return int(time.mktime(now.timetuple()))
|
return int(time.mktime(now.timetuple()))
|
||||||
|
|
||||||
|
|
||||||
|
def file_copy(source, target='', name=''):
|
||||||
|
p, f, n, e = get_info_path(source)
|
||||||
|
if target:
|
||||||
|
p = target
|
||||||
|
if name:
|
||||||
|
n = name
|
||||||
|
path_new = join(p, '{}{}'.format(n, e))
|
||||||
|
shutil.copy(source, path_new)
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
def get_files(path, ext='*'):
|
||||||
|
docs = []
|
||||||
|
for folder, _, files in os.walk(path):
|
||||||
|
pattern = re.compile(r'\.{}'.format(ext), re.IGNORECASE)
|
||||||
|
docs += [join(folder, f) for f in files if pattern.search(f)]
|
||||||
|
return docs
|
||||||
|
|
||||||
|
|
||||||
|
def _get_menu(type_doc, name_menu):
|
||||||
|
instance = 'com.sun.star.ui.ModuleUIConfigurationManagerSupplier'
|
||||||
|
service = TYPE_DOC[type_doc]
|
||||||
|
manager = create_instance(instance, True)
|
||||||
|
ui = manager.getUIConfigurationManager(service)
|
||||||
|
menus = ui.getSettings(NODE_MENUBAR, True)
|
||||||
|
command = MENUS_APP[type_doc][name_menu]
|
||||||
|
for menu in menus:
|
||||||
|
data = property_to_dict(menu)
|
||||||
|
if data.get('CommandURL', '') == command:
|
||||||
|
idc = data.get('ItemDescriptorContainer', None)
|
||||||
|
return ui, menus, idc
|
||||||
|
return None, None, None
|
||||||
|
|
||||||
|
|
||||||
|
def _get_index_menu(menu, command):
|
||||||
|
for i, m in enumerate(menu):
|
||||||
|
data = property_to_dict(m)
|
||||||
|
cmd = data.get('CommandURL', '')
|
||||||
|
if cmd == command:
|
||||||
|
return i
|
||||||
|
# ~ submenu = data.get('ItemDescriptorContainer', None)
|
||||||
|
# ~ if not submenu is None:
|
||||||
|
# ~ get_index_menu(submenu, command, count + 1)
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
def _store_menu(ui, menus, menu, index, data=(), remove=False):
|
||||||
|
if remove:
|
||||||
|
uno.invoke(menu, 'removeByIndex', (index,))
|
||||||
|
else:
|
||||||
|
properties = dict_to_property(data, True)
|
||||||
|
uno.invoke(menu, 'insertByIndex', (index + 1, properties))
|
||||||
|
ui.replaceSettings(NODE_MENUBAR, menus)
|
||||||
|
ui.store()
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
def insert_menu(type_doc, name_menu, **kwargs):
|
||||||
|
ui, menus, menu = _get_menu(type_doc, name_menu.lower())
|
||||||
|
if menu is None:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
label = kwargs.get('Label', '-')
|
||||||
|
separator = False
|
||||||
|
if label == '-':
|
||||||
|
separator = True
|
||||||
|
command = kwargs.get('Command', '')
|
||||||
|
index = kwargs.get('Index', 0)
|
||||||
|
if not index:
|
||||||
|
index = _get_index_menu(menu, kwargs['After'])
|
||||||
|
if separator:
|
||||||
|
data = {'Type': 1}
|
||||||
|
_store_menu(ui, menus, menu, index, data)
|
||||||
|
return index + 1
|
||||||
|
|
||||||
|
index_menu = _get_index_menu(menu, command)
|
||||||
|
if index_menu:
|
||||||
|
msg = 'Exists: %s' % command
|
||||||
|
debug(msg)
|
||||||
|
return 0
|
||||||
|
|
||||||
|
sub_menu = kwargs.get('Submenu', ())
|
||||||
|
idc = None
|
||||||
|
if sub_menu:
|
||||||
|
idc = ui.createSettings()
|
||||||
|
|
||||||
|
data = {
|
||||||
|
'CommandURL': command,
|
||||||
|
'Label': label,
|
||||||
|
'Style': 0,
|
||||||
|
'Type': 0,
|
||||||
|
'ItemDescriptorContainer': idc
|
||||||
|
}
|
||||||
|
_store_menu(ui, menus, menu, index, data)
|
||||||
|
if sub_menu:
|
||||||
|
_add_sub_menus(ui, menus, idc, sub_menu)
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def _add_sub_menus(ui, menus, menu, sub_menu):
|
||||||
|
for i, sm in enumerate(sub_menu):
|
||||||
|
submenu = sm.pop('Submenu', ())
|
||||||
|
sm['Type'] = 0
|
||||||
|
if submenu:
|
||||||
|
idc = ui.createSettings()
|
||||||
|
sm['ItemDescriptorContainer'] = idc
|
||||||
|
_store_menu(ui, menus, menu, i - 1, sm)
|
||||||
|
if submenu:
|
||||||
|
_add_sub_menus(ui, menus, idc, submenu)
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
def remove_menu(type_doc, name_menu, command):
|
||||||
|
ui, menus, menu = _get_menu(type_doc, name_menu.lower())
|
||||||
|
if menu is None:
|
||||||
|
return False
|
||||||
|
|
||||||
|
index = _get_index_menu(menu, command)
|
||||||
|
if not index:
|
||||||
|
debug('Not exists: %s' % command)
|
||||||
|
return False
|
||||||
|
|
||||||
|
_store_menu(ui, menus, menu, index, remove=True)
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
# ~ name = 'com.sun.star.configuration.ConfigurationProvider'
|
||||||
|
# ~ cp = create_instance(name, True)
|
||||||
|
# ~ node = PropertyValue(Name='nodepath', Value=NODE_SETTING)
|
||||||
|
# ~ try:
|
||||||
|
# ~ cua = cp.createInstanceWithArguments(
|
||||||
|
# ~ 'com.sun.star.configuration.ConfigurationUpdateAccess', (node,))
|
||||||
|
# ~ cua.setPropertyValue(key, json.dumps(value))
|
||||||
|
# ~ cua.commitChanges()
|
||||||
|
# ~ except Exception as e:
|
||||||
|
# ~ log.error(e, exc_info=True)
|
||||||
|
# ~ return False
|
||||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -5,10 +5,10 @@
|
||||||
xmlns:xlink="http://www.w3.org/1999/xlink">
|
xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
|
||||||
<identifier value="net.elmau.zaz.BarCode" />
|
<identifier value="net.elmau.zaz.BarCode" />
|
||||||
<version value="0.2.1" />
|
<version value="0.3.0" />
|
||||||
|
|
||||||
<update-download>
|
<update-download>
|
||||||
<src xlink:href="https://gitlab.com/mauriciobaeza/zaz-barcode/raw/master/files/ZAZBarCode_v0.2.1.oxt"/>
|
<src xlink:href="https://gitlab.com/mauriciobaeza/zaz-barcode/raw/master/files/ZAZBarCode_v0.3.0.oxt"/>
|
||||||
</update-download>
|
</update-download>
|
||||||
<release-notes>
|
<release-notes>
|
||||||
</release-notes>
|
</release-notes>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import gettext
|
import gettext
|
||||||
import uno
|
import uno
|
||||||
import unohelper
|
import unohelper
|
||||||
from com.sun.star.task import XJobExecutor
|
from com.sun.star.task import XJobExecutor, XJob
|
||||||
import easymacro as app
|
import easymacro as app
|
||||||
|
|
||||||
import qrcode
|
import qrcode
|
||||||
|
@ -22,6 +22,7 @@ try:
|
||||||
lang.install()
|
lang.install()
|
||||||
_ = lang.gettext
|
_ = lang.gettext
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
from gettext import gettext as _
|
||||||
app.error(e)
|
app.error(e)
|
||||||
|
|
||||||
|
|
||||||
|
@ -46,13 +47,27 @@ class Controllers(object):
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
class ZAZBarCode(unohelper.Base, XJobExecutor):
|
class ZAZBarCode(unohelper.Base, XJob, XJobExecutor):
|
||||||
|
|
||||||
def __init__(self, ctx):
|
def __init__(self, ctx):
|
||||||
self.ctx = ctx
|
self.ctx = ctx
|
||||||
self._data = ''
|
self._data = ''
|
||||||
self._type = ''
|
self._type = ''
|
||||||
|
|
||||||
|
def execute(self, args):
|
||||||
|
data = app.property_to_dict(args)
|
||||||
|
|
||||||
|
if data['Type'] == QR:
|
||||||
|
factory = svg.SvgImage
|
||||||
|
img = qrcode.make(data['Data'], image_factory=factory)
|
||||||
|
img.save(data['Path'])
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
generate(data['Type'].lower(), data['Data'], output=data['Path'])
|
||||||
|
except Exception as e:
|
||||||
|
app.debug(str(e))
|
||||||
|
return
|
||||||
|
|
||||||
def trigger(self, args):
|
def trigger(self, args):
|
||||||
self._type = args
|
self._type = args
|
||||||
if args == 'ask' and not self._get_values():
|
if args == 'ask' and not self._get_values():
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?xml version='1.0' encoding='UTF-8'?>
|
<?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">
|
<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.BarCode" />
|
<identifier value="net.elmau.zaz.BarCode" />
|
||||||
<version value="0.2.1" />
|
<version value="0.3.0" />
|
||||||
<display-name>
|
<display-name>
|
||||||
<name lang="en">ZAZ Bar Code</name>
|
<name lang="en">ZAZ Bar Code</name>
|
||||||
<name lang="es">ZAZ Códigos de Barras</name>
|
<name lang="es">ZAZ Códigos de Barras</name>
|
||||||
|
|
Binary file not shown.
|
@ -0,0 +1,52 @@
|
||||||
|
# SOME DESCRIPTIVE TITLE.
|
||||||
|
# Copyright (C) YEAR ORGANIZATION
|
||||||
|
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||||
|
#
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: \n"
|
||||||
|
"POT-Creation-Date: 2019-09-14 14:23-0500\n"
|
||||||
|
"PO-Revision-Date: 2019-09-20 19:21+0200\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.0.6\n"
|
||||||
|
"Last-Translator: \n"
|
||||||
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||||
|
"Language: eo\n"
|
||||||
|
|
||||||
|
#: source/ZAZBarCode.py:38
|
||||||
|
msgid "Select barcode type"
|
||||||
|
msgstr "Elektu strikodan tipon"
|
||||||
|
|
||||||
|
#: source/ZAZBarCode.py:43
|
||||||
|
msgid "Data field is mandatory"
|
||||||
|
msgstr "Datumkampo estas deviga"
|
||||||
|
|
||||||
|
#: source/ZAZBarCode.py:95 source/ZAZBarCode.py:117
|
||||||
|
msgid "Select data"
|
||||||
|
msgstr "Elektu datumojn"
|
||||||
|
|
||||||
|
#: source/ZAZBarCode.py:149
|
||||||
|
msgid ""
|
||||||
|
"Error in: {}\n"
|
||||||
|
"\n"
|
||||||
|
"{}"
|
||||||
|
msgstr ""
|
||||||
|
"Eraro en: {}\n"
|
||||||
|
"\n"
|
||||||
|
"{}"
|
||||||
|
|
||||||
|
#: source/ZAZBarCode.py:167
|
||||||
|
msgid "~Select barcode type"
|
||||||
|
msgstr "~Elektu strikodan tipon"
|
||||||
|
|
||||||
|
#: source/ZAZBarCode.py:179
|
||||||
|
msgid "~Capture data for barcode"
|
||||||
|
msgstr "~Kaptu datumojn por strikodo"
|
||||||
|
|
||||||
|
#: source/ZAZBarCode.py:212
|
||||||
|
msgid "~Insert Barcode"
|
||||||
|
msgstr "~Enmetu Strikodon"
|
|
@ -22,10 +22,13 @@ import ctypes
|
||||||
import datetime
|
import datetime
|
||||||
import errno
|
import errno
|
||||||
import getpass
|
import getpass
|
||||||
|
import json
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import platform
|
import platform
|
||||||
|
import re
|
||||||
import shlex
|
import shlex
|
||||||
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
|
@ -33,6 +36,8 @@ import threading
|
||||||
import time
|
import time
|
||||||
import zipfile
|
import zipfile
|
||||||
|
|
||||||
|
from collections import OrderedDict
|
||||||
|
from collections.abc import MutableMapping
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
from pathlib import Path, PurePath
|
from pathlib import Path, PurePath
|
||||||
|
@ -65,26 +70,18 @@ MSG_LANG = {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
FILE_NAME_DEBUG = 'zaz-debug.log'
|
|
||||||
LOG_FORMAT = '%(asctime)s - %(levelname)s - %(message)s'
|
|
||||||
LOG_DATE = '%d/%m/%Y %H:%M:%S'
|
|
||||||
logging.addLevelName(logging.ERROR, '\033[1;41mERROR\033[1;0m')
|
|
||||||
logging.addLevelName(logging.DEBUG, '\x1b[33mDEBUG\033[1;0m')
|
|
||||||
logging.addLevelName(logging.INFO, '\x1b[32mINFO\033[1;0m')
|
|
||||||
logging.basicConfig(level=logging.DEBUG, format=LOG_FORMAT, datefmt=LOG_DATE)
|
|
||||||
log = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
OS = platform.system()
|
OS = platform.system()
|
||||||
USER = getpass.getuser()
|
USER = getpass.getuser()
|
||||||
PC = platform.node()
|
PC = platform.node()
|
||||||
DESKTOP = os.environ.get('DESKTOP_SESSION', '')
|
DESKTOP = os.environ.get('DESKTOP_SESSION', '')
|
||||||
INFO_DEBUG = '{}\n\n{}\n\n{}'.format(sys.version, platform.platform(), '\n'.join(sys.path))
|
INFO_DEBUG = '{}\n\n{}\n\n{}'.format(sys.version, platform.platform(), '\n'.join(sys.path))
|
||||||
|
|
||||||
|
|
||||||
IS_WIN = OS == 'Windows'
|
IS_WIN = OS == 'Windows'
|
||||||
LOG_NAME = 'ZAZ'
|
LOG_NAME = 'ZAZ'
|
||||||
CLIPBOARD_FORMAT_TEXT = 'text/plain;charset=utf-16'
|
CLIPBOARD_FORMAT_TEXT = 'text/plain;charset=utf-16'
|
||||||
|
|
||||||
|
|
||||||
CALC = 'calc'
|
CALC = 'calc'
|
||||||
WRITER = 'writer'
|
WRITER = 'writer'
|
||||||
OBJ_CELL = 'ScCellObj'
|
OBJ_CELL = 'ScCellObj'
|
||||||
|
@ -92,6 +89,46 @@ OBJ_RANGE = 'ScCellRangeObj'
|
||||||
OBJ_RANGES = 'ScCellRangesObj'
|
OBJ_RANGES = 'ScCellRangesObj'
|
||||||
OBJ_TYPE_RANGES = (OBJ_CELL, OBJ_RANGE, OBJ_RANGES)
|
OBJ_TYPE_RANGES = (OBJ_CELL, OBJ_RANGE, OBJ_RANGES)
|
||||||
|
|
||||||
|
TYPE_DOC = {
|
||||||
|
'calc': 'com.sun.star.sheet.SpreadsheetDocument',
|
||||||
|
'writer': 'com.sun.star.text.TextDocument',
|
||||||
|
'impress': 'com.sun.star.presentation.PresentationDocument',
|
||||||
|
'draw': 'com.sun.star.drawing.DrawingDocument',
|
||||||
|
'base': 'com.sun.star.sdb.OfficeDatabaseDocument',
|
||||||
|
'math': 'com.sun.star.formula.FormulaProperties',
|
||||||
|
'basic': 'com.sun.star.script.BasicIDE',
|
||||||
|
}
|
||||||
|
|
||||||
|
NODE_MENUBAR = 'private:resource/menubar/menubar'
|
||||||
|
MENUS_CALC = {
|
||||||
|
'file': '.uno:PickList',
|
||||||
|
'edit': '.uno:EditMenu',
|
||||||
|
'view': '.uno:ViewMenu',
|
||||||
|
'insert': '.uno:InsertMenu',
|
||||||
|
'format': '.uno:FormatMenu',
|
||||||
|
'styles': '.uno:FormatStylesMenu',
|
||||||
|
'sheet': '.uno:SheetMenu',
|
||||||
|
'data': '.uno:DataMenu',
|
||||||
|
'tools': '.uno:ToolsMenu',
|
||||||
|
'windows': '.uno:WindowList',
|
||||||
|
'help': '.uno:HelpMenu',
|
||||||
|
}
|
||||||
|
|
||||||
|
MENUS_APP = {
|
||||||
|
'calc': MENUS_CALC,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FILE_NAME_DEBUG = 'zaz-debug.log'
|
||||||
|
FILE_NAME_CONFIG = 'zaz-config.json'
|
||||||
|
LOG_FORMAT = '%(asctime)s - %(levelname)s - %(message)s'
|
||||||
|
LOG_DATE = '%d/%m/%Y %H:%M:%S'
|
||||||
|
logging.addLevelName(logging.ERROR, '\033[1;41mERROR\033[1;0m')
|
||||||
|
logging.addLevelName(logging.DEBUG, '\x1b[33mDEBUG\033[1;0m')
|
||||||
|
logging.addLevelName(logging.INFO, '\x1b[32mINFO\033[1;0m')
|
||||||
|
logging.basicConfig(level=logging.DEBUG, format=LOG_FORMAT, datefmt=LOG_DATE)
|
||||||
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
CTX = uno.getComponentContext()
|
CTX = uno.getComponentContext()
|
||||||
SM = CTX.getServiceManager()
|
SM = CTX.getServiceManager()
|
||||||
|
@ -105,7 +142,7 @@ def create_instance(name, with_context=False):
|
||||||
return instance
|
return instance
|
||||||
|
|
||||||
|
|
||||||
def _get_config(key, node_name):
|
def _get_app_config(key, node_name):
|
||||||
name = 'com.sun.star.configuration.ConfigurationProvider'
|
name = 'com.sun.star.configuration.ConfigurationProvider'
|
||||||
service = 'com.sun.star.configuration.ConfigurationAccess'
|
service = 'com.sun.star.configuration.ConfigurationAccess'
|
||||||
cp = create_instance(name, True)
|
cp = create_instance(name, True)
|
||||||
|
@ -120,10 +157,10 @@ def _get_config(key, node_name):
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
|
|
||||||
LANGUAGE = _get_config('ooLocale', 'org.openoffice.Setup/L10N/')
|
LANGUAGE = _get_app_config('ooLocale', 'org.openoffice.Setup/L10N/')
|
||||||
LANG = LANGUAGE.split('-')[0]
|
LANG = LANGUAGE.split('-')[0]
|
||||||
NAME = TITLE = _get_config('ooName', 'org.openoffice.Setup/Product')
|
NAME = TITLE = _get_app_config('ooName', 'org.openoffice.Setup/Product')
|
||||||
VERSION = _get_config('ooSetupVersion', 'org.openoffice.Setup/Product')
|
VERSION = _get_app_config('ooSetupVersion', 'org.openoffice.Setup/Product')
|
||||||
|
|
||||||
|
|
||||||
def mri(obj):
|
def mri(obj):
|
||||||
|
@ -202,8 +239,34 @@ def run_in_thread(fn):
|
||||||
return run
|
return run
|
||||||
|
|
||||||
|
|
||||||
def sleep(sec):
|
def get_config(key=''):
|
||||||
time.sleep(sec)
|
values = {}
|
||||||
|
path = join(get_config_path('UserConfig'), FILE_NAME_CONFIG)
|
||||||
|
if not exists_path(path):
|
||||||
|
return values
|
||||||
|
|
||||||
|
with open(path, 'r', encoding='utf-8') as fh:
|
||||||
|
data = fh.read()
|
||||||
|
if data:
|
||||||
|
values = json.loads(data)
|
||||||
|
|
||||||
|
if key:
|
||||||
|
return values.get(key, None)
|
||||||
|
|
||||||
|
return values
|
||||||
|
|
||||||
|
|
||||||
|
def set_config(key, value):
|
||||||
|
path = join(get_config_path('UserConfig'), FILE_NAME_CONFIG)
|
||||||
|
values = get_config()
|
||||||
|
values[key] = value
|
||||||
|
with open(path, 'w', encoding='utf-8') as fh:
|
||||||
|
json.dump(values, fh, ensure_ascii=False, sort_keys=True, indent=4)
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def sleep(seconds):
|
||||||
|
time.sleep(seconds)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
|
@ -278,30 +341,116 @@ def exists_app(name):
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
# ~ Delete
|
||||||
def exists(path):
|
def exists(path):
|
||||||
return Path(path).exists()
|
return Path(path).exists()
|
||||||
|
def exists_path(path):
|
||||||
|
return Path(path).exists()
|
||||||
|
|
||||||
|
|
||||||
def get_type_doc(obj):
|
def get_type_doc(obj):
|
||||||
services = {
|
# ~ services = {
|
||||||
'calc': 'com.sun.star.sheet.SpreadsheetDocument',
|
# ~ 'calc': 'com.sun.star.sheet.SpreadsheetDocument',
|
||||||
'writer': 'com.sun.star.text.TextDocument',
|
# ~ 'writer': 'com.sun.star.text.TextDocument',
|
||||||
'impress': 'com.sun.star.presentation.PresentationDocument',
|
# ~ 'impress': 'com.sun.star.presentation.PresentationDocument',
|
||||||
'draw': 'com.sun.star.drawing.DrawingDocument',
|
# ~ 'draw': 'com.sun.star.drawing.DrawingDocument',
|
||||||
'base': 'com.sun.star.sdb.OfficeDatabaseDocument',
|
# ~ 'base': 'com.sun.star.sdb.OfficeDatabaseDocument',
|
||||||
'math': 'com.sun.star.formula.FormulaProperties',
|
# ~ 'math': 'com.sun.star.formula.FormulaProperties',
|
||||||
'basic': 'com.sun.star.script.BasicIDE',
|
# ~ 'basic': 'com.sun.star.script.BasicIDE',
|
||||||
}
|
# ~ }
|
||||||
for k, v in services.items():
|
for k, v in TYPE_DOC.items():
|
||||||
if obj.supportsService(v):
|
if obj.supportsService(v):
|
||||||
return k
|
return k
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
|
|
||||||
def _properties(values):
|
# ~ def _properties(values):
|
||||||
p = [PropertyValue(Name=n, Value=v) for n, v in values.items()]
|
# ~ p = [PropertyValue(Name=n, Value=v) for n, v in values.items()]
|
||||||
return tuple(p)
|
# ~ return tuple(p)
|
||||||
|
|
||||||
|
def dict_to_property(values, uno_any=False):
|
||||||
|
ps = tuple([PropertyValue(Name=n, Value=v) for n, v in values.items()])
|
||||||
|
if uno_any:
|
||||||
|
ps = uno.Any('[]com.sun.star.beans.PropertyValue', ps)
|
||||||
|
return ps
|
||||||
|
|
||||||
|
|
||||||
|
def property_to_dict(values):
|
||||||
|
d = {i.Name: i.Value for i in values}
|
||||||
|
return d
|
||||||
|
|
||||||
|
|
||||||
|
# ~ Third classes
|
||||||
|
|
||||||
|
|
||||||
|
# ~ https://github.com/psf/requests/blob/v2.22.0/requests/structures.py
|
||||||
|
class CaseInsensitiveDict(MutableMapping):
|
||||||
|
"""A case-insensitive ``dict``-like object.
|
||||||
|
Implements all methods and operations of
|
||||||
|
``MutableMapping`` as well as dict's ``copy``. Also
|
||||||
|
provides ``lower_items``.
|
||||||
|
All keys are expected to be strings. The structure remembers the
|
||||||
|
case of the last key to be set, and ``iter(instance)``,
|
||||||
|
``keys()``, ``items()``, ``iterkeys()``, and ``iteritems()``
|
||||||
|
will contain case-sensitive keys. However, querying and contains
|
||||||
|
testing is case insensitive::
|
||||||
|
cid = CaseInsensitiveDict()
|
||||||
|
cid['Accept'] = 'application/json'
|
||||||
|
cid['aCCEPT'] == 'application/json' # True
|
||||||
|
list(cid) == ['Accept'] # True
|
||||||
|
For example, ``headers['content-encoding']`` will return the
|
||||||
|
value of a ``'Content-Encoding'`` response header, regardless
|
||||||
|
of how the header name was originally stored.
|
||||||
|
If the constructor, ``.update``, or equality comparison
|
||||||
|
operations are given keys that have equal ``.lower()``s, the
|
||||||
|
behavior is undefined.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, data=None, **kwargs):
|
||||||
|
self._store = OrderedDict()
|
||||||
|
if data is None:
|
||||||
|
data = {}
|
||||||
|
self.update(data, **kwargs)
|
||||||
|
|
||||||
|
def __setitem__(self, key, value):
|
||||||
|
# Use the lowercased key for lookups, but store the actual
|
||||||
|
# key alongside the value.
|
||||||
|
self._store[key.lower()] = (key, value)
|
||||||
|
|
||||||
|
def __getitem__(self, key):
|
||||||
|
return self._store[key.lower()][1]
|
||||||
|
|
||||||
|
def __delitem__(self, key):
|
||||||
|
del self._store[key.lower()]
|
||||||
|
|
||||||
|
def __iter__(self):
|
||||||
|
return (casedkey for casedkey, mappedvalue in self._store.values())
|
||||||
|
|
||||||
|
def __len__(self):
|
||||||
|
return len(self._store)
|
||||||
|
|
||||||
|
def lower_items(self):
|
||||||
|
"""Like iteritems(), but with all lowercase keys."""
|
||||||
|
return (
|
||||||
|
(lowerkey, keyval[1])
|
||||||
|
for (lowerkey, keyval)
|
||||||
|
in self._store.items()
|
||||||
|
)
|
||||||
|
|
||||||
|
def __eq__(self, other):
|
||||||
|
if isinstance(other, Mapping):
|
||||||
|
other = CaseInsensitiveDict(other)
|
||||||
|
else:
|
||||||
|
return NotImplemented
|
||||||
|
# Compare insensitively
|
||||||
|
return dict(self.lower_items()) == dict(other.lower_items())
|
||||||
|
|
||||||
|
# Copy is required
|
||||||
|
def copy(self):
|
||||||
|
return CaseInsensitiveDict(self._store.values())
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return str(dict(self.items()))
|
||||||
|
|
||||||
|
|
||||||
# ~ Custom classes
|
# ~ Custom classes
|
||||||
|
@ -371,7 +520,8 @@ class LODocument(object):
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
def save(self, path='', **kwargs):
|
def save(self, path='', **kwargs):
|
||||||
opt = _properties(kwargs)
|
# ~ opt = _properties(kwargs)
|
||||||
|
opt = dict_to_property(kwargs)
|
||||||
if path:
|
if path:
|
||||||
self._obj.storeAsURL(_path_url(path), opt)
|
self._obj.storeAsURL(_path_url(path), opt)
|
||||||
else:
|
else:
|
||||||
|
@ -1127,9 +1277,30 @@ def set_properties(model, properties):
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
def get_file(filters=(), multiple=False):
|
def get_config_path(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 _path_system(getattr(path, name))
|
||||||
|
|
||||||
|
|
||||||
|
def get_file(init_dir='', multiple=False, filters=()):
|
||||||
|
"""
|
||||||
|
init_folder: folder default open
|
||||||
|
multiple: True for multiple selected
|
||||||
|
filters: Example
|
||||||
|
(
|
||||||
|
('XML', '*.xml'),
|
||||||
|
('TXT', '*.txt'),
|
||||||
|
)
|
||||||
|
"""
|
||||||
|
if not init_dir:
|
||||||
|
init_dir = get_config_path()
|
||||||
file_picker = create_instance('com.sun.star.ui.dialogs.FilePicker')
|
file_picker = create_instance('com.sun.star.ui.dialogs.FilePicker')
|
||||||
file_picker.setTitle(_('Select file'))
|
file_picker.setTitle(_('Select file'))
|
||||||
|
file_picker.setDisplayDirectory(init_dir)
|
||||||
file_picker.setMultiSelectionMode(multiple)
|
file_picker.setMultiSelectionMode(multiple)
|
||||||
|
|
||||||
if filters:
|
if filters:
|
||||||
|
@ -1242,7 +1413,8 @@ def open_doc(path, **kwargs):
|
||||||
http://api.libreoffice.org/docs/idl/ref/servicecom_1_1sun_1_1star_1_1document_1_1MediaDescriptor.html
|
http://api.libreoffice.org/docs/idl/ref/servicecom_1_1sun_1_1star_1_1document_1_1MediaDescriptor.html
|
||||||
"""
|
"""
|
||||||
path = _path_url(path)
|
path = _path_url(path)
|
||||||
opt = _properties(kwargs)
|
# ~ opt = _properties(kwargs)
|
||||||
|
opt = dict_to_property(kwargs)
|
||||||
doc = get_desktop().loadComponentFromURL(path, '_blank', 0, opt)
|
doc = get_desktop().loadComponentFromURL(path, '_blank', 0, opt)
|
||||||
if doc is None:
|
if doc is None:
|
||||||
return
|
return
|
||||||
|
@ -1278,9 +1450,9 @@ def is_created(path):
|
||||||
return is_file(path) and bool(get_file_size(path))
|
return is_file(path) and bool(get_file_size(path))
|
||||||
|
|
||||||
|
|
||||||
def replace_ext(path, ext):
|
def replace_ext(path, extension):
|
||||||
path, _, name, _ = get_info_path(path)
|
path, _, name, _ = get_info_path(path)
|
||||||
return '{}/{}.{}'.format(path, name, ext)
|
return '{}/{}.{}'.format(path, name, extension)
|
||||||
|
|
||||||
|
|
||||||
def zip_names(path):
|
def zip_names(path):
|
||||||
|
@ -1477,8 +1649,8 @@ class TextTransferable(unohelper.Base, XTransferable):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def set_clipboard(text):
|
def set_clipboard(value):
|
||||||
ts = TextTransferable(text)
|
ts = TextTransferable(value)
|
||||||
sc = create_instance('com.sun.star.datatransfer.clipboard.SystemClipboard')
|
sc = create_instance('com.sun.star.datatransfer.clipboard.SystemClipboard')
|
||||||
sc.setContents(ts, None)
|
sc.setContents(ts, None)
|
||||||
return
|
return
|
||||||
|
@ -1499,3 +1671,142 @@ def copy(doc=None):
|
||||||
def get_epoch():
|
def get_epoch():
|
||||||
now = datetime.datetime.now()
|
now = datetime.datetime.now()
|
||||||
return int(time.mktime(now.timetuple()))
|
return int(time.mktime(now.timetuple()))
|
||||||
|
|
||||||
|
|
||||||
|
def file_copy(source, target='', name=''):
|
||||||
|
p, f, n, e = get_info_path(source)
|
||||||
|
if target:
|
||||||
|
p = target
|
||||||
|
if name:
|
||||||
|
n = name
|
||||||
|
path_new = join(p, '{}{}'.format(n, e))
|
||||||
|
shutil.copy(source, path_new)
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
def get_files(path, ext='*'):
|
||||||
|
docs = []
|
||||||
|
for folder, _, files in os.walk(path):
|
||||||
|
pattern = re.compile(r'\.{}'.format(ext), re.IGNORECASE)
|
||||||
|
docs += [join(folder, f) for f in files if pattern.search(f)]
|
||||||
|
return docs
|
||||||
|
|
||||||
|
|
||||||
|
def _get_menu(type_doc, name_menu):
|
||||||
|
instance = 'com.sun.star.ui.ModuleUIConfigurationManagerSupplier'
|
||||||
|
service = TYPE_DOC[type_doc]
|
||||||
|
manager = create_instance(instance, True)
|
||||||
|
ui = manager.getUIConfigurationManager(service)
|
||||||
|
menus = ui.getSettings(NODE_MENUBAR, True)
|
||||||
|
command = MENUS_APP[type_doc][name_menu]
|
||||||
|
for menu in menus:
|
||||||
|
data = property_to_dict(menu)
|
||||||
|
if data.get('CommandURL', '') == command:
|
||||||
|
idc = data.get('ItemDescriptorContainer', None)
|
||||||
|
return ui, menus, idc
|
||||||
|
return None, None, None
|
||||||
|
|
||||||
|
|
||||||
|
def _get_index_menu(menu, command):
|
||||||
|
for i, m in enumerate(menu):
|
||||||
|
data = property_to_dict(m)
|
||||||
|
cmd = data.get('CommandURL', '')
|
||||||
|
if cmd == command:
|
||||||
|
return i
|
||||||
|
# ~ submenu = data.get('ItemDescriptorContainer', None)
|
||||||
|
# ~ if not submenu is None:
|
||||||
|
# ~ get_index_menu(submenu, command, count + 1)
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
def _store_menu(ui, menus, menu, index, data=(), remove=False):
|
||||||
|
if remove:
|
||||||
|
uno.invoke(menu, 'removeByIndex', (index,))
|
||||||
|
else:
|
||||||
|
properties = dict_to_property(data, True)
|
||||||
|
uno.invoke(menu, 'insertByIndex', (index + 1, properties))
|
||||||
|
ui.replaceSettings(NODE_MENUBAR, menus)
|
||||||
|
ui.store()
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
def insert_menu(type_doc, name_menu, **kwargs):
|
||||||
|
ui, menus, menu = _get_menu(type_doc, name_menu.lower())
|
||||||
|
if menu is None:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
label = kwargs.get('Label', '-')
|
||||||
|
separator = False
|
||||||
|
if label == '-':
|
||||||
|
separator = True
|
||||||
|
command = kwargs.get('Command', '')
|
||||||
|
index = kwargs.get('Index', 0)
|
||||||
|
if not index:
|
||||||
|
index = _get_index_menu(menu, kwargs['After'])
|
||||||
|
if separator:
|
||||||
|
data = {'Type': 1}
|
||||||
|
_store_menu(ui, menus, menu, index, data)
|
||||||
|
return index + 1
|
||||||
|
|
||||||
|
index_menu = _get_index_menu(menu, command)
|
||||||
|
if index_menu:
|
||||||
|
msg = 'Exists: %s' % command
|
||||||
|
debug(msg)
|
||||||
|
return 0
|
||||||
|
|
||||||
|
sub_menu = kwargs.get('Submenu', ())
|
||||||
|
idc = None
|
||||||
|
if sub_menu:
|
||||||
|
idc = ui.createSettings()
|
||||||
|
|
||||||
|
data = {
|
||||||
|
'CommandURL': command,
|
||||||
|
'Label': label,
|
||||||
|
'Style': 0,
|
||||||
|
'Type': 0,
|
||||||
|
'ItemDescriptorContainer': idc
|
||||||
|
}
|
||||||
|
_store_menu(ui, menus, menu, index, data)
|
||||||
|
if sub_menu:
|
||||||
|
_add_sub_menus(ui, menus, idc, sub_menu)
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def _add_sub_menus(ui, menus, menu, sub_menu):
|
||||||
|
for i, sm in enumerate(sub_menu):
|
||||||
|
submenu = sm.pop('Submenu', ())
|
||||||
|
sm['Type'] = 0
|
||||||
|
if submenu:
|
||||||
|
idc = ui.createSettings()
|
||||||
|
sm['ItemDescriptorContainer'] = idc
|
||||||
|
_store_menu(ui, menus, menu, i - 1, sm)
|
||||||
|
if submenu:
|
||||||
|
_add_sub_menus(ui, menus, idc, submenu)
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
def remove_menu(type_doc, name_menu, command):
|
||||||
|
ui, menus, menu = _get_menu(type_doc, name_menu.lower())
|
||||||
|
if menu is None:
|
||||||
|
return False
|
||||||
|
|
||||||
|
index = _get_index_menu(menu, command)
|
||||||
|
if not index:
|
||||||
|
debug('Not exists: %s' % command)
|
||||||
|
return False
|
||||||
|
|
||||||
|
_store_menu(ui, menus, menu, index, remove=True)
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
# ~ name = 'com.sun.star.configuration.ConfigurationProvider'
|
||||||
|
# ~ cp = create_instance(name, True)
|
||||||
|
# ~ node = PropertyValue(Name='nodepath', Value=NODE_SETTING)
|
||||||
|
# ~ try:
|
||||||
|
# ~ cua = cp.createInstanceWithArguments(
|
||||||
|
# ~ 'com.sun.star.configuration.ConfigurationUpdateAccess', (node,))
|
||||||
|
# ~ cua.setPropertyValue(key, json.dumps(value))
|
||||||
|
# ~ cua.commitChanges()
|
||||||
|
# ~ except Exception as e:
|
||||||
|
# ~ log.error(e, exc_info=True)
|
||||||
|
# ~ return False
|
||||||
|
|
Loading…
Reference in New Issue