# Tableview: 1) couleur, 2) sélection multiple



## 6ix (3 Novembre 2005)

Bonjour tt le monde,

1) J'ai fait un petit menu contextuel sur une tableview, avec un menuitem "colorier" qui a pour but de mettre le texte des lignes s&#233;lectionn&#233;es en rouge.
Pour cela, mon id&#233;e est la suivante: l'utilisateur clique sur l'item, qui a pour action colorier: ; r&#233;cup&#233;rer les lignes s&#233;lectionn&#233;es, puis faire un [aCell setTextColor: "ma couleur"] sur ces cellules. Mon probl&#232;me: comment r&#233;cup&#233;rer les lignes s&#233;lectionn&#233;es? Je ne vois pas comment faire avec les m&#233;thodes de tableview... Une autre solution serait de ne r&#233;cup&#233;rer que la ligne sur laquelle le menu contextuel est appel&#233;; mais m&#234;me probl&#232;me, comment r&#233;cup&#233;rer cette ligne?

2) J'ai une m&#233;thode qui me permet d'effacer plusieurs &#233;l&#233;ments de mon tableau, prenant en compte la s&#233;lection multiple, impl&#233;ment&#233;e de la sorte:

```
if([maTable selectedRow] != -1) {
		NSEnumerator *enumerator = [maTable selectedRowEnumerator];   // **
		NSNumber *index;
		NSMutableArray *toRemoveArray = [NSMutableArray array];
		id currentArticle;
		while ((index = [enumerator nextObject])) {
			currentArticle = [[_articles articles] objectAtIndex:[index intValue]];
			[toRemoveArray addObject:currentArticle]; // garde trace dans toRemoveArray de l'enregistrement &#224; supprimer
		}
```
Apparemment, selectedRowEnumerator est deprecated et il faudrait employer [maTable selectedRowIndexes]; mais le m&#233;canisme me semble bien diff&#233;rent, et je ne vois pas trop comment employer cette m&#233;thode pour regrouper dans toRemoveArray (NSMutableArray) les objets des diff&#233;rentes lignes s&#233;lectionn&#233;es... Une id&#233;e?

Merci pour votre aide


----------



## mpergand (4 Novembre 2005)

Salut,

petit exemple:

```
#import "Controller.h"

@implementation Controller


-(void) awakeFromNib
{
	dataArray=[[NSMutableArray alloc] init];
	
	[dataArray addObject:	[NSMutableDictionary  
			dictionaryWithObjects:[NSArray arrayWithObjects:@"1",@"Ligne 1",[NSColor blackColor],nil]
			 forKeys:[NSArray arrayWithObjects:@"no",@"texte",@"couleur",nil]]];
	[dataArray addObject:	[NSMutableDictionary  
			dictionaryWithObjects:[NSArray arrayWithObjects:@"2",@"Ligne 2",[NSColor blackColor],nil]
			 forKeys:[NSArray arrayWithObjects:@"no",@"texte",@"couleur",nil]]];
	[dataArray addObject:	[NSMutableDictionary  
			dictionaryWithObjects:[NSArray arrayWithObjects:@"3",@"Ligne 3",[NSColor blackColor],nil]
			forKeys:[NSArray arrayWithObjects:@"no",@"texte",@"couleur",nil]]];									  
}

// actions menu contextuel 
- (IBAction)menuAction:(id)sender
{
	//NSLog(@" menu action %@",sender);
	
	int selectedRow=[tableView selectedRow];
	
	if(selectedRow!=-1)
		{
		NSMutableDictionary* data=[dataArray objectAtIndex:selectedRow];
		
		if([sender tag]==100)	// bleu
			[data setObject:[NSColor blueColor] forKey:@"couleur"];
		if([sender tag]==101)	// bleu
			[data setObject:[NSColor redColor] forKey:@"couleur"];
		if([sender tag]==102)	// bleu
			[data setObject:[NSColor blackColor] forKey:@"couleur"];
			
		[tableView setNeedsDisplay:YES];
			
		}
	
}

#pragma mark Delegate tableview

- (void)tableView:(NSTableView *)aTableView willDisplayCell:(id)aCell forTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex
{
	NSDictionary* data=[dataArray objectAtIndex:rowIndex];
	[aCell setTextColor:[data objectForKey:@"couleur"]];

}

#pragma mark Data source


- (int)numberOfRowsInTableView:(NSTableView *)aTableView
{
	return [dataArray count];
}


- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex
{
	return [[dataArray objectAtIndex:rowIndex]objectForKey:[aTableColumn identifier]];
}


@end
```

