Clean old document

This commit is contained in:
Mauricio Baeza 2022-08-17 11:42:44 -05:00
parent 0392d8acb5
commit cd81063674
63 changed files with 107 additions and 11500 deletions

1
.gitignore vendored
View File

@ -3,3 +3,4 @@ __pycache__
build/
*.bk
*.lock
bk/

4
CHANGELOG.md Normal file
View File

@ -0,0 +1,4 @@
v 0.1.0 [17-Ago-2022]
---------------------
- Tools refactorize and documented.

View File

@ -10,7 +10,7 @@ Rapid develop macros in LibreOffice with Python.
#### but, don't make the mistake of many of *thinking only in gratis software* that so much damage has done to **Free Software**.
This library have a cost of maintenance of 1 euros every year.
This library have a cost of maintenance of 1 euro every year.
In order of preferred.

1
VERSION Normal file
View File

@ -0,0 +1 @@
0.1.0

View File

@ -3,8 +3,44 @@ title = "LibreOffice"
weight = 4
+++
### create_instance
### fonts
Devolver todas las fuentes visibles en LibreOffice. Mire [FontDescriptor][1]
```python
fonts = app.fonts()
for f in fonts:
app.debug(f'Nombre: {f.Name} - Estilo: {f.StyleName}')
```
### filters
Devolver todos los filtros soportados en LibreOffice. Mire la [ayuda][2] y en [API FilterFactory][3] para más detalles.
```python
filtros = app.filters()
for f in filtros:
info = f"Nombre UI: {f['UIName']} - Nombre: {f['Name']} - Tipo: {f['Type']}"
app.debug(info)
```
### dispatch
Ejecutar cualquier comando `UNO` de LibreOffice, mire la [lista de comandos][4] y [API dispatch][5].
Este método automáticamente agrega el prefijo necesario: `.uno:`
```python
doc = app.active
comando = 'Gallery'
app.dispatch(doc, comando)
```
[1]: https://api.libreoffice.org/docs/idl/ref/structcom_1_1sun_1_1star_1_1awt_1_1FontDescriptor.html
[2]: https://help.libreoffice.org/latest/en-US/text/shared/guide/convertfilters.html
[3]: https://api.libreoffice.org/docs/idl/ref/servicecom_1_1sun_1_1star_1_1document_1_1FilterFactory.html
[4]: https://wiki.documentfoundation.org/Development/DispatchCommands
[5]: https://api.libreoffice.org/docs/idl/ref/interfacecom_1_1sun_1_1star_1_1frame_1_1XDispatch.html#a42beb1ea2ddae35c076b6e65867025ea

View File

@ -1,20 +0,0 @@
# Minimal makefile for Sphinx documentation
#
# You can set these variables from the command line, and also
# from the environment for the first two.
SPHINXOPTS ?=
SPHINXBUILD ?= sphinx-build
SOURCEDIR = source
BUILDDIR = build
# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
.PHONY: help Makefile
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

View File

@ -1,35 +0,0 @@
@ECHO OFF
pushd %~dp0
REM Command file for Sphinx documentation
if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=sphinx-build
)
set SOURCEDIR=source
set BUILDDIR=build
if "%1" == "" goto help
%SPHINXBUILD% >NUL 2>NUL
if errorlevel 9009 (
echo.
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
echo.installed, then set the SPHINXBUILD environment variable to point
echo.to the full path of the 'sphinx-build' executable. Alternatively you
echo.may add the Sphinx directory to PATH.
echo.
echo.If you don't have Sphinx installed, grab it from
echo.https://www.sphinx-doc.org/
exit /b 1
)
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
goto end
:help
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
:end
popd

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 81 KiB

View File

@ -1,368 +0,0 @@
Application
===========
Remember, always import library.
.. code-block:: python
import easymacro as app
Create instances
----------------
* Instances without context
.. code-block:: python
toolkit = app.create_instance('com.sun.star.awt.Toolkit')
* Instances with context
.. code-block:: python
service = 'com.sun.star.awt.DialogProvider2'
dialog = app.create_instance(service, True)
* Get desktop
.. code-block:: python
desktop = app.create_instance('com.sun.star.frame.Desktop', True)
Or
.. code-block:: python
desktop = app.lo.desktop
Fonst
-----
* Get all fonts
.. code-block:: python
fonts = app.lo.fonts()
for f in fonts:
print(f'Name: {f.Name} - StyleName: {f.StyleName}')
Filters
-------
* Get all `support filters`_
.. code-block:: python
filters = app.lo.filters()
ds = []
for f in filters:
data = f"UI Name: {f['UIName']} - Name: {f['Name']} - Type: {f['Type']}"
app.debug(data)
Call dispatch
-------------
You can call any `dispatch command`_ used only if property or method no exists in original object or in `easymacro.py`
.. code-block:: python
doc = app.docs.active
command = 'Gallery'
app.lo.dispatch(doc, command)
Method automatically add `.uno:`
ClipBoard
---------
* Set text in clipboard
.. code-block:: python
app.clipboard.set('My Text')
* Get content of clipboard
.. code-block:: python
content = app.clipboard.content
app.debug(content)
Disable or enabled commands
---------------------------
You can disable any command.
.. code-block:: python
cmd = 'OpenFromCalc'
result = app.command.disable(cmd)
app.debug(result)
And enabled.
.. code-block:: python
result = app.command.enabled(cmd)
app.debug(result)
`OpenFromCalc` is options for open documents in calc, disable or enabled menu entry and icon toolbar.
LibreOffice configuration
-------------------------
Get value
^^^^^^^^^
Some values are read only.
.. code-block:: python
node_name = '/org.openoffice.Office.Common/Help'
key = 'System'
value = app.get_app_config(node_name, key)
app.debug(value)
node_name = '/org.openoffice.Office.Common/Misc/'
key = 'FirstRun'
value = app.get_app_config(node_name, key)
app.debug(value)
key = 'UseSystemFileDialog'
value = app.get_app_config(node_name, key)
app.debug(value)
Set value
^^^^^^^^^
.. code-block:: python
node_name = '/org.openoffice.Office.UI/ColorScheme'
key = 'CurrentColorScheme'
new_value = 'LibreOffice Dark'
result = app.set_app_config(node_name, key, new_value)
app.debug(result)
.. warning::
Caution with modify registry, not all nodes we can change.
Some nodes and keys:
* `/org.openoffice.Office.Common/Save/Document`
* AutoSave
* AutoSaveTimeIntervall
Shortcuts
---------
Global
^^^^^^
Iter in all shortcuts. Shortcuts for all applications.
.. code-block:: python
for shortcut, command in app.shortcuts:
app.debug(shortcut, command)
If you want all info.
.. code-block:: python
sc = app.shortcuts
data = sc.get_all()
app.debug(data)
Verify if exists shortcut.
.. code-block:: python
sc = app.shortcuts
shortcut = 'Shift+Ctrl+Alt+T'
app.debug(shortcut in sc)
Add new shortcut for execute uno command.
.. code-block:: python
sc = app.shortcuts
shortcut = 'Shift+Ctrl+Alt+T'
command = 'MacroDialog'
sc.set(shortcut, command)
Add new shortcut for execute macro.
.. code-block:: python
sc = app.shortcuts
shortcut = 'Shift+Ctrl+Alt+M'
macro = {'library': 'test', 'name': 'main'}
sc.set(shortcut, macro)
Get `command` by `shortcut`.
.. code-block:: python
sc = app.shortcuts
shortcut = 'Shift+Ctrl+Alt+M'
command = sc.get_by_shortcut(shortcut)
app.debug(command)
Get `shortcut` by `command`. Could be more than one.
.. code-block:: python
sc = app.shortcuts
command = 'MacroDialog'
shortcuts = sc.get_by_command(command)
app.debug(shortcuts)
Remove by shortcut.
.. code-block:: python
sc = app.shortcuts
shortcut = 'Shift+Ctrl+Alt+M'
sc.remove_by_shortcut(shortcut)
Remove by command.
.. code-block:: python
sc = app.shortcuts
macro = {'library': 'test', 'name': 'main'}
sc.remove_by_command(macro)
Reset all editions.
.. code-block:: python
app.shortcuts.reset()
For applications
^^^^^^^^^^^^^^^^
Get shortcuts for application. For Calc.
.. code-block:: python
sc = app.shortcuts['calc']
All methods some the same.
For other applications: `writer`, `draw`, `impress`, `math`
Menus
-----
Add new
^^^^^^^
Insert new menu in Calc.
.. code-block:: python
menu_name = 'zaz.my.menu'
menu = {
'Label': 'My menu',
'CommandURL': menu_name,
'Submenu': [
{
'Label': 'Open Macros Dialog...',
'CommandURL': 'MacroDialog',
},
{
'Label': '-',
},
{
'Label': 'My macro',
'CommandURL': {'library': 'test', 'name': 'hello'},
},
{
'Label': 'Execute macro...',
'CommandURL': 'RunMacro',
'ShortCut': 'Shift+Ctrl+Alt+E',
},
]
}
menu_bar = app.menus['calc']
menu_bar.insert(menu)
Remove
^^^^^^
.. code-block:: python
menu_name = 'zaz.my.menu'
menu_bar = app.menus['calc']
menu_bar.remove(menu_name)
Insert in exists menu
^^^^^^^^^^^^^^^^^^^^^
Insert if not exists in menu Tools, after submenu Macros.
.. code-block:: python
menu = app.menus['calc']['tools']
menu_name = 'zaz.my.menu'
menu_new = {
'Label': 'My menu',
'CommandURL': menu_name,
'Submenu': [
{
'Label': 'Open Macros Dialog...',
'CommandURL': 'MacroDialog',
},
{
'Label': '-',
},
{
'Label': 'My macro',
'CommandURL': {'library': 'test', 'name': 'hello'},
},
{
'Label': 'Execute macro...',
'CommandURL': 'RunMacro',
'ShortCut': 'Shift+Ctrl+Alt+E',
},
]
}
if menu_name in menu:
menu.remove(menu_name)
else:
menu.insert(menu_new, '.uno:MacrosMenu')
.. _dispatch command: https://wiki.documentfoundation.org/Development/DispatchCommands
.. _support filters: https://help.libreoffice.org/latest/en-US/text/shared/guide/convertfilters.html

