1 /* -*- Mode: C; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 3 -*- */
2
3 /*
4 * GImageView
5 * Copyright (C) 2001 Takuro Ashie
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 *
21 * $Id: exif_view.c,v 1.23 2004/09/22 15:37:11 makeinu Exp $
22 */
23
24 #include "gimageview.h"
25
26 #ifdef ENABLE_EXIF
27
28 #include <libexif/jpeg-data.h>
29 #include <libexif/exif-data.h>
30
31 #include "exif_view.h"
32 #include "gimv_image.h"
33 #include "gimv_io_mem.h"
34 #include "gtkutils.h"
35 #include "gimv_icon_stock.h"
36 #include "gimv_image_loader.h"
37
38
39 #ifdef ENABLE_TREEVIEW
40 typedef enum {
41 COLUMN_TERMINATOR = -1,
42 COLUMN_KEY,
43 COLUMN_VALUE,
44 N_COLUMN
45 } ListStoreColumn;
46 #endif /* ENABLE_TREEVIEW */
47
48
49 /******************************************************************************
50 *
51 * Callback Functions.
52 *
53 ******************************************************************************/
54 static void
cb_exif_view_destroy(GtkWidget * widget,ExifView * ev)55 cb_exif_view_destroy (GtkWidget *widget, ExifView *ev)
56 {
57 g_return_if_fail (ev);
58
59 if (ev->exif_data)
60 exif_data_unref (ev->exif_data);
61 ev->exif_data = NULL;
62
63 if (ev->jpeg_data)
64 jpeg_data_unref (ev->jpeg_data);
65 ev->jpeg_data = NULL;
66
67 g_free (ev);
68 }
69
70
71 static void
cb_exif_window_close(GtkWidget * button,ExifView * ev)72 cb_exif_window_close (GtkWidget *button, ExifView *ev)
73 {
74 g_return_if_fail (ev);
75
76 gtk_widget_destroy (ev->window);
77 }
78
79
80 /******************************************************************************
81 *
82 * Other Private Functions.
83 *
84 ******************************************************************************/
85 static void
exif_view_content_list_set_data(GtkWidget * clist,ExifContent * content)86 exif_view_content_list_set_data (GtkWidget *clist,
87 ExifContent *content)
88 {
89 const gchar *text[2];
90 guint i;
91
92 g_return_if_fail (clist);
93 g_return_if_fail (content);
94
95 #ifdef ENABLE_TREEVIEW
96 {
97 GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (clist));
98 gtk_list_store_clear (GTK_LIST_STORE (model));
99 }
100 #else /* ENABLE_TREEVIEW */
101 gtk_clist_clear (GTK_CLIST (clist));
102 #endif /* ENABLE_TREEVIEW */
103
104 for (i = 0; i < content->count; i++) {
105 text[0] = exif_tag_get_name (content->entries[i]->tag);
106 if (text[0] && *text[0]) text[0] = _(text[0]);
107 text[1] = exif_entry_get_value (content->entries[i]);
108 if (text[1] && *text[1]) text[1] = _(text[1]);
109 #ifdef ENABLE_TREEVIEW
110 {
111 GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (clist));
112 GtkTreeIter iter;
113
114 gtk_list_store_append (GTK_LIST_STORE (model), &iter);
115 gtk_list_store_set (GTK_LIST_STORE (model), &iter,
116 COLUMN_KEY, text[0],
117 COLUMN_VALUE, text[1],
118 COLUMN_TERMINATOR);
119 }
120 #else /* ENABLE_TREEVIEW */
121 gtk_clist_append (GTK_CLIST (clist), (gchar **) text);
122 #endif /* ENABLE_TREEVIEW */
123 }
124 }
125
126
127 /******************************************************************************
128 *
129 * Public Functions.
130 *
131 ******************************************************************************/
132 ExifView *
exif_view_create_window(const gchar * filename,GtkWindow * parent)133 exif_view_create_window (const gchar *filename, GtkWindow *parent)
134 {
135 ExifView *ev;
136 GtkWidget *button;
137 gchar buf[BUF_SIZE];
138
139 g_return_val_if_fail (filename && *filename, NULL);
140
141 ev = exif_view_create (filename, parent);
142 if (!ev) return NULL;
143
144 ev->window = gtk_dialog_new ();
145 if (parent)
146 gtk_window_set_transient_for (GTK_WINDOW (ev->window), parent);
147 g_snprintf (buf, BUF_SIZE, _("%s EXIF data"), filename);
148 gtk_window_set_title (GTK_WINDOW (ev->window), buf);
149 gtk_window_set_default_size (GTK_WINDOW (ev->window), 500, 400);
150 gtk_window_set_position (GTK_WINDOW (ev->window), GTK_WIN_POS_CENTER);
151
152 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (ev->window)->vbox),
153 ev->container,
154 TRUE, TRUE, 0);
155
156 gtk_widget_show_all (ev->window);
157
158 /* button */
159 button = gtk_button_new_with_label (_("Close"));
160 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (ev->window)->action_area),
161 button, TRUE, TRUE, 0);
162 gtk_signal_connect (GTK_OBJECT (button), "clicked",
163 GTK_SIGNAL_FUNC (cb_exif_window_close), ev);
164 GTK_WIDGET_SET_FLAGS(button,GTK_CAN_DEFAULT);
165 gtk_widget_show (button);
166
167 gtk_widget_grab_focus (button);
168
169 gimv_icon_stock_set_window_icon (ev->window->window, "gimv_icon");
170
171 return ev;
172 }
173
174
175 static GtkWidget *
exif_view_get_thumbnail(ExifData * edata)176 exif_view_get_thumbnail (ExifData *edata)
177 {
178 GtkWidget *image;
179 GimvImageLoader *loader;
180 GimvIO *gio;
181 GimvImage *gimvimage;
182 GdkPixmap *pixmap = NULL;
183 GdkBitmap *bitmap = NULL;
184
185
186 g_return_val_if_fail (edata, NULL);
187
188 if (!edata->data) return NULL;
189 if (edata->size <= 0) return NULL;
190
191 loader = gimv_image_loader_new ();
192 if (!loader) return NULL;
193
194 gio = gimv_io_mem_new (NULL, "rb", GimvIOMemModeWrap);
195 gimv_io_mem_wrap ((GimvIOMem *) gio, edata->data, edata->size, FALSE);
196 gimv_image_loader_set_gio (loader, gio);
197
198 gimv_image_loader_load (loader);
199
200 gimvimage = gimv_image_loader_get_image (loader);
201 if (!gimvimage) {
202 gimv_image_loader_unref (loader);
203 return NULL;
204 }
205
206 gimv_image_scale_get_pixmap (gimvimage,
207 gimv_image_width (gimvimage),
208 gimv_image_height (gimvimage),
209 &pixmap, &bitmap);
210
211 gimv_image_loader_unref (loader);
212 gimv_io_unref (gio);
213
214 #ifdef USE_GTK2
215 image = gtk_image_new_from_pixmap (pixmap, bitmap);
216 #else
217 image = gtk_pixmap_new (pixmap, bitmap);
218 #endif
219
220 if (pixmap)
221 gdk_pixmap_unref (pixmap);
222
223 return image;
224 }
225
226
227 ExifView *
exif_view_create(const gchar * filename,GtkWindow * parent)228 exif_view_create (const gchar *filename, GtkWindow *parent)
229 {
230 JPEGData *jdata;
231 ExifData *edata;
232 ExifView *ev = NULL;
233 ExifContent *contents[EXIF_IFD_COUNT];
234 GtkWidget *notebook, *label;
235 GtkWidget *vbox, *pixmap;
236 gint i;
237
238 gchar *titles[] = {
239 N_("Tag"), N_("Value"),
240 };
241
242 g_return_val_if_fail (filename && *filename, NULL);
243
244 jdata = jpeg_data_new_from_file (filename);
245 if (!jdata) {
246 gtkutil_message_dialog (_("Error!!"), _("EXIF data not found."),
247 GTK_WINDOW (ev->window));
248 return NULL;
249 }
250
251 edata = jpeg_data_get_exif_data (jdata);
252 if (!edata) {
253 gtkutil_message_dialog (_("Error!!"), _("EXIF data not found."),
254 GTK_WINDOW (parent));
255 goto ERROR;
256 }
257
258 ev = g_new0 (ExifView, 1);
259 ev->exif_data = edata;
260 ev->jpeg_data = jdata;
261
262 #if 0
263 contents[0] = edata->ifd0;
264 contents[1] = edata->ifd1;
265 contents[2] = edata->ifd_exif;
266 contents[3] = edata->ifd_gps;
267 contents[4] = edata->ifd_interoperability;
268 #else
269 for (i = 0; i < EXIF_IFD_COUNT; i++)
270 contents[i] = edata->ifd[i];
271 #endif
272
273 ev->container = gtk_vbox_new (FALSE, 0);
274 gtk_signal_connect (GTK_OBJECT (ev->container), "destroy",
275 GTK_SIGNAL_FUNC (cb_exif_view_destroy), ev);
276 gtk_widget_show (ev->container);
277
278 notebook = gtk_notebook_new ();
279 gtk_notebook_set_scrollable (GTK_NOTEBOOK (notebook), TRUE);
280 gtk_box_pack_start(GTK_BOX(ev->container), notebook, TRUE, TRUE, 0);
281 gtk_widget_show (notebook);
282
283 /* Tag Tables */
284 for (i = 0; i < EXIF_IFD_COUNT; i++) {
285 GtkWidget *scrolledwin, *clist;
286
287 /* scrolled window & clist */
288 label = gtk_label_new (_(exif_ifd_get_name(i)));
289 scrolledwin = gtk_scrolled_window_new (NULL, NULL);
290 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW(scrolledwin),
291 GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
292 #ifdef USE_GTK2
293 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolledwin),
294 GTK_SHADOW_IN);
295 #endif /* USE_GTK2 */
296 gtk_container_set_border_width (GTK_CONTAINER (scrolledwin), 5);
297 gtk_notebook_append_page (GTK_NOTEBOOK(notebook),
298 scrolledwin, label);
299 gtk_widget_show (scrolledwin);
300
301 #ifdef ENABLE_TREEVIEW
302 {
303 GtkListStore *store;
304 GtkTreeViewColumn *col;
305 GtkCellRenderer *render;
306
307 store = gtk_list_store_new (N_COLUMN, G_TYPE_STRING, G_TYPE_STRING);
308 clist = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));
309
310 gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (clist), TRUE);
311
312 /* set column for key */
313 col = gtk_tree_view_column_new();
314 gtk_tree_view_column_set_resizable (col, TRUE);
315 gtk_tree_view_column_set_title (col, _(titles[0]));
316 render = gtk_cell_renderer_text_new ();
317 gtk_tree_view_column_pack_start (col, render, TRUE);
318 gtk_tree_view_column_add_attribute (col, render, "text", COLUMN_KEY);
319 gtk_tree_view_append_column (GTK_TREE_VIEW (clist), col);
320
321 /* set column for value */
322 col = gtk_tree_view_column_new();
323 gtk_tree_view_column_set_resizable (col, TRUE);
324 gtk_tree_view_column_set_title (col, _(titles[1]));
325 render = gtk_cell_renderer_text_new ();
326 gtk_tree_view_column_pack_start (col, render, TRUE);
327 gtk_tree_view_column_add_attribute (col, render, "text", COLUMN_VALUE);
328 gtk_tree_view_append_column (GTK_TREE_VIEW (clist), col);
329 }
330 #else /* ENABLE_TREEVIEW */
331 clist = gtk_clist_new_with_titles (2, titles);
332 gtk_clist_set_selection_mode (GTK_CLIST (clist), GTK_SELECTION_SINGLE);
333 gtk_clist_set_column_auto_resize (GTK_CLIST (clist), 0, TRUE);
334 gtk_clist_set_column_auto_resize (GTK_CLIST (clist), 1, TRUE);
335 #endif /* ENABLE_TREEVIEW */
336
337 gtk_container_add (GTK_CONTAINER (scrolledwin), clist);
338 gtk_widget_show (clist);
339
340 exif_view_content_list_set_data (clist, contents[i]);
341 }
342
343 /* Thumbnail page */
344 label = gtk_label_new (_("Thumbnail"));
345 vbox = gtk_vbox_new (TRUE, 0);
346 gtk_notebook_append_page (GTK_NOTEBOOK(notebook),
347 vbox, label);
348 gtk_widget_show (vbox);
349
350 pixmap = exif_view_get_thumbnail (edata);
351
352 if (pixmap)
353 gtk_box_pack_start (GTK_BOX (vbox), pixmap, TRUE, TRUE, 0);
354
355 return ev;
356
357 ERROR:
358 jpeg_data_unref (jdata);
359 return NULL;
360 }
361
362 #endif /* ENABLE_EXIF */
363