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