Ca donne:


----------



## 6ix (4 Novembre 2005)

Merci beaucoup! C'est exactement ce qu'il me faut, je vais voir ça!


----------



## 6ix (5 Novembre 2005)

Tout marche bien pour le 1), merci pour le code.

Quelqu'un aurait-il tout de même une piste pour le 2) ?


----------



## mpergand (5 Novembre 2005)

Alors, au sujet de NSIndexSet, moi non plus que connais pas trop et tout comme toi, j'aimerais bien qu'il y ait un chti exemple de code dans la doc Apple hein ? juste pour nous montrer comment ça fonctionne, histoire de ne pas trop perdre son temps à tester les méthodes au hasard !!!! Mais non, y a rien, nada, car n'oublie pas qu'Apple a toujours fait la doc la plus nulle du monde, généralement mal écrite, incomplète et très proche du bazar organisé  

Pour en revenir au sujet, la méthode la plus simple doit être un truc de ce genre:
http://www.cocoabuilder.com/archive/message/cocoa/2005/10/3/147412 (pas testé)

sinon j'ai fait un truc un peu différent:

```
- (IBAction)menuAction:(id)sender
{
	NSIndexSet* selectedRowIndex=[tableView selectedRowIndexes];
	unsigned int count=[selectedRowIndex count];	// nombre d'index
	unsigned int indexBuffer[count];		// allocation tableau des index
	NSRange range=NSMakeRange(0,[tableView numberOfRows]);
	unsigned int numberOfIndexes =[selectedRowIndex getIndexes:indexBuffer 
							maxCount: count
							inIndexRange:&range];
		
	unsigned int i;
	
	for(i=0;i<numberOfIndexes;i++)
		{
		unsigned int index=indexBuffer[i];
		printf("index %d\n",index);
		NSMutableDictionary* data=[dataArray objectAtIndex:index];
		if([sender tag]==100)	// bleu
			[data setObject:[NSColor blueColor] forKey:@"couleur"];
		if([sender tag]==101)	// rouge
			[data setObject:[NSColor redColor] forKey:@"couleur"];
		if([sender tag]==102)	//noir
			[data setObject:[NSColor blackColor] forKey:@"couleur"];
		}
			
		
		
	[tableView setNeedsDisplay:YES];
			
		
	
}
```

Ce n'est pas idéal, car ma méthode crée un buffer unique pour tous les index de la table(comme l'ancienne méthode en fait). Imagine une table avec plusieurs milliers de lignes et si elle sont toutes séléctionnées, il faut créer un buffer énorme, c'est pas trés efficace, ça peut même faire planter l'appli, si comme dans mon code , ce buffer est alloué dans la pile !
Il vaut mieux donc, procéder par intervalle, par ex:


```
unsigned int indexBuffer[10];				// allocation  pour 10 index
NSRange range=NSMakeRange(0,10);
unsigned int numberOfIndexes =[selectedRowIndex getIndexes:indexBuffer 
							maxCount:10 inIndexRange:&range];
```
puis modifier range par palier de 10 (0,10),(10,10),(20,10) ...
jusqu'a la fin de la table.

voili voilà


----------



## 6ix (6 Novembre 2005)

Merci.

Finalement, en cherchant encore et encore, j'ai vu que plusieurs personnes disaient carrément de garder la 1e méthode citée, bien que deprecated, car bcp plus adaptée (en plus du fait que cette nlle méthode ne marche pas avant la 10.3). Alors bon, je garde cette nouvelle façon de faire en commentaires, jusqu'à ce que cette méthode deprecated disparaisse complètement.

Concernant la doc Apple, effectivement... L'impression que j'ai, c'est de voir moult méthodes qui paraissent intéressantes, et de ne pas savoir quoi en faire. Résultat, go sur les tutos, mais cela reste souvent des choses simples; et vu que je suis relativement nouveau dans cocoa et que je ne fais pas encore certains liens entre les différentes choses, bonjour les forums... qui aident énormément!


----------

