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.
This commit is contained in:
Christian Hammond
2010-02-05 21:12:37 -08:00
committed by Federico Mena Quintero
parent 9289e75934
commit b11da2d25b

View File

@@ -137,6 +137,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;
@@ -433,6 +435,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 ();
@@ -525,6 +529,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,
@@ -541,24 +596,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;
g_object_ref (G_OBJECT (file));
priv->shortcuts = g_slist_append (priv->shortcuts, file);
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++;
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;
@@ -584,6 +631,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);
@@ -610,6 +658,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;
@@ -743,6 +803,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)
{
@@ -811,8 +872,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_SELECT_MULTIPLE:
@@ -857,6 +932,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;
@@ -875,6 +951,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);
}
@@ -1735,7 +1818,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)
@@ -1743,7 +1828,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)
@@ -1752,28 +1839,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)
{
if (!g_file_is_native (base_file))
{
g_object_unref (base_file);
continue;
}
else
g_object_unref (base_file);
}
}
}
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_unref (volume);
continue;
}
pixbuf = _gtk_file_system_volume_render_icon (volume,
GTK_WIDGET (button),
@@ -1810,13 +1900,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)
{
@@ -1824,6 +1916,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);
@@ -2041,14 +2136,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;
@@ -2065,10 +2172,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,
@@ -2084,7 +2193,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:
{
@@ -2880,3 +2990,8 @@ gtk_file_chooser_button_get_focus_on_click (GtkFileChooserButton *button)
return button->priv->focus_on_click;
}
#define __GTK_FILE_CHOOSER_BUTTON_C__
#include "gtkaliasdef.c"
// vim: et sw=2 cinoptions=(0,t0,f1s,n-1s,{1s,>2s,^-1s