]> git.sur5r.net Git - glabels/blob - glabels2/src/object-editor-image-page.c
2005-04-03 Jim Evins <evins@snaught.com>
[glabels] / glabels2 / src / object-editor-image-page.c
1 /*
2  *  (GLABELS) Label and Business Card Creation program for GNOME
3  *
4  *  object-editor.c:  object properties editor module
5  *
6  *  Copyright (C) 2003  Jim Evins <evins@snaught.com>.
7  *
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 2 of the License, or
11  *  (at your option) any later version.
12  *
13  *  This program is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with this program; if not, write to the Free Software
20  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
21  */
22 #include <config.h>
23
24 #include <gnome.h>
25 #include <math.h>
26 #include <gtk/gtkimage.h>
27
28 #include "object-editor.h"
29 #include "prefs.h"
30
31 #include "object-editor-private.h"
32
33 #include "debug.h"
34
35 /*===========================================*/
36 /* Private macros                            */
37 /*===========================================*/
38
39 /*===========================================*/
40 /* Private data types                        */
41 /*===========================================*/
42
43 /*===========================================*/
44 /* Private globals                           */
45 /*===========================================*/
46
47 /*===========================================*/
48 /* Local function prototypes                 */
49 /*===========================================*/
50
51 static void img_radio_toggled_cb                (glObjectEditor        *editor);
52
53 static void update_preview_cb                   (GtkFileChooser *file_chooser,
54                                                  gpointer        data);
55 static void add_image_filters_to_chooser        (GtkFileChooser *file_chooser);
56
57
58 \f
59 /*--------------------------------------------------------------------------*/
60 /* PRIVATE.  Prepare image page.                                             */
61 /*--------------------------------------------------------------------------*/
62 void
63 gl_object_editor_prepare_image_page (glObjectEditor *editor)
64 {
65         GdkColor      *gdk_color;
66         GtkFileFilter *filter;
67         GtkWidget     *preview;
68
69
70         gl_debug (DEBUG_EDITOR, "START");
71
72         /* Extract widgets from XML tree. */
73         editor->priv->img_page_vbox    = glade_xml_get_widget (editor->priv->gui,
74                                                                "img_page_vbox");
75         editor->priv->img_file_radio   = glade_xml_get_widget (editor->priv->gui,
76                                                                "img_file_radio");
77         editor->priv->img_key_radio    = glade_xml_get_widget (editor->priv->gui,
78                                                                "img_key_radio");
79         editor->priv->img_file_button  = glade_xml_get_widget (editor->priv->gui,
80                                                                "img_file_button");
81         editor->priv->img_key_combo    = glade_xml_get_widget (editor->priv->gui,
82                                                                "img_key_combo");
83         editor->priv->img_key_entry    = glade_xml_get_widget (editor->priv->gui,
84                                                                "img_key_entry");
85
86         /* Modify file button properties. */
87         add_image_filters_to_chooser (GTK_FILE_CHOOSER (editor->priv->img_file_button));
88         preview = gtk_image_new ();
89         gtk_file_chooser_set_preview_widget (GTK_FILE_CHOOSER (editor->priv->img_file_button), preview);
90         g_signal_connect (G_OBJECT (editor->priv->img_file_button),
91                           "update-preview",
92                           G_CALLBACK (update_preview_cb), preview);
93
94         /* Un-hide */
95         gtk_widget_show_all (editor->priv->img_page_vbox);
96
97         /* Connect signals */
98         g_signal_connect_swapped (G_OBJECT (editor->priv->img_file_button),
99                                   "selection-changed",
100                                   G_CALLBACK (gl_object_editor_changed_cb),
101                                   G_OBJECT (editor));
102         g_signal_connect_swapped (G_OBJECT (editor->priv->img_key_entry),
103                                   "changed",
104                                   G_CALLBACK (gl_object_editor_changed_cb),
105                                   G_OBJECT (editor));
106         g_signal_connect_swapped (G_OBJECT (editor->priv->img_file_radio),
107                                   "toggled",
108                                   G_CALLBACK (img_radio_toggled_cb),
109                                   G_OBJECT (editor));
110         g_signal_connect_swapped (G_OBJECT (editor->priv->img_key_radio),
111                                   "toggled",
112                                   G_CALLBACK (img_radio_toggled_cb),
113                                   G_OBJECT (editor));
114
115         gl_debug (DEBUG_EDITOR, "END");
116 }
117
118 /*--------------------------------------------------------------------------*/
119 /* PRIVATE.  image radio callback.                                          */
120 /*--------------------------------------------------------------------------*/
121 static void
122 img_radio_toggled_cb (glObjectEditor *editor)
123 {
124         gl_debug (DEBUG_WDGT, "START");
125  
126         if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (editor->priv->img_file_radio))) {
127                 gtk_widget_set_sensitive (editor->priv->img_file_button, TRUE);
128                 gtk_widget_set_sensitive (editor->priv->img_key_combo, FALSE);
129         } else {
130                 gtk_widget_set_sensitive (editor->priv->img_file_button, FALSE);
131                 gtk_widget_set_sensitive (editor->priv->img_key_combo, TRUE);
132         }
133  
134         /* Emit our "changed" signal */
135         g_signal_emit (G_OBJECT (editor), gl_object_editor_signals[CHANGED], 0);
136  
137         gl_debug (DEBUG_WDGT, "END");
138 }
139
140 /*****************************************************************************/
141 /* Set image.                                                                */
142 /*****************************************************************************/
143 void
144 gl_object_editor_set_image (glObjectEditor      *editor,
145                             gboolean             merge_flag,
146                             glTextNode          *text_node)
147 {
148         gint pos;
149  
150         gl_debug (DEBUG_EDITOR, "START");
151  
152         g_signal_handlers_block_by_func (G_OBJECT (editor->priv->img_file_button),
153                                          G_CALLBACK (gl_object_editor_changed_cb),
154                                          editor);
155         g_signal_handlers_block_by_func (G_OBJECT (editor->priv->img_key_entry),
156                                          G_CALLBACK (gl_object_editor_changed_cb),
157                                          editor);
158
159         gtk_widget_set_sensitive (editor->priv->img_key_radio, merge_flag);
160  
161         if (!text_node->field_flag) {
162  
163                 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON
164                                               (editor->priv->img_file_radio), TRUE); 
165                 gtk_widget_set_sensitive (editor->priv->img_file_button, TRUE);
166                 gtk_widget_set_sensitive (editor->priv->img_key_combo, FALSE);
167  
168                 if (text_node->data != NULL ) {
169                         gtk_file_chooser_set_filename (GTK_FILE_CHOOSER(editor->priv->img_file_button),
170                                                        text_node->data);
171                 } else {
172                         gtk_file_chooser_unselect_all (GTK_FILE_CHOOSER(editor->priv->img_file_button));
173                 }
174         } else {
175                                                                                 
176                 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON
177                                               (editor->priv->img_key_radio), TRUE);
178                                                                                 
179                 gtk_widget_set_sensitive (editor->priv->img_file_button, FALSE);
180                 gtk_widget_set_sensitive (editor->priv->img_key_combo, TRUE);
181                                                                                 
182                 gtk_editable_delete_text (GTK_EDITABLE (editor->priv->img_key_entry), 0, -1);
183                 pos = 0;
184                 gtk_editable_insert_text (GTK_EDITABLE (editor->priv->img_key_entry),
185                                           text_node->data,
186                                           strlen (text_node->data),
187                                           &pos);
188         }
189                                                                                 
190         g_signal_handlers_unblock_by_func (G_OBJECT (editor->priv->img_file_button),
191                                            G_CALLBACK (gl_object_editor_changed_cb),
192                                            editor);
193         g_signal_handlers_unblock_by_func (G_OBJECT (editor->priv->img_key_entry),
194                                            G_CALLBACK (gl_object_editor_changed_cb),
195                                            editor);
196                                                                                 
197         gl_debug (DEBUG_EDITOR, "END");
198 }
199
200 /*****************************************************************************/
201 /* Query image.                                                              */
202 /*****************************************************************************/
203 glTextNode *
204 gl_object_editor_get_image (glObjectEditor      *editor)
205 {
206         glTextNode *text_node;
207  
208         gl_debug (DEBUG_EDITOR, "START");
209  
210         text_node = g_new0(glTextNode,1);
211  
212         if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (editor->priv->img_file_radio))) {
213                 text_node->field_flag = FALSE;
214                 text_node->data =
215                         gtk_file_chooser_get_filename (GTK_FILE_CHOOSER(editor->priv->img_file_button));
216         } else {
217                 text_node->field_flag = TRUE;
218                 text_node->data =
219                     gtk_editable_get_chars (GTK_EDITABLE (editor->priv->img_key_entry),
220                                             0, -1);
221         }
222  
223         gl_debug (DEBUG_EDITOR, "text_node: field_flag=%d, data=%s",
224                   text_node->field_flag, text_node->data);
225
226         gl_debug (DEBUG_EDITOR, "END");
227  
228         return text_node;
229 }
230
231 /*--------------------------------------------------------------------------*/
232 /* PRIVATE.  Update preview image.                                          */
233 /*--------------------------------------------------------------------------*/
234 static void
235 update_preview_cb (GtkFileChooser *file_chooser, gpointer data)
236 {
237   GtkWidget *preview;
238   char *filename;
239   GdkPixbuf *pixbuf;
240   gboolean have_preview;
241
242   preview = GTK_WIDGET (data);
243   filename = gtk_file_chooser_get_preview_filename (file_chooser);
244
245   if (filename) {
246           pixbuf = gdk_pixbuf_new_from_file_at_size (filename, 128, 128, NULL);
247           have_preview = (pixbuf != NULL);
248           g_free (filename);
249
250           gtk_image_set_from_pixbuf (GTK_IMAGE (preview), pixbuf);
251           if (pixbuf)
252                   gdk_pixbuf_unref (pixbuf);
253
254           gtk_file_chooser_set_preview_widget_active (file_chooser,
255                                                       have_preview);
256   } else {
257           gtk_file_chooser_set_preview_widget_active (file_chooser, FALSE);
258   }
259 }
260
261 /*--------------------------------------------------------------------------*/
262 /* PRIVATE.  Add filters to file chooser.                                   */
263 /*           Based on eog's eog_file_selection_add_filter().                */
264 /*--------------------------------------------------------------------------*/
265 static void
266 add_image_filters_to_chooser (GtkFileChooser *chooser)
267 {
268         GtkFileFilter *all_file_filter;
269         GtkFileFilter *all_img_filter;
270         GSList        *formats;
271         GSList        *it;
272         GtkFileFilter *filter;
273         GSList        *filters = NULL;
274         gchar        **mime_types, **pattern, *tmp;
275         int            i;
276
277         /* All Files Filter */
278         all_file_filter = gtk_file_filter_new ();
279         gtk_file_filter_set_name (all_file_filter, _("All Files"));
280         gtk_file_filter_add_pattern (all_file_filter, "*");
281
282         /* All Image Filter */
283         all_img_filter = gtk_file_filter_new ();
284         gtk_file_filter_set_name (all_img_filter, _("All Images"));
285
286         /* Individual image filters */
287         formats = gdk_pixbuf_get_formats ();
288         for (it = formats; it != NULL; it = it->next) {
289                 char *filter_name;
290                 GdkPixbufFormat *format;
291                 filter = gtk_file_filter_new ();
292
293                 format = (GdkPixbufFormat*) it->data;
294
295                 /* Filter name: First description then file extension, eg. "The PNG-Format (*.png)".*/
296                 filter_name = g_strdup_printf (_("%s (*.%s)"), 
297                                                gdk_pixbuf_format_get_description (format),
298                                                gdk_pixbuf_format_get_name (format));
299                 gtk_file_filter_set_name (filter, filter_name);
300                 g_free (filter_name);
301
302                 mime_types = gdk_pixbuf_format_get_mime_types ((GdkPixbufFormat *) it->data);
303                 for (i = 0; mime_types[i] != NULL; i++) {
304                         gtk_file_filter_add_mime_type (filter, mime_types[i]);
305                         gtk_file_filter_add_mime_type (all_img_filter, mime_types[i]);
306                 }
307                 g_strfreev (mime_types);
308  
309                 pattern = gdk_pixbuf_format_get_extensions ((GdkPixbufFormat *) it->data);
310                 for (i = 0; pattern[i] != NULL; i++) {
311                         tmp = g_strconcat ("*.", pattern[i], NULL);
312                         gtk_file_filter_add_pattern (filter, tmp);
313                         gtk_file_filter_add_pattern (all_img_filter, tmp);
314                         g_free (tmp);
315                 }
316                 g_strfreev (pattern);
317
318                 filters = g_slist_prepend (filters, filter);
319         }
320         g_slist_free (formats);
321
322         /* Add filter to filechooser */
323         gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (chooser), all_file_filter);
324         gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (chooser), all_img_filter);
325         gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (chooser), all_img_filter);
326
327         for (it = filters; it != NULL; it = it->next) {
328                 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (chooser),
329                                              GTK_FILE_FILTER (it->data));
330         }
331         g_slist_free (filters);
332 }