View File

@ -1,18 +0,0 @@
Calc
====
Remember, always import library.
.. code-block:: python
import easymacro as app
.. toctree::
:maxdepth: 2
calc_doc.rst
calc_sheets.rst
calc_ranges.rst
calc_cells.rst
calc_data.rst

View File

@ -1,151 +0,0 @@
Cells and Ranges
----------------
By selection
^^^^^^^^^^^^
.. code-block:: python
doc = app.active
selection = doc.selection
app.debug(selection)
By name
^^^^^^^
.. code-block:: python
doc = app.active
sheet = doc.active
cell = sheet['A1']
rango = sheet['C10:D15']
app.debug(cell)
app.debug(rango)
By position
^^^^^^^^^^^
For cells: `sheet[row,column]`
For ranges: `sheet[start_row:end_row, start_column:end_column]`
.. code-block:: python
sheet = app.active.active
'Cell A10
cell = sheet[9,0]
'Range A1:C10
rango = sheet[0:10,0:3]
Iteration cells
^^^^^^^^^^^^^^^
.. code-block:: python
rango = sheet['B10:C15']
for cell in rango:
app.debug(cell)
Properties
^^^^^^^^^^
is_cell
~~~~~~~
.. code-block:: python
cell = sheet['A1']
app.debug(cell.is_cell)
rango = sheet['A1:C5']
app.debug(rango.is_cell)
name
~~~~
Return `AbsoluteName`
.. code-block:: python
cell = sheet['A1']
app.debug(cell.name)
rango = sheet['A1:C5']
app.debug(rango.name)
address
~~~~~~~
Return struct `com.sun.star.table.CellAddress`
.. code-block:: python
cell = sheet['A1']
if cell.is_cell:
app.debug(cell.address)
range_address
~~~~~~~~~~~~~
Return struct `com.sun.star.table.CellRangeAddress`
.. code-block:: python
rango = sheet['A1:C5']
if not rango.is_cell:
app.debug(rango.range_address)
sheet
~~~~~
Get parent sheet, return LOCalcSheet class
.. code-block:: python
rango = sheet['A1:C5']
sheet = rango.sheet
app.debug(sheet)
doc
~~~
Get parent document, return LODocCalc class
.. code-block:: python
rango = sheet['A1:C5']
doc = rango.doc
app.debug(doc)
cursor
~~~~~~
Get cursor by self range, return ScCellCursorObj instance.
.. code-block:: python
rango = sheet['A1:C5']
cursor = rango.cursor
app.debug(cursor.ImplementationName)
style
~~~~~
Get or set cell style. Style must exists.
.. code-block:: python
rango = sheet['A1:C5']
app.debug(rango.style)
rango.style = 'Good'
Methods
^^^^^^^

View File

@ -1,122 +0,0 @@
Active document
---------------
.. code-block:: python
doc = app.active
app.debug(doc.type)
|
Headers
-------
Hide or show columns and rows headers.
.. code-block:: python
doc = app.active
app.msgbox(doc.headers)
doc.headers = not doc.headers
app.msgbox(doc.headers)
doc.headers = not doc.headers
|
Tabs
----
Hide or show tab sheets.
.. code-block:: python
doc = app.active
app.msgbox(doc.tabs)
doc.tabs = not doc.tabs
app.msgbox(doc.tabs)
doc.tabs = not doc.tabs
|
Events
------
See all the events that can be used.
.. code-block:: python
doc = app.active
event_names = doc.events.names
app.debug(event_names)
Assing some macro to event.
.. code-block:: python
doc = app.active
events = doc.events
if 'OnViewClosed' in events:
macro = {'library': 'test', 'name': 'on_view_closed'}
events['OnViewClosed'] = macro
Remove
.. code-block:: python
events['OnViewClosed'] = {}
Or
.. code-block:: python
events.remove('OnViewClosed')
|
Select range by user
--------------------
.. code-block:: python
class Controllers():
def __init__(self, doc):
self.doc = doc
def range_selection_done(self, range_selection):
if range_selection:
app.debug(range_selection)
self.doc.remove_range_selection_listener()
return
def range_selection_aborted(self):
self.doc.remove_range_selection_listener()
return
def main():
doc = app.active
doc.start_range_selection(Controllers)
return
|
Selection
---------
.. code-block:: python
doc = app.active
selection = doc.selection
app.debug(selection.is_cell)
|
Select
------
.. code-block:: python
doc = app.active
cell = doc[0]['A1']
doc.select(cell)

View File

@ -1,123 +0,0 @@
Ranges
------
By selection
^^^^^^^^^^^^
.. code-block:: python
doc = app.active
selection = doc.selection
app.debug(selection)
Count
^^^^^
.. code-block:: python
selection = doc.selection
count = len(selection)
app.debug(count)
Iter
^^^^
.. code-block:: python
selection = doc.selection
for rango in selection:
app.debug(rango)
Get
^^^
* By index
.. code-block:: python
selection = doc.selection
rango = selection[1]
app.debug(rango)
* By name
.. code-block:: python
selection = doc.selection
rango = selection['Sheet1.D9:E11']
app.debug(rango)
New ranges container
^^^^^^^^^^^^^^^^^^^^
.. code-block:: python
ranges = doc.ranges
Add
^^^
.. code-block:: python
doc = app.active
sheet = doc.active
rangos = doc.ranges
rangos.add(sheet['A1:B2'])
rangos.add(sheet['D5:F10'])
app.debug(rangos)
Remove
^^^^^^
.. code-block:: python
rangos.remove(sheet['A1:B2'])
If contains
^^^^^^^^^^^
.. code-block:: python
result = sheet['D5:F10'] in rangos
app.debug(result)
Get same range in all sheets
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. code-block:: python
rangos = doc.get_ranges('A1:C5')
app.debug(rangos)
Names
^^^^^
.. code-block:: python
app.debug(rangos.names)
Get and set data
^^^^^^^^^^^^^^^^
.. note::
Each range of data must be the exact size of each range.
.. code-block:: python
rangos = doc.get_ranges('A1:C5')
data = rangos.data
app.debug(data)
rangos.data = data
Style
^^^^^
Apply the same style to all ranges.
.. code-block:: python
rangos = doc.get_ranges('A1:C5')
rangos.style = 'Good'

