Add render cells

This commit is contained in:
Mauricio Baeza 2020-10-20 21:32:07 -05:00
parent 925adfa982
commit 3b9e13b246
2 changed files with 229 additions and 21 deletions

View File

@ -36,6 +36,7 @@ import sys
import threading import threading
import time import time
from decimal import Decimal
from enum import IntEnum from enum import IntEnum
from functools import wraps from functools import wraps
from pathlib import Path from pathlib import Path
@ -45,7 +46,7 @@ import uno
import unohelper import unohelper
from com.sun.star.awt import MessageBoxButtons as MSG_BUTTONS from com.sun.star.awt import MessageBoxButtons as MSG_BUTTONS
from com.sun.star.awt.MessageBoxResults import YES 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.awt import Key, KeyModifier, KeyEvent
from com.sun.star.container import NoSuchElementException from com.sun.star.container import NoSuchElementException
@ -167,6 +168,11 @@ MENUS = {
'show': '.uno:SlideShowMenu', 'show': '.uno:SlideShowMenu',
} }
MIME_TYPE = {
'png': 'image/png',
'jpg': 'image/jpeg',
}
MESSAGES = { MESSAGES = {
'es': { 'es': {
'OK': 'Aceptar', 'OK': 'Aceptar',
@ -639,7 +645,7 @@ class LODocument(object):
return self return self
def __exit__(self, exc_type, exc_value, traceback): def __exit__(self, exc_type, exc_value, traceback):
pass self.close()
@property @property
def obj(self): def obj(self):
@ -726,13 +732,6 @@ class LODocument(object):
def to_pdf(self, path: str='', args: dict={}): def to_pdf(self, path: str='', args: dict={}):
path_pdf = path 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_name = '{}_pdf_Export'.format(self.type)
filter_data = dict_to_property(args, True) filter_data = dict_to_property(args, True)
args = { args = {
@ -741,12 +740,12 @@ class LODocument(object):
} }
opt = dict_to_property(args) opt = dict_to_property(args)
try: try:
self.obj.storeToURL(_path_url(path_pdf), opt) self.obj.storeToURL(_P.to_url(path), opt)
except Exception as e: except Exception as e:
error(e) error(e)
path_pdf = '' path_pdf = ''
return path_pdf return _P.exists(path_pdf)
def save(self, path: str='', args: dict={}) -> bool: def save(self, path: str='', args: dict={}) -> bool:
result = True result = True
@ -795,6 +794,12 @@ class LOCalc(LODocument):
# ~ return LOCalcDataBaseRanges(self.obj.DataBaseRanges) # ~ return LOCalcDataBaseRanges(self.obj.DataBaseRanges)
return 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): class LOChart(object):
@ -997,13 +1002,27 @@ class LOCalcSheet(object):
def name(self, value): def name(self, value):
self._obj.Name = value self._obj.Name = value
@property
def used_area(self):
cursor = self.get_cursor()
cursor.gotoEndOfUsedArea(True)
return LOCalcRange(self[cursor.AbsoluteName].obj)
@property @property
def draw_page(self): 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 @property
def doc(self): def doc(self):
return self.draw_page.Forms.Parent return self.obj.DrawPage.Forms.Parent
@property @property
def charts(self): def charts(self):
@ -1013,14 +1032,25 @@ class LOCalcSheet(object):
def forms(self): def forms(self):
return LOSheetForms(self.obj.DrawPage.Forms) return LOSheetForms(self.obj.DrawPage.Forms)
def get_cursor(self, cell): def get_cursor(self, cell=None):
return self.obj.createCursorByRange(cell) 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): class LOCalcRange(object):
def __init__(self, obj): def __init__(self, obj):
self._obj = obj self._obj = obj
self._sd = None
def __getitem__(self, index): def __getitem__(self, index):
return LOCalcRange(self.obj[index]) return LOCalcRange(self.obj[index])
@ -1098,12 +1128,14 @@ class LOCalcRange(object):
@value.setter @value.setter
def value(self, data): def value(self, data):
if isinstance(data, str): if isinstance(data, str):
print(isinstance(data, str), data[0]) # ~ print(isinstance(data, str), data[0])
if data[0] in '=+-': if data[0] in '=':
self.obj.setFormula(data) self.obj.setFormula(data)
print('Set Formula') # ~ print('Set Formula')
else: else:
self.obj.setString(data) self.obj.setString(data)
elif isinstance(data, Decimal):
self.obj.setValue(float(data))
elif isinstance(data, (int, float, bool)): elif isinstance(data, (int, float, bool)):
self.obj.setValue(data) self.obj.setValue(data)
elif isinstance(data, datetime.datetime): elif isinstance(data, datetime.datetime):
@ -1199,6 +1231,56 @@ class LOCalcRange(object):
self.obj.Columns.OptimalWidth = True self.obj.Columns.OptimalWidth = True
return 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): def filter(self, args, with_headers=True):
ff = TableFilterField() ff = TableFilterField()
ff.Field = args['Field'] ff.Field = args['Field']
@ -1218,12 +1300,54 @@ class LOCalcRange(object):
return 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): class LOWriter(LODocument):
def __init__(self, obj): def __init__(self, obj):
super().__init__(obj) super().__init__(obj)
self._type = WRITER 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): class LOShape(LOBaseObject):
@ -1234,6 +1358,9 @@ class LOShape(LOBaseObject):
@property @property
def name(self): def name(self):
return self.obj.Name or f'shape{self.index}' return self.obj.Name or f'shape{self.index}'
@name.setter
def name(self, value):
self.obj.Name = value
@property @property
def index(self): def index(self):
@ -1246,6 +1373,10 @@ class LOShape(LOBaseObject):
def string(self, value): def string(self, value):
self.obj.String = value self.obj.String = value
def remove(self):
self.obj.Parent.remove(self.obj)
return
class LODrawPage(LOBaseObject): class LODrawPage(LOBaseObject):
@ -1268,6 +1399,10 @@ class LODrawPage(LOBaseObject):
def name(self): def name(self):
return self.obj.Name return self.obj.Name
@property
def doc(self):
return self.obj.Forms.Parent
@property @property
def width(self): def width(self):
return self.obj.Width return self.obj.Width
@ -1280,6 +1415,45 @@ class LODrawPage(LOBaseObject):
def count(self): def count(self):
return self.obj.Count 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): class LODrawImpress(LODocument):
@ -1298,10 +1472,29 @@ class LODrawImpress(LODocument):
sel = self.obj.CurrentSelection[0] sel = self.obj.CurrentSelection[0]
return _get_class_uno(sel) return _get_class_uno(sel)
@property
def current_page(self):
return LODrawPage(self._cc.getCurrentPage())
def paste(self): def paste(self):
call_dispatch(self.frame, '.uno:Paste') call_dispatch(self.frame, '.uno:Paste')
return self.selection 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): class LODraw(LODrawImpress):
@ -2666,9 +2859,20 @@ class Paths(object):
def home(self): def home(self):
return str(Path.home()) 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 @classmethod
def exists(cls, path): def exists(cls, path):
return Path(path).exists() result = False
if path:
path = cls.to_system(path)
result = Path(path).exists()
return result
@classmethod @classmethod
def is_dir(cls, path): def is_dir(cls, path):
@ -2676,7 +2880,7 @@ class Paths(object):
@classmethod @classmethod
def join(cls, *paths): def join(cls, *paths):
return str(Path(paths[0]).joinpath(paths[1])) return str(Path(paths[0]).joinpath(*paths[1:]))
@classmethod @classmethod
def save(cls, path, data, encoding='utf-8'): def save(cls, path, data, encoding='utf-8'):

View File

@ -747,7 +747,9 @@ def main(args):
if not _validate_update(): if not _validate_update():
return return
_update_files() if not args.only_compress:
_update_files()
_compress_oxt() _compress_oxt()
if args.install: if args.install:
@ -772,6 +774,8 @@ def _process_command_line_arguments():
default=False, required=False) default=False, required=False)
parser.add_argument('-u', '--update', dest='update', action='store_true', parser.add_argument('-u', '--update', dest='update', action='store_true',
default=False, required=False) default=False, required=False)
parser.add_argument('-oc', '--only_compress', dest='only_compress',
action='store_true', default=False, required=False)
return parser.parse_args() return parser.parse_args()