# [NSOpenPanel]PB de récuperation du nom du fichier



## kollyv (24 Avril 2007)

Salut,

Depuis une action sur un bouton j'ouvre un NSOpenPanel afin de récupérer un fichier.
Je décclare une variable global dans mon .h 
@interface Ihm : NSObject

{
    NSString * filename;
}
- (IBAction)openFileid)sender;
- (IBAction)startUploadid)sender;
@end

et je l'affecte depuis l'action openFile:

NSArray* files = [oPanel filenames];
fileName =(NSString *) [files objectAtIndex:0];

Dans startUpload j'aimerais récupérer le string. Mais la impossible. Le debuggueur me note invalide dans la partie summery. Si je fais le test avec une url j'obtien "out of scope".

Si je set filename de cette facon (en du) filneame = @"/chemin du fichier";
La ca fonctionne 

qqu peut il m'aider


----------



## Céroce (24 Avril 2007)

L'Open Panel n'est pas "modal", il ne bloque pas le d&#233;roulement de l'appli. C'est &#224; dire que quand tu fais l'appel &#224; la m&#233;thode

beginForDirectory:file:types:modelessDelegate:didEndSelector:contextInfo:

ta m&#233;thode d'action continue &#224; se d&#233;rouler, et forc&#233;ment, l'utilisateur n'a pas encore choisi de fichier. Il est n&#233;cessaire de mettre une m&#233;thode en face du param&#232;tre didEndSelector: qui sera appel&#233;e quand le fichier sera s&#233;lectionn&#233;; l&#224; tu pourras savoir quel est le fichier s&#233;lectionn&#233;.

Ex d'appel:


```
[beginForDirectory:... 
file:... 
types:... 
modelessDelegate:.. 
didEndSelector:@selector(openPanelDidEnd:returnCode:contextInfo:) 
contextInfo:nil]
```


Et la m&#233;thode appel&#233;e doit &#234;tre de la forme:


```
openPanelDidEnd:(NSWindow*) sheet 
returnCode:(int) retCode
 contextInfo:(void*)contextInfo
```


La doc d'Apple est une r&#233;f&#233;rence; tous les d&#233;tails y sont, mais du coup elle est lourde et peu pratique. Ach&#232;te-toi un bon bouquin comme _Cocoa par la pratique_ qui met en valeur les &#233;l&#233;ments importants.


----------



## kollyv (25 Avril 2007)

Merci pour ta r&#233;ponse. J'ai donc utilis&#233; ce principe mais le probl&#232;me persiste. Voici le code au plus simple:


```
- (IBAction)openFile:(id)sender
{
    NSArray *fileTypes = [NSArray arrayWithObjects:@"hex", nil];
    NSString *path = [[[NSUserDefaults standardUserDefaults] stringForKey:@"JVChatTranscriptFolder"] stringByStandardizingPath];    
    oPanel = [[NSOpenPanel openPanel] retain];    
    [oPanel setCanChooseDirectories:NO];
    [oPanel setCanChooseFiles:YES];
    [oPanel setAllowsMultipleSelection:NO];
    [oPanel setResolvesAliases:YES];    
    [oPanel beginForDirectory:path file:nil types:fileTypes modelessDelegate:self didEndSelector:@selector( openDocumentPanelDidEnd:returnCode:contextInfo: ) contextInfo:NULL];
}
```


```
- (void) openDocumentPanelDidEnd:(NSOpenPanel *) panel returnCode:(int) returnCode contextInfo:(void *) contextInfo {
        [oPanel autorelease];         
        filename = [oPanel filename];    //tout va bien jusqu'ici: filename vaut bien le chemin du fichier selectionn&#233;      
}
```
Action suivante r&#233;cuperation du nom du fichier:

```
- (IBAction)startUpload:(id)sender{
    if ([ewoo ewooConnected]){    
        HexConverter * hexConv = [[HexConverter alloc] init]; 
        [ewoo startUpload:[hexConv formatFirmware:filename]]; //filename est invalide
    
    }else{
        NSRunAlertPanel( @"Error", @"Ewoo not connected", @"OK", nil, nil ); 
    }
    
}
```
filename est toujour not&#233; invalide.

Haaaa ca fait 1 jours et demi que je suis la dessus :rateau: 

Je vois pas ce qui ne joue pas...


----------



## ntx (25 Avril 2007)

Si on regarde l'exemple suivant, ta fonction openDocumentPanelDidEnd devrait récupérer filename sur panel et pas oPanel.


----------



## kollyv (25 Avril 2007)

Effectivement, mais ca n'arrange pas les choses. Ce que je ne comprend pas bien: quand je récupère le nom du fichier dans la méthode openDocumentPanelDidEnd, j'ai bel et bien mon string chargé du bon nom.

Je le met bien en variable global, mais impossible de le récupérer dans l'action suivante. Le debug me permet ben de voir que une fois le NSOpenPanel fermé c'est bien cette méthode qui est appellé.


----------



## ntx (25 Avril 2007)

Ca ne serait pas un probl&#232;me de gestion de la m&#233;moire : tu fais pointer ta globale sur une variable qui est d&#233;truite lors de la destruction du NSOpenPanel.
Au lieu d'une affectation d'adresse, fais une copie du contenu du tableau ou utilise un retain.


----------



## kollyv (25 Avril 2007)

Haaaa yep  alors effectivement un retain  J'ai pas tellement bien compris ce que ca faisait, j'ai lu qq part d'une sorte de renvoi vers la variable global enfin c'est tout bon. Merci pour votre aide!


----------



## ntx (25 Avril 2007)

Il faudrait (d'urgence) te renseigner sur la gestion de la m&#233;moire en Obj-C : &#231;a n'a rien &#224; voir avec celle du C et tr&#232;s susceptible &#224; bug si tu la ma&#238;trises pas. 

PS : si tu ne l'avais pas d&#233;j&#224; remarqu&#233;, Obj-C ne travaille qu'avec des pointeurs
Ex :

```
NSString* toto; titi;
...
toto = titi; // signifie adresse de toto = adresse de titi donc si la valeur de titi change, la valeur de toto change aussi
...
```


----------



## kollyv (25 Avril 2007)

Ok je vais étudier tout ca. Le langage est plutot différent de ceux dont j'ai l'habitude (JAVA et C#). Je ne connais pas très bien le C non plus, pas évident de le prendre en main.

thx


----------



## Céroce (25 Avril 2007)

La prochaine version d'ObjC (celle livr&#233;e avec Mac OS X.5 L&#233;opard) aura un ramasse-miettes. En attendant un article int&#233;ressant sur la gestion m&#233;moire chez stepwise

Sachant que la doc la plus claire &#224; ce sujet que j'aie pu voir se trouvait dans le bouquin dont je donnais la r&#233;f&#233;rence (l'objet est un chien. Quand tu lui fais un retain, il a une laisse suppl&#233;mentaire autour du cou. A chaque release, il perd une laisse. Quand il n'a plus de laisse, il s'enfuit).

Bon courage!


P.S.: Les globales, c'est mal. La preuve.


----------

