From e377ea5e61171e57f9e892652d0fd1f77953eda8 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Mon, 27 Apr 2009 14:53:18 -0400 Subject: =?UTF-8?q?Bug=20516933=20=E2=80=93=20Rewrite=20attachment=20UI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rewrite the attachment UI to better utilize GIO and also to migrate from GnomeIconList to GtkIconView. This also introduces a "List View" option similar to Nautilus, as well as the EAttachmentHandler framework for extending attachment handling (may eventually replace EMFormatHook). This commit also fixes a number of secondary attachment bugs: Bug 311609 – new attachment bar should use regular gtk+ expander Bug 314923 – Drag and Drop in attachment window is inconsistent and requires additional click Bug 338179 – attachment saving ... Bug 350364 – Action to get info about attachments Bug 383047 – Viewing mail attachments Bug 427235 – Can't copy attachment mime type string Bug 454091 – Cannot save multiple attachments who have the same name Bug 494629 – Rethink composer's attachment UI Bug 553970 – Evolution ignores umask when saving attachments Bug 577375 – mailto: and attach doesn't URL un-escape --- widgets/misc/e-attachment-handler-image.c | 280 ++++++++++++++++++++++++++++++ 1 file changed, 280 insertions(+) create mode 100644 widgets/misc/e-attachment-handler-image.c (limited to 'widgets/misc/e-attachment-handler-image.c') diff --git a/widgets/misc/e-attachment-handler-image.c b/widgets/misc/e-attachment-handler-image.c new file mode 100644 index 0000000000..ba5f8d759c --- /dev/null +++ b/widgets/misc/e-attachment-handler-image.c @@ -0,0 +1,280 @@ +/* + * e-attachment-handler-image.c + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#include "e-attachment-handler-image.h" + +#include +#include + +#define E_ATTACHMENT_HANDLER_IMAGE_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_ATTACHMENT_HANDLER_IMAGE, EAttachmentHandlerImagePrivate)) + +struct _EAttachmentHandlerImagePrivate { + gint placeholder; +}; + +static gpointer parent_class; + +static const gchar *ui = +"" +" " +" " +" " +" " +" " +""; + +static void +action_image_set_as_background_saved_cb (EAttachment *attachment, + GAsyncResult *result, + EAttachmentHandler *handler) +{ + EAttachmentView *view; + GConfClient *client; + GtkWidget *dialog; + GFile *file; + const gchar *key; + gpointer parent; + gchar *value; + GError *error = NULL; + + client = gconf_client_get_default (); + view = e_attachment_handler_get_view (handler); + + file = e_attachment_save_finish (attachment, result, &error); + + if (error != NULL) + goto error; + + value = g_file_get_path (file); + g_object_unref (file); + + key = "/desktop/gnome/background/picture_filename"; + gconf_client_set_string (client, key, value, &error); + g_free (value); + + if (error != NULL) + goto error; + + /* Ignore errors for this part. */ + key = "/desktop/gnome/background/picture_options"; + value = gconf_client_get_string (client, key, NULL); + if (g_strcmp0 (value, "none") == 0) + gconf_client_set_string (client, key, "wallpaper", NULL); + g_free (value); + + goto exit; + +error: + parent = gtk_widget_get_toplevel (GTK_WIDGET (view)); + parent = GTK_WIDGET_TOPLEVEL (parent) ? parent : NULL; + + dialog = gtk_message_dialog_new_with_markup ( + parent, GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, + "%s", + _("Could not set as background")); + + gtk_message_dialog_format_secondary_text ( + GTK_MESSAGE_DIALOG (dialog), "%s", error->message); + + gtk_dialog_run (GTK_DIALOG (dialog)); + + gtk_widget_destroy (dialog); + g_error_free (error); + +exit: + g_object_unref (client); + g_object_unref (handler); +} + +static void +action_image_set_as_background_cb (GtkAction *action, + EAttachmentHandler *handler) +{ + EAttachmentView *view; + EAttachment *attachment; + GFile *destination; + GList *selected; + gchar *path; + + view = e_attachment_handler_get_view (handler); + selected = e_attachment_view_get_selected_attachments (view); + g_return_if_fail (g_list_length (selected) == 1); + attachment = E_ATTACHMENT (selected->data); + + /* Save the image under ~/.gnome2/wallpapers/. */ + path = g_build_filename ( + g_get_home_dir (), ".gnome2", "wallpapers", NULL); + destination = g_file_new_for_path (path); + g_mkdir_with_parents (path, 0755); + g_free (path); + + e_attachment_save_async ( + attachment, destination, (GAsyncReadyCallback) + action_image_set_as_background_saved_cb, + g_object_ref (handler)); + + g_object_unref (destination); + + g_list_foreach (selected, (GFunc) g_object_unref, NULL); + g_list_free (selected); +} + +static GtkActionEntry standard_entries[] = { + + { "image-set-as-background", + NULL, + N_("Set as _Background"), + NULL, + NULL, /* XXX Add a tooltip! */ + G_CALLBACK (action_image_set_as_background_cb) } +}; + +static void +attachment_handler_image_update_actions_cb (EAttachmentView *view, + EAttachmentHandler *handler) +{ + EAttachmentHandlerImagePrivate *priv; + EAttachment *attachment; + GFileInfo *file_info; + GtkActionGroup *action_group; + const gchar *content_type; + gchar *mime_type; + GList *selected; + gboolean visible = FALSE; + + priv = E_ATTACHMENT_HANDLER_IMAGE_GET_PRIVATE (handler); + + selected = e_attachment_view_get_selected_attachments (view); + + if (g_list_length (selected) != 1) + goto exit; + + attachment = E_ATTACHMENT (selected->data); + file_info = e_attachment_get_file_info (attachment); + + if (file_info == NULL) + goto exit; + + if (e_attachment_get_loading (attachment)) + goto exit; + + if (e_attachment_get_saving (attachment)) + goto exit; + + content_type = g_file_info_get_content_type (file_info); + + mime_type = g_content_type_get_mime_type (content_type); + visible = (g_ascii_strncasecmp (mime_type, "image/", 6) == 0); + g_free (mime_type); + +exit: + action_group = e_attachment_view_get_action_group (view, "image"); + gtk_action_group_set_visible (action_group, visible); + + g_list_foreach (selected, (GFunc) g_object_unref, NULL); + g_list_free (selected); +} + +static void +attachment_handler_image_constructed (GObject *object) +{ + EAttachmentHandlerImagePrivate *priv; + EAttachmentHandler *handler; + EAttachmentView *view; + GtkActionGroup *action_group; + GtkUIManager *ui_manager; + GError *error = NULL; + + handler = E_ATTACHMENT_HANDLER (object); + priv = E_ATTACHMENT_HANDLER_IMAGE_GET_PRIVATE (object); + + /* Chain up to parent's constructed() method. */ + G_OBJECT_CLASS (parent_class)->constructed (object); + + view = e_attachment_handler_get_view (handler); + + action_group = e_attachment_view_add_action_group (view, "image"); + gtk_action_group_add_actions ( + action_group, standard_entries, + G_N_ELEMENTS (standard_entries), object); + + ui_manager = e_attachment_view_get_ui_manager (view); + gtk_ui_manager_add_ui_from_string (ui_manager, ui, -1, &error); + + if (error != NULL) { + g_warning ("%s", error->message); + g_error_free (error); + } + + g_signal_connect ( + view, "update-actions", + G_CALLBACK (attachment_handler_image_update_actions_cb), + object); +} + +static void +attachment_handler_image_class_init (EAttachmentHandlerImageClass *class) +{ + GObjectClass *object_class; + + parent_class = g_type_class_peek_parent (class); + g_type_class_add_private (class, sizeof (EAttachmentHandlerImagePrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->constructed = attachment_handler_image_constructed; +} + +static void +attachment_handler_image_init (EAttachmentHandlerImage *handler) +{ + handler->priv = E_ATTACHMENT_HANDLER_IMAGE_GET_PRIVATE (handler); +} + +GType +e_attachment_handler_image_get_type (void) +{ + static GType type = 0; + + if (G_UNLIKELY (type == 0)) { + static const GTypeInfo type_info = { + sizeof (EAttachmentHandlerImageClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) attachment_handler_image_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ + sizeof (EAttachmentHandlerImage), + 0, /* n_preallocs */ + (GInstanceInitFunc) attachment_handler_image_init, + NULL /* value_table */ + }; + + type = g_type_register_static ( + E_TYPE_ATTACHMENT_HANDLER, + "EAttachmentHandlerImage", + &type_info, 0); + } + + return type; +} -- cgit v1.2.3