X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=gtk%2Fgtkfilechooserentry.c;h=98ecd24c71d88301a7ae92e3d0f9d9a0b20b7698;hb=61344219d4ba6d81854cc5bea8cf90f600358501;hp=88ddc30c41d55605537c98274a8135f7a8310858;hpb=57766f194892fc670396bd79a28af71cf412c198;p=~andy%2Fgtk diff --git a/gtk/gtkfilechooserentry.c b/gtk/gtkfilechooserentry.c index 88ddc30c4..98ecd24c7 100644 --- a/gtk/gtkfilechooserentry.c +++ b/gtk/gtkfilechooserentry.c @@ -13,9 +13,7 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * License along with this library. If not, see . */ #include "config.h" @@ -45,12 +43,6 @@ struct _GtkFileChooserEntryClass GtkEntryClass parent_class; }; -/* Action to take when the current folder finishes loading (for explicit or automatic completion) */ -typedef enum { - LOAD_COMPLETE_NOTHING, - LOAD_COMPLETE_EXPLICIT_COMPLETION -} LoadCompleteAction; - struct _GtkFileChooserEntry { GtkEntry parent_instance; @@ -80,8 +72,8 @@ enum static void gtk_file_chooser_entry_finalize (GObject *object); static void gtk_file_chooser_entry_dispose (GObject *object); static void gtk_file_chooser_entry_grab_focus (GtkWidget *widget); -static gboolean gtk_file_chooser_entry_key_press_event (GtkWidget *widget, - GdkEventKey *event); +static gboolean gtk_file_chooser_entry_tab_handler (GtkWidget *widget, + GdkEventKey *event); static gboolean gtk_file_chooser_entry_focus_out_event (GtkWidget *widget, GdkEventFocus *event); @@ -160,7 +152,6 @@ _gtk_file_chooser_entry_class_init (GtkFileChooserEntryClass *class) gobject_class->dispatch_properties_changed = gtk_file_chooser_entry_dispatch_properties_changed; widget_class->grab_focus = gtk_file_chooser_entry_grab_focus; - widget_class->key_press_event = gtk_file_chooser_entry_key_press_event; widget_class->focus_out_event = gtk_file_chooser_entry_focus_out_event; } @@ -171,7 +162,6 @@ _gtk_file_chooser_entry_init (GtkFileChooserEntry *chooser_entry) GtkCellRenderer *cell; chooser_entry->local_only = TRUE; - chooser_entry->base_folder = g_file_new_for_path (g_get_home_dir ()); g_object_set (chooser_entry, "truncate-multiline", TRUE, NULL); @@ -200,6 +190,10 @@ _gtk_file_chooser_entry_init (GtkFileChooserEntry *chooser_entry) gtk_entry_set_completion (GTK_ENTRY (chooser_entry), comp); g_object_unref (comp); + /* NB: This needs to happen after the completion is set, so this handler + * runs before the handler installed by entrycompletion */ + g_signal_connect (chooser_entry, "key-press-event", + G_CALLBACK (gtk_file_chooser_entry_tab_handler), NULL); #ifdef G_OS_WIN32 g_signal_connect (chooser_entry, "insert-text", @@ -214,7 +208,8 @@ gtk_file_chooser_entry_finalize (GObject *object) { GtkFileChooserEntry *chooser_entry = GTK_FILE_CHOOSER_ENTRY (object); - g_object_unref (chooser_entry->base_folder); + if (chooser_entry->base_folder) + g_object_unref (chooser_entry->base_folder); if (chooser_entry->current_folder_file) g_object_unref (chooser_entry->current_folder_file); @@ -238,23 +233,25 @@ gtk_file_chooser_entry_dispose (GObject *object) /* Match functions for the GtkEntryCompletion */ static gboolean match_selected_callback (GtkEntryCompletion *completion, - GtkTreeModel *model, - GtkTreeIter *iter, - GtkFileChooserEntry *chooser_entry) + GtkTreeModel *model, + GtkTreeIter *iter, + GtkFileChooserEntry *chooser_entry) { char *path; - + gint pos; + gtk_tree_model_get (model, iter, - FULL_PATH_COLUMN, &path, + FULL_PATH_COLUMN, &path, -1); gtk_editable_delete_text (GTK_EDITABLE (chooser_entry), - 0, + 0, gtk_editable_get_position (GTK_EDITABLE (chooser_entry))); + pos = 0; gtk_editable_insert_text (GTK_EDITABLE (chooser_entry), - path, - 0, - NULL); + path, + -1, + &pos); g_free (path); @@ -304,8 +301,10 @@ gtk_file_chooser_get_file_for_text (GtkFileChooserEntry *chooser_entry, if (str[0] == '~' || g_path_is_absolute (str) || has_uri_scheme (str)) file = g_file_parse_name (str); - else + else if (chooser_entry->base_folder != NULL) file = g_file_resolve_relative_path (chooser_entry->base_folder, str); + else + file = NULL; return file; } @@ -318,6 +317,9 @@ gtk_file_chooser_get_directory_for_text (GtkFileChooserEntry *chooser_entry, file = gtk_file_chooser_get_file_for_text (chooser_entry, text); + if (file == NULL) + return NULL; + if (text[0] == 0 || text[strlen (text) - 1] == G_DIR_SEPARATOR) return file; @@ -379,46 +381,37 @@ start_explicit_completion (GtkFileChooserEntry *chooser_entry) } static gboolean -gtk_file_chooser_entry_key_press_event (GtkWidget *widget, - GdkEventKey *event) +gtk_file_chooser_entry_tab_handler (GtkWidget *widget, + GdkEventKey *event) { GtkFileChooserEntry *chooser_entry; GtkEditable *editable; GdkModifierType state; - gboolean control_pressed; + gint start, end; chooser_entry = GTK_FILE_CHOOSER_ENTRY (widget); editable = GTK_EDITABLE (widget); if (!chooser_entry->eat_tabs) - return GTK_WIDGET_CLASS (_gtk_file_chooser_entry_parent_class)->key_press_event (widget, event); + return FALSE; - control_pressed = FALSE; + if (event->keyval != GDK_KEY_Tab) + return FALSE; - if (gtk_get_current_event_state (&state)) - { - if ((state & GDK_CONTROL_MASK) == GDK_CONTROL_MASK) - control_pressed = TRUE; - } + if (gtk_get_current_event_state (&state) && + (state & GDK_CONTROL_MASK) == GDK_CONTROL_MASK) + return FALSE; /* This is a bit evil -- it makes Tab never leave the entry. It basically * makes it 'safe' for people to hit. */ - if (event->keyval == GDK_KEY_Tab && !control_pressed) - { - gint start, end; - - gtk_editable_get_selection_bounds (editable, &start, &end); + gtk_editable_get_selection_bounds (editable, &start, &end); - if (start != end) - gtk_editable_set_position (editable, MAX (start, end)); - else - start_explicit_completion (chooser_entry); - - return TRUE; - } - - return GTK_WIDGET_CLASS (_gtk_file_chooser_entry_parent_class)->key_press_event (widget, event); + if (start != end) + gtk_editable_set_position (editable, MAX (start, end)); + else + start_explicit_completion (chooser_entry); + return TRUE; } static gboolean @@ -432,6 +425,30 @@ gtk_file_chooser_entry_focus_out_event (GtkWidget *widget, return GTK_WIDGET_CLASS (_gtk_file_chooser_entry_parent_class)->focus_out_event (widget, event); } +static void +update_inline_completion (GtkFileChooserEntry *chooser_entry) +{ + GtkEntryCompletion *completion = gtk_entry_get_completion (GTK_ENTRY (chooser_entry)); + + if (!chooser_entry->current_folder_loaded) + { + gtk_entry_completion_set_inline_completion (completion, FALSE); + return; + } + + switch (chooser_entry->action) + { + case GTK_FILE_CHOOSER_ACTION_OPEN: + case GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER: + gtk_entry_completion_set_inline_completion (completion, TRUE); + break; + case GTK_FILE_CHOOSER_ACTION_SAVE: + case GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER: + gtk_entry_completion_set_inline_completion (completion, FALSE); + break; + } +} + static void discard_completion_store (GtkFileChooserEntry *chooser_entry) { @@ -439,7 +456,7 @@ discard_completion_store (GtkFileChooserEntry *chooser_entry) return; gtk_entry_completion_set_model (gtk_entry_get_completion (GTK_ENTRY (chooser_entry)), NULL); - gtk_entry_completion_set_inline_completion (gtk_entry_get_completion (GTK_ENTRY (chooser_entry)), FALSE); + update_inline_completion (chooser_entry); g_object_unref (chooser_entry->completion_store); chooser_entry->completion_store = NULL; } @@ -497,6 +514,9 @@ populate_completion_store (GtkFileChooserEntry *chooser_entry) _gtk_file_system_model_set_filter_folders (GTK_FILE_SYSTEM_MODEL (chooser_entry->completion_store), TRUE); + _gtk_file_system_model_set_show_files (GTK_FILE_SYSTEM_MODEL (chooser_entry->completion_store), + chooser_entry->action == GTK_FILE_CHOOSER_ACTION_OPEN || + chooser_entry->action == GTK_FILE_CHOOSER_ACTION_SAVE); gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (chooser_entry->completion_store), DISPLAY_NAME_COLUMN, GTK_SORT_ASCENDING); @@ -527,7 +547,7 @@ finished_loading_cb (GtkFileSystemModel *model, gtk_widget_set_tooltip_text (GTK_WIDGET (chooser_entry), NULL); completion = gtk_entry_get_completion (GTK_ENTRY (chooser_entry)); - gtk_entry_completion_set_inline_completion (completion, TRUE); + update_inline_completion (chooser_entry); gtk_entry_completion_complete (completion); gtk_entry_completion_insert_prefix (completion); } @@ -710,16 +730,16 @@ void _gtk_file_chooser_entry_set_base_folder (GtkFileChooserEntry *chooser_entry, GFile *file) { + g_return_if_fail (GTK_IS_FILE_CHOOSER_ENTRY (chooser_entry)); + g_return_if_fail (file == NULL || G_IS_FILE (file)); + + if (chooser_entry->base_folder == file || + (file != NULL && chooser_entry->base_folder != NULL + && g_file_equal (chooser_entry->base_folder, file))) + return; + if (file) g_object_ref (file); - else - file = g_file_new_for_path (g_get_home_dir ()); - - if (g_file_equal (chooser_entry->base_folder, file)) - { - g_object_unref (file); - return; - } if (chooser_entry->base_folder) g_object_unref (chooser_entry->base_folder); @@ -815,6 +835,13 @@ _gtk_file_chooser_entry_set_action (GtkFileChooserEntry *chooser_entry, gtk_entry_completion_set_popup_single_match (comp, TRUE); break; } + + if (chooser_entry->completion_store) + _gtk_file_system_model_set_show_files (GTK_FILE_SYSTEM_MODEL (chooser_entry->completion_store), + action == GTK_FILE_CHOOSER_ACTION_OPEN || + action == GTK_FILE_CHOOSER_ACTION_SAVE); + + update_inline_completion (chooser_entry); } }