View File

@ -1,438 +0,0 @@
Sheets
------
Active sheet
^^^^^^^^^^^^
.. code-block:: python
doc = app.active
sheet = doc.active
app.debug(sheet.name)
|
Get by index
^^^^^^^^^^^^
.. code-block:: python
doc = app.active
sheet = doc[0]
app.debug(sheet.name)
|
Get by name
^^^^^^^^^^^
.. code-block:: python
doc = app.active
sheet = doc['Sheet1']
app.debug(sheet.name)
|
Contains
^^^^^^^^
.. code-block:: python
doc = app.active
app.debug('Sheet1' in doc)
|
Get tuple with all names
^^^^^^^^^^^^^^^^^^^^^^^^
.. code-block:: python
doc = app.active
app.debug(doc.names)
|
Count
^^^^^
.. code-block:: python
doc = app.active
app.debug(len(doc))
|
Iter
^^^^
.. code-block:: python
doc = app.active
for sheet in doc:
app.debug(sheet)
|
New
^^^
Always validate if new name not exists.
.. warning::
If 'NewSheet' exists, reset it to clean sheet.
.. code-block:: python
doc = app.active
doc['NewSheet'] = doc.new_sheet
# ~ or
sheet = doc.insert('NewSheet2')
|
Insert multiple, get last insert.
.. code-block:: python
names = ('One', 'Two', 'Three')
sheet = doc.insert(names)
app.debug(sheet.name)
|
Move
^^^^
Move by object to last position.
.. code-block:: python
sheet = doc[0]
doc.move(sheet)
Move by name to last position.
.. code-block:: python
doc.move('Sheet1')
Move to position.
.. code-block:: python
sheet = doc[0]
doc.move(sheet, 2)
Move from sheet
.. code-block:: python
sheet = doc.active
sheet.move()
Move to position.
.. code-block:: python
sheet = doc.active
sheet.move(2)
|
Remove
^^^^^^
Remove by object.
.. note::
Always should be exists at least one sheet.
.. code-block:: python
sheet = doc[0]
doc.remove(sheet)
Remove by name.
.. code-block:: python
doc.remove('One')
Remove from sheet.
.. code-block:: python
sheet = doc.active
sheet.remove()
|
Copy
^^^^
Copy inside the same spreadsheet. Always validate if new name not exists.
* By object
.. code-block:: python
sheet = doc[0]
doc.copy_sheet(sheet, 'OtherSheet')
* By name
.. code-block:: python
doc.copy_sheet('Sheet1', 'Sheet2')
* From sheet
.. code-block:: python
sheet = doc.active
sheet.copy(f'{sheet.name}_2')
* If not set new name, automatically get next name free with `name + index`
.. code-block:: python
sheet = doc.active
sheet.copy()
|
Copy from
^^^^^^^^^
* Copy sheet from one spreadsheet to other.
.. code-block:: python
doc = app.active
doc_source = app.docs['Contacts.ods']
name_source = 'Names'
name_target = 'Names'
position = 0
doc.copy_from(doc_source, name_source, name_target, position)
* If not set `name_source` and `name_target`, copy all sheet in doc source.
.. code-block:: python
doc_source = app.docs['Contacts.ods']
doc.copy_from(doc_source)
|
Copy to
^^^^^^^
* Copy from sheet with the same name
.. code-block:: python
doc = app.active
sheet = doc.active
doc = app.docs.new()
sheet.copy_to(doc)
* Used new name
.. code-block:: python
doc = app.active
sheet = doc.active
doc = app.docs.new()
sheet.copy_to(doc, 'NewName')
|
Sort
^^^^
* Sort sheets by names.
.. code-block:: python
doc = app.active
doc.sort()
* Sort in reverse.
.. code-block:: python
doc = app.active
doc.sort(True)
|
Name
^^^^
Name visible by the user.
.. code-block:: python
sheet = doc.active
app.msgbox(sheet.name)
sheet.name = 'NewName'
app.msgbox(sheet.name)
Code name
^^^^^^^^^
Only accessible by code.
.. code-block:: python
sheet = doc.active
app.msgbox(sheet.code_name)
sheet.code_name = 'my_name'
app.msgbox(sheet.code_name)
Visible
^^^^^^^
Apply only with spreadsheet with two or more sheets.
.. code-block:: python
sheet = doc.active
app.msgbox(sheet.visible)
sheet.visible = not sheet.visible
app.msgbox(sheet.visible)
sheet.visible = not sheet.visible
Is protected
^^^^^^^^^^^^
If sheet is protected with password.
.. code-block:: python
sheet = doc.active
app.msgbox(sheet.is_protected)
Set password
^^^^^^^^^^^^
.. code-block:: python
sheet = doc.active
sheet.password = 'letmein'
app.msgbox(sheet.is_protected)
Remove password
^^^^^^^^^^^^^^^
.. code-block:: python
sheet = doc.active
sheet.password = 'letmein'
app.msgbox(sheet.is_protected)
sheet.unprotect('letmein')
app.msgbox(sheet.is_protected)
Tab color
^^^^^^^^^
.. code-block:: python
sheet = doc.active
app.msgbox(sheet.color)
sheet.color = 'red'
app.msgbox(sheet.color)
# RGB
sheet.color = (125, 200, 10)
app.msgbox(sheet.color)
Document parent
^^^^^^^^^^^^^^^
.. code-block:: python
doc = sheet.doc
app.msgbox(doc.title)
Activate
^^^^^^^^
.. code-block:: python
doc = app.active
# Get last sheet
sheet = doc[-1]
# Activate from sheet
sheet.activate()
# Activate from doc
doc.activate(doc[1])
# Activate by name
doc.activate('Sheet3')
|
Events
^^^^^^
* See all the events that can be used.
.. code-block:: python
sheet = doc.active
event_names = sheet.events.names
app.debug(event_names)
* Assing some macro to event.
.. code-block:: python
def on_select(source):
app.debug(source.AbsoluteName)
return
def main():
doc = app.active
sheet = doc.active
events = sheet.events
if 'OnSelect' in events:
macro = {'library': 'test', 'name': 'on_select'}
events['OnSelect'] = macro
return
* Remove
.. code-block:: python
events['OnSelect'] = {}
* Or
.. code-block:: python
events.remove('OnSelect')

View File

@ -1,58 +0,0 @@
# Configuration file for the Sphinx documentation builder.
#
# This file only contains a selection of the most common options. For a full
# list see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html
# -- Path setup --------------------------------------------------------------
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
import os
import sys
sys.path.insert(0, os.path.abspath('../../source'))
# -- Project information -----------------------------------------------------
project = 'easymacro'
copyright = '2022, El Mau'
author = 'El Mau'
release = '0.1.0'
# -- General configuration ---------------------------------------------------
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.autosummary',
]
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = []
# -- Options for HTML output -------------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
# ~ html_theme = 'alabaster'
html_theme = 'sphinx_book_theme'
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
autosummary_generate = True

View File

