After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 545980 - GtkFileChooserEntry doesn't handle uris properly
GtkFileChooserEntry doesn't handle uris properly
Status: RESOLVED FIXED
Product: gtk+
Classification: Platform
Component: Widget: GtkFileChooser
unspecified
Other Linux
: Normal normal
: ---
Assigned To: Federico Mena Quintero
Federico Mena Quintero
: 139261 559626 569506 (view as bug list)
Depends on:
Blocks: 561494
 
 
Reported: 2008-08-02 13:27 UTC by Carlos Garnacho
Modified: 2013-05-25 03:15 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
patch (7.91 KB, patch)
2008-08-02 13:28 UTC, Carlos Garnacho
none Details | Review
[PATCH] Fix gtk_file_system_parse() to accept full URIs. (514 bytes, patch)
2008-08-09 17:51 UTC, Carlos Garnacho
none Details | Review
[PATCH] Mount the enclosing volume if the folder we're switching to is not mounted. (2.21 KB, patch)
2008-08-09 17:51 UTC, Carlos Garnacho
needs-work Details | Review
[PATCH] Discard correctly the current folder. (3.92 KB, patch)
2008-08-09 17:51 UTC, Carlos Garnacho
none Details | Review
[PATCH] Add local_only to GtkFileChooserEntry. (3.37 KB, patch)
2008-08-09 17:52 UTC, Carlos Garnacho
none Details | Review
[PATCH] Mount the enclosing volume if the folder we're switching to is not mounted. (2.37 KB, patch)
2008-11-18 16:27 UTC, Tomas Bzatek
committed Details | Review
Updated patchset based on Garnacho's patches (21.62 KB, patch)
2009-01-21 03:20 UTC, Federico Mena Quintero
committed Details | Review

Description Carlos Garnacho 2008-08-02 13:27:38 UTC
Hi!

the filechooser location entry doesn't work fine with uris. I'm attaching a patch that fixes the following issues:

- Parses uris correctly
- Mounts the activated uri if it wasn't mounted
- Adds local_only API to the filechooser entry, so it doesn't autocomplete remote uris if the filechooser has local_only=TRUE
- Some oddities found while autocompleting remote/slow uris
Comment 1 Carlos Garnacho 2008-08-02 13:28:05 UTC
Created attachment 115730 [details] [review]
patch
Comment 2 Alexander “weej” Jones 2008-08-02 13:28:39 UTC
Just hit this bug yesterday too, good work!
Comment 3 Christian Dywan 2008-08-02 13:53:10 UTC
Awesome, that is just what I was missing ^_^
Comment 4 Matthias Clasen 2008-08-03 14:42:31 UTC
Might be nice to break out the addition of local-only to the entry as a separate patch.

