diff options
author | Federico Mena Quintero <federico@ximian.com> | 2005-06-10 05:54:28 +0000 |
---|---|---|
committer | Federico Mena Quintero <federico@src.gnome.org> | 2005-06-10 05:54:28 +0000 |
commit | ab44ea2b8cbe72aee536ef478a95c6b0c445a376 (patch) | |
tree | 4f03a78493348e7720f27826f0a8b79df3a416d1 /gtk/gtkfilechooserentry.c | |
parent | 252e7dfa848bd78a72f6bcad98816b5e2d26b168 (diff) | |
download | gtk+-ab44ea2b8cbe72aee536ef478a95c6b0c445a376.tar.gz |
Merged from gtk-2-6:
2005-06-10 Federico Mena Quintero <federico@ximian.com>
Merged from gtk-2-6:
Fixes #162358:
* gtk/gtkfilechooserdefault.c (update_chooser_entry): Don't return
immediately if we are in CREATE_FOLDER mode, so that we can fill
the entry with the newly-selected folder.
(gtk_file_chooser_default_set_property): Warn against turning on
multiple selection for CREATE_FOLDER mode, or about setting that
action while multiple selection is on.
(update_chooser_entry): Change the entry's contents as well if we
are in CREATE_FOLDER mode. If nothing is selected, clear the
chooser entry.
(trap_activate_cb): Don't trap enter/space if modifiers are
pressed. This lets one use Ctrl-space to toggle rows in multiple
selection mode.
(gtk_file_chooser_default_should_respond): Clean up the if-chain
mess of special cases by using an array to determine what to do.
Also, for the save-entry case in CREATE_FOLDER mode, actually fix
the bug where the file chooser would switch to an existing folder
rather than confirming with it, and create the folder ourselves.
(error_creating_folder_over_existing_file_dialog): New function.
* gtk/gtkfilechooserentry.c (check_completion_callback): Only
insert the common prefix if we are in an "open" mode. Use a
helper function.
(append_common_prefix): New helper function; code moved over from
check_completion_callback().
(find_common_prefix): New helper function.
(gtk_file_chooser_entry_focus): Append the common prefix if the
user requests it explicitly.
Diffstat (limited to 'gtk/gtkfilechooserentry.c')
-rw-r--r-- | gtk/gtkfilechooserentry.c | 123 |
1 files changed, 76 insertions, 47 deletions
diff --git a/gtk/gtkfilechooserentry.c b/gtk/gtkfilechooserentry.c index 97b0f2327f..4967832b90 100644 --- a/gtk/gtkfilechooserentry.c +++ b/gtk/gtkfilechooserentry.c @@ -384,28 +384,25 @@ maybe_append_separator_to_path (GtkFileChooserEntry *chooser_entry, return display_name; } -static gboolean -check_completion_callback (GtkFileChooserEntry *chooser_entry) +/* Determines if the completion model has entries with a common prefix relative + * to the current contents of the entry. Also, if there's one and only one such + * path, stores it in unique_path_ret. + */ +static void +find_common_prefix (GtkFileChooserEntry *chooser_entry, + gchar **common_prefix_ret, + GtkFilePath **unique_path_ret) { GtkTreeIter iter; - gchar *common_prefix = NULL; - GtkFilePath *unique_path = NULL; gboolean valid; - GDK_THREADS_ENTER (); - - g_assert (chooser_entry->file_part); - - chooser_entry->check_completion_idle = NULL; - - if (strcmp (chooser_entry->file_part, "") == 0) - goto done; + *common_prefix_ret = NULL; + *unique_path_ret = NULL; if (chooser_entry->completion_store == NULL) - goto done; + return; - valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (chooser_entry->completion_store), - &iter); + valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (chooser_entry->completion_store), &iter); while (valid) { @@ -420,14 +417,14 @@ check_completion_callback (GtkFileChooserEntry *chooser_entry) if (g_str_has_prefix (display_name, chooser_entry->file_part)) { - if (!common_prefix) + if (!*common_prefix_ret) { - common_prefix = g_strdup (display_name); - unique_path = gtk_file_path_copy (path); + *common_prefix_ret = g_strdup (display_name); + *unique_path_ret = gtk_file_path_copy (path); } else { - gchar *p = common_prefix; + gchar *p = *common_prefix_ret; const gchar *q = display_name; while (*p && *p == *q) @@ -438,16 +435,26 @@ check_completion_callback (GtkFileChooserEntry *chooser_entry) *p = '\0'; - gtk_file_path_free (unique_path); - unique_path = NULL; + gtk_file_path_free (*unique_path_ret); + *unique_path_ret = NULL; } } g_free (display_name); gtk_file_path_free (path); - valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (chooser_entry->completion_store), - &iter); + valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (chooser_entry->completion_store), &iter); } +} + +/* Finds a common prefix based on the contents of the entry and mandatorily appends it */ +static void +append_common_prefix (GtkFileChooserEntry *chooser_entry, + gboolean highlight) +{ + gchar *common_prefix; + GtkFilePath *unique_path; + + find_common_prefix (chooser_entry, &common_prefix, &unique_path); if (unique_path) { @@ -457,19 +464,6 @@ check_completion_callback (GtkFileChooserEntry *chooser_entry) gtk_file_path_free (unique_path); } - switch (chooser_entry->action) - { - case GTK_FILE_CHOOSER_ACTION_SAVE: - case GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER: - if (common_prefix && !g_str_has_suffix (common_prefix, "/")) - { - g_free (common_prefix); - common_prefix = NULL; - } - break; - default: ; - } - if (common_prefix) { gint file_part_len; @@ -489,16 +483,40 @@ check_completion_callback (GtkFileChooserEntry *chooser_entry) gtk_editable_insert_text (GTK_EDITABLE (chooser_entry), common_prefix, -1, &pos); - gtk_editable_select_region (GTK_EDITABLE (chooser_entry), - chooser_entry->file_part_pos + file_part_len, - chooser_entry->file_part_pos + common_prefix_len); chooser_entry->in_change = FALSE; - chooser_entry->has_completion = TRUE; + if (highlight) + { + gtk_editable_select_region (GTK_EDITABLE (chooser_entry), + chooser_entry->file_part_pos + file_part_len, + chooser_entry->file_part_pos + common_prefix_len); + chooser_entry->has_completion = TRUE; + } } - + g_free (common_prefix); } +} + +static gboolean +check_completion_callback (GtkFileChooserEntry *chooser_entry) +{ + GDK_THREADS_ENTER (); + + g_assert (chooser_entry->file_part); + + chooser_entry->check_completion_idle = NULL; + + if (strcmp (chooser_entry->file_part, "") == 0) + goto done; + + /* We only insert the common prefix without requiring the user to hit Tab in + * the "open" modes. For "save" modes, the user must hit Tab to cause the prefix + * to be inserted. That happens in gtk_file_chooser_entry_focus(). + */ + if (chooser_entry->action == GTK_FILE_CHOOSER_ACTION_OPEN + || chooser_entry->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER) + append_common_prefix (chooser_entry, TRUE); done: @@ -660,13 +678,21 @@ static gboolean gtk_file_chooser_entry_focus (GtkWidget *widget, GtkDirectionType direction) { - GtkFileChooserEntry *chooser_entry = GTK_FILE_CHOOSER_ENTRY (widget); + GtkFileChooserEntry *chooser_entry; + GtkEditable *editable; + GtkEntry *entry; GdkModifierType state; - gboolean control_pressed = FALSE; + 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 (parent_class)->focus (widget, direction); + control_pressed = FALSE; + if (gtk_get_current_event_state (&state)) { if ((state & GDK_CONTROL_MASK) == GDK_CONTROL_MASK) @@ -681,13 +707,16 @@ gtk_file_chooser_entry_focus (GtkWidget *widget, { gint pos = 0; - if (chooser_entry->has_completion) - gtk_editable_set_position (GTK_EDITABLE (widget), - GTK_ENTRY (widget)->text_length); + if (!chooser_entry->has_completion + && gtk_editable_get_position (editable) == entry->text_length) + append_common_prefix (chooser_entry, FALSE); + + gtk_editable_set_position (editable, entry->text_length); + /* Trigger the completion window to pop up again by a * zero-length insertion, a bit of a hack. */ - gtk_editable_insert_text (GTK_EDITABLE (widget), "", -1, &pos); + gtk_editable_insert_text (editable, "", -1, &pos); return TRUE; } |