forked from AuroraMiddleware/gtk
Merge of the GTK+ asynchronous file chooser branch. Please see the
2006-05-01 Kristian Rietveld <kris@imendio.com> Merge of the GTK+ asynchronous file chooser branch. Please see the kris-asynch-branch for more detailed ChangeLog entries. * configure.in: increase binary version to 2.9.0. * gtk.symbols: * gtkfilechooser.c: * gtkfilechooserbutton.c: * gtkfilechooserdefault.c: * gtkfilechooserdialog.c: * gtkfilechooserembed.c: * gtkfilechooserembed.h: * gtkfilechooserentry.c: * gtkfilechooserentry.h: * gtkfilechooserprivate.h: * gtkfilesystem.c: * gtkfilesystem.h: * gtkfilesystemmodel.c: * gtkfilesystemmodel.h: * gtkfilesystemunix.c: * gtkpathbar.c: * gtkpathbar.h: Merge from kris-async-branch.
This commit is contained in:
parent
46789c877d
commit
2c97a8f6e8
26
ChangeLog
26
ChangeLog
@ -1,3 +1,29 @@
|
||||
2006-05-01 Kristian Rietveld <kris@imendio.com>
|
||||
|
||||
Merge of the GTK+ asynchronous file chooser branch. Please see
|
||||
the kris-asynch-branch for more detailed ChangeLog entries.
|
||||
|
||||
* configure.in: increase binary version to 2.9.0.
|
||||
|
||||
* gtk.symbols:
|
||||
* gtkfilechooser.c:
|
||||
* gtkfilechooserbutton.c:
|
||||
* gtkfilechooserdefault.c:
|
||||
* gtkfilechooserdialog.c:
|
||||
* gtkfilechooserembed.c:
|
||||
* gtkfilechooserembed.h:
|
||||
* gtkfilechooserentry.c:
|
||||
* gtkfilechooserentry.h:
|
||||
* gtkfilechooserprivate.h:
|
||||
* gtkfilesystem.c:
|
||||
* gtkfilesystem.h:
|
||||
* gtkfilesystemmodel.c:
|
||||
* gtkfilesystemmodel.h:
|
||||
* gtkfilesystemunix.c:
|
||||
* gtkpathbar.c:
|
||||
* gtkpathbar.h:
|
||||
Merge from kris-async-branch.
|
||||
|
||||
2006-05-01 Matthias Clasen <mclasen@dhcp83-48.boston.redhat.com>
|
||||
|
||||
* NEWS: Updates
|
||||
|
@ -1,3 +1,29 @@
|
||||
2006-05-01 Kristian Rietveld <kris@imendio.com>
|
||||
|
||||
Merge of the GTK+ asynchronous file chooser branch. Please see
|
||||
the kris-asynch-branch for more detailed ChangeLog entries.
|
||||
|
||||
* configure.in: increase binary version to 2.9.0.
|
||||
|
||||
* gtk.symbols:
|
||||
* gtkfilechooser.c:
|
||||
* gtkfilechooserbutton.c:
|
||||
* gtkfilechooserdefault.c:
|
||||
* gtkfilechooserdialog.c:
|
||||
* gtkfilechooserembed.c:
|
||||
* gtkfilechooserembed.h:
|
||||
* gtkfilechooserentry.c:
|
||||
* gtkfilechooserentry.h:
|
||||
* gtkfilechooserprivate.h:
|
||||
* gtkfilesystem.c:
|
||||
* gtkfilesystem.h:
|
||||
* gtkfilesystemmodel.c:
|
||||
* gtkfilesystemmodel.h:
|
||||
* gtkfilesystemunix.c:
|
||||
* gtkpathbar.c:
|
||||
* gtkpathbar.h:
|
||||
Merge from kris-async-branch.
|
||||
|
||||
2006-05-01 Matthias Clasen <mclasen@dhcp83-48.boston.redhat.com>
|
||||
|
||||
* NEWS: Updates
|
||||
|
@ -28,7 +28,7 @@ m4_define([gtk_api_version], [2.0])
|
||||
# for GTK+.
|
||||
#
|
||||
#GTK_BINARY_VERSION=$GTK_MAJOR_VERSION.$GTK_MINOR_VERSION.$LT_CURRENT
|
||||
m4_define([gtk_binary_version], [2.4.0])
|
||||
m4_define([gtk_binary_version], [2.9.0])
|
||||
|
||||
# required versions of other packages
|
||||
m4_define([glib_required_version], [2.10.1])
|
||||
|
@ -1392,6 +1392,7 @@ gtk_file_info_copy
|
||||
gtk_file_info_free
|
||||
gtk_file_info_get_display_key
|
||||
gtk_file_info_get_display_name
|
||||
gtk_file_info_get_icon_name
|
||||
gtk_file_info_get_is_folder
|
||||
gtk_file_info_get_is_hidden
|
||||
gtk_file_info_get_mime_type
|
||||
@ -1399,7 +1400,9 @@ gtk_file_info_get_modification_time
|
||||
gtk_file_info_get_size
|
||||
gtk_file_info_get_type G_GNUC_CONST
|
||||
gtk_file_info_new
|
||||
gtk_file_info_render_icon
|
||||
gtk_file_info_set_display_name
|
||||
gtk_file_info_set_icon_name
|
||||
gtk_file_info_set_is_folder
|
||||
gtk_file_info_set_is_hidden
|
||||
gtk_file_info_set_mime_type
|
||||
@ -1409,9 +1412,11 @@ gtk_file_path_get_type G_GNUC_CONST
|
||||
gtk_file_paths_copy
|
||||
gtk_file_paths_free
|
||||
gtk_file_paths_sort
|
||||
gtk_file_system_cancel_operation
|
||||
gtk_file_system_create_folder
|
||||
gtk_file_system_error_quark
|
||||
gtk_file_system_filename_to_path
|
||||
gtk_file_system_get_info
|
||||
gtk_file_system_get_folder
|
||||
gtk_file_system_get_parent
|
||||
gtk_file_system_get_type G_GNUC_CONST
|
||||
@ -1425,11 +1430,11 @@ gtk_file_system_path_is_local
|
||||
gtk_file_system_path_to_filename
|
||||
gtk_file_system_path_to_uri
|
||||
gtk_file_system_remove_bookmark
|
||||
gtk_file_system_render_icon
|
||||
gtk_file_system_uri_to_path
|
||||
gtk_file_system_volume_free
|
||||
gtk_file_system_volume_get_base_path
|
||||
gtk_file_system_volume_get_display_name
|
||||
gtk_file_system_volume_get_icon_name
|
||||
gtk_file_system_volume_get_is_mounted
|
||||
gtk_file_system_volume_mount
|
||||
gtk_file_system_volume_render_icon
|
||||
|
@ -717,6 +717,9 @@ gtk_file_chooser_get_current_folder (GtkFileChooser *chooser)
|
||||
file_system = _gtk_file_chooser_get_file_system (chooser);
|
||||
|
||||
path = _gtk_file_chooser_get_current_folder_path (chooser);
|
||||
if (!path)
|
||||
return NULL;
|
||||
|
||||
filename = gtk_file_system_path_to_filename (file_system, path);
|
||||
gtk_file_path_free (path);
|
||||
|
||||
|
@ -93,6 +93,8 @@ enum
|
||||
DISPLAY_NAME_COLUMN,
|
||||
TYPE_COLUMN,
|
||||
DATA_COLUMN,
|
||||
IS_FOLDER_COLUMN,
|
||||
HANDLE_COLUMN,
|
||||
NUM_COLUMNS
|
||||
};
|
||||
|
||||
@ -142,6 +144,10 @@ struct _GtkFileChooserButtonPrivate
|
||||
gulong fs_volumes_changed_id;
|
||||
gulong fs_bookmarks_changed_id;
|
||||
|
||||
GtkFileSystemHandle *dnd_select_folder_handle;
|
||||
GtkFileSystemHandle *update_button_handle;
|
||||
GSList *change_icon_theme_handles;
|
||||
|
||||
gint icon_size;
|
||||
|
||||
guint8 n_special;
|
||||
@ -229,8 +235,9 @@ static void gtk_file_chooser_button_screen_changed (GtkWidget *wi
|
||||
|
||||
/* Utility Functions */
|
||||
static GtkIconTheme *get_icon_theme (GtkWidget *widget);
|
||||
static gchar *get_display_name_for_path (GtkFileSystem *fs,
|
||||
const GtkFilePath *path);
|
||||
static void set_info_for_path_at_iter (GtkFileChooserButton *fs,
|
||||
const GtkFilePath *path,
|
||||
GtkTreeIter *iter);
|
||||
|
||||
static gint model_get_type_position (GtkFileChooserButton *button,
|
||||
RowType row_type);
|
||||
@ -451,7 +458,9 @@ gtk_file_chooser_button_init (GtkFileChooserButton *button)
|
||||
GDK_TYPE_PIXBUF, /* Icon */
|
||||
G_TYPE_STRING, /* Display Name */
|
||||
G_TYPE_CHAR, /* Row Type */
|
||||
G_TYPE_POINTER /* Volume || Path */));
|
||||
G_TYPE_POINTER /* Volume || Path */,
|
||||
G_TYPE_BOOLEAN /* Is Folder? */,
|
||||
G_TYPE_OBJECT /* handle */));
|
||||
|
||||
priv->combo_box = gtk_combo_box_new ();
|
||||
priv->combo_box_changed_id =
|
||||
@ -519,30 +528,21 @@ gtk_file_chooser_button_add_shortcut_folder (GtkFileChooser *chooser,
|
||||
GtkFileChooserButtonPrivate *priv = button->priv;
|
||||
GtkTreeIter iter;
|
||||
gint pos;
|
||||
GdkPixbuf *pixbuf;
|
||||
gchar *display_name;
|
||||
|
||||
pos = model_get_type_position (button, ROW_TYPE_SHORTCUT);
|
||||
pos += priv->n_shortcuts;
|
||||
|
||||
pixbuf = gtk_file_system_render_icon (priv->fs, path,
|
||||
GTK_WIDGET (chooser),
|
||||
priv->icon_size, NULL);
|
||||
display_name = get_display_name_for_path (priv->fs, path);
|
||||
|
||||
gtk_list_store_insert (GTK_LIST_STORE (priv->model), &iter, pos);
|
||||
gtk_list_store_set (GTK_LIST_STORE (priv->model), &iter,
|
||||
ICON_COLUMN, pixbuf,
|
||||
DISPLAY_NAME_COLUMN, display_name,
|
||||
ICON_COLUMN, NULL,
|
||||
DISPLAY_NAME_COLUMN, _(FALLBACK_DISPLAY_NAME),
|
||||
TYPE_COLUMN, ROW_TYPE_SHORTCUT,
|
||||
DATA_COLUMN, gtk_file_path_copy (path),
|
||||
IS_FOLDER_COLUMN, FALSE,
|
||||
-1);
|
||||
set_info_for_path_at_iter (button, path, &iter);
|
||||
priv->n_shortcuts++;
|
||||
|
||||
if (pixbuf)
|
||||
g_object_unref (pixbuf);
|
||||
g_free (display_name);
|
||||
|
||||
gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (priv->filter_model));
|
||||
}
|
||||
|
||||
@ -868,26 +868,10 @@ gtk_file_chooser_button_finalize (GObject *object)
|
||||
{
|
||||
GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (object);
|
||||
GtkFileChooserButtonPrivate *priv = button->priv;
|
||||
GtkTreeIter iter;
|
||||
|
||||
if (priv->old_path)
|
||||
gtk_file_path_free (priv->old_path);
|
||||
|
||||
gtk_tree_model_get_iter_first (priv->model, &iter);
|
||||
|
||||
do
|
||||
{
|
||||
model_free_row_data (button, &iter);
|
||||
}
|
||||
while (gtk_tree_model_iter_next (priv->model, &iter));
|
||||
|
||||
g_object_unref (priv->model);
|
||||
g_object_unref (priv->filter_model);
|
||||
|
||||
g_signal_handler_disconnect (priv->fs, priv->fs_volumes_changed_id);
|
||||
g_signal_handler_disconnect (priv->fs, priv->fs_bookmarks_changed_id);
|
||||
g_object_unref (priv->fs);
|
||||
|
||||
if (G_OBJECT_CLASS (gtk_file_chooser_button_parent_class)->finalize != NULL)
|
||||
(*G_OBJECT_CLASS (gtk_file_chooser_button_parent_class)->finalize) (object);
|
||||
}
|
||||
@ -901,9 +885,65 @@ gtk_file_chooser_button_destroy (GtkObject *object)
|
||||
{
|
||||
GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (object);
|
||||
GtkFileChooserButtonPrivate *priv = button->priv;
|
||||
GtkTreeIter iter;
|
||||
GSList *l;
|
||||
|
||||
if (priv->dialog != NULL)
|
||||
gtk_widget_destroy (priv->dialog);
|
||||
{
|
||||
gtk_widget_destroy (priv->dialog);
|
||||
priv->dialog = NULL;
|
||||
}
|
||||
|
||||
gtk_tree_model_get_iter_first (priv->model, &iter);
|
||||
|
||||
do
|
||||
{
|
||||
model_free_row_data (button, &iter);
|
||||
}
|
||||
while (gtk_tree_model_iter_next (priv->model, &iter));
|
||||
|
||||
if (priv->dnd_select_folder_handle)
|
||||
{
|
||||
gtk_file_system_cancel_operation (priv->dnd_select_folder_handle);
|
||||
priv->dnd_select_folder_handle = NULL;
|
||||
}
|
||||
|
||||
if (priv->update_button_handle)
|
||||
{
|
||||
gtk_file_system_cancel_operation (priv->update_button_handle);
|
||||
priv->update_button_handle = NULL;
|
||||
}
|
||||
|
||||
if (priv->change_icon_theme_handles)
|
||||
{
|
||||
for (l = priv->change_icon_theme_handles; l; l = l->next)
|
||||
{
|
||||
GtkFileSystemHandle *handle = GTK_FILE_SYSTEM_HANDLE (l->data);
|
||||
gtk_file_system_cancel_operation (handle);
|
||||
}
|
||||
g_slist_free (priv->change_icon_theme_handles);
|
||||
priv->change_icon_theme_handles = NULL;
|
||||
}
|
||||
|
||||
if (priv->model)
|
||||
{
|
||||
g_object_unref (priv->model);
|
||||
priv->model = NULL;
|
||||
}
|
||||
|
||||
if (priv->filter_model)
|
||||
{
|
||||
g_object_unref (priv->filter_model);
|
||||
priv->filter_model = NULL;
|
||||
}
|
||||
|
||||
if (priv->fs)
|
||||
{
|
||||
g_signal_handler_disconnect (priv->fs, priv->fs_volumes_changed_id);
|
||||
g_signal_handler_disconnect (priv->fs, priv->fs_bookmarks_changed_id);
|
||||
g_object_unref (priv->fs);
|
||||
priv->fs = NULL;
|
||||
}
|
||||
|
||||
if (GTK_OBJECT_CLASS (gtk_file_chooser_button_parent_class)->destroy != NULL)
|
||||
(*GTK_OBJECT_CLASS (gtk_file_chooser_button_parent_class)->destroy) (object);
|
||||
@ -914,6 +954,76 @@ gtk_file_chooser_button_destroy (GtkObject *object)
|
||||
* GtkWidget Functions *
|
||||
* ********************* */
|
||||
|
||||
struct DndSelectFolderData
|
||||
{
|
||||
GtkFileChooserButton *button;
|
||||
GtkFileChooserAction action;
|
||||
GtkFilePath *path;
|
||||
gchar **uris;
|
||||
guint i;
|
||||
gboolean selected;
|
||||
};
|
||||
|
||||
static void
|
||||
dnd_select_folder_get_info_cb (GtkFileSystemHandle *handle,
|
||||
const GtkFileInfo *info,
|
||||
const GError *error,
|
||||
gpointer user_data)
|
||||
{
|
||||
gboolean cancelled = handle->cancelled;
|
||||
struct DndSelectFolderData *data = user_data;
|
||||
|
||||
if (handle != data->button->priv->dnd_select_folder_handle)
|
||||
{
|
||||
g_object_unref (data->button);
|
||||
gtk_file_path_free (data->path);
|
||||
g_strfreev (data->uris);
|
||||
g_free (data);
|
||||
|
||||
g_object_unref (handle);
|
||||
return;
|
||||
}
|
||||
|
||||
data->button->priv->dnd_select_folder_handle = NULL;
|
||||
|
||||
if (!cancelled && !error && info != NULL)
|
||||
{
|
||||
data->selected =
|
||||
(((data->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER &&
|
||||
gtk_file_info_get_is_folder (info)) ||
|
||||
(data->action == GTK_FILE_CHOOSER_ACTION_OPEN &&
|
||||
!gtk_file_info_get_is_folder (info))) &&
|
||||
_gtk_file_chooser_select_path (GTK_FILE_CHOOSER (data->button->priv->dialog),
|
||||
data->path, NULL));
|
||||
}
|
||||
else
|
||||
data->selected = FALSE;
|
||||
|
||||
if (data->selected || data->uris[++data->i] == NULL)
|
||||
{
|
||||
g_object_unref (data->button);
|
||||
gtk_file_path_free (data->path);
|
||||
g_strfreev (data->uris);
|
||||
g_free (data);
|
||||
|
||||
g_object_unref (handle);
|
||||
return;
|
||||
}
|
||||
|
||||
if (data->path)
|
||||
gtk_file_path_free (data->path);
|
||||
|
||||
data->path = gtk_file_system_uri_to_path (handle->file_system,
|
||||
data->uris[data->i]);
|
||||
|
||||
data->button->priv->dnd_select_folder_handle =
|
||||
gtk_file_system_get_info (handle->file_system, data->path,
|
||||
GTK_FILE_INFO_IS_FOLDER,
|
||||
dnd_select_folder_get_info_cb, user_data);
|
||||
|
||||
g_object_unref (handle);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_file_chooser_button_drag_data_received (GtkWidget *widget,
|
||||
GdkDragContext *context,
|
||||
@ -943,59 +1053,30 @@ gtk_file_chooser_button_drag_data_received (GtkWidget *widget,
|
||||
case TEXT_URI_LIST:
|
||||
{
|
||||
gchar **uris;
|
||||
GtkFilePath *base_path;
|
||||
guint i;
|
||||
gboolean selected;
|
||||
struct DndSelectFolderData *info;
|
||||
|
||||
uris = gtk_selection_data_get_uris (data);
|
||||
|
||||
if (uris == NULL)
|
||||
break;
|
||||
|
||||
selected = FALSE;
|
||||
for (i = 0; !selected && uris[i] != NULL; i++)
|
||||
{
|
||||
path = gtk_file_system_uri_to_path (priv->fs, uris[i]);
|
||||
info = g_new0 (struct DndSelectFolderData, 1);
|
||||
info->button = g_object_ref (button);
|
||||
info->i = 0;
|
||||
info->uris = uris;
|
||||
info->selected = FALSE;
|
||||
g_object_get (priv->dialog, "action", &info->action, NULL);
|
||||
|
||||
base_path = NULL;
|
||||
if (path != NULL &&
|
||||
gtk_file_system_get_parent (priv->fs, path, &base_path, NULL))
|
||||
{
|
||||
GtkFileFolder *folder;
|
||||
GtkFileInfo *info;
|
||||
info->path = gtk_file_system_uri_to_path (priv->fs,
|
||||
info->uris[info->i]);
|
||||
|
||||
folder = gtk_file_system_get_folder (priv->fs, base_path,
|
||||
GTK_FILE_INFO_IS_FOLDER,
|
||||
NULL);
|
||||
if (priv->dnd_select_folder_handle)
|
||||
gtk_file_system_cancel_operation (priv->dnd_select_folder_handle);
|
||||
|
||||
info = gtk_file_folder_get_info (folder, path, NULL);
|
||||
|
||||
if (info != NULL)
|
||||
{
|
||||
GtkFileChooserAction action;
|
||||
|
||||
g_object_get (priv->dialog, "action", &action, NULL);
|
||||
|
||||
selected =
|
||||
(((action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER &&
|
||||
gtk_file_info_get_is_folder (info)) ||
|
||||
(action == GTK_FILE_CHOOSER_ACTION_OPEN &&
|
||||
!gtk_file_info_get_is_folder (info))) &&
|
||||
_gtk_file_chooser_select_path (GTK_FILE_CHOOSER (priv->dialog),
|
||||
path, NULL));
|
||||
|
||||
gtk_file_info_free (info);
|
||||
}
|
||||
else
|
||||
selected = FALSE;
|
||||
|
||||
gtk_file_path_free (base_path);
|
||||
}
|
||||
|
||||
gtk_file_path_free (path);
|
||||
}
|
||||
|
||||
g_strfreev (uris);
|
||||
priv->dnd_select_folder_handle =
|
||||
gtk_file_system_get_info (priv->fs, info->path,
|
||||
GTK_FILE_INFO_IS_FOLDER,
|
||||
dnd_select_folder_get_info_cb, info);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1096,6 +1177,64 @@ gtk_file_chooser_button_mnemonic_activate (GtkWidget *widget,
|
||||
}
|
||||
|
||||
/* Changes the icons wherever it is needed */
|
||||
struct ChangeIconThemeData
|
||||
{
|
||||
GtkFileChooserButton *button;
|
||||
GtkTreeRowReference *row_ref;
|
||||
};
|
||||
|
||||
static void
|
||||
change_icon_theme_get_info_cb (GtkFileSystemHandle *handle,
|
||||
const GtkFileInfo *info,
|
||||
const GError *error,
|
||||
gpointer user_data)
|
||||
{
|
||||
gboolean cancelled = handle->cancelled;
|
||||
GdkPixbuf *pixbuf;
|
||||
struct ChangeIconThemeData *data = user_data;
|
||||
|
||||
if (!g_slist_find (data->button->priv->change_icon_theme_handles, handle))
|
||||
goto out;
|
||||
|
||||
data->button->priv->change_icon_theme_handles =
|
||||
g_slist_remove (data->button->priv->change_icon_theme_handles, handle);
|
||||
|
||||
if (cancelled || error)
|
||||
goto out;
|
||||
|
||||
pixbuf = gtk_file_info_render_icon (info, GTK_WIDGET (data->button),
|
||||
data->button->priv->icon_size, NULL);
|
||||
|
||||
if (pixbuf)
|
||||
{
|
||||
gint width = 0;
|
||||
GtkTreeIter iter;
|
||||
GtkTreePath *path;
|
||||
|
||||
width = MAX (width, gdk_pixbuf_get_width (pixbuf));
|
||||
|
||||
path = gtk_tree_row_reference_get_path (data->row_ref);
|
||||
gtk_tree_model_get_iter (data->button->priv->model, &iter, path);
|
||||
gtk_tree_path_free (path);
|
||||
|
||||
gtk_list_store_set (GTK_LIST_STORE (data->button->priv->model), &iter,
|
||||
ICON_COLUMN, pixbuf,
|
||||
-1);
|
||||
g_object_unref (pixbuf);
|
||||
|
||||
g_object_set (data->button->priv->icon_cell,
|
||||
"width", width,
|
||||
NULL);
|
||||
}
|
||||
|
||||
out:
|
||||
g_object_unref (data->button);
|
||||
gtk_tree_row_reference_free (data->row_ref);
|
||||
g_free (data);
|
||||
|
||||
g_object_unref (handle);
|
||||
}
|
||||
|
||||
static void
|
||||
change_icon_theme (GtkFileChooserButton *button)
|
||||
{
|
||||
@ -1103,7 +1242,16 @@ change_icon_theme (GtkFileChooserButton *button)
|
||||
GtkSettings *settings;
|
||||
GtkIconTheme *theme;
|
||||
GtkTreeIter iter;
|
||||
gint width, height;
|
||||
GSList *l;
|
||||
gint width = 0, height = 0;
|
||||
|
||||
for (l = button->priv->change_icon_theme_handles; l; l = l->next)
|
||||
{
|
||||
GtkFileSystemHandle *handle = GTK_FILE_SYSTEM_HANDLE (l->data);
|
||||
gtk_file_system_cancel_operation (handle);
|
||||
}
|
||||
g_slist_free (button->priv->change_icon_theme_handles);
|
||||
button->priv->change_icon_theme_handles = NULL;
|
||||
|
||||
settings = gtk_settings_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (button)));
|
||||
|
||||
@ -1138,9 +1286,25 @@ change_icon_theme (GtkFileChooserButton *button)
|
||||
case ROW_TYPE_BOOKMARK:
|
||||
case ROW_TYPE_CURRENT_FOLDER:
|
||||
if (data)
|
||||
pixbuf = gtk_file_system_render_icon (priv->fs, data,
|
||||
GTK_WIDGET (button),
|
||||
priv->icon_size, NULL);
|
||||
{
|
||||
GtkTreePath *path;
|
||||
GtkFileSystemHandle *handle;
|
||||
struct ChangeIconThemeData *info;
|
||||
|
||||
info = g_new0 (struct ChangeIconThemeData, 1);
|
||||
info->button = g_object_ref (button);
|
||||
path = gtk_tree_model_get_path (priv->model, &iter);
|
||||
info->row_ref = gtk_tree_row_reference_new (priv->model, path);
|
||||
gtk_tree_path_free (path);
|
||||
|
||||
handle =
|
||||
gtk_file_system_get_info (priv->fs, data, GTK_FILE_INFO_ICON,
|
||||
change_icon_theme_get_info_cb,
|
||||
info);
|
||||
button->priv->change_icon_theme_handles =
|
||||
g_slist_append (button->priv->change_icon_theme_handles, handle);
|
||||
pixbuf = NULL;
|
||||
}
|
||||
else
|
||||
pixbuf = gtk_icon_theme_load_icon (theme, FALLBACK_ICON_NAME,
|
||||
priv->icon_size, 0, NULL);
|
||||
@ -1215,43 +1379,92 @@ get_icon_theme (GtkWidget *widget)
|
||||
return gtk_icon_theme_get_default ();
|
||||
}
|
||||
|
||||
static gchar *
|
||||
get_display_name_for_path (GtkFileSystem *fs,
|
||||
const GtkFilePath *path)
|
||||
|
||||
struct SetDisplayNameData
|
||||
{
|
||||
GtkFilePath *parent_path;
|
||||
GtkFileFolder *folder;
|
||||
gchar *retval;
|
||||
GtkFileChooserButton *button;
|
||||
GtkTreeRowReference *row_ref;
|
||||
};
|
||||
|
||||
parent_path = NULL;
|
||||
retval = NULL;
|
||||
static void
|
||||
set_info_get_info_cb (GtkFileSystemHandle *handle,
|
||||
const GtkFileInfo *info,
|
||||
const GError *error,
|
||||
gpointer callback_data)
|
||||
{
|
||||
gboolean cancelled = handle->cancelled;
|
||||
GdkPixbuf *pixbuf;
|
||||
GtkTreePath *path;
|
||||
GtkTreeIter iter;
|
||||
GtkFileSystemHandle *model_handle;
|
||||
struct SetDisplayNameData *data = callback_data;
|
||||
|
||||
gtk_file_system_get_parent (fs, path, &parent_path, NULL);
|
||||
path = gtk_tree_row_reference_get_path (data->row_ref);
|
||||
if (!path)
|
||||
/* Handle doesn't exist anymore in the model */
|
||||
goto out;
|
||||
|
||||
folder = gtk_file_system_get_folder (fs, parent_path ? parent_path : path,
|
||||
GTK_FILE_INFO_DISPLAY_NAME, NULL);
|
||||
gtk_tree_model_get_iter (data->button->priv->model, &iter, path);
|
||||
gtk_tree_path_free (path);
|
||||
|
||||
if (folder)
|
||||
{
|
||||
GtkFileInfo *info;
|
||||
/* Validate the handle */
|
||||
gtk_tree_model_get (data->button->priv->model, &iter,
|
||||
HANDLE_COLUMN, &model_handle,
|
||||
-1);
|
||||
if (handle != model_handle)
|
||||
goto out;
|
||||
|
||||
info = gtk_file_folder_get_info (folder, path, NULL);
|
||||
g_object_unref (folder);
|
||||
gtk_list_store_set (GTK_LIST_STORE (data->button->priv->model), &iter,
|
||||
HANDLE_COLUMN, NULL,
|
||||
-1);
|
||||
|
||||
if (info)
|
||||
{
|
||||
retval = g_strdup (gtk_file_info_get_display_name (info));
|
||||
gtk_file_info_free (info);
|
||||
}
|
||||
}
|
||||
if (cancelled || error)
|
||||
/* There was an error, leave the fallback name in there */
|
||||
goto out;
|
||||
|
||||
if (parent_path)
|
||||
gtk_file_path_free (parent_path);
|
||||
pixbuf = gtk_file_info_render_icon (info, GTK_WIDGET (data->button),
|
||||
data->button->priv->icon_size, NULL);
|
||||
|
||||
if (!retval)
|
||||
retval = g_strdup (_(FALLBACK_DISPLAY_NAME));
|
||||
gtk_list_store_set (GTK_LIST_STORE (data->button->priv->model), &iter,
|
||||
ICON_COLUMN, pixbuf,
|
||||
DISPLAY_NAME_COLUMN, gtk_file_info_get_display_name (info),
|
||||
IS_FOLDER_COLUMN, gtk_file_info_get_is_folder (info),
|
||||
-1);
|
||||
|
||||
return retval;
|
||||
if (pixbuf)
|
||||
g_object_unref (pixbuf);
|
||||
|
||||
out:
|
||||
g_object_unref (data->button);
|
||||
gtk_tree_row_reference_free (data->row_ref);
|
||||
g_free (data);
|
||||
|
||||
g_object_unref (handle);
|
||||
}
|
||||
|
||||
static void
|
||||
set_info_for_path_at_iter (GtkFileChooserButton *button,
|
||||
const GtkFilePath *path,
|
||||
GtkTreeIter *iter)
|
||||
{
|
||||
struct SetDisplayNameData *data;
|
||||
GtkTreePath *tree_path;
|
||||
GtkFileSystemHandle *handle;
|
||||
|
||||
data = g_new0 (struct SetDisplayNameData, 1);
|
||||
data->button = g_object_ref (button);
|
||||
|
||||
tree_path = gtk_tree_model_get_path (button->priv->model, iter);
|
||||
data->row_ref = gtk_tree_row_reference_new (button->priv->model, tree_path);
|
||||
gtk_tree_path_free (tree_path);
|
||||
|
||||
handle = gtk_file_system_get_info (button->priv->fs, path,
|
||||
GTK_FILE_INFO_DISPLAY_NAME | GTK_FILE_INFO_IS_FOLDER | GTK_FILE_INFO_ICON,
|
||||
set_info_get_info_cb, data);
|
||||
|
||||
gtk_list_store_set (GTK_LIST_STORE (button->priv->model), iter,
|
||||
HANDLE_COLUMN, handle,
|
||||
-1);
|
||||
}
|
||||
|
||||
/* Shortcuts Model */
|
||||
@ -1314,12 +1527,17 @@ model_free_row_data (GtkFileChooserButton *button,
|
||||
{
|
||||
gchar type;
|
||||
gpointer data;
|
||||
GtkFileSystemHandle *handle;
|
||||
|
||||
gtk_tree_model_get (button->priv->model, iter,
|
||||
TYPE_COLUMN, &type,
|
||||
DATA_COLUMN, &data,
|
||||
HANDLE_COLUMN, &handle,
|
||||
-1);
|
||||
|
||||
if (handle)
|
||||
gtk_file_system_cancel_operation (handle);
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case ROW_TYPE_SPECIAL:
|
||||
@ -1336,16 +1554,70 @@ model_free_row_data (GtkFileChooserButton *button,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
model_add_special_get_info_cb (GtkFileSystemHandle *handle,
|
||||
const GtkFileInfo *info,
|
||||
const GError *error,
|
||||
gpointer user_data)
|
||||
{
|
||||
gboolean cancelled = handle->cancelled;
|
||||
GtkTreeIter iter;
|
||||
GtkTreePath *path;
|
||||
GdkPixbuf *pixbuf;
|
||||
GtkFileSystemHandle *model_handle;
|
||||
struct ChangeIconThemeData *data = user_data;
|
||||
|
||||
path = gtk_tree_row_reference_get_path (data->row_ref);
|
||||
if (!path)
|
||||
/* Handle doesn't exist anymore in the model */
|
||||
goto out;
|
||||
|
||||
gtk_tree_model_get_iter (data->button->priv->model, &iter, path);
|
||||
gtk_tree_path_free (path);
|
||||
|
||||
gtk_tree_model_get (data->button->priv->model, &iter,
|
||||
HANDLE_COLUMN, &model_handle,
|
||||
-1);
|
||||
if (handle != model_handle)
|
||||
goto out;
|
||||
|
||||
gtk_list_store_set (GTK_LIST_STORE (data->button->priv->model), &iter,
|
||||
HANDLE_COLUMN, NULL,
|
||||
-1);
|
||||
|
||||
if (cancelled || error)
|
||||
goto out;
|
||||
|
||||
pixbuf = gtk_file_info_render_icon (info, GTK_WIDGET (data->button),
|
||||
data->button->priv->icon_size, NULL);
|
||||
|
||||
if (pixbuf)
|
||||
{
|
||||
gtk_list_store_set (GTK_LIST_STORE (data->button->priv->model), &iter,
|
||||
ICON_COLUMN, pixbuf,
|
||||
-1);
|
||||
g_object_unref (pixbuf);
|
||||
}
|
||||
|
||||
gtk_list_store_set (GTK_LIST_STORE (data->button->priv->model), &iter,
|
||||
DISPLAY_NAME_COLUMN, gtk_file_info_get_display_name (info),
|
||||
-1);
|
||||
|
||||
out:
|
||||
gtk_tree_row_reference_free (data->row_ref);
|
||||
g_free (data);
|
||||
|
||||
g_object_unref (handle);
|
||||
}
|
||||
|
||||
static inline void
|
||||
model_add_special (GtkFileChooserButton *button)
|
||||
{
|
||||
const gchar *homedir;
|
||||
const gchar *display_name;
|
||||
gchar *desktopdir = NULL;
|
||||
GtkListStore *store;
|
||||
GtkTreeIter iter;
|
||||
GtkFilePath *path;
|
||||
GdkPixbuf *pixbuf;
|
||||
gint pos;
|
||||
|
||||
store = GTK_LIST_STORE (button->priv->model);
|
||||
@ -1355,23 +1627,34 @@ model_add_special (GtkFileChooserButton *button)
|
||||
|
||||
if (homedir)
|
||||
{
|
||||
GtkTreePath *tree_path;
|
||||
GtkFileSystemHandle *handle;
|
||||
struct ChangeIconThemeData *info;
|
||||
|
||||
path = gtk_file_system_filename_to_path (button->priv->fs, homedir);
|
||||
display_name = get_display_name_for_path (button->priv->fs, path);
|
||||
pixbuf = gtk_file_system_render_icon (button->priv->fs, path,
|
||||
GTK_WIDGET (button),
|
||||
button->priv->icon_size, NULL);
|
||||
gtk_list_store_insert (store, &iter, pos);
|
||||
pos++;
|
||||
|
||||
info = g_new0 (struct ChangeIconThemeData, 1);
|
||||
info->button = g_object_ref (button);
|
||||
tree_path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), &iter);
|
||||
info->row_ref = gtk_tree_row_reference_new (GTK_TREE_MODEL (store),
|
||||
tree_path);
|
||||
gtk_tree_path_free (tree_path);
|
||||
|
||||
handle = gtk_file_system_get_info (button->priv->fs, path,
|
||||
GTK_FILE_INFO_ICON,
|
||||
model_add_special_get_info_cb, info);
|
||||
|
||||
gtk_list_store_set (store, &iter,
|
||||
ICON_COLUMN, pixbuf,
|
||||
DISPLAY_NAME_COLUMN, display_name,
|
||||
ICON_COLUMN, NULL,
|
||||
DISPLAY_NAME_COLUMN, NULL,
|
||||
TYPE_COLUMN, ROW_TYPE_SPECIAL,
|
||||
DATA_COLUMN, path,
|
||||
IS_FOLDER_COLUMN, TRUE,
|
||||
HANDLE_COLUMN, handle,
|
||||
-1);
|
||||
|
||||
if (pixbuf)
|
||||
g_object_unref (pixbuf);
|
||||
g_free (display_name);
|
||||
button->priv->n_special++;
|
||||
|
||||
#ifndef G_OS_WIN32
|
||||
@ -1385,22 +1668,34 @@ model_add_special (GtkFileChooserButton *button)
|
||||
|
||||
if (desktopdir)
|
||||
{
|
||||
GtkTreePath *tree_path;
|
||||
GtkFileSystemHandle *handle;
|
||||
struct ChangeIconThemeData *info;
|
||||
|
||||
path = gtk_file_system_filename_to_path (button->priv->fs, desktopdir);
|
||||
g_free (desktopdir);
|
||||
pixbuf = gtk_file_system_render_icon (button->priv->fs, path,
|
||||
GTK_WIDGET (button),
|
||||
button->priv->icon_size, NULL);
|
||||
gtk_list_store_insert (store, &iter, pos);
|
||||
pos++;
|
||||
|
||||
info = g_new0 (struct ChangeIconThemeData, 1);
|
||||
info->button = g_object_ref (button);
|
||||
tree_path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), &iter);
|
||||
info->row_ref = gtk_tree_row_reference_new (GTK_TREE_MODEL (store),
|
||||
tree_path);
|
||||
gtk_tree_path_free (tree_path);
|
||||
|
||||
handle = gtk_file_system_get_info (button->priv->fs, path,
|
||||
GTK_FILE_INFO_ICON,
|
||||
model_add_special_get_info_cb, info);
|
||||
|
||||
gtk_list_store_set (store, &iter,
|
||||
TYPE_COLUMN, ROW_TYPE_SPECIAL,
|
||||
ICON_COLUMN, pixbuf,
|
||||
ICON_COLUMN, NULL,
|
||||
DISPLAY_NAME_COLUMN, _(DESKTOP_DISPLAY_NAME),
|
||||
DATA_COLUMN, path,
|
||||
IS_FOLDER_COLUMN, TRUE,
|
||||
-1);
|
||||
|
||||
if (pixbuf)
|
||||
g_object_unref (pixbuf);
|
||||
button->priv->n_special++;
|
||||
}
|
||||
}
|
||||
@ -1438,6 +1733,7 @@ model_add_volumes (GtkFileChooserButton *button,
|
||||
DISPLAY_NAME_COLUMN, display_name,
|
||||
TYPE_COLUMN, ROW_TYPE_VOLUME,
|
||||
DATA_COLUMN, volumes->data,
|
||||
IS_FOLDER_COLUMN, TRUE,
|
||||
-1);
|
||||
|
||||
if (pixbuf)
|
||||
@ -1473,32 +1769,24 @@ model_add_bookmarks (GtkFileChooserButton *button,
|
||||
DISPLAY_NAME_COLUMN, NULL,
|
||||
TYPE_COLUMN, ROW_TYPE_BOOKMARK_SEPARATOR,
|
||||
DATA_COLUMN, NULL,
|
||||
IS_FOLDER_COLUMN, FALSE,
|
||||
-1);
|
||||
button->priv->has_bookmark_separator = TRUE;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
GdkPixbuf *pixbuf;
|
||||
gchar *display_name;
|
||||
|
||||
pos++;
|
||||
pixbuf = gtk_file_system_render_icon (button->priv->fs, bookmarks->data,
|
||||
GTK_WIDGET (button),
|
||||
button->priv->icon_size, NULL);
|
||||
display_name = get_display_name_for_path (button->priv->fs,
|
||||
bookmarks->data);
|
||||
|
||||
gtk_list_store_insert (store, &iter, pos);
|
||||
gtk_list_store_set (store, &iter,
|
||||
ICON_COLUMN, pixbuf,
|
||||
DISPLAY_NAME_COLUMN, display_name,
|
||||
ICON_COLUMN, NULL,
|
||||
DISPLAY_NAME_COLUMN, _(FALLBACK_DISPLAY_NAME),
|
||||
TYPE_COLUMN, ROW_TYPE_BOOKMARK,
|
||||
DATA_COLUMN, gtk_file_path_copy (bookmarks->data),
|
||||
IS_FOLDER_COLUMN, FALSE,
|
||||
-1);
|
||||
if (pixbuf)
|
||||
g_object_unref (pixbuf);
|
||||
g_free (display_name);
|
||||
set_info_for_path_at_iter (button, bookmarks->data, &iter);
|
||||
|
||||
button->priv->n_bookmarks++;
|
||||
bookmarks = bookmarks->next;
|
||||
@ -1513,8 +1801,6 @@ model_update_current_folder (GtkFileChooserButton *button,
|
||||
GtkListStore *store;
|
||||
GtkTreeIter iter;
|
||||
gint pos;
|
||||
GdkPixbuf *pixbuf;
|
||||
gchar *display_name;
|
||||
|
||||
if (!path)
|
||||
return;
|
||||
@ -1530,6 +1816,7 @@ model_update_current_folder (GtkFileChooserButton *button,
|
||||
DISPLAY_NAME_COLUMN, NULL,
|
||||
TYPE_COLUMN, ROW_TYPE_CURRENT_FOLDER_SEPARATOR,
|
||||
DATA_COLUMN, NULL,
|
||||
IS_FOLDER_COLUMN, FALSE,
|
||||
-1);
|
||||
button->priv->has_current_folder_separator = TRUE;
|
||||
}
|
||||
@ -1546,19 +1833,14 @@ model_update_current_folder (GtkFileChooserButton *button,
|
||||
model_free_row_data (button, &iter);
|
||||
}
|
||||
|
||||
pixbuf = gtk_file_system_render_icon (button->priv->fs, path,
|
||||
GTK_WIDGET (button),
|
||||
button->priv->icon_size, NULL);
|
||||
display_name = get_display_name_for_path (button->priv->fs, path);
|
||||
gtk_list_store_set (store, &iter,
|
||||
ICON_COLUMN, pixbuf,
|
||||
DISPLAY_NAME_COLUMN, display_name,
|
||||
ICON_COLUMN, NULL,
|
||||
DISPLAY_NAME_COLUMN, _(FALLBACK_DISPLAY_NAME),
|
||||
TYPE_COLUMN, ROW_TYPE_CURRENT_FOLDER,
|
||||
DATA_COLUMN, gtk_file_path_copy (path),
|
||||
IS_FOLDER_COLUMN, FALSE,
|
||||
-1);
|
||||
if (pixbuf)
|
||||
g_object_unref (pixbuf);
|
||||
g_free (display_name);
|
||||
set_info_for_path_at_iter (button, path, &iter);
|
||||
}
|
||||
|
||||
static inline void
|
||||
@ -1577,6 +1859,7 @@ model_add_other (GtkFileChooserButton *button)
|
||||
DISPLAY_NAME_COLUMN, NULL,
|
||||
TYPE_COLUMN, ROW_TYPE_OTHER_SEPARATOR,
|
||||
DATA_COLUMN, NULL,
|
||||
IS_FOLDER_COLUMN, FALSE,
|
||||
-1);
|
||||
button->priv->has_other_separator = TRUE;
|
||||
pos++;
|
||||
@ -1587,6 +1870,7 @@ model_add_other (GtkFileChooserButton *button)
|
||||
DISPLAY_NAME_COLUMN, _("Other..."),
|
||||
TYPE_COLUMN, ROW_TYPE_OTHER,
|
||||
DATA_COLUMN, NULL,
|
||||
IS_FOLDER_COLUMN, FALSE,
|
||||
-1);
|
||||
}
|
||||
|
||||
@ -1620,42 +1904,17 @@ model_remove_rows (GtkFileChooserButton *button,
|
||||
static inline gboolean
|
||||
test_if_path_is_visible (GtkFileSystem *fs,
|
||||
const GtkFilePath *path,
|
||||
gboolean local_only)
|
||||
gboolean local_only,
|
||||
gboolean is_folder)
|
||||
{
|
||||
GtkFilePath *parent_path;
|
||||
GtkFileFolder *folder;
|
||||
GtkFileInfo *info;
|
||||
|
||||
if (!path)
|
||||
return FALSE;
|
||||
|
||||
if (local_only && !gtk_file_system_path_is_local (fs, path))
|
||||
return FALSE;
|
||||
|
||||
parent_path = NULL;
|
||||
gtk_file_system_get_parent (fs, path, &parent_path, NULL);
|
||||
|
||||
folder = gtk_file_system_get_folder (fs, parent_path ? parent_path : path,
|
||||
GTK_FILE_INFO_IS_FOLDER, NULL);
|
||||
gtk_file_path_free (parent_path);
|
||||
|
||||
if (folder)
|
||||
{
|
||||
info = gtk_file_folder_get_info (folder, path, NULL);
|
||||
g_object_unref (folder);
|
||||
}
|
||||
else
|
||||
info = NULL;
|
||||
|
||||
if (!info)
|
||||
if (!is_folder)
|
||||
return FALSE;
|
||||
else if (!gtk_file_info_get_is_folder (info))
|
||||
{
|
||||
gtk_file_info_free (info);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gtk_file_info_free (info);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@ -1669,7 +1928,7 @@ filter_model_visible_func (GtkTreeModel *model,
|
||||
GtkFileChooserButtonPrivate *priv = button->priv;
|
||||
gchar type;
|
||||
gpointer data;
|
||||
gboolean local_only, retval;
|
||||
gboolean local_only, retval, is_folder;
|
||||
|
||||
type = ROW_TYPE_INVALID;
|
||||
data = NULL;
|
||||
@ -1678,6 +1937,7 @@ filter_model_visible_func (GtkTreeModel *model,
|
||||
gtk_tree_model_get (model, iter,
|
||||
TYPE_COLUMN, &type,
|
||||
DATA_COLUMN, &data,
|
||||
IS_FOLDER_COLUMN, &is_folder,
|
||||
-1);
|
||||
|
||||
switch (type)
|
||||
@ -1688,7 +1948,7 @@ filter_model_visible_func (GtkTreeModel *model,
|
||||
case ROW_TYPE_SPECIAL:
|
||||
case ROW_TYPE_SHORTCUT:
|
||||
case ROW_TYPE_BOOKMARK:
|
||||
retval = test_if_path_is_visible (priv->fs, data, local_only);
|
||||
retval = test_if_path_is_visible (priv->fs, data, local_only, is_folder);
|
||||
break;
|
||||
case ROW_TYPE_VOLUME:
|
||||
{
|
||||
@ -1836,6 +2096,43 @@ update_combo_box (GtkFileChooserButton *button)
|
||||
}
|
||||
|
||||
/* Button */
|
||||
static void
|
||||
update_label_get_info_cb (GtkFileSystemHandle *handle,
|
||||
const GtkFileInfo *info,
|
||||
const GError *error,
|
||||
gpointer data)
|
||||
{
|
||||
gboolean cancelled = handle->cancelled;
|
||||
GdkPixbuf *pixbuf;
|
||||
GtkFileChooserButton *button = data;
|
||||
GtkFileChooserButtonPrivate *priv = button->priv;
|
||||
|
||||
if (handle != priv->update_button_handle)
|
||||
goto out;
|
||||
|
||||
priv->update_button_handle = NULL;
|
||||
|
||||
if (cancelled || error)
|
||||
goto out;
|
||||
|
||||
gtk_label_set_text (GTK_LABEL (priv->label), gtk_file_info_get_display_name (info));
|
||||
|
||||
pixbuf = gtk_file_info_render_icon (info, GTK_WIDGET (priv->image),
|
||||
priv->icon_size, NULL);
|
||||
if (!pixbuf)
|
||||
pixbuf = gtk_icon_theme_load_icon (get_icon_theme (GTK_WIDGET (priv->image)),
|
||||
FALLBACK_ICON_NAME,
|
||||
priv->icon_size, 0, NULL);
|
||||
|
||||
gtk_image_set_from_pixbuf (GTK_IMAGE (priv->image), pixbuf);
|
||||
if (pixbuf)
|
||||
g_object_unref (pixbuf);
|
||||
|
||||
out:
|
||||
g_object_unref (button);
|
||||
g_object_unref (handle);
|
||||
}
|
||||
|
||||
static void
|
||||
update_label_and_image (GtkFileChooserButton *button)
|
||||
{
|
||||
@ -1848,11 +2145,10 @@ update_label_and_image (GtkFileChooserButton *button)
|
||||
label_text = NULL;
|
||||
pixbuf = NULL;
|
||||
|
||||
if (paths)
|
||||
if (paths && paths->data)
|
||||
{
|
||||
GtkFilePath *path, *parent_path;
|
||||
GtkFileSystemVolume *volume;
|
||||
GtkFileFolder *folder;
|
||||
GtkFilePath *path;
|
||||
GtkFileSystemVolume *volume = NULL;
|
||||
|
||||
path = paths->data;
|
||||
|
||||
@ -1881,32 +2177,14 @@ update_label_and_image (GtkFileChooserButton *button)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!pixbuf)
|
||||
pixbuf = gtk_file_system_render_icon (priv->fs, path,
|
||||
GTK_WIDGET (button),
|
||||
priv->icon_size, NULL);
|
||||
if (priv->update_button_handle)
|
||||
gtk_file_system_cancel_operation (priv->update_button_handle);
|
||||
|
||||
parent_path = NULL;
|
||||
gtk_file_system_get_parent (priv->fs, path, &parent_path, NULL);
|
||||
|
||||
folder = gtk_file_system_get_folder (priv->fs,
|
||||
parent_path ? parent_path : path,
|
||||
GTK_FILE_INFO_DISPLAY_NAME, NULL);
|
||||
gtk_file_path_free (parent_path);
|
||||
|
||||
if (folder)
|
||||
{
|
||||
GtkFileInfo *info;
|
||||
|
||||
info = gtk_file_folder_get_info (folder, path, NULL);
|
||||
g_object_unref (folder);
|
||||
|
||||
if (info)
|
||||
{
|
||||
label_text = g_strdup (gtk_file_info_get_display_name (info));
|
||||
gtk_file_info_free (info);
|
||||
}
|
||||
}
|
||||
priv->update_button_handle =
|
||||
gtk_file_system_get_info (priv->fs, path,
|
||||
GTK_FILE_INFO_DISPLAY_NAME | GTK_FILE_INFO_ICON,
|
||||
update_label_get_info_cb,
|
||||
g_object_ref (button));
|
||||
|
||||
out:
|
||||
gtk_file_paths_free (paths);
|
||||
@ -1919,15 +2197,6 @@ update_label_and_image (GtkFileChooserButton *button)
|
||||
}
|
||||
else
|
||||
gtk_label_set_text (GTK_LABEL (priv->label), _(FALLBACK_DISPLAY_NAME));
|
||||
|
||||
if (!pixbuf)
|
||||
pixbuf = gtk_icon_theme_load_icon (get_icon_theme (GTK_WIDGET (button)),
|
||||
FALLBACK_ICON_NAME,
|
||||
priv->icon_size, 0, NULL);
|
||||
|
||||
gtk_image_set_from_pixbuf (GTK_IMAGE (priv->image), pixbuf);
|
||||
if (pixbuf)
|
||||
g_object_unref (pixbuf);
|
||||
}
|
||||
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -129,6 +129,7 @@ gtk_file_chooser_dialog_init (GtkFileChooserDialog *dialog)
|
||||
dialog->priv->default_height = -1;
|
||||
dialog->priv->resize_horizontally = TRUE;
|
||||
dialog->priv->resize_vertically = TRUE;
|
||||
dialog->priv->response_requested = FALSE;
|
||||
|
||||
gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);
|
||||
|
||||
@ -355,6 +356,39 @@ file_chooser_widget_default_size_changed (GtkWidget *widget,
|
||||
else
|
||||
file_chooser_widget_default_unrealized_size_changed (widget, dialog);
|
||||
}
|
||||
|
||||
static void
|
||||
file_chooser_widget_response_requested (GtkWidget *widget,
|
||||
GtkFileChooserDialog *dialog)
|
||||
{
|
||||
GList *children, *l;
|
||||
|
||||
/* There probably isn't a default widget, so make things easier for the
|
||||
* programmer by looking for a reasonable button on our own.
|
||||
*/
|
||||
|
||||
children = gtk_container_get_children (GTK_CONTAINER (GTK_DIALOG (dialog)->action_area));
|
||||
|
||||
for (l = children; l; l = l->next)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
int response_id;
|
||||
|
||||
widget = GTK_WIDGET (l->data);
|
||||
response_id = gtk_dialog_get_response_for_widget (GTK_DIALOG (dialog), widget);
|
||||
if (response_id == GTK_RESPONSE_ACCEPT
|
||||
|| response_id == GTK_RESPONSE_OK
|
||||
|| response_id == GTK_RESPONSE_YES
|
||||
|| response_id == GTK_RESPONSE_APPLY)
|
||||
{
|
||||
dialog->priv->response_requested = TRUE;
|
||||
gtk_widget_activate (widget); /* Should we gtk_dialog_response (dialog, response_id) instead? */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
g_list_free (children);
|
||||
}
|
||||
|
||||
static GObject*
|
||||
gtk_file_chooser_dialog_constructor (GType type,
|
||||
@ -382,6 +416,8 @@ gtk_file_chooser_dialog_constructor (GType type,
|
||||
G_CALLBACK (file_chooser_widget_file_activated), object);
|
||||
g_signal_connect (priv->widget, "default-size-changed",
|
||||
G_CALLBACK (file_chooser_widget_default_size_changed), object);
|
||||
g_signal_connect (priv->widget, "response-requested",
|
||||
G_CALLBACK (file_chooser_widget_response_requested), object);
|
||||
|
||||
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (object)->vbox), priv->widget, TRUE, TRUE, 0);
|
||||
|
||||
@ -550,8 +586,11 @@ response_cb (GtkDialog *dialog,
|
||||
|| response_id == GTK_RESPONSE_APPLY))
|
||||
return;
|
||||
|
||||
if (!_gtk_file_chooser_embed_should_respond (GTK_FILE_CHOOSER_EMBED (priv->widget)))
|
||||
g_signal_stop_emission_by_name (dialog, "response");
|
||||
if (!priv->response_requested && !_gtk_file_chooser_embed_should_respond (GTK_FILE_CHOOSER_EMBED (priv->widget)))
|
||||
{
|
||||
g_signal_stop_emission_by_name (dialog, "response");
|
||||
priv->response_requested = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
|
@ -35,6 +35,8 @@ static gboolean delegate_should_respond (GtkFileChooserEmbed *chooser_embe
|
||||
static void delegate_initial_focus (GtkFileChooserEmbed *chooser_embed);
|
||||
static void delegate_default_size_changed (GtkFileChooserEmbed *chooser_embed,
|
||||
gpointer data);
|
||||
static void delegate_response_requested (GtkFileChooserEmbed *chooser_embed,
|
||||
gpointer data);
|
||||
|
||||
static GtkFileChooserEmbed *
|
||||
get_delegate (GtkFileChooserEmbed *receiver)
|
||||
@ -81,6 +83,8 @@ _gtk_file_chooser_embed_set_delegate (GtkFileChooserEmbed *receiver,
|
||||
|
||||
g_signal_connect (delegate, "default_size_changed",
|
||||
G_CALLBACK (delegate_default_size_changed), receiver);
|
||||
g_signal_connect (delegate, "response_requested",
|
||||
G_CALLBACK (delegate_response_requested), receiver);
|
||||
}
|
||||
|
||||
|
||||
@ -120,6 +124,13 @@ delegate_default_size_changed (GtkFileChooserEmbed *chooser_embed,
|
||||
g_signal_emit_by_name (data, "default-size-changed");
|
||||
}
|
||||
|
||||
static void
|
||||
delegate_response_requested (GtkFileChooserEmbed *chooser_embed,
|
||||
gpointer data)
|
||||
{
|
||||
g_signal_emit_by_name (data, "response-requested");
|
||||
}
|
||||
|
||||
|
||||
/* publicly callable functions */
|
||||
|
||||
@ -160,6 +171,13 @@ gtk_file_chooser_embed_class_init (gpointer g_iface)
|
||||
NULL, NULL,
|
||||
_gtk_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
g_signal_new (_("response-requested"),
|
||||
iface_type,
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GtkFileChooserEmbedIface, response_requested),
|
||||
NULL, NULL,
|
||||
_gtk_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -53,6 +53,7 @@ struct _GtkFileChooserEmbedIface
|
||||
/* Signals
|
||||
*/
|
||||
void (*default_size_changed) (GtkFileChooserEmbed *chooser_embed);
|
||||
void (*response_requested) (GtkFileChooserEmbed *chooser_embed);
|
||||
};
|
||||
|
||||
GType _gtk_file_chooser_embed_get_type (void) G_GNUC_CONST;
|
||||
|
@ -55,6 +55,7 @@ struct _GtkFileChooserEntry
|
||||
GSource *load_directory_idle;
|
||||
|
||||
GtkFileFolder *current_folder;
|
||||
GtkFileSystemHandle *load_folder_handle;
|
||||
|
||||
GtkListStore *completion_store;
|
||||
|
||||
@ -75,6 +76,7 @@ static void gtk_file_chooser_entry_iface_init (GtkEditableClass *iface);
|
||||
static void gtk_file_chooser_entry_init (GtkFileChooserEntry *chooser_entry);
|
||||
|
||||
static void gtk_file_chooser_entry_finalize (GObject *object);
|
||||
static void gtk_file_chooser_entry_dispose (GObject *object);
|
||||
static gboolean gtk_file_chooser_entry_focus (GtkWidget *widget,
|
||||
GtkDirectionType direction);
|
||||
static void gtk_file_chooser_entry_activate (GtkEntry *entry);
|
||||
@ -156,6 +158,7 @@ gtk_file_chooser_entry_class_init (GtkFileChooserEntryClass *class)
|
||||
parent_class = g_type_class_peek_parent (class);
|
||||
|
||||
gobject_class->finalize = gtk_file_chooser_entry_finalize;
|
||||
gobject_class->dispose = gtk_file_chooser_entry_dispose;
|
||||
|
||||
widget_class->focus = gtk_file_chooser_entry_focus;
|
||||
|
||||
@ -211,8 +214,29 @@ gtk_file_chooser_entry_finalize (GObject *object)
|
||||
{
|
||||
GtkFileChooserEntry *chooser_entry = GTK_FILE_CHOOSER_ENTRY (object);
|
||||
|
||||
gtk_file_path_free (chooser_entry->base_folder);
|
||||
gtk_file_path_free (chooser_entry->current_folder_path);
|
||||
g_free (chooser_entry->file_part);
|
||||
|
||||
parent_class->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_file_chooser_entry_dispose (GObject *object)
|
||||
{
|
||||
GtkFileChooserEntry *chooser_entry = GTK_FILE_CHOOSER_ENTRY (object);
|
||||
|
||||
if (chooser_entry->completion_store)
|
||||
g_object_unref (chooser_entry->completion_store);
|
||||
{
|
||||
g_object_unref (chooser_entry->completion_store);
|
||||
chooser_entry->completion_store = NULL;
|
||||
}
|
||||
|
||||
if (chooser_entry->load_folder_handle)
|
||||
{
|
||||
gtk_file_system_cancel_operation (chooser_entry->load_folder_handle);
|
||||
chooser_entry->load_folder_handle = NULL;
|
||||
}
|
||||
|
||||
if (chooser_entry->current_folder)
|
||||
{
|
||||
@ -221,16 +245,16 @@ gtk_file_chooser_entry_finalize (GObject *object)
|
||||
g_signal_handlers_disconnect_by_func (chooser_entry->current_folder,
|
||||
G_CALLBACK (files_deleted_cb), chooser_entry);
|
||||
g_object_unref (chooser_entry->current_folder);
|
||||
chooser_entry->current_folder = NULL;
|
||||
}
|
||||
|
||||
if (chooser_entry->file_system)
|
||||
g_object_unref (chooser_entry->file_system);
|
||||
{
|
||||
g_object_unref (chooser_entry->file_system);
|
||||
chooser_entry->file_system = NULL;
|
||||
}
|
||||
|
||||
gtk_file_path_free (chooser_entry->base_folder);
|
||||
gtk_file_path_free (chooser_entry->current_folder_path);
|
||||
g_free (chooser_entry->file_part);
|
||||
|
||||
parent_class->finalize (object);
|
||||
parent_class->dispose (object);
|
||||
}
|
||||
|
||||
/* Match functions for the GtkEntryCompletion */
|
||||
@ -601,6 +625,41 @@ files_deleted_cb (GtkFileSystem *file_system,
|
||||
/* FIXME: gravy... */
|
||||
}
|
||||
|
||||
static void
|
||||
load_directory_get_folder_callback (GtkFileSystemHandle *handle,
|
||||
GtkFileFolder *folder,
|
||||
const GError *error,
|
||||
gpointer data)
|
||||
{
|
||||
gboolean cancelled = handle->cancelled;
|
||||
GtkFileChooserEntry *chooser_entry = data;
|
||||
|
||||
if (handle != chooser_entry->load_folder_handle)
|
||||
goto out;
|
||||
|
||||
chooser_entry->load_folder_handle = NULL;
|
||||
|
||||
if (cancelled || error)
|
||||
goto out;
|
||||
|
||||
chooser_entry->current_folder = folder;
|
||||
g_signal_connect (chooser_entry->current_folder, "files-added",
|
||||
G_CALLBACK (files_added_cb), chooser_entry);
|
||||
g_signal_connect (chooser_entry->current_folder, "files-removed",
|
||||
G_CALLBACK (files_deleted_cb), chooser_entry);
|
||||
|
||||
chooser_entry->completion_store = gtk_list_store_new (N_COLUMNS,
|
||||
G_TYPE_STRING,
|
||||
GTK_TYPE_FILE_PATH);
|
||||
|
||||
gtk_entry_completion_set_model (gtk_entry_get_completion (GTK_ENTRY (chooser_entry)),
|
||||
GTK_TREE_MODEL (chooser_entry->completion_store));
|
||||
|
||||
out:
|
||||
g_object_unref (chooser_entry);
|
||||
g_object_unref (handle);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
load_directory_callback (GtkFileChooserEntry *chooser_entry)
|
||||
{
|
||||
@ -623,38 +682,15 @@ load_directory_callback (GtkFileChooserEntry *chooser_entry)
|
||||
g_assert (chooser_entry->completion_store == NULL);
|
||||
|
||||
/* Load the folder */
|
||||
chooser_entry->current_folder = gtk_file_system_get_folder (chooser_entry->file_system,
|
||||
chooser_entry->current_folder_path,
|
||||
GTK_FILE_INFO_DISPLAY_NAME | GTK_FILE_INFO_IS_FOLDER,
|
||||
NULL); /* NULL-GError */
|
||||
if (chooser_entry->load_folder_handle)
|
||||
gtk_file_system_cancel_operation (chooser_entry->load_folder_handle);
|
||||
|
||||
/* There is no folder by that name */
|
||||
if (!chooser_entry->current_folder)
|
||||
goto done;
|
||||
g_signal_connect (chooser_entry->current_folder, "files-added",
|
||||
G_CALLBACK (files_added_cb), chooser_entry);
|
||||
g_signal_connect (chooser_entry->current_folder, "files-removed",
|
||||
G_CALLBACK (files_deleted_cb), chooser_entry);
|
||||
|
||||
chooser_entry->completion_store = gtk_list_store_new (N_COLUMNS,
|
||||
G_TYPE_STRING,
|
||||
GTK_TYPE_FILE_PATH);
|
||||
|
||||
if (chooser_entry->file_part_pos != -1)
|
||||
{
|
||||
gtk_file_folder_list_children (chooser_entry->current_folder,
|
||||
&child_paths,
|
||||
NULL); /* NULL-GError */
|
||||
if (child_paths)
|
||||
{
|
||||
update_current_folder_files (chooser_entry, child_paths);
|
||||
add_completion_idle (chooser_entry);
|
||||
gtk_file_paths_free (child_paths);
|
||||
}
|
||||
}
|
||||
|
||||
gtk_entry_completion_set_model (gtk_entry_get_completion (GTK_ENTRY (chooser_entry)),
|
||||
GTK_TREE_MODEL (chooser_entry->completion_store));
|
||||
chooser_entry->load_folder_handle =
|
||||
gtk_file_system_get_folder (chooser_entry->file_system,
|
||||
chooser_entry->current_folder_path,
|
||||
GTK_FILE_INFO_DISPLAY_NAME | GTK_FILE_INFO_IS_FOLDER,
|
||||
load_directory_get_folder_callback,
|
||||
g_object_ref (chooser_entry));
|
||||
|
||||
done:
|
||||
|
||||
@ -1041,5 +1077,27 @@ _gtk_file_chooser_entry_get_action (GtkFileChooserEntry *chooser_entry)
|
||||
return chooser_entry->action;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gtk_file_chooser_entry_get_is_folder (GtkFileChooserEntry *chooser_entry,
|
||||
const GtkFilePath *path)
|
||||
{
|
||||
gboolean retval = FALSE;
|
||||
|
||||
if (chooser_entry->current_folder)
|
||||
{
|
||||
GtkFileInfo *file_info;
|
||||
|
||||
file_info = gtk_file_folder_get_info (chooser_entry->current_folder,
|
||||
path, NULL);
|
||||
if (file_info)
|
||||
{
|
||||
retval = gtk_file_info_get_is_folder (file_info);
|
||||
gtk_file_info_free (file_info);
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
#define __GTK_FILE_CHOOSER_ENTRY_C__
|
||||
#include "gtkaliasdef.c"
|
||||
|
@ -46,6 +46,8 @@ void _gtk_file_chooser_entry_set_file_part (GtkFileChooserEnt
|
||||
const gchar *file_part);
|
||||
const GtkFilePath *_gtk_file_chooser_entry_get_current_folder (GtkFileChooserEntry *chooser_entry);
|
||||
const gchar * _gtk_file_chooser_entry_get_file_part (GtkFileChooserEntry *chooser_entry);
|
||||
gboolean _gtk_file_chooser_entry_get_is_folder (GtkFileChooserEntry *chooser_entry,
|
||||
const GtkFilePath *path);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
@ -113,6 +113,7 @@ struct _GtkFileChooserDialogPrivate
|
||||
gint default_height;
|
||||
gboolean resize_horizontally;
|
||||
gboolean resize_vertically;
|
||||
gboolean response_requested;
|
||||
};
|
||||
|
||||
|
||||
@ -187,6 +188,17 @@ struct _GtkFileChooserDefault
|
||||
|
||||
GtkTreeModelSort *sort_model;
|
||||
|
||||
/* Handles */
|
||||
GSList *loading_shortcuts;
|
||||
GSList *reload_icon_handles;
|
||||
GtkFileSystemHandle *file_list_drag_data_received_handle;
|
||||
GtkFileSystemHandle *update_current_folder_handle;
|
||||
GtkFileSystemHandle *show_and_select_paths_handle;
|
||||
GtkFileSystemHandle *should_respond_get_info_handle;
|
||||
GtkFileSystemHandle *update_from_entry_handle;
|
||||
GtkFileSystemHandle *shortcuts_activate_iter_handle;
|
||||
GSList *pending_handles;
|
||||
|
||||
LoadState load_state;
|
||||
ReloadState reload_state;
|
||||
guint load_timeout_id;
|
||||
@ -267,9 +279,10 @@ struct _GtkFileSystemModel
|
||||
|
||||
GSList *idle_clears;
|
||||
GSource *idle_clear_source;
|
||||
GSource *idle_finished_loading_source;
|
||||
|
||||
gushort max_depth;
|
||||
|
||||
GSList *pending_handles;
|
||||
|
||||
guint show_hidden : 1;
|
||||
guint show_folders : 1;
|
||||
@ -300,6 +313,7 @@ struct _FileModelNode
|
||||
guint is_visible : 1;
|
||||
guint loaded : 1;
|
||||
guint idle_clear : 1;
|
||||
guint load_pending : 1;
|
||||
};
|
||||
|
||||
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "gtkmodules.h"
|
||||
#include "gtkintl.h"
|
||||
#include "gtkalias.h"
|
||||
#include "gtkstock.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
@ -35,6 +36,7 @@ struct _GtkFileInfo
|
||||
gchar *display_name;
|
||||
gchar *display_key;
|
||||
gchar *mime_type;
|
||||
gchar *icon_name;
|
||||
guint is_folder : 1;
|
||||
guint is_hidden : 1;
|
||||
};
|
||||
@ -88,6 +90,10 @@ gtk_file_info_copy (GtkFileInfo *info)
|
||||
new_info->display_key = g_strdup (new_info->display_key);
|
||||
if (new_info->mime_type)
|
||||
new_info->mime_type = g_strdup (new_info->mime_type);
|
||||
if (new_info->icon_name)
|
||||
new_info->icon_name = g_strdup (new_info->icon_name);
|
||||
if (new_info->display_key)
|
||||
new_info->display_key = g_strdup (new_info->display_key);
|
||||
|
||||
return new_info;
|
||||
}
|
||||
@ -103,6 +109,8 @@ gtk_file_info_free (GtkFileInfo *info)
|
||||
g_free (info->mime_type);
|
||||
if (info->display_key)
|
||||
g_free (info->display_key);
|
||||
if (info->icon_name)
|
||||
g_free (info->icon_name);
|
||||
|
||||
g_free (info);
|
||||
}
|
||||
@ -250,6 +258,171 @@ gtk_file_info_set_size (GtkFileInfo *info,
|
||||
info->size = size;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_file_info_set_icon_name (GtkFileInfo *info,
|
||||
const gchar *icon_name)
|
||||
{
|
||||
g_return_if_fail (info != NULL);
|
||||
|
||||
if (info->icon_name)
|
||||
g_free (info->icon_name);
|
||||
|
||||
info->icon_name = g_strdup (icon_name);
|
||||
}
|
||||
|
||||
G_CONST_RETURN gchar *
|
||||
gtk_file_info_get_icon_name (const GtkFileInfo *info)
|
||||
{
|
||||
g_return_val_if_fail (info != NULL, NULL);
|
||||
|
||||
return info->icon_name;
|
||||
}
|
||||
|
||||
GdkPixbuf *
|
||||
gtk_file_info_render_icon (const GtkFileInfo *info,
|
||||
GtkWidget *widget,
|
||||
gint pixel_size,
|
||||
GError **error)
|
||||
{
|
||||
GdkPixbuf *pixbuf = NULL;
|
||||
|
||||
g_return_val_if_fail (info != NULL, NULL);
|
||||
g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
|
||||
|
||||
if (info->icon_name)
|
||||
{
|
||||
if (g_path_is_absolute (info->icon_name))
|
||||
pixbuf = gdk_pixbuf_new_from_file_at_size (info->icon_name,
|
||||
pixel_size,
|
||||
pixel_size,
|
||||
NULL);
|
||||
else
|
||||
{
|
||||
GtkIconTheme *icon_theme;
|
||||
|
||||
icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (widget));
|
||||
pixbuf = gtk_icon_theme_load_icon (icon_theme, info->icon_name,
|
||||
pixel_size, 0, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if (!pixbuf)
|
||||
{
|
||||
/* load a fallback icon */
|
||||
pixbuf = gtk_widget_render_icon (widget, GTK_STOCK_FILE, GTK_ICON_SIZE_SMALL_TOOLBAR, NULL);
|
||||
if (!pixbuf && error)
|
||||
g_set_error (error,
|
||||
GTK_FILE_SYSTEM_ERROR,
|
||||
GTK_FILE_SYSTEM_ERROR_FAILED,
|
||||
_("Could not get a stock icon for %s\n"),
|
||||
info->icon_name);
|
||||
}
|
||||
|
||||
return pixbuf;
|
||||
}
|
||||
|
||||
/*****************************************
|
||||
* GtkFileSystemHandle *
|
||||
*****************************************/
|
||||
|
||||
static void gtk_file_system_handle_init (GtkFileSystemHandle *handle);
|
||||
static void gtk_file_system_handle_class_init (GtkFileSystemHandleClass *klass);
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_CANCELLED
|
||||
};
|
||||
|
||||
GType
|
||||
gtk_file_system_handle_get_type (void)
|
||||
{
|
||||
static GType file_system_handle_type = 0;
|
||||
|
||||
if (!file_system_handle_type)
|
||||
{
|
||||
static const GTypeInfo file_system_handle_info =
|
||||
{
|
||||
sizeof (GtkFileSystemHandleClass),
|
||||
NULL,
|
||||
NULL,
|
||||
(GClassInitFunc) gtk_file_system_handle_class_init,
|
||||
NULL,
|
||||
NULL,
|
||||
sizeof (GtkFileSystemHandle),
|
||||
0,
|
||||
(GInstanceInitFunc) gtk_file_system_handle_init,
|
||||
};
|
||||
|
||||
file_system_handle_type = g_type_register_static (G_TYPE_OBJECT,
|
||||
I_("GtkFileSystemHandle"),
|
||||
&file_system_handle_info, 0);
|
||||
}
|
||||
|
||||
return file_system_handle_type;
|
||||
}
|
||||
|
||||
#if 0
|
||||
GtkFileSystemHandle *
|
||||
gtk_file_system_handle_new (void)
|
||||
{
|
||||
return g_object_new (GTK_TYPE_FILE_SYSTEM_HANDLE, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
gtk_file_system_handle_init (GtkFileSystemHandle *handle)
|
||||
{
|
||||
handle->file_system = NULL;
|
||||
handle->cancelled = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_file_system_handle_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_file_system_handle_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GtkFileSystemHandle *handle = GTK_FILE_SYSTEM_HANDLE (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_CANCELLED:
|
||||
g_value_set_boolean (value, handle->cancelled);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_file_system_handle_class_init (GtkFileSystemHandleClass *klass)
|
||||
{
|
||||
GObjectClass *o_class;
|
||||
|
||||
o_class = (GObjectClass *)klass;
|
||||
o_class->set_property = gtk_file_system_handle_set_property;
|
||||
o_class->get_property = gtk_file_system_handle_get_property;
|
||||
|
||||
g_object_class_install_property (o_class,
|
||||
PROP_CANCELLED,
|
||||
g_param_spec_boolean ("cancelled",
|
||||
P_("Cancelled"),
|
||||
P_("Whether or not the operation has been successfully cancelled"),
|
||||
FALSE,
|
||||
G_PARAM_READABLE));
|
||||
}
|
||||
|
||||
/*****************************************
|
||||
* GtkFileSystem *
|
||||
@ -314,29 +487,53 @@ gtk_file_system_list_volumes (GtkFileSystem *file_system)
|
||||
return GTK_FILE_SYSTEM_GET_IFACE (file_system)->list_volumes (file_system);
|
||||
}
|
||||
|
||||
GtkFileFolder *
|
||||
gtk_file_system_get_folder (GtkFileSystem *file_system,
|
||||
const GtkFilePath *path,
|
||||
GtkFileInfoType types,
|
||||
GError **error)
|
||||
GtkFileSystemHandle *
|
||||
gtk_file_system_get_folder (GtkFileSystem *file_system,
|
||||
const GtkFilePath *path,
|
||||
GtkFileInfoType types,
|
||||
GtkFileSystemGetFolderCallback callback,
|
||||
gpointer data)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), NULL);
|
||||
g_return_val_if_fail (path != NULL, NULL);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
||||
g_return_val_if_fail (callback != NULL, NULL);
|
||||
|
||||
return GTK_FILE_SYSTEM_GET_IFACE (file_system)->get_folder (file_system, path, types, error);
|
||||
return GTK_FILE_SYSTEM_GET_IFACE (file_system)->get_folder (file_system, path, types, callback, data);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gtk_file_system_create_folder(GtkFileSystem *file_system,
|
||||
const GtkFilePath *path,
|
||||
GError **error)
|
||||
GtkFileSystemHandle *
|
||||
gtk_file_system_get_info (GtkFileSystem *file_system,
|
||||
const GtkFilePath *path,
|
||||
GtkFileInfoType types,
|
||||
GtkFileSystemGetInfoCallback callback,
|
||||
gpointer data)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), FALSE);
|
||||
g_return_val_if_fail (path != NULL, FALSE);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
||||
g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), NULL);
|
||||
g_return_val_if_fail (path != NULL, NULL);
|
||||
g_return_val_if_fail (callback != NULL, NULL);
|
||||
|
||||
return GTK_FILE_SYSTEM_GET_IFACE (file_system)->create_folder (file_system, path, error);
|
||||
return GTK_FILE_SYSTEM_GET_IFACE (file_system)->get_info (file_system, path, types, callback, data);
|
||||
}
|
||||
|
||||
GtkFileSystemHandle *
|
||||
gtk_file_system_create_folder (GtkFileSystem *file_system,
|
||||
const GtkFilePath *path,
|
||||
GtkFileSystemCreateFolderCallback callback,
|
||||
gpointer data)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), NULL);
|
||||
g_return_val_if_fail (path != NULL, NULL);
|
||||
g_return_val_if_fail (callback != NULL, NULL);
|
||||
|
||||
return GTK_FILE_SYSTEM_GET_IFACE (file_system)->create_folder (file_system, path, callback, data);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_file_system_cancel_operation (GtkFileSystemHandle *handle)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_FILE_SYSTEM_HANDLE (handle));
|
||||
|
||||
return GTK_FILE_SYSTEM_GET_IFACE (handle->file_system)->cancel_operation (handle);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -432,16 +629,18 @@ gtk_file_system_volume_get_is_mounted (GtkFileSystem *file_system,
|
||||
*
|
||||
* Return value: TRUE if the @volume was mounted successfully, FALSE otherwise.
|
||||
**/
|
||||
gboolean
|
||||
gtk_file_system_volume_mount (GtkFileSystem *file_system,
|
||||
GtkFileSystemVolume *volume,
|
||||
GError **error)
|
||||
/* FIXME XXX: update documentation above */
|
||||
GtkFileSystemHandle *
|
||||
gtk_file_system_volume_mount (GtkFileSystem *file_system,
|
||||
GtkFileSystemVolume *volume,
|
||||
GtkFileSystemVolumeMountCallback callback,
|
||||
gpointer data)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), FALSE);
|
||||
g_return_val_if_fail (volume != NULL, FALSE);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
||||
g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), NULL);
|
||||
g_return_val_if_fail (volume != NULL, NULL);
|
||||
g_return_val_if_fail (callback != NULL, NULL);
|
||||
|
||||
return GTK_FILE_SYSTEM_GET_IFACE (file_system)->volume_mount (file_system, volume, error);
|
||||
return GTK_FILE_SYSTEM_GET_IFACE (file_system)->volume_mount (file_system, volume, callback, data);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -485,17 +684,53 @@ gtk_file_system_volume_render_icon (GtkFileSystem *file_system,
|
||||
gint pixel_size,
|
||||
GError **error)
|
||||
{
|
||||
gchar *icon_name;
|
||||
GdkPixbuf *pixbuf;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), NULL);
|
||||
g_return_val_if_fail (volume != NULL, NULL);
|
||||
g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
|
||||
g_return_val_if_fail (pixel_size > 0, NULL);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
||||
|
||||
return GTK_FILE_SYSTEM_GET_IFACE (file_system)->volume_render_icon (file_system,
|
||||
volume,
|
||||
widget,
|
||||
pixel_size,
|
||||
error);
|
||||
icon_name = gtk_file_system_volume_get_icon_name (file_system, volume,
|
||||
error);
|
||||
if (!icon_name)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_for_screen (gtk_widget_get_screen (widget)),
|
||||
icon_name, pixel_size, 0, NULL);
|
||||
g_free (icon_name);
|
||||
|
||||
return pixbuf;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_file_system_volume_get_icon_name:
|
||||
* @file_system: a #GtkFileSystem
|
||||
* @volume: a #GtkFileSystemVolume
|
||||
* @error: location to store error, or %NULL
|
||||
*
|
||||
* Gets an icon name suitable for a #GtkFileSystemVolume.
|
||||
*
|
||||
* Return value: An icon name which can be used for rendering an icon for
|
||||
* this volume, or %NULL if no icon name could be found. In the latter
|
||||
* case, the @error value will be set as appropriate.
|
||||
**/
|
||||
gchar *
|
||||
gtk_file_system_volume_get_icon_name (GtkFileSystem *file_system,
|
||||
GtkFileSystemVolume *volume,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), NULL);
|
||||
g_return_val_if_fail (volume != NULL, NULL);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
||||
|
||||
return GTK_FILE_SYSTEM_GET_IFACE (file_system)->volume_get_icon_name (file_system,
|
||||
volume,
|
||||
error);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -682,21 +917,6 @@ gtk_file_system_path_is_local (GtkFileSystem *file_system,
|
||||
return result;
|
||||
}
|
||||
|
||||
GdkPixbuf *
|
||||
gtk_file_system_render_icon (GtkFileSystem *file_system,
|
||||
const GtkFilePath *path,
|
||||
GtkWidget *widget,
|
||||
gint pixel_size,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), NULL);
|
||||
g_return_val_if_fail (path != NULL, NULL);
|
||||
g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
|
||||
g_return_val_if_fail (pixel_size > 0, NULL);
|
||||
|
||||
return GTK_FILE_SYSTEM_GET_IFACE (file_system)->render_icon (file_system, path, widget, pixel_size, error);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_file_system_insert_bookmark:
|
||||
* @file_system: a #GtkFileSystem
|
||||
|
@ -55,7 +55,8 @@ typedef enum {
|
||||
GTK_FILE_INFO_MIME_TYPE = 1 << 3,
|
||||
GTK_FILE_INFO_MODIFICATION_TIME = 1 << 4,
|
||||
GTK_FILE_INFO_SIZE = 1 << 5,
|
||||
GTK_FILE_INFO_ALL = (1 << 6) - 1
|
||||
GTK_FILE_INFO_ICON = 1 << 6,
|
||||
GTK_FILE_INFO_ALL = (1 << 7) - 1
|
||||
} GtkFileInfoType;
|
||||
|
||||
/* GError enumeration for GtkFileSystem
|
||||
@ -106,6 +107,43 @@ gint64 gtk_file_info_get_size (const GtkFileInfo *in
|
||||
void gtk_file_info_set_size (GtkFileInfo *info,
|
||||
gint64 size);
|
||||
|
||||
void gtk_file_info_set_icon_name (GtkFileInfo *info,
|
||||
const gchar *con_name);
|
||||
G_CONST_RETURN gchar *gtk_file_info_get_icon_name (const GtkFileInfo *info);
|
||||
GdkPixbuf *gtk_file_info_render_icon (const GtkFileInfo *info,
|
||||
GtkWidget *widget,
|
||||
gint pixel_size,
|
||||
GError **error);
|
||||
|
||||
/* GtkFileSystemHandle
|
||||
*/
|
||||
|
||||
#define GTK_TYPE_FILE_SYSTEM_HANDLE (gtk_file_system_handle_get_type ())
|
||||
#define GTK_FILE_SYSTEM_HANDLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_FILE_SYSTEM_HANDLE, GtkFileSystemHandle))
|
||||
#define GTK_IS_FILE_SYSTEM_HANDLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_FILE_SYSTEM_HANDLE))
|
||||
#define GTK_FILE_SYSTEM_HANDLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_FILE_SYSTEM_HANDLE, GtkFileSystemHandleUnixClass))
|
||||
#define GTK_IS_FILE_SYSTEM_HANDLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_FILE_SYSTEM_HANDLE))
|
||||
#define GTK_FILE_SYSTEM_HANDLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_FILE_SYSTEM_HANDLE, GtkFileSystemHandleClass))
|
||||
|
||||
typedef struct _GtkFileSystemHandle GtkFileSystemHandle;
|
||||
typedef struct _GtkFileSystemHandleClass GtkFileSystemHandleClass;
|
||||
|
||||
struct _GtkFileSystemHandle
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
GtkFileSystem *file_system;
|
||||
|
||||
guint cancelled : 1;
|
||||
};
|
||||
|
||||
struct _GtkFileSystemHandleClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
GType gtk_file_system_handle_get_type (void);
|
||||
|
||||
/* The base GtkFileSystem interface
|
||||
*/
|
||||
#define GTK_TYPE_FILE_SYSTEM (gtk_file_system_get_type ())
|
||||
@ -113,6 +151,29 @@ void gtk_file_info_set_size (GtkFileInfo *in
|
||||
#define GTK_IS_FILE_SYSTEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_FILE_SYSTEM))
|
||||
#define GTK_FILE_SYSTEM_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), GTK_TYPE_FILE_SYSTEM, GtkFileSystemIface))
|
||||
|
||||
/* Callbacks for the asynchronous GtkFileSystem operations
|
||||
*/
|
||||
|
||||
typedef void (* GtkFileSystemGetInfoCallback) (GtkFileSystemHandle *handle,
|
||||
const GtkFileInfo *file_info,
|
||||
const GError *error,
|
||||
gpointer data);
|
||||
typedef void (* GtkFileSystemGetFolderCallback) (GtkFileSystemHandle *handle,
|
||||
GtkFileFolder *folder,
|
||||
const GError *error,
|
||||
gpointer data);
|
||||
typedef void (* GtkFileSystemCreateFolderCallback) (GtkFileSystemHandle *handle,
|
||||
const GtkFilePath *path,
|
||||
const GError *error,
|
||||
gpointer data);
|
||||
typedef void (* GtkFileSystemVolumeMountCallback) (GtkFileSystemHandle *handle,
|
||||
GtkFileSystemVolume *volume,
|
||||
const GError *error,
|
||||
gpointer data);
|
||||
|
||||
/*
|
||||
*/
|
||||
|
||||
struct _GtkFileSystemIface
|
||||
{
|
||||
GTypeInterface base_iface;
|
||||
@ -123,13 +184,22 @@ struct _GtkFileSystemIface
|
||||
GtkFileSystemVolume * (*get_volume_for_path) (GtkFileSystem *file_system,
|
||||
const GtkFilePath *path);
|
||||
|
||||
GtkFileFolder * (*get_folder) (GtkFileSystem *file_system,
|
||||
const GtkFilePath *path,
|
||||
GtkFileInfoType types,
|
||||
GError **error);
|
||||
gboolean (*create_folder) (GtkFileSystem *file_system,
|
||||
const GtkFilePath *path,
|
||||
GError **error);
|
||||
GtkFileSystemHandle * (*get_folder) (GtkFileSystem *file_system,
|
||||
const GtkFilePath *path,
|
||||
GtkFileInfoType types,
|
||||
GtkFileSystemGetFolderCallback callback,
|
||||
gpointer data);
|
||||
GtkFileSystemHandle * (*get_info) (GtkFileSystem *file_system,
|
||||
const GtkFilePath *path,
|
||||
GtkFileInfoType types,
|
||||
GtkFileSystemGetInfoCallback callback,
|
||||
gpointer data);
|
||||
GtkFileSystemHandle * (*create_folder) (GtkFileSystem *file_system,
|
||||
const GtkFilePath *path,
|
||||
GtkFileSystemCreateFolderCallback callback,
|
||||
gpointer data);
|
||||
|
||||
void (*cancel_operation) (GtkFileSystemHandle *handle);
|
||||
|
||||
/* Volumes
|
||||
*/
|
||||
@ -139,15 +209,14 @@ struct _GtkFileSystemIface
|
||||
GtkFileSystemVolume *volume);
|
||||
gboolean (*volume_get_is_mounted) (GtkFileSystem *file_system,
|
||||
GtkFileSystemVolume *volume);
|
||||
gboolean (*volume_mount) (GtkFileSystem *file_system,
|
||||
GtkFileSystemVolume *volume,
|
||||
GError **error);
|
||||
char * (*volume_get_display_name) (GtkFileSystem *file_system,
|
||||
GtkFileSystemHandle * (*volume_mount) (GtkFileSystem *file_system,
|
||||
GtkFileSystemVolume *volume,
|
||||
GtkFileSystemVolumeMountCallback callback,
|
||||
gpointer data);
|
||||
char * (*volume_get_display_name) (GtkFileSystem *file_system,
|
||||
GtkFileSystemVolume *volume);
|
||||
GdkPixbuf * (*volume_render_icon) (GtkFileSystem *file_system,
|
||||
gchar * (*volume_get_icon_name) (GtkFileSystem *file_system,
|
||||
GtkFileSystemVolume *volume,
|
||||
GtkWidget *widget,
|
||||
gint pixel_size,
|
||||
GError **error);
|
||||
|
||||
/* Path Manipulation
|
||||
@ -175,14 +244,6 @@ struct _GtkFileSystemIface
|
||||
GtkFilePath *(*filename_to_path) (GtkFileSystem *file_system,
|
||||
const gchar *path);
|
||||
|
||||
/* Icons
|
||||
*/
|
||||
GdkPixbuf * (*render_icon) (GtkFileSystem *file_system,
|
||||
const GtkFilePath *path,
|
||||
GtkWidget *widget,
|
||||
gint pixel_size,
|
||||
GError **error);
|
||||
|
||||
/* Bookmarks
|
||||
*/
|
||||
gboolean (*insert_bookmark) (GtkFileSystem *file_system,
|
||||
@ -221,9 +282,10 @@ GtkFilePath * gtk_file_system_volume_get_base_path (GtkFileSystem
|
||||
GtkFileSystemVolume *volume);
|
||||
gboolean gtk_file_system_volume_get_is_mounted (GtkFileSystem *file_system,
|
||||
GtkFileSystemVolume *volume);
|
||||
gboolean gtk_file_system_volume_mount (GtkFileSystem *file_system,
|
||||
GtkFileSystemVolume *volume,
|
||||
GError **error);
|
||||
GtkFileSystemHandle *gtk_file_system_volume_mount (GtkFileSystem *file_system,
|
||||
GtkFileSystemVolume *volume,
|
||||
GtkFileSystemVolumeMountCallback callback,
|
||||
gpointer data);
|
||||
char * gtk_file_system_volume_get_display_name (GtkFileSystem *file_system,
|
||||
GtkFileSystemVolume *volume);
|
||||
GdkPixbuf * gtk_file_system_volume_render_icon (GtkFileSystem *file_system,
|
||||
@ -231,18 +293,29 @@ GdkPixbuf * gtk_file_system_volume_render_icon (GtkFileSystem
|
||||
GtkWidget *widget,
|
||||
gint pixel_size,
|
||||
GError **error);
|
||||
gchar * gtk_file_system_volume_get_icon_name (GtkFileSystem *file_system,
|
||||
GtkFileSystemVolume *volume,
|
||||
GError **error);
|
||||
|
||||
gboolean gtk_file_system_get_parent (GtkFileSystem *file_system,
|
||||
const GtkFilePath *path,
|
||||
GtkFilePath **parent,
|
||||
GError **error);
|
||||
GtkFileFolder *gtk_file_system_get_folder (GtkFileSystem *file_system,
|
||||
const GtkFilePath *path,
|
||||
GtkFileInfoType types,
|
||||
GError **error);
|
||||
gboolean gtk_file_system_create_folder (GtkFileSystem *file_system,
|
||||
const GtkFilePath *path,
|
||||
GError **error);
|
||||
GtkFileSystemHandle *gtk_file_system_get_folder (GtkFileSystem *file_system,
|
||||
const GtkFilePath *path,
|
||||
GtkFileInfoType types,
|
||||
GtkFileSystemGetFolderCallback callback,
|
||||
gpointer data);
|
||||
GtkFileSystemHandle *gtk_file_system_get_info (GtkFileSystem *file_system,
|
||||
const GtkFilePath *path,
|
||||
GtkFileInfoType types,
|
||||
GtkFileSystemGetInfoCallback callback,
|
||||
gpointer data);
|
||||
GtkFileSystemHandle *gtk_file_system_create_folder (GtkFileSystem *file_system,
|
||||
const GtkFilePath *path,
|
||||
GtkFileSystemCreateFolderCallback callback,
|
||||
gpointer data);
|
||||
void gtk_file_system_cancel_operation (GtkFileSystemHandle *handle);
|
||||
GtkFilePath * gtk_file_system_make_path (GtkFileSystem *file_system,
|
||||
const GtkFilePath *base_path,
|
||||
const gchar *display_name,
|
||||
@ -266,12 +339,6 @@ GtkFilePath *gtk_file_system_filename_to_path (GtkFileSystem *file_system,
|
||||
gboolean gtk_file_system_path_is_local (GtkFileSystem *filesystem,
|
||||
const GtkFilePath *path);
|
||||
|
||||
GdkPixbuf *gtk_file_system_render_icon (GtkFileSystem *file_system,
|
||||
const GtkFilePath *path,
|
||||
GtkWidget *widget,
|
||||
gint pixel_size,
|
||||
GError **error);
|
||||
|
||||
gboolean gtk_file_system_insert_bookmark (GtkFileSystem *file_system,
|
||||
const GtkFilePath *path,
|
||||
gint position,
|
||||
|
@ -50,6 +50,7 @@ static void gtk_file_system_model_class_init (GtkFileSystemModelClass *class);
|
||||
static void gtk_file_system_model_iface_init (GtkTreeModelIface *iface);
|
||||
static void gtk_file_system_model_init (GtkFileSystemModel *model);
|
||||
static void gtk_file_system_model_finalize (GObject *object);
|
||||
static void gtk_file_system_model_dispose (GObject *object);
|
||||
|
||||
static void drag_source_iface_init (GtkTreeDragSourceIface *iface);
|
||||
|
||||
@ -205,6 +206,7 @@ gtk_file_system_model_class_init (GtkFileSystemModelClass *class)
|
||||
parent_class = g_type_class_peek_parent (class);
|
||||
|
||||
gobject_class->finalize = gtk_file_system_model_finalize;
|
||||
gobject_class->dispose = gtk_file_system_model_dispose;
|
||||
|
||||
file_system_model_signals[FINISHED_LOADING] =
|
||||
g_signal_new (I_("finished-loading"),
|
||||
@ -258,9 +260,6 @@ gtk_file_system_model_finalize (GObject *object)
|
||||
if (model->file_system)
|
||||
g_object_unref (model->file_system);
|
||||
|
||||
if (model->idle_finished_loading_source)
|
||||
g_source_destroy (model->idle_finished_loading_source);
|
||||
|
||||
children = model->roots;
|
||||
while (children)
|
||||
{
|
||||
@ -272,6 +271,25 @@ gtk_file_system_model_finalize (GObject *object)
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
gtk_file_system_model_dispose (GObject *object)
|
||||
{
|
||||
GtkFileSystemModel *model = GTK_FILE_SYSTEM_MODEL (object);
|
||||
|
||||
if (model->pending_handles)
|
||||
{
|
||||
GSList *l;
|
||||
|
||||
for (l = model->pending_handles; l; l = l->next)
|
||||
gtk_file_system_cancel_operation (l->data);
|
||||
g_slist_free (model->pending_handles);
|
||||
model->pending_handles = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
drag_source_iface_init (GtkTreeDragSourceIface *iface)
|
||||
{
|
||||
@ -630,33 +648,75 @@ root_folder_finished_loading_cb (GtkFileFolder *folder,
|
||||
g_signal_emit (model, file_system_model_signals[FINISHED_LOADING], 0);
|
||||
}
|
||||
|
||||
/* Emits the "finished-loading" signal as an idle handler; see the comment in
|
||||
* _gtk_file_system_model_new()
|
||||
*/
|
||||
static gboolean
|
||||
idle_finished_loading_cb (GtkFileSystemModel *model)
|
||||
{
|
||||
GDK_THREADS_ENTER ();
|
||||
|
||||
g_signal_emit (model, file_system_model_signals[FINISHED_LOADING], 0);
|
||||
|
||||
g_source_destroy (model->idle_finished_loading_source);
|
||||
model->idle_finished_loading_source = NULL;
|
||||
|
||||
GDK_THREADS_LEAVE ();
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Queues an idle handler to emit the "finished-loading" signal */
|
||||
static void
|
||||
queue_finished_loading (GtkFileSystemModel *model)
|
||||
got_root_folder_cb (GtkFileSystemHandle *handle,
|
||||
GtkFileFolder *folder,
|
||||
const GError *error,
|
||||
gpointer data)
|
||||
{
|
||||
model->idle_finished_loading_source = g_idle_source_new ();
|
||||
g_source_set_closure (model->idle_finished_loading_source,
|
||||
g_cclosure_new_object (G_CALLBACK (idle_finished_loading_cb),
|
||||
G_OBJECT (model)));
|
||||
g_source_attach (model->idle_finished_loading_source, NULL);
|
||||
GSList *roots = NULL;
|
||||
GSList *tmp_list;
|
||||
gboolean cancelled = handle->cancelled;
|
||||
GtkFileSystemModel *model = data;
|
||||
|
||||
tmp_list = g_slist_find (model->pending_handles, handle);
|
||||
if (!tmp_list)
|
||||
goto out;
|
||||
|
||||
model->pending_handles = g_slist_remove_link (model->pending_handles,
|
||||
tmp_list);
|
||||
|
||||
if (cancelled || !folder)
|
||||
goto out;
|
||||
|
||||
model->root_folder = folder;
|
||||
|
||||
if (gtk_file_folder_is_finished_loading (model->root_folder))
|
||||
g_signal_emit (model, file_system_model_signals[FINISHED_LOADING], 0);
|
||||
else
|
||||
g_signal_connect_object (model->root_folder, "finished-loading",
|
||||
G_CALLBACK (root_folder_finished_loading_cb), model, 0);
|
||||
|
||||
gtk_file_folder_list_children (model->root_folder, &roots, NULL);
|
||||
|
||||
g_signal_connect_object (model->root_folder, "deleted",
|
||||
G_CALLBACK (root_deleted_callback), model, 0);
|
||||
g_signal_connect_object (model->root_folder, "files-added",
|
||||
G_CALLBACK (root_files_added_callback), model, 0);
|
||||
g_signal_connect_object (model->root_folder, "files-changed",
|
||||
G_CALLBACK (root_files_changed_callback), model, 0);
|
||||
g_signal_connect_object (model->root_folder, "files-removed",
|
||||
G_CALLBACK (root_files_removed_callback), model, 0);
|
||||
|
||||
roots = gtk_file_paths_sort (roots);
|
||||
|
||||
for (tmp_list = roots; tmp_list; tmp_list = tmp_list->next)
|
||||
{
|
||||
FileModelNode *node = file_model_node_new (model, tmp_list->data);
|
||||
gtk_file_path_free (tmp_list->data);
|
||||
node->is_visible = file_model_node_is_visible (model, node);
|
||||
node->next = model->roots;
|
||||
node->depth = 0;
|
||||
model->roots = node;
|
||||
|
||||
if (node->is_visible)
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
GtkTreePath *path;
|
||||
|
||||
iter.user_data = node;
|
||||
path = gtk_tree_model_get_path (GTK_TREE_MODEL (model), &iter);
|
||||
gtk_tree_model_row_inserted (GTK_TREE_MODEL (model), path, &iter);
|
||||
gtk_tree_path_free (path);
|
||||
}
|
||||
}
|
||||
g_slist_free (roots);
|
||||
|
||||
model->roots = (FileModelNode *) g_slist_reverse ((GSList *)model->roots);
|
||||
|
||||
out:
|
||||
g_object_unref (model);
|
||||
g_object_unref (handle);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -691,28 +751,15 @@ _gtk_file_system_model_new (GtkFileSystem *file_system,
|
||||
GError **error)
|
||||
{
|
||||
GtkFileSystemModel *model;
|
||||
GtkFileFolder *root_folder;
|
||||
GSList *roots;
|
||||
GSList *tmp_list;
|
||||
GtkFileSystemHandle *handle;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), NULL);
|
||||
g_return_val_if_fail (root_path != NULL, NULL);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
||||
|
||||
/* First, try to load the folder */
|
||||
/* First, start loading the root folder */
|
||||
|
||||
types |= GTK_FILE_INFO_IS_FOLDER | GTK_FILE_INFO_IS_HIDDEN;
|
||||
|
||||
root_folder = gtk_file_system_get_folder (file_system, root_path, types, error);
|
||||
|
||||
if (!root_folder)
|
||||
return NULL;
|
||||
|
||||
if (!gtk_file_folder_list_children (root_folder, &roots, error))
|
||||
{
|
||||
g_object_unref (root_folder);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Then, actually create the model and the root nodes */
|
||||
|
||||
@ -724,39 +771,32 @@ _gtk_file_system_model_new (GtkFileSystem *file_system,
|
||||
model->max_depth = MIN (max_depth, G_MAXUSHORT);
|
||||
|
||||
model->types = types;
|
||||
model->root_folder = root_folder;
|
||||
model->root_folder = NULL;
|
||||
model->root_path = gtk_file_path_copy (root_path);
|
||||
|
||||
if (gtk_file_folder_is_finished_loading (model->root_folder))
|
||||
queue_finished_loading (model); /* done in an idle because we are being created */
|
||||
else
|
||||
g_signal_connect_object (model->root_folder, "finished-loading",
|
||||
G_CALLBACK (root_folder_finished_loading_cb), model, 0);
|
||||
model->roots = NULL;
|
||||
|
||||
g_signal_connect_object (model->root_folder, "deleted",
|
||||
G_CALLBACK (root_deleted_callback), model, 0);
|
||||
g_signal_connect_object (model->root_folder, "files-added",
|
||||
G_CALLBACK (root_files_added_callback), model, 0);
|
||||
g_signal_connect_object (model->root_folder, "files-changed",
|
||||
G_CALLBACK (root_files_changed_callback), model, 0);
|
||||
g_signal_connect_object (model->root_folder, "files-removed",
|
||||
G_CALLBACK (root_files_removed_callback), model, 0);
|
||||
|
||||
roots = gtk_file_paths_sort (roots);
|
||||
|
||||
for (tmp_list = roots; tmp_list; tmp_list = tmp_list->next)
|
||||
handle = gtk_file_system_get_folder (file_system, root_path, types,
|
||||
got_root_folder_cb,
|
||||
g_object_ref (model));
|
||||
if (!handle)
|
||||
{
|
||||
FileModelNode *node = file_model_node_new (model, tmp_list->data);
|
||||
gtk_file_path_free (tmp_list->data);
|
||||
node->is_visible = file_model_node_is_visible (model, node);
|
||||
node->next = model->roots;
|
||||
node->depth = 0;
|
||||
model->roots = node;
|
||||
}
|
||||
g_slist_free (roots);
|
||||
/* In this case got_root_folder_cb() will never be called, so we
|
||||
* need to unref model twice.
|
||||
*/
|
||||
g_object_unref (model);
|
||||
g_object_unref (model);
|
||||
|
||||
g_set_error (error,
|
||||
GTK_FILE_CHOOSER_ERROR,
|
||||
GTK_FILE_CHOOSER_ERROR_NONEXISTENT,
|
||||
_("Could not obtain root folder"));
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
model->pending_handles = g_slist_append (model->pending_handles, handle);
|
||||
|
||||
model->roots = (FileModelNode *) g_slist_reverse ((GSList *)model->roots);
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
@ -988,58 +1028,6 @@ find_child_node (GtkFileSystemModel *model,
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static FileModelNode *
|
||||
find_and_ref_path (GtkFileSystemModel *model,
|
||||
const GtkFilePath *path,
|
||||
GSList **cleanups)
|
||||
{
|
||||
GtkFilePath *parent_path;
|
||||
FileModelNode *parent_node;
|
||||
FileModelNode *child_node;
|
||||
GtkFileFolder *folder;
|
||||
|
||||
if (gtk_file_path_compare (path, model->root_path) == 0
|
||||
|| !gtk_file_system_get_parent (model->file_system, path, &parent_path, NULL))
|
||||
return NULL;
|
||||
|
||||
if (parent_path)
|
||||
{
|
||||
parent_node = find_and_ref_path (model, parent_path, cleanups);
|
||||
gtk_file_path_free (parent_path);
|
||||
}
|
||||
else
|
||||
parent_node = NULL;
|
||||
|
||||
child_node = find_child_node (model, parent_node, path);
|
||||
if (child_node)
|
||||
{
|
||||
file_model_node_ref (child_node);
|
||||
return child_node;
|
||||
}
|
||||
|
||||
folder = gtk_file_system_get_folder (model->file_system,
|
||||
path,
|
||||
model->types,
|
||||
NULL); /* NULL-GError */
|
||||
if (folder)
|
||||
{
|
||||
*cleanups = g_slist_prepend (*cleanups, folder);
|
||||
|
||||
child_node = find_child_node (model, parent_node, path);
|
||||
if (child_node)
|
||||
{
|
||||
file_model_node_ref (child_node);
|
||||
return child_node;
|
||||
}
|
||||
}
|
||||
|
||||
if (parent_node)
|
||||
unref_node_and_parents (model, parent_node);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* _gtk_file_system_model_set_filter:
|
||||
@ -1064,6 +1052,126 @@ _gtk_file_system_model_set_filter (GtkFileSystemModel *model,
|
||||
model_refilter_all (model);
|
||||
}
|
||||
|
||||
|
||||
struct RefPathData
|
||||
{
|
||||
GtkFileSystemModel *model;
|
||||
FileModelNode *node;
|
||||
FileModelNode *parent_node;
|
||||
GSList *paths;
|
||||
GSList *cleanups;
|
||||
GtkFileSystemModelPathFunc func;
|
||||
gpointer user_data;
|
||||
};
|
||||
|
||||
/* FIXME: maybe we have to wait on finished-loading? */
|
||||
static void
|
||||
ref_path_cb (GtkFileSystemHandle *handle,
|
||||
GtkFileFolder *folder,
|
||||
const GError *error,
|
||||
gpointer data)
|
||||
{
|
||||
struct RefPathData *info = data;
|
||||
gboolean cancelled = handle->cancelled;
|
||||
|
||||
if (!g_slist_find (info->model->pending_handles, handle))
|
||||
goto out;
|
||||
|
||||
info->model->pending_handles = g_slist_remove (info->model->pending_handles, handle);
|
||||
|
||||
/* Note that !folder means that the child node was already
|
||||
* found, without using get_folder.
|
||||
*/
|
||||
if (cancelled || error)
|
||||
goto out;
|
||||
|
||||
if (folder)
|
||||
info->cleanups = g_slist_prepend (info->cleanups, folder);
|
||||
else if (g_slist_length (info->paths) == 1
|
||||
&& gtk_file_path_compare (info->node->path, info->paths->data) == 0)
|
||||
{
|
||||
/* Done, now call the function */
|
||||
if (info->node)
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
GtkTreePath *path;
|
||||
|
||||
iter.user_data = info->node;
|
||||
path = gtk_tree_model_get_path (GTK_TREE_MODEL (info->model), &iter);
|
||||
|
||||
(* info->func) (info->model, path, &iter, info->user_data);
|
||||
|
||||
gtk_tree_path_free (path);
|
||||
}
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
||||
info->node = find_child_node (info->model, info->parent_node, info->paths->data);
|
||||
if (info->node)
|
||||
file_model_node_ref (info->node);
|
||||
else
|
||||
{
|
||||
goto out;
|
||||
}
|
||||
|
||||
gtk_file_path_free (info->paths->data);
|
||||
info->paths = g_slist_remove (info->paths, info->paths->data);
|
||||
|
||||
if (g_slist_length (info->paths) < 1)
|
||||
{
|
||||
/* Done, now call the function */
|
||||
if (info->node)
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
GtkTreePath *path;
|
||||
|
||||
iter.user_data = info->node;
|
||||
path = gtk_tree_model_get_path (GTK_TREE_MODEL (info->model), &iter);
|
||||
|
||||
(* info->func) (info->model, path, &iter, info->user_data);
|
||||
|
||||
gtk_tree_path_free (path);
|
||||
}
|
||||
|
||||
goto out;
|
||||
}
|
||||
else
|
||||
{
|
||||
info->parent_node = info->node;
|
||||
|
||||
if (info->parent_node->loaded)
|
||||
{
|
||||
info->node = find_child_node (info->model, info->parent_node, info->paths->data);
|
||||
ref_path_cb (NULL, NULL, NULL, info);
|
||||
}
|
||||
else
|
||||
{
|
||||
GtkFileSystemHandle *handle;
|
||||
|
||||
handle = gtk_file_system_get_folder (info->model->file_system,
|
||||
info->paths->data,
|
||||
info->model->types,
|
||||
ref_path_cb, data);
|
||||
info->model->pending_handles =
|
||||
g_slist_append (info->model->pending_handles, handle);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
out:
|
||||
if (info->node)
|
||||
unref_node_and_parents (info->model, info->node);
|
||||
gtk_file_paths_free (info->paths);
|
||||
g_slist_foreach (info->cleanups, (GFunc)g_object_unref, NULL);
|
||||
g_slist_free (info->cleanups);
|
||||
g_object_unref (info->model);
|
||||
g_free (info);
|
||||
|
||||
g_object_unref (handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* _gtk_file_system_model_path_do:
|
||||
* @model: a #GtkFileSystemModel
|
||||
@ -1090,33 +1198,90 @@ _gtk_file_system_model_set_filter (GtkFileSystemModel *model,
|
||||
* Return value: %TRUE if the path was successfully
|
||||
* found in @model and @func was called.
|
||||
**/
|
||||
gboolean
|
||||
_gtk_file_system_model_path_do (GtkFileSystemModel *model,
|
||||
const GtkFilePath *path,
|
||||
GtkFileSystemModelPathFunc func,
|
||||
gpointer user_data)
|
||||
void
|
||||
_gtk_file_system_model_path_do (GtkFileSystemModel *model,
|
||||
const GtkFilePath *path,
|
||||
GtkFileSystemModelPathFunc func,
|
||||
gpointer user_data)
|
||||
{
|
||||
GSList *cleanups = NULL;
|
||||
FileModelNode *node = find_and_ref_path (model, path, &cleanups);
|
||||
GtkFilePath *parent_path;
|
||||
GSList *paths = NULL;
|
||||
FileModelNode *node;
|
||||
struct RefPathData *info;
|
||||
|
||||
if (node)
|
||||
if (gtk_file_path_compare (path, model->root_path) == 0
|
||||
|| !gtk_file_system_get_parent (model->file_system, path, &parent_path, NULL))
|
||||
return;
|
||||
|
||||
paths = g_slist_prepend (paths, gtk_file_path_copy (path));
|
||||
while (gtk_file_path_compare (parent_path, model->root_path) != 0)
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
GtkTreePath *path;
|
||||
|
||||
iter.user_data = node;
|
||||
path = gtk_tree_model_get_path (GTK_TREE_MODEL (model), &iter);
|
||||
|
||||
(*func) (model, path, &iter, user_data);
|
||||
|
||||
gtk_tree_path_free (path);
|
||||
unref_node_and_parents (model, node);
|
||||
paths = g_slist_prepend (paths, parent_path);
|
||||
if (!gtk_file_system_get_parent (model->file_system, parent_path, &parent_path, NULL))
|
||||
{
|
||||
gtk_file_paths_free (paths);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
g_slist_foreach (cleanups, (GFunc)g_object_unref, NULL);
|
||||
g_slist_free (cleanups);
|
||||
if (g_slist_length (paths) < 1)
|
||||
return;
|
||||
|
||||
return node != NULL;
|
||||
/* Now we have all paths, except the root path */
|
||||
node = find_child_node (model, NULL, paths->data);
|
||||
if (!node)
|
||||
{
|
||||
gtk_file_paths_free (paths);
|
||||
return;
|
||||
}
|
||||
|
||||
file_model_node_ref (node);
|
||||
|
||||
gtk_file_path_free (paths->data);
|
||||
paths = g_slist_remove (paths, paths->data);
|
||||
|
||||
if (g_slist_length (paths) < 1)
|
||||
{
|
||||
/* Done, now call the function */
|
||||
if (node)
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
GtkTreePath *path;
|
||||
|
||||
iter.user_data = node;
|
||||
path = gtk_tree_model_get_path (GTK_TREE_MODEL (model), &iter);
|
||||
|
||||
(* func) (model, path, &iter, user_data);
|
||||
|
||||
gtk_tree_path_free (path);
|
||||
unref_node_and_parents (model, node);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
info = g_new0 (struct RefPathData, 1);
|
||||
info->paths = paths;
|
||||
info->model = g_object_ref (model);
|
||||
info->func = func;
|
||||
info->user_data = user_data;
|
||||
info->node = node;
|
||||
|
||||
if (info->node->loaded)
|
||||
{
|
||||
info->parent_node = info->node;
|
||||
info->node = find_child_node (model, info->parent_node, info->paths->data);
|
||||
ref_path_cb (NULL, NULL, NULL, info);
|
||||
}
|
||||
else
|
||||
{
|
||||
GtkFileSystemHandle *handle;
|
||||
|
||||
handle = gtk_file_system_get_folder (model->file_system,
|
||||
paths->data, model->types,
|
||||
ref_path_cb, info);
|
||||
model->pending_handles = g_slist_append (model->pending_handles, handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1389,6 +1554,114 @@ file_model_node_child_unref (FileModelNode *parent)
|
||||
file_model_node_idle_clear (parent);
|
||||
}
|
||||
|
||||
struct GetChildrenData
|
||||
{
|
||||
GtkFileSystemModel *model;
|
||||
FileModelNode *node;
|
||||
};
|
||||
|
||||
static void
|
||||
get_children_get_folder_cb (GtkFileSystemHandle *handle,
|
||||
GtkFileFolder *folder,
|
||||
const GError *error,
|
||||
gpointer callback_data)
|
||||
{
|
||||
GSList *child_paths, *tmp_list;
|
||||
gboolean has_children = FALSE;
|
||||
gboolean cancelled = handle->cancelled;
|
||||
struct GetChildrenData *data = callback_data;
|
||||
|
||||
tmp_list = g_slist_find (data->model->pending_handles, handle);
|
||||
|
||||
if (!tmp_list)
|
||||
goto out;
|
||||
|
||||
data->model->pending_handles = g_slist_remove_link (data->model->pending_handles, tmp_list);
|
||||
|
||||
if (cancelled || !folder)
|
||||
{
|
||||
/* error, no folder, remove dummy child */
|
||||
if (data->node->parent && data->node->parent->has_dummy)
|
||||
{
|
||||
data->node->parent->children = NULL;
|
||||
data->node->parent->has_dummy = FALSE;
|
||||
}
|
||||
|
||||
file_model_node_free (data->node);
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
||||
data->node->folder = folder;
|
||||
data->node->load_pending = FALSE;
|
||||
|
||||
if (gtk_file_folder_list_children (folder, &child_paths, NULL)) /* NULL-GError */
|
||||
{
|
||||
child_paths = gtk_file_paths_sort (child_paths);
|
||||
|
||||
for (tmp_list = child_paths; tmp_list; tmp_list = tmp_list->next)
|
||||
{
|
||||
FileModelNode *child_node = file_model_node_new (data->model, tmp_list->data);
|
||||
gtk_file_path_free (tmp_list->data);
|
||||
child_node->next = data->node->children;
|
||||
child_node->parent = data->node;
|
||||
child_node->depth = data->node->depth + 1;
|
||||
child_node->is_visible = file_model_node_is_visible (data->model, child_node);
|
||||
|
||||
if (child_node->is_visible)
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
GtkTreePath *path;
|
||||
|
||||
has_children = TRUE;
|
||||
|
||||
iter.user_data = child_node;
|
||||
path = gtk_tree_model_get_path (GTK_TREE_MODEL (data->model), &iter);
|
||||
gtk_tree_model_row_inserted (GTK_TREE_MODEL (data->model), path, &iter);
|
||||
gtk_tree_path_free (path);
|
||||
}
|
||||
|
||||
data->node->children = child_node;
|
||||
}
|
||||
g_slist_free (child_paths);
|
||||
}
|
||||
|
||||
data->node->children = (FileModelNode *)g_slist_reverse ((GSList *)data->node->children);
|
||||
|
||||
g_signal_connect (data->node->folder, "deleted",
|
||||
G_CALLBACK (deleted_callback), data->node);
|
||||
g_signal_connect (data->node->folder, "files-added",
|
||||
G_CALLBACK (files_added_callback), data->node);
|
||||
g_signal_connect (data->node->folder, "files-changed",
|
||||
G_CALLBACK (files_changed_callback), data->node);
|
||||
g_signal_connect (data->node->folder, "files-removed",
|
||||
G_CALLBACK (files_removed_callback), data->node);
|
||||
|
||||
data->node->loaded = TRUE;
|
||||
|
||||
if (!has_children)
|
||||
{
|
||||
/* The hard case ... we claimed this folder had children, but actually
|
||||
* it didn't. We have to add a dummy child, possibly to remove later.
|
||||
*/
|
||||
FileModelNode *child_node = file_model_node_new (data->model, NULL);
|
||||
child_node->is_visible = TRUE;
|
||||
child_node->parent = data->node;
|
||||
child_node->is_dummy = TRUE;
|
||||
|
||||
data->node->children = child_node;
|
||||
data->node->has_dummy = TRUE;
|
||||
}
|
||||
|
||||
g_object_set_data (G_OBJECT (data->node->folder), I_("model-node"), data->node);
|
||||
|
||||
out:
|
||||
g_object_unref (data->model);
|
||||
g_free (data);
|
||||
|
||||
g_object_unref (handle);
|
||||
}
|
||||
|
||||
static FileModelNode *
|
||||
file_model_node_get_children (GtkFileSystemModel *model,
|
||||
FileModelNode *node)
|
||||
@ -1396,7 +1669,7 @@ file_model_node_get_children (GtkFileSystemModel *model,
|
||||
if (node->ref_count == 0)
|
||||
return NULL;
|
||||
|
||||
if (!node->loaded)
|
||||
if (!node->loaded && !node->load_pending)
|
||||
{
|
||||
const GtkFileInfo *info = file_model_node_get_info (model, node);
|
||||
gboolean has_children = FALSE;
|
||||
@ -1405,48 +1678,25 @@ file_model_node_get_children (GtkFileSystemModel *model,
|
||||
file_model_node_idle_clear_cancel (node);
|
||||
|
||||
if (is_folder)
|
||||
node->folder = gtk_file_system_get_folder (model->file_system,
|
||||
node->path,
|
||||
model->types,
|
||||
NULL); /* NULL-GError */
|
||||
{
|
||||
struct GetChildrenData *data;
|
||||
GtkFileSystemHandle *handle;
|
||||
|
||||
if (node->folder)
|
||||
{
|
||||
GSList *child_paths, *tmp_list;
|
||||
|
||||
if (gtk_file_folder_list_children (node->folder, &child_paths, NULL)) /* NULL-GError */
|
||||
{
|
||||
child_paths = gtk_file_paths_sort (child_paths);
|
||||
data = g_new (struct GetChildrenData, 1);
|
||||
data->model = g_object_ref (model);
|
||||
data->node = node;
|
||||
|
||||
for (tmp_list = child_paths; tmp_list; tmp_list = tmp_list->next)
|
||||
{
|
||||
FileModelNode *child_node = file_model_node_new (model, tmp_list->data);
|
||||
gtk_file_path_free (tmp_list->data);
|
||||
child_node->next = node->children;
|
||||
child_node->parent = node;
|
||||
child_node->depth = node->depth + 1;
|
||||
child_node->is_visible = file_model_node_is_visible (model, child_node);
|
||||
if (child_node->is_visible)
|
||||
has_children = TRUE;
|
||||
node->children = child_node;
|
||||
}
|
||||
g_slist_free (child_paths);
|
||||
}
|
||||
handle =
|
||||
gtk_file_system_get_folder (model->file_system,
|
||||
node->path,
|
||||
model->types,
|
||||
get_children_get_folder_cb,
|
||||
data);
|
||||
|
||||
node->children = (FileModelNode *)g_slist_reverse ((GSList *)node->children);
|
||||
|
||||
g_signal_connect (node->folder, "deleted",
|
||||
G_CALLBACK (deleted_callback), node);
|
||||
g_signal_connect (node->folder, "files-added",
|
||||
G_CALLBACK (files_added_callback), node);
|
||||
g_signal_connect (node->folder, "files-changed",
|
||||
G_CALLBACK (files_changed_callback), node);
|
||||
g_signal_connect (node->folder, "files-removed",
|
||||
G_CALLBACK (files_removed_callback), node);
|
||||
|
||||
g_object_set_data (G_OBJECT (node->folder), I_("model-node"), node);
|
||||
model->pending_handles = g_slist_append (model->pending_handles, handle);
|
||||
node->load_pending = TRUE;
|
||||
}
|
||||
|
||||
|
||||
if (is_folder && !has_children)
|
||||
{
|
||||
/* The hard case ... we claimed this folder had children, but actually
|
||||
@ -1460,8 +1710,6 @@ file_model_node_get_children (GtkFileSystemModel *model,
|
||||
node->children = child_node;
|
||||
node->has_dummy = TRUE;
|
||||
}
|
||||
|
||||
node->loaded = TRUE;
|
||||
}
|
||||
|
||||
return node->children;
|
||||
|
@ -71,7 +71,7 @@ typedef void (*GtkFileSystemModelPathFunc) (GtkFileSystemModel *model,
|
||||
GtkTreeIter *iter,
|
||||
gpointer user_data);
|
||||
|
||||
gboolean _gtk_file_system_model_path_do (GtkFileSystemModel *model,
|
||||
void _gtk_file_system_model_path_do (GtkFileSystemModel *model,
|
||||
const GtkFilePath *path,
|
||||
GtkFileSystemModelPathFunc func,
|
||||
gpointer user_data);
|
||||
|
File diff suppressed because it is too large
Load Diff
387
gtk/gtkpathbar.c
387
gtk/gtkpathbar.c
@ -65,6 +65,7 @@ struct _ButtonData
|
||||
GtkFilePath *path;
|
||||
GtkWidget *image;
|
||||
GtkWidget *label;
|
||||
GtkFileSystemHandle *handle;
|
||||
guint ignore_changes : 1;
|
||||
guint file_is_hidden : 1;
|
||||
};
|
||||
@ -140,6 +141,8 @@ gtk_path_bar_init (GtkPathBar *path_bar)
|
||||
GTK_WIDGET_SET_FLAGS (path_bar, GTK_NO_WINDOW);
|
||||
gtk_widget_set_redraw_on_allocate (GTK_WIDGET (path_bar), FALSE);
|
||||
|
||||
path_bar->set_path_handle = NULL;
|
||||
|
||||
path_bar->spacing = 3;
|
||||
path_bar->up_slider_button = get_slider_button (path_bar, GTK_ARROW_LEFT);
|
||||
path_bar->down_slider_button = get_slider_button (path_bar, GTK_ARROW_RIGHT);
|
||||
@ -247,8 +250,13 @@ remove_settings_signal (GtkPathBar *path_bar,
|
||||
static void
|
||||
gtk_path_bar_dispose (GObject *object)
|
||||
{
|
||||
remove_settings_signal (GTK_PATH_BAR (object),
|
||||
gtk_widget_get_screen (GTK_WIDGET (object)));
|
||||
GtkPathBar *path_bar = GTK_PATH_BAR (object);
|
||||
|
||||
remove_settings_signal (path_bar, gtk_widget_get_screen (GTK_WIDGET (object)));
|
||||
|
||||
if (path_bar->set_path_handle)
|
||||
gtk_file_system_cancel_operation (path_bar->set_path_handle);
|
||||
path_bar->set_path_handle = NULL;
|
||||
|
||||
G_OBJECT_CLASS (gtk_path_bar_parent_class)->dispose (object);
|
||||
}
|
||||
@ -957,7 +965,11 @@ button_clicked_cb (GtkWidget *button,
|
||||
button_list = g_list_find (path_bar->button_list, button_data);
|
||||
g_assert (button_list != NULL);
|
||||
|
||||
g_signal_handlers_block_by_func (button,
|
||||
G_CALLBACK (button_clicked_cb), data);
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
|
||||
g_signal_handlers_unblock_by_func (button,
|
||||
G_CALLBACK (button_clicked_cb), data);
|
||||
|
||||
if (button_list->prev)
|
||||
{
|
||||
@ -977,22 +989,79 @@ button_clicked_cb (GtkWidget *button,
|
||||
button_data->path, child_path, child_is_hidden);
|
||||
}
|
||||
|
||||
static GdkPixbuf *
|
||||
get_button_image (GtkPathBar *path_bar,
|
||||
ButtonType button_type)
|
||||
struct SetButtonImageData
|
||||
{
|
||||
GtkPathBar *path_bar;
|
||||
ButtonData *button_data;
|
||||
};
|
||||
|
||||
static void
|
||||
set_button_image_get_info_cb (GtkFileSystemHandle *handle,
|
||||
const GtkFileInfo *info,
|
||||
const GError *error,
|
||||
gpointer user_data)
|
||||
{
|
||||
gboolean cancelled = handle->cancelled;
|
||||
GdkPixbuf *pixbuf;
|
||||
struct SetButtonImageData *data = user_data;
|
||||
|
||||
if (handle != data->button_data->handle)
|
||||
goto out;
|
||||
|
||||
data->button_data->handle = NULL;
|
||||
|
||||
if (cancelled || error)
|
||||
goto out;
|
||||
|
||||
pixbuf = gtk_file_info_render_icon (info, GTK_WIDGET (data->path_bar),
|
||||
data->path_bar->icon_size, NULL);
|
||||
gtk_image_set_from_pixbuf (GTK_IMAGE (data->button_data->image), pixbuf);
|
||||
|
||||
switch (data->button_data->type)
|
||||
{
|
||||
case HOME_BUTTON:
|
||||
if (data->path_bar->home_icon)
|
||||
g_object_unref (pixbuf);
|
||||
else
|
||||
data->path_bar->home_icon = pixbuf;
|
||||
break;
|
||||
|
||||
case DESKTOP_BUTTON:
|
||||
if (data->path_bar->desktop_icon)
|
||||
g_object_unref (pixbuf);
|
||||
else
|
||||
data->path_bar->desktop_icon = pixbuf;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
};
|
||||
|
||||
out:
|
||||
g_free (data);
|
||||
g_object_unref (handle);
|
||||
}
|
||||
|
||||
static void
|
||||
set_button_image (GtkPathBar *path_bar,
|
||||
ButtonData *button_data)
|
||||
{
|
||||
GtkFileSystemVolume *volume;
|
||||
struct SetButtonImageData *data;
|
||||
|
||||
switch (button_type)
|
||||
switch (button_data->type)
|
||||
{
|
||||
case ROOT_BUTTON:
|
||||
|
||||
if (path_bar->root_icon != NULL)
|
||||
return path_bar->root_icon;
|
||||
{
|
||||
gtk_image_set_from_pixbuf (GTK_IMAGE (button_data->image), path_bar->root_icon);
|
||||
break;
|
||||
}
|
||||
|
||||
volume = gtk_file_system_get_volume_for_path (path_bar->file_system, path_bar->root_path);
|
||||
if (volume == NULL)
|
||||
return NULL;
|
||||
return;
|
||||
|
||||
path_bar->root_icon = gtk_file_system_volume_render_icon (path_bar->file_system,
|
||||
volume,
|
||||
@ -1001,37 +1070,63 @@ get_button_image (GtkPathBar *path_bar,
|
||||
NULL);
|
||||
gtk_file_system_volume_free (path_bar->file_system, volume);
|
||||
|
||||
return path_bar->root_icon;
|
||||
gtk_image_set_from_pixbuf (GTK_IMAGE (button_data->image), path_bar->root_icon);
|
||||
break;
|
||||
|
||||
case HOME_BUTTON:
|
||||
if (path_bar->home_icon != NULL)
|
||||
return path_bar->home_icon;
|
||||
{
|
||||
gtk_image_set_from_pixbuf (GTK_IMAGE (button_data->image), path_bar->home_icon);
|
||||
break;
|
||||
}
|
||||
|
||||
data = g_new0 (struct SetButtonImageData, 1);
|
||||
data->path_bar = path_bar;
|
||||
data->button_data = button_data;
|
||||
|
||||
if (button_data->handle)
|
||||
gtk_file_system_cancel_operation (button_data->handle);
|
||||
|
||||
button_data->handle =
|
||||
gtk_file_system_get_info (path_bar->file_system,
|
||||
path_bar->home_path,
|
||||
GTK_FILE_INFO_ICON,
|
||||
set_button_image_get_info_cb,
|
||||
data);
|
||||
break;
|
||||
|
||||
path_bar->home_icon = gtk_file_system_render_icon (path_bar->file_system,
|
||||
path_bar->home_path,
|
||||
GTK_WIDGET (path_bar),
|
||||
path_bar->icon_size,
|
||||
NULL);
|
||||
return path_bar->home_icon;
|
||||
case DESKTOP_BUTTON:
|
||||
if (path_bar->desktop_icon != NULL)
|
||||
return path_bar->desktop_icon;
|
||||
{
|
||||
gtk_image_set_from_pixbuf (GTK_IMAGE (button_data->image), path_bar->desktop_icon);
|
||||
break;
|
||||
}
|
||||
|
||||
path_bar->desktop_icon = gtk_file_system_render_icon (path_bar->file_system,
|
||||
path_bar->desktop_path,
|
||||
GTK_WIDGET (path_bar),
|
||||
path_bar->icon_size,
|
||||
NULL);
|
||||
return path_bar->desktop_icon;
|
||||
data = g_new0 (struct SetButtonImageData, 1);
|
||||
data->path_bar = path_bar;
|
||||
data->button_data = button_data;
|
||||
|
||||
if (button_data->handle)
|
||||
gtk_file_system_cancel_operation (button_data->handle);
|
||||
|
||||
button_data->handle =
|
||||
gtk_file_system_get_info (path_bar->file_system,
|
||||
path_bar->desktop_path,
|
||||
GTK_FILE_INFO_ICON,
|
||||
set_button_image_get_info_cb,
|
||||
data);
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
button_data_free (ButtonData *button_data)
|
||||
{
|
||||
if (button_data->handle)
|
||||
gtk_file_system_cancel_operation (button_data->handle);
|
||||
|
||||
gtk_file_path_free (button_data->path);
|
||||
g_free (button_data->dir_name);
|
||||
g_free (button_data);
|
||||
@ -1094,9 +1189,7 @@ gtk_path_bar_update_button_appearance (GtkPathBar *path_bar,
|
||||
|
||||
if (button_data->image != NULL)
|
||||
{
|
||||
GdkPixbuf *pixbuf;
|
||||
pixbuf = get_button_image (path_bar, button_data->type);
|
||||
gtk_image_set_from_pixbuf (GTK_IMAGE (button_data->image), pixbuf);
|
||||
set_button_image (path_bar, button_data);
|
||||
}
|
||||
|
||||
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button_data->button)) != current_dir)
|
||||
@ -1294,17 +1387,136 @@ gtk_path_bar_check_parent_path (GtkPathBar *path_bar,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
struct SetPathInfo
|
||||
{
|
||||
GtkFilePath *path;
|
||||
GtkFilePath *parent_path;
|
||||
GtkPathBar *path_bar;
|
||||
GList *new_buttons;
|
||||
GList *fake_root;
|
||||
gboolean first_directory;
|
||||
};
|
||||
|
||||
static void
|
||||
gtk_path_bar_set_path_finish (struct SetPathInfo *info,
|
||||
gboolean result)
|
||||
{
|
||||
if (result)
|
||||
{
|
||||
GList *l;
|
||||
|
||||
gtk_path_bar_clear_buttons (info->path_bar);
|
||||
info->path_bar->button_list = g_list_reverse (info->new_buttons);
|
||||
info->path_bar->fake_root = info->fake_root;
|
||||
|
||||
for (l = info->path_bar->button_list; l; l = l->next)
|
||||
{
|
||||
GtkWidget *button = BUTTON_DATA (l->data)->button;
|
||||
gtk_container_add (GTK_CONTAINER (info->path_bar), button);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GList *l;
|
||||
|
||||
for (l = info->new_buttons; l; l = l->next)
|
||||
{
|
||||
ButtonData *button_data;
|
||||
|
||||
button_data = BUTTON_DATA (l->data);
|
||||
gtk_widget_destroy (button_data->button);
|
||||
}
|
||||
|
||||
g_list_free (info->new_buttons);
|
||||
}
|
||||
|
||||
if (info->path)
|
||||
gtk_file_path_free (info->path);
|
||||
if (info->parent_path)
|
||||
gtk_file_path_free (info->parent_path);
|
||||
g_free (info);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_path_bar_get_info_callback (GtkFileSystemHandle *handle,
|
||||
const GtkFileInfo *file_info,
|
||||
const GError *error,
|
||||
gpointer data)
|
||||
{
|
||||
gboolean cancelled = handle->cancelled;
|
||||
struct SetPathInfo *path_info = data;
|
||||
ButtonData *button_data;
|
||||
const gchar *display_name;
|
||||
gboolean is_hidden;
|
||||
gboolean valid;
|
||||
|
||||
if (handle != path_info->path_bar->set_path_handle)
|
||||
{
|
||||
gtk_path_bar_set_path_finish (path_info, FALSE);
|
||||
g_object_unref (handle);
|
||||
return;
|
||||
}
|
||||
|
||||
g_object_unref (handle);
|
||||
path_info->path_bar->set_path_handle = NULL;
|
||||
|
||||
if (cancelled || !file_info)
|
||||
{
|
||||
gtk_path_bar_set_path_finish (path_info, FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
display_name = gtk_file_info_get_display_name (file_info);
|
||||
is_hidden = gtk_file_info_get_is_hidden (file_info);
|
||||
|
||||
gtk_widget_push_composite_child ();
|
||||
button_data = make_directory_button (path_info->path_bar, display_name,
|
||||
path_info->path,
|
||||
path_info->first_directory, is_hidden);
|
||||
gtk_widget_pop_composite_child ();
|
||||
gtk_file_path_free (path_info->path);
|
||||
|
||||
path_info->new_buttons = g_list_prepend (path_info->new_buttons, button_data);
|
||||
|
||||
if (BUTTON_IS_FAKE_ROOT (button_data))
|
||||
path_info->fake_root = path_info->new_buttons;
|
||||
|
||||
path_info->path = path_info->parent_path;
|
||||
path_info->first_directory = FALSE;
|
||||
|
||||
if (!path_info->path)
|
||||
{
|
||||
gtk_path_bar_set_path_finish (path_info, TRUE);
|
||||
return;
|
||||
}
|
||||
|
||||
valid = gtk_file_system_get_parent (path_info->path_bar->file_system,
|
||||
path_info->path,
|
||||
&path_info->parent_path,
|
||||
NULL);
|
||||
if (!valid)
|
||||
{
|
||||
gtk_path_bar_set_path_finish (path_info, FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
path_info->path_bar->set_path_handle =
|
||||
gtk_file_system_get_info (handle->file_system,
|
||||
path_info->path,
|
||||
GTK_FILE_INFO_DISPLAY_NAME | GTK_FILE_INFO_IS_HIDDEN,
|
||||
gtk_path_bar_get_info_callback,
|
||||
path_info);
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gtk_path_bar_set_path (GtkPathBar *path_bar,
|
||||
const GtkFilePath *file_path,
|
||||
const gboolean keep_trail,
|
||||
GError **error)
|
||||
{
|
||||
GtkFilePath *path;
|
||||
gboolean first_directory = TRUE;
|
||||
struct SetPathInfo *info;
|
||||
gboolean result;
|
||||
GList *new_buttons = NULL;
|
||||
GList *fake_root = NULL;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_PATH_BAR (path_bar), FALSE);
|
||||
g_return_val_if_fail (file_path != NULL, FALSE);
|
||||
@ -1318,102 +1530,31 @@ _gtk_path_bar_set_path (GtkPathBar *path_bar,
|
||||
gtk_path_bar_check_parent_path (path_bar, file_path, path_bar->file_system))
|
||||
return TRUE;
|
||||
|
||||
path = gtk_file_path_copy (file_path);
|
||||
info = g_new0 (struct SetPathInfo, 1);
|
||||
info->path = gtk_file_path_copy (file_path);
|
||||
info->path_bar = path_bar;
|
||||
info->first_directory = TRUE;
|
||||
|
||||
gtk_widget_push_composite_child ();
|
||||
|
||||
while (path != NULL)
|
||||
result = gtk_file_system_get_parent (path_bar->file_system,
|
||||
info->path, &info->parent_path, error);
|
||||
if (!result)
|
||||
{
|
||||
GtkFilePath *parent_path = NULL;
|
||||
ButtonData *button_data;
|
||||
const gchar *display_name;
|
||||
gboolean is_hidden;
|
||||
GtkFileFolder *file_folder;
|
||||
GtkFileInfo *file_info;
|
||||
gboolean valid;
|
||||
|
||||
valid = gtk_file_system_get_parent (path_bar->file_system,
|
||||
path,
|
||||
&parent_path,
|
||||
error);
|
||||
if (!valid)
|
||||
{
|
||||
result = FALSE;
|
||||
gtk_file_path_free (path);
|
||||
break;
|
||||
}
|
||||
|
||||
file_folder = gtk_file_system_get_folder (path_bar->file_system,
|
||||
parent_path ? parent_path : path,
|
||||
GTK_FILE_INFO_DISPLAY_NAME | GTK_FILE_INFO_IS_HIDDEN,
|
||||
NULL);
|
||||
if (!file_folder)
|
||||
{
|
||||
result = FALSE;
|
||||
gtk_file_path_free (parent_path);
|
||||
gtk_file_path_free (path);
|
||||
break;
|
||||
}
|
||||
|
||||
file_info = gtk_file_folder_get_info (file_folder, parent_path ? path : NULL, error);
|
||||
g_object_unref (file_folder);
|
||||
|
||||
if (!file_info)
|
||||
{
|
||||
result = FALSE;
|
||||
gtk_file_path_free (parent_path);
|
||||
gtk_file_path_free (path);
|
||||
break;
|
||||
}
|
||||
|
||||
display_name = gtk_file_info_get_display_name (file_info);
|
||||
is_hidden = gtk_file_info_get_is_hidden (file_info);
|
||||
|
||||
button_data = make_directory_button (path_bar, display_name, path, first_directory, is_hidden);
|
||||
gtk_file_info_free (file_info);
|
||||
gtk_file_path_free (path);
|
||||
|
||||
new_buttons = g_list_prepend (new_buttons, button_data);
|
||||
|
||||
if (BUTTON_IS_FAKE_ROOT (button_data))
|
||||
fake_root = new_buttons;
|
||||
|
||||
path = parent_path;
|
||||
first_directory = FALSE;
|
||||
gtk_file_path_free (info->path);
|
||||
g_free (info);
|
||||
return result;
|
||||
}
|
||||
|
||||
if (result)
|
||||
{
|
||||
GList *l;
|
||||
if (path_bar->set_path_handle)
|
||||
gtk_file_system_cancel_operation (path_bar->set_path_handle);
|
||||
|
||||
gtk_path_bar_clear_buttons (path_bar);
|
||||
path_bar->button_list = g_list_reverse (new_buttons);
|
||||
path_bar->fake_root = fake_root;
|
||||
path_bar->set_path_handle =
|
||||
gtk_file_system_get_info (path_bar->file_system,
|
||||
info->path,
|
||||
GTK_FILE_INFO_DISPLAY_NAME | GTK_FILE_INFO_IS_HIDDEN,
|
||||
gtk_path_bar_get_info_callback,
|
||||
info);
|
||||
|
||||
for (l = path_bar->button_list; l; l = l->next)
|
||||
{
|
||||
GtkWidget *button = BUTTON_DATA (l->data)->button;
|
||||
gtk_container_add (GTK_CONTAINER (path_bar), button);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GList *l;
|
||||
|
||||
for (l = new_buttons; l; l = l->next)
|
||||
{
|
||||
ButtonData *button_data;
|
||||
|
||||
button_data = BUTTON_DATA (l->data);
|
||||
gtk_widget_destroy (button_data->button);
|
||||
}
|
||||
|
||||
g_list_free (new_buttons);
|
||||
}
|
||||
|
||||
gtk_widget_pop_composite_child ();
|
||||
|
||||
return result;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* FIXME: This should be a construct-only property */
|
||||
|
@ -45,6 +45,8 @@ struct _GtkPathBar
|
||||
GtkFilePath *home_path;
|
||||
GtkFilePath *desktop_path;
|
||||
|
||||
GtkFileSystemHandle *set_path_handle;
|
||||
|
||||
GdkPixbuf *root_icon;
|
||||
GdkPixbuf *home_icon;
|
||||
GdkPixbuf *desktop_icon;
|
||||
|
Loading…
Reference in New Issue
Block a user