[Résolu] [Basic]Passage de paramètres à une macro Java via le ScriptProvider

Discussions et questions sur tout ce qui concerne la programmation tous langages et tous modules confondus.

Modérateur : Vilains modOOs

Règles du forum
:alerte: Balisage obligatoire dans cette section !
Aidez-nous à vous aider au mieux en balisant correctement votre question : reportez-vous sur les règles de cette section avant de poster !
Cormic2
NOOuvel adepte
NOOuvel adepte
Messages : 23
Inscription : 18 juil. 2024 23:21

[Résolu] [Basic]Passage de paramètres à une macro Java via le ScriptProvider

Message par Cormic2 »

Bonsoir,
J'ai besoin d'appeler des macros écrites en Java depuis une fonction Basic, et je n'arrive pas à faire des appels avec passage de paramètres.
Dans le fichier ci-joint, j'ai embarqué deux macros java élémentaires. L'une qui n'attend pas de paramètres, et que j'arrive à appeler correctement. L'autre avec des paramètres, que je n'arrive pas à appeler.
Le code des macros est simplissime :

Code : Tout sélectionner

import com.sun.star.script.provider.XScriptContext;
public class MacroJava {
    public static int getArgsCount(XScriptContext xScriptContext, Object[] args) {
        return args.length;
    }
    public static String getMessage(XScriptContext xScriptContext) {
        return "Appel OK de la macro java";
    }
}
Le bouton "Call Java macros" sur la page du document joint appelle la fonction Basic TestMacroJava() qui appelle successivement les deux macros Java et affiche le résultat sur la page. Visiblement, pour la macro avec paramètres, le script manager n'arrive pas à trouver une fonction Java avec la bonne signature.
Dans le module Standard.Module1 du fichier, j'ai aussi ajouté une fonction TestMacroBasic (à lancer directement depuis l'éditeur Basic), qui montre que l'appel avec passage de paramètres fonctionne pour un appel de macro Basic.
J'espère que quelqu'un pourra m'éclairer là-dessus. J'ai déjà publié la question sur le site anglais, mais sans obtenir de solution.

Je travaille sur une machine Windows10 Pro 64bits, avec un LibreOffice 24.2.5.2
Pour info, le parcel-descriptor ajouté dans le fichier ODT est :

Code : Tout sélectionner

<?xml version="1.0" encoding="UTF-8"?>
<parcel language="Java" xmlns:parcel="scripting.dtd">
  <script language="Java">
    <locale lang="fr">
      <displayname value="getArgsCount"/>
      <description>
        macro java getArgsCount (avec paramètres)
      </description>
    </locale>
    <functionname value="MacroJava.getArgsCount"/>
    <logicalname value="MacroJava.getArgsCount"/>
    <languagedepprops>
        <prop name="classpath" value="TestMacroJava.jar"/>
    </languagedepprops>
  </script>
  <script language="Java">
    <locale lang="fr">
      <displayname value="getMessage"/>
      <description>
        macro java getMessage (sans paramètres)
      </description>
    </locale>
    <functionname value="MacroJava.getMessage"/>
    <logicalname value="MacroJava.getMessage"/>
    <languagedepprops>
        <prop name="classpath" value="TestMacroJava.jar"/>
    </languagedepprops>
  </script>
</parcel>
Vous ne pouvez pas consulter les pièces jointes insérées à ce message.
Dernière modification par Cormic2 le 08 août 2024 21:21, modifié 1 fois.
LibreOffice 24.2.5.2 sous Windows 10
Avatar de l’utilisateur
Bidouille
RespOOnsable forum
RespOOnsable forum
Messages : 12895
Inscription : 08 nov. 2005 16:23
Localisation : Brest, France

Re: [Basic]Passage de paramètres à une macro Java via le ScriptProvider

Message par Bidouille »

Bonjour,
Bidouille a écrit : ↑02 août 2024 21:15En revanche, il est d'usage lorsqu'on pose une question sur plusieurs forums de l'indiquer.
Cela évite la dispersion d'effort des bénévoles et la perte de temps à donner des réponses qui vous ont été faites ailleurs surtout si la solution s'y trouve.
https://forum.openoffice.org/en/forum/v ... p?t=111784

