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:
committed by
Federico Mena Quintero
parent
9289e75934
commit
b11da2d25b
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user