]> git.sur5r.net Git - glabels/blob - glabels2/src/wdgt-media-select.c
Initial revision
[glabels] / glabels2 / src / wdgt-media-select.c
1 /*
2  *  (GLABELS) Label and Business Card Creation program for GNOME
3  *
4  *  wdgt_media_select.c:  media selection widget module
5  *
6  *  Copyright (C) 2001-2002  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
23 #include <config.h>
24
25 #include "wdgt-media-select.h"
26 #include "template.h"
27 #include "wdgt-mini-preview.h"
28 #include "prefs.h"
29 #include "util.h"
30 #include "marshal.h"
31
32 #include "debug.h"
33
34 #define WDGT_MINI_PREVIEW_WIDTH  160
35 #define WDGT_MINI_PREVIEW_HEIGHT 200
36
37 /*===========================================*/
38 /* Private types                             */
39 /*===========================================*/
40
41 enum {
42         CHANGED,
43         LAST_SIGNAL
44 };
45
46 typedef void (*glWdgtMediaSelectSignal) (GObject * object, gpointer data);
47
48 /*===========================================*/
49 /* Private globals                           */
50 /*===========================================*/
51
52 static GObjectClass *parent_class;
53
54 static gint wdgt_media_select_signals[LAST_SIGNAL] = { 0 };
55
56 /*===========================================*/
57 /* Local function prototypes                 */
58 /*===========================================*/
59
60 static void gl_wdgt_media_select_class_init    (glWdgtMediaSelectClass * class);
61 static void gl_wdgt_media_select_instance_init (glWdgtMediaSelect * media_select);
62 static void gl_wdgt_media_select_finalize      (GObject * object);
63
64 static void gl_wdgt_media_select_construct     (glWdgtMediaSelect * media_select);
65
66 static void page_size_entry_changed_cb         (GtkEntry * entry,
67                                                 gpointer user_data);
68 static void template_entry_changed_cb          (GtkEntry * entry,
69                                                 gpointer user_data);
70
71 static void details_update                     (glWdgtMediaSelect * media_select,
72                                                 gchar * name);
73 \f
74 /****************************************************************************/
75 /* Boilerplate Object stuff.                                                */
76 /****************************************************************************/
77 guint
78 gl_wdgt_media_select_get_type (void)
79 {
80         static guint wdgt_media_select_type = 0;
81
82         if (!wdgt_media_select_type) {
83                 GTypeInfo wdgt_media_select_info = {
84                         sizeof (glWdgtMediaSelectClass),
85                         NULL,
86                         NULL,
87                         (GClassInitFunc) gl_wdgt_media_select_class_init,
88                         NULL,
89                         NULL,
90                         sizeof (glWdgtMediaSelect),
91                         0,
92                         (GInstanceInitFunc) gl_wdgt_media_select_instance_init,
93                 };
94
95                 wdgt_media_select_type =
96                         g_type_register_static (gtk_vbox_get_type (),
97                                                 "glWdgtMediaSelect",
98                                                 &wdgt_media_select_info, 0);
99         }
100
101         return wdgt_media_select_type;
102 }
103
104 static void
105 gl_wdgt_media_select_class_init (glWdgtMediaSelectClass * class)
106 {
107         GObjectClass *object_class;
108
109         gl_debug (DEBUG_MEDIA_SELECT, "START");
110
111         object_class = (GObjectClass *) class;
112
113         parent_class = gtk_type_class (gtk_vbox_get_type ());
114
115         object_class->finalize = gl_wdgt_media_select_finalize;
116
117         wdgt_media_select_signals[CHANGED] =
118             g_signal_new ("changed",
119                           G_OBJECT_CLASS_TYPE(object_class),
120                           G_SIGNAL_RUN_LAST,
121                           G_STRUCT_OFFSET (glWdgtMediaSelectClass, changed),
122                           NULL, NULL,
123                           gl_marshal_VOID__VOID,
124                           G_TYPE_NONE, 0);
125
126         gl_debug (DEBUG_MEDIA_SELECT, "END");
127 }
128
129 static void
130 gl_wdgt_media_select_instance_init (glWdgtMediaSelect * media_select)
131 {
132         gl_debug (DEBUG_MEDIA_SELECT, "START");
133
134         media_select->page_size_entry = NULL;
135         media_select->template_entry = NULL;
136
137         media_select->mini_preview = NULL;
138
139         media_select->desc_label = NULL;
140         media_select->sheet_size_label = NULL;
141         media_select->number_label = NULL;
142         media_select->label_size_label = NULL;
143
144         gl_debug (DEBUG_MEDIA_SELECT, "END");
145 }
146
147 static void
148 gl_wdgt_media_select_finalize (GObject * object)
149 {
150         glWdgtMediaSelect *media_select;
151         glWdgtMediaSelectClass *class;
152
153         gl_debug (DEBUG_MEDIA_SELECT, "START");
154
155         g_return_if_fail (object != NULL);
156         g_return_if_fail (GL_IS_WDGT_MEDIA_SELECT (object));
157
158         media_select = GL_WDGT_MEDIA_SELECT (object);
159
160         G_OBJECT_CLASS (parent_class)->finalize (object);
161
162         gl_debug (DEBUG_MEDIA_SELECT, "END");
163 }
164
165 GtkWidget *
166 gl_wdgt_media_select_new (void)
167 {
168         glWdgtMediaSelect *media_select;
169
170         gl_debug (DEBUG_MEDIA_SELECT, "START");
171
172         media_select = g_object_new (gl_wdgt_media_select_get_type (), NULL);
173
174         gl_wdgt_media_select_construct (media_select);
175
176         gl_debug (DEBUG_MEDIA_SELECT, "END");
177
178         return GTK_WIDGET (media_select);
179 }
180
181 /*--------------------------------------------------------------------------*/
182 /* PRIVATE.  Construct composite widget.                                    */
183 /*--------------------------------------------------------------------------*/
184 static void
185 gl_wdgt_media_select_construct (glWdgtMediaSelect * media_select)
186 {
187         GtkWidget *whbox, *wvbox, *wcombo, *wvbox1, *whbox1;
188         gchar *name;
189         GList *template_names, *page_sizes = NULL;
190         const gchar *page_size;
191
192         gl_debug (DEBUG_MEDIA_SELECT, "START");
193
194         page_size = gl_prefs_get_page_size ();
195
196         wvbox = GTK_WIDGET (media_select);
197
198         whbox = gtk_hbox_new (FALSE, GNOME_PAD);
199         gtk_box_pack_start (GTK_BOX (wvbox), whbox, TRUE, TRUE, GNOME_PAD);
200
201         /* Page size selection control */
202         gl_debug (DEBUG_MEDIA_SELECT, "Creating page size combo...");
203         wcombo = gtk_combo_new ();
204         page_sizes = gl_template_get_page_size_list ();
205         gtk_combo_set_popdown_strings (GTK_COMBO (wcombo), page_sizes);
206         gl_template_free_page_size_list (&page_sizes);
207         media_select->page_size_entry = GTK_COMBO (wcombo)->entry;
208         gtk_entry_set_editable (GTK_ENTRY (media_select->page_size_entry),
209                                 FALSE);
210         gtk_combo_set_value_in_list (GTK_COMBO(wcombo), TRUE, FALSE);
211         gtk_widget_set_size_request (media_select->page_size_entry, 100, -1);
212         gtk_entry_set_text (GTK_ENTRY (media_select->page_size_entry),
213                             page_size);
214         gtk_box_pack_start (GTK_BOX (whbox), wcombo, FALSE, FALSE, GNOME_PAD);
215
216         /* Actual selection control */
217         gl_debug (DEBUG_MEDIA_SELECT, "Creating template combo...");
218         gl_debug (DEBUG_MEDIA_SELECT, "page_size = %s", page_size);
219         template_names = gl_template_get_name_list (page_size);
220         media_select->template_combo = gtk_combo_new ();
221         gtk_combo_set_popdown_strings (GTK_COMBO (media_select->template_combo),
222                                        template_names);
223         gl_template_free_name_list (&template_names);
224         media_select->template_entry =
225             GTK_COMBO (media_select->template_combo)->entry;
226         gtk_entry_set_editable (GTK_ENTRY (media_select->template_entry),
227                                 FALSE);
228         gtk_combo_set_value_in_list (GTK_COMBO(media_select->template_combo),
229                                      TRUE, FALSE);
230         gtk_widget_set_size_request (media_select->template_entry, 400, -1);
231         gtk_box_pack_start (GTK_BOX (whbox), media_select->template_combo,
232                             FALSE, FALSE, GNOME_PAD);
233
234         whbox = gtk_hbox_new (FALSE, GNOME_PAD);
235         gtk_box_pack_start (GTK_BOX (wvbox), whbox, TRUE, TRUE, GNOME_PAD);
236
237         /* mini_preview canvas */
238         gl_debug (DEBUG_MEDIA_SELECT, "Creating mini preview...");
239         media_select->mini_preview = gl_wdgt_mini_preview_new ( WDGT_MINI_PREVIEW_HEIGHT,
240                                                            WDGT_MINI_PREVIEW_WIDTH);
241         gtk_box_pack_start (GTK_BOX (whbox), media_select->mini_preview,
242                             FALSE, FALSE, GNOME_PAD);
243
244         /* Label column */
245         gl_debug (DEBUG_MEDIA_SELECT, "Creating label column...");
246         wvbox1 = gtk_vbox_new (FALSE, GNOME_PAD);
247         gtk_box_pack_start (GTK_BOX (whbox), wvbox1, FALSE, FALSE, 0);
248
249         whbox1 = gtk_hbox_new (FALSE, 0);
250         gtk_box_pack_start (GTK_BOX (wvbox1), whbox1, FALSE, FALSE, 0);
251         gtk_box_pack_start (GTK_BOX (whbox1),
252                             gtk_label_new (_("Description:")),
253                             FALSE, FALSE, GNOME_PAD);
254         whbox1 = gtk_hbox_new (FALSE, 0);
255         gtk_box_pack_start (GTK_BOX (wvbox1), whbox1, FALSE, FALSE, 0);
256         gtk_box_pack_start (GTK_BOX (whbox1),
257                             gtk_label_new (_("Page size:")),
258                             FALSE, FALSE, GNOME_PAD);
259         whbox1 = gtk_hbox_new (FALSE, 0);
260         gtk_box_pack_start (GTK_BOX (wvbox1), whbox1, FALSE, FALSE, 0);
261         gtk_box_pack_start (GTK_BOX (whbox1),
262                             gtk_label_new (_("Label size:")),
263                             FALSE, FALSE, GNOME_PAD);
264         whbox1 = gtk_hbox_new (FALSE, 0);
265         gtk_box_pack_start (GTK_BOX (wvbox1), whbox1, FALSE, FALSE, 0);
266         gtk_box_pack_start (GTK_BOX (whbox1),
267                             gtk_label_new (_("Layout:")),
268                             FALSE, FALSE, GNOME_PAD);
269
270         /* detail widgets column */
271         gl_debug (DEBUG_MEDIA_SELECT, "Creating details column...");
272         wvbox1 = gtk_vbox_new (FALSE, GNOME_PAD);
273         gtk_box_pack_start (GTK_BOX (whbox), wvbox1, FALSE, FALSE, 0);
274
275         whbox1 = gtk_hbox_new (FALSE, 0);
276         gtk_box_pack_start (GTK_BOX (wvbox1), whbox1, FALSE, FALSE, 0);
277         media_select->desc_label = gtk_label_new ("");
278         gtk_box_pack_start (GTK_BOX (whbox1), media_select->desc_label,
279                             FALSE, FALSE, GNOME_PAD);
280         whbox1 = gtk_hbox_new (FALSE, 0);
281         gtk_box_pack_start (GTK_BOX (wvbox1), whbox1, FALSE, FALSE, 0);
282         media_select->sheet_size_label = gtk_label_new ("");
283         gtk_box_pack_start (GTK_BOX (whbox1), media_select->sheet_size_label,
284                             FALSE, FALSE, GNOME_PAD);
285         whbox1 = gtk_hbox_new (FALSE, 0);
286         gtk_box_pack_start (GTK_BOX (wvbox1), whbox1, FALSE, FALSE, 0);
287         media_select->label_size_label = gtk_label_new ("");
288         gtk_box_pack_start (GTK_BOX (whbox1), media_select->label_size_label,
289                             FALSE, FALSE, GNOME_PAD);
290         whbox1 = gtk_hbox_new (FALSE, 0);
291         gtk_box_pack_start (GTK_BOX (wvbox1), whbox1, FALSE, FALSE, 0);
292         media_select->number_label = gtk_label_new ("");
293         gtk_box_pack_start (GTK_BOX (whbox1), media_select->number_label,
294                             FALSE, FALSE, GNOME_PAD);
295
296         /* Update mini_preview and details from default template */
297         
298         gl_debug (DEBUG_MEDIA_SELECT, "template_entry = %p",
299                   media_select->template_entry);
300         name =
301             gtk_editable_get_chars (GTK_EDITABLE (media_select->template_entry),
302                                     0, -1);
303         gl_debug (DEBUG_MEDIA_SELECT, "name = \"%s\"", name);
304         gl_wdgt_mini_preview_set_label (GL_WDGT_MINI_PREVIEW (media_select->mini_preview),
305                                    name);
306         details_update (media_select, name);
307         g_free (name);
308
309         /* Connect signals to controls */
310         g_signal_connect (G_OBJECT (media_select->page_size_entry), "changed",
311                           G_CALLBACK (page_size_entry_changed_cb),
312                           media_select);
313         g_signal_connect (G_OBJECT (media_select->template_entry), "changed",
314                           G_CALLBACK (template_entry_changed_cb),
315                           media_select);
316
317         gl_debug (DEBUG_MEDIA_SELECT, "END");
318 }
319
320 /*--------------------------------------------------------------------------*/
321 /* PRIVATE.  modify widget due to change in selection                       */
322 /*--------------------------------------------------------------------------*/
323 static void
324 page_size_entry_changed_cb (GtkEntry * entry,
325                             gpointer user_data)
326 {
327         glWdgtMediaSelect *media_select = GL_WDGT_MEDIA_SELECT (user_data);
328         gchar *page_size;
329         GList *template_names;
330
331         gl_debug (DEBUG_MEDIA_SELECT, "START");
332
333
334         /* Update template selections for new page size */
335         page_size = gtk_editable_get_chars (GTK_EDITABLE (entry), 0, -1);
336         if ( strlen(page_size) ) {
337                 gl_debug (DEBUG_MEDIA_SELECT, "page_size = \"%s\"", page_size);
338                 template_names = gl_template_get_name_list (page_size);
339                 gtk_combo_set_popdown_strings (GTK_COMBO (media_select->template_combo),
340                                                template_names);
341                 gl_template_free_name_list (&template_names);
342         }
343         g_free (page_size);
344
345         gl_debug (DEBUG_MEDIA_SELECT, "END");
346 }
347
348 /*--------------------------------------------------------------------------*/
349 /* PRIVATE.  modify widget due to change in selection                       */
350 /*--------------------------------------------------------------------------*/
351 static void
352 template_entry_changed_cb (GtkEntry * entry,
353                            gpointer user_data)
354 {
355         glWdgtMediaSelect *media_select = GL_WDGT_MEDIA_SELECT (user_data);
356         gchar *name;
357
358         gl_debug (DEBUG_MEDIA_SELECT, "START");
359
360         /* Update mini_preview canvas & details with template */
361         gl_debug (DEBUG_MEDIA_SELECT, "template_entry = %p", entry);
362         name = gtk_editable_get_chars (GTK_EDITABLE (entry), 0, -1);
363         if ( strlen(name) ) {
364                 gl_debug (DEBUG_MEDIA_SELECT, "name = \"%s\"", name);
365                 gl_wdgt_mini_preview_set_label (GL_WDGT_MINI_PREVIEW (media_select->mini_preview),
366                                            name);
367                 gl_debug (DEBUG_MEDIA_SELECT, "m1");
368                 details_update (media_select, name);
369                 gl_debug (DEBUG_MEDIA_SELECT, "m2");
370
371                 /* Emit our "changed" signal */
372                 g_signal_emit (G_OBJECT (user_data),
373                                wdgt_media_select_signals[CHANGED], 0);
374         }
375         g_free (name);
376
377         gl_debug (DEBUG_MEDIA_SELECT, "END");
378 }
379
380 /*--------------------------------------------------------------------------*/
381 /* PRIVATE. update "details" widgets from new template.               */
382 /*--------------------------------------------------------------------------*/
383 static void
384 details_update (glWdgtMediaSelect * media_select,
385                 gchar * name)
386 {
387         glTemplate *template;
388         gchar *text;
389         glPrefsUnits units;
390         const gchar *units_string;
391         gdouble units_per_point;
392
393         gl_debug (DEBUG_MEDIA_SELECT, "START");
394
395         units = gl_prefs_get_units ();
396         units_string = gl_prefs_get_units_string ();
397         units_per_point = gl_prefs_get_units_per_point ();
398
399         /* Fetch template */
400         template = gl_template_from_name (name);
401
402         gtk_label_set_text (GTK_LABEL (media_select->desc_label),
403                             template->description);
404
405         gtk_label_set_text (GTK_LABEL (media_select->sheet_size_label),
406                             template->page_size);
407
408         text = g_strdup_printf (_("%d x %d  (%d per sheet)"),
409                                 template->nx, template->ny,
410                                 template->nx * template->ny);
411
412         gtk_label_set_text (GTK_LABEL (media_select->number_label), text);
413         g_free (text);
414
415         if ( units == GL_PREFS_UNITS_INCHES ) {
416                 gchar *xstr, *ystr;
417
418                 xstr = gl_util_fraction (template->label_height
419                                          * units_per_point);
420                 ystr = gl_util_fraction (template->label_width
421                                          * units_per_point);
422                 text = g_strdup_printf (_("%s x %s %s"),
423                                         xstr, ystr, units_string);
424                 g_free (xstr);
425                 g_free (ystr);
426         } else {
427                 text = g_strdup_printf (_("%.5g x %.5g %s"),
428                                         template->label_height*units_per_point,
429                                         template->label_width*units_per_point,
430                                         units_string);
431         }
432         gtk_label_set_text (GTK_LABEL (media_select->label_size_label), text);
433         g_free (text);
434
435         gl_template_free( &template );
436
437         gl_debug (DEBUG_MEDIA_SELECT, "END");
438 }
439
440 /****************************************************************************/
441 /* query selected label template name.                                      */
442 /****************************************************************************/
443 gchar *
444 gl_wdgt_media_select_get_name (glWdgtMediaSelect * media_select)
445 {
446         gl_debug (DEBUG_MEDIA_SELECT, "");
447         return
448             gtk_editable_get_chars (GTK_EDITABLE (media_select->template_entry),
449                                     0, -1);
450 }
451
452 /****************************************************************************/
453 /* set selected label template name.                                        */
454 /****************************************************************************/
455 void
456 gl_wdgt_media_select_set_name (glWdgtMediaSelect * media_select,
457                                gchar * name)
458 {
459         gint pos;
460
461         gl_debug (DEBUG_MEDIA_SELECT, "START");
462
463         g_signal_handlers_block_by_func (G_OBJECT(media_select->template_entry),
464                                         G_CALLBACK(template_entry_changed_cb),
465                                         media_select);
466         gtk_editable_delete_text (GTK_EDITABLE (media_select->template_entry),
467                                   0, -1);
468         g_signal_handlers_unblock_by_func (G_OBJECT(media_select->template_entry),
469                                            G_CALLBACK(template_entry_changed_cb),
470                                            media_select);
471
472         pos = 0;
473         gtk_editable_insert_text (GTK_EDITABLE (media_select->template_entry),
474                                   name, strlen (name), &pos);
475
476         gl_debug (DEBUG_MEDIA_SELECT, "END");
477 }
478
479 /****************************************************************************/
480 /* query selected label template page size.                                 */
481 /****************************************************************************/
482 gchar *
483 gl_wdgt_media_select_get_page_size (glWdgtMediaSelect * media_select)
484 {
485         gl_debug (DEBUG_MEDIA_SELECT, "");
486
487         return
488             gtk_editable_get_chars (GTK_EDITABLE
489                                     (media_select->page_size_entry), 0, -1);
490 }
491
492 /****************************************************************************/
493 /* set selected label template page size.                                   */
494 /****************************************************************************/
495 void
496 gl_wdgt_media_select_set_page_size (glWdgtMediaSelect * media_select,
497                                     gchar * page_size)
498 {
499         gint pos;
500
501         gl_debug (DEBUG_MEDIA_SELECT, "START");
502
503         g_signal_handlers_block_by_func (G_OBJECT(media_select->page_size_entry),
504                                         G_CALLBACK(page_size_entry_changed_cb),
505                                         media_select);
506         gtk_editable_delete_text (GTK_EDITABLE (media_select->page_size_entry),
507                                   0, -1);
508         g_signal_handlers_unblock_by_func (G_OBJECT(media_select->page_size_entry),
509                                           G_CALLBACK(page_size_entry_changed_cb),
510                                           media_select);
511
512         pos = 0;
513         gtk_editable_insert_text (GTK_EDITABLE (media_select->page_size_entry),
514                                   page_size, strlen (page_size), &pos);
515
516         gl_debug (DEBUG_MEDIA_SELECT, "END");
517 }