Newsgroup: it.comp.os.linux.development
Titolo: Problema con GtkFileSelection

Salve a tutti.
Sto scrivendo un programmino di utilita' personale in cui, tramite il
GtkFileSelection, devo selezionare un file e leggerlo.
Il programma funziona ma mi da un "Segmentation Fault" all'atto del
click sul pulsante OK. Debuggando ho scoperto che recuperando il percorso
del file selezionato in questo modo:
file_name = gtk_file_selection_get_filename(GTK_FILE_SELECTION(opdlg));
nella variabile file name mi finisce il path del file "inquinato" da una
serie di caratteri strani, per esempio se seleziono il file:
/home/marco/tmp/file.mp3 
ritrovo che file_name contiene un path del tipo:
@#@~rco/tmp/file.mp3
Sicuramente ho commesso una qualche bischerata, se qualcuno avesse un idea
di cosa succeda mi faccia sapere.
Un grazie anticipato a tutti.
Ciao
-- 
Slaine Mc Roth
Linux User# 312607
Linux Machine# 198324

 di cosa succeda mi faccia sapere.
Se non mandi il codice del callback (togliendo le parti inutili), allora
sarà molto difficile capire quale sia l'errore.
Ciao,
 Emmanuele.
-- 
Emmanuele Bassi (Zefram)           [ 
http://digilander.libero.it/ebassi/
 ]
GnuPG Key fingerprint = 4DD0 C90D 4070 F071 5738  08BD 8ECC DB8F A432 0FF4

 sarà molto difficile capire quale sia l'errore.
In effetti non hai tutti i torti :))
Il codice che viene eseguito dopo la pressione del tasto OK sulla dialog
di selezione file e' questo:
void
on_okbtn_clicked                       (GtkButton       *button,
                                        gpointer         user_data)
{
	GtkWidget *opdlg;
	opdlg = lookup_widget(GTK_WIDGET(button),"fileselection");
	file_name = gtk_file_selection_get_filename(GTK_FILE_SELECTION(opdlg));
	gtk_widget_destroy(opdlg);
	open_file(widget);
}
La funzione open_file e' quella che si occupa dell'apertura e lettura del
file e funziona bene in quanto l'ho provata passando un nome di file
valido direttamente da codice.
Mentre se io provo a stampare il contenuto di file_name subito dopo averla
settata con gtk_file_selection_get_filename mi ritrovo con gli strani
caratteri che ho postato precedentemente.
Grazie


 }
E poi, non usare i callback sui pulsanti "Ok" e di "Annulla". Usa il
segnale "response":
#v+
void
on_fileselection_response (GtkWidget *dialog,
                           gint response,
			   gpointer user_data)
{
	if (response == GTK_RESPONSE_OK) {
		/* the user clicked Ok */
		const gchar *file_name;
		file_name = gtk_file_selection_get_filename
			(GTK_FILE_SELECTION (dialog));
		fprintf (stdout, "file selected: %s\n", file_name);
	}
}
#v-
È più semplice, perché non devi fare il reverse lookup sul widget, e
perché puoi fare un check all'interno del callback, per vedere se il
file è corretto, e, nel caso, rimanere comunque nella file selection
dialog.
[Tanto per cambiare, il codice è testato. :-)]
Esempio, in Python (in C non ho voglia di scriverlo :-)):
#v+
class CheckedFileSelection(gtk.FileSelection):
    def __init__(self, parent=None):
        gtk.FileSelection.__init__(self, "Open file")
        self.set_select_multiple(gtk.FALSE)
        if parent is not None:
            self.set_transient_for(parent)
 
        # strip the class signature, using an inner function
        def check_file(dialog, response):
            if not response == gtk.RESPONSE_OK:
                return
 
            filename = dialog.get_filename()
            # stupid sanity check, but sometimes users are either insane,
            # or stupid.
            if os.path.isdir(filename):
                dialog.stop_emission('response')
        self.connect('response', check_file)
#v-


 
[cut]
Da quello che sento in giro Python dovrebbe essere un mostriciattolo molto
interessante, prima o poi dovro' decidermi a dargli un occhiata.
Ciao.


 sbaglio?
Più che quello, sembra che tu stia modificando il path ritornato dalla
get_filename(), cosa che non deve essere fatta (e che produrrebbe una
segnmentation fault).
Se vuoi modificare il path, copia la stringa (e ricordati di liberarla
quando hai finito):
 
	GtkFileSelection *dialog;
	const gchar *file_name;
	gchar *tmp;
	file_name = gtk_file_selection_get_filename (dialog);
	tmp = g_strdup (file_name);
	[...] 
	g_free (tmp);


Il giorno Sat, 09 Aug 2003 12:33:45 +0000 lo sventurato Emmanuele Bassi 
ebbe l'ardire di pronunciare tali nefaste parole:
Grazie mille per i preziosi consigli.
Ciao


 
Avevi ragione. Copiando file_name in un altra variabile ed usando questa
come nel tuo esempio il difetto e' sparito.
Pero' non mi spiego perche'! Io la variabile file_name non la modifico ma
la imposto tramite gtk_file_selection_get_filename e poi la passo
direttamente a "fopen".
A meno che file_name non venga modificata dalla chiamata a fopen??!!
mah..
Ciao


 mah..
La variabile file_name che dichiari e' un puntatore all'array di byte 
presente all'interno del widget stesso. Nel momento che distruggi il 
widget l'array di byte viene liberato, quindi file_name rimane un 
puntatore appeso ad un'area di memoria non valida, di qui il 
segmentation fault.
Bye,
  Gabry

 
Cazzo non ci avevo pensato!!!
Hai ragione in effetti copio il puntatore ma l'array di char e' lo stesso.
Purtroppo stavo trattando la variabile file_name come una stringa
Pascal:(((
Sti cavoli di puntatori del c...o!! mi ci impapino sempre:(((
Vabbe' grazie per il chiarimento e scusate per la domanda stupida.
Ciao.
