From 20808790d2c29e8a45aea62169f2245453bb527d Mon Sep 17 00:00:00 2001 From: Jonathan Blandford Date: Mon, 15 Mar 2004 06:54:34 +0000 Subject: [PATCH] Rewritten to use the GtkEntryCompletion API more correctly. Now pops down Mon Mar 15 01:50:28 2004 Jonathan Blandford * gtkfilechooserentry.c: Rewritten to use the GtkEntryCompletion API more correctly. Now pops down the dropdown well. * gtkfilesystem.c (gtk_file_path_get_type): New boxed type for the FilePath. * test/testfilechooser.c: disable preview widget temporarily. It's not representative of a good preview widget. --- ChangeLog | 11 + ChangeLog.pre-2-10 | 11 + ChangeLog.pre-2-4 | 11 + ChangeLog.pre-2-6 | 11 + ChangeLog.pre-2-8 | 11 + gtk/gtkfilechooserentry.c | 465 +++++++++++++++++++++----------------- gtk/gtkfilesystem.c | 33 +++ gtk/gtkfilesystem.h | 7 + tests/testfilechooser.c | 6 +- 9 files changed, 355 insertions(+), 211 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1e7a0acb91..e56cb4683d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +Mon Mar 15 01:50:28 2004 Jonathan Blandford + + * gtkfilechooserentry.c: Rewritten to use the GtkEntryCompletion + API more correctly. Now pops down the dropdown well. + + * gtkfilesystem.c (gtk_file_path_get_type): New boxed type for the + FilePath. + + * test/testfilechooser.c: disable preview widget temporarily. + It's not representative of a good preview widget. + 2004-03-15 Federico Mena Quintero * gtk/gtkfilechooserdefault.c (shortcuts_find_current_folder): diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index 1e7a0acb91..e56cb4683d 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,14 @@ +Mon Mar 15 01:50:28 2004 Jonathan Blandford + + * gtkfilechooserentry.c: Rewritten to use the GtkEntryCompletion + API more correctly. Now pops down the dropdown well. + + * gtkfilesystem.c (gtk_file_path_get_type): New boxed type for the + FilePath. + + * test/testfilechooser.c: disable preview widget temporarily. + It's not representative of a good preview widget. + 2004-03-15 Federico Mena Quintero * gtk/gtkfilechooserdefault.c (shortcuts_find_current_folder): diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 index 1e7a0acb91..e56cb4683d 100644 --- a/ChangeLog.pre-2-4 +++ b/ChangeLog.pre-2-4 @@ -1,3 +1,14 @@ +Mon Mar 15 01:50:28 2004 Jonathan Blandford + + * gtkfilechooserentry.c: Rewritten to use the GtkEntryCompletion + API more correctly. Now pops down the dropdown well. + + * gtkfilesystem.c (gtk_file_path_get_type): New boxed type for the + FilePath. + + * test/testfilechooser.c: disable preview widget temporarily. + It's not representative of a good preview widget. + 2004-03-15 Federico Mena Quintero * gtk/gtkfilechooserdefault.c (shortcuts_find_current_folder): diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index 1e7a0acb91..e56cb4683d 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,3 +1,14 @@ +Mon Mar 15 01:50:28 2004 Jonathan Blandford + + * gtkfilechooserentry.c: Rewritten to use the GtkEntryCompletion + API more correctly. Now pops down the dropdown well. + + * gtkfilesystem.c (gtk_file_path_get_type): New boxed type for the + FilePath. + + * test/testfilechooser.c: disable preview widget temporarily. + It's not representative of a good preview widget. + 2004-03-15 Federico Mena Quintero * gtk/gtkfilechooserdefault.c (shortcuts_find_current_folder): diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index 1e7a0acb91..e56cb4683d 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,14 @@ +Mon Mar 15 01:50:28 2004 Jonathan Blandford + + * gtkfilechooserentry.c: Rewritten to use the GtkEntryCompletion + API more correctly. Now pops down the dropdown well. + + * gtkfilesystem.c (gtk_file_path_get_type): New boxed type for the + FilePath. + + * test/testfilechooser.c: disable preview widget temporarily. + It's not representative of a good preview widget. + 2004-03-15 Federico Mena Quintero * gtk/gtkfilechooserdefault.c (shortcuts_find_current_folder): diff --git a/gtk/gtkfilechooserentry.c b/gtk/gtkfilechooserentry.c index 6235e0d82b..196876cf65 100644 --- a/gtk/gtkfilechooserentry.c +++ b/gtk/gtkfilechooserentry.c @@ -45,7 +45,8 @@ struct _GtkFileChooserEntry GtkFilePath *base_folder; GtkFilePath *current_folder_path; gchar *file_part; - GSource *completion_idle; + GSource *load_directory_idle; + GSource *check_completion_idle; GtkFileFolder *current_folder; @@ -54,6 +55,12 @@ struct _GtkFileChooserEntry guint has_completion : 1; }; +enum +{ + DISPLAY_NAME_COLUMN, + N_COLUMNS +}; + static void gtk_file_chooser_entry_class_init (GtkFileChooserEntryClass *class); static void gtk_file_chooser_entry_iface_init (GtkEditableClass *iface); static void gtk_file_chooser_entry_init (GtkFileChooserEntry *chooser_entry); @@ -62,18 +69,28 @@ static void gtk_file_chooser_entry_finalize (GObject *object) static gboolean gtk_file_chooser_entry_focus (GtkWidget *widget, GtkDirectionType direction); static void gtk_file_chooser_entry_changed (GtkEditable *editable); -static void gtk_file_chooser_entry_do_insert_text (GtkEditable *editable, - const gchar *new_text, - gint new_text_length, - gint *position); +static void gtk_file_chooser_entry_do_insert_text (GtkEditable *editable, + const gchar *new_text, + gint new_text_length, + gint *position); -static void clear_completion_callback (GtkFileChooserEntry *chooser_entry, - GParamSpec *pspec); +static void clear_completion_callback (GtkFileChooserEntry *chooser_entry, + GParamSpec *pspec); +static gboolean match_selected_callback (GtkEntryCompletion *completion, + GtkTreeModel *model, + GtkTreeIter *iter, + GtkFileChooserEntry *chooser_entry); +static gboolean completion_match_func (GtkEntryCompletion *comp, + const char *key, + GtkTreeIter *iter, + gpointer data); +static void files_added_cb (GtkFileSystem *file_system, + GSList *added_uris, + GtkFileChooserEntry *chooser_entry); +static void files_deleted_cb (GtkFileSystem *file_system, + GSList *deleted_uris, + GtkFileChooserEntry *chooser_entry); -static gboolean completion_match_func (GtkEntryCompletion *comp, - const char *key, - GtkTreeIter *iter, - gpointer data); static GObjectClass *parent_class; static GtkEditableClass *parent_editable_iface; @@ -105,7 +122,7 @@ _gtk_file_chooser_entry_get_type (void) NULL /* interface_data */ }; - + file_chooser_entry_type = g_type_register_static (GTK_TYPE_ENTRY, "GtkFileChooserEntry", &file_chooser_entry_info, 0); g_type_add_interface_static (file_chooser_entry_type, @@ -143,17 +160,23 @@ static void gtk_file_chooser_entry_init (GtkFileChooserEntry *chooser_entry) { GtkEntryCompletion *comp; - GtkCellRenderer *renderer; - - chooser_entry->completion_store = gtk_list_store_new (1, G_TYPE_STRING); + GtkCellRenderer *cell; comp = gtk_entry_completion_new (); - gtk_entry_completion_set_model (comp, GTK_TREE_MODEL (chooser_entry->completion_store)); gtk_entry_completion_set_match_func (comp, completion_match_func, chooser_entry, NULL); - gtk_entry_completion_set_text_column (comp, 0); + + cell = gtk_cell_renderer_text_new (); + gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (comp), + cell, TRUE); + gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (comp), + cell, + "text", 0); + + g_signal_connect (comp, "match-selected", + G_CALLBACK (match_selected_callback), chooser_entry); gtk_entry_set_completion (GTK_ENTRY (chooser_entry), comp); g_object_unref (comp); @@ -173,11 +196,17 @@ gtk_file_chooser_entry_finalize (GObject *object) g_object_unref (chooser_entry->completion_store); if (chooser_entry->current_folder) - g_object_unref (chooser_entry->current_folder); - + { + g_signal_handlers_disconnect_by_func (chooser_entry->current_folder, + G_CALLBACK (files_added_cb), chooser_entry); + g_signal_handlers_disconnect_by_func (chooser_entry->current_folder, + G_CALLBACK (files_deleted_cb), chooser_entry); + g_object_unref (chooser_entry->current_folder); + } + 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); @@ -185,90 +214,100 @@ gtk_file_chooser_entry_finalize (GObject *object) parent_class->finalize (object); } +/* Match functions for the GtkEntryCompletion */ +static gboolean +match_selected_callback (GtkEntryCompletion *completion, + GtkTreeModel *model, + GtkTreeIter *iter, + GtkFileChooserEntry *chooser_entry) +{ + char *display_name; + + gtk_tree_model_get (model, iter, + DISPLAY_NAME_COLUMN, &display_name, + -1); + + if (display_name) + { + g_print ("\t:%s:\n", display_name); + g_free (display_name); + } + return TRUE; +} + /* Match function for the GtkEntryCompletion */ static gboolean completion_match_func (GtkEntryCompletion *comp, - const char *key, + const char *key_unused, GtkTreeIter *iter, gpointer data) { GtkFileChooserEntry *chooser_entry; char *name; gboolean result; + char *norm_file_part; + char *norm_name; chooser_entry = GTK_FILE_CHOOSER_ENTRY (data); + /* We ignore the key because it is the contents of the entry. Instead, we + * just use our precomputed file_part. + */ + if (!chooser_entry->file_part) + return FALSE; + gtk_tree_model_get (GTK_TREE_MODEL (chooser_entry->completion_store), iter, 0, &name, -1); if (!name) return FALSE; /* Uninitialized row, ugh */ - /* We ignore the key because it is the contents of the entry. Instead, we - * just use our precomputed file_part. + /* If we have an empty file_part, then we're at the root of a directory. In + * that case, we want to match all non-dot files. It's possible that we would + * want to match dot_files too if show_hidden is TRUE on the fileselector. + */ + if (chooser_entry->file_part[0] == '\000') + { + if (name[0] == '.') + result = FALSE; + else + result = TRUE; + g_free (name); + + return result; + } + + + norm_file_part = g_utf8_normalize (chooser_entry->file_part, -1, G_NORMALIZE_ALL); + norm_name = g_utf8_normalize (name, -1, G_NORMALIZE_ALL); + + result = (strncmp (norm_file_part, norm_name, strlen (norm_file_part)) == 0); + + /* FIXME: Owen suggests first doing a case-folded comparison, then a + * non-case-folded one if the first one yielded more than one match. */ - if (chooser_entry->file_part) - { - char *norm_file_part; - char *norm_name; - - norm_file_part = g_utf8_normalize (chooser_entry->file_part, -1, G_NORMALIZE_ALL); - norm_name = g_utf8_normalize (name, -1, G_NORMALIZE_ALL); - - result = (strncmp (norm_file_part, norm_name, strlen (norm_file_part)) == 0); - - /* FIXME: Owen suggests first doing a case-folded comparison, then a - * non-case-folded one if the first one yielded more than one match. - */ - - g_free (norm_file_part); - g_free (norm_name); - } - else - result = FALSE; - - - result = (strncmp (key, name, strlen (key)) == 0); - + g_free (norm_file_part); + g_free (norm_name); g_free (name); + return result; } -static gboolean -completion_idle_callback (GtkFileChooserEntry *chooser_entry) +static void +update_current_folder_files (GtkFileChooserEntry *chooser_entry, + GSList *added_uris) { - GtkEditable *editable = GTK_EDITABLE (chooser_entry); - GSList *child_paths = NULL; GSList *tmp_list; - gchar *common_prefix = NULL; - GtkFilePath *unique_path = NULL; - GtkListStore *new_store; - chooser_entry->completion_idle = NULL; + g_assert (chooser_entry->completion_store != NULL); - if (strcmp (chooser_entry->file_part, "") == 0) - return FALSE; - - if (!chooser_entry->current_folder && - chooser_entry->file_system && - chooser_entry->current_folder_path) - 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 */ - if (chooser_entry->current_folder) - gtk_file_folder_list_children (chooser_entry->current_folder, - &child_paths, - NULL); /* NULL-GError */ - - new_store = gtk_list_store_new (1, G_TYPE_STRING); - - for (tmp_list = child_paths; tmp_list; tmp_list = tmp_list->next) + /* Bah. Need to turn off sorting */ + for (tmp_list = added_uris; tmp_list; tmp_list = tmp_list->next) { GtkFileInfo *info; GtkFilePath *path; path = tmp_list->data; - + info = gtk_file_folder_get_info (chooser_entry->current_folder, path, NULL); /* NULL-GError */ @@ -277,99 +316,84 @@ completion_idle_callback (GtkFileChooserEntry *chooser_entry) const gchar *display_name = gtk_file_info_get_display_name (info); GtkTreeIter iter; - gtk_list_store_append (new_store, &iter); - gtk_list_store_set (new_store, &iter, - 0, display_name, + gtk_list_store_append (chooser_entry->completion_store, &iter); + gtk_list_store_set (chooser_entry->completion_store, &iter, + DISPLAY_NAME_COLUMN, display_name, -1); - if (g_str_has_prefix (display_name, chooser_entry->file_part)) - { - if (!common_prefix) - { - common_prefix = g_strdup (display_name); - unique_path = gtk_file_path_copy (path); - } - else - { - gchar *p = common_prefix; - const gchar *q = display_name; - - while (*p && *p == *q) - { - p++; - q++; - } - - *p = '\0'; - - gtk_file_path_free (unique_path); - unique_path = NULL; - } - } - gtk_file_info_free (info); } } - g_object_unref (chooser_entry->completion_store); - chooser_entry->completion_store = new_store; + /* FIXME: we want to turn off sorting temporarily. I suck... */ + gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (chooser_entry->completion_store), + DISPLAY_NAME_COLUMN, GTK_SORT_ASCENDING); + /* FIXME: add the selection-completion idle here */ +} + +static void +files_added_cb (GtkFileSystem *file_system, + GSList *added_uris, + GtkFileChooserEntry *chooser_entry) +{ + update_current_folder_files (chooser_entry, added_uris); +} + +static void +files_deleted_cb (GtkFileSystem *file_system, + GSList *deleted_uris, + GtkFileChooserEntry *chooser_entry) +{ + /* FIXME: gravy... */ +} + +static gboolean +load_directory_callback (GtkFileChooserEntry *chooser_entry) +{ + GSList *child_paths = NULL; + + chooser_entry->load_directory_idle = NULL; + + /* guard against bogus settings*/ + if (chooser_entry->current_folder_path == NULL || + chooser_entry->file_system == NULL) + return FALSE; + + if (chooser_entry->current_folder != NULL) + { + g_warning ("idle activate multiple times without clearing the folder object first."); + return FALSE; + } + 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) + return FALSE; + 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); + + gtk_file_folder_list_children (chooser_entry->current_folder, + &child_paths, + NULL); /* NULL-GError */ + chooser_entry->completion_store = gtk_list_store_new (N_COLUMNS, + G_TYPE_STRING); + + if (child_paths) + { + update_current_folder_files (chooser_entry, child_paths); + gtk_file_paths_free (child_paths); + } + gtk_entry_completion_set_model (gtk_entry_get_completion (GTK_ENTRY (chooser_entry)), - GTK_TREE_MODEL (new_store)); - - if (unique_path) - { - GtkFileInfo *info; - - info = gtk_file_folder_get_info (chooser_entry->current_folder, - unique_path, - NULL); /* NULL-GError */ - - if (info) - { - if (gtk_file_info_get_is_folder (info)) - { - gchar *tmp = common_prefix; - common_prefix = g_strconcat (tmp, "/", NULL); - g_free (tmp); - } - - gtk_file_info_free (info); - } - - gtk_file_path_free (unique_path); - } - - gtk_file_paths_free (child_paths); - - if (common_prefix) - { - gint total_len; - gint file_part_len; - gint common_prefix_len; - gint pos; - - total_len = g_utf8_strlen (gtk_entry_get_text (GTK_ENTRY (chooser_entry)), -1); - file_part_len = g_utf8_strlen (chooser_entry->file_part, -1); - common_prefix_len = g_utf8_strlen (common_prefix, -1); - - if (common_prefix_len > file_part_len) - { - pos = total_len - file_part_len; - gtk_editable_delete_text (editable, - pos, -1); - gtk_editable_insert_text (editable, - common_prefix, -1, - &pos); - gtk_editable_select_region (editable, - total_len, - total_len - file_part_len + common_prefix_len); - - chooser_entry->has_completion = TRUE; - } - - g_free (common_prefix); - } - + GTK_TREE_MODEL (chooser_entry->completion_store)); return FALSE; } @@ -379,20 +403,7 @@ gtk_file_chooser_entry_do_insert_text (GtkEditable *editable, gint new_text_length, gint *position) { - GtkFileChooserEntry *chooser_entry = GTK_FILE_CHOOSER_ENTRY (editable); - parent_editable_iface->do_insert_text (editable, new_text, new_text_length, position); - - if (*position == GTK_ENTRY (editable)->text_length && - !chooser_entry->completion_idle) - { - chooser_entry->completion_idle = g_idle_source_new (); - g_source_set_priority (chooser_entry->completion_idle, G_PRIORITY_HIGH); - g_source_set_closure (chooser_entry->completion_idle, - g_cclosure_new_object (G_CALLBACK (completion_idle_callback), - G_OBJECT (chooser_entry))); - g_source_attach (chooser_entry->completion_idle, NULL); - } } static gboolean @@ -400,7 +411,7 @@ gtk_file_chooser_entry_focus (GtkWidget *widget, GtkDirectionType direction) { GtkFileChooserEntry *chooser_entry = GTK_FILE_CHOOSER_ENTRY (widget); - + if (direction == GTK_DIR_TAB_FORWARD && GTK_WIDGET_HAS_FOCUS (widget) && chooser_entry->has_completion) @@ -413,6 +424,67 @@ gtk_file_chooser_entry_focus (GtkWidget *widget, return GTK_WIDGET_CLASS (parent_class)->focus (widget, direction); } +/* This will see if a path typed by the user is new, and installs the loading + * idle if it is. + */ +static void +gtk_file_chooser_entry_maybe_update_directory (GtkFileChooserEntry *chooser_entry, + GtkFilePath *folder_path) +{ + gboolean queue_idle = FALSE; + + if (chooser_entry->current_folder_path) + { + if (gtk_file_path_compare (folder_path, chooser_entry->current_folder_path) != 0) + { + /* We changed our current directory. We need to clear out the old + * directory information. + */ + if (chooser_entry->current_folder) + { + g_signal_handlers_disconnect_by_func (chooser_entry->current_folder, + G_CALLBACK (files_added_cb), chooser_entry); + 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->completion_store) + { + gtk_list_store_clear (GTK_LIST_STORE (chooser_entry->completion_store)); + /* FIXME: Uncomment this line and get rid of the _clear above + * after #137211 is fixed */ + /* gtk_entry_completion_set_model (gtk_entry_get_completion (GTK_ENTRY (chooser_entry)), NULL);*/ + g_object_unref (chooser_entry->completion_store); + chooser_entry->completion_store = NULL; + } + + queue_idle = TRUE; + } + + gtk_file_path_free (chooser_entry->current_folder_path); + } + else + { + queue_idle = TRUE; + } + + chooser_entry->current_folder_path = folder_path; + + if (queue_idle && chooser_entry->load_directory_idle == NULL) + { + chooser_entry->load_directory_idle = g_idle_source_new (); + g_source_set_priority (chooser_entry->load_directory_idle, G_PRIORITY_HIGH); + g_source_set_closure (chooser_entry->load_directory_idle, + g_cclosure_new_object (G_CALLBACK (load_directory_callback), + G_OBJECT (chooser_entry))); + g_source_attach (chooser_entry->load_directory_idle, NULL); + } +} + + + static void gtk_file_chooser_entry_changed (GtkEditable *editable) { @@ -433,21 +505,7 @@ gtk_file_chooser_entry_changed (GtkEditable *editable) file_part = g_strdup (""); } - if (chooser_entry->current_folder_path) - { - if (gtk_file_path_compare (folder_path, chooser_entry->current_folder_path) != 0) - { - if (chooser_entry->current_folder) - { - g_object_unref (chooser_entry->current_folder); - chooser_entry->current_folder = NULL; - } - } - - gtk_file_path_free (chooser_entry->current_folder_path); - } - - chooser_entry->current_folder_path = folder_path; + gtk_file_chooser_entry_maybe_update_directory (chooser_entry, folder_path); if (chooser_entry->file_part) g_free (chooser_entry->file_part); @@ -464,12 +522,12 @@ clear_completion_callback (GtkFileChooserEntry *chooser_entry, /** * _gtk_file_chooser_entry_new: - * + * * Creates a new #GtkFileChooserEntry object. #GtkFileChooserEntry * is an internal implementation widget for the GTK+ file chooser * which is an entry with completion with respect to a * #GtkFileSystem object. - * + * * Return value: the newly created #GtkFileChooserEntry **/ GtkWidget * @@ -482,7 +540,7 @@ _gtk_file_chooser_entry_new (void) * _gtk_file_chooser_entry_set_file_system: * @chooser_entry: a #GtkFileChooser * @file_system: an object implementing #GtkFileSystem - * + * * Sets the file system for @chooser_entry. **/ void @@ -491,7 +549,7 @@ _gtk_file_chooser_entry_set_file_system (GtkFileChooserEntry *chooser_entry, { g_return_if_fail (GTK_IS_FILE_CHOOSER_ENTRY (chooser_entry)); g_return_if_fail (GTK_IS_FILE_SYSTEM (file_system)); - + if (file_system != chooser_entry->file_system) { if (chooser_entry->file_system) @@ -512,29 +570,18 @@ void _gtk_file_chooser_entry_set_base_folder (GtkFileChooserEntry *chooser_entry, const GtkFilePath *path) { - char *text; - if (chooser_entry->base_folder) gtk_file_path_free (chooser_entry->base_folder); chooser_entry->base_folder = gtk_file_path_copy (path); - /* We first try to get the path as a filename, and then use an uri if that fails */ - text = gtk_file_system_path_to_filename (chooser_entry->file_system, path); - if (!text) - text = gtk_file_system_path_to_uri (chooser_entry->file_system, path); - - gtk_entry_set_text (GTK_ENTRY (chooser_entry), text); - - g_free (text); - - gtk_editable_select_region (GTK_EDITABLE (chooser_entry), 0, -1); + gtk_editable_select_region (GTK_EDITABLE (chooser_entry), 0, -1); } /** * _gtk_file_chooser_entry_get_current_folder: * @chooser_entry: a #GtkFileChooserEntry - * + * * Gets the current folder for the #GtkFileChooserEntry. If the * user has only entered a filename, this will be the base folder * (see _gtk_file_chooser_entry_set_base_folder()), but if the @@ -542,7 +589,7 @@ _gtk_file_chooser_entry_set_base_folder (GtkFileChooserEntry *chooser_entry, * be different. If the user has entered a relative or absolute * path that doesn't point to a folder in the file system, it will * be %NULL. - * + * * Return value: the path of current folder - this value is owned by the * chooser entry and must not be modified or freed. **/ @@ -555,12 +602,12 @@ _gtk_file_chooser_entry_get_current_folder (GtkFileChooserEntry *chooser_entry) /** * _gtk_file_chooser_entry_get_file_part: * @chooser_entry: a #GtkFileChooserEntry - * + * * Gets the non-folder portion of whatever the user has entered * into the file selector. What is returned is a UTF-8 string, * and if a filename path is needed, gtk_file_system_make_path() * must be used - * + * * Return value: the entered filename - this value is owned by the * chooser entry and must not be modified or freed. **/ @@ -574,7 +621,7 @@ _gtk_file_chooser_entry_get_file_part (GtkFileChooserEntry *chooser_entry) * _gtk_file_chooser_entry_set_file_part: * @chooser_entry: a #GtkFileChooserEntry * @file_part: text to display in the entry, in UTF-8 - * + * * Sets the current text shown in the file chooser entry. **/ void diff --git a/gtk/gtkfilesystem.c b/gtk/gtkfilesystem.c index 1b3430f236..cd2b072257 100644 --- a/gtk/gtkfilesystem.c +++ b/gtk/gtkfilesystem.c @@ -876,6 +876,39 @@ gtk_file_folder_get_info (GtkFileFolder *folder, return GTK_FILE_FOLDER_GET_IFACE (folder)->get_info (folder, path, error); } + +/***************************************** + * GtkFilePath modules * + *****************************************/ + +/* We make these real functions in case either copy or free are implemented as macros + */ +static gpointer +gtk_file_path_real_copy (gpointer boxed) +{ + return gtk_file_path_new_dup (gtk_file_path_get_string ((GtkFilePath *) boxed)); +} + +static void +gtk_file_path_real_free (gpointer boxed) +{ + gtk_file_path_free (boxed); +} + +GType +gtk_file_path_get_type (void) +{ + static GType our_type = 0; + + if (our_type == 0) + our_type = g_boxed_type_register_static ("GtkFilePath", + (GBoxedCopyFunc) gtk_file_path_real_copy, + (GBoxedFreeFunc) gtk_file_path_real_free); + + return our_type; +} + + GSList * gtk_file_paths_sort (GSList *paths) { diff --git a/gtk/gtkfilesystem.h b/gtk/gtkfilesystem.h index 98c80b8498..1124fc9f52 100644 --- a/gtk/gtkfilesystem.h +++ b/gtk/gtkfilesystem.h @@ -317,6 +317,13 @@ GtkFileInfo *gtk_file_folder_get_info (GtkFileFolder *folder, const GtkFilePath *path, GError **error); + +/* GtkFilePath */ +#define GTK_TYPE_FILE_PATH (gtk_file_path_get_type ()) +#define GTK_FILE_PATH(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_FILE_PATH, GtkFilePath)) +#define GTK_IS_FILE_PATH(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_FILE_PATH)) + +GType gtk_file_path_get_type (void); #ifdef __GNUC__ #define gtk_file_path_new_dup(str) \ ({ const gchar *__s = (str); (GtkFilePath *)g_strdup(__s); }) diff --git a/tests/testfilechooser.c b/tests/testfilechooser.c index dbb573d28a..5c32627f88 100644 --- a/tests/testfilechooser.c +++ b/tests/testfilechooser.c @@ -403,7 +403,7 @@ main (int argc, char **argv) dialog = g_object_new (GTK_TYPE_FILE_CHOOSER_DIALOG, "action", action, - "file-system-backend", "gnome-vfs", + /* "file-system-backend", "gtk+",*/ "select-multiple", multiple, NULL); switch (action) @@ -457,8 +457,10 @@ main (int argc, char **argv) gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter); /* Preview widget */ + /* THIS IS A TERRIBLE PREVIEW WIDGET, AND SHOULD NOT BE COPIED AT ALL. + */ preview_vbox = gtk_vbox_new (0, FALSE); - gtk_file_chooser_set_preview_widget (GTK_FILE_CHOOSER (dialog), preview_vbox); + /* gtk_file_chooser_set_preview_widget (GTK_FILE_CHOOSER (dialog), preview_vbox);*/ preview_label = gtk_label_new (NULL); gtk_box_pack_start (GTK_BOX (preview_vbox), preview_label, TRUE, TRUE, 0);