[Résolu] Récupérer la référence du document lors de son activation
Bonjour,
Je reviens sur un sujet qui n'a pas trouvé de réponse, et le reprendre avec des yeux que j'espérais neufs me replonge dans la confusion.
Je souhaite créer un NSPanel unique à l'application (dans MainMenu.xib) dont le contenu changerait en fonction du document actif (un peu comme l'inspecteur de l'ancien Pages).
Les bindings devront se faire à la volée, puisque le document se trouve dans un autre xib, Mais je pense y arriver sans trop de zombies à la fermeture du document.
Mon problème est de savoir où et comment actualiser mon panel. Une sorte de notification "applicationWillActivateWindow", mais quel est le mécanisme existant ?
- Notification ? Existante ? A créer ? Classes à dériver ?
- Délégation ? Mais qui est le délégué de qui ?
Quels sont les acteurs concernés par cette opération qui semble très banale ? NSApplication? NSDocument? NSWindow? NSWindowController? Je m'y perds complètement...
Surtout, je ne voudrais pas réinventer la roue (et surtout que ma propre roue soit bringuebalante). Quelqu'un a implémentée quelque chose de semblable ou connaà®t un lien?
D'avance merci.
Réponses
Tu peux binder sur [NSApplication sharedApplication].mainWindow.windowController.document.
Pour signifier de changer de NSDocument à mon NSPanel, en fait mon inspecteur j'utilise les notifications indiquées ci-après.
Les éléments de mon inspecteur bindent sur les éléments voulus en passant par une propriété monDocument que je règle lors des notifications. C'est assez efficace mais nécessite un peu de réflexion.
Le windowWillClose me permet de déterminer si j'ai encore un Document ouvert pour signifier au NSPanel qu'il n'y a pas de document ouvert et afficher un avertissement adéquat (ou rendre inactif les contrôles).
J'ai indiqué windowDidResignMain mais cette notification ne me sert pas a proprement parler pour indiquer que le document n'est plus celui géré par l'inspecteur. j'y supprime des bindings que je crée à la volée dans le windowDidBecomeMain.
Merci à vous deux.
J'ai utilisé la solution de fleurantin (moins le windowDidResignMain) et ça fonctionne bien. Avec le document comme objet de la notification, je n'ai même pas besoin d'outlets. Les notifications sont très bien pour limiter le couplage entre des classes qui ne sont pas logiquement apparentées. Et comme l'inspecteur a une durée de vie égale à celle de l'application, pas de risque de laisser des zombies dans le centre de notification...
J'avais essayé cette technique mais elle n'était pas satisfaisante, les notifications n'étant pas émises dans certains cas. Essaie bien tous les cas: placer dans le Dock, passer à un autre écran, fermer la fenêtre alors que l'appli n'est pas au premier plan, activer Mission Control, etc.
ça a l'air de tenir la route...
Sinon, j'ai réfléchi à faire du contrôleur de l'inspecteur une sharedInstance, dans ce cas on pourrait éviter les notifications... Quelque chose comme
et bien sûr un [[SBInspector sharedInstance]setCurrentDocument: nil]; à la fermeture du document.
Je ne sais pas quelle est la meilleure solution (la plus propre, la plus OOP-correcte ou la plus efficace). Mais à partir du moment où l'inspecteur possède la propriété (strong) SBDocument *currentDocument, on peut binder à partir de là ...
Cette solution a l'inconvénient d'augmenter le couplage entre ton inspecteur et ton document : l'inspecteur connaà®t le document, et le document connaà®t l'inspecteur.
Définir la méthode setCurrentDocument dans un protocole de délégué de document permettrait de garder le même principe mais sans augmenter le couplage : le document n'a plus besoin de connaà®tre son inspecteur.
Dans ton cas, la notification me paraà®t parfaitement adaptée.