# NSTableView, dataSource et NSTabView



## thomzz (20 Mars 2003)

Salut à tous,

J'ai quelque problèmes avec les sources de données des tables. 
J'aimerai faire une application qui, quand on clique sur un bouton, ajoute un NSTabItem dans un NSTabView avec, à l'intérieur, une nouvelle table. Le pb c'est que n'arrive pas à "connecter" une source de données cette table (que doit être la source de données ?).

Si quelqu'un peut m'aider.

Merci


----------



## Luc G (20 Mars 2003)

J'ai juste commencé à plonger dans le même sujet. Tu peux trouver des choses très intéressantes sur le projet omega et o'reilly, en particulier  ici 

Regarde en particulier les tutoriels sur les préférences et sur le carnet d'adresses : ça m'a permis de comprendre un minimum la gestion tablewiew/datasource.

Télécharge les pdf et les projets, teste et modifie. J'ai une ou deux autres références, mais pas ici. Je t'en ferais part plus tard.

Je commence juste, donc je préfère te donner des références que te faire part de mes avis qui sont très peu informés  
	

	
	
		
		

		
			





.


PS. Si tu sais te débrouiller avec les tables et que ton pb, c'est uniquement les tables dans les tables, là c'est plutôt moi qui aurais besoin de ton aide


----------



## thomzz (20 Mars 2003)

Merci 
	

	
	
		
		

		
		
	


	




En fait, c'est à partir de ça que je suis parti mais j'ai pas tout compris?


----------



## Luc G (20 Mars 2003)

Moi, non plus  
	

	
	
		
		

		
		
	


	



Mais, hier, j'ai eu enfin l'occasion de passer 2 heures dessus et j'ai pu me créer 2 tables avec les datasource (NSarray) qui apparemment semblent prêtes à se mettre à jour quand il faut (c'était ça mon premier problème : je n'avais pas bien pigé le object..; et le setobject...). Il me reste à rajouter 2-3 trucs (dont le reload) pour vérifier que ça marche, même si c'est pas malin, c'est à dire que les modifs par l'utilisateur dans une des tables sont prises en compte et peuvent éventuellement entraîne des modifs dans l'autre.

(Pas encore à travers des delegate ou des notifications, ça on verra après).


----------



## Manu (20 Mars 2003)

Pour bien comprendre  la relation NSTableViexw et  les data sources il faut se souvenir de ceci :

Une TableView a besoin d'une source de données pour retrouver ces objets.

Cette source de données doit  implémenter au moins 3 methodes du protocole NSTableDtaSource. Ces methodes sont appelées automatiquement par la NStableView qu'elle alimente pour :
- Retrouver un élément de ligne i et de colonne j
- de le modifier
- de savoir combien  la source contient d'éléments.

Voyer en détail ces méthodes ici :
http://developer.apple.com/techpubs/macosx/Cocoa/Reference/ApplicationKit/ObjC_classic/Protocols/NSTableDataSource.html#BCICFCDE

La data source on peut la définir de plusieurs façons. ça peut être un fichier, une table, etc. L'essentiel c'est qu'on puisse implémenter les méthodes que j'ai décrit.
En général (pour des raisons de commodité), on fait tout pour avoir une data source qui soit une NSMutableDictionnary ou NSDictionnary car les méthodes du protocoles y sont quasiment implémentées.
N'oubliez pas que l'on peut ajouter à la data source d'autres méthodes. Par exemple le tri par une colonne, la suppression, d'une ligne, etc. Ne pas oublier qu'en fait le reload de la NStableView a pour conséquence d'appeler la méthode de recherche d'une ligne autant de fois que la data source a d'elements.

J'espère que cela vous eclairera.

Il y a un exemple ici :

http://developer.apple.com/techpubs/macosx/Cocoa/TasksAndConcepts/ProgrammingTopics/TableView/Tasks/UsingTableDataSource.html#//apple_ref/doc/uid/20000117


----------



## Luc G (20 Mars 2003)

Effectivement, les dictionnaires ont l'air très propres pour plein de choses. Mais je commence avec des NSarray pour y aller progressivement et éviter de m'embrouiller entre la compréhension de la liaison tableview/datasource et celle des dictionnaires. Dès que j'ai au moins un schéma avec les array qui me convient, je passe aux dictionnaires.

Là, il faudra que je vois à quel endroit placer des messages de recalcul lorsque les données sont modifées pour qu'ils soient le plus efficaces possible : dans le setObject ? avec un delegate ou une notification spécifique ? ailleurs ?

(typiquement, dans les trucs que je veux faire, la modification d'une cellule de la table par l'utilisateur impose de recalculer le contenu de cellules d'autres tables).


----------



## thomzz (21 Mars 2003)

Et comment on fait pour que les datasource ne soit pas le Controller ?
Car en suivant le tutoriel O'Reilly/ProjectOmega, dans Interface Builder on relie tableView à l'outlet du Controller.


----------



## Manu (21 Mars 2003)

Il ne faut pas confondre Controller et data source. Généralement quand on a une interface graphique, on l'associe à un Controller. En effet les objets de l'interface sont décrits dans le controller sous forme d'outlets ainsi que les actions executées par une target (un bouton par exemple).
une data source est un objet associé à une tableview. c'est elle qui l'allimente. Quand tu demandes à une tableview de faire reload par exemple, Ta tableview appelle la méthode tableviewbjectValueForTableColumn:row: de sa data source autant de fois que sa data source a d'éléments. Ce nombre d"éléments est fourni par une autre méthode de sa data source qui est numberOfRowsInTableView:

exemple de data source

@interface UNEDataSource : NSObject &lt;NSTableDataSource&gt;
{
   id *tableau[100][100];
   int taille = 0;
}
- (id)tableViewNSTableView *)aTableView    objectValueForTableColumnNSTableColumn *)aTableColumn    rowint)rowIndex

- (void)tableViewNSTableView *)aTableView    setObjectValue:anObject    forTableColumnNSTableColumn *)aTableColumn    rowint)rowIndex

- int)numberOfRowsInTableViewNSTableView *)aTableView
@end

l'implémentation serait :

- int)numberOfRowsInTableViewNSTableView *)aTableView
{
   return taille;
}

- (id)tableViewNSTableView *)aTableView    objectValueForTableColumnNSTableColumn *)aTableColumn    rowint)rowIndex
{
   int i,j;
   if ([[aTableColumn identifier] stringValue] == "Nom") then j = 2
else j = 1;
    return Tableau[rowIndex][j];
}

etc.....

Dans  le controller de la tableview si vous avez appelé par myTableView son outlet, et par laDataSource sa datasource (déclarée par UNEDataSource *ladataSource)
l'association est faite par :

[myTbleView setDataSource:laDataSource];

Par contre si vous avez un bouton qui permet de calculer par exemple le total d'une colonne, vous pouver ajouter dans la data source la méthode SommeColumn: qui le fait. Par contre dans le controller vous faites :

[laDatasource SommeColumn:j];


----------



## thomzz (25 Mars 2003)

OK, merci. Je pense que je vais pouvoir me débrouiller maintenant !


----------

