From 868e1feffd177fe2db1a408e259d3a692cdb2406 Mon Sep 17 00:00:00 2001 From: tudstlennkozh <61184193+tudstlennkozh@users.noreply.github.com> Date: Tue, 18 Feb 2020 11:03:37 +0100 Subject: [PATCH 01/17] Update __init__.py for LibreOffice >= 6 to avoid errors in LibreOffice >= 6, use winreg and read some more registry keys --- oosheet/__init__.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/oosheet/__init__.py b/oosheet/__init__.py index 1989bd4..cb2d917 100644 --- a/oosheet/__init__.py +++ b/oosheet/__init__.py @@ -9,14 +9,16 @@ #Some environment variables must be modified #get the install path from registry - import _winreg + import winreg # try with OpenOffice, LibreOffice on W7 - for _key in [# OpenOffice 3.3 + for key in [# OpenOffice 3.3 "SOFTWARE\\OpenOffice.org\\UNO\\InstallPath", # LibreOffice 3.4.5 on W7 - "SOFTWARE\\Wow6432Node\\LibreOffice\\UNO\\InstallPath"]: + "SOFTWARE\\Wow6432Node\\LibreOffice\\UNO\\InstallPath", + # LibreOffice >= 6 + "SOFTWARE\\LibreOffice\\UNO\\InstallPath"]: try: - value = _winreg.QueryValue(_winreg.HKEY_LOCAL_MACHINE, _key) + value = winreg.QueryValue(winreg.HKEY_LOCAL_MACHINE, key) except Exception as detail: _errMess = "%s" % detail else: @@ -75,7 +77,7 @@ def load_cache(self): def _detect_macro_environment(self): for layer in inspect.stack(): - if layer[1].startswith('vnd.sun.star.tdoc:'): + if layer[1].startswith('vnd.sun.star.tdoc:') or 'pythonscript.py' in layer[1]: return True return False From 523519b26b5f3d4ee1b3a4341325be00de30c2ff Mon Sep 17 00:00:00 2001 From: tudstlennkozh <61184193+tudstlennkozh@users.noreply.github.com> Date: Thu, 27 Feb 2020 14:42:55 +0100 Subject: [PATCH 02/17] update __init__.py for OODoc.alert() modified OODoc.alert() in order to run correctly --- oosheet/__init__.py | 28 ++++++++-------------------- 1 file changed, 8 insertions(+), 20 deletions(-) diff --git a/oosheet/__init__.py b/oosheet/__init__.py index cb2d917..26859f5 100644 --- a/oosheet/__init__.py +++ b/oosheet/__init__.py @@ -40,10 +40,10 @@ import uno, re, zipfile, types, inspect, tempfile, shutil, subprocess from datetime import datetime, timedelta -# http://codesnippets.services.openoffice.org/Office/Office.MessageBoxWithTheUNOBasedToolkit.snip -from com.sun.star.awt import WindowDescriptor -from com.sun.star.awt.WindowClass import MODALTOP -from com.sun.star.awt.VclWindowPeerAttribute import OK +# for alert() +from com.sun.star.awt import MessageBoxButtons as MSG_BUTTONS +from com.sun.star.awt.MessageBoxType import MESSAGEBOX + class OODoc(object): """ @@ -173,22 +173,10 @@ def dispatch(self, cmd, *args): def alert(self, msg, title = u'Alert'): """Opens an alert window with a message and title, and requires user to click 'Ok'""" - parentWin = self.model.CurrentController.Frame.ContainerWindow - - aDescriptor = WindowDescriptor() - aDescriptor.Type = MODALTOP - aDescriptor.WindowServiceName = 'messbox' - aDescriptor.ParentIndex = -1 - aDescriptor.Parent = parentWin - aDescriptor.WindowAttributes = OK - - tk = parentWin.getToolkit() - box = tk.createWindow(aDescriptor) - - box.setMessageText(msg) - - if title: - box.setCaptionText(title) + ctx = self.get_context() + toolkit = ctx.ServiceManager.createInstanceWithContext('com.sun.star.awt.Toolkit', ctx) + parentWin = toolkit.getDesktopWindow() + box = toolkit.createMessageBox(parentWin, MESSAGEBOX, MSG_BUTTONS.BUTTONS_OK, title, str(msg)) box.execute() From bae72a2783dcdf0cacbbef31716b899969b4e37d Mon Sep 17 00:00:00 2001 From: tudstlennkozh <61184193+tudstlennkozh@users.noreply.github.com> Date: Fri, 28 Feb 2020 16:23:18 +0100 Subject: [PATCH 03/17] update __init__.py added _msgBox() and alertOkCancel() functions --- oosheet/__init__.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/oosheet/__init__.py b/oosheet/__init__.py index 26859f5..dccd6a1 100644 --- a/oosheet/__init__.py +++ b/oosheet/__init__.py @@ -171,15 +171,23 @@ def dispatch(self, cmd, *args): self.dispatcher.executeDispatch(self.model.getCurrentController(), '.uno:%s' % cmd, '', 0, args) - def alert(self, msg, title = u'Alert'): - """Opens an alert window with a message and title, and requires user to click 'Ok'""" + def _msgBox(self, msg, title, box_type, button_type): + """call to uno API to display a messageBox""" ctx = self.get_context() toolkit = ctx.ServiceManager.createInstanceWithContext('com.sun.star.awt.Toolkit', ctx) parentWin = toolkit.getDesktopWindow() - box = toolkit.createMessageBox(parentWin, MESSAGEBOX, MSG_BUTTONS.BUTTONS_OK, title, str(msg)) + box = toolkit.createMessageBox(parentWin, box_type, button_type, title, msg) + + return box.execute() - box.execute() + def alert(self, msg, title = u'Alert'): + """Opens an alert window with a message and title, and requires user to click 'Ok'""" + self._msgBox(str(msg), title, MESSAGEBOX, MSG_BUTTONS.BUTTONS_OK) + def alertOkCancel(self, msg, title = u'Alert'): + """Opens an alert window and allows user to choose between ok or cancel""" + return self._msgBox(str(msg), title, MESSAGEBOX, MSG_BUTTONS.BUTTONS_OK_CANCEL) + def undo(self): """Undo the last action""" self.dispatch('.uno:Undo') From 59141b9eab04fdd2b72247cdc2bf5822b08a4aa5 Mon Sep 17 00:00:00 2001 From: tudstlennkozh <61184193+tudstlennkozh@users.noreply.github.com> Date: Mon, 19 Oct 2020 15:22:27 +0200 Subject: [PATCH 04/17] moving to version 1.3.1 (to simplify updates via pip) --- docs/index.rst | 4 ++++ setup.py | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/index.rst b/docs/index.rst index 3d0a5e8..6896eb5 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -95,6 +95,10 @@ Luc Jean sent patch that allows OOSheet to run on Windows Vista with default Pyt Changelog ========= +- 1.3.1 + - added OODoc.alert() + - Works with LO >= 6 + - 1.3 - Works with Python 3 and LibreOffice 5 diff --git a/setup.py b/setup.py index 5b6465e..96ce8ff 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ import os setup(name = 'oosheet', - version = '1.3', + version = '1.3.1', description = 'LibreOffice Spreadsheet scripting library', long_description = open(os.path.join(os.path.dirname(__file__), "README")).read(), author = "Luis Fagundes", From 65b7ecf841ceb7a7d0ae3f8b25ec852728a321e7 Mon Sep 17 00:00:00 2001 From: tudstlennkozh <61184193+tudstlennkozh@users.noreply.github.com> Date: Mon, 19 Oct 2020 15:26:36 +0200 Subject: [PATCH 05/17] code a bit reformated adding code to access annotation for a cell or a selector via propterty: annotation (R/W) --- docs/index.rst | 1 + oosheet/__init__.py | 188 ++++++++++++++++++++++++++++++-------------- 2 files changed, 128 insertions(+), 61 deletions(-) diff --git a/docs/index.rst b/docs/index.rst index 6896eb5..8222b1d 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -98,6 +98,7 @@ Changelog - 1.3.1 - added OODoc.alert() - Works with LO >= 6 + - adding code to access annotation for a cell or a selector via propterty: annotation (R/W) - 1.3 diff --git a/oosheet/__init__.py b/oosheet/__init__.py index dccd6a1..3d166ff 100644 --- a/oosheet/__init__.py +++ b/oosheet/__init__.py @@ -5,37 +5,38 @@ from .columns import name as col_name, index as col_index if sys.platform == 'win32': - #This is required in order to make pyuno usable with the default python interpreter under windows - #Some environment variables must be modified + # This is required in order to make pyuno usable with the default python interpreter under windows + # Some environment variables must be modified - #get the install path from registry + # get the install path from registry import winreg + # try with OpenOffice, LibreOffice on W7 - for key in [# OpenOffice 3.3 - "SOFTWARE\\OpenOffice.org\\UNO\\InstallPath", - # LibreOffice 3.4.5 on W7 - "SOFTWARE\\Wow6432Node\\LibreOffice\\UNO\\InstallPath", - # LibreOffice >= 6 - "SOFTWARE\\LibreOffice\\UNO\\InstallPath"]: + for key in [ # OpenOffice 3.3 + "SOFTWARE\\OpenOffice.org\\UNO\\InstallPath", + # LibreOffice 3.4.5 on W7 + "SOFTWARE\\Wow6432Node\\LibreOffice\\UNO\\InstallPath", + # LibreOffice >= 6 + "SOFTWARE\\LibreOffice\\UNO\\InstallPath"]: try: value = winreg.QueryValue(winreg.HKEY_LOCAL_MACHINE, key) except Exception as detail: _errMess = "%s" % detail else: - break # first existing key will do - install_folder = '\\'.join(value.split('\\')[:-1]) # 'C:\\Program Files\\OpenOffice.org 3' + break # first existing key will do + install_folder = '\\'.join(value.split('\\')[:-1]) # 'C:\\Program Files\\OpenOffice.org 3' - #modify the environment variables + # modify the environment variables os.environ['URE_BOOTSTRAP'] = 'vnd.sun.star.pathname:{0}\\program\\fundamental.ini'.format(install_folder) - os.environ['UNO_PATH'] = install_folder+'\\program\\' + os.environ['UNO_PATH'] = install_folder + '\\program\\' - sys.path.append(install_folder+'\\Basis\\program') - sys.path.append(install_folder+'\\program') + sys.path.append(install_folder + '\\Basis\\program') + sys.path.append(install_folder + '\\program') paths = '' for path in ("\\URE\\bin;", "\\Basis\\program;", "'\\program;"): paths += install_folder + path - os.environ['PATH'] = paths+ os.environ['PATH'] + os.environ['PATH'] = paths + os.environ['PATH'] import uno, re, zipfile, types, inspect, tempfile, shutil, subprocess from datetime import datetime, timedelta @@ -88,8 +89,9 @@ def get_context(self): return localContext else: # We have to connect by socket - resolver = localContext.ServiceManager.createInstanceWithContext("com.sun.star.bridge.UnoUrlResolver", localContext) - return resolver.resolve( "uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext" ) + resolver = localContext.ServiceManager.createInstanceWithContext("com.sun.star.bridge.UnoUrlResolver", + localContext) + return resolver.resolve("uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext") def get_model(self): """ @@ -104,7 +106,7 @@ def get_model(self): """ smgr = self.context.ServiceManager - desktop = smgr.createInstanceWithContext( "com.sun.star.frame.Desktop", self.context) + desktop = smgr.createInstanceWithContext("com.sun.star.frame.Desktop", self.context) return desktop.getCurrentComponent() def get_dispatcher(self): @@ -120,7 +122,7 @@ def get_dispatcher(self): The current environment is detected to decide to connect either via socket or directly. """ smgr = self.context.ServiceManager - return smgr.createInstanceWithContext( "com.sun.star.frame.DispatchHelper", self.context) + return smgr.createInstanceWithContext("com.sun.star.frame.DispatchHelper", self.context) def args(self, name, *args): """ @@ -142,6 +144,23 @@ def args(self, name, *args): return tuple(uno_struct) + def has_interface(self, name): + """ returns True if 'name' interface is supported by this object + """ + m = self.model + if hasattr(m, "getSupportedServiceNames"): + sn = m.getSupportedServiceNames() + for n in sn: + if str(n) == name: + return True + + return False + + def is_spreadsheet(self): + """ returns True if document is of type com.sun.star.sheet.SpreadsheetDocument + """ + return self.has_interface("com.sun.star.sheet.SpreadsheetDocument") + def dispatch(self, cmd, *args): """ Combines OODoc.dispatcher and OODoc.args to dispatch a event. @@ -180,14 +199,17 @@ def _msgBox(self, msg, title, box_type, button_type): return box.execute() - def alert(self, msg, title = u'Alert'): + def alert(self, msg, title=u'Alert'): """Opens an alert window with a message and title, and requires user to click 'Ok'""" self._msgBox(str(msg), title, MESSAGEBOX, MSG_BUTTONS.BUTTONS_OK) - def alertOkCancel(self, msg, title = u'Alert'): - """Opens an alert window and allows user to choose between ok or cancel""" + def alertOkCancel(self, msg, title=u'Alert'): + """Opens an alert window and allows user to choose between ok or cancel + Use this in your code to get constants for return values : + from com.sun.star.awt.MessageBoxResults import CANCEL, OK + """ return self._msgBox(str(msg), title, MESSAGEBOX, MSG_BUTTONS.BUTTONS_OK_CANCEL) - + def undo(self): """Undo the last action""" self.dispatch('.uno:Undo') @@ -220,13 +242,14 @@ def quit(self): """Closes the OpenOffice.org instance""" self.dispatch('Quit') + class OOSheet(OODoc): """ Interacts with an OpenOffice.org Spreadsheet instance. This high-level library works with a group of cells defined by a selector. """ - def __init__(self, selector = None, _row_sliced = False): + def __init__(self, selector=None, _row_sliced=False): """ Constructor gets a selector as parameter. Selector can be one of the following forms: a10 @@ -308,8 +331,8 @@ def _cells(self): A generator of all cells of this selector. Each cell returned will be a python-uno com.sun.star.table.XCell object. """ - for col in range(self.start_col, self.end_col+1): - for row in range(self.start_row, self.end_row+1): + for col in range(self.start_col, self.end_col + 1): + for row in range(self.start_row, self.end_row + 1): yield self.sheet.getCellByPosition(col, row) def __iter__(self): @@ -338,14 +361,13 @@ def __getitem__(self, key): self.end_col, self.start_row + start, self.start_row + stop), - _row_sliced = True) + _row_sliced=True) else: return OOSheet(self._generate_selector(self.start_col + start, self.start_col + stop, self.start_row, self.end_row)) - def __eq__(self, peer): return ((self.sheet.Name == peer.sheet.Name) and (self.start_row == peer.start_row) and @@ -353,16 +375,14 @@ def __eq__(self, peer): (self.end_row == peer.end_row) and (self.end_col == peer.end_col)) - - @property def cells(self): """ A generator of all cells of this selector. Each cell returned will be a single-cell OOSheet object """ - for col in range(self.start_col, self.end_col+1): - for row in range(self.start_row, self.end_row+1): + for col in range(self.start_col, self.end_col + 1): + for row in range(self.start_row, self.end_row + 1): yield OOSheet(self._generate_selector(col, col, row, row)) @property @@ -371,9 +391,9 @@ def rows(self): A generator of all cells of this selector. Each cell returned will be a single-cell OOSheet object """ - for row in range(self.start_row, self.end_row+1): + for row in range(self.start_row, self.end_row + 1): yield OOSheet(self._generate_selector(self.start_col, self.end_col, row, row), - _row_sliced = True) + _row_sliced=True) @property def columns(self): @@ -381,11 +401,9 @@ def columns(self): A generator of all cells of this selector. Each cell returned will be a single-cell OOSheet object """ - for col in range(self.start_col, self.end_col+1): + for col in range(self.start_col, self.end_col + 1): yield OOSheet(self._generate_selector(col, col, self.start_row, self.end_row)) - - @property def data_array(self): """ @@ -394,7 +412,6 @@ def data_array(self): """ return self.sheet.getCellRangeByName(self.selector).getDataArray() - def __repr__(self): try: return self.selector @@ -476,6 +493,31 @@ def set_string(self, string): self.string = string return self + @property + def annotation(self): + """The annotation associated with the cell. Only works for single-cell selectors""" + assert self.cell is not None + aCell = self.cell + return aCell.getAnnotation().getString() + + @staticmethod + def _setCellAnnotation(aCell, supplier, string): + """private function to set annotation via UNO API""" + aCellAddr = aCell.CellAddress + supplier.insertNew(aCellAddr, string) + + @annotation.setter + def annotation(self, string): + """Sets annotation associated of all cells affected by this selector. Expects a string.""" + annotationsSupplier = self.sheet.getAnnotations() + for cell in self._cells: + self._setCellAnnotation(cell, annotationsSupplier, string) + + def set_annotation(self, string): + """Sets the annotation of all cells affected by this selector. Expects a string.""" + self.annotation = string + return self + @property def date(self): """The date representation of a cell. Only works for single-cell selectors""" @@ -488,15 +530,14 @@ def date(self, date): delta = date - self.basedate self.value = delta.days - date_format = uno.getConstantByName( "com.sun.star.util.NumberFormat.DATE" ) + date_format = uno.getConstantByName("com.sun.star.util.NumberFormat.DATE") formats = self.model.getNumberFormats() cells = self.sheet.getCellRangeByName(self.selector) - #if formats.getByKey(cells).Type != date_format: + # if formats.getByKey(cells).Type != date_format: for cell in self._cells: if formats.getByKey(cell.NumberFormat).Type != date_format: - locale = uno.createUnoStruct( "com.sun.star.lang.Locale" ) - cell.NumberFormat = formats.getStandardFormat( date_format, locale ) - + locale = uno.createUnoStruct("com.sun.star.lang.Locale") + cell.NumberFormat = formats.getStandardFormat(date_format, locale) def set_date(self, date): """Sets the date of all cells affected by this selector. Expects a datetime.datetime object.""" @@ -586,12 +627,15 @@ def flatten(self): @property def first_row(self): return self.clone().shrink_down(self.height - 1) + @property def last_row(self): return self.clone().shrink_up(self.height - 1) + @property def first_column(self): return self.clone().shrink_right(self.width - 1) + @property def last_column(self): return self.clone().shrink_left(self.width - 1) @@ -698,16 +742,19 @@ def each(self, function): for cell in self.cells: function(cell) - def shift_right(self, num = 1): + def shift_right(self, num=1): """Moves the selector to right, but number of columns given by "num" parameter.""" return self.shift(num, 0) - def shift_left(self, num = 1): + + def shift_left(self, num=1): """Moves the selector to left, but number of columns given by "num" parameter.""" return self.shift(-num, 0) - def shift_down(self, num = 1): + + def shift_down(self, num=1): """Moves the selector down, but number of rows given by "num" parameter.""" return self.shift(0, num) - def shift_up(self, num = 1): + + def shift_up(self, num=1): """Moves the selector up, but number of rows given by "num" parameter.""" return self.shift(0, -num) @@ -796,12 +843,15 @@ def shift_until(self, col, row, *args, **kwargs): def shift_right_until(self, *args, **kwargs): """Moves selector to right until condition is matched. See shift_until()""" return self.shift_until(1, 0, *args, **kwargs) + def shift_left_until(self, *args, **kwargs): """Moves selector to left until condition is matched. See shift_until()""" return self.shift_until(-1, 0, *args, **kwargs) + def shift_down_until(self, *args, **kwargs): """Moves selector down until condition is matched. See shift_until()""" return self.shift_until(0, 1, *args, **kwargs) + def shift_up_until(self, *args, **kwargs): """Moves selector up until condition is matched. See shift_until()""" return self.shift_until(0, -1, *args, **kwargs) @@ -822,16 +872,19 @@ def grow(self, col, row): return self - def grow_right(self, num = 1): + def grow_right(self, num=1): """Add columns to right of selector""" return self.grow(num, 0) - def grow_left(self, num = 1): + + def grow_left(self, num=1): """Add columns to left of selector""" return self.grow(-num, 0) - def grow_up(self, num = 1): + + def grow_up(self, num=1): """Add rows before selector""" return self.grow(0, -num) - def grow_down(self, num = 1): + + def grow_down(self, num=1): """Add rows after selector""" return self.grow(0, num) @@ -850,12 +903,15 @@ def grow_until(self, col, row, *args, **kwargs): def grow_right_until(self, *args, **kwargs): """Expands selection to right until condition is matched. Conditions are same as shift_until()""" return self.grow_until(1, 0, *args, **kwargs) + def grow_left_until(self, *args, **kwargs): """Expands selection to left until condition is matched. Conditions are same as shift_until()""" return self.grow_until(-1, 0, *args, **kwargs) + def grow_down_until(self, *args, **kwargs): """Expands selection down until condition is matched. Conditions are same as shift_until()""" return self.grow_until(0, 1, *args, **kwargs) + def grow_up_until(self, *args, **kwargs): """Expands selection up until condition is matched. Conditions are same as shift_until()""" return self.grow_until(0, -1, *args, **kwargs) @@ -876,16 +932,19 @@ def shrink(self, col, row): return self - def shrink_right(self, num = 1): + def shrink_right(self, num=1): """Removes columns from right of selector. Does not afect data, only the selector.""" return self.shrink(num, 0) - def shrink_left(self, num = 1): + + def shrink_left(self, num=1): """Removes columns from left of selector. Does not afect data, only the selector.""" return self.shrink(-num, 0) - def shrink_up(self, num = 1): + + def shrink_up(self, num=1): """Removes rows from top of selector. Does not afect data, only the selector.""" return self.shrink(0, -num) - def shrink_down(self, num = 1): + + def shrink_down(self, num=1): """Removes rows from bottom of selector. Does not afect data, only the selector.""" return self.shrink(0, num) @@ -893,14 +952,17 @@ def shrink_right_until(self, *args, **kwargs): """Reduces selection on right border until condition is matched. Conditions are same as shift_until()""" self.end_col = self.last_column.shift_left_until(*args, **kwargs).end_col return self + def shrink_left_until(self, *args, **kwargs): """Reduces selection on left border until condition is matched. Conditions are same as shift_until()""" self.start_col = self.first_column.shift_right_until(*args, **kwargs).start_col return self + def shrink_down_until(self, *args, **kwargs): """Reduces selection on bottom border until condition is matched. Conditions are same as shift_until()""" self.end_row = self.last_row.shift_up_until(*args, **kwargs).end_row return self + def shrink_up_until(self, *args, **kwargs): """Reduces selection on top border until condition is matched. Conditions are same as shift_until()""" self.start_row = self.first_row.shift_down_until(*args, **kwargs).start_row @@ -913,7 +975,7 @@ def clone(self): """ return OOSheet(self.selector) - def protect_sheet(self, password = ""): + def protect_sheet(self, password=""): """ Protects selection's sheet against editions. When sheet is protected, only unprotected cells can be modified. @@ -922,7 +984,7 @@ def protect_sheet(self, password = ""): self.sheet.protect(password) return self - def unprotect_sheet(self, password = ""): + def unprotect_sheet(self, password=""): """ Unprotects selection's sheet against editions. When sheet is unprotected, all cells can be modified. @@ -968,7 +1030,7 @@ def __init__(self, document_path, script_path): def open(self, path, mode='r'): fullpath = os.path.join(self.tmp, path) if not os.path.exists(fullpath): - os.makedirs(os.path.dirname(fullpath)) + os.makedirs(os.path.dirname(fullpath)) return open(os.path.join(self.tmp, path), mode) @property @@ -984,7 +1046,8 @@ def manifest_add(self, path): manifest = [] for line in self.open('META-INF/manifest.xml'): if '' in line: - manifest.append(' ' % path) + manifest.append( + ' ' % path) elif ('full-path="%s"' % path) in line: return @@ -1002,7 +1065,7 @@ def pack(self): fh.write(open(self.script).read()) fh.close() - #Backup + # Backup open(self.document + '.bak', 'wb').write(open(self.document, 'rb').read()) os.remove(self.document) @@ -1015,6 +1078,7 @@ def pack(self): shutil.rmtree(self.tmp) + def pack(): """Command line to pack the script in a document. Acessed as "oosheet-pack".""" try: @@ -1033,12 +1097,14 @@ def pack(): OOPacker(document, script).pack() + def print_help(): """Prints help message for pack()""" script_name = sys.argv[0].split('/')[-1] print("Usage: %s document script.py" % script_name) sys.exit(1) + def launch(): print(""" # This is just a reminder of the complicated command needed to launch From cb48208de59ff74a5b9a23864ea7e3fa4e61f93a Mon Sep 17 00:00:00 2001 From: tudstlennkozh <61184193+tudstlennkozh@users.noreply.github.com> Date: Thu, 1 Jul 2021 15:40:53 +0200 Subject: [PATCH 06/17] moving to 1.3.2 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 96ce8ff..7c202a7 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ import os setup(name = 'oosheet', - version = '1.3.1', + version = '1.3.2', description = 'LibreOffice Spreadsheet scripting library', long_description = open(os.path.join(os.path.dirname(__file__), "README")).read(), author = "Luis Fagundes", From 921b513dc8015b1d36386e2e688bf3bc2a509d33 Mon Sep 17 00:00:00 2001 From: tudstlennkozh <61184193+tudstlennkozh@users.noreply.github.com> Date: Thu, 1 Jul 2021 16:21:54 +0200 Subject: [PATCH 07/17] added related project --- README | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README b/README index 9ed5467..aa5e0e9 100644 --- a/README +++ b/README @@ -17,3 +17,7 @@ You're supposed to be using a Debian-based GNU/Linux distribution, other environ Tests assume you have your OpenOffice.org in English - USA default language. +See also : + * https://github.com/CosminEugenDinu/libreoffice-python-library + + From caff4d67f1f0a96e85f3b75bcdbe9d4dc3e75a5d Mon Sep 17 00:00:00 2001 From: tudstlennkozh <61184193+tudstlennkozh@users.noreply.github.com> Date: Thu, 1 Jul 2021 17:39:26 +0200 Subject: [PATCH 08/17] added append_string(self, text, format) for a single Cell --- oosheet/__init__.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/oosheet/__init__.py b/oosheet/__init__.py index 3d166ff..fcdbf2e 100644 --- a/oosheet/__init__.py +++ b/oosheet/__init__.py @@ -45,6 +45,9 @@ from com.sun.star.awt import MessageBoxButtons as MSG_BUTTONS from com.sun.star.awt.MessageBoxType import MESSAGEBOX +# for append_string() +from com.sun.star.awt.FontSlant import NONE, OBLIQUE, ITALIC +from com.sun.star.awt.FontWeight import NORMAL, BOLD class OODoc(object): """ @@ -482,6 +485,15 @@ def string(self): assert self.cell is not None return self.cell.getString() + def append_string(self, text, format): + """ append :text to the end of the current cell string, using format. + Only works for single-cell selectors + """ + assert self.cell is not None + end_text_range = self.cell.End + self.cell.CharPosture = format + self.cell.insertString(end_text_range, text, False) + @string.setter def string(self, string): """Sets the string of all cells affected by this selector. Expects a string.""" From 4486876f90d946403d0aa640b842c25dcdcb1542 Mon Sep 17 00:00:00 2001 From: tudstlennkozh <61184193+tudstlennkozh@users.noreply.github.com> Date: Fri, 2 Jul 2021 16:12:26 +0200 Subject: [PATCH 09/17] append_string(... text_format) now accepts bitfield values from Format --- oosheet/__init__.py | 43 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 36 insertions(+), 7 deletions(-) diff --git a/oosheet/__init__.py b/oosheet/__init__.py index fcdbf2e..eccb69c 100644 --- a/oosheet/__init__.py +++ b/oosheet/__init__.py @@ -2,6 +2,7 @@ import sys import os +from enum import Flag from .columns import name as col_name, index as col_index if sys.platform == 'win32': @@ -46,8 +47,18 @@ from com.sun.star.awt.MessageBoxType import MESSAGEBOX # for append_string() -from com.sun.star.awt.FontSlant import NONE, OBLIQUE, ITALIC -from com.sun.star.awt.FontWeight import NORMAL, BOLD + +class FontSlant: + from com.sun.star.awt.FontSlant import NONE, ITALIC + +class FontWeight: + from com.sun.star.awt.FontWeight import NORMAL, BOLD + +class Format(Flag): + RESET = 0 + ITALIC = 0b01 + BOLD = 0b10 + class OODoc(object): """ @@ -485,14 +496,32 @@ def string(self): assert self.cell is not None return self.cell.getString() - def append_string(self, text, format): + def _cellInsertString(self, where, text, s_format=None, w_format=None): + """insert text into LO cell with a specific slant of weight attribute""" + if s_format is not None: + where.CharPosture = s_format + if w_format is not None: + where.CharWeight = w_format + self.cell.insertString(where, text, False) + + def append_string(self, text, text_format): """ append :text to the end of the current cell string, using format. - Only works for single-cell selectors + Only works - for the moment - for single-cell selectors """ assert self.cell is not None - end_text_range = self.cell.End - self.cell.CharPosture = format - self.cell.insertString(end_text_range, text, False) + + s_format = None + w_format = None + if text_format == Format.RESET: + s_format = FontSlant.NONE + w_format = FontWeight.NORMAL + else: + if text_format & Format.BOLD: + w_format = FontWeight.BOLD + if text_format & Format.ITALIC: + s_format = FontSlant.ITALIC + + self._cellInsertString(self.cell.End, text, s_format, w_format) @string.setter def string(self, string): From f42e6251371655b8f64e8992b4a0d2b354ed32f4 Mon Sep 17 00:00:00 2001 From: tudstlennkozh <61184193+tudstlennkozh@users.noreply.github.com> Date: Fri, 2 Jul 2021 17:02:42 +0200 Subject: [PATCH 10/17] append_string() can be called without a format --- oosheet/__init__.py | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/oosheet/__init__.py b/oosheet/__init__.py index eccb69c..973aa75 100644 --- a/oosheet/__init__.py +++ b/oosheet/__init__.py @@ -504,7 +504,7 @@ def _cellInsertString(self, where, text, s_format=None, w_format=None): where.CharWeight = w_format self.cell.insertString(where, text, False) - def append_string(self, text, text_format): + def append_string(self, text, text_format = None): """ append :text to the end of the current cell string, using format. Only works - for the moment - for single-cell selectors """ @@ -512,14 +512,15 @@ def append_string(self, text, text_format): s_format = None w_format = None - if text_format == Format.RESET: - s_format = FontSlant.NONE - w_format = FontWeight.NORMAL - else: - if text_format & Format.BOLD: - w_format = FontWeight.BOLD - if text_format & Format.ITALIC: - s_format = FontSlant.ITALIC + if text_format is not None: + if text_format == Format.RESET: + s_format = FontSlant.NONE + w_format = FontWeight.NORMAL + else: + if text_format & Format.BOLD: + w_format = FontWeight.BOLD + if text_format & Format.ITALIC: + s_format = FontSlant.ITALIC self._cellInsertString(self.cell.End, text, s_format, w_format) From 7f60df7e10326ca8b755667d7d9b7b533acc76c6 Mon Sep 17 00:00:00 2001 From: tudstlennkozh <61184193+tudstlennkozh@users.noreply.github.com> Date: Fri, 2 Jul 2021 17:15:55 +0200 Subject: [PATCH 11/17] PEP reformating ... --- oosheet/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/oosheet/__init__.py b/oosheet/__init__.py index 973aa75..175a407 100644 --- a/oosheet/__init__.py +++ b/oosheet/__init__.py @@ -504,7 +504,7 @@ def _cellInsertString(self, where, text, s_format=None, w_format=None): where.CharWeight = w_format self.cell.insertString(where, text, False) - def append_string(self, text, text_format = None): + def append_string(self, text, text_format=None): """ append :text to the end of the current cell string, using format. Only works - for the moment - for single-cell selectors """ From da7f638c2b0ff4f2ee2c4fb316f29d936c3858d7 Mon Sep 17 00:00:00 2001 From: tudstlennkozh <61184193+tudstlennkozh@users.noreply.github.com> Date: Thu, 12 Aug 2021 14:04:23 +0200 Subject: [PATCH 12/17] moving to 1.4.0 --- README | 3 +++ setup.py | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/README b/README index aa5e0e9..7209ad6 100644 --- a/README +++ b/README @@ -20,4 +20,7 @@ Tests assume you have your OpenOffice.org in English - USA default language. See also : * https://github.com/CosminEugenDinu/libreoffice-python-library +now possible to + extend append_string() to muliple cells + add methods for color (background and fore), modify all cell at once diff --git a/setup.py b/setup.py index 7c202a7..0df3b2a 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ import os setup(name = 'oosheet', - version = '1.3.2', + version = '1.4.0', description = 'LibreOffice Spreadsheet scripting library', long_description = open(os.path.join(os.path.dirname(__file__), "README")).read(), author = "Luis Fagundes", From fc28818d9d811195ca653a36d6d93fee80ba67ee Mon Sep 17 00:00:00 2001 From: tudstlennkozh <61184193+tudstlennkozh@users.noreply.github.com> Date: Thu, 12 Aug 2021 14:04:47 +0200 Subject: [PATCH 13/17] format change --- README | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README b/README index 7209ad6..3790f44 100644 --- a/README +++ b/README @@ -21,6 +21,6 @@ See also : * https://github.com/CosminEugenDinu/libreoffice-python-library now possible to - extend append_string() to muliple cells - add methods for color (background and fore), modify all cell at once + * extend append_string() to muliple cells + * add methods for color (background and fore), modify all cell at once From 7673d9b0821206b8ce2ab50ea11e7c397a08fd20 Mon Sep 17 00:00:00 2001 From: tudstlennkozh <61184193+tudstlennkozh@users.noreply.github.com> Date: Wed, 18 Aug 2021 16:32:14 +0200 Subject: [PATCH 14/17] added info on bug with OODoc class variables --- README | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README b/README index 3790f44..44f0213 100644 --- a/README +++ b/README @@ -24,3 +24,8 @@ now possible to * extend append_string() to muliple cells * add methods for color (background and fore), modify all cell at once +Addendum to the doc : + * in case you use oosheet in python macros, please be cautious since a global var. is used (see OODoc ctor) and it could be a bug's nest ... + * in this case, do not hesitate to call doc.connect() at the beginnig of each macro you write :-) + * see the discussion in https://github.com/tudstlennkozh/oosheet/issues/1 to get details + From ce54a65f325134851bd44e9211fc48be3c790f70 Mon Sep 17 00:00:00 2001 From: tudstlennkozh <61184193+tudstlennkozh@users.noreply.github.com> Date: Mon, 2 Jan 2023 11:14:38 +0100 Subject: [PATCH 15/17] in OOSheet.__init__ if selector passed, and no sheet name, use the current sheet instead of the 1st one --- oosheet/__init__.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/oosheet/__init__.py b/oosheet/__init__.py index 175a407..72760af 100644 --- a/oosheet/__init__.py +++ b/oosheet/__init__.py @@ -46,14 +46,17 @@ from com.sun.star.awt import MessageBoxButtons as MSG_BUTTONS from com.sun.star.awt.MessageBoxType import MESSAGEBOX + # for append_string() class FontSlant: from com.sun.star.awt.FontSlant import NONE, ITALIC + class FontWeight: from com.sun.star.awt.FontWeight import NORMAL, BOLD + class Format(Flag): RESET = 0 ITALIC = 0b01 @@ -291,8 +294,10 @@ def __init__(self, selector=None, _row_sliced=False): sheet_name, cells = selector.split('.') self.sheet = self.model.Sheets.getByName(sheet_name) except ValueError: - self.sheet = self.model.Sheets.getByIndex(0) + address = self.model.CurrentSelection.RangeAddress + self.sheet = self.model.Sheets.getByIndex(address.Sheet) cells = selector + cells.replace('$', '') cells = cells.upper() From 10ec712b25672f6b8e80a2cac18862ad5484179d Mon Sep 17 00:00:00 2001 From: tudstlennkozh <61184193+tudstlennkozh@users.noreply.github.com> Date: Mon, 2 Jan 2023 11:15:07 +0100 Subject: [PATCH 16/17] args() as a static method --- oosheet/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/oosheet/__init__.py b/oosheet/__init__.py index 72760af..a577e51 100644 --- a/oosheet/__init__.py +++ b/oosheet/__init__.py @@ -141,7 +141,8 @@ def get_dispatcher(self): smgr = self.context.ServiceManager return smgr.createInstanceWithContext("com.sun.star.frame.DispatchHelper", self.context) - def args(self, name, *args): + @staticmethod + def args(name, *args): """ Receives a list of tupples and returns a list of com.sun.star.beans.PropertyValue objects corresponding to those tupples. This result can be passed to OODoc.dispatcher. From 9d7287ef962b1f9567271646cbb6e251cef77d52 Mon Sep 17 00:00:00 2001 From: tudstlennkozh <61184193+tudstlennkozh@users.noreply.github.com> Date: Mon, 2 Jan 2023 11:41:36 +0100 Subject: [PATCH 17/17] _file_url() and _detect_macro_environment() as static methods --- oosheet/__init__.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/oosheet/__init__.py b/oosheet/__init__.py index a577e51..e5d7640 100644 --- a/oosheet/__init__.py +++ b/oosheet/__init__.py @@ -93,7 +93,8 @@ def load_cache(self): self.model = OODoc._model self.dispatcher = OODoc._dispatcher - def _detect_macro_environment(self): + @staticmethod + def _detect_macro_environment(): for layer in inspect.stack(): if layer[1].startswith('vnd.sun.star.tdoc:') or 'pythonscript.py' in layer[1]: return True @@ -236,7 +237,8 @@ def redo(self): """Redo the last undo""" self.dispatch('.uno:Redo') - def _file_url(self, filename): + @staticmethod + def _file_url(filename): if not filename.startswith('/'): filename = os.path.join(os.environ['PWD'], filename)