diff --git a/source/easymacro2.py b/source/easymacro2.py index 8c51200..b5ed6a1 100644 --- a/source/easymacro2.py +++ b/source/easymacro2.py @@ -36,6 +36,7 @@ import sys import threading import time +from decimal import Decimal from enum import IntEnum from functools import wraps from pathlib import Path @@ -45,7 +46,7 @@ import uno import unohelper from com.sun.star.awt import MessageBoxButtons as MSG_BUTTONS from com.sun.star.awt.MessageBoxResults import YES -from com.sun.star.awt import Rectangle +from com.sun.star.awt import Rectangle, Size, Point from com.sun.star.awt import Key, KeyModifier, KeyEvent from com.sun.star.container import NoSuchElementException @@ -167,6 +168,11 @@ MENUS = { 'show': '.uno:SlideShowMenu', } +MIME_TYPE = { + 'png': 'image/png', + 'jpg': 'image/jpeg', +} + MESSAGES = { 'es': { 'OK': 'Aceptar', @@ -639,7 +645,7 @@ class LODocument(object): return self def __exit__(self, exc_type, exc_value, traceback): - pass + self.close() @property def obj(self): @@ -726,13 +732,6 @@ class LODocument(object): def to_pdf(self, path: str='', args: dict={}): path_pdf = path - if path: - if is_dir(path): - _, _, n, _ = get_info_path(self.path) - path_pdf = join(path, '{}.{}'.format(n, EXT['pdf'])) - else: - path_pdf = replace_ext(self.path, EXT['pdf']) - filter_name = '{}_pdf_Export'.format(self.type) filter_data = dict_to_property(args, True) args = { @@ -741,12 +740,12 @@ class LODocument(object): } opt = dict_to_property(args) try: - self.obj.storeToURL(_path_url(path_pdf), opt) + self.obj.storeToURL(_P.to_url(path), opt) except Exception as e: error(e) path_pdf = '' - return path_pdf + return _P.exists(path_pdf) def save(self, path: str='', args: dict={}) -> bool: result = True @@ -795,6 +794,12 @@ class LOCalc(LODocument): # ~ return LOCalcDataBaseRanges(self.obj.DataBaseRanges) return self.obj.DatabaseRanges + def render(self, data, sheet=None, clean=True): + if sheet is None: + sheet = self.active + sheet.render(data, clean=clean) + return + class LOChart(object): @@ -997,13 +1002,27 @@ class LOCalcSheet(object): def name(self, value): self._obj.Name = value + @property + def used_area(self): + cursor = self.get_cursor() + cursor.gotoEndOfUsedArea(True) + return LOCalcRange(self[cursor.AbsoluteName].obj) + @property def draw_page(self): - return self.obj.DrawPage + return LODrawPage(self.obj.DrawPage) + + @property + def dp(self): + return self.draw_page + + @property + def shapes(self): + return self.draw_page @property def doc(self): - return self.draw_page.Forms.Parent + return self.obj.DrawPage.Forms.Parent @property def charts(self): @@ -1013,14 +1032,25 @@ class LOCalcSheet(object): def forms(self): return LOSheetForms(self.obj.DrawPage.Forms) - def get_cursor(self, cell): - return self.obj.createCursorByRange(cell) + def get_cursor(self, cell=None): + if cell is None: + cursor = self.obj.createCursor() + else: + cursor = self.obj.createCursorByRange(cell) + return cursor + + def render(self, data, rango=None, clean=True): + if rango is None: + rango = self.used_area + rango.render(data, clean) + return class LOCalcRange(object): def __init__(self, obj): self._obj = obj + self._sd = None def __getitem__(self, index): return LOCalcRange(self.obj[index]) @@ -1098,12 +1128,14 @@ class LOCalcRange(object): @value.setter def value(self, data): if isinstance(data, str): - print(isinstance(data, str), data[0]) - if data[0] in '=+-': + # ~ print(isinstance(data, str), data[0]) + if data[0] in '=': self.obj.setFormula(data) - print('Set Formula') + # ~ print('Set Formula') else: self.obj.setString(data) + elif isinstance(data, Decimal): + self.obj.setValue(float(data)) elif isinstance(data, (int, float, bool)): self.obj.setValue(data) elif isinstance(data, datetime.datetime): @@ -1199,6 +1231,56 @@ class LOCalcRange(object): self.obj.Columns.OptimalWidth = True return + def render(self, data, clean=True): + self._sd = self.sheet.obj.createSearchDescriptor() + self._sd.SearchCaseSensitive = False + for k, v in data.items(): + self._render_value(k, v) + return + + def _render_value(self, key, value, parent=''): + if isinstance(value, dict): + for k, v in value.items(): + self._render_value(k, v, key) + return + elif isinstance(value, (list, tuple)): + self._render_list(key, value) + return + + search = f'{{{key}}}' + if parent: + search = f'{{{parent}.{key}}}' + ranges = self.find_all(search) + + for cell in ranges or range(0): + self._set_new_value(cell, search, value) + return + + def _set_new_value(self, cell, search, value): + if not cell.ImplementationName == 'ScCellObj': + return + + if isinstance(value, str): + pattern = re.compile(search, re.IGNORECASE) + new_value = pattern.sub(value, cell.String) + cell.String = new_value + else: + LOCalcRange(cell).value = value + return + + def _render_list(self, key, values): + + return + + def find_all(self, search_string): + if self._sd is None: + self._sd = self.sheet.obj.createSearchDescriptor() + self._sd.SearchCaseSensitive = False + + self._sd.setSearchString(search_string) + ranges = self.obj.findAll(self._sd) + return ranges + def filter(self, args, with_headers=True): ff = TableFilterField() ff.Field = args['Field'] @@ -1218,12 +1300,54 @@ class LOCalcRange(object): return +class LOWriterPageStyle(LOBaseObject): + + def __init__(self, obj): + super().__init__(obj) + + def __str__(self): + return f'Page Style: {self.name}' + + @property + def name(self): + return self._obj.Name + + +class LOWriterPageStyles(object): + + def __init__(self, styles): + self._styles = styles + + def __getitem__(self, index): + return LOWriterPageStyle(self._styles[index]) + + @property + def names(self): + return self._styles.ElementNames + + def __str__(self): + return '\n'.join(self.names) + + class LOWriter(LODocument): def __init__(self, obj): super().__init__(obj) self._type = WRITER + @property + def view_cursor(self): + return self._cc.ViewCursor + + @property + def cursor(self): + return self.obj.Text.createTextCursor() + + @property + def page_styles(self): + ps = self.obj.StyleFamilies['PageStyles'] + return LOWriterPageStyles(ps) + class LOShape(LOBaseObject): @@ -1234,6 +1358,9 @@ class LOShape(LOBaseObject): @property def name(self): return self.obj.Name or f'shape{self.index}' + @name.setter + def name(self, value): + self.obj.Name = value @property def index(self): @@ -1246,6 +1373,10 @@ class LOShape(LOBaseObject): def string(self, value): self.obj.String = value + def remove(self): + self.obj.Parent.remove(self.obj) + return + class LODrawPage(LOBaseObject): @@ -1268,6 +1399,10 @@ class LODrawPage(LOBaseObject): def name(self): return self.obj.Name + @property + def doc(self): + return self.obj.Forms.Parent + @property def width(self): return self.obj.Width @@ -1280,6 +1415,45 @@ class LODrawPage(LOBaseObject): def count(self): return self.obj.Count + def create_instance(self, name): + return self.doc.createInstance(name) + + def add(self, type_shape, args={}): + """Insert a shape in page, type shapes: + Line + Rectangle + Ellipse + Text + """ + w = args.get('Width', 3000) + h = args.get('Height', 3000) + x = args.get('X', 1000) + y = args.get('Y', 1000) + + service = f'com.sun.star.drawing.{type_shape}Shape' + shape = self.create_instance(service) + shape.Size = Size(w, h) + shape.Position = Point(x, y) + index = self.count + shape.Name = f'{type_shape.lower()}{index}' + self.obj.add(shape) + return LOShape(self.obj[index], index) + + def insert_image(self, path, args={}): + w = args.get('Width', 3000) + h = args.get('Height', 3000) + x = args.get('X', 1000) + y = args.get('Y', 1000) + + image = self.create_instance('com.sun.star.drawing.GraphicObjectShape') + image.GraphicURL = _P.to_url(path) + image.Size = Size(w, h) + image.Position = Point(x, y) + index = self.count + image.Name = f'image{index}' + self.obj.add(image) + return LOShape(self.obj[index], index) + class LODrawImpress(LODocument): @@ -1298,10 +1472,29 @@ class LODrawImpress(LODocument): sel = self.obj.CurrentSelection[0] return _get_class_uno(sel) + @property + def current_page(self): + return LODrawPage(self._cc.getCurrentPage()) + def paste(self): call_dispatch(self.frame, '.uno:Paste') return self.selection + def add(self, type_shape, args={}): + return self.current_page.add(type_shape, args) + + def insert_image(self, path, args={}): + self.current_page.insert_image(path, args) + return + + # ~ def export(self, path, mimetype='png'): + # ~ args = dict( + # ~ URL = _P.to_url(path), + # ~ MimeType = MIME_TYPE[mimetype], + # ~ ) + # ~ result = _export_image(self.obj, args) + # ~ return result + class LODraw(LODrawImpress): @@ -2666,9 +2859,20 @@ class Paths(object): def home(self): return str(Path.home()) + @classmethod + def replace_ext(cls, path, new_ext): + p = Paths(path) + name = f'{p.name}.{new_ext}' + path = cls.join(p.path, name) + return path + @classmethod def exists(cls, path): - return Path(path).exists() + result = False + if path: + path = cls.to_system(path) + result = Path(path).exists() + return result @classmethod def is_dir(cls, path): @@ -2676,7 +2880,7 @@ class Paths(object): @classmethod def join(cls, *paths): - return str(Path(paths[0]).joinpath(paths[1])) + return str(Path(paths[0]).joinpath(*paths[1:])) @classmethod def save(cls, path, data, encoding='utf-8'): diff --git a/source/zaz.py b/source/zaz.py index 1d40e32..d08a269 100644 --- a/source/zaz.py +++ b/source/zaz.py @@ -747,7 +747,9 @@ def main(args): if not _validate_update(): return - _update_files() + if not args.only_compress: + _update_files() + _compress_oxt() if args.install: @@ -772,6 +774,8 @@ def _process_command_line_arguments(): default=False, required=False) parser.add_argument('-u', '--update', dest='update', action='store_true', default=False, required=False) + parser.add_argument('-oc', '--only_compress', dest='only_compress', + action='store_true', default=False, required=False) return parser.parse_args()