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 <glib/gi18n.h>
27 #include "wdgt-media-select.h"
29 #include "wdgt-mini-preview.h"
33 #include <libglabels/paper.h>
34 #include <libglabels/template.h>
38 #define WDGT_MINI_PREVIEW_WIDTH 160
39 #define WDGT_MINI_PREVIEW_HEIGHT 200
41 /*===========================================*/
43 /*===========================================*/
50 typedef void (*glWdgtMediaSelectSignal) (GObject * object, gpointer data);
52 /*===========================================*/
54 /*===========================================*/
56 static GObjectClass *parent_class;
58 static gint wdgt_media_select_signals[LAST_SIGNAL] = { 0 };
60 /*===========================================*/
61 /* Local function prototypes */
62 /*===========================================*/
64 static void gl_wdgt_media_select_class_init (glWdgtMediaSelectClass *class);
65 static void gl_wdgt_media_select_instance_init (glWdgtMediaSelect *media_select);
66 static void gl_wdgt_media_select_finalize (GObject *object);
68 static void gl_wdgt_media_select_construct (glWdgtMediaSelect *media_select);
70 static void page_size_entry_changed_cb (GtkEntry *entry,
72 static void template_entry_changed_cb (GtkEntry *entry,
74 static void prefs_changed_cb (glPrefsModel *gl_prefs,
77 static void details_update (glWdgtMediaSelect *media_select,
80 static gchar *get_layout_desc (const glTemplate *template);
81 static gchar *get_label_size_desc (const glTemplate *template);
83 /****************************************************************************/
84 /* Boilerplate Object stuff. */
85 /****************************************************************************/
87 gl_wdgt_media_select_get_type (void)
89 static GType type = 0;
92 static const GTypeInfo info = {
93 sizeof (glWdgtMediaSelectClass),
96 (GClassInitFunc) gl_wdgt_media_select_class_init,
99 sizeof (glWdgtMediaSelect),
101 (GInstanceInitFunc) gl_wdgt_media_select_instance_init,
105 type = g_type_register_static (GL_TYPE_HIG_VBOX,
106 "glWdgtMediaSelect", &info, 0);
113 gl_wdgt_media_select_class_init (glWdgtMediaSelectClass *class)
115 GObjectClass *object_class;
117 gl_debug (DEBUG_MEDIA_SELECT, "START");
119 object_class = (GObjectClass *) class;
121 parent_class = g_type_class_peek_parent (class);
123 object_class->finalize = gl_wdgt_media_select_finalize;
125 wdgt_media_select_signals[CHANGED] =
126 g_signal_new ("changed",
127 G_OBJECT_CLASS_TYPE(object_class),
129 G_STRUCT_OFFSET (glWdgtMediaSelectClass, changed),
131 gl_marshal_VOID__VOID,
134 gl_debug (DEBUG_MEDIA_SELECT, "END");
138 gl_wdgt_media_select_instance_init (glWdgtMediaSelect *media_select)
140 gl_debug (DEBUG_MEDIA_SELECT, "START");
142 media_select->page_size_entry = NULL;
143 media_select->template_entry = NULL;
145 media_select->mini_preview = NULL;
147 media_select->desc_label = NULL;
148 media_select->sheet_size_label = NULL;
149 media_select->number_label = NULL;
150 media_select->label_size_label = NULL;
152 gl_debug (DEBUG_MEDIA_SELECT, "END");
156 gl_wdgt_media_select_finalize (GObject *object)
158 glWdgtMediaSelect *media_select;
159 glWdgtMediaSelectClass *class;
161 gl_debug (DEBUG_MEDIA_SELECT, "START");
163 g_return_if_fail (object != NULL);
164 g_return_if_fail (GL_IS_WDGT_MEDIA_SELECT (object));
166 media_select = GL_WDGT_MEDIA_SELECT (object);
168 g_signal_handlers_disconnect_by_func (G_OBJECT(gl_prefs),
169 prefs_changed_cb, media_select);
171 G_OBJECT_CLASS (parent_class)->finalize (object);
173 gl_debug (DEBUG_MEDIA_SELECT, "END");
177 gl_wdgt_media_select_new (void)
179 glWdgtMediaSelect *media_select;
181 gl_debug (DEBUG_MEDIA_SELECT, "START");
183 media_select = g_object_new (gl_wdgt_media_select_get_type (), NULL);
185 gl_wdgt_media_select_construct (media_select);
187 gl_debug (DEBUG_MEDIA_SELECT, "END");
189 return GTK_WIDGET (media_select);
192 /*--------------------------------------------------------------------------*/
193 /* PRIVATE. Construct composite widget. */
194 /*--------------------------------------------------------------------------*/
196 gl_wdgt_media_select_construct (glWdgtMediaSelect *media_select)
198 GtkWidget *whbox, *wvbox, *wcombo, *wvbox1, *whbox1, *wlabel;
199 GtkSizeGroup *label_size_group;
201 GList *template_names, *page_sizes = NULL;
202 const gchar *page_size_id;
203 gchar *page_size_name;
205 gl_debug (DEBUG_MEDIA_SELECT, "START");
207 page_size_id = gl_prefs_get_page_size ();
208 page_size_name = gl_paper_lookup_name_from_id (page_size_id);
210 wvbox = GTK_WIDGET (media_select);
212 whbox = gl_hig_hbox_new ();
213 gl_hig_vbox_add_widget (GL_HIG_VBOX(wvbox), whbox);
215 /* Page size selection control */
216 gl_debug (DEBUG_MEDIA_SELECT, "Creating page size combo...");
217 wcombo = gtk_combo_new ();
218 page_sizes = gl_paper_get_name_list ();
219 gtk_combo_set_popdown_strings (GTK_COMBO (wcombo), page_sizes);
220 gl_paper_free_name_list (page_sizes);
221 media_select->page_size_entry = GTK_COMBO (wcombo)->entry;
222 gtk_entry_set_editable (GTK_ENTRY (media_select->page_size_entry),
224 gtk_combo_set_value_in_list (GTK_COMBO(wcombo), TRUE, FALSE);
225 gtk_widget_set_size_request (media_select->page_size_entry, 100, -1);
226 gtk_entry_set_text (GTK_ENTRY (media_select->page_size_entry),
228 gl_hig_hbox_add_widget (GL_HIG_HBOX(whbox), wcombo);
230 /* Actual selection control */
231 gl_debug (DEBUG_MEDIA_SELECT, "Creating template combo...");
232 gl_debug (DEBUG_MEDIA_SELECT, "page_size_name = %s", page_size_name);
233 template_names = gl_template_get_name_list (page_size_id);
234 media_select->template_combo = gtk_combo_new ();
235 gtk_combo_set_popdown_strings (GTK_COMBO (media_select->template_combo),
237 media_select->template_entry =
238 GTK_COMBO (media_select->template_combo)->entry;
239 gtk_entry_set_editable (GTK_ENTRY (media_select->template_entry),
241 gtk_combo_set_value_in_list (GTK_COMBO(media_select->template_combo),
243 gtk_widget_set_size_request (media_select->template_entry, 400, -1);
244 gtk_entry_set_text (GTK_ENTRY (media_select->template_entry),
245 template_names->data);
246 gl_hig_hbox_add_widget (GL_HIG_HBOX(whbox),
247 media_select->template_combo);
248 gl_template_free_name_list (template_names);
250 whbox = gl_hig_hbox_new ();
251 gl_hig_vbox_add_widget (GL_HIG_VBOX(wvbox), whbox);
253 /* mini_preview canvas */
254 gl_debug (DEBUG_MEDIA_SELECT, "Creating mini preview...");
255 media_select->mini_preview = gl_wdgt_mini_preview_new ( WDGT_MINI_PREVIEW_HEIGHT,
256 WDGT_MINI_PREVIEW_WIDTH);
257 gl_hig_hbox_add_widget (GL_HIG_HBOX(whbox),
258 media_select->mini_preview);
260 /* ---- Information area ---- */
261 wvbox1 = gl_hig_vbox_new (GL_HIG_VBOX_INNER);
262 gl_hig_hbox_add_widget (GL_HIG_HBOX(whbox), wvbox1);
263 label_size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
266 gl_hig_vbox_add_widget (GL_HIG_VBOX(wvbox1), gtk_label_new (""));
268 /* Description line */
269 whbox1 = gl_hig_hbox_new ();
270 gl_hig_vbox_add_widget (GL_HIG_VBOX(wvbox1), whbox1);
271 wlabel = gtk_label_new (_("Description:"));
272 gtk_size_group_add_widget (label_size_group, wlabel);
273 gtk_misc_set_alignment (GTK_MISC(wlabel), 0.0, 0.0);
274 gl_hig_hbox_add_widget (GL_HIG_HBOX(whbox1), wlabel);
275 media_select->desc_label = gtk_label_new ("");
276 gl_hig_hbox_add_widget (GL_HIG_HBOX(whbox1), media_select->desc_label);
279 whbox1 = gl_hig_hbox_new ();
280 gl_hig_vbox_add_widget (GL_HIG_VBOX(wvbox1), whbox1);
281 wlabel = gtk_label_new (_("Page size:"));
282 gtk_size_group_add_widget (label_size_group, wlabel);
283 gtk_misc_set_alignment (GTK_MISC(wlabel), 0.0, 0.0);
284 gl_hig_hbox_add_widget (GL_HIG_HBOX(whbox1), wlabel);
285 media_select->sheet_size_label = gtk_label_new ("");
286 gl_hig_hbox_add_widget (GL_HIG_HBOX(whbox1),
287 media_select->sheet_size_label);
289 /* Label size line */
290 whbox1 = gl_hig_hbox_new ();
291 gl_hig_vbox_add_widget (GL_HIG_VBOX(wvbox1), whbox1);
292 wlabel = gtk_label_new (_("Label size:"));
293 gtk_size_group_add_widget (label_size_group, wlabel);
294 gtk_misc_set_alignment (GTK_MISC(wlabel), 0.0, 0.0);
295 gl_hig_hbox_add_widget (GL_HIG_HBOX(whbox1), wlabel);
296 media_select->label_size_label = gtk_label_new ("");
297 gl_hig_hbox_add_widget (GL_HIG_HBOX(whbox1),
298 media_select->label_size_label);
301 whbox1 = gl_hig_hbox_new ();
302 gl_hig_vbox_add_widget (GL_HIG_VBOX(wvbox1), whbox1);
303 wlabel = gtk_label_new (_("Layout:"));
304 gtk_size_group_add_widget (label_size_group, wlabel);
305 gtk_misc_set_alignment (GTK_MISC(wlabel), 0.0, 0.0);
306 gl_hig_hbox_add_widget (GL_HIG_HBOX(whbox1), wlabel);
307 media_select->number_label = gtk_label_new ("");
308 gl_hig_hbox_add_widget (GL_HIG_HBOX(whbox1),
309 media_select->number_label);
311 /* Update mini_preview and details from default template */
313 gl_debug (DEBUG_MEDIA_SELECT, "template_entry = %p",
314 media_select->template_entry);
316 gtk_editable_get_chars (GTK_EDITABLE (media_select->template_entry),
318 gl_debug (DEBUG_MEDIA_SELECT, "name = \"%s\"", name);
319 gl_wdgt_mini_preview_set_label_by_name (GL_WDGT_MINI_PREVIEW (media_select->mini_preview),
321 details_update (media_select, name);
324 /* Connect signals to controls */
325 g_signal_connect (G_OBJECT (media_select->page_size_entry), "changed",
326 G_CALLBACK (page_size_entry_changed_cb),
328 g_signal_connect (G_OBJECT (media_select->template_entry), "changed",
329 G_CALLBACK (template_entry_changed_cb),
331 g_signal_connect (G_OBJECT (gl_prefs), "changed",
332 G_CALLBACK (prefs_changed_cb),
335 g_free (page_size_name);
337 gl_debug (DEBUG_MEDIA_SELECT, "END");
340 /*--------------------------------------------------------------------------*/
341 /* PRIVATE. modify widget due to change in selection */
342 /*--------------------------------------------------------------------------*/
344 page_size_entry_changed_cb (GtkEntry *entry,
347 glWdgtMediaSelect *media_select = GL_WDGT_MEDIA_SELECT (user_data);
348 gchar *page_size_name, *page_size_id;
349 GList *template_names;
351 gl_debug (DEBUG_MEDIA_SELECT, "START");
354 /* Update template selections for new page size */
355 page_size_name = gtk_editable_get_chars (GTK_EDITABLE (entry), 0, -1);
356 if ( strlen(page_size_name) ) {
357 gl_debug (DEBUG_MEDIA_SELECT, "page_size_name = \"%s\"", page_size_name);
358 page_size_id = gl_paper_lookup_id_from_name (page_size_name);
359 template_names = gl_template_get_name_list (page_size_id);
360 if (template_names == NULL) {
361 template_names = g_list_append (template_names, g_strdup(""));
363 gtk_combo_set_popdown_strings (GTK_COMBO (media_select->template_combo),
365 gtk_entry_set_text (GTK_ENTRY (media_select->template_entry),
366 template_names->data);
367 gl_template_free_name_list (template_names);
368 g_free (page_size_id);
370 g_free (page_size_name);
372 gl_debug (DEBUG_MEDIA_SELECT, "END");
375 /*--------------------------------------------------------------------------*/
376 /* PRIVATE. modify widget due to change in selection */
377 /*--------------------------------------------------------------------------*/
379 template_entry_changed_cb (GtkEntry *entry,
382 glWdgtMediaSelect *media_select = GL_WDGT_MEDIA_SELECT (user_data);
385 gl_debug (DEBUG_MEDIA_SELECT, "START");
387 /* Update mini_preview canvas & details with template */
388 gl_debug (DEBUG_MEDIA_SELECT, "template_entry = %p", entry);
389 name = gtk_editable_get_chars (GTK_EDITABLE (entry), 0, -1);
390 if ( strlen(name) ) {
391 gl_debug (DEBUG_MEDIA_SELECT, "name = \"%s\"", name);
392 gl_wdgt_mini_preview_set_label_by_name (GL_WDGT_MINI_PREVIEW (media_select->mini_preview),
394 gl_debug (DEBUG_MEDIA_SELECT, "m1");
395 details_update (media_select, name);
396 gl_debug (DEBUG_MEDIA_SELECT, "m2");
398 /* Emit our "changed" signal */
399 g_signal_emit (G_OBJECT (user_data),
400 wdgt_media_select_signals[CHANGED], 0);
404 gl_debug (DEBUG_MEDIA_SELECT, "END");
407 /*--------------------------------------------------------------------------*/
408 /* PRIVATE. modify widget due to change in prefs */
409 /*--------------------------------------------------------------------------*/
411 prefs_changed_cb (glPrefsModel *gl_prefs,
414 glWdgtMediaSelect *media_select = GL_WDGT_MEDIA_SELECT (user_data);
417 gl_debug (DEBUG_MEDIA_SELECT, "START");
419 /* Update mini_preview canvas & details with template */
420 name = gtk_editable_get_chars (GTK_EDITABLE (media_select->template_entry), 0, -1);
421 if ( strlen(name) ) {
422 gl_debug (DEBUG_MEDIA_SELECT, "name = \"%s\"", name);
423 details_update (media_select, name);
427 gl_debug (DEBUG_MEDIA_SELECT, "END");
430 /*--------------------------------------------------------------------------*/
431 /* PRIVATE. update "details" widgets from new template. */
432 /*--------------------------------------------------------------------------*/
434 details_update (glWdgtMediaSelect *media_select,
437 glTemplate *template;
440 const gchar *units_string;
441 gdouble units_per_point;
443 gl_debug (DEBUG_MEDIA_SELECT, "START");
445 units = gl_prefs_get_units ();
446 units_string = gl_prefs_get_units_string ();
447 units_per_point = gl_prefs_get_units_per_point ();
450 template = gl_template_from_name (name);
452 gtk_label_set_text (GTK_LABEL (media_select->desc_label),
453 template->description);
455 gtk_label_set_text (GTK_LABEL (media_select->sheet_size_label),
456 template->page_size);
458 text = get_layout_desc (template);
459 gtk_label_set_text (GTK_LABEL (media_select->number_label), text);
462 text = get_label_size_desc (template);
463 gtk_label_set_text (GTK_LABEL (media_select->label_size_label), text);
466 gl_template_free (template);
468 gl_debug (DEBUG_MEDIA_SELECT, "END");
471 /****************************************************************************/
472 /* query selected label template name. */
473 /****************************************************************************/
475 gl_wdgt_media_select_get_name (glWdgtMediaSelect *media_select)
477 gl_debug (DEBUG_MEDIA_SELECT, "");
479 gtk_editable_get_chars (GTK_EDITABLE (media_select->template_entry),
483 /****************************************************************************/
484 /* set selected label template name. */
485 /****************************************************************************/
487 gl_wdgt_media_select_set_name (glWdgtMediaSelect *media_select,
492 gl_debug (DEBUG_MEDIA_SELECT, "START");
494 g_signal_handlers_block_by_func (G_OBJECT(media_select->template_entry),
495 G_CALLBACK(template_entry_changed_cb),
497 gtk_editable_delete_text (GTK_EDITABLE (media_select->template_entry),
499 g_signal_handlers_unblock_by_func (G_OBJECT(media_select->template_entry),
500 G_CALLBACK(template_entry_changed_cb),
504 gtk_editable_insert_text (GTK_EDITABLE (media_select->template_entry),
505 name, strlen (name), &pos);
507 gl_debug (DEBUG_MEDIA_SELECT, "END");
510 /****************************************************************************/
511 /* query selected label template page size. */
512 /****************************************************************************/
514 gl_wdgt_media_select_get_page_size (glWdgtMediaSelect *media_select)
516 gchar *page_size_name, *page_size_id;
518 gl_debug (DEBUG_MEDIA_SELECT, "");
521 gtk_editable_get_chars (GTK_EDITABLE
522 (media_select->page_size_entry), 0, -1);
524 page_size_id = gl_paper_lookup_id_from_name (page_size_name);
526 g_free (page_size_name);
531 /****************************************************************************/
532 /* set selected label template page size. */
533 /****************************************************************************/
535 gl_wdgt_media_select_set_page_size (glWdgtMediaSelect *media_select,
539 gchar *page_size_name;
541 gl_debug (DEBUG_MEDIA_SELECT, "START");
543 page_size_name = gl_paper_lookup_name_from_id (page_size_id);
545 g_signal_handlers_block_by_func (G_OBJECT(media_select->page_size_entry),
546 G_CALLBACK(page_size_entry_changed_cb),
548 gtk_editable_delete_text (GTK_EDITABLE (media_select->page_size_entry),
550 g_signal_handlers_unblock_by_func (G_OBJECT(media_select->page_size_entry),
551 G_CALLBACK(page_size_entry_changed_cb),
555 gtk_editable_insert_text (GTK_EDITABLE (media_select->page_size_entry),
556 page_size_name, strlen (page_size_name), &pos);
558 g_free (page_size_name);
560 gl_debug (DEBUG_MEDIA_SELECT, "END");
563 /*--------------------------------------------------------------------------*/
564 /* PRIVATE. Get a description of the layout and number of labels. */
565 /*--------------------------------------------------------------------------*/
567 get_layout_desc (const glTemplate *template)
569 const glTemplateLabelType *label_type;
571 glTemplateLayout *layout;
574 label_type = gl_template_get_first_label_type (template);
576 n_labels = gl_template_get_n_labels (label_type);
578 if ( label_type->layouts->next == NULL ) {
579 layout = (glTemplateLayout *)label_type->layouts->data;
580 string = g_strdup_printf (_("%d x %d (%d per sheet)"),
581 layout->nx, layout->ny,
584 string = g_strdup_printf (_("%d per sheet"),
591 /*--------------------------------------------------------------------------*/
592 /* PRIVATE. Get label size description. */
593 /*--------------------------------------------------------------------------*/
595 get_label_size_desc (const glTemplate *template)
598 const gchar *units_string;
599 gdouble units_per_point;
600 const glTemplateLabelType *label_type;
601 gchar *string = NULL;
603 units = gl_prefs_get_units ();
604 units_string = gl_prefs_get_units_string ();
605 units_per_point = gl_prefs_get_units_per_point ();
607 label_type = gl_template_get_first_label_type (template);
609 switch (label_type->shape) {
610 case GL_TEMPLATE_SHAPE_RECT:
611 if ( units == GL_UNITS_INCH ) {
614 xstr = gl_util_fraction (label_type->size.rect.w*units_per_point);
615 ystr = gl_util_fraction (label_type->size.rect.h*units_per_point);
616 string = g_strdup_printf (_("%s x %s %s"),
617 xstr, ystr, units_string);
621 string = g_strdup_printf (_("%.5g x %.5g %s"),
622 label_type->size.rect.w*units_per_point,
623 label_type->size.rect.h*units_per_point,
627 case GL_TEMPLATE_SHAPE_ROUND:
628 if ( units == GL_UNITS_INCH ) {
631 dstr = gl_util_fraction (2.0*label_type->size.round.r*units_per_point);
632 string = g_strdup_printf (_("%s %s diameter"),
636 string = g_strdup_printf (_("%.5g %s diameter"),
637 2.0*label_type->size.round.r*units_per_point,
641 case GL_TEMPLATE_SHAPE_CD:
642 if ( units == GL_UNITS_INCH ) {
645 dstr = gl_util_fraction (2.0*label_type->size.cd.r1*units_per_point);
646 string = g_strdup_printf (_("%s %s diameter"),
650 string = g_strdup_printf (_("%.5g %s diameter"),
651 2.0*label_type->size.cd.r1*units_per_point,