ich versuche gerade ein GTK+ Programm zu realisieren, mit dem man Dateinamen ändern kann. Seltsamerweise bricht das Programm, nachdem man den Namen einer ausgewählten Datei geändert hat, mit folgender Fehlermeldung ab:
Code: Alles auswählen
Gtk:ERROR:/build/buildd/gtk+3.0-3.4.2/./gtk/gtkrbtree.c:465:_gtk_rbtree_insert_after: assertion failed: (_gtk_rbtree_is_nil (tree->root)) Abgebrochen (Speicherabzug geschrieben)
Code: Alles auswählen
#include <glib/gstdio.h>
#include <gtk/gtk.h>
#include <unistd.h>
/* Struktur mit drei Widgets zur Änderung von Dateinamen. */
typedef struct
{
GtkWidget *datei,
*name,
*neuer_name;
} W_Pack;
/* Prototypen */
static void datei_auswahl( GtkFileChooser *, W_Pack * );
static void name_aendern( GtkButton *, W_Pack * );
int main( int argc, char *argv[] )
{
W_Pack *wp = ( W_Pack * )g_malloc( sizeof( W_Pack ) );
GtkWidget *window, *hbox, *vbox;
gtk_init( &argc, &argv );
window = gtk_window_new( GTK_WINDOW_TOPLEVEL );
gtk_window_set_title( GTK_WINDOW( window ), "Dateinamen ändern" );
gtk_container_set_border_width( GTK_CONTAINER( window ), 10 );
g_signal_connect( G_OBJECT( window ), "destroy",
G_CALLBACK( gtk_main_quit ), NULL );
wp->datei = gtk_file_chooser_button_new( "Dateiauswahl",
GTK_FILE_CHOOSER_ACTION_OPEN ); /* Dateiauswahlknopf */
/* home als Standardverzeichnis bei der Auswahl der gewünschten Datei. */
gtk_file_chooser_set_current_folder( GTK_FILE_CHOOSER( wp->datei ), g_get_home_dir() );
wp->name = gtk_entry_new(); /* Texteingabefeld für gewünschten Dateinamen */
wp->neuer_name = gtk_button_new_from_stock( GTK_STOCK_APPLY ); /* Knopf zur Anwendung der Änderung */
/* Bevor noch keine Datei ausgewählt wurde, Texteingabefeld und Knopf zur Anwendung sperren. */
gtk_widget_set_sensitive( wp->name, FALSE ); /* Texteingabefeld sperren */
gtk_widget_set_sensitive( wp->neuer_name, FALSE ); /* Knopf zur Anwendung sperren */
/* Dateiauswahlknopf mit der Funktion datei_auswahl() verknüpfen. */
g_signal_connect( G_OBJECT( wp->datei ), "selection-changed",
G_CALLBACK( datei_auswahl ),
( gpointer ) wp );
/* Knopf zur Anwendung der Namensänderung mit der Funktion name_aendern() verknüpfen. */
g_signal_connect( G_OBJECT( wp->neuer_name ), "clicked",
G_CALLBACK( name_aendern ),
( gpointer ) wp );
/* Texteingabefeld und Anwendungsknopf in eine horizontale Box packen. */
hbox = gtk_box_new( FALSE, 5 );
gtk_box_pack_start( GTK_BOX( hbox ), wp->name, TRUE, TRUE, 0 );
gtk_box_pack_start( GTK_BOX( hbox ), wp->neuer_name, FALSE, TRUE, 0 );
/* Dateiauswahlknopf und horizontale Box in eine vertikale Box packen. */
vbox = gtk_box_new( TRUE, 5 );
gtk_box_pack_start( GTK_BOX( vbox ), wp->datei, TRUE, TRUE, 0 );
gtk_box_pack_start( GTK_BOX( vbox ), hbox, FALSE, TRUE, 0 );
gtk_container_add( GTK_CONTAINER( window ), vbox );
gtk_widget_show_all( window );
gtk_main();
return 0;
}
static void datei_auswahl( GtkFileChooser *datei, W_Pack *wp )
{
gchar *datei_name = gtk_file_chooser_get_filename( datei ); /* Name der ausgewählten Datei. */
gint mode = g_access( datei_name, W_OK ); /* ausgewählte Datei auf Schreibrechte überprüfen */
gtk_widget_set_sensitive( wp->name, !mode ); /* wenn mode == 0 - also TRUE -dann Texteingabefeld entsperren */
gtk_widget_set_sensitive( wp->neuer_name, !mode ); /* Knopf zur Bestätigung der Anwendung entsperren */
}
static void name_aendern( GtkButton *neuer_name, W_Pack *wp )
{
gchar *alt, *neu, *ort;
alt = gtk_file_chooser_get_filename( GTK_FILE_CHOOSER( wp->datei ) ); /* alte Datei im Auswahlknopf */
ort = gtk_file_chooser_get_current_folder( GTK_FILE_CHOOSER( wp->datei ) ); /* Verzeichnis der ausgewählten Datei */
/* neuer Name im Textfeld zum überschreiben des alten Namens im selben Ort */
neu = g_strconcat( ort, "/", gtk_entry_get_text( GTK_ENTRY( wp->name ) ), NULL );
g_rename( alt, neu ); /* alten mit neuen Namen überschreiben */
gtk_widget_set_sensitive( wp->name, FALSE ); /* Texteingabefeld sperren */
gtk_widget_set_sensitive( wp->neuer_name, FALSE ); /* Knopf zur Bestätigung der Anwendung sperren */
}
Gruß Dave
