[gtk+/multiroot-filechooser-2-20: 11/21] Add support for multiple roots.
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/multiroot-filechooser-2-20: 11/21] Add support for multiple roots.
- Date: Wed, 25 Aug 2010 17:45:43 +0000 (UTC)
commit 077ce84578354b09010a86956e862310b9f73ab5
Author: Christian Hammond <chipx86 chipx86 com>
Date: Tue Mar 16 17:05:34 2010 -0700
Add support for multiple roots.
This introduces support for multiple roots on the file chooser. Instead
of rooting to a single URI, there can now be several roots, which will be
taken into account when selecting files, typing custom file paths, or showing
parts of the UI.
This makes it possible to, for example, limit the file chooser to the user's
home directory and memory stick.
gtk/gtkfilechooser.c | 129 ++++++++++--------
gtk/gtkfilechooser.h | 6 +-
gtk/gtkfilechooserbutton.c | 29 +++--
gtk/gtkfilechooserdefault.c | 302 ++++++++++++++++++++++++-------------------
gtk/gtkfilechooserentry.c | 30 ++---
gtk/gtkfilechooserentry.h | 6 +-
gtk/gtkfilechooserprivate.h | 6 +-
gtk/gtkfilechooserutils.c | 4 +-
gtk/gtkfilechooserutils.h | 4 +-
gtk/gtkpathbar.c | 26 ++--
gtk/gtkpathbar.h | 6 +-
11 files changed, 297 insertions(+), 251 deletions(-)
---
diff --git a/gtk/gtkfilechooser.c b/gtk/gtkfilechooser.c
index d0d5003..475fe56 100644
--- a/gtk/gtkfilechooser.c
+++ b/gtk/gtkfilechooser.c
@@ -852,23 +852,22 @@ gtk_file_chooser_class_init (gpointer g_iface)
GTK_PARAM_READWRITE));
/**
- * GtkFileChooser:root-uri:
+ * GtkFileChooser:root-uris:
*
- * The absolute root URI that can be accessed in the file chooser.
+ * The absolute root URIs that can be accessed in the file chooser.
* Any shortcuts (special or user-defined) or volumes not within
- * this URI will be filtered out for this dialog.
+ * these URIs will be filtered out for this dialog.
*
- * The default is an empty string or NULL, which provides the
- * default level of access for the file chooser.
+ * The default is NULL, which provides the default level of access
+ * for the file chooser.
*
* Since: 2.18
*/
g_object_interface_install_property (g_iface,
- g_param_spec_string ("root-uri",
- P_("Root URI"),
- P_("The URI, if any, to use as the root for all access in the file chooser."),
- NULL,
- GTK_PARAM_READWRITE));
+ g_param_spec_pointer ("root-uris",
+ P_("Root URIs"),
+ P_("The URIs, if any, to use as the root for all access in the file chooser."),
+ GTK_PARAM_READWRITE));
}
/**
@@ -946,8 +945,8 @@ gtk_file_chooser_get_action (GtkFileChooser *chooser)
* rather than the URI functions like
* gtk_file_chooser_get_uri(),
*
- * This implies a root URI of "file://". See
- * gtk_file_chooser_set_root_uri().
+ * This implies a single root URI of "file://". See
+ * gtk_file_chooser_set_root_uris().
*
* Since: 2.4
**/
@@ -968,7 +967,7 @@ gtk_file_chooser_set_local_only (GtkFileChooser *chooser,
* file selector. See gtk_file_chooser_set_local_only()
*
* This is %TRUE when the root URI of the file chooser is
- * "file://". See gtk_file_chooser_get_root_uri().
+ * "file://". See gtk_file_chooser_get_root_uris().
*
* Return value: %TRUE if only local files can be selected.
*
@@ -987,12 +986,12 @@ gtk_file_chooser_get_local_only (GtkFileChooser *chooser)
}
/**
- * gtk_file_chooser_set_root_uri:
+ * gtk_file_chooser_set_root_uris:
* @chooser: a #GtkFileChooser
* @root_uri: The root URI, or %NULL to allow access to everything.
*
- * Sets the URI that will be the root of the file chooser. The file
- * chooser will not display or allow access to files outside of this URI.
+ * Sets the URIs that will be the roots of the file chooser. The file
+ * chooser will not display or allow access to files outside of these URIs.
*
* If this is set to %NULL, then the file chooser will have access to all
* local and remote volumes and files.
@@ -1001,25 +1000,29 @@ gtk_file_chooser_get_local_only (GtkFileChooser *chooser)
* directory and its subdirectories, to a particular storage device, or to a
* remote server.
*
- * See gtk_file_chooser_get_root_uri()
+ * If more than one root URI is provided for the same filesystem or protocol
+ * (for example, "file:///home" and "file:///"), then the most permissive will
+ * be used (in this case, "file:///").
+ *
+ * See gtk_file_chooser_get_root_uris()
*
* Since: 2.18
**/
void
-gtk_file_chooser_set_root_uri (GtkFileChooser *chooser,
- const gchar *root_uri)
+gtk_file_chooser_set_root_uris (GtkFileChooser *chooser,
+ GSList *root_uris)
{
g_return_if_fail (GTK_IS_FILE_CHOOSER (chooser));
- g_object_set (chooser, "root-uri", root_uri, NULL);
+ g_object_set (chooser, "root-uris", root_uris, NULL);
}
/**
- * gtk_file_chooser_get_root_uri:
+ * gtk_file_chooser_get_root_uris:
* @chooser: a #GtkFileChooser
*
- * Gets the URI that is the root of the file chooser. The file chooser
- * will not display or allow access to files outside of this URI.
+ * Gets the URIs that are the roots of the file chooser. The file chooser
+ * will not display or allow access to files outside of these URIs.
*
* If this is %NULL, then the file chooser has access to all local and
* remote volumes and files.
@@ -1028,22 +1031,26 @@ gtk_file_chooser_set_root_uri (GtkFileChooser *chooser,
* directory and its subdirectories, to a particular storage device, or to a
* remote server.
*
- * See gtk_file_chooser_set_root_uri()
+ * If more than one root URI is provided for the same filesystem or protocol
+ * (for example, "file:///home" and "file:///"), then the most permissive will
+ * be used (in this case, "file:///").
+ *
+ * See gtk_file_chooser_set_root_uris()
*
- * Return value: The root URI, or %NULL.
+ * Return value: The root URIs, or %NULL.
*
* Since: 2.18
**/
-const gchar *
-gtk_file_chooser_get_root_uri (GtkFileChooser *chooser)
+GSList *
+gtk_file_chooser_get_root_uris (GtkFileChooser *chooser)
{
- const gchar *root_uri;
+ GSList *root_uris;
g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), NULL);
- g_object_get (chooser, "root-uri", &root_uri, NULL);
+ g_object_get (chooser, "root-uris", &root_uris, NULL);
- return root_uri;
+ return root_uris;
}
/**
@@ -2860,41 +2867,46 @@ gtk_file_chooser_list_shortcut_folders (GtkFileChooser *chooser)
#endif
gboolean
-_gtk_file_chooser_uri_has_prefix (const char *uri,
- const char *prefix)
+_gtk_file_chooser_uri_has_prefix (const char *uri,
+ const GSList *prefixes)
{
int uri_len;
- int prefix_len;
- gboolean result;
- char *new_prefix = NULL;
+ gboolean result = FALSE;
+ const GSList *l;
g_return_val_if_fail (uri != NULL, FALSE);
- g_return_val_if_fail (prefix != NULL, FALSE);
+ g_return_val_if_fail (prefixes != NULL, FALSE);
uri_len = strlen (uri);
- prefix_len = strlen (prefix);
- if (prefix[prefix_len - 1] != '/')
+ for (l = prefixes; l != NULL && !result; l = l->next)
{
- new_prefix = g_strdup_printf ("%s/", prefix);
- prefix = new_prefix;
- prefix_len++;
+ char *new_prefix = NULL;
+ char *prefix = (char *)l->data;
+ int prefix_len = strlen (prefix);
+
+ if (prefix[prefix_len - 1] != '/')
+ {
+ new_prefix = g_strdup_printf ("%s/", prefix);
+ prefix = new_prefix;
+ prefix_len++;
+ }
+
+ if (prefix_len == uri_len + 1)
+ {
+ /*
+ * Special case. The prefix URI may contain a trailing slash while the
+ * URI we're comparing against may not (or vice-versa), despite the
+ * URIs being equal.
+ */
+ result = !strncmp (prefix, uri, uri_len);
+ }
+ else
+ result = (uri_len >= prefix_len && g_str_has_prefix (uri, prefix));
+
+ g_free (new_prefix);
}
- if (prefix_len == uri_len + 1)
- {
- /*
- * Special case. The prefix URI may contain a trailing slash while the
- * URI we're comparing against may not (or vice-versa), despite the
- * URIs being equal.
- */
- result = !strncmp (prefix, uri, uri_len);
- }
- else
- result = (uri_len >= prefix_len && g_str_has_prefix (uri, prefix));
-
- g_free (new_prefix);
-
return result;
}
@@ -2902,14 +2914,15 @@ gboolean
_gtk_file_chooser_is_uri_in_root (GtkFileChooser *chooser,
const char *uri)
{
- const char *root_uri;
+ GSList *root_uris;
g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), FALSE);
g_return_val_if_fail (uri != NULL, FALSE);
- root_uri = gtk_file_chooser_get_root_uri (chooser);
+ root_uris = gtk_file_chooser_get_root_uris (chooser);
- return root_uri == NULL || _gtk_file_chooser_uri_has_prefix (uri, root_uri);
+ return root_uris == NULL ||
+ _gtk_file_chooser_uri_has_prefix (uri, root_uris);
}
gboolean
diff --git a/gtk/gtkfilechooser.h b/gtk/gtkfilechooser.h
index 9ac4058..63ec0a1 100644
--- a/gtk/gtkfilechooser.h
+++ b/gtk/gtkfilechooser.h
@@ -123,9 +123,9 @@ GtkFileChooserAction gtk_file_chooser_get_action (GtkFileChooser
void gtk_file_chooser_set_local_only (GtkFileChooser *chooser,
gboolean local_only);
gboolean gtk_file_chooser_get_local_only (GtkFileChooser *chooser);
-void gtk_file_chooser_set_root_uri (GtkFileChooser *chooser,
- const gchar *root_uri);
-const gchar *gtk_file_chooser_get_root_uri (GtkFileChooser *chooser);
+void gtk_file_chooser_set_root_uris (GtkFileChooser *chooser,
+ GSList *root_uris);
+GSList *gtk_file_chooser_get_root_uris (GtkFileChooser *chooser);
void gtk_file_chooser_set_select_multiple (GtkFileChooser *chooser,
gboolean select_multiple);
gboolean gtk_file_chooser_get_select_multiple (GtkFileChooser *chooser);
diff --git a/gtk/gtkfilechooserbutton.c b/gtk/gtkfilechooserbutton.c
index 0c71092..69d70de 100644
--- a/gtk/gtkfilechooserbutton.c
+++ b/gtk/gtkfilechooserbutton.c
@@ -876,14 +876,17 @@ gtk_file_chooser_button_set_property (GObject *object,
break;
case GTK_FILE_CHOOSER_PROP_LOCAL_ONLY:
- case GTK_FILE_CHOOSER_PROP_ROOT_URI:
+ case GTK_FILE_CHOOSER_PROP_ROOT_URIS:
g_object_set_property (G_OBJECT (priv->dialog), pspec->name, value);
if (!_gtk_file_chooser_is_file_in_root (filechooser,
gtk_file_chooser_get_current_folder_file (filechooser)))
{
- GFile *file = g_file_new_for_uri (
- gtk_file_chooser_get_root_uri (filechooser));
+ GSList *root_uris = gtk_file_chooser_get_root_uris (filechooser);
+
+ GFile *file = g_file_new_for_uri (root_uris == NULL
+ ? "file:///"
+ : (char *)root_uris->data);
gtk_file_chooser_set_current_folder_file (filechooser, file, NULL);
model_update_current_folder (button, file);
@@ -943,7 +946,7 @@ gtk_file_chooser_button_get_property (GObject *object,
case GTK_FILE_CHOOSER_PROP_SHOW_HIDDEN:
case GTK_FILE_CHOOSER_PROP_DO_OVERWRITE_CONFIRMATION:
case GTK_FILE_CHOOSER_PROP_CREATE_FOLDERS:
- case GTK_FILE_CHOOSER_PROP_ROOT_URI:
+ case GTK_FILE_CHOOSER_PROP_ROOT_URIS:
g_object_get_property (G_OBJECT (priv->dialog), pspec->name, value);
break;
@@ -1834,7 +1837,7 @@ model_add_volumes (GtkFileChooserButton *button,
GtkListStore *store;
gint pos;
gboolean local_only;
- const char *root_uri;
+ GSList *root_uris;
GtkFileSystem *file_system;
GtkFileChooser *filechooser;
GSList *l;
@@ -1846,7 +1849,7 @@ model_add_volumes (GtkFileChooserButton *button,
pos = model_get_type_position (button, ROW_TYPE_VOLUME);
filechooser = GTK_FILE_CHOOSER (button->priv->dialog);
local_only = gtk_file_chooser_get_local_only (filechooser);
- root_uri = gtk_file_chooser_get_root_uri (filechooser);
+ root_uris = gtk_file_chooser_get_root_uris (filechooser);
file_system = button->priv->fs;
for (l = volumes; l; l = l->next)
@@ -1867,7 +1870,7 @@ model_add_volumes (GtkFileChooserButton *button,
_gtk_file_system_volume_is_mounted (volume) &&
!g_file_is_native (base_file))
skip = TRUE;
- else if (root_uri != NULL &&
+ else if (root_uris != NULL &&
(base_file == NULL ||
!_gtk_file_chooser_is_file_in_root (filechooser, base_file)))
skip = TRUE;
@@ -2152,7 +2155,7 @@ static inline gboolean
test_if_file_is_visible (GtkFileSystem *fs,
GFile *file,
gboolean local_only,
- const char *root_uri,
+ GSList *root_uris,
gboolean is_folder)
{
char *uri;
@@ -2165,8 +2168,8 @@ test_if_file_is_visible (GtkFileSystem *fs,
return FALSE;
uri = g_file_get_uri (file);
- result = (root_uri == NULL ||
- _gtk_file_chooser_uri_has_prefix (uri, root_uri));
+ result = (root_uris == NULL ||
+ _gtk_file_chooser_uri_has_prefix (uri, root_uris));
g_free (uri);
if (!result)
@@ -2188,12 +2191,12 @@ filter_model_visible_func (GtkTreeModel *model,
gchar type;
gpointer data;
gboolean local_only, retval, is_folder;
- const char *root_uri;
+ GSList *root_uris;
type = ROW_TYPE_INVALID;
data = NULL;
local_only = gtk_file_chooser_get_local_only (GTK_FILE_CHOOSER (priv->dialog));
- root_uri = gtk_file_chooser_get_root_uri (GTK_FILE_CHOOSER (priv->dialog));
+ root_uris = gtk_file_chooser_get_root_uris (GTK_FILE_CHOOSER (priv->dialog));
gtk_tree_model_get (model, iter,
TYPE_COLUMN, &type,
@@ -2209,7 +2212,7 @@ filter_model_visible_func (GtkTreeModel *model,
case ROW_TYPE_SPECIAL:
case ROW_TYPE_SHORTCUT:
case ROW_TYPE_BOOKMARK:
- retval = test_if_file_is_visible (priv->fs, data, local_only, root_uri,
+ retval = test_if_file_is_visible (priv->fs, data, local_only, root_uris,
is_folder);
break;
case ROW_TYPE_VOLUME:
diff --git a/gtk/gtkfilechooserdefault.c b/gtk/gtkfilechooserdefault.c
index 2fb3980..193a75b 100644
--- a/gtk/gtkfilechooserdefault.c
+++ b/gtk/gtkfilechooserdefault.c
@@ -709,7 +709,7 @@ _gtk_file_chooser_default_init (GtkFileChooserDefault *impl)
#ifdef PROFILE_FILE_CHOOSER
access ("MARK: *** CREATE FILE CHOOSER", F_OK);
#endif
- impl->root_uri = g_strdup ("file://");
+ impl->root_uris = g_slist_append (NULL, g_strdup ("file://"));
impl->preview_widget_active = TRUE;
impl->use_preview_label = TRUE;
impl->select_multiple = FALSE;
@@ -1765,11 +1765,26 @@ shortcuts_append_search (GtkFileChooserDefault *impl)
gboolean old_changing_folders = impl->changing_folder;
impl->changing_folder = TRUE;
int start_row = shortcuts_get_index (impl, SHORTCUTS_SEARCH);
+ gboolean can_search = (impl->root_uris == NULL);
if (impl->has_search)
shortcuts_remove_rows (impl, start_row, 1);
- if (impl->root_uri == NULL || g_str_has_prefix (impl->root_uri, "file:"))
+ if (!can_search)
+ {
+ GSList *l;
+
+ for (l = impl->root_uris; l != NULL; l = l->next)
+ {
+ if (g_str_has_prefix ((char *)l->data, "file:"))
+ {
+ can_search = TRUE;
+ break;
+ }
+ }
+ }
+
+ if (can_search)
{
GtkTreeIter iter;
GdkPixbuf *pixbuf = render_search_icon (impl);
@@ -2086,7 +2101,7 @@ shortcuts_add_volumes (GtkFileChooserDefault *impl)
_gtk_file_system_volume_is_mounted (volume) &&
!g_file_is_native (base_file))
skip = TRUE;
- else if (impl->root_uri != NULL &&
+ else if (impl->root_uris != NULL &&
(base_file == NULL ||
!_gtk_file_chooser_is_file_in_root (GTK_FILE_CHOOSER (impl),
base_file)))
@@ -2270,7 +2285,7 @@ shortcuts_add_custom_folders (GtkFileChooserDefault *impl)
{
GFile *file = (GFile *)l->data;
- if (impl->root_uri != NULL &&
+ if (impl->root_uris != NULL &&
_gtk_file_chooser_is_file_in_root (GTK_FILE_CHOOSER (impl), file))
{
int pos = shortcuts_get_pos_for_shortcut_folder (impl,
@@ -4937,10 +4952,11 @@ save_widgets_create (GtkFileChooserDefault *impl)
_gtk_file_chooser_entry_set_local_only (
GTK_FILE_CHOOSER_ENTRY (impl->location_entry),
gtk_file_chooser_get_local_only (GTK_FILE_CHOOSER (impl)));
- _gtk_file_chooser_entry_set_root_uri (
+ _gtk_file_chooser_entry_set_root_uris (
GTK_FILE_CHOOSER_ENTRY (impl->location_entry),
- impl->root_uri);
- _gtk_path_bar_set_root_uri (GTK_PATH_BAR (impl->browse_path_bar), impl->root_uri);
+ impl->root_uris);
+ _gtk_path_bar_set_root_uris (GTK_PATH_BAR (impl->browse_path_bar),
+ impl->root_uris);
gtk_entry_set_width_chars (GTK_ENTRY (impl->location_entry), 45);
gtk_entry_set_activates_default (GTK_ENTRY (impl->location_entry), TRUE);
gtk_table_attach (GTK_TABLE (table), impl->location_entry,
@@ -5098,9 +5114,9 @@ location_switch_to_filename_entry (GtkFileChooserDefault *impl)
_gtk_file_chooser_entry_set_local_only (
GTK_FILE_CHOOSER_ENTRY (impl->location_entry),
gtk_file_chooser_get_local_only (GTK_FILE_CHOOSER (impl)));
- _gtk_file_chooser_entry_set_root_uri (
+ _gtk_file_chooser_entry_set_root_uris (
GTK_FILE_CHOOSER_ENTRY (impl->location_entry),
- impl->root_uri);
+ impl->root_uris);
/* Done */
@@ -5385,145 +5401,143 @@ set_extra_widget (GtkFileChooserDefault *impl,
}
static void
-set_root_uri (GtkFileChooserDefault *impl,
- const gchar *root_uri)
+set_root_uris (GtkFileChooserDefault *impl,
+ GSList *root_uris)
{
- if (root_uri == NULL || *root_uri == '\0')
- root_uri = NULL;
+ GtkTreeIter iter;
+ GFile *list_selected = NULL;
+ ShortcutType shortcut_type = -1;
+ gboolean local_only;
- if (g_strcmp0 (root_uri, impl->root_uri))
- {
- GtkTreeIter iter;
- GFile *list_selected = NULL;
- ShortcutType shortcut_type = -1;
- gboolean local_only;
+ if (root_uris == impl->root_uris)
+ return;
- g_free (impl->root_uri);
- impl->root_uri = (root_uri == NULL ? NULL : g_strdup (root_uri));
+ g_slist_foreach (impl->root_uris, (GFunc)g_free, NULL);
+ g_slist_free (impl->root_uris);
- local_only = gtk_file_chooser_get_local_only (GTK_FILE_CHOOSER (impl));
+ impl->root_uris = root_uris;
- if (impl->location_entry)
- {
- _gtk_file_chooser_entry_set_root_uri (
- GTK_FILE_CHOOSER_ENTRY (impl->location_entry),
- impl->root_uri);
- _gtk_file_chooser_entry_set_local_only (
- GTK_FILE_CHOOSER_ENTRY (impl->location_entry),
- local_only);
- }
+ local_only = gtk_file_chooser_get_local_only (GTK_FILE_CHOOSER (impl));
- _gtk_path_bar_set_root_uri (GTK_PATH_BAR (impl->browse_path_bar),
- impl->root_uri);
+ if (impl->location_entry)
+ {
+ _gtk_file_chooser_entry_set_root_uris (
+ GTK_FILE_CHOOSER_ENTRY (impl->location_entry),
+ impl->root_uris);
+ _gtk_file_chooser_entry_set_local_only (
+ GTK_FILE_CHOOSER_ENTRY (impl->location_entry),
+ local_only);
+ }
- /* Attempt to preserve the sidebar selection if possible. */
- if (shortcuts_get_selected (impl, &iter))
- {
- gpointer col_data = NULL;
+ _gtk_path_bar_set_root_uris (GTK_PATH_BAR (impl->browse_path_bar),
+ impl->root_uris);
- gtk_tree_model_get (GTK_TREE_MODEL (impl->shortcuts_model),
- &iter,
- SHORTCUTS_COL_DATA, &col_data,
- SHORTCUTS_COL_TYPE, &shortcut_type,
- -1);
+ /* Attempt to preserve the sidebar selection if possible. */
+ if (shortcuts_get_selected (impl, &iter))
+ {
+ gpointer col_data = NULL;
- if (col_data != NULL)
- {
- if (shortcut_type == SHORTCUT_TYPE_FILE)
- list_selected = g_object_ref (col_data);
- else if (shortcut_type == SHORTCUT_TYPE_VOLUME)
- list_selected = col_data;
- }
- }
+ gtk_tree_model_get (GTK_TREE_MODEL (impl->shortcuts_model),
+ &iter,
+ SHORTCUTS_COL_DATA, &col_data,
+ SHORTCUTS_COL_TYPE, &shortcut_type,
+ -1);
- if (impl->shortcuts_model && impl->file_system)
+ if (col_data != NULL)
{
- /* Update all the sidebar entries to filter the root URI. */
- shortcuts_model_create (impl);
- shortcuts_add_bookmarks (impl);
- shortcuts_add_custom_folders (impl);
+ if (shortcut_type == SHORTCUT_TYPE_FILE)
+ list_selected = g_object_ref (col_data);
+ else if (shortcut_type == SHORTCUT_TYPE_VOLUME)
+ list_selected = col_data;
}
+ }
- if (impl->current_folder != NULL)
- {
- if (local_only && !g_file_is_native (impl->current_folder))
- {
- /* If we are pointing to a non-local folder, make an effort to
- * change back to a local folder, but it's really up to the app
- * to not cause such a situation, so we ignore errors.
- */
- const gchar *home = g_get_home_dir ();
- GFile *home_file;
+ if (impl->shortcuts_model && impl->file_system)
+ {
+ /* Update all the sidebar entries to filter the root URI. */
+ shortcuts_model_create (impl);
+ shortcuts_add_bookmarks (impl);
+ shortcuts_add_custom_folders (impl);
+ }
- if (home != NULL)
- {
- home_file = g_file_new_for_path (home);
- gtk_file_chooser_set_current_folder_file (
- GTK_FILE_CHOOSER (impl),
- home_file, NULL);
+ if (impl->current_folder != NULL)
+ {
+ if (local_only && !g_file_is_native (impl->current_folder))
+ {
+ /* If we are pointing to a non-local folder, make an effort to
+ * change back to a local folder, but it's really up to the app
+ * to not cause such a situation, so we ignore errors.
+ */
+ const gchar *home = g_get_home_dir ();
+ GFile *home_file;
- g_object_unref (home_file);
- }
- }
- else if (impl->root_uri != NULL &&
- !_gtk_file_chooser_is_file_in_root (GTK_FILE_CHOOSER (impl),
- impl->current_folder))
+ if (home != NULL)
{
- /*
- * If we are pointing to a folder outside of the root URI,
- * set the folder to the root URI.
- */
-
- /*
- * Clear the list first, in case we can't load this path.
- * We don't want to show files they shouldn't be able to access.
- */
- if (impl->operation_mode == OPERATION_MODE_BROWSE)
- stop_operation (impl, impl->operation_mode);
+ home_file = g_file_new_for_path (home);
+ gtk_file_chooser_set_current_folder_file (
+ GTK_FILE_CHOOSER (impl),
+ home_file, NULL);
- gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER (impl),
- impl->root_uri);
- }
- else
- {
- /* Re-set the current folder so we'll display it properly. */
- gtk_file_chooser_set_current_folder_file (GTK_FILE_CHOOSER (impl),
- impl->current_folder,
- NULL);
+ g_object_unref (home_file);
}
}
+ else if (impl->root_uris != NULL &&
+ !_gtk_file_chooser_is_file_in_root (GTK_FILE_CHOOSER (impl),
+ impl->current_folder))
+ {
+ /*
+ * If we are pointing to a folder outside of the root URI,
+ * set the folder to the root URI.
+ */
- if (shortcut_type != -1)
+ /*
+ * Clear the list first, in case we can't load this path.
+ * We don't want to show files they shouldn't be able to access.
+ */
+ if (impl->operation_mode == OPERATION_MODE_BROWSE)
+ stop_operation (impl, impl->operation_mode);
+
+ gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER (impl),
+ (char *)impl->root_uris->data);
+ }
+ else
{
- if (list_selected != NULL)
- {
- shortcuts_find_folder (impl, list_selected);
+ /* Re-set the current folder so we'll display it properly. */
+ gtk_file_chooser_set_current_folder_file (GTK_FILE_CHOOSER (impl),
+ impl->current_folder,
+ NULL);
+ }
+ }
- if (shortcut_type == SHORTCUT_TYPE_FILE)
- g_object_unref (list_selected);
- }
- else
- {
- int pos = -1;
+ if (shortcut_type != -1)
+ {
+ if (list_selected != NULL)
+ {
+ shortcuts_find_folder (impl, list_selected);
- /*
- * Switch the operation mode to browse, a good default.
- * We'll go back to Search or Recent if that's what was
- * selected. The advantage is that we'll reload the results
- * as well.
- */
- stop_operation (impl, impl->operation_mode);
+ if (shortcut_type == SHORTCUT_TYPE_FILE)
+ g_object_unref (list_selected);
+ }
+ else
+ {
+ int pos = -1;
- impl->operation_mode = OPERATION_MODE_BROWSE;
+ /*
+ * Switch the operation mode to browse, a good default.
+ * We'll go back to Search or Recent if that's what was
+ * selected. The advantage is that we'll reload the results
+ * as well.
+ */
+ stop_operation (impl, impl->operation_mode);
+ impl->operation_mode = OPERATION_MODE_BROWSE;
- if (shortcut_type == SHORTCUT_TYPE_SEARCH)
- pos = shortcuts_get_index (impl, SHORTCUTS_SEARCH);
- else if (shortcut_type == SHORTCUT_TYPE_RECENT)
- pos = shortcuts_get_index (impl, SHORTCUTS_RECENT);
+ if (shortcut_type == SHORTCUT_TYPE_SEARCH)
+ pos = shortcuts_get_index (impl, SHORTCUTS_SEARCH);
+ else if (shortcut_type == SHORTCUT_TYPE_RECENT)
+ pos = shortcuts_get_index (impl, SHORTCUTS_RECENT);
- if (pos != -1)
- shortcuts_find_pos (impl, pos);
- }
+ if (pos != -1)
+ shortcuts_find_pos (impl, pos);
}
}
}
@@ -5706,7 +5720,10 @@ gtk_file_chooser_default_set_property (GObject *object,
break;
case GTK_FILE_CHOOSER_PROP_LOCAL_ONLY:
- set_root_uri (impl, g_value_get_boolean (value) ? "file://" : NULL);
+ set_root_uris (impl,
+ g_value_get_boolean (value)
+ ? g_slist_append (NULL, g_strdup ("file://"))
+ : NULL);
break;
case GTK_FILE_CHOOSER_PROP_PREVIEW_WIDGET:
@@ -5772,8 +5789,8 @@ gtk_file_chooser_default_set_property (GObject *object,
}
break;
- case GTK_FILE_CHOOSER_PROP_ROOT_URI:
- set_root_uri (impl, g_value_get_string (value));
+ case GTK_FILE_CHOOSER_PROP_ROOT_URIS:
+ set_root_uris (impl, (GSList *)g_value_get_pointer (value));
break;
default:
@@ -5801,10 +5818,26 @@ gtk_file_chooser_default_get_property (GObject *object,
break;
case GTK_FILE_CHOOSER_PROP_LOCAL_ONLY:
- g_value_set_boolean (value,
- impl->root_uri != NULL &&
- g_str_has_prefix (impl->root_uri, "file://"));
- break;
+ {
+ gboolean local_only = (impl->root_uris != NULL);
+
+ if (local_only)
+ {
+ GSList *l;
+
+ for (l = impl->root_uris; l != NULL; l = l->next)
+ {
+ if (!g_str_has_prefix ((char *)l->data, "file://"))
+ {
+ local_only = FALSE;
+ break;
+ }
+ }
+ }
+
+ g_value_set_boolean (value, local_only);
+ break;
+ }
case GTK_FILE_CHOOSER_PROP_PREVIEW_WIDGET:
g_value_set_object (value, impl->preview_widget);
@@ -5838,8 +5871,8 @@ gtk_file_chooser_default_get_property (GObject *object,
g_value_set_boolean (value, impl->create_folders);
break;
- case GTK_FILE_CHOOSER_PROP_ROOT_URI:
- g_value_set_string (value, impl->root_uri);
+ case GTK_FILE_CHOOSER_PROP_ROOT_URIS:
+ g_value_set_pointer (value, impl->root_uris);
break;
default:
@@ -5876,8 +5909,9 @@ gtk_file_chooser_default_dispose (GObject *object)
impl->extra_widget = NULL;
}
- g_free (impl->root_uri);
- impl->root_uri = NULL;
+ g_slist_foreach (impl->root_uris, (GFunc)g_free, NULL);
+ g_slist_free (impl->root_uris);
+ impl->root_uris = NULL;
pending_select_files_free (impl);
diff --git a/gtk/gtkfilechooserentry.c b/gtk/gtkfilechooserentry.c
index 8ed3eba..cfc107a 100644
--- a/gtk/gtkfilechooserentry.c
+++ b/gtk/gtkfilechooserentry.c
@@ -67,7 +67,7 @@ struct _GtkFileChooserEntry
GtkFileChooserAction action;
GtkFileSystem *file_system;
- char *root_uri;
+ const GSList *root_uris;
GFile *base_folder;
GFile *current_folder_file;
gchar *file_part;
@@ -208,7 +208,7 @@ _gtk_file_chooser_entry_init (GtkFileChooserEntry *chooser_entry)
GtkCellRenderer *cell;
chooser_entry->local_only = TRUE;
- chooser_entry->root_uri = NULL;
+ chooser_entry->root_uris = NULL;
g_object_set (chooser_entry, "truncate-multiline", TRUE, NULL);
@@ -297,9 +297,6 @@ gtk_file_chooser_entry_dispose (GObject *object)
discard_current_folder (chooser_entry);
discard_loading_and_current_folder_file (chooser_entry);
- g_free (chooser_entry->root_uri);
- chooser_entry->root_uri = NULL;
-
if (chooser_entry->start_autocompletion_idle_id != 0)
{
g_source_remove (chooser_entry->start_autocompletion_idle_id);
@@ -457,9 +454,9 @@ is_file_in_root (GtkFileChooserEntry *chooser_entry,
GFile *file)
{
char *uri = g_file_get_uri (file);
- gboolean result = chooser_entry->root_uri == NULL ||
- _gtk_file_chooser_uri_has_prefix (uri,
- chooser_entry->root_uri);
+ gboolean result =
+ chooser_entry->root_uris == NULL ||
+ _gtk_file_chooser_uri_has_prefix (uri, chooser_entry->root_uris);
g_free (uri);
return result;
@@ -1488,7 +1485,7 @@ start_loading_current_folder (GtkFileChooserEntry *chooser_entry)
if ((chooser_entry->local_only
&& !g_file_is_native (chooser_entry->current_folder_file)) ||
- (chooser_entry->root_uri != NULL
+ (chooser_entry->root_uris != NULL
&& !is_file_in_root (chooser_entry,
chooser_entry->current_folder_file)))
{
@@ -2028,19 +2025,18 @@ _gtk_file_chooser_entry_get_local_only (GtkFileChooserEntry *chooser_entry)
}
void
-_gtk_file_chooser_entry_set_root_uri (GtkFileChooserEntry *chooser_entry,
- const char *root_uri)
+_gtk_file_chooser_entry_set_root_uris (GtkFileChooserEntry *chooser_entry,
+ const GSList *root_uris)
{
- g_free (chooser_entry->root_uri);
-
- chooser_entry->root_uri = (root_uri == NULL ? NULL : g_strdup(root_uri));
+ /* This doesn't need its own copy. */
+ chooser_entry->root_uris = root_uris;
clear_completions (chooser_entry);
}
-const char *
-_gtk_file_chooser_entry_get_root_uri (GtkFileChooserEntry *chooser_entry)
+const GSList *
+_gtk_file_chooser_entry_get_root_uris (GtkFileChooserEntry *chooser_entry)
{
- return chooser_entry->root_uri;
+ return chooser_entry->root_uris;
}
// vim: et sw=2 cinoptions=(0,t0,f1s,n-1s,{1s,>2s,^-1s
diff --git a/gtk/gtkfilechooserentry.h b/gtk/gtkfilechooserentry.h
index 38e4ebb..ef392f9 100644
--- a/gtk/gtkfilechooserentry.h
+++ b/gtk/gtkfilechooserentry.h
@@ -51,9 +51,9 @@ void _gtk_file_chooser_entry_select_filename (GtkFileChooserEnt
void _gtk_file_chooser_entry_set_local_only (GtkFileChooserEntry *chooser_entry,
gboolean local_only);
gboolean _gtk_file_chooser_entry_get_local_only (GtkFileChooserEntry *chooser_entry);
-void _gtk_file_chooser_entry_set_root_uri (GtkFileChooserEntry *chooser_entry,
- const char *root_uri);
-const char *_gtk_file_chooser_entry_get_root_uri (GtkFileChooserEntry *chooser_entry);
+void _gtk_file_chooser_entry_set_root_uris (GtkFileChooserEntry *chooser_entry,
+ const GSList *root_uris);
+const GSList *_gtk_file_chooser_entry_get_root_uris (GtkFileChooserEntry *chooser_entry);
G_END_DECLS
diff --git a/gtk/gtkfilechooserprivate.h b/gtk/gtkfilechooserprivate.h
index 92caf8d..dc339c7 100644
--- a/gtk/gtkfilechooserprivate.h
+++ b/gtk/gtkfilechooserprivate.h
@@ -111,8 +111,8 @@ gboolean _gtk_file_chooser_is_uri_in_root (GtkFileChooser *chooser,
gboolean _gtk_file_chooser_is_file_in_root (GtkFileChooser *chooser,
GFile *file);
-gboolean _gtk_file_chooser_uri_has_prefix (const char *uri,
- const char *prefix);
+gboolean _gtk_file_chooser_uri_has_prefix (const char *uri,
+ const GSList *prefixes);
/* GtkFileChooserDialog private */
@@ -170,7 +170,7 @@ struct _GtkFileChooserDefault
GtkFileChooserAction action;
GtkFileSystem *file_system;
- char *root_uri;
+ GSList *root_uris;
/* Save mode widgets */
GtkWidget *save_widgets;
diff --git a/gtk/gtkfilechooserutils.c b/gtk/gtkfilechooserutils.c
index 8a881bf..f18c171 100644
--- a/gtk/gtkfilechooserutils.c
+++ b/gtk/gtkfilechooserutils.c
@@ -121,8 +121,8 @@ _gtk_file_chooser_install_properties (GObjectClass *klass)
GTK_FILE_CHOOSER_PROP_CREATE_FOLDERS,
"create-folders");
g_object_class_override_property (klass,
- GTK_FILE_CHOOSER_PROP_ROOT_URI,
- "root-uri");
+ GTK_FILE_CHOOSER_PROP_ROOT_URIS,
+ "root-uris");
}
/**
diff --git a/gtk/gtkfilechooserutils.h b/gtk/gtkfilechooserutils.h
index 53d6e83..770656f 100644
--- a/gtk/gtkfilechooserutils.h
+++ b/gtk/gtkfilechooserutils.h
@@ -42,8 +42,8 @@ typedef enum {
GTK_FILE_CHOOSER_PROP_SHOW_HIDDEN,
GTK_FILE_CHOOSER_PROP_DO_OVERWRITE_CONFIRMATION,
GTK_FILE_CHOOSER_PROP_CREATE_FOLDERS,
- GTK_FILE_CHOOSER_PROP_ROOT_URI,
- GTK_FILE_CHOOSER_PROP_LAST = GTK_FILE_CHOOSER_PROP_ROOT_URI
+ GTK_FILE_CHOOSER_PROP_ROOT_URIS,
+ GTK_FILE_CHOOSER_PROP_LAST = GTK_FILE_CHOOSER_PROP_ROOT_URIS
} GtkFileChooserProp;
void _gtk_file_chooser_install_properties (GObjectClass *klass);
diff --git a/gtk/gtkpathbar.c b/gtk/gtkpathbar.c
index aad2670..6efe569 100644
--- a/gtk/gtkpathbar.c
+++ b/gtk/gtkpathbar.c
@@ -261,8 +261,6 @@ gtk_path_bar_finalize (GObject *object)
g_list_free (path_bar->button_list);
if (path_bar->root_file)
g_object_unref (path_bar->root_file);
- if (path_bar->root_uri)
- g_free (path_bar->root_uri);
if (path_bar->home_file)
g_object_unref (path_bar->home_file);
if (path_bar->desktop_file)
@@ -1457,6 +1455,8 @@ static ButtonType
find_button_type (GtkPathBar *path_bar,
GFile *file)
{
+ const GSList *l;
+
if (path_bar->root_file != NULL &&
g_file_equal (file, path_bar->root_file))
return ROOT_BUTTON;
@@ -1467,15 +1467,16 @@ find_button_type (GtkPathBar *path_bar,
g_file_equal (file, path_bar->desktop_file))
return DESKTOP_BUTTON;
- if (path_bar->root_uri != NULL)
+ for (l = path_bar->root_uris; l != NULL; l = l->next)
{
+ char *root_uri = (char *)l->data;
char *uri = g_file_get_uri (file);
- int root_uri_len = strlen (path_bar->root_uri);
+ int root_uri_len = strlen (root_uri);
- if (!strcmp (uri, path_bar->root_uri) ||
- (path_bar->root_uri[root_uri_len - 1] == '/' &&
+ if (!strcmp (uri, root_uri) ||
+ (root_uri[root_uri_len - 1] == '/' &&
root_uri_len == strlen (uri) + 1 &&
- !strncmp (uri, path_bar->root_uri, root_uri_len - 1)))
+ !strncmp (uri, root_uri, root_uri_len - 1)))
{
return VIRTUAL_ROOT_BUTTON;
}
@@ -1665,8 +1666,8 @@ is_file_in_root (GtkPathBar *path_bar,
GFile *file)
{
char *uri = g_file_get_uri (file);
- gboolean result = path_bar->root_uri == NULL ||
- _gtk_file_chooser_uri_has_prefix (uri, path_bar->root_uri);
+ gboolean result = path_bar->root_uris == NULL ||
+ _gtk_file_chooser_uri_has_prefix (uri, path_bar->root_uris);
g_free(uri);
return result;
@@ -1857,13 +1858,12 @@ _gtk_path_bar_set_file_system (GtkPathBar *path_bar,
}
void
-_gtk_path_bar_set_root_uri (GtkPathBar *path_bar,
- const char *root_uri)
+_gtk_path_bar_set_root_uris (GtkPathBar *path_bar,
+ const GSList *root_uris)
{
g_return_if_fail (GTK_IS_PATH_BAR (path_bar));
- g_free (path_bar->root_uri);
- path_bar->root_uri = (root_uri == NULL ? NULL : g_strdup (root_uri));
+ path_bar->root_uris = root_uris;
/*
* We don't know if we can even query this URI, so clear the buttons as
diff --git a/gtk/gtkpathbar.h b/gtk/gtkpathbar.h
index 5aad390..b27ceec 100644
--- a/gtk/gtkpathbar.h
+++ b/gtk/gtkpathbar.h
@@ -45,7 +45,7 @@ struct _GtkPathBar
GFile *home_file;
GFile *desktop_file;
- char *root_uri;
+ const GSList *root_uris;
GCancellable *get_info_cancellable;
@@ -90,8 +90,8 @@ gboolean _gtk_path_bar_set_file (GtkPathBar *path_bar,
GFile *file,
gboolean keep_trail,
GError **error);
-void _gtk_path_bar_set_root_uri (GtkPathBar *path_bar,
- const char *root_uri);
+void _gtk_path_bar_set_root_uris (GtkPathBar *path_bar,
+ const GSList *root_uris);
void _gtk_path_bar_up (GtkPathBar *path_bar);
void _gtk_path_bar_down (GtkPathBar *path_bar);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]