Application avec plusieurs types de documents

misiu91misiu91 Membre
janvier 2008 modifié dans API AppKit #1
Bonjour à  tous,
Je suis débutant sur Cocoa et malgré toute la littérature que j'ai pu consulter, je ne trouve pas la réponse à  ma question.
Je veux développer une application (Cocoa document-based application) qui me permette de créer des documents type texte (jusque là  je sais faire).
La barre de menu de mon application comprend également 4 ou 5 commandes de lancement de calculs dont le résultat est affiché sous forme de table dans un autre type de document que je veux sauvegarder en format CSV.
Je voudrais que l'enregistrement et l'ouverture de ce deuxième type de document soient gérés par la même commande que celle des documents texte (Ouvrir, Enregistrer, Enregistrer sous du menu fichier).
Ceci est-il réalisable ?
D'autre part, pour pouvoir lancer les calculs à  partir de mes 4 ou 5 commandes de la barre de menu, faut-il que je place les instances des classes correspondantes dans le fichier MainMenu.nib ou puis-je les créer dynamiquement ?
Je patauge un peu et j'aimerai de l'aide.
Merci d'avance pour votre compréhension.


Edit modération Titre de sujet plus en rapport avec la demande.

Réponses

  • Philippe49Philippe49 Membre
    18:47 modifié #2
    :p Bienvenu mislu91  :p



    Comma-separated values (CSV) est un format informatique ouvert représentant des données tabulaires sous forme de " valeurs séparées par des virgules ".
    Comma-Separated Values
    Extension de fichier :  .csv
    Type MIME :  text/csv
    Type de format :  fichier texte
    Standard(s) : (en) RFC 4180
    Spécification :

    Format ouvert
    Ce format n'a jamais vraiment fait l'objet d'une spécification formelle. Toutefois, la RFC 4180 décrit la forme la plus courante et établit son type MIME "text/csv", enregistré auprès de l'IANA.
    Un fichier CSV est un fichier texte (par opposition aux formats dit " binaires "). Chaque ligne correspond à  une rangée du tableau et les cellules d'une même rangée sont séparées par une virgule.
    Par exemple :
    Sexe, Prénom, Année de naissance
    M,Alphonse,1932
    F,Béatrice,1964
    F,Charlotte,1970



    On ne voit pas bien dans ton post ce qu'est ton modèle : un fichier, une NSString via un  NSTextView, une NSTableView où les données sont déjà  séparées ?

    dans 1201437608:

    Ceci est-il réalisable ?

    Si ce que tu appelles CSV est ce qu'il y a au dessus, je ne vois pas où il pourrait y avoir problème

    dans 1201437608:

    D'autre part, pour pouvoir lancer les calculs à  partir de mes 4 ou 5 commandes de la barre de menu, faut-il que je place les instances des classes correspondantes dans le fichier MainMenu.nib ou puis-je les créer dynamiquement ?


    La barre de menu envoie un message à  la chaà®ne des Responder, qui débute par .. le FirstResponder. Voir ce post

  • psychoh13psychoh13 Mothership Developer Membre
    18:47 modifié #3
    Je pense que son problème c'est surtout d'avoir une application multi-documents...
    De plus, je sais pas si les NSArchiver sont capables de faire du CSV.
  • misiu91misiu91 Membre
    18:47 modifié #4
    Merci à  Philippe49 et à  psychoh13 d'avoir pris le temps de lire et d'essayer de comprendre mon problème.
    Mon problème est effectivement d'avoir une application multi-documents de plusieurs formats.
    J'ai beaucoup programmé en C sous OS9 et j'ai vraiment du mal à  me mettre à  l'objet !!!
    J'ai notamment du mal à  voir comment doit s'articuler la boucle principale de mon programme. Comment se fait l'appel des différentes fonctions à  partir de ma barre de menu.
    Dans toute la documentation que j'ai pu ingurgiter, les exemples se limitent à  la gestion d'un type de document et je n'ai pas trouvé d'exemples de gestion multi-documents de différents formats.
    Je ne sais pas si je suis suffisamment clair.
    Merci
  • Philippe49Philippe49 Membre
    janvier 2008 modifié #5
    Je ne sais pas si ta question est aussi simple, mais si tu mets

    -(IBAction) saveDocument:(id) sender
    {
    NSLog(@Saving Document);
    }

    dans le code de MyDocument, tu verras que l'instance de cette classe répond aux actions déclenchées par le menu.(item File>Save)

    Après comme le dit Psycho, reste à  savoir si il existe un traitement prédéfini pour le type de fichier CSV .. lecture de Doc, ou un pénible switch() pour traiter les différents types de documents à  traiter.
  • misiu91misiu91 Membre
    18:47 modifié #6
    Merci Philippe49 c'est déjà  une idée qui peut me permettre de mieux comprendre comment cela fonctionne.
    Je vais te donner un exemple plus concret.
    Imaginons que la barre de menu de mon application contienne 2 items :
    - File avec la commande New
    - Toto avec la commande Titi
    Dans mon application, lorsque je fais File>New, j'ouvre un document de type "texte". La gestion de ce doc est contenue dans le fichier MyDocument1.m.
    Lorsque je fais Toto>Titi, je crée un document contenant une NSTableView. La gestion de gestion de ce doc est contenue dans le fichier MyDocument2.m.
    Ce que je veux c'est que lorsque je fais File>Save, le document actif soit enregistré avec son modèle de données. Si j'ai bien compris, à  l'envoi de cette commande, c'est le FirstResponder du document actif qui va être appelé et déclencher la bonne méthode d'enregistrement.
    Suis-je dans le vrai ou n'ai-je rien compris au film ???
    Merci de ton indulgence.
  • Philippe49Philippe49 Membre
    18:47 modifié #7
    dans 1201446046:

    Si j'ai bien compris, à  l'envoi de cette commande, c'est le FirstResponder du document actif qui va être appelé et déclencher la bonne méthode d'enregistrement.


    Oui
  • janvier 2008 modifié #8
    Deux choses à  faire: spécifier au niveau de ton info.plist les différents types de documents (tu as déjà  réussi à  en préciser un, donc les autres ne devraient pas causer de problème, le principe est le même).

    Là  deux possibilités:
    Soit tes documents sont assez différents et dans ce cas, tu dois  faire une sous-classe de NSDocument par type de document.
    Soit tes documents ne sont pas très différents et dans ce cas, tu peux utiliser la même classe pour les 2. Pour différencier les comportements pour les 2 types de documents à  la sauvegarde/couverture, tu as toujours un argument spécifiant le type dans les méthodes à  utiliser. Exemple:
    [tt]- (id)initWithContentsOfURL:(NSURL *)absoluteURL ofType:(NSString *)typeName error:(NSError **)outError[/tt]

    Avec ça, les méthodes d'ouverture et de sauvegarde devraient fonctionner de manière transparente. Pour les nouveaux documents, la commande "nouveau" crée par définition un document du type principal, si tu veux un autre type, tu dois rajouter un article dans le menu. Pour le "Save As", c'est un peu particulier. Un document est toujours créé avec un type (le type par défaut sauf si le cas contraire est spécifié). Donc si tu veux faire une conversion d'un type vers un autre, il faudra sans doute coder un peu.
  • janvier 2008 modifié #9
    dans 1201446046:
    Si j'ai bien compris, à  l'envoi de cette commande, c'est le FirstResponder du document actif qui va être appelé et déclencher la bonne méthode d'enregistrement.


    Oui et non. Le message est envoyé dans la "chaine du first responder", qui commence par le first responder de la fenêtre active. Les détails ici
  • Philippe49Philippe49 Membre
    18:47 modifié #10
    J'aimerais quand même te poser ici une question sur l'architecture de ton programme.
    La philosophie des Cocoa-Based document est plutôt mono-document.
    En débutant en Cocoa, avec le besoin de plusieurs interfaces de représentations, j'essaierais d'abord de le faire en changeant la contentView de la fenêtre principale ou une View remplissant complètement cette contentView.
    En mettant une variable d'instance correspondant au type de données traitées dans le document.

    Ceci dit je n'ai jamais essayé de faire des multi-documents, je m'en vais de ce pas faire un petit essai ... :o
  • Philippe49Philippe49 Membre
    18:47 modifié #11
    dans 1201447043:

    dans 1201446046:
    Si j'ai bien compris, à  l'envoi de cette commande, c'est le FirstResponder du document actif qui va être appelé et déclencher la bonne méthode d'enregistrement.


    Oui et non. Le message est envoyé dans la "chaine du first responder", qui commence par le first responder de la fenêtre active. Les détails ici


    Et si le fisrtResponder n'est pas en mesure de répondre, le message est transmis au suivant
  • misiu91misiu91 Membre
    18:47 modifié #12
    Merci à  tous pour vos explications qui ont été on ne peut plus limpides.
    Dans mon post de départ, il y avait une question subsidiaire pour laquelle je n'ai pas encore de réponse.
    Pour la commande Toto>Titi que j'évoquai dans mon dernier post, faut-il que je mette dans le MainMenu.nib une instance de la classe qui crée le type de document associé ou puis-je créer dynamiquement différentes instances dans le contrôleur de mon application ?
    Dans ce cas, comment est-ce que je gère ces différentes instances ?
  • misiu91misiu91 Membre
    18:47 modifié #13
    dans 1201448218:

    J'aimerais quand même te poser ici une question sur l'architecture de ton programme.
    La philosophie des Cocoa-Based document est plutôt mono-document.
    En débutant en Cocoa, avec le besoin de plusieurs interfaces de représentations, j'essaierais d'abord de le faire en changeant la contentView de la fenêtre principale ou une View remplissant complètement cette contentView.
    En mettant une variable d'instance correspondant au type de données traitées dans le document.

    Ceci dit je n'ai jamais essayé de faire des multi-documents, je m'en vais de ce pas faire un petit essai ... :o

    Mon programme effectuera différents calculs de statistiques dont les résultats seront présentés dans une table surmontée probablement d'une représentation graphique. Le document de type texte permettra de rédiger des comptes-rendus sur ces résultats.
    Ta proposition de changer la contentView de la fenêtre principale est certainement un bonne idée mais je ne vois (pas encore mais ça viendra) comment est-ce que l'on réalise cela.
  • misiu91misiu91 Membre
    18:47 modifié #14
    dans 1201446751:

    Un document est toujours créé avec un type (le type par défaut sauf si le cas contraire est spécifié).

    Comment détermine-t-on ou spécifie-t-on le type par défaut ?
  • 18:47 modifié #15
    Les différents types de documents au niveau du plist sont stockés dans un array, c'est le premier de la liste.
  • Philippe49Philippe49 Membre
    janvier 2008 modifié #16
    dans 1201449078:

    Ta proposition de changer la contentView de la fenêtre principale est certainement un bonne idée mais je ne vois (pas encore mais ça viendra) comment est-ce que l'on réalise cela.


    NSWindow propose la méthode
    - (void)setContentView:(NSView *)view

    et on peut mettre autant de custom view que l'on veut dans le fichier MyDocument.nib par drag/drop
    Un double-clic dessus dans IB l'ouvre, et permet de la remplir comme on veut 

    Après il suffit de répertorier les views par IBOutlet.

    Mais n'ayant jamais essayé des appli multi-documents, ...  Renaud qu'en penses-tu ?
  • psychoh13psychoh13 Mothership Developer Membre
    18:47 modifié #17
    Tu peux aussi, et surtout, les voir de manière plus lisibles en cliquant sur la cible de ton application situé dans le groupe "Targets", il suffit de faire cmd + i et tu vas dans l'onglet "Properties", tu auras alors un tableau en bas de la fenêtre qui t'afficheras tous les documents gérés par ton application. Mais aussi la forme d'enregistrement :
    • Binary
    • SQL
    • XML
    • In memory (ne me demande pas ce que c'est je n'en ai aucune idée)


    Tu as aussi plusieurs autres options attachés à  chaque types de document (MIME, extension, icone, classe principale, si c'est un bundle ou pas, etc.)
  • Philippe49Philippe49 Membre
    18:47 modifié #18

    dans 1201449078:

    Mon programme effectuera différents calculs de statistiques dont les résultats seront présentés dans une table surmontée probablement d'une représentation graphique. Le document de type texte permettra de rédiger des comptes-rendus sur ces résultats.


    Il y a au point de vue interface des solutions encore plus simples :
    NSTabView, sorte de container de vue à  onglets.
    NSSplitView  , container de vue comme dans XCode ou Grapher
  • Philippe49Philippe49 Membre
    janvier 2008 modifié #19
    Voilà  ci-joint un exemple d'application multi-documents avec un item Test , et item NewSecondDocument opérationnel


    2008-01-27 17:48:51.545 essai document[2047:10b] test from <NSWindow: 0x15b410>
    2008-01-27 17:49:00.674 essai document[2047:10b] create new secondDocument
    2008-01-27 17:49:07.081 essai document[2047:10b] test from <NSWindow: 0x181630>
    2008-01-27 17:49:12.736 essai document[2047:10b] test from <NSWindow: 0x15b410>


    Voir une solution plus étoffée plus loin dans le post par Renaud 
  • misiu91misiu91 Membre
    18:47 modifié #20
    dans 1201452812:

    Voilà  ci-joint un exemple d'application multi-documents avec un item Test , et item NewSecondDocument opérationnel

    Merci pour ce petit bout de code. Je l'ai décortiqué et cela me parait très clair.
    Je l'ai fait tourné avec ObjectAlloc et j'ai constaté les choses suivantes :
    - Lorsque je crée des docs avec File>New et que les ferme, je vois bien le nombre d'instances courantes de MyDocument s'incrémenter et se décrémenter. Il en est de même avec les instances de NSWindowController.
    - En revanche, lorsque je crée des "seconds docs" avec File>NewSecond, je ne vois pas d'instances de MySecondDocument (ce que je ne comprends pas) et les instances de NSWindowController s'incrémentent mais ne se décrémentent pas. Il y a donc une fuite mémoire potentielle.
    Est-ce que je me trompe ?
    Si non, que faut-il faire pour que les instances de NSWindowController ne restent pas en mémoire après fermeture ?
    Merci
  • Philippe49Philippe49 Membre
    janvier 2008 modifié #21
    Tout à  fait exact, le windowController est en alloc+init donc son retainCount est de 1. 

    Rectifié
  • misiu91misiu91 Membre
    18:47 modifié #22
    Par contre, comme pour MyDocument, je m'attendais à  passer dans l'init de MySecondDocument or cela ne se produit pas. Ce qui explique pourquoi avec ObjectAlloc je ne vois pas d'instance de cette classe. Je ne vois donc pas bien l'utilité de MySecondDocument.m et MySecondDocument.h ????
  • Philippe49Philippe49 Membre
    janvier 2008 modifié #23
    Oui j'ai rectifié le code (post au-dessus): il faut initialiser un second document, et lui attribuer un WindowController par makeWindowController (cf le commentaire Apple dans windowNibName), et non le contraire comme je l'avais fait auparavant.  :o

    MySecondDocument pourra ainsi avoir ses propres méthodes d'archivage, de désarchivage, ...
  • misiu91misiu91 Membre
    18:47 modifié #24
    J'ai testé ta dernière évolution et j'ai constaté que les instances de NSWindowController s'incrémentent et se décrémentent bien au fur et à  mesure que je crée ou que je ferme des MySecondDocument en revanche, les instances de MySecondDocument ne cessent de s'incrémenter sans jamais se purger de la mémoire.
    J'ai donc apporté les évolutions suivantes :
    • Tout d'abord, j'ai appliqué dans MySecondDocument.m le même code que dans MyDocument.m en supprimant ce que tu avais ajouté. Je n'ai pas vu de raison de faire autrement que MyDocument.

    • Ensuite, dans MySecondDocument.m j'ai ajouté le code suivant qui permet de purger la mémoire à  la fermeture de la fenêtre :
    - (void)close<br />{<br />	[self release];<br />}<br />
    

    • Enfin dans le fichier MySecondDocument.nib, j'ai constaté que le File's Owner était un document de la classe MyDocument. Je l'ai donc changé en MySecondDocument. Je ne sais pas si cela est important mais cela m'a semblé plus logique.


    Tout cela fonctionne parfaitement bien et il n'y a plus aucune fuite mémoire. Il me reste à  appliquer tout cela à  mon application.
    Qu'en penses-tu ?
    Avec mes remerciements pour ton aide.
  • Philippe49Philippe49 Membre
    janvier 2008 modifié #25
    dans 1201553034:

    J'ai testé ta dernière évolution et j'ai constaté que les instances de NSWindowController s'incrémentent et se décrémentent bien au fur et à  mesure que je crée ou que je ferme des MySecondDocument en revanche, les instances de MySecondDocument ne cessent de s'incrémenter sans jamais se purger de la mémoire.

    C'est normal, dans ce code ils sont retenus par AppController

    dans 1201553034:

    Tout d'abord, j'ai appliqué dans MySecondDocument.m le même code que dans MyDocument.m en supprimant ce que tu avais ajouté. Je n'ai pas vu de raison de faire autrement que MyDocument.

    Ca ne suit pas les recommandations qu'Apple a mis en commentaires dans windowNibName 

    dans 1201553034:

    Dans le fichier MySecondDocument.nib, j'ai constaté que le File's Owner était un document de la classe MyDocument. Je l'ai donc changé en MySecondDocument. Je ne sais pas si cela est important mais cela m'a semblé plus logique.

    C'est plus logique en effet mais il me semble que c'est fait par addWindowController
    Il suffit de mettre un log dans le code :
      [self addWindowController:wController]; //
      NSLog(@The document associated with the windowController is : %@ \nThe document owning this window controller is : %@",[wController document],self);




    dans 1201553034:

    Voici un complément de code pour "observer" ce qui se passe


    static int numberOfInstances=0; <br /><br />@implementation MySecondDocument<br /><br />- (id)init<br />{<br />    self = [super init];<br />    numberOfInstances++;<br />    if (self) {<br />    <br />        // Add your subclass-specific initialization here.<br />        // If an error occurs here, send a [self release] message and return nil.<br />    <br />    }<br />    NSLog(@&quot;Initializing an instance of MySecondDocument. After init, numberOfInstances=%d&quot;,numberOfInstances);<br />    return self;<br />}<br />-(oneway void) release<br />{	<br />	NSLog(@&quot;Releasing an instance of MySecondDocument. After release, numberOfInstances=%d&quot;,numberOfInstances);<br />	[super release];<br />}<br /><br />-(void) dealloc<br />{<br />  numberOfInstances--;<br />  NSLog(@&quot;deallocing an instance of MySecondDocument. After release, numberOfInstances=%d&quot;,numberOfInstances);<br />  [super dealloc];<br />}<br /><br />-(void) close<br />{<br />  // message  &quot;do you want to save ?&quot;<br />  [super close];<br />  [self autorelease];<br />}
    


    Tout cela fourni (SGDG) sans garantie du gouvernement car je n'ai personnellement jamais vu ou fait d'appli multi-doc
    Un petit tour sur Internet permettrait de confirmer/infirmer


  • Philippe49Philippe49 Membre
    janvier 2008 modifié #26
  • janvier 2008 modifié #27
    dans 1201449956:
    Mais n'ayant jamais essayé des appli multi-documents, ...  Renaud qu'en penses-tu ?


    Oups, sorry pour le délai.

    Remplacer la contentView me semble pas des plus approprié. Soit les types de documents ont une même UI, mais ne diffèrent que par le stockage et dans ce cas on ne fait la différenciation que dans les méthodes de sauvegarde. Si l'UI est différente, alors dans ce cas, il y a des chances qu'à  mesure que l'interface se développe les différences s'accentuent et que le code devienne un beau schmilblick. Autant utiliser les possibilités offertes par la POO et faire une sous classe du document initial pour vraiment différencier les comportements.

    dans 1201553034:

    - (void)close<br />{<br />	[self release];<br />}<br />
    



    Alors ça, surtout pas! On est pas censer libérer des objets qu'on a pas instancié/retenu soi-même! Les instances des documents doivent être créées par NSDocumentController, donc c'est à  lui de releaser les instances (à  moins que tu aies fait un [self retain] ailleurs dans cette classe, mais ça n'a pas de sens). Sans compter que surcharger une méthode comme celle-là  sans appeler [tt][super close][/tt] peut être source de problème.




    Pour le code que tu as posté, les corrections:

    1. Info.plist non complété
    Seul le premier type de document était mentionné, il faut mentionner les 2.

    2. MySecondDocument.nib
    Si tu sous-classes [tt]-windowNibName[/tt], le file's owner du nib doit être le document.
    Si tu sous-classes [tt]-makeWindowControllers[/tt], le file's owner du nib doit être autre chose. Le autre chose est laissé à  ton appréciation, mais vu que tu utilises la méthode [tt]-[NSWindowController initWithWindowNibName:][/tt], le file's owner doit être une instance de NSWindowController (et les outlets correctement reliés).

    3. Création du second document
    Il est beaucoup plus judicieux de passer par les méthodes ad hoc de NSDocumentController (puisque le Info.plist est remplit correctement).

    Au lieu de:
    [tt]MySecondDocument * doc=[[MySecondDocument alloc] init];
    [doc makeWindowControllers];
    [doc showWindows];[/tt]
    -
    Tu mets donc:
    [tt]NSError *error = nil;
    [[MyDocumentController sharedDocumentController] setDefaultType:@SecondDocument];
    id doc = [[MyDocumentController sharedDocumentController] openUntitledDocumentAndDisplay:YES error:&error];
    [[MyDocumentController sharedDocumentController] setDefaultType:nil];
    if ( !doc ) {
    [[NSDocumentController sharedDocumentController] presentError:error];
    }[/tt]

    Tu remarqueras que j'ai du sous-classer NSDocumentController, c'est une nouveauté du 10.4, la méthode [tt]-openUntitledDocumentOfType:display:[/tt] étant dépréciée.

    4. Définir la fenêtre principale d'un document
    Pour qu'un document soit fermé (et libéré) lorsque la fenêtre principale est fermée, il faut utiliser la méthode [tt]-[NSWindowController setShouldCloseDocument:][/tt] lorsque tu instancies le window controller de la fenêtre principale. C'est fait automatiquement dans le cas de MyDocument car c'est assuré par l'implémentation par défaut de [tt]-makeWindowController[/tt].

    5. Autorelease dans [tt]-[MySecondDocument close][/tt]
    Voir plus haut. Si tu me réponds que tu l'as mis là  parce tu as mis toi-même le [tt]init[/tt] dans AppController, je prends un règle et je te tape sur les doigts: faire les [tt]retain/init[/tt] dans une classe et les [tt]release[/tt] dans une autre, c'est une belle façon de se créer des maux de têtes en cas de problème.

    J'ai mis le projet corrigé en pièce jointe (note: MyDocumentController est déclaré dans  AppController.m)
  • Philippe49Philippe49 Membre
    18:47 modifié #28
    dans 1201626304:

    [[MyDocumentController sharedDocumentController] setDefaultType:@SecondDocument];
    id doc = [[MyDocumentController sharedDocumentController] openUntitledDocumentAndDisplay:YES error:&error];
    [[MyDocumentController sharedDocumentController] setDefaultType:nil];

    Ce qu'il faut comprendre ici, c'est qu'il n'y a qu'un seul sharedDocumentController pour toutes les sous-classes de NSDocumentController :
    [NSDocumentController sharedDocumentController]=[MyDocumentController sharedDocumentController]
    D'ou l'utilité de la définition de defaultType, qui permet de lire la classe du document créé via la plist .

    openUntitledDocumentAndDisplay:YES
    The default implementation of this method invokes defaultType to determine the type of new document to create, invokes makeUntitledDocumentOfType:error: to create it, then invokes addDocument: to record its opening. If displayDocument is YES, it then sends the new document makeWindowControllers and showWindows messages.





    dans 1201626304:

    5. Autorelease dans [tt]-[MySecondDocument close][/tt]
    Voir plus haut. Si tu me réponds que tu l'as mis là  parce tu as mis toi-même le [tt]init[/tt] dans AppController, je prends un règle et je te tape sur les doigts: faire les [tt]retain/init[/tt] dans une classe et les [tt]release[/tt] dans une autre, c'est une belle façon de se créer des maux de têtes en cas de problème.

    Effectivement ! :o   :o c'est mal.
    Dans ton schéma c'est qui envoie le message de "fin de vie au document" : le windowController ? le documentController ?

     

  • janvier 2008 modifié #29
    dans 1201636558:
    Ce qu'il faut comprendre ici, c'est qu'il n'y a qu'un seul sharedDocumentController pour toutes les sous-classes de NSDocumentController :
    [NSDocumentController sharedDocumentController]=[MyDocumentController sharedDocumentController]
    D'ou l'utilité de la définition de defaultType, qui permet de lire la classe du document créé via la plist .


    Je ne sais plus où c'est écrit dans la doc, mais la première instance créée de NSDocumentController (ou d'une de ses sous-classes) devient le sharedDocumentController. D'où l'appel [tt][MyDocumentController sharedDocumentController][/tt] dans [tt]+[AppController initialize][/tt] pour s'assurer que c'est bien la bonne sous-classe de NSDocumentController qui sera utilisée.

    dans 1201636558:
    Dans ton schéma c'est qui envoie le message de "fin de vie au document" : le windowController ? le documentController ?

    ça dépend de la manière dont tu définis "fin de vie". Si je te prends au mot, c'est à  partir d'un [tt]-release[/tt] et là  c'est le NSDocument lui même (pas taper).

    Bon, le principe c'est que la méthode [tt]-close[/tt] est envoyée lorsqu'un document est fermé, pas pour demander la fermeture d'un document. Donc je reviens sur un point que j'avais oublié de mentionner dans ma correction: pas besoin de demander de confirmation pour dans [tt]-close[/tt]. Si cette méthode est appelée c'est trop tard.

    Pour demander la fermeture d'un document, si tu veux le faire de la manière la plus simple, il faut juste que tu aies au moins une instance de NSWindowController qui renvoie YES à  [tt]-shouldCloseDocument[/tt]. De cette manière quand tu fermes la fenêtre qu'il gère, l'implémentation par défaut est telle qu'il vérifie que le document est bien enregistré, si c'est pas le cas, il demande une confirmation,.... pour au final envoyer le [tt]-close[/tt]. Le menu File->Close utilise en fait ce mécanisme: il ne fait que demander de fermer la fenêtre et puis le window controller fait le reste.

    Donc dans ce schéma, c'est le window controller si la demande se fait suite à  une fermeture de fenêtre et le document controller si le but est de faire suite à  une demander de quitter l'appli.


    EDIT: misiu91: petit détail, j'ai renommé le titre de la conversation. Pour la prochaine fois, lorsque tu poses une question, utilise un terme moins générique (accessoirement, celui que tu as mis a tendance à  me faire fuire d'habitude - dans neuf cas sur dix, sous ce genre de titre se cachent des questions auxquelles la réponse a été donnée plusieurs fois).
  • Philippe49Philippe49 Membre
    18:47 modifié #30
    Thanks ! 
Connectez-vous ou Inscrivez-vous pour répondre.