13
0

Handle Filechooser Location entry

In order for the Filechooser Location widget to work two
things need to be setup, which only the FileChooserDialog
does:
 * subscribe to Widget's "response-requested" signal
 * call should_respond () hook from top-level window's
   default handler.

The Location Entry emits "activates-default". In case of
the Dialog, that calls the dialogs response callback,
which then calls ` _gtk_file_chooser_embed_should_respond`.

That handles changes made by the user to the location entry.

-=-

Gtk::FileChooserWidget does not handle this, "response-requested"
signal is not exposed, nor is _gtk_file_chooser_embed_should_respond
available outside Gtk.

This change at least selects the file in the treeview, which
allows further handling, without interfering with FileChooserDialog's
behavior.
This commit is contained in:
Robin Gareus 2024-09-04 22:29:24 +02:00
parent 26217e9d85
commit 3acc8c76ca
Signed by: rgareus
GPG Key ID: A090BCE02CF57F04

View File

@ -321,6 +321,8 @@ static void gtk_file_chooser_default_get_default_size (GtkFileCh
static gboolean gtk_file_chooser_default_should_respond (GtkFileChooserEmbed *chooser_embed); static gboolean gtk_file_chooser_default_should_respond (GtkFileChooserEmbed *chooser_embed);
static void gtk_file_chooser_default_initial_focus (GtkFileChooserEmbed *chooser_embed); static void gtk_file_chooser_default_initial_focus (GtkFileChooserEmbed *chooser_embed);
static void gtk_file_chooser_activate_location_entry (GtkWidget *item, gpointer user_data);
static void add_selection_to_recent_list (GtkFileChooserDefault *impl); static void add_selection_to_recent_list (GtkFileChooserDefault *impl);
static void location_popup_handler (GtkFileChooserDefault *impl, static void location_popup_handler (GtkFileChooserDefault *impl,
@ -4442,6 +4444,9 @@ location_entry_create (GtkFileChooserDefault *impl)
_gtk_file_chooser_entry_set_local_only (GTK_FILE_CHOOSER_ENTRY (impl->location_entry), impl->local_only); _gtk_file_chooser_entry_set_local_only (GTK_FILE_CHOOSER_ENTRY (impl->location_entry), impl->local_only);
_gtk_file_chooser_entry_set_action (GTK_FILE_CHOOSER_ENTRY (impl->location_entry), impl->action); _gtk_file_chooser_entry_set_action (GTK_FILE_CHOOSER_ENTRY (impl->location_entry), impl->action);
gtk_entry_set_width_chars (GTK_ENTRY (impl->location_entry), 45); gtk_entry_set_width_chars (GTK_ENTRY (impl->location_entry), 45);
if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN)
g_signal_connect (impl->location_entry, "activate", G_CALLBACK (gtk_file_chooser_activate_location_entry), impl);
else
gtk_entry_set_activates_default (GTK_ENTRY (impl->location_entry), TRUE); gtk_entry_set_activates_default (GTK_ENTRY (impl->location_entry), TRUE);
} }
@ -8520,7 +8525,10 @@ file_exists_get_info_cb (GCancellable *cancellable,
else else
{ {
if (file_exists) if (file_exists)
{
gtk_file_chooser_default_select_file (GTK_FILE_CHOOSER (data->impl), data->file, NULL);
request_response_and_add_to_recent_list (data->impl); /* user typed an existing filename; we are done */ request_response_and_add_to_recent_list (data->impl); /* user typed an existing filename; we are done */
}
else else
needs_parent_check = TRUE; /* file doesn't exist; see if its parent exists */ needs_parent_check = TRUE; /* file doesn't exist; see if its parent exists */
} }
@ -8917,6 +8925,68 @@ gtk_file_chooser_default_should_respond (GtkFileChooserEmbed *chooser_embed)
return retval; return retval;
} }
static void
gtk_file_chooser_activate_location_entry (GtkWidget *item, gpointer user_data)
{
/* This is similar to gtk_file_chooser_default_should_respond,
* and used in case the default handler is not activated by
* the location entry.
*/
GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (user_data);
GFile *file;
gboolean is_well_formed, is_empty, is_file_part_empty;
gboolean is_folder;
GtkFileChooserEntry *entry;
GError *error;
g_assert (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN);
entry = GTK_FILE_CHOOSER_ENTRY (impl->location_entry);
check_save_entry (impl, &file, &is_well_formed, &is_empty, &is_file_part_empty, &is_folder);
if (!is_well_formed || is_empty)
return;
g_assert (file != NULL);
error = NULL;
if (is_folder)
{
change_folder_and_display_error (impl, file, TRUE);
}
else
{
struct FileExistsData *data;
/* We need to check whether file exists and whether it is a folder -
* the GtkFileChooserEntry *does* report is_folder==FALSE as a false
* negative (it doesn't know yet if your last path component is a
* folder).
*/
data = g_new0 (struct FileExistsData, 1);
data->impl = g_object_ref (impl);
data->file = g_object_ref (file);
data->parent_file = _gtk_file_chooser_entry_get_current_folder (entry);
if (impl->file_exists_get_info_cancellable)
g_cancellable_cancel (impl->file_exists_get_info_cancellable);
impl->file_exists_get_info_cancellable =
_gtk_file_system_get_info (impl->file_system, file,
"standard::type",
file_exists_get_info_cb,
data);
set_busy_cursor (impl, TRUE);
if (error != NULL)
g_error_free (error);
}
g_object_unref (file);
}
/* Implementation for GtkFileChooserEmbed::initial_focus() */ /* Implementation for GtkFileChooserEmbed::initial_focus() */
static void static void
gtk_file_chooser_default_initial_focus (GtkFileChooserEmbed *chooser_embed) gtk_file_chooser_default_initial_focus (GtkFileChooserEmbed *chooser_embed)