1 /*
2  * e-attachment-handler-image.c
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms of the GNU Lesser General Public License as published by
6  * the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
11  * for more details.
12  *
13  * You should have received a copy of the GNU Lesser General Public License
14  * along with this program; if not, see <http://www.gnu.org/licenses/>.
15  *
16  *
17  * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
18  *
19  */
20 
21 #include "evolution-config.h"
22 
23 #include "e-attachment-handler-image.h"
24 
25 #include <glib/gi18n.h>
26 #include <gdesktop-enums.h>
27 
28 #include "e-misc-utils.h"
29 
30 #define E_ATTACHMENT_HANDLER_IMAGE_GET_PRIVATE(obj) \
31 	(G_TYPE_INSTANCE_GET_PRIVATE \
32 	((obj), E_TYPE_ATTACHMENT_HANDLER_IMAGE, EAttachmentHandlerImagePrivate))
33 
34 struct _EAttachmentHandlerImagePrivate {
35 	gint placeholder;
36 };
37 
38 static const gchar *ui =
39 "<ui>"
40 "  <popup name='context'>"
41 "    <placeholder name='custom-actions'>"
42 "      <menuitem action='image-set-as-background'/>"
43 "    </placeholder>"
44 "  </popup>"
45 "</ui>";
46 
G_DEFINE_TYPE(EAttachmentHandlerImage,e_attachment_handler_image,E_TYPE_ATTACHMENT_HANDLER)47 G_DEFINE_TYPE (
48 	EAttachmentHandlerImage,
49 	e_attachment_handler_image,
50 	E_TYPE_ATTACHMENT_HANDLER)
51 
52 static void
53 action_image_set_as_background_saved_cb (EAttachment *attachment,
54                                          GAsyncResult *result,
55                                          EAttachmentHandler *handler)
56 {
57 	GDesktopBackgroundStyle style;
58 	EAttachmentView *view;
59 	GSettings *settings;
60 	GtkWidget *dialog;
61 	GFile *file;
62 	gpointer parent;
63 	gchar *uri;
64 	GError *error = NULL;
65 
66 	view = e_attachment_handler_get_view (handler);
67 	settings = e_util_ref_settings ("org.gnome.desktop.background");
68 
69 	file = e_attachment_save_finish (attachment, result, &error);
70 
71 	if (error != NULL)
72 		goto error;
73 
74 	uri = g_file_get_uri (file);
75 	g_settings_set_string (settings, "picture-uri", uri);
76 	g_free (uri);
77 
78 	style = g_settings_get_enum (settings, "picture-options");
79 	if (style == G_DESKTOP_BACKGROUND_STYLE_NONE)
80 		g_settings_set_enum (
81 			settings, "picture-options",
82 			G_DESKTOP_BACKGROUND_STYLE_WALLPAPER);
83 
84 	g_object_unref (file);
85 
86 	goto exit;
87 
88 error:
89 	parent = gtk_widget_get_toplevel (GTK_WIDGET (view));
90 	parent = gtk_widget_is_toplevel (parent) ? parent : NULL;
91 
92 	dialog = gtk_message_dialog_new_with_markup (
93 		parent, GTK_DIALOG_DESTROY_WITH_PARENT,
94 		GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,
95 		"<big><b>%s</b></big>",
96 		_("Could not set as background"));
97 
98 	gtk_message_dialog_format_secondary_text (
99 		GTK_MESSAGE_DIALOG (dialog), "%s", error->message);
100 
101 	gtk_dialog_run (GTK_DIALOG (dialog));
102 
103 	gtk_widget_destroy (dialog);
104 	g_error_free (error);
105 
106 exit:
107 	g_object_unref (settings);
108 	g_object_unref (handler);
109 }
110 
111 static void
action_image_set_as_background_cb(GtkAction * action,EAttachmentHandler * handler)112 action_image_set_as_background_cb (GtkAction *action,
113                                    EAttachmentHandler *handler)
114 {
115 	EAttachmentView *view;
116 	EAttachment *attachment;
117 	GFile *destination;
118 	GList *selected;
119 	const gchar *path;
120 
121 	view = e_attachment_handler_get_view (handler);
122 	selected = e_attachment_view_get_selected_attachments (view);
123 	g_return_if_fail (g_list_length (selected) == 1);
124 	attachment = E_ATTACHMENT (selected->data);
125 
126 	/* Save the image under the user's Pictures directory. */
127 	path = g_get_user_special_dir (G_USER_DIRECTORY_PICTURES);
128 	destination = g_file_new_for_path (path);
129 	g_mkdir_with_parents (path, 0755);
130 
131 	e_attachment_save_async (
132 		attachment, destination, (GAsyncReadyCallback)
133 		action_image_set_as_background_saved_cb,
134 		g_object_ref (handler));
135 
136 	g_object_unref (destination);
137 
138 	g_list_foreach (selected, (GFunc) g_object_unref, NULL);
139 	g_list_free (selected);
140 }
141 
142 static GtkActionEntry standard_entries[] = {
143 
144 	{ "image-set-as-background",
145 	  NULL,
146 	  N_("Set as _Background"),
147 	  NULL,
148 	  NULL,  /* XXX Add a tooltip! */
149 	  G_CALLBACK (action_image_set_as_background_cb) }
150 };
151 
152 static void
attachment_handler_image_update_actions_cb(EAttachmentView * view,EAttachmentHandler * handler)153 attachment_handler_image_update_actions_cb (EAttachmentView *view,
154                                             EAttachmentHandler *handler)
155 {
156 	EAttachment *attachment;
157 	GtkActionGroup *action_group;
158 	gchar *mime_type;
159 	GList *selected;
160 	gboolean visible = FALSE;
161 
162 	selected = e_attachment_view_get_selected_attachments (view);
163 
164 	if (g_list_length (selected) != 1)
165 		goto exit;
166 
167 	attachment = E_ATTACHMENT (selected->data);
168 
169 	if (e_attachment_get_loading (attachment))
170 		goto exit;
171 
172 	if (e_attachment_get_saving (attachment))
173 		goto exit;
174 
175 	mime_type = e_attachment_dup_mime_type (attachment);
176 	visible =
177 		(mime_type != NULL) &&
178 		(g_ascii_strncasecmp (mime_type, "image/", 6) == 0);
179 	g_free (mime_type);
180 
181 exit:
182 	action_group = e_attachment_view_get_action_group (view, "image");
183 	gtk_action_group_set_visible (action_group, visible);
184 
185 	g_list_foreach (selected, (GFunc) g_object_unref, NULL);
186 	g_list_free (selected);
187 }
188 
189 static void
attachment_handler_image_constructed(GObject * object)190 attachment_handler_image_constructed (GObject *object)
191 {
192 	EAttachmentHandler *handler;
193 	EAttachmentView *view;
194 	GtkActionGroup *action_group;
195 	GtkUIManager *ui_manager;
196 	GError *error = NULL;
197 
198 	handler = E_ATTACHMENT_HANDLER (object);
199 
200 	/* Chain up to parent's constructed() method. */
201 	G_OBJECT_CLASS (e_attachment_handler_image_parent_class)->constructed (object);
202 
203 	view = e_attachment_handler_get_view (handler);
204 
205 	action_group = e_attachment_view_add_action_group (view, "image");
206 	gtk_action_group_add_actions (
207 		action_group, standard_entries,
208 		G_N_ELEMENTS (standard_entries), object);
209 
210 	ui_manager = e_attachment_view_get_ui_manager (view);
211 	gtk_ui_manager_add_ui_from_string (ui_manager, ui, -1, &error);
212 
213 	if (error != NULL) {
214 		g_warning ("%s", error->message);
215 		g_error_free (error);
216 	}
217 
218 	g_signal_connect (
219 		view, "update-actions",
220 		G_CALLBACK (attachment_handler_image_update_actions_cb),
221 		object);
222 }
223 
224 static void
e_attachment_handler_image_class_init(EAttachmentHandlerImageClass * class)225 e_attachment_handler_image_class_init (EAttachmentHandlerImageClass *class)
226 {
227 	GObjectClass *object_class;
228 
229 	g_type_class_add_private (class, sizeof (EAttachmentHandlerImagePrivate));
230 
231 	object_class = G_OBJECT_CLASS (class);
232 	object_class->constructed = attachment_handler_image_constructed;
233 }
234 
235 static void
e_attachment_handler_image_init(EAttachmentHandlerImage * handler)236 e_attachment_handler_image_init (EAttachmentHandlerImage *handler)
237 {
238 	handler->priv = E_ATTACHMENT_HANDLER_IMAGE_GET_PRIVATE (handler);
239 }
240