[gtk+/multiroot-filechooser: 12/15] Show the roots in the sidebar.
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/multiroot-filechooser: 12/15] Show the roots in the sidebar.
- Date: Thu, 17 Jun 2010 17:31:13 +0000 (UTC)
commit 556d86fb5fb47d723837d13b8acc691dbbf99331
Author: Christian Hammond <chipx86 chipx86 com>
Date: Mon Mar 22 17:47:26 2010 -0700
Show the roots in the sidebar.
Roots will be shown only if:
1) They're not the user's Desktop or Home directories (which would already
be listed otherwise).
2) It's not the URI of an existing volume.
3) The parent volume isn't already a root.
4) The root actually does exist (preventing non-browseable roots, like "ftp:")
gtk/gtkfilechooser.c | 78 +++++++++++++++++++++++++++++++++++++++++++
gtk/gtkfilechooserbutton.c | 50 +++++++++++++++++++++++++++
gtk/gtkfilechooserdefault.c | 55 ++++++++++++++++++++++++++++++
gtk/gtkfilechooserprivate.h | 2 +
4 files changed, 185 insertions(+), 0 deletions(-)
---
diff --git a/gtk/gtkfilechooser.c b/gtk/gtkfilechooser.c
index 4306151..2398ce2 100644
--- a/gtk/gtkfilechooser.c
+++ b/gtk/gtkfilechooser.c
@@ -2941,6 +2941,84 @@ _gtk_file_chooser_is_file_in_root (GtkFileChooser *chooser,
return result;
}
+GSList *
+_gtk_file_chooser_get_visible_roots (GtkFileChooser *chooser)
+{
+ GSList *l, *results = NULL;
+ GtkFileSystem *file_system = _gtk_file_chooser_get_file_system (chooser);
+
+ for (l = gtk_file_chooser_get_root_uris (chooser); l != NULL; l = l->next)
+ {
+ GFile *file = g_file_new_for_uri ((char *)l->data);
+ gboolean skip = FALSE;
+ GtkFileSystemVolume *volume;
+ GFileInfo *file_info;
+ char *file_path;
+
+ if (file == NULL)
+ continue;
+
+ file_path = g_file_get_path (file);
+
+ /*
+ * See if this is the Desktop directory or Home directory, which will
+ * already be listed.
+ */
+ if (!g_strcmp0 (file_path,
+ g_get_user_special_dir (G_USER_DIRECTORY_DESKTOP)) ||
+ !g_strcmp0 (file_path, g_get_home_dir()))
+ {
+ g_object_unref (file);
+ g_free (file_path);
+ continue;
+ }
+
+ /* Make sure the file exists in some form. */
+ file_info = g_file_query_info (file,
+ G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME,
+ G_FILE_QUERY_INFO_NONE,
+ NULL,
+ NULL);
+
+ if (file_info == NULL)
+ {
+ g_object_unref (file_info);
+ g_object_unref (file);
+ continue;
+ }
+
+ volume = _gtk_file_system_get_volume_for_file (file_system, file);
+
+ if (volume != NULL)
+ {
+ GFile *fs_root = _gtk_file_system_volume_get_root (volume);
+
+ if (fs_root != NULL)
+ {
+ if (_gtk_file_chooser_is_file_in_root (GTK_FILE_CHOOSER (chooser),
+ fs_root))
+ {
+ // This is going to be listed already. Ignore it for now.
+ skip = TRUE;
+ }
+
+ g_object_unref (fs_root);
+ }
+ }
+
+ if (skip)
+ {
+ g_object_unref (file);
+ continue;
+ }
+
+ results = g_slist_append (results, file);
+ }
+
+ return results;
+}
+
+
#define __GTK_FILE_CHOOSER_C__
#include "gtkaliasdef.c"
diff --git a/gtk/gtkfilechooserbutton.c b/gtk/gtkfilechooserbutton.c
index ca4415e..1c79a75 100644
--- a/gtk/gtkfilechooserbutton.c
+++ b/gtk/gtkfilechooserbutton.c
@@ -106,6 +106,7 @@ enum
typedef enum
{
ROW_TYPE_SPECIAL,
+ ROW_TYPE_ROOT,
ROW_TYPE_VOLUME,
ROW_TYPE_SHORTCUT,
ROW_TYPE_BOOKMARK_SEPARATOR,
@@ -156,6 +157,7 @@ struct _GtkFileChooserButtonPrivate
gint icon_size;
guint8 n_special;
+ guint8 n_roots;
guint8 n_volumes;
guint8 n_shortcuts;
guint8 n_bookmarks;
@@ -536,6 +538,47 @@ gtk_file_chooser_button_file_chooser_iface_init (GtkFileChooserIface *iface)
}
static void
+reload_roots (GtkFileChooserButton *button)
+{
+ GtkFileChooser *filechooser;
+ GtkFileChooserButtonPrivate *priv = button->priv;
+ GSList *l, *roots;
+ gint start_pos;
+
+ start_pos = model_get_type_position (button, ROW_TYPE_ROOT);
+ model_remove_rows (button, start_pos, priv->n_roots);
+ priv->n_roots = 0;
+
+ filechooser = GTK_FILE_CHOOSER (button->priv->dialog);
+ roots = _gtk_file_chooser_get_visible_roots (GTK_FILE_CHOOSER (filechooser));
+
+ for (l = roots; l != NULL; l = l->next)
+ {
+ GFile *file = (GFile *)l->data;
+ gint pos = start_pos + priv->n_roots;
+ 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_ROOT,
+ DATA_COLUMN, file,
+ IS_FOLDER_COLUMN, FALSE,
+ -1);
+ set_info_for_file_at_iter (button, file, &iter);
+ priv->n_roots++;
+ }
+
+ g_slist_free (roots);
+
+ gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (priv->filter_model));
+
+ update_label_and_image (button);
+ update_combo_box (button);
+}
+
+static void
add_shortcut_to_list (GtkFileChooserButton *button,
GFile *shortcut)
{
@@ -895,6 +938,7 @@ gtk_file_chooser_button_set_property (GObject *object,
fs_volumes_changed_cb (priv->fs, button);
fs_bookmarks_changed_cb (priv->fs, button);
+ reload_roots (button);
reload_shortcuts (button);
break;
@@ -1605,6 +1649,11 @@ model_get_type_position (GtkFileChooserButton *button,
retval += button->priv->n_special;
+ if (row_type == ROW_TYPE_ROOT)
+ return retval;
+
+ retval += button->priv->n_roots;
+
if (row_type == ROW_TYPE_VOLUME)
return retval;
@@ -2631,6 +2680,7 @@ combo_box_changed_cb (GtkComboBox *combo_box,
switch (type)
{
case ROW_TYPE_SPECIAL:
+ case ROW_TYPE_ROOT:
case ROW_TYPE_SHORTCUT:
case ROW_TYPE_BOOKMARK:
case ROW_TYPE_CURRENT_FOLDER:
diff --git a/gtk/gtkfilechooserdefault.c b/gtk/gtkfilechooserdefault.c
index d4b94ed..335a666 100644
--- a/gtk/gtkfilechooserdefault.c
+++ b/gtk/gtkfilechooserdefault.c
@@ -244,6 +244,7 @@ typedef enum {
SHORTCUTS_RECENT_SEPARATOR,
SHORTCUTS_HOME,
SHORTCUTS_DESKTOP,
+ SHORTCUTS_ROOTS,
SHORTCUTS_VOLUMES,
SHORTCUTS_SHORTCUTS,
SHORTCUTS_BOOKMARKS_SEPARATOR,
@@ -1410,6 +1411,10 @@ shortcuts_update_count (GtkFileChooserDefault *impl,
impl->has_desktop = TRUE;
break;
+ case SHORTCUTS_ROOTS:
+ impl->num_roots += value;
+ break;
+
case SHORTCUTS_VOLUMES:
impl->num_volumes += value;
break;
@@ -1957,6 +1962,49 @@ shortcuts_append_desktop (GtkFileChooserDefault *impl)
profile_end ("end", NULL);
}
+static void
+shortcuts_append_roots (GtkFileChooserDefault *impl)
+{
+ GSList *l, *roots;
+ gboolean old_changing_folders;
+ int start_row;
+ int n = 0;
+
+ profile_start ("start", NULL);
+
+ old_changing_folders = impl->changing_folder;
+ impl->changing_folder = TRUE;
+
+ start_row = shortcuts_get_index (impl, SHORTCUTS_ROOTS);
+ shortcuts_remove_rows (impl, start_row, impl->num_roots);
+ impl->num_roots = 0;
+
+ roots = _gtk_file_chooser_get_visible_roots (GTK_FILE_CHOOSER (impl));
+
+ for (l = roots; l != NULL; l = l->next)
+ {
+ GFile *file = (GFile *)l->data;
+
+ shortcuts_insert_file (impl, start_row + n, SHORTCUT_TYPE_FILE,
+ NULL, file, NULL, FALSE, SHORTCUTS_ROOTS);
+ n++;
+ }
+
+ g_slist_free (roots);
+
+ impl->num_roots = n;
+
+ if (impl->shortcuts_pane_filter_model)
+ gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (impl->shortcuts_pane_filter_model));
+
+ if (impl->shortcuts_combo_filter_model)
+ gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (impl->shortcuts_combo_filter_model));
+
+ impl->changing_folder = old_changing_folders;
+
+ profile_end ("end", NULL);
+}
+
/* Appends a list of GFile to the shortcuts model; returns how many were inserted */
static int
shortcuts_append_bookmarks (GtkFileChooserDefault *impl,
@@ -2036,6 +2084,11 @@ shortcuts_get_index (GtkFileChooserDefault *impl,
n += impl->has_desktop ? 1 : 0;
+ if (where == SHORTCUTS_ROOTS)
+ goto out;
+
+ n += impl->num_roots;
+
if (where == SHORTCUTS_VOLUMES)
goto out;
@@ -2426,6 +2479,7 @@ shortcuts_model_create (GtkFileChooserDefault *impl)
{
shortcuts_append_home (impl);
shortcuts_append_desktop (impl);
+ shortcuts_append_roots (impl);
shortcuts_add_volumes (impl);
}
@@ -5553,6 +5607,7 @@ static void
volumes_bookmarks_changed_cb (GtkFileSystem *file_system,
GtkFileChooserDefault *impl)
{
+ shortcuts_append_roots (impl);
shortcuts_add_volumes (impl);
shortcuts_add_bookmarks (impl);
diff --git a/gtk/gtkfilechooserprivate.h b/gtk/gtkfilechooserprivate.h
index dc339c7..c02c3ee 100644
--- a/gtk/gtkfilechooserprivate.h
+++ b/gtk/gtkfilechooserprivate.h
@@ -110,6 +110,7 @@ gboolean _gtk_file_chooser_is_uri_in_root (GtkFileChooser *chooser,
const char *uri);
gboolean _gtk_file_chooser_is_file_in_root (GtkFileChooser *chooser,
GFile *file);
+GSList * _gtk_file_chooser_get_visible_roots (GtkFileChooser *chooser);
gboolean _gtk_file_chooser_uri_has_prefix (const char *uri,
const GSList *prefixes);
@@ -262,6 +263,7 @@ struct _GtkFileChooserDefault
GtkFileFilter *current_filter;
GSList *filters;
+ int num_roots;
int num_volumes;
int num_shortcuts;
int num_bookmarks;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]