2 * (GLABELS) Label and Business Card Creation program for GNOME
4 * wdgt_media_select.c: media selection widget module
6 * Copyright (C) 2001-2002 Jim Evins <evins@snaught.com>.
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.
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.
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
25 #include "wdgt-media-select.h"
27 #include "wdgt-mini-preview.h"
31 #include <libglabels/paper.h>
32 #include <libglabels/template.h>
36 #define WDGT_MINI_PREVIEW_WIDTH 160
37 #define WDGT_MINI_PREVIEW_HEIGHT 200
39 /*===========================================*/
41 /*===========================================*/
48 typedef void (*glWdgtMediaSelectSignal) (GObject * object, gpointer data);
50 /*===========================================*/
52 /*===========================================*/
54 static GObjectClass *parent_class;
56 static gint wdgt_media_select_signals[LAST_SIGNAL] = { 0 };
58 /*===========================================*/
59 /* Local function prototypes */
60 /*===========================================*/
62 static void gl_wdgt_media_select_class_init (glWdgtMediaSelectClass *class);
63 static void gl_wdgt_media_select_instance_init (glWdgtMediaSelect *media_select);
64 static void gl_wdgt_media_select_finalize (GObject *object);
66 static void gl_wdgt_media_select_construct (glWdgtMediaSelect *media_select);
68 static void page_size_entry_changed_cb (GtkEntry *entry,
70 static void template_entry_changed_cb (GtkEntry *entry,
72 static void prefs_changed_cb (glPrefsModel *gl_prefs,
75 static void details_update (glWdgtMediaSelect *media_select,
78 static gchar *get_layout_desc (const glTemplate *template);
79 static gchar *get_label_size_desc (const glTemplate *template);
81 /****************************************************************************/
82 /* Boilerplate Object stuff. */
83 /****************************************************************************/
85 gl_wdgt_media_select_get_type (void)
87 static guint wdgt_media_select_type = 0;
89 if (!wdgt_media_select_type) {
90 GTypeInfo wdgt_media_select_info = {
91 sizeof (glWdgtMediaSelectClass),
94 (GClassInitFunc) gl_wdgt_media_select_class_init,
97 sizeof (glWdgtMediaSelect),
99 (GInstanceInitFunc) gl_wdgt_media_select_instance_init,
102 wdgt_media_select_type =
103 g_type_register_static (gl_hig_vbox_get_type (),
105 &wdgt_media_select_info, 0);
108 return wdgt_media_select_type;
112 gl_wdgt_media_select_class_init (glWdgtMediaSelectClass *class)
114 GObjectClass *object_class;
116 gl_debug (DEBUG_MEDIA_SELECT, "START");
118 object_class = (GObjectClass *) class;
120 parent_class = g_type_class_peek_parent (class);
122 object_class->finalize = gl_wdgt_media_select_finalize;
124 wdgt_media_select_signals[CHANGED] =
125 g_signal_new ("changed",
126 G_OBJECT_CLASS_TYPE(object_class),
128 G_STRUCT_OFFSET (glWdgtMediaSelectClass, changed),
130 gl_marshal_VOID__VOID,
133 gl_debug (DEBUG_MEDIA_SELECT, "END");
137 gl_wdgt_media_select_instance_init (glWdgtMediaSelect *media_select)
139 gl_debug (DEBUG_MEDIA_SELECT, "START");
141 media_select->page_size_entry = NULL;
142 media_select->template_entry = NULL;
144 media_select->mini_preview = NULL;
146 media_select->desc_label = NULL;
147 media_select->sheet_size_label = NULL;
148 media_select->number_label = NULL;
149 media_select->label_size_label = NULL;
151 gl_debug (DEBUG_MEDIA_SELECT, "END");
155 gl_wdgt_media_select_finalize (GObject *object)
157 glWdgtMediaSelect *media_select;
158 glWdgtMediaSelectClass *class;
160 gl_debug (DEBUG_MEDIA_SELECT, "START");
162 g_return_if_fail (object != NULL);
163 g_return_if_fail (GL_IS_WDGT_MEDIA_SELECT (object));
165 media_select = GL_WDGT_MEDIA_SELECT (object);
167 g_signal_handlers_disconnect_by_func (G_OBJECT(gl_prefs),
168 prefs_changed_cb, media_select);
170 G_OBJECT_CLASS (parent_class)->finalize (object);
172 gl_debug (DEBUG_MEDIA_SELECT, "END");
176 gl_wdgt_media_select_new (void)
178 glWdgtMediaSelect *media_select;
180 gl_debug (DEBUG_MEDIA_SELECT, "START");
182 media_select = g_object_new (gl_wdgt_media_select_get_type (), NULL);
184 gl_wdgt_media_select_construct (media_select);
186 gl_debug (DEBUG_MEDIA_SELECT, "END");
188 return GTK_WIDGET (media_select);
191 /*--------------------------------------------------------------------------*/
192 /* PRIVATE. Construct composite widget. */
193 /*--------------------------------------------------------------------------*/
195 gl_wdgt_media_select_construct (glWdgtMediaSelect *media_select)
197 GtkWidget *whbox, *wvbox, *wcombo, *wvbox1, *whbox1, *wlabel;
198 GtkSizeGroup *label_size_group;
200 GList *template_names, *page_sizes = NULL;
201 const gchar *page_size_id;
202 gchar *page_size_name;
204 gl_debug (DEBUG_MEDIA_SELECT, "START");
206 page_size_id = gl_prefs_get_page_size ();
207 page_size_name = gl_paper_lookup_name_from_id (page_size_id);
209 wvbox = GTK_WIDGET (media_select);
211 whbox = gl_hig_hbox_new ();
212 gl_hig_vbox_add_widget (GL_HIG_VBOX(wvbox), whbox);
214 /* Page size selection control */
215 gl_debug (DEBUG_MEDIA_SELECT, "Creating page size combo...");
216 wcombo = gtk_combo_new ();
217 page_sizes = gl_paper_get_name_list ();
218 gtk_combo_set_popdown_strings (GTK_COMBO (wcombo), page_sizes);
219 gl_paper_free_name_list (page_sizes);
220 media_select->page_size_entry = GTK_COMBO (wcombo)->entry;
221 gtk_entry_set_editable (GTK_ENTRY (media_select->page_size_entry),
223 gtk_combo_set_value_in_list (GTK_COMBO(wcombo), TRUE, FALSE);
224 gtk_widget_set_size_request (media_select->page_size_entry, 100, -1);
225 gtk_entry_set_text (GTK_ENTRY (media_select->page_size_entry),
227 gl_hig_hbox_add_widget (GL_HIG_HBOX(whbox), wcombo);
229 /* Actual selection control */
230 gl_debug (DEBUG_MEDIA_SELECT, "Creating template combo...");
231 gl_debug (DEBUG_MEDIA_SELECT, "page_size_name = %s", page_size_name);
232 template_names = gl_template_get_name_list (page_size_id);
233 media_select->template_combo = gtk_combo_new ();
234 gtk_combo_set_popdown_strings (GTK_COMBO (media_select->template_combo),
236 media_select->template_entry =
237 GTK_COMBO (media_select->template_combo)->entry;
238 gtk_entry_set_editable (GTK_ENTRY (media_select->template_entry),
240 gtk_combo_set_value_in_list (GTK_COMBO(media_select->template_combo),
242 gtk_widget_set_size_request (media_select->template_entry, 400, -1);
243 gtk_entry_set_text (GTK_ENTRY (media_select->template_entry),
244 template_names->data);
245 gl_hig_hbox_add_widget (GL_HIG_HBOX(whbox),
246 media_select->template_combo);
247 gl_template_free_name_list (template_names);
249 whbox = gl_hig_hbox_new ();
250 gl_hig_vbox_add_widget (GL_HIG_VBOX(wvbox), whbox);
252 /* mini_preview canvas */
253 gl_debug (DEBUG_MEDIA_SELECT, "Creating mini preview...");
254 media_select->mini_preview = gl_wdgt_mini_preview_new ( WDGT_MINI_PREVIEW_HEIGHT,
255 WDGT_MINI_PREVIEW_WIDTH);
256 gl_hig_hbox_add_widget (GL_HIG_HBOX(whbox),
257 media_select->mini_preview);
259 /* ---- Information area ---- */
260 wvbox1 = gl_hig_vbox_new (GL_HIG_VBOX_INNER);
261 gl_hig_hbox_add_widget (GL_HIG_HBOX(whbox), wvbox1);
262 label_size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
265 gl_hig_vbox_add_widget (GL_HIG_VBOX(wvbox1), gtk_label_new (""));
267 /* Description line */
268 whbox1 = gl_hig_hbox_new ();
269 gl_hig_vbox_add_widget (GL_HIG_VBOX(wvbox1), whbox1);
270 wlabel = gtk_label_new (_("Description:"));
271 gtk_size_group_add_widget (label_size_group, wlabel);
272 gtk_misc_set_alignment (GTK_MISC(wlabel), 0.0, 0.0);
273 gl_hig_hbox_add_widget (GL_HIG_HBOX(whbox1), wlabel);
274 media_select->desc_label = gtk_label_new ("");
275 gl_hig_hbox_add_widget (GL_HIG_HBOX(whbox1), media_select->desc_label);
278 whbox1 = gl_hig_hbox_new ();
279 gl_hig_vbox_add_widget (GL_HIG_VBOX(wvbox1), whbox1);
280 wlabel = gtk_label_new (_("Page size:"));
281 gtk_size_group_add_widget (label_size_group, wlabel);
282 gtk_misc_set_alignment (GTK_MISC(wlabel), 0.0, 0.0);
283 gl_hig_hbox_add_widget (GL_HIG_HBOX(whbox1), wlabel);
284 media_select->sheet_size_label = gtk_label_new ("");
285 gl_hig_hbox_add_widget (GL_HIG_HBOX(whbox1),
286 media_select->sheet_size_label);
288 /* Label size line */
289 whbox1 = gl_hig_hbox_new ();
290 gl_hig_vbox_add_widget (GL_HIG_VBOX(wvbox1), whbox1);
291 wlabel = gtk_label_new (_("Label size:"));
292 gtk_size_group_add_widget (label_size_group, wlabel);
293 gtk_misc_set_alignment (GTK_MISC(wlabel), 0.0, 0.0);
294 gl_hig_hbox_add_widget (GL_HIG_HBOX(whbox1), wlabel);
295 media_select->label_size_label = gtk_label_new ("");
296 gl_hig_hbox_add_widget (GL_HIG_HBOX(whbox1),
297 media_select->label_size_label);
300 whbox1 = gl_hig_hbox_new ();
301 gl_hig_vbox_add_widget (GL_HIG_VBOX(wvbox1), whbox1);
302 wlabel = gtk_label_new (_("Layout:"));
303 gtk_size_group_add_widget (label_size_group, wlabel);
304 gtk_misc_set_alignment (GTK_MISC(wlabel), 0.0, 0.0);
305 gl_hig_hbox_add_widget (GL_HIG_HBOX(whbox1), wlabel);
306 media_select->number_label = gtk_label_new ("");
307 gl_hig_hbox_add_widget (GL_HIG_HBOX(whbox1),
308 media_select->number_label);
310 /* Update mini_preview and details from default template */
312 gl_debug (DEBUG_MEDIA_SELECT, "template_entry = %p",
313 media_select->template_entry);
315 gtk_editable_get_chars (GTK_EDITABLE (media_select->template_entry),
317 gl_debug (DEBUG_MEDIA_SELECT, "name = \"%s\"", name);
318 gl_wdgt_mini_preview_set_label_by_name (GL_WDGT_MINI_PREVIEW (media_select->mini_preview),
320 details_update (media_select, name);
323 /* Connect signals to controls */
324 g_signal_connect (G_OBJECT (media_select->page_size_entry), "changed",
325 G_CALLBACK (page_size_entry_changed_cb),
327 g_signal_connect (G_OBJECT (media_select->template_entry), "changed",
328 G_CALLBACK (template_entry_changed_cb),
330 g_signal_connect (G_OBJECT (gl_prefs), "changed",
331 G_CALLBACK (prefs_changed_cb),
334 g_free (page_size_name);
336 gl_debug (DEBUG_MEDIA_SELECT, "END");
339 /*--------------------------------------------------------------------------*/
340 /* PRIVATE. modify widget due to change in selection */
341 /*--------------------------------------------------------------------------*/
343 page_size_entry_changed_cb (GtkEntry *entry,
346 glWdgtMediaSelect *media_select = GL_WDGT_MEDIA_SELECT (user_data);
347 gchar *page_size_name, *page_size_id;
348 GList *template_names;
350 gl_debug (DEBUG_MEDIA_SELECT, "START");
353 /* Update template selections for new page size */
354 page_size_name = gtk_editable_get_chars (GTK_EDITABLE (entry), 0, -1);
355 if ( strlen(page_size_name) ) {
356 gl_debug (DEBUG_MEDIA_SELECT, "page_size_name = \"%s\"", page_size_name);
357 page_size_id = gl_paper_lookup_id_from_name (page_size_name);
358 template_names = gl_template_get_name_list (page_size_id);
359 if (template_names == NULL) {
360 template_names = g_list_append (template_names, g_strdup(""));
362 gtk_combo_set_popdown_strings (GTK_COMBO (media_select->template_combo),
364 gtk_entry_set_text (GTK_ENTRY (media_select->template_entry),
365 template_names->data);
366 gl_template_free_name_list (template_names);
367 g_free (page_size_id);
369 g_free (page_size_name);
371 gl_debug (DEBUG_MEDIA_SELECT, "END");
374 /*--------------------------------------------------------------------------*/
375 /* PRIVATE. modify widget due to change in selection */
376 /*--------------------------------------------------------------------------*/
378 template_entry_changed_cb (GtkEntry *entry,
381 glWdgtMediaSelect *media_select = GL_WDGT_MEDIA_SELECT (user_data);
384 gl_debug (DEBUG_MEDIA_SELECT, "START");
386 /* Update mini_preview canvas & details with template */
387 gl_debug (DEBUG_MEDIA_SELECT, "template_entry = %p", entry);
388 name = gtk_editable_get_chars (GTK_EDITABLE (entry), 0, -1);
389 if ( strlen(name) ) {
390 gl_debug (DEBUG_MEDIA_SELECT, "name = \"%s\"", name);
391 gl_wdgt_mini_preview_set_label_by_name (GL_WDGT_MINI_PREVIEW (media_select->mini_preview),
393 gl_debug (DEBUG_MEDIA_SELECT, "m1");
394 details_update (media_select, name);
395 gl_debug (DEBUG_MEDIA_SELECT, "m2");
397 /* Emit our "changed" signal */
398 g_signal_emit (G_OBJECT (user_data),
399 wdgt_media_select_signals[CHANGED], 0);
403 gl_debug (DEBUG_MEDIA_SELECT, "END");
406 /*--------------------------------------------------------------------------*/
407 /* PRIVATE. modify widget due to change in prefs */
408 /*--------------------------------------------------------------------------*/
410 prefs_changed_cb (glPrefsModel *gl_prefs,
413 glWdgtMediaSelect *media_select = GL_WDGT_MEDIA_SELECT (user_data);
416 gl_debug (DEBUG_MEDIA_SELECT, "START");
418 /* Update mini_preview canvas & details with template */
419 name = gtk_editable_get_chars (GTK_EDITABLE (media_select->template_entry), 0, -1);
420 if ( strlen(name) ) {
421 gl_debug (DEBUG_MEDIA_SELECT, "name = \"%s\"", name);
422 details_update (media_select, name);
426 gl_debug (DEBUG_MEDIA_SELECT, "END");
429 /*--------------------------------------------------------------------------*/
430 /* PRIVATE. update "details" widgets from new template. */
431 /*--------------------------------------------------------------------------*/
433 details_update (glWdgtMediaSelect *media_select,
436 glTemplate *template;
439 const gchar *units_string;
440 gdouble units_per_point;
442 gl_debug (DEBUG_MEDIA_SELECT, "START");
444 units = gl_prefs_get_units ();
445 units_string = gl_prefs_get_units_string ();
446 units_per_point = gl_prefs_get_units_per_point ();
449 template = gl_template_from_name (name);
451 gtk_label_set_text (GTK_LABEL (media_select->desc_label),
452 template->description);
454 gtk_label_set_text (GTK_LABEL (media_select->sheet_size_label),
455 template->page_size);
457 text = get_layout_desc (template);
458 gtk_label_set_text (GTK_LABEL (media_select->number_label), text);
461 text = get_label_size_desc (template);
462 gtk_label_set_text (GTK_LABEL (media_select->label_size_label), text);
465 gl_template_free (template);
467 gl_debug (DEBUG_MEDIA_SELECT, "END");
470 /****************************************************************************/
471 /* query selected label template name. */
472 /****************************************************************************/
474 gl_wdgt_media_select_get_name (glWdgtMediaSelect *media_select)
476 gl_debug (DEBUG_MEDIA_SELECT, "");
478 gtk_editable_get_chars (GTK_EDITABLE (media_select->template_entry),
482 /****************************************************************************/
483 /* set selected label template name. */
484 /****************************************************************************/
486 gl_wdgt_media_select_set_name (glWdgtMediaSelect *media_select,
491 gl_debug (DEBUG_MEDIA_SELECT, "START");
493 g_signal_handlers_block_by_func (G_OBJECT(media_select->template_entry),
494 G_CALLBACK(template_entry_changed_cb),
496 gtk_editable_delete_text (GTK_EDITABLE (media_select->template_entry),
498 g_signal_handlers_unblock_by_func (G_OBJECT(media_select->template_entry),
499 G_CALLBACK(template_entry_changed_cb),
503 gtk_editable_insert_text (GTK_EDITABLE (media_select->template_entry),
504 name, strlen (name), &pos);
506 gl_debug (DEBUG_MEDIA_SELECT, "END");
509 /****************************************************************************/
510 /* query selected label template page size. */
511 /****************************************************************************/
513 gl_wdgt_media_select_get_page_size (glWdgtMediaSelect *media_select)
515 gchar *page_size_name, *page_size_id;
517 gl_debug (DEBUG_MEDIA_SELECT, "");
520 gtk_editable_get_chars (GTK_EDITABLE
521 (media_select->page_size_entry), 0, -1);
523 page_size_id = gl_paper_lookup_id_from_name (page_size_name);
525 g_free (page_size_name);
530 /****************************************************************************/
531 /* set selected label template page size. */
532 /****************************************************************************/
534 gl_wdgt_media_select_set_page_size (glWdgtMediaSelect *media_select,
538 gchar *page_size_name;
540 gl_debug (DEBUG_MEDIA_SELECT, "START");
542 page_size_name = gl_paper_lookup_name_from_id (page_size_id);
544 g_signal_handlers_block_by_func (G_OBJECT(media_select->page_size_entry),
545 G_CALLBACK(page_size_entry_changed_cb),
547 gtk_editable_delete_text (GTK_EDITABLE (media_select->page_size_entry),
549 g_signal_handlers_unblock_by_func (G_OBJECT(media_select->page_size_entry),
550 G_CALLBACK(page_size_entry_changed_cb),
554 gtk_editable_insert_text (GTK_EDITABLE (media_select->page_size_entry),
555 page_size_name, strlen (page_size_name), &pos);
557 g_free (page_size_name);
559 gl_debug (DEBUG_MEDIA_SELECT, "END");
562 /*--------------------------------------------------------------------------*/
563 /* PRIVATE. Get a description of the layout and number of labels. */
564 /*--------------------------------------------------------------------------*/
566 get_layout_desc (const glTemplate *template)
568 const glTemplateLabelType *label_type;
570 glTemplateLayout *layout;
573 label_type = gl_template_get_first_label_type (template);
575 n_labels = gl_template_get_n_labels (label_type);
577 if ( label_type->layouts->next == NULL ) {
578 layout = (glTemplateLayout *)label_type->layouts->data;
579 string = g_strdup_printf (_("%d x %d (%d per sheet)"),
580 layout->nx, layout->ny,
583 string = g_strdup_printf (_("%d per sheet"),
590 /*--------------------------------------------------------------------------*/
591 /* PRIVATE. Get label size description. */
592 /*--------------------------------------------------------------------------*/
594 get_label_size_desc (const glTemplate *template)
597 const gchar *units_string;
598 gdouble units_per_point;
599 const glTemplateLabelType *label_type;
600 gchar *string = NULL;
602 units = gl_prefs_get_units ();
603 units_string = gl_prefs_get_units_string ();
604 units_per_point = gl_prefs_get_units_per_point ();
606 label_type = gl_template_get_first_label_type (template);
608 switch (label_type->shape) {
609 case GL_TEMPLATE_SHAPE_RECT:
610 if ( units == GL_UNITS_INCHES ) {
613 xstr = gl_util_fraction (label_type->size.rect.w*units_per_point);
614 ystr = gl_util_fraction (label_type->size.rect.h*units_per_point);
615 string = g_strdup_printf (_("%s x %s %s"),
616 xstr, ystr, units_string);
620 string = g_strdup_printf (_("%.5g x %.5g %s"),
621 label_type->size.rect.w*units_per_point,
622 label_type->size.rect.h*units_per_point,
626 case GL_TEMPLATE_SHAPE_ROUND:
627 if ( units == GL_UNITS_INCHES ) {
630 dstr = gl_util_fraction (2.0*label_type->size.round.r*units_per_point);
631 string = g_strdup_printf (_("%s %s diameter"),
635 string = g_strdup_printf (_("%.5g %s diameter"),
636 2.0*label_type->size.round.r*units_per_point,
640 case GL_TEMPLATE_SHAPE_CD:
641 if ( units == GL_UNITS_INCHES ) {
644 dstr = gl_util_fraction (2.0*label_type->size.cd.r1*units_per_point);
645 string = g_strdup_printf (_("%s %s diameter"),
649 string = g_strdup_printf (_("%.5g %s diameter"),
650 2.0*label_type->size.cd.r1*units_per_point,