From 45d54fcba62371dcbc1cc4e82797a0eb5aa72747 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Sun, 6 Nov 2011 03:00:47 +0100 Subject: [PATCH] filechooserentry: Use inline completion ... from GtkEntryCompletion instead of implementing a poor copy ourselves. This also makes the file chooser entry behave a lot closer to normal entries. --- gtk/gtkfilechooserentry.c | 106 +++++++------------------------------- 1 file changed, 19 insertions(+), 87 deletions(-) diff --git a/gtk/gtkfilechooserentry.c b/gtk/gtkfilechooserentry.c index 2f6112e0b8..af28d80e5d 100644 --- a/gtk/gtkfilechooserentry.c +++ b/gtk/gtkfilechooserentry.c @@ -48,7 +48,6 @@ struct _GtkFileChooserEntryClass /* Action to take when the current folder finishes loading (for explicit or automatic completion) */ typedef enum { LOAD_COMPLETE_NOTHING, - LOAD_COMPLETE_AUTOCOMPLETE, LOAD_COMPLETE_EXPLICIT_COMPLETION } LoadCompleteAction; @@ -82,7 +81,6 @@ struct _GtkFileChooserEntry guint completion_feedback_timeout_id; guint current_folder_loaded : 1; - guint has_completion : 1; guint in_change : 1; guint eat_tabs : 1; guint local_only : 1; @@ -153,8 +151,6 @@ static RefreshStatus refresh_current_folder_and_file_part (GtkFileChooserEntry * static void finished_loading_cb (GtkFileSystemModel *model, GError *error, GtkFileChooserEntry *chooser_entry); -static void autocomplete (GtkFileChooserEntry *chooser_entry); -static void start_autocompletion (GtkFileChooserEntry *chooser_entry); static void remove_completion_feedback (GtkFileChooserEntry *chooser_entry); static void pop_up_completion_feedback (GtkFileChooserEntry *chooser_entry, const gchar *feedback); @@ -382,7 +378,6 @@ completion_match_func (GtkEntryCompletion *comp, static void clear_completions (GtkFileChooserEntry *chooser_entry) { - chooser_entry->has_completion = FALSE; chooser_entry->load_complete_action = LOAD_COMPLETE_NOTHING; remove_completion_feedback (chooser_entry); @@ -660,9 +655,7 @@ typedef enum { * and mandatorily appends it */ static CommonPrefixResult -append_common_prefix (GtkFileChooserEntry *chooser_entry, - gboolean highlight, - gboolean show_errors) +append_common_prefix (GtkFileChooserEntry *chooser_entry) { gchar *common_prefix; GFile *unique_file; @@ -726,16 +719,7 @@ append_common_prefix (GtkFileChooserEntry *chooser_entry, &pos); chooser_entry->in_change = FALSE; - if (highlight) - { - /* equivalent to cursor_pos + common_prefix_len); */ - gtk_editable_select_region (GTK_EDITABLE (chooser_entry), - cursor_pos, - pos); - chooser_entry->has_completion = TRUE; - } - else - gtk_editable_set_position (GTK_EDITABLE (chooser_entry), pos); + gtk_editable_set_position (GTK_EDITABLE (chooser_entry), pos); } else if (!have_result) { @@ -766,11 +750,6 @@ gtk_file_chooser_entry_do_insert_text (GtkEditable *editable, gint *position) { GtkFileChooserEntry *chooser_entry = GTK_FILE_CHOOSER_ENTRY (editable); - gint old_text_len; - gint insert_pos; - - old_text_len = gtk_entry_get_text_length (GTK_ENTRY (chooser_entry)); - insert_pos = *position; parent_editable_iface->do_insert_text (editable, new_text, new_text_length, position); @@ -778,11 +757,7 @@ gtk_file_chooser_entry_do_insert_text (GtkEditable *editable, return; remove_completion_feedback (chooser_entry); - - if ((chooser_entry->action == GTK_FILE_CHOOSER_ACTION_OPEN - || chooser_entry->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER) - && insert_pos == old_text_len) - start_autocompletion (chooser_entry); + refresh_current_folder_and_file_part (chooser_entry, REFRESH_UP_TO_CURSOR_POSITION); } static void @@ -1055,7 +1030,7 @@ explicitly_complete (GtkFileChooserEntry *chooser_entry) * - If there are no matches at all, beep and bring up a tooltip (done) * - If the suggestion window is already up, scroll it */ - result = append_common_prefix (chooser_entry, FALSE, TRUE); + result = append_common_prefix (chooser_entry); switch (result) { @@ -1198,13 +1173,11 @@ gtk_file_chooser_entry_key_press_event (GtkWidget *widget, { GtkFileChooserEntry *chooser_entry; GtkEditable *editable; - GtkEntry *entry; GdkModifierType state; gboolean control_pressed; chooser_entry = GTK_FILE_CHOOSER_ENTRY (widget); editable = GTK_EDITABLE (widget); - entry = GTK_ENTRY (widget); if (!chooser_entry->eat_tabs) return GTK_WIDGET_CLASS (_gtk_file_chooser_entry_parent_class)->key_press_event (widget, event); @@ -1221,8 +1194,12 @@ gtk_file_chooser_entry_key_press_event (GtkWidget *widget, * makes it 'safe' for people to hit. */ if (event->keyval == GDK_KEY_Tab && !control_pressed) { - if (chooser_entry->has_completion) - gtk_editable_set_position (editable, gtk_entry_get_text_length (entry)); + gint 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); @@ -1247,12 +1224,6 @@ gtk_file_chooser_entry_focus_out_event (GtkWidget *widget, static void commit_completion_and_refresh (GtkFileChooserEntry *chooser_entry) { - if (chooser_entry->has_completion) - { - gtk_editable_set_position (GTK_EDITABLE (chooser_entry), - gtk_entry_get_text_length (GTK_ENTRY (chooser_entry))); - } - /* Here we ignore the result of refresh_current_folder_and_file_part(); there is nothing we can do with it */ refresh_current_folder_and_file_part (chooser_entry, REFRESH_WHOLE_TEXT); } @@ -1273,6 +1244,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); g_object_unref (chooser_entry->completion_store); chooser_entry->completion_store = NULL; } @@ -1342,7 +1314,7 @@ populate_completion_store (GtkFileChooserEntry *chooser_entry) } /* When we finish loading the current folder, this function should get called to - * perform the deferred autocompletion or explicit completion. + * perform the deferred explicit completion. */ static void perform_load_complete_action (GtkFileChooserEntry *chooser_entry) @@ -1352,10 +1324,6 @@ perform_load_complete_action (GtkFileChooserEntry *chooser_entry) case LOAD_COMPLETE_NOTHING: break; - case LOAD_COMPLETE_AUTOCOMPLETE: - autocomplete (chooser_entry); - break; - case LOAD_COMPLETE_EXPLICIT_COMPLETION: explicitly_complete (chooser_entry); break; @@ -1373,6 +1341,8 @@ finished_loading_cb (GtkFileSystemModel *model, GError *error, GtkFileChooserEntry *chooser_entry) { + GtkEntryCompletion *completion; + chooser_entry->current_folder_loaded = TRUE; if (error) @@ -1398,6 +1368,11 @@ finished_loading_cb (GtkFileSystemModel *model, perform_load_complete_action (chooser_entry); 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); + gtk_entry_completion_complete (completion); + gtk_entry_completion_insert_prefix (completion); } static RefreshStatus @@ -1522,49 +1497,6 @@ refresh_current_folder_and_file_part (GtkFileChooserEntry *chooser_entry, return result; } -static void -autocomplete (GtkFileChooserEntry *chooser_entry) -{ - if (!(chooser_entry->current_folder_loaded - && gtk_editable_get_position (GTK_EDITABLE (chooser_entry)) == gtk_entry_get_text_length (GTK_ENTRY (chooser_entry)))) - return; - - append_common_prefix (chooser_entry, TRUE, FALSE); -} - -static void -start_autocompletion (GtkFileChooserEntry *chooser_entry) -{ - RefreshStatus status; - - status = refresh_current_folder_and_file_part (chooser_entry, REFRESH_UP_TO_CURSOR_POSITION); - - switch (status) - { - case REFRESH_OK: - g_assert (chooser_entry->current_folder_file != NULL); - - if (chooser_entry->current_folder_loaded) - autocomplete (chooser_entry); - else - chooser_entry->load_complete_action = LOAD_COMPLETE_AUTOCOMPLETE; - - break; - - case REFRESH_INVALID_INPUT: - case REFRESH_INCOMPLETE_HOSTNAME: - case REFRESH_NONEXISTENT: - case REFRESH_NOT_LOCAL: - /* We don't beep or anything, since this is autocompletion - the user - * didn't request any action explicitly. - */ - break; - - default: - g_assert_not_reached (); - } -} - #ifdef G_OS_WIN32 static gint insert_text_callback (GtkFileChooserEntry *chooser_entry,