[basic][Calc] EventListener pour la modification de la liste des feuilles

Bonjour à tous,

Je cherche un moyen d’appeler une macro quand une feuille est renommée, déplacée ou supprimée. Pour les deux derniers j’ai trouvé une astuce en affectant un ModifyListener à une cellule de la feuille (n’ayant pas vocation à être modifiée), mais celui ne fait rien lorsque la feuille est renommée.
Je pourrais bien sûr mettre un ModifyListener sur la feuille elle-même mais il serait appelé beaucoup trop souvent, de même qu’un listener sur le UndoManager, comme suggéré dans le forum openoffice en anglais : Listener for a spreadsheet rename event (View topic) • Apache OpenOffice Community Forum

Un PropertyChangeListener serait bien, mais ça ne marche que pour les propriétés ayant l’attribut “bound” (au passage, quelqu’un a-t-il un explication sur ce concept d’attribut ?). N’y a-t-il pas moyen de mettre un listener sur l’objet représentant la collection des feuilles (celui qu’on obtient avec ThisComponent.getSheets) ? Ou une autre astuce plus efficace ?

Merci d’avance pour votre aide :slight_smile:

Bonjour @willy35

Tout d’abord au cas où le but serait de contrôler ces événements (renommer, supprimer), tu pourrais OutilsProtéger la structure.

Sinon, ci-joint une proposition mettant en oeuvre un XModifyListener. Le principe est de mémoriser la liste des noms de feuille et de comparer lors d’une modification à ce qui était mémorisé.

  • En cas de renommage, affichage de l’ancien nom et du nouveau
  • En cas d’ajout de feuille, affichage du nom en A1 de cette feuille

J’atttire quand même ton attention sur la “fragilité” des listeners pouvant être perdus/désactivés relativement facilement. C’est plutôt à utiliser “pour soi” qu’en production chez des utilisateurs néophytes.

Voir ListenerClasseurFeuilles.ods

Cordialement

Bonjour PIerre-Yves,

Merci beaucoup pour ta réponse et ton exemple très instructif.
Ce qui m’embête avec cette manière de faire c’est qu’un événement est généré pour toutes les modifications (voire plusieurs fois, par exemple 6 fois quand je ferme le document). Comme j’ai d’autres macros qui me servent à faire beaucoup de modifications d’un coup, et que ces modifications concerneront très rarement le événements qui m’intéressent ici, il me semble que ça risque de ralentir l’exécution “inutilement”.

À la limite, quitte à déclencher un événement à chaque modification, il me semble qu’un UndoManagerListener serait plus efficace, non ? Au moins il ne se déclencherait pas lors d’une modification par une macro ou de la fermeture du document.

@willy35 J’ai suivi quelques pistes mais il semble en effet que UndoManagerListener génère le moins d’activité. Toutefois, le moins impactant serait peut-être de gérer toi même le renommage par macro et affecter cette macro aux menus concernés : pas de listener. Il y a juste à gérer la saise pour contrôler les erreurs (caractères interdits, noms déjà utilisés, etc.) mais c’est une simple boucle.

J’ai regardé le PropertyChangeListener mais en effet cela ne se déclenche au niveau feuille que pour ce qui modifie la “vue” (scroll, zoom, affichage normal/page, etc).

Cordialement

@PYS Merci pour ton aide !
Effectivement j’ai fait ça pour ajouter une nouvelle feuille et je pourrais surement faire pareil pour renommer/supprimer, mais pour déplacer cela impliquerait de ne passer que par les menus, ce qui est quand même beaucoup moins pratique que par glisser/déposer (sauf si on peut affecter une macro à cette action ?).

C’est sans doute l’option la plus “propre”, mais je trouve ça étonnant qu’il n’y ait pas de manière aussi simple que mettre un listener sur ThisComponent.Sheets ou sur les propriétés des feuilles. Je ne m’y connais pas suffisamment en POO, mais est-ce qu’il n’y a pas moyen de faire en sorte que l’un des deux prenne en charge l’interface XModifyBroadcaster ?

@willy35 on ne dispose que ce qui est offert par l’API. Cela dit, tu pourrais poser la question sur la liste dev ou sur notre instance anglophone où davantage de développeurs répondent.

Quelle que soit la réponse ce serait intéressant si tu pouvais la faire remonter ici :slight_smile:

Cordialement