Add support for dialogs
This commit is contained in:
parent
619740267c
commit
3ba5a3982d
14
README.md
14
README.md
|
@ -1,4 +1,4 @@
|
||||||
ZAZ
|
# ZAZ
|
||||||
|
|
||||||
Scripts and library for develop macros in LibreOffice with Python.
|
Scripts and library for develop macros in LibreOffice with Python.
|
||||||
|
|
||||||
|
@ -8,3 +8,15 @@ For Python 3.6+
|
||||||
|
|
||||||
* See [documentation](https://gitlab.com/mauriciobaeza/zaz/wikis/home)
|
* See [documentation](https://gitlab.com/mauriciobaeza/zaz/wikis/home)
|
||||||
* Ver [documentación](https://gitlab.com/mauriciobaeza/zaz/wikis/inicio)
|
* Ver [documentación](https://gitlab.com/mauriciobaeza/zaz/wikis/inicio)
|
||||||
|
|
||||||
|
|
||||||
|
This extension have a cost of maintenance of 1 euro every year.
|
||||||
|
|
||||||
|
BCH: `1RPLWHJW34p7pMQV1ft4x7eWhAYw69Dsb`
|
||||||
|
|
||||||
|
BTC: `3Fe4JuADrAK8Qs7GDAxbSXR8E54avwZJLW`
|
||||||
|
|
||||||
|
|
||||||
|
## Extension develop with ZAZ
|
||||||
|
|
||||||
|
* https://gitlab.com/mauriciobaeza/zaz-barcode
|
||||||
|
|
|
@ -23,7 +23,7 @@ import logging
|
||||||
# ~ 1 = normal extension
|
# ~ 1 = normal extension
|
||||||
# ~ 2 = new component
|
# ~ 2 = new component
|
||||||
# ~ 3 = Calc addin
|
# ~ 3 = Calc addin
|
||||||
TYPE_EXTENSION = 1
|
TYPE_EXTENSION = 2
|
||||||
|
|
||||||
# ~ https://semver.org/
|
# ~ https://semver.org/
|
||||||
VERSION = '0.1.0'
|
VERSION = '0.1.0'
|
||||||
|
@ -94,8 +94,8 @@ CONTEXT = {
|
||||||
# ~ Menus, only for TYPE_EXTENSION = 1
|
# ~ Menus, only for TYPE_EXTENSION = 1
|
||||||
# ~ Parent can be: AddonMenu or OfficeMenuBar
|
# ~ Parent can be: AddonMenu or OfficeMenuBar
|
||||||
# ~ For icons con name: NAME_16.bmp, used only NAME
|
# ~ For icons con name: NAME_16.bmp, used only NAME
|
||||||
# ~ PARENT = 'AddonMenu'
|
# ~ PARENT = ''
|
||||||
# ~ MENU_MAIN = ''
|
# ~ MENU_MAIN = {}
|
||||||
PARENT = 'OfficeMenuBar'
|
PARENT = 'OfficeMenuBar'
|
||||||
MENU_MAIN = {
|
MENU_MAIN = {
|
||||||
'en': 'My Extension',
|
'en': 'My Extension',
|
||||||
|
@ -362,29 +362,31 @@ for i, m in enumerate(MENUS):
|
||||||
toolbar.append(NODE_MENU.format(**values))
|
toolbar.append(NODE_MENU.format(**values))
|
||||||
|
|
||||||
NODE_TOOLBAR = ''
|
NODE_TOOLBAR = ''
|
||||||
if PARENT == 'AddonMenu':
|
NODE_MENUS = ''
|
||||||
NODE_MENUS = '\n'.join(menus)
|
if TYPE_EXTENSION == 1:
|
||||||
else:
|
if PARENT == 'AddonMenu':
|
||||||
tmp = ' <value xml:lang="{}">{}</value>'
|
NODE_MENUS = '\n'.join(menus)
|
||||||
titles = '\n'.join([tmp.format(k, v) for k, v in MENU_MAIN.items()])
|
else:
|
||||||
SUBMENUS = '<node oor:name="Submenu">\n ' + '\n'.join(menus) + '\n </node>'
|
tmp = ' <value xml:lang="{}">{}</value>'
|
||||||
NODE_MENUS = f""" <node oor:name="{ID}" oor:op="replace">
|
titles = '\n'.join([tmp.format(k, v) for k, v in MENU_MAIN.items()])
|
||||||
<prop oor:name="Title" oor:type="xs:string">
|
SUBMENUS = '<node oor:name="Submenu">\n ' + '\n'.join(menus) + '\n </node>'
|
||||||
{titles}
|
NODE_MENUS = f""" <node oor:name="{ID}" oor:op="replace">
|
||||||
</prop>
|
<prop oor:name="Title" oor:type="xs:string">
|
||||||
<prop oor:name="Target" oor:type="xs:string">
|
{titles}
|
||||||
<value>_self</value>
|
</prop>
|
||||||
</prop>
|
<prop oor:name="Target" oor:type="xs:string">
|
||||||
{SUBMENUS}
|
<value>_self</value>
|
||||||
</node>"""
|
</prop>
|
||||||
|
{SUBMENUS}
|
||||||
|
</node>"""
|
||||||
|
|
||||||
if toolbar:
|
if toolbar:
|
||||||
node_toolbars = '\n'.join(toolbar)
|
node_toolbars = '\n'.join(toolbar)
|
||||||
NODE_TOOLBAR = f""" <node oor:name="OfficeToolBar">
|
NODE_TOOLBAR = f""" <node oor:name="OfficeToolBar">
|
||||||
<node oor:name="{ID}" oor:op="replace">
|
<node oor:name="{ID}" oor:op="replace">
|
||||||
{node_toolbars}
|
{node_toolbars}
|
||||||
</node>
|
</node>
|
||||||
</node>"""
|
</node>"""
|
||||||
|
|
||||||
FILE_ADDONS = f"""<?xml version='1.0' encoding='UTF-8'?>
|
FILE_ADDONS = f"""<?xml version='1.0' encoding='UTF-8'?>
|
||||||
<oor:component-data xmlns:oor="http://openoffice.org/2001/registry" xmlns:xs="http://www.w3.org/2001/XMLSchema" oor:name="Addons" oor:package="org.openoffice.Office">
|
<oor:component-data xmlns:oor="http://openoffice.org/2001/registry" xmlns:xs="http://www.w3.org/2001/XMLSchema" oor:name="Addons" oor:package="org.openoffice.Office">
|
||||||
|
|
|
@ -44,31 +44,39 @@ from com.sun.star.awt import XActionListener
|
||||||
from com.sun.star.awt import XMouseListener
|
from com.sun.star.awt import XMouseListener
|
||||||
|
|
||||||
|
|
||||||
FILE_NAME_DEBUG = 'debug.log'
|
|
||||||
MSG_LANG = {
|
MSG_LANG = {
|
||||||
'es': {
|
'es': {
|
||||||
'OK': 'Aceptar',
|
'OK': 'Aceptar',
|
||||||
'Cancel': 'Cancelar',
|
'Cancel': 'Cancelar',
|
||||||
|
'Select file': 'Seleccionar archivo',
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FORMAT = '%(asctime)s - %(levelname)s - %(message)s'
|
|
||||||
DATE = '%d/%m/%Y %H:%M:%S'
|
FILE_NAME_DEBUG = 'zaz-debug.log'
|
||||||
|
LOG_FORMAT = '%(asctime)s - %(levelname)s - %(message)s'
|
||||||
|
LOG_DATE = '%d/%m/%Y %H:%M:%S'
|
||||||
LEVEL_ERROR = logging.getLevelName(logging.ERROR)
|
LEVEL_ERROR = logging.getLevelName(logging.ERROR)
|
||||||
LEVEL_DEBUG = logging.getLevelName(logging.DEBUG)
|
LEVEL_DEBUG = logging.getLevelName(logging.DEBUG)
|
||||||
LEVEL_INFO = logging.getLevelName(logging.INFO)
|
LEVEL_INFO = logging.getLevelName(logging.INFO)
|
||||||
logging.addLevelName(logging.ERROR, f'\033[1;41m{LEVEL_ERROR}\033[1;0m')
|
logging.addLevelName(logging.ERROR, f'\033[1;41m{LEVEL_ERROR}\033[1;0m')
|
||||||
logging.addLevelName(logging.DEBUG, f'\x1b[33m{LEVEL_DEBUG}\033[1;0m')
|
logging.addLevelName(logging.DEBUG, f'\x1b[33m{LEVEL_DEBUG}\033[1;0m')
|
||||||
logging.addLevelName(logging.INFO, f'\x1b[32m{LEVEL_INFO}\033[1;0m')
|
logging.addLevelName(logging.INFO, f'\x1b[32m{LEVEL_INFO}\033[1;0m')
|
||||||
logging.basicConfig(level=logging.DEBUG, format=FORMAT, datefmt=DATE)
|
logging.basicConfig(level=logging.DEBUG, format=LOG_FORMAT, datefmt=LOG_DATE)
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
OS = sys.platform
|
||||||
|
USER = getpass.getuser()
|
||||||
|
PC = platform.node()
|
||||||
|
|
||||||
|
WIN = 'win32'
|
||||||
OBJ_CELL = 'ScCellObj'
|
OBJ_CELL = 'ScCellObj'
|
||||||
OBJ_RANGE = 'ScCellRangeObj'
|
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)
|
||||||
|
|
||||||
|
|
||||||
CTX = uno.getComponentContext()
|
CTX = uno.getComponentContext()
|
||||||
SM = CTX.getServiceManager()
|
SM = CTX.getServiceManager()
|
||||||
|
|
||||||
|
@ -96,15 +104,9 @@ def _get_config(key, node_name):
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
|
|
||||||
OS = sys.platform
|
|
||||||
USER = getpass.getuser()
|
|
||||||
PC = platform.node()
|
|
||||||
|
|
||||||
LANGUAGE = _get_config('ooLocale', 'org.openoffice.Setup/L10N/')
|
LANGUAGE = _get_config('ooLocale', 'org.openoffice.Setup/L10N/')
|
||||||
NAME = TITLE = _get_config('ooName', 'org.openoffice.Setup/Product')
|
NAME = TITLE = _get_config('ooName', 'org.openoffice.Setup/Product')
|
||||||
VERSION = _get_config('ooSetupVersion', 'org.openoffice.Setup/Product')
|
VERSION = _get_config('ooSetupVersion', 'org.openoffice.Setup/Product')
|
||||||
# ~ DESKTOP = create_instance('com.sun.star.frame.Desktop', True)
|
|
||||||
|
|
||||||
INFO_DEBUG = '{}\n\n{}\n\n{}'.format(
|
INFO_DEBUG = '{}\n\n{}\n\n{}'.format(
|
||||||
sys.version, platform.platform(), '\n'.join(sys.path))
|
sys.version, platform.platform(), '\n'.join(sys.path))
|
||||||
|
|
||||||
|
@ -120,8 +122,9 @@ def mri(obj):
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
def debug(info):
|
def debug(*info):
|
||||||
log.debug(info)
|
for i in info:
|
||||||
|
log.debug(i)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
|
@ -219,6 +222,11 @@ def get_type_doc(obj):
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
|
|
||||||
|
def _properties(values):
|
||||||
|
p = [PropertyValue(Name=n, Value=v) for n, v in values.items()]
|
||||||
|
return tuple(p)
|
||||||
|
|
||||||
|
|
||||||
# ~ Custom classes
|
# ~ Custom classes
|
||||||
|
|
||||||
|
|
||||||
|
@ -281,6 +289,10 @@ class LODocument(object):
|
||||||
obj = self.obj.createInstance(name)
|
obj = self.obj.createInstance(name)
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
|
def close(self):
|
||||||
|
self.obj.close(True)
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
class LOCalc(LODocument):
|
class LOCalc(LODocument):
|
||||||
|
|
||||||
|
@ -926,6 +938,7 @@ class LODialog(object):
|
||||||
}
|
}
|
||||||
return classes[tipo](obj)
|
return classes[tipo](obj)
|
||||||
|
|
||||||
|
@catch_exception
|
||||||
def add_control(self, properties):
|
def add_control(self, properties):
|
||||||
tipo = properties.pop('Type').lower()
|
tipo = properties.pop('Type').lower()
|
||||||
model = self.model.createInstance(self._get_control_model(tipo))
|
model = self.model.createInstance(self._get_control_model(tipo))
|
||||||
|
@ -989,6 +1002,7 @@ def create_dialog(properties):
|
||||||
return LODialog(properties)
|
return LODialog(properties)
|
||||||
|
|
||||||
|
|
||||||
|
@catch_exception
|
||||||
def set_properties(model, properties):
|
def set_properties(model, properties):
|
||||||
if 'X' in properties:
|
if 'X' in properties:
|
||||||
properties['PositionX'] = properties.pop('X')
|
properties['PositionX'] = properties.pop('X')
|
||||||
|
@ -998,3 +1012,129 @@ def set_properties(model, properties):
|
||||||
values = tuple(properties.values())
|
values = tuple(properties.values())
|
||||||
model.setPropertyValues(keys, values)
|
model.setPropertyValues(keys, values)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
|
def get_file(filters=(), multiple=False):
|
||||||
|
file_picker = create_instance('com.sun.star.ui.dialogs.FilePicker')
|
||||||
|
file_picker.setTitle(_('Select file'))
|
||||||
|
file_picker.setMultiSelectionMode(multiple)
|
||||||
|
|
||||||
|
if filters:
|
||||||
|
file_picker.setCurrentFilter(filters[0][0])
|
||||||
|
for f in filters:
|
||||||
|
file_picker.appendFilter(f[0], f[1])
|
||||||
|
|
||||||
|
if file_picker.execute():
|
||||||
|
if multiple:
|
||||||
|
return [_path_system(f) for f in file_picker.getSelectedFiles()]
|
||||||
|
return _path_system(file_picker.getSelectedFiles()[0])
|
||||||
|
|
||||||
|
return ''
|
||||||
|
|
||||||
|
|
||||||
|
def get_info_path(path):
|
||||||
|
path, filename = os.path.split(path)
|
||||||
|
name, extension = os.path.splitext(filename)
|
||||||
|
return (path, filename, name, extension)
|
||||||
|
|
||||||
|
|
||||||
|
def inputbox(message, default='', title=TITLE):
|
||||||
|
|
||||||
|
class ControllersInput(object):
|
||||||
|
|
||||||
|
def __init__(self, dlg):
|
||||||
|
self.d = dlg
|
||||||
|
|
||||||
|
def cmd_ok_action(self, event):
|
||||||
|
self.d.close(1)
|
||||||
|
return
|
||||||
|
|
||||||
|
args = {
|
||||||
|
'Title': title,
|
||||||
|
'Width': 200,
|
||||||
|
'Height': 80,
|
||||||
|
}
|
||||||
|
dlg = LODialog(args)
|
||||||
|
dlg.events = ControllersInput(dlg)
|
||||||
|
|
||||||
|
args = {
|
||||||
|
'Type': 'Label',
|
||||||
|
'Name': 'lbl_msg',
|
||||||
|
'Label': message,
|
||||||
|
'Width': 140,
|
||||||
|
'Height': 50,
|
||||||
|
'X': 5,
|
||||||
|
'Y': 5,
|
||||||
|
'MultiLine': True,
|
||||||
|
'Border': 1,
|
||||||
|
}
|
||||||
|
dlg.add_control(args)
|
||||||
|
|
||||||
|
args = {
|
||||||
|
'Type': 'Text',
|
||||||
|
'Name': 'txt_value',
|
||||||
|
'Text': default,
|
||||||
|
'Width': 190,
|
||||||
|
'Height': 15,
|
||||||
|
}
|
||||||
|
dlg.add_control(args)
|
||||||
|
dlg.txt_value.move(dlg.lbl_msg)
|
||||||
|
|
||||||
|
args = {
|
||||||
|
'Type': 'button',
|
||||||
|
'Name': 'cmd_ok',
|
||||||
|
'Label': _('OK'),
|
||||||
|
'Width': 40,
|
||||||
|
'Height': 15,
|
||||||
|
'DefaultButton': True,
|
||||||
|
'PushButtonType': 1,
|
||||||
|
}
|
||||||
|
dlg.add_control(args)
|
||||||
|
dlg.cmd_ok.move(dlg.lbl_msg, 10, 0)
|
||||||
|
|
||||||
|
args = {
|
||||||
|
'Type': 'button',
|
||||||
|
'Name': 'cmd_cancel',
|
||||||
|
'Label': _('Cancel'),
|
||||||
|
'Width': 40,
|
||||||
|
'Height': 15,
|
||||||
|
'PushButtonType': 2,
|
||||||
|
}
|
||||||
|
dlg.add_control(args)
|
||||||
|
dlg.cmd_cancel.move(dlg.cmd_ok)
|
||||||
|
|
||||||
|
if dlg.open():
|
||||||
|
return dlg.txt_value.value
|
||||||
|
|
||||||
|
return ''
|
||||||
|
|
||||||
|
|
||||||
|
def open(path, **kwargs):
|
||||||
|
""" Open document in path
|
||||||
|
Usually options:
|
||||||
|
Hidden: True or False
|
||||||
|
AsTemplate: True or False
|
||||||
|
ReadOnly: True or False
|
||||||
|
Password: super_secret
|
||||||
|
MacroExecutionMode: 4 = Activate macros
|
||||||
|
Preview: True or False
|
||||||
|
"""
|
||||||
|
path = _path_url(path)
|
||||||
|
opt = _properties(kwargs)
|
||||||
|
doc = get_desktop().loadComponentFromURL(path, '_blank', 0, opt)
|
||||||
|
if doc is None:
|
||||||
|
return
|
||||||
|
|
||||||
|
return _get_class_doc(doc)
|
||||||
|
|
||||||
|
|
||||||
|
def open_file(path):
|
||||||
|
if OS == WIN:
|
||||||
|
os.startfile(path)
|
||||||
|
else:
|
||||||
|
subprocess.call(['xdg-open', path])
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
def join(*paths):
|
||||||
|
return os.path.join(*paths)
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 754 B After Width: | Height: | Size: 26 KiB |
Loading…
Reference in New Issue