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

6ix

Membre junior
12 Juillet 2005
28
0
36
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électionnées en rouge.
Pour cela, mon idée est la suivante: l'utilisateur clique sur l'item, qui a pour action colorier: ; récupérer les lignes sélectionnées, puis faire un [aCell setTextColor: "ma couleur"] sur ces cellules. Mon problème: comment récupérer les lignes sélectionnées? Je ne vois pas comment faire avec les méthodes de tableview... Une autre solution serait de ne récupérer que la ligne sur laquelle le menu contextuel est appelé; mais même problème, comment récupérer cette ligne?

2) J'ai une méthode qui me permet d'effacer plusieurs éléments de mon tableau, prenant en compte la sélection multiple, implémentée de la sorte:
Bloc de code:
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 à supprimer
		}
Apparemment, selectedRowEnumerator est deprecated et il faudrait employer [maTable selectedRowIndexes]; mais le mécanisme me semble bien différent, et je ne vois pas trop comment employer cette méthode pour regrouper dans toRemoveArray (NSMutableArray) les objets des différentes lignes sélectionnées... Une idée?

Merci pour votre aide
 

mpergand

Membre confirmé
10 Novembre 2003
220
18
Salut,

petit exemple:
Bloc de code:
#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:
 

mpergand

Membre confirmé
10 Novembre 2003
220
18
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é :mad:

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:
Bloc de code:
- (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:

Bloc de code:
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

Membre junior
12 Juillet 2005
28
0
36
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!