@ -1,486 +0,0 @@
Documents
=========
Remember, always import library.
.. code-block:: python
import easymacro as app
Current doc
-----------
.. code-block:: python
doc = app.docs.active
app.msgbox(doc.title)
Iter docs
---------
.. code-block:: python
for doc in app.docs:
app.debug(doc.type, doc.title)
Count
-----
.. code-block:: python
count = len(app.docs)
app.debug(count)
Get by index
------------
.. code-block:: python
doc = app.docs[1]
app.debug(doc.type, doc.title)
Get by name
-----------
.. code-block:: python
name = 'MyDoc.ods'
if name in app.docs:
doc = app.docs[name]
app.debug(doc.type, doc.title)
If contain
----------
.. code-block:: python
result = 'myfile.ods' in app.docs
app.debug(result)
New
---
For default create new Calc document.
.. code-block:: python
doc = app.docs.new()
app.debug(doc.type)
For new Writer document.
.. code-block:: python
doc = app.docs.new('writer')
app.debug(doc.type)
With arguments.
.. code-block:: python
args= {'Hidden': True}
doc = app.docs.new('writer', args)
msg = f'{doc.type} - {doc.title}'
app.msgbox(msg)
doc.visible = True
Other documents.
.. code-block:: python
doc = app.docs.new('draw')
app.debug(doc.type)
doc = app.docs.new('impress')
app.debug(doc.type)
doc = app.docs.new('math')
app.debug(doc.type)
Open
----
.. code-block:: python
path = '/home/mau/ask_example.ods'
doc = app.docs.open(path)
While LibreOffice support format, you can open arbitrary file.
.. code-block:: python
path = '/home/mau/example.xlsx'
doc = app.docs.open(path)
With arguments.
.. code-block:: python
path = '/home/mau/example.ods'
args = {'Password': 'letmein'}
doc = app.docs.open(path, args)
Save
----
* Save new documents
.. code-block:: python
path = '/home/mau/myfile.ods'
doc = app.docs.new()
doc.save(path)
* If previously open and modify then.
.. code-block:: python
doc.save()
* Open exists file and save with other name.
.. code-block:: python
path = '/home/mau/myfile.ods'
doc = app.docs.open(path)
new_path = '/home/mau/other_name.ods'
doc.save(new_path)
Close
-----
.. code-block:: python
doc = app.docs.new()
app.msgbox(doc.title)
doc.close()
To PDF
------
* Save in path
.. code-block:: python
doc = app.active
path = '/home/mau/test.pdf'
doc.to_pdf(path)
* Save in memory
.. code-block:: python
doc = app.active
pdf = doc.to_pdf()
Export
------
* Export common formats
.. code-block:: python
doc = app.docs.new()
path = '/home/mau/myfile.xlsx'
filter_name = 'xlsx'
doc.export(path, filter_name)
path = '/home/mau/myfile.xls'
filter_name = 'xls'
doc.export(path, filter_name)
doc = app.docs.new('writer')
path = '/home/mau/myfile.docx'
filter_name = 'docx'
doc.export(path, filter_name)
path = '/home/mau/myfile.doc'
filter_name = 'doc'
doc.export(path, filter_name)
path = '/home/mau/myfile.rtf'
filter_name = 'rtf'
doc.export(path, filter_name)
* Export in memory.
.. code-block:: python
doc = app.docs.new()
filter_name = 'xlsx'
excel_doc = doc.export(filter_name=filter_name)
Properties
----------
Common properties for documents
obj
^^^
* Get original object pyUNO (read only)
.. code-block:: python
doc = app.active
app.debug(type(doc))
app.debug(type(doc.obj))
title
^^^^^
.. code-block:: python
doc = app.active
app.debug(doc.title)
doc.title = 'New title'
app.debug(doc.title)
type
^^^^
* Get type document: calc, writer, etc. (read only)
.. code-block:: python
doc = app.active
app.debug(doc.type)
uid
^^^
* Get internal RuntimeUID form document. (read only)
.. code-block:: python
doc = app.active
app.debug(doc.uid)
is_saved
^^^^^^^^
* If document is saved or not (read only)
.. code-block:: python
doc = app.active
app.debug(doc.is_saved)
is_modified
^^^^^^^^^^^
* If document has been modified (read only)
.. code-block:: python
doc = app.active
app.debug(doc.is_modified)
is_read_only
^^^^^^^^^^^^
.. code-block:: python
doc = app.active
app.debug(doc.is_read_only)
path
^^^^
* Get path of document. (read only)
.. code-block:: python
doc = app.active
app.debug(doc.path)
dir
^^^
* Get only directory from path saved (read only)
.. code-block:: python
doc = app.active
app.debug(doc.dir)
file_name
^^^^^^^^^
* Get only file name from path saved (read only)
.. code-block:: python
doc = app.active
app.debug(doc.file_name)
name
^^^^
* Get only name without extension (read only)
.. code-block:: python
doc = app.active
app.debug(doc.name)
visible
^^^^^^^
* Hide or show document.
.. code-block:: python
doc = app.active
doc.visible = False
app.msgbox(doc.visible)
doc.visible = True
zoom
^^^^
* Get or set zoom value.
.. code-block:: python
doc = app.active
zoom = doc.zoom
app.msgbox(zoom)
doc.zoom = zoom * 2
app.msgbox(doc.zoom)
doc.zoom = zoom
status_bar
^^^^^^^^^^
* Get status bar, always control in other thread.
.. code-block:: python
@app.run_in_thread
def update_status_bar(sb, text, limit):
sb.start(text, limit)
for i in range(limit):
sb.setValue(i)
app.sleep(1)
# ~ Is important free status bar
sb.end()
return
def main():
doc = app.active
update_status_bar(doc.status_bar, 'Line', 10)
return
selection
^^^^^^^^^
* **CAUTION**: Selection can be many things.
.. code-block:: python
doc = app.active
selection = doc.selection
app.debug(selection)
Methods
-------
set_focus
^^^^^^^^^
.. code-block:: python
for doc in app.docs:
app.debug(doc.title)
doc.set_focus()
app.sleep(1)
copy
^^^^
* Copy current selection
.. code-block:: python
doc = app.active
doc.copy()
paste
^^^^^
* Paste any content in clipboard
.. code-block:: python
doc = app.active
doc.paste()
paste_special
^^^^^^^^^^^^^
* Show dialog box Paste Special
.. code-block:: python
doc = app.active
doc.paste_special()
paste_values
^^^^^^^^^^^^
* Paste only values
.. code-block:: python
doc = app.active
doc.paste_values()
clear_undo
^^^^^^^^^^
* Clear history undo
.. code-block:: python
doc = app.active
doc.clear_undo()

View File

@ -1,109 +0,0 @@
Email
=====
Remember, always import library.
.. code-block:: python
import easymacro as app
**IMPORTANT:** Always save your config the more security way possible.
Send email
----------
.. code-block:: python
from conf import PASSWORD
SERVER = dict(
server = 'mail.server.net' ,
port = 495,
ssl = True,
user = 'no-responder@noexiste.mx',
password = PASSWORD,
)
body = "Hello Ingrid\n\nWho are you?\n\nBest regards"
message = dict(
to = 'ingrid.bergman@love.you',
subject = 'I love you',
body = body,
)
app.email.send(SERVER, message)
* We can use fields `cc`, `bcc` too and send to more than one address emails.
.. code-block:: python
to = 'mail1@correo.com,mail2@correo.com,mail3@correo.com'
cc = 'other@correo.com'
bcc = 'hidden@correo.com'
* We can send too more than one message.
.. code-block:: python
message1 = dict(
to = 'ingrid.bergman@email.net',
subject = 'I love you',
body = "Hello Ingrid\n\nWho are you?\n\nBest regards",
)
message2 = dict(
to = 'sophia.loren@email.net',
subject = 'I love you',
body = "Hello Sophia\n\nWho are you?\n\nBest regards",
)
messages = (message1, message2)
app.email.send(SERVER, messages)
.. code-block:: bash
30/06/2021 13:43:23 - DEBUG - Connect to: mail.gandi.net
30/06/2021 13:43:24 - DEBUG - Email sent...
30/06/2021 13:43:26 - DEBUG - Email sent...
30/06/2021 13:43:26 - DEBUG - Close connection...
* Send with attachment
.. code-block:: python
files = '/home/mau/file.epub'
message = dict(
to = 'ingrid.bergman@email.net',
subject = 'I love you',
body = "Hello Ingrid\n\nWho are you?\n\nBest regards",
files = files,
)
* Send more than one file.
.. code-block:: python
files = (
'/home/mau/file1.epub',
'/home/mau/file2.epub',
)
* If your client email used `mbox` format, we can save in any path into your email client configuration.
.. code-block:: python
path_save = '/home/mau/.thunderbird/7iznrbyw.default/Mail/Local Folders/LibreOffice'
message = dict(
to = 'ingrid.bergman@email.net',
subject = 'I love you',
body = "Hello Ingrid\n\nWho are you?\n\nBest regards",
path = path_save
)
app.email.send(SERVER, message)
* All emails always send in other thread.

View File

