Drag & Drop, gros problème.

tabliertablier Membre
février 2011 modifié dans API AppKit #1
Je souhaite faire des glisser-déposer sur une fenêtre pour récupérer les noms des fichiers déposés sur la fenêtre.
Je met le "delegate de la fenêtre sur un contrôleur et J'enregistre la fenêtre dans awakeFromNib:
  [o_fenetre registerForDraggedTypes:[NSArray arrayWithObject:NSFilenamesPboardType]] ;
puis, comme dans le précise la documentation j'ai:
- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
{ return (NSDragOperationEvery) ;  }

- (BOOL)prepareForDragOperation:(id <NSDraggingInfo>)sender
{ return (!encours)  ;  }

- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
{
NSPasteboard *pboard = [sender draggingPasteboard];
if ( pboard types] containsObject:NSFilenamesPboardType] )<br /> {<br /> NSArray *files = [pboard propertyListForType:NSFilenamesPboardType];<br /> if ([files count] &gt; 0)<br /> {&nbsp; [litem setString: [NSString stringWithString:[files objectAtIndex:0] ;
return [litem length] != 0 ;  } ;
} ;
return NO ;
}

- (void)concludeDragOperation:(id <NSDraggingInfo>)sender
{
[self  faireLeBoulot:litem] ; // paramètres de travail
}
Mon problème: Je veux pouvoir glisser-déposer soit des fichiers de type texte soit des applications. Les textes sont utilisés comme données, mais les applications sont lancées par un NSTask.  Le glisser-déposer des textes ne pose aucun problème! Par contre si je dépose une application, elle s'exécute correctement, je récupère les données en retour, puis, juste après j'obtiens systématiquement l'erreur:
Canceling drag because exception 'NSInvalidArgumentException' (reason '*** -[NSCFArray insertObject:atIndex:]: attempt to insert nil') was raised during a dragging session
et mon application s'arrête.  Pour vérifier, j'ai supprimé le NSTask et je ne fais qu'afficher le nom de l'appli. Dans ce cas plus d'erreur!
J'en conclus que le "drag & drop" est interrompu par l'exécution du NSTask, ce qui le plante.
Je ne sais pas comment m'en sortir sur ce coup!

Qui aurait une idée?

Réponses

  • AliGatorAliGator Membre, Modérateur
    14:40 modifié #2
    Une solution un peu crade mais qui devrait marcher : utiliser performSelector:withObject:afterDelay: pour lancer ta méthode qui appelle la NSTask un tout petit poil après ? (un délai de 0.1 suffit amplement mais permettra au moins d'exécuter le code juste à  la prochaine RunLoop et laisser le temps au drag de se terminer)
  • tabliertablier Membre
    14:40 modifié #3
    J'avais pensé à  utiliser un timer. Mais je vais utiliser ta solution qui, je pense, doit utiliser un timer sans le dire.

    Pour info, l'application lancée est un AppleScript compilé qui ouvre un nouveau message dans mail, le tout sous un environnement qui fait fonctionner le "Apple Event Logging". Je sais, pas très simple, beaucoup de chose à  la fois!
    D'autre part je lance le NSTask en mode "waitUntilExit". Je me demande si ce n'est pas ça qui me plante le drag&drop.
  • AliGatorAliGator Membre, Modérateur
    14:40 modifié #4
    dans 1297849136:

    J'avais pensé à  utiliser un timer. Mais je vais utiliser ta solution qui, je pense, doit utiliser un timer sans le dire.
    Je confirme, c'est ce que ça fait. Pour être plus précis, cela crée sous le capot un NSTimer, prépare une NSInvocation, et quand le timer se déclenche, appelle la NSInvocation. Donc ça revient strictement au même mais en moins de lignes puisque c'est lui qui fait tout le reste

    dans 1297849136:

    D'autre part je lance le NSTask en mode "waitUntilExit". Je me demande si ce n'est pas ça qui me plante le drag&drop.
    Y'a de fortes chances
  • laudemalaudema Membre
    14:40 modifié #5
    dans 1297849136:

    D'autre part je lance le NSTask en mode "waitUntilExit". Je me demande si ce n'est pas ça qui me plante le drag&drop.

    Il y a aussi les NSOperation et NSOperationQueue qui permettent d'attendre la fin du process lancé NSOperation waitUntilFinished
    ça ne te fera certainement pas moins de code mais ça s'intégrera peut être mieux au niveau de la "RunLoop" ?
  • tabliertablier Membre
    14:40 modifié #6
      :P  J'ai trouvé:  Le drag&drop s'imbriquait avec le NSTask. Mais, dans le traitement du NSTask, j'ai une conversion data->Cstring->NSString avec un mauvais encodage (resultat:nil).  Donc l'erreur interrompait le NSTask et le drag&drop en cours de route! d'ou l'erreur:
    Canceling drag because exception 'NSInvalidArgumentException' (reason '*** -[NSCFArray insertObject:atIndex:]: attempt to insert nil') was raised during a dragging session
    C'est le fait de décaler le NSTask qui m'a permis de trouver la véritable erreur! Par contre, le "AppleEvent Logging" qui ne renvoie pas de l'utf8 mais du MacOsRoman, c'est à  savoir!
Connectez-vous ou Inscrivez-vous pour répondre.