G_PARAM_READWRITE));
}
+/**
+ * gtk_file_chooser_error_quark:
+ *
+ * Registers an error quark for #GtkFileChooser if necessary.
+ *
+ * Return value: The error quark used for #GtkFileChooser errors.
+ **/
+GQuark
+gtk_file_chooser_error_quark (void)
+{
+ static GQuark quark = 0;
+ if (quark == 0)
+ quark = g_quark_from_static_string ("gtk-file-chooser-error-quark");
+ return quark;
+}
+
/**
* gtk_file_chooser_set_action:
* @chooser: a #GtkFileChooser
}
}
+/* Converts a list of GtkFilePath* to a list of strings using the specified function */
+static GSList *
+file_paths_to_strings (GtkFileSystem *fs,
+ GSList *paths,
+ gchar * (*convert_func) (GtkFileSystem *fs, const GtkFilePath *path))
+{
+ GSList *strings;
+
+ strings = NULL;
+
+ for (; paths; paths = paths->next)
+ {
+ GtkFilePath *path;
+ gchar *string;
+
+ path = paths->data;
+ string = (* convert_func) (fs, path);
+
+ if (string)
+ strings = g_slist_prepend (strings, string);
+ }
+
+ return g_slist_reverse (strings);
+}
+
/**
* gtk_file_chooser_get_filenames:
* @chooser: a #GtkFileChooser
{
GtkFileSystem *file_system;
GSList *paths;
- GSList *tmp_list;
- GSList *result = NULL;
+ GSList *result;
g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), NULL);
file_system = _gtk_file_chooser_get_file_system (chooser);
paths = _gtk_file_chooser_get_paths (chooser);
- for (tmp_list = paths; tmp_list; tmp_list = tmp_list->next)
- {
- gchar *filename = gtk_file_system_path_to_filename (file_system, tmp_list->data);
- if (filename)
- result = g_slist_prepend (result, filename);
- }
-
+ result = file_paths_to_strings (file_system, paths, gtk_file_system_path_to_filename);
gtk_file_paths_free (paths);
-
- return g_slist_reverse (result);
+ return result;
}
/**
{
GtkFileSystem *file_system;
GSList *paths;
- GSList *tmp_list;
- GSList *result = NULL;
+ GSList *result;
g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), NULL);
file_system = _gtk_file_chooser_get_file_system (chooser);
paths = _gtk_file_chooser_get_paths (chooser);
- for (tmp_list = paths; tmp_list; tmp_list = tmp_list->next)
- {
- gchar *uri = gtk_file_system_path_to_uri (file_system, tmp_list->data);
- if (uri)
- result = g_slist_prepend (result, uri);
- }
-
+ result = file_paths_to_strings (file_system, paths, gtk_file_system_path_to_uri);
gtk_file_paths_free (paths);
-
- return g_slist_reverse (result);
+ return result;
}
/**
* @chooser: a #GtkFileChooser
*
* Gets the filename that should be previewed in a custom preview
- * Internal function, see gtk_file_chooser_get_preview_uri().n
+ * Internal function, see gtk_file_chooser_get_preview_uri().
*
* Return value: the #GtkFilePath for the file to preview, or %NULL if no file
* is selected. Free with gtk_file_path_free().
return GTK_FILE_CHOOSER_GET_IFACE (chooser)->get_preview_path (chooser);
}
+/**
+ * _gtk_file_chooser_add_shortcut_folder:
+ * @chooser: a #GtkFileChooser
+ * @path: path of the folder to add
+ * @error: location to store error, or %NULL
+ *
+ * Adds a folder to be displayed with the shortcut folders in a file chooser.
+ * Internal function, see gtk_file_chooser_add_shortcut_folder().
+ *
+ * Return value: TRUE if the folder could be added successfully, FALSE
+ * otherwise.
+ **/
+gboolean
+_gtk_file_chooser_add_shortcut_folder (GtkFileChooser *chooser,
+ const GtkFilePath *path,
+ GError **error)
+{
+ g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), FALSE);
+ g_return_val_if_fail (path != NULL, FALSE);
+
+ return GTK_FILE_CHOOSER_GET_IFACE (chooser)->add_shortcut_folder (chooser, path, error);
+}
+
+/**
+ * _gtk_file_chooser_remove_shortcut_folder:
+ * @chooser: a #GtkFileChooser
+ * @path: path of the folder to remove
+ * @error: location to store error, or %NULL
+ *
+ * Removes a folder from the shortcut folders in a file chooser. Internal
+ * function, see gtk_file_chooser_remove_shortcut_folder().
+ *
+ * Return value: TRUE if the folder could be removed successfully, FALSE
+ * otherwise.
+ **/
+gboolean
+_gtk_file_chooser_remove_shortcut_folder (GtkFileChooser *chooser,
+ const GtkFilePath *path,
+ GError **error)
+{
+ g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), FALSE);
+ g_return_val_if_fail (path != NULL, FALSE);
+
+ return GTK_FILE_CHOOSER_GET_IFACE (chooser)->remove_shortcut_folder (chooser, path, error);
+}
+
/**
* gtk_file_chooser_get_preview_filename:
* @chooser: a #GtkFileChooser
return filter;
}
-/* gtk_file_chooser_set_shortcut_folders:
+/**
+ * gtk_file_chooser_add_shortcut_folder:
* @chooser: a #GtkFileChooser
- * @shortcut_folders: a list of #GtkFilePath, or NULL if you want to clear the
- * current list of shortcut folders.
+ * @folder: filename of the folder to add
+ * @error: location to store error, or %NULL
*
- * 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.
+ * Adds a folder to be displayed with the shortcut folders in a file chooser.
+ * Note that shortcut folders do not get saved, as they are provided by the
+ * application. For example, you can use this to add a
+ * "/usr/share/mydrawprogram/Clipart" folder to the volume list.
+ *
+ * Return value: TRUE if the folder could be added successfully, FALSE
+ * otherwise. In the latter case, the @error will be set as appropriate.
**/
-void
-gtk_file_chooser_set_shortcut_folders (GtkFileChooser *chooser,
- GSList *shortcut_folders)
+gboolean
+gtk_file_chooser_add_shortcut_folder (GtkFileChooser *chooser,
+ const char *folder,
+ GError **error)
{
- g_return_if_fail (GTK_IS_FILE_CHOOSER (chooser));
+ GtkFilePath *path;
+ gboolean result;
+
+ g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), FALSE);
+ g_return_val_if_fail (folder != NULL, FALSE);
+
+ path = gtk_file_system_filename_to_path (_gtk_file_chooser_get_file_system (chooser), folder);
+ if (!path)
+ {
+ g_set_error (error,
+ GTK_FILE_CHOOSER_ERROR,
+ GTK_FILE_CHOOSER_ERROR_BAD_FILENAME,
+ "Invalid filename: %s",
+ folder);
+ return FALSE;
+ }
+
+ result = GTK_FILE_CHOOSER_GET_IFACE (chooser)->add_shortcut_folder (chooser, path, error);
+
+ gtk_file_path_free (path);
+
+ return result;
+}
+
+/**
+ * gtk_file_chooser_remove_shortcut_folder:
+ * @chooser: a #GtkFileChooser
+ * @folder: filename of the folder to remove
+ * @error: location to store error, or %NULL
+ *
+ * Removes a folder from a file chooser's list of shortcut folders.
+ *
+ * Return value: TRUE if the operation succeeds, FALSE otherwise. In the latter
+ * case, the @error will be set as appropriate.
+ *
+ * See also: gtk_file_chooser_add_shortcut_folder()
+ **/
+gboolean
+gtk_file_chooser_remove_shortcut_folder (GtkFileChooser *chooser,
+ const char *folder,
+ GError **error)
+{
+ GtkFilePath *path;
+ gboolean result;
+
+ g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), FALSE);
+ g_return_val_if_fail (folder != NULL, FALSE);
+
+ path = gtk_file_system_filename_to_path (_gtk_file_chooser_get_file_system (chooser), folder);
+ if (!path)
+ {
+ g_set_error (error,
+ GTK_FILE_CHOOSER_ERROR,
+ GTK_FILE_CHOOSER_ERROR_BAD_FILENAME,
+ "Invalid filename: %s",
+ folder);
+ return FALSE;
+ }
- GTK_FILE_CHOOSER_GET_IFACE (chooser)->set_shortcut_folders (chooser, shortcut_folders);
+ result = GTK_FILE_CHOOSER_GET_IFACE (chooser)->remove_shortcut_folder (chooser, path, error);
+
+ gtk_file_path_free (path);
+
+ return result;
}
/**
* 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.
+ * Return value: A list of folder filenames, or NULL if there are no shortcut
+ * folders. Free the returned list with g_slist_free(), and the filenames with
+ * g_free().
**/
GSList *
gtk_file_chooser_list_shortcut_folders (GtkFileChooser *chooser)
{
+ GSList *folders;
+ GSList *result;
+
+ g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), NULL);
+
+ folders = GTK_FILE_CHOOSER_GET_IFACE (chooser)->list_shortcut_folders (chooser);
+
+ result = file_paths_to_strings (_gtk_file_chooser_get_file_system (chooser),
+ folders,
+ gtk_file_system_path_to_filename);
+ gtk_file_paths_free (folders);
+ return result;
+}
+
+/**
+ * gtk_file_chooser_add_shortcut_folder_uri:
+ * @chooser: a #GtkFileChooser
+ * @folder: URI of the folder to add
+ * @error: location to store error, or %NULL
+ *
+ * Adds a folder URI to be displayed with the shortcut folders in a file
+ * chooser. Note that shortcut folders do not get saved, as they are provided
+ * by the application. For example, you can use this to add a
+ * "file:///usr/share/mydrawprogram/Clipart" folder to the volume list.
+ *
+ * Return value: TRUE if the folder could be added successfully, FALSE
+ * otherwise. In the latter case, the @error will be set as appropriate.
+ **/
+gboolean
+gtk_file_chooser_add_shortcut_folder_uri (GtkFileChooser *chooser,
+ const char *uri,
+ GError **error)
+{
+ GtkFilePath *path;
+ gboolean result;
+
+ g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), FALSE);
+ g_return_val_if_fail (uri != NULL, FALSE);
+
+ path = gtk_file_system_uri_to_path (_gtk_file_chooser_get_file_system (chooser), uri);
+ if (!path)
+ {
+ g_set_error (error,
+ GTK_FILE_CHOOSER_ERROR,
+ GTK_FILE_CHOOSER_ERROR_BAD_FILENAME,
+ "Invalid filename: %s",
+ uri);
+ return FALSE;
+ }
+
+ result = GTK_FILE_CHOOSER_GET_IFACE (chooser)->add_shortcut_folder (chooser, path, error);
+
+ gtk_file_path_free (path);
+
+ return result;
+}
+
+/**
+ * gtk_file_chooser_remove_shortcut_folder_uri:
+ * @chooser: a #GtkFileChooser
+ * @uri: URI of the folder to remove
+ * @error: location to store error, or %NULL
+ *
+ * Removes a folder URI from a file chooser's list of shortcut folders.
+ *
+ * Return value: TRUE if the operation succeeds, FALSE otherwise. In the latter
+ * case, the @error will be set as appropriate.
+ *
+ * See also: gtk_file_chooser_add_shortcut_folder_uri()
+ **/
+gboolean
+gtk_file_chooser_remove_shortcut_folder_uri (GtkFileChooser *chooser,
+ const char *uri,
+ GError **error)
+{
+ GtkFilePath *path;
+ gboolean result;
+
+ g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), FALSE);
+ g_return_val_if_fail (uri != NULL, FALSE);
+
+ path = gtk_file_system_filename_to_path (_gtk_file_chooser_get_file_system (chooser), uri);
+ if (!path)
+ {
+ g_set_error (error,
+ GTK_FILE_CHOOSER_ERROR,
+ GTK_FILE_CHOOSER_ERROR_BAD_FILENAME,
+ "Invalid filename: %s",
+ uri);
+ return FALSE;
+ }
+
+ result = GTK_FILE_CHOOSER_GET_IFACE (chooser)->remove_shortcut_folder (chooser, path, error);
+
+ gtk_file_path_free (path);
+
+ return result;
+}
+
+/**
+ * gtk_file_chooser_list_shortcut_folder_uris:
+ * @chooser: a #GtkFileChooser
+ *
+ * Queries the list of shortcut folders in the file chooser, as set by
+ * gtk_file_chooser_set_shortcut_folder_uris().
+ *
+ * Return value: A list of folder URIs, or NULL if there are no shortcut
+ * folders. Free the returned list with g_slist_free(), and the URIs with
+ * g_free().
+ **/
+GSList *
+gtk_file_chooser_list_shortcut_folder_uris (GtkFileChooser *chooser)
+{
+ GSList *folders;
+ GSList *result;
+
g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), NULL);
- return GTK_FILE_CHOOSER_GET_IFACE (chooser)->list_shortcut_folders (chooser);
+ folders = GTK_FILE_CHOOSER_GET_IFACE (chooser)->list_shortcut_folders (chooser);
+
+ result = file_paths_to_strings (_gtk_file_chooser_get_file_system (chooser),
+ folders,
+ gtk_file_system_path_to_uri);
+ gtk_file_paths_free (folders);
+ return result;
}
GType gtk_file_chooser_get_type (void);
+/* GError enumeration for GtkFileChooser */
+
+#define GTK_FILE_CHOOSER_ERROR (gtk_file_chooser_error_quark ())
+
+typedef enum {
+ GTK_FILE_CHOOSER_ERROR_NONEXISTENT,
+ GTK_FILE_CHOOSER_ERROR_BAD_FILENAME
+} GtkFileChooserError;
+
+GQuark gtk_file_chooser_error_quark (void);
+
/* Configuration
*/
void gtk_file_chooser_set_action (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);
+gboolean gtk_file_chooser_add_shortcut_folder (GtkFileChooser *chooser,
+ const char *folder,
+ GError **error);
+gboolean gtk_file_chooser_remove_shortcut_folder (GtkFileChooser *chooser,
+ const char *folder,
+ GError **error);
+GSList *gtk_file_chooser_list_shortcut_folders (GtkFileChooser *chooser);
+
+gboolean gtk_file_chooser_add_shortcut_folder_uri (GtkFileChooser *chooser,
+ const char *folder,
+ GError **error);
+gboolean gtk_file_chooser_remove_shortcut_folder_uri (GtkFileChooser *chooser,
+ const char *folder,
+ GError **error);
+GSList *gtk_file_chooser_list_shortcut_folder_uris (GtkFileChooser *chooser);
G_END_DECLS
GtkFileFilter *current_filter;
GSList *filters;
- GSList *shortcut_folders;
+ gboolean has_home;
+ gboolean has_desktop;
+ int num_roots;
+ int num_shortcuts;
+ int num_bookmarks;
guint bookmarks_changed_id;
GtkTreeIter bookmarks_iter;
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 gboolean gtk_file_chooser_impl_default_add_shortcut_folder (GtkFileChooser *chooser,
+ const GtkFilePath *path,
+ GError **error);
+static gboolean gtk_file_chooser_impl_default_remove_shortcut_folder (GtkFileChooser *chooser,
+ const GtkFilePath *path,
+ GError **error);
static GSList * gtk_file_chooser_impl_default_list_shortcut_folders (GtkFileChooser *chooser);
static void set_current_filter (GtkFileChooserImplDefault *impl,
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->add_shortcut_folder = gtk_file_chooser_impl_default_add_shortcut_folder;
+ iface->remove_shortcut_folder = gtk_file_chooser_impl_default_remove_shortcut_folder;
iface->list_shortcut_folders = gtk_file_chooser_impl_default_list_shortcut_folders;
}
/* Convenience function to get the display name and icon info for a path */
static GtkFileInfo *
-get_file_info (GtkFileSystem *file_system, GtkFilePath *path, GError **error)
+get_file_info (GtkFileSystem *file_system, const GtkFilePath *path, GError **error)
{
GtkFilePath *parent_path;
GtkFileFolder *parent_folder;
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.
+/* Inserts a path in the shortcuts tree, making a copy of it. A position of -1
+ * indicates 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,
+static gboolean
+shortcuts_insert_path (GtkFileChooserImplDefault *impl,
+ int pos,
+ const GtkFilePath *path,
gboolean is_root,
- const char *label)
+ const char *label,
+ GError **error)
{
GtkFileInfo *info;
GtkFilePath *path_copy;
info = gtk_file_system_get_root_info (impl->file_system,
path,
GTK_FILE_INFO_DISPLAY_NAME | GTK_FILE_INFO_ICON,
- NULL); /* FIXME: Use GError? */
+ error);
else
- info = get_file_info (impl->file_system, path, NULL); /* FIXME: use GError? */
+ info = get_file_info (impl->file_system, path, error);
if (!info)
- return;
+ return FALSE;
pixbuf = gtk_file_info_render_icon (info, impl->shortcuts_tree, ICON_SIZE);
- gtk_tree_store_append (impl->shortcuts_model, &iter, parent);
+ gtk_tree_store_insert (impl->shortcuts_model, &iter, NULL, pos);
path_copy = gtk_file_path_copy (path);
if (!label)
if (pixbuf)
g_object_unref (pixbuf);
+
+ return TRUE;
}
/* Appends an item for the user's home directory to the shortcuts model */
home = g_get_home_dir ();
home_path = gtk_file_system_filename_to_path (impl->file_system, home);
- shortcuts_append_path (impl, NULL, home_path, FALSE, label);
+ impl->has_home = shortcuts_insert_path (impl, -1, home_path, FALSE, label, NULL); /* FIXME: use GError? */
g_free (label);
gtk_file_path_free (home_path);
}
+/* Appends the ~/Desktop directory to the shortcuts model */
+static void
+shortcuts_append_desktop (GtkFileChooserImplDefault *impl)
+{
+ char *name;
+ GtkFilePath *path;
+
+ /* FIXME: What is the Right Way of finding the desktop directory? */
+
+ name = g_build_filename (g_get_home_dir (), "Desktop", NULL);
+ path = gtk_file_system_filename_to_path (impl->file_system, name);
+ g_free (name);
+
+ impl->has_desktop = shortcuts_insert_path (impl, -1, path, FALSE, NULL, NULL); /* FIXME: use GError? */
+ gtk_file_path_free (path);
+}
+
/* Appends all the file system roots to the shortcuts model */
static void
shortcuts_append_file_system_roots (GtkFileChooserImplDefault *impl)
GSList *roots, *l;
roots = gtk_file_system_list_roots (impl->file_system);
+ /* FIXME: handle the roots-changed signal on the file system */
+
+ impl->num_roots = 0;
for (l = roots; l; l = l->next)
{
GtkFilePath *path;
path = l->data;
- shortcuts_append_path (impl, NULL, path, TRUE, NULL);
+ if (shortcuts_insert_path (impl, -1, path, TRUE, NULL, NULL)) /* FIXME: use GError? */
+ impl->num_roots++;
}
gtk_file_paths_free (roots);
}
-/* Appends the application-specific shortcut folders to the shortcuts model */
-static void
-shortcuts_append_shortcut_folders (GtkFileChooserImplDefault *impl)
-{
- GSList *l;
-
- for (l = impl->shortcut_folders; l; l = l->next)
- {
- GtkFilePath *path;
-
- path = l->data;
- shortcuts_append_path (impl, NULL, path, FALSE, NULL);
- }
-}
-
/* Removes the bookmarks separator node and all the bookmarks from the tree
* model.
*/
SHORTCUTS_COL_PATH, NULL,
-1);
impl->bookmarks_set = TRUE;
+ impl->num_bookmarks = 0;
bookmarks = gtk_file_system_list_bookmarks (impl->file_system);
GtkFilePath *path;
path = l->data;
- shortcuts_append_path (impl, NULL, path, FALSE, NULL);
+ if (shortcuts_insert_path (impl, -1, path, FALSE, NULL, NULL)) /* FIXME: use GError? */
+ impl->num_bookmarks++;
}
-
- gtk_tree_view_expand_all (GTK_TREE_VIEW (impl->shortcuts_tree));
}
/* Creates the GtkTreeStore used as the shortcuts model */
if (impl->file_system)
{
shortcuts_append_home (impl);
+ shortcuts_append_desktop (impl);
shortcuts_append_file_system_roots (impl);
- shortcuts_append_shortcut_folders (impl);
shortcuts_append_bookmarks (impl);
}
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);
+ gtk_file_system_add_bookmark (impl->file_system, impl->current_folder, NULL); /* FIXME: use GError */
}
/* Callback used when the "Remove bookmark" button is clicked */
GtkTreeSelection *selection;
GtkTreeIter iter;
GtkFilePath *path;
- GSList *bookmarks, *l;;
- gboolean changed;
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->shortcuts_tree));
gtk_tree_model_get (GTK_TREE_MODEL (impl->shortcuts_model), &iter, SHORTCUTS_COL_PATH, &path, -1);
- bookmarks = gtk_file_system_list_bookmarks (impl->file_system);
- changed = FALSE;
-
- for (l = bookmarks; l; l = l->next)
- {
- GtkFilePath *p;
-
- p = l->data;
- if (gtk_file_path_compare (path, p) == 0)
- {
- gtk_file_path_free (p);
- bookmarks = g_slist_delete_link (bookmarks, l);
- changed = TRUE;
- break;
- }
- }
-
- if (changed)
- gtk_file_system_set_bookmarks (impl->file_system, bookmarks, NULL); /* FIXME: use GError */
-
- gtk_file_paths_free (bookmarks);
+ gtk_file_system_remove_bookmark (impl->file_system, path, NULL); /* FIXME: use GError */
}
/* Sensitize the "add bookmark" button if the current folder is not in the
GtkTreeIter iter;
gboolean exists;
- if (!gtk_file_system_get_supports_bookmarks (impl->file_system))
- return;
-
exists = FALSE;
if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (impl->shortcuts_model), &iter))
G_CALLBACK (add_bookmark_button_clicked_cb), impl);
gtk_box_pack_start (GTK_BOX (hbox), impl->add_bookmark_button, TRUE, TRUE, 0);
gtk_widget_set_sensitive (impl->add_bookmark_button, FALSE);
+ gtk_widget_show (impl->add_bookmark_button);
impl->remove_bookmark_button = gtk_button_new ();
g_signal_connect (impl->remove_bookmark_button, "clicked",
gtk_widget_show (image);
gtk_widget_set_sensitive (impl->remove_bookmark_button, FALSE);
gtk_box_pack_start (GTK_BOX (hbox), impl->remove_bookmark_button, FALSE, FALSE, 0);
-
- if (gtk_file_system_get_supports_bookmarks (impl->file_system))
- {
- gtk_widget_show (impl->add_bookmark_button);
- gtk_widget_show (impl->remove_bookmark_button);
- }
+ gtk_widget_show (impl->remove_bookmark_button);
shortcuts_select_folder (impl);
return g_slist_copy (impl->filters);
}
-static void
-gtk_file_chooser_impl_default_set_shortcut_folders (GtkFileChooser *chooser,
- GSList *shortcut_folders)
+/* Returns the position in the shortcuts tree where the nth specified shortcut would appear */
+static int
+shortcuts_get_pos_for_shortcut_folder (GtkFileChooserImplDefault *impl,
+ int pos)
+{
+ return pos + ((impl->has_home ? 1 : 0)
+ + (impl->has_desktop ? 1 : 0)
+ + impl->num_roots);
+}
+
+static gboolean
+gtk_file_chooser_impl_default_add_shortcut_folder (GtkFileChooser *chooser,
+ const GtkFilePath *path,
+ GError **error)
{
GtkFileChooserImplDefault *impl = GTK_FILE_CHOOSER_IMPL_DEFAULT (chooser);
+ gboolean result;
+ int pos;
- gtk_file_paths_free (impl->shortcut_folders);
- impl->shortcut_folders = gtk_file_paths_copy (shortcut_folders);
+ pos = shortcuts_get_pos_for_shortcut_folder (impl, impl->num_shortcuts);
- create_shortcuts_model (impl);
+ /* FIXME: how do we know if the path is a file system root? */
+ result = shortcuts_insert_path (impl, pos, path, FALSE, NULL, error);
+
+ if (result)
+ impl->num_shortcuts++;
+
+ return result;
+}
+
+static gboolean
+gtk_file_chooser_impl_default_remove_shortcut_folder (GtkFileChooser *chooser,
+ const GtkFilePath *path,
+ GError **error)
+{
+ GtkFileChooserImplDefault *impl = GTK_FILE_CHOOSER_IMPL_DEFAULT (chooser);
+ int pos;
+ GtkTreeIter iter;
+ int i;
+
+ if (impl->num_shortcuts == 0)
+ goto out;
+
+ pos = shortcuts_get_pos_for_shortcut_folder (impl, 0);
+ if (!gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (impl->shortcuts_model), &iter, NULL, pos))
+ g_assert_not_reached ();
+
+ for (i = 0; i < impl->num_shortcuts; i++)
+ {
+ GtkFilePath *shortcut;
+
+ gtk_tree_model_get (GTK_TREE_MODEL (impl->shortcuts_model), &iter, SHORTCUTS_COL_PATH, &shortcut, -1);
+ g_assert (shortcut != NULL);
+
+ if (gtk_file_path_compare (shortcut, path) == 0)
+ {
+ /* The other columns are freed by the GtkTreeStore */
+ gtk_file_path_free (shortcut);
+ gtk_tree_store_remove (impl->shortcuts_model, &iter);
+ impl->num_shortcuts--;
+ return TRUE;
+ }
+
+ if (!gtk_tree_model_iter_next (GTK_TREE_MODEL (impl->shortcuts_model), &iter))
+ g_assert_not_reached ();
+ }
+
+ out:
+
+ g_set_error (error,
+ GTK_FILE_CHOOSER_ERROR,
+ GTK_FILE_CHOOSER_ERROR_NONEXISTENT,
+ "shortcut %s does not exist",
+ gtk_file_path_get_string (path));
+
+ return FALSE;
}
static GSList *
gtk_file_chooser_impl_default_list_shortcut_folders (GtkFileChooser *chooser)
{
GtkFileChooserImplDefault *impl = GTK_FILE_CHOOSER_IMPL_DEFAULT (chooser);
+ int pos;
+ GtkTreeIter iter;
+ int i;
+ GSList *list;
+
+ pos = shortcuts_get_pos_for_shortcut_folder (impl, 0);
+ if (!gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (impl->shortcuts_model), &iter, NULL, pos))
+ g_assert_not_reached ();
+
+ list = NULL;
+
+ for (i = 0; i < impl->num_shortcuts; i++)
+ {
+ GtkFilePath *shortcut;
+
+ gtk_tree_model_get (GTK_TREE_MODEL (impl->shortcuts_model), &iter, SHORTCUTS_COL_PATH, &shortcut, -1);
+ g_assert (shortcut != NULL);
+
+ list = g_slist_prepend (list, gtk_file_path_copy (shortcut));
+
+ if (!gtk_tree_model_iter_next (GTK_TREE_MODEL (impl->shortcuts_model), &iter))
+ g_assert_not_reached ();
+ }
- return gtk_file_paths_copy (impl->shortcut_folders);
+ return g_slist_reverse (list);
}
static void
void (*remove_filter) (GtkFileChooser *chooser,
GtkFileFilter *filter);
GSList * (*list_filters) (GtkFileChooser *chooser);
- void (*set_shortcut_folders) (GtkFileChooser *chooser,
- GSList *bookmarks);
+ gboolean (*add_shortcut_folder) (GtkFileChooser *chooser,
+ const GtkFilePath *path,
+ GError **error);
+ gboolean (*remove_shortcut_folder) (GtkFileChooser *chooser,
+ const GtkFilePath *path,
+ GError **error);
GSList * (*list_shortcut_folders) (GtkFileChooser *chooser);
/* Signals
const GtkFilePath *path);
GSList * _gtk_file_chooser_get_paths (GtkFileChooser *chooser);
GtkFilePath * _gtk_file_chooser_get_preview_path (GtkFileChooser *chooser);
+gboolean _gtk_file_chooser_add_shortcut_folder (GtkFileChooser *chooser,
+ const GtkFilePath *path,
+ GError **error);
+gboolean _gtk_file_chooser_remove_shortcut_folder (GtkFileChooser *chooser,
+ const GtkFilePath *path,
+ GError **error);
G_END_DECLS
static void delegate_remove_filter (GtkFileChooser *chooser,
GtkFileFilter *filter);
static GSList * delegate_list_filters (GtkFileChooser *chooser);
+static gboolean delegate_add_shortcut_folder (GtkFileChooser *chooser,
+ const GtkFilePath *path,
+ GError **error);
+static gboolean delegate_remove_shortcut_folder (GtkFileChooser *chooser,
+ const GtkFilePath *path,
+ GError **error);
+static GSList * delegate_list_shortcut_folders (GtkFileChooser *chooser);
static void delegate_notify (GObject *object,
GParamSpec *pspec,
gpointer data);
iface->add_filter = delegate_add_filter;
iface->remove_filter = delegate_remove_filter;
iface->list_filters = delegate_list_filters;
+ iface->add_shortcut_folder = delegate_add_shortcut_folder;
+ iface->remove_shortcut_folder = delegate_remove_shortcut_folder;
+ iface->list_shortcut_folders = delegate_list_shortcut_folders;
}
/**
return gtk_file_chooser_list_filters (get_delegate (chooser));
}
+static gboolean
+delegate_add_shortcut_folder (GtkFileChooser *chooser,
+ const GtkFilePath *path,
+ GError **error)
+{
+ return _gtk_file_chooser_add_shortcut_folder (get_delegate (chooser), path, error);
+}
+
+static gboolean
+delegate_remove_shortcut_folder (GtkFileChooser *chooser,
+ const GtkFilePath *path,
+ GError **error)
+{
+ return _gtk_file_chooser_remove_shortcut_folder (get_delegate (chooser), path, error);
+}
+
+static GSList *
+delegate_list_shortcut_folders (GtkFileChooser *chooser)
+{
+ return gtk_file_chooser_list_shortcut_folders (get_delegate (chooser));
+}
+
static void
delegate_set_current_folder (GtkFileChooser *chooser,
const GtkFilePath *path)
}
/**
- * gtk_file_system_get_supports_bookmarks:
- * @chooser: a #GtkFileSystem
+ * gtk_file_system_add_bookmark:
+ * @file_system: a #GtkFileSystem
+ * @bookmark: path of the bookmark to add
+ * @error: location to store error, or %NULL
*
- * 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.
+ * Adds a bookmark folder to the user's bookmarks list. If the operation succeeds,
+ * the "bookmarks_changed" signal will be emitted.
*
- * Return value: TRUE if the file system supports bookmarks, FALSE otherwise.
+ * Return value: TRUE if the operation succeeds, FALSE otherwise. In the latter case,
+ * the @error value will be set.
**/
gboolean
-gtk_file_system_get_supports_bookmarks (GtkFileSystem *file_system)
+gtk_file_system_add_bookmark (GtkFileSystem *file_system,
+ const GtkFilePath *path,
+ GError **error)
{
g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), FALSE);
+ g_return_val_if_fail (path != NULL, FALSE);
- return GTK_FILE_SYSTEM_GET_IFACE (file_system)->get_supports_bookmarks (file_system);
+ return GTK_FILE_SYSTEM_GET_IFACE (file_system)->add_bookmark (file_system, path, error);
}
/**
- * gtk_file_system_set_bookmarks:
+ * gtk_file_system_remove_bookmark:
* @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.
+ * @bookmark: path of the bookmark to remove
+ * @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()
+ * Removes a bookmark folder from the user's bookmarks list. If the operation
+ * succeeds, the "bookmarks_changed" signal will be emitted.
+ *
+ * Return value: TRUE if the operation succeeds, FALSE otherwise. In the latter
+ * case, the @error value will be set.
**/
-void
-gtk_file_system_set_bookmarks (GtkFileSystem *file_system,
- GSList *bookmarks,
- GError **error)
+gboolean
+gtk_file_system_remove_bookmark (GtkFileSystem *file_system,
+ const GtkFilePath *path,
+ GError **error)
{
- g_return_if_fail (GTK_IS_FILE_SYSTEM (file_system));
- g_return_if_fail (gtk_file_system_get_supports_bookmarks (file_system));
+ g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), FALSE);
+ g_return_val_if_fail (path != NULL, FALSE);
- GTK_FILE_SYSTEM_GET_IFACE (file_system)->set_bookmarks (file_system, bookmarks, error);
+ return GTK_FILE_SYSTEM_GET_IFACE (file_system)->remove_bookmark (file_system, path, error);
}
/**
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);
}
const GtkFilePath *path,
GError **error);
- gboolean (*supports_shortcuts) (GtkFileSystem *file_system);
- GSList * (*list_shortcuts) (GtkFileSystem *file_system,
- GError **error);
- gboolean (*set_shortcuts) (GtkFileSystem *file_system,
- GSList *shortcuts,
- GError **error);
-
/* Path Manipulation
*/
gboolean (*get_parent) (GtkFileSystem *file_system,
/* Bookmarks */
- gboolean (*get_supports_bookmarks) (GtkFileSystem *file_system);
- void (*set_bookmarks) (GtkFileSystem *file_system,
- GSList *bookmarks,
- GError **error);
+ gboolean (*add_bookmark) (GtkFileSystem *file_system,
+ const GtkFilePath *path,
+ GError **error);
+ gboolean (*remove_bookmark) (GtkFileSystem *file_system,
+ const GtkFilePath *path,
+ GError **error);
GSList * (*list_bookmarks) (GtkFileSystem *file_system);
/* Signals
GtkFileInfoType types,
GError **error);
-gboolean gtk_file_system_supports_shortcuts (GtkFileSystem *file_system);
-GSList * gtk_file_system_list_shortcuts (GtkFileSystem *file_system,
- GError **error);
-gboolean gtk_file_system_set_shortcuts (GtkFileSystem *file_system,
- GSList *shortcuts,
- GError **error);
-
gboolean gtk_file_system_get_parent (GtkFileSystem *file_system,
const GtkFilePath *path,
GtkFilePath **parent,
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);
+gboolean gtk_file_system_add_bookmark (GtkFileSystem *file_system,
+ const GtkFilePath *path,
+ GError **error);
+gboolean gtk_file_system_remove_bookmark (GtkFileSystem *file_system,
+ const GtkFilePath *path,
+ GError **error);
+GSList *gtk_file_system_list_bookmarks (GtkFileSystem *file_system);
/*
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 gboolean gtk_file_system_unix_add_bookmark (GtkFileSystem *file_system,
+ const GtkFilePath *path,
+ GError **error);
+static gboolean gtk_file_system_unix_remove_bookmark (GtkFileSystem *file_system,
+ const GtkFilePath *path,
+ 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);
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->add_bookmark = gtk_file_system_unix_add_bookmark;
+ iface->remove_bookmark = gtk_file_system_unix_remove_bookmark;
iface->list_bookmarks = gtk_file_system_unix_list_bookmarks;
}
}
static gboolean
-gtk_file_system_unix_get_supports_bookmarks (GtkFileSystem *file_system)
+gtk_file_system_unix_add_bookmark (GtkFileSystem *file_system,
+ const GtkFilePath *path,
+ GError **error)
{
+ g_set_error (error,
+ GTK_FILE_SYSTEM_ERROR,
+ GTK_FILE_SYSTEM_ERROR_FAILED,
+ "This file system does not support bookmarks");
return FALSE;
}
-static void
-gtk_file_system_unix_set_bookmarks (GtkFileSystem *file_system,
- GSList *bookmarks,
- GError **error)
+static gboolean
+gtk_file_system_unix_remove_bookmark (GtkFileSystem *file_system,
+ const GtkFilePath *path,
+ GError **error)
{
g_set_error (error,
GTK_FILE_SYSTEM_ERROR,
GTK_FILE_SYSTEM_ERROR_FAILED,
- "This file system does not support bookmarks");
+ "This file system does not support bookmarks");
+ return FALSE;
}
static GSList *
/* Extra widget */
extra = gtk_check_button_new_with_mnemonic ("_Frobnicate the file");
gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER (dialog), extra);
-
+
+ /* Shortcuts */
+
+ gtk_file_chooser_add_shortcut_folder_uri (GTK_FILE_CHOOSER (dialog),
+ "file:///usr/share/pixmaps",
+ NULL);
+
+ /* Done with the dialog */
gtk_window_set_default_size (GTK_WINDOW (dialog), 600, 400);
/* show_all() to reveal bugs in composite widget handling */
gtk_widget_show_all (dialog);