diff --git a/.gitignore b/.gitignore
index 399bdd7..0030b5e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,8 +3,7 @@ __pycache__/
*.po~
*.log
-images/
-
+/images
docs/
# Virtualenv
diff --git a/easymacro.py b/easymacro.py
index 16715df..16563ad 100644
--- a/easymacro.py
+++ b/easymacro.py
@@ -85,6 +85,7 @@ from com.sun.star.lang import XEventListener
from com.sun.star.awt import XMouseListener
from com.sun.star.awt import XMouseMotionListener
from com.sun.star.awt import XFocusListener
+from com.sun.star.awt import XKeyListener
# ~ https://api.libreoffice.org/docs/idl/ref/namespacecom_1_1sun_1_1star_1_1awt_1_1FontUnderline.html
from com.sun.star.awt import FontUnderline
@@ -184,6 +185,11 @@ DIR = {
'locales': 'locales',
}
DEFAULT_MIME_TYPE = 'png'
+
+KEY = {
+ 'enter': 1280,
+}
+
MODIFIERS = {
'shift': KeyModifier.SHIFT,
'ctrl': KeyModifier.MOD1,
@@ -1153,6 +1159,64 @@ class LODocument(object):
return
+class LOCellStyle(LOBaseObject):
+
+ def __init__(self, obj):
+ super().__init__(obj)
+
+ @property
+ def name(self):
+ return self.obj.Name
+
+ @property
+ def properties(self):
+ properties = self.obj.PropertySetInfo.Properties
+ data = {p.Name: getattr(self.obj, p.Name) for p in properties}
+ return data
+ @properties.setter
+ def properties(self, values):
+ _set_properties(self.obj, values)
+
+
+class LOCellStyles(object):
+
+ def __init__(self, obj, doc):
+ self._obj = obj
+ self._doc = doc
+
+ def __len__(self):
+ return len(self.obj)
+
+ def __getitem__(self, index):
+ return LOCellStyle(self.obj[index])
+
+ def __setitem__(self, key, value):
+ self.obj[key] = value
+
+ def __delitem__(self, key):
+ if not isinstance(key, str):
+ key = key.Name
+ del self.obj[key]
+
+ def __contains__(self, item):
+ return item in self.obj
+
+ @property
+ def obj(self):
+ return self._obj
+
+ @property
+ def names(self):
+ return self.obj.ElementNames
+
+ def new(self, name: str=''):
+ obj = self._doc.create_instance('com.sun.star.style.CellStyle')
+ if name:
+ self.obj[name] = obj
+ obj = LOCellStyle(obj)
+ return obj
+
+
class LOCalc(LODocument):
def __init__(self, obj):
@@ -1208,6 +1272,14 @@ class LOCalc(LODocument):
def tabs(self, value):
self._cc.SheetTabs = value
+ @property
+ def cs(self):
+ return self.cell_styles
+ @property
+ def cell_styles(self):
+ obj = self.obj.StyleFamilies['CellStyles']
+ return LOCellStyles(obj, self)
+
@property
def db_ranges(self):
# ~ return LOCalcDataBaseRanges(self.obj.DataBaseRanges)
@@ -2121,6 +2193,18 @@ class LOWriterTextRange(object):
self._is_paragraph = self.obj.ImplementationName == 'SwXParagraph'
self._is_table = self.obj.ImplementationName == 'SwXTextTable'
+ def __iter__(self):
+ self._index = 0
+ return self
+
+ def __next__(self):
+ for i, p in enumerate(self.obj):
+ if i == self._index:
+ obj = LOWriterTextRange(p, self._doc)
+ self._index += 1
+ return obj
+ raise StopIteration
+
@property
def obj(self):
return self._obj
@@ -2142,7 +2226,7 @@ class LOWriterTextRange(object):
@property
def text(self):
- return self.obj.getText()
+ return self.obj.Text
@property
def cursor(self):
@@ -2152,6 +2236,10 @@ class LOWriterTextRange(object):
def dp(self):
return self._doc.dp
+ @property
+ def is_table(self):
+ return self._is_table
+
def offset(self):
cursor = self.cursor.getEnd()
return LOWriterTextRange(cursor, self._doc)
@@ -2181,7 +2269,23 @@ class LOWriterTextRanges(object):
self._doc = doc
def __getitem__(self, index):
- return LOWriterTextRange(self.obj[index], self._doc)
+ for i, p in enumerate(self.obj):
+ if i == index:
+ obj = LOWriterTextRange(p, self._doc)
+ break
+ return obj
+
+ def __iter__(self):
+ self._index = 0
+ return self
+
+ def __next__(self):
+ for i, p in enumerate(self.obj):
+ if i == self._index:
+ obj = LOWriterTextRange(p, self._doc)
+ self._index += 1
+ return obj
+ raise StopIteration
@property
def obj(self):
@@ -2194,6 +2298,14 @@ class LOWriter(LODocument):
super().__init__(obj)
self._type = WRITER
+ @property
+ def text(self):
+ return LOWriterTextRange(self.obj.Text, self)
+
+ @property
+ def paragraphs(self):
+ return LOWriterTextRanges(self.obj.Text, self)
+
@property
def selection(self):
sel = self.obj.CurrentSelection
@@ -2841,7 +2953,7 @@ def _add_listeners(events, control, name=''):
'addMouseListener': EventsMouse,
'addFocusListener': EventsFocus,
# ~ 'addItemListener': EventsItem,
- # ~ 'addKeyListener': EventsKey,
+ 'addKeyListener': EventsKey,
# ~ 'addTabListener': EventsTab,
}
if hasattr(control, 'obj'):
@@ -2984,6 +3096,27 @@ class EventsFocus(EventsListenerBase, XFocusListener):
return
+class EventsKey(EventsListenerBase, XKeyListener):
+ """
+ event.KeyChar
+ event.KeyCode
+ event.KeyFunc
+ event.Modifiers
+ """
+
+ def __init__(self, controller, name):
+ super().__init__(controller, name)
+
+ def keyPressed(self, event):
+ pass
+
+ def keyReleased(self, event):
+ event_name = '{}_key_released'.format(self._name)
+ if hasattr(self._controller, event_name):
+ getattr(self._controller, event_name)(event)
+ return
+
+
# ~ BorderColor = ?
# ~ FontStyleName = ?
# ~ HelpURL = ?
diff --git a/files/ZAZPip_v0.6.0.oxt b/files/ZAZPip_v0.6.0.oxt
new file mode 100644
index 0000000..c62bcdb
Binary files /dev/null and b/files/ZAZPip_v0.6.0.oxt differ
diff --git a/source/images/close.svg b/source/images/close.svg
new file mode 100644
index 0000000..8b7bc47
--- /dev/null
+++ b/source/images/close.svg
@@ -0,0 +1,52 @@
+
+
diff --git a/source/images/home.svg b/source/images/home.svg
new file mode 100644
index 0000000..517ac7d
--- /dev/null
+++ b/source/images/home.svg
@@ -0,0 +1,37 @@
+
+
diff --git a/source/images/icon_16.bmp b/source/images/icon_16.bmp
new file mode 100644
index 0000000..8eaab00
Binary files /dev/null and b/source/images/icon_16.bmp differ
diff --git a/source/images/install.svg b/source/images/install.svg
new file mode 100644
index 0000000..c878786
--- /dev/null
+++ b/source/images/install.svg
@@ -0,0 +1,62 @@
+
+
diff --git a/source/images/ok.svg b/source/images/ok.svg
new file mode 100644
index 0000000..f211040
--- /dev/null
+++ b/source/images/ok.svg
@@ -0,0 +1,50 @@
+
+
diff --git a/source/images/python.svg b/source/images/python.svg
new file mode 100644
index 0000000..9d3262f
--- /dev/null
+++ b/source/images/python.svg
@@ -0,0 +1,57 @@
+
+
diff --git a/source/images/question.svg b/source/images/question.svg
new file mode 100644
index 0000000..2fc074d
--- /dev/null
+++ b/source/images/question.svg
@@ -0,0 +1,27 @@
+
+
diff --git a/source/images/search.svg b/source/images/search.svg
new file mode 100644
index 0000000..d928e3b
--- /dev/null
+++ b/source/images/search.svg
@@ -0,0 +1,41 @@
+
+
diff --git a/source/images/shell.svg b/source/images/shell.svg
new file mode 100644
index 0000000..2e4350a
--- /dev/null
+++ b/source/images/shell.svg
@@ -0,0 +1,48 @@
+
+
diff --git a/source/images/uninstall.svg b/source/images/uninstall.svg
new file mode 100644
index 0000000..5a7c6bd
--- /dev/null
+++ b/source/images/uninstall.svg
@@ -0,0 +1,63 @@
+
+
diff --git a/source/images/zazpip.png b/source/images/zazpip.png
new file mode 100644
index 0000000..2f210ed
Binary files /dev/null and b/source/images/zazpip.png differ
diff --git a/source/pythonpath/easymacro.py b/source/pythonpath/easymacro.py
index c2e81bd..16563ad 100644
--- a/source/pythonpath/easymacro.py
+++ b/source/pythonpath/easymacro.py
@@ -85,6 +85,7 @@ from com.sun.star.lang import XEventListener
from com.sun.star.awt import XMouseListener
from com.sun.star.awt import XMouseMotionListener
from com.sun.star.awt import XFocusListener
+from com.sun.star.awt import XKeyListener
# ~ https://api.libreoffice.org/docs/idl/ref/namespacecom_1_1sun_1_1star_1_1awt_1_1FontUnderline.html
from com.sun.star.awt import FontUnderline
@@ -184,6 +185,11 @@ DIR = {
'locales': 'locales',
}
DEFAULT_MIME_TYPE = 'png'
+
+KEY = {
+ 'enter': 1280,
+}
+
MODIFIERS = {
'shift': KeyModifier.SHIFT,
'ctrl': KeyModifier.MOD1,
@@ -556,8 +562,7 @@ def popen(command):
yield line.decode().rstrip()
except Exception as e:
error(e)
- msg = f'Error No: {e.errno} - {e.strerror}'
- yield msg
+ yield (e.errno, e.strerror)
def sleep(seconds):
@@ -1154,6 +1159,64 @@ class LODocument(object):
return
+class LOCellStyle(LOBaseObject):
+
+ def __init__(self, obj):
+ super().__init__(obj)
+
+ @property
+ def name(self):
+ return self.obj.Name
+
+ @property
+ def properties(self):
+ properties = self.obj.PropertySetInfo.Properties
+ data = {p.Name: getattr(self.obj, p.Name) for p in properties}
+ return data
+ @properties.setter
+ def properties(self, values):
+ _set_properties(self.obj, values)
+
+
+class LOCellStyles(object):
+
+ def __init__(self, obj, doc):
+ self._obj = obj
+ self._doc = doc
+
+ def __len__(self):
+ return len(self.obj)
+
+ def __getitem__(self, index):
+ return LOCellStyle(self.obj[index])
+
+ def __setitem__(self, key, value):
+ self.obj[key] = value
+
+ def __delitem__(self, key):
+ if not isinstance(key, str):
+ key = key.Name
+ del self.obj[key]
+
+ def __contains__(self, item):
+ return item in self.obj
+
+ @property
+ def obj(self):
+ return self._obj
+
+ @property
+ def names(self):
+ return self.obj.ElementNames
+
+ def new(self, name: str=''):
+ obj = self._doc.create_instance('com.sun.star.style.CellStyle')
+ if name:
+ self.obj[name] = obj
+ obj = LOCellStyle(obj)
+ return obj
+
+
class LOCalc(LODocument):
def __init__(self, obj):
@@ -1209,6 +1272,14 @@ class LOCalc(LODocument):
def tabs(self, value):
self._cc.SheetTabs = value
+ @property
+ def cs(self):
+ return self.cell_styles
+ @property
+ def cell_styles(self):
+ obj = self.obj.StyleFamilies['CellStyles']
+ return LOCellStyles(obj, self)
+
@property
def db_ranges(self):
# ~ return LOCalcDataBaseRanges(self.obj.DataBaseRanges)
@@ -2122,6 +2193,18 @@ class LOWriterTextRange(object):
self._is_paragraph = self.obj.ImplementationName == 'SwXParagraph'
self._is_table = self.obj.ImplementationName == 'SwXTextTable'
+ def __iter__(self):
+ self._index = 0
+ return self
+
+ def __next__(self):
+ for i, p in enumerate(self.obj):
+ if i == self._index:
+ obj = LOWriterTextRange(p, self._doc)
+ self._index += 1
+ return obj
+ raise StopIteration
+
@property
def obj(self):
return self._obj
@@ -2143,7 +2226,7 @@ class LOWriterTextRange(object):
@property
def text(self):
- return self.obj.getText()
+ return self.obj.Text
@property
def cursor(self):
@@ -2153,6 +2236,10 @@ class LOWriterTextRange(object):
def dp(self):
return self._doc.dp
+ @property
+ def is_table(self):
+ return self._is_table
+
def offset(self):
cursor = self.cursor.getEnd()
return LOWriterTextRange(cursor, self._doc)
@@ -2182,7 +2269,23 @@ class LOWriterTextRanges(object):
self._doc = doc
def __getitem__(self, index):
- return LOWriterTextRange(self.obj[index], self._doc)
+ for i, p in enumerate(self.obj):
+ if i == index:
+ obj = LOWriterTextRange(p, self._doc)
+ break
+ return obj
+
+ def __iter__(self):
+ self._index = 0
+ return self
+
+ def __next__(self):
+ for i, p in enumerate(self.obj):
+ if i == self._index:
+ obj = LOWriterTextRange(p, self._doc)
+ self._index += 1
+ return obj
+ raise StopIteration
@property
def obj(self):
@@ -2195,6 +2298,14 @@ class LOWriter(LODocument):
super().__init__(obj)
self._type = WRITER
+ @property
+ def text(self):
+ return LOWriterTextRange(self.obj.Text, self)
+
+ @property
+ def paragraphs(self):
+ return LOWriterTextRanges(self.obj.Text, self)
+
@property
def selection(self):
sel = self.obj.CurrentSelection
@@ -2842,7 +2953,7 @@ def _add_listeners(events, control, name=''):
'addMouseListener': EventsMouse,
'addFocusListener': EventsFocus,
# ~ 'addItemListener': EventsItem,
- # ~ 'addKeyListener': EventsKey,
+ 'addKeyListener': EventsKey,
# ~ 'addTabListener': EventsTab,
}
if hasattr(control, 'obj'):
@@ -2985,6 +3096,27 @@ class EventsFocus(EventsListenerBase, XFocusListener):
return
+class EventsKey(EventsListenerBase, XKeyListener):
+ """
+ event.KeyChar
+ event.KeyCode
+ event.KeyFunc
+ event.Modifiers
+ """
+
+ def __init__(self, controller, name):
+ super().__init__(controller, name)
+
+ def keyPressed(self, event):
+ pass
+
+ def keyReleased(self, event):
+ event_name = '{}_key_released'.format(self._name)
+ if hasattr(self._controller, event_name):
+ getattr(self._controller, event_name)(event)
+ return
+
+
# ~ BorderColor = ?
# ~ FontStyleName = ?
# ~ HelpURL = ?
diff --git a/source/pythonpath/main.py b/source/pythonpath/main.py
index ebc9bd3..47e167c 100644
--- a/source/pythonpath/main.py
+++ b/source/pythonpath/main.py
@@ -11,20 +11,21 @@ TITLE = 'ZAZ-PIP'
URL_PIP = 'https://bootstrap.pypa.io/get-pip.py'
PIP = 'pip'
URL_GIT = 'https://git.elmau.net/elmau'
-
+ICON_OK = 'ok.svg'
+ICON_QUESTION = 'question.svg'
PACKAGES = {
- 'cffi': 'ok.png',
- 'cryptography': 'ok.png',
- 'httpx': 'ok.png',
- 'lxml': 'ok.png',
- 'numpy': 'ok.png',
- 'pandas': 'ok.png',
- 'psycopg2-binary': 'ok.png',
- 'peewee': 'ok.png',
- 'pillow': 'ok.png',
- 'pytesseract': 'ok.png',
- 'sounddevice': 'ok.png',
+ 'cffi': ICON_OK,
+ 'cryptography': ICON_OK,
+ 'httpx': ICON_OK,
+ 'lxml': ICON_OK,
+ 'numpy': ICON_OK,
+ 'pandas': ICON_OK,
+ 'psycopg2-binary': ICON_OK,
+ 'peewee': ICON_OK,
+ 'pillow': ICON_OK,
+ 'pytesseract': ICON_OK,
+ 'sounddevice': ICON_OK,
}
@@ -75,7 +76,6 @@ class Controllers(object):
path_pip = app.paths.tmp()
self.d.lst_log.insert(_('Download PIP...'))
data, h, err = app.url_open(URL_PIP, verify=False)
- app.msgbox(path_pip)
if err:
msg = _('Do you have internet connection?')
app.errorbox('{}\n\n{}'.format(msg, err))
@@ -155,7 +155,7 @@ class Controllers(object):
for p in packages:
t = '{} - ({})'.format(p['name'], p['version'])
- self.d.lst_package.insert(t, 'ok.png')
+ self.d.lst_package.insert(t, ICON_OK)
self.d.lst_package.select()
self.d.txt_search.set_focus()
return
@@ -173,7 +173,7 @@ class Controllers(object):
parts = name.split('(')
name_verify = parts[0].strip()
package = '{} {}'.format(name, description)
- image = PACKAGES.get(name_verify, 'question.png')
+ image = PACKAGES.get(name_verify, ICON_QUESTION)
self.d.lst_package.insert(package, image)
if line:
@@ -191,6 +191,21 @@ class Controllers(object):
self._search(search)
return
+ def cmd_install_action(self, event):
+ name = self.d.txt_search.value.strip()
+ if not name:
+ msg = _('Enter package name to install')
+ app.warning(msg)
+ self.d.txt_search.set_focus()
+ return
+
+ msg = _(f'Install package: {name} ?')
+ if not app.question(msg):
+ return
+
+ self._install(name)
+ return
+
@app.run_in_thread
def _install(self, value):
self._set_state('install')
@@ -301,7 +316,6 @@ def _create_dialog():
path_python = app.paths.python
cmd = '"{}" -V'.format(path_python)
- app.msgbox(cmd)
label = app.run(cmd, True)
args = {
@@ -320,9 +334,7 @@ def _create_dialog():
dialog.center(dialog.lbl_python, y=25)
cmd = '"{}" -m pip -V'.format(path_python)
- app.msgbox(cmd)
label = app.run(cmd, True)
- app.msgbox(label)
exists_pip = True
if not label:
exists_pip = False
@@ -349,7 +361,7 @@ def _create_dialog():
'Width': 70,
'Height': BUTTON_WH,
'Step': 10,
- 'ImageURL': 'python.png',
+ 'ImageURL': 'python.svg',
'ImagePosition': 1,
}
dialog.add_control(args)
@@ -432,7 +444,7 @@ def _create_dialog():
'Width': 70,
'Height': BUTTON_WH,
'Step': 1,
- 'ImageURL': 'close.png',
+ 'ImageURL': 'close.svg',
'ImagePosition': 1,
# ~ 'PushButtonType': 2,
}
@@ -445,7 +457,7 @@ def _create_dialog():
'Width': BUTTON_WH,
'Height': BUTTON_WH,
'Step': 1,
- 'ImageURL': 'home.png',
+ 'ImageURL': 'home.svg',
'FocusOnClick': False,
'Y': 2,
}
@@ -457,7 +469,7 @@ def _create_dialog():
'Width': BUTTON_WH,
'Height': BUTTON_WH,
'Step': 1,
- 'ImageURL': 'search.png',
+ 'ImageURL': 'search.svg',
'FocusOnClick': False,
'Y': 2,
}
@@ -469,7 +481,7 @@ def _create_dialog():
'Width': BUTTON_WH,
'Height': BUTTON_WH,
'Step': 1,
- 'ImageURL': 'uninstall.png',
+ 'ImageURL': 'uninstall.svg',
'FocusOnClick': False,
'Y': 2,
}
@@ -481,7 +493,7 @@ def _create_dialog():
'Width': BUTTON_WH,
'Height': BUTTON_WH,
'Step': 1,
- 'ImageURL': 'install.png',
+ 'ImageURL': 'install.svg',
'FocusOnClick': False,
'Y': 2,
}
@@ -493,7 +505,7 @@ def _create_dialog():
'Width': BUTTON_WH,
'Height': BUTTON_WH,
'Step': 1,
- 'ImageURL': 'shell.png',
+ 'ImageURL': 'shell.svg',
'FocusOnClick': False,
'Y': 2,
}