Interdiction de sélection dans une NSTableView dans un certain contexte

Eddy58Eddy58 Membre
18:52 modifié dans API AppKit #1
J'ai besoin de vérifier la modification dans une NSTableView, pour un type de colonne (des cells avec des textfields éditables), si la donnée rentrée n'est pas identique a une donnée déjà  rentrée dans la base de donnée. Pour cela pas de problème...:)
Le problème vient du fait, qu'à  partir du moment ou on appuie sur la touche return pour valider la modification dans la cell, la sélection passe a la row suivante. Pas de problème si l'entrée vérifiée est valide c'est le fonctionnement voulu, par contre si l'entrée est invalidée, je voudrais que la sélection reste sur la row adéquate, afin que l'utilisateur puisse rentrer autre chose. J'ai essayé pleins de trucs avec les notifications et les delegates pour bloquer le changement de sélection, mais ca marche pas terrible, apparemment le changement de sélection se fait avant l'appel de la méthode delegate pour récupérer les valeurs modifiées....donc c'est plutot genant, car la row du dessous se sélectionne alors qu'il ne faut pas...:-\\
Voici un extrait du code :

<br />-(void)tableView:(NSTableView *)tableView setObjectValue:(id)object forTableColumn:(NSTableColumn *)tableColumn row:(int)row<br />{<br />	ClientMaintenance *client;<br />&nbsp; &nbsp; &nbsp;  int a;<br /><br />	client=[clientsMaintenancesArray objectAtIndex:row];<br />	<br />       //...//<br /><br />	if ([[tableColumn identifier] isEqualToString:@&quot;noms&quot;])<br />	{<br />		for (a=0;a&lt;[clientsMaintenancesArray count];a++)			{<br />			if ([[[clientsMaintenancesArray objectAtIndex:a] nom] isEqualToString:object] &amp;&amp; [[[clientsMaintenancesArray objectAtIndex:a] service] isEqualToString:[client service]])<br />			{<br />				typeAlertSheet=2;<br />				if ([[client service] isEqualToString:@&quot;MAI&quot;])<br />				{<br />					NSBeginAlertSheet(@&quot;Nom déjà  utilisé&quot;,@&quot;OK&quot;,nil,nil,fenetreAXEZ,self,@selector(didEndShouldCloseSheet:returnCode:contextInfo:),NULL,fenetreAXEZ,@&quot;Ce nom est déjà  utilisé pour le service Maintenances.&#092;nVeuillez en choisir un autre.&quot;,nil);<br />				}<br />				if ([[client service] isEqualToString:@&quot;TEL&quot;])<br />				{<br />					NSBeginAlertSheet(@&quot;Nom déjà  utilisé&quot;,@&quot;OK&quot;,nil,nil,fenetreAXEZ,self,@selector(didEndShouldCloseSheet:returnCode:contextInfo:),NULL,fenetreAXEZ,@&quot;Ce nom est déjà  utilisé pour le service Télésauvegarde.&#092;nVeuillez en choisir un autre.&quot;,nil);<br />				}<br />				//[clientsMaintenancesTableView selectRowIndexes:[NSIndexSet indexSetWithIndex:[clientsMaintenancesTableView selectedRow]-1] byExtendingSelection:NO];<br />				return;<br />			}<br />		}<br />		[self synchronisationPrelevements:[tableColumn identifier] nom:[client nom] objet:object montantHT:0 service:[client service]];<br />		[client setNom:object];<br />	}<br /><br />       //...//<br />	<br />	[NSArchiver archiveRootObject:clientsMaintenancesArray toFile:clientsMaintenancesFichier];<br />}<br />

Réponses

  • BruBru Membre
    décembre 2004 modifié #2
    Le delegate de NSControl
    - (BOOL)control:(NSControl *)control textShouldEndEditing:(NSText *)fieldEditor
    est parfait pour ça, je pense.

    C'est un delegate attaché à  la tableView et qui doit être appelé en fin d'édition d'une cellule éditable. En returnant NO, ce delegate empêche de quitter le saisie de la cellule.

    .
  • décembre 2004 modifié #3
    Et une oraison funèbre pour Eddy, et une! (je crois qu'on l'a eu là )
    Pour les autres: private joke....
  • Eddy58Eddy58 Membre
    décembre 2004 modifié #4
    Non, vous m'aurez pas aussi facilement, Mc Ducf et Jack l'éventreur :P, je suis pas un newbie quand même ;), et je me passe volontiers de cet horrible air de cornemuse joué par un canard écossais sadique, qui ne doit être agréable à  entendre qu'avec des boule Quies, et encore je suis gentil ! ;D

    Bru, en effet ce type de méthodes delegate est efficace si le texte est en cours d'édition, et j'ai tenté pleins de trucs avec ces méthodes sans succés. Et en cours d'édition, cela signifie qu'une modification, ajout ou suppression de caractère dans le textfield ait eu lieue. Je veux dire par là , que quand on double-clique sur le textfield après la sélection de la row, le texte qu'il comporte commence d'abord par se mettre sur fond bleu, donc se sélectionne entièrement. Ensuite, en recliquant une fois dans le textfield, on place le point d'insertion ou on veut. Et à  partir de la, si on ajoute ou efface un caractère, on passe en mode édition, et les delegates associés deviennent pleinement exploitables...
    Le problème que je rencontrais était aussi dans le cas ou on est pas en mode d'édition, et finalement je me dis, si le texte n'est pas édité, alors pas besoin de lancer les diverses routines qui suivent une modif. Je commence donc par détecter l'édition avec une notification NSControlTextDidChangeNotification (une ligne à  rajouter dans cette notification dont je me sers déjà  pour brider le nombre de caractères dans les textfields), puis en fonction modification d'un flag, pour autoriser ou pas le changement de sélection avec le delegate approprié...et le tout fonctionne très bien.... :kicking: <3 :adios!:<br />
    <br />       //...//<br /><br />	if ([[tableColumn identifier] isEqualToString:@&quot;noms&quot;] &amp;&amp; nomTextFieldEdit==YES) // Rajout de la condition d&#39;édition du textfield dans le datasource<br />	{<br />      //...//<br />	  nomTextFieldEdit=NO; // Remettre le flag sur NO une fois que le boulot est fait<br />    }<br />	<br />	//...//<br /><br />// Méthode appelée lors d&#39;un changement de sélection, mode édition ou pas<br />// Si le mode édition est en cours, on sort de celui-ci automatiquement<br />-(BOOL)selectionShouldChangeInTableView:(NSTableView *)tableView<br />{<br />	if (nomTextFieldEdit==YES) // Si édition en cours alors<br />	{                                        <br />		return NO;             // Empecher le changement de sélection<br />	}<br />	else                       // Sinon<br />	{<br />		return YES;            // Autoriser le changement de sélection<br />	}<br />}<br /><br />-(void)maintenancesTableViewModif:(NSNotification *)notification<br />{<br />	NSCell *textfieldCell;<br />	<br />	nomTextFieldEdit=YES; // Edition en cours : mettre le flag sur YES<br />	if ([clientsMaintenancesTableView editedColumn]==1)<br />	{<br />		textfieldCell=[clientsMaintenancesTableView selectedCell];<br />		if ([[textfieldCell stringValue] length]&gt;24)<br />		{<br />			[textfieldCell setStringValue:[[textfieldCell stringValue] substringToIndex:24]];<br />		}<br />	}<br />}<br /><br />
    
  • 18:52 modifié #5
    Tu as donc réussi?

    ça se fête en musique ça!
  • Eddy58Eddy58 Membre
    18:52 modifié #6
    dans 1102769486:

    Tu as donc réussi?

    ça se fête en musique ça!

    Oui Sir Mc Ducf ! :)
    Fêtons cela en "musique" ;) :kicking: et trinquons à  la santé des Cocoaculteurs !
    :p
Connectez-vous ou Inscrivez-vous pour répondre.