@ -1,42 +0,0 @@
.. easymacro documentation master file, created by
sphinx-quickstart on Tue Feb 22 16:10:57 2022.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
Welcome to easymacro's documentation!
=====================================
**easymacro** it's a library for easily develop macros en LibreOffice con Python. It is an abstraction layer between the extensive and complex LibreOffice API UNO and your code.
Probably, you will be more happy if used it. :)
You can used **easymacro** with any extension or directly in your macros.
.. note::
This project is under active development.
.. toctree::
:maxdepth: 2
:caption: Contents:
install
tools_debug
tools
paths
email
application
documents
calc
.. ~ .. automodule:: easymacro
.. ~ :members:
Indices and tables
==================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`

View File

@ -1,48 +0,0 @@
Installation
============
Clone repository
----------------
Clone repository in your favorite folder projects.
.. code-block:: console
git clone https://git.cuates.net/elmau/easymacro
and copy library into `pythonpath` in your macros.
.. code-block:: console
/home/USER/.config/libreoffice/4/user/Scripts/python/pythonpath/easymacro.py
Test
----
In your favorite macros file, for example:
.. code-block:: console
vim /home/USER/.config/libreoffice/4/user/Scripts/python/mymacros.py
copy this code:
.. code-block:: python
import easymacro as app
def main():
app.msgbox(app.INFO_DEBUG)
return
and execute from LibreOffice, if you see similar next info, great!
.. image:: _static/images/install_01.png
|
you are ready for develop with **easymacro**.
Happy develop!

View File

@ -1,548 +0,0 @@
Paths and files
===============
Remember, always import library first.
.. code-block:: python
import easymacro as app
Get info path
-------------
.. code-block:: python
path = '/home/mau/myfile.ods'
p = app.path(path)
app.debug(p.path)
app.debug(p.file_name)
app.debug(p.name)
app.debug(p.ext)
app.debug(p.size)
app.debug(p.url)
.. image:: _static/images/path_01.png
|
Get info like tuple
.. code-block:: python
app.debug(p.info)
.. image:: _static/images/path_02.png
|
Or like dict
.. code-block:: python
app.debug(p.dict)
.. image:: _static/images/path_03.png
Get home path
-------------
.. code-block:: python
p = app.path
app.debug(p.home)
Get document path
------------------
.. code-block:: python
p = app.path
app.debug(p.documents)
Get path user profile
---------------------
.. code-block:: python
p = app.path
app.debug(p.user_profile)
Get path user config
--------------------
.. code-block:: python
p = app.path
app.debug(p.user_config)
Get python executable path
--------------------------
.. code-block:: python
p = app.path
app.debug(p.python)
Path URL to system
------------------
.. code-block:: python
path = 'file:///home/mau/myfile.ods'
app.debug(app.path.to_system(path))
Path system to URL
------------------
.. code-block:: python
path = 'file:///home/mau/myfile.ods'
path = app.path.to_system(path)
app.debug(app.path.to_url(path))
Get path from user config
-------------------------
Default get path documents. `See Api XPathSettings <http://api.libreoffice.org/docs/idl/ref/interfacecom_1_1sun_1_1star_1_1util_1_1XPathSettings.html>`_
.. code-block:: python
path = app.path.config()
app.debug(path)
path = app.path.config('UserConfig')
app.debug(path)
.. note::
Some paths can be more than one path separated by a semicolon, in this case, you get a `list` of paths.
Path join
---------
.. code-block:: python
path = app.path.join('/home/mau', 'test', 'file.ods')
app.debug(path)
Exists path
-----------
.. code-block:: python
exists = app.path.exists('/home/mau/test/file.ods')
app.debug(exists)
Verify if application exists
----------------------------
.. code-block:: python
app_name = 'nosoffice'
app.debug(app.path.exists_app(app_name))
app_name = 'soffice'
app.debug(app.path.exists_app(app_name))
Path is file
------------
.. code-block:: python
path = '/home/mau/myfile.ott'
app.msgbox(app.path.is_file(path))
Path is dir
-----------
.. code-block:: python
path = '/home/mau'
app.msgbox(app.path.is_dir(path))
Make temporary file
-------------------
It will be destroyed as soon as it is closed.
.. code-block:: python
f = app.path.temp_file()
f.write(app.NAME)
f.close()
If used in context, It will be destroyed too.
.. code-block:: python
with app.path.temp_file() as f:
app.debug(f.name)
f.write('test')
Make temporary directory
------------------------
On completion of the context or destruction of the temporary directory object, the newly created temporary directory and all its contents are removed from the filesystem.
.. code-block:: python
with app.path.temp_dir() as d:
app.debug(app.path.exists(d))
app.debug(d)
Get path for save
-----------------
Default open in user documents
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. code-block:: python
path = app.path.get()
app.msgbox(path)
Open in other path
^^^^^^^^^^^^^^^^^^
.. code-block:: python
path_tmp = app.path.config('Temp')
path = app.path.get(path_tmp)
app.msgbox(path)
Add one filter
^^^^^^^^^^^^^^
.. code-block:: python
path = app.path.get(filters='xml')
app.msgbox(path)
Add multiple filters
^^^^^^^^^^^^^^^^^^^^
.. code-block:: python
path = app.path.get(filters='xml,txt')
Select directory
----------------
Default open in user documents
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. code-block:: python
path = app.path.get_dir()
app.debug(path)
Open in other path
^^^^^^^^^^^^^^^^^^
.. code-block:: python
path_tmp = app.path.config('Temp')
path_dir = app.paths.get_dir(path_tmp)
app.debug(path_dir)
Get path exists file
--------------------
Default open in user documents
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. code-block:: python
path_file = app.path.get_file()
app.msgbox(path_file)
Change init dir
^^^^^^^^^^^^^^^
.. code-block:: python
path = '/home/mau'
path_file = app.path.get_file(path)
app.msgbox(path_file)
Add filter or filters
^^^^^^^^^^^^^^^^^^^^^
.. code-block:: python
path_file = app.path.get_file(filters='ods')
# or
path_file = app.path.get_file(filters='ods,odt')
Can select multiple files
^^^^^^^^^^^^^^^^^^^^^^^^^
.. code-block:: python
path_files = app.path.get_file(multiple=True)
Get files
---------
Get files not recursively
^^^^^^^^^^^^^^^^^^^^^^^^^
.. code-block:: python
path = '/home/mau/Documents'
files = app.path.files(path)
for f in files:
app.debug(f)
Add filter
^^^^^^^^^^
.. code-block:: python
files = app.path.files(path, '*.pdf')
Get content files, recursively
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. code-block:: python
files = app.path.files(path, '**/*.pdf')
Get content files recursively
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This method use `os.walk`
.. code-block:: python
path = '/home/mau/Documents'
files = app.path.walk(path)
for f in files:
app.debug(f)
Add filter
^^^^^^^^^^
.. code-block:: python
files = app.path.walk(path, 'ods')
# or filters
files = app.path.walk(path, 'ods|odt')
Get directories
---------------
Get directories not recursively
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This method use library `pathlib`
.. code-block:: python
path = '/home/mau/Documents'
folders = app.path.dirs(path)
for f in folders:
app.debug(f)
Get directories recursively
^^^^^^^^^^^^^^^^^^^^^^^^^^^
This method use `os.walk`
.. code-block:: python
path = '/home/mau/Documents'
folders = app.path.walk_dirs(path)
for f in folders:
app.debug(f)
Get info in a tuple
^^^^^^^^^^^^^^^^^^^
Like (ID_FOLDER, ID_PARENT, NAME)
.. code-block:: python
path = '/home/mau/Documents'
folders = app.path.walk_dirs(path, True)
for f in folders:
app.debug(f)
Get install path extension from id
----------------------------------
.. code-block:: python
id_ext = 'net.elmau.zaz.EasyMacro'
path = app.path.extension(id_ext)
app.debug(path)
.. code-block:: bash
24/06/2021 21:47:29 - DEBUG - /home/mau/.config/libreoffice/4/user/uno_packages/cache/uno_packages/lu20665x29msz.tmp_/ZAZEasyMacro_v0.1.0.oxt
Replace extension
-----------------
.. code-block:: python
path = '/home/mau/myFile.ods'
path_new = app.path.replace_ext(path, 'pdf')
app.debug(path_new)
Open any type file
------------------
Open with default application in OS.
.. code-block:: python
path = '/home/mau/file.pdf'
app.path.open(path)
path = '/home/mau/index.html'
app.path.open(path)
Save and read text data
-----------------------
Default encoding is UTF8
.. code-block:: python
data = """Do you want to know who you are? Don't ask. Act!
Action will delineate and define you.
Thomas Jefferson
"""
path = '/home/mau/temp.txt'
app.path.save(path, data)
data = app.path.read(path)
app.msgbox(data)
Change encoding
.. code-block:: python
app.path.save(path, data, 'iso-8859-1')
Save and read binary data
-------------------------
.. code-block:: python
data = b'Binary data'
path = '/home/mau/temp.bin'
app.path.save_bin(path, data)
data = app.path.read_bin(path)
app.msgbox(data)
Save and read json
------------------
.. code-block:: python
path = '/home/mau/data.json'
data = {
'type': 'calc',
'name': 'myfile.ods',
}
app.path.to_json(path, data)
data = app.path.from_json(path)
app.msgbox(data)
Save and read csv
-----------------
You can used the same way that `python csv`_
.. code-block:: python
path = '/home/mau/data.csv'
data = (
(1, 'one', app.now()),
(2, 'two', app.now()),
(3, 'three', app.now()),
)
app.path.to_csv(path, data)
data = app.path.from_csv(path)
app.msgbox(data)
Delete files and directories
----------------------------
**CAUTION**: This method delete files and directories without confirmation, always ask to user first.
.. code-block:: python
path = '/home/mau/temp.bin'
result = app.path.kill(path)
app.msgbox(result)
Delete directory and all content
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. code-block:: python
path = '/home/mau/safe_for_delete'
result = app.path.kill(path)
app.msgbox(result)
.. _python csv: https://docs.python.org/3.7/library/csv.html

