2007-08-27 [colin] 2.10.0cvs179
[claws.git] / src / image_viewer.c
blobbc2eec55e778f5c13d1773b534b7f1a795bceef8
1 /*
2 * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3 * Copyright (C) 1999-2007 Hiroyuki Yamamoto and the Claws Mail team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #ifdef HAVE_CONFIG_H
21 # include "config.h"
22 #endif
24 #include <glib.h>
25 #include <glib/gi18n.h>
26 #include <gtk/gtkscrolledwindow.h>
27 #include <gtk/gtkpixmap.h>
29 #include "procmime.h"
30 #include "utils.h"
31 #include "mimeview.h"
33 #include "prefs_common.h"
35 typedef struct _ImageViewer ImageViewer;
37 MimeViewerFactory image_viewer_factory;
38 void image_viewer_get_resized_size(gint w, gint h, gint aw, gint ah,
39 gint * sw, gint * sh);
40 static void image_viewer_clear_viewer(MimeViewer *imageviewer);
41 static void scrolledwin_resize_cb(GtkWidget *scrolledwin, GtkAllocation *alloc,
42 ImageViewer *imageviewer);
43 struct _ImageViewer
45 MimeViewer mimeviewer;
47 gchar *file;
48 MimeInfo *mimeinfo;
49 gboolean resize_img;
51 GtkWidget *scrolledwin;
52 GtkWidget *image;
53 GtkWidget *notebook;
54 GtkWidget *filename;
55 GtkWidget *filesize;
56 GtkWidget *content_type;
59 static GtkWidget *image_viewer_get_widget(MimeViewer *_mimeviewer)
61 ImageViewer *imageviewer = (ImageViewer *) _mimeviewer;
63 debug_print("image_viewer_get_widget\n");
65 return imageviewer->notebook;
68 static void image_viewer_load_file(ImageViewer *imageviewer, const gchar *imgfile)
70 GdkPixbuf *pixbuf;
71 gint avail_width;
72 gint avail_height;
73 GError *error = NULL;
75 debug_print("image_viewer_show_mimepart\n");
77 if (!imageviewer->resize_img) {
78 pixbuf = gdk_pixbuf_new_from_file(imgfile, &error);
79 } else {
80 gint w, h;
81 gdk_pixbuf_get_file_info(imgfile, &w, &h);
82 avail_width = imageviewer->notebook->parent->allocation.width;
83 avail_height = imageviewer->notebook->parent->allocation.height;
84 if (avail_width > 8) avail_width -= 8;
85 if (avail_height > 8) avail_height -= 8;
86 if (avail_width - 100 > 0 &&
87 (w > avail_width || h > avail_height))
88 pixbuf = gdk_pixbuf_new_from_file_at_scale(imgfile, avail_width,
89 avail_height, TRUE, &error);
90 else
91 pixbuf = gdk_pixbuf_new_from_file(imgfile, &error);
94 if (error) {
95 g_warning(error->message);
96 g_error_free(error);
98 if (!pixbuf) {
99 g_warning("Can't load the image.");
100 return;
103 if (!imageviewer->image) {
104 imageviewer->image = gtk_image_new();
106 gtk_scrolled_window_add_with_viewport
107 (GTK_SCROLLED_WINDOW(imageviewer->scrolledwin),
108 imageviewer->image);
111 g_signal_handlers_block_by_func(G_OBJECT(imageviewer->scrolledwin),
112 G_CALLBACK(scrolledwin_resize_cb), imageviewer);
114 gtk_image_set_from_pixbuf(GTK_IMAGE(imageviewer->image), pixbuf);
116 gtk_widget_show(imageviewer->image);
117 GTK_EVENTS_FLUSH();
118 g_signal_handlers_unblock_by_func(G_OBJECT(imageviewer->scrolledwin),
119 G_CALLBACK(scrolledwin_resize_cb), imageviewer);
121 g_object_unref(pixbuf);
124 static void image_viewer_set_notebook_page(MimeViewer *_mimeviewer)
126 ImageViewer *imageviewer = (ImageViewer *) _mimeviewer;
128 if (!prefs_common.display_img)
129 gtk_notebook_set_current_page(GTK_NOTEBOOK(imageviewer->notebook), 0);
130 else
131 gtk_notebook_set_current_page(GTK_NOTEBOOK(imageviewer->notebook), 1);
134 static void image_viewer_load_image(ImageViewer *imageviewer)
136 gchar *imgfile;
138 if (imageviewer->mimeinfo == NULL)
139 return;
141 imgfile = procmime_get_tmp_file_name(imageviewer->mimeinfo);
142 if (procmime_get_part(imgfile, imageviewer->mimeinfo) < 0) {
143 g_warning("Can't get mimepart file");
144 g_free(imgfile);
145 return;
147 image_viewer_load_file(imageviewer, imgfile);
148 g_unlink(imgfile);
149 g_free(imgfile);
152 static void image_viewer_show_mimepart(MimeViewer *_mimeviewer, const gchar *file, MimeInfo *mimeinfo)
154 ImageViewer *imageviewer = (ImageViewer *) _mimeviewer;
156 image_viewer_clear_viewer(_mimeviewer);
157 g_free(imageviewer->file);
158 imageviewer->file = g_strdup(file);
159 imageviewer->mimeinfo = mimeinfo;
161 if (prefs_common.display_img)
162 image_viewer_load_image(imageviewer);
163 else {
164 gtk_label_set_text(GTK_LABEL(imageviewer->filename),
165 procmime_mimeinfo_get_parameter(mimeinfo, "name"));
166 gtk_label_set_text(GTK_LABEL(imageviewer->filesize), to_human_readable(mimeinfo->length));
167 gtk_label_set_text(GTK_LABEL(imageviewer->content_type), mimeinfo->subtype);
171 static void image_viewer_clear_viewer(MimeViewer *_mimeviewer)
173 ImageViewer *imageviewer = (ImageViewer *) _mimeviewer;
174 GtkAdjustment *hadj, *vadj;
176 debug_print("image_viewer_clear_viewer\n");
178 image_viewer_set_notebook_page(_mimeviewer);
180 if (imageviewer->image != NULL) {
181 gtk_widget_destroy(imageviewer->image);
182 imageviewer->image = NULL;
185 if (imageviewer->scrolledwin) {
186 hadj = gtk_scrolled_window_get_hadjustment
187 (GTK_SCROLLED_WINDOW(imageviewer->scrolledwin));
188 if (hadj)
189 gtk_adjustment_set_value(hadj, 0.0);
190 vadj = gtk_scrolled_window_get_vadjustment
191 (GTK_SCROLLED_WINDOW(imageviewer->scrolledwin));
192 if (vadj)
193 gtk_adjustment_set_value(vadj, 0.0);
195 g_free(imageviewer->file);
196 imageviewer->file = NULL;
197 imageviewer->mimeinfo = NULL;
198 imageviewer->resize_img = prefs_common.resize_img;
201 static void image_viewer_destroy_viewer(MimeViewer *_mimeviewer)
203 ImageViewer *imageviewer = (ImageViewer *) _mimeviewer;
205 debug_print("image_viewer_destroy_viewer\n");
207 image_viewer_clear_viewer(_mimeviewer);
208 g_object_unref(imageviewer->notebook);
209 g_free(imageviewer);
212 void image_viewer_get_resized_size(gint w, gint h, gint aw, gint ah,
213 gint *sw, gint *sh)
215 gfloat wratio = 1.0;
216 gfloat hratio = 1.0;
217 gfloat ratio = 1.0;
219 if (w > aw)
220 wratio = (gfloat)aw / (gfloat)w;
221 if (h > ah)
222 hratio = (gfloat)ah / (gfloat)h;
224 ratio = (wratio > hratio) ? hratio : wratio;
226 *sw = (gint)(w * ratio);
227 *sh = (gint)(h * ratio);
229 /* be paranoid */
230 if (*sw <= 0 || *sh <= 0) {
231 *sw = w;
232 *sh = h;
236 static void load_cb(GtkButton *button, ImageViewer *imageviewer)
238 gtk_notebook_set_current_page(GTK_NOTEBOOK(imageviewer->notebook), 1);
239 image_viewer_load_image(imageviewer);
242 static gboolean scrolledwin_button_cb(GtkWidget *scrolledwin, GdkEventButton *event,
243 ImageViewer *imageviewer)
245 if (event->button == 1 && imageviewer->image) {
246 imageviewer->resize_img = !imageviewer->resize_img;
247 image_viewer_load_image(imageviewer);
248 return TRUE;
250 return FALSE;
253 static void scrolledwin_resize_cb(GtkWidget *scrolledwin, GtkAllocation *alloc,
254 ImageViewer *imageviewer)
256 if (imageviewer->resize_img)
257 image_viewer_load_image(imageviewer);
260 static MimeViewer *image_viewer_create(void)
262 ImageViewer *imageviewer;
264 * glade generated code (do not touch)
266 GtkWidget *notebook;
267 GtkWidget *table1;
268 GtkWidget *label3;
269 GtkWidget *label4;
270 GtkWidget *filename;
271 GtkWidget *filesize;
272 GtkWidget *load_button;
273 GtkWidget *label5;
274 GtkWidget *content_type;
275 GtkWidget *scrolledwin;
277 notebook = gtk_notebook_new();
278 gtk_widget_show(notebook);
279 GTK_WIDGET_UNSET_FLAGS(notebook, GTK_CAN_FOCUS);
280 gtk_notebook_set_show_tabs(GTK_NOTEBOOK(notebook), FALSE);
281 gtk_notebook_set_show_border(GTK_NOTEBOOK(notebook), FALSE);
283 table1 = gtk_table_new(4, 3, FALSE);
284 gtk_widget_show(table1);
285 gtk_container_add(GTK_CONTAINER(notebook), table1);
286 gtk_container_set_border_width(GTK_CONTAINER(table1), 8);
287 gtk_table_set_row_spacings(GTK_TABLE(table1), 4);
288 gtk_table_set_col_spacings(GTK_TABLE(table1), 4);
290 label3 = gtk_label_new(_("Filename:"));
291 gtk_widget_show(label3);
292 gtk_table_attach(GTK_TABLE(table1), label3, 0, 1, 0, 1,
293 (GtkAttachOptions) (GTK_FILL),
294 (GtkAttachOptions) (0), 0, 0);
295 gtk_misc_set_alignment(GTK_MISC(label3), 0, 0.5);
297 label4 = gtk_label_new(_("Filesize:"));
298 gtk_widget_show(label4);
299 gtk_table_attach(GTK_TABLE(table1), label4, 0, 1, 1, 2,
300 (GtkAttachOptions) (GTK_FILL),
301 (GtkAttachOptions) (0), 0, 0);
302 gtk_misc_set_alignment(GTK_MISC(label4), 0, 0.5);
304 filename = gtk_label_new("");
305 gtk_widget_show(filename);
306 gtk_table_attach(GTK_TABLE(table1), filename, 1, 3, 0, 1,
307 (GtkAttachOptions) (GTK_FILL),
308 (GtkAttachOptions) (0), 0, 0);
309 gtk_misc_set_alignment(GTK_MISC(filename), 0, 0.5);
311 filesize = gtk_label_new("");
312 gtk_widget_show(filesize);
313 gtk_table_attach(GTK_TABLE(table1), filesize, 1, 3, 1, 2,
314 (GtkAttachOptions) (GTK_FILL),
315 (GtkAttachOptions) (0), 0, 0);
316 gtk_misc_set_alignment(GTK_MISC(filesize), 0, 0.5);
318 load_button = gtk_button_new_with_label(_("Load Image"));
319 gtk_widget_show(load_button);
320 gtk_table_attach(GTK_TABLE(table1), load_button, 1, 2, 3, 4,
321 (GtkAttachOptions) (GTK_FILL),
322 (GtkAttachOptions) (0), 0, 0);
324 label5 = gtk_label_new(_("Content-Type:"));
325 gtk_widget_show(label5);
326 gtk_table_attach(GTK_TABLE(table1), label5, 0, 1, 2, 3,
327 (GtkAttachOptions) (GTK_FILL),
328 (GtkAttachOptions) (0), 0, 0);
329 gtk_misc_set_alignment(GTK_MISC(label5), 0, 0.5);
331 content_type = gtk_label_new("");
332 gtk_widget_show(content_type);
333 gtk_table_attach(GTK_TABLE(table1), content_type, 1, 3, 2, 3,
334 (GtkAttachOptions) (GTK_FILL),
335 (GtkAttachOptions) (0), 0, 0);
336 gtk_misc_set_alignment(GTK_MISC(content_type), 0, 0.5);
338 scrolledwin = gtk_scrolled_window_new(NULL, NULL);
339 gtk_widget_show(scrolledwin);
340 gtk_container_add(GTK_CONTAINER(notebook), scrolledwin);
341 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledwin),
342 GTK_POLICY_AUTOMATIC,
343 GTK_POLICY_AUTOMATIC);
345 * end of glade code
348 debug_print("Creating image view...\n");
349 imageviewer = g_new0(ImageViewer, 1);
350 imageviewer->mimeviewer.factory = &image_viewer_factory;
352 imageviewer->mimeviewer.get_widget = image_viewer_get_widget;
353 imageviewer->mimeviewer.show_mimepart = image_viewer_show_mimepart;
354 imageviewer->mimeviewer.clear_viewer = image_viewer_clear_viewer;
355 imageviewer->mimeviewer.destroy_viewer = image_viewer_destroy_viewer;
356 imageviewer->mimeviewer.get_selection = NULL;
358 imageviewer->resize_img = prefs_common.resize_img;
360 imageviewer->scrolledwin = scrolledwin;
361 imageviewer->image = NULL;
362 imageviewer->notebook = notebook;
363 imageviewer->filename = filename;
364 imageviewer->filesize = filesize;
365 imageviewer->content_type = content_type;
367 gtk_widget_ref(notebook);
369 g_signal_connect(G_OBJECT(load_button), "clicked",
370 G_CALLBACK(load_cb), imageviewer);
371 g_signal_connect(G_OBJECT(scrolledwin), "button-press-event",
372 G_CALLBACK(scrolledwin_button_cb), imageviewer);
373 g_signal_connect(G_OBJECT(scrolledwin), "size-allocate",
374 G_CALLBACK(scrolledwin_resize_cb), imageviewer);
376 image_viewer_set_notebook_page((MimeViewer *)imageviewer);
378 return (MimeViewer *) imageviewer;
381 static gchar *content_types[] =
382 {"image/*", NULL};
384 MimeViewerFactory image_viewer_factory =
386 content_types,
389 image_viewer_create,
392 void image_viewer_init(void)
394 mimeview_register_viewer_factory(&image_viewer_factory);
397 void image_viewer_done(void)
399 mimeview_unregister_viewer_factory(&image_viewer_factory);