summaryrefslogtreecommitdiff
path: root/gtk
diff options
context:
space:
mode:
authorFederico Mena Quintero <federico@ximian.com>2003-10-08 04:14:55 +0000
committerFederico Mena Quintero <federico@src.gnome.org>2003-10-08 04:14:55 +0000
commit462aab4a64c5a00932fcb445a20bed4110684503 (patch)
tree1e26a017335f53de77f065bc4442c24a5e432398 /gtk
parentcc46d181bd74f25793e0d5dd3c73396b37a71ed0 (diff)
downloadgtk+-462aab4a64c5a00932fcb445a20bed4110684503.tar.gz
Added methods for ::get_supports_bookmarks(), ::set_bookmarks(),
2003-10-07 Federico Mena Quintero <federico@ximian.com> * gtkfilesystem.h (struct _GtkFileSystemIface): Added methods for ::get_supports_bookmarks(), ::set_bookmarks(), ::list_bookmarks(). Added a ::bookmarks_changed() signal. * gtkfilesystem.c (gtk_file_system_get_supports_bookmarks): New function. (gtk_file_system_set_bookmarks): New function. (gtk_file_system_list_bookmarks): New function. (gtk_file_system_base_init): Create the "bookmarks-changed" signal. (gtk_file_paths_copy): New function. * gtkfilesystemunix.c (gtk_file_system_unix_get_supports_bookmarks): Implement. (gtk_file_system_unix_set_bookmarks): Implement. (gtk_file_system_unix_get_bookmarks): Implement. * gtkfilesystemgnomevfs.c (struct _GtkFileSystemGnomeVFS): Added fields for the bookmarks and the GConfClient. (gtk_file_system_gnome_vfs_set_bookmarks): Implement. (gtk_file_system_gnome_vfs_list_bookmarks): Implement. * gtkfilechooserprivate.h (struct _GtkFileChooserIface): Added methods for ::set_shortcut_folders(), ::list_shortcut_folders(). * gtkfilechooser.c (gtk_file_chooser_set_shortcut_folders): New function. (gtk_file_chooser_list_shortcut_folders): New function. * gtkfilechooserimpldefault.c (create_shortcuts_model): Unref the old shortcuts model if it exists. Create the nodes for the app-specific shortcut folders. (struct _GtkFileChooserImplDefault): Added a field for the shortcut_folders. (gtk_file_chooser_impl_default_set_shortcut_folders): Implement. (select_shortcuts_folder): New helper function. (gtk_file_chooser_impl_default_set_current_folder): Use select_shortcuts_folder(). (shortcuts_append_path): Get the file info here, instead of the caller. (shortcuts_append_home): Use shortcuts_append_path(). (shortcuts_append_file_system_roots): Likewise. (create_shortcuts_model): Add the app-specific shortcut folders and the bookmarks. (gtk_file_chooser_impl_default_list_shortcut_folders): Implement. (create_shortcuts_tree): Added a button to let the user add the current folder to the bookmarks. (gtk_file_chooser_impl_default_set_property): Connect to "bookmarks-changed" on the file system. (shortcuts_append_bookmarks): New function. * configure.ac: Depend on GConf.
Diffstat (limited to 'gtk')
-rw-r--r--gtk/gtkfilechooser.c37
-rw-r--r--gtk/gtkfilechooser.h6
-rw-r--r--gtk/gtkfilechooserdefault.c359
-rw-r--r--gtk/gtkfilechooserprivate.h44
-rw-r--r--gtk/gtkfilesystem.c105
-rw-r--r--gtk/gtkfilesystem.h20
-rw-r--r--gtk/gtkfilesystemunix.c32
7 files changed, 473 insertions, 130 deletions
diff --git a/gtk/gtkfilechooser.c b/gtk/gtkfilechooser.c
index 0153b23d55..c3cd8bf96e 100644
--- a/gtk/gtkfilechooser.c
+++ b/gtk/gtkfilechooser.c
@@ -1231,3 +1231,40 @@ gtk_file_chooser_get_filter (GtkFileChooser *chooser)
return filter;
}
+
+/* gtk_file_chooser_set_shortcut_folders:
+ * @chooser: a #GtkFileChooser
+ * @shortcut_folders: a list of #GtkFilePath, or NULL if you want to clear the
+ * current list of shortcut folders.
+ *
+ * Sets the list of shortcut folders to be shown in a file chooser. Note that
+ * these do not get saved, as they are provided by the application. For
+ * example, you can use this to add a "/usr/share/myapp/Clipart" folder to the
+ * volume list.
+ **/
+void
+gtk_file_chooser_set_shortcut_folders (GtkFileChooser *chooser,
+ GSList *shortcut_folders)
+{
+ g_return_if_fail (GTK_IS_FILE_CHOOSER (chooser));
+
+ GTK_FILE_CHOOSER_GET_IFACE (chooser)->set_shortcut_folders (chooser, shortcut_folders);
+}
+
+/**
+ * gtk_file_chooser_list_shortcut_folders:
+ * @chooser: a #GtkFileChooser
+ *
+ * Queries the list of shortcut folders in the file chooser, as set by
+ * gtk_file_chooser_set_shortcut_folders().
+ *
+ * Return value: A list of #GtkFilePath, or NULL if there are no shortcut
+ * folders. You should use gtk_file_paths_free() to free this list.
+ **/
+GSList *
+gtk_file_chooser_list_shortcut_folders (GtkFileChooser *chooser)
+{
+ g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), NULL);
+
+ return GTK_FILE_CHOOSER_GET_IFACE (chooser)->list_shortcut_folders (chooser);
+}
diff --git a/gtk/gtkfilechooser.h b/gtk/gtkfilechooser.h
index e2d55c240f..4ee520f063 100644
--- a/gtk/gtkfilechooser.h
+++ b/gtk/gtkfilechooser.h
@@ -121,6 +121,12 @@ void gtk_file_chooser_set_filter (GtkFileChooser *chooser,
GtkFileFilter *filter);
GtkFileFilter *gtk_file_chooser_get_filter (GtkFileChooser *chooser);
+/* Per-application shortcut folders */
+
+void gtk_file_chooser_set_shortcut_folders (GtkFileChooser *chooser,
+ GSList *shortcut_directories);
+GSList *gtk_file_chooser_list_shortcut_folders (GtkFileChooser *chooser);
+
G_END_DECLS
#endif /* __GTK_FILE_CHOOSER_H__ */
diff --git a/gtk/gtkfilechooserdefault.c b/gtk/gtkfilechooserdefault.c
index fc08b2cc14..322039cd87 100644
--- a/gtk/gtkfilechooserdefault.c
+++ b/gtk/gtkfilechooserdefault.c
@@ -73,6 +73,11 @@ struct _GtkFileChooserImplDefault
GtkFileFilter *current_filter;
GSList *filters;
+ GSList *shortcut_folders;
+
+ guint bookmarks_changed_id;
+ GtkTreeIter bookmarks_iter;
+
GtkFilePath *current_folder;
GtkFilePath *preview_path;
@@ -84,6 +89,7 @@ struct _GtkFileChooserImplDefault
GtkWidget *tree;
GtkWidget *shortcuts_scrollwin;
GtkWidget *shortcuts_tree;
+ GtkWidget *add_bookmark_button;
GtkWidget *list_scrollwin;
GtkWidget *list;
GtkWidget *entry;
@@ -97,6 +103,7 @@ struct _GtkFileChooserImplDefault
guint show_hidden : 1;
guint changing_folder : 1;
guint list_sort_ascending : 1;
+ guint bookmarks_set : 1;
};
/* Column numbers for the shortcuts tree */
@@ -136,25 +143,28 @@ static void gtk_file_chooser_impl_default_get_property (GObject
GParamSpec *pspec);
static void gtk_file_chooser_impl_default_show_all (GtkWidget *widget);
-static void gtk_file_chooser_impl_default_set_current_folder (GtkFileChooser *chooser,
- const GtkFilePath *path);
-static GtkFilePath * gtk_file_chooser_impl_default_get_current_folder (GtkFileChooser *chooser);
-static void gtk_file_chooser_impl_default_set_current_name (GtkFileChooser *chooser,
- const gchar *name);
-static void gtk_file_chooser_impl_default_select_path (GtkFileChooser *chooser,
- const GtkFilePath *path);
-static void gtk_file_chooser_impl_default_unselect_path (GtkFileChooser *chooser,
- const GtkFilePath *path);
-static void gtk_file_chooser_impl_default_select_all (GtkFileChooser *chooser);
-static void gtk_file_chooser_impl_default_unselect_all (GtkFileChooser *chooser);
-static GSList * gtk_file_chooser_impl_default_get_paths (GtkFileChooser *chooser);
-static GtkFilePath * gtk_file_chooser_impl_default_get_preview_path (GtkFileChooser *chooser);
-static GtkFileSystem *gtk_file_chooser_impl_default_get_file_system (GtkFileChooser *chooser);
-static void gtk_file_chooser_impl_default_add_filter (GtkFileChooser *chooser,
- GtkFileFilter *filter);
-static void gtk_file_chooser_impl_default_remove_filter (GtkFileChooser *chooser,
- GtkFileFilter *filter);
-static GSList * gtk_file_chooser_impl_default_list_filters (GtkFileChooser *chooser);
+static void gtk_file_chooser_impl_default_set_current_folder (GtkFileChooser *chooser,
+ const GtkFilePath *path);
+static GtkFilePath * gtk_file_chooser_impl_default_get_current_folder (GtkFileChooser *chooser);
+static void gtk_file_chooser_impl_default_set_current_name (GtkFileChooser *chooser,
+ const gchar *name);
+static void gtk_file_chooser_impl_default_select_path (GtkFileChooser *chooser,
+ const GtkFilePath *path);
+static void gtk_file_chooser_impl_default_unselect_path (GtkFileChooser *chooser,
+ const GtkFilePath *path);
+static void gtk_file_chooser_impl_default_select_all (GtkFileChooser *chooser);
+static void gtk_file_chooser_impl_default_unselect_all (GtkFileChooser *chooser);
+static GSList * gtk_file_chooser_impl_default_get_paths (GtkFileChooser *chooser);
+static GtkFilePath * gtk_file_chooser_impl_default_get_preview_path (GtkFileChooser *chooser);
+static GtkFileSystem *gtk_file_chooser_impl_default_get_file_system (GtkFileChooser *chooser);
+static void gtk_file_chooser_impl_default_add_filter (GtkFileChooser *chooser,
+ GtkFileFilter *filter);
+static void gtk_file_chooser_impl_default_remove_filter (GtkFileChooser *chooser,
+ GtkFileFilter *filter);
+static GSList * gtk_file_chooser_impl_default_list_filters (GtkFileChooser *chooser);
+static void gtk_file_chooser_impl_default_set_shortcut_folders (GtkFileChooser *chooser,
+ GSList *shortcut_folders);
+static GSList * gtk_file_chooser_impl_default_list_shortcut_folders (GtkFileChooser *chooser);
static void set_current_filter (GtkFileChooserImplDefault *impl,
GtkFileFilter *filter);
@@ -276,6 +286,8 @@ gtk_file_chooser_impl_default_iface_init (GtkFileChooserIface *iface)
iface->add_filter = gtk_file_chooser_impl_default_add_filter;
iface->remove_filter = gtk_file_chooser_impl_default_remove_filter;
iface->list_filters = gtk_file_chooser_impl_default_list_filters;
+ iface->set_shortcut_folders = gtk_file_chooser_impl_default_set_shortcut_folders;
+ iface->list_shortcut_folders = gtk_file_chooser_impl_default_list_shortcut_folders;
}
static void
@@ -295,6 +307,8 @@ gtk_file_chooser_impl_default_finalize (GObject *object)
{
GtkFileChooserImplDefault *impl = GTK_FILE_CHOOSER_IMPL_DEFAULT (object);
+ g_signal_handler_disconnect (impl->file_system, impl->bookmarks_changed_id);
+ impl->bookmarks_changed_id = 0;
g_object_unref (impl->file_system);
G_OBJECT_CLASS (parent_class)->finalize (object);
@@ -331,19 +345,39 @@ set_preview_widget (GtkFileChooserImplDefault *impl,
update_preview_widget_visibility (impl);
}
-/* Appends a directory to the shortcuts model at the specified iter */
-static void
-shortcuts_append_path (GtkFileChooserImplDefault *impl, GtkTreeIter *iter, GdkPixbuf *pixbuf, const char *label, GtkFilePath *path)
+/* Used from gtk_tree_model_foreach(); selects the item that corresponds to the
+ * current path. */
+static gboolean
+set_current_shortcut_foreach_cb (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
{
- GtkFilePath *path_copy;
+ GtkFileChooserImplDefault *impl;
+ GtkFilePath *model_path;
+ GtkTreeSelection *selection;
- path_copy = gtk_file_path_copy (path);
+ impl = GTK_FILE_CHOOSER_IMPL_DEFAULT (data);
- gtk_tree_store_set (impl->shortcuts_model, iter,
- SHORTCUTS_COL_PIXBUF, pixbuf,
- SHORTCUTS_COL_NAME, label,
- SHORTCUTS_COL_PATH, path_copy,
- -1);
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->shortcuts_tree));
+
+ gtk_tree_model_get (model, iter, SHORTCUTS_COL_PATH, &model_path, -1);
+
+ if (model_path && impl->current_folder && gtk_file_path_compare (model_path, impl->current_folder) == 0)
+ {
+ gtk_tree_selection_select_path (selection, path);
+ return TRUE;
+ }
+ else
+ gtk_tree_selection_unselect_path (selection, path);
+
+ return FALSE;
+}
+
+/* Selects the appropriate node in the shortcuts tree based on the current folder */
+static void
+select_shortcuts_folder (GtkFileChooserImplDefault *impl)
+{
+ gtk_tree_model_foreach (GTK_TREE_MODEL (impl->shortcuts_model),
+ set_current_shortcut_foreach_cb,
+ impl);
}
/* Convenience function to get the display name and icon info for a path */
@@ -371,17 +405,63 @@ get_file_info (GtkFileSystem *file_system, GtkFilePath *path, GError **error)
return info;
}
+/* Appends a path to the shortcuts tree, making a copy of it. If parent is
+ * NULL, then the item is appened at the end of the tree. If the label is NULL,
+ * then the display name of a GtkFileInfo is used.
+ */
+static void
+shortcuts_append_path (GtkFileChooserImplDefault *impl,
+ GtkTreeIter *parent,
+ GtkFilePath *path,
+ gboolean is_root,
+ const char *label)
+{
+ GtkFileInfo *info;
+ GtkFilePath *path_copy;
+ GdkPixbuf *pixbuf;
+ GtkTreeIter iter;
+
+ /* FIXME: what if someone adds a shortcut to a root? get_file_info() will not
+ * work in that case, I think...
+ */
+
+ if (is_root)
+ info = gtk_file_system_get_root_info (impl->file_system,
+ path,
+ GTK_FILE_INFO_DISPLAY_NAME | GTK_FILE_INFO_ICON,
+ NULL); /* FIXME: Use GError? */
+ else
+ info = get_file_info (impl->file_system, path, NULL); /* FIXME: use GError? */
+
+ if (!info)
+ return;
+
+ pixbuf = gtk_file_info_render_icon (info, impl->shortcuts_tree, ICON_SIZE);
+
+ gtk_tree_store_append (impl->shortcuts_model, &iter, parent);
+ path_copy = gtk_file_path_copy (path);
+
+ if (!label)
+ label = gtk_file_info_get_display_name (info);
+
+ gtk_tree_store_set (impl->shortcuts_model, &iter,
+ SHORTCUTS_COL_PIXBUF, pixbuf,
+ SHORTCUTS_COL_NAME, label,
+ SHORTCUTS_COL_PATH, path_copy,
+ -1);
+
+ if (pixbuf)
+ g_object_unref (pixbuf);
+}
+
/* Appends an item for the user's home directory to the shortcuts model */
static void
shortcuts_append_home (GtkFileChooserImplDefault *impl)
{
- GtkTreeIter iter;
const char *name;
const char *home;
GtkFilePath *home_path;
char *label;
- GtkFileInfo *info;
- GdkPixbuf *pixbuf;
name = g_get_user_name ();
label = g_strdup_printf ("%s's Home", name);
@@ -389,21 +469,7 @@ shortcuts_append_home (GtkFileChooserImplDefault *impl)
home = g_get_home_dir ();
home_path = gtk_file_system_filename_to_path (impl->file_system, home);
- /* FIXME: use GError? */
- info = get_file_info (impl->file_system, home_path, NULL);
- if (!info)
- goto out;
-
- pixbuf = gtk_file_info_render_icon (info, impl->shortcuts_tree, ICON_SIZE);
- gtk_file_info_free (info);
-
- gtk_tree_store_append (impl->shortcuts_model, &iter, NULL);
- shortcuts_append_path (impl, &iter, pixbuf, label, home_path);
-
- if (pixbuf)
- gdk_pixbuf_unref (pixbuf);
-
- out:
+ shortcuts_append_path (impl, NULL, home_path, FALSE, label);
g_free (label);
gtk_file_path_free (home_path);
@@ -419,52 +485,89 @@ shortcuts_append_file_system_roots (GtkFileChooserImplDefault *impl)
for (l = roots; l; l = l->next)
{
- GtkFilePath *path, *path_copy;
- GtkFileInfo *info;
- GdkPixbuf *pixbuf;
- GtkTreeIter iter;
+ GtkFilePath *path;
path = l->data;
- path_copy = gtk_file_path_copy (path);
- gtk_file_path_free (path);
+ shortcuts_append_path (impl, NULL, path, TRUE, NULL);
+ }
- info = gtk_file_system_get_root_info (impl->file_system,
- path_copy,
- GTK_FILE_INFO_DISPLAY_NAME | GTK_FILE_INFO_ICON,
- NULL); /* FIXME: Use GError? */
- if (!info)
- continue;
+ gtk_file_paths_free (roots);
+}
- pixbuf = gtk_file_info_render_icon (info, impl->shortcuts_tree, ICON_SIZE);
+/* Appends the application-specific shortcut folders to the shortcuts model */
+static void
+shortcuts_append_shortcut_folders (GtkFileChooserImplDefault *impl)
+{
+ GSList *l;
- gtk_tree_store_append (impl->shortcuts_model, &iter, NULL);
- shortcuts_append_path (impl, &iter, pixbuf, gtk_file_info_get_display_name (info), path_copy);
+ for (l = impl->shortcut_folders; l; l = l->next)
+ {
+ GtkFilePath *path;
- gtk_file_info_free (info);
+ path = l->data;
+ shortcuts_append_path (impl, NULL, path, FALSE, NULL);
+ }
+}
- if (pixbuf)
- gdk_pixbuf_unref (pixbuf);
+static void
+shortcuts_append_bookmarks (GtkFileChooserImplDefault *impl)
+{
+ GSList *bookmarks, *l;
+
+ if (impl->bookmarks_set)
+ {
+ gtk_tree_store_remove (impl->shortcuts_model, &impl->bookmarks_iter);
+ impl->bookmarks_set = FALSE;
}
- g_slist_free (roots);
+ if (!gtk_file_system_get_supports_bookmarks (impl->file_system))
+ return;
+
+ gtk_tree_store_append (impl->shortcuts_model, &impl->bookmarks_iter, NULL);
+ gtk_tree_store_set (impl->shortcuts_model, &impl->bookmarks_iter,
+ SHORTCUTS_COL_PIXBUF, NULL, /* FIXME: use a nice icon */
+ SHORTCUTS_COL_NAME, "Bookmarks",
+ SHORTCUTS_COL_PATH, NULL,
+ -1);
+ impl->bookmarks_set = TRUE;
+
+ bookmarks = gtk_file_system_list_bookmarks (impl->file_system);
+
+ for (l = bookmarks; l; l = l->next)
+ {
+ GtkFilePath *path;
+
+ path = l->data;
+ shortcuts_append_path (impl, &impl->bookmarks_iter, path, FALSE, NULL);
+ }
+
+ gtk_tree_view_expand_all (GTK_TREE_VIEW (impl->shortcuts_tree));
+
+ select_shortcuts_folder (impl);
}
/* Creates the GtkTreeStore used as the shortcuts model */
static void
create_shortcuts_model (GtkFileChooserImplDefault *impl)
{
- g_assert (impl->shortcuts_model == NULL);
+ if (impl->shortcuts_model)
+ g_object_unref (impl->shortcuts_model);
impl->shortcuts_model = gtk_tree_store_new (SHORTCUTS_COL_NUM_COLUMNS,
GDK_TYPE_PIXBUF, /* pixbuf */
G_TYPE_STRING, /* name */
G_TYPE_POINTER); /* path */
- if (!impl->file_system)
- return;
+ if (impl->file_system)
+ {
+ shortcuts_append_home (impl);
+ shortcuts_append_file_system_roots (impl);
+ shortcuts_append_shortcut_folders (impl);
+ shortcuts_append_bookmarks (impl);
+ }
- shortcuts_append_home (impl);
- shortcuts_append_file_system_roots (impl);
+ gtk_tree_view_set_model (GTK_TREE_VIEW (impl->shortcuts_tree), GTK_TREE_MODEL (impl->shortcuts_model));
+ select_shortcuts_folder (impl);
}
/* Creates the widgets for the filter option menu */
@@ -513,7 +616,9 @@ create_folder_tree (GtkFileChooserImplDefault *impl)
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (impl->tree_scrollwin),
GTK_SHADOW_IN);
+#if 0
gtk_widget_show (impl->tree_scrollwin);
+#endif
/* Tree */
@@ -548,14 +653,36 @@ create_folder_tree (GtkFileChooserImplDefault *impl)
return impl->tree_scrollwin;
}
+/* Callback used when the "Add bookmark" button is clicked */
+static void
+add_bookmark_button_clicked_cb (GtkButton *button,
+ GtkFileChooserImplDefault *impl)
+{
+ GSList *bookmarks;
+
+ if (!gtk_file_system_get_supports_bookmarks (impl->file_system))
+ return;
+
+ bookmarks = gtk_file_system_list_bookmarks (impl->file_system);
+ bookmarks = g_slist_append (bookmarks, gtk_file_path_copy (impl->current_folder));
+
+ gtk_file_system_set_bookmarks (impl->file_system, bookmarks, NULL); /* FIXME: use GError */
+
+ gtk_file_paths_free (bookmarks);
+}
+
/* Creates the widgets for the shortcuts and bookmarks tree */
static GtkWidget *
create_shortcuts_tree (GtkFileChooserImplDefault *impl)
{
+ GtkWidget *vbox;
GtkTreeSelection *selection;
GtkTreeViewColumn *column;
GtkCellRenderer *renderer;
+ vbox = gtk_vbox_new (FALSE, 12);
+ gtk_widget_show (vbox);
+
/* Scrolled window */
impl->shortcuts_scrollwin = gtk_scrolled_window_new (NULL, NULL);
@@ -563,6 +690,7 @@ create_shortcuts_tree (GtkFileChooserImplDefault *impl)
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (impl->shortcuts_scrollwin),
GTK_SHADOW_IN);
+ gtk_box_pack_start (GTK_BOX (vbox), impl->shortcuts_scrollwin, TRUE, TRUE, 0);
gtk_widget_show (impl->shortcuts_scrollwin);
/* Tree */
@@ -580,7 +708,6 @@ create_shortcuts_tree (GtkFileChooserImplDefault *impl)
/* Model */
create_shortcuts_model (impl);
- gtk_tree_view_set_model (GTK_TREE_VIEW (impl->shortcuts_tree), GTK_TREE_MODEL (impl->shortcuts_model));
/* Column */
@@ -588,7 +715,7 @@ create_shortcuts_tree (GtkFileChooserImplDefault *impl)
gtk_tree_view_column_set_title (column, "Folder");
renderer = gtk_cell_renderer_pixbuf_new ();
- gtk_tree_view_column_pack_start (column, renderer, TRUE);
+ gtk_tree_view_column_pack_start (column, renderer, FALSE);
gtk_tree_view_column_set_attributes (column, renderer,
"pixbuf", 0,
NULL);
@@ -601,7 +728,17 @@ create_shortcuts_tree (GtkFileChooserImplDefault *impl)
gtk_tree_view_append_column (GTK_TREE_VIEW (impl->shortcuts_tree), column);
- return impl->shortcuts_scrollwin;
+ /* Button */
+
+ impl->add_bookmark_button = gtk_button_new_with_label ("Add bookmark");
+ g_signal_connect (impl->add_bookmark_button, "clicked",
+ G_CALLBACK (add_bookmark_button_clicked_cb), impl);
+ gtk_box_pack_end (GTK_BOX (vbox), impl->add_bookmark_button, FALSE, FALSE, 0);
+
+ if (gtk_file_system_get_supports_bookmarks (impl->file_system))
+ gtk_widget_show (impl->add_bookmark_button);
+
+ return vbox;
}
/* Creates the widgets for the folder tree */
@@ -822,6 +959,14 @@ set_extra_widget (GtkFileChooserImplDefault *impl,
}
}
+/* Callback used when the set of bookmarks changes in the file system */
+static void
+bookmarks_changed_cb (GtkFileSystem *file_system,
+ GtkFileChooserImplDefault *impl)
+{
+ shortcuts_append_bookmarks (impl);
+}
+
static void
gtk_file_chooser_impl_default_set_property (GObject *object,
guint prop_id,
@@ -842,10 +987,19 @@ gtk_file_chooser_impl_default_set_property (GObject *object,
if (impl->file_system != file_system)
{
if (impl->file_system)
- g_object_unref (impl->file_system);
+ {
+ g_signal_handler_disconnect (impl->file_system, impl->bookmarks_changed_id);
+ impl->bookmarks_changed_id = 0;
+ g_object_unref (impl->file_system);
+ }
impl->file_system = file_system;
if (impl->file_system)
- g_object_ref (impl->file_system);
+ {
+ g_object_ref (impl->file_system);
+ impl->bookmarks_changed_id = g_signal_connect (impl->file_system, "bookmarks-changed",
+ G_CALLBACK (bookmarks_changed_cb),
+ impl);
+ }
}
}
break;
@@ -984,32 +1138,6 @@ expand_and_select_func (GtkFileSystemModel *model,
gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (impl->tree), path, NULL, TRUE, 0.3, 0.5);
}
-/* Used from gtk_tree_model_foreach(); selects the item that corresponds to the
- * current path. */
-static gboolean
-set_current_shortcut_foreach_cb (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
-{
- GtkFileChooserImplDefault *impl;
- GtkFilePath *model_path;
- GtkTreeSelection *selection;
-
- impl = GTK_FILE_CHOOSER_IMPL_DEFAULT (data);
-
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->shortcuts_tree));
-
- gtk_tree_model_get (model, iter, SHORTCUTS_COL_PATH, &model_path, -1);
-
- if (model_path && impl->current_folder && gtk_file_path_compare (model_path, impl->current_folder) == 0)
- {
- gtk_tree_selection_select_path (selection, path);
- return TRUE;
- }
- else
- gtk_tree_selection_unselect_path (selection, path);
-
- return FALSE;
-}
-
static void
gtk_file_chooser_impl_default_set_current_folder (GtkFileChooser *chooser,
const GtkFilePath *path)
@@ -1019,13 +1147,8 @@ gtk_file_chooser_impl_default_set_current_folder (GtkFileChooser *chooser,
_gtk_file_system_model_path_do (impl->tree_model, path,
expand_and_select_func, impl);
- /* Select the appropriate item in the shortcuts tree if there is an item that
- * matches the selected path.
- */
if (!impl->changing_folder)
- gtk_tree_model_foreach (GTK_TREE_MODEL (impl->shortcuts_model),
- set_current_shortcut_foreach_cb,
- impl);
+ select_shortcuts_folder (impl);
}
static GtkFilePath *
@@ -1307,6 +1430,26 @@ gtk_file_chooser_impl_default_list_filters (GtkFileChooser *chooser)
return g_slist_copy (impl->filters);
}
+static void
+gtk_file_chooser_impl_default_set_shortcut_folders (GtkFileChooser *chooser,
+ GSList *shortcut_folders)
+{
+ GtkFileChooserImplDefault *impl = GTK_FILE_CHOOSER_IMPL_DEFAULT (chooser);
+
+ gtk_file_paths_free (impl->shortcut_folders);
+ impl->shortcut_folders = gtk_file_paths_copy (shortcut_folders);
+
+ create_shortcuts_model (impl);
+}
+
+static GSList *
+gtk_file_chooser_impl_default_list_shortcut_folders (GtkFileChooser *chooser)
+{
+ GtkFileChooserImplDefault *impl = GTK_FILE_CHOOSER_IMPL_DEFAULT (chooser);
+
+ return gtk_file_paths_copy (impl->shortcut_folders);
+}
+
static gboolean
list_model_filter_func (GtkFileSystemModel *model,
GtkFilePath *path,
diff --git a/gtk/gtkfilechooserprivate.h b/gtk/gtkfilechooserprivate.h
index aeb79ee89d..9f0361896a 100644
--- a/gtk/gtkfilechooserprivate.h
+++ b/gtk/gtkfilechooserprivate.h
@@ -36,33 +36,35 @@ struct _GtkFileChooserIface
/* Methods
*/
- void (*set_current_folder) (GtkFileChooser *chooser,
- const GtkFilePath *path);
- GtkFilePath * (*get_current_folder) (GtkFileChooser *chooser);
- void (*set_current_name) (GtkFileChooser *chooser,
- const gchar *name);
- void (*select_path) (GtkFileChooser *chooser,
- const GtkFilePath *path);
- void (*unselect_path) (GtkFileChooser *chooser,
- const GtkFilePath *path);
- void (*select_all) (GtkFileChooser *chooser);
- void (*unselect_all) (GtkFileChooser *chooser);
- GSList * (*get_paths) (GtkFileChooser *chooser);
- GtkFilePath * (*get_preview_path) (GtkFileChooser *chooser);
- GtkFileSystem *(*get_file_system) (GtkFileChooser *chooser);
- void (*add_filter) (GtkFileChooser *chooser,
- GtkFileFilter *filter);
- void (*remove_filter) (GtkFileChooser *chooser,
- GtkFileFilter *filter);
- GSList * (*list_filters) (GtkFileChooser *chooser);
-
+ void (*set_current_folder) (GtkFileChooser *chooser,
+ const GtkFilePath *path);
+ GtkFilePath * (*get_current_folder) (GtkFileChooser *chooser);
+ void (*set_current_name) (GtkFileChooser *chooser,
+ const gchar *name);
+ void (*select_path) (GtkFileChooser *chooser,
+ const GtkFilePath *path);
+ void (*unselect_path) (GtkFileChooser *chooser,
+ const GtkFilePath *path);
+ void (*select_all) (GtkFileChooser *chooser);
+ void (*unselect_all) (GtkFileChooser *chooser);
+ GSList * (*get_paths) (GtkFileChooser *chooser);
+ GtkFilePath * (*get_preview_path) (GtkFileChooser *chooser);
+ GtkFileSystem *(*get_file_system) (GtkFileChooser *chooser);
+ void (*add_filter) (GtkFileChooser *chooser,
+ GtkFileFilter *filter);
+ void (*remove_filter) (GtkFileChooser *chooser,
+ GtkFileFilter *filter);
+ GSList * (*list_filters) (GtkFileChooser *chooser);
+ void (*set_shortcut_folders) (GtkFileChooser *chooser,
+ GSList *bookmarks);
+ GSList * (*list_shortcut_folders) (GtkFileChooser *chooser);
/* Signals
*/
void (*current_folder_changed) (GtkFileChooser *chooser);
void (*selection_changed) (GtkFileChooser *chooser);
void (*update_preview) (GtkFileChooser *chooser);
- void (*file_activated) (GtkFileChooser *chooser);
+ void (*file_activated) (GtkFileChooser *chooser);
};
GtkFileSystem *_gtk_file_chooser_get_file_system (GtkFileChooser *chooser);
diff --git a/gtk/gtkfilesystem.c b/gtk/gtkfilesystem.c
index a7a7be53f6..82f974dc24 100644
--- a/gtk/gtkfilesystem.c
+++ b/gtk/gtkfilesystem.c
@@ -448,6 +448,13 @@ gtk_file_system_base_init (gpointer g_class)
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
+ g_signal_new ("bookmarks-changed",
+ iface_type,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GtkFileSystemIface, bookmarks_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
initialized = TRUE;
}
@@ -644,6 +651,68 @@ gtk_file_system_filename_to_path (GtkFileSystem *file_system,
return GTK_FILE_SYSTEM_GET_IFACE (file_system)->filename_to_path (file_system, filename);
}
+/**
+ * gtk_file_system_get_supports_bookmarks:
+ * @chooser: a #GtkFileSystem
+ *
+ * Queries whether the file system supports the bookmarks feature. If this
+ * returns FALSE, then gtk_file_system_set_bookmarks() and
+ * gtk_file_system_list_bookmarks() will do nothing.
+ *
+ * Return value: TRUE if the file system supports bookmarks, FALSE otherwise.
+ **/
+gboolean
+gtk_file_system_get_supports_bookmarks (GtkFileSystem *file_system)
+{
+ g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), FALSE);
+
+ return GTK_FILE_SYSTEM_GET_IFACE (file_system)->get_supports_bookmarks (file_system);
+}
+
+/**
+ * gtk_file_system_set_bookmarks:
+ * @file_system: a #GtkFileSystem
+ * @bookmarks: a list of #GtkFilePath, or NULL if you want to clear the current
+ * list of bookmarks.
+ * @error: location to store error, or %NULL.
+ *
+ * Sets the list of bookmarks to be stored by a file system. This will also
+ * cause the bookmarks list to get saved. The ::bookmarks_changed signal will
+ * be emitted. Normally you do not need to call this function.
+ *
+ * See also: gtk_file_system_get_supports_bookmarks()
+ **/
+void
+gtk_file_system_set_bookmarks (GtkFileSystem *file_system,
+ GSList *bookmarks,
+ GError **error)
+{
+ g_return_if_fail (GTK_IS_FILE_SYSTEM (file_system));
+ g_return_if_fail (gtk_file_system_get_supports_bookmarks (file_system));
+
+ GTK_FILE_SYSTEM_GET_IFACE (file_system)->set_bookmarks (file_system, bookmarks, error);
+}
+
+/**
+ * gtk_file_system_list_bookmarks:
+ * @file_system: a #GtkFileSystem
+ *
+ * Queries the list of bookmarks in the file system.
+ *
+ * Return value: A list of #GtkFilePath, or NULL if there are no configured
+ * bookmarks. You should use gtk_file_paths_free() to free this list.
+ *
+ * See also: gtk_file_system_get_supports_bookmarks()
+ **/
+GSList *
+gtk_file_system_list_bookmarks (GtkFileSystem *file_system)
+{
+ g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), NULL);
+ g_return_val_if_fail (gtk_file_system_get_supports_bookmarks (file_system), NULL);
+
+ return GTK_FILE_SYSTEM_GET_IFACE (file_system)->list_bookmarks (file_system);
+}
+
/*****************************************
* GtkFileFolder *
*****************************************/
@@ -756,6 +825,42 @@ gtk_file_paths_sort (GSList *paths)
return g_slist_sort (paths, (GCompareFunc)strcmp);
}
+/**
+ * gtk_file_paths_copy:
+ * @paths: A #GSList of 3GtkFilePath structures.
+ *
+ * Copies a list of #GtkFilePath structures.
+ *
+ * Return value: A copy of @paths. Since the contents of the list are copied as
+ * well, you should use gtk_file_paths_free() to free the result.
+ **/
+GSList *
+gtk_file_paths_copy (GSList *paths)
+{
+ GSList *head, *tail, *l;
+
+ head = tail = NULL;
+
+ for (l = paths; l; l = l->next)
+ {
+ GtkFilePath *path;
+ GSList *node;
+
+ path = l->data;
+ node = g_slist_alloc ();
+
+ if (tail)
+ tail->next = node;
+ else
+ head = node;
+
+ node->data = gtk_file_path_copy (path);
+ tail = node;
+ }
+
+ return head;
+}
+
void
gtk_file_paths_free (GSList *paths)
{
diff --git a/gtk/gtkfilesystem.h b/gtk/gtkfilesystem.h
index f57616369c..8eefad487b 100644
--- a/gtk/gtkfilesystem.h
+++ b/gtk/gtkfilesystem.h
@@ -176,9 +176,18 @@ struct _GtkFileSystemIface
GtkFilePath *(*filename_to_path) (GtkFileSystem *file_system,
const gchar *path);
+ /* Bookmarks */
+
+ gboolean (*get_supports_bookmarks) (GtkFileSystem *file_system);
+ void (*set_bookmarks) (GtkFileSystem *file_system,
+ GSList *bookmarks,
+ GError **error);
+ GSList * (*list_bookmarks) (GtkFileSystem *file_system);
+
/* Signals
*/
- void (*roots_changed) (GtkFileSystem *file_system);
+ void (*roots_changed) (GtkFileSystem *file_system);
+ void (*bookmarks_changed) (GtkFileSystem *file_system);
};
GType gtk_file_system_get_type (void);
@@ -227,6 +236,14 @@ GtkFilePath *gtk_file_system_uri_to_path (GtkFileSystem *file_system,
GtkFilePath *gtk_file_system_filename_to_path (GtkFileSystem *file_system,
const gchar *filename);
+gboolean gtk_file_system_get_supports_bookmarks (GtkFileSystem *file_system);
+
+void gtk_file_system_set_bookmarks (GtkFileSystem *file_system,
+ GSList *bookmarks,
+ GError **error);
+GSList *gtk_file_system_list_bookmarks (GtkFileSystem *file_system);
+
+
/*
* Detailed information about a particular folder
*/
@@ -290,6 +307,7 @@ GtkFileInfo *gtk_file_folder_get_info (GtkFileFolder *folder,
gtk_file_path_get_string (path2))
GSList *gtk_file_paths_sort (GSList *paths);
+GSList *gtk_file_paths_copy (GSList *paths);
void gtk_file_paths_free (GSList *paths);
G_END_DECLS
diff --git a/gtk/gtkfilesystemunix.c b/gtk/gtkfilesystemunix.c
index a2a9c9b200..f62f44e1c5 100644
--- a/gtk/gtkfilesystemunix.c
+++ b/gtk/gtkfilesystemunix.c
@@ -112,6 +112,12 @@ static GtkFilePath *gtk_file_system_unix_uri_to_path (GtkFileSystem *fi
static GtkFilePath *gtk_file_system_unix_filename_to_path (GtkFileSystem *file_system,
const gchar *filename);
+static gboolean gtk_file_system_unix_get_supports_bookmarks (GtkFileSystem *file_system);
+static void gtk_file_system_unix_set_bookmarks (GtkFileSystem *file_system,
+ GSList *bookmarks,
+ GError **error);
+static GSList * gtk_file_system_unix_list_bookmarks (GtkFileSystem *file_system);
+
static GType gtk_file_folder_unix_get_type (void);
static void gtk_file_folder_unix_class_init (GtkFileFolderUnixClass *class);
static void gtk_file_folder_unix_iface_init (GtkFileFolderIface *iface);
@@ -213,6 +219,9 @@ gtk_file_system_unix_iface_init (GtkFileSystemIface *iface)
iface->path_to_filename = gtk_file_system_unix_path_to_filename;
iface->uri_to_path = gtk_file_system_unix_uri_to_path;
iface->filename_to_path = gtk_file_system_unix_filename_to_path;
+ iface->get_supports_bookmarks = gtk_file_system_unix_get_supports_bookmarks;
+ iface->set_bookmarks = gtk_file_system_unix_set_bookmarks;
+ iface->list_bookmarks = gtk_file_system_unix_list_bookmarks;
}
static void
@@ -532,6 +541,29 @@ gtk_file_system_unix_filename_to_path (GtkFileSystem *file_system,
return gtk_file_path_new_dup (filename);
}
+static gboolean
+gtk_file_system_unix_get_supports_bookmarks (GtkFileSystem *file_system)
+{
+ return FALSE;
+}
+
+static void
+gtk_file_system_unix_set_bookmarks (GtkFileSystem *file_system,
+ GSList *bookmarks,
+ GError **error)
+{
+ g_set_error (error,
+ GTK_FILE_SYSTEM_ERROR,
+ GTK_FILE_SYSTEM_ERROR_FAILED,
+ "This file system does not support bookmarks");
+}
+
+static GSList *
+gtk_file_system_unix_list_bookmarks (GtkFileSystem *file_system)
+{
+ return NULL;
+}
+
/*
* GtkFileFolderUnix
*/