View File

@ -1,757 +0,0 @@
Tools
=====
Remember, always import library first.
.. code-block:: python
import easymacro as app
Info from PC
------------
Operate system
^^^^^^^^^^^^^^
.. code-block:: python
app.msgbox(app.OS)
.. image:: _static/images/tools_01.png
Desktop
^^^^^^^
Name desktop, only GNU/Linux
.. code-block:: python
app.msgbox(app.DESKTOP)
.. image:: _static/images/tools_02.png
Name PC
^^^^^^^
.. code-block:: python
app.msgbox(app.PC)
.. image:: _static/images/tools_03.png
Current user
^^^^^^^^^^^^
.. code-block:: python
app.msgbox(app.USER)
.. image:: _static/images/tools_04.png
Is Windows
^^^^^^^^^^
.. code-block:: python
app.msgbox(app.IS_WIN)
.. image:: _static/images/tools_05.png
Is Mac
^^^^^^
.. code-block:: python
app.msgbox(app.IS_MAC)
.. image:: _static/images/tools_05.png
Info from LibO
--------------
Application name
^^^^^^^^^^^^^^^^
.. code-block:: python
app.msgbox(app.NAME)
.. image:: _static/images/tools_06.png
Version
^^^^^^^
.. code-block:: python
app.msgbox(app.VERSION)
.. image:: _static/images/tools_07.png
Language
^^^^^^^^
.. code-block:: python
app.msgbox(app.LANG)
.. image:: _static/images/tools_08.png
Language with variant
^^^^^^^^^^^^^^^^^^^^^
.. code-block:: python
app.msgbox(app.LANGUAGE)
.. image:: _static/images/tools_09.png
Message Box
-----------
.. code-block:: python
app.msgbox('Damed World', 'My Macro')
.. image:: _static/images/tools_10.png
Show warning box
----------------
.. code-block:: python
message = 'Caution, this action is dangerous'
title = 'My App'
app.warning(message, title)
.. image:: _static/images/tools_11.png
Show error box
--------------
.. code-block:: python
message = 'ERROR: Contact technical support'
title = 'My App'
app.errorbox(message, title)
.. image:: _static/images/tools_12.png
Make question
-------------
.. code-block:: python
message = 'Is easy Python?'
title = 'My App'
result = app.question(message, title)
app.msgbox(result)
.. image:: _static/images/tools_13.png
InputBox
^^^^^^^^
* Normal data
.. code-block:: python
message = 'Type your name'
default = ''
title = 'My App'
result = app.inputbox(message, default, title)
app.msgbox(result)
* Private data
.. code-block:: python
message = 'Type your password'
default = ''
title = 'My App'
echochar = "*"
result = app.inputbox(message, default, title, echochar)
app.msgbox(result)
Date and times
--------------
Get today
^^^^^^^^^
.. code-block:: python
d = app.dates
app.msgbox(d.today)
.. image:: _static/images/tools_14.png
Get now
^^^^^^^
.. code-block:: python
d = app.dates
app.msgbox(d.now)
.. image:: _static/images/tools_15.png
Get `Unix Time`_
^^^^^^^^^^^^^^^^
.. code-block:: python
d = app.dates
app.msgbox(app.d.epoch)
.. image:: _static/images/tools_16.png
Simple measure time
^^^^^^^^^^^^^^^^^^^
.. code-block:: python
d = app.dates
d.start()
app.sleep(5)
seconds = d.end()
app.msgbox(seconds)
.. image:: _static/images/tools_17.png
.. image:: _static/images/tools_18.png
Make date
^^^^^^^^^
.. code-block:: python
d = app.dates
date = d.date(1974, 1, 15)
app.msgbox(date)
.. image:: _static/images/tools_19.png
.. note::
Start date in Python and Calc is diferent.
String to date
^^^^^^^^^^^^^^
See `Python strftime cheatsheet <https://strftime.org/>`_
.. code-block:: python
d = app.dates
str_date = '1974-01-15'
template = '%Y-%m-%d'
date = d.str_to_date(str_date, template)
app.msgbox(type(date))
.. image:: _static/images/tools_20.png
|
For correct date for Calc.
.. code-block:: python
d = app.dates
str_date = '1974-01-15'
template = '%Y-%m-%d'
date = d.str_to_date(str_date, template, True)
app.msgbox(type(date))
.. image:: _static/images/tools_21.png
Calc to date
^^^^^^^^^^^^
Get star date in Calc configuration.
.. code-block:: python
d = app.dates
cell_value = 1
date = d.calc_to_date(cell_value)
app.msgbox(date)
.. image:: _static/images/tools_22.png
Thread
------
You can execute any macro in thread
Normal execution
^^^^^^^^^^^^^^^^
.. code-block:: python
def show_time(seconds):
app.sleep(seconds)
app.msgbox(app.NAME)
return
def main(args=None):
show_time(5)
app.msgbox('Finish...')
return
Run in thread
^^^^^^^^^^^^^
.. code-block:: python
@app.run_in_thread
def show_time(seconds):
app.sleep(seconds)
app.msgbox(app.NAME)
return
def main(args=None):
show_time(5)
app.msgbox('Finish...')
return
Dictionary to/from Properties
-----------------------------
.. code-block:: python
args = {
'Hidden': True,
'Password': 'letmein',
}
properties = app.dict_to_property(args)
app.msgbox(properties)
data = app.data_to_dict(properties)
app.msgbox(data)
Tuples or lists to dictionary
-----------------------------
.. code-block:: python
tuple_of_tuples = (
('Hidden', True),
('Password', 'letmein'),
)
data = app.data_to_dict(tuple_of_tuples)
app.msgbox(data)
list_of_lists = [
['Hidden', True],
['Password', 'letmein'],
]
data = app.data_to_dict(list_of_lists)
app.msgbox(data)
Json
----
Dumps data
^^^^^^^^^^
.. code-block:: python
data = {
'Hidden': True,
'Password': 'letmein',
}
json = app.json.dumps(data)
app.msgbox(json)
Loads data
^^^^^^^^^^
.. code-block:: python
data = app.json.loads(json)
app.msgbox(data)
Call Macros
-----------
You can execute any macro, for default call macros Python.
.. code-block:: python
def show_message():
app.msgbox(app.INFO_DEBUG)
return
def main(args=None):
args = {
'library': 'test',
'name': 'show_message',
}
app.macro.call(args)
return
Of course is better call directly if both macros are the same languaje, but, you can call macro in Basic too.
.. code-block:: vbnet
Sub show_message()
MsgBox "Basic from Python"
End Sub
Call from Python with.
.. code-block:: python
args = {
'language': 'Basic',
'library': 'Standard',
'module': 'Module1',
'name': 'show_message',
}
app.call_macro(args)
Execute macro in other thread
.. code-block:: python
app.call_macro(args, True)
Call external program
---------------------
.. code-block:: python
app_name = 'gnome-calculator'
app.shell.run(app_name)
app.debug(app_name)
Call command line and capture output
.. code-block:: python
args = 'ls -lh ~'
result = app.shell.run(args, True)
app.debug(result)
.. code-block:: bash
21/06/2021 22:27:22 - DEBUG - total 1.3M
drwxr-xr-x 5 mau mau 4.0K Jun 17 13:09 Desktop
drwxr-xr-x 6 mau mau 4.0K Jun 15 12:35 Documents
drwxr-xr-x 2 mau mau 4.0K Jun 21 20:26 Downloads
drwxr-xr-x 2 mau mau 4.0K Jun 21 16:18 Pictures
drwxr-xr-x 13 mau mau 4.0K Jun 21 15:34 Projects
drwxr-xr-x 2 mau mau 4.0K May 11 18:48 Templates
drwxr-xr-x 2 mau mau 4.0K Jun 20 23:27 Videos
Call command line and capture output line by line.
.. code-block:: python
args = 'ls -lh /home/mau'
for line in app.popen(args):
app.debug(line)
.. code-block:: bash
21/06/2021 22:34:42 - DEBUG - total 1.3M
21/06/2021 22:34:42 - DEBUG - drwxr-xr-x 5 mau mau 4.0K Jun 17 13:09 Desktop
21/06/2021 22:34:42 - DEBUG - drwxr-xr-x 6 mau mau 4.0K Jun 15 12:35 Documents
21/06/2021 22:34:42 - DEBUG - drwxr-xr-x 2 mau mau 4.0K Jun 21 20:26 Downloads
21/06/2021 22:34:42 - DEBUG - -rw-r----- 1 mau mau 1.3M Jun 14 11:53 out.png
21/06/2021 22:34:42 - DEBUG - drwxr-xr-x 2 mau mau 4.0K Jun 21 16:18 Pictures
21/06/2021 22:34:42 - DEBUG - drwxr-xr-x 13 mau mau 4.0K Jun 21 15:34 Projects
21/06/2021 22:34:42 - DEBUG - drwxr-xr-x 2 mau mau 4.0K May 11 18:48 Templates
21/06/2021 22:34:42 - DEBUG - drwxr-xr-x 2 mau mau 4.0K Jun 20 23:27 Videos
Timer
-----
Only once
^^^^^^^^^
Execute any macro only once in N seconds.
.. code-block:: python
TIMER_NAME = 'clock'
def show_time():
app.debug(app.dates.time)
return
def start_clock():
seconds = 5
macro = {
'library': 'test',
'name': 'show_time',
}
app.timer.once(TIMER_NAME, seconds, macro)
return
def main(args=None):
start_clock()
return
Cancel execution, before start.
.. code-block:: python
TIMER_NAME = 'clock'
def show_time():
app.debug(app.dates.time)
return
def start_clock():
seconds = 60
macro = {
'library': 'test',
'name': 'show_time',
}
app.timer.once(TIMER_NAME, seconds, macro)
return
def stop_clock():
app.timer.cancel(TIMER_NAME)
return
.. code-block:: bash
26/02/2022 12:23:09 - INFO - Event: "clock", started... execute in 60 seconds
26/02/2022 12:23:16 - INFO - Cancel event: "clock", ok...
Every seconds
^^^^^^^^^^^^^
Execute any macro every seconds.
.. code-block:: python
TIMER_NAME = 'clock'
def show_time():
app.debug(app.dates.time)
return
def start_clock():
seconds = 1
macro = {
'library': 'test',
'name': 'show_time',
}
app.timer.start(TIMER_NAME, seconds, macro)
return
def stop_clock():
app.timer.stop(TIMER_NAME)
return
def main(args=None):
start_clock()
return
Execute **stop_clock** for stop timer.
.. code-block:: bash
26/02/2022 11:28:01 - INFO - Timer 'clock' started, execute macro: 'show_time'
26/02/2022 11:28:02 - DEBUG - 11:28:02
26/02/2022 11:28:03 - DEBUG - 11:28:03
...
26/02/2022 11:28:08 - DEBUG - 11:28:08
26/02/2022 11:28:09 - DEBUG - 11:28:09
26/02/2022 11:28:10 - INFO - Timer stopped...
.. note::
Be sure to use a unique name for each timer.
.. warning::
Be sure to macro for execute not block UI LibO
Get digest
----------
For default get digest in hex
.. code-block:: python
data = 'LibreOffice with Python'
digest = app.hash.digest('md5', data)
app.debug('MD5 = ', digest)
digest = app.hash.digest('sha1', data)
app.debug('SHA1 = ', digest)
digest = app.hash.digest('sha256', data)
app.debug('SHA256 = ', digest)
digest = app.hash.digest('sha512', data)
app.debug('SHA512 = ', digest)
# Get bytes
digest = app.hash.digest('md5', data, False)
app.debug('MD5 = ', digest)
.. code-block:: bash
26/02/2022 15:57:53 - DEBUG - MD5 = e0cb96d2c04b26db79dbd30c4d56b555
26/02/2022 15:57:53 - DEBUG - SHA1 = 7006fb17b7a235245cfc986710a11f10543ae10d
26/02/2022 15:57:53 - DEBUG - SHA256 = 3fe4586d51fa3e352ec28c05b7e71eaee2e41d5ee78f372c44eeb2f433f7e002
26/02/2022 15:57:53 - DEBUG - SHA512 = b6eaea6bc11956eae7f990034ff950eba4b0fe51a577d301272cc8b4c1c603abd36ce852311766e5af2f603d1d96741797b62d4b405459348bacae7ec54e2982
26/02/2022 15:57:53 - DEBUG - MD5 = b'\xe0\xcb\x96\xd2\xc0K&\xdby\xdb\xd3\x0cMV\xb5U'
Save and get configurations
---------------------------
You can save any data.
.. code-block:: python
my_app = 'my_extension'
data = {
'path': '/home/mau/work',
'save_data': True,
}
if app.config.set(my_app, data):
app.msgbox('Save config')
path = app.config.get(my_app)
app.msgbox(data)
You can get any key
.. code-block:: python
path = app.config.get(my_app, 'path')
app.msgbox(path)
Render string
-------------
.. code-block:: python
template = """Hello $name
I send you this $file_name
Best regards
"""
data = {'name': 'Ingrid Bergman', 'file_name': 'letter_love.odt'}
render = app.render(template, data)
app.msgbox(render)
Simple url open
---------------
Get text data
^^^^^^^^^^^^^
.. code-block:: python
url = 'https://api.ipify.org'
result, headers, err = app.url.get(url)
if err:
app.error(err)
else:
app.debug(type(result), result)
app.debug(headers)
.. image:: _static/images/tools_23.png
|
Get json data
^^^^^^^^^^^^^
.. code-block:: python
url = 'https://api.ipify.org?format=json'
result, headers, err = app.url.get(url, json=True)
if err:
app.error(err)
else:
app.debug(type(result), result)
app.debug(headers)
.. image:: _static/images/tools_24.png
|
Color
-----
Look colors that you can used in `web colors`_
.. code-block:: python
color_name = 'darkblue'
color = app.color(color_name)
app.debug(color)
color_rgb = (125, 200, 10)
color = app.color(color_rgb)
app.debug(color)
color_html = '#008080'
color = app.color(color_html)
app.debug(color)
.. _Unix Time: https://en.wikipedia.org/wiki/Unix_time
.. _web colors: https://en.wikipedia.org/wiki/Web_colors

