[Résolu] Outlineview et sauvegarde des items dépliés ou pliés...

LeChatNoirLeChatNoir Membre, Modérateur
décembre 2005 modifié dans API AppKit #1
Salut,
J'ai une outlineView qui fonctionne (ouehhhh !).
Les objets qu'elle affiche sont conforme au NSCoding protocol et à  l'affichage de l'outlineview, ca désarchive bien et à  sa fermeture, ca archive bien.

Par contre, j'ai découvert la possibilité de sauvegarder la configuration de l'outline (avec autosaveName) et également de la configuration des items dépliés ou pas (ceux qui ont des fils).
Ca se fait avec setAutosaveExpandedItem.

Quand on souhaite utiliser cette mécanique par contre, il faut ajouter ces  2 méthodes dans le delegate :
- (id)outlineView:(NSOutlineView *)outlineView persistentObjectForItem:(id)item
et
- (id)outlineView:(NSOutlineView *)outlineView

Je les ai défini telles que :
- (id)outlineView:(NSOutlineView *)outlineView persistentObjectForItem:(id)item
{
    return [NSKeyedArchiver archivedDataWithRootObject:item];
}

- (id)outlineView:(NSOutlineView *)outlineView itemForPersistentObject:(id)object
{
    return [NSKeyedUnarchiver unarchiveObjectWithData:object];
}


Bon ben ca se plante sur un message "selector not recognize" étrange dans mon encodeWithCoder mais là  n'est pas (encore) la question.

Je me demandais simplement si ces fonctions ne faisaient pas plus que sauver la configuration des items dépliés/pliés...

Par ce qu'en tentant de debugger, je m'aperçois qu'il alloue/désalloue carrément mes objets perso...

Faut il alors laisser tomber le désarchivage à  l'ouverture et l'archivage à  la fermeture  ou pas ?

Mais peut être faut il que je résolve d'abord mon erreur de encode...
Si quelqu'un a déjà  expérimenté ça, je suis preneur de ses retours...



