Merge branch 'develop'

Add DrawPage
Add access sheets by code name
This commit is contained in:
el Mau 2022-09-23 12:56:30 -05:00
commit 0ff38cf55f
8 changed files with 480 additions and 16 deletions

View File

@ -1,3 +1,7 @@
v 0.2.0 [23-Sep-2022]
---------------------
- Add DrawPage.
v 0.1.0 [21-Sep-2022] v 0.1.0 [21-Sep-2022]
--------------------- ---------------------
- Tools refactorize and documented. - Tools refactorize and documented.

View File

@ -7,7 +7,6 @@ from .easydocs import LODocuments
def __getattr__(name): def __getattr__(name):
print(name)
classes = { classes = {
'active': LODocuments().active, 'active': LODocuments().active,
'active_sheet': LODocuments().active.active, 'active_sheet': LODocuments().active.active,

View File

@ -14,6 +14,7 @@ from .easymain import (log, DATE_OFFSET,
from .easydoc import LODocument from .easydoc import LODocument
from .easyevents import EventsRangeSelectionListener, LOEvents from .easyevents import EventsRangeSelectionListener, LOEvents
from .easyshape import LOShapes, LOShape from .easyshape import LOShapes, LOShape
from .easydrawpage import LODrawPage
SECONDS_DAY = 60 * 60 * 24 SECONDS_DAY = 60 * 60 * 24
@ -83,6 +84,74 @@ class LOCellStyles():
return LOCellStyle(obj) return LOCellStyle(obj)
# ~ IsFiltered,
# ~ IsManualPageBreak,
# ~ IsStartOfNewPage
class LOSheetRows():
def __init__(self, sheet, obj):
self._sheet = sheet
self._obj = obj
def __getitem__(self, index):
if isinstance(index, int):
rows = LOSheetRows(self._sheet, self.obj[index])
else:
rango = self._sheet[index.start:index.stop,0:]
rows = LOSheetRows(self._sheet, rango.obj.Rows)
return rows
def __len__(self):
return self.obj.Count
def __str__(self):
return self.obj.Name
@property
def obj(self):
return self._obj
@property
def visible(self):
return self._obj.IsVisible
@visible.setter
def visible(self, value):
self._obj.IsVisible = value
@property
def color(self):
return self.obj.CellBackColor
@color.setter
def color(self, value):
self.obj.CellBackColor = value
@property
def is_transparent(self):
return self.obj.IsCellBackgroundTransparent
@is_transparent.setter
def is_transparent(self, value):
self.obj.IsCellBackgroundTransparent = value
@property
def height(self):
return self.obj.Height
@height.setter
def height(self, value):
self.obj.Height = value
def optimal(self):
self.obj.OptimalHeight = True
return
def insert(self, index, count):
self.obj.insertByIndex(index, count)
return
def remove(self, index, count):
self.obj.removeByIndex(index, count)
return
class LOCalcRanges(object): class LOCalcRanges(object):
def __init__(self, obj): def __init__(self, obj):
@ -231,6 +300,10 @@ class LOCalcRange():
"""True if range is cell""" """True if range is cell"""
return self._is_cell return self._is_cell
@property
def is_range(self):
return not self._is_cell
@property @property
def name(self): def name(self):
"""Return the range address like string""" """Return the range address like string"""
@ -456,6 +529,47 @@ class LOCalcRange():
cursor = self.obj.Spreadsheet.createCursorByRange(self.obj) cursor = self.obj.Spreadsheet.createCursorByRange(self.obj)
return cursor return cursor
# ~ To doc
@property
def position(self):
return self.obj.Position
# ~ To doc
@property
def size(self):
return self.obj.Size
@property
def height(self):
return self.obj.Size.Height
@property
def width(self):
return self.obj.Size.Width
@property
def x(self):
return self.obj.Position.X
@property
def y(self):
return self.obj.Position.Y
# ~ To doc
@property
def possize(self):
data = {
'Width': self.size.Width,
'Height': self.size.Height,
'X': self.position.X,
'Y': self.position.Y,
}
return data
@property
def rows(self):
return LOSheetRows(self.sheet, self.obj.Rows)
def clear(self, what: int=ONLY_VALUES): def clear(self, what: int=ONLY_VALUES):
"""Clear contents""" """Clear contents"""
# ~ http://api.libreoffice.org/docs/idl/ref/namespacecom_1_1sun_1_1star_1_1sheet_1_1CellFlags.html # ~ http://api.libreoffice.org/docs/idl/ref/namespacecom_1_1sun_1_1star_1_1sheet_1_1CellFlags.html
@ -541,10 +655,28 @@ class LOCalcSheet(BaseObject):
def password(self, value): def password(self, value):
self.obj.protect(value) self.obj.protect(value)
@property
def draw_page(self):
return LODrawPage(self.obj.DrawPage)
@property
def dp(self):
return self.draw_page
@property
def shapes(self):
return self.draw_page
@property @property
def events(self): def events(self):
return LOEvents(self.obj.Events) return LOEvents(self.obj.Events)
@property
def height(self):
return self.obj.Size.Height
@property
def width(self):
return self.obj.Size.Width
def protect(self, value): def protect(self, value):
self.obj.protect(value) self.obj.protect(value)
return return
@ -587,6 +719,7 @@ class LOCalcSheet(BaseObject):
return sheet return sheet
def activate(self): def activate(self):
"""Activate sheet"""
self.doc.activate(self.obj) self.doc.activate(self.obj)
return return
@ -601,6 +734,41 @@ class LOCalcSheet(BaseObject):
return cursor return cursor
class LOCalcSheetsCodeName(BaseObject):
"""Access by code name sheet"""
def __init__(self, obj):
super().__init__(obj)
self._sheets = obj.Sheets
def __getitem__(self, index):
"""Index access"""
for sheet in self._sheets:
if sheet.CodeName == index:
return LOCalcSheet(sheet)
raise IndexError
def __iter__(self):
self._i = 0
return self
def __next__(self):
"""Interation sheets"""
try:
sheet = LOCalcSheet(self._sheets[self._i])
except Exception as e:
raise StopIteration
self._i += 1
return sheet
def __contains__(self, item):
"""Contains"""
for sheet in self._sheets:
if sheet.CodeName == item:
return True
return False
class LOCalc(LODocument): class LOCalc(LODocument):
"""Classe for Calc module""" """Classe for Calc module"""
TYPE_RANGES = ('ScCellObj', 'ScCellRangeObj') TYPE_RANGES = ('ScCellObj', 'ScCellRangeObj')
@ -622,9 +790,11 @@ class LOCalc(LODocument):
self._sheets[key] = value self._sheets[key] = value
def __len__(self): def __len__(self):
"""Count sheets"""
return self._sheets.Count return self._sheets.Count
def __contains__(self, item): def __contains__(self, item):
"""Contains"""
return item in self._sheets return item in self._sheets
def __iter__(self): def __iter__(self):
@ -632,6 +802,7 @@ class LOCalc(LODocument):
return self return self
def __next__(self): def __next__(self):
"""Interation sheets"""
try: try:
sheet = LOCalcSheet(self._sheets[self._i]) sheet = LOCalcSheet(self._sheets[self._i])
except Exception as e: except Exception as e:
@ -642,6 +813,11 @@ class LOCalc(LODocument):
def __str__(self): def __str__(self):
return f'Calc: {self.title}' return f'Calc: {self.title}'
@property
def sheets(self):
"""Acces by code name sheet"""
return LOCalcSheetsCodeName(self.obj)
@property @property
def headers(self): def headers(self):
"""Get true if is visible columns/rows headers""" """Get true if is visible columns/rows headers"""

View File

@ -7,8 +7,7 @@ from com.sun.star.view.SelectionType import SINGLE, MULTI, RANGE
from .easyevents import * from .easyevents import *
from .easydocs import LODocuments from .easydocs import LODocuments
from .easymain import log, TITLE, Color, BaseObject, create_instance, set_properties from .easymain import log, TITLE, Color, BaseObject, create_instance, set_properties
from .easytools import LOInspect, Paths, Services from .easytools import _, LOInspect, Paths, Services
from .easytools import _
__all__ = [ __all__ = [

View File

@ -0,0 +1,233 @@
#!/usr/bin/env python3
from com.sun.star.awt import Size, Point
from .easymain import BaseObject, set_properties
from .easyshape import LOShape
DEFAULT_WH = 3000
DEFAULT_XY = 1000
# ~ class LOShapeBK(BaseObject):
# ~ @property
# ~ def cell(self):
# ~ return self.anchor
# ~ @property
# ~ def anchor(self):
# ~ obj = self.obj.Anchor
# ~ if obj.ImplementationName == OBJ_CELL:
# ~ obj = LOCalcRange(obj)
# ~ elif obj.ImplementationName == OBJ_TEXT:
# ~ obj = LOWriterTextRange(obj, LODocs().active)
# ~ else:
# ~ debug('Anchor', obj.ImplementationName)
# ~ return obj
# ~ @anchor.setter
# ~ def anchor(self, value):
# ~ if hasattr(value, 'obj'):
# ~ value = value.obj
# ~ try:
# ~ self.obj.Anchor = value
# ~ except Exception as e:
# ~ self.obj.AnchorType = value
# ~ @property
# ~ def visible(self):
# ~ return self.obj.Visible
# ~ @visible.setter
# ~ def visible(self, value):
# ~ self.obj.Visible = value
# ~ @property
# ~ def path(self):
# ~ return self.url
# ~ @property
# ~ def url(self):
# ~ url = ''
# ~ if self.is_image:
# ~ url = _P.to_system(self.obj.GraphicURL.OriginURL)
# ~ return url
# ~ @property
# ~ def mimetype(self):
# ~ mt = ''
# ~ if self.is_image:
# ~ mt = self.obj.GraphicURL.MimeType
# ~ return mt
# ~ @property
# ~ def linked(self):
# ~ l = False
# ~ if self.is_image:
# ~ l = self.obj.GraphicURL.Linked
# ~ return l
# ~ def delete(self):
# ~ self.remove()
# ~ return
# ~ def remove(self):
# ~ self.obj.Parent.remove(self.obj)
# ~ return
# ~ def save(self, path: str, mimetype=DEFAULT_MIME_TYPE):
# ~ if _P.is_dir(path):
# ~ name = self.name
# ~ ext = mimetype.lower()
# ~ else:
# ~ p = _P(path)
# ~ path = p.path
# ~ name = p.name
# ~ ext = p.ext.lower()
# ~ path = _P.join(path, f'{name}.{ext}')
# ~ args = dict(
# ~ URL = _P.to_url(path),
# ~ MimeType = MIME_TYPE[ext],
# ~ )
# ~ if not _export_image(self.obj, args):
# ~ path = ''
# ~ return path
# ~ def save2(self, path: str):
# ~ size = len(self.obj.Bitmap.DIB)
# ~ data = self.obj.GraphicStream.readBytes((), size)
# ~ data = data[-1].value
# ~ path = _P.join(path, f'{self.name}.png')
# ~ _P.save_bin(path, b'')
# ~ return
class LODrawPage(BaseObject):
_type = 'draw_page'
def __init__(self, obj):
super().__init__(obj)
def __getitem__(self, index):
if isinstance(index, int):
shape = LOShape(self.obj[index])
else:
for i, o in enumerate(self.obj):
shape = self.obj[i]
name = shape.Name or f'shape{i}'
if name == index:
shape = LOShape(shape)
break
return shape
def __iter__(self):
self._index = 0
return self
def __next__(self):
if self._index == self.count:
raise StopIteration
shape = self[self._index]
self._index += 1
return shape
def __contains__(self, source_name):
result = False
for i, o in enumerate(self.obj):
shape = self.obj[i]
name = shape.Name or f'shape{i}'
if name == source_name:
result = True
break
return result
@property
def name(self):
return self.obj.Name
@property
def doc(self):
return self.obj.Forms.Parent
@property
def width(self):
return self.obj.Width
@property
def height(self):
return self.obj.Height
@property
def count(self):
return self.obj.Count
@property
def last(self):
return self[self.count - 1]
def _create_instance(self, name):
return self.doc.createInstance(name)
def add(self, type_shape, options={}):
properties = options.copy()
"""Insert a shape in page, type shapes:
Line
Rectangle
Ellipse
Text
Connector
"""
index = self.count
default_height = DEFAULT_WH
if type_shape == 'Line':
default_height = 0
w = properties.pop('Width', DEFAULT_WH)
h = properties.pop('Height', default_height)
x = properties.pop('X', DEFAULT_XY)
y = properties.pop('Y', DEFAULT_XY)
name = properties.pop('Name', f'{type_shape.lower()}{index}')
service = f'com.sun.star.drawing.{type_shape}Shape'
shape = self._create_instance(service)
shape.Size = Size(w, h)
shape.Position = Point(x, y)
shape.Name = name
self.obj.add(shape)
if properties:
set_properties(shape, properties)
# ~ return LOShape(self.obj[index], index)
return LOShape(self.obj[index])
def remove(self, shape):
if hasattr(shape, 'obj'):
shape = shape.obj
return self.obj.remove(shape)
def remove_all(self):
while self.count:
self.obj.remove(self.obj[0])
return
def insert_image(self, path, options={}):
args = options.copy()
index = self.count
w = args.get('Width', 3000)
h = args.get('Height', 3000)
x = args.get('X', 1000)
y = args.get('Y', 1000)
name = args.get('Name', f'image{index}')
image = self.create_instance('com.sun.star.drawing.GraphicObjectShape')
if isinstance(path, str):
image.GraphicURL = _P.to_url(path)
else:
gp = create_instance('com.sun.star.graphic.GraphicProvider')
properties = dict_to_property({'InputStream': path})
image.Graphic = gp.queryGraphic(properties)
self.obj.add(image)
image.Size = Size(w, h)
image.Position = Point(x, y)
image.Name = name
return LOShape(self.obj[index], index)

View File

@ -15,8 +15,11 @@ from typing import Any, Union
import uno import uno
import unohelper import unohelper
from com.sun.star.beans import PropertyValue, NamedValue from com.sun.star.beans import PropertyValue, NamedValue, StringPair
from com.sun.star.datatransfer import XTransferable, DataFlavor from com.sun.star.datatransfer import XTransferable, DataFlavor
from com.sun.star.ui.dialogs import TemplateDescription
from .messages import MESSAGES
__all__ = [ __all__ = [
@ -144,6 +147,16 @@ _info_debug = f"Python: {sys.version}\n\n{platform.platform()}\n\n" + '\n'.join(
INFO_DEBUG = f"{NAME} v{VERSION} {LANGUAGE}\n\n{_info_debug}" INFO_DEBUG = f"{NAME} v{VERSION} {LANGUAGE}\n\n{_info_debug}"
def _(msg):
if LANG == 'en':
return msg
if not LANG in MESSAGES:
return msg
return MESSAGES[LANG][msg]
def dict_to_property(values: dict, uno_any: bool=False): def dict_to_property(values: dict, uno_any: bool=False):
"""Convert dictionary to array of PropertyValue """Convert dictionary to array of PropertyValue
@ -842,6 +855,8 @@ class Paths(object):
`See API <https://api.libreoffice.org/docs/idl/ref/namespacecom_1_1sun_1_1star_1_1ui_1_1dialogs_1_1TemplateDescription.html>`_ `See API <https://api.libreoffice.org/docs/idl/ref/namespacecom_1_1sun_1_1star_1_1ui_1_1dialogs_1_1TemplateDescription.html>`_
""" """
paths = ''
if not init_dir: if not init_dir:
init_dir = cls.documents init_dir = cls.documents
init_dir = cls.to_url(init_dir) init_dir = cls.to_url(init_dir)
@ -858,6 +873,7 @@ class Paths(object):
paths = [cls.to_system(p) for p in file_picker.getSelectedFiles()] paths = [cls.to_system(p) for p in file_picker.getSelectedFiles()]
if not multiple: if not multiple:
paths = paths[0] paths = paths[0]
return paths return paths
@classmethod @classmethod

View File

@ -1,5 +1,8 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
from com.sun.star.awt import Size, Point
from .easymain import BaseObject, set_properties
class LOShapes(object): class LOShapes(object):
_type = 'ShapeCollection' _type = 'ShapeCollection'
@ -38,7 +41,7 @@ class LOShapes(object):
return self._obj return self._obj
class LOShape(): class LOShape(BaseObject):
IMAGE = 'com.sun.star.drawing.GraphicObjectShape' IMAGE = 'com.sun.star.drawing.GraphicObjectShape'
def __init__(self, obj): def __init__(self, obj):
@ -117,9 +120,30 @@ class LOShape():
@property @property
def x(self): def x(self):
return self.position.X return self.position.X
@x.setter
def x(self, value):
self.obj.Position = Point(value, self.y)
@property @property
def y(self): def y(self):
return self.position.Y return self.position.Y
@y.setter
def y(self, value):
self.obj.Position = Point(self.x, value)
@property
def possize(self):
data = {
'Width': self.size.Width,
'Height': self.size.Height,
'X': self.position.X,
'Y': self.position.Y,
}
return data
@possize.setter
def possize(self, value):
self.obj.Size = Size(value['Width'], value['Height'])
self.obj.Position = Point(value['X'], value['Y'])
@property @property
def string(self): def string(self):
@ -142,3 +166,26 @@ class LOShape():
def description(self, value): def description(self, value):
self.obj.Description = value self.obj.Description = value
@property
def in_background(self):
return self.obj.LayerID
@in_background.setter
def in_background(self, value):
self.obj.LayerID = value
@property
def layerid(self):
return self.obj.LayerID
@layerid.setter
def layerid(self, value):
self.obj.LayerID = value
@property
def is_range(self):
return False
@property
def is_cell(self):
return False

View File

@ -40,9 +40,9 @@ from com.sun.star.ui.dialogs import TemplateDescription
from .easyuno import MessageBoxType from .easyuno import MessageBoxType
from .easydocs import LODocuments from .easydocs import LODocuments
from .messages import MESSAGES
from .easyplus import mureq from .easyplus import mureq
from .easymain import ( from .easymain import (
_,
CTX, CTX,
DATE_OFFSET, DATE_OFFSET,
IS_MAC, IS_MAC,
@ -96,16 +96,6 @@ FILES = {
_EVENTS = {} _EVENTS = {}
def _(msg):
if LANG == 'en':
return msg
if not LANG in MESSAGES:
return msg
return MESSAGES[LANG][msg]
def debug(*messages) -> None: def debug(*messages) -> None:
"""Show messages debug """Show messages debug