[gtk+/multiroot-filechooser-2-20] Use a boxed G_TYPE_STRV for the 'root-uris' property, not a pointer to a list
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/multiroot-filechooser-2-20] Use a boxed G_TYPE_STRV for the 'root-uris' property, not a pointer to a list
- Date: Mon, 6 Sep 2010 20:33:04 +0000 (UTC)
commit 33026141792469d54d599bc23f1590bb9747cf82
Author: Federico Mena Quintero <federico novell com>
Date: Mon Sep 6 15:07:42 2010 -0500
Use a boxed G_TYPE_STRV for the 'root-uris' property, not a pointer to a list
That should be friendlier to language bindings, and it makes our memory management correct.
Signed-off-by: Federico Mena Quintero <federico novell com>
gtk/gtkfilechooser.c | 57 +++++++++++++++++++++++--------
gtk/gtkfilechooser.h | 4 +-
gtk/gtkfilechooserbutton.c | 27 +++++----------
gtk/gtkfilechooserdefault.c | 76 +++++++++++++++++++++++++++++++++++--------
gtk/gtkfilechooserentry.c | 2 +-
gtk/gtkfilechooserprivate.h | 3 +-
gtk/gtkpathbar.c | 2 +-
7 files changed, 118 insertions(+), 53 deletions(-)
---
diff --git a/gtk/gtkfilechooser.c b/gtk/gtkfilechooser.c
index 5c6669c..8b124e0 100644
--- a/gtk/gtkfilechooser.c
+++ b/gtk/gtkfilechooser.c
@@ -864,9 +864,10 @@ gtk_file_chooser_class_init (gpointer g_iface)
* Since: 2.18
*/
g_object_interface_install_property (g_iface,
- g_param_spec_pointer ("root-uris",
+ g_param_spec_boxed ("root-uris",
P_("Root URIs"),
P_("The URIs, if any, to use as the root for all access in the file chooser."),
+ G_TYPE_STRV,
GTK_PARAM_READWRITE));
}
@@ -988,7 +989,7 @@ gtk_file_chooser_get_local_only (GtkFileChooser *chooser)
/**
* gtk_file_chooser_set_root_uris:
* @chooser: a #GtkFileChooser
- * @root_uri: The root URI, or %NULL to allow access to everything.
+ * @root_uris: A %NULL-terminated array of strings with the root URIs, or %NULL to allow access to everything.
*
* 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.
@@ -1010,7 +1011,7 @@ gtk_file_chooser_get_local_only (GtkFileChooser *chooser)
**/
void
gtk_file_chooser_set_root_uris (GtkFileChooser *chooser,
- GSList *root_uris)
+ const gchar **root_uris)
{
g_return_if_fail (GTK_IS_FILE_CHOOSER (chooser));
@@ -1037,14 +1038,16 @@ gtk_file_chooser_set_root_uris (GtkFileChooser *chooser,
*
* See gtk_file_chooser_set_root_uris()
*
- * Return value: The root URIs, or %NULL.
+ * Return value: A %NULL-terminated array of strings with the URIs of the roots,
+ * or simply %NULL if there are no roots set for the @chooser. You should free
+ * this array with g_strfreev().
*
* Since: 2.18
**/
-GSList *
+gchar **
gtk_file_chooser_get_root_uris (GtkFileChooser *chooser)
{
- GSList *root_uris;
+ gchar **root_uris;
g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), NULL);
@@ -2885,16 +2888,16 @@ uri_has_prefix (const char *uri, const char *prefix)
}
gboolean
-_gtk_file_chooser_uri_has_prefix (const char *uri, GSList *prefixes)
+_gtk_file_chooser_uri_is_in_roots_list (const char *uri, GSList *roots)
{
GSList *l;
g_return_val_if_fail (uri != NULL, FALSE);
- if (prefixes == NULL)
- return TRUE; /* No prefix means all URIs are good */
+ if (roots == NULL)
+ return TRUE; /* No roots means all URIs are good */
- for (l = prefixes; l != NULL; l = l->next)
+ for (l = roots; l; l = l->next)
{
const char *prefix = l->data;
@@ -2905,18 +2908,36 @@ _gtk_file_chooser_uri_has_prefix (const char *uri, GSList *prefixes)
return FALSE;
}
+static gboolean
+uri_is_in_roots_strv (const char *uri, gchar **roots)
+{
+ gchar **r;
+
+ if (!roots)
+ return TRUE; /* No roots means all URIs are good */
+
+ for (r = roots; *r; r++)
+ if (uri_has_prefix (uri, *r))
+ return TRUE;
+
+ return FALSE;
+}
+
gboolean
_gtk_file_chooser_is_uri_in_roots (GtkFileChooser *chooser,
const char *uri)
{
- GSList *root_uris;
+ gchar **root_uris;
+ gboolean is_in_roots;
g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), FALSE);
g_return_val_if_fail (uri != NULL, FALSE);
root_uris = gtk_file_chooser_get_root_uris (chooser);
+ is_in_roots = uri_is_in_roots_strv (uri, root_uris);
+ g_strfreev (root_uris);
- return _gtk_file_chooser_uri_has_prefix (uri, root_uris);
+ return is_in_roots;
}
gboolean
@@ -2939,12 +2960,16 @@ _gtk_file_chooser_is_file_in_roots (GtkFileChooser *chooser,
GSList *
_gtk_file_chooser_get_visible_roots (GtkFileChooser *chooser)
{
- GSList *l, *results = NULL;
+ GSList *results = NULL;
GtkFileSystem *file_system = _gtk_file_chooser_get_file_system (chooser);
+ gchar **root_uris;
+ gchar **r;
- for (l = gtk_file_chooser_get_root_uris (chooser); l != NULL; l = l->next)
+ root_uris = gtk_file_chooser_get_root_uris (chooser);
+
+ for (r = root_uris; r && *r; r++)
{
- GFile *file = g_file_new_for_uri ((char *)l->data);
+ GFile *file = g_file_new_for_uri (*r);
gboolean skip = FALSE;
GtkFileSystemVolume *volume;
GFileInfo *file_info;
@@ -3011,6 +3036,8 @@ _gtk_file_chooser_get_visible_roots (GtkFileChooser *chooser)
results = g_slist_append (results, file);
}
+ g_strfreev (root_uris);
+
return results;
}
diff --git a/gtk/gtkfilechooser.h b/gtk/gtkfilechooser.h
index 63ec0a1..47dff02 100644
--- a/gtk/gtkfilechooser.h
+++ b/gtk/gtkfilechooser.h
@@ -124,8 +124,8 @@ void gtk_file_chooser_set_local_only (GtkFileChooser
gboolean local_only);
gboolean gtk_file_chooser_get_local_only (GtkFileChooser *chooser);
void gtk_file_chooser_set_root_uris (GtkFileChooser *chooser,
- GSList *root_uris);
-GSList *gtk_file_chooser_get_root_uris (GtkFileChooser *chooser);
+ const gchar **root_uris);
+gchar **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 83369cb..178e68b 100644
--- a/gtk/gtkfilechooserbutton.c
+++ b/gtk/gtkfilechooserbutton.c
@@ -924,11 +924,12 @@ gtk_file_chooser_button_set_property (GObject *object,
if (!_gtk_file_chooser_is_file_in_roots (filechooser, gtk_file_chooser_get_current_folder_file (filechooser)))
{
- GSList *root_uris = gtk_file_chooser_get_root_uris (filechooser);
+ char **root_uris = gtk_file_chooser_get_root_uris (filechooser);
- GFile *file = g_file_new_for_uri (root_uris == NULL
+ GFile *file = g_file_new_for_uri ((root_uris == NULL || *root_uris == NULL)
? "file:///"
- : (char *)root_uris->data);
+ : root_uris[0]);
+ g_strfreev (root_uris);
gtk_file_chooser_set_current_folder_file (filechooser, file, NULL);
model_update_current_folder (button, file);
@@ -1885,7 +1886,6 @@ model_add_volumes (GtkFileChooserButton *button,
GtkListStore *store;
gint pos;
gboolean local_only;
- GSList *root_uris;
GtkFileSystem *file_system;
GtkFileChooser *filechooser;
GSList *l;
@@ -1897,7 +1897,6 @@ 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_uris = gtk_file_chooser_get_root_uris (filechooser);
file_system = button->priv->fs;
for (l = volumes; l; l = l->next)
@@ -1918,9 +1917,8 @@ model_add_volumes (GtkFileChooserButton *button,
_gtk_file_system_volume_is_mounted (volume) &&
!g_file_is_native (base_file))
skip = TRUE;
- else if (root_uris != NULL &&
- (base_file == NULL ||
- !_gtk_file_chooser_is_file_in_roots (filechooser, base_file)))
+ else if (base_file == NULL ||
+ !_gtk_file_chooser_is_file_in_roots (filechooser, base_file))
skip = TRUE;
if (base_file != NULL)
@@ -2200,13 +2198,11 @@ model_remove_rows (GtkFileChooserButton *button,
/* Filter Model */
static inline gboolean
-test_if_file_is_visible (GtkFileSystem *fs,
+test_if_file_is_visible (GtkFileChooserButton *button,
GFile *file,
gboolean local_only,
- GSList *root_uris,
gboolean is_folder)
{
- char *uri;
gboolean result;
if (!file)
@@ -2215,9 +2211,7 @@ test_if_file_is_visible (GtkFileSystem *fs,
if (local_only && !g_file_is_native (file))
return FALSE;
- uri = g_file_get_uri (file);
- result = _gtk_file_chooser_uri_has_prefix (uri, root_uris);
- g_free (uri);
+ result = _gtk_file_chooser_is_file_in_roots (GTK_FILE_CHOOSER (button), file);
if (!result)
return FALSE;
@@ -2238,12 +2232,10 @@ filter_model_visible_func (GtkTreeModel *model,
gchar type;
gpointer data;
gboolean local_only, retval, is_folder;
- GSList *root_uris;
type = ROW_TYPE_INVALID;
data = NULL;
local_only = gtk_file_chooser_get_local_only (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,
@@ -2259,8 +2251,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_uris,
- is_folder);
+ retval = test_if_file_is_visible (button, data, local_only, is_folder);
break;
case ROW_TYPE_VOLUME:
{
diff --git a/gtk/gtkfilechooserdefault.c b/gtk/gtkfilechooserdefault.c
index a5e8eac..1235f65 100644
--- a/gtk/gtkfilechooserdefault.c
+++ b/gtk/gtkfilechooserdefault.c
@@ -1976,6 +1976,7 @@ shortcuts_append_roots (GtkFileChooserDefault *impl)
shortcuts_insert_file (impl, start_row + n, SHORTCUT_TYPE_FILE,
NULL, file, NULL, FALSE, SHORTCUTS_ROOTS);
+ g_object_unref (file);
n++;
}
@@ -5449,22 +5450,34 @@ set_extra_widget (GtkFileChooserDefault *impl,
gtk_widget_hide (impl->extra_align);
}
+static GSList *
+strv_to_slist (const gchar **strv)
+{
+ const gchar **s;
+ GSList *list;
+
+ list = NULL;
+ for (s = strv; s && *s; s++)
+ list = g_slist_prepend (list, g_strdup (*s));
+
+ list = g_slist_reverse (list);
+
+ return list;
+}
+
static void
set_root_uris (GtkFileChooserDefault *impl,
- GSList *root_uris)
+ const gchar **root_uris)
{
GtkTreeIter iter;
GFile *list_selected = NULL;
ShortcutType shortcut_type = -1;
gboolean local_only;
- if (root_uris == impl->root_uris)
- return;
-
g_slist_foreach (impl->root_uris, (GFunc)g_free, NULL);
g_slist_free (impl->root_uris);
- impl->root_uris = root_uris;
+ impl->root_uris = strv_to_slist (root_uris);
local_only = gtk_file_chooser_get_local_only (GTK_FILE_CHOOSER (impl));
@@ -5769,11 +5782,11 @@ gtk_file_chooser_default_set_property (GObject *object,
break;
case GTK_FILE_CHOOSER_PROP_LOCAL_ONLY:
- set_root_uris (impl,
- g_value_get_boolean (value)
- ? g_slist_append (NULL, g_strdup ("file://"))
- : NULL);
- break;
+ {
+ const char *local_only_uris[] = { "file:///", NULL };
+ set_root_uris (impl, g_value_get_boolean (value) ? local_only_uris : NULL);
+ break;
+ }
case GTK_FILE_CHOOSER_PROP_PREVIEW_WIDGET:
set_preview_widget (impl, g_value_get_object (value));
@@ -5839,7 +5852,7 @@ gtk_file_chooser_default_set_property (GObject *object,
break;
case GTK_FILE_CHOOSER_PROP_ROOT_URIS:
- set_root_uris (impl, (GSList *)g_value_get_pointer (value));
+ set_root_uris (impl, (const gchar **) g_value_get_boxed (value));
break;
default:
@@ -5848,6 +5861,36 @@ gtk_file_chooser_default_set_property (GObject *object,
}
}
+static gchar **
+slist_to_strv (GSList *list)
+{
+ int n;
+ gchar **strv;
+ int i;
+ GSList *l;
+
+ n = g_slist_length (list);
+
+ if (n == 0)
+ return NULL;
+
+ strv = g_new (char *, n + 1);
+
+ i = 0;
+ for (l = list; l; l = l->next)
+ {
+ gchar *s;
+
+ s = l->data;
+ strv[i] = g_strdup (s);
+ i++;
+ }
+
+ strv[i] = NULL;
+
+ return strv;
+}
+
static void
gtk_file_chooser_default_get_property (GObject *object,
guint prop_id,
@@ -5921,8 +5964,13 @@ gtk_file_chooser_default_get_property (GObject *object,
break;
case GTK_FILE_CHOOSER_PROP_ROOT_URIS:
- g_value_set_pointer (value, impl->root_uris);
- break;
+ {
+ char **strv;
+
+ strv = slist_to_strv (impl->root_uris);
+ g_value_set_boxed (value, strv);
+ g_strfreev (strv);
+ }
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -9672,7 +9720,7 @@ recent_idle_load (gpointer data)
GtkRecentInfo *info = walk->data;
const char *uri = gtk_recent_info_get_uri (info);
- if (_gtk_file_chooser_is_uri_in_roots (GTK_FILE_CHOOSER (impl), uri))
+ if (_gtk_file_chooser_uri_is_in_roots_list (uri, impl->root_uris))
{
/* We'll sort this later, so prepend for efficiency. */
load_data->items = g_list_prepend(load_data->items, info);
diff --git a/gtk/gtkfilechooserentry.c b/gtk/gtkfilechooserentry.c
index bc7eaf9..f52615f 100644
--- a/gtk/gtkfilechooserentry.c
+++ b/gtk/gtkfilechooserentry.c
@@ -454,7 +454,7 @@ is_file_in_roots (GtkFileChooserEntry *chooser_entry,
GFile *file)
{
char *uri = g_file_get_uri (file);
- gboolean result = _gtk_file_chooser_uri_has_prefix (uri, chooser_entry->root_uris);
+ gboolean result = _gtk_file_chooser_uri_is_in_roots_list (uri, chooser_entry->root_uris);
g_free (uri);
return result;
diff --git a/gtk/gtkfilechooserprivate.h b/gtk/gtkfilechooserprivate.h
index 7ab7583..9b55e66 100644
--- a/gtk/gtkfilechooserprivate.h
+++ b/gtk/gtkfilechooserprivate.h
@@ -112,8 +112,7 @@ gboolean _gtk_file_chooser_is_file_in_roots (GtkFileChooser *chooser,
GFile *file);
GSList * _gtk_file_chooser_get_visible_roots (GtkFileChooser *chooser);
-gboolean _gtk_file_chooser_uri_has_prefix (const char *uri,
- GSList *prefixes);
+gboolean _gtk_file_chooser_uri_is_in_roots_list (const char *uri, GSList *roots);
/* GtkFileChooserDialog private */
diff --git a/gtk/gtkpathbar.c b/gtk/gtkpathbar.c
index 6c3bdcf..24af3da 100644
--- a/gtk/gtkpathbar.c
+++ b/gtk/gtkpathbar.c
@@ -1666,7 +1666,7 @@ is_file_in_roots (GtkPathBar *path_bar,
GFile *file)
{
char *uri = g_file_get_uri (file);
- gboolean result = _gtk_file_chooser_uri_has_prefix (uri, path_bar->root_uris);
+ gboolean result = _gtk_file_chooser_uri_is_in_roots_list (uri, path_bar->root_uris);
g_free(uri);
return result;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]