View File

@ -1,216 +0,0 @@
Tools for debug
===============
INFO_DEBUG
----------
Show info debug, show in message box.
If you have any problem in your code, you can `open issue`_ in this project,
always copy the information of **INFO_DEBUG** in your ticket.
.. code-block:: python
import easymacro as app
def info():
app.msgbox(app.INFO_DEBUG)
return
.. image:: _static/images/install_01.png
|
Show in shell.
.. code-block:: python
import easymacro as app
def info():
app.debug(app.INFO_DEBUG)
return
.. code-block:: console
mau@oficina ~> soffice --calc
25/02/2022 16:44:24 - DEBUG - LibreOffice v7.3 en-US
Python: 3.10.2 (main, Jan 15 2022, 19:56:27) [GCC 11.1.0]
Linux-5.16.11-arch1-1-x86_64-with-glibc2.35
/usr/lib/libreoffice/program
/usr/lib/python310.zip
/usr/lib/python3.10
/usr/lib/python3.10/lib-dynload
/home/mau/.local/lib/python3.10/site-packages
/usr/lib/python3.10/site-packages
/usr/lib/libreoffice/program/
/home/mau/.config/libreoffice/4/user/Scripts/python/pythonpath
Log error
---------
Show message error in shell.
.. code-block:: python
import easymacro as app
def test_error():
msg = 'My error 500'
app.error(msg)
return
.. image:: _static/images/toolsdebug_01.png
Log debug
---------
Show message debug in shell.
.. code-block:: python
import easymacro as app
def test_debug():
msg = 'Verify this data...'
app.debug(msg)
return
.. image:: _static/images/toolsdebug_02.png
Log info
--------
Show message info in shell.
.. code-block:: python
import easymacro as app
def test_info():
msg = 'Start process...'
app.info(msg)
return
.. image:: _static/images/toolsdebug_03.png
Log to file
-----------
Save log to file, automatic add date and time.
.. code-block:: python
import easymacro as app
def log():
app.save_log('/home/mau/log.txt', 'PyUNO')
app.save_log('/home/mau/log.txt', 'Damed World')
return
.. image:: _static/images/toolsdebug_04.png
Message Box
-----------
Show any data in message box
.. code-block:: python
import easymacro as app
def message():
msg = 'Please, save the planet'
app.msgbox(msg)
msg = ('one', 2, 'three')
app.msgbox(msg)
msg = {'name': 'Teresa'}
app.msgbox(msg)
app.msgbox(app)
return
.. image:: _static/images/toolsdebug_05.png
Catch exceptions
----------------
Sometimes, for difficult errors, you can catch exceptions.
.. code-block:: python
import easymacro as app
@app.catch_exception
def test():
r = 1 / 0
return
.. image:: _static/images/toolsdebug_06.png
.. warning::
Not, not used you this function in production.
Call MRI
--------
`MRI`_ is the best extension for debug any object in LibreOffice, you need
install before call it.
.. code-block:: python
import easymacro as app
def error():
obj = app.active
app.mri(obj)
return
.. image:: _static/images/toolsdebug_07.png
Inspect
-------
Show info in shell debug
.. code-block:: python
import easymacro as app
def inspect():
obj = app.active
data = app.inspect(doc)
for p in data.properties:
app.debug(p)
for m in data.methods:
app.debug(m)
return
Or show in new Calc document.
.. code-block:: python
obj = app.active
app.inspect(doc, True)
.. _MRI: https://github.com/hanya/MRI
.. _open issue: https://git.cuates.net/elmau/easymacro/issues

