Relier un élément de menu à  une action de document

J'ai une application qui est document-based.


Je souhaite créer une entrée dans le menu qui lance une action relative au document, et non relative à  l'application.


 


Quand j'ouvre MainMenu.xib, j'ai les bons outils en main pour linker des entrées de menu avec des actions liées à  mon application : par exemple, le MainMen.xib est le bon endroit où mettre mon AppDelegate, où je peux ensuite définir mes actions dont le scope est l'application.


 


Comment faire pour linker un élément de menu à  une action dont le scope est le document ?


 


Voilà  comment j'ai fait. Je voulais savoir s'il y a mieux.


-> je linke mon entrée de menu avec une action doAction de mon appDelegate.


-> dans le corps de cette méthode doAction, je récupère le document en cours, à  l'aide de



MyDocument * myDoc = [[NSDocumentController sharedDocumentController] currentDocument];

 


-> Je lance une action : [myDoc doRealAction].


 


Une des mes craintes est l'emploi de [[NSDocumentController sharedDocumentController] currentDocument]. J'ai lu qu'il ne marche pas toujours (cf. http://stackoverflow.com/questions/8912314/nsdocumentcontroller-currentdocument-returning-nil)


 


Merci


Réponses

  • mpergandmpergand Membre
    avril 2013 modifié #2

    Ca se passe dans first responder dans xcode:


    First Responder

    The First Responder placeholder object represents the first object in the responder chain, which is determined dynamically at runtime by the AppKit and UIKit frameworks.

    To add new action messages to the first responder's supported list

     

    1.Select the First Responder placeholder object in your Interface Builder document.


    2.Open the Attributes inspector.

    3.Click the Add (+) button at the bottom of the User Defined section to create a new action method entry.

    4.Double-click the method name in the Action column and type the name of the method.

    5.Select the class in which the method will be defined from the pop-up list in the Type column.

    6.After you are done making connections in Interface Builder, add the code for the method to the header and implementation class files in your project that you specified in step 5.

The name of the method must match the name specified in step 4.


     

    Adding action methods to the First Responder placeholder object does not add the corresponding method definition to your Xcode source files. All it does is let Xcode know that such a method exists in one of the objects in the responder chain of your project. It is up to you to ensure the method names you add to the First Responder placeholder match the names of the methods in your code. Xcode does not validate these method names for you. At runtime, if a method name is misspelled or does not exist in an object, the corresponding action message is never received by the target object.

     

    Interface Builder does not prevent you from deleting the standard system messages associated with the First Responder placeholder. Doing so removes the message name from the current nib file only.

     


     


    http://developer.apple.com/library/ios/#documentation/ToolsLanguages/Conceptual/Xcode_User_Guide/030-Edit_User_Interfaces/edit_user_interface.html


     


    Pour envoyer une message au first responder par code, il faut utiliser sendAction:to:from: de NSApplication


     


    ex:



    [NSApp sendAction:@selector(monAction:) to:nil from:self];
  • Merci !


  • J'ai cependant un problème : quand je veux faire un binding sur un tel élément de menu (en l'occurrence pour le caractère enabled ou pas), je n'ai pas accès dans la liste proposée au First Reponder.


     


    J'imagine que c'est un cas courant, pourtant...

  • Bonjour,


     


    Il faudra en passer par là :


    https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/ApplicationKit/Protocols/NSMenuValidation_Protocol/Reference/Reference.html


     


     


    Quand les bindings vous lâchent, il reste les notifications... :'(

  • laudemalaudema Membre
    avril 2013 modifié #6

    J'ai cependant un problème : quand je veux faire un binding sur un tel élément de menu (en l'occurrence pour le caractère enabled ou pas), je n'ai pas accès dans la liste proposée au First Reponder.


     


    J'imagine que c'est un cas courant, pourtant...


    Pas si certain que toi puisque sera firstResponder le premier NSResponder dans la chaà®ne des répondeurs donc n'importe quel objet Vue->SuperVue->Fenêtre->Contrôleur de fenêtre->Document->Contrôleur de document->Application.


     The exact path up the modified responder chain depends on the type of application window:



    • Windows owned by document: view to superviews to window to window controller to document object to document controller to the application object



    Et ça changera selon l'élément sélectionné par l'utilisateur. Difficile dans ces conditions de faire un binding et encore plus de le garder à  jour !


     


    Pour le côté enabled il suffit d'ajouter ta méthode à  l'objet firstResponder de ton nib comme te l'a indiqué mpergand puis de control-clic tirer l'action de ton menu sur cet objet FirstResponder du nib et pas sur une méthode de AppDelegate.


    Ensuite si ta méthode est définie dans le .h de ton Document (ou d'un autre répondeur de la liste) le menu sera activé, sinon pas. Pas besoin de bindings, c'est la disponibilité de la méthode dans la chaà®ne des répondeurs qui l'activera. Le cas courant (et antérieur aux bindings) est plutôt celui là  ;)


Connectez-vous ou Inscrivez-vous pour répondre.