:evil:
Cormic2
NOOuvel adepte
NOOuvel adepte
Messages : 23
Inscription : 18 juil. 2024 23:21

Re: [Basic]Passage de paramètres à une macro Java via le ScriptProvider

Message par Cormic2 »

Bonjour,
Je croyais pourtant bien l'avoir fait puisque j'ai écrit : "J'ai déjà publié la question sur le site anglais, mais sans obtenir de solution."
LibreOffice 24.2.5.2 sous Windows 10
Avatar de l’utilisateur
Bidouille
RespOOnsable forum
RespOOnsable forum
Messages : 12895
Inscription : 08 nov. 2005 16:23
Localisation : Brest, France

Re: [Basic]Passage de paramètres à une macro Java via le ScriptProvider

Message par Bidouille »

Cormic2 a écrit : ↑08 août 2024 12:17 "J'ai déjà publié la question sur le site anglais, mais sans obtenir de solution."
Et comment font les lecteurs pour retrouver le fil de discussion avec cette phrase ?
Le forum anglophone rassemble plus de 500.000 messages.
Cormic2
NOOuvel adepte
NOOuvel adepte
Messages : 23
Inscription : 18 juil. 2024 23:21

Re: [Basic]Passage de paramètres à une macro Java via le ScriptProvider

Message par Cormic2 »

Certes. Et bien qu'ayant le nez dans le guidon de ma question, je ne suis pas fier de ne pas l'avoir anticipé.
En tout cas, merci d'avoir pris la peine de rechercher le lien sur le forum anglais.
LibreOffice 24.2.5.2 sous Windows 10
Avatar de l’utilisateur
Dude
IdOOle de la suite
IdOOle de la suite
Messages : 26242
Inscription : 03 mars 2006 07:45
Localisation : 127.0.0.1

Re: [Basic]Passage de paramètres à une macro Java via le ScriptProvider

Message par Dude »

Salut,

Je ne pratique pas Java mais pour moi le problème vient de ton JAR.
Invoquer du Javascript avec passage de paramètres fonctionne sans problème :

Code : Tout sélectionner

Sub Main
   Dim oSP, oJS
   Dim aParam(1)
   aParam(0) = "Dude moi !"
   aParam(1) = chr(10)
   oSP = ThisComponent.getScriptProvider()
   oJS = oSP.getScript("vnd.sun.star.script:Library1.Hello.js?language=JavaScript&location=document")
   oJS.invoke(aParam,Array(),Array())
End Sub
Le script JS écrit simplement les deux variables reçues dans le document :

Code : Tout sélectionner

importClass(Packages.com.sun.star.uno.UnoRuntime);
importClass(Packages.com.sun.star.text.XTextDocument);
importClass(Packages.com.sun.star.text.XText);
importClass(Packages.com.sun.star.text.XTextRange);
importClass(Packages.com.sun.star.frame.XModel);

sItem1 = String(ARGUMENTS[0]);
sItem2 = String(ARGUMENTS[1]);

oDoc = UnoRuntime.queryInterface(XModel,XSCRIPTCONTEXT.getInvocationContext());
if ( !oDoc )
  oDoc = XSCRIPTCONTEXT.getDocument();
xTextDoc = UnoRuntime.queryInterface(XTextDocument,oDoc);
xText = xTextDoc.getText();
xTextRange = xText.getEnd();
xTextRange.setString( sItem1 + sItem2 );
Vous ne pouvez pas consulter les pièces jointes insérées à ce message.
Cormic2
NOOuvel adepte
NOOuvel adepte
Messages : 23
Inscription : 18 juil. 2024 23:21

Re: [Résolu] [Basic]Passage de paramètres à une macro Java via le ScriptProvider

Message par Cormic2 »

Je viens de trouver la raison du problème, et mon JAR n'est pas en cause.

Je m'étais inspiré du Developer's Guide chapitre 28 - Scripting Framework
https://wiki.documentfoundation.org/Doc ... ing_Macros
dans lequel il est écrit au paragraphe "Handling arguments passed to macros"