View File

@ -932,55 +932,6 @@ class LOMain():
obj = create_instance('com.sun.star.frame.Desktop', True)
return obj
@classmethod
def dispatch(cls, frame: Any, command: str, args: dict={}) -> None:
"""Call dispatch, used only if not exists directly in API
:param frame: doc or frame instance
:type frame: pyUno
:param command: Command to execute
:type command: str
:param args: Extra argument for command
:type args: dict
`See DispatchCommands <`See DispatchCommands <https://wiki.documentfoundation.org/Development/DispatchCommands>`_>`_
"""
dispatch = create_instance('com.sun.star.frame.DispatchHelper')
if hasattr(frame, 'frame'):
frame = frame.frame
url = command
if not command.startswith('.uno:'):
url = f'.uno:{command}'
opt = dict_to_property(args)
dispatch.executeDispatch(frame, url, '', 0, opt)
return
@classmethod
def fonts(cls):
"""Get all font visibles in LibreOffice
:return: tuple of FontDescriptors
:rtype: tuple
`See API FontDescriptor <https://api.libreoffice.org/docs/idl/ref/structcom_1_1sun_1_1star_1_1awt_1_1FontDescriptor.html>`_
"""
toolkit = create_instance('com.sun.star.awt.Toolkit')
device = toolkit.createScreenCompatibleDevice(0, 0)
return device.FontDescriptors
@classmethod
def filters(cls):
"""Get all support filters
`See Help ConvertFilters <https://help.libreoffice.org/latest/en-US/text/shared/guide/convertfilters.html>`_
`See API FilterFactory <https://api.libreoffice.org/docs/idl/ref/servicecom_1_1sun_1_1star_1_1document_1_1FilterFactory.html>`_
"""
factory = create_instance('com.sun.star.document.FilterFactory')
rows = [data_to_dict(factory[name]) for name in factory]
for row in rows:
row['UINames'] = data_to_dict(row['UINames'])
return rows
class LODocument():
@ -1005,11 +956,6 @@ class LODocument():
"""Get type document"""
return self._type
@property
def frame(self):
"""Get frame document"""
return self._cc.getFrame()
@property
def title(self):
"""Get title document"""

View File

@ -13,7 +13,10 @@ def __getattr__(name):
'config': Config,
'dates': Dates,
'dialog': LODialog,
'dispatch': LOMain.dispatch,
'email': Email,
'filters': LOMain.filters,
'fonts': LOMain.fonts,
'hash': Hash,
'inspect': LOInspect,
'macro': Macro,

View File

@ -18,6 +18,11 @@ class LODocument(BaseObject):
"""Get type document"""
return self._type
@property
def frame(self):
"""Get frame document"""
return self._cc.getFrame()
def _create_instance(self, name):
obj = self.obj.createInstance(name)
return obj

View File

@ -25,10 +25,11 @@ __all__ = [
'PC',
'USER',
'VERSION',
'create_instance',
'LOMain',
# ~ 'create_instance',
'data_to_dict',
'dict_to_property',
'get_app_config',
# ~ 'get_app_config',
]
@ -176,3 +177,55 @@ class BaseObject():
"""Return original pyUno object"""
return self._obj
class LOMain():
"""Classe for LibreOffice"""
@classmethod
def fonts(cls):
"""Get all font visibles in LibreOffice
:return: tuple of FontDescriptors
:rtype: tuple
`See API FontDescriptor <https://api.libreoffice.org/docs/idl/ref/structcom_1_1sun_1_1star_1_1awt_1_1FontDescriptor.html>`_
"""
toolkit = create_instance('com.sun.star.awt.Toolkit')
device = toolkit.createScreenCompatibleDevice(0, 0)
return device.FontDescriptors
@classmethod
def filters(cls):
"""Get all support filters
`See Help ConvertFilters <https://help.libreoffice.org/latest/en-US/text/shared/guide/convertfilters.html>`_
`See API FilterFactory <https://api.libreoffice.org/docs/idl/ref/servicecom_1_1sun_1_1star_1_1document_1_1FilterFactory.html>`_
"""
factory = create_instance('com.sun.star.document.FilterFactory')
rows = [data_to_dict(factory[name]) for name in factory]
for row in rows:
row['UINames'] = data_to_dict(row['UINames'])
return rows
@classmethod
def dispatch(cls, frame: Any, command: str, args: dict={}) -> None:
"""Call dispatch, used only if not exists directly in API
:param frame: doc or frame instance
:type frame: pyUno
:param command: Command to execute
:type command: str
:param args: Extra argument for command
:type args: dict
`See DispatchCommands <`See DispatchCommands <https://wiki.documentfoundation.org/Development/DispatchCommands>`_>`_
"""
dispatch = create_instance('com.sun.star.frame.DispatchHelper')
if hasattr(frame, 'frame'):
frame = frame.frame
url = command
if not command.startswith('.uno:'):
url = f'.uno:{command}'
opt = dict_to_property(args)
dispatch.executeDispatch(frame, url, '', 0, opt)
return

View File

@ -1 +0,0 @@
#!/usr/bin/env python3

File diff suppressed because it is too large Load Diff