From 563ac48a6b7ca01240628b4dbdaeb022846f9b98 Mon Sep 17 00:00:00 2001 From: Mauricio Baeza Date: Sat, 14 Sep 2019 18:19:38 -0500 Subject: [PATCH] Delete source test --- source/source/Addons.xcu | 58 - source/source/META-INF/manifest.xml | 5 - source/source/TestMacro.py | 33 - source/source/description.xml | 26 - source/source/description/desc_en.txt | 1 - source/source/description/desc_es.txt | 1 - source/source/images/icon_16.bmp | Bin 2134 -> 0 bytes source/source/images/testmacro.png | Bin 26700 -> 0 bytes source/source/pythonpath/easymacro.py | 1494 --------------------- source/source/registration/license_en.txt | 14 - source/source/registration/license_es.txt | 14 - 11 files changed, 1646 deletions(-) delete mode 100644 source/source/Addons.xcu delete mode 100644 source/source/META-INF/manifest.xml delete mode 100644 source/source/TestMacro.py delete mode 100644 source/source/description.xml delete mode 100644 source/source/description/desc_en.txt delete mode 100644 source/source/description/desc_es.txt delete mode 100644 source/source/images/icon_16.bmp delete mode 100644 source/source/images/testmacro.png delete mode 100644 source/source/pythonpath/easymacro.py delete mode 100644 source/source/registration/license_en.txt delete mode 100644 source/source/registration/license_es.txt diff --git a/source/source/Addons.xcu b/source/source/Addons.xcu deleted file mode 100644 index b726cdf..0000000 --- a/source/source/Addons.xcu +++ /dev/null @@ -1,58 +0,0 @@ - - - - - - - My Extension - Mi Extensión - - - _self - - - - - Option 1 - Opción 1 - - - service:org.myextension.test?option1 - - - _self - - - com.sun.star.sheet.SpreadsheetDocument,com.sun.star.text.TextDocument - - - %origin%/images/icon - - - - - - - - - - Option 1 - Opción 1 - - - service:org.myextension.test?option1 - - - _self - - - com.sun.star.sheet.SpreadsheetDocument,com.sun.star.text.TextDocument - - - %origin%/images/icon - - - - - - diff --git a/source/source/META-INF/manifest.xml b/source/source/META-INF/manifest.xml deleted file mode 100644 index 6c00e70..0000000 --- a/source/source/META-INF/manifest.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/source/source/TestMacro.py b/source/source/TestMacro.py deleted file mode 100644 index 79cd31f..0000000 --- a/source/source/TestMacro.py +++ /dev/null @@ -1,33 +0,0 @@ -import gettext -import uno -import unohelper -from com.sun.star.task import XJobExecutor -import easymacro as app - - -ID_EXTENSION = 'org.myextension.test' -SERVICE = ('com.sun.star.task.Job',) - - -p, *_ = app.get_info_path(__file__) -path_locales = app.join(p, 'locales') -try: - lang = gettext.translation('base', path_locales, languages=[app.LANG]) - lang.install() - _ = lang.gettext -except Exception as e: - app.error(e) - - -class TestMacro(unohelper.Base, XJobExecutor): - - def __init__(self, ctx): - self.ctx = ctx - - def trigger(self, args='pyUNO'): - print('Hello World', args) - return - - -g_ImplementationHelper = unohelper.ImplementationHelper() -g_ImplementationHelper.addImplementation(TestMacro, ID_EXTENSION, SERVICE) diff --git a/source/source/description.xml b/source/source/description.xml deleted file mode 100644 index cf73104..0000000 --- a/source/source/description.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - Test Macro - Macro de Prueba - - - - - - - - - - El Mau - El Mau - - - - - - - - diff --git a/source/source/description/desc_en.txt b/source/source/description/desc_en.txt deleted file mode 100644 index b667a4b..0000000 --- a/source/source/description/desc_en.txt +++ /dev/null @@ -1 +0,0 @@ -My great extension \ No newline at end of file diff --git a/source/source/description/desc_es.txt b/source/source/description/desc_es.txt deleted file mode 100644 index d8d8fdc..0000000 --- a/source/source/description/desc_es.txt +++ /dev/null @@ -1 +0,0 @@ -Mi gran extensión \ No newline at end of file diff --git a/source/source/images/icon_16.bmp b/source/source/images/icon_16.bmp deleted file mode 100644 index a954508e75c862a5b08b53f65013f0dd6de13bb4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2134 zcmeIyFHFNw5C-tWRaP<-4F*MmK_DxeU?vbt5M)7+1wja6X=*AF6J$YQCo3mGkbpo` zAV4e`0*RbJ!guewaxHD?{umOLug$&dy#$Y|+Tf|F3f7 zc9vAM{vOpe^_(;HEt%{&vSlt0Tj?@GV!4>dnis0ssI2 diff --git a/source/source/images/testmacro.png b/source/source/images/testmacro.png deleted file mode 100644 index 2f210eda94433623e613c91ad5675eb6631dd370..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 26700 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. - - -import ctypes -import datetime -import errno -import getpass -import logging -import os -import platform -import shlex -import subprocess -import sys -import tempfile -import threading -import time -import zipfile - -from datetime import datetime -from functools import wraps -from pathlib import Path, PurePath -from pprint import pprint -from subprocess import PIPE - -import uno -import unohelper -from com.sun.star.beans import PropertyValue -from com.sun.star.awt import MessageBoxButtons as MSG_BUTTONS -from com.sun.star.awt.MessageBoxResults import YES -from com.sun.star.awt.PosSize import POSSIZE, SIZE -from com.sun.star.awt import Size, Point -from com.sun.star.datatransfer import XTransferable, DataFlavor -from com.sun.star.table.CellContentType import EMPTY, VALUE, TEXT, FORMULA - -from com.sun.star.text.TextContentAnchorType import AS_CHARACTER - -from com.sun.star.lang import XEventListener -from com.sun.star.awt import XActionListener -from com.sun.star.awt import XMouseListener - - -MSG_LANG = { - 'es': { - 'OK': 'Aceptar', - 'Cancel': 'Cancelar', - 'Select file': 'Seleccionar archivo', - } -} - - -FILE_NAME_DEBUG = 'zaz-debug.log' -LOG_FORMAT = '%(asctime)s - %(levelname)s - %(message)s' -LOG_DATE = '%d/%m/%Y %H:%M:%S' -LEVEL_ERROR = logging.getLevelName(logging.ERROR) -LEVEL_DEBUG = logging.getLevelName(logging.DEBUG) -LEVEL_INFO = logging.getLevelName(logging.INFO) -logging.addLevelName(logging.ERROR, f'\033[1;41m{LEVEL_ERROR}\033[1;0m') -logging.addLevelName(logging.DEBUG, f'\x1b[33m{LEVEL_DEBUG}\033[1;0m') -logging.addLevelName(logging.INFO, f'\x1b[32m{LEVEL_INFO}\033[1;0m') -logging.basicConfig(level=logging.DEBUG, format=LOG_FORMAT, datefmt=LOG_DATE) -log = logging.getLogger(__name__) - - -OS = platform.system() -USER = getpass.getuser() -PC = platform.node() -DESKTOP = os.environ.get('DESKTOP_SESSION', '') -INFO_DEBUG = '{}\n\n{}\n\n{}'.format(sys.version, platform.platform(), '\n'.join(sys.path)) - -IS_WIN = OS == 'Windows' -LOG_NAME = 'ZAZ' -CLIPBOARD_FORMAT_TEXT = 'text/plain;charset=utf-16' - -CALC = 'calc' -WRITER = 'writer' -OBJ_CELL = 'ScCellObj' -OBJ_RANGE = 'ScCellRangeObj' -OBJ_RANGES = 'ScCellRangesObj' -OBJ_TYPE_RANGES = (OBJ_CELL, OBJ_RANGE, OBJ_RANGES) - - -CTX = uno.getComponentContext() -SM = CTX.getServiceManager() - - -def create_instance(name, with_context=False): - if with_context: - instance = SM.createInstanceWithContext(name, CTX) - else: - instance = SM.createInstance(name) - return instance - - -def _get_config(key, node_name): - name = 'com.sun.star.configuration.ConfigurationProvider' - service = 'com.sun.star.configuration.ConfigurationAccess' - cp = create_instance(name, True) - node = PropertyValue(Name='nodepath', Value=node_name) - try: - ca = cp.createInstanceWithArguments(service, (node,)) - if ca and (ca.hasByName(key)): - data = ca.getPropertyValue(key) - return data - except Exception as e: - log.error(e) - return '' - - -LANGUAGE = _get_config('ooLocale', 'org.openoffice.Setup/L10N/') -LANG = LANGUAGE.split('-')[0] -NAME = TITLE = _get_config('ooName', 'org.openoffice.Setup/Product') -VERSION = _get_config('ooSetupVersion', 'org.openoffice.Setup/Product') - - -def mri(obj): - m = create_instance('mytools.Mri') - if m is None: - msg = 'Extension MRI not found' - error(msg) - return - - m.inspect(obj) - return - - -def catch_exception(f): - @wraps(f) - def func(*args, **kwargs): - try: - return f(*args, **kwargs) - except Exception as e: - log.error(f.__name__, exc_info=True) - return func - - -class LogWin(object): - - def __init__(self, doc): - self.doc = doc - - def write(self, info): - text = self.doc.Text - cursor = text.createTextCursor() - cursor.gotoEnd(False) - text.insertString(cursor, str(info), 0) - return - - -def info(data): - log.info(data) - return - - -def debug(info): - if IS_WIN: - # ~ app = LOApp(self.ctx, self.sm, self.desktop, self.toolkit) - # ~ doc = app.getDoc(FILE_NAME_DEBUG) - # ~ if not doc: - # ~ doc = app.newDoc(WRITER) - # ~ out = OutputDoc(doc) - # ~ sys.stdout = out - pprint(info) - return - - log.debug(info) - return - - -def error(info): - log.error(info) - return - - -def save_log(path, data): - with open(path, 'a') as out: - out.write('{} -{}- '.format(str(datetime.now())[:19], LOG_NAME)) - pprint(data, stream=out) - return - - -def run_in_thread(fn): - def run(*k, **kw): - t = threading.Thread(target=fn, args=k, kwargs=kw) - t.start() - return t - return run - - -def _(msg): - L = LANGUAGE.split('-')[0] - if L == 'en': - return msg - - if not L in MSG_LANG: - return msg - - return MSG_LANG[L][msg] - - -def msgbox(message, title=TITLE, buttons=MSG_BUTTONS.BUTTONS_OK, type_msg='infobox'): - """ Create message box - type_msg: infobox, warningbox, errorbox, querybox, messbox - http://api.libreoffice.org/docs/idl/ref/interfacecom_1_1sun_1_1star_1_1awt_1_1XMessageBoxFactory.html - """ - toolkit = create_instance('com.sun.star.awt.Toolkit') - parent = toolkit.getDesktopWindow() - mb = toolkit.createMessageBox(parent, type_msg, buttons, title, str(message)) - return mb.execute() - - -def question(message, title=TITLE): - res = msgbox(message, title, MSG_BUTTONS.BUTTONS_YES_NO, 'querybox') - return res == YES - - -def warning(message, title=TITLE): - return msgbox(message, title, type_msg='warningbox') - - -def errorbox(message, title=TITLE): - return msgbox(message, title, type_msg='errorbox') - - -def get_desktop(): - return create_instance('com.sun.star.frame.Desktop', True) - - -def get_dispatch(): - return create_instance('com.sun.star.frame.DispatchHelper') - - -def get_temp_file(): - return tempfile.NamedTemporaryFile() - - -def _path_url(path): - if path.startswith('file://'): - return path - return uno.systemPathToFileUrl(path) - - -def _path_system(path): - if path.startswith('file://'): - return os.path.abspath(uno.fileUrlToSystemPath(path)) - return path - - -def exists_app(name): - try: - dn = subprocess.DEVNULL - subprocess.Popen([name, ''], stdout=dn, stderr=dn).terminate() - except OSError as e: - if e.errno == errno.ENOENT: - return False - return True - - -def exists(path): - return Path(path).exists() - - -def get_type_doc(obj): - services = { - 'calc': 'com.sun.star.sheet.SpreadsheetDocument', - 'writer': 'com.sun.star.text.TextDocument', - 'impress': 'com.sun.star.presentation.PresentationDocument', - 'draw': 'com.sun.star.drawing.DrawingDocument', - 'base': 'com.sun.star.sdb.OfficeDatabaseDocument', - 'math': 'com.sun.star.formula.FormulaProperties', - 'basic': 'com.sun.star.script.BasicIDE', - } - for k, v in services.items(): - if obj.supportsService(v): - return k - return '' - - -def _properties(values): - p = [PropertyValue(Name=n, Value=v) for n, v in values.items()] - return tuple(p) - - -# ~ Custom classes - - -class LODocument(object): - - def __init__(self, obj): - self._obj = obj - self._init_values() - - def _init_values(self): - self._type_doc = get_type_doc(self.obj) - self._cc = self.obj.getCurrentController() - return - - @property - def obj(self): - return self._obj - - @property - def type(self): - return self._type_doc - - @property - def title(self): - return self.obj.getTitle() - - @property - def frame(self): - return self._cc.getFrame() - - @property - def is_saved(self): - return self.obj.hasLocation() - - @property - def is_modified(self): - return self.obj.isModified() - - @property - def is_read_only(self): - return self.obj.isReadOnly() - - @property - def path(self): - return _path_system(self.obj.getURL()) - - @property - def visible(self): - w = self._cc.getFrame().getContainerWindow() - return w.Visible - @visible.setter - def visible(self, value): - w = self._cc.getFrame().getContainerWindow() - w.setVisible(value) - - @property - def zoom(self): - return self._cc.ZoomValue - @zoom.setter - def zoom(self, value): - self._cc.ZoomValue = value - - def create_instance(self, name): - obj = self.obj.createInstance(name) - return obj - - def save(self, path='', **kwargs): - opt = _properties(kwargs) - if path: - self._obj.storeAsURL(_path_url(path), opt) - else: - self._obj.store() - return True - - def close(self): - self.obj.close(True) - return - - def focus(self): - w = self._cc.getFrame().getComponentWindow() - w.setFocus() - return - - def paste(self): - sc = create_instance('com.sun.star.datatransfer.clipboard.SystemClipboard') - transferable = sc.getContents() - self._cc.insertTransferable(transferable) - return self.obj.getCurrentSelection() - - -class LOCalc(LODocument): - - def __init__(self, obj): - super().__init__(obj) - - @property - def obj(self): - return self._obj - - @property - def active(self): - return LOCalcSheet(self._cc.getActiveSheet(), self) - - @property - def selection(self): - sel = self.obj.getCurrentSelection() - if sel.ImplementationName in OBJ_TYPE_RANGES: - sel = LOCellRange(sel, self) - return sel - - def get_cell(self, index=None): - """ - index is str 'A1' - index is tuple (row, col) - """ - if index is None: - cell = self.selection.first - else: - cell = LOCellRange(self.active[index].obj, self) - return cell - - def select(self, rango): - r = rango - if hasattr(rango, 'obj'): - r = rango.obj - elif isinstance(rango, str): - r = self.get_cell(rango).obj - self._cc.select(r) - return - - -class LOCalcSheet(object): - - def __init__(self, obj, doc): - self._obj = obj - self._doc = doc - self._init_values() - - def __getitem__(self, index): - return LOCellRange(self.obj[index], self.doc) - - def _init_values(self): - return - - @property - def obj(self): - return self._obj - - @property - def doc(self): - return self._doc - - -class LOWriter(LODocument): - - def __init__(self, obj): - super().__init__(obj) - - @property - def obj(self): - return self._obj - - @property - def string(self): - return self._obj.getText().String - - @property - def text(self): - return self._obj.getText() - - @property - def cursor(self): - return self.text.createTextCursor() - - @property - def selection(self): - sel = self._cc.getSelection() - return LOTextRange(sel[0]) - - def insert_content(self, cursor, data, replace=False): - self.text.insertTextContent(cursor, data, replace) - return - - # ~ tt = doc.createInstance('com.sun.star.text.TextTable') - # ~ tt.initialize(5, 2) - - # ~ f = doc.createInstance('com.sun.star.text.TextFrame') - # ~ f.setSize(Size(10000, 500)) - - def insert_image(self, path, **kwargs): - cursor = kwargs.get('cursor', self.selection.cursor.getEnd()) - w = kwargs.get('width', 1000) - h = kwargs.get('Height', 1000) - image = self.create_instance('com.sun.star.text.GraphicObject') - image.GraphicURL = _path_url(path) - image.AnchorType = AS_CHARACTER - image.Width = w - image.Height = h - self.insert_content(cursor, image) - return - - -class LOTextRange(object): - - def __init__(self, obj): - self._obj = obj - - @property - def obj(self): - return self._obj - - @property - def string(self): - return self.obj.String - - @property - def text(self): - return self.obj.getText() - - @property - def cursor(self): - return self.text.createTextCursorByRange(self.obj) - - -class LOBase(LODocument): - - def __init__(self, obj): - super().__init__(obj) - - -class LODrawImpress(LODocument): - - def __init__(self, obj): - super().__init__(obj) - - @property - def draw_page(self): - return self._cc.getCurrentPage() - - @catch_exception - def insert_image(self, path, **kwargs): - w = kwargs.get('width', 3000) - h = kwargs.get('Height', 1000) - x = kwargs.get('X', 1000) - y = kwargs.get('Y', 1000) - - image = self.create_instance('com.sun.star.drawing.GraphicObjectShape') - image.GraphicURL = _path_url(path) - image.Size = Size(w, h) - image.Position = Point(x, y) - self.draw_page.add(image) - return - - -class LOImpress(LODrawImpress): - - def __init__(self, obj): - super().__init__(obj) - - -class LODraw(LODrawImpress): - - def __init__(self, obj): - super().__init__(obj) - - -class LOMath(LODocument): - - def __init__(self, obj): - super().__init__(obj) - - -class LOBasicIde(LODocument): - - def __init__(self, obj): - super().__init__(obj) - - @property - def selection(self): - sel = self._cc.getSelection() - return sel - - -class LOCellRange(object): - - def __init__(self, obj, doc): - self._obj = obj - self._doc = doc - self._init_values() - - def __enter__(self): - return self - - def __exit__(self, *args): - pass - - def __getitem__(self, index): - return LOCellRange(self.obj[index], self.doc) - - def _init_values(self): - self._type_obj = self.obj.ImplementationName - self._type_content = EMPTY - - if self._type_obj == OBJ_CELL: - self._type_content = self.obj.getType() - return - - @property - def obj(self): - return self._obj - - @property - def doc(self): - return self._doc - - @property - def type(self): - return self._type_obj - - @property - def type_content(self): - return self._type_content - - @property - def first(self): - if self.type == OBJ_RANGES: - obj = LOCellRange(self.obj[0][0,0], self.doc) - else: - obj = LOCellRange(self.obj[0,0], self.doc) - return obj - - @property - def value(self): - v = None - if self._type_content == VALUE: - v = self.obj.getValue() - elif self._type_content == TEXT: - v = self.obj.getString() - elif self._type_content == FORMULA: - v = self.obj.getFormula() - return v - @value.setter - def value(self, data): - if isinstance(data, str): - if data.startswith('='): - self.obj.setFormula(data) - else: - self.obj.setString(data) - elif isinstance(data, (int, float)): - self.obj.setValue(data) - - @property - def data(self): - return self.obj.getDataArray() - @data.setter - def data(self, values): - if isinstance(values, list): - values = tuple(values) - self.obj.setDataArray(values) - - def offset(self, col=1, row=0): - a = self.address - col = a.Column + col - row = a.Row + row - return LOCellRange(self.sheet[row,col], self.doc) - - @property - def sheet(self): - return self.obj.Spreadsheet - - @property - def draw_page(self): - return self.sheet.getDrawPage() - - @property - def name(self): - return self.obj.AbsoluteName - - @property - def address(self): - if self._type_obj == OBJ_CELL: - a = self.obj.getCellAddress() - elif self._type_obj == OBJ_RANGE: - a = self.obj.getRangeAddress() - else: - a = self.obj.getRangeAddressesAsString() - return a - - @property - def current_region(self): - cursor = self.sheet.createCursorByRange(self.obj[0,0]) - cursor.collapseToCurrentRegion() - return LOCellRange(self.sheet[cursor.AbsoluteName], self.doc) - - def insert_image(self, path, **kwargs): - s = self.obj.Size - w = kwargs.get('width', s.Width) - h = kwargs.get('Height', s.Height) - img = self.doc.create_instance('com.sun.star.drawing.GraphicObjectShape') - img.GraphicURL = _path_url(path) - self.draw_page.add(img) - img.Anchor = self.obj - img.setSize(Size(w, h)) - return - - def select(self): - self.doc._cc.select(self.obj) - return - - -class EventsListenerBase(unohelper.Base, XEventListener): - - def __init__(self, controller, window=None): - self._controller = controller - self._window = window - - def disposing(self, event): - self._controller = None - if not self._window is None: - self._window.setMenuBar(None) - - -class EventsButton(EventsListenerBase, XActionListener): - - def __init__(self, controller): - super().__init__(controller) - - def actionPerformed(self, event): - name = event.Source.Model.Name - event_name = '{}_action'.format(name) - if hasattr(self._controller, event_name): - getattr(self._controller, event_name)(event) - return - - -class EventsMouse(EventsListenerBase, XMouseListener): - - def __init__(self, controller): - super().__init__(controller) - - def mousePressed(self, event): - name = event.Source.Model.Name - event_name = '{}_click'.format(name) - if event.ClickCount == 2: - event_name = '{}_double_click'.format(name) - if hasattr(self._controller, event_name): - getattr(self._controller, event_name)(event) - return - - def mouseReleased(self, event): - pass - - def mouseEntered(self, event): - pass - - def mouseExited(self, event): - pass - - -class UnoBaseObject(object): - - def __init__(self, obj): - self._obj = obj - self._model = self.obj.Model - self._rules = {} - - @property - def obj(self): - return self._obj - - @property - def model(self): - return self._model - - @property - def name(self): - return self.model.Name - - @property - def parent(self): - return self.obj.getContext() - - @property - def x(self): - return self.model.PositionX - @x.setter - def x(self, value): - self.model.PositionX = value - - @property - def y(self): - return self.model.PositionY - @y.setter - def y(self, value): - self.model.PositionY = value - - @property - def width(self): - return self._model.Width - @width.setter - def width(self, value): - self._model.Width = value - - @property - def height(self): - return self._model.Height - @height.setter - def height(self, value): - self._model.Height = value - - @property - def tag(self): - return self.model.Tag - @tag.setter - def tag(self, value): - self.model.Tag = value - - @property - def step(self): - return self.model.Step - @step.setter - def step(self, value): - self.model.Step = value - - @property - def rules(self): - return self._rules - @rules.setter - def rules(self, value): - self._rules = value - - def set_focus(self): - self.obj.setFocus() - return - - def center(self, horizontal=True, vertical=False): - p = self.parent.Model - w = p.Width - h = p.Height - if horizontal: - x = w / 2 - self.width / 2 - self.x = x - if vertical: - y = h / 2 - self.height / 2 - self.y = y - return - - def move(self, origin, x=0, y=5): - w = 0 - h = 0 - if x: - w = origin.width - if y: - h = origin.height - x = origin.x + x + w - y = origin.y + y + h - self.x = x - self.y = y - return - - -class UnoLabel(UnoBaseObject): - - def __init__(self, obj): - super().__init__(obj) - - @property - def value(self): - return self.model.Label - @value.setter - def value(self, value): - self.model.Label = value - - -class UnoButton(UnoBaseObject): - - def __init__(self, obj): - super().__init__(obj) - # ~ self._set_icon() - - def _set_icon(self): - icon_name = self.tag.strip() - if icon_name: - path_icon = _file_url('{}/img/{}'.format(CURRENT_PATH, icon_name)) - self._model.ImageURL = path_icon - if self.value: - self._model.ImageAlign = 0 - return - - @property - def value(self): - return self.model.Label - @value.setter - def value(self, value): - self.model.Label = value - - -class UnoText(UnoBaseObject): - - def __init__(self, obj): - super().__init__(obj) - - @property - def value(self): - return self.model.Text - @value.setter - def value(self, value): - self.model.Text = value - - def validate(self): - - return - - -class UnoListBox(UnoBaseObject): - - def __init__(self, obj): - super().__init__(obj) - self._data = [] - - @property - def value(self): - return self.obj.SelectedItem - - @property - def data(self): - return self._data - @data.setter - def data(self, values): - self._data = list(sorted(values)) - self.model.StringItemList = self.data - return - - -class LODialog(object): - - def __init__(self, properties): - self._obj = self._create(properties) - self._init_values() - - def _init_values(self): - self._model = self._obj.Model - self._init_controls() - self._events = None - # ~ self._response = None - return - - def _create(self, properties): - path = properties.pop('Path', '') - if path: - dp = create_instance('com.sun.star.awt.DialogProvider2', True) - return dp.createDialog(_path_url(path)) - - if 'Library' in properties: - location = properties['Location'] - if location == 'user': - location = 'application' - dp = create_instance('com.sun.star.awt.DialogProvider2', True) - path = 'vnd.sun.star.script:{}.{}?location={}'.format( - properties['Library'], properties['Name'], location) - return dp.createDialog(path) - - dlg = create_instance('com.sun.star.awt.UnoControlDialog', True) - model = create_instance('com.sun.star.awt.UnoControlDialogModel', True) - toolkit = create_instance('com.sun.star.awt.Toolkit', True) - set_properties(model, properties) - dlg.setModel(model) - dlg.setVisible(False) - dlg.createPeer(toolkit, None) - - return dlg - - def _init_controls(self): - - return - - @property - def obj(self): - return self._obj - - @property - def model(self): - return self._model - - @property - def events(self): - return self._events - @events.setter - def events(self, controllers): - self._events = controllers - self._connect_listeners() - - def _connect_listeners(self): - - return - - def _add_listeners(self, control): - if self.events is None: - return - - listeners = { - 'addActionListener': EventsButton, - 'addMouseListener': EventsMouse, - } - for key, value in listeners.items(): - if hasattr(control.obj, key): - getattr(control.obj, key)(listeners[key](self.events)) - return - - def open(self): - return self.obj.execute() - - def close(self, value=0): - return self.obj.endDialog(value) - - def _get_control_model(self, control): - services = { - 'label': 'com.sun.star.awt.UnoControlFixedTextModel', - 'button': 'com.sun.star.awt.UnoControlButtonModel', - 'text': 'com.sun.star.awt.UnoControlEditModel', - 'listbox': 'com.sun.star.awt.UnoControlListBoxModel', - 'link': 'com.sun.star.awt.UnoControlFixedHyperlinkModel', - 'roadmap': 'com.sun.star.awt.UnoControlRoadmapModel', - 'image': 'com.sun.star.awt.UnoControlImageControlModel', - 'groupbox': 'com.sun.star.awt.UnoControlGroupBoxModel', - 'radio': 'com.sun.star.awt.UnoControlRadioButtonModel', - 'tree': 'com.sun.star.awt.tree.TreeControlModel', - 'grid': 'com.sun.star.awt.grid.UnoControlGridModel', - } - return services[control] - - def _get_custom_class(self, tipo, obj): - classes = { - 'label': UnoLabel, - 'button': UnoButton, - 'text': UnoText, - 'listbox': UnoListBox, - # ~ 'link': UnoLink, - # ~ 'tab': UnoTab, - # ~ 'roadmap': UnoRoadmap, - # ~ 'image': UnoImage, - # ~ 'radio': UnoRadio, - # ~ 'groupbox': UnoGroupBox, - # ~ 'tree': UnoTree, - # ~ 'grid': UnoGrid, - } - return classes[tipo](obj) - - @catch_exception - def add_control(self, properties): - tipo = properties.pop('Type').lower() - model = self.model.createInstance(self._get_control_model(tipo)) - set_properties(model, properties) - name = properties['Name'] - self.model.insertByName(name, model) - control = self._get_custom_class(tipo, self.obj.getControl(name)) - self._add_listeners(control) - setattr(self, name, control) - return - - -# ~ Python >= 3.7 -# ~ def __getattr__(name): - - -def _get_class_doc(obj): - classes = { - 'calc': LOCalc, - 'writer': LOWriter, - 'base': LOBase, - 'impress': LOImpress, - 'draw': LODraw, - 'math': LOMath, - 'basic': LOBasicIde, - } - type_doc = get_type_doc(obj) - return classes[type_doc](obj) - - -def get_document(): - doc = None - desktop = get_desktop() - try: - doc = _get_class_doc(desktop.getCurrentComponent()) - except Exception as e: - log.error(e) - return doc - - -def get_selection(): - return get_document().selection - - -def get_cell(*args): - if args: - index = args - if len(index) == 1: - index = args[0] - cell = get_document().get_cell(index) - else: - cell = get_selection().first - return cell - - -def active_cell(): - return get_cell() - - -def create_dialog(properties): - return LODialog(properties) - - -def set_properties(model, properties): - if 'X' in properties: - properties['PositionX'] = properties.pop('X') - if 'Y' in properties: - properties['PositionY'] = properties.pop('Y') - keys = tuple(properties.keys()) - values = tuple(properties.values()) - model.setPropertyValues(keys, values) - return - - -def get_file(filters=(), multiple=False): - file_picker = create_instance('com.sun.star.ui.dialogs.FilePicker') - file_picker.setTitle(_('Select file')) - file_picker.setMultiSelectionMode(multiple) - - if filters: - file_picker.setCurrentFilter(filters[0][0]) - for f in filters: - file_picker.appendFilter(f[0], f[1]) - - if file_picker.execute(): - if multiple: - return [_path_system(f) for f in file_picker.getSelectedFiles()] - return _path_system(file_picker.getSelectedFiles()[0]) - - return '' - - -def get_info_path(path): - path, filename = os.path.split(path) - name, extension = os.path.splitext(filename) - return (path, filename, name, extension) - - -def inputbox(message, default='', title=TITLE): - - class ControllersInput(object): - - def __init__(self, dlg): - self.d = dlg - - def cmd_ok_action(self, event): - self.d.close(1) - return - - args = { - 'Title': title, - 'Width': 200, - 'Height': 80, - } - dlg = LODialog(args) - dlg.events = ControllersInput(dlg) - - args = { - 'Type': 'Label', - 'Name': 'lbl_msg', - 'Label': message, - 'Width': 140, - 'Height': 50, - 'X': 5, - 'Y': 5, - 'MultiLine': True, - 'Border': 1, - } - dlg.add_control(args) - - args = { - 'Type': 'Text', - 'Name': 'txt_value', - 'Text': default, - 'Width': 190, - 'Height': 15, - } - dlg.add_control(args) - dlg.txt_value.move(dlg.lbl_msg) - - args = { - 'Type': 'button', - 'Name': 'cmd_ok', - 'Label': _('OK'), - 'Width': 40, - 'Height': 15, - 'DefaultButton': True, - 'PushButtonType': 1, - } - dlg.add_control(args) - dlg.cmd_ok.move(dlg.lbl_msg, 10, 0) - - args = { - 'Type': 'button', - 'Name': 'cmd_cancel', - 'Label': _('Cancel'), - 'Width': 40, - 'Height': 15, - 'PushButtonType': 2, - } - dlg.add_control(args) - dlg.cmd_cancel.move(dlg.cmd_ok) - - if dlg.open(): - return dlg.txt_value.value - - return '' - - -def new_doc(type_doc=CALC): - path = 'private:factory/s{}'.format(type_doc) - doc = get_desktop().loadComponentFromURL(path, '_default', 0, ()) - return _get_class_doc(doc) - - -def open_doc(path, **kwargs): - """ Open document in path - Usually options: - Hidden: True or False - AsTemplate: True or False - ReadOnly: True or False - Password: super_secret - MacroExecutionMode: 4 = Activate macros - Preview: True or False - - http://api.libreoffice.org/docs/idl/ref/interfacecom_1_1sun_1_1star_1_1frame_1_1XComponentLoader.html - http://api.libreoffice.org/docs/idl/ref/servicecom_1_1sun_1_1star_1_1document_1_1MediaDescriptor.html - """ - path = _path_url(path) - opt = _properties(kwargs) - doc = get_desktop().loadComponentFromURL(path, '_blank', 0, opt) - if doc is None: - return - - return _get_class_doc(doc) - - -def open_file(path): - if IS_WIN: - os.startfile(path) - else: - subprocess.Popen(['xdg-open', path]) - return - - -def join(*paths): - return os.path.join(*paths) - - -def is_dir(path): - return Path(path).is_dir() - - -def is_file(path): - return Path(path).is_file() - - -def get_file_size(path): - return Path(path).stat().st_size - - -def is_created(path): - return is_file(path) and bool(get_file_size(path)) - - -def replace_ext(path, ext): - path, _, name, _ = get_info_path(path) - return '{}/{}.{}'.format(path, name, ext) - - -def zip_names(path): - with zipfile.ZipFile(path) as z: - names = z.namelist() - return names - - -def run(command, wait=False): - # ~ debug(command) - # ~ debug(shlex.split(command)) - try: - if wait: - # ~ p = subprocess.Popen(shlex.split(command), stdout=subprocess.PIPE) - # ~ p.wait() - result = subprocess.check_output(command, shell=True) - else: - p = subprocess.Popen(shlex.split(command), stdin=None, - stdout=None, stderr=None, close_fds=True) - result, er = p.communicate() - except subprocess.CalledProcessError as e: - msg = ("run [ERROR]: output = %s, error code = %s\n" - % (e.output, e.returncode)) - error(msg) - return False - - if result is None: - return True - - return result.decode() - - -def _zippwd(source, target, pwd): - if IS_WIN: - return False - if not exists_app('zip'): - return False - - cmd = 'zip' - opt = '-j ' - args = "{} --password {} ".format(cmd, pwd) - - if isinstance(source, (tuple, list)): - if not target: - return False - args += opt + target + ' ' + ' '.join(source) - else: - if is_file(source) and not target: - target = replace_ext(source, 'zip') - elif is_dir(source) and not target: - target = join(PurePath(source).parent, - '{}.zip'.format(PurePath(source).name)) - opt = '-r ' - args += opt + target + ' ' + source - - result = run(args, True) - if not result: - return False - - return is_created(target) - - -def zip(source, target='', mode='w', pwd=''): - if pwd: - return _zippwd(source, target, pwd) - - if isinstance(source, (tuple, list)): - if not target: - return False - - with zipfile.ZipFile(target, mode, compression=zipfile.ZIP_DEFLATED) as z: - for path in source: - _, name, _, _ = get_info_path(path) - z.write(path, name) - - return is_created(target) - - if is_file(source): - if not target: - target = replace_ext(source, 'zip') - z = zipfile.ZipFile(target, mode, compression=zipfile.ZIP_DEFLATED) - _, name, _, _ = get_info_path(source) - z.write(source, name) - z.close() - return is_created(target) - - if not target: - target = join( - PurePath(source).parent, - '{}.zip'.format(PurePath(source).name)) - z = zipfile.ZipFile(target, mode, compression=zipfile.ZIP_DEFLATED) - root_len = len(os.path.abspath(source)) - for root, dirs, files in os.walk(source): - relative = os.path.abspath(root)[root_len:] - for f in files: - fullpath = join(root, f) - file_name = join(relative, f) - z.write(fullpath, file_name) - z.close() - - return is_created(target) - - -def unzip(source, path='', members=None, pwd=None): - if not path: - path, _, _, _ = get_info_path(source) - with zipfile.ZipFile(source) as z: - if not pwd is None: - pwd = pwd.encode() - if isinstance(members, str): - members = (members,) - z.extractall(path, members=members, pwd=pwd) - return True - - -def merge_zip(target, zips): - try: - with zipfile.ZipFile(target, 'w', compression=zipfile.ZIP_DEFLATED) as t: - for path in zips: - with zipfile.ZipFile(path, compression=zipfile.ZIP_DEFLATED) as s: - for name in s.namelist(): - t.writestr(name, s.open(name).read()) - except Exception as e: - error(e) - return False - - return True - - -def kill(path): - p = Path(path) - if p.is_file(): - try: - p.unlink() - except: - pass - elif p.is_dir(): - p.rmdir() - return - - -def get_size_screen(): - if IS_WIN: - user32 = ctypes.windll.user32 - res = '{}x{}'.format(user32.GetSystemMetrics(0), user32.GetSystemMetrics(1)) - else: - args = 'xrandr | grep "*" | cut -d " " -f4' - res = run(args, True) - return res.strip() - - -def get_clipboard(): - df = None - text = '' - sc = create_instance('com.sun.star.datatransfer.clipboard.SystemClipboard') - transferable = sc.getContents() - data = transferable.getTransferDataFlavors() - for df in data: - if df.MimeType == CLIPBOARD_FORMAT_TEXT: - break - if df: - text = transferable.getTransferData(df) - return text - - -class TextTransferable(unohelper.Base, XTransferable): - """Keep clipboard data and provide them.""" - - def __init__(self, text): - df = DataFlavor() - df.MimeType = CLIPBOARD_FORMAT_TEXT - df.HumanPresentableName = "encoded text utf-16" - self.flavors = [df] - self.data = [text] - - def getTransferData(self, flavor): - if not flavor: - return - for i, f in enumerate(self.flavors): - if flavor.MimeType == f.MimeType: - return self.data[i] - return - - def getTransferDataFlavors(self): - return tuple(self.flavors) - - def isDataFlavorSupported(self, flavor): - if not flavor: - return False - mtype = flavor.MimeType - for f in self.flavors: - if mtype == f.MimeType: - return True - return False - - -def set_clipboard(text): - ts = TextTransferable(text) - sc = create_instance('com.sun.star.datatransfer.clipboard.SystemClipboard') - sc.setContents(ts, None) - return - - -def copy(doc=None): - if doc is None: - doc = get_document() - if hasattr(doc, 'frame'): - frame = doc.frame - else: - frame = doc.getCurrentController().getFrame() - dispatch = get_dispatch() - dispatch.executeDispatch(frame, '.uno:Copy', '', 0, ()) - return - - -def get_epoch(): - now = datetime.datetime.now() - return int(time.mktime(now.timetuple())) diff --git a/source/source/registration/license_en.txt b/source/source/registration/license_en.txt deleted file mode 100644 index 3e7ef0e..0000000 --- a/source/source/registration/license_en.txt +++ /dev/null @@ -1,14 +0,0 @@ -This file is part of TestMacro. - - TestMacro is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - TestMacro is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with TestMacro. If not, see . diff --git a/source/source/registration/license_es.txt b/source/source/registration/license_es.txt deleted file mode 100644 index 3e7ef0e..0000000 --- a/source/source/registration/license_es.txt +++ /dev/null @@ -1,14 +0,0 @@ -This file is part of TestMacro. - - TestMacro is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - TestMacro is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with TestMacro. If not, see .