Code : Tout sélectionner

Java: The arguments are passed as an Object[] in the second parameter to the macro method

 public void handleButtonPress( XScriptContext xScriptContext, Object[] args)
 
En fait c'est obsolète, et maintenant, il faut déclarer les paramètres explicitement.
En changeant la définition de la macro Java en

Code : Tout sélectionner

    public static int getArgsCount(XScriptContext xScriptContext, String[] textes, String message) {
et en utilisant l'appel Basic

Code : Tout sélectionner

	Dim textes(2), params(1), outIndex(), outParams() 
	textes(0) =  "valeur 1" : textes(1) = "valeur 2" : textes(2) = "valeur 3"
	params(0) = textes : params(1) = "message"
	uri    = "vnd.sun.star.script:TestMacroJava.MacroJava.getArgsCount?language=java&location=document"
    script = javaProvider.getScript(uri)
    N = script.invoke(params, outIndex, outParams)
ça fonctionne parfaitement, et la macro Java reçoit bien les paramètres.
LibreOffice 24.2.5.2 sous Windows 10
Avatar de l’utilisateur
Dude
IdOOle de la suite
IdOOle de la suite
Messages : 26242
Inscription : 03 mars 2006 07:45
Localisation : 127.0.0.1

Re: [Basic]Passage de paramètres à une macro Java via le ScriptProvider

Message par Dude »

Cormic2 a écrit : ↑08 août 2024 21:00 et mon JAR n'est pas en cause.
Bah si puisque tu dis toi-même que tu as modifié :
Cormic2 a écrit : ↑08 août 2024 21:00 la définition de la macro Java
Le problème ne vient donc pas du Basic.

Et le [Résolu] se met dans le PREMIER message pour être visible.
Regarde comment sont postés tous les autres sujets dans ce forum.
Cormic2
NOOuvel adepte
NOOuvel adepte
Messages : 23
Inscription : 18 juil. 2024 23:21

Re: [Basic]Passage de paramètres à une macro Java via le ScriptProvider

Message par Cormic2 »

Je n'ai jamais pensé que cela venait du Basic, mais bien sûr du Script Manager.
Et effectivement, c'est bien lui qui a changé sa façon de transmettre les paramètres entre la version LibreOffice du Programmers's guide et la version 24.2 actuelle. Il fallait donc bien que je change le prototype de la fonction, mais on ne peut quand même pas dire que le problème venait du jar comme s'il avait été mal écrit. Il était correct ... pour une version ancienne :-))
Cordialement, et merci pour le temps passé à me répondre.
Dernière modification par Cormic2 le 08 août 2024 21:28, modifié 2 fois.
LibreOffice 24.2.5.2 sous Windows 10
Avatar de l’utilisateur
Dude
IdOOle de la suite
IdOOle de la suite
Messages : 26242
Inscription : 03 mars 2006 07:45
Localisation : 127.0.0.1

Re: [Basic]Passage de paramètres à une macro Java via le ScriptProvider

Message par Dude »

Cormic2 a écrit : ↑08 août 2024 21:21 Je n'ai jamais pensé que cela venait du Basic, mais bien sûr du Script Manager.
Et effectivement, c'est bien lui qui a changé sa façon de transmettre les paramètres
Ah bon, je ne vois pas en quoi il y a eu un changement. Dans ton code comme dans le mien, tu lui passes un array().
Cormic2
NOOuvel adepte
NOOuvel adepte
Messages : 23
Inscription : 18 juil. 2024 23:21

Re: [Résolu] [Basic]Passage de paramètres à une macro Java via le ScriptProvider

Message par Cormic2 »

Ben, moi j'en vois un.
Je passe un array au ScriptProvider, qui contient un premier paramètre array de 3 strings et un second paramètre String.
En LibreOffice "ancien", le ScriptProvider transmettait un seul tableau à la macro java dans un paramètre Object[] de taille 2.
Maintenant, il explose les données et transmet tous les paramètres séparément, qu'il faut donc déclarer avec leur type explicite, c'est à dire un premier paramètre tableau (qui sera ici de taille 3) et un second String.
Ce n'est donc pas du tout la même chose, et la doc qui dit que "Java: The arguments are passed as an Object[] in the second parameter to the macro method" est obsolète, et induit en erreur.
LibreOffice 24.2.5.2 sous Windows 10
Avatar de l’utilisateur
Dude
IdOOle de la suite
IdOOle de la suite
Messages : 26242
Inscription : 03 mars 2006 07:45
Localisation : 127.0.0.1

Re: [Résolu] [Basic]Passage de paramètres à une macro Java via le ScriptProvider

Message par Dude »

Cormic2 a écrit : ↑08 août 2024 21:39 En LibreOffice "ancien", le ScriptProvider transmettait un seul tableau à la macro java dans un paramètre Object[] de taille 2.
Il n'y a pas de notion d'ancien. Peut-être que le bénévole qui a écrit la documentation s'est trompé.
Il faut alors le signaler.
Cormic2 a écrit : ↑08 août 2024 21:39 Je passe un array au ScriptProvider, qui contient un premier paramètre array de 3 strings et un second paramètre String.
Depuis toujours, on ne passe qu'un seul tableau qui peut contenir lui-même d'autres tableaux.

Code : Tout sélectionner

Sub Main
	Dim oSP, oJS
	Dim aParam(1)
	Dim aMots(2)
	aMots(0)="Dude"
	aMots(1)="moi"
	aMots(2)="encore"
    aParam(0) = aMots
    aParam(1) = chr(10)
	oSP = ThisComponent.getScriptProvider()
	oJS = oSP.getScript("vnd.sun.star.script:Library1.Hello2.js?language=JavaScript&location=document")
	oJS.invoke(aParam, array(), array())
End Sub
C'est bien le script de réception qui doit ensuite se débrouiller pour éclater les valeurs reçues :

Code : Tout sélectionner

importClass(Packages.com.sun.star.uno.UnoRuntime);
importClass(Packages.com.sun.star.text.XTextDocument);
importClass(Packages.com.sun.star.text.XText);
importClass(Packages.com.sun.star.text.XTextRange);
importClass(Packages.com.sun.star.frame.XModel);

var sRecu = ARGUMENTS[0];
var sMot = String(ARGUMENTS[1]);
var sTexte;

oDoc = UnoRuntime.queryInterface(XModel,XSCRIPTCONTEXT.getInvocationContext());
if ( !oDoc )
  oDoc = XSCRIPTCONTEXT.getDocument();
xTextDoc = UnoRuntime.queryInterface(XTextDocument,oDoc);
xText = xTextDoc.getText();
xTextRange = xText.getEnd();
sTexte = sRecu.join(' ');
xTextRange.setString( sTexte + sMot );
Cormic2
NOOuvel adepte
NOOuvel adepte
Messages : 23
Inscription : 18 juil. 2024 23:21

Re: [Résolu] [Basic]Passage de paramètres à une macro Java via le ScriptProvider

Message par Cormic2 »

Nous ne parlons pas de la même chose.
Bien sûr, en Basic, on passe un tableau pouvant contenir plusieurs tableaux. Je n'ai jamais prétendu le contraire
Par exemple :

Code : Tout sélectionner

	Dim data(2)
	data(0) =  12 : data(1) = 15 :data(2) = 20
	Dim params(1)
	params(0) = data : params(1) = "texte quelconque" :
	N = script.invoke(params, outIndex, outParams)
Si on se fie au Developer's Guide chapitre 28 - Scripting Framework
dans lequel il est écrit au paragraphe "Handling arguments passed to macros"

Code : Tout sélectionner

Java: The arguments are passed as an Object[] in the second parameter to the macro method
 public void handleButtonPress( XScriptContext xScriptContext, Object[] args)
cela signifie que l'on doit alors déclarer la fonction java avec 2 paramètres seulement, et le paramètre args reçu sera un tableau de taille 2, contenant à l'index 0 un tableau de 3 integers 12, 15 et 20, et à l'index 1 une string "texte quelconque".

Mais en fait ce n'est pas du tout ça. Il faut déclarer la fonction java avec 3 paramètres

Code : Tout sélectionner

 public void handleButtonPress( XScriptContext xScriptContext, Integer[] arg1, String arg2)
Et la fonction reçoit dans arg1 un tableau de 3 entiers 12,15 et 20, et dans arg2 la chaîne "texte quelconque"
Comme je suivais naïvement la doc avec la version à 2 paramètres, et que le ScriptProvider recherchait une fonction dont la signature en avait 3, il protestait que la fonction n'existait pas.

Je ne sais pas si c'est le rédacteur de la doc qui s'est trompé, ou si le format de passage des paramètres à évolué. Ayant lu que le Developer's Guide avait été écrit pour une version ancienne (la 3 je crois), j'en avais - peut être à tort - conclu que les choses avaient changé depuis.
Je veux bien signaler l'erreur pour qu'elle soit corrigée, mais je ne sais pas où. Est-ce que c'est sur le même site que pour les bugs (https://bugs.documentfoundation.org) ?
LibreOffice 24.2.5.2 sous Windows 10
Cormic2
NOOuvel adepte
NOOuvel adepte
Messages : 23
Inscription : 18 juil. 2024 23:21

Re: [Résolu] [Basic]Passage de paramètres à une macro Java via le ScriptProvider

Message par Cormic2 »

J'ai eu tort de dire que la doc. était obsolète. Elle est seulement très incomplète et ambiguë.
Si l'on applique strictement la doc, on déclare un script java par

Code : Tout sélectionner

public static String maMacro(XScriptContext xScriptContext, Object[] args)
Cela ne fonctionne que si l'on passe en paramètres un tableau de données qui comporte au moins 2 types différents.
Par exemple

Code : Tout sélectionner

Dim param1(2)
param1(0)=thisComponent : param1(1)="un texte" : param1(2) = 12.5
Dim params(0) : params(0) = param1
result = script.invoke(params, outIndex, outParams)
Le script java reçoit alors bien args[0] de type "any", args[1] de type String et args[2] de type Double.
Par contre, cela ne marche plus si les paramètres sont de même type, par exemple

Code : Tout sélectionner

param1(0)="un texte": param1(1)="un deuxième texte" : param1(2) = "un troisième texte"]
Dans ce cas, il faut déclarer la macro avec le type explicite par

