forked from AuroraMiddleware/gtk
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.
This commit is contained in:
parent
252e7dfa84
commit
ab44ea2b8c
34
ChangeLog
34
ChangeLog
@ -1,3 +1,37 @@
|
|||||||
|
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.
|
||||||
|
|
||||||
2005-06-10 Matthias Clasen <mclasen@redhat.com>
|
2005-06-10 Matthias Clasen <mclasen@redhat.com>
|
||||||
|
|
||||||
* gtk/gtktreeviewcolumn.c (gtk_tree_view_column_set_expand):
|
* gtk/gtktreeviewcolumn.c (gtk_tree_view_column_set_expand):
|
||||||
|
@ -1,3 +1,37 @@
|
|||||||
|
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.
|
||||||
|
|
||||||
2005-06-10 Matthias Clasen <mclasen@redhat.com>
|
2005-06-10 Matthias Clasen <mclasen@redhat.com>
|
||||||
|
|
||||||
* gtk/gtktreeviewcolumn.c (gtk_tree_view_column_set_expand):
|
* gtk/gtktreeviewcolumn.c (gtk_tree_view_column_set_expand):
|
||||||
|
@ -1,3 +1,37 @@
|
|||||||
|
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.
|
||||||
|
|
||||||
2005-06-10 Matthias Clasen <mclasen@redhat.com>
|
2005-06-10 Matthias Clasen <mclasen@redhat.com>
|
||||||
|
|
||||||
* gtk/gtktreeviewcolumn.c (gtk_tree_view_column_set_expand):
|
* gtk/gtktreeviewcolumn.c (gtk_tree_view_column_set_expand):
|
||||||
|
@ -951,6 +951,21 @@ error_creating_folder_dialog (GtkFileChooserDefault *impl,
|
|||||||
path, error);
|
path, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Shows an error about not being able to create a folder because a file with
|
||||||
|
* the same name is already there.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
error_creating_folder_over_existing_file_dialog (GtkFileChooserDefault *impl,
|
||||||
|
const GtkFilePath *path,
|
||||||
|
GError *error)
|
||||||
|
{
|
||||||
|
error_dialog (impl,
|
||||||
|
_("The folder could not be created, as a file with the same name "
|
||||||
|
"already exists. Try using a different name for the folder, "
|
||||||
|
"or rename the file first."),
|
||||||
|
path, error);
|
||||||
|
}
|
||||||
|
|
||||||
/* Shows an error dialog about not being able to create a filename */
|
/* Shows an error dialog about not being able to create a filename */
|
||||||
static void
|
static void
|
||||||
error_building_filename_dialog (GtkFileChooserDefault *impl,
|
error_building_filename_dialog (GtkFileChooserDefault *impl,
|
||||||
@ -3209,11 +3224,14 @@ trap_activate_cb (GtkWidget *widget,
|
|||||||
gpointer data)
|
gpointer data)
|
||||||
{
|
{
|
||||||
GtkFileChooserDefault *impl;
|
GtkFileChooserDefault *impl;
|
||||||
|
int modifiers;
|
||||||
|
|
||||||
impl = (GtkFileChooserDefault *) data;
|
impl = (GtkFileChooserDefault *) data;
|
||||||
|
|
||||||
|
modifiers = gtk_accelerator_get_default_mod_mask ();
|
||||||
|
|
||||||
if (event->keyval == GDK_slash &&
|
if (event->keyval == GDK_slash &&
|
||||||
! (event->state & (~GDK_SHIFT_MASK & gtk_accelerator_get_default_mod_mask ())))
|
! (event->state & (~GDK_SHIFT_MASK & modifiers)))
|
||||||
{
|
{
|
||||||
location_popup_handler (impl, "/");
|
location_popup_handler (impl, "/");
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@ -3223,6 +3241,7 @@ trap_activate_cb (GtkWidget *widget,
|
|||||||
|| event->keyval == GDK_ISO_Enter
|
|| event->keyval == GDK_ISO_Enter
|
||||||
|| event->keyval == GDK_KP_Enter
|
|| event->keyval == GDK_KP_Enter
|
||||||
|| event->keyval == GDK_space)
|
|| event->keyval == GDK_space)
|
||||||
|
&& ((event->state && modifiers) == 0)
|
||||||
&& !(impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ||
|
&& !(impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ||
|
||||||
impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER))
|
impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER))
|
||||||
{
|
{
|
||||||
@ -4056,9 +4075,12 @@ gtk_file_chooser_default_set_property (GObject *object,
|
|||||||
{
|
{
|
||||||
gtk_file_chooser_default_unselect_all (GTK_FILE_CHOOSER (impl));
|
gtk_file_chooser_default_unselect_all (GTK_FILE_CHOOSER (impl));
|
||||||
|
|
||||||
if (action == GTK_FILE_CHOOSER_ACTION_SAVE && impl->select_multiple)
|
if ((action == GTK_FILE_CHOOSER_ACTION_SAVE || action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
|
||||||
|
&& impl->select_multiple)
|
||||||
{
|
{
|
||||||
g_warning ("Multiple selection mode is not allowed in Save mode");
|
g_warning ("Tried to change the file chooser action to SAVE or CREATE_FOLDER, but "
|
||||||
|
"this is not allowed in multiple selection mode. Resetting the file chooser "
|
||||||
|
"to single selection mode.");
|
||||||
set_select_multiple (impl, FALSE, TRUE);
|
set_select_multiple (impl, FALSE, TRUE);
|
||||||
}
|
}
|
||||||
impl->action = action;
|
impl->action = action;
|
||||||
@ -4096,9 +4118,12 @@ gtk_file_chooser_default_set_property (GObject *object,
|
|||||||
case GTK_FILE_CHOOSER_PROP_SELECT_MULTIPLE:
|
case GTK_FILE_CHOOSER_PROP_SELECT_MULTIPLE:
|
||||||
{
|
{
|
||||||
gboolean select_multiple = g_value_get_boolean (value);
|
gboolean select_multiple = g_value_get_boolean (value);
|
||||||
if (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE && select_multiple)
|
if ((impl->action == GTK_FILE_CHOOSER_ACTION_SAVE || impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
|
||||||
|
&& select_multiple)
|
||||||
{
|
{
|
||||||
g_warning ("Multiple selection mode is not allowed in Save mode");
|
g_warning ("Tried to set the file chooser to multiple selection mode, but this is "
|
||||||
|
"not allowed in SAVE or CREATE_FOLDER modes. Ignoring the change and "
|
||||||
|
"leaving the file chooser in single selection mode.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4899,15 +4924,19 @@ update_chooser_entry (GtkFileChooserDefault *impl)
|
|||||||
const GtkFileInfo *info;
|
const GtkFileInfo *info;
|
||||||
GtkTreeIter iter;
|
GtkTreeIter iter;
|
||||||
GtkTreeIter child_iter;
|
GtkTreeIter child_iter;
|
||||||
|
gboolean change_entry;
|
||||||
|
|
||||||
if (impl->action != GTK_FILE_CHOOSER_ACTION_SAVE)
|
if (!(impl->action == GTK_FILE_CHOOSER_ACTION_SAVE || impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
g_assert (!impl->select_multiple);
|
g_assert (!impl->select_multiple);
|
||||||
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
|
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
|
||||||
|
|
||||||
if (!gtk_tree_selection_get_selected (selection, NULL, &iter))
|
if (!gtk_tree_selection_get_selected (selection, NULL, &iter))
|
||||||
return;
|
{
|
||||||
|
_gtk_file_chooser_entry_set_file_part (GTK_FILE_CHOOSER_ENTRY (impl->save_file_name_entry), "");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
gtk_tree_model_sort_convert_iter_to_child_iter (impl->sort_model,
|
gtk_tree_model_sort_convert_iter_to_child_iter (impl->sort_model,
|
||||||
&child_iter,
|
&child_iter,
|
||||||
@ -4915,7 +4944,12 @@ update_chooser_entry (GtkFileChooserDefault *impl)
|
|||||||
|
|
||||||
info = _gtk_file_system_model_get_info (impl->browse_files_model, &child_iter);
|
info = _gtk_file_system_model_get_info (impl->browse_files_model, &child_iter);
|
||||||
|
|
||||||
if (!gtk_file_info_get_is_folder (info))
|
if (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE)
|
||||||
|
change_entry = !gtk_file_info_get_is_folder (info); /* We don't want the name to change when clicking on a folder... */
|
||||||
|
else
|
||||||
|
change_entry = TRUE; /* ... unless we are in CREATE_FOLDER mode */
|
||||||
|
|
||||||
|
if (change_entry)
|
||||||
_gtk_file_chooser_entry_set_file_part (GTK_FILE_CHOOSER_ENTRY (impl->save_file_name_entry),
|
_gtk_file_chooser_entry_set_file_part (GTK_FILE_CHOOSER_ENTRY (impl->save_file_name_entry),
|
||||||
gtk_file_info_get_display_name (info));
|
gtk_file_info_get_display_name (info));
|
||||||
}
|
}
|
||||||
@ -5644,41 +5678,75 @@ gtk_file_chooser_default_should_respond (GtkFileChooserEmbed *chooser_embed)
|
|||||||
|
|
||||||
if (current_focus == impl->browse_files_tree_view)
|
if (current_focus == impl->browse_files_tree_view)
|
||||||
{
|
{
|
||||||
|
/* The following array encodes what we do based on the impl->action and the
|
||||||
|
* number of files selected.
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
NOOP, /* Do nothing (don't respond) */
|
||||||
|
RESPOND, /* Respond immediately */
|
||||||
|
RESPOND_OR_SWITCH, /* Respond immediately if the selected item is a file; switch to it if it is a folder */
|
||||||
|
ALL_FILES, /* Respond only if everything selected is a file */
|
||||||
|
ALL_FOLDERS, /* Respond only if everything selected is a folder */
|
||||||
|
SAVE_ENTRY, /* Go to the code for handling the save entry */
|
||||||
|
NOT_REACHED /* Sanity check */
|
||||||
|
} ActionToTake;
|
||||||
|
static const ActionToTake what_to_do[4][3] = {
|
||||||
|
/* 0 selected 1 selected many selected */
|
||||||
|
/* ACTION_OPEN */ { NOOP, RESPOND_OR_SWITCH, ALL_FILES },
|
||||||
|
/* ACTION_SAVE */ { SAVE_ENTRY, RESPOND_OR_SWITCH, NOT_REACHED },
|
||||||
|
/* ACTION_SELECT_FOLDER */ { RESPOND, ALL_FOLDERS, ALL_FOLDERS },
|
||||||
|
/* ACTION_CREATE_FOLDER */ { SAVE_ENTRY, ALL_FOLDERS, NOT_REACHED }
|
||||||
|
};
|
||||||
|
|
||||||
int num_selected;
|
int num_selected;
|
||||||
gboolean all_files, all_folders;
|
gboolean all_files, all_folders;
|
||||||
|
int k;
|
||||||
|
ActionToTake action;
|
||||||
|
|
||||||
file_list:
|
file_list:
|
||||||
|
|
||||||
|
g_assert (impl->action >= GTK_FILE_CHOOSER_ACTION_OPEN && impl->action <= GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER);
|
||||||
|
|
||||||
selection_check (impl, &num_selected, &all_files, &all_folders);
|
selection_check (impl, &num_selected, &all_files, &all_folders);
|
||||||
|
|
||||||
if (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)
|
if (num_selected > 2)
|
||||||
{
|
k = 2;
|
||||||
if (num_selected != 1)
|
|
||||||
return TRUE; /* zero means current folder; more than one means use the whole selection */
|
|
||||||
else if (current_focus != impl->browse_files_tree_view)
|
|
||||||
{
|
|
||||||
/* a single folder is selected and a button was clicked */
|
|
||||||
switch_to_selected_folder (impl);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (num_selected == 0)
|
|
||||||
{
|
|
||||||
if (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE
|
|
||||||
|| impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
|
|
||||||
goto save_entry; /* it makes sense to use the typed name */
|
|
||||||
else
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (num_selected == 1 && all_folders)
|
|
||||||
{
|
|
||||||
switch_to_selected_folder (impl);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
return all_files;
|
k = num_selected;
|
||||||
|
|
||||||
|
action = what_to_do [impl->action] [k];
|
||||||
|
|
||||||
|
switch (action)
|
||||||
|
{
|
||||||
|
case NOOP:
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
case RESPOND:
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
case RESPOND_OR_SWITCH:
|
||||||
|
g_assert (num_selected == 1);
|
||||||
|
|
||||||
|
if (all_folders)
|
||||||
|
{
|
||||||
|
switch_to_selected_folder (impl);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
case ALL_FILES:
|
||||||
|
return all_files;
|
||||||
|
|
||||||
|
case ALL_FOLDERS:
|
||||||
|
return all_folders;
|
||||||
|
|
||||||
|
case SAVE_ENTRY:
|
||||||
|
goto save_entry;
|
||||||
|
|
||||||
|
default:
|
||||||
|
g_assert_not_reached ();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (current_focus == impl->save_file_name_entry)
|
else if (current_focus == impl->save_file_name_entry)
|
||||||
{
|
{
|
||||||
@ -5686,7 +5754,8 @@ gtk_file_chooser_default_should_respond (GtkFileChooserEmbed *chooser_embed)
|
|||||||
gboolean is_valid, is_empty;
|
gboolean is_valid, is_empty;
|
||||||
gboolean is_folder;
|
gboolean is_folder;
|
||||||
gboolean retval;
|
gboolean retval;
|
||||||
GtkFileChooserEntry *entry;
|
GtkFileChooserEntry *entry;
|
||||||
|
GError *error;
|
||||||
|
|
||||||
save_entry:
|
save_entry:
|
||||||
|
|
||||||
@ -5696,32 +5765,67 @@ gtk_file_chooser_default_should_respond (GtkFileChooserEmbed *chooser_embed)
|
|||||||
entry = GTK_FILE_CHOOSER_ENTRY (impl->save_file_name_entry);
|
entry = GTK_FILE_CHOOSER_ENTRY (impl->save_file_name_entry);
|
||||||
path = check_save_entry (impl, &is_valid, &is_empty);
|
path = check_save_entry (impl, &is_valid, &is_empty);
|
||||||
|
|
||||||
if (!is_empty && !is_valid)
|
if (!is_valid)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (is_empty)
|
g_assert (!is_empty);
|
||||||
path = gtk_file_path_copy (_gtk_file_chooser_entry_get_current_folder (entry));
|
|
||||||
|
error = NULL;
|
||||||
is_folder = check_is_folder (impl->file_system, path, NULL);
|
is_folder = check_is_folder (impl->file_system, path, &error);
|
||||||
if (is_folder)
|
if (is_folder)
|
||||||
{
|
{
|
||||||
_gtk_file_chooser_entry_set_file_part (entry, "");
|
if (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE)
|
||||||
change_folder_and_display_error (impl, path);
|
|
||||||
retval = FALSE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* check that everything up to the last component exists */
|
|
||||||
gtk_file_path_free (path);
|
|
||||||
path = gtk_file_path_copy (_gtk_file_chooser_entry_get_current_folder (entry));
|
|
||||||
is_folder = check_is_folder (impl->file_system, path, NULL);
|
|
||||||
if (!is_folder)
|
|
||||||
{
|
{
|
||||||
|
_gtk_file_chooser_entry_set_file_part (entry, "");
|
||||||
change_folder_and_display_error (impl, path);
|
change_folder_and_display_error (impl, path);
|
||||||
retval = FALSE;
|
retval = FALSE;
|
||||||
}
|
}
|
||||||
|
else /* GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER */
|
||||||
|
{
|
||||||
|
retval = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER
|
||||||
|
&& g_error_matches (error, GTK_FILE_SYSTEM_ERROR, GTK_FILE_SYSTEM_ERROR_NOT_FOLDER))
|
||||||
|
{
|
||||||
|
/* Oops, the user typed the name of an existing path which is not a folder */
|
||||||
|
error_creating_folder_over_existing_file_dialog (impl, path, error);
|
||||||
|
retval = FALSE;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
retval = TRUE;
|
{
|
||||||
|
GtkFilePath *parent_path;
|
||||||
|
|
||||||
|
/* check that everything up to the last component exists */
|
||||||
|
|
||||||
|
parent_path = gtk_file_path_copy (_gtk_file_chooser_entry_get_current_folder (entry));
|
||||||
|
is_folder = check_is_folder (impl->file_system, parent_path, NULL);
|
||||||
|
if (!is_folder)
|
||||||
|
{
|
||||||
|
change_folder_and_display_error (impl, parent_path);
|
||||||
|
retval = FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GError *create_error;
|
||||||
|
|
||||||
|
create_error = NULL;
|
||||||
|
if (gtk_file_system_create_folder (impl->file_system, path, &create_error))
|
||||||
|
retval = TRUE;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
error_creating_folder_dialog (impl, path, create_error);
|
||||||
|
retval = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gtk_file_path_free (parent_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error != NULL)
|
||||||
|
g_error_free (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
gtk_file_path_free (path);
|
gtk_file_path_free (path);
|
||||||
|
@ -384,28 +384,25 @@ maybe_append_separator_to_path (GtkFileChooserEntry *chooser_entry,
|
|||||||
return display_name;
|
return display_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
/* Determines if the completion model has entries with a common prefix relative
|
||||||
check_completion_callback (GtkFileChooserEntry *chooser_entry)
|
* 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;
|
GtkTreeIter iter;
|
||||||
gchar *common_prefix = NULL;
|
|
||||||
GtkFilePath *unique_path = NULL;
|
|
||||||
gboolean valid;
|
gboolean valid;
|
||||||
|
|
||||||
GDK_THREADS_ENTER ();
|
*common_prefix_ret = NULL;
|
||||||
|
*unique_path_ret = NULL;
|
||||||
g_assert (chooser_entry->file_part);
|
|
||||||
|
|
||||||
chooser_entry->check_completion_idle = NULL;
|
|
||||||
|
|
||||||
if (strcmp (chooser_entry->file_part, "") == 0)
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
if (chooser_entry->completion_store == NULL)
|
if (chooser_entry->completion_store == NULL)
|
||||||
goto done;
|
return;
|
||||||
|
|
||||||
valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (chooser_entry->completion_store),
|
valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (chooser_entry->completion_store), &iter);
|
||||||
&iter);
|
|
||||||
|
|
||||||
while (valid)
|
while (valid)
|
||||||
{
|
{
|
||||||
@ -420,14 +417,14 @@ check_completion_callback (GtkFileChooserEntry *chooser_entry)
|
|||||||
|
|
||||||
if (g_str_has_prefix (display_name, chooser_entry->file_part))
|
if (g_str_has_prefix (display_name, chooser_entry->file_part))
|
||||||
{
|
{
|
||||||
if (!common_prefix)
|
if (!*common_prefix_ret)
|
||||||
{
|
{
|
||||||
common_prefix = g_strdup (display_name);
|
*common_prefix_ret = g_strdup (display_name);
|
||||||
unique_path = gtk_file_path_copy (path);
|
*unique_path_ret = gtk_file_path_copy (path);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
gchar *p = common_prefix;
|
gchar *p = *common_prefix_ret;
|
||||||
const gchar *q = display_name;
|
const gchar *q = display_name;
|
||||||
|
|
||||||
while (*p && *p == *q)
|
while (*p && *p == *q)
|
||||||
@ -438,16 +435,26 @@ check_completion_callback (GtkFileChooserEntry *chooser_entry)
|
|||||||
|
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
|
|
||||||
gtk_file_path_free (unique_path);
|
gtk_file_path_free (*unique_path_ret);
|
||||||
unique_path = NULL;
|
*unique_path_ret = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
g_free (display_name);
|
g_free (display_name);
|
||||||
gtk_file_path_free (path);
|
gtk_file_path_free (path);
|
||||||
valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (chooser_entry->completion_store),
|
valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (chooser_entry->completion_store), &iter);
|
||||||
&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)
|
if (unique_path)
|
||||||
{
|
{
|
||||||
@ -457,19 +464,6 @@ check_completion_callback (GtkFileChooserEntry *chooser_entry)
|
|||||||
gtk_file_path_free (unique_path);
|
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)
|
if (common_prefix)
|
||||||
{
|
{
|
||||||
gint file_part_len;
|
gint file_part_len;
|
||||||
@ -489,16 +483,40 @@ check_completion_callback (GtkFileChooserEntry *chooser_entry)
|
|||||||
gtk_editable_insert_text (GTK_EDITABLE (chooser_entry),
|
gtk_editable_insert_text (GTK_EDITABLE (chooser_entry),
|
||||||
common_prefix, -1,
|
common_prefix, -1,
|
||||||
&pos);
|
&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->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);
|
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:
|
done:
|
||||||
|
|
||||||
@ -660,13 +678,21 @@ static gboolean
|
|||||||
gtk_file_chooser_entry_focus (GtkWidget *widget,
|
gtk_file_chooser_entry_focus (GtkWidget *widget,
|
||||||
GtkDirectionType direction)
|
GtkDirectionType direction)
|
||||||
{
|
{
|
||||||
GtkFileChooserEntry *chooser_entry = GTK_FILE_CHOOSER_ENTRY (widget);
|
GtkFileChooserEntry *chooser_entry;
|
||||||
|
GtkEditable *editable;
|
||||||
|
GtkEntry *entry;
|
||||||
GdkModifierType state;
|
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)
|
if (!chooser_entry->eat_tabs)
|
||||||
return GTK_WIDGET_CLASS (parent_class)->focus (widget, direction);
|
return GTK_WIDGET_CLASS (parent_class)->focus (widget, direction);
|
||||||
|
|
||||||
|
control_pressed = FALSE;
|
||||||
|
|
||||||
if (gtk_get_current_event_state (&state))
|
if (gtk_get_current_event_state (&state))
|
||||||
{
|
{
|
||||||
if ((state & GDK_CONTROL_MASK) == GDK_CONTROL_MASK)
|
if ((state & GDK_CONTROL_MASK) == GDK_CONTROL_MASK)
|
||||||
@ -681,13 +707,16 @@ gtk_file_chooser_entry_focus (GtkWidget *widget,
|
|||||||
{
|
{
|
||||||
gint pos = 0;
|
gint pos = 0;
|
||||||
|
|
||||||
if (chooser_entry->has_completion)
|
if (!chooser_entry->has_completion
|
||||||
gtk_editable_set_position (GTK_EDITABLE (widget),
|
&& gtk_editable_get_position (editable) == entry->text_length)
|
||||||
GTK_ENTRY (widget)->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
|
/* Trigger the completion window to pop up again by a
|
||||||
* zero-length insertion, a bit of a hack.
|
* 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;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user