1 /* gtk-exif-entry-number.c
2  *
3  * Copyright © 2001 Lutz Müller <lutz@users.sourceforge.net>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library 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 GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20 
21 #include "config.h"
22 #include "gtk-exif-entry-number.h"
23 #include "gtk-exif-util.h"
24 
25 #include <string.h>
26 #include <gtk/gtk.h>
27 #include <libexif/exif-utils.h>
28 
29 #ifdef ENABLE_NLS
30 #  include <libintl.h>
31 #  undef _
32 #  define _(String) dgettext (GETTEXT_PACKAGE, String)
33 #  ifdef gettext_noop
34 #    define N_(String) gettext_noop (String)
35 #  else
36 #    define N_(String) (String)
37 #  endif
38 #else
39 #  define textdomain(String) (String)
40 #  define gettext(String) (String)
41 #  define dgettext(Domain,Message) (Message)
42 #  define dcgettext(Domain,Message,Type) (Message)
43 #  define bindtextdomain(Domain,Directory) (Domain)
44 #  define _(String) (String)
45 #  define N_(String) (String)
46 #endif
47 
48 struct _GtkExifEntryNumberPrivate {
49 	ExifEntry *entry;
50 
51 	GPtrArray *a;
52 };
53 
54 #define PARENT_TYPE GTK_EXIF_TYPE_ENTRY
55 static GtkExifEntryClass *parent_class;
56 
57 static void
58 #if GTK_CHECK_VERSION(3,0,0)
gtk_exif_entry_number_destroy(GtkWidget * widget)59 gtk_exif_entry_number_destroy (GtkWidget *widget)
60 #else
61 gtk_exif_entry_number_destroy (GtkObject *object)
62 #endif
63 {
64 #if GTK_CHECK_VERSION(3,0,0)
65 	GtkExifEntryNumber *entry = GTK_EXIF_ENTRY_NUMBER (widget);
66 #else
67 	GtkExifEntryNumber *entry = GTK_EXIF_ENTRY_NUMBER (object);
68 #endif
69 
70 	if (entry->priv->entry) {
71 		exif_entry_unref (entry->priv->entry);
72 		entry->priv->entry = NULL;
73 	}
74 
75 	if (entry->priv->a) {
76 		g_ptr_array_free (entry->priv->a, TRUE);
77 		entry->priv->a = NULL;
78 	}
79 
80 #if GTK_CHECK_VERSION(3,0,0)
81 	GTK_WIDGET_CLASS (parent_class)->destroy (widget);
82 #else
83 	GTK_OBJECT_CLASS (parent_class)->destroy (object);
84 #endif
85 }
86 
GTK_EXIF_FINALIZE(entry_number,EntryNumber)87 GTK_EXIF_FINALIZE (entry_number, EntryNumber)
88 
89 static void
90 gtk_exif_entry_number_class_init (gpointer g_class, gpointer class_data G_GNUC_UNUSED)
91 {
92 #if GTK_CHECK_VERSION(3,0,0)
93 	GtkWidgetClass *widget_class;
94 	GObjectClass *gobject_class;
95 
96 	widget_class = GTK_WIDGET_CLASS (g_class);
97 	widget_class->destroy = gtk_exif_entry_number_destroy;
98 #else
99 	GtkObjectClass *object_class;
100 	GObjectClass *gobject_class;
101 
102 	object_class = GTK_OBJECT_CLASS (g_class);
103 	object_class->destroy  = gtk_exif_entry_number_destroy;
104 #endif
105 
106 	gobject_class = G_OBJECT_CLASS (g_class);
107 	gobject_class->finalize = gtk_exif_entry_number_finalize;
108 
109 	parent_class = g_type_class_peek_parent (g_class);
110 }
111 
112 static void
gtk_exif_entry_number_init(GTypeInstance * instance,gpointer g_class G_GNUC_UNUSED)113 gtk_exif_entry_number_init (GTypeInstance *instance, gpointer g_class G_GNUC_UNUSED)
114 {
115 	GtkExifEntryNumber *entry = GTK_EXIF_ENTRY_NUMBER (instance);
116 
117 	entry->priv = g_new0 (GtkExifEntryNumberPrivate, 1);
118 	entry->priv->a = g_ptr_array_new ();
119 }
120 
121 GTK_EXIF_CLASS (entry_number, EntryNumber, "EntryNumber")
122 
123 static void
gtk_exif_entry_number_load(GtkExifEntryNumber * entry)124 gtk_exif_entry_number_load (GtkExifEntryNumber *entry)
125 {
126 	ExifByte v_byte;
127 	ExifShort v_short;
128 	ExifLong v_long;
129 	ExifSLong v_slong;
130 	GtkAdjustment *a;
131 	ExifEntry *e;
132 	guint i;
133 	ExifByteOrder o;
134 
135 	g_return_if_fail (GTK_EXIF_IS_ENTRY_NUMBER (entry));
136 
137 	o = exif_data_get_byte_order (entry->priv->entry->parent->parent);
138 	e = entry->priv->entry;
139 	for (i = 0; i < e->components; i++) {
140 		a = entry->priv->a->pdata[i];
141 		g_signal_handlers_block_matched (G_OBJECT (a),
142 				G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, entry);
143 		switch (e->format) {
144 		case EXIF_FORMAT_BYTE:
145 			v_byte = e->data[i];
146 			gtk_adjustment_set_value (a, v_byte);
147 			break;
148 		case EXIF_FORMAT_SHORT:
149 			v_short = exif_get_short (e->data + 2 * i, o);
150 			gtk_adjustment_set_value (a, v_short);
151 			break;
152 		case EXIF_FORMAT_LONG:
153 			v_long = exif_get_long (e->data + 4 * i, o);
154 			gtk_adjustment_set_value (a, v_long);
155 			break;
156 		case EXIF_FORMAT_SLONG:
157 			v_slong = exif_get_slong (e->data + 4 * i, o);
158 			gtk_adjustment_set_value (a, v_slong);
159 			break;
160 		default:
161 			g_warning ("Invalid format!");
162 			break;
163 		}
164 		g_signal_handlers_unblock_matched (G_OBJECT (a),
165 				G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, entry);
166 	}
167 }
168 
169 static void
gtk_exif_entry_number_save(GtkExifEntryNumber * entry)170 gtk_exif_entry_number_save (GtkExifEntryNumber *entry)
171 {
172 	ExifEntry *e;
173 	GtkAdjustment *a;
174 	guint i;
175 	ExifByteOrder o;
176 
177 	g_return_if_fail (GTK_EXIF_IS_ENTRY_NUMBER (entry));
178 
179 	o = exif_data_get_byte_order (entry->priv->entry->parent->parent);
180 	e = entry->priv->entry;
181 	for (i = 0; i < e->components; i++) {
182 		a = entry->priv->a->pdata[i];
183 		switch (e->format) {
184 		case EXIF_FORMAT_BYTE:
185 			e->data[i] = gtk_adjustment_get_value (a);
186 			break;
187 		case EXIF_FORMAT_SHORT:
188 			exif_set_short (e->data + 2 * i, o, gtk_adjustment_get_value (a));
189 			break;
190 		case EXIF_FORMAT_LONG:
191 			exif_set_long (e->data + 4 * i, o, gtk_adjustment_get_value (a));
192 			break;
193 		case EXIF_FORMAT_SLONG:
194 			exif_set_slong (e->data + 4 * i, o, gtk_adjustment_get_value (a));
195 			break;
196 		default:
197 			g_warning ("Invalid format!");
198 			return;
199 		}
200 	}
201 	g_signal_emit_by_name (G_OBJECT (entry), "entry_changed", e);
202 }
203 
204 static void
on_adjustment_value_changed(GtkAdjustment * adj G_GNUC_UNUSED,GtkExifEntryNumber * entry)205 on_adjustment_value_changed (GtkAdjustment *adj G_GNUC_UNUSED, GtkExifEntryNumber *entry)
206 {
207 	gtk_exif_entry_number_save (entry);
208 }
209 
210 GtkWidget *
gtk_exif_entry_number_new(ExifEntry * e)211 gtk_exif_entry_number_new (ExifEntry *e)
212 {
213 	GtkExifEntryNumber *entry;
214 	GtkWidget *table, *label, *spin;
215 #if GTK_CHECK_VERSION(3,0,0)
216 	GtkAdjustment *a;
217 #else
218 	GtkObject *a;
219 #endif
220 	gchar *txt;
221 	guint i;
222 
223 	g_return_val_if_fail (e != NULL, NULL);
224 	g_return_val_if_fail ((e->format == EXIF_FORMAT_BYTE) ||
225 			      (e->format == EXIF_FORMAT_SHORT) ||
226 			      (e->format == EXIF_FORMAT_LONG) ||
227 			      (e->format == EXIF_FORMAT_SLONG), NULL);
228 
229 	bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
230 	bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
231 
232 	entry = g_object_new (GTK_EXIF_TYPE_ENTRY_NUMBER, NULL);
233 	entry->priv->entry = e;
234 	exif_entry_ref (e);
235 	gtk_exif_entry_construct (GTK_EXIF_ENTRY (entry),
236 		exif_tag_get_title_in_ifd (e->tag, exif_content_get_ifd(e->parent)),
237 		exif_tag_get_description_in_ifd (e->tag, exif_content_get_ifd(e->parent)));
238 
239 	table = gtk_table_new (2, 1, FALSE);
240 	gtk_widget_show (table);
241 	gtk_box_pack_start (GTK_BOX (entry), table, TRUE, TRUE, 0);
242 	gtk_table_set_col_spacings (GTK_TABLE (table), 5);
243 	gtk_table_set_row_spacings (GTK_TABLE (table), 5);
244 
245 	g_ptr_array_set_size (entry->priv->a, e->components);
246 	for (i = 0; i < e->components; i++) {
247 		if (e->components > 1)
248 			txt = g_strdup_printf (_("Value %i:"), i + 1);
249 		else
250 			txt = g_strdup (_("Value:"));
251 		label = gtk_label_new (txt);
252 		g_free (txt);
253 		gtk_widget_show (label);
254 		gtk_table_attach (GTK_TABLE (table), label, 0, 1, i, i + 1,
255 				  GTK_FILL, 0, 0, 0);
256 		gtk_misc_set_alignment (GTK_MISC (label), 0, 0);
257 		gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
258 
259 		a = gtk_adjustment_new (0, 0, 0xffff, 1, 0xff, 0);
260 		spin = gtk_spin_button_new (GTK_ADJUSTMENT (a), 0, 0);
261 		gtk_widget_show (spin);
262 		gtk_table_attach (GTK_TABLE (table), spin, 1, 2, i, i + 1,
263 				  GTK_FILL | GTK_EXPAND, 0, 0, 0);
264 		entry->priv->a->pdata[i] = a;
265 		g_signal_connect (a, "value_changed",
266 			G_CALLBACK (on_adjustment_value_changed), entry);
267 	}
268 
269 	gtk_exif_entry_number_load (entry);
270 
271 	return (GTK_WIDGET (entry));
272 }
273