+          impl->update_current_folder_cancellable =
+            _gtk_file_system_mount_enclosing_volume (impl->file_system, [...]

This had me confused. The filesystem methods really need documentation about the lifecycle handling of the returned cancellable objects.

+  if (chooser_entry->local_only &&
+      !g_file_is_native (chooser_entry->current_folder_file))
+    return;

I haven't tried this patch, so I don't know how this behaves, but I wonder if it would be a good idea to pop up one of those completion tooltips explaining that this file chooser can only do local files. Otherwise users might be confused if some file choosers complete remote files in the entry and some don't.
Comment 5 Matthias Clasen 2008-08-03 21:41:22 UTC
*** Bug 139261 has been marked as a duplicate of this bug. ***
Comment 6 Carlos Garnacho 2008-08-04 15:07:04 UTC
(In reply to comment #4)
> Might be nice to break out the addition of local-only to the entry as a
> separate patch.
> 
> +          impl->update_current_folder_cancellable =
> +            _gtk_file_system_mount_enclosing_volume (impl->file_system, [...]
> 
> This had me confused. The filesystem methods really need documentation about
> the lifecycle handling of the returned cancellable objects.

Basically, since the callbacks are ensured to be called, you could just not keep track of the cancellable, and just unref it in the callback.

So the async filesystem methods return the GCancellable so you can cancel these operations (and the callback will unref it). Basically I'm reusing the cancellable pointer in impl because both the get_folder() and mount_enclosing_volume() will run sequentially (if needed) and given the case you want the overall operation to be cancelled at any point.

> 
> +  if (chooser_entry->local_only &&
> +      !g_file_is_native (chooser_entry->current_folder_file))
> +    return;
> 
> I haven't tried this patch, so I don't know how this behaves, but I wonder if
> it would be a good idea to pop up one of those completion tooltips explaining
> that this file chooser can only do local files. Otherwise users might be
> confused if some file choosers complete remote files in the entry and some
> don't.

Yeah, sounds worthwhile, I'll work on splitting the local-only changes and get this done.
Comment 7 Federico Mena Quintero 2008-08-05 22:29:26 UTC
Nice work, Garnacho :)

Matthias is right; please split the patch into three patches:

1. Mount the volume if unmounted.

2. Disconnect from the folder in gtkfilechooserentry.c, call discard_completion_store(), cancel the cancellables.  For the first part, there are three places in the code that do disconnect()/unref()/nullify - please factor that out into a discard_current_folder() function.

3. Add support for local_only; see the following.

When you do explicit completion by hitting Tab, the code goes like this:

start_explicit_completion()
  refresh_current_folder_and_file_part()
    reload_current_folder()
      start_loading_current_folder()
        _gtk_file_system_get_folder(), and your code to check for local_only

When refresh_current_folder_and_file_part() returns, start_explicit_completion() has this check:

  if (!chooser_entry->current_folder_file)
    {
      /* Here, no folder path means we couldn't parse what the user typed. */

which is of course pretty ad-hoc :)

The *other* place that calls refresh_current_folder_and_file_part() and has a more or less similar check is in start_autocompletion().

So, the main problem is how to propagate the information from start_loading_current_folder() up to those two callers --- "I refused to start loading the current_folder_file because it's not a local file".  You may want to add a new flag or something, so that you can distinguish that case from the normal "user typed something bogus".

Once you have that information, you can simply call pop_up_completion_feedback() with a suitable message.
Comment 8 Carlos Garnacho 2008-08-09 17:51:16 UTC
Created attachment 116249 [details] [review]
[PATCH] Fix gtk_file_system_parse() to accept full URIs.

 gtk/gtkfilesystem.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
Comment 9 Carlos Garnacho 2008-08-09 17:51:37 UTC
Created attachment 116250 [details] [review]
[PATCH] Mount the enclosing volume if the folder we're switching to is not mounted.

 gtk/gtkfilechooserdefault.c |   47 +++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 47 insertions(+), 0 deletions(-)
Comment 10 Carlos Garnacho 2008-08-09 17:51:58 UTC
Created attachment 116251 [details] [review]
[PATCH] Discard correctly the current folder.

 gtk/gtkfilechooserentry.c |   53 +++++++++++++++++++++-----------------------
 1 files changed, 25 insertions(+), 28 deletions(-)
Comment 11 Carlos Garnacho 2008-08-09 17:52:17 UTC
Created attachment 116252 [details] [review]
[PATCH] Add local_only to GtkFileChooserEntry.

 gtk/gtkfilechooserdefault.c |    3 +++
 gtk/gtkfilechooserentry.c   |   30 ++++++++++++++++++++++++++++++
 gtk/gtkfilechooserentry.h   |    4 ++++
 3 files changed, 37 insertions(+), 0 deletions(-)
Comment 12 Matthias Clasen 2008-08-09 23:53:15 UTC
+
+          g_object_unref (cancellable);
+          toplevel = gtk_widget_get_toplevel (GTK_WIDGET (impl));
+
+          mount_operation = gtk_mount_operation_new (GTK_WINDOW (toplevel));
+
+          impl->update_current_folder_cancellable =
+            _gtk_file_system_mount_enclosing_volume (impl->file_system, data->file,
+                                                     mount_operation,
+                                                     update_current_folder_mount_enclosing_volume_cb,
+                                                     data);

It seems somewhat misdesigned that you free the passed-in cancellable here,
only to get a new one back from the next operation. Really, _gtk_file_system_mount_enclosing_volume and similar operations should (optionally) take an existing cancellable.


          set_busy_cursor (impl, TRUE);

Where does that get undone ? Should update_current_folder_mount_enclosing_volume_cb set it back ?


+      beep (chooser_entry);

That beep function seems pretty pointless. Better to just call
gtk_widget_error_bell directly, methinks. But thats independent from this change.


+      pop_up_completion_feedback (chooser_entry, _("Only local paths can be selected"));

Might be better to talk about 'local files' here ? Or maybe not, since then you have to look at the action to figure out if you are selecting files or directories. Anyway, don't forget to announce this string addition to gnome-i18n@gnome.org when committing.
Comment 13 Matthias Clasen 2008-08-16 02:59:03 UTC
I've now played a bit with the patch, and there are a number of areas where it doesn't behave as I would expect.

First, with local-only set to TRUE, I enter ftp://ftp. At this point, I start getting a completion popup, but it lists completions for the local root directory. As I continue to type, the completion window hides and comes back for each character I type, very annoying. When I'm done typing ftp://ftp.gtk.org, I hit Tab to get completions. Instead, I get a tooltip that says "Invalid path". Ok, I forget the /, so lets add that and try Tab again. After typing /, I get all the local / completions popped up again. Typing Tab now finally gives me 
"Only local paths can be selected". Ok, but if I now type a b, I get local completions for /b.

Now, set local-only to FALSE, and repeat the experiment. All the annoyances repeat until I have entered ftp://ftp.gtk.org. At this point, I get adventurous and hit Enter. The uri I typed vanishes, but no directory change takes place :-(
Ok, enter it all again and add a /. Hitting Tab now gives me a tooltip saying "Completing..." for a while, and then...no completions. Probably because it wasn't mounted yet, so hit Enter. Password dialog comes up, and allows me to mount it, and indeed, the directory is changed. At this point, the entry is emptied again, so I wonder how to continue typing now... trying p, followed by Tab doesn't give me any completions, I would have expected it to complete to pub. So I continue to type it manually, up to pub/ and hit Tab again, still no completions. Adding a b, I suddenly do get completions for the two directories in ftp://ftp.gtk.org/pub/ that are starting with b.

Backing up one last time, by changing to the the local root. At this point, ftp.gtk.org is mounted, so I type ftp:// and type Tab to see if I get a completion - nope.


Overall, I would say that we haven't quite mastered how completions and mounting are supposed to interact...
Comment 14 Tomas Bzatek 2008-11-18 16:27:31 UTC
Created attachment 122952 [details] [review]
[PATCH] Mount the enclosing volume if the folder we're switching to is not mounted.

(In reply to comment #9)
> Created an attachment (id=116250) [edit]
> [PATCH] Mount the enclosing volume if the folder we're switching to is not
> mounted.
> 
>  gtk/gtkfilechooserdefault.c |   47 +++++++++++++++++++++++++++++++++++++++++++
>  1 files changed, 47 insertions(+), 0 deletions(-)
> 

Attaching updated patch, preventing endless loop when error happens (incl. login dialog cancellation). Doing unref of some objects and setting set_busy_cursor (impl, FALSE) looks unfortunate to me to happen in the callback, however change_folder_and_display_error() doesn't take any errors into account.

Anyway, the patch works fine and correctly spawns mount process during browsing in the right tree view.
Comment 15 Matthias Clasen 2008-12-03 16:49:24 UTC
+  impl->update_current_folder_cancellable = NULL;
+
+  if (cancelled)
+    goto out;
+
+  if (error)
+    {
+      error_changing_folder_dialog (data->impl, data->file, g_error_copy (error));
+      impl->update_current_folder_cancellable = NULL;
+      impl->reload_state = RELOAD_EMPTY;
+      set_busy_cursor (impl, FALSE);
+      goto out;
+    }

Seems to me that update_current_folder_cancellable is getting set to NULL twice 
in the error case. 

What I wonder about here is: Who is resetting the busy cursor if the operation was cancelled or successful ?


+          impl->update_current_folder_cancellable =
+            _gtk_file_system_mount_enclosing_volume (impl->file_system, data->file,
+                                                     mount_operation,
+                                                     update_current_folder_mount_enclosing_volume_cb,
+                                                     data);
+          set_busy_cursor (impl, TRUE);


I know it probably can't happen that the mount operation completes synchronously, but it would still look cleaner to me to set the busy cursor before starting the mount op. 


Other than that, I'm in favour of committing this.
Comment 16 Matthias Clasen 2008-12-14 03:35:10 UTC
2008-12-13  Matthias Clasen  <mclasen@redhat.com>

        * gtk/gtkfilechooserdefault.c (update_current_folder_get_info_cb):
        Mount the enclosing volume if the folder we're switching to is not
        mounted. Patch by Tomas Bzatek, based on work by Carlos Garnacho
Comment 17 Federico Mena Quintero 2009-01-21 03:20:38 UTC
Created attachment 126899 [details] [review]
Updated patchset based on Garnacho's patches

I just committed this patchset; it is based on Garnacho's patches.

2009-01-20  Federico Mena Quintero  <federico@novell.com>

	http://bugzilla.gnome.org/show_bug.cgi?id=545980 -
	GtkFileChooserEntry should handle URIs

	* gtk/gtkfilesystem.c (_gtk_file_system_parse): Detect URI schemes
	and parse the full URI.
	(has_uri_scheme): New function, stolen from the old
	gtkfilesystemgnomevfs.c.

	Patch by Carlos Garnacho <carlos@imendio.com>:

	* gtk/gtkfilechooserentry.c (discard_current_folder): New
	function, factored out for when we need to get rid of the
	current_folder.
	(gtk_file_chooser_entry_dispose): Use discard_current_folder().
	(finished_loading_cb): Fix prototype.
	(load_directory_get_folder_callback): Discard the completion
	store, as well as clearing the completion feedback, if we find an
	error while loading the folder.  Also, use
	discard_current_folder().
	(reload_current_folder): Use discard_current_folder().

	Patch by Carlos Garnacho <carlos@imendio.com> - add a local_only
	property to GtkFileChooserEntry:

	* gtk/gtkfilechooserentry.c (struct _GtkFileChooserEntry): Add a
	local_only field.
	(_gtk_file_chooser_entry_init): Default to local_only being true.
	(start_explicit_completion): Don't allow completion of non-native
	files if local_only is turned on.
	(start_loading_current_folder): Don't start loading non-native
	folders if local_only is turned on.
	(_gtk_file_chooser_entry_set_local_only): New function.
	(_gtk_file_chooser_entry_get_local_only): New function.

	* gtk/gtkfilechooserentry.h (_gtk_file_chooser_entry_set_local_only,
	_gtk_file_chooser_entry_get_local_only): New prototypes.

	* gtk/gtkfilechooserdefault.c (set_local_only): Set the local_only
	property on the entry.

	Fix completion so it doesn't pop up for every character in a URI
	hostname:

	* gtk/gtkfilechooser.h (GtkFileChooserError): Add a
	GTK_FILE_CHOOSER_ERROR_INCOMPLETE_HOSTNAME.

	* gtk/gtkfilesystem.c (_gtk_file_system_parse): Return an
	"incomplete hostname" error if the user has not typed a full
	hostname yet in an URI.

	* gtk/gtkfilechooserentry.c (append_common_prefix): If we get an
	incomplete hostname, just don't pop up an error, since that is a
	transient state and the user doesn't need to be notified about it.
	(refresh_current_folder_and_file_part): Don't revert to showing
	the base folder if we have an incomplete hostname.
	(reload_current_folder): Handle the passed folder being NULL, even
	if we must force a reload.  Also, reload the folder if we didn't
	have a cancellable for it (i.e. we hadn't started to load it
	before).
Comment 18 Philip Withnall 2009-04-02 20:31:12 UTC
*** Bug 569506 has been marked as a duplicate of this bug. ***
Comment 19 Timothy Arceri 2013-05-25 03:15:42 UTC
*** Bug 559626 has been marked as a duplicate of this bug. ***