Drag & drop entre 2 NSTableView
UniX
Membre
Salut.
Bon, j'ai un drag & drop qui fonctionne entre 2 NSTableView.
Le problème, c'est que l'opération duplique l'entité déplacée dans la 2ème NSTableView. C'est à dire que si je modifie l'élément de ma NSTableView de départ, ce changement n'est pas reflété dans la seconde, vu que les 2 éléments ne sont pas identiques, c'est une copie.
Moi, je voudrais que lors du drag & drop, ce ne soit pas une copie mais l'élément de départ qui soit inséré dans la NSTableView d'arrivée ....
Voilà mon code pour le drag & drop :
Bon, j'ai un drag & drop qui fonctionne entre 2 NSTableView.
Le problème, c'est que l'opération duplique l'entité déplacée dans la 2ème NSTableView. C'est à dire que si je modifie l'élément de ma NSTableView de départ, ce changement n'est pas reflété dans la seconde, vu que les 2 éléments ne sont pas identiques, c'est une copie.
Moi, je voudrais que lors du drag & drop, ce ne soit pas une copie mais l'élément de départ qui soit inséré dans la NSTableView d'arrivée ....
Voilà mon code pour le drag & drop :
- (BOOL)tableView:(NSTableView *)tv writeRows:(NSArray*)rows toPasteboard:(NSPasteboard*)pb<br />{<br /> NSMutableArray *lignesTableau = [NSMutableArray array];<br /> NSData *lignesData;<br /><br /> // remplissage du tableau lignesTableau<br /><br /> lignesData = [NSKeyedArchiver archivedDataWithRootObject:lignesTableau];<br /> [pb declareTypes:[NSArray arrayWithObjects:@"drag", nil] owner:self];<br /> return [pb setData:lignesData forType:@"drag"];<br />}<br /><br />- (NSDragOperation)tableView: (NSTableView *)aTableView validateDrop:(id <NSDraggingInfo>)item proposedRow:(int)row proposedDropOperation:(NSTableViewDropOperation)op<br /> { <br /> [listeTable setDropRow:row dropOperation:NSTableViewDropOn];<br /> return NSDragOperationMove;<br /> }<br /><br /> - (BOOL)tableView:(NSTableView*)aTableView acceptDrop:(id <NSDraggingInfo>)item row:(int)row dropOperation:(NSTableViewDropOperation)op<br /> {<br /> NSPasteboard *pboard = [item draggingPasteboard];<br /> <br /> if ([pboard availableTypeFromArray:[NSArray arrayWithObject: @"drag"]])<br /> {<br /> NSData *lignesData = [pboard dataForType:@"drag"];<br /> NSMutableArray *lignes = [NSKeyedUnarchiver unarchiveObjectWithData:lignesData];<br /> <br /> // ajout des objets dans mon tableau d'arrivée<br /> }<br /> return YES;<br /> }
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
Il y a un moyen, sans affirmer que c'est la meilleure solution bien sûr : si les objets que tu mets dans ton array sont des dictionarys, ou des objets d'une classe modèle, tu rajoutes lors de la création de tes objets une key (en cas de dictionary) ou une variable d'instance (en cas de classe modèle) du genre "ObjectUniqueID". A cet "ObjectUniqueID" tu te débrouilles bien sûr pour affecter des chaines uniques afin de pouvoir différencier les objets.
Ensuite, quand tu fais une modif dans une table, il faut aller comparer l'"ObjectUniqueID" de l'objet modifié aux "ObjectUniqueID" de l'autre table, et répercuter les changements en conséquence.
Par contre, avec cette méthode, il faut veiller à ne pas D&Dropper plusieurs fois le même objet car il y aura à ce moment des problèmes de doublon dans les "ObjectUniqueID". Donc soit tu interdis le drop si l'objet est déjà présent, soit tu lui affectes un nouvel "ObjectUniqueID".
En dernier lieu, je ne te cache pas qu'une fois ceci fini tu risques d'avoir très soif, mais c'est un autre problème... :P
Je trouve bizarre qu'il n'y ai rien de prévu de base dans Cocoa pour faire ça ..... Rien n'est parfait ....
Si tu penses en terme de MVC, tes données manipulées sont dans le modèle, accessibles par tout le monde. Et ensuite tu demandes à accéder à ces données via les accesseurs pour les manipuler (Controller) et les afficher (Vue).
Ce n'est donc pas l'objet qu'il faut archiver, mais l'identifiant qui te sert à ... l'identifier.
Tu as sûrement si tu as un bon MVC un moyen propre de récupérer le bon objet : index dans un tableau, clé unique... pour appeler ton accesseur myObjectWithName: ou un truc dans le genre en lui passant un nom unique, non ? ou myObjectAtIndex: ou dans ce goût là .
C'est ce que tu utilises pour identifier/récupérer ton objet qu'il faut que tu mettes dans le pasteBoard à mon avis, qui est la référence/identifiant unique.
Si tu n'avais pas cette clé unique et que tu l'as créée pour l'occasion comme tu sembles le dire, c'est que c'est pas plus mal parce que c'est toujours bon d'avoir de quoi identifier les objets de façon unique... et ça aurait sans doute dû être le cas dès le début si tu avais fait un modèle comme il faut (mais bon le prend pas mal on peut pas penser à tout et souvent chze moi aussi la clé unique elle passe à la trappe )
Tout ça pour dire que c'est prévu dans Cocoa dans le sens où Cocoa part de la base que tu as un beau schéma MVC avec un identifiant unique... et que cette solution vient du coup naturellement à l'esprit.... enfin quand on suit la logique Cocoa
Mon modèle MVC est fait (je pense ...) correctement. J'ai donc repris mon code, et au lieu d'archiver les données elles-mêmes, j'archive la référence du tableau de départ, ainsi que les numéros de lignes des éléments, tout ça dans un NSDictionary.
Et à l'arrivée, je n'ai plus qu'à faire des copies à partir des informations contenues dans le NSDictionary.
Merci pour cet éclaircissement bienvenu ...!
Allez !
Je me repenche sur mon appli après quelques mois d'abandon ???
J'essaie de reprendre les diverses docs sur le Drag & Drop entre 2 NSTableView mais ça ne fonctionne pas, pourtant j'ai repris la doc Apple :
J'ai entendu parler du codage des données avant le drop mais qu'en est-il vraiment ?
A ce propos ça Drag bien mais ça ne Drop rien du tout
Ce code est incomplet... D'un côté tu enregistres dans le presse-papier l'index des lignes sélectionnées du tableau d'origine, de l'autre côté, tu récupères la première ligne de cet index mais tu n'en fais rien ("// Move the specified row to its new location...").
En plus, s'il y a plusieurs tables permettant le drag, il faudrait aussi enregistrer quelque-chose permettant de retrouver la table d'origine, non ?
Je continue...
C'est le meilleur moyen de voir où ça clocheÂ
(Enfin pas tout en même temps sinon ça n'ira pas... D'abord un breakpoint dans la fonction de drag et ensuite un autre sur la fonction de drop...)
On peut débuguer avec des NSLog quand on maà®trise mal gdb
Mets en un peu partout, et regarde ce que ça donne...
[tt]*** -[NSCFArray objectAtIndex:]: index (5) beyond bounds (1)[/tt]
A l'inverse il y a bien une ligne insérée mais le contenu n'est qu'une ligne recopiée du tableau cible correspondant à la même position sur le tableau source.
Il n'y a pas de copie d'un tableau à l'autre mais bien une copie du tableau sur lui-même...
Je suis preneur de toute proposition pour en finir avec ce Drag & Drop...