From 152801582be2d492c36ae988133e1060d5b6a5c1 Mon Sep 17 00:00:00 2001 From: prrvchr Date: Sat, 30 Aug 2025 21:10:41 +0200 Subject: [PATCH 01/11] git subrepo pull uno subrepo: subdir: "uno" merged: "c7979458" upstream: origin: "https://github.com/prrvchr/uno.git" branch: "main" commit: "c7979458" git-subrepo: version: "0.4.9" origin: "https://github.com/ingydotnet/git-subrepo.git" commit: "4f60dd7" --- uno/.gitrepo | 4 ++-- uno/dialog/jdbc/OptionDialog_en_US.properties | 2 +- uno/dialog/jdbc/OptionDialog_fr_FR.properties | 2 +- uno/lib/java/UnoHelper/UnoHelper.jar | Bin 37519 -> 23913 bytes uno/lib/uno/jdbcdriver/configuration.py | 2 +- uno/lib/uno/oauth20/configuration.py | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/uno/.gitrepo b/uno/.gitrepo index c8385146..82ae153e 100644 --- a/uno/.gitrepo +++ b/uno/.gitrepo @@ -6,7 +6,7 @@ [subrepo] remote = https://github.com/prrvchr/uno.git branch = main - commit = 66e9aea6994add573be9c1556b90c87449543a11 - parent = d90335647633a232bccd30cb806b65cec5ec58ec + commit = c7979458ef44a2fdf33dbb4b1822a6ee63381e55 + parent = 0e645fe4eb92d50b98b8d62733f0e1a775761b98 method = merge cmdver = 0.4.9 diff --git a/uno/dialog/jdbc/OptionDialog_en_US.properties b/uno/dialog/jdbc/OptionDialog_en_US.properties index 9071f3ee..1f687e6e 100644 --- a/uno/dialog/jdbc/OptionDialog_en_US.properties +++ b/uno/dialog/jdbc/OptionDialog_en_US.properties @@ -10,7 +10,7 @@ OptionDialog.OptionButton2.HelpText=The delivered SDBC API level will be: com.su OptionDialog.OptionButton2.Label=css.sdbcx OptionDialog.OptionButton3.HelpText=The delivered SDBC API level will be: com.sun.star.sdb.* OptionDialog.OptionButton3.Label=css.sdb -OptionDialog.Label2.HelpText=Use javax.sql.rowset.CachedRowSet to provide ResultSet +OptionDialog.Label2.HelpText=Use javax.sql.rowset.CachedRowSet to provide ResultSet. Using Bookmark is a prerequisite. OptionDialog.Label2.Label=Use CachedRowSet: OptionDialog.OptionButton4.HelpText=Never use CachedRowSet (not recommended) OptionDialog.OptionButton4.Label=Never diff --git a/uno/dialog/jdbc/OptionDialog_fr_FR.properties b/uno/dialog/jdbc/OptionDialog_fr_FR.properties index 1c9de951..77eb2f81 100644 --- a/uno/dialog/jdbc/OptionDialog_fr_FR.properties +++ b/uno/dialog/jdbc/OptionDialog_fr_FR.properties @@ -10,7 +10,7 @@ OptionDialog.OptionButton2.HelpText=Le niveau de l'API SDBC d OptionDialog.OptionButton2.Label=css.sdbcx OptionDialog.OptionButton3.HelpText=Le niveau de l'API SDBC dιlivrι sera: com.sun.star.sdb.* OptionDialog.OptionButton3.Label=css.sdb -OptionDialog.Label2.HelpText=Utilise javax.sql.rowset.CachedRowSet pour fournir les ResutSets +OptionDialog.Label2.HelpText=Utilise javax.sql.rowset.CachedRowSet pour fournir les ResutSets. L'utilisation de signets (ie: Bookmark) est une condition prιalable. OptionDialog.Label2.Label=Utiliser CachedRowSet: OptionDialog.OptionButton4.HelpText=Ne jamais utiliser les CachedRowSet (non conseillι) OptionDialog.OptionButton4.Label=Jamais diff --git a/uno/lib/java/UnoHelper/UnoHelper.jar b/uno/lib/java/UnoHelper/UnoHelper.jar index 977a88f5517b91b3f54d61c9a981ed796e69d2ce..41d3d66de7bdee9c15715ae8baacdfd5d8cbd863 100644 GIT binary patch delta 22208 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

b#n|@wUlB z^Sul1^Oqv6K6vNGmGgn_JjZRJhjy8MT`rkdG}${MEZI9Nu8_=cdDUaeZaI-dMN>i2 z(??UqN!;pF#VTzv%prs;a@PS@tTJL*!kJ!$;J+xqoLW#0pa0r~R} z#lCi4J)}A7c6xa$_lOZfdaPp5_@rVbtbRs*j`=CIT)=+SV0%Mfj!+W#mt3=rMPtn( z1PQ<4+Eu9*qR@_yQ67x3FmUS_)UeK54#Y2%9Y;V1z~6XjuHh zj;IRltg%H!F+Jg;58JY4MlL{}R$waccOE0wFD3VKFG!D_?tfBAdiLSfUR&P>w0Gw% zf67`Q9*g9)RBp$C%ITJ_X5G|~L>q}FQ~F@mGz1?m7ezb(iGT|RXuz*&Z+Pz!{29f(F4 z3JWP`++82{UR;&uw}(nv>WY%~A>h&dr9{@81Q$k(KmxLOM-p{MLKaq{9`+(qJS>_9 zhgvlIV?#s%oPB9BToL_hac^l{)`w}bR_(sbIx7IdQhXxFj+klt|>vG%R`ufWg zPD{OxFus%i4R*lSPOK=xK|*2#{x`&bi0~^O5MW4u9lXibbSb|GNg*zV#7ZO~P^2tQ zoM%s~7Sl)+KVrHAtg$-Qm(6z7`VM#BcyP z330INuX~CNVT-KsgnK}RA!S;5n}}ON6F#_e^Aqm%nAYOA3(hba7S2K6W2@RrI0+(3yj6j5D{FC7@it4p;=#>Vh)-nRcg3lc=|2nTUi7f4aGO0B7jmA?I zk9vNZehgegY8!dB63ysL>PZBl)Lf#~p3}yQJbV#~hH^nMZUtrGn35taVV7KMR>(aL z(+8i7_b%d>nvgdaMyF5a=Q%sx_;)|0THKz_d!!yyW$Z)#co$1X)i47C$04$2UW_+R zP<4m#wN~R8c;&g-d!$};MfWIp4)L0{lpbW*FR-GLsb?4c#O6)@8Nt(2o0i!(TH$3V zwiNU33G^NYq9{&w%8v}!EsOl8gL*5)KD|PJEg)K9Wl0H{`H-TmrhRt)b3ep#P|!he zOM|S)=K0zq8XbTeW{nN{fe96nf2Q=x;P`YpqKrk+e%;r|P0*DxHoc6h$3?gfuC|TOA zq%JS2*@zDj#4ff)s{rQknz;e~<6*8Nqfhd7*-W zaI)~}(}+y;;^DFYIIkc0Lut3p1t?ubQfiVeW6)zE>n12a=$VCN^?ktK7J{EKarS7c zb?}j?FUMGx;BljuT-dBuLJLiKVltm2C`|!Z#An=GGQ4WXwD~+%sBP3n=S8C)#dGN< z+Zsw3*#eG!u?9CU68uiqdw9-g!dzPoFBvyRkQXnge=M`a1}$a03|}=jgLVA^($cj0 zvLS~<9Qz4CzvN{od@z>frK|X`10_&Lzp$h9=>#g{ozVLL9n(VA3GC=dm=)>VJaUDQmL+Bs z)24;JvlwT$msYRmUAh?R$QBgJTjny^PZ$CrK#Eup&R$?J@C2eS{6 z7{6B;q3+Demk4-DewXO#oH~`RTSVmjG1B*N?U^@-igh%BmT*ZgY{~As;+8b>bKtl; z`wxyJj^5Of)Baz-JFmAW)hXc*RGOGSRGLS~BuM{bqo(x7%Kit6iW4V6_H?9FKBJ{PvZj5YB2u&eYxx_F!~c)P4d;)A1VH-# z>M7Ukx0XRhLZWzRKleW-3xYo;O?|?Y2^cQjZ>-MW|71A-5&tCmBOar{|9>_7y?P_@ zkE!wLA5(5TJKgVB{(B7gw<$Nue}s{7AiCc}!r$MU_n#-;==~A?A|xi$Qbj}meGmKL N3_w9bS~UKB^?yu%Y7YPa delta 35316 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 Date: Mon, 1 Sep 2025 16:45:26 +0200 Subject: [PATCH 02/11] new version 1.3.3 --- README.md | 14 +++++++++----- README_fr.md | 14 +++++++++----- source/SQLiteOOo/description.xml | 2 +- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 203be12b..df9b01a5 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ **The use of this software subjects you to our [Terms Of Use][4].** -# version [1.3.2][5] +# version [1.3.3][5] ## Introduction: @@ -64,7 +64,7 @@ If necessary, rename it before installing it. - [![jdbcDriverOOo logo][18]][19] Install **[jdbcDriverOOo.oxt][20]** extension [![Version][21]][20] - This extension is necessary to use SQLite version 3.42.0.0 with all its features. + This extension is required to use the latest version of SQLite with all its features. - ![SQLiteOOo logo][22] Install **[SQLiteOOo.oxt][23]** extension [![Version][24]][23] @@ -246,7 +246,11 @@ ___ - Requires the **jdbcDriverOOo extension at least version 1.5.4**. -### What remains to be done for version 1.3.2: +### What has been done for version 1.3.3: + +- Requires the **jdbcDriverOOo extension at least version 1.5.7**. + +### What remains to be done for version 1.3.3: - Add new language for internationalization... @@ -256,7 +260,7 @@ ___ [2]: [3]: [4]: -[5]: +[5]: [6]: [7]: [8]: @@ -274,7 +278,7 @@ ___ [21]: [22]: [23]: -[24]: +[24]: [25]: [26]: [27]: diff --git a/README_fr.md b/README_fr.md index 465af79d..53f5d593 100644 --- a/README_fr.md +++ b/README_fr.md @@ -29,7 +29,7 @@ **L'utilisation de ce logiciel vous soumet Γ  nos [Conditions d'utilisation][4].** -# version [1.3.2][5] +# version [1.3.3][5] ## Introduction: @@ -64,7 +64,7 @@ Si nΓ©cessaire, renommez-le avant de l'installer. - [![jdbcDriverOOo logo][18]][19] Installer l'extension **[jdbcDriverOOo.oxt][20]** [![Version][21]][20] - Cette extension est nΓ©cessaire pour utiliser SQLite version 3.42.0.0 avec toutes ses fonctionnalitΓ©s. + Cette extension est nΓ©cessaire pour utiliser la derniΓ¨re version de SQLite avec toutes ses fonctionnalitΓ©s. - ![SQLiteOOo logo][22] Installer l'extension **[SQLiteOOo.oxt][23]** [![Version][24]][23] @@ -246,7 +246,11 @@ ___ - NΓ©cessite l'extension **jdbcDriverOOo en version 1.5.4 minimum**. -### Que reste-t-il Γ  faire pour la version 1.3.2: +### Ce qui a Γ©tΓ© fait pour la version 1.3.3: + +- NΓ©cessite l'extension **jdbcDriverOOo en version 1.5.7 minimum**. + +### Que reste-t-il Γ  faire pour la version 1.3.3: - Ajouter de nouvelles langue pour l'internationalisation... @@ -256,7 +260,7 @@ ___ [2]: [3]: [4]: -[5]: +[5]: [6]: [7]: [8]: @@ -274,7 +278,7 @@ ___ [21]: [22]: [23]: -[24]: +[24]: [25]: [26]: [27]: diff --git a/source/SQLiteOOo/description.xml b/source/SQLiteOOo/description.xml index 92a907e4..04ec0c9e 100644 --- a/source/SQLiteOOo/description.xml +++ b/source/SQLiteOOo/description.xml @@ -28,7 +28,7 @@ xmlns:d="http://openoffice.org/extensions/description/2006" xmlns:l="http://libreoffice.org/extensions/description/2011" xmlns:xlink="http://www.w3.org/1999/xlink"> - + From e7bb738fc1e5672b0857c07baded8f2bed221831 Mon Sep 17 00:00:00 2001 From: prrvchr Date: Mon, 1 Sep 2025 16:45:54 +0200 Subject: [PATCH 03/11] git subrepo pull uno subrepo: subdir: "uno" merged: "7fb79f2a" upstream: origin: "https://github.com/prrvchr/uno.git" branch: "main" commit: "7fb79f2a" git-subrepo: version: "0.4.9" origin: "https://github.com/ingydotnet/git-subrepo.git" commit: "4f60dd7" --- uno/.gitrepo | 4 +- uno/lib/uno/jdbcdriver/__init__.py | 3 ++ uno/lib/uno/jdbcdriver/configuration.py | 8 ++++ uno/lib/uno/jdbcdriver/jdbctool.py | 44 +++++++++++++++++++ .../uno/options/embedded/optionsmanager.py | 3 +- uno/lib/uno/options/embedded/optionsmodel.py | 5 +++ uno/lib/uno/options/jdbc/optionmanager.py | 7 +-- uno/lib/uno/options/jdbc/optionmodel.py | 19 +++++--- uno/lib/uno/options/jdbc/optionview.py | 9 ++-- 9 files changed, 86 insertions(+), 16 deletions(-) create mode 100644 uno/lib/uno/jdbcdriver/jdbctool.py diff --git a/uno/.gitrepo b/uno/.gitrepo index 82ae153e..4df1510b 100644 --- a/uno/.gitrepo +++ b/uno/.gitrepo @@ -6,7 +6,7 @@ [subrepo] remote = https://github.com/prrvchr/uno.git branch = main - commit = c7979458ef44a2fdf33dbb4b1822a6ee63381e55 - parent = 0e645fe4eb92d50b98b8d62733f0e1a775761b98 + commit = 7fb79f2a7187737cbbbfc4db37f33a30f7811f5c + parent = 93716213db508f1c21dea778116cf8a269dcb5dd method = merge cmdver = 0.4.9 diff --git a/uno/lib/uno/jdbcdriver/__init__.py b/uno/lib/uno/jdbcdriver/__init__.py index 30efb5d2..badde637 100644 --- a/uno/lib/uno/jdbcdriver/__init__.py +++ b/uno/lib/uno/jdbcdriver/__init__.py @@ -27,8 +27,11 @@ β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β• """ +from .jdbctool import isInstrumented + from .configuration import g_extension from .configuration import g_identifier from .configuration import g_service from .configuration import g_services from .configuration import g_version + diff --git a/uno/lib/uno/jdbcdriver/configuration.py b/uno/lib/uno/jdbcdriver/configuration.py index 93b85d7c..e1d66e12 100644 --- a/uno/lib/uno/jdbcdriver/configuration.py +++ b/uno/lib/uno/jdbcdriver/configuration.py @@ -35,3 +35,11 @@ 'io.github.prrvchr.jdbcdriver.sdbcx.Driver', 'io.github.prrvchr.jdbcdriver.sdb.Driver') g_version = '1.5.7' +g_instrumented = 'SupportsInstrumentationAgent' + +# jdbcDriverOOo special configuration +g_resource = 'resource' +g_basename = 'Driver' +g_defaultlog = 'Driver' +g_errorlog = 'jdbcDriverError' + diff --git a/uno/lib/uno/jdbcdriver/jdbctool.py b/uno/lib/uno/jdbcdriver/jdbctool.py new file mode 100644 index 00000000..2af2ccdf --- /dev/null +++ b/uno/lib/uno/jdbcdriver/jdbctool.py @@ -0,0 +1,44 @@ +#! +# -*- coding: utf-8 -*- + +""" +╔════════════════════════════════════════════════════════════════════════════════════╗ +β•‘ β•‘ +β•‘ Copyright (c) 2020-25 https://prrvchr.github.io β•‘ +β•‘ β•‘ +β•‘ Permission is hereby granted, free of charge, to any person obtaining β•‘ +β•‘ a copy of this software and associated documentation files (the "Software"), β•‘ +β•‘ to deal in the Software without restriction, including without limitation β•‘ +β•‘ the rights to use, copy, modify, merge, publish, distribute, sublicense, β•‘ +β•‘ and/or sell copies of the Software, and to permit persons to whom the Software β•‘ +β•‘ is furnished to do so, subject to the following conditions: β•‘ +β•‘ β•‘ +β•‘ The above copyright notice and this permission notice shall be included in β•‘ +β•‘ all copies or substantial portions of the Software. β•‘ +β•‘ β•‘ +β•‘ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, β•‘ +β•‘ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES β•‘ +β•‘ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. β•‘ +β•‘ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY β•‘ +β•‘ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, β•‘ +β•‘ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE β•‘ +β•‘ OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. β•‘ +β•‘ β•‘ +β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β• +""" + +from ..unotool import createService +from ..unotool import getPropertyValueSet + +from .configuration import g_instrumented +from .configuration import g_service + + +def isInstrumented(ctx, url): + support = False + driver = createService(ctx, g_service) + for info in driver.getPropertyInfo(url, getPropertyValueSet({g_instrumented: True})): + if (info.Name == g_instrumented): + support = info.Value != 'false' + return support + diff --git a/uno/lib/uno/options/embedded/optionsmanager.py b/uno/lib/uno/options/embedded/optionsmanager.py index 669ad65c..f5374b80 100644 --- a/uno/lib/uno/options/embedded/optionsmanager.py +++ b/uno/lib/uno/options/embedded/optionsmanager.py @@ -41,7 +41,8 @@ class OptionsManager(): def __init__(self, ctx, logger, window, options, url=None): self._model = OptionsModel(ctx, logger, url) - self._manager = OptionManager(ctx, window, options, OptionsManager._restart, 20, g_defaultlog) + instrumented = self._model.isInstrumented() + self._manager = OptionManager(ctx, window, options, instrumented, OptionsManager._restart, 20, g_defaultlog) self._view = OptionsView(window) window.addEventListener(OptionsListener(self)) self._manager.initView() diff --git a/uno/lib/uno/options/embedded/optionsmodel.py b/uno/lib/uno/options/embedded/optionsmodel.py index 049914fb..51b14d45 100644 --- a/uno/lib/uno/options/embedded/optionsmodel.py +++ b/uno/lib/uno/options/embedded/optionsmodel.py @@ -35,6 +35,7 @@ from ..unotool import createService from ..jdbcdriver import g_service as jdbc +from ..jdbcdriver import isInstrumented from ..configuration import g_service as embedded @@ -45,10 +46,14 @@ class OptionsModel(): def __init__(self, ctx, logger, url=None): self._ctx = ctx self._url = url + self._instrumented = isInstrumented(ctx, 'xdbc:jdbc') self._logger = logger self._logger.logprb(INFO, 'OptionsModel', '__init__', 401) # OptionsModel getter methods + def isInstrumented(self): + return self._instrumented + def getDriverVersion(self, apilevel): driver = None version = 'N/A' diff --git a/uno/lib/uno/options/jdbc/optionmanager.py b/uno/lib/uno/options/jdbc/optionmanager.py index 2f8f4d35..1f88ce7c 100644 --- a/uno/lib/uno/options/jdbc/optionmanager.py +++ b/uno/lib/uno/options/jdbc/optionmanager.py @@ -37,9 +37,9 @@ class OptionManager(): - def __init__(self, ctx, window, options, restart, offset, logger, *loggers): + def __init__(self, ctx, window, options, instrumented, restart, offset, logger, *loggers): self._logmanager = LogManager(ctx, window, 'requirements.txt', logger, *loggers) - self._model = OptionModel(ctx) + self._model = OptionModel(ctx, instrumented) self._view = OptionWindow(ctx, window, WindowHandler(self), options, restart, offset) # OptionManager setter methods @@ -79,5 +79,6 @@ def setSystemTable(self, state): # OptionManager private methods def _initView(self): - self._view.initView(*self._model.getViewData()) + instrumented = self._model.isInstrumented() + self._view.initView(instrumented, *self._model.getViewData()) diff --git a/uno/lib/uno/options/jdbc/optionmodel.py b/uno/lib/uno/options/jdbc/optionmodel.py index 680827cf..c0354523 100644 --- a/uno/lib/uno/options/jdbc/optionmodel.py +++ b/uno/lib/uno/options/jdbc/optionmodel.py @@ -42,14 +42,18 @@ class OptionModel(): - def __init__(self, ctx): + def __init__(self, ctx, instrumented): self._rebootkeys = ('ApiLevel', 'CachedRowSet') configkeys = ('ShowSystemTable', ) self._keys = self._rebootkeys + configkeys self._config = getConfiguration(ctx, g_identifier, True) self._settings = self._getSettings() + self._instrumented = instrumented # OptionModel getter methods + def isInstrumented(self): + return self._instrumented + def getConfigApiLevel(self): return self._config.getByName('ApiLevel') @@ -63,7 +67,7 @@ def getViewData(self): # OptionModel setter methods def setApiLevel(self, level): self._settings['ApiLevel'] = level - return self._isRowSetEnabled(level) + return self._instrumented and self._isRowSetEnabled(level) def setCachedRowSet(self, level): self._settings['CachedRowSet'] = level @@ -74,11 +78,12 @@ def setSystemTable(self, state): def saveSetting(self): reboot = False for key in self._keys: - value = self._settings.get(key) - if value != self._config.getByName(key): - self._config.replaceByName(key, value) - if key in self._rebootkeys: - reboot = True + if key != 'CachedRowSet' or self._instrumented: + value = self._settings.get(key) + if value != self._config.getByName(key): + self._config.replaceByName(key, value) + if key in self._rebootkeys: + reboot = True if self._config.hasPendingChanges(): self._config.commitChanges() return reboot diff --git a/uno/lib/uno/options/jdbc/optionview.py b/uno/lib/uno/options/jdbc/optionview.py index 866dbdb9..61b8e19d 100644 --- a/uno/lib/uno/options/jdbc/optionview.py +++ b/uno/lib/uno/options/jdbc/optionview.py @@ -47,10 +47,13 @@ def __init__(self, ctx, window, handler, options, restart, offset): def dispose(self): self._window.dispose() - def initView(self, level, crs, system, enabled): + def initView(self, instrumented, level, crs, system, enabled): self._getApiLevel(level).State = 1 - self._getCachedRowSet(crs).State = 1 - self.enableCachedRowSet(enabled) + if instrumented: + self._getCachedRowSet(crs).State = 1 + else: + self._getCachedRowSet(0).State = 1 + self.enableCachedRowSet(instrumented and enabled) self._getSytemTable().State = int(system) def enableCachedRowSet(self, enabled): From 2c9da9a6f27432d2deca1cc3fb2408fff7a40911 Mon Sep 17 00:00:00 2001 From: prrvchr Date: Wed, 15 Oct 2025 15:45:05 +0200 Subject: [PATCH 04/11] git subrepo pull uno subrepo: subdir: "uno" merged: "d781bba3" upstream: origin: "https://github.com/prrvchr/uno.git" branch: "main" commit: "d781bba3" git-subrepo: version: "0.4.9" origin: "https://github.com/ingydotnet/git-subrepo.git" commit: "4f60dd7" --- uno/.gitrepo | 4 +- uno/dialog/card/OptionDialog.xdl | 44 ++ uno/dialog/card/OptionsDialog.xdl | 14 +- uno/dialog/card/OptionsDialog_en_US.default | 0 .../card/OptionsDialog_en_US.properties | 8 + .../card/OptionsDialog_fr_FR.properties | 8 + uno/dialog/dialog.dtd | 426 ++++++++++++++++++ uno/dialog/embedded/OptionsDialog.xdl | 28 ++ .../embedded/OptionsDialog_en_US.properties | 6 + .../embedded/OptionsDialog_fr_FR.properties | 6 + uno/dialog/grid/GridWindow.xdl | 3 +- uno/dialog/grid/GridWindow_en_US.properties | 2 +- uno/dialog/grid/GridWindow_fr_FR.properties | 2 +- uno/dialog/jdbc/OptionDialog.xdl | 4 +- uno/dialog/jdbc/OptionDialog_en_US.properties | 3 +- uno/dialog/jdbc/OptionDialog_fr_FR.properties | 3 +- uno/dialog/logger/LogDialog.xdl | 4 +- uno/dialog/logger/LogDialog_en_US.properties | 1 + uno/dialog/logger/LogDialog_fr_FR.properties | 1 + uno/dialog/logger/LogWindow.xdl | 6 +- uno/dialog/logger/LogWindow_en_US.properties | 2 - uno/dialog/logger/LogWindow_fr_FR.properties | 2 - uno/dialog/ucb/OptionsDialog.xdl | 23 +- uno/dialog/wizard/Wizard.xdl | 18 +- uno/dialog/wizard/WizardTop.xdl | 47 ++ uno/dialog/wizard/WizardTop_en_US.default | 1 + uno/dialog/wizard/WizardTop_en_US.properties | 1 + uno/dialog/wizard/WizardTop_fr_FR.properties | 1 + uno/dialog/wizard/Wizard_en_US.properties | 3 +- uno/dialog/wizard/Wizard_fr_FR.properties | 3 +- uno/lib/uno/component-schema.dtd | 142 ++++++ uno/lib/uno/component-update.dtd | 108 +++++ uno/lib/uno/dbtool/__init__.py | 1 + uno/lib/uno/dbtool/dbtool.py | 8 + uno/lib/uno/grid/__init__.py | 3 +- uno/lib/uno/grid/gridhandler.py | 37 +- uno/lib/uno/grid/gridmanager.py | 53 ++- uno/lib/uno/grid/gridmodel.py | 3 +- uno/lib/uno/grid/gridview.py | 4 +- uno/lib/uno/jdbcdriver/configuration.py | 2 +- uno/lib/uno/jdbcdriver/jdbctool.py | 9 +- uno/lib/uno/library.dtd | 33 ++ uno/lib/uno/logger/dialog/logmodel.py | 4 +- uno/lib/uno/logger/logcontroller.py | 28 +- uno/lib/uno/logger/loghandler.py | 4 + uno/lib/uno/module.dtd | 24 + uno/lib/uno/oauth20/configuration.py | 2 +- uno/lib/uno/options/addressbook/__init__.py | 1 + .../uno/options/addressbook/optionshandler.py | 55 +++ .../uno/options/addressbook/optionsmanager.py | 30 +- .../uno/options/addressbook/optionsmodel.py | 13 +- .../uno/options/addressbook/optionsview.py | 20 +- uno/lib/uno/options/embedded/options | 1 + .../uno/options/embedded/optionsmanager.py | 14 +- uno/lib/uno/options/embedded/optionsmodel.py | 7 + uno/lib/uno/options/embedded/optionsview.py | 23 +- uno/lib/uno/options/jdbc/__init__.py | 3 +- .../{optionhandler.py => optionshandler.py} | 0 .../{optionmanager.py => optionsmanager.py} | 24 +- .../jdbc/{optionmodel.py => optionsmodel.py} | 18 +- .../jdbc/{optionview.py => optionsview.py} | 25 +- uno/lib/uno/options/ucb/optionsmanager.py | 14 +- uno/lib/uno/options/ucb/optionsmodel.py | 24 +- uno/lib/uno/options/ucb/optionsview.py | 46 +- uno/lib/uno/unotool/__init__.py | 16 + uno/lib/uno/unotool/statusindicator.py | 94 ++++ uno/lib/uno/unotool/taskevent.py | 57 +++ uno/lib/uno/unotool/unotool.py | 111 ++++- uno/lib/uno/wizard/__init__.py | 1 + uno/lib/uno/wizard/wizard.py | 97 +++- uno/lib/uno/wizard/wizardhandler.py | 56 +++ uno/lib/uno/wizard/wizardmodel.py | 11 +- uno/lib/uno/wizard/wizardview.py | 83 +++- uno/rdb/idl/com/sun/star/task/XTaskEvent.idl | 49 ++ 74 files changed, 1791 insertions(+), 241 deletions(-) create mode 100644 uno/dialog/card/OptionDialog.xdl create mode 100644 uno/dialog/card/OptionsDialog_en_US.default create mode 100644 uno/dialog/card/OptionsDialog_en_US.properties create mode 100644 uno/dialog/card/OptionsDialog_fr_FR.properties create mode 100644 uno/dialog/dialog.dtd create mode 100644 uno/dialog/wizard/WizardTop.xdl create mode 120000 uno/dialog/wizard/WizardTop_en_US.default create mode 120000 uno/dialog/wizard/WizardTop_en_US.properties create mode 120000 uno/dialog/wizard/WizardTop_fr_FR.properties create mode 100644 uno/lib/uno/component-schema.dtd create mode 100644 uno/lib/uno/component-update.dtd create mode 100644 uno/lib/uno/library.dtd create mode 100644 uno/lib/uno/module.dtd create mode 100644 uno/lib/uno/options/addressbook/optionshandler.py create mode 120000 uno/lib/uno/options/embedded/options rename uno/lib/uno/options/jdbc/{optionhandler.py => optionshandler.py} (100%) rename uno/lib/uno/options/jdbc/{optionmanager.py => optionsmanager.py} (85%) rename uno/lib/uno/options/jdbc/{optionmodel.py => optionsmodel.py} (91%) rename uno/lib/uno/options/jdbc/{optionview.py => optionsview.py} (84%) create mode 100644 uno/lib/uno/unotool/statusindicator.py create mode 100644 uno/lib/uno/unotool/taskevent.py create mode 100644 uno/rdb/idl/com/sun/star/task/XTaskEvent.idl diff --git a/uno/.gitrepo b/uno/.gitrepo index 4df1510b..ce475c4e 100644 --- a/uno/.gitrepo +++ b/uno/.gitrepo @@ -6,7 +6,7 @@ [subrepo] remote = https://github.com/prrvchr/uno.git branch = main - commit = 7fb79f2a7187737cbbbfc4db37f33a30f7811f5c - parent = 93716213db508f1c21dea778116cf8a269dcb5dd + commit = d781bba36bafa8338fb6914fea7d155b1369dea8 + parent = e7bb738fc1e5672b0857c07baded8f2bed221831 method = merge cmdver = 0.4.9 diff --git a/uno/dialog/card/OptionDialog.xdl b/uno/dialog/card/OptionDialog.xdl new file mode 100644 index 00000000..71b21e9d --- /dev/null +++ b/uno/dialog/card/OptionDialog.xdl @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/uno/dialog/card/OptionsDialog.xdl b/uno/dialog/card/OptionsDialog.xdl index 5da50845..573f84f8 100644 --- a/uno/dialog/card/OptionsDialog.xdl +++ b/uno/dialog/card/OptionsDialog.xdl @@ -24,20 +24,14 @@ β•‘ β•‘ β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β• --> + - - - - - - - - - - + + + diff --git a/uno/dialog/card/OptionsDialog_en_US.default b/uno/dialog/card/OptionsDialog_en_US.default new file mode 100644 index 00000000..e69de29b diff --git a/uno/dialog/card/OptionsDialog_en_US.properties b/uno/dialog/card/OptionsDialog_en_US.properties new file mode 100644 index 00000000..f656e782 --- /dev/null +++ b/uno/dialog/card/OptionsDialog_en_US.properties @@ -0,0 +1,8 @@ +OptionsDialog.HelpText= +OptionsDialog.Title= +OptionsDialog.Label1.HelpText= +OptionsDialog.Label1.Label=The changes will take effect after restarting LibreOffice... +OptionsDialog.Hyperlink1.HelpText= +OptionsDialog.Hyperlink1.Label=You must install the Java Instrumentation Agent to use jdbcDriverOOO... +OptionsDialog.Hyperlink1.Url=https://prrvchr.github.io/jdbcDriverOOo/#how-to-install-java-instrumentation + diff --git a/uno/dialog/card/OptionsDialog_fr_FR.properties b/uno/dialog/card/OptionsDialog_fr_FR.properties new file mode 100644 index 00000000..9fcdca9f --- /dev/null +++ b/uno/dialog/card/OptionsDialog_fr_FR.properties @@ -0,0 +1,8 @@ +OptionsDialog.HelpText= +OptionsDialog.Title= +OptionsDialog.Label1.HelpText= +OptionsDialog.Label1.Label=Les modifications prendront effet apr\u00e8s le red\u00e9marrage de LibreOffice... +OptionsDialog.Hyperlink1.HelpText= +OptionsDialog.Hyperlink1.Label=Veuillez installer l'instrumentation Java pour utiliser jdbcDriverOOO... +OptionsDialog.Hyperlink1.Url=https://prrvchr.github.io/jdbcDriverOOo/README_fr#comment-installer-linstrumentation-java + diff --git a/uno/dialog/dialog.dtd b/uno/dialog/dialog.dtd new file mode 100644 index 00000000..7290b8d2 --- /dev/null +++ b/uno/dialog/dialog.dtd @@ -0,0 +1,426 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/uno/dialog/embedded/OptionsDialog.xdl b/uno/dialog/embedded/OptionsDialog.xdl index 3800155d..0f861bb4 100644 --- a/uno/dialog/embedded/OptionsDialog.xdl +++ b/uno/dialog/embedded/OptionsDialog.xdl @@ -1,4 +1,29 @@ + @@ -7,5 +32,8 @@ + + + diff --git a/uno/dialog/embedded/OptionsDialog_en_US.properties b/uno/dialog/embedded/OptionsDialog_en_US.properties index c078b893..18ef2e71 100644 --- a/uno/dialog/embedded/OptionsDialog_en_US.properties +++ b/uno/dialog/embedded/OptionsDialog_en_US.properties @@ -4,3 +4,9 @@ OptionsDialog.Label1.HelpText= OptionsDialog.Label1.Label=Driver version: OptionsDialog.Label2.HelpText= OptionsDialog.Label2.Label= +OptionsDialog.Label3.HelpText=You have made changes. Restart LibreOffice for the changes to take effect +OptionsDialog.Label3.Label=Changes will take effect after restarting LibreOffice... +OptionsDialog.Hyperlink1.HelpText= +OptionsDialog.Hyperlink1.Label=You must install the Java Instrumentation Agent to use jdbcDriverOOO... +OptionsDialog.Hyperlink1.Url=https://prrvchr.github.io/jdbcDriverOOo/#how-to-install-java-instrumentation + diff --git a/uno/dialog/embedded/OptionsDialog_fr_FR.properties b/uno/dialog/embedded/OptionsDialog_fr_FR.properties index 1b4de163..cc8866fc 100644 --- a/uno/dialog/embedded/OptionsDialog_fr_FR.properties +++ b/uno/dialog/embedded/OptionsDialog_fr_FR.properties @@ -4,3 +4,9 @@ OptionsDialog.Label1.HelpText= OptionsDialog.Label1.Label=Version du pilote: OptionsDialog.Label2.HelpText= OptionsDialog.Label2.Label= +OptionsDialog.Label3.HelpText=Vous avez effectuι des modifications. Redιmarrez LibreOffice pour que les modifications soient prises en compte +OptionsDialog.Label3.Label=Les modifications prendront effet aprθs le redιmarrage de LibreOffice... +OptionsDialog.Hyperlink1.HelpText= +OptionsDialog.Hyperlink1.Label=Veuillez installer l'instrumentation Java pour utiliser jdbcDriverOOO... +OptionsDialog.Hyperlink1.Url=https://prrvchr.github.io/jdbcDriverOOo/README_fr#comment-installer-linstrumentation-java + diff --git a/uno/dialog/grid/GridWindow.xdl b/uno/dialog/grid/GridWindow.xdl index c1bb2d88..f0a2bba6 100644 --- a/uno/dialog/grid/GridWindow.xdl +++ b/uno/dialog/grid/GridWindow.xdl @@ -31,8 +31,9 @@ - + + diff --git a/uno/dialog/grid/GridWindow_en_US.properties b/uno/dialog/grid/GridWindow_en_US.properties index 9c3c60b4..68ffd080 100644 --- a/uno/dialog/grid/GridWindow_en_US.properties +++ b/uno/dialog/grid/GridWindow_en_US.properties @@ -5,4 +5,4 @@ GridWindow.CommandButton1.Label=+ GridWindow.Label1.HelpText=Columns to display GridWindow.Label1.Label=Show columns: GridWindow.ListBox1.HelpText=Define the name of the columns to display -GridWindow.ListBox1.Text= + diff --git a/uno/dialog/grid/GridWindow_fr_FR.properties b/uno/dialog/grid/GridWindow_fr_FR.properties index 5c5089cc..a676b2d2 100644 --- a/uno/dialog/grid/GridWindow_fr_FR.properties +++ b/uno/dialog/grid/GridWindow_fr_FR.properties @@ -5,4 +5,4 @@ GridWindow.CommandButton1.Label=+ GridWindow.Label1.HelpText=Colonnes \u00e0 afficher GridWindow.Label1.Label=Afficher les colonnes: GridWindow.ListBox1.HelpText=D\u00e9finir le nom des colonnes \u00e0 afficher -GridWindow.ListBox1.Text= + diff --git a/uno/dialog/jdbc/OptionDialog.xdl b/uno/dialog/jdbc/OptionDialog.xdl index 14f97dc9..ee070c9f 100644 --- a/uno/dialog/jdbc/OptionDialog.xdl +++ b/uno/dialog/jdbc/OptionDialog.xdl @@ -25,7 +25,7 @@ β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β• --> - + @@ -58,6 +58,6 @@ - + diff --git a/uno/dialog/jdbc/OptionDialog_en_US.properties b/uno/dialog/jdbc/OptionDialog_en_US.properties index 1f687e6e..b30760d0 100644 --- a/uno/dialog/jdbc/OptionDialog_en_US.properties +++ b/uno/dialog/jdbc/OptionDialog_en_US.properties @@ -20,5 +20,4 @@ OptionDialog.OptionButton6.HelpText=Always use CachedRowSet OptionDialog.OptionButton6.Label=Always OptionDialog.CheckBox1.HelpText=Show system tables in the Base browser OptionDialog.CheckBox1.Label=View system tables -OptionDialog.Label3.HelpText=You have made changes. Restart LibreOffice for the changes to take effect -OptionDialog.Label3.Label=Changes will take effect after restarting LibreOffice... + diff --git a/uno/dialog/jdbc/OptionDialog_fr_FR.properties b/uno/dialog/jdbc/OptionDialog_fr_FR.properties index 77eb2f81..7a6b34e7 100644 --- a/uno/dialog/jdbc/OptionDialog_fr_FR.properties +++ b/uno/dialog/jdbc/OptionDialog_fr_FR.properties @@ -20,5 +20,4 @@ OptionDialog.OptionButton6.HelpText=Toujours utiliser les CachedRowSet OptionDialog.OptionButton6.Label=Toujours OptionDialog.CheckBox1.HelpText=Afficher les tables systθmes dans le navigateur de Base OptionDialog.CheckBox1.Label=Voir les tables systθme -OptionDialog.Label3.HelpText=Vous avez effectuι des modifications. Redιmarrez LibreOffice pour que les modifications soient prises en compte -OptionDialog.Label3.Label=Les modifications prendront effet aprθs le redιmarrage de LibreOffice... + diff --git a/uno/dialog/logger/LogDialog.xdl b/uno/dialog/logger/LogDialog.xdl index 1d7040b1..978fd93e 100644 --- a/uno/dialog/logger/LogDialog.xdl +++ b/uno/dialog/logger/LogDialog.xdl @@ -24,12 +24,14 @@ β•‘ β•‘ β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β• --> + - + + diff --git a/uno/dialog/logger/LogDialog_en_US.properties b/uno/dialog/logger/LogDialog_en_US.properties index 03fb7f46..cfd2480d 100644 --- a/uno/dialog/logger/LogDialog_en_US.properties +++ b/uno/dialog/logger/LogDialog_en_US.properties @@ -6,3 +6,4 @@ LogDialog.CommandButton1.HelpText= LogDialog.CommandButton1.Label=System info LogDialog.CommandButton2.HelpText= LogDialog.CommandButton2.Label=Close + diff --git a/uno/dialog/logger/LogDialog_fr_FR.properties b/uno/dialog/logger/LogDialog_fr_FR.properties index 793e16bb..f4e09a06 100644 --- a/uno/dialog/logger/LogDialog_fr_FR.properties +++ b/uno/dialog/logger/LogDialog_fr_FR.properties @@ -6,3 +6,4 @@ LogDialog.CommandButton1.HelpText= LogDialog.CommandButton1.Label=Info systθme LogDialog.CommandButton2.HelpText= LogDialog.CommandButton2.Label=Fermer + diff --git a/uno/dialog/logger/LogWindow.xdl b/uno/dialog/logger/LogWindow.xdl index 2508a6d6..b5d450f0 100644 --- a/uno/dialog/logger/LogWindow.xdl +++ b/uno/dialog/logger/LogWindow.xdl @@ -24,6 +24,7 @@ β•‘ β•‘ β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β• --> + @@ -31,7 +32,7 @@ - + @@ -51,7 +52,6 @@ - @@ -62,6 +62,8 @@ + + diff --git a/uno/dialog/logger/LogWindow_en_US.properties b/uno/dialog/logger/LogWindow_en_US.properties index 68ff1f72..e24f69e6 100644 --- a/uno/dialog/logger/LogWindow_en_US.properties +++ b/uno/dialog/logger/LogWindow_en_US.properties @@ -5,7 +5,6 @@ LogWindow.FixedLine1.Label=Logging options LogWindow.Label1.HelpText= LogWindow.Label1.Label=Available logs: LogWindow.ListBox1.HelpText= -LogWindow.ListBox1.Text= LogWindow.CheckBox1.HelpText= LogWindow.CheckBox1.Label=Enable log LogWindow.Label2.HelpText= @@ -19,7 +18,6 @@ LogWindow.CommandButton1.Label=View log LogWindow.Label3.HelpText= LogWindow.Label3.Label=Level: LogWindow.ListBox2.HelpText= -LogWindow.ListBox2.Text= LogWindow.ListBox2.StringItemList.0=Sever LogWindow.ListBox2.StringItemList.1=Warning LogWindow.ListBox2.StringItemList.2=Info diff --git a/uno/dialog/logger/LogWindow_fr_FR.properties b/uno/dialog/logger/LogWindow_fr_FR.properties index 68ca2564..3cb145f0 100644 --- a/uno/dialog/logger/LogWindow_fr_FR.properties +++ b/uno/dialog/logger/LogWindow_fr_FR.properties @@ -5,7 +5,6 @@ LogWindow.FixedLine1.Label=Options de journalisation LogWindow.Label1.HelpText= LogWindow.Label1.Label=Journaux disponibles: LogWindow.ListBox1.HelpText= -LogWindow.ListBox1.Text= LogWindow.CheckBox1.HelpText= LogWindow.CheckBox1.Label=Activer le journal LogWindow.Label2.HelpText= @@ -19,7 +18,6 @@ LogWindow.CommandButton1.Label=Voir journal LogWindow.Label3.HelpText= LogWindow.Label3.Label=Seuil: LogWindow.ListBox2.HelpText= -LogWindow.ListBox2.Text= LogWindow.ListBox2.StringItemList.0=Grave LogWindow.ListBox2.StringItemList.1=Alerte LogWindow.ListBox2.StringItemList.2=Info diff --git a/uno/dialog/ucb/OptionsDialog.xdl b/uno/dialog/ucb/OptionsDialog.xdl index d9a13b34..3c8b6e4a 100644 --- a/uno/dialog/ucb/OptionsDialog.xdl +++ b/uno/dialog/ucb/OptionsDialog.xdl @@ -24,6 +24,7 @@ β•‘ β•‘ β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β• --> + @@ -54,7 +55,7 @@ - + @@ -65,8 +66,8 @@ - - + + @@ -80,22 +81,24 @@ - - + + - - + + - + - + + - \ No newline at end of file + + diff --git a/uno/dialog/wizard/Wizard.xdl b/uno/dialog/wizard/Wizard.xdl index d7487129..558b7eaa 100644 --- a/uno/dialog/wizard/Wizard.xdl +++ b/uno/dialog/wizard/Wizard.xdl @@ -24,26 +24,24 @@ β•‘ β•‘ β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β• --> - - - - + + - - + - + - + - + - + + diff --git a/uno/dialog/wizard/WizardTop.xdl b/uno/dialog/wizard/WizardTop.xdl new file mode 100644 index 00000000..4754d9fe --- /dev/null +++ b/uno/dialog/wizard/WizardTop.xdl @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/uno/dialog/wizard/WizardTop_en_US.default b/uno/dialog/wizard/WizardTop_en_US.default new file mode 120000 index 00000000..3a9c45d0 --- /dev/null +++ b/uno/dialog/wizard/WizardTop_en_US.default @@ -0,0 +1 @@ +./Wizard_en_US.default \ No newline at end of file diff --git a/uno/dialog/wizard/WizardTop_en_US.properties b/uno/dialog/wizard/WizardTop_en_US.properties new file mode 120000 index 00000000..a1fe6e0e --- /dev/null +++ b/uno/dialog/wizard/WizardTop_en_US.properties @@ -0,0 +1 @@ +./Wizard_en_US.properties \ No newline at end of file diff --git a/uno/dialog/wizard/WizardTop_fr_FR.properties b/uno/dialog/wizard/WizardTop_fr_FR.properties new file mode 120000 index 00000000..887d01c3 --- /dev/null +++ b/uno/dialog/wizard/WizardTop_fr_FR.properties @@ -0,0 +1 @@ +./Wizard_fr_FR.properties \ No newline at end of file diff --git a/uno/dialog/wizard/Wizard_en_US.properties b/uno/dialog/wizard/Wizard_en_US.properties index a08f1aea..5c620869 100644 --- a/uno/dialog/wizard/Wizard_en_US.properties +++ b/uno/dialog/wizard/Wizard_en_US.properties @@ -1,8 +1,6 @@ Wizard.HelpText= Wizard.Title= Wizard.Roadmap.Text=Steps -Wizard.FixedLine1.HelpText= -Wizard.FixedLine1.Label= Wizard.CommandButton5.HelpText= Wizard.CommandButton5.Label=Help Wizard.CommandButton4.HelpText= @@ -13,3 +11,4 @@ Wizard.CommandButton2.HelpText= Wizard.CommandButton2.Label=Finish Wizard.CommandButton1.HelpText= Wizard.CommandButton1.Label=Cancel + diff --git a/uno/dialog/wizard/Wizard_fr_FR.properties b/uno/dialog/wizard/Wizard_fr_FR.properties index 4a12f9db..fc2e4bd0 100644 --- a/uno/dialog/wizard/Wizard_fr_FR.properties +++ b/uno/dialog/wizard/Wizard_fr_FR.properties @@ -1,8 +1,6 @@ Wizard.HelpText= Wizard.Title= Wizard.Roadmap.Text=\u00c9tapes -Wizard.FixedLine1.HelpText= -Wizard.FixedLine1.Label= Wizard.CommandButton5.HelpText= Wizard.CommandButton5.Label=Aide Wizard.CommandButton4.HelpText= @@ -13,3 +11,4 @@ Wizard.CommandButton2.HelpText= Wizard.CommandButton2.Label=Terminer Wizard.CommandButton1.HelpText= Wizard.CommandButton1.Label=Annuler + diff --git a/uno/lib/uno/component-schema.dtd b/uno/lib/uno/component-schema.dtd new file mode 100644 index 00000000..70bd51bf --- /dev/null +++ b/uno/lib/uno/component-schema.dtd @@ -0,0 +1,142 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/uno/lib/uno/component-update.dtd b/uno/lib/uno/component-update.dtd new file mode 100644 index 00000000..0659e412 --- /dev/null +++ b/uno/lib/uno/component-update.dtd @@ -0,0 +1,108 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/uno/lib/uno/dbtool/__init__.py b/uno/lib/uno/dbtool/__init__.py index 41dbed8b..a5ca8616 100644 --- a/uno/lib/uno/dbtool/__init__.py +++ b/uno/lib/uno/dbtool/__init__.py @@ -61,6 +61,7 @@ from .dbtool import getDateTimeFromString from .dbtool import getDateTimeToString from .dbtool import getDictFromResult +from .dbtool import getDictSequenceFromResult from .dbtool import getDriverInfos from .dbtool import getDriverPropertyInfo from .dbtool import getDriverPropertyInfos diff --git a/uno/lib/uno/dbtool/dbtool.py b/uno/lib/uno/dbtool/dbtool.py index 62b3043c..6f75a0b1 100644 --- a/uno/lib/uno/dbtool/dbtool.py +++ b/uno/lib/uno/dbtool/dbtool.py @@ -303,6 +303,14 @@ def getRowDict(result, default=None, count=None): row[name] = value return row +def getDictSequenceFromResult(result, default=None): + sequence = [] + count = result.MetaData.ColumnCount +1 + while result.next(): + data = getRowDict(result, default, count) + sequence.append(data) + return tuple(sequence) + def getObjectFromResult(result, default=None, count=None): obj = Object() if count is None: diff --git a/uno/lib/uno/grid/__init__.py b/uno/lib/uno/grid/__init__.py index 261096be..8a211532 100644 --- a/uno/lib/uno/grid/__init__.py +++ b/uno/lib/uno/grid/__init__.py @@ -31,5 +31,6 @@ from .gridmodel import GridModel -from .gridhandler import GridListener +from .gridhandler import GridDataListener +from .gridhandler import GridSelectionListener diff --git a/uno/lib/uno/grid/gridhandler.py b/uno/lib/uno/grid/gridhandler.py index 509e7491..5fd13a80 100644 --- a/uno/lib/uno/grid/gridhandler.py +++ b/uno/lib/uno/grid/gridhandler.py @@ -30,6 +30,7 @@ import unohelper from com.sun.star.awt import XContainerWindowEventHandler +from com.sun.star.awt.grid import XGridDataListener from com.sun.star.awt.grid import XGridSelectionListener import traceback @@ -60,8 +61,40 @@ def getSupportedMethodNames(self): 'SetColumn') -class GridListener(unohelper.Base, - XGridSelectionListener): +class GridDataListener(unohelper.Base, + XGridDataListener): + def __init__(self, manager): + self._manager = manager + + # XGridDataListener + def rowsInserted(self, event): + try: + print("GridDataListener.dataChanged()") + self._manager.dataGridChanged() + except Exception as e: + msg = "Error: %s" % traceback.format_exc() + print(msg) + + def rowsRemoved(self, event): + try: + print("GridDataListener.dataChanged()") + self._manager.dataGridChanged() + except Exception as e: + msg = "Error: %s" % traceback.format_exc() + print(msg) + + def dataChanged(self, event): + pass + + def rowHeadingChanged(self, event): + pass + + def disposing(self, event): + pass + + +class GridSelectionListener(unohelper.Base, + XGridSelectionListener): def __init__(self, manager, grid=1): self._manager = manager self._grid = grid diff --git a/uno/lib/uno/grid/gridmanager.py b/uno/lib/uno/grid/gridmanager.py index 2c48bf7d..64b7935c 100644 --- a/uno/lib/uno/grid/gridmanager.py +++ b/uno/lib/uno/grid/gridmanager.py @@ -37,11 +37,11 @@ from .gridhandler import WindowHandler -from ..unotool import createService -from ..unotool import getConfiguration -from ..unotool import getPropertyValue +from ...unotool import createService +from ...unotool import getConfiguration +from ...unotool import getPropertyValue -from ..configuration import g_identifier +from ...configuration import g_identifier import json from collections import OrderedDict @@ -101,10 +101,9 @@ def getSelectedRows(self): def getSelectedColumn(self, column): value = None - if self._view.hasSelectedRows() and column in self._headers: - index = tuple(self._headers.keys()).index(column) - row = self.getUnsortedIndex(self._view.getSelectedRow()) - value = self._model.getCellData(index, row) + if self._view.hasSelectedRows(): + row = self._view.getSelectedRow() + value = self._getColumnValue(row, column) return value def getSelectedIdentifier(self, identifier): @@ -113,6 +112,25 @@ def getSelectedIdentifier(self, identifier): value = self._getRowValue(identifier, self.getUnsortedIndex(self._view.getSelectedRow())) return value + def getSelectedIdentifiers(self, identifier): + values = [] + if self._view.hasSelectedRows(): + for row in self._view.getSelectedRows(): + values.append(self._getRowValue(identifier, self.getUnsortedIndex(row))) + return tuple(values) + + def getGridData(self, columns, default=None): + values = {} + for row in (range(self._model.RowCount)): + filter = self._getRowFilter(row) + for column in columns: + if column in self._headers: + value = self._getColumnValue(row, column, default) + if value: + values[filter] = value + break + return values + def getGridFilters(self): filters = [] for row in (range(self._model.RowCount)): @@ -125,6 +143,18 @@ def getSelectedStructuredFilters(self): filters.append(self._getRowStructuredFilter(row)) return tuple(filters) + def getRowPredicates(self, row): + predicates = [] + for identifier in self._indexes: + predicates.append(self._getRowValue(identifier, row)) + return tuple(predicates) + + def _getColumnValue(self, row, column, value=None): + if column in self._headers: + keys = tuple(self._headers.keys()) + value = self._model.getCellData(keys.index(column), self.getUnsortedIndex(row)) + return value + def _getRowFilter(self, row): filters = [] for identifier in self._indexes: @@ -159,7 +189,6 @@ def _getRowValue(self, identifier, row): # GridManager setter methods def dispose(self): - self.saveColumnSettings() self.Column.dispose() self.Model.dispose() @@ -172,6 +201,12 @@ def addSelectionListener(self, listener): def removeSelectionListener(self, listener): self._view.getGrid().removeSelectionListener(listener) + def addGridDataListener(self, listener): + self._model.addGridDataListener(listener) + + def removeGridDataListener(self, listener): + self._model.removeGridDataListener(listener) + def showColumns(self, state): self._view.showColumns(state) diff --git a/uno/lib/uno/grid/gridmodel.py b/uno/lib/uno/grid/gridmodel.py index 2b3e05f8..3e0c7f20 100644 --- a/uno/lib/uno/grid/gridmodel.py +++ b/uno/lib/uno/grid/gridmodel.py @@ -32,7 +32,7 @@ from com.sun.star.awt.grid import XMutableGridDataModel -from ..unotool import hasInterface +from ...unotool import hasInterface import traceback @@ -113,6 +113,7 @@ def removeGridDataListener(self, listener): # XComponent def dispose(self): + print("GridModel.dispose() 1") event = uno.createUnoStruct('com.sun.star.lang.EventObject') event.Source = self for listener in self._events: diff --git a/uno/lib/uno/grid/gridview.py b/uno/lib/uno/grid/gridview.py index ebe2e52f..c6750298 100644 --- a/uno/lib/uno/grid/gridview.py +++ b/uno/lib/uno/grid/gridview.py @@ -31,9 +31,9 @@ from com.sun.star.view.SelectionType import MULTI -from ..unotool import getContainerWindow +from ...unotool import getContainerWindow -from ..configuration import g_identifier +from ...configuration import g_identifier class GridView(unohelper.Base): diff --git a/uno/lib/uno/jdbcdriver/configuration.py b/uno/lib/uno/jdbcdriver/configuration.py index e1d66e12..776bb608 100644 --- a/uno/lib/uno/jdbcdriver/configuration.py +++ b/uno/lib/uno/jdbcdriver/configuration.py @@ -34,7 +34,7 @@ g_services = ('io.github.prrvchr.jdbcdriver.sdbc.Driver', 'io.github.prrvchr.jdbcdriver.sdbcx.Driver', 'io.github.prrvchr.jdbcdriver.sdb.Driver') -g_version = '1.5.7' +g_version = '1.6.0' g_instrumented = 'SupportsInstrumentationAgent' # jdbcDriverOOo special configuration diff --git a/uno/lib/uno/jdbcdriver/jdbctool.py b/uno/lib/uno/jdbcdriver/jdbctool.py index 2af2ccdf..99b0cb17 100644 --- a/uno/lib/uno/jdbcdriver/jdbctool.py +++ b/uno/lib/uno/jdbcdriver/jdbctool.py @@ -37,8 +37,11 @@ def isInstrumented(ctx, url): support = False driver = createService(ctx, g_service) - for info in driver.getPropertyInfo(url, getPropertyValueSet({g_instrumented: True})): - if (info.Name == g_instrumented): - support = info.Value != 'false' + if driver: + properties = getPropertyValueSet({g_instrumented: True}) + for info in driver.getPropertyInfo(url, properties): + if info.Name == g_instrumented: + support = info.Value != 'false' + break return support diff --git a/uno/lib/uno/library.dtd b/uno/lib/uno/library.dtd new file mode 100644 index 00000000..c0341ed5 --- /dev/null +++ b/uno/lib/uno/library.dtd @@ -0,0 +1,33 @@ + + + + + + + + + diff --git a/uno/lib/uno/logger/dialog/logmodel.py b/uno/lib/uno/logger/dialog/logmodel.py index 4cfd975b..44303128 100644 --- a/uno/lib/uno/logger/dialog/logmodel.py +++ b/uno/lib/uno/logger/dialog/logmodel.py @@ -56,7 +56,7 @@ from packaging.requirements import Requirement from importlib import metadata -import distutils.sysconfig as ds +import sysconfig import pkg_resources as pkgr import os, sys import traceback @@ -140,7 +140,7 @@ def logInfos(self, level, clazz, method, requirements): else: msg = self._resolver.resolveString(123).format(sys.executable) self._logger.logp(level, clazz, method, msg) - msg = self._resolver.resolveString(124).format(ds.get_config_var('EXT_SUFFIX')) + msg = self._resolver.resolveString(124).format(sysconfig.get_config_var('EXT_SUFFIX')) self._logger.logp(level, clazz, method, msg) msg = self._resolver.resolveString(125).format(os.pathsep.join(sys.path)) self._logger.logp(level, clazz, method, msg) diff --git a/uno/lib/uno/logger/logcontroller.py b/uno/lib/uno/logger/logcontroller.py index 50a896f6..5b910124 100644 --- a/uno/lib/uno/logger/logcontroller.py +++ b/uno/lib/uno/logger/logcontroller.py @@ -27,6 +27,8 @@ β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β• """ +import uno + from com.sun.star.logging.LogLevel import SEVERE from .logwrapper import LogWrapper @@ -50,7 +52,8 @@ def __init__(self, ctx, name, basename=g_basename, listener=None): self._listener = listener self._setting = None self._config = LogConfig(ctx) - if listener is not None: + self._handler = None + if listener: self._logger.addModifyListener(listener) # Public getter method @@ -62,17 +65,26 @@ def dispose(self): if self._listener is not None: self._logger.removeModifyListener(self._listener) + def addRollerHandler(self, handler=None): + if handler is None: + handler = RollerHandler(self._ctx, self.Name) + super().addRollerHandler(handler) + self._handler = handler + if self._listener: + event = uno.createUnoStruct('com.sun.star.lang.EventObject', self._logger) + self._listener.modified(event) + + def removeRollerHandler(self, handler=None): + if handler is None: + handler = self._handler + super().removeRollerHandler(handler) + def clearLogger(self): - url = getRollerHandlerUrl(self._ctx, self.Name) - sf = getSimpleFile(self._ctx) - if sf.exists(url): - sf.kill(url) + if self._handler: + self._handler.clearLogger() resolver = getStringResourceWithLocation(self._ctx, self._url, 'Logger') msg = resolver.resolveString(111) - handler = RollerHandler(self._ctx, self.Name) - self.addRollerHandler(handler) self._logger.logp(SEVERE, 'Logger', 'clearLogger', msg) - self.removeRollerHandler(handler) def addModifyListener(self, listener): self._logger.addModifyListener(listener) diff --git a/uno/lib/uno/logger/loghandler.py b/uno/lib/uno/logger/loghandler.py index f537bfa3..c426f421 100644 --- a/uno/lib/uno/logger/loghandler.py +++ b/uno/lib/uno/logger/loghandler.py @@ -108,6 +108,10 @@ def removeEventListener(self, listener): if listener in self._listeners: self._listeners.remove(listener) + def clearLogger(self): + if self._sf.exists(self._url): + self._sf.kill(self._url) + def _publishRecord(self, record): if not self._sf.exists(self._url): msg = self._formatter.getHead() diff --git a/uno/lib/uno/module.dtd b/uno/lib/uno/module.dtd new file mode 100644 index 00000000..b77d62f4 --- /dev/null +++ b/uno/lib/uno/module.dtd @@ -0,0 +1,24 @@ + + + + diff --git a/uno/lib/uno/oauth20/configuration.py b/uno/lib/uno/oauth20/configuration.py index 68e134f9..d9030399 100644 --- a/uno/lib/uno/oauth20/configuration.py +++ b/uno/lib/uno/oauth20/configuration.py @@ -33,7 +33,7 @@ g_service = '%s.OAuth2Service' % g_identifier g_resource = 'resource' -g_version = '1.5.3' +g_version = '1.6.0' g_chunk = g_chunk = 320 * 1024 g_token = 'Bearer ${AccessToken}' diff --git a/uno/lib/uno/options/addressbook/__init__.py b/uno/lib/uno/options/addressbook/__init__.py index c2eddf4f..f6f7a27b 100644 --- a/uno/lib/uno/options/addressbook/__init__.py +++ b/uno/lib/uno/options/addressbook/__init__.py @@ -28,3 +28,4 @@ """ from .optionsmanager import OptionsManager + diff --git a/uno/lib/uno/options/addressbook/optionshandler.py b/uno/lib/uno/options/addressbook/optionshandler.py new file mode 100644 index 00000000..ed8e8385 --- /dev/null +++ b/uno/lib/uno/options/addressbook/optionshandler.py @@ -0,0 +1,55 @@ +#! +# -*- coding: utf-8 -*- + +""" +╔════════════════════════════════════════════════════════════════════════════════════╗ +β•‘ β•‘ +β•‘ Copyright (c) 2020-25 https://prrvchr.github.io β•‘ +β•‘ β•‘ +β•‘ Permission is hereby granted, free of charge, to any person obtaining β•‘ +β•‘ a copy of this software and associated documentation files (the "Software"), β•‘ +β•‘ to deal in the Software without restriction, including without limitation β•‘ +β•‘ the rights to use, copy, modify, merge, publish, distribute, sublicense, β•‘ +β•‘ and/or sell copies of the Software, and to permit persons to whom the Software β•‘ +β•‘ is furnished to do so, subject to the following conditions: β•‘ +β•‘ β•‘ +β•‘ The above copyright notice and this permission notice shall be included in β•‘ +β•‘ all copies or substantial portions of the Software. β•‘ +β•‘ β•‘ +β•‘ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, β•‘ +β•‘ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES β•‘ +β•‘ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. β•‘ +β•‘ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY β•‘ +β•‘ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, β•‘ +β•‘ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE β•‘ +β•‘ OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. β•‘ +β•‘ β•‘ +β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β• +""" + +import unohelper + +from com.sun.star.awt import XContainerWindowEventHandler + +import traceback + + +class WindowHandler(unohelper.Base, + XContainerWindowEventHandler): + def __init__(self, manager): + self._manager = manager + + # XContainerWindowEventHandler + def callHandlerMethod(self, window, event, method): + try: + handled = False + if method == 'ViewData': + self._manager.viewData() + handled = True + return handled + except Exception as e: + print("ERROR: %s - %s" % (e, traceback.format_exc())) + + def getSupportedMethodNames(self): + return ('ViewData', ) + diff --git a/uno/lib/uno/options/addressbook/optionsmanager.py b/uno/lib/uno/options/addressbook/optionsmanager.py index 7d010716..a04b943f 100644 --- a/uno/lib/uno/options/addressbook/optionsmanager.py +++ b/uno/lib/uno/options/addressbook/optionsmanager.py @@ -31,44 +31,42 @@ from com.sun.star.logging.LogLevel import SEVERE from .optionsmodel import OptionsModel + from .optionsview import OptionsView -from ..unotool import getDesktop +from .optionshandler import WindowHandler + +from ...unotool import getDesktop -from ..logger import LogManager +from ...logger import LogManager -from ..configuration import g_defaultlog -from ..configuration import g_synclog +from ...configuration import g_defaultlog +from ...configuration import g_synclog class OptionsManager(): - def __init__(self, ctx, logger, window, offset=0): + def __init__(self, ctx, logger, window): self._ctx = ctx - self._logger = logger self._model = OptionsModel(ctx) - self._view = OptionsView(window, OptionsManager._restart, offset, *self._model.getViewData()) - self._logmanager = LogManager(self._ctx, window, 'requirements.txt', g_defaultlog, g_synclog) + self._view = OptionsView(ctx, window, WindowHandler(self), *self._model.getViewData()) + self._logmanager = LogManager(ctx, self._view.getWindow(), 'requirements.txt', g_defaultlog, g_synclog) self._logmanager.initView() + self._logger = logger self._logger.logprb(INFO, 'OptionsManager', '__init__()', 301) self._model.loadDriver() - _restart = False - def loadSetting(self): self._view.setTimeout(self._model.getTimeout()) self._view.setViewName(self._model.getViewName()) - self._view.setRestart(OptionsManager._restart) self._logmanager.loadSetting() self._logger.logprb(INFO, 'OptionsManager', 'loadSetting()', 311) def saveSetting(self): timeout, view = self._view.getViewData() option = self._model.setViewData(timeout, view) - log = self._logmanager.saveSetting() - if log: - OptionsManager._restart = True - self._view.setRestart(True) - self._logger.logprb(INFO, 'OptionsManager', 'saveSetting()', 321, option, log) + saved = self._logmanager.saveSetting() + self._logger.logprb(INFO, 'OptionsManager', 'saveSetting()', 321, option, saved) + return saved def viewData(self): url = self._model.getDatasourceUrl() diff --git a/uno/lib/uno/options/addressbook/optionsmodel.py b/uno/lib/uno/options/addressbook/optionsmodel.py index 85b76b3e..30cb662c 100644 --- a/uno/lib/uno/options/addressbook/optionsmodel.py +++ b/uno/lib/uno/options/addressbook/optionsmodel.py @@ -27,14 +27,14 @@ β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β• """ -from ..unotool import createService -from ..unotool import getConfiguration -from ..unotool import getSimpleFile +from ...unotool import createService +from ...unotool import getConfiguration +from ...unotool import getSimpleFile -from ..helper import getDataBaseUrl +from ...helper import getDataBaseUrl -from ..configuration import g_identifier -from ..configuration import g_implementation +from ...configuration import g_identifier +from ...configuration import g_implementation class OptionsModel(): @@ -65,7 +65,6 @@ def getViewName(self): def getDatasourceUrl(self): return self._url - # OptionsModel setter methods def loadDriver(self): try: diff --git a/uno/lib/uno/options/addressbook/optionsview.py b/uno/lib/uno/options/addressbook/optionsview.py index 2d335949..2f5da84e 100644 --- a/uno/lib/uno/options/addressbook/optionsview.py +++ b/uno/lib/uno/options/addressbook/optionsview.py @@ -27,21 +27,25 @@ β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β• """ -import unohelper +from ...unotool import getContainerWindow + +from ...configuration import g_identifier import traceback class OptionsView(): - def __init__(self, window, restart, offset, timeout, view, enabled): - self._window = window + def __init__(self, ctx, window, handler, timeout, view, enabled): + self._window = getContainerWindow(ctx, window.getPeer(), handler, g_identifier, 'OptionDialog') + self._window.setVisible(True) self._getTimeout().Value = timeout self._getDatasource().Model.Enabled = enabled self._setViewName(view, not enabled) - self.setRestart(restart) - self._getRestart().Model.PositionY += offset # OptionsView getter methods + def getWindow(self): + return self._window + def getViewData(self): return int(self._getTimeout().Value), self._getViewName().Text @@ -52,9 +56,6 @@ def setTimeout(self, timeout): def setViewName(self, view): self._getViewName().Text = view - def setRestart(self, enabled): - self._getRestart().setVisible(enabled) - # OptionsView private setter methods def _setViewName(self, view, disabled): self._getViewLabel().Model.Enabled = disabled @@ -75,6 +76,3 @@ def _getViewLabel(self): def _getViewName(self): return self._window.getControl('TextField1') - def _getRestart(self): - return self._window.getControl('Label4') - diff --git a/uno/lib/uno/options/embedded/options b/uno/lib/uno/options/embedded/options new file mode 120000 index 00000000..9b1eeeec --- /dev/null +++ b/uno/lib/uno/options/embedded/options @@ -0,0 +1 @@ +../jdbc \ No newline at end of file diff --git a/uno/lib/uno/options/embedded/optionsmanager.py b/uno/lib/uno/options/embedded/optionsmanager.py index f5374b80..141dc395 100644 --- a/uno/lib/uno/options/embedded/optionsmanager.py +++ b/uno/lib/uno/options/embedded/optionsmanager.py @@ -31,7 +31,7 @@ from .optionsview import OptionsView from .optionshandler import OptionsListener -from ..option import OptionManager +from .options import OptionsManager as Manager from ..configuration import g_defaultlog @@ -41,9 +41,9 @@ class OptionsManager(): def __init__(self, ctx, logger, window, options, url=None): self._model = OptionsModel(ctx, logger, url) - instrumented = self._model.isInstrumented() - self._manager = OptionManager(ctx, window, options, instrumented, OptionsManager._restart, 20, g_defaultlog) - self._view = OptionsView(window) + link, instrumented = self._model.getDriverInfo() + self._manager = Manager(ctx, window, instrumented, options, g_defaultlog) + self._view = OptionsView(window, OptionsManager._restart, link, instrumented) window.addEventListener(OptionsListener(self)) self._manager.initView() self._initView() @@ -57,13 +57,11 @@ def dispose(self): def saveSetting(self): if self._manager.saveSetting(): OptionsManager._restart = True - self._manager.setRestart(True) - + self._view.setWarning(True, self._model.isInstrumented()) def loadSetting(self): self._manager.loadSetting() - version = self._model.getDriverVersion(self._getConfigApiLevel()) - self._view.setDriverVersion(version) + self._initView() # OptionsManager private getter methods def _getConfigApiLevel(self): diff --git a/uno/lib/uno/options/embedded/optionsmodel.py b/uno/lib/uno/options/embedded/optionsmodel.py index 51b14d45..c8f1686a 100644 --- a/uno/lib/uno/options/embedded/optionsmodel.py +++ b/uno/lib/uno/options/embedded/optionsmodel.py @@ -33,10 +33,12 @@ from com.sun.star.uno import Exception as UnoException from ..unotool import createService +from ..unotool import getStringResource from ..jdbcdriver import g_service as jdbc from ..jdbcdriver import isInstrumented +from ..configuration import g_identifier from ..configuration import g_service as embedded import traceback @@ -47,10 +49,15 @@ def __init__(self, ctx, logger, url=None): self._ctx = ctx self._url = url self._instrumented = isInstrumented(ctx, 'xdbc:jdbc') + resolver = getStringResource(ctx, g_identifier, 'dialogs', 'OptionsDialog') + self._link = resolver.resolveString('OptionsDialog.Hyperlink1.Url') self._logger = logger self._logger.logprb(INFO, 'OptionsModel', '__init__', 401) # OptionsModel getter methods + def getDriverInfo(self): + return self._link, self._instrumented + def isInstrumented(self): return self._instrumented diff --git a/uno/lib/uno/options/embedded/optionsview.py b/uno/lib/uno/options/embedded/optionsview.py index 98170ae8..19450086 100644 --- a/uno/lib/uno/options/embedded/optionsview.py +++ b/uno/lib/uno/options/embedded/optionsview.py @@ -31,14 +31,35 @@ class OptionsView(): - def __init__(self, window): + def __init__(self, window, restart, url, instrumented): self._window = window + control = self._getWarning() + control.URL = url + self._setWarning(control, restart, instrumented) # OptionsView setter methods + def setWarning(self, restart, instrumented): + self._setWarning(self._getWarning(), restart, instrumented) + def setDriverVersion(self, version): self._getVersion().Text = version +# OptionsView private methods + def _setWarning(self, control, restart, instrumented): + if restart: + control.setVisible(False) + self._getRestart().setVisible(True) + else: + self._getRestart().setVisible(False) + control.setVisible(not instrumented) + # OptionsView private control methods def _getVersion(self): return self._window.getControl('Label2') + def _getRestart(self): + return self._window.getControl('Label3') + + def _getWarning(self): + return self._window.getControl('Hyperlink1') + diff --git a/uno/lib/uno/options/jdbc/__init__.py b/uno/lib/uno/options/jdbc/__init__.py index eab324b7..f6f7a27b 100644 --- a/uno/lib/uno/options/jdbc/__init__.py +++ b/uno/lib/uno/options/jdbc/__init__.py @@ -27,4 +27,5 @@ β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β• """ -from .optionmanager import OptionManager +from .optionsmanager import OptionsManager + diff --git a/uno/lib/uno/options/jdbc/optionhandler.py b/uno/lib/uno/options/jdbc/optionshandler.py similarity index 100% rename from uno/lib/uno/options/jdbc/optionhandler.py rename to uno/lib/uno/options/jdbc/optionshandler.py diff --git a/uno/lib/uno/options/jdbc/optionmanager.py b/uno/lib/uno/options/jdbc/optionsmanager.py similarity index 85% rename from uno/lib/uno/options/jdbc/optionmanager.py rename to uno/lib/uno/options/jdbc/optionsmanager.py index 1f88ce7c..ac7cb0b1 100644 --- a/uno/lib/uno/options/jdbc/optionmanager.py +++ b/uno/lib/uno/options/jdbc/optionsmanager.py @@ -27,20 +27,22 @@ β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β• """ -from .optionmodel import OptionModel -from .optionview import OptionWindow -from .optionhandler import WindowHandler +from .optionsmodel import OptionsModel -from ..logger import LogManager +from .optionsview import OptionsWindow + +from .optionshandler import WindowHandler + +from ...logger import LogManager import traceback -class OptionManager(): - def __init__(self, ctx, window, options, instrumented, restart, offset, logger, *loggers): +class OptionsManager(): + def __init__(self, ctx, window, instrumented, options, logger, *loggers): self._logmanager = LogManager(ctx, window, 'requirements.txt', logger, *loggers) - self._model = OptionModel(ctx, instrumented) - self._view = OptionWindow(ctx, window, WindowHandler(self), options, restart, offset) + self._model = OptionsModel(ctx, instrumented) + self._view = OptionsWindow(ctx, window, WindowHandler(self), options) # OptionManager setter methods def initView(self): @@ -61,9 +63,6 @@ def saveSetting(self): saved |= self._model.saveSetting() return saved - def setRestart(self, state): - self._view.setRestart(state) - def loadSetting(self): self._logmanager.loadSetting() self._initView() @@ -79,6 +78,5 @@ def setSystemTable(self, state): # OptionManager private methods def _initView(self): - instrumented = self._model.isInstrumented() - self._view.initView(instrumented, *self._model.getViewData()) + self._view.initView(*self._model.getViewData()) diff --git a/uno/lib/uno/options/jdbc/optionmodel.py b/uno/lib/uno/options/jdbc/optionsmodel.py similarity index 91% rename from uno/lib/uno/options/jdbc/optionmodel.py rename to uno/lib/uno/options/jdbc/optionsmodel.py index c0354523..65262b7a 100644 --- a/uno/lib/uno/options/jdbc/optionmodel.py +++ b/uno/lib/uno/options/jdbc/optionsmodel.py @@ -27,21 +27,14 @@ β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β• """ -from com.sun.star.logging.LogLevel import INFO +from ...unotool import getConfiguration -from ..unotool import getConfiguration - -from ..logger import getLogger - -from ..jdbcdriver import g_services - -from ..configuration import g_identifier -from ..configuration import g_basename +from ...configuration import g_identifier import traceback -class OptionModel(): +class OptionsModel(): def __init__(self, ctx, instrumented): self._rebootkeys = ('ApiLevel', 'CachedRowSet') configkeys = ('ShowSystemTable', ) @@ -51,9 +44,6 @@ def __init__(self, ctx, instrumented): self._instrumented = instrumented # OptionModel getter methods - def isInstrumented(self): - return self._instrumented - def getConfigApiLevel(self): return self._config.getByName('ApiLevel') @@ -62,7 +52,7 @@ def getViewData(self): level = self._settings.get('ApiLevel') crs = self._settings.get('CachedRowSet') system = self._settings.get('ShowSystemTable') - return level, crs, system, self._isRowSetEnabled(level) + return self._instrumented, level, crs, system, self._isRowSetEnabled(level) # OptionModel setter methods def setApiLevel(self, level): diff --git a/uno/lib/uno/options/jdbc/optionview.py b/uno/lib/uno/options/jdbc/optionsview.py similarity index 84% rename from uno/lib/uno/options/jdbc/optionview.py rename to uno/lib/uno/options/jdbc/optionsview.py index 61b8e19d..c1b8a17f 100644 --- a/uno/lib/uno/options/jdbc/optionview.py +++ b/uno/lib/uno/options/jdbc/optionsview.py @@ -27,21 +27,18 @@ β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β• """ -from ..unotool import getContainerWindow +from ...unotool import getContainerWindow -from ..configuration import g_identifier +from ...configuration import g_identifier import traceback -class OptionWindow(): - def __init__(self, ctx, window, handler, options, restart, offset): +class OptionsWindow(): + def __init__(self, ctx, window, handler, options): self._window = getContainerWindow(ctx, window.getPeer(), handler, g_identifier, 'OptionDialog') self._window.setVisible(True) - for crs in options: - self._getCachedRowSet(crs).Model.Enabled = False - self.setRestart(restart) - self._getRestart().Model.PositionY += offset + self.enableCachedRowSet(False, options) # OptionWindow setter methods def dispose(self): @@ -56,12 +53,9 @@ def initView(self, instrumented, level, crs, system, enabled): self.enableCachedRowSet(instrumented and enabled) self._getSytemTable().State = int(system) - def enableCachedRowSet(self, enabled): - for crs in range(3): - self._getCachedRowSet(crs).Model.Enabled = enabled - - def setRestart(self, enabled): - self._getRestart().setVisible(enabled) + def enableCachedRowSet(self, enabled, options=(0, 1, 2)): + for index in options: + self._getCachedRowSet(index).Model.Enabled = enabled # OptionWindow private control methods def _getApiLevel(self, index): @@ -73,6 +67,3 @@ def _getCachedRowSet(self, index): def _getSytemTable(self): return self._window.getControl('CheckBox1') - def _getRestart(self): - return self._window.getControl('Label3') - diff --git a/uno/lib/uno/options/ucb/optionsmanager.py b/uno/lib/uno/options/ucb/optionsmanager.py index ccbc5ba6..3aaa5ef8 100644 --- a/uno/lib/uno/options/ucb/optionsmanager.py +++ b/uno/lib/uno/options/ucb/optionsmanager.py @@ -55,10 +55,10 @@ def __init__(self, ctx, source, logger, window): self._ctx = ctx self._logger = logger self._model = OptionsModel(ctx) - self._view = OptionsView(window, *self._model.getInitData()) + self._view = OptionsView(window, OptionsManager._restart, *self._model.getInitData()) self._logmanager = LogManager(ctx, window, 'requirements.txt', g_defaultlog, g_synclog) self._logmanager.initView() - self._view.setViewData(*self._model.getViewData(OptionsManager._restart)) + self._view.setViewData(OptionsManager._restart, *self._model.getViewData()) self._logger.logprb(INFO, 'OptionsManager', '__init__', 151) try: url = getDataBaseUrl(ctx) @@ -71,7 +71,7 @@ def __init__(self, ctx, source, logger, window): _restart = False def loadSetting(self): - self._view.setViewData(*self._model.getViewData(OptionsManager._restart)) + self._view.setViewData(OptionsManager._restart, *self._model.getViewData()) self._logmanager.loadSetting() self._logger.logprb(INFO, 'OptionsManager', 'loadSetting', 161) @@ -80,14 +80,14 @@ def saveSetting(self): changed = self._logmanager.saveSetting() if changed: OptionsManager._restart = True - self._view.setRestart(True) + self._view.setWarning(True, self._model.isInstrumented()) self._logger.logprb(INFO, 'OptionsManager', 'saveSetting', 171, option, changed) def enableShare(self, enabled): self._view.enableShare(enabled) def enableSync(self, enabled): - self._view.enableSync(enabled, OptionsManager._restart, self._model.hasDataBase()) + self._view.enableSync(OptionsManager._restart, self._model.isInstrumented(), enabled, self._model.hasDataBase()) def setReset(self, enabled): self._view.enableResetFile(enabled) @@ -103,10 +103,10 @@ def viewFile(self): fp.dispose() def download(self): - self._view.setStep(1, OptionsManager._restart) + self._view.setStep(1, OptionsManager._restart, self._model.isInstrumented()) def upload(self): - self._view.setStep(2, OptionsManager._restart) + self._view.setStep(2, OptionsManager._restart, self._model.isInstrumented()) def spinUp(self, index): self._view.setChunk(index, self._view.getChunk(index) * 2) diff --git a/uno/lib/uno/options/ucb/optionsmodel.py b/uno/lib/uno/options/ucb/optionsmodel.py index 4061f310..d912b59f 100644 --- a/uno/lib/uno/options/ucb/optionsmodel.py +++ b/uno/lib/uno/options/ucb/optionsmodel.py @@ -31,6 +31,8 @@ from com.sun.star.ucb.SynchronizePolicy import CLIENT_IS_MASTER from com.sun.star.ucb.SynchronizePolicy import NONE_IS_MASTER +from ..jdbcdriver import isInstrumented + from ..unotool import getConfiguration from ..unotool import getResourceLocation from ..unotool import getSimpleFile @@ -50,6 +52,7 @@ class OptionsModel(): def __init__(self, ctx): self._config = getConfiguration(ctx, g_identifier, True) self._common = getConfiguration(ctx, 'org.openoffice.Office.Common', True) + self._instrumented = isInstrumented(ctx, 'xdbc:hsqldb:') self._url = getResourceLocation(ctx, g_identifier) self._policies = {'SERVER_IS_MASTER': 1, 'CLIENT_IS_MASTER': 2, 'NONE_IS_MASTER': 3} self._factors = {'Timeout': 60, 'Chunk': 1024} @@ -57,8 +60,8 @@ def __init__(self, ctx): self._hasdatabase = sf.exists(self.getDatasourceUrl()) self._hasfile = sf.exists(self.getFileUrl()) self._resolver = getStringResource(ctx, g_identifier, 'dialogs', 'OptionsDialog') - self._resources = {'Link': 'OptionsDialog.Hyperlink1.Link'} - + self._resources = {'Link': 'OptionsDialog.Hyperlink1.Url', + 'Url': 'OptionsDialog.Hyperlink2.Url'} @property def _ResetSync(self): @@ -95,15 +98,18 @@ def _Macro(self): # OptionsModel getter methods def getInitData(self): resumable = self._config.getByName('ResumableUpload') - return self._hasdatabase, self._hasfile, resumable, self._getLink() + return self._getUrl(), self._instrumented, self._hasdatabase, self._hasfile, resumable, self._getLink() + + def isInstrumented(self): + return self._instrumented def hasDataBase(self): return self._hasdatabase - def getViewData(self, restart): - return (self._hasdatabase, self._ResetSync, self._SupportShare, - self._IsShared, self._ShareName, self._Policy, - self._Timeout, self._Download, self._Upload, self._Macro, restart) + def getViewData(self): + return (self._instrumented, self._hasdatabase, self._ResetSync, + self._SupportShare, self._IsShared, self._ShareName, + self._Policy, self._Timeout, self._Download, self._Upload, self._Macro) def getDatasourceUrl(self): folder = g_ucbseparator + g_folder + g_ucbseparator + g_scheme @@ -188,6 +194,10 @@ def _setMacro(self, enabled): if enabled != self._Macro: self._common.replaceByHierarchicalName('Misc/UseSystemFileDialog', enabled) + def _getUrl(self): + resource = self._resources.get('Url') + return self._resolver.resolveString(resource) + def _getLink(self): resource = self._resources.get('Link') return self._resolver.resolveString(resource) diff --git a/uno/lib/uno/options/ucb/optionsview.py b/uno/lib/uno/options/ucb/optionsview.py index 7e058c83..7d6603ec 100644 --- a/uno/lib/uno/options/ucb/optionsview.py +++ b/uno/lib/uno/options/ucb/optionsview.py @@ -31,7 +31,7 @@ class OptionsView(): - def __init__(self, window, exist, hasfile, resumable, link): + def __init__(self, window, restart, url, instrumented, exist, hasfile, resumable, link): self._window = window if exist: self._disableShare() @@ -41,6 +41,9 @@ def __init__(self, window, exist, hasfile, resumable, link): self._getFile().Model.Enabled = hasfile self._getUpload().Model.Enabled = resumable self._getLink().URL = link + control = self._getWarning() + control.URL = url + self._setWarning(control, restart, instrumented) # OptionsView getter methods def getViewData(self): @@ -59,13 +62,16 @@ def getChunk(self, index): return int(self._getChunk(index).Value) # OptionsView setter methods - def setStep(self, step, restart): + def setWarning(self, restart, instrumented): + self._setWarning(self._getWarning(), restart, instrumented) + + def setStep(self, step, restart, instrumented): self._window.Model.Step = step # XXX: If we change the step, we have to restore the visibility of the controls # XXX: because it was lost (ie: after setting the new step everything is visible). - self.setRestart(restart) + self.setWarning(restart, instrumented) - def setViewData(self, exist, reset, support, share, name, index, timeout, download, upload, macro, restart): + def setViewData(self, restart, instrumented, exist, reset, support, share, name, index, timeout, download, upload, macro): self._getResetSync().State = int(reset != 0) self._getResetFile().State = int(reset == 2) self.enableResetFile(reset != 0) @@ -80,22 +86,22 @@ def setViewData(self, exist, reset, support, share, name, index, timeout, downlo self._getShareName().Text = name self.enableShare(False) self._getOption(index).State = 1 - self.enableSync(index != 3, restart, exist) + self.enableSync(restart, instrumented, index != 3, exist) self._getTimeout().Value = timeout self._setSetting(download, 0) self._setSetting(upload, 1) self._getMacro().State = int(macro) self.enableCustomize(macro) - self.setRestart(restart) + self.setWarning(restart, instrumented) def enableShare(self, enabled): self._getShareName().Model.Enabled = enabled - def enableSync(self, enabled, restart, exist): + def enableSync(self, restart, instrumented, enabled, exist): self._getResetSync().Model.Enabled = enabled and exist self._getTimeoutLabel().Model.Enabled = enabled self._getTimeout().Model.Enabled = enabled - self._enableUpload(enabled, restart) + self._enableUpload(restart, instrumented, enabled) def enableResetFile(self, enabled): self._getResetFile().Model.Enabled = enabled @@ -106,9 +112,6 @@ def enableCustomize(self, enabled): self._getLink().Model.Enabled = enabled self._getCustomize().Model.Enabled = enabled - def setRestart(self, enabled): - self._getRestart().setVisible(enabled) - def setChunk(self, index, chunk): control = self._getChunk(index) control.Value = chunk @@ -130,6 +133,14 @@ def _getSetting(self, index): 'Retry': int(self._getRetry(index).Value)} # OptionsView private setter methods + def _setWarning(self, control, restart, instrumented): + if restart: + control.setVisible(False) + self._getRestart().setVisible(True) + else: + self._getRestart().setVisible(False) + control.setVisible(not instrumented) + def _disableShare(self): self._getShare().Model.Enabled = False self._getShareName().Model.Enabled = False @@ -139,11 +150,11 @@ def _setSetting(self, setting, index): self._getDelay(index).Value = setting.get('Delay') self._getRetry(index).Value = setting.get('Retry') - def _enableUpload(self, enabled, restart): + def _enableUpload(self, restart, instrumented, enabled): control = self._getUpload() if not enabled and control.State: self._getDownload().State = 1 - self.setStep(1, restart) + self.setStep(1, restart, instrumented) control.Model.Enabled = enabled # OptionsView private control methods @@ -200,9 +211,6 @@ def _getRetry(self, index): index += 6 return self._window.getControl('NumericField%s' % index) - def _getRestart(self): - return self._window.getControl('Label8') - def _getMacro(self): return self._window.getControl('CheckBox4') @@ -212,3 +220,9 @@ def _getLink(self): def _getCustomize(self): return self._window.getControl('CommandButton7') + def _getRestart(self): + return self._window.getControl('Label8') + + def _getWarning(self): + return self._window.getControl('Hyperlink2') + diff --git a/uno/lib/uno/unotool/__init__.py b/uno/lib/uno/unotool/__init__.py index 4419bb72..323fe83d 100644 --- a/uno/lib/uno/unotool/__init__.py +++ b/uno/lib/uno/unotool/__init__.py @@ -27,22 +27,31 @@ β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β• """ +from .taskevent import TaskEvent + +from .statusindicator import StatusIndicator + from .unotool import checkVersion from .unotool import createMessageBox from .unotool import createService from .unotool import createWindow +from .unotool import executeDesktopDispatch from .unotool import executeDispatch from .unotool import executeFrameDispatch from .unotool import executeShell +from .unotool import findFrame from .unotool import generateUuid from .unotool import getArgumentSet +from .unotool import getCallBack from .unotool import getConfiguration from .unotool import getConnectionMode +from .unotool import getConnector from .unotool import getContainerWindow from .unotool import getCurrentLocale from .unotool import getDateTime from .unotool import getDefaultPropertyValueSet from .unotool import getDesktop +from .unotool import getDialogPosSize from .unotool import getDispatcher from .unotool import getDialog from .unotool import getDialogUrl @@ -55,10 +64,13 @@ from .unotool import getInteractionHandler from .unotool import getInterfaceNames from .unotool import getInterfaceTypes +from .unotool import getLastNamedParts from .unotool import getLibreOfficeInfo from .unotool import getLibreOfficeVersion +from .unotool import getMailMerge from .unotool import getMessageBox from .unotool import getMimeTypeFactory +from .unotool import getMri from .unotool import getNamedValue from .unotool import getNamedValueSet from .unotool import getParentWindow @@ -75,6 +87,8 @@ from .unotool import getStringResourceWithLocation from .unotool import getTempFile from .unotool import getToolKit +from .unotool import getTopWindow +from .unotool import getTopWindowPosition from .unotool import getTypeDetection from .unotool import getUriFactory from .unotool import getUrl @@ -84,5 +98,7 @@ from .unotool import hasService from .unotool import parseDateTime from .unotool import parseUrl +from .unotool import saveTopWindowPosition +from .unotool import setProgress from .unotool import unparseDateTime from .unotool import unparseTimeStamp diff --git a/uno/lib/uno/unotool/statusindicator.py b/uno/lib/uno/unotool/statusindicator.py new file mode 100644 index 00000000..67962f71 --- /dev/null +++ b/uno/lib/uno/unotool/statusindicator.py @@ -0,0 +1,94 @@ +#! +# -*- coding: utf-8 -*- + +""" +╔════════════════════════════════════════════════════════════════════════════════════╗ +β•‘ β•‘ +β•‘ Copyright (c) 2020-25 https://prrvchr.github.io β•‘ +β•‘ β•‘ +β•‘ Permission is hereby granted, free of charge, to any person obtaining β•‘ +β•‘ a copy of this software and associated documentation files (the "Software"), β•‘ +β•‘ to deal in the Software without restriction, including without limitation β•‘ +β•‘ the rights to use, copy, modify, merge, publish, distribute, sublicense, β•‘ +β•‘ and/or sell copies of the Software, and to permit persons to whom the Software β•‘ +β•‘ is furnished to do so, subject to the following conditions: β•‘ +β•‘ β•‘ +β•‘ The above copyright notice and this permission notice shall be included in β•‘ +β•‘ all copies or substantial portions of the Software. β•‘ +β•‘ β•‘ +β•‘ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, β•‘ +β•‘ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES β•‘ +β•‘ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. β•‘ +β•‘ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY β•‘ +β•‘ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, β•‘ +β•‘ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE β•‘ +β•‘ OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. β•‘ +β•‘ β•‘ +β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β• +""" + +import uno +import unohelper + +from com.sun.star.awt.PosSize import SIZE + +from com.sun.star.task import XStatusIndicator + +from com.sun.star.util.MeasureUnit import APPFONT + +from .unotool import findFrame + +import traceback + + +class StatusIndicator(unohelper.Base, + XStatusIndicator): + def __init__(self, ctx, name, offset=10): + frame = findFrame(ctx, name) + if frame: + self._window = frame.getContainerWindow() + self._progress = frame.createStatusIndicator() + self._point = uno.createUnoStruct('com.sun.star.awt.Point', 0, offset) + else: + self._window = self._progress = self._point = None + self._value = 0 + + def start(self, text, value): + if self._progress: + self._value = 0 + self._setWindowHeight() + self._progress.start(text, value) + + def setText(self, text): + if self._progress: + self._progress.setText(text) + # XXX: After defining the text, it is necessary to also define + # XXX: its value if we do not want to display an empty status bar. + self._progress.setValue(self._value) + + def setValue(self, value): + if self._progress: + # XXX: In order to be able to progress in the loops it is necessary + # XXX: to be able to add value to the current progression value. + # XXX: This is what is done here thanks to a negative value + if value < 0: + self._value += abs(value) + else: + self._value = value + self._progress.setValue(self._value) + + def end(self): + if self._progress: + self._progress.end() + self._setWindowHeight(-1) + + def reset(self): + if self._progress: + self._value = 0 + self._progress.reset() + + def _setWindowHeight(self, factor=1): + size = self._window.getPosSize() + offset = self._window.convertPointToPixel(self._point, APPFONT).Y * factor + self._window.setPosSize(0, 0, size.Width, size.Height + offset, SIZE) + diff --git a/uno/lib/uno/unotool/taskevent.py b/uno/lib/uno/unotool/taskevent.py new file mode 100644 index 00000000..22ddaf5a --- /dev/null +++ b/uno/lib/uno/unotool/taskevent.py @@ -0,0 +1,57 @@ +#! +# -*- coding: utf-8 -*- + +""" +╔════════════════════════════════════════════════════════════════════════════════════╗ +β•‘ β•‘ +β•‘ Copyright (c) 2020-25 https://prrvchr.github.io β•‘ +β•‘ β•‘ +β•‘ Permission is hereby granted, free of charge, to any person obtaining β•‘ +β•‘ a copy of this software and associated documentation files (the "Software"), β•‘ +β•‘ to deal in the Software without restriction, including without limitation β•‘ +β•‘ the rights to use, copy, modify, merge, publish, distribute, sublicense, β•‘ +β•‘ and/or sell copies of the Software, and to permit persons to whom the Software β•‘ +β•‘ is furnished to do so, subject to the following conditions: β•‘ +β•‘ β•‘ +β•‘ The above copyright notice and this permission notice shall be included in β•‘ +β•‘ all copies or substantial portions of the Software. β•‘ +β•‘ β•‘ +β•‘ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, β•‘ +β•‘ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES β•‘ +β•‘ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. β•‘ +β•‘ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY β•‘ +β•‘ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, β•‘ +β•‘ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE β•‘ +β•‘ OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. β•‘ +β•‘ β•‘ +β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β• +""" + +import unohelper + +from com.sun.star.task import XTaskEvent + +from threading import Event + + +class TaskEvent(unohelper.Base, + XTaskEvent): + def __init__(self, set=False): + self._event = Event() + if set: + self._event.set() + + def isSet(self): + return self._event.is_set() + + def set(self): + self._event.set() + + def clear(self): + return self._event.clear() + + def wait(self, timeout): + if not timeout > 0: + timeout = None + return self._event.wait(timeout) + diff --git a/uno/lib/uno/unotool/unotool.py b/uno/lib/uno/unotool/unotool.py index 66f4d5c5..0341793b 100644 --- a/uno/lib/uno/unotool/unotool.py +++ b/uno/lib/uno/unotool/unotool.py @@ -29,7 +29,19 @@ import uno +from com.sun.star.awt import Point from com.sun.star.awt import Rectangle +from com.sun.star.awt import Size + +from com.sun.star.awt.WindowAttribute import SHOW +from com.sun.star.awt.WindowAttribute import MINSIZE +from com.sun.star.awt.WindowAttribute import BORDER +from com.sun.star.awt.WindowAttribute import MOVEABLE +from com.sun.star.awt.WindowAttribute import CLOSEABLE +from com.sun.star.awt.WindowAttribute import NODECORATION + +from com.sun.star.awt.WindowClass import TOP +from com.sun.star.awt.WindowClass import CONTAINER from com.sun.star.beans.PropertyState import DIRECT_VALUE @@ -37,6 +49,8 @@ from com.sun.star.document.MacroExecMode import ALWAYS_EXECUTE_NO_WARN +from com.sun.star.frame.FrameSearchFlag import GLOBAL + from com.sun.star.lang import WrappedTargetRuntimeException from com.sun.star.ucb.ConnectionMode import ONLINE @@ -44,6 +58,8 @@ from com.sun.star.ui.dialogs.ExecutableDialogResults import OK +from com.sun.star.util.MeasureUnit import APPFONT + import binascii import datetime from packaging import version @@ -51,16 +67,22 @@ def getConnectionMode(ctx, host, port=80): - connector = createService(ctx, 'com.sun.star.connection.Connector') + connector = getConnector(ctx) try: connection = connector.connect('socket,host=%s,port=%s' % (host, port)) except NoConnectException: mode = OFFLINE else: - connection.close() + try: + connection.close() + except: + pass mode = ONLINE return mode +def getConnector(ctx): + return createService(ctx, 'com.sun.star.connection.Connector') + def getDesktop(ctx): return createService(ctx, 'com.sun.star.frame.Desktop') @@ -94,6 +116,15 @@ def getUrlTransformer(ctx): def getInteractionHandler(ctx): return createService(ctx, 'com.sun.star.task.InteractionHandler') +def getMailMerge(ctx): + return createService(ctx, 'com.sun.star.text.MailMerge') + +def getMri(ctx): + return createService(ctx, 'mytools.Mri') + +def getCallBack(ctx): + return createService(ctx, 'com.sun.star.awt.AsyncCallback') + def getSequenceInputStream(ctx, sequence): service = 'com.sun.star.io.SequenceInputStream' return createService(ctx, service, sequence) @@ -119,11 +150,14 @@ def parseUrl(transformer, location, protocol=None): success, url = transformer.parseSmart(url, protocol) return url if success else None -def getDocument(ctx, url): - properties = {'Hidden': True, - 'OpenNewView': True, - 'MacroExecutionMode': ALWAYS_EXECUTE_NO_WARN} - descriptor = getPropertyValueSet(properties) +def getDocument(ctx, url, readonly=True): + # XXX: ReadOnly: documents opened for mailing are opened readonly because they must + # XXX: be opened as a new document and this document could be open already + # XXX: OpenNewView: always open a new document because it must be disposed afterwards. + # XXX: Hidden: mailing is done in a hidden view + # XXX: Silence: load document for mailing without user interaction + arguments = {'ReadOnly': readonly, 'OpenNewView': True, 'Hidden': True, 'Silence': True} + descriptor = getPropertyValueSet(arguments) document = getDesktop(ctx).loadComponentFromURL(url, '_blank', 0, descriptor) return document @@ -218,6 +252,12 @@ def getExtensionVersion(ctx, extension): return version return None +def getLastNamedParts(name, sep='.'): + part1, sep, part2 = name.rpartition(sep) + if not sep: + part1, part2 = part2, None + return part1, part2 + def getLibreOfficeInfo(ctx): config = getConfiguration(ctx, '/org.openoffice.Setup/Product') name = config.getByName('ooName') @@ -279,6 +319,10 @@ def getStringResourceWithLocation(ctx, url, filename, locale=None): def generateUuid(): return binascii.hexlify(uno.generateUuid().value).decode('utf-8') +def setProgress(callback, caller, value): + data = {'call': 'progress', 'value': value} + callback.addCallback(caller, getNamedValueSet(data)) + def getDialog(ctx, identifier, xdl, handler=None, window=None): dialog = None provider = createService(ctx, 'com.sun.star.awt.DialogProvider2') @@ -296,6 +340,53 @@ def getDialog(ctx, identifier, xdl, handler=None, window=None): dialog = provider.createDialogWithArguments(url, args) return dialog +def findFrame(ctx, name, flags=GLOBAL): + return getDesktop(ctx).findFrame(name, flags) + +def getDialogPosSize(ctx, extension, xdl, point=None, unit=APPFONT): + dialog = getDialog(ctx, extension, xdl, None, None) + size = dialog.convertSizeToPixel(Size(dialog.Model.Width, dialog.Model.Height), unit) + if point: + position = dialog.convertPointToPixel(point, unit) + else: + position = Point(0, 0) + dialog.dispose() + return Rectangle(position.X, position.Y, size.Width, size.Height) + +def getTopWindow(ctx, name, rectangle=None, parent=None, modal=TOP, attrs=BORDER | MOVEABLE | CLOSEABLE | NODECORATION): + service = 'com.sun.star.frame.TaskCreator' + arguments = {'FrameName': name} + descriptor = uno.createUnoStruct('com.sun.star.awt.WindowDescriptor') + descriptor.Type = modal + descriptor.WindowServiceName = 'window' + if parent: + descriptor.Parent = parent + else: + descriptor.ParentIndex = -1 + if rectangle: + attrs |= SHOW + descriptor.Bounds = rectangle + descriptor.WindowAttributes = attrs + arguments['ContainerWindow'] = getToolKit(ctx).createWindow(descriptor) + #if rectangle: + # arguments['PosSize'] = rectangle + frame = createService(ctx, service).createInstanceWithArguments(getNamedValueSet(arguments)) + desktop = getDesktop(ctx) + frame.setCreator(desktop) + desktop.getFrames().append(frame) + return frame + +def getTopWindowPosition(window): + size = window.getPosSize() + point = uno.createUnoStruct('com.sun.star.awt.Point', size.X, size.Y) + return window.convertPointToLogic(point, APPFONT) + +def saveTopWindowPosition(config, position, property): + if config.hasByName(property): + any = uno.Any('[]long', (position.X, position.Y)) + uno.invoke(config, 'replaceByName', (property, any)) + config.commitChanges() + def getContainerWindow(ctx, parent, handler, identifier, xdl): service = 'com.sun.star.awt.ContainerWindowProvider' provider = createService(ctx, service) @@ -338,6 +429,11 @@ def executeDispatch(ctx, url, /, **args): arguments = getPropertyValueSet(args) getDispatcher(ctx).executeDispatch(frame, url, '', 0, arguments) +def executeDesktopDispatch(ctx, url, listener=None, /, **args): + frame = getDesktop(ctx).getCurrentFrame() + properties = getPropertyValueSet(args) + executeFrameDispatch(ctx, frame, url, listener, *properties) + def executeFrameDispatch(ctx, frame, url, listener=None, /, *properties): url = getUrl(ctx, url) dispatcher = frame.queryDispatch(url, '', 0) @@ -430,7 +526,6 @@ def _getUniqueName(frames, name): name = '%s - %s' % (name, (count +1)) return name - def getParentWindow(ctx): desktop = getDesktop(ctx) try: diff --git a/uno/lib/uno/wizard/__init__.py b/uno/lib/uno/wizard/__init__.py index 47432631..0f7a7349 100644 --- a/uno/lib/uno/wizard/__init__.py +++ b/uno/lib/uno/wizard/__init__.py @@ -28,3 +28,4 @@ """ from .wizard import Wizard + diff --git a/uno/lib/uno/wizard/wizard.py b/uno/lib/uno/wizard/wizard.py index bd30d116..9dcdca31 100644 --- a/uno/lib/uno/wizard/wizard.py +++ b/uno/lib/uno/wizard/wizard.py @@ -30,16 +30,15 @@ import uno import unohelper -from com.sun.star.logging.LogLevel import SEVERE - -from com.sun.star.ui.dialogs import XWizard +from com.sun.star.container import NoSuchElementException +from com.sun.star.lang import XComponent from com.sun.star.lang import XInitialization from com.sun.star.lang import IllegalArgumentException -from com.sun.star.util import InvalidStateException +from com.sun.star.logging.LogLevel import SEVERE -from com.sun.star.container import NoSuchElementException +from com.sun.star.ui.dialogs import XWizard from com.sun.star.ui.dialogs.ExecutableDialogResults import CANCEL from com.sun.star.ui.dialogs.ExecutableDialogResults import OK @@ -48,24 +47,31 @@ from com.sun.star.ui.dialogs.WizardTravelType import BACKWARD from com.sun.star.ui.dialogs.WizardTravelType import FINISH +from com.sun.star.util import CloseVetoException +from com.sun.star.util import InvalidStateException + from .wizardmodel import WizardModel + from .wizardview import WizardView + +from .wizardhandler import CloseListener from .wizardhandler import DialogHandler from .wizardhandler import ItemListener +from .wizardhandler import WindowHandler -from ..logger import getLogger +from ...logger import getLogger -from ..unotool import hasInterface +from ...unotool import hasInterface -from ..configuration import g_extension +from ...configuration import g_extension import traceback class Wizard(unohelper.Base, XWizard, - XInitialization): - def __init__(self, ctx, auto=-1, resize=False, parent=None): + XComponent): + def __init__(self, ctx, auto=-1, resize=False, parent=None, name=None, point=None): self._ctx = ctx self._helpUrl = '' self._auto = auto @@ -74,12 +80,52 @@ def __init__(self, ctx, auto=-1, resize=False, parent=None): self._currentPath = -1 self._multiPaths = False self._controller = None + self._listeners = [] + self._closed = False + self._disposed = False self._model = WizardModel(ctx) title = self._model.getRoadmapTitle() - self._view = WizardView(ctx, DialogHandler(self), ItemListener(self), parent, title) + if name: + handler, self._listener = WindowHandler(self), CloseListener(self) + else: + handler, self._listener = DialogHandler(self), None + self._view = WizardView(ctx, handler, self._listener, ItemListener(self), parent, name, title, resize, point) roadmap = self._view.getRoadmapModel() self._model.setRoadmapModel(roadmap) +# XCloseListener + def queryClosing(self, source, ownership): + self._queryClosing(ownership) + + def notifyClosing(self, source): + if self._listener: + source.removeCloseListener(self._listener) + self.dispose() + +# XComponent + def dispose(self): + self._disposed = True + event = self._getEventObject() + for listener in self._listeners: + listener.disposing(event) + interface = 'com.sun.star.lang.XComponent' + if self._controller and hasInterface(self._controller, interface): + self._controller.dispose() + self._model.dispose() + self._view.dispose() + + def addEventListener(self, listener): + interface = 'com.sun.star.lang.XEventListener' + if hasInterface(listener, interface): + if self._disposed: + listener.disposing(self._getEventObject()) + else: + self._listeners.append(listener) + + def removeEventListener(self, listener): + if not self._disposed and listener in self._listeners: + self._listeners.remove(listener) + # XWizard # XWizard Attributes @property @@ -93,7 +139,7 @@ def HelpURL(self, url): @property def DialogWindow(self): - return self._view.getDialog() + return self._view.getDialogWindow() # XWizard Methods def getCurrentPage(self): @@ -194,10 +240,16 @@ def doFinish(self): reason = self._getCommitReason() if self._model.doFinish(reason): if self._controller.confirmFinish(): - self._view.endDialog(OK) + if self._view.isModal(): + self._view.endDialog(OK) + else: + self._tryToClose() def doCancel(self): - self._view.endDialog(CANCEL) + if self._view.isModal(): + self._view.endDialog(CANCEL) + else: + self._tryToClose() # Wizard private getter methods def _isComplete(self): @@ -343,6 +395,20 @@ def _initNextPage(self): return init # Wizard private setter methods + def _tryToClose(self): + try: + self._queryClosing() + except CloseVetoException as e: + pass + else: + self._view.close() + + def _queryClosing(self, ownership=False): + if not ownership: + interface = 'com.sun.star.util.XCloseable' + if self._controller and hasInterface(self._controller, interface): + self._controller.close(ownership) + def _initPath(self, index, final): complete, paths = self._getPath(index, final) self._model.initRoadmap(self._controller, paths, complete) @@ -384,6 +450,9 @@ def _updateButton(self): self._view.updateButtonFinish(enabled) # Private Exception getter methods + def _getEventObject(self): + return uno.createUnoStruct('com.sun.star.lang.EventObject', self) + def _getIllegalArgumentException(self, position, code, method): e = IllegalArgumentException() e.ArgumentPosition = position diff --git a/uno/lib/uno/wizard/wizardhandler.py b/uno/lib/uno/wizard/wizardhandler.py index c3a85c87..317c54e2 100644 --- a/uno/lib/uno/wizard/wizardhandler.py +++ b/uno/lib/uno/wizard/wizardhandler.py @@ -29,9 +29,12 @@ import unohelper +from com.sun.star.awt import XContainerWindowEventHandler from com.sun.star.awt import XDialogEventHandler from com.sun.star.awt import XItemListener +from com.sun.star.util import XCloseListener + import traceback @@ -71,6 +74,42 @@ def getSupportedMethodNames(self): 'Cancel') +class WindowHandler(unohelper.Base, + XContainerWindowEventHandler): + def __init__(self, manager): + self._manager = manager + +# XContainerWindowEventHandler + def callHandlerMethod(self, dialog, event, method): + try: + handled = False + if method == 'Help': + handled = True + elif method == 'Previous': + self._manager.travelPrevious() + handled = True + elif method == 'Next': + self._manager.travelNext() + handled = True + elif method == 'Finish': + self._manager.doFinish() + handled = True + elif method == 'Cancel': + self._manager.doCancel() + handled = True + return handled + except Exception as e: + msg = "Error: %s" % traceback.format_exc() + print(msg) + + def getSupportedMethodNames(self): + return ('Help', + 'Previous', + 'Next', + 'Finish', + 'Cancel') + + class ItemListener(unohelper.Base, XItemListener): def __init__(self, manager): @@ -86,3 +125,20 @@ def itemStateChanged(self, event): def disposing(self, event): pass + + +class CloseListener(unohelper.Base, + XCloseListener): + def __init__(self, manager): + self._manager = manager + + # XCloseListener + def queryClosing(self, event, ownership): + self._manager.queryClosing(event.Source, ownership) + + def notifyClosing(self, event): + self._manager.notifyClosing(event.Source) + + def disposing(self, event): + pass + diff --git a/uno/lib/uno/wizard/wizardmodel.py b/uno/lib/uno/wizard/wizardmodel.py index e9344333..265bc04e 100644 --- a/uno/lib/uno/wizard/wizardmodel.py +++ b/uno/lib/uno/wizard/wizardmodel.py @@ -30,9 +30,10 @@ import uno import unohelper -from ..unotool import getStringResource +from ...unotool import getStringResource +from ...unotool import hasInterface -from ..configuration import g_identifier +from ...configuration import g_identifier import traceback @@ -46,6 +47,12 @@ def __init__(self, ctx): self._resolver = getStringResource(ctx, g_identifier, 'dialogs', 'Wizard') self._resources = {'Roadmap': 'Wizard.Roadmap.Text'} + def dispose(self): + interface = 'com.sun.star.lang.XComponent' + for page in self._pages.values(): + if page and hasInterface(page, interface): + page.dispose() + def setRoadmapModel(self, model): self._roadmap = model diff --git a/uno/lib/uno/wizard/wizardview.py b/uno/lib/uno/wizard/wizardview.py index 8d293687..b591079f 100644 --- a/uno/lib/uno/wizard/wizardview.py +++ b/uno/lib/uno/wizard/wizardview.py @@ -30,55 +30,91 @@ import uno import unohelper +from com.sun.star.awt import Size +from com.sun.star.awt.PosSize import POSSIZE +from com.sun.star.awt.PosSize import SIZE + from com.sun.star.ui.dialogs.WizardButton import NEXT from com.sun.star.ui.dialogs.WizardButton import PREVIOUS from com.sun.star.ui.dialogs.WizardButton import FINISH from com.sun.star.ui.dialogs.WizardButton import CANCEL from com.sun.star.ui.dialogs.WizardButton import HELP -from ..unotool import createWindow -from ..unotool import getDialog +from com.sun.star.util.MeasureUnit import APPFONT + +from ...unotool import getContainerWindow +from ...unotool import getDialog +from ...unotool import getTopWindow -from ..configuration import g_identifier +from ...configuration import g_identifier import traceback class WizardView(unohelper.Base): - def __init__(self, ctx, handler, listener, parent, title, modal=True): + def __init__(self, ctx, handler, listener, listener1, parent, name, title, resize, point): self._name = 'Roadmap1' - #if not modal and parent is None: - # parent = createWindow(ctx, g_identifier, 'Wizard', title).getPeer() - self._dialog = getDialog(ctx, g_identifier, 'Wizard', handler, parent) + if name: + # XXX: We use a TOP XWindow + self._frame = getTopWindow(ctx, name) + peer = self._frame.getContainerWindow() + self._dialog = getContainerWindow(ctx, peer, handler, g_identifier, 'WizardTop') + # XXX: setComponent is needed if we want a StatusIndicator at the bottom + self._frame.setComponent(self._dialog, None) + self._frame.addCloseListener(listener) + else: + # XXX: We use a MODAL XDialog + self._frame = None + self._dialog = getDialog(ctx, g_identifier, 'Wizard', handler, parent) + self._point = point rectangle = uno.createUnoStruct('com.sun.star.awt.Rectangle', 0, 0, 85, 180) roadmap = self._getRoadmap(title, rectangle, 0) - roadmap.addItemListener(listener) + roadmap.addItemListener(listener1) self._button = {CANCEL: 1, FINISH: 2, NEXT: 3, PREVIOUS: 4, HELP: 5} self._spacer = 5 + if self._frame and not resize: + peer.setVisible(True) + self._dialog.setVisible(True) # WizardView getter methods + def isModal(self): + return self._frame is None + def getDialog(self): return self._dialog + def getDialogWindow(self): + if self._frame: + dialog = self._frame.getContainerWindow() + else: + dialog = self._dialog + return dialog + def getRoadmapModel(self): return self._getRoadmapControl().Model # WizardView setter methods def execute(self): - return self._dialog.execute() + if self._frame is None: + return self._dialog.execute() def endDialog(self, result): - self._dialog.endDialog(result) + if self._frame is None: + self._dialog.endDialog(result) - def dispose(self): - self._dialog.dispose() - self._dialog = None + def close(self): + if self._frame: + self._frame.close(True) - def isDisposed(self): - return self._dialog is None + def dispose(self): + if self._frame is None: + self._dialog.dispose() def setDialogTitle(self, title): - self._dialog.setTitle(title) + if self._frame: + self._frame.setTitle(title) + else: + self._dialog.setTitle(title) def setDialogSize(self, page): button = self._getButton(HELP).Model @@ -87,8 +123,21 @@ def setDialogSize(self, page): dialog.Height = button.PositionY + button.Height + self._spacer dialog.Width = page.PositionX + page.Width # We assume all buttons are named appropriately - for i in (1,2,3,4): + for i in (1, 2, 3, 4): self._setButtonPosition(i, button.PositionY, dialog.Width) + if self._frame: + window = self._frame.getContainerWindow() + size = self._dialog.convertSizeToPixel(Size(dialog.Width, dialog.Height), APPFONT) + if self._point: + point = self._dialog.convertPointToPixel(self._point, APPFONT) + possize = POSSIZE + else: + point = uno.createUnoStruct('com.sun.star.awt.Point', 0, 0) + possize = SIZE + window.setPosSize(point.X, point.Y, size.Width, size.Height, possize) + # XXX: Visibility should be done after size adjustment + window.setVisible(True) + self._dialog.setVisible(True) def enableHelpButton(self, enabled): self._getButton(HELP).Model.Enabled = enabled diff --git a/uno/rdb/idl/com/sun/star/task/XTaskEvent.idl b/uno/rdb/idl/com/sun/star/task/XTaskEvent.idl new file mode 100644 index 00000000..2223e66a --- /dev/null +++ b/uno/rdb/idl/com/sun/star/task/XTaskEvent.idl @@ -0,0 +1,49 @@ +/* +╔════════════════════════════════════════════════════════════════════════════════════╗ +β•‘ β•‘ +β•‘ Copyright (c) 2020-25 https://prrvchr.github.io β•‘ +β•‘ β•‘ +β•‘ Permission is hereby granted, free of charge, to any person obtaining β•‘ +β•‘ a copy of this software and associated documentation files (the "Software"), β•‘ +β•‘ to deal in the Software without restriction, including without limitation β•‘ +β•‘ the rights to use, copy, modify, merge, publish, distribute, sublicense, β•‘ +β•‘ and/or sell copies of the Software, and to permit persons to whom the Software β•‘ +β•‘ is furnished to do so, subject to the following conditions: β•‘ +β•‘ β•‘ +β•‘ The above copyright notice and this permission notice shall be included in β•‘ +β•‘ all copies or substantial portions of the Software. β•‘ +β•‘ β•‘ +β•‘ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, β•‘ +β•‘ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES β•‘ +β•‘ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. β•‘ +β•‘ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY β•‘ +β•‘ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, β•‘ +β•‘ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE β•‘ +β•‘ OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. β•‘ +β•‘ β•‘ +β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β• + */ + +#ifndef __com_sun_star_task_XTaskEvent_idl__ +#define __com_sun_star_task_XTaskEvent_idl__ + +#include + +module com { module sun { module star { module task { + +interface XTaskEvent : com::sun::star::uno::XInterface +{ + + boolean isSet(); + + void set(); + + void clear(); + + boolean wait([in] float Timeout); + +}; + +}; }; }; }; + +#endif From d46e9720194702074544e156dd8e4829a55d5224 Mon Sep 17 00:00:00 2001 From: prrvchr Date: Fri, 24 Oct 2025 12:03:52 +0200 Subject: [PATCH 05/11] new version 1.4.0 --- .github/FUNDING.yml | 3 + source/SQLiteOOo/Drivers.xcu | 175 +++++++++--------- source/SQLiteOOo/Options.xcs | 7 +- source/SQLiteOOo/Options.xcu | 5 +- source/SQLiteOOo/OptionsDialog.xcu | 57 +++--- source/SQLiteOOo/component-schema.dtd | 1 + source/SQLiteOOo/component-update.dtd | 1 + source/SQLiteOOo/dialogs/dialog.dtd | 1 + .../idl/com/sun/star/task/XTaskEvent.idl | 1 + source/SQLiteOOo/package.properties | 4 +- source/SQLiteOOo/service/OptionsHandler.py | 1 + .../service/pythonpath/sqlite/option | 1 - source/SQLiteOOo/types.rdb | Bin 910 -> 1097 bytes 13 files changed, 136 insertions(+), 121 deletions(-) create mode 100644 .github/FUNDING.yml create mode 120000 source/SQLiteOOo/component-schema.dtd create mode 120000 source/SQLiteOOo/component-update.dtd create mode 120000 source/SQLiteOOo/dialogs/dialog.dtd create mode 120000 source/SQLiteOOo/idl/com/sun/star/task/XTaskEvent.idl delete mode 120000 source/SQLiteOOo/service/pythonpath/sqlite/option diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 00000000..bcd5e647 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,3 @@ +# These are supported funding model platforms + +github: prrvchr diff --git a/source/SQLiteOOo/Drivers.xcu b/source/SQLiteOOo/Drivers.xcu index c6970224..f7d0f7bd 100644 --- a/source/SQLiteOOo/Drivers.xcu +++ b/source/SQLiteOOo/Drivers.xcu @@ -24,96 +24,99 @@ β•‘ β•‘ β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β• --> + - - - - io.github.prrvchr.SQLiteOOo.Driver - - - Embedded SQLite Driver - Pilote SQLite intΓ©grΓ© - - - - - true - - - - - true - - - - - PRIMARY KEY AUTOINCREMENT - - - - - - - - - - true - - - - - true - - - - - - - true - - - - - true - - - - - true - - - - - true - - - - - true - - - - - true - - - - - - - true - - - - - true - - - + + + + io.github.prrvchr.SQLiteOOo.Driver + + + Embedded SQLite Driver + Pilote SQLite intΓ©grΓ© + + + + + true + - + + + true + + + + + PRIMARY KEY AUTOINCREMENT + + + + + + + + + + true + + + + + true + + + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + + + true + + + + + true + + + + + + diff --git a/source/SQLiteOOo/Options.xcs b/source/SQLiteOOo/Options.xcs index a3709d84..af62942c 100644 --- a/source/SQLiteOOo/Options.xcs +++ b/source/SQLiteOOo/Options.xcs @@ -24,16 +24,17 @@ β•‘ β•‘ β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β• --> + + oor:name="SQLiteOOo" + xml:lang="en-US"> + diff --git a/source/SQLiteOOo/Options.xcu b/source/SQLiteOOo/Options.xcu index 8c34e60e..dd6878aa 100644 --- a/source/SQLiteOOo/Options.xcu +++ b/source/SQLiteOOo/Options.xcu @@ -24,11 +24,11 @@ β•‘ β•‘ β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β• --> + @@ -41,3 +41,4 @@ false + diff --git a/source/SQLiteOOo/OptionsDialog.xcu b/source/SQLiteOOo/OptionsDialog.xcu index e0c533a8..f3ab5a1d 100644 --- a/source/SQLiteOOo/OptionsDialog.xcu +++ b/source/SQLiteOOo/OptionsDialog.xcu @@ -23,38 +23,41 @@ β•‘ OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. β•‘ β•‘ β•‘ β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β• ---> + + - + + + + LibreOffice Base + LibreOffice Base + + + true + + - - LibreOffice Base - LibreOffice Base - - - true - - - - - io.github.prrvchr.SQLiteOOo - - - Embedded SQLite Driver - Pilote SQLite intΓ©grΓ© - - - %origin%/dialogs/OptionsDialog.xdl - - - io.github.prrvchr.SQLiteOOo.OptionsHandler - - - + + io.github.prrvchr.SQLiteOOo + + + Embedded SQLite Driver + Pilote SQLite intΓ©grΓ© + + + %origin%/dialogs/OptionsDialog.xdl + + + io.github.prrvchr.SQLiteOOo.OptionsHandler + + + + diff --git a/source/SQLiteOOo/component-schema.dtd b/source/SQLiteOOo/component-schema.dtd new file mode 120000 index 00000000..8bd8f795 --- /dev/null +++ b/source/SQLiteOOo/component-schema.dtd @@ -0,0 +1 @@ +../../uno/lib/uno/component-schema.dtd \ No newline at end of file diff --git a/source/SQLiteOOo/component-update.dtd b/source/SQLiteOOo/component-update.dtd new file mode 120000 index 00000000..90c5befb --- /dev/null +++ b/source/SQLiteOOo/component-update.dtd @@ -0,0 +1 @@ +../../uno/lib/uno/component-update.dtd \ No newline at end of file diff --git a/source/SQLiteOOo/dialogs/dialog.dtd b/source/SQLiteOOo/dialogs/dialog.dtd new file mode 120000 index 00000000..aee03339 --- /dev/null +++ b/source/SQLiteOOo/dialogs/dialog.dtd @@ -0,0 +1 @@ +../../../uno/dialog/dialog.dtd \ No newline at end of file diff --git a/source/SQLiteOOo/idl/com/sun/star/task/XTaskEvent.idl b/source/SQLiteOOo/idl/com/sun/star/task/XTaskEvent.idl new file mode 120000 index 00000000..04f9701c --- /dev/null +++ b/source/SQLiteOOo/idl/com/sun/star/task/XTaskEvent.idl @@ -0,0 +1 @@ +../../../../../../../uno/rdb/idl/com/sun/star/task/XTaskEvent.idl \ No newline at end of file diff --git a/source/SQLiteOOo/package.properties b/source/SQLiteOOo/package.properties index cab6b7cf..752a17c5 100644 --- a/source/SQLiteOOo/package.properties +++ b/source/SQLiteOOo/package.properties @@ -1,3 +1,3 @@ #Written by the OOEclipseIntegration -#Thu May 01 13:22:29 CEST 2025 -contents=description.xml, description/desc_en.txt, description/desc_fr.txt, dialogs/LogDialog.xdl, dialogs/LogDialog_en_US.default, dialogs/LogDialog_en_US.properties, dialogs/LogDialog_fr_FR.properties, dialogs/LogWindow.xdl, dialogs/LogWindow_en_US.default, dialogs/LogWindow_en_US.properties, dialogs/LogWindow_fr_FR.properties, dialogs/OptionDialog.xdl, dialogs/OptionDialog_en_US.default, dialogs/OptionDialog_en_US.properties, dialogs/OptionDialog_fr_FR.properties, dialogs/OptionsDialog.xdl, dialogs/OptionsDialog_en_US.default, dialogs/OptionsDialog_en_US.properties, dialogs/OptionsDialog_fr_FR.properties, Drivers.xcu, img/SQLiteOOo.svg, META-INF/manifest.xml, Options.xcs, Options.xcu, OptionsDialog.xcu, package.components, registration/TermsOfUse_en.md, registration/TermsOfUse_fr.md, requirements.txt, resource/Driver_en_US.default, resource/Driver_en_US.properties, resource/Driver_fr_FR.properties, resource/Logger_en_US.default, resource/Logger_en_US.properties, resource/Logger_fr_FR.properties, service/Driver.py, service/OptionsHandler.py, service/pythonpath/_distutils_hack/__init__.py, service/pythonpath/_distutils_hack/override.py, service/pythonpath/distutils-precedence.pth, service/pythonpath/packaging-25.0.dist-info/licenses/LICENSE, service/pythonpath/packaging-25.0.dist-info/licenses/LICENSE.APACHE, service/pythonpath/packaging-25.0.dist-info/licenses/LICENSE.BSD, service/pythonpath/packaging-25.0.dist-info/METADATA, service/pythonpath/packaging-25.0.dist-info/RECORD, service/pythonpath/packaging-25.0.dist-info/WHEEL, service/pythonpath/packaging/__init__.py, service/pythonpath/packaging/_elffile.py, service/pythonpath/packaging/_manylinux.py, service/pythonpath/packaging/_musllinux.py, service/pythonpath/packaging/_parser.py, service/pythonpath/packaging/_structures.py, service/pythonpath/packaging/_tokenizer.py, service/pythonpath/packaging/licenses/__init__.py, service/pythonpath/packaging/licenses/_spdx.py, service/pythonpath/packaging/markers.py, service/pythonpath/packaging/metadata.py, service/pythonpath/packaging/py.typed, service/pythonpath/packaging/requirements.py, service/pythonpath/packaging/specifiers.py, service/pythonpath/packaging/tags.py, service/pythonpath/packaging/utils.py, service/pythonpath/packaging/version.py, service/pythonpath/pkg_resources/__init__.py, service/pythonpath/pkg_resources/api_tests.txt, service/pythonpath/pkg_resources/py.typed, service/pythonpath/pkg_resources/tests/__init__.py, service/pythonpath/pkg_resources/tests/data/my-test-package-source/setup.cfg, service/pythonpath/pkg_resources/tests/data/my-test-package-source/setup.py, service/pythonpath/pkg_resources/tests/data/my-test-package-zip/my-test-package.zip, service/pythonpath/pkg_resources/tests/data/my-test-package_unpacked-egg/my_test_package-1.0-py3.7.egg/EGG-INFO/dependency_links.txt, service/pythonpath/pkg_resources/tests/data/my-test-package_unpacked-egg/my_test_package-1.0-py3.7.egg/EGG-INFO/PKG-INFO, service/pythonpath/pkg_resources/tests/data/my-test-package_unpacked-egg/my_test_package-1.0-py3.7.egg/EGG-INFO/SOURCES.txt, service/pythonpath/pkg_resources/tests/data/my-test-package_unpacked-egg/my_test_package-1.0-py3.7.egg/EGG-INFO/top_level.txt, service/pythonpath/pkg_resources/tests/data/my-test-package_unpacked-egg/my_test_package-1.0-py3.7.egg/EGG-INFO/zip-safe, service/pythonpath/pkg_resources/tests/data/my-test-package_zipped-egg/my_test_package-1.0-py3.7.egg, service/pythonpath/pkg_resources/tests/test_find_distributions.py, service/pythonpath/pkg_resources/tests/test_integration_zope_interface.py, service/pythonpath/pkg_resources/tests/test_markers.py, service/pythonpath/pkg_resources/tests/test_pkg_resources.py, service/pythonpath/pkg_resources/tests/test_resources.py, service/pythonpath/pkg_resources/tests/test_working_set.py, service/pythonpath/setuptools-75.3.2.dist-info/entry_points.txt, service/pythonpath/setuptools-75.3.2.dist-info/LICENSE, service/pythonpath/setuptools-75.3.2.dist-info/METADATA, service/pythonpath/setuptools-75.3.2.dist-info/RECORD, service/pythonpath/setuptools-75.3.2.dist-info/top_level.txt, service/pythonpath/setuptools-75.3.2.dist-info/WHEEL, service/pythonpath/setuptools/__init__.py, service/pythonpath/setuptools/_core_metadata.py, service/pythonpath/setuptools/_distutils/__init__.py, service/pythonpath/setuptools/_distutils/_log.py, service/pythonpath/setuptools/_distutils/_macos_compat.py, service/pythonpath/setuptools/_distutils/_modified.py, service/pythonpath/setuptools/_distutils/_msvccompiler.py, service/pythonpath/setuptools/_distutils/archive_util.py, service/pythonpath/setuptools/_distutils/ccompiler.py, service/pythonpath/setuptools/_distutils/cmd.py, service/pythonpath/setuptools/_distutils/command/__init__.py, service/pythonpath/setuptools/_distutils/command/_framework_compat.py, service/pythonpath/setuptools/_distutils/command/bdist.py, service/pythonpath/setuptools/_distutils/command/bdist_dumb.py, service/pythonpath/setuptools/_distutils/command/bdist_rpm.py, service/pythonpath/setuptools/_distutils/command/build.py, service/pythonpath/setuptools/_distutils/command/build_clib.py, service/pythonpath/setuptools/_distutils/command/build_ext.py, service/pythonpath/setuptools/_distutils/command/build_py.py, service/pythonpath/setuptools/_distutils/command/build_scripts.py, service/pythonpath/setuptools/_distutils/command/check.py, service/pythonpath/setuptools/_distutils/command/clean.py, service/pythonpath/setuptools/_distutils/command/config.py, service/pythonpath/setuptools/_distutils/command/install.py, service/pythonpath/setuptools/_distutils/command/install_data.py, service/pythonpath/setuptools/_distutils/command/install_egg_info.py, service/pythonpath/setuptools/_distutils/command/install_headers.py, service/pythonpath/setuptools/_distutils/command/install_lib.py, service/pythonpath/setuptools/_distutils/command/install_scripts.py, service/pythonpath/setuptools/_distutils/command/sdist.py, service/pythonpath/setuptools/_distutils/compat/__init__.py, service/pythonpath/setuptools/_distutils/compat/py38.py, service/pythonpath/setuptools/_distutils/compat/py39.py, service/pythonpath/setuptools/_distutils/core.py, service/pythonpath/setuptools/_distutils/cygwinccompiler.py, service/pythonpath/setuptools/_distutils/debug.py, service/pythonpath/setuptools/_distutils/dep_util.py, service/pythonpath/setuptools/_distutils/dir_util.py, service/pythonpath/setuptools/_distutils/dist.py, service/pythonpath/setuptools/_distutils/errors.py, service/pythonpath/setuptools/_distutils/extension.py, service/pythonpath/setuptools/_distutils/fancy_getopt.py, service/pythonpath/setuptools/_distutils/file_util.py, service/pythonpath/setuptools/_distutils/filelist.py, service/pythonpath/setuptools/_distutils/log.py, service/pythonpath/setuptools/_distutils/spawn.py, service/pythonpath/setuptools/_distutils/sysconfig.py, service/pythonpath/setuptools/_distutils/tests/__init__.py, service/pythonpath/setuptools/_distutils/tests/compat/__init__.py, service/pythonpath/setuptools/_distutils/tests/compat/py38.py, service/pythonpath/setuptools/_distutils/tests/support.py, service/pythonpath/setuptools/_distutils/tests/test_archive_util.py, service/pythonpath/setuptools/_distutils/tests/test_bdist.py, service/pythonpath/setuptools/_distutils/tests/test_bdist_dumb.py, service/pythonpath/setuptools/_distutils/tests/test_bdist_rpm.py, service/pythonpath/setuptools/_distutils/tests/test_build.py, service/pythonpath/setuptools/_distutils/tests/test_build_clib.py, service/pythonpath/setuptools/_distutils/tests/test_build_ext.py, service/pythonpath/setuptools/_distutils/tests/test_build_py.py, service/pythonpath/setuptools/_distutils/tests/test_build_scripts.py, service/pythonpath/setuptools/_distutils/tests/test_ccompiler.py, service/pythonpath/setuptools/_distutils/tests/test_check.py, service/pythonpath/setuptools/_distutils/tests/test_clean.py, service/pythonpath/setuptools/_distutils/tests/test_cmd.py, service/pythonpath/setuptools/_distutils/tests/test_config_cmd.py, service/pythonpath/setuptools/_distutils/tests/test_core.py, service/pythonpath/setuptools/_distutils/tests/test_cygwinccompiler.py, service/pythonpath/setuptools/_distutils/tests/test_dir_util.py, service/pythonpath/setuptools/_distutils/tests/test_dist.py, service/pythonpath/setuptools/_distutils/tests/test_extension.py, service/pythonpath/setuptools/_distutils/tests/test_file_util.py, service/pythonpath/setuptools/_distutils/tests/test_filelist.py, service/pythonpath/setuptools/_distutils/tests/test_install.py, service/pythonpath/setuptools/_distutils/tests/test_install_data.py, service/pythonpath/setuptools/_distutils/tests/test_install_headers.py, service/pythonpath/setuptools/_distutils/tests/test_install_lib.py, service/pythonpath/setuptools/_distutils/tests/test_install_scripts.py, service/pythonpath/setuptools/_distutils/tests/test_log.py, service/pythonpath/setuptools/_distutils/tests/test_mingwccompiler.py, service/pythonpath/setuptools/_distutils/tests/test_modified.py, service/pythonpath/setuptools/_distutils/tests/test_msvccompiler.py, service/pythonpath/setuptools/_distutils/tests/test_sdist.py, service/pythonpath/setuptools/_distutils/tests/test_spawn.py, service/pythonpath/setuptools/_distutils/tests/test_sysconfig.py, service/pythonpath/setuptools/_distutils/tests/test_text_file.py, service/pythonpath/setuptools/_distutils/tests/test_unixccompiler.py, service/pythonpath/setuptools/_distutils/tests/test_util.py, service/pythonpath/setuptools/_distutils/tests/test_version.py, service/pythonpath/setuptools/_distutils/tests/test_versionpredicate.py, service/pythonpath/setuptools/_distutils/tests/unix_compat.py, service/pythonpath/setuptools/_distutils/text_file.py, service/pythonpath/setuptools/_distutils/unixccompiler.py, service/pythonpath/setuptools/_distutils/util.py, service/pythonpath/setuptools/_distutils/version.py, service/pythonpath/setuptools/_distutils/versionpredicate.py, service/pythonpath/setuptools/_distutils/zosccompiler.py, service/pythonpath/setuptools/_entry_points.py, service/pythonpath/setuptools/_imp.py, service/pythonpath/setuptools/_importlib.py, service/pythonpath/setuptools/_itertools.py, service/pythonpath/setuptools/_normalization.py, service/pythonpath/setuptools/_path.py, service/pythonpath/setuptools/_reqs.py, service/pythonpath/setuptools/_vendor/autocommand-2.2.2.dist-info/INSTALLER, service/pythonpath/setuptools/_vendor/autocommand-2.2.2.dist-info/LICENSE, service/pythonpath/setuptools/_vendor/autocommand-2.2.2.dist-info/METADATA, service/pythonpath/setuptools/_vendor/autocommand-2.2.2.dist-info/RECORD, service/pythonpath/setuptools/_vendor/autocommand-2.2.2.dist-info/top_level.txt, service/pythonpath/setuptools/_vendor/autocommand-2.2.2.dist-info/WHEEL, service/pythonpath/setuptools/_vendor/autocommand/__init__.py, service/pythonpath/setuptools/_vendor/autocommand/autoasync.py, service/pythonpath/setuptools/_vendor/autocommand/autocommand.py, service/pythonpath/setuptools/_vendor/autocommand/automain.py, service/pythonpath/setuptools/_vendor/autocommand/autoparse.py, service/pythonpath/setuptools/_vendor/autocommand/errors.py, service/pythonpath/setuptools/_vendor/backports.tarfile-1.2.0.dist-info/INSTALLER, service/pythonpath/setuptools/_vendor/backports.tarfile-1.2.0.dist-info/LICENSE, service/pythonpath/setuptools/_vendor/backports.tarfile-1.2.0.dist-info/METADATA, service/pythonpath/setuptools/_vendor/backports.tarfile-1.2.0.dist-info/RECORD, service/pythonpath/setuptools/_vendor/backports.tarfile-1.2.0.dist-info/REQUESTED, service/pythonpath/setuptools/_vendor/backports.tarfile-1.2.0.dist-info/top_level.txt, service/pythonpath/setuptools/_vendor/backports.tarfile-1.2.0.dist-info/WHEEL, service/pythonpath/setuptools/_vendor/backports/__init__.py, service/pythonpath/setuptools/_vendor/backports/tarfile/__init__.py, service/pythonpath/setuptools/_vendor/backports/tarfile/__main__.py, service/pythonpath/setuptools/_vendor/backports/tarfile/compat/__init__.py, service/pythonpath/setuptools/_vendor/backports/tarfile/compat/py38.py, service/pythonpath/setuptools/_vendor/importlib_metadata-8.0.0.dist-info/INSTALLER, service/pythonpath/setuptools/_vendor/importlib_metadata-8.0.0.dist-info/LICENSE, service/pythonpath/setuptools/_vendor/importlib_metadata-8.0.0.dist-info/METADATA, service/pythonpath/setuptools/_vendor/importlib_metadata-8.0.0.dist-info/RECORD, service/pythonpath/setuptools/_vendor/importlib_metadata-8.0.0.dist-info/REQUESTED, service/pythonpath/setuptools/_vendor/importlib_metadata-8.0.0.dist-info/top_level.txt, service/pythonpath/setuptools/_vendor/importlib_metadata-8.0.0.dist-info/WHEEL, service/pythonpath/setuptools/_vendor/importlib_metadata/__init__.py, service/pythonpath/setuptools/_vendor/importlib_metadata/_adapters.py, service/pythonpath/setuptools/_vendor/importlib_metadata/_collections.py, service/pythonpath/setuptools/_vendor/importlib_metadata/_compat.py, service/pythonpath/setuptools/_vendor/importlib_metadata/_functools.py, service/pythonpath/setuptools/_vendor/importlib_metadata/_itertools.py, service/pythonpath/setuptools/_vendor/importlib_metadata/_meta.py, service/pythonpath/setuptools/_vendor/importlib_metadata/_text.py, service/pythonpath/setuptools/_vendor/importlib_metadata/compat/__init__.py, service/pythonpath/setuptools/_vendor/importlib_metadata/compat/py311.py, service/pythonpath/setuptools/_vendor/importlib_metadata/compat/py39.py, service/pythonpath/setuptools/_vendor/importlib_metadata/diagnose.py, service/pythonpath/setuptools/_vendor/importlib_metadata/py.typed, service/pythonpath/setuptools/_vendor/importlib_resources-6.4.0.dist-info/INSTALLER, service/pythonpath/setuptools/_vendor/importlib_resources-6.4.0.dist-info/LICENSE, service/pythonpath/setuptools/_vendor/importlib_resources-6.4.0.dist-info/METADATA, service/pythonpath/setuptools/_vendor/importlib_resources-6.4.0.dist-info/RECORD, service/pythonpath/setuptools/_vendor/importlib_resources-6.4.0.dist-info/REQUESTED, service/pythonpath/setuptools/_vendor/importlib_resources-6.4.0.dist-info/top_level.txt, service/pythonpath/setuptools/_vendor/importlib_resources-6.4.0.dist-info/WHEEL, service/pythonpath/setuptools/_vendor/importlib_resources/__init__.py, service/pythonpath/setuptools/_vendor/importlib_resources/_adapters.py, service/pythonpath/setuptools/_vendor/importlib_resources/_common.py, service/pythonpath/setuptools/_vendor/importlib_resources/_itertools.py, service/pythonpath/setuptools/_vendor/importlib_resources/abc.py, service/pythonpath/setuptools/_vendor/importlib_resources/compat/__init__.py, service/pythonpath/setuptools/_vendor/importlib_resources/compat/py38.py, service/pythonpath/setuptools/_vendor/importlib_resources/compat/py39.py, service/pythonpath/setuptools/_vendor/importlib_resources/functional.py, service/pythonpath/setuptools/_vendor/importlib_resources/future/__init__.py, service/pythonpath/setuptools/_vendor/importlib_resources/future/adapters.py, service/pythonpath/setuptools/_vendor/importlib_resources/py.typed, service/pythonpath/setuptools/_vendor/importlib_resources/readers.py, service/pythonpath/setuptools/_vendor/importlib_resources/simple.py, service/pythonpath/setuptools/_vendor/importlib_resources/tests/__init__.py, service/pythonpath/setuptools/_vendor/importlib_resources/tests/_path.py, service/pythonpath/setuptools/_vendor/importlib_resources/tests/compat/__init__.py, service/pythonpath/setuptools/_vendor/importlib_resources/tests/compat/py312.py, service/pythonpath/setuptools/_vendor/importlib_resources/tests/compat/py39.py, service/pythonpath/setuptools/_vendor/importlib_resources/tests/data01/__init__.py, service/pythonpath/setuptools/_vendor/importlib_resources/tests/data01/binary.file, service/pythonpath/setuptools/_vendor/importlib_resources/tests/data01/subdirectory/__init__.py, service/pythonpath/setuptools/_vendor/importlib_resources/tests/data01/subdirectory/binary.file, service/pythonpath/setuptools/_vendor/importlib_resources/tests/data01/utf-16.file, service/pythonpath/setuptools/_vendor/importlib_resources/tests/data01/utf-8.file, service/pythonpath/setuptools/_vendor/importlib_resources/tests/data02/__init__.py, service/pythonpath/setuptools/_vendor/importlib_resources/tests/data02/one/__init__.py, service/pythonpath/setuptools/_vendor/importlib_resources/tests/data02/one/resource1.txt, service/pythonpath/setuptools/_vendor/importlib_resources/tests/data02/subdirectory/subsubdir/resource.txt, service/pythonpath/setuptools/_vendor/importlib_resources/tests/data02/two/__init__.py, service/pythonpath/setuptools/_vendor/importlib_resources/tests/data02/two/resource2.txt, service/pythonpath/setuptools/_vendor/importlib_resources/tests/namespacedata01/binary.file, service/pythonpath/setuptools/_vendor/importlib_resources/tests/namespacedata01/subdirectory/binary.file, service/pythonpath/setuptools/_vendor/importlib_resources/tests/namespacedata01/utf-16.file, service/pythonpath/setuptools/_vendor/importlib_resources/tests/namespacedata01/utf-8.file, service/pythonpath/setuptools/_vendor/importlib_resources/tests/test_compatibilty_files.py, service/pythonpath/setuptools/_vendor/importlib_resources/tests/test_contents.py, service/pythonpath/setuptools/_vendor/importlib_resources/tests/test_custom.py, service/pythonpath/setuptools/_vendor/importlib_resources/tests/test_files.py, service/pythonpath/setuptools/_vendor/importlib_resources/tests/test_functional.py, service/pythonpath/setuptools/_vendor/importlib_resources/tests/test_open.py, service/pythonpath/setuptools/_vendor/importlib_resources/tests/test_path.py, service/pythonpath/setuptools/_vendor/importlib_resources/tests/test_read.py, service/pythonpath/setuptools/_vendor/importlib_resources/tests/test_reader.py, service/pythonpath/setuptools/_vendor/importlib_resources/tests/test_resource.py, service/pythonpath/setuptools/_vendor/importlib_resources/tests/util.py, service/pythonpath/setuptools/_vendor/importlib_resources/tests/zip.py, service/pythonpath/setuptools/_vendor/inflect-7.3.1.dist-info/INSTALLER, service/pythonpath/setuptools/_vendor/inflect-7.3.1.dist-info/LICENSE, service/pythonpath/setuptools/_vendor/inflect-7.3.1.dist-info/METADATA, service/pythonpath/setuptools/_vendor/inflect-7.3.1.dist-info/RECORD, service/pythonpath/setuptools/_vendor/inflect-7.3.1.dist-info/top_level.txt, service/pythonpath/setuptools/_vendor/inflect-7.3.1.dist-info/WHEEL, service/pythonpath/setuptools/_vendor/inflect/__init__.py, service/pythonpath/setuptools/_vendor/inflect/compat/__init__.py, service/pythonpath/setuptools/_vendor/inflect/compat/py38.py, service/pythonpath/setuptools/_vendor/inflect/py.typed, service/pythonpath/setuptools/_vendor/jaraco.collections-5.1.0.dist-info/INSTALLER, service/pythonpath/setuptools/_vendor/jaraco.collections-5.1.0.dist-info/LICENSE, service/pythonpath/setuptools/_vendor/jaraco.collections-5.1.0.dist-info/METADATA, service/pythonpath/setuptools/_vendor/jaraco.collections-5.1.0.dist-info/RECORD, service/pythonpath/setuptools/_vendor/jaraco.collections-5.1.0.dist-info/REQUESTED, service/pythonpath/setuptools/_vendor/jaraco.collections-5.1.0.dist-info/top_level.txt, service/pythonpath/setuptools/_vendor/jaraco.collections-5.1.0.dist-info/WHEEL, service/pythonpath/setuptools/_vendor/jaraco.context-5.3.0.dist-info/INSTALLER, service/pythonpath/setuptools/_vendor/jaraco.context-5.3.0.dist-info/LICENSE, service/pythonpath/setuptools/_vendor/jaraco.context-5.3.0.dist-info/METADATA, service/pythonpath/setuptools/_vendor/jaraco.context-5.3.0.dist-info/RECORD, service/pythonpath/setuptools/_vendor/jaraco.context-5.3.0.dist-info/top_level.txt, service/pythonpath/setuptools/_vendor/jaraco.context-5.3.0.dist-info/WHEEL, service/pythonpath/setuptools/_vendor/jaraco.functools-4.0.1.dist-info/INSTALLER, service/pythonpath/setuptools/_vendor/jaraco.functools-4.0.1.dist-info/LICENSE, service/pythonpath/setuptools/_vendor/jaraco.functools-4.0.1.dist-info/METADATA, service/pythonpath/setuptools/_vendor/jaraco.functools-4.0.1.dist-info/RECORD, service/pythonpath/setuptools/_vendor/jaraco.functools-4.0.1.dist-info/top_level.txt, service/pythonpath/setuptools/_vendor/jaraco.functools-4.0.1.dist-info/WHEEL, service/pythonpath/setuptools/_vendor/jaraco.text-3.12.1.dist-info/INSTALLER, service/pythonpath/setuptools/_vendor/jaraco.text-3.12.1.dist-info/LICENSE, service/pythonpath/setuptools/_vendor/jaraco.text-3.12.1.dist-info/METADATA, service/pythonpath/setuptools/_vendor/jaraco.text-3.12.1.dist-info/RECORD, service/pythonpath/setuptools/_vendor/jaraco.text-3.12.1.dist-info/REQUESTED, service/pythonpath/setuptools/_vendor/jaraco.text-3.12.1.dist-info/top_level.txt, service/pythonpath/setuptools/_vendor/jaraco.text-3.12.1.dist-info/WHEEL, service/pythonpath/setuptools/_vendor/jaraco/collections/__init__.py, service/pythonpath/setuptools/_vendor/jaraco/collections/py.typed, service/pythonpath/setuptools/_vendor/jaraco/context.py, service/pythonpath/setuptools/_vendor/jaraco/functools/__init__.py, service/pythonpath/setuptools/_vendor/jaraco/functools/__init__.pyi, service/pythonpath/setuptools/_vendor/jaraco/functools/py.typed, service/pythonpath/setuptools/_vendor/jaraco/text/__init__.py, service/pythonpath/setuptools/_vendor/jaraco/text/layouts.py, service/pythonpath/setuptools/_vendor/jaraco/text/Lorem ipsum.txt, service/pythonpath/setuptools/_vendor/jaraco/text/show-newlines.py, service/pythonpath/setuptools/_vendor/jaraco/text/strip-prefix.py, service/pythonpath/setuptools/_vendor/jaraco/text/to-dvorak.py, service/pythonpath/setuptools/_vendor/jaraco/text/to-qwerty.py, service/pythonpath/setuptools/_vendor/more_itertools-10.3.0.dist-info/INSTALLER, service/pythonpath/setuptools/_vendor/more_itertools-10.3.0.dist-info/LICENSE, service/pythonpath/setuptools/_vendor/more_itertools-10.3.0.dist-info/METADATA, service/pythonpath/setuptools/_vendor/more_itertools-10.3.0.dist-info/RECORD, service/pythonpath/setuptools/_vendor/more_itertools-10.3.0.dist-info/REQUESTED, service/pythonpath/setuptools/_vendor/more_itertools-10.3.0.dist-info/WHEEL, service/pythonpath/setuptools/_vendor/more_itertools/__init__.py, service/pythonpath/setuptools/_vendor/more_itertools/__init__.pyi, service/pythonpath/setuptools/_vendor/more_itertools/more.py, service/pythonpath/setuptools/_vendor/more_itertools/more.pyi, service/pythonpath/setuptools/_vendor/more_itertools/py.typed, service/pythonpath/setuptools/_vendor/more_itertools/recipes.py, service/pythonpath/setuptools/_vendor/more_itertools/recipes.pyi, service/pythonpath/setuptools/_vendor/packaging-24.1.dist-info/INSTALLER, service/pythonpath/setuptools/_vendor/packaging-24.1.dist-info/LICENSE, service/pythonpath/setuptools/_vendor/packaging-24.1.dist-info/LICENSE.APACHE, service/pythonpath/setuptools/_vendor/packaging-24.1.dist-info/LICENSE.BSD, service/pythonpath/setuptools/_vendor/packaging-24.1.dist-info/METADATA, service/pythonpath/setuptools/_vendor/packaging-24.1.dist-info/RECORD, service/pythonpath/setuptools/_vendor/packaging-24.1.dist-info/REQUESTED, service/pythonpath/setuptools/_vendor/packaging-24.1.dist-info/WHEEL, service/pythonpath/setuptools/_vendor/packaging/__init__.py, service/pythonpath/setuptools/_vendor/packaging/_elffile.py, service/pythonpath/setuptools/_vendor/packaging/_manylinux.py, service/pythonpath/setuptools/_vendor/packaging/_musllinux.py, service/pythonpath/setuptools/_vendor/packaging/_parser.py, service/pythonpath/setuptools/_vendor/packaging/_structures.py, service/pythonpath/setuptools/_vendor/packaging/_tokenizer.py, service/pythonpath/setuptools/_vendor/packaging/markers.py, service/pythonpath/setuptools/_vendor/packaging/metadata.py, service/pythonpath/setuptools/_vendor/packaging/py.typed, service/pythonpath/setuptools/_vendor/packaging/requirements.py, service/pythonpath/setuptools/_vendor/packaging/specifiers.py, service/pythonpath/setuptools/_vendor/packaging/tags.py, service/pythonpath/setuptools/_vendor/packaging/utils.py, service/pythonpath/setuptools/_vendor/packaging/version.py, service/pythonpath/setuptools/_vendor/platformdirs-4.2.2.dist-info/INSTALLER, service/pythonpath/setuptools/_vendor/platformdirs-4.2.2.dist-info/licenses/LICENSE, service/pythonpath/setuptools/_vendor/platformdirs-4.2.2.dist-info/METADATA, service/pythonpath/setuptools/_vendor/platformdirs-4.2.2.dist-info/RECORD, service/pythonpath/setuptools/_vendor/platformdirs-4.2.2.dist-info/REQUESTED, service/pythonpath/setuptools/_vendor/platformdirs-4.2.2.dist-info/WHEEL, service/pythonpath/setuptools/_vendor/platformdirs/__init__.py, service/pythonpath/setuptools/_vendor/platformdirs/__main__.py, service/pythonpath/setuptools/_vendor/platformdirs/android.py, service/pythonpath/setuptools/_vendor/platformdirs/api.py, service/pythonpath/setuptools/_vendor/platformdirs/macos.py, service/pythonpath/setuptools/_vendor/platformdirs/py.typed, service/pythonpath/setuptools/_vendor/platformdirs/unix.py, service/pythonpath/setuptools/_vendor/platformdirs/version.py, service/pythonpath/setuptools/_vendor/platformdirs/windows.py, service/pythonpath/setuptools/_vendor/ruff.toml, service/pythonpath/setuptools/_vendor/tomli-2.0.1.dist-info/INSTALLER, service/pythonpath/setuptools/_vendor/tomli-2.0.1.dist-info/LICENSE, service/pythonpath/setuptools/_vendor/tomli-2.0.1.dist-info/METADATA, service/pythonpath/setuptools/_vendor/tomli-2.0.1.dist-info/RECORD, service/pythonpath/setuptools/_vendor/tomli-2.0.1.dist-info/REQUESTED, service/pythonpath/setuptools/_vendor/tomli-2.0.1.dist-info/WHEEL, service/pythonpath/setuptools/_vendor/tomli/__init__.py, service/pythonpath/setuptools/_vendor/tomli/_parser.py, service/pythonpath/setuptools/_vendor/tomli/_re.py, service/pythonpath/setuptools/_vendor/tomli/_types.py, service/pythonpath/setuptools/_vendor/tomli/py.typed, service/pythonpath/setuptools/_vendor/typeguard-4.3.0.dist-info/entry_points.txt, service/pythonpath/setuptools/_vendor/typeguard-4.3.0.dist-info/INSTALLER, service/pythonpath/setuptools/_vendor/typeguard-4.3.0.dist-info/LICENSE, service/pythonpath/setuptools/_vendor/typeguard-4.3.0.dist-info/METADATA, service/pythonpath/setuptools/_vendor/typeguard-4.3.0.dist-info/RECORD, service/pythonpath/setuptools/_vendor/typeguard-4.3.0.dist-info/top_level.txt, service/pythonpath/setuptools/_vendor/typeguard-4.3.0.dist-info/WHEEL, service/pythonpath/setuptools/_vendor/typeguard/__init__.py, service/pythonpath/setuptools/_vendor/typeguard/_checkers.py, service/pythonpath/setuptools/_vendor/typeguard/_config.py, service/pythonpath/setuptools/_vendor/typeguard/_decorators.py, service/pythonpath/setuptools/_vendor/typeguard/_exceptions.py, service/pythonpath/setuptools/_vendor/typeguard/_functions.py, service/pythonpath/setuptools/_vendor/typeguard/_importhook.py, service/pythonpath/setuptools/_vendor/typeguard/_memo.py, service/pythonpath/setuptools/_vendor/typeguard/_pytest_plugin.py, service/pythonpath/setuptools/_vendor/typeguard/_suppression.py, service/pythonpath/setuptools/_vendor/typeguard/_transformer.py, service/pythonpath/setuptools/_vendor/typeguard/_union_transformer.py, service/pythonpath/setuptools/_vendor/typeguard/_utils.py, service/pythonpath/setuptools/_vendor/typeguard/py.typed, service/pythonpath/setuptools/_vendor/typing_extensions-4.12.2.dist-info/INSTALLER, service/pythonpath/setuptools/_vendor/typing_extensions-4.12.2.dist-info/LICENSE, service/pythonpath/setuptools/_vendor/typing_extensions-4.12.2.dist-info/METADATA, service/pythonpath/setuptools/_vendor/typing_extensions-4.12.2.dist-info/RECORD, service/pythonpath/setuptools/_vendor/typing_extensions-4.12.2.dist-info/WHEEL, service/pythonpath/setuptools/_vendor/typing_extensions.py, service/pythonpath/setuptools/_vendor/wheel-0.43.0.dist-info/entry_points.txt, service/pythonpath/setuptools/_vendor/wheel-0.43.0.dist-info/INSTALLER, service/pythonpath/setuptools/_vendor/wheel-0.43.0.dist-info/LICENSE.txt, service/pythonpath/setuptools/_vendor/wheel-0.43.0.dist-info/METADATA, service/pythonpath/setuptools/_vendor/wheel-0.43.0.dist-info/RECORD, service/pythonpath/setuptools/_vendor/wheel-0.43.0.dist-info/REQUESTED, service/pythonpath/setuptools/_vendor/wheel-0.43.0.dist-info/WHEEL, service/pythonpath/setuptools/_vendor/wheel/__init__.py, service/pythonpath/setuptools/_vendor/wheel/__main__.py, service/pythonpath/setuptools/_vendor/wheel/_setuptools_logging.py, service/pythonpath/setuptools/_vendor/wheel/bdist_wheel.py, service/pythonpath/setuptools/_vendor/wheel/cli/__init__.py, service/pythonpath/setuptools/_vendor/wheel/cli/convert.py, service/pythonpath/setuptools/_vendor/wheel/cli/pack.py, service/pythonpath/setuptools/_vendor/wheel/cli/tags.py, service/pythonpath/setuptools/_vendor/wheel/cli/unpack.py, service/pythonpath/setuptools/_vendor/wheel/macosx_libfile.py, service/pythonpath/setuptools/_vendor/wheel/metadata.py, service/pythonpath/setuptools/_vendor/wheel/util.py, service/pythonpath/setuptools/_vendor/wheel/vendored/__init__.py, service/pythonpath/setuptools/_vendor/wheel/vendored/packaging/__init__.py, service/pythonpath/setuptools/_vendor/wheel/vendored/packaging/_elffile.py, service/pythonpath/setuptools/_vendor/wheel/vendored/packaging/_manylinux.py, service/pythonpath/setuptools/_vendor/wheel/vendored/packaging/_musllinux.py, service/pythonpath/setuptools/_vendor/wheel/vendored/packaging/_parser.py, service/pythonpath/setuptools/_vendor/wheel/vendored/packaging/_structures.py, service/pythonpath/setuptools/_vendor/wheel/vendored/packaging/_tokenizer.py, service/pythonpath/setuptools/_vendor/wheel/vendored/packaging/markers.py, service/pythonpath/setuptools/_vendor/wheel/vendored/packaging/requirements.py, service/pythonpath/setuptools/_vendor/wheel/vendored/packaging/specifiers.py, service/pythonpath/setuptools/_vendor/wheel/vendored/packaging/tags.py, service/pythonpath/setuptools/_vendor/wheel/vendored/packaging/utils.py, service/pythonpath/setuptools/_vendor/wheel/vendored/packaging/version.py, service/pythonpath/setuptools/_vendor/wheel/vendored/vendor.txt, service/pythonpath/setuptools/_vendor/wheel/wheelfile.py, service/pythonpath/setuptools/_vendor/zipp-3.19.2.dist-info/INSTALLER, service/pythonpath/setuptools/_vendor/zipp-3.19.2.dist-info/LICENSE, service/pythonpath/setuptools/_vendor/zipp-3.19.2.dist-info/METADATA, service/pythonpath/setuptools/_vendor/zipp-3.19.2.dist-info/RECORD, service/pythonpath/setuptools/_vendor/zipp-3.19.2.dist-info/REQUESTED, service/pythonpath/setuptools/_vendor/zipp-3.19.2.dist-info/top_level.txt, service/pythonpath/setuptools/_vendor/zipp-3.19.2.dist-info/WHEEL, service/pythonpath/setuptools/_vendor/zipp/__init__.py, service/pythonpath/setuptools/_vendor/zipp/compat/__init__.py, service/pythonpath/setuptools/_vendor/zipp/compat/py310.py, service/pythonpath/setuptools/_vendor/zipp/glob.py, service/pythonpath/setuptools/archive_util.py, service/pythonpath/setuptools/build_meta.py, service/pythonpath/setuptools/cli-32.exe, service/pythonpath/setuptools/cli-64.exe, service/pythonpath/setuptools/cli-arm64.exe, service/pythonpath/setuptools/cli.exe, service/pythonpath/setuptools/command/__init__.py, service/pythonpath/setuptools/command/_requirestxt.py, service/pythonpath/setuptools/command/alias.py, service/pythonpath/setuptools/command/bdist_egg.py, service/pythonpath/setuptools/command/bdist_rpm.py, service/pythonpath/setuptools/command/bdist_wheel.py, service/pythonpath/setuptools/command/build.py, service/pythonpath/setuptools/command/build_clib.py, service/pythonpath/setuptools/command/build_ext.py, service/pythonpath/setuptools/command/build_py.py, service/pythonpath/setuptools/command/develop.py, service/pythonpath/setuptools/command/dist_info.py, service/pythonpath/setuptools/command/easy_install.py, service/pythonpath/setuptools/command/editable_wheel.py, service/pythonpath/setuptools/command/egg_info.py, service/pythonpath/setuptools/command/install.py, service/pythonpath/setuptools/command/install_egg_info.py, service/pythonpath/setuptools/command/install_lib.py, service/pythonpath/setuptools/command/install_scripts.py, service/pythonpath/setuptools/command/launcher manifest.xml, service/pythonpath/setuptools/command/rotate.py, service/pythonpath/setuptools/command/saveopts.py, service/pythonpath/setuptools/command/sdist.py, service/pythonpath/setuptools/command/setopt.py, service/pythonpath/setuptools/command/test.py, service/pythonpath/setuptools/compat/__init__.py, service/pythonpath/setuptools/compat/py310.py, service/pythonpath/setuptools/compat/py311.py, service/pythonpath/setuptools/compat/py312.py, service/pythonpath/setuptools/compat/py39.py, service/pythonpath/setuptools/config/__init__.py, service/pythonpath/setuptools/config/_apply_pyprojecttoml.py, service/pythonpath/setuptools/config/_validate_pyproject/__init__.py, service/pythonpath/setuptools/config/_validate_pyproject/error_reporting.py, service/pythonpath/setuptools/config/_validate_pyproject/extra_validations.py, service/pythonpath/setuptools/config/_validate_pyproject/fastjsonschema_exceptions.py, service/pythonpath/setuptools/config/_validate_pyproject/fastjsonschema_validations.py, service/pythonpath/setuptools/config/_validate_pyproject/formats.py, service/pythonpath/setuptools/config/_validate_pyproject/NOTICE, service/pythonpath/setuptools/config/distutils.schema.json, service/pythonpath/setuptools/config/expand.py, service/pythonpath/setuptools/config/NOTICE, service/pythonpath/setuptools/config/pyprojecttoml.py, service/pythonpath/setuptools/config/setupcfg.py, service/pythonpath/setuptools/config/setuptools.schema.json, service/pythonpath/setuptools/depends.py, service/pythonpath/setuptools/discovery.py, service/pythonpath/setuptools/dist.py, service/pythonpath/setuptools/errors.py, service/pythonpath/setuptools/extension.py, service/pythonpath/setuptools/glob.py, service/pythonpath/setuptools/gui-32.exe, service/pythonpath/setuptools/gui-64.exe, service/pythonpath/setuptools/gui-arm64.exe, service/pythonpath/setuptools/gui.exe, service/pythonpath/setuptools/installer.py, service/pythonpath/setuptools/launch.py, service/pythonpath/setuptools/logging.py, service/pythonpath/setuptools/modified.py, service/pythonpath/setuptools/monkey.py, service/pythonpath/setuptools/msvc.py, service/pythonpath/setuptools/namespaces.py, service/pythonpath/setuptools/package_index.py, service/pythonpath/setuptools/sandbox.py, service/pythonpath/setuptools/script (dev).tmpl, service/pythonpath/setuptools/script.tmpl, service/pythonpath/setuptools/tests/__init__.py, service/pythonpath/setuptools/tests/compat/__init__.py, service/pythonpath/setuptools/tests/compat/py39.py, service/pythonpath/setuptools/tests/config/__init__.py, service/pythonpath/setuptools/tests/config/downloads/__init__.py, service/pythonpath/setuptools/tests/config/downloads/preload.py, service/pythonpath/setuptools/tests/config/setupcfg_examples.txt, service/pythonpath/setuptools/tests/config/test_apply_pyprojecttoml.py, service/pythonpath/setuptools/tests/config/test_expand.py, service/pythonpath/setuptools/tests/config/test_pyprojecttoml.py, service/pythonpath/setuptools/tests/config/test_pyprojecttoml_dynamic_deps.py, service/pythonpath/setuptools/tests/config/test_setupcfg.py, service/pythonpath/setuptools/tests/contexts.py, service/pythonpath/setuptools/tests/environment.py, service/pythonpath/setuptools/tests/fixtures.py, service/pythonpath/setuptools/tests/indexes/test_links_priority/external.html, service/pythonpath/setuptools/tests/indexes/test_links_priority/simple/foobar/index.html, service/pythonpath/setuptools/tests/integration/__init__.py, service/pythonpath/setuptools/tests/integration/helpers.py, service/pythonpath/setuptools/tests/integration/test_pip_install_sdist.py, service/pythonpath/setuptools/tests/mod_with_constant.py, service/pythonpath/setuptools/tests/namespaces.py, service/pythonpath/setuptools/tests/script-with-bom.py, service/pythonpath/setuptools/tests/server.py, service/pythonpath/setuptools/tests/test_archive_util.py, service/pythonpath/setuptools/tests/test_bdist_deprecations.py, service/pythonpath/setuptools/tests/test_bdist_egg.py, service/pythonpath/setuptools/tests/test_bdist_wheel.py, service/pythonpath/setuptools/tests/test_build.py, service/pythonpath/setuptools/tests/test_build_clib.py, service/pythonpath/setuptools/tests/test_build_ext.py, service/pythonpath/setuptools/tests/test_build_meta.py, service/pythonpath/setuptools/tests/test_build_py.py, service/pythonpath/setuptools/tests/test_config_discovery.py, service/pythonpath/setuptools/tests/test_core_metadata.py, service/pythonpath/setuptools/tests/test_depends.py, service/pythonpath/setuptools/tests/test_develop.py, service/pythonpath/setuptools/tests/test_dist.py, service/pythonpath/setuptools/tests/test_dist_info.py, service/pythonpath/setuptools/tests/test_distutils_adoption.py, service/pythonpath/setuptools/tests/test_easy_install.py, service/pythonpath/setuptools/tests/test_editable_install.py, service/pythonpath/setuptools/tests/test_egg_info.py, service/pythonpath/setuptools/tests/test_extern.py, service/pythonpath/setuptools/tests/test_find_packages.py, service/pythonpath/setuptools/tests/test_find_py_modules.py, service/pythonpath/setuptools/tests/test_glob.py, service/pythonpath/setuptools/tests/test_install_scripts.py, service/pythonpath/setuptools/tests/test_logging.py, service/pythonpath/setuptools/tests/test_manifest.py, service/pythonpath/setuptools/tests/test_namespaces.py, service/pythonpath/setuptools/tests/test_packageindex.py, service/pythonpath/setuptools/tests/test_sandbox.py, service/pythonpath/setuptools/tests/test_sdist.py, service/pythonpath/setuptools/tests/test_setopt.py, service/pythonpath/setuptools/tests/test_setuptools.py, service/pythonpath/setuptools/tests/test_unicode_utils.py, service/pythonpath/setuptools/tests/test_virtualenv.py, service/pythonpath/setuptools/tests/test_warnings.py, service/pythonpath/setuptools/tests/test_wheel.py, service/pythonpath/setuptools/tests/test_windows_wrappers.py, service/pythonpath/setuptools/tests/text.py, service/pythonpath/setuptools/tests/textwrap.py, service/pythonpath/setuptools/unicode_utils.py, service/pythonpath/setuptools/version.py, service/pythonpath/setuptools/warnings.py, service/pythonpath/setuptools/wheel.py, service/pythonpath/setuptools/windows_support.py, service/pythonpath/six-1.17.0.dist-info/LICENSE, service/pythonpath/six-1.17.0.dist-info/METADATA, service/pythonpath/six-1.17.0.dist-info/RECORD, service/pythonpath/six-1.17.0.dist-info/top_level.txt, service/pythonpath/six-1.17.0.dist-info/WHEEL, service/pythonpath/six.py, service/pythonpath/sqlite/__init__.py, service/pythonpath/sqlite/configuration.py, service/pythonpath/sqlite/documenthandler.py, service/pythonpath/sqlite/driver.py, service/pythonpath/sqlite/helper.py, service/pythonpath/sqlite/jdbcdriver/__init__.py, service/pythonpath/sqlite/jdbcdriver/configuration.py, service/pythonpath/sqlite/logger/__init__.py, service/pythonpath/sqlite/logger/dialog/__init__.py, service/pythonpath/sqlite/logger/dialog/loghandler.py, service/pythonpath/sqlite/logger/dialog/logmanager.py, service/pythonpath/sqlite/logger/dialog/logmodel.py, service/pythonpath/sqlite/logger/dialog/logview.py, service/pythonpath/sqlite/logger/logconfig.py, service/pythonpath/sqlite/logger/logcontroller.py, service/pythonpath/sqlite/logger/logger.py, service/pythonpath/sqlite/logger/loggerpool.py, service/pythonpath/sqlite/logger/loghandler.py, service/pythonpath/sqlite/logger/loghelper.py, service/pythonpath/sqlite/logger/logwrapper.py, service/pythonpath/sqlite/option/__init__.py, service/pythonpath/sqlite/option/optionhandler.py, service/pythonpath/sqlite/option/optionmanager.py, service/pythonpath/sqlite/option/optionmodel.py, service/pythonpath/sqlite/option/optionview.py, service/pythonpath/sqlite/options/__init__.py, service/pythonpath/sqlite/options/optionshandler.py, service/pythonpath/sqlite/options/optionsmanager.py, service/pythonpath/sqlite/options/optionsmodel.py, service/pythonpath/sqlite/options/optionsview.py, service/pythonpath/sqlite/sdbc/__init__.py, service/pythonpath/sqlite/sdbc/driver.py, service/pythonpath/sqlite/sdbcx/__init__.py, service/pythonpath/sqlite/sdbcx/driver.py, service/pythonpath/sqlite/unotool/__init__.py, service/pythonpath/sqlite/unotool/unotool.py, service/SQLiteOOo.py +#Wed Oct 15 16:12:30 CEST 2025 +contents=component-schema.dtd, component-update.dtd, description.xml, description/desc_en.txt, description/desc_fr.txt, dialogs/dialog.dtd, dialogs/LogDialog.xdl, dialogs/LogDialog_en_US.default, dialogs/LogDialog_en_US.properties, dialogs/LogDialog_fr_FR.properties, dialogs/LogWindow.xdl, dialogs/LogWindow_en_US.default, dialogs/LogWindow_en_US.properties, dialogs/LogWindow_fr_FR.properties, dialogs/OptionDialog.xdl, dialogs/OptionDialog_en_US.default, dialogs/OptionDialog_en_US.properties, dialogs/OptionDialog_fr_FR.properties, dialogs/OptionsDialog.xdl, dialogs/OptionsDialog_en_US.default, dialogs/OptionsDialog_en_US.properties, dialogs/OptionsDialog_fr_FR.properties, Drivers.xcu, img/SQLiteOOo.svg, META-INF/manifest.xml, Options.xcs, Options.xcu, OptionsDialog.xcu, package.components, registration/TermsOfUse_en.md, registration/TermsOfUse_fr.md, requirements.txt, resource/Driver_en_US.default, resource/Driver_en_US.properties, resource/Driver_fr_FR.properties, resource/Logger_en_US.default, resource/Logger_en_US.properties, resource/Logger_fr_FR.properties, service/Driver.py, service/OptionsHandler.py, service/pythonpath/_distutils_hack/__init__.py, service/pythonpath/_distutils_hack/override.py, service/pythonpath/distutils-precedence.pth, service/pythonpath/packaging-25.0.dist-info/licenses/LICENSE, service/pythonpath/packaging-25.0.dist-info/licenses/LICENSE.APACHE, service/pythonpath/packaging-25.0.dist-info/licenses/LICENSE.BSD, service/pythonpath/packaging-25.0.dist-info/METADATA, service/pythonpath/packaging-25.0.dist-info/RECORD, service/pythonpath/packaging-25.0.dist-info/WHEEL, service/pythonpath/packaging/__init__.py, service/pythonpath/packaging/_elffile.py, service/pythonpath/packaging/_manylinux.py, service/pythonpath/packaging/_musllinux.py, service/pythonpath/packaging/_parser.py, service/pythonpath/packaging/_structures.py, service/pythonpath/packaging/_tokenizer.py, service/pythonpath/packaging/licenses/__init__.py, service/pythonpath/packaging/licenses/_spdx.py, service/pythonpath/packaging/markers.py, service/pythonpath/packaging/metadata.py, service/pythonpath/packaging/py.typed, service/pythonpath/packaging/requirements.py, service/pythonpath/packaging/specifiers.py, service/pythonpath/packaging/tags.py, service/pythonpath/packaging/utils.py, service/pythonpath/packaging/version.py, service/pythonpath/pkg_resources/__init__.py, service/pythonpath/pkg_resources/api_tests.txt, service/pythonpath/pkg_resources/py.typed, service/pythonpath/pkg_resources/tests/__init__.py, service/pythonpath/pkg_resources/tests/data/my-test-package-source/setup.cfg, service/pythonpath/pkg_resources/tests/data/my-test-package-source/setup.py, service/pythonpath/pkg_resources/tests/data/my-test-package-zip/my-test-package.zip, service/pythonpath/pkg_resources/tests/data/my-test-package_unpacked-egg/my_test_package-1.0-py3.7.egg/EGG-INFO/dependency_links.txt, service/pythonpath/pkg_resources/tests/data/my-test-package_unpacked-egg/my_test_package-1.0-py3.7.egg/EGG-INFO/PKG-INFO, service/pythonpath/pkg_resources/tests/data/my-test-package_unpacked-egg/my_test_package-1.0-py3.7.egg/EGG-INFO/SOURCES.txt, service/pythonpath/pkg_resources/tests/data/my-test-package_unpacked-egg/my_test_package-1.0-py3.7.egg/EGG-INFO/top_level.txt, service/pythonpath/pkg_resources/tests/data/my-test-package_unpacked-egg/my_test_package-1.0-py3.7.egg/EGG-INFO/zip-safe, service/pythonpath/pkg_resources/tests/data/my-test-package_zipped-egg/my_test_package-1.0-py3.7.egg, service/pythonpath/pkg_resources/tests/test_find_distributions.py, service/pythonpath/pkg_resources/tests/test_integration_zope_interface.py, service/pythonpath/pkg_resources/tests/test_markers.py, service/pythonpath/pkg_resources/tests/test_pkg_resources.py, service/pythonpath/pkg_resources/tests/test_resources.py, service/pythonpath/pkg_resources/tests/test_working_set.py, service/pythonpath/setuptools-75.3.2.dist-info/entry_points.txt, service/pythonpath/setuptools-75.3.2.dist-info/LICENSE, service/pythonpath/setuptools-75.3.2.dist-info/METADATA, service/pythonpath/setuptools-75.3.2.dist-info/RECORD, service/pythonpath/setuptools-75.3.2.dist-info/top_level.txt, service/pythonpath/setuptools-75.3.2.dist-info/WHEEL, service/pythonpath/setuptools/__init__.py, service/pythonpath/setuptools/_core_metadata.py, service/pythonpath/setuptools/_distutils/__init__.py, service/pythonpath/setuptools/_distutils/_log.py, service/pythonpath/setuptools/_distutils/_macos_compat.py, service/pythonpath/setuptools/_distutils/_modified.py, service/pythonpath/setuptools/_distutils/_msvccompiler.py, service/pythonpath/setuptools/_distutils/archive_util.py, service/pythonpath/setuptools/_distutils/ccompiler.py, service/pythonpath/setuptools/_distutils/cmd.py, service/pythonpath/setuptools/_distutils/command/__init__.py, service/pythonpath/setuptools/_distutils/command/_framework_compat.py, service/pythonpath/setuptools/_distutils/command/bdist.py, service/pythonpath/setuptools/_distutils/command/bdist_dumb.py, service/pythonpath/setuptools/_distutils/command/bdist_rpm.py, service/pythonpath/setuptools/_distutils/command/build.py, service/pythonpath/setuptools/_distutils/command/build_clib.py, service/pythonpath/setuptools/_distutils/command/build_ext.py, service/pythonpath/setuptools/_distutils/command/build_py.py, service/pythonpath/setuptools/_distutils/command/build_scripts.py, service/pythonpath/setuptools/_distutils/command/check.py, service/pythonpath/setuptools/_distutils/command/clean.py, service/pythonpath/setuptools/_distutils/command/config.py, service/pythonpath/setuptools/_distutils/command/install.py, service/pythonpath/setuptools/_distutils/command/install_data.py, service/pythonpath/setuptools/_distutils/command/install_egg_info.py, service/pythonpath/setuptools/_distutils/command/install_headers.py, service/pythonpath/setuptools/_distutils/command/install_lib.py, service/pythonpath/setuptools/_distutils/command/install_scripts.py, service/pythonpath/setuptools/_distutils/command/sdist.py, service/pythonpath/setuptools/_distutils/compat/__init__.py, service/pythonpath/setuptools/_distutils/compat/py38.py, service/pythonpath/setuptools/_distutils/compat/py39.py, service/pythonpath/setuptools/_distutils/core.py, service/pythonpath/setuptools/_distutils/cygwinccompiler.py, service/pythonpath/setuptools/_distutils/debug.py, service/pythonpath/setuptools/_distutils/dep_util.py, service/pythonpath/setuptools/_distutils/dir_util.py, service/pythonpath/setuptools/_distutils/dist.py, service/pythonpath/setuptools/_distutils/errors.py, service/pythonpath/setuptools/_distutils/extension.py, service/pythonpath/setuptools/_distutils/fancy_getopt.py, service/pythonpath/setuptools/_distutils/file_util.py, service/pythonpath/setuptools/_distutils/filelist.py, service/pythonpath/setuptools/_distutils/log.py, service/pythonpath/setuptools/_distutils/spawn.py, service/pythonpath/setuptools/_distutils/sysconfig.py, service/pythonpath/setuptools/_distutils/tests/__init__.py, service/pythonpath/setuptools/_distutils/tests/compat/__init__.py, service/pythonpath/setuptools/_distutils/tests/compat/py38.py, service/pythonpath/setuptools/_distutils/tests/support.py, service/pythonpath/setuptools/_distutils/tests/test_archive_util.py, service/pythonpath/setuptools/_distutils/tests/test_bdist.py, service/pythonpath/setuptools/_distutils/tests/test_bdist_dumb.py, service/pythonpath/setuptools/_distutils/tests/test_bdist_rpm.py, service/pythonpath/setuptools/_distutils/tests/test_build.py, service/pythonpath/setuptools/_distutils/tests/test_build_clib.py, service/pythonpath/setuptools/_distutils/tests/test_build_ext.py, service/pythonpath/setuptools/_distutils/tests/test_build_py.py, service/pythonpath/setuptools/_distutils/tests/test_build_scripts.py, service/pythonpath/setuptools/_distutils/tests/test_ccompiler.py, service/pythonpath/setuptools/_distutils/tests/test_check.py, service/pythonpath/setuptools/_distutils/tests/test_clean.py, service/pythonpath/setuptools/_distutils/tests/test_cmd.py, service/pythonpath/setuptools/_distutils/tests/test_config_cmd.py, service/pythonpath/setuptools/_distutils/tests/test_core.py, service/pythonpath/setuptools/_distutils/tests/test_cygwinccompiler.py, service/pythonpath/setuptools/_distutils/tests/test_dir_util.py, service/pythonpath/setuptools/_distutils/tests/test_dist.py, service/pythonpath/setuptools/_distutils/tests/test_extension.py, service/pythonpath/setuptools/_distutils/tests/test_file_util.py, service/pythonpath/setuptools/_distutils/tests/test_filelist.py, service/pythonpath/setuptools/_distutils/tests/test_install.py, service/pythonpath/setuptools/_distutils/tests/test_install_data.py, service/pythonpath/setuptools/_distutils/tests/test_install_headers.py, service/pythonpath/setuptools/_distutils/tests/test_install_lib.py, service/pythonpath/setuptools/_distutils/tests/test_install_scripts.py, service/pythonpath/setuptools/_distutils/tests/test_log.py, service/pythonpath/setuptools/_distutils/tests/test_mingwccompiler.py, service/pythonpath/setuptools/_distutils/tests/test_modified.py, service/pythonpath/setuptools/_distutils/tests/test_msvccompiler.py, service/pythonpath/setuptools/_distutils/tests/test_sdist.py, service/pythonpath/setuptools/_distutils/tests/test_spawn.py, service/pythonpath/setuptools/_distutils/tests/test_sysconfig.py, service/pythonpath/setuptools/_distutils/tests/test_text_file.py, service/pythonpath/setuptools/_distutils/tests/test_unixccompiler.py, service/pythonpath/setuptools/_distutils/tests/test_util.py, service/pythonpath/setuptools/_distutils/tests/test_version.py, service/pythonpath/setuptools/_distutils/tests/test_versionpredicate.py, service/pythonpath/setuptools/_distutils/tests/unix_compat.py, service/pythonpath/setuptools/_distutils/text_file.py, service/pythonpath/setuptools/_distutils/unixccompiler.py, service/pythonpath/setuptools/_distutils/util.py, service/pythonpath/setuptools/_distutils/version.py, service/pythonpath/setuptools/_distutils/versionpredicate.py, service/pythonpath/setuptools/_distutils/zosccompiler.py, service/pythonpath/setuptools/_entry_points.py, service/pythonpath/setuptools/_imp.py, service/pythonpath/setuptools/_importlib.py, service/pythonpath/setuptools/_itertools.py, service/pythonpath/setuptools/_normalization.py, service/pythonpath/setuptools/_path.py, service/pythonpath/setuptools/_reqs.py, service/pythonpath/setuptools/_vendor/autocommand-2.2.2.dist-info/INSTALLER, service/pythonpath/setuptools/_vendor/autocommand-2.2.2.dist-info/LICENSE, service/pythonpath/setuptools/_vendor/autocommand-2.2.2.dist-info/METADATA, service/pythonpath/setuptools/_vendor/autocommand-2.2.2.dist-info/RECORD, service/pythonpath/setuptools/_vendor/autocommand-2.2.2.dist-info/top_level.txt, service/pythonpath/setuptools/_vendor/autocommand-2.2.2.dist-info/WHEEL, service/pythonpath/setuptools/_vendor/autocommand/__init__.py, service/pythonpath/setuptools/_vendor/autocommand/autoasync.py, service/pythonpath/setuptools/_vendor/autocommand/autocommand.py, service/pythonpath/setuptools/_vendor/autocommand/automain.py, service/pythonpath/setuptools/_vendor/autocommand/autoparse.py, service/pythonpath/setuptools/_vendor/autocommand/errors.py, service/pythonpath/setuptools/_vendor/backports.tarfile-1.2.0.dist-info/INSTALLER, service/pythonpath/setuptools/_vendor/backports.tarfile-1.2.0.dist-info/LICENSE, service/pythonpath/setuptools/_vendor/backports.tarfile-1.2.0.dist-info/METADATA, service/pythonpath/setuptools/_vendor/backports.tarfile-1.2.0.dist-info/RECORD, service/pythonpath/setuptools/_vendor/backports.tarfile-1.2.0.dist-info/REQUESTED, service/pythonpath/setuptools/_vendor/backports.tarfile-1.2.0.dist-info/top_level.txt, service/pythonpath/setuptools/_vendor/backports.tarfile-1.2.0.dist-info/WHEEL, service/pythonpath/setuptools/_vendor/backports/__init__.py, service/pythonpath/setuptools/_vendor/backports/tarfile/__init__.py, service/pythonpath/setuptools/_vendor/backports/tarfile/__main__.py, service/pythonpath/setuptools/_vendor/backports/tarfile/compat/__init__.py, service/pythonpath/setuptools/_vendor/backports/tarfile/compat/py38.py, service/pythonpath/setuptools/_vendor/importlib_metadata-8.0.0.dist-info/INSTALLER, service/pythonpath/setuptools/_vendor/importlib_metadata-8.0.0.dist-info/LICENSE, service/pythonpath/setuptools/_vendor/importlib_metadata-8.0.0.dist-info/METADATA, service/pythonpath/setuptools/_vendor/importlib_metadata-8.0.0.dist-info/RECORD, service/pythonpath/setuptools/_vendor/importlib_metadata-8.0.0.dist-info/REQUESTED, service/pythonpath/setuptools/_vendor/importlib_metadata-8.0.0.dist-info/top_level.txt, service/pythonpath/setuptools/_vendor/importlib_metadata-8.0.0.dist-info/WHEEL, service/pythonpath/setuptools/_vendor/importlib_metadata/__init__.py, service/pythonpath/setuptools/_vendor/importlib_metadata/_adapters.py, service/pythonpath/setuptools/_vendor/importlib_metadata/_collections.py, service/pythonpath/setuptools/_vendor/importlib_metadata/_compat.py, service/pythonpath/setuptools/_vendor/importlib_metadata/_functools.py, service/pythonpath/setuptools/_vendor/importlib_metadata/_itertools.py, service/pythonpath/setuptools/_vendor/importlib_metadata/_meta.py, service/pythonpath/setuptools/_vendor/importlib_metadata/_text.py, service/pythonpath/setuptools/_vendor/importlib_metadata/compat/__init__.py, service/pythonpath/setuptools/_vendor/importlib_metadata/compat/py311.py, service/pythonpath/setuptools/_vendor/importlib_metadata/compat/py39.py, service/pythonpath/setuptools/_vendor/importlib_metadata/diagnose.py, service/pythonpath/setuptools/_vendor/importlib_metadata/py.typed, service/pythonpath/setuptools/_vendor/importlib_resources-6.4.0.dist-info/INSTALLER, service/pythonpath/setuptools/_vendor/importlib_resources-6.4.0.dist-info/LICENSE, service/pythonpath/setuptools/_vendor/importlib_resources-6.4.0.dist-info/METADATA, service/pythonpath/setuptools/_vendor/importlib_resources-6.4.0.dist-info/RECORD, service/pythonpath/setuptools/_vendor/importlib_resources-6.4.0.dist-info/REQUESTED, service/pythonpath/setuptools/_vendor/importlib_resources-6.4.0.dist-info/top_level.txt, service/pythonpath/setuptools/_vendor/importlib_resources-6.4.0.dist-info/WHEEL, service/pythonpath/setuptools/_vendor/importlib_resources/__init__.py, service/pythonpath/setuptools/_vendor/importlib_resources/_adapters.py, service/pythonpath/setuptools/_vendor/importlib_resources/_common.py, service/pythonpath/setuptools/_vendor/importlib_resources/_itertools.py, service/pythonpath/setuptools/_vendor/importlib_resources/abc.py, service/pythonpath/setuptools/_vendor/importlib_resources/compat/__init__.py, service/pythonpath/setuptools/_vendor/importlib_resources/compat/py38.py, service/pythonpath/setuptools/_vendor/importlib_resources/compat/py39.py, service/pythonpath/setuptools/_vendor/importlib_resources/functional.py, service/pythonpath/setuptools/_vendor/importlib_resources/future/__init__.py, service/pythonpath/setuptools/_vendor/importlib_resources/future/adapters.py, service/pythonpath/setuptools/_vendor/importlib_resources/py.typed, service/pythonpath/setuptools/_vendor/importlib_resources/readers.py, service/pythonpath/setuptools/_vendor/importlib_resources/simple.py, service/pythonpath/setuptools/_vendor/importlib_resources/tests/__init__.py, service/pythonpath/setuptools/_vendor/importlib_resources/tests/_path.py, service/pythonpath/setuptools/_vendor/importlib_resources/tests/compat/__init__.py, service/pythonpath/setuptools/_vendor/importlib_resources/tests/compat/py312.py, service/pythonpath/setuptools/_vendor/importlib_resources/tests/compat/py39.py, service/pythonpath/setuptools/_vendor/importlib_resources/tests/data01/__init__.py, service/pythonpath/setuptools/_vendor/importlib_resources/tests/data01/binary.file, service/pythonpath/setuptools/_vendor/importlib_resources/tests/data01/subdirectory/__init__.py, service/pythonpath/setuptools/_vendor/importlib_resources/tests/data01/subdirectory/binary.file, service/pythonpath/setuptools/_vendor/importlib_resources/tests/data01/utf-16.file, service/pythonpath/setuptools/_vendor/importlib_resources/tests/data01/utf-8.file, service/pythonpath/setuptools/_vendor/importlib_resources/tests/data02/__init__.py, service/pythonpath/setuptools/_vendor/importlib_resources/tests/data02/one/__init__.py, service/pythonpath/setuptools/_vendor/importlib_resources/tests/data02/one/resource1.txt, service/pythonpath/setuptools/_vendor/importlib_resources/tests/data02/subdirectory/subsubdir/resource.txt, service/pythonpath/setuptools/_vendor/importlib_resources/tests/data02/two/__init__.py, service/pythonpath/setuptools/_vendor/importlib_resources/tests/data02/two/resource2.txt, service/pythonpath/setuptools/_vendor/importlib_resources/tests/namespacedata01/binary.file, service/pythonpath/setuptools/_vendor/importlib_resources/tests/namespacedata01/subdirectory/binary.file, service/pythonpath/setuptools/_vendor/importlib_resources/tests/namespacedata01/utf-16.file, service/pythonpath/setuptools/_vendor/importlib_resources/tests/namespacedata01/utf-8.file, service/pythonpath/setuptools/_vendor/importlib_resources/tests/test_compatibilty_files.py, service/pythonpath/setuptools/_vendor/importlib_resources/tests/test_contents.py, service/pythonpath/setuptools/_vendor/importlib_resources/tests/test_custom.py, service/pythonpath/setuptools/_vendor/importlib_resources/tests/test_files.py, service/pythonpath/setuptools/_vendor/importlib_resources/tests/test_functional.py, service/pythonpath/setuptools/_vendor/importlib_resources/tests/test_open.py, service/pythonpath/setuptools/_vendor/importlib_resources/tests/test_path.py, service/pythonpath/setuptools/_vendor/importlib_resources/tests/test_read.py, service/pythonpath/setuptools/_vendor/importlib_resources/tests/test_reader.py, service/pythonpath/setuptools/_vendor/importlib_resources/tests/test_resource.py, service/pythonpath/setuptools/_vendor/importlib_resources/tests/util.py, service/pythonpath/setuptools/_vendor/importlib_resources/tests/zip.py, service/pythonpath/setuptools/_vendor/inflect-7.3.1.dist-info/INSTALLER, service/pythonpath/setuptools/_vendor/inflect-7.3.1.dist-info/LICENSE, service/pythonpath/setuptools/_vendor/inflect-7.3.1.dist-info/METADATA, service/pythonpath/setuptools/_vendor/inflect-7.3.1.dist-info/RECORD, service/pythonpath/setuptools/_vendor/inflect-7.3.1.dist-info/top_level.txt, service/pythonpath/setuptools/_vendor/inflect-7.3.1.dist-info/WHEEL, service/pythonpath/setuptools/_vendor/inflect/__init__.py, service/pythonpath/setuptools/_vendor/inflect/compat/__init__.py, service/pythonpath/setuptools/_vendor/inflect/compat/py38.py, service/pythonpath/setuptools/_vendor/inflect/py.typed, service/pythonpath/setuptools/_vendor/jaraco.collections-5.1.0.dist-info/INSTALLER, service/pythonpath/setuptools/_vendor/jaraco.collections-5.1.0.dist-info/LICENSE, service/pythonpath/setuptools/_vendor/jaraco.collections-5.1.0.dist-info/METADATA, service/pythonpath/setuptools/_vendor/jaraco.collections-5.1.0.dist-info/RECORD, service/pythonpath/setuptools/_vendor/jaraco.collections-5.1.0.dist-info/REQUESTED, service/pythonpath/setuptools/_vendor/jaraco.collections-5.1.0.dist-info/top_level.txt, service/pythonpath/setuptools/_vendor/jaraco.collections-5.1.0.dist-info/WHEEL, service/pythonpath/setuptools/_vendor/jaraco.context-5.3.0.dist-info/INSTALLER, service/pythonpath/setuptools/_vendor/jaraco.context-5.3.0.dist-info/LICENSE, service/pythonpath/setuptools/_vendor/jaraco.context-5.3.0.dist-info/METADATA, service/pythonpath/setuptools/_vendor/jaraco.context-5.3.0.dist-info/RECORD, service/pythonpath/setuptools/_vendor/jaraco.context-5.3.0.dist-info/top_level.txt, service/pythonpath/setuptools/_vendor/jaraco.context-5.3.0.dist-info/WHEEL, service/pythonpath/setuptools/_vendor/jaraco.functools-4.0.1.dist-info/INSTALLER, service/pythonpath/setuptools/_vendor/jaraco.functools-4.0.1.dist-info/LICENSE, service/pythonpath/setuptools/_vendor/jaraco.functools-4.0.1.dist-info/METADATA, service/pythonpath/setuptools/_vendor/jaraco.functools-4.0.1.dist-info/RECORD, service/pythonpath/setuptools/_vendor/jaraco.functools-4.0.1.dist-info/top_level.txt, service/pythonpath/setuptools/_vendor/jaraco.functools-4.0.1.dist-info/WHEEL, service/pythonpath/setuptools/_vendor/jaraco.text-3.12.1.dist-info/INSTALLER, service/pythonpath/setuptools/_vendor/jaraco.text-3.12.1.dist-info/LICENSE, service/pythonpath/setuptools/_vendor/jaraco.text-3.12.1.dist-info/METADATA, service/pythonpath/setuptools/_vendor/jaraco.text-3.12.1.dist-info/RECORD, service/pythonpath/setuptools/_vendor/jaraco.text-3.12.1.dist-info/REQUESTED, service/pythonpath/setuptools/_vendor/jaraco.text-3.12.1.dist-info/top_level.txt, service/pythonpath/setuptools/_vendor/jaraco.text-3.12.1.dist-info/WHEEL, service/pythonpath/setuptools/_vendor/jaraco/collections/__init__.py, service/pythonpath/setuptools/_vendor/jaraco/collections/py.typed, service/pythonpath/setuptools/_vendor/jaraco/context.py, service/pythonpath/setuptools/_vendor/jaraco/functools/__init__.py, service/pythonpath/setuptools/_vendor/jaraco/functools/__init__.pyi, service/pythonpath/setuptools/_vendor/jaraco/functools/py.typed, service/pythonpath/setuptools/_vendor/jaraco/text/__init__.py, service/pythonpath/setuptools/_vendor/jaraco/text/layouts.py, service/pythonpath/setuptools/_vendor/jaraco/text/Lorem ipsum.txt, service/pythonpath/setuptools/_vendor/jaraco/text/show-newlines.py, service/pythonpath/setuptools/_vendor/jaraco/text/strip-prefix.py, service/pythonpath/setuptools/_vendor/jaraco/text/to-dvorak.py, service/pythonpath/setuptools/_vendor/jaraco/text/to-qwerty.py, service/pythonpath/setuptools/_vendor/more_itertools-10.3.0.dist-info/INSTALLER, service/pythonpath/setuptools/_vendor/more_itertools-10.3.0.dist-info/LICENSE, service/pythonpath/setuptools/_vendor/more_itertools-10.3.0.dist-info/METADATA, service/pythonpath/setuptools/_vendor/more_itertools-10.3.0.dist-info/RECORD, service/pythonpath/setuptools/_vendor/more_itertools-10.3.0.dist-info/REQUESTED, service/pythonpath/setuptools/_vendor/more_itertools-10.3.0.dist-info/WHEEL, service/pythonpath/setuptools/_vendor/more_itertools/__init__.py, service/pythonpath/setuptools/_vendor/more_itertools/__init__.pyi, service/pythonpath/setuptools/_vendor/more_itertools/more.py, service/pythonpath/setuptools/_vendor/more_itertools/more.pyi, service/pythonpath/setuptools/_vendor/more_itertools/py.typed, service/pythonpath/setuptools/_vendor/more_itertools/recipes.py, service/pythonpath/setuptools/_vendor/more_itertools/recipes.pyi, service/pythonpath/setuptools/_vendor/packaging-24.1.dist-info/INSTALLER, service/pythonpath/setuptools/_vendor/packaging-24.1.dist-info/LICENSE, service/pythonpath/setuptools/_vendor/packaging-24.1.dist-info/LICENSE.APACHE, service/pythonpath/setuptools/_vendor/packaging-24.1.dist-info/LICENSE.BSD, service/pythonpath/setuptools/_vendor/packaging-24.1.dist-info/METADATA, service/pythonpath/setuptools/_vendor/packaging-24.1.dist-info/RECORD, service/pythonpath/setuptools/_vendor/packaging-24.1.dist-info/REQUESTED, service/pythonpath/setuptools/_vendor/packaging-24.1.dist-info/WHEEL, service/pythonpath/setuptools/_vendor/packaging/__init__.py, service/pythonpath/setuptools/_vendor/packaging/_elffile.py, service/pythonpath/setuptools/_vendor/packaging/_manylinux.py, service/pythonpath/setuptools/_vendor/packaging/_musllinux.py, service/pythonpath/setuptools/_vendor/packaging/_parser.py, service/pythonpath/setuptools/_vendor/packaging/_structures.py, service/pythonpath/setuptools/_vendor/packaging/_tokenizer.py, service/pythonpath/setuptools/_vendor/packaging/markers.py, service/pythonpath/setuptools/_vendor/packaging/metadata.py, service/pythonpath/setuptools/_vendor/packaging/py.typed, service/pythonpath/setuptools/_vendor/packaging/requirements.py, service/pythonpath/setuptools/_vendor/packaging/specifiers.py, service/pythonpath/setuptools/_vendor/packaging/tags.py, service/pythonpath/setuptools/_vendor/packaging/utils.py, service/pythonpath/setuptools/_vendor/packaging/version.py, service/pythonpath/setuptools/_vendor/platformdirs-4.2.2.dist-info/INSTALLER, service/pythonpath/setuptools/_vendor/platformdirs-4.2.2.dist-info/licenses/LICENSE, service/pythonpath/setuptools/_vendor/platformdirs-4.2.2.dist-info/METADATA, service/pythonpath/setuptools/_vendor/platformdirs-4.2.2.dist-info/RECORD, service/pythonpath/setuptools/_vendor/platformdirs-4.2.2.dist-info/REQUESTED, service/pythonpath/setuptools/_vendor/platformdirs-4.2.2.dist-info/WHEEL, service/pythonpath/setuptools/_vendor/platformdirs/__init__.py, service/pythonpath/setuptools/_vendor/platformdirs/__main__.py, service/pythonpath/setuptools/_vendor/platformdirs/android.py, service/pythonpath/setuptools/_vendor/platformdirs/api.py, service/pythonpath/setuptools/_vendor/platformdirs/macos.py, service/pythonpath/setuptools/_vendor/platformdirs/py.typed, service/pythonpath/setuptools/_vendor/platformdirs/unix.py, service/pythonpath/setuptools/_vendor/platformdirs/version.py, service/pythonpath/setuptools/_vendor/platformdirs/windows.py, service/pythonpath/setuptools/_vendor/ruff.toml, service/pythonpath/setuptools/_vendor/tomli-2.0.1.dist-info/INSTALLER, service/pythonpath/setuptools/_vendor/tomli-2.0.1.dist-info/LICENSE, service/pythonpath/setuptools/_vendor/tomli-2.0.1.dist-info/METADATA, service/pythonpath/setuptools/_vendor/tomli-2.0.1.dist-info/RECORD, service/pythonpath/setuptools/_vendor/tomli-2.0.1.dist-info/REQUESTED, service/pythonpath/setuptools/_vendor/tomli-2.0.1.dist-info/WHEEL, service/pythonpath/setuptools/_vendor/tomli/__init__.py, service/pythonpath/setuptools/_vendor/tomli/_parser.py, service/pythonpath/setuptools/_vendor/tomli/_re.py, service/pythonpath/setuptools/_vendor/tomli/_types.py, service/pythonpath/setuptools/_vendor/tomli/py.typed, service/pythonpath/setuptools/_vendor/typeguard-4.3.0.dist-info/entry_points.txt, service/pythonpath/setuptools/_vendor/typeguard-4.3.0.dist-info/INSTALLER, service/pythonpath/setuptools/_vendor/typeguard-4.3.0.dist-info/LICENSE, service/pythonpath/setuptools/_vendor/typeguard-4.3.0.dist-info/METADATA, service/pythonpath/setuptools/_vendor/typeguard-4.3.0.dist-info/RECORD, service/pythonpath/setuptools/_vendor/typeguard-4.3.0.dist-info/top_level.txt, service/pythonpath/setuptools/_vendor/typeguard-4.3.0.dist-info/WHEEL, service/pythonpath/setuptools/_vendor/typeguard/__init__.py, service/pythonpath/setuptools/_vendor/typeguard/_checkers.py, service/pythonpath/setuptools/_vendor/typeguard/_config.py, service/pythonpath/setuptools/_vendor/typeguard/_decorators.py, service/pythonpath/setuptools/_vendor/typeguard/_exceptions.py, service/pythonpath/setuptools/_vendor/typeguard/_functions.py, service/pythonpath/setuptools/_vendor/typeguard/_importhook.py, service/pythonpath/setuptools/_vendor/typeguard/_memo.py, service/pythonpath/setuptools/_vendor/typeguard/_pytest_plugin.py, service/pythonpath/setuptools/_vendor/typeguard/_suppression.py, service/pythonpath/setuptools/_vendor/typeguard/_transformer.py, service/pythonpath/setuptools/_vendor/typeguard/_union_transformer.py, service/pythonpath/setuptools/_vendor/typeguard/_utils.py, service/pythonpath/setuptools/_vendor/typeguard/py.typed, service/pythonpath/setuptools/_vendor/typing_extensions-4.12.2.dist-info/INSTALLER, service/pythonpath/setuptools/_vendor/typing_extensions-4.12.2.dist-info/LICENSE, service/pythonpath/setuptools/_vendor/typing_extensions-4.12.2.dist-info/METADATA, service/pythonpath/setuptools/_vendor/typing_extensions-4.12.2.dist-info/RECORD, service/pythonpath/setuptools/_vendor/typing_extensions-4.12.2.dist-info/WHEEL, service/pythonpath/setuptools/_vendor/typing_extensions.py, service/pythonpath/setuptools/_vendor/wheel-0.43.0.dist-info/entry_points.txt, service/pythonpath/setuptools/_vendor/wheel-0.43.0.dist-info/INSTALLER, service/pythonpath/setuptools/_vendor/wheel-0.43.0.dist-info/LICENSE.txt, service/pythonpath/setuptools/_vendor/wheel-0.43.0.dist-info/METADATA, service/pythonpath/setuptools/_vendor/wheel-0.43.0.dist-info/RECORD, service/pythonpath/setuptools/_vendor/wheel-0.43.0.dist-info/REQUESTED, service/pythonpath/setuptools/_vendor/wheel-0.43.0.dist-info/WHEEL, service/pythonpath/setuptools/_vendor/wheel/__init__.py, service/pythonpath/setuptools/_vendor/wheel/__main__.py, service/pythonpath/setuptools/_vendor/wheel/_setuptools_logging.py, service/pythonpath/setuptools/_vendor/wheel/bdist_wheel.py, service/pythonpath/setuptools/_vendor/wheel/cli/__init__.py, service/pythonpath/setuptools/_vendor/wheel/cli/convert.py, service/pythonpath/setuptools/_vendor/wheel/cli/pack.py, service/pythonpath/setuptools/_vendor/wheel/cli/tags.py, service/pythonpath/setuptools/_vendor/wheel/cli/unpack.py, service/pythonpath/setuptools/_vendor/wheel/macosx_libfile.py, service/pythonpath/setuptools/_vendor/wheel/metadata.py, service/pythonpath/setuptools/_vendor/wheel/util.py, service/pythonpath/setuptools/_vendor/wheel/vendored/__init__.py, service/pythonpath/setuptools/_vendor/wheel/vendored/packaging/__init__.py, service/pythonpath/setuptools/_vendor/wheel/vendored/packaging/_elffile.py, service/pythonpath/setuptools/_vendor/wheel/vendored/packaging/_manylinux.py, service/pythonpath/setuptools/_vendor/wheel/vendored/packaging/_musllinux.py, service/pythonpath/setuptools/_vendor/wheel/vendored/packaging/_parser.py, service/pythonpath/setuptools/_vendor/wheel/vendored/packaging/_structures.py, service/pythonpath/setuptools/_vendor/wheel/vendored/packaging/_tokenizer.py, service/pythonpath/setuptools/_vendor/wheel/vendored/packaging/markers.py, service/pythonpath/setuptools/_vendor/wheel/vendored/packaging/requirements.py, service/pythonpath/setuptools/_vendor/wheel/vendored/packaging/specifiers.py, service/pythonpath/setuptools/_vendor/wheel/vendored/packaging/tags.py, service/pythonpath/setuptools/_vendor/wheel/vendored/packaging/utils.py, service/pythonpath/setuptools/_vendor/wheel/vendored/packaging/version.py, service/pythonpath/setuptools/_vendor/wheel/vendored/vendor.txt, service/pythonpath/setuptools/_vendor/wheel/wheelfile.py, service/pythonpath/setuptools/_vendor/zipp-3.19.2.dist-info/INSTALLER, service/pythonpath/setuptools/_vendor/zipp-3.19.2.dist-info/LICENSE, service/pythonpath/setuptools/_vendor/zipp-3.19.2.dist-info/METADATA, service/pythonpath/setuptools/_vendor/zipp-3.19.2.dist-info/RECORD, service/pythonpath/setuptools/_vendor/zipp-3.19.2.dist-info/REQUESTED, service/pythonpath/setuptools/_vendor/zipp-3.19.2.dist-info/top_level.txt, service/pythonpath/setuptools/_vendor/zipp-3.19.2.dist-info/WHEEL, service/pythonpath/setuptools/_vendor/zipp/__init__.py, service/pythonpath/setuptools/_vendor/zipp/compat/__init__.py, service/pythonpath/setuptools/_vendor/zipp/compat/py310.py, service/pythonpath/setuptools/_vendor/zipp/glob.py, service/pythonpath/setuptools/archive_util.py, service/pythonpath/setuptools/build_meta.py, service/pythonpath/setuptools/cli-32.exe, service/pythonpath/setuptools/cli-64.exe, service/pythonpath/setuptools/cli-arm64.exe, service/pythonpath/setuptools/cli.exe, service/pythonpath/setuptools/command/__init__.py, service/pythonpath/setuptools/command/_requirestxt.py, service/pythonpath/setuptools/command/alias.py, service/pythonpath/setuptools/command/bdist_egg.py, service/pythonpath/setuptools/command/bdist_rpm.py, service/pythonpath/setuptools/command/bdist_wheel.py, service/pythonpath/setuptools/command/build.py, service/pythonpath/setuptools/command/build_clib.py, service/pythonpath/setuptools/command/build_ext.py, service/pythonpath/setuptools/command/build_py.py, service/pythonpath/setuptools/command/develop.py, service/pythonpath/setuptools/command/dist_info.py, service/pythonpath/setuptools/command/easy_install.py, service/pythonpath/setuptools/command/editable_wheel.py, service/pythonpath/setuptools/command/egg_info.py, service/pythonpath/setuptools/command/install.py, service/pythonpath/setuptools/command/install_egg_info.py, service/pythonpath/setuptools/command/install_lib.py, service/pythonpath/setuptools/command/install_scripts.py, service/pythonpath/setuptools/command/launcher manifest.xml, service/pythonpath/setuptools/command/rotate.py, service/pythonpath/setuptools/command/saveopts.py, service/pythonpath/setuptools/command/sdist.py, service/pythonpath/setuptools/command/setopt.py, service/pythonpath/setuptools/command/test.py, service/pythonpath/setuptools/compat/__init__.py, service/pythonpath/setuptools/compat/py310.py, service/pythonpath/setuptools/compat/py311.py, service/pythonpath/setuptools/compat/py312.py, service/pythonpath/setuptools/compat/py39.py, service/pythonpath/setuptools/config/__init__.py, service/pythonpath/setuptools/config/_apply_pyprojecttoml.py, service/pythonpath/setuptools/config/_validate_pyproject/__init__.py, service/pythonpath/setuptools/config/_validate_pyproject/error_reporting.py, service/pythonpath/setuptools/config/_validate_pyproject/extra_validations.py, service/pythonpath/setuptools/config/_validate_pyproject/fastjsonschema_exceptions.py, service/pythonpath/setuptools/config/_validate_pyproject/fastjsonschema_validations.py, service/pythonpath/setuptools/config/_validate_pyproject/formats.py, service/pythonpath/setuptools/config/_validate_pyproject/NOTICE, service/pythonpath/setuptools/config/distutils.schema.json, service/pythonpath/setuptools/config/expand.py, service/pythonpath/setuptools/config/NOTICE, service/pythonpath/setuptools/config/pyprojecttoml.py, service/pythonpath/setuptools/config/setupcfg.py, service/pythonpath/setuptools/config/setuptools.schema.json, service/pythonpath/setuptools/depends.py, service/pythonpath/setuptools/discovery.py, service/pythonpath/setuptools/dist.py, service/pythonpath/setuptools/errors.py, service/pythonpath/setuptools/extension.py, service/pythonpath/setuptools/glob.py, service/pythonpath/setuptools/gui-32.exe, service/pythonpath/setuptools/gui-64.exe, service/pythonpath/setuptools/gui-arm64.exe, service/pythonpath/setuptools/gui.exe, service/pythonpath/setuptools/installer.py, service/pythonpath/setuptools/launch.py, service/pythonpath/setuptools/logging.py, service/pythonpath/setuptools/modified.py, service/pythonpath/setuptools/monkey.py, service/pythonpath/setuptools/msvc.py, service/pythonpath/setuptools/namespaces.py, service/pythonpath/setuptools/package_index.py, service/pythonpath/setuptools/sandbox.py, service/pythonpath/setuptools/script (dev).tmpl, service/pythonpath/setuptools/script.tmpl, service/pythonpath/setuptools/tests/__init__.py, service/pythonpath/setuptools/tests/compat/__init__.py, service/pythonpath/setuptools/tests/compat/py39.py, service/pythonpath/setuptools/tests/config/__init__.py, service/pythonpath/setuptools/tests/config/downloads/__init__.py, service/pythonpath/setuptools/tests/config/downloads/preload.py, service/pythonpath/setuptools/tests/config/setupcfg_examples.txt, service/pythonpath/setuptools/tests/config/test_apply_pyprojecttoml.py, service/pythonpath/setuptools/tests/config/test_expand.py, service/pythonpath/setuptools/tests/config/test_pyprojecttoml.py, service/pythonpath/setuptools/tests/config/test_pyprojecttoml_dynamic_deps.py, service/pythonpath/setuptools/tests/config/test_setupcfg.py, service/pythonpath/setuptools/tests/contexts.py, service/pythonpath/setuptools/tests/environment.py, service/pythonpath/setuptools/tests/fixtures.py, service/pythonpath/setuptools/tests/indexes/test_links_priority/external.html, service/pythonpath/setuptools/tests/indexes/test_links_priority/simple/foobar/index.html, service/pythonpath/setuptools/tests/integration/__init__.py, service/pythonpath/setuptools/tests/integration/helpers.py, service/pythonpath/setuptools/tests/integration/test_pip_install_sdist.py, service/pythonpath/setuptools/tests/mod_with_constant.py, service/pythonpath/setuptools/tests/namespaces.py, service/pythonpath/setuptools/tests/script-with-bom.py, service/pythonpath/setuptools/tests/server.py, service/pythonpath/setuptools/tests/test_archive_util.py, service/pythonpath/setuptools/tests/test_bdist_deprecations.py, service/pythonpath/setuptools/tests/test_bdist_egg.py, service/pythonpath/setuptools/tests/test_bdist_wheel.py, service/pythonpath/setuptools/tests/test_build.py, service/pythonpath/setuptools/tests/test_build_clib.py, service/pythonpath/setuptools/tests/test_build_ext.py, service/pythonpath/setuptools/tests/test_build_meta.py, service/pythonpath/setuptools/tests/test_build_py.py, service/pythonpath/setuptools/tests/test_config_discovery.py, service/pythonpath/setuptools/tests/test_core_metadata.py, service/pythonpath/setuptools/tests/test_depends.py, service/pythonpath/setuptools/tests/test_develop.py, service/pythonpath/setuptools/tests/test_dist.py, service/pythonpath/setuptools/tests/test_dist_info.py, service/pythonpath/setuptools/tests/test_distutils_adoption.py, service/pythonpath/setuptools/tests/test_easy_install.py, service/pythonpath/setuptools/tests/test_editable_install.py, service/pythonpath/setuptools/tests/test_egg_info.py, service/pythonpath/setuptools/tests/test_extern.py, service/pythonpath/setuptools/tests/test_find_packages.py, service/pythonpath/setuptools/tests/test_find_py_modules.py, service/pythonpath/setuptools/tests/test_glob.py, service/pythonpath/setuptools/tests/test_install_scripts.py, service/pythonpath/setuptools/tests/test_logging.py, service/pythonpath/setuptools/tests/test_manifest.py, service/pythonpath/setuptools/tests/test_namespaces.py, service/pythonpath/setuptools/tests/test_packageindex.py, service/pythonpath/setuptools/tests/test_sandbox.py, service/pythonpath/setuptools/tests/test_sdist.py, service/pythonpath/setuptools/tests/test_setopt.py, service/pythonpath/setuptools/tests/test_setuptools.py, service/pythonpath/setuptools/tests/test_unicode_utils.py, service/pythonpath/setuptools/tests/test_virtualenv.py, service/pythonpath/setuptools/tests/test_warnings.py, service/pythonpath/setuptools/tests/test_wheel.py, service/pythonpath/setuptools/tests/test_windows_wrappers.py, service/pythonpath/setuptools/tests/text.py, service/pythonpath/setuptools/tests/textwrap.py, service/pythonpath/setuptools/unicode_utils.py, service/pythonpath/setuptools/version.py, service/pythonpath/setuptools/warnings.py, service/pythonpath/setuptools/wheel.py, service/pythonpath/setuptools/windows_support.py, service/pythonpath/six-1.17.0.dist-info/LICENSE, service/pythonpath/six-1.17.0.dist-info/METADATA, service/pythonpath/six-1.17.0.dist-info/RECORD, service/pythonpath/six-1.17.0.dist-info/top_level.txt, service/pythonpath/six-1.17.0.dist-info/WHEEL, service/pythonpath/six.py, service/pythonpath/sqlite/__init__.py, service/pythonpath/sqlite/configuration.py, service/pythonpath/sqlite/documenthandler.py, service/pythonpath/sqlite/driver.py, service/pythonpath/sqlite/helper.py, service/pythonpath/sqlite/jdbcdriver/__init__.py, service/pythonpath/sqlite/jdbcdriver/configuration.py, service/pythonpath/sqlite/jdbcdriver/jdbctool.py, service/pythonpath/sqlite/logger/__init__.py, service/pythonpath/sqlite/logger/dialog/__init__.py, service/pythonpath/sqlite/logger/dialog/loghandler.py, service/pythonpath/sqlite/logger/dialog/logmanager.py, service/pythonpath/sqlite/logger/dialog/logmodel.py, service/pythonpath/sqlite/logger/dialog/logview.py, service/pythonpath/sqlite/logger/logconfig.py, service/pythonpath/sqlite/logger/logcontroller.py, service/pythonpath/sqlite/logger/logger.py, service/pythonpath/sqlite/logger/loggerpool.py, service/pythonpath/sqlite/logger/loghandler.py, service/pythonpath/sqlite/logger/loghelper.py, service/pythonpath/sqlite/logger/logwrapper.py, service/pythonpath/sqlite/options/__init__.py, service/pythonpath/sqlite/options/options/__init__.py, service/pythonpath/sqlite/options/options/optionshandler.py, service/pythonpath/sqlite/options/options/optionsmanager.py, service/pythonpath/sqlite/options/options/optionsmodel.py, service/pythonpath/sqlite/options/options/optionsview.py, service/pythonpath/sqlite/options/optionshandler.py, service/pythonpath/sqlite/options/optionsmanager.py, service/pythonpath/sqlite/options/optionsmodel.py, service/pythonpath/sqlite/options/optionsview.py, service/pythonpath/sqlite/sdbc/__init__.py, service/pythonpath/sqlite/sdbc/driver.py, service/pythonpath/sqlite/sdbcx/__init__.py, service/pythonpath/sqlite/sdbcx/driver.py, service/pythonpath/sqlite/unotool/__init__.py, service/pythonpath/sqlite/unotool/statusindicator.py, service/pythonpath/sqlite/unotool/taskevent.py, service/pythonpath/sqlite/unotool/unotool.py, service/SQLiteOOo.py diff --git a/source/SQLiteOOo/service/OptionsHandler.py b/source/SQLiteOOo/service/OptionsHandler.py index 1b270eb1..102ae1dc 100644 --- a/source/SQLiteOOo/service/OptionsHandler.py +++ b/source/SQLiteOOo/service/OptionsHandler.py @@ -78,6 +78,7 @@ def callHandlerMethod(self, window, event, method): handled = True return handled except Exception as e: + print("OptionsHandler.callHandlerMethod() ERROR: %s" % traceback.format_exc()) self._logger.logprb(SEVERE, 'OptionsHandler', 'callHandlerMethod', 301, e, traceback.format_exc()) def getSupportedMethodNames(self): diff --git a/source/SQLiteOOo/service/pythonpath/sqlite/option b/source/SQLiteOOo/service/pythonpath/sqlite/option deleted file mode 120000 index 322f3aa0..00000000 --- a/source/SQLiteOOo/service/pythonpath/sqlite/option +++ /dev/null @@ -1 +0,0 @@ -../../../../../uno/lib/uno/options/jdbc \ No newline at end of file diff --git a/source/SQLiteOOo/types.rdb b/source/SQLiteOOo/types.rdb index 1ac3de2784c306fe2b13deabb50829cbebbc101f..cbaf24150772c78db12b1117e087c69c36b3e104 100644 GIT binary patch delta 277 zcmeBUKgq!r>gVt2;`5)uk!2&719LqqBLf42G!Q4}=js)g=IIreBo^tF=H=@}c;=O) z7NsR7rvhccfCWgh0&!+>aB4{cBSQmN6i6@wadB!%EdxRbq%JupHL(a;5M)4kVkTHG z$X*8adLR*!nVXtlS_0CMmXn`Y0+NUbNi5EGElbS<@<1vd0Il!>;+*{S^vt|;h7zDO x0|OIK<_A#J6yyM);je)-$o&vKQa}+_AO`vhBA^50$OAFZs|>b4+JFUUHUJ+IG3o#S delta 88 zcmX@f(Z|je>gVt2;`5)Ojd>%N1G7s`etLRlUOEE Date: Fri, 24 Oct 2025 12:04:07 +0200 Subject: [PATCH 06/11] git subrepo pull uno subrepo: subdir: "uno" merged: "8ed49904" upstream: origin: "https://github.com/prrvchr/uno.git" branch: "main" commit: "8ed49904" git-subrepo: version: "0.4.9" origin: "https://github.com/ingydotnet/git-subrepo.git" commit: "4f60dd7" --- uno/.gitrepo | 4 +-- uno/lib/uno/card/datasource.py | 20 +++++++++--- .../uno/card/resource/Driver_en_US.properties | 1 + .../uno/card/resource/Driver_fr_FR.properties | 1 + uno/lib/uno/grid/gridmanager.py | 21 +++++-------- uno/lib/uno/oauth20/oauth2core.py | 9 ++++-- uno/lib/uno/ucb/__init__.py | 2 +- uno/lib/uno/unotool/__init__.py | 1 + uno/lib/uno/unotool/statusindicator.py | 31 ++++++++++++------- uno/lib/uno/unotool/taskevent.py | 3 +- uno/lib/uno/unotool/unotool.py | 26 +++++++++++----- uno/lib/uno/wizard/wizardview.py | 4 +-- 12 files changed, 77 insertions(+), 46 deletions(-) diff --git a/uno/.gitrepo b/uno/.gitrepo index ce475c4e..55b5cf2b 100644 --- a/uno/.gitrepo +++ b/uno/.gitrepo @@ -6,7 +6,7 @@ [subrepo] remote = https://github.com/prrvchr/uno.git branch = main - commit = d781bba36bafa8338fb6914fea7d155b1369dea8 - parent = e7bb738fc1e5672b0857c07baded8f2bed221831 + commit = 8ed499049ce1f91b7301b9e3ab840799005766f3 + parent = d46e9720194702074544e156dd8e4829a55d5224 method = merge cmdver = 0.4.9 diff --git a/uno/lib/uno/card/datasource.py b/uno/lib/uno/card/datasource.py index 72bdfc99..789edbfc 100644 --- a/uno/lib/uno/card/datasource.py +++ b/uno/lib/uno/card/datasource.py @@ -30,6 +30,8 @@ from com.sun.star.logging.LogLevel import INFO from com.sun.star.logging.LogLevel import SEVERE +from com.sun.star.uno import Exception as UnoException + from .database import DataBase from .provider import Provider @@ -45,6 +47,7 @@ from .helper import getSqlException +from .configuration import g_extension from threading import Event @@ -87,22 +90,29 @@ def closeConnection(self, connection): # Procedures called by Driver def getConnection(self, source, logger, url, scheme, server, account, password=''): + mtd = 'getConnection' uri = self._provider.getUserUri(server, account) if uri in self._maps: name = self._maps.get(uri) user = self._users.get(name) if not user.Request.isAuthorized(): - cls, mtd = 'DataSource', 'getConnection()' - raise getSqlException(self._ctx, source, 1002, 1401, cls, mtd, name) + raise getSqlException(self._ctx, source, 1002, 1401, self._cls, mtd, name, g_extension) else: user = User(self._ctx, source, logger, self._database, self._provider, url, scheme, server, account, password) name = user.getName() - self._users[name] = user - self._maps[uri] = name if user.isOnLine(): - self._provider.initAddressbooks(self._database, user) + try: + self._provider.initAddressbooks(self._database, user) + except UnoException as ex: + e = getSqlException(self._ctx, source, 1001, 1402, self._cls, mtd, name, g_extension) + e.NextException = ex + raise e connection = self._database.getConnection(name, user.getPassword()) + # XXX: New users are cached only if the connection is successful. + if not uri in self._maps: + self._users[name] = user + self._maps[uri] = name user.addSession(self._database.getSessionId(connection)) # User and/or AddressBooks has been initialized and the connection to the database is done... # We can start the database replication in a background task. diff --git a/uno/lib/uno/card/resource/Driver_en_US.properties b/uno/lib/uno/card/resource/Driver_en_US.properties index 06c3f67e..87b2ab9e 100644 --- a/uno/lib/uno/card/resource/Driver_en_US.properties +++ b/uno/lib/uno/card/resource/Driver_en_US.properties @@ -47,6 +47,7 @@ 1400=DataSource.getConnection() 1401=The user {} has abandoned the OAuth2 authorization wizard, the {} extension cannot continue without this authorization!!! +1402=The user {} cannot connect, the {} extension cannot continue without connection!!! 1500=User.__init__() diff --git a/uno/lib/uno/card/resource/Driver_fr_FR.properties b/uno/lib/uno/card/resource/Driver_fr_FR.properties index 3a578563..a40d95bd 100644 --- a/uno/lib/uno/card/resource/Driver_fr_FR.properties +++ b/uno/lib/uno/card/resource/Driver_fr_FR.properties @@ -47,6 +47,7 @@ 1400=DataSource.getConnection() 1401=L'utilisateur {} a abandonnι l'assistant d'autorisation OAuth2, l'extension {} ne peut pas continuer sans cette autorisation!!! +1402=L'utilisateur {} ne peut pas se connecter, l'extension {} ne peut pas continuer sans connexion!!! 1500=User.__init__() diff --git a/uno/lib/uno/grid/gridmanager.py b/uno/lib/uno/grid/gridmanager.py index 64b7935c..a972aacf 100644 --- a/uno/lib/uno/grid/gridmanager.py +++ b/uno/lib/uno/grid/gridmanager.py @@ -49,8 +49,7 @@ class GridManager(): - def __init__(self, ctx, url, model, window, quote, setting, selection, resources=None, maxi=None, multi=False, factor=5): - self._quote = quote + def __init__(self, ctx, url, model, window, setting, selection, resources=None, maxi=None, multi=False, factor=5): self._factor = factor self._datasource = None self._table = None @@ -119,10 +118,10 @@ def getSelectedIdentifiers(self, identifier): values.append(self._getRowValue(identifier, self.getUnsortedIndex(row))) return tuple(values) - def getGridData(self, columns, default=None): + def getGridData(self, columns, quote, default=None): values = {} for row in (range(self._model.RowCount)): - filter = self._getRowFilter(row) + filter = self._getRowFilter(row, quote) for column in columns: if column in self._headers: value = self._getColumnValue(row, column, default) @@ -131,12 +130,6 @@ def getGridData(self, columns, default=None): break return values - def getGridFilters(self): - filters = [] - for row in (range(self._model.RowCount)): - filters.append(self._getRowFilter(row)) - return tuple(filters) - def getSelectedStructuredFilters(self): filters = [] for row in self._view.getSelectedRows(): @@ -155,10 +148,10 @@ def _getColumnValue(self, row, column, value=None): value = self._model.getCellData(keys.index(column), self.getUnsortedIndex(row)) return value - def _getRowFilter(self, row): + def _getRowFilter(self, row, quote): filters = [] for identifier in self._indexes: - column = self._getQuotedIdentifier(identifier) + column = self._getQuotedIdentifier(identifier, quote) value = self._getQuotedValue(identifier, row) filter = '%s = %s' % (column, value) filters.append(filter) @@ -181,8 +174,8 @@ def _getQuotedValue(self, identifier, row): value = "%s" % value return value - def _getQuotedIdentifier(self, identifier): - return "%s%s%s" % (self._quote, identifier, self._quote) + def _getQuotedIdentifier(self, identifier, quote): + return quote + identifier + quote def _getRowValue(self, identifier, row): return self._model.getCellData(self._indexes[identifier], row) diff --git a/uno/lib/uno/oauth20/oauth2core.py b/uno/lib/uno/oauth20/oauth2core.py index 19e8762b..463c03d5 100644 --- a/uno/lib/uno/oauth20/oauth2core.py +++ b/uno/lib/uno/oauth20/oauth2core.py @@ -27,23 +27,28 @@ β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β• """ +from ..unotool import getPropertyValueSet from ..unotool import getInteractionHandler from .oauth2lib import InteractionRequest -def getOAuth2UserName(ctx, source, url, message=''): +def getOAuth2UserName(ctx, source, url, message='', parent=None, context=''): username = '' handler = getInteractionHandler(ctx) + if parent: + handler.initialize(getPropertyValueSet({'Parent': parent, 'Context': context})) interaction = InteractionRequest(source, url, '', '', message) if handler.handleInteractionRequest(interaction): continuation = interaction.getContinuations()[-1] username = continuation.getUserName() return username -def getOAuth2Token(ctx, source, url, user, format=''): +def getOAuth2Token(ctx, source, url, user, format='', parent=None, context=''): token = '' handler = getInteractionHandler(ctx) + if parent: + handler.initialize(getPropertyValueSet({'Parent': parent, 'Context': context})) interaction = InteractionRequest(source, url, user, format, '') if handler.handleInteractionRequest(interaction): continuation = interaction.getContinuations()[-1] diff --git a/uno/lib/uno/ucb/__init__.py b/uno/lib/uno/ucb/__init__.py index 45be9115..621a3b35 100644 --- a/uno/lib/uno/ucb/__init__.py +++ b/uno/lib/uno/ucb/__init__.py @@ -33,7 +33,7 @@ from .dispatch import Dispatch -from .unotool import hasInterface +from .unotool import hasFrameInterface from .logger import getLogger diff --git a/uno/lib/uno/unotool/__init__.py b/uno/lib/uno/unotool/__init__.py index 323fe83d..5b23c277 100644 --- a/uno/lib/uno/unotool/__init__.py +++ b/uno/lib/uno/unotool/__init__.py @@ -94,6 +94,7 @@ from .unotool import getUrl from .unotool import getUrlPresentation from .unotool import getUrlTransformer +from .unotool import hasFrameInterface from .unotool import hasInterface from .unotool import hasService from .unotool import parseDateTime diff --git a/uno/lib/uno/unotool/statusindicator.py b/uno/lib/uno/unotool/statusindicator.py index 67962f71..bd766a1a 100644 --- a/uno/lib/uno/unotool/statusindicator.py +++ b/uno/lib/uno/unotool/statusindicator.py @@ -38,6 +38,7 @@ from .unotool import findFrame +from threading import Lock import traceback @@ -49,33 +50,27 @@ def __init__(self, ctx, name, offset=10): self._window = frame.getContainerWindow() self._progress = frame.createStatusIndicator() self._point = uno.createUnoStruct('com.sun.star.awt.Point', 0, offset) + self._lock = Lock() else: - self._window = self._progress = self._point = None + self._window = self._progress = self._point = self._lock = None self._value = 0 def start(self, text, value): if self._progress: - self._value = 0 + self._setValue(0) self._setWindowHeight() self._progress.start(text, value) def setText(self, text): if self._progress: - self._progress.setText(text) - # XXX: After defining the text, it is necessary to also define - # XXX: its value if we do not want to display an empty status bar. - self._progress.setValue(self._value) + self._setText(text) def setValue(self, value): if self._progress: # XXX: In order to be able to progress in the loops it is necessary # XXX: to be able to add value to the current progression value. # XXX: This is what is done here thanks to a negative value - if value < 0: - self._value += abs(value) - else: - self._value = value - self._progress.setValue(self._value) + self._setValue(value) def end(self): if self._progress: @@ -84,9 +79,21 @@ def end(self): def reset(self): if self._progress: - self._value = 0 + self._setValue(0) self._progress.reset() + def _setText(self, text): + with self._lock: + self._progress.setText(text) + + def _setValue(self, value): + with self._lock: + if value < 0: + self._value += abs(value) + else: + self._value = value + self._progress.setValue(self._value) + def _setWindowHeight(self, factor=1): size = self._window.getPosSize() offset = self._window.convertPointToPixel(self._point, APPFONT).Y * factor diff --git a/uno/lib/uno/unotool/taskevent.py b/uno/lib/uno/unotool/taskevent.py index 22ddaf5a..300197d3 100644 --- a/uno/lib/uno/unotool/taskevent.py +++ b/uno/lib/uno/unotool/taskevent.py @@ -32,6 +32,7 @@ from com.sun.star.task import XTaskEvent from threading import Event +import traceback class TaskEvent(unohelper.Base, @@ -51,7 +52,7 @@ def clear(self): return self._event.clear() def wait(self, timeout): - if not timeout > 0: + if timeout <= 0: timeout = None return self._event.wait(timeout) diff --git a/uno/lib/uno/unotool/unotool.py b/uno/lib/uno/unotool/unotool.py index 0341793b..1c9debfe 100644 --- a/uno/lib/uno/unotool/unotool.py +++ b/uno/lib/uno/unotool/unotool.py @@ -216,6 +216,11 @@ def hasInterface(component, interface): return True return False +def hasFrameInterface(component): + frame = 'com.sun.star.frame.XFrame2' + desktop = 'com.sun.star.frame.XDesktop2' + return hasInterface(component, frame) or hasInterface(component, desktop) + def hasService(ctx, name): service = createService(ctx, name) return service is not None @@ -424,16 +429,23 @@ def executeShell(ctx, url, option=''): shell = createService(ctx, 'com.sun.star.system.SystemShellExecute') shell.execute(url, option, 0) -def executeDispatch(ctx, url, /, **args): - frame = getDesktop(ctx).getCurrentFrame() - arguments = getPropertyValueSet(args) - getDispatcher(ctx).executeDispatch(frame, url, '', 0, arguments) +def executeDispatch(ctx, url, /, **kwargs): + frame = _getCurrentFrame(ctx) + properties = getPropertyValueSet(kwargs) + getDispatcher(ctx).executeDispatch(frame, url, '', 0, properties) -def executeDesktopDispatch(ctx, url, listener=None, /, **args): - frame = getDesktop(ctx).getCurrentFrame() - properties = getPropertyValueSet(args) +def executeDesktopDispatch(ctx, url, listener=None, /, **kwargs): + frame = _getCurrentFrame(ctx) + properties = getPropertyValueSet(kwargs) executeFrameDispatch(ctx, frame, url, listener, *properties) +def _getCurrentFrame(ctx): + desktop = getDesktop(ctx) + frame = desktop.getCurrentFrame() + if frame is None: + frame = desktop + return frame + def executeFrameDispatch(ctx, frame, url, listener=None, /, *properties): url = getUrl(ctx, url) dispatcher = frame.queryDispatch(url, '', 0) diff --git a/uno/lib/uno/wizard/wizardview.py b/uno/lib/uno/wizard/wizardview.py index b591079f..be855b3f 100644 --- a/uno/lib/uno/wizard/wizardview.py +++ b/uno/lib/uno/wizard/wizardview.py @@ -55,7 +55,7 @@ class WizardView(unohelper.Base): def __init__(self, ctx, handler, listener, listener1, parent, name, title, resize, point): self._name = 'Roadmap1' if name: - # XXX: We use a TOP XWindow + # XXX: With a frame name we use a TOP XWindow self._frame = getTopWindow(ctx, name) peer = self._frame.getContainerWindow() self._dialog = getContainerWindow(ctx, peer, handler, g_identifier, 'WizardTop') @@ -63,7 +63,7 @@ def __init__(self, ctx, handler, listener, listener1, parent, name, title, resiz self._frame.setComponent(self._dialog, None) self._frame.addCloseListener(listener) else: - # XXX: We use a MODAL XDialog + # XXX: Without frame name we use a MODAL XDialog self._frame = None self._dialog = getDialog(ctx, g_identifier, 'Wizard', handler, parent) self._point = point From 836be5f376c3634fa66b9f00f3f7b49d07046189 Mon Sep 17 00:00:00 2001 From: prrvchr Date: Fri, 24 Oct 2025 13:51:01 +0200 Subject: [PATCH 07/11] new version 1.4.0 --- README.md | 171 ++++++++++++++++--------------- README_fr.md | 171 ++++++++++++++++--------------- source/SQLiteOOo/description.xml | 2 +- 3 files changed, 181 insertions(+), 163 deletions(-) diff --git a/README.md b/README.md index df9b01a5..e081621f 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ **The use of this software subjects you to our [Terms Of Use][4].** -# version [1.3.3][5] +# version [1.4.0][5] ## Introduction: @@ -42,6 +42,7 @@ Being free software I encourage you: - To duplicate its [source code][12]. - To make changes, corrections, improvements. - To open [issue][13] if needed. +- To [participate in the costs][14] of [CASA certification][15]. In short, to participate in the development of this extension. Because it is together that we can make Free Software smarter. @@ -51,9 +52,9 @@ ___ ## Requirement: The SQLiteOOo extension uses the jdbcDriverOOo extension to work. -It must therefore meet the [requirement of the jdbcDriverOOo extension][14]. +It must therefore meet the [requirement of the jdbcDriverOOo extension][16]. -Additionally, due to [issue #156471][15] and following [PR#154989][16], the SQLiteOOo extension requires **LibreOffice version 24.2.x** minimum to work. +Additionally, due to [issue #156471][17] and following [PR#154989][18], the SQLiteOOo extension requires **LibreOffice version 24.2.x** minimum to work. ___ @@ -62,11 +63,11 @@ ___ It seems important that the file was not renamed when it was downloaded. If necessary, rename it before installing it. -- [![jdbcDriverOOo logo][18]][19] Install **[jdbcDriverOOo.oxt][20]** extension [![Version][21]][20] +- [![jdbcDriverOOo logo][20]][21] Install **[jdbcDriverOOo.oxt][22]** extension [![Version][23]][22] This extension is required to use the latest version of SQLite with all its features. -- ![SQLiteOOo logo][22] Install **[SQLiteOOo.oxt][23]** extension [![Version][24]][23] +- ![SQLiteOOo logo][24] Install **[SQLiteOOo.oxt][25]** extension [![Version][26]][25] Restart LibreOffice after installation. **Be careful, restarting LibreOffice may not be enough.** @@ -88,20 +89,20 @@ ___ In LibreOffice / OpenOffice go to File -> New -> Database...: -![SQLiteOOo screenshot 1][25] +![SQLiteOOo screenshot 1][27] In step: Select database: - select: Create a new database - in: Emdedded database: choose: Embedded SQLite Driver - click on button: Next -![SQLiteOOo screenshot 2][26] +![SQLiteOOo screenshot 2][28] In step: Save and proceed: - adjust the parameters according to your needs... - click on button: Finish -![SQLiteOOo screenshot 3][27] +![SQLiteOOo screenshot 3][29] Have fun... @@ -109,17 +110,17 @@ ___ ## How does it work: -SQLiteOOo is an [com.sun.star.sdbc.Driver][28] UNO service written in Python. -It is an overlay to the [jdbcDriverOOo][19] extension allowing to store the SQLite database in an odb file (which is, in fact, a compressed file). +SQLiteOOo is an [com.sun.star.sdbc.Driver][30] UNO service written in Python. +It is an overlay to the [jdbcDriverOOo][21] extension allowing to store the SQLite database in an odb file (which is, in fact, a compressed file). Its operation is quite basic, namely: - When requesting a connection, several things are done: - If it does not already exist, a **subdirectory** with name: `.` + `odb_file_name` + `.lck` is created in the location of the odb file where all SQLite files are extracted from the **database** directory of the odb file (unzip). - - The [jdbcDriverOOo][19] extension is used to get the [com.sun.star.sdbc.XConnection][29] interface from the **subdirectory** path + `/sqlite`. - - If the connection is successful, a [DocumentHandler][30] is added as an [com.sun.star.util.XCloseListener][31] and [com.sun.star.document.XStorageChangeListener][32] to the odb file. + - The [jdbcDriverOOo][21] extension is used to get the [com.sun.star.sdbc.XConnection][31] interface from the **subdirectory** path + `/sqlite`. + - If the connection is successful, a [DocumentHandler][32] is added as an [com.sun.star.util.XCloseListener][33] and [com.sun.star.document.XStorageChangeListener][34] to the odb file. - If the connection is unsuccessful and the files was extracted in phase 1, the **subdirectory** will be deleted. -- When closing or renaming (Save As) the odb file, if the connection was successful, the [DocumentHandler][30] copies all files present in the **subdirectory** into the (new) **database** directory of the odb file (zip), then delete the **subdirectory**. +- When closing or renaming (Save As) the odb file, if the connection was successful, the [DocumentHandler][32] copies all files present in the **subdirectory** into the (new) **database** directory of the odb file (zip), then delete the **subdirectory**. The main purpose of this mode of operation is to take advantage of the ACID characteristics of the underlying database in the event of an abnormal closure of LibreOffice. On the other hand, the function: **file -> Save** has **no effect on the underlying database**. Only closing the odb file or saving it under a different name (File -> Save As) will save the database in the odb file. @@ -128,12 +129,12 @@ ___ ## How to build the extension: -Normally, the extension is created with Eclipse for Java and [LOEclipse][33]. To work around Eclipse, I modified LOEclipse to allow the extension to be created with Apache Ant. +Normally, the extension is created with Eclipse for Java and [LOEclipse][35]. To work around Eclipse, I modified LOEclipse to allow the extension to be created with Apache Ant. To create the SQLiteOOo extension with the help of Apache Ant, you need to: -- Install the [Java SDK][34] version 8 or higher. -- Install [Apache Ant][35] version 1.10.0 or higher. -- Install [LibreOffice and its SDK][36] version 7.x or higher. -- Clone the [SQLiteOOo][37] repository on GitHub into a folder. +- Install the [Java SDK][36] version 8 or higher. +- Install [Apache Ant][37] version 1.10.0 or higher. +- Install [LibreOffice and its SDK][38] version 7.x or higher. +- Clone the [SQLiteOOo][39] repository on GitHub into a folder. - From this folder, move to the directory: `source/SQLiteOOo/` - In this directory, edit the file: `build.properties` so that the `office.install.dir` and `sdk.dir` properties point to the folders where LibreOffice and its SDK were installed, respectively. - Start the archive creation process using the command: `ant` @@ -157,11 +158,11 @@ ___ ### What has been done for version 1.0.0: -- Integration of SQLite JDBC version 3.42.0.0. I especially want to thank [gotson][38] for the [many improvements to the SQLite JDBC driver][39] that made it possible to use SQLite in LibreOffice/OpenOffice. +- Integration of SQLite JDBC version 3.42.0.0. I especially want to thank [gotson][40] for the [many improvements to the SQLite JDBC driver][41] that made it possible to use SQLite in LibreOffice/OpenOffice. ### What has been done for version 1.0.1: -- Fixed [bug 156511][40] occurring when using the com.sun.star.embed.XStorage interface. The [workaround][41] is to use the copyElementTo() method instead of moveElementTo(). Versions of LibreOffice 7.6.x and higher become usable. +- Fixed [bug 156511][42] occurring when using the com.sun.star.embed.XStorage interface. The [workaround][43] is to use the copyElementTo() method instead of moveElementTo(). Versions of LibreOffice 7.6.x and higher become usable. ### What has been done for version 1.0.2: @@ -171,22 +172,22 @@ ___ ### What has been done for version 1.1.0: -- All Python packages necessary for the extension are now recorded in a [requirements.txt][42] file following [PEP 508][43]. +- All Python packages necessary for the extension are now recorded in a [requirements.txt][44] file following [PEP 508][45]. - Now if you are not on Windows then the Python packages necessary for the extension can be easily installed with the command: `pip install requirements.txt` -- Modification of the [Requirement][44] section. +- Modification of the [Requirement][46] section. ### What has been done for version 1.1.1: -- Support for [new features][45] in **jdbcDriverOOo 1.1.2**. +- Support for [new features][47] in **jdbcDriverOOo 1.1.2**. ### What has been done for version 1.1.2: -- SQLite driver updated to latest version [SQLite-jdbc-3.45.1.3-SNAPSHOT.jar][46]. This new driver has been implemented to support part of the JDBC 4.1 specifications and more particularly the `java.sql.Statement.getGeneratedKeys()` interface and allows the use of the [com.sun.star.sdbc.XGeneratedResultSet][47] interface. +- SQLite driver updated to latest version [SQLite-jdbc-3.45.1.3-SNAPSHOT.jar][48]. This new driver has been implemented to support part of the JDBC 4.1 specifications and more particularly the `java.sql.Statement.getGeneratedKeys()` interface and allows the use of the [com.sun.star.sdbc.XGeneratedResultSet][49] interface. ### What has been done for version 1.1.3: -- Support for the latest version of **jdbcDriverOOo 1.1.4** and the [SQLite-jdbc-3.45.1.6-SNAPSHOT.jar][48]. +- Support for the latest version of **jdbcDriverOOo 1.1.4** and the [SQLite-jdbc-3.45.1.6-SNAPSHOT.jar][50]. - Now for proper functioning in Base under: **Edit -> Database -> Advanced Settings... -> Query of generated values** must be left blank. If you want to use an odb file created with a previous version of SQLiteOOo you must change this setting manually. - Normally the next versions of SQLiteOOo should be able to be updated in the list of extensions installed under LibreOffice: **Tools -> Extension manager... -> Check for Updates**. @@ -201,19 +202,19 @@ ___ ### What has been done for version 1.2.0: -- This version is based on [fix #154989][49] available since LibreOffice 24.2.x. It can therefore work with other extensions offering integrated database services. +- This version is based on [fix #154989][51] available since LibreOffice 24.2.x. It can therefore work with other extensions offering integrated database services. - Now SQLiteOOo requires LibreOffice 24.2.x minimum and will load for the url: `sdbc:embedded:sqlite`. ### What has been done for version 1.2.1: -- Updated the [Python packaging][50] package to version 24.1. -- Updated the [Python setuptools][51] package to version 72.1.0. +- Updated the [Python packaging][52] package to version 24.1. +- Updated the [Python setuptools][53] package to version 72.1.0. - The extension will ask you to install the jdbcDriverOOo extension in versions 1.4.2 minimum. ### What has been done for version 1.2.2: -- Fixed [issue #2][52] which appears to be a regression related to the release of JaybirdOOo. Thanks to madalienist for reporting it. -- Updated the [Python setuptools][51] package to version 73.0.1. +- Fixed [issue #2][54] which appears to be a regression related to the release of JaybirdOOo. Thanks to madalienist for reporting it. +- Updated the [Python setuptools][53] package to version 73.0.1. - The extension options are now accessible via: **Tools -> Options -> LibreOffice Base -> Embedded SQLite Driver** - Logging accessible in extension options now displays correctly on Windows. - Changes to extension options that require a restart of LibreOffice will result in a message being displayed. @@ -228,12 +229,12 @@ ___ ### What has been done for version 1.3.0: -- Updated the [Python packaging][50] package to version 25.0. -- Updated the [Python setuptools][51] package to version 75.3.2. -- Passive registration deployment that allows for much faster installation of extensions and differentiation of registered UNO services from those provided by a Java or Python implementation. This passive registration is provided by the [LOEclipse][33] extension via [PR#152][53] and [PR#157][54]. -- Modified [LOEclipse][33] to support the new `rdb` file format produced by the `unoidl-write` compilation utility. `idl` files have been updated to support both available compilation tools: idlc and unoidl-write. -- Implemented [PEP 570][55] in [logging][56] to support unique multiple arguments. -- It is now possible to build the oxt file of the SQLiteOOo extension only with the help of Apache Ant and a copy of the GitHub repository. The [How to build the extension][57] section has been added to the documentation. +- Updated the [Python packaging][52] package to version 25.0. +- Updated the [Python setuptools][53] package to version 75.3.2. +- Passive registration deployment that allows for much faster installation of extensions and differentiation of registered UNO services from those provided by a Java or Python implementation. This passive registration is provided by the [LOEclipse][35] extension via [PR#152][55] and [PR#157][56]. +- Modified [LOEclipse][35] to support the new `rdb` file format produced by the `unoidl-write` compilation utility. `idl` files have been updated to support both available compilation tools: idlc and unoidl-write. +- Implemented [PEP 570][57] in [logging][58] to support unique multiple arguments. +- It is now possible to build the oxt file of the SQLiteOOo extension only with the help of Apache Ant and a copy of the GitHub repository. The [How to build the extension][59] section has been added to the documentation. - Any errors occurring while loading the driver will be logged in the extension's log if logging has been previously enabled. This makes it easier to identify installation problems on Windows. - Requires the **jdbcDriverOOo extension at least version 1.5.0**. @@ -250,7 +251,13 @@ ___ - Requires the **jdbcDriverOOo extension at least version 1.5.7**. -### What remains to be done for version 1.3.3: +### What has been done for version 1.4.0: + +- If the jdbcDriverOOo extension works without Java instrumentation, a warning message will be displayed in the extension options. +- Requires the **jdbcDriverOOo extension at least version 1.6.0**. +- Has been tested under LibreOfficeDev 26.2. + +### What remains to be done for version 1.4.0: - Add new language for internationalization... @@ -260,7 +267,7 @@ ___ [2]: [3]: [4]: -[5]: +[5]: [6]: [7]: [8]: @@ -269,46 +276,48 @@ ___ [11]: [12]: [13]: -[14]: -[15]: -[16]: -[18]: -[19]: -[20]: -[21]: -[22]: -[23]: -[24]: -[25]: -[26]: -[27]: -[28]: -[29]: -[30]: -[31]: -[32]: -[33]: -[34]: -[35]: -[36]: -[37]: -[38]: -[39]: -[40]: -[41]: -[42]: -[43]: -[44]: -[45]: -[46]: -[47]: -[48]: -[49]: -[50]: -[51]: -[52]: -[53]: -[54]: -[55]: -[56]: -[57]: +[14]: +[15]: +[16]: +[17]: +[18]: +[20]: +[21]: +[22]: +[23]: +[24]: +[25]: +[26]: +[27]: +[28]: +[29]: +[30]: +[31]: +[32]: +[33]: +[34]: +[35]: +[36]: +[37]: +[38]: +[39]: +[40]: +[41]: +[42]: +[43]: +[44]: +[45]: +[46]: +[47]: +[48]: +[49]: +[50]: +[51]: +[52]: +[53]: +[54]: +[55]: +[56]: +[57]: +[58]: +[59]: diff --git a/README_fr.md b/README_fr.md index 53f5d593..c2959dea 100644 --- a/README_fr.md +++ b/README_fr.md @@ -29,7 +29,7 @@ **L'utilisation de ce logiciel vous soumet Γ  nos [Conditions d'utilisation][4].** -# version [1.3.3][5] +# version [1.4.0][5] ## Introduction: @@ -42,6 +42,7 @@ Etant un logiciel libre je vous encourage: - A dupliquer son [code source][12]. - A apporter des modifications, des corrections, des amΓ©liorations. - D'ouvrir un [dysfonctionnement][13] si nΓ©cessaire. +- De [participer au frais][14] de la [certification CASA][15]. Bref, Γ  participer au developpement de cette extension. Car c'est ensemble que nous pouvons rendre le Logiciel Libre plus intelligent. @@ -51,9 +52,9 @@ ___ ## PrΓ©requis: L'extension SQLiteOOo utilise l'extension jdbcDriverOOo pour fonctionner. -Elle doit donc rΓ©pondre aux [prΓ©requis de l'extension jdbcDriverOOo][14]. +Elle doit donc rΓ©pondre aux [prΓ©requis de l'extension jdbcDriverOOo][16]. -De plus, en raison du [dysfonctionnement #156471][15] et suivant le [PR#154989][16], l'extension SQLiteOOo nΓ©cessite **LibreOffice version 24.2.x** minimum pour fonctionner. +De plus, en raison du [dysfonctionnement #156471][17] et suivant le [PR#154989][18], l'extension SQLiteOOo nΓ©cessite **LibreOffice version 24.2.x** minimum pour fonctionner. ___ @@ -62,11 +63,11 @@ ___ Il semble important que le fichier n'ait pas Γ©tΓ© renommΓ© lors de son tΓ©lΓ©chargement. Si nΓ©cessaire, renommez-le avant de l'installer. -- [![jdbcDriverOOo logo][18]][19] Installer l'extension **[jdbcDriverOOo.oxt][20]** [![Version][21]][20] +- [![jdbcDriverOOo logo][20]][21] Installer l'extension **[jdbcDriverOOo.oxt][22]** [![Version][23]][22] Cette extension est nΓ©cessaire pour utiliser la derniΓ¨re version de SQLite avec toutes ses fonctionnalitΓ©s. -- ![SQLiteOOo logo][22] Installer l'extension **[SQLiteOOo.oxt][23]** [![Version][24]][23] +- ![SQLiteOOo logo][24] Installer l'extension **[SQLiteOOo.oxt][25]** [![Version][26]][25] RedΓ©marrez LibreOffice aprΓ¨s l'installation. **Attention, redΓ©marrer LibreOffice peut ne pas suffire.** @@ -88,20 +89,20 @@ ___ Dans LibreOffice / OpenOffice aller Γ : Fichier -> Nouveau -> Base de donnΓ©es...: -![SQLiteOOo screenshot 1][25] +![SQLiteOOo screenshot 1][27] A l'Γ©tape: SΓ©lectionner une base de donnΓ©es: - selectionner: CrΓ©er une nouvelle base de donnΓ©es - Dans: Base de donnΓ©es intΓ©grΓ©e: choisir: Pilote SQLite intΓ©grΓ© - cliquer sur le bouton: Suivant -![SQLiteOOo screenshot 2][26] +![SQLiteOOo screenshot 2][28] A l'Γ©tape: Enregistrer et continuer: - ajuster les paramΓ¨tres selon vos besoins... - cliquer sur le bouton: Terminer -![SQLiteOOo screenshot 3][27] +![SQLiteOOo screenshot 3][29] Maintenant Γ  vous d'en profiter... @@ -109,17 +110,17 @@ ___ ## Comment Γ§a marche: -SQLiteOOo est un service [com.sun.star.sdbc.Driver][28] UNO Γ©crit en Python. -Il s'agit d'une surcouche Γ  l'extension [jdbcDriverOOo][19] permettant de stocker la base de donnΓ©es SQLite dans un fichier odb (qui est, en fait, un fichier compressΓ©). +SQLiteOOo est un service [com.sun.star.sdbc.Driver][30] UNO Γ©crit en Python. +Il s'agit d'une surcouche Γ  l'extension [jdbcDriverOOo][21] permettant de stocker la base de donnΓ©es SQLite dans un fichier odb (qui est, en fait, un fichier compressΓ©). Son fonctionnement est assez basique, Γ  savoir: - Lors d'une demande de connexion, plusieurs choses sont faites: - S'il n'existe pas dΓ©jΓ , un **sous-rΓ©pertoire** avec le nom: `.` + `nom_du_fichier_odb` + `.lck` est créé Γ  l'emplacement du fichier odb dans lequel tous les fichiers SQLite sont extraits du rΓ©pertoire **database** du fichier odb (dΓ©compression). - - L'extension [jdbcDriverOOo][19] est utilisΓ©e pour obtenir l'interface [com.sun.star.sdbc.XConnection][29] Γ  partir du chemin du **sous-rΓ©pertoire** + `/sqlite`. - - Si la connexion rΓ©ussi, un [DocumentHandler][30] est ajoutΓ© en tant que [com.sun.star.util.XCloseListener][31] et [com.sun.star.document.XStorageChangeListener][32] au fichier odb. + - L'extension [jdbcDriverOOo][21] est utilisΓ©e pour obtenir l'interface [com.sun.star.sdbc.XConnection][31] Γ  partir du chemin du **sous-rΓ©pertoire** + `/sqlite`. + - Si la connexion rΓ©ussi, un [DocumentHandler][32] est ajoutΓ© en tant que [com.sun.star.util.XCloseListener][33] et [com.sun.star.document.XStorageChangeListener][34] au fichier odb. - Si la connexion Γ©choue et que les fichiers ont Γ©tΓ© extraits lors de la phase 1, le **sous-rΓ©pertoire** est supprimΓ©. -- Lors de la fermeture ou du changement de nom (Enregistrer sous) du fichier odb, si la connexion a rΓ©ussi, le [DocumentHandler][30] copie tous les fichiers prΓ©sents dans le **sous-rΓ©pertoire** dans le (nouveau) rΓ©pertoire **database** du fichier odb (zip), puis supprime le **sous-rΓ©pertoire**. +- Lors de la fermeture ou du changement de nom (Enregistrer sous) du fichier odb, si la connexion a rΓ©ussi, le [DocumentHandler][32] copie tous les fichiers prΓ©sents dans le **sous-rΓ©pertoire** dans le (nouveau) rΓ©pertoire **database** du fichier odb (zip), puis supprime le **sous-rΓ©pertoire**. Le but principal de ce mode de fonctionnement est de profiter des caractΓ©ristiques ACID de la base de donnΓ©es sous-jacente en cas de fermeture anormale de LibreOffice. En contre partie, la fonction: **fichier -> Sauvegarder** n'a **aucun effet sur la base de donnΓ©es sous jacente**. Seul la fermeture du fichier odb ou son enregistrement sous un nom different (Fichier -> Enregistrer sous) effectura la sauvegarde de la base de donnΓ©e dans le fichier odb. @@ -128,12 +129,12 @@ ___ ## Comment crΓ©er l'extension: -Normalement, l'extension est créée avec Eclipse pour Java et [LOEclipse][33]. Pour contourner Eclipse, j'ai modifiΓ© LOEclipse afin de permettre la crΓ©ation de l'extension avec Apache Ant. +Normalement, l'extension est créée avec Eclipse pour Java et [LOEclipse][35]. Pour contourner Eclipse, j'ai modifiΓ© LOEclipse afin de permettre la crΓ©ation de l'extension avec Apache Ant. Pour crΓ©er l'extension SQLiteOOo avec l'aide d'Apache Ant, vous devez: -- Installer le [SDK Java][34] version 8 ou supΓ©rieure. -- Installer [Apache Ant][35] version 1.10.0 ou supΓ©rieure. -- Installer [LibreOffice et son SDK][36] version 7.x ou supΓ©rieure. -- Cloner le dΓ©pΓ΄t [SQLiteOOo][37] sur GitHub dans un dossier. +- Installer le [SDK Java][36] version 8 ou supΓ©rieure. +- Installer [Apache Ant][37] version 1.10.0 ou supΓ©rieure. +- Installer [LibreOffice et son SDK][38] version 7.x ou supΓ©rieure. +- Cloner le dΓ©pΓ΄t [SQLiteOOo][39] sur GitHub dans un dossier. - Depuis ce dossier, accΓ©dez au rΓ©pertoire: `source/SQLiteOOo/` - Dans ce rΓ©pertoire, modifiez le fichier `build.properties` afin que les propriΓ©tΓ©s `office.install.dir` et `sdk.dir` pointent vers les dossiers d'installation de LibreOffice et de son SDK, respectivement. - Lancez la crΓ©ation de l'archive avec la commande: `ant` @@ -157,11 +158,11 @@ ___ ### Ce qui a Γ©tΓ© fait pour la version 1.0.0: -- IntΓ©gration de SQLite JDBC version 3.42.0.0. Je tiens tout particuliΓ¨rement Γ  remercier [gotson][38] pour les [nombreuses amΓ©liorations apportΓ©es au pilote SQLite JDBC][39] qui ont rendu possible l'utilisation de SQLite dans LibreOffice/OpenOffice. +- IntΓ©gration de SQLite JDBC version 3.42.0.0. Je tiens tout particuliΓ¨rement Γ  remercier [gotson][40] pour les [nombreuses amΓ©liorations apportΓ©es au pilote SQLite JDBC][41] qui ont rendu possible l'utilisation de SQLite dans LibreOffice/OpenOffice. ### Ce qui a Γ©tΓ© fait pour la version 1.0.1: -- RΓ©solution du [dysfonctionnement 156511][40] survenant lors de l'utilisation de l'interface com.sun.star.embed.XStorage. Le [contournement][41] consiste Γ  utiliser la mΓ©thode copyElementTo() au lieu de moveElementTo(). Les versions de LibreOffice 7.6.x et supΓ©rieures deviennent utilisables. +- RΓ©solution du [dysfonctionnement 156511][42] survenant lors de l'utilisation de l'interface com.sun.star.embed.XStorage. Le [contournement][43] consiste Γ  utiliser la mΓ©thode copyElementTo() au lieu de moveElementTo(). Les versions de LibreOffice 7.6.x et supΓ©rieures deviennent utilisables. ### Ce qui a Γ©tΓ© fait pour la version 1.0.2: @@ -171,22 +172,22 @@ ___ ### Ce qui a Γ©tΓ© fait pour la version 1.1.0: -- Tous les paquets Python nΓ©cessaires Γ  l'extension sont dΓ©sormais enregistrΓ©s dans un fichier [requirements.txt][42] suivant la [PEP 508][43]. +- Tous les paquets Python nΓ©cessaires Γ  l'extension sont dΓ©sormais enregistrΓ©s dans un fichier [requirements.txt][44] suivant la [PEP 508][45]. - DΓ©sormais si vous n'Γͺtes pas sous Windows alors les paquets Python nΓ©cessaires Γ  l'extension peuvent Γͺtre facilement installΓ©s avec la commande: `pip install requirements.txt` -- Modification de la section [PrΓ©requis][44]. +- Modification de la section [PrΓ©requis][46]. ### Ce qui a Γ©tΓ© fait pour la version 1.1.1: -- Prise en charge des [nouvelles fonctionnalitΓ©s][45] de **jdbcDriverOOo 1.1.2**. +- Prise en charge des [nouvelles fonctionnalitΓ©s][47] de **jdbcDriverOOo 1.1.2**. ### Ce qui a Γ©tΓ© fait pour la version 1.1.2: -- Pilote SQLite mis Γ  jour vers la derniΓ¨re version [SQLite-jdbc-3.45.1.3-SNAPSHOT.jar][46]. Ce nouveau pilote a Γ©tΓ© implΓ©mentΓ© pour supporter une partie des spΓ©cifications JDBC 4.1 et plus particuliΓ¨rement l'interface `java.sql.Statement.getGeneratedKeys()` et permet l'utilisation de l'interface [com.sun.star.sdbc.XGeneratedResultSet][47]. +- Pilote SQLite mis Γ  jour vers la derniΓ¨re version [SQLite-jdbc-3.45.1.3-SNAPSHOT.jar][48]. Ce nouveau pilote a Γ©tΓ© implΓ©mentΓ© pour supporter une partie des spΓ©cifications JDBC 4.1 et plus particuliΓ¨rement l'interface `java.sql.Statement.getGeneratedKeys()` et permet l'utilisation de l'interface [com.sun.star.sdbc.XGeneratedResultSet][49]. ### Ce qui a Γ©tΓ© fait pour la version 1.1.3: -- Prise en charge de la derniΓ¨re version de **jdbcDriverOOo 1.1.4** et de [SQLite-jdbc-3.45.1.6-SNAPSHOT.jar][48]. +- Prise en charge de la derniΓ¨re version de **jdbcDriverOOo 1.1.4** et de [SQLite-jdbc-3.45.1.6-SNAPSHOT.jar][50]. - Maintenant, pour un bon fonctionnement dans Base sous : **Γ‰dition -> Base de donnΓ©es -> ParamΓ¨tres avancΓ©s... -> RequΓͺte des valeurs gΓ©nΓ©rΓ©es** doit Γͺtre laissΓ©e vide. Si vous souhaitez utiliser un fichier odb créé avec une version prΓ©cΓ©dente de SQLiteOOo vous devez modifier ce paramΓ¨tre manuellement. - Normalement les prochaines versions de SQLiteOOo devraient pouvoir Γͺtre mises Γ  jour dans la liste des extensions installΓ©es sous LibreOffice: **Outils -> Gestionnaire des extensions... -> VΓ©rifier les mises Γ  jour**. @@ -201,19 +202,19 @@ ___ ### Ce qui a Γ©tΓ© fait pour la version 1.2.0: -- Cette version est basΓ©e sur la [correction #154989][49] disponible depuis LibreOffice 24.2.x. Elle peut donc fonctionner avec les autres extensions proposant des services de bases de donnΓ©es intΓ©grΓ©es. +- Cette version est basΓ©e sur la [correction #154989][51] disponible depuis LibreOffice 24.2.x. Elle peut donc fonctionner avec les autres extensions proposant des services de bases de donnΓ©es intΓ©grΓ©es. - DΓ©sormais, SQLiteOOo nΓ©cessite LibreOffice 24.2.x minimum et se chargera pour l'url: `sdbc:embedded:sqlite`. ### Ce qui a Γ©tΓ© fait pour la version 1.2.1: -- Mise Γ  jour du paquet [Python packaging][50] vers la version 24.1. -- Mise Γ  jour du paquet [Python setuptools][51] vers la version 72.1.0. +- Mise Γ  jour du paquet [Python packaging][52] vers la version 24.1. +- Mise Γ  jour du paquet [Python setuptools][53] vers la version 72.1.0. - L'extension vous demandera d'installer l'extensions jdbcDriverOOo en version 1.4.2 minimum. ### Ce qui a Γ©tΓ© fait pour la version 1.2.2: -- Correction du [problΓ¨me nΒ°2][52] qui semble Γͺtre une rΓ©gression liΓ©e Γ  la sortie de JaybirdOOo. Merci Γ  madalienist de l'avoir signalΓ©. -- Mise Γ  jour du paquet [Python setuptools][51] vers la version 73.0.1. +- Correction du [problΓ¨me nΒ°2][54] qui semble Γͺtre une rΓ©gression liΓ©e Γ  la sortie de JaybirdOOo. Merci Γ  madalienist de l'avoir signalΓ©. +- Mise Γ  jour du paquet [Python setuptools][53] vers la version 73.0.1. - Les options de l'extension sont dΓ©sormais accessibles via: **Outils -> Options -> LibreOffice Base -> Pilote SQLite intΓ©grΓ©** - La journalisation accessible dans les options de l’extension s’affiche dΓ©sormais correctement sous Windows. - Les modifications apportΓ©es aux options de l'extension, qui nΓ©cessitent un redΓ©marrage de LibreOffice, entraΓneront l'affichage d'un message. @@ -228,12 +229,12 @@ ___ ### Ce qui a Γ©tΓ© fait pour la version 1.3.0: -- Mise Γ  jour du paquet [Python packaging][50] vers la version 25.0. -- Mise Γ  jour du paquet [Python setuptools][51] vers la version 75.3.2. -- DΓ©ploiement de l'enregistrement passif permettant une installation beaucoup plus rapide des extensions et de diffΓ©rencier les services UNO enregistrΓ©s de ceux fournis par une implΓ©mentation Java ou Python. Cet enregistrement passif est assurΓ© par l'extension [LOEclipse][33] via les [PR#152][53] et [PR#157][54]. -- Modification de [LOEclipse][33] pour prendre en charge le nouveau format de fichier `rdb` produit par l'utilitaire de compilation `unoidl-write`. Les fichiers `idl` ont Γ©tΓ© mis Γ  jour pour prendre en charge les deux outils de compilation disponibles: idlc et unoidl-write. -- ImplΓ©mentation de [PEP 570][55] dans la [journalisation][56] pour prendre en charge les arguments multiples uniques. -- Il est dΓ©sormais possible de crΓ©er le fichier oxt de l'extension SQLiteOOo uniquement avec Apache Ant et une copie du dΓ©pΓ΄t GitHub. La section [Comment crΓ©er l'extension][57] a Γ©tΓ© ajoutΓ©e Γ  la documentation. +- Mise Γ  jour du paquet [Python packaging][52] vers la version 25.0. +- Mise Γ  jour du paquet [Python setuptools][53] vers la version 75.3.2. +- DΓ©ploiement de l'enregistrement passif permettant une installation beaucoup plus rapide des extensions et de diffΓ©rencier les services UNO enregistrΓ©s de ceux fournis par une implΓ©mentation Java ou Python. Cet enregistrement passif est assurΓ© par l'extension [LOEclipse][35] via les [PR#152][55] et [PR#157][56]. +- Modification de [LOEclipse][35] pour prendre en charge le nouveau format de fichier `rdb` produit par l'utilitaire de compilation `unoidl-write`. Les fichiers `idl` ont Γ©tΓ© mis Γ  jour pour prendre en charge les deux outils de compilation disponibles: idlc et unoidl-write. +- ImplΓ©mentation de [PEP 570][57] dans la [journalisation][58] pour prendre en charge les arguments multiples uniques. +- Il est dΓ©sormais possible de crΓ©er le fichier oxt de l'extension SQLiteOOo uniquement avec Apache Ant et une copie du dΓ©pΓ΄t GitHub. La section [Comment crΓ©er l'extension][59] a Γ©tΓ© ajoutΓ©e Γ  la documentation. - Toute erreur survenant lors du chargement du pilote sera consignΓ©e dans le journal de l'extension si la journalisation a Γ©tΓ© prΓ©alablement activΓ©. Cela facilite l'identification des problΓ¨mes d'installation sous Windows. - NΓ©cessite l'extension **jdbcDriverOOo en version 1.5.0 minimum**. @@ -250,7 +251,13 @@ ___ - NΓ©cessite l'extension **jdbcDriverOOo en version 1.5.7 minimum**. -### Que reste-t-il Γ  faire pour la version 1.3.3: +### Ce qui a Γ©tΓ© fait pour la version 1.4.0: + +- Si l'extension jdbcDriverOOo fonctionne sans l'instrumentation Java, un message d'avertissement s'affichera dans les options de l'extension. +- NΓ©cessite l'extension **jdbcDriverOOo en version 1.6.0 minimum**. +- A Γ©tΓ© testΓ© sous LibreOfficeDev 26.2. + +### Que reste-t-il Γ  faire pour la version 1.4.0: - Ajouter de nouvelles langue pour l'internationalisation... @@ -260,7 +267,7 @@ ___ [2]: [3]: [4]: -[5]: +[5]: [6]: [7]: [8]: @@ -269,46 +276,48 @@ ___ [11]: [12]: [13]: -[14]: -[15]: -[16]: -[18]: -[19]: -[20]: -[21]: -[22]: -[23]: -[24]: -[25]: -[26]: -[27]: -[28]: -[29]: -[30]: -[31]: -[32]: -[33]: -[34]: -[35]: -[36]: -[37]: -[38]: -[39]: -[40]: -[41]: -[42]: -[43]: -[44]: -[45]: -[46]: -[47]: -[48]: -[49]: -[50]: -[51]: -[52]: -[53]: -[54]: -[55]: -[56]: -[57]: +[14]: +[15]: +[16]: +[17]: +[18]: +[20]: +[21]: +[22]: +[23]: +[24]: +[25]: +[26]: +[27]: +[28]: +[29]: +[30]: +[31]: +[32]: +[33]: +[34]: +[35]: +[36]: +[37]: +[38]: +[39]: +[40]: +[41]: +[42]: +[43]: +[44]: +[45]: +[46]: +[47]: +[48]: +[49]: +[50]: +[51]: +[52]: +[53]: +[54]: +[55]: +[56]: +[57]: +[58]: +[59]: diff --git a/source/SQLiteOOo/description.xml b/source/SQLiteOOo/description.xml index 04ec0c9e..6fc46a4a 100644 --- a/source/SQLiteOOo/description.xml +++ b/source/SQLiteOOo/description.xml @@ -28,7 +28,7 @@ xmlns:d="http://openoffice.org/extensions/description/2006" xmlns:l="http://libreoffice.org/extensions/description/2011" xmlns:xlink="http://www.w3.org/1999/xlink"> - + From 589abab89cd8232834cc7cc7e431320a03653d03 Mon Sep 17 00:00:00 2001 From: prrvchr Date: Fri, 24 Oct 2025 18:04:34 +0200 Subject: [PATCH 08/11] git subrepo pull uno subrepo: subdir: "uno" merged: "bd0eb94d" upstream: origin: "https://github.com/prrvchr/uno.git" branch: "main" commit: "bd0eb94d" git-subrepo: version: "0.4.9" origin: "https://github.com/ingydotnet/git-subrepo.git" commit: "4f60dd7" --- uno/.gitrepo | 4 ++-- uno/lib/uno/grid/gridhandler.py | 14 ++++---------- uno/lib/uno/grid/gridmodel.py | 1 - uno/lib/uno/logger/dialog/loghandler.py | 1 - 4 files changed, 6 insertions(+), 14 deletions(-) diff --git a/uno/.gitrepo b/uno/.gitrepo index 55b5cf2b..a727ef58 100644 --- a/uno/.gitrepo +++ b/uno/.gitrepo @@ -6,7 +6,7 @@ [subrepo] remote = https://github.com/prrvchr/uno.git branch = main - commit = 8ed499049ce1f91b7301b9e3ab840799005766f3 - parent = d46e9720194702074544e156dd8e4829a55d5224 + commit = bd0eb94d87c86a3cfa38e3d057035249f9af2e40 + parent = 836be5f376c3634fa66b9f00f3f7b49d07046189 method = merge cmdver = 0.4.9 diff --git a/uno/lib/uno/grid/gridhandler.py b/uno/lib/uno/grid/gridhandler.py index 5fd13a80..5fca4af9 100644 --- a/uno/lib/uno/grid/gridhandler.py +++ b/uno/lib/uno/grid/gridhandler.py @@ -53,8 +53,7 @@ def callHandlerMethod(self, window, event, method): handled = True return handled except Exception as e: - msg = "Error: %s" % traceback.format_exc() - print(msg) + print("WindowHandler.callHandlerMethod() ERROR: %s" % traceback.format_exc()) def getSupportedMethodNames(self): return ('ShowColumns', @@ -69,19 +68,15 @@ def __init__(self, manager): # XGridDataListener def rowsInserted(self, event): try: - print("GridDataListener.dataChanged()") self._manager.dataGridChanged() except Exception as e: - msg = "Error: %s" % traceback.format_exc() - print(msg) + print("GridDataListener.rowsInserted() ERROR: %s" % traceback.format_exc()) def rowsRemoved(self, event): try: - print("GridDataListener.dataChanged()") self._manager.dataGridChanged() except Exception as e: - msg = "Error: %s" % traceback.format_exc() - print(msg) + print("GridDataListener.rowsRemoved() ERROR: %s" % traceback.format_exc()) def dataChanged(self, event): pass @@ -106,8 +101,7 @@ def selectionChanged(self, event): index = control.getSelectedRows()[-1] if control.hasSelectedRows() else -1 self._manager.changeGridSelection(index, self._grid) except Exception as e: - msg = "Error: %s" % traceback.format_exc() - print(msg) + print("GridSelectionListener.selectionChanged() ERROR: %s" % traceback.format_exc()) def disposing(self, event): pass diff --git a/uno/lib/uno/grid/gridmodel.py b/uno/lib/uno/grid/gridmodel.py index 3e0c7f20..94c863d2 100644 --- a/uno/lib/uno/grid/gridmodel.py +++ b/uno/lib/uno/grid/gridmodel.py @@ -113,7 +113,6 @@ def removeGridDataListener(self, listener): # XComponent def dispose(self): - print("GridModel.dispose() 1") event = uno.createUnoStruct('com.sun.star.lang.EventObject') event.Source = self for listener in self._events: diff --git a/uno/lib/uno/logger/dialog/loghandler.py b/uno/lib/uno/logger/dialog/loghandler.py index 343510f1..65110788 100644 --- a/uno/lib/uno/logger/dialog/loghandler.py +++ b/uno/lib/uno/logger/dialog/loghandler.py @@ -123,7 +123,6 @@ def __init__(self, manager): # XModifyListener def modified(self, event): try: - print("PoolListener.modified()") self._manager.updateLoggers() except Exception as e: msg = f"Error: {traceback.format_exc()}" From 03248b99582bfd847d94836a5d1736f072ba4f1d Mon Sep 17 00:00:00 2001 From: prrvchr Date: Sun, 2 Nov 2025 20:43:54 +0100 Subject: [PATCH 09/11] git subrepo pull uno subrepo: subdir: "uno" merged: "71034eaa" upstream: origin: "https://github.com/prrvchr/uno.git" branch: "main" commit: "71034eaa" git-subrepo: version: "0.4.9" origin: "https://github.com/ingydotnet/git-subrepo.git" commit: "4f60dd7" --- uno/.gitrepo | 4 +- uno/dialog/ucb/DialogStrings_en_US.default | 0 uno/dialog/ucb/DialogStrings_en_US.properties | 53 ---------- uno/dialog/ucb/DialogStrings_fr_FR.properties | 53 ---------- uno/dialog/wizard/Wizard.xdl | 2 +- uno/lib/python/pyRdfa/extras/httpheader.py | 6 +- .../LICENSE | 0 .../METADATA | 10 +- .../RECORD | 12 +-- .../WHEEL | 2 +- .../top_level.txt | 0 uno/lib/uno/grid/gridhandler.py | 8 +- uno/lib/uno/jdbcdriver/configuration.py | 2 +- uno/lib/uno/logger/dialog/loghandler.py | 19 ++-- uno/lib/uno/oauth20/__init__.py | 1 - uno/lib/uno/oauth20/configuration.py | 2 +- uno/lib/uno/oauth20/oauth2tool.py | 7 -- .../uno/options/addressbook/optionshandler.py | 4 +- uno/lib/uno/options/jdbc/optionshandler.py | 4 +- uno/lib/uno/ucb/datasource.py | 10 +- uno/lib/uno/ucb/dispatch.py | 14 +-- uno/lib/uno/ucb/helper.py | 37 +++---- uno/lib/uno/ucb/ucp/user.py | 10 +- uno/lib/uno/unotool/__init__.py | 3 - uno/lib/uno/unotool/statusindicator.py | 45 ++++----- uno/lib/uno/unotool/unotool.py | 98 +++++++------------ uno/lib/uno/wizard/wizard.py | 49 ++++------ uno/lib/uno/wizard/wizardhandler.py | 15 ++- uno/lib/uno/wizard/wizardview.py | 2 +- 29 files changed, 135 insertions(+), 337 deletions(-) delete mode 100644 uno/dialog/ucb/DialogStrings_en_US.default delete mode 100644 uno/dialog/ucb/DialogStrings_en_US.properties delete mode 100644 uno/dialog/ucb/DialogStrings_fr_FR.properties rename uno/lib/python/{pyRdfa3-3.6.4.dist-info => pyRdfa3-3.6.5.dist-info}/LICENSE (100%) rename uno/lib/python/{pyRdfa3-3.6.4.dist-info => pyRdfa3-3.6.5.dist-info}/METADATA (94%) rename uno/lib/python/{pyRdfa3-3.6.4.dist-info => pyRdfa3-3.6.5.dist-info}/RECORD (81%) rename uno/lib/python/{pyRdfa3-3.6.4.dist-info => pyRdfa3-3.6.5.dist-info}/WHEEL (65%) rename uno/lib/python/{pyRdfa3-3.6.4.dist-info => pyRdfa3-3.6.5.dist-info}/top_level.txt (100%) diff --git a/uno/.gitrepo b/uno/.gitrepo index a727ef58..7d565a77 100644 --- a/uno/.gitrepo +++ b/uno/.gitrepo @@ -6,7 +6,7 @@ [subrepo] remote = https://github.com/prrvchr/uno.git branch = main - commit = bd0eb94d87c86a3cfa38e3d057035249f9af2e40 - parent = 836be5f376c3634fa66b9f00f3f7b49d07046189 + commit = 71034eaa9f7627b2689444c2b80850322e67f5ea + parent = 589abab89cd8232834cc7cc7e431320a03653d03 method = merge cmdver = 0.4.9 diff --git a/uno/dialog/ucb/DialogStrings_en_US.default b/uno/dialog/ucb/DialogStrings_en_US.default deleted file mode 100644 index e69de29b..00000000 diff --git a/uno/dialog/ucb/DialogStrings_en_US.properties b/uno/dialog/ucb/DialogStrings_en_US.properties deleted file mode 100644 index 744963c8..00000000 --- a/uno/dialog/ucb/DialogStrings_en_US.properties +++ /dev/null @@ -1,53 +0,0 @@ -OptionsDialog.HelpText= -OptionsDialog.Title= -OptionsDialog.FixedLine1.HelpText= -OptionsDialog.FixedLine1.Label=gDriveOOo settings -OptionsDialog.Label1.HelpText= -OptionsDialog.Label1.Label=Replication interval: -OptionsDialog.NumericField1.HelpText=Replication interval in minutes -OptionsDialog.Label2.HelpText= -OptionsDialog.Label2.Label=View datasource: -OptionsDialog.CommandButton1.HelpText= -OptionsDialog.CommandButton1.Label=View DataBase - -LogWindow.HelpText= -LogWindow.Title= -LogWindow.FixedLine1.HelpText= -LogWindow.FixedLine1.Label=Logger settings -LogWindow.Label1.HelpText= -LogWindow.Label1.Label=Available loggers: -LogWindow.ListBox1.HelpText= -LogWindow.ListBox1.Text= -LogWindow.CheckBox1.HelpText= -LogWindow.CheckBox1.Label=Enable logger -LogWindow.Label2.HelpText= -LogWindow.Label2.Label=Output: -LogWindow.OptionButton1.HelpText= -LogWindow.OptionButton1.Label=Console -LogWindow.OptionButton2.HelpText= -LogWindow.OptionButton2.Label=File -LogWindow.CommandButton1.HelpText= -LogWindow.CommandButton1.Label=View log -LogWindow.Label3.HelpText= -LogWindow.Label3.Label=Level: -LogWindow.ListBox2.HelpText= -LogWindow.ListBox2.Text= -LogWindow.ListBox2.StringItemList.0=Sever -LogWindow.ListBox2.StringItemList.1=Warning -LogWindow.ListBox2.StringItemList.2=Info -LogWindow.ListBox2.StringItemList.3=Config -LogWindow.ListBox2.StringItemList.4=Fine -LogWindow.ListBox2.StringItemList.5=Finer -LogWindow.ListBox2.StringItemList.6=Finest -LogWindow.ListBox2.StringItemList.7=All - -LogDialog.HelpText= -LogDialog.Title=Log file - %s -LogDialog.TextField1.HelpText= -LogDialog.TextField1.Text= -LogDialog.CommandButton1.HelpText= -LogDialog.CommandButton1.Label=System Info -LogDialog.CommandButton2.HelpText= -LogDialog.CommandButton2.Label=Clear -LogDialog.CommandButton3.HelpText= -LogDialog.CommandButton3.Label=Close diff --git a/uno/dialog/ucb/DialogStrings_fr_FR.properties b/uno/dialog/ucb/DialogStrings_fr_FR.properties deleted file mode 100644 index a91d7b93..00000000 --- a/uno/dialog/ucb/DialogStrings_fr_FR.properties +++ /dev/null @@ -1,53 +0,0 @@ -OptionsDialog.HelpText= -OptionsDialog.Title= -OptionsDialog.FixedLine1.HelpText= -OptionsDialog.FixedLine1.Label=Options gDriveOOo -OptionsDialog.Label1.HelpText= -OptionsDialog.Label1.Label=Intervalle de r\u00e9plication: -OptionsDialog.NumericField1.HelpText=Intervalle de r\u00e9plication en minutes -OptionsDialog.Label2.HelpText= -OptionsDialog.Label2.Label=Voir la source de donn\u00e9es: -OptionsDialog.CommandButton1.HelpText= -OptionsDialog.CommandButton1.Label=Voir la base de donn\u00e9es - -LogWindow.HelpText= -LogWindow.Title= -LogWindow.FixedLine1.HelpText= -LogWindow.FixedLine1.Label=Options de journalisation -LogWindow.Label1.HelpText= -LogWindow.Label1.Label=Journaux disponibles: -LogWindow.ListBox1.HelpText= -LogWindow.ListBox1.Text= -LogWindow.CheckBox1.HelpText= -LogWindow.CheckBox1.Label=Activer le journal -LogWindow.Label2.HelpText= -LogWindow.Label2.Label=Sortie: -LogWindow.OptionButton1.HelpText= -LogWindow.OptionButton1.Label=Console -LogWindow.OptionButton2.HelpText= -LogWindow.OptionButton2.Label=Fichier -LogWindow.CommandButton1.HelpText= -LogWindow.CommandButton1.Label=Voir journal -LogWindow.Label3.HelpText= -LogWindow.Label3.Label=Seuil: -LogWindow.ListBox2.HelpText= -LogWindow.ListBox2.Text= -LogWindow.ListBox2.StringItemList.0=Grave -LogWindow.ListBox2.StringItemList.1=Alerte -LogWindow.ListBox2.StringItemList.2=Info -LogWindow.ListBox2.StringItemList.3=Config -LogWindow.ListBox2.StringItemList.4=Basique -LogWindow.ListBox2.StringItemList.5=Fin -LogWindow.ListBox2.StringItemList.6=Tr\u00e9s fin -LogWindow.ListBox2.StringItemList.7=Tout - -LogDialog.HelpText= -LogDialog.Title=Fichier journal - %s -LogDialog.TextField1.HelpText= -LogDialog.TextField1.Text= -LogDialog.CommandButton1.HelpText= -LogDialog.CommandButton1.Label=Info syst\u00e8me -LogDialog.CommandButton2.HelpText= -LogDialog.CommandButton2.Label=Effacer -LogDialog.CommandButton3.HelpText= -LogDialog.CommandButton3.Label=Fermer diff --git a/uno/dialog/wizard/Wizard.xdl b/uno/dialog/wizard/Wizard.xdl index 558b7eaa..3fcd3627 100644 --- a/uno/dialog/wizard/Wizard.xdl +++ b/uno/dialog/wizard/Wizard.xdl @@ -25,7 +25,7 @@ β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β• --> - + diff --git a/uno/lib/python/pyRdfa/extras/httpheader.py b/uno/lib/python/pyRdfa/extras/httpheader.py index 7a81a263..e43b1207 100644 --- a/uno/lib/python/pyRdfa/extras/httpheader.py +++ b/uno/lib/python/pyRdfa/extras/httpheader.py @@ -344,7 +344,7 @@ def parse_quoted_string(s, start=0): """Parses a quoted string. Returns a tuple (string, chars_consumed). The quote marks will - have been removed and all \-escapes will have been replaced with + have been removed and all \\-escapes will have been replaced with the characters they represent. """ @@ -356,7 +356,7 @@ def parse_token_or_quoted_string(s, start=0, allow_quoted=True, allow_token=True 's' is the string to parse, while start is the position within the string where parsing should begin. It will returns a tuple - (token, chars_consumed), with all \-escapes and quotation already + (token, chars_consumed), with all \\-escapes and quotation already processed. Syntax is according to BNF rules in RFC 2161 section 2.2, @@ -522,7 +522,7 @@ def parse_comment(s, start=0): nested comments will still have their parentheses and whitespace left intact. - All \-escaped quoted pairs will have been replaced with the actual + All \\-escaped quoted pairs will have been replaced with the actual characters they represent, even within the inner nested comments. You should note that only a few HTTP headers, such as User-Agent diff --git a/uno/lib/python/pyRdfa3-3.6.4.dist-info/LICENSE b/uno/lib/python/pyRdfa3-3.6.5.dist-info/LICENSE similarity index 100% rename from uno/lib/python/pyRdfa3-3.6.4.dist-info/LICENSE rename to uno/lib/python/pyRdfa3-3.6.5.dist-info/LICENSE diff --git a/uno/lib/python/pyRdfa3-3.6.4.dist-info/METADATA b/uno/lib/python/pyRdfa3-3.6.5.dist-info/METADATA similarity index 94% rename from uno/lib/python/pyRdfa3-3.6.4.dist-info/METADATA rename to uno/lib/python/pyRdfa3-3.6.5.dist-info/METADATA index c86833e1..ff2ca97b 100644 --- a/uno/lib/python/pyRdfa3-3.6.4.dist-info/METADATA +++ b/uno/lib/python/pyRdfa3-3.6.5.dist-info/METADATA @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: pyRdfa3 -Version: 3.6.4 +Version: 3.6.5 Summary: pyRdfa distiller/parser library Author-email: Ivan Herman & prrvchr Project-URL: Homepage, https://prrvchr.github.io/pyrdfa3/ @@ -11,9 +11,9 @@ Classifier: Operating System :: OS Independent Requires-Python: >=3.8 Description-Content-Type: text/markdown License-File: LICENSE -Requires-Dist: requests >=2.32.3 -Requires-Dist: rdflib >=7.0.0 -Requires-Dist: html5lib >=1.1 +Requires-Dist: requests (>=2.32.3) +Requires-Dist: rdflib (>=7.0.0) +Requires-Dist: html5lib (>=1.1) [![DOI](https://zenodo.org/badge/doi/10.5281/zenodo.14547.svg)](http://dx.doi.org/10.5281/zenodo.14547) @@ -21,7 +21,7 @@ Requires-Dist: html5lib >=1.1 > **Note:** since I retired a few months ago I do not really maintain this package any more. I would be more than happy if an interested party was interested to take over. In the meantime, I have "archived" the repository to clearly signal that there is no maintenance. I would be happy to unarchive it and transfer ownership if someone is interested. > [@iherman](https://github.com/iherman) -> **This new version 3.6.4 is now built and maintained on [prrvchr.github.io/pyrdfa3][1]** +> **This new version 3.6.5 is now built and maintained on [prrvchr.github.io/pyrdfa3][1]** The package can be installed from [PyPI][2] with command: diff --git a/uno/lib/python/pyRdfa3-3.6.4.dist-info/RECORD b/uno/lib/python/pyRdfa3-3.6.5.dist-info/RECORD similarity index 81% rename from uno/lib/python/pyRdfa3-3.6.4.dist-info/RECORD rename to uno/lib/python/pyRdfa3-3.6.5.dist-info/RECORD index 6a5cbf20..a41c40d4 100644 --- a/uno/lib/python/pyRdfa3-3.6.4.dist-info/RECORD +++ b/uno/lib/python/pyRdfa3-3.6.5.dist-info/RECORD @@ -9,7 +9,7 @@ pyRdfa/state.py,sha256=gbD41iGy-zJ7edkLmYFAPCAwC0VeUez38eXGF-RIQoM,24502 pyRdfa/termorcurie.py,sha256=M0ocu76xb1fTG6xGR5GAlfmK5aulVzBViBIIUUUzCBc,23387 pyRdfa/utils.py,sha256=apkz3UBF9zyObsnIadl2i6sm6ORzZA7xnuBSCCQBcPc,10229 pyRdfa/extras/__init__.py,sha256=ewApVDdXUYUQJiq-fpZBZ0ZO6OCIifz4kThymF8sCKs,105 -pyRdfa/extras/httpheader.py,sha256=D8DzCGmv6wEufJs1yg1d7ubDY2NY7rxF4XIeaUN8_g8,70183 +pyRdfa/extras/httpheader.py,sha256=fdn_P1zdAGLPR43VZ9rxeVxC1UVz2qDHBmlQ-jN1bsk,70186 pyRdfa/host/__init__.py,sha256=M0YxNcG3LGmj6aUf8QyCbbFi61UddyitcqYV9BmwvZY,10493 pyRdfa/host/atom.py,sha256=eO3kHFL3sIELeMp1EGZGbhhY9D45R9WfoFlyEQvBg0w,1141 pyRdfa/host/html5.py,sha256=aso2SDUvcOaCEM1wK1n-TRZB0YvwKx5jscbYKv1a94A,8241 @@ -22,8 +22,8 @@ pyRdfa/transform/__init__.py,sha256=rdLhZQSfv5K8zt4km8p1x7WIrjfcgJ6dqyGgIabgVRc, pyRdfa/transform/lite.py,sha256=0dI11FWNOJo7gYFwEDNuegXg9UZexuA5IoRCmXw2K1s,3478 pyRdfa/transform/metaname.py,sha256=3zB5M3jSyyQx1D3n_AUdVsFyjYShy938PzKVOFR3rIM,1153 pyRdfa/transform/prototype.py,sha256=eH8Bub1iIZ1SUu9FsskHmKtGKDJy0wWq3B9WhxqIevY,1328 -pyRdfa3-3.6.4.dist-info/LICENSE,sha256=GOjCqSTUS9_c4wVdtwvU3n-tfx1g3ylFh1WmS8sEdm8,1901 -pyRdfa3-3.6.4.dist-info/METADATA,sha256=dSqs6Fbnl9oggoWS5UVWCgxpGwEWe2UTh2K4FMt7IXk,3369 -pyRdfa3-3.6.4.dist-info/WHEEL,sha256=Wyh-_nZ0DJYolHNn1_hMa4lM7uDedD_RGVwbmTjyItk,91 -pyRdfa3-3.6.4.dist-info/top_level.txt,sha256=NhGN9_N-teibyYvfbpX1aDUW7al6WiIPLTdEjpWUII4,7 -pyRdfa3-3.6.4.dist-info/RECORD,, +pyRdfa3-3.6.5.dist-info/LICENSE,sha256=GOjCqSTUS9_c4wVdtwvU3n-tfx1g3ylFh1WmS8sEdm8,1901 +pyRdfa3-3.6.5.dist-info/METADATA,sha256=P2PhrqeYHeGPp26cr-RG8tof1UWoSjReXiBOQgjL80s,3375 +pyRdfa3-3.6.5.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91 +pyRdfa3-3.6.5.dist-info/top_level.txt,sha256=NhGN9_N-teibyYvfbpX1aDUW7al6WiIPLTdEjpWUII4,7 +pyRdfa3-3.6.5.dist-info/RECORD,, diff --git a/uno/lib/python/pyRdfa3-3.6.4.dist-info/WHEEL b/uno/lib/python/pyRdfa3-3.6.5.dist-info/WHEEL similarity index 65% rename from uno/lib/python/pyRdfa3-3.6.4.dist-info/WHEEL rename to uno/lib/python/pyRdfa3-3.6.5.dist-info/WHEEL index ecaf39f3..9b78c445 100644 --- a/uno/lib/python/pyRdfa3-3.6.4.dist-info/WHEEL +++ b/uno/lib/python/pyRdfa3-3.6.5.dist-info/WHEEL @@ -1,5 +1,5 @@ Wheel-Version: 1.0 -Generator: setuptools (71.1.0) +Generator: setuptools (75.3.0) Root-Is-Purelib: true Tag: py3-none-any diff --git a/uno/lib/python/pyRdfa3-3.6.4.dist-info/top_level.txt b/uno/lib/python/pyRdfa3-3.6.5.dist-info/top_level.txt similarity index 100% rename from uno/lib/python/pyRdfa3-3.6.4.dist-info/top_level.txt rename to uno/lib/python/pyRdfa3-3.6.5.dist-info/top_level.txt diff --git a/uno/lib/uno/grid/gridhandler.py b/uno/lib/uno/grid/gridhandler.py index 5fca4af9..d1426cdf 100644 --- a/uno/lib/uno/grid/gridhandler.py +++ b/uno/lib/uno/grid/gridhandler.py @@ -52,7 +52,7 @@ def callHandlerMethod(self, window, event, method): self._manager.setColumn(event.Source.getSelectedItemPos()) handled = True return handled - except Exception as e: + except: print("WindowHandler.callHandlerMethod() ERROR: %s" % traceback.format_exc()) def getSupportedMethodNames(self): @@ -69,13 +69,13 @@ def __init__(self, manager): def rowsInserted(self, event): try: self._manager.dataGridChanged() - except Exception as e: + except: print("GridDataListener.rowsInserted() ERROR: %s" % traceback.format_exc()) def rowsRemoved(self, event): try: self._manager.dataGridChanged() - except Exception as e: + except: print("GridDataListener.rowsRemoved() ERROR: %s" % traceback.format_exc()) def dataChanged(self, event): @@ -100,7 +100,7 @@ def selectionChanged(self, event): control = event.Source index = control.getSelectedRows()[-1] if control.hasSelectedRows() else -1 self._manager.changeGridSelection(index, self._grid) - except Exception as e: + except: print("GridSelectionListener.selectionChanged() ERROR: %s" % traceback.format_exc()) def disposing(self, event): diff --git a/uno/lib/uno/jdbcdriver/configuration.py b/uno/lib/uno/jdbcdriver/configuration.py index 776bb608..149e3931 100644 --- a/uno/lib/uno/jdbcdriver/configuration.py +++ b/uno/lib/uno/jdbcdriver/configuration.py @@ -34,7 +34,7 @@ g_services = ('io.github.prrvchr.jdbcdriver.sdbc.Driver', 'io.github.prrvchr.jdbcdriver.sdbcx.Driver', 'io.github.prrvchr.jdbcdriver.sdb.Driver') -g_version = '1.6.0' +g_version = '1.6.1' g_instrumented = 'SupportsInstrumentationAgent' # jdbcDriverOOo special configuration diff --git a/uno/lib/uno/logger/dialog/loghandler.py b/uno/lib/uno/logger/dialog/loghandler.py index 65110788..63073747 100644 --- a/uno/lib/uno/logger/dialog/loghandler.py +++ b/uno/lib/uno/logger/dialog/loghandler.py @@ -65,8 +65,8 @@ def callHandlerMethod(self, dialog, event, method): self._manager.setLevel(event.Source.getSelectedItemPos()) handled = True return handled - except Exception as e: - print("ERROR: %s - %s" % (e, traceback.format_exc())) + except: + print("WindowHandler.callHandlerMethod() ERROR: %s" % traceback.format_exc()) def getSupportedMethodNames(self): return ('SetLogger', @@ -90,9 +90,8 @@ def callHandlerMethod(self, dialog, event, method): self._manager.logInfos() handled = True return handled - except Exception as e: - msg = f"Error: {traceback.format_exc()}" - print(msg) + except: + print("DialogHandler.callHandlerMethod() ERROR: %s" % traceback.format_exc()) def getSupportedMethodNames(self): return ('LogInfo', ) @@ -107,9 +106,8 @@ def __init__(self, manager): def modified(self, event): try: self._manager.updateLogger() - except Exception as e: - msg = f"Error: {traceback.format_exc()}" - print(msg) + except: + print("LoggerListener.modified() ERROR: %s" % traceback.format_exc()) def disposing(self, event): pass @@ -124,9 +122,8 @@ def __init__(self, manager): def modified(self, event): try: self._manager.updateLoggers() - except Exception as e: - msg = f"Error: {traceback.format_exc()}" - print(msg) + except: + print("PoolListener.modified() ERROR: %s" % traceback.format_exc()) def disposing(self, event): pass diff --git a/uno/lib/uno/oauth20/__init__.py b/uno/lib/uno/oauth20/__init__.py index 87c7eb48..721859f2 100644 --- a/uno/lib/uno/oauth20/__init__.py +++ b/uno/lib/uno/oauth20/__init__.py @@ -32,7 +32,6 @@ from .oauth2lib import NoOAuth2 from .oauth2lib import OAuth2OOo -from .oauth2tool import getOAuth2 from .oauth2tool import getOAuth2Version from .oauth2tool import getParserItems from .oauth2tool import getRequest diff --git a/uno/lib/uno/oauth20/configuration.py b/uno/lib/uno/oauth20/configuration.py index d9030399..6c9ecd8e 100644 --- a/uno/lib/uno/oauth20/configuration.py +++ b/uno/lib/uno/oauth20/configuration.py @@ -33,7 +33,7 @@ g_service = '%s.OAuth2Service' % g_identifier g_resource = 'resource' -g_version = '1.6.0' +g_version = '1.6.1' g_chunk = g_chunk = 320 * 1024 g_token = 'Bearer ${AccessToken}' diff --git a/uno/lib/uno/oauth20/oauth2tool.py b/uno/lib/uno/oauth20/oauth2tool.py index 65c15a59..9d594b87 100644 --- a/uno/lib/uno/oauth20/oauth2tool.py +++ b/uno/lib/uno/oauth20/oauth2tool.py @@ -51,13 +51,6 @@ def getRequest(ctx, url=None, name=None): request = createService(ctx, g_service) return request -def getOAuth2(ctx, url='', name=''): - if url and name: - oauth2 = createService(ctx, g_service, url, name) - else: - oauth2 = createService(ctx, g_service) - return oauth2 - def getOAuth2Version(ctx): version = getExtensionVersion(ctx, g_identifier) return version diff --git a/uno/lib/uno/options/addressbook/optionshandler.py b/uno/lib/uno/options/addressbook/optionshandler.py index ed8e8385..e8e38c75 100644 --- a/uno/lib/uno/options/addressbook/optionshandler.py +++ b/uno/lib/uno/options/addressbook/optionshandler.py @@ -47,8 +47,8 @@ def callHandlerMethod(self, window, event, method): self._manager.viewData() handled = True return handled - except Exception as e: - print("ERROR: %s - %s" % (e, traceback.format_exc())) + except: + print("WindowHandler.callHandlerMethod() ERROR: %s" % traceback.format_exc()) def getSupportedMethodNames(self): return ('ViewData', ) diff --git a/uno/lib/uno/options/jdbc/optionshandler.py b/uno/lib/uno/options/jdbc/optionshandler.py index d58b7af5..aeaec53e 100644 --- a/uno/lib/uno/options/jdbc/optionshandler.py +++ b/uno/lib/uno/options/jdbc/optionshandler.py @@ -65,8 +65,8 @@ def callHandlerMethod(self, window, event, method): self._manager.setSystemTable(event.Source.State) handled = True return handled - except Exception as e: - print("ERROR: %s - %s" % (e, traceback.format_exc())) + except: + print("WindowHandler.callHandlerMethod() ERROR: %s" % traceback.format_exc()) def getSupportedMethodNames(self): return ('Level0', diff --git a/uno/lib/uno/ucb/datasource.py b/uno/lib/uno/ucb/datasource.py index d62020d0..606dd974 100644 --- a/uno/lib/uno/ucb/datasource.py +++ b/uno/lib/uno/ucb/datasource.py @@ -124,7 +124,7 @@ def _getUser(self, source, authority, url): name = uri.getAuthority() else: title, msg = self._getExceptionMessage(322, url) - showWarning(self._ctx, msg, title) + showWarning(self._ctx, title, msg) raise IllegalIdentifierException(msg, source) elif self._default: name = self._default @@ -138,7 +138,7 @@ def _getUser(self, source, authority, url): # XXX: The user's OAuth2 configuration has been deleted and # XXX: the OAuth2 configuration wizard has been canceled. title, msg = self._getExceptionMessage(324, name) - showWarning(self._ctx, msg, title) + showWarning(self._ctx, title, msg) raise IllegalIdentifierException(msg, source) else: user = User(self._ctx, source, self._logger, self.DataBase, @@ -153,11 +153,11 @@ def _getUser(self, source, authority, url): def _getUserName(self, source, url): try: name = getOAuth2UserName(self._ctx, source, self._provider.Scheme) - except Exception as e: - print("DataSource._getUserName() ERROR: %s - %s" % (e, traceback.format_exc())) + except: + print("DataSource._getUserName() ERROR: %s" % traceback.format_exc()) if not name: title, msg = self._getExceptionMessage(331, url) - showWarning(self._ctx, msg, title) + showWarning(self._ctx, title, msg) raise IllegalIdentifierException(msg, source) return name diff --git a/uno/lib/uno/ucb/dispatch.py b/uno/lib/uno/ucb/dispatch.py index 68d3cec5..2c76f680 100644 --- a/uno/lib/uno/ucb/dispatch.py +++ b/uno/lib/uno/ucb/dispatch.py @@ -41,10 +41,7 @@ from com.sun.star.frame.DispatchResultState import FAILURE from .unotool import createService -from .unotool import getArgumentSet from .unotool import getDesktop -from .unotool import getMessageBox -from .unotool import getToolKit import traceback @@ -79,8 +76,6 @@ def dispatch(self, url, arguments): elif url.Path == 'SaveAs': document = self._frame.getController().getModel() state = self._saveAs(document) - elif url.Path == 'ShowWarning': - state = self._showWarning(arguments) return state, result def addStatusListener(self, listener, url): @@ -95,6 +90,7 @@ def removeStatusListener(self, listener, url): if listener in self._listeners: self._listeners.remove(listener) +# Private methods def _open(self): state = FAILURE fp = createService(self._ctx, self._service, FILEOPEN_SIMPLE) @@ -126,11 +122,3 @@ def _saveAs(self, document): fp.dispose() return state - def _showWarning(self, arguments): - toolkit = getToolKit(self._ctx) - peer = toolkit.getActiveTopWindow() - args = getArgumentSet(arguments) - msgbox = getMessageBox(toolkit, peer, args['Box'], args['Button'], args['Title'], args['Message']) - msgbox.execute() - msgbox.dispose() - return SUCCESS diff --git a/uno/lib/uno/ucb/helper.py b/uno/lib/uno/ucb/helper.py index aaf119a6..e1c835e9 100644 --- a/uno/lib/uno/ucb/helper.py +++ b/uno/lib/uno/ucb/helper.py @@ -29,11 +29,6 @@ import uno -from com.sun.star.connection import NoConnectException - -from com.sun.star.logging.LogLevel import INFO -from com.sun.star.logging.LogLevel import SEVERE - from com.sun.star.ucb.ContentAction import INSERTED from com.sun.star.ucb.ContentAction import REMOVED from com.sun.star.ucb.ContentAction import DELETED @@ -42,9 +37,6 @@ from com.sun.star.ucb import IllegalIdentifierException from com.sun.star.ucb import InteractiveAugmentedIOException -from com.sun.star.ucb.ConnectionMode import ONLINE -from com.sun.star.ucb.ConnectionMode import OFFLINE - from com.sun.star.sdb import ParametersRequest from .dbtool import getConnectionUrl @@ -53,17 +45,10 @@ from .unotool import checkVersion from .unotool import createMessageBox -from .unotool import createService -from .unotool import executeDispatch from .unotool import hasInterface -from .unotool import getDesktop -from .unotool import getDispatcher from .unotool import getExtensionVersion -from .unotool import getNamedValueSet -from .unotool import getParentWindow from .unotool import getProperty from .unotool import getPropertyValue -from .unotool import getPropertyValueSet from .unotool import getSimpleFile from .unotool import parseUrl @@ -86,6 +71,8 @@ from .ucp import g_ucbseparator +import traceback + def getPresentationUrl(transformer, url): # FIXME: Sometimes the url can end with a dot, it must be removed @@ -218,10 +205,10 @@ def getExceptionMessage(logger, code, extension, *args): message = logger.resolveString(code + 1, *args) return title, message -def showWarning(ctx, message, title): - box = uno.Enum('com.sun.star.awt.MessageBoxType', 'ERRORBOX') - args = {'Box': box, 'Button': 1, 'Title': title, 'Message': message} - executeDispatch(ctx, '%s:ShowWarning' % g_scheme, **args) +def showWarning(ctx, title, message): + msgbox = createMessageBox(ctx, title, message) + msgbox.execute() + msgbox.dispose() # Private method def _checkConfiguration(ctx, source, logger, warn): @@ -230,22 +217,22 @@ def _checkConfiguration(ctx, source, logger, warn): if oauth2 is None: title, msg = getExceptionMessage(logger, 801, g_oauth2ext, g_oauth2ext, g_extension) if warn: - showWarning(ctx, msg, title) + showWarning(ctx, title, msg) raise IllegalIdentifierException(msg, source) if not checkVersion(oauth2, g_oauth2ver): title, msg = getExceptionMessage(logger, 803, g_oauth2ext, oauth2, g_oauth2ext, g_oauth2ver) if warn: - showWarning(ctx, msg, title) + showWarning(ctx, title, msg) raise IllegalIdentifierException(msg, source) if driver is None: title, msg = getExceptionMessage(logger, 801, g_jdbcext, g_jdbcext, g_extension) if warn: - showWarning(ctx, msg, title) + showWarning(ctx, title, msg) raise IllegalIdentifierException(msg, source) if not checkVersion(driver, g_jdbcver): title, msg = getExceptionMessage(logger, 803, g_jdbcext, driver, g_jdbcext, g_jdbcver) if warn: - showWarning(ctx, msg, title) + showWarning(ctx, title, msg) raise IllegalIdentifierException(msg, source) def _getDataSourceConnection(ctx, url, new, infos=None): @@ -259,7 +246,7 @@ def _checkConnection(ctx, source, connection, logger, new, warn): connection.close() title, msg = getExceptionMessage(logger, 811, g_jdbcext, version, g_version) if warn: - showWarning(ctx, msg, title) + showWarning(ctx, title, msg) raise IllegalIdentifierException(msg, source) service = 'com.sun.star.sdb.Connection' interface = 'com.sun.star.sdbcx.XGroupsSupplier' @@ -267,7 +254,7 @@ def _checkConnection(ctx, source, connection, logger, new, warn): connection.close() title, msg = getExceptionMessage(logger, 813, g_jdbcext, service, interface) if warn: - showWarning(ctx, msg, title) + showWarning(ctx, title, msg) raise IllegalIdentifierException(msg, source) def _checkConnectionApi(connection, service, interface): diff --git a/uno/lib/uno/ucb/ucp/user.py b/uno/lib/uno/ucb/ucp/user.py index 4167cb59..f03eea2c 100644 --- a/uno/lib/uno/ucb/ucp/user.py +++ b/uno/lib/uno/ucb/ucp/user.py @@ -91,29 +91,29 @@ def __init__(self, ctx, source, logger, database, provider, sync, name, password # If we have a Null value here then it means that the user has abandoned # the OAuth2 Wizard, there is nothing more to do except throw an exception title, msg = self._getExceptionMessage(501, name) - showWarning(self._ctx, msg, title) + showWarning(self._ctx, title, msg) raise IllegalIdentifierException(msg, source) else: if not self.Provider.isOnLine(): title, msg = self._getExceptionMessage(503, name) - showWarning(self._ctx, msg, title) + showWarning(self._ctx, title, msg) raise IllegalIdentifierException(msg, source) request = getRequest(ctx, self.Provider.Scheme, name) if request is None: # If we have a Null value here then it means that the user has abandoned # the OAuth2 Wizard, there is nothing more to do except throw an exception title, msg = self._getExceptionMessage(501, g_service) - showWarning(self._ctx, msg, title) + showWarning(self._ctx, title, msg) raise IllegalIdentifierException(msg, source) user = self.Provider.getUser(source, request, name) metadata = database.insertUser(user) if metadata is None: title, msg = self._getExceptionMessage(505, name) - showWarning(self._ctx, msg, title) + showWarning(self._ctx, title, msg) raise IllegalIdentifierException(msg, source) if not database.createUser(name, password): title, msg = self._getExceptionMessage(507, name) - showWarning(self._ctx, msg, title) + showWarning(self._ctx, title, msg) raise IllegalIdentifierException(msg, source) self._paths = {} self._contents = {} diff --git a/uno/lib/uno/unotool/__init__.py b/uno/lib/uno/unotool/__init__.py index 5b23c277..02148529 100644 --- a/uno/lib/uno/unotool/__init__.py +++ b/uno/lib/uno/unotool/__init__.py @@ -34,7 +34,6 @@ from .unotool import checkVersion from .unotool import createMessageBox from .unotool import createService -from .unotool import createWindow from .unotool import executeDesktopDispatch from .unotool import executeDispatch from .unotool import executeFrameDispatch @@ -68,12 +67,10 @@ from .unotool import getLibreOfficeInfo from .unotool import getLibreOfficeVersion from .unotool import getMailMerge -from .unotool import getMessageBox from .unotool import getMimeTypeFactory from .unotool import getMri from .unotool import getNamedValue from .unotool import getNamedValueSet -from .unotool import getParentWindow from .unotool import getPathSettings from .unotool import getPathSubstitution from .unotool import getProperty diff --git a/uno/lib/uno/unotool/statusindicator.py b/uno/lib/uno/unotool/statusindicator.py index bd766a1a..335a2636 100644 --- a/uno/lib/uno/unotool/statusindicator.py +++ b/uno/lib/uno/unotool/statusindicator.py @@ -36,51 +36,40 @@ from com.sun.star.util.MeasureUnit import APPFONT -from .unotool import findFrame - from threading import Lock import traceback class StatusIndicator(unohelper.Base, XStatusIndicator): - def __init__(self, ctx, name, offset=10): - frame = findFrame(ctx, name) - if frame: - self._window = frame.getContainerWindow() - self._progress = frame.createStatusIndicator() - self._point = uno.createUnoStruct('com.sun.star.awt.Point', 0, offset) - self._lock = Lock() - else: - self._window = self._progress = self._point = self._lock = None + def __init__(self, frame, offset=10): + self._window = frame.getContainerWindow() + self._progress = frame.createStatusIndicator() + self._point = uno.createUnoStruct('com.sun.star.awt.Point', 0, offset) + self._lock = Lock() self._value = 0 def start(self, text, value): - if self._progress: - self._setValue(0) - self._setWindowHeight() - self._progress.start(text, value) + self._setValue(0) + self._setWindowHeight() + self._progress.start(text, value) def setText(self, text): - if self._progress: - self._setText(text) + self._setText(text) def setValue(self, value): - if self._progress: - # XXX: In order to be able to progress in the loops it is necessary - # XXX: to be able to add value to the current progression value. - # XXX: This is what is done here thanks to a negative value - self._setValue(value) + # XXX: In order to be able to progress in the loops it is necessary + # XXX: to be able to add value to the current progression value. + # XXX: This is what is done here thanks to a negative value + self._setValue(value) def end(self): - if self._progress: - self._progress.end() - self._setWindowHeight(-1) + self._progress.end() + self._setWindowHeight(-1) def reset(self): - if self._progress: - self._setValue(0) - self._progress.reset() + self._setValue(0) + self._progress.reset() def _setText(self, text): with self._lock: diff --git a/uno/lib/uno/unotool/unotool.py b/uno/lib/uno/unotool/unotool.py index 1c9debfe..7a186395 100644 --- a/uno/lib/uno/unotool/unotool.py +++ b/uno/lib/uno/unotool/unotool.py @@ -33,6 +33,8 @@ from com.sun.star.awt import Rectangle from com.sun.star.awt import Size +from com.sun.star.awt.MessageBoxType import ERRORBOX + from com.sun.star.awt.WindowAttribute import SHOW from com.sun.star.awt.WindowAttribute import MINSIZE from com.sun.star.awt.WindowAttribute import BORDER @@ -328,39 +330,34 @@ def setProgress(callback, caller, value): data = {'call': 'progress', 'value': value} callback.addCallback(caller, getNamedValueSet(data)) -def getDialog(ctx, identifier, xdl, handler=None, window=None): +def getDialog(ctx, identifier, xdl, handler=None, parent=None): dialog = None provider = createService(ctx, 'com.sun.star.awt.DialogProvider2') url = getDialogUrl(identifier, xdl) - if handler is None and window is None: - dialog = provider.createDialog(url) - toolkit = createService(ctx, 'com.sun.star.awt.Toolkit') - dialog.createPeer(toolkit, None) - elif handler is not None and window is None: - dialog = provider.createDialogWithHandler(url, handler) - toolkit = createService(ctx, 'com.sun.star.awt.Toolkit') - dialog.createPeer(toolkit, None) + if handler and parent: + properties = getNamedValueSet({'ParentWindow': parent, 'EventHandler': handler}) + dialog = provider.createDialogWithArguments(url, properties) else: - args = getNamedValueSet({'ParentWindow': window, 'EventHandler': handler}) - dialog = provider.createDialogWithArguments(url, args) + if handler: + dialog = provider.createDialogWithHandler(url, handler) + else: + dialog = provider.createDialog(url) + toolkit = getToolKit(ctx) + dialog.createPeer(toolkit, toolkit.getDesktopWindow()) return dialog def findFrame(ctx, name, flags=GLOBAL): return getDesktop(ctx).findFrame(name, flags) def getDialogPosSize(ctx, extension, xdl, point=None, unit=APPFONT): - dialog = getDialog(ctx, extension, xdl, None, None) + dialog = getDialog(ctx, extension, xdl) size = dialog.convertSizeToPixel(Size(dialog.Model.Width, dialog.Model.Height), unit) - if point: - position = dialog.convertPointToPixel(point, unit) - else: - position = Point(0, 0) dialog.dispose() - return Rectangle(position.X, position.Y, size.Width, size.Height) + if point is None: + point = Point(0, 0) + return Rectangle(point.X, point.Y, size.Width, size.Height) def getTopWindow(ctx, name, rectangle=None, parent=None, modal=TOP, attrs=BORDER | MOVEABLE | CLOSEABLE | NODECORATION): - service = 'com.sun.star.frame.TaskCreator' - arguments = {'FrameName': name} descriptor = uno.createUnoStruct('com.sun.star.awt.WindowDescriptor') descriptor.Type = modal descriptor.WindowServiceName = 'window' @@ -372,19 +369,17 @@ def getTopWindow(ctx, name, rectangle=None, parent=None, modal=TOP, attrs=BORDER attrs |= SHOW descriptor.Bounds = rectangle descriptor.WindowAttributes = attrs - arguments['ContainerWindow'] = getToolKit(ctx).createWindow(descriptor) - #if rectangle: - # arguments['PosSize'] = rectangle + # XXX: We use the TaskCreator UNO service instead of Frame + # XXX: in order to be able to assign a title to the window. + service = 'com.sun.star.frame.TaskCreator' + arguments = {'FrameName': name, 'ContainerWindow': getToolKit(ctx).createWindow(descriptor)} frame = createService(ctx, service).createInstanceWithArguments(getNamedValueSet(arguments)) - desktop = getDesktop(ctx) - frame.setCreator(desktop) - desktop.getFrames().append(frame) + getDesktop(ctx).getFrames().append(frame) return frame def getTopWindowPosition(window): size = window.getPosSize() - point = uno.createUnoStruct('com.sun.star.awt.Point', size.X, size.Y) - return window.convertPointToLogic(point, APPFONT) + return Point(size.X, size.Y) def saveTopWindowPosition(config, position, property): if config.hasByName(property): @@ -409,15 +404,10 @@ def getFileUrl(ctx, title, path, filters=(), multi=False): filepicker.setCurrentFilter(name) filepicker.setMultiSelectionMode(multi) if filepicker.execute() == OK: - url = filepicker.getFiles()[0] if multi: - try: - urls = filepicker.getSelectedFiles() - except: - urls = filepicker.getFiles() - if len(urls) > 1: - urls = [url + u for u in urls[1:]] - url = urls + url = filepicker.getSelectedFiles() + else: + url = filepicker.getSelectedFiles()[0] path = filepicker.getDisplayDirectory() filepicker.dispose() return url, path @@ -455,11 +445,11 @@ def executeFrameDispatch(ctx, frame, url, listener=None, /, *properties): else: dispatcher.dispatch(url, properties) -def createMessageBox(peer, box, button, title, message): - return getMessageBox(peer.getToolkit(), peer, box, button, title, message) - -def getMessageBox(toolkit, peer, box, button, title, message): - return toolkit.createMessageBox(peer, box, button, title, message) +def createMessageBox(ctx, title, message, box=ERRORBOX, button=1, parent=None): + toolkit = getToolKit(ctx) + if parent is None: + parent = toolkit.getDesktopWindow() + return toolkit.createMessageBox(parent, box, button, title, message) def createService(ctx, name, *args, **kwargs): if args: @@ -471,10 +461,13 @@ def createService(ctx, name, *args, **kwargs): service = ctx.ServiceManager.createInstanceWithContext(name, ctx) return service -def getArgumentSet(properties): +def getArgumentSet(properties, lower=True): arguments = {} for property in properties: - arguments[property.Name] = property.Value + name = property.Name + if lower: + name = name.lower() + arguments[name] = property.Value return arguments def getDefaultPropertyValueSet(args, default): @@ -516,19 +509,6 @@ def getPropertySetInfoChangeEvent(source, name, reason, handle=-1): event.Handle = handle event.Reason = reason -def createWindow(ctx, extension, xdl, name): - dialog = getDialog(ctx, extension, xdl, None, None) - possize = Rectangle(dialog.Model.PositionX, dialog.Model.PositionY, dialog.Model.Width, dialog.Model.Height) - dialog.dispose() - desktop = getDesktop(ctx) - args = getNamedValueSet({'FrameName': name, 'PosSize': possize}) - frame = createService(ctx, 'com.sun.star.frame.TaskCreator').createInstanceWithArguments(args) - frames = desktop.getFrames() - frame.setTitle(_getUniqueName(frames, name)) - frame.setCreator(desktop) - frames.append(frame) - return frame.getContainerWindow() - def _getUniqueName(frames, name): count = 0 for i in range(frames.getCount()): @@ -538,14 +518,6 @@ def _getUniqueName(frames, name): name = '%s - %s' % (name, (count +1)) return name -def getParentWindow(ctx): - desktop = getDesktop(ctx) - try: - parent = desktop.getCurrentFrame().getContainerWindow() - except: - parent = None - return parent - def getDateTime(utc=True): if utc: t = datetime.datetime.utcnow() diff --git a/uno/lib/uno/wizard/wizard.py b/uno/lib/uno/wizard/wizard.py index 9dcdca31..a6050a67 100644 --- a/uno/lib/uno/wizard/wizard.py +++ b/uno/lib/uno/wizard/wizard.py @@ -69,9 +69,8 @@ class Wizard(unohelper.Base, - XWizard, - XComponent): - def __init__(self, ctx, auto=-1, resize=False, parent=None, name=None, point=None): + XWizard): + def __init__(self, ctx, auto=-1, name=None, point=None, parent=None, resize=True): self._ctx = ctx self._helpUrl = '' self._auto = auto @@ -80,9 +79,7 @@ def __init__(self, ctx, auto=-1, resize=False, parent=None, name=None, point=Non self._currentPath = -1 self._multiPaths = False self._controller = None - self._listeners = [] self._closed = False - self._disposed = False self._model = WizardModel(ctx) title = self._model.getRoadmapTitle() if name: @@ -100,31 +97,7 @@ def queryClosing(self, source, ownership): def notifyClosing(self, source): if self._listener: source.removeCloseListener(self._listener) - self.dispose() - -# XComponent - def dispose(self): - self._disposed = True - event = self._getEventObject() - for listener in self._listeners: - listener.disposing(event) - interface = 'com.sun.star.lang.XComponent' - if self._controller and hasInterface(self._controller, interface): - self._controller.dispose() - self._model.dispose() - self._view.dispose() - - def addEventListener(self, listener): - interface = 'com.sun.star.lang.XEventListener' - if hasInterface(listener, interface): - if self._disposed: - listener.disposing(self._getEventObject()) - else: - self._listeners.append(listener) - - def removeEventListener(self, listener): - if not self._disposed and listener in self._listeners: - self._listeners.remove(listener) + self._dispose() # XWizard # XWizard Attributes @@ -211,7 +184,12 @@ def execute(self): if not self._isCurrentPathSet(): self._initPath(0, False) self._initPage() - return self._view.execute() + if self._view.isModal(): + status = self._view.execute() + self._dispose() + else: + status = OK + return status # XInitialization def initialize(self, arguments): @@ -355,7 +333,7 @@ def _isAutoLoad(self, page=None): if page is None: nextindex = self._getFirstPageId() else: - nextindex = self._getCurrentPath().index(page) +1 + nextindex = self._getCurrentPath().index(page) + 1 return nextindex < self._auto def _getPath(self, index, final): @@ -395,6 +373,13 @@ def _initNextPage(self): return init # Wizard private setter methods + def _dispose(self): + interface = 'com.sun.star.lang.XComponent' + if self._controller and hasInterface(self._controller, interface): + self._controller.dispose() + self._model.dispose() + self._view.dispose() + def _tryToClose(self): try: self._queryClosing() diff --git a/uno/lib/uno/wizard/wizardhandler.py b/uno/lib/uno/wizard/wizardhandler.py index 317c54e2..31674704 100644 --- a/uno/lib/uno/wizard/wizardhandler.py +++ b/uno/lib/uno/wizard/wizardhandler.py @@ -62,9 +62,8 @@ def callHandlerMethod(self, dialog, event, method): self._manager.doCancel() handled = True return handled - except Exception as e: - msg = "Error: %s" % traceback.format_exc() - print(msg) + except: + print("DialogHandler.callHandlerMethod() ERROR: %s" % traceback.format_exc()) def getSupportedMethodNames(self): return ('Help', @@ -98,9 +97,8 @@ def callHandlerMethod(self, dialog, event, method): self._manager.doCancel() handled = True return handled - except Exception as e: - msg = "Error: %s" % traceback.format_exc() - print(msg) + except: + print("WindowHandler.callHandlerMethod() ERROR: %s" % traceback.format_exc()) def getSupportedMethodNames(self): return ('Help', @@ -119,9 +117,8 @@ def __init__(self, manager): def itemStateChanged(self, event): try: self._manager.changeRoadmapStep(event.ItemId) - except Exception as e: - msg = "Error: %s" % traceback.format_exc() - print(msg) + except: + print("ItemListener.itemStateChanged() ERROR: %s" % traceback.format_exc()) def disposing(self, event): pass diff --git a/uno/lib/uno/wizard/wizardview.py b/uno/lib/uno/wizard/wizardview.py index be855b3f..745ede03 100644 --- a/uno/lib/uno/wizard/wizardview.py +++ b/uno/lib/uno/wizard/wizardview.py @@ -118,7 +118,7 @@ def setDialogTitle(self, title): def setDialogSize(self, page): button = self._getButton(HELP).Model - button.PositionY = page.Height + self._spacer + button.PositionY = page.Height + self._spacer dialog = self._dialog.Model dialog.Height = button.PositionY + button.Height + self._spacer dialog.Width = page.PositionX + page.Width From 258f73d6727186c0fb2258064e6204c9a49bd481 Mon Sep 17 00:00:00 2001 From: prrvchr Date: Tue, 4 Nov 2025 11:52:25 +0100 Subject: [PATCH 10/11] new version 1.4.0 --- README.md | 2 +- README_fr.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e081621f..943e67f1 100644 --- a/README.md +++ b/README.md @@ -254,7 +254,7 @@ ___ ### What has been done for version 1.4.0: - If the jdbcDriverOOo extension works without Java instrumentation, a warning message will be displayed in the extension options. -- Requires the **jdbcDriverOOo extension at least version 1.6.0**. +- Requires the **jdbcDriverOOo extension at least version 1.6.1**. - Has been tested under LibreOfficeDev 26.2. ### What remains to be done for version 1.4.0: diff --git a/README_fr.md b/README_fr.md index c2959dea..c5c7bd0f 100644 --- a/README_fr.md +++ b/README_fr.md @@ -254,7 +254,7 @@ ___ ### Ce qui a Γ©tΓ© fait pour la version 1.4.0: - Si l'extension jdbcDriverOOo fonctionne sans l'instrumentation Java, un message d'avertissement s'affichera dans les options de l'extension. -- NΓ©cessite l'extension **jdbcDriverOOo en version 1.6.0 minimum**. +- NΓ©cessite l'extension **jdbcDriverOOo en version 1.6.1 minimum**. - A Γ©tΓ© testΓ© sous LibreOfficeDev 26.2. ### Que reste-t-il Γ  faire pour la version 1.4.0: From 6b86c49e99abef630982654472b2e2c36b36312f Mon Sep 17 00:00:00 2001 From: prrvchr Date: Tue, 4 Nov 2025 11:52:39 +0100 Subject: [PATCH 11/11] git subrepo pull uno subrepo: subdir: "uno" merged: "c1a100b6" upstream: origin: "https://github.com/prrvchr/uno.git" branch: "main" commit: "c1a100b6" git-subrepo: version: "0.4.9" origin: "https://github.com/ingydotnet/git-subrepo.git" commit: "4f60dd7" --- uno/.gitrepo | 4 ++-- uno/dialog/wizard/Wizard.xdl | 2 +- uno/lib/java/UnoHelper/UnoHelper.jar | Bin 23913 -> 23884 bytes 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/uno/.gitrepo b/uno/.gitrepo index 7d565a77..3442600a 100644 --- a/uno/.gitrepo +++ b/uno/.gitrepo @@ -6,7 +6,7 @@ [subrepo] remote = https://github.com/prrvchr/uno.git branch = main - commit = 71034eaa9f7627b2689444c2b80850322e67f5ea - parent = 589abab89cd8232834cc7cc7e431320a03653d03 + commit = c1a100b6f093ceef9aef387d4e88660e70568d3f + parent = 258f73d6727186c0fb2258064e6204c9a49bd481 method = merge cmdver = 0.4.9 diff --git a/uno/dialog/wizard/Wizard.xdl b/uno/dialog/wizard/Wizard.xdl index 3fcd3627..73131871 100644 --- a/uno/dialog/wizard/Wizard.xdl +++ b/uno/dialog/wizard/Wizard.xdl @@ -25,7 +25,7 @@ β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β• --> - + diff --git a/uno/lib/java/UnoHelper/UnoHelper.jar b/uno/lib/java/UnoHelper/UnoHelper.jar index 41d3d66de7bdee9c15715ae8baacdfd5d8cbd863..b5fda0197f778a60e83b237113c249dba1d3a379 100644 GIT binary patch delta 12072 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 xBJ&?Ksz*Zp@2S94=(^e{{cT!J4FBh