Date: prev next · Thread: first prev next last
2018 Archives by date, by thread · List index


Bonjour,

J'utilise Base avec les Macros Basic pour développer une base de donnée documentaire. Lors du traitement de l'évènement du formulaire principal "Changement d'enregistrement" j’exécute une macro un peu longue et je suis confronté à un problème de réentrance. Ma macro est un peu longue car j'utilise des formulaires un peu complexes utilisant des sections pour gérer à la fois des onglets mais aussi l'affichage contextuel de telle ou telle section en fonction des valeurs de certains champs saisies par l'utilisateur... Ce problème de réentrance peut être schématisé par le scénario suivant :

t = 0                  Enregistrement courrant de la forme est le n°10
t1 EVENEMENT 1 (Enregistrement courrant de la forme devient le n°11) t1 + delta t EVENEMENT 2 (Enregistrement courrant de la forme devient le n°12, Macros évènement 1 interrompue n'importe où...) t2 FIN TRAITEMENT EVENEMENT 2 (synchrone avec l'enregistrement courrant n°12 de la forme) t3 REPRISE ET FIN DU TRAITEMENT DE L'EVENEMENT 1 (/!\ Traitement de l'enregistrement n°11 qui n'est plus l'enregistrement courrant de la forme, et qui devrait au contraire s'interrompre immédiatement par un appel à exit())

Ce problème n'est pas seulement révélé par la durée du traitement de ma macro mais aussi il me semble pour deux raisons spécifiques à l'application LibreOffice:

1. Il me semble que par défaut la barre de navigation des formulaires utiliserait le principe de la répétition sur ses touches (activé après un délai très cours). Si bien que très souvent l'appui sur le bouton (avec le triangle) pour passer à l'enregistrement suivant commande un double changement d'enregistrement... Et donc je reçois deux évènements très rapprochés à traiter... 2. J'ai lu dans le livre "Benitez , Roberto - Database Programming with OpenOffice.org Base & Basic – 10 septembre 2008" que le formulaire pouvait déclencher deux évènements envoyés pour le premier par le composant "com.sun.star.form.FmXFormController" et l'autre par "com.sun.star.comp.forms.ODatabaseForm". Mais un test dans mon code de traitement de l'évènement ne semble pas révéler ce problème... C'est plutôt le cas 1 qui semble concerner ma macro...

Pour essayer une première solution j'ai caché la barre de navigation des formulaires et j'ai ajouté 2 ou 3 boutons de navigation spécifiques à mon formulaire, en veillant à désactiver la répétition de touche. De fait je suis moins confronté au problème des doubles évènements. Mais cela n'empêche pas l'utilisateur de double cliquer rapidement ou même triple cliquer rapidement sur les boutons, et je me retrouve à nouveau avec le même problème de réentrance...

J'ai essayé d'utiliser dans ma macro basic les appels aux quelques APIs UNO comme par exemple ThisDatabaseDocument.lockControllers (ou encore addActionLock). Mais cela n'empêche pas l'envoi des doubles messages. J'ai cherché dans la documentation UNO des informations sur les mutex, le multithreading mais je n'ai trouvé aucune API disponible dans les macros basic... J'ai compris que cette partie de LibreOffice était en cours de refactoring. Mais cela concernera t-il les APIs des macro Basic ? Pour quelle prochaine date/version ?

J'ai également essayé de mettre en place un flag et un appel à wait() pour gérer une forme de Mutex. J'ai aussi utilisé un chien de garde pour détruire ma tache si le temps d'attente dépassait un timer. Mais l'appel à wait dans l'évènement n°2 ne redonne pas la main au thread du traitement de l'évènement n°1, et donc cela ne sert à rien...

Je me pause une autre question : Est-il possible de modifier la gestion des évènements au niveau de l'objet gérant le broadcaste, pour envoyer les évènement uniquement en série ? je crois comprendre que le broadcast serait géré par un objet frame en lien avec mon formulaire ...

Je pourrais aussi envisager transformer ma macro pour la rendre réentrante. Techniquement j'ai compris qu'il suffirait de n'utiliser que des variables locales. Mais lorsque la macro de l'évènement 1 terminera son traitement elle ne sera pas informée que l'enregistrement courrant a été modifié, et donc elle ne devrait pas être réentrante, mais plutôt quitter par un appel exit() ou même un appel stop()... Et pour cela il faudrait que les évènements 1 et 2 communiquent ensembles ...

Merci pour votre aide ...
Patrick

--
Envoyez un mail à users+unsubscribe@fr.libreoffice.org pour vous désinscrire
Les archives de la liste sont disponibles à https://listarchives.libreoffice.org/fr/users/
Tous les messages envoyés sur cette liste seront archivés publiquement et ne pourront pas être 
supprimés

Context


Privacy Policy | Impressum (Legal Info) | Copyright information: Unless otherwise specified, all text and images on this website are licensed under the Creative Commons Attribution-Share Alike 3.0 License. This does not include the source code of LibreOffice, which is licensed under the Mozilla Public License (MPLv2). "LibreOffice" and "The Document Foundation" are registered trademarks of their corresponding registered owners or are in actual use as trademarks in one or more countries. Their respective logos and icons are also subject to international copyright laws. Use thereof is explained in our trademark policy.