diff options
Diffstat (limited to 'gtk/gtkfilechooserentry.c')
-rw-r--r-- | gtk/gtkfilechooserentry.c | 134 |
1 files changed, 96 insertions, 38 deletions
diff --git a/gtk/gtkfilechooserentry.c b/gtk/gtkfilechooserentry.c index acbd1206c2..cbae54c121 100644 --- a/gtk/gtkfilechooserentry.c +++ b/gtk/gtkfilechooserentry.c @@ -55,6 +55,7 @@ struct _GtkFileChooserEntry GSource *load_directory_idle; GtkFileFolder *current_folder; + GtkFileSystemHandle *load_folder_handle; GtkListStore *completion_store; @@ -75,6 +76,7 @@ static void gtk_file_chooser_entry_iface_init (GtkEditableClass *iface); static void gtk_file_chooser_entry_init (GtkFileChooserEntry *chooser_entry); static void gtk_file_chooser_entry_finalize (GObject *object); +static void gtk_file_chooser_entry_dispose (GObject *object); static gboolean gtk_file_chooser_entry_focus (GtkWidget *widget, GtkDirectionType direction); static void gtk_file_chooser_entry_activate (GtkEntry *entry); @@ -156,6 +158,7 @@ gtk_file_chooser_entry_class_init (GtkFileChooserEntryClass *class) parent_class = g_type_class_peek_parent (class); gobject_class->finalize = gtk_file_chooser_entry_finalize; + gobject_class->dispose = gtk_file_chooser_entry_dispose; widget_class->focus = gtk_file_chooser_entry_focus; @@ -211,8 +214,29 @@ gtk_file_chooser_entry_finalize (GObject *object) { GtkFileChooserEntry *chooser_entry = GTK_FILE_CHOOSER_ENTRY (object); + gtk_file_path_free (chooser_entry->base_folder); + gtk_file_path_free (chooser_entry->current_folder_path); + g_free (chooser_entry->file_part); + + parent_class->finalize (object); +} + +static void +gtk_file_chooser_entry_dispose (GObject *object) +{ + GtkFileChooserEntry *chooser_entry = GTK_FILE_CHOOSER_ENTRY (object); + if (chooser_entry->completion_store) - g_object_unref (chooser_entry->completion_store); + { + g_object_unref (chooser_entry->completion_store); + chooser_entry->completion_store = NULL; + } + + if (chooser_entry->load_folder_handle) + { + gtk_file_system_cancel_operation (chooser_entry->load_folder_handle); + chooser_entry->load_folder_handle = NULL; + } if (chooser_entry->current_folder) { @@ -221,16 +245,16 @@ gtk_file_chooser_entry_finalize (GObject *object) g_signal_handlers_disconnect_by_func (chooser_entry->current_folder, G_CALLBACK (files_deleted_cb), chooser_entry); g_object_unref (chooser_entry->current_folder); + chooser_entry->current_folder = NULL; } if (chooser_entry->file_system) - g_object_unref (chooser_entry->file_system); - - gtk_file_path_free (chooser_entry->base_folder); - gtk_file_path_free (chooser_entry->current_folder_path); - g_free (chooser_entry->file_part); + { + g_object_unref (chooser_entry->file_system); + chooser_entry->file_system = NULL; + } - parent_class->finalize (object); + parent_class->dispose (object); } /* Match functions for the GtkEntryCompletion */ @@ -601,6 +625,41 @@ files_deleted_cb (GtkFileSystem *file_system, /* FIXME: gravy... */ } +static void +load_directory_get_folder_callback (GtkFileSystemHandle *handle, + GtkFileFolder *folder, + const GError *error, + gpointer data) +{ + gboolean cancelled = handle->cancelled; + GtkFileChooserEntry *chooser_entry = data; + + if (handle != chooser_entry->load_folder_handle) + goto out; + + chooser_entry->load_folder_handle = NULL; + + if (cancelled || error) + goto out; + + chooser_entry->current_folder = folder; + g_signal_connect (chooser_entry->current_folder, "files-added", + G_CALLBACK (files_added_cb), chooser_entry); + g_signal_connect (chooser_entry->current_folder, "files-removed", + G_CALLBACK (files_deleted_cb), chooser_entry); + + chooser_entry->completion_store = gtk_list_store_new (N_COLUMNS, + G_TYPE_STRING, + GTK_TYPE_FILE_PATH); + + gtk_entry_completion_set_model (gtk_entry_get_completion (GTK_ENTRY (chooser_entry)), + GTK_TREE_MODEL (chooser_entry->completion_store)); + +out: + g_object_unref (chooser_entry); + g_object_unref (handle); +} + static gboolean load_directory_callback (GtkFileChooserEntry *chooser_entry) { @@ -623,38 +682,15 @@ load_directory_callback (GtkFileChooserEntry *chooser_entry) g_assert (chooser_entry->completion_store == NULL); /* Load the folder */ - chooser_entry->current_folder = gtk_file_system_get_folder (chooser_entry->file_system, - chooser_entry->current_folder_path, - GTK_FILE_INFO_DISPLAY_NAME | GTK_FILE_INFO_IS_FOLDER, - NULL); /* NULL-GError */ - - /* There is no folder by that name */ - if (!chooser_entry->current_folder) - goto done; - g_signal_connect (chooser_entry->current_folder, "files-added", - G_CALLBACK (files_added_cb), chooser_entry); - g_signal_connect (chooser_entry->current_folder, "files-removed", - G_CALLBACK (files_deleted_cb), chooser_entry); - - chooser_entry->completion_store = gtk_list_store_new (N_COLUMNS, - G_TYPE_STRING, - GTK_TYPE_FILE_PATH); + if (chooser_entry->load_folder_handle) + gtk_file_system_cancel_operation (chooser_entry->load_folder_handle); - if (chooser_entry->file_part_pos != -1) - { - gtk_file_folder_list_children (chooser_entry->current_folder, - &child_paths, - NULL); /* NULL-GError */ - if (child_paths) - { - update_current_folder_files (chooser_entry, child_paths); - add_completion_idle (chooser_entry); - gtk_file_paths_free (child_paths); - } - } - - gtk_entry_completion_set_model (gtk_entry_get_completion (GTK_ENTRY (chooser_entry)), - GTK_TREE_MODEL (chooser_entry->completion_store)); + chooser_entry->load_folder_handle = + gtk_file_system_get_folder (chooser_entry->file_system, + chooser_entry->current_folder_path, + GTK_FILE_INFO_DISPLAY_NAME | GTK_FILE_INFO_IS_FOLDER, + load_directory_get_folder_callback, + g_object_ref (chooser_entry)); done: @@ -1041,5 +1077,27 @@ _gtk_file_chooser_entry_get_action (GtkFileChooserEntry *chooser_entry) return chooser_entry->action; } +gboolean +_gtk_file_chooser_entry_get_is_folder (GtkFileChooserEntry *chooser_entry, + const GtkFilePath *path) +{ + gboolean retval = FALSE; + + if (chooser_entry->current_folder) + { + GtkFileInfo *file_info; + + file_info = gtk_file_folder_get_info (chooser_entry->current_folder, + path, NULL); + if (file_info) + { + retval = gtk_file_info_get_is_folder (file_info); + gtk_file_info_free (file_info); + } + } + + return retval; +} + #define __GTK_FILE_CHOOSER_ENTRY_C__ #include "gtkaliasdef.c" |