diff options
author | Kristian Rietveld <kris@imendio.com> | 2006-05-01 21:41:12 +0000 |
---|---|---|
committer | Kristian Rietveld <kristian@src.gnome.org> | 2006-05-01 21:41:12 +0000 |
commit | 2c97a8f6e8f260695515dabcb5185d0603dcd4f3 (patch) | |
tree | 68a070f95b168f8415fc6a438aa5436a9096716d /gtk/gtkpathbar.c | |
parent | 46789c877d6b4f73ca267bc78f31337be30ad889 (diff) | |
download | gdk-pixbuf-2c97a8f6e8f260695515dabcb5185d0603dcd4f3.tar.gz |
Merge of the GTK+ asynchronous file chooser branch. Please see theAFTER_KRIS_ASYNC_BRANCH_MERGE
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.
Diffstat (limited to 'gtk/gtkpathbar.c')
-rw-r--r-- | gtk/gtkpathbar.c | 387 |
1 files changed, 264 insertions, 123 deletions
diff --git a/gtk/gtkpathbar.c b/gtk/gtkpathbar.c index ec62d32d3..2688c1ee3 100644 --- a/gtk/gtkpathbar.c +++ b/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; - - 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; + { + 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; + case DESKTOP_BUTTON: if (path_bar->desktop_icon != NULL) - return path_bar->desktop_icon; - - 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; + { + gtk_image_set_from_pixbuf (GTK_IMAGE (button_data->image), path_bar->desktop_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->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,126 +1387,174 @@ gtk_path_bar_check_parent_path (GtkPathBar *path_bar, return FALSE; } -gboolean -_gtk_path_bar_set_path (GtkPathBar *path_bar, - const GtkFilePath *file_path, - const gboolean keep_trail, - GError **error) + +struct SetPathInfo { GtkFilePath *path; - gboolean first_directory = TRUE; - 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); - - result = TRUE; - - /* Check whether the new path is already present in the pathbar as buttons. - * This could be a parent directory or a previous selected subdirectory. - */ - if (keep_trail && - gtk_path_bar_check_parent_path (path_bar, file_path, path_bar->file_system)) - return TRUE; + GtkFilePath *parent_path; + GtkPathBar *path_bar; + GList *new_buttons; + GList *fake_root; + gboolean first_directory; +}; - path = gtk_file_path_copy (file_path); +static void +gtk_path_bar_set_path_finish (struct SetPathInfo *info, + gboolean result) +{ + if (result) + { + GList *l; - gtk_widget_push_composite_child (); + 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; - while (path != NULL) - { - 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) + for (l = info->path_bar->button_list; l; l = l->next) { - result = FALSE; - gtk_file_path_free (path); - break; + GtkWidget *button = BUTTON_DATA (l->data)->button; + gtk_container_add (GTK_CONTAINER (info->path_bar), button); } + } + else + { + GList *l; - 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) + for (l = info->new_buttons; l; l = l->next) { - 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); + ButtonData *button_data; - if (!file_info) - { - result = FALSE; - gtk_file_path_free (parent_path); - gtk_file_path_free (path); - break; + button_data = BUTTON_DATA (l->data); + gtk_widget_destroy (button_data->button); } - 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); + g_list_free (info->new_buttons); + } - new_buttons = g_list_prepend (new_buttons, button_data); + if (info->path) + gtk_file_path_free (info->path); + if (info->parent_path) + gtk_file_path_free (info->parent_path); + g_free (info); +} - if (BUTTON_IS_FAKE_ROOT (button_data)) - fake_root = new_buttons; +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; - path = parent_path; - first_directory = FALSE; + if (handle != path_info->path_bar->set_path_handle) + { + gtk_path_bar_set_path_finish (path_info, FALSE); + g_object_unref (handle); + return; } - if (result) + g_object_unref (handle); + path_info->path_bar->set_path_handle = NULL; + + if (cancelled || !file_info) { - GList *l; + gtk_path_bar_set_path_finish (path_info, FALSE); + return; + } - gtk_path_bar_clear_buttons (path_bar); - path_bar->button_list = g_list_reverse (new_buttons); - path_bar->fake_root = fake_root; + display_name = gtk_file_info_get_display_name (file_info); + is_hidden = gtk_file_info_get_is_hidden (file_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); - } + 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; } - else + + valid = gtk_file_system_get_parent (path_info->path_bar->file_system, + path_info->path, + &path_info->parent_path, + NULL); + if (!valid) { - GList *l; + gtk_path_bar_set_path_finish (path_info, FALSE); + return; + } - for (l = new_buttons; l; l = l->next) - { - ButtonData *button_data; + 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); +} - button_data = BUTTON_DATA (l->data); - gtk_widget_destroy (button_data->button); - } +gboolean +_gtk_path_bar_set_path (GtkPathBar *path_bar, + const GtkFilePath *file_path, + const gboolean keep_trail, + GError **error) +{ + struct SetPathInfo *info; + gboolean result; + + g_return_val_if_fail (GTK_IS_PATH_BAR (path_bar), FALSE); + g_return_val_if_fail (file_path != NULL, FALSE); + + result = TRUE; + + /* Check whether the new path is already present in the pathbar as buttons. + * This could be a parent directory or a previous selected subdirectory. + */ + if (keep_trail && + gtk_path_bar_check_parent_path (path_bar, file_path, path_bar->file_system)) + return TRUE; - g_list_free (new_buttons); + info = g_new0 (struct SetPathInfo, 1); + info->path = gtk_file_path_copy (file_path); + info->path_bar = path_bar; + info->first_directory = TRUE; + + result = gtk_file_system_get_parent (path_bar->file_system, + info->path, &info->parent_path, error); + if (!result) + { + gtk_file_path_free (info->path); + g_free (info); + return result; } - gtk_widget_pop_composite_child (); + if (path_bar->set_path_handle) + gtk_file_system_cancel_operation (path_bar->set_path_handle); + + 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); - return result; + return TRUE; } /* FIXME: This should be a construct-only property */ |