Code : Tout sélectionner

public static String maMacro(XScriptContext xScriptContext, String[] args)
Par ailleurs, rien n'oblige à utiliser un tableau. On peut parfaitement utiliser un seul paramètre, à condition de déclarer son type explicitement (Object n'est pas possible). Par exemple

Code : Tout sélectionner

public static String maMacro(XScriptContext xScriptContext, Double args)
peut être appelé par :

Code : Tout sélectionner

Dim D as Double : D = 12.5
Dim params(0) : params(0) = D
result = script.invoke(params, outIndex, outParams)
Le passage de paramètres numériques de cette façon est assez problématique, car le ScriptManager ne tient pas compte du type déclaré dans le Dim, mais seulement de la valeur de la donnée. C'est à dire que si on remplace D = 12.5 par D = 12.0, le ScriptManager considère la valeur comme un Byte, et la macro ne sera reconnue que si on remplace 'Double args' par 'Byte args' dans le prototype de la fonction Java (ou par 'Short args' ou 'Long args' selon le nombre de bits nécessaires pour coder l'entier). Autrement dit le passage de paramètre numérique en tant que paramètre simple est inexploitable, et ne peut s'envisager que dans un tableau de paramètres Object[] en gérant ensuite le type reçu.

Enfin, rien n'oblige à n'avoir que deux paramètres dans le prototype Java. On peut très bien avoir une déclaration

Code : Tout sélectionner

public static String maMacro(XScriptContext xScriptContext, String[] args1, Object[] args2, String args3, ActionEvent args4)
chaque paramètre étant défini avec les même règles que ci-dessus.
LibreOffice 24.2.5.2 sous Windows 10