[gtk+/multiroot-filechooser: 7/15] Make GtkFileChooserButton work with root URI.
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/multiroot-filechooser: 7/15] Make GtkFileChooserButton work with root URI.
- Date: Thu, 17 Jun 2010 17:30:48 +0000 (UTC)
commit a0a949adad5b0e420bcb9bb1ec2dd93e7c91e433
Author: Christian Hammond <chipx86 chipx86 com>
Date: Fri Feb 5 21:12:37 2010 -0800
Make GtkFileChooserButton work with root URI.
GtkFileChooserButton now understands root URIs and only displays entries
in the list that would be shown in the file chooser.
gtk/gtkfilechooserbutton.c | 181 ++++++++++++++++++++++++++++++++++++--------
1 files changed, 149 insertions(+), 32 deletions(-)
---
diff --git a/gtk/gtkfilechooserbutton.c b/gtk/gtkfilechooserbutton.c
index c09af62..0d3c87f 100644
--- a/gtk/gtkfilechooserbutton.c
+++ b/gtk/gtkfilechooserbutton.c
@@ -140,6 +140,8 @@ struct _GtkFileChooserButtonPrivate
GtkFileSystem *fs;
GFile *old_file;
+ GSList *shortcuts;
+
gulong combo_box_changed_id;
gulong dialog_file_activated_id;
gulong dialog_folder_changed_id;
@@ -439,6 +441,8 @@ gtk_file_chooser_button_init (GtkFileChooserButton *button)
priv->icon_size = FALLBACK_ICON_SIZE;
priv->focus_on_click = TRUE;
+ priv->shortcuts = NULL;
+ priv->n_shortcuts = 0;
gtk_widget_push_composite_child ();
@@ -531,6 +535,57 @@ gtk_file_chooser_button_file_chooser_iface_init (GtkFileChooserIface *iface)
iface->remove_shortcut_folder = gtk_file_chooser_button_remove_shortcut_folder;
}
+static void
+add_shortcut_to_list (GtkFileChooserButton *button,
+ GFile *shortcut)
+{
+ GtkFileChooserButtonPrivate *priv = button->priv;
+ gint pos = model_get_type_position (button, ROW_TYPE_SHORTCUT) +
+ priv->n_shortcuts;
+ GtkTreeIter iter;
+
+ gtk_list_store_insert (GTK_LIST_STORE (priv->model), &iter, pos);
+ gtk_list_store_set (GTK_LIST_STORE (priv->model), &iter,
+ ICON_COLUMN, NULL,
+ DISPLAY_NAME_COLUMN, _(FALLBACK_DISPLAY_NAME),
+ TYPE_COLUMN, ROW_TYPE_SHORTCUT,
+ DATA_COLUMN, g_object_ref (shortcut),
+ IS_FOLDER_COLUMN, FALSE,
+ -1);
+ set_info_for_file_at_iter (button, shortcut, &iter);
+ priv->n_shortcuts++;
+}
+
+static void
+reload_shortcuts (GtkFileChooserButton *button)
+{
+ GtkFileChooser *filechooser;
+ GtkFileChooserButtonPrivate *priv = button->priv;
+ GSList *l;
+
+ model_remove_rows (button,
+ model_get_type_position (button, ROW_TYPE_SHORTCUT),
+ priv->n_shortcuts);
+ priv->n_shortcuts = 0;
+
+ filechooser = GTK_FILE_CHOOSER (button->priv->dialog);
+
+ for (l = priv->shortcuts; l != NULL; l = l->next)
+ {
+ GFile *shortcut = (GFile *)l->data;
+
+ if (_gtk_file_chooser_is_file_in_root (filechooser, shortcut))
+ {
+ add_shortcut_to_list (button, shortcut);
+ }
+ }
+
+ gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (priv->filter_model));
+
+ update_label_and_image (button);
+ update_combo_box (button);
+}
+
static gboolean
gtk_file_chooser_button_add_shortcut_folder (GtkFileChooser *chooser,
GFile *file,
@@ -547,24 +602,16 @@ gtk_file_chooser_button_add_shortcut_folder (GtkFileChooser *chooser,
{
GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (chooser);
GtkFileChooserButtonPrivate *priv = button->priv;
- GtkTreeIter iter;
- gint pos;
-
- pos = model_get_type_position (button, ROW_TYPE_SHORTCUT);
- pos += priv->n_shortcuts;
- gtk_list_store_insert (GTK_LIST_STORE (priv->model), &iter, pos);
- gtk_list_store_set (GTK_LIST_STORE (priv->model), &iter,
- ICON_COLUMN, NULL,
- DISPLAY_NAME_COLUMN, _(FALLBACK_DISPLAY_NAME),
- TYPE_COLUMN, ROW_TYPE_SHORTCUT,
- DATA_COLUMN, g_object_ref (file),
- IS_FOLDER_COLUMN, FALSE,
- -1);
- set_info_for_file_at_iter (button, file, &iter);
- priv->n_shortcuts++;
+ g_object_ref (G_OBJECT (file));
+ priv->shortcuts = g_slist_append (priv->shortcuts, file);
- gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (priv->filter_model));
+ if (_gtk_file_chooser_is_file_in_root (GTK_FILE_CHOOSER (priv->dialog),
+ file))
+ {
+ add_shortcut_to_list (button, file);
+ gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (priv->filter_model));
+ }
}
return retval;
@@ -590,6 +637,7 @@ gtk_file_chooser_button_remove_shortcut_folder (GtkFileChooser *chooser,
GtkTreeIter iter;
gint pos;
gchar type;
+ GSList *l;
pos = model_get_type_position (button, ROW_TYPE_SHORTCUT);
gtk_tree_model_iter_nth_child (priv->model, &iter, NULL, pos);
@@ -616,6 +664,18 @@ gtk_file_chooser_button_remove_shortcut_folder (GtkFileChooser *chooser,
}
while (type == ROW_TYPE_SHORTCUT &&
gtk_tree_model_iter_next (priv->model, &iter));
+
+ for (l = priv->shortcuts; l != NULL; l = l->next)
+ {
+ GFile *shortcut = (GFile *)l->data;
+
+ if (g_file_equal (shortcut, file))
+ {
+ g_object_unref (G_OBJECT (shortcut));
+ priv->shortcuts = g_slist_remove_link (priv->shortcuts, l);
+ break;
+ }
+ }
}
return retval;
@@ -749,6 +809,7 @@ gtk_file_chooser_button_set_property (GObject *object,
{
GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (object);
GtkFileChooserButtonPrivate *priv = button->priv;
+ GtkFileChooser *filechooser = GTK_FILE_CHOOSER (priv->dialog);
switch (param_id)
{
@@ -817,8 +878,22 @@ gtk_file_chooser_button_set_property (GObject *object,
case GTK_FILE_CHOOSER_PROP_LOCAL_ONLY:
case GTK_FILE_CHOOSER_PROP_ROOT_URI:
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));
+
+ gtk_file_chooser_set_current_folder_file (filechooser, file, NULL);
+ model_update_current_folder (button, file);
+ g_object_unref (G_OBJECT (file));
+ }
+
fs_volumes_changed_cb (priv->fs, button);
fs_bookmarks_changed_cb (priv->fs, button);
+ reload_shortcuts (button);
+
break;
case GTK_FILE_CHOOSER_PROP_FILE_SYSTEM_BACKEND:
@@ -868,6 +943,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:
g_object_get_property (G_OBJECT (priv->dialog), pspec->name, value);
break;
@@ -886,6 +962,13 @@ gtk_file_chooser_button_finalize (GObject *object)
if (priv->old_file)
g_object_unref (priv->old_file);
+ if (priv->shortcuts)
+ {
+ g_slist_foreach (priv->shortcuts, (GFunc)g_object_unref, NULL);
+ g_slist_free (priv->shortcuts);
+ priv->shortcuts = NULL;
+ }
+
G_OBJECT_CLASS (gtk_file_chooser_button_parent_class)->finalize (object);
}
@@ -1751,7 +1834,9 @@ model_add_volumes (GtkFileChooserButton *button,
GtkListStore *store;
gint pos;
gboolean local_only;
+ const char *root_uri;
GtkFileSystem *file_system;
+ GtkFileChooser *filechooser;
GSList *l;
if (!volumes)
@@ -1759,7 +1844,9 @@ model_add_volumes (GtkFileChooserButton *button,
store = GTK_LIST_STORE (button->priv->model);
pos = model_get_type_position (button, ROW_TYPE_VOLUME);
- local_only = gtk_file_chooser_get_local_only (GTK_FILE_CHOOSER (button->priv->dialog));
+ 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);
file_system = button->priv->fs;
for (l = volumes; l; l = l->next)
@@ -1768,23 +1855,31 @@ model_add_volumes (GtkFileChooserButton *button,
GtkTreeIter iter;
GdkPixbuf *pixbuf;
gchar *display_name;
+ GFile *base_file;
+ gboolean skip = FALSE;
volume = l->data;
- if (local_only)
- {
- if (_gtk_file_system_volume_is_mounted (volume))
- {
- GFile *base_file;
+ base_file = _gtk_file_system_volume_get_root (volume);
- base_file = _gtk_file_system_volume_get_root (volume);
- if (base_file != NULL && !g_file_is_native (base_file))
- {
- _gtk_file_system_volume_free (volume);
- continue;
- }
- }
- }
+ if (local_only &&
+ base_file != NULL &&
+ _gtk_file_system_volume_is_mounted (volume) &&
+ !g_file_is_native (base_file))
+ skip = TRUE;
+ else if (root_uri != NULL &&
+ (base_file == NULL ||
+ !_gtk_file_chooser_is_file_in_root (filechooser, base_file)))
+ skip = TRUE;
+
+ if (base_file != NULL)
+ g_object_unref (base_file);
+
+ if (skip)
+ {
+ _gtk_file_system_volume_free (volume);
+ continue;
+ }
pixbuf = _gtk_file_system_volume_render_icon (volume,
GTK_WIDGET (button),
@@ -1821,13 +1916,15 @@ model_add_bookmarks (GtkFileChooserButton *button,
gint pos;
gboolean local_only;
GSList *l;
+ GtkFileChooser *filechooser;
if (!bookmarks)
return;
store = GTK_LIST_STORE (button->priv->model);
pos = model_get_type_position (button, ROW_TYPE_BOOKMARK);
- local_only = gtk_file_chooser_get_local_only (GTK_FILE_CHOOSER (button->priv->dialog));
+ filechooser = GTK_FILE_CHOOSER (button->priv->dialog);
+ local_only = gtk_file_chooser_get_local_only (filechooser);
for (l = bookmarks; l; l = l->next)
{
@@ -1835,6 +1932,9 @@ model_add_bookmarks (GtkFileChooserButton *button,
file = l->data;
+ if (!_gtk_file_chooser_is_file_in_root (filechooser, file))
+ continue;
+
if (g_file_is_native (file))
{
gtk_list_store_insert (store, &iter, pos);
@@ -2052,14 +2152,26 @@ static inline gboolean
test_if_file_is_visible (GtkFileSystem *fs,
GFile *file,
gboolean local_only,
+ const char *root_uri,
gboolean is_folder)
{
+ char *uri;
+ gboolean result;
+
if (!file)
return FALSE;
if (local_only && !g_file_is_native (file))
return FALSE;
+ uri = g_file_get_uri (file);
+ result = (root_uri == NULL ||
+ _gtk_file_chooser_uri_has_prefix (uri, root_uri));
+ g_free (uri);
+
+ if (!result)
+ return FALSE;
+
if (!is_folder)
return FALSE;
@@ -2076,10 +2188,12 @@ filter_model_visible_func (GtkTreeModel *model,
gchar type;
gpointer data;
gboolean local_only, retval, is_folder;
+ const char *root_uri;
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));
gtk_tree_model_get (model, iter,
TYPE_COLUMN, &type,
@@ -2095,7 +2209,8 @@ 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, is_folder);
+ retval = test_if_file_is_visible (priv->fs, data, local_only, root_uri,
+ is_folder);
break;
case ROW_TYPE_VOLUME:
{
@@ -2921,3 +3036,5 @@ gtk_file_chooser_button_get_focus_on_click (GtkFileChooserButton *button)
#define __GTK_FILE_CHOOSER_BUTTON_C__
#include "gtkaliasdef.c"
+
+// vim: et sw=2 cinoptions=(0,t0,f1s,n-1s,{1s,>2s,^-1s
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]