Réponses

  • LeChatNoirLeChatNoir Membre, Modérateur
    12:53 modifié #2
    Ben vous allez pas me croire mais pour une fois, je suis retombé sur mes pattes !  :-*

    J'ai trouvé comment fonctionne la sauvegarde/restauration de l'état de l'outlineview.

    First :
    dire qu'on veut que ca soit sauver via :
    [outlineView setAutosaveName:@UnNomSousLequelSeraSauvéeaLConfDeLaOutline];
    [outlineView setAutosaveExpandedItems:YES];

    J'ai l'impression qu'il utilise le NSUserDefault en arrière plan l'air de rien...

    Second :
    Implémenter les 2 méthodes de persistance à  savoir "- (id)outlineView:(NSOutlineView *)outlineView itemForPersistentObject:(id)object" et "- (id)outlineView:(NSOutlineView *)outlineView persistentObjectForItem:(id)item".

    Voyons la première : - (id)outlineView:(NSOutlineView *)outlineView itemForPersistentObject:(id)object
    elle est appelée quand l'outline s'affiche et qu'elle essaye de récupérer l'état de chaque item (collapse ou pas).
    Il faut donc, à  partir de ce qu'on a sauvé (=> cf. explication de la seconde méthode), renvoyer l'item correspondant.

    Voyons la seconde : - (id)outlineView:(NSOutlineView *)outlineView persistentObjectForItem:(id)item
    Celle ci est appelée chaque fois qu'on déplie ou plie un item (et ce pour sauvegarder son état). C'est là  qu'il faut envoyer l'item à  sauvegarder.

    Bon jusque là , vous allez me dire "C'est exactement, ce qui est marqué dans la doc".


    Oui mais voilà , ce que j'avais pas capté, c'est qu'il met ça dans une property list ou un truc du style et que si les items de l'outlineview sont des objets customisés (comme c'est le cas pour moi) dans lesquels il y q des types non "property listables", ben ca marche pas et ca dit pas grand chose...

    Donc dans ce cas, il faut :
    * renvoyer l'item identifié par un identificateur unique qu'on récup' via le paramètre "object" de la méthode  (ce qui oblige à  parcourir l'arbre dans mon cas pour rechercher l'objet) ; ca dans la première méthode,
    * renvoyer un identificateur de "item" qui soit compatible "property list" dans la 2eme méthode.

    Bon, j'espère que c'est clair et que ca servira un jour à  quelqu'un :-)
    a+

    Et pis tiens, je m'applaudis pour une fois que je me débrouille tout seul  :adios!:
  • aranaudaranaud Membre
    12:53 modifié #3
    Je voudrai savoir s'il y a une méthode "propre" pour récupérer les informations enregistrer de setAutosaveName. Pour les intégrés dans un autre fichier que celui des préférences.

    dans 1134586886:

    Oui mais voilà , ce que j'avais pas capté, c'est qu'il met ça dans une property list ou un truc du style et que si les items de l'outlineview sont des objets customisés (comme c'est le cas pour moi) dans lesquels il y q des types non "property listables", ben ca marche pas et ca dit pas grand chose...

    Tu entends quoi par "objets customisés". Des objets que tu créais toi même ?
  • LeChatNoirLeChatNoir Membre, Modérateur
    12:53 modifié #4
    Incapable de répondre à  ta première question.
    Par objet customisé, oui, en fait, il s'agit de sous-calsse de NSObject à  moi dans laquelle je met ce que j'ai envie.
    Ce que je voulqis dire par là , c'est que ce ne sont pas de simples NSString ou des trucs comme çq.
    Dedans, j'ai des types style NSImage qui ne peuvent être mis dans une property list d'où le problème que j'ai rencontré !

    a+
  • aranaudaranaud Membre
    12:53 modifié #5
    dans 1135069619:

    Incapable de répondre à  ta première question.

    J'ai bien une idée mais elle me semble pas "propre" (récupérer les informations directement dans les préférences).

    dans 1135069619:

    Par objet customisé, oui, en fait, il s'agit de sous-calsse de NSObject à  moi dans laquelle je met ce que j'ai envie.

    Donc, si je comprends bien, avec les objects NSString, cocoa se débrouille tous seul mais avec des objects perso, c'est à  moi de faire le bouleau.
  • LeChatNoirLeChatNoir Membre, Modérateur
    12:53 modifié #6
    dans 1135070420:

    Donc, si je comprends bien, avec les objects NSString, cocoa se débrouille tous seul mais avec des objects perso, c'est à  moi de faire le bouleau.


    Non non. Je me suis mal exprimé en fait.
    C'est bien Cocoa qui fait tout.

    Le seul truc c'est qu'en fait, dans les 2 méthodes de persistences à  définir si tu veux sauver l'état plié/déplié de ton outline, il faut pouvoir encoder/décoder les objets de l'outline pour qu'il les archives/désarchive d'un fichier de sauvegarde (qui semble être les prefs mais c'est même pas sûr, j'ai pas vérifié).

    Le problème, c'est que ton objet ne doit alors contenir que des types acceptés par les property list.
    Si ca n'est pas le cas, il suffit de se débrouiller pour archiver un identifiant de ton objet seulement (un style de clé unique). Ca reste hyper simple du coup et on peut considérer que c'est Cocoa qui fait tout.

    Je suis peut être pas super clair mais c'est tout simplement parce que je suis passé à  autre chose depuis et je ne me rappelle déjà  plus franchement de tous les tenants et aboutissants...



  • aranaudaranaud Membre
    12:53 modifié #7
    On dirait qui faut utiliser les méthodes : - (void)encodeWithCoder:(NSCoder *)encoder et - (id)initWithCoder:(NSCoder *)decoder pour les objects perso. Ceci doit déjà  être implanté dans les object NSString, ...
  • LeChatNoirLeChatNoir Membre, Modérateur
    12:53 modifié #8
    Moi j'ai pas eu besoin de ça en utilisant un identificateur.

    En gros, dans ovl:... persistentObjectForItem, je renvoie l'identificateur de mon objet, et dans l'autre, je cherche l'objet ayant pour identificateur "object" (qui est le paramètre de la méthode) et le renvoit.

    J'ai été obligé de faire comme ça (ça y est, les détails me reviennent, j'suis pas si vieux que ca finalement !!!) car mes objets forment une hiérarchie. C'est un arbre en fait (dans un objet, j'ai un pointeur vers un objet père et un tableau de pointeurs vers des objets fils).
    Or les Archiver et UnArchiver archivent ton objet et tous ceux liés à  ton objet => donc quand tu fais un encodeWithCoder de ton objet, il archive tout ton arbre !!!!!

    Bref, pour cette raison et pour d'autres (ce fameux identifieur va me servir pour plein d'autres trucs !) j'ai opté pour la solution sus citée.



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