]> git.sur5r.net Git - glabels/blob - glabels2/src/view-barcode.c
Made set_size and get_size into child methods for label-object, and construct_dialog...
[glabels] / glabels2 / src / view-barcode.c
1 /*
2  *  (GLABELS) Label and Business Card Creation program for GNOME
3  *
4  *  view_barcode.c:  GLabels label barcode object widget
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 <glib.h>
24
25 #include <libgnomeprint/gnome-glyphlist.h>
26
27 #include "view-barcode.h"
28 #include "canvas-hacktext.h"
29
30 #include "view-highlight.h"
31
32 #include "wdgt-bc-data.h"
33 #include "wdgt-bc-props.h"
34 #include "wdgt-bc-style.h"
35 #include "wdgt-position.h"
36 #include "color.h"
37 #include "prefs.h"
38
39 #include "pixmaps/cursor_barcode.xbm"
40 #include "pixmaps/cursor_barcode_mask.xbm"
41
42 #include "debug.h"
43
44 /*========================================================*/
45 /* Private macros and constants.                          */
46 /*========================================================*/
47
48 /*========================================================*/
49 /* Private types.                                         */
50 /*========================================================*/
51
52 struct _glViewBarcodePrivate {
53
54         GList     *item_list;
55
56         /* Page 0 widgets */
57         GtkWidget *bc_data;
58
59         /* Page 1 widgets */
60         GtkWidget *bc_props;
61         GtkWidget *bc_style;
62
63         /* Page 2 widgets */
64         GtkWidget *position;
65 };
66
67 /*========================================================*/
68 /* Private globals.                                       */
69 /*========================================================*/
70
71 static glViewObjectClass *parent_class = NULL;
72
73
74 /*========================================================*/
75 /* Private function prototypes.                           */
76 /*========================================================*/
77
78 static void      gl_view_barcode_class_init    (glViewBarcodeClass *klass);
79 static void      gl_view_barcode_instance_init (glViewBarcode  *view_barcode);
80 static void      gl_view_barcode_finalize      (GObject        *object);
81
82 static void      update_view_barcode_cb        (glLabelObject  *object,
83                                                 glViewBarcode  *view_barcode);
84
85 static GtkWidget *construct_properties_dialog  (glViewObject   *view_object);
86
87 static void      response_cb                   (GtkDialog      *dialog,
88                                                 gint            response,
89                                                 glViewBarcode  *view_barcode);
90
91 static void      bc_data_changed_cb            (glWdgtBCData   *bc_data,
92                                                 glViewBarcode  *view_barcode);
93
94 static void      bc_props_changed_cb           (glWdgtBCProps  *bc_props,
95                                                 glViewBarcode  *view_barcode);
96
97 static void      bc_style_changed_cb           (glWdgtBCStyle  *bc_style,
98                                                 glViewBarcode  *view_barcode);
99
100 static void      position_changed_cb           (glWdgtPosition *position,
101                                                 glViewBarcode  *view_barcode);
102
103 static void      update_dialog_cb              (glLabelObject  *object,
104                                                 glViewBarcode  *view_barcode);
105
106 static void      update_dialog_from_move_cb    (glLabelObject  *object,
107                                                 gdouble         dx,
108                                                 gdouble         dy,
109                                                 glViewBarcode  *view_barcode);
110
111 static void      draw_barcode                  (glViewBarcode  *view_barcode);
112
113 \f
114 /*****************************************************************************/
115 /* Boilerplate object stuff.                                                 */
116 /*****************************************************************************/
117 GType
118 gl_view_barcode_get_type (void)
119 {
120         static GType type = 0;
121
122         if (!type) {
123                 GTypeInfo info = {
124                         sizeof (glViewBarcodeClass),
125                         NULL,
126                         NULL,
127                         (GClassInitFunc) gl_view_barcode_class_init,
128                         NULL,
129                         NULL,
130                         sizeof (glViewBarcode),
131                         0,
132                         (GInstanceInitFunc) gl_view_barcode_instance_init,
133                 };
134
135                 type = g_type_register_static (GL_TYPE_VIEW_OBJECT,
136                                                "glViewBarcode", &info, 0);
137         }
138
139         return type;
140 }
141
142 static void
143 gl_view_barcode_class_init (glViewBarcodeClass *klass)
144 {
145         GObjectClass      *object_class      = (GObjectClass *) klass;
146         glViewObjectClass *view_object_class = (glViewObjectClass *) klass;
147
148         gl_debug (DEBUG_VIEW, "START");
149
150         parent_class = g_type_class_peek_parent (klass);
151
152         object_class->finalize = gl_view_barcode_finalize;
153
154         view_object_class->construct_dialog = construct_properties_dialog;
155
156         gl_debug (DEBUG_VIEW, "END");
157 }
158
159 static void
160 gl_view_barcode_instance_init (glViewBarcode *view_barcode)
161 {
162         gl_debug (DEBUG_VIEW, "START");
163
164         view_barcode->private = g_new0 (glViewBarcodePrivate, 1);
165
166         gl_debug (DEBUG_VIEW, "END");
167 }
168
169 static void
170 gl_view_barcode_finalize (GObject *object)
171 {
172         glLabel       *parent;
173
174         gl_debug (DEBUG_VIEW, "START");
175
176         g_return_if_fail (object && GL_IS_VIEW_BARCODE (object));
177
178         G_OBJECT_CLASS (parent_class)->finalize (object);
179
180         gl_debug (DEBUG_VIEW, "END");
181 }
182
183 /*****************************************************************************/
184 /* NEW barcode object view.                                                  */
185 /*****************************************************************************/
186 glViewObject *
187 gl_view_barcode_new (glLabelBarcode *object,
188                      glView         *view)
189 {
190         glViewBarcode      *view_barcode;
191         GtkMenu            *menu;
192
193         gl_debug (DEBUG_VIEW, "START");
194         g_return_if_fail (object && GL_IS_LABEL_BARCODE (object));
195         g_return_if_fail (view && GL_IS_VIEW (view));
196         
197         view_barcode = g_object_new (gl_view_barcode_get_type(), NULL);
198
199         gl_view_object_set_view (GL_VIEW_OBJECT(view_barcode), view);
200         gl_view_object_set_object (GL_VIEW_OBJECT(view_barcode),
201                                    GL_LABEL_OBJECT(object),
202                                    GL_VIEW_HIGHLIGHT_SIMPLE);
203
204         /* Create analogous canvas items. */
205         draw_barcode (view_barcode);
206
207         g_signal_connect (G_OBJECT (object), "changed",
208                           G_CALLBACK (update_view_barcode_cb), view_barcode);
209
210         gl_debug (DEBUG_VIEW, "END");
211
212         return GL_VIEW_OBJECT (view_barcode);
213 }
214
215 /*---------------------------------------------------------------------------*/
216 /* PRIVATE. label object "changed" callback.                                 */
217 /*---------------------------------------------------------------------------*/
218 static void
219 update_view_barcode_cb (glLabelObject *object,
220                         glViewBarcode *view_barcode)
221 {
222         glView             *view;
223         GnomeCanvasItem    *group;
224
225         gl_debug (DEBUG_VIEW, "START");
226
227         view = gl_view_object_get_view (GL_VIEW_OBJECT(view_barcode));
228
229         /* Adjust appearance of analogous canvas items. */
230         draw_barcode (view_barcode);
231
232         gl_debug (DEBUG_VIEW, "END");
233 }
234
235 /*****************************************************************************/
236 /* Create a properties dialog for a barcode object.                          */
237 /*****************************************************************************/
238 static GtkWidget *
239 construct_properties_dialog (glViewObject *view_object)
240 {
241         glViewBarcode      *view_barcode = (glViewBarcode *)view_object;
242         GtkWidget          *dialog, *wsection;
243         glLabelObject      *object;
244         gdouble            x, y, w, h, label_width, label_height;
245         glTextNode         *text_node;
246         glBarcodeStyle     style;
247         gboolean           text_flag;
248         guint              color;
249         gdouble            scale;
250         glMerge            *merge;
251         GtkSizeGroup       *label_size_group;
252         GtkWidget          *window;
253
254         gl_debug (DEBUG_VIEW, "START");
255
256         /* retrieve object and query parameters */
257         object = gl_view_object_get_object (view_object);
258         gl_label_object_get_position (GL_LABEL_OBJECT(object), &x, &y);
259         text_node = gl_label_barcode_get_data(GL_LABEL_BARCODE(object));
260         gl_label_barcode_get_props (GL_LABEL_BARCODE(object),
261                                     &style, &text_flag, &color, &scale);
262         gl_label_get_size (GL_LABEL(object->parent),
263                            &label_width, &label_height);
264         merge = gl_label_get_merge (GL_LABEL(object->parent));
265
266         /*-----------------------------------------------------------------*/
267         /* Build dialog.                                                   */
268         /*-----------------------------------------------------------------*/
269         window = gtk_widget_get_toplevel (
270                 GTK_WIDGET(gl_view_object_get_view(view_object)));
271         dialog = gl_hig_dialog_new_with_buttons ( _("Edit barcode object properties"),
272                                                   GTK_WINDOW (window),
273                                                   GTK_DIALOG_DESTROY_WITH_PARENT,
274                                                   GTK_STOCK_CLOSE,
275                                                            GTK_RESPONSE_CLOSE,
276                                                   NULL );
277         gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
278         g_signal_connect (G_OBJECT (dialog), "response",
279                           G_CALLBACK (response_cb), view_object);
280
281         label_size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
282
283         /*---------------------------*/
284         /* Data section              */
285         /*---------------------------*/
286         wsection = gl_hig_category_new (_("Data"));
287         gl_hig_dialog_add_widget (GL_HIG_DIALOG(dialog), wsection);
288
289         /* barcode data */
290         view_barcode->private->bc_data =
291                 gl_wdgt_bc_data_new (merge->field_defs);
292         gl_wdgt_bc_data_set_label_size_group (GL_WDGT_BC_DATA(view_barcode->private->bc_data),
293                                               label_size_group);
294         gl_wdgt_bc_data_set_data (GL_WDGT_BC_DATA(view_barcode->private->bc_data),
295                                   (merge->type != GL_MERGE_NONE),
296                                   text_node);
297         gl_hig_category_add_widget (GL_HIG_CATEGORY(wsection),
298                                     view_barcode->private->bc_data);
299         g_signal_connect ( G_OBJECT(view_barcode->private->bc_data),
300                            "changed", G_CALLBACK (bc_data_changed_cb),
301                            view_barcode);
302
303
304         /*---------------------------*/
305         /* Appearance section        */
306         /*---------------------------*/
307         wsection = gl_hig_category_new (_("Properties"));
308         gl_hig_dialog_add_widget (GL_HIG_DIALOG(dialog), wsection);
309
310         /* Barcode style widget */
311         view_barcode->private->bc_style = gl_wdgt_bc_style_new ();
312         gl_wdgt_bc_style_set_label_size_group (GL_WDGT_BC_STYLE(view_barcode->private->bc_style),
313                                                label_size_group);
314         gl_wdgt_bc_style_set_params (GL_WDGT_BC_STYLE (view_barcode->private->bc_style),
315                                      style, text_flag);
316         gl_hig_category_add_widget (GL_HIG_CATEGORY(wsection),
317                                     view_barcode->private->bc_style);
318         g_signal_connect (G_OBJECT (view_barcode->private->bc_style),
319                           "changed", G_CALLBACK (bc_style_changed_cb),
320                           view_barcode);
321
322         /* barcode props entry */
323         gl_debug (DEBUG_VIEW, "Creating props entry...");
324         view_barcode->private->bc_props = gl_wdgt_bc_props_new ();
325         gl_wdgt_bc_props_set_label_size_group (GL_WDGT_BC_PROPS(view_barcode->private->bc_props),
326                                                label_size_group);
327         gl_wdgt_bc_props_set_params (GL_WDGT_BC_PROPS(view_barcode->private->bc_props),
328                                      scale, color);
329         gl_hig_category_add_widget (GL_HIG_CATEGORY(wsection),
330                                     view_barcode->private->bc_props);
331         g_signal_connect ( G_OBJECT(view_barcode->private->bc_props),
332                            "changed", G_CALLBACK (bc_props_changed_cb),
333                            view_barcode);
334
335
336         /*----------------------------*/
337         /* Position section           */
338         /*----------------------------*/
339         wsection = gl_hig_category_new (_("Position"));
340         gl_hig_dialog_add_widget (GL_HIG_DIALOG(dialog), wsection);
341
342         /* ------ Position Frame ------ */
343         view_barcode->private->position = gl_wdgt_position_new ();
344         gl_wdgt_position_set_label_size_group (GL_WDGT_POSITION(view_barcode->private->position),
345                                                label_size_group);
346         gl_wdgt_position_set_params (GL_WDGT_POSITION (view_barcode->private->position),
347                                      x, y,
348                                      label_width, label_height);
349         gl_hig_category_add_widget (GL_HIG_CATEGORY(wsection),
350                                     view_barcode->private->position);
351         g_signal_connect (G_OBJECT (view_barcode->private->position),
352                           "changed",
353                           G_CALLBACK(position_changed_cb), view_barcode);
354
355
356         /*----------------------------*/
357         /* Track object changes.      */
358         /*----------------------------*/
359         g_signal_connect (G_OBJECT (object), "changed",
360                           G_CALLBACK (update_dialog_cb), view_barcode);
361         g_signal_connect (G_OBJECT (object), "moved",
362                           G_CALLBACK (update_dialog_from_move_cb),
363                           view_barcode);
364
365         gl_debug (DEBUG_VIEW, "END");
366
367         return dialog;
368 }
369
370 /*---------------------------------------------------------------------------*/
371 /* PRIVATE.  "Response" callback.                                            */
372 /*---------------------------------------------------------------------------*/
373 static void
374 response_cb (GtkDialog     *dialog,
375              gint          response,
376              glViewBarcode   *view_barcode)
377 {
378         gl_debug (DEBUG_VIEW, "START");
379
380         g_return_if_fail(dialog != NULL);
381         g_return_if_fail(GTK_IS_DIALOG(dialog));
382
383         switch(response) {
384         case GTK_RESPONSE_CLOSE:
385                 gtk_widget_hide (GTK_WIDGET(dialog));
386                 break;
387         case GTK_RESPONSE_DELETE_EVENT:
388                 break;
389         default:
390                 g_print ("response = %d", response);
391                 g_assert_not_reached();
392         }
393
394         gl_debug (DEBUG_VIEW, "END");
395 }
396
397 /*---------------------------------------------------------------------------*/
398 /* PRIVATE.  barcode data "changed" callback.                                */
399 /*---------------------------------------------------------------------------*/
400 static void
401 bc_data_changed_cb (glWdgtBCData        *bc_data,
402                     glViewBarcode       *view_barcode)
403 {
404         glLabelObject    *object;
405         glTextNode       *text_node;
406
407         gl_debug (DEBUG_VIEW, "START");
408
409         object = gl_view_object_get_object (GL_VIEW_OBJECT(view_barcode));
410
411         text_node = gl_wdgt_bc_data_get_data (bc_data);
412
413         g_signal_handlers_block_by_func (G_OBJECT(object),
414                                          update_dialog_cb, view_barcode);
415         gl_label_barcode_set_data (GL_LABEL_BARCODE(object), text_node);
416         g_signal_handlers_unblock_by_func (G_OBJECT(object),
417                                            update_dialog_cb, view_barcode);
418
419         gl_text_node_free (&text_node);
420
421         gl_debug (DEBUG_VIEW, "END");
422 }
423
424 /*---------------------------------------------------------------------------*/
425 /* PRIVATE.  barcode props "changed" callback.                               */
426 /*---------------------------------------------------------------------------*/
427 static void
428 bc_props_changed_cb (glWdgtBCProps  *text_props,
429                      glViewBarcode  *view_barcode)
430 {
431         glLabelObject      *object;
432         glBarcodeStyle     style;
433         gboolean           text_flag;
434         guint              color;
435         gdouble            scale;
436
437
438         gl_debug (DEBUG_VIEW, "START");
439
440         object = gl_view_object_get_object (GL_VIEW_OBJECT(view_barcode));
441
442         gl_label_barcode_get_props (GL_LABEL_BARCODE(object),
443                                     &style, &text_flag, &color, &scale);
444         gl_wdgt_bc_props_get_params (text_props, &scale, &color);
445
446         g_signal_handlers_block_by_func (G_OBJECT(object),
447                                          update_dialog_cb, view_barcode);
448         gl_label_barcode_set_props (GL_LABEL_BARCODE(object),
449                                     style, text_flag, color, scale);
450         g_signal_handlers_unblock_by_func (G_OBJECT(object),
451                                            update_dialog_cb, view_barcode);
452
453         gl_debug (DEBUG_VIEW, "END");
454 }
455
456 /*---------------------------------------------------------------------------*/
457 /* PRIVATE.  barcode style "changed" callback.                               */
458 /*---------------------------------------------------------------------------*/
459 static void
460 bc_style_changed_cb (glWdgtBCStyle  *bc_style,
461                      glViewBarcode  *view_barcode)
462 {
463         glLabelObject      *object;
464         glBarcodeStyle     style;
465         gboolean           text_flag;
466         guint              color;
467         gdouble            scale;
468
469
470         gl_debug (DEBUG_VIEW, "START");
471
472         object = gl_view_object_get_object (GL_VIEW_OBJECT(view_barcode));
473
474         gl_label_barcode_get_props (GL_LABEL_BARCODE(object),
475                                     &style, &text_flag, &color, &scale);
476         gl_wdgt_bc_style_get_params (bc_style, &style, &text_flag);
477
478         g_signal_handlers_block_by_func (G_OBJECT(object),
479                                          update_dialog_cb, view_barcode);
480         gl_label_barcode_set_props (GL_LABEL_BARCODE(object),
481                                     style, text_flag, color, scale);
482         g_signal_handlers_unblock_by_func (G_OBJECT(object),
483                                            update_dialog_cb, view_barcode);
484
485         gl_debug (DEBUG_VIEW, "END");
486 }
487
488 /*---------------------------------------------------------------------------*/
489 /* PRIVATE.  position "changed" callback.                                    */
490 /*---------------------------------------------------------------------------*/
491 static void
492 position_changed_cb (glWdgtPosition     *position,
493                      glViewBarcode         *view_barcode)
494 {
495         glLabelObject      *object;
496         gdouble            x, y;
497
498         gl_debug (DEBUG_VIEW, "START");
499
500         gl_wdgt_position_get_position (GL_WDGT_POSITION (position), &x, &y);
501
502         object = gl_view_object_get_object (GL_VIEW_OBJECT(view_barcode));
503
504         g_signal_handlers_block_by_func (G_OBJECT(object),
505                                          update_dialog_cb, view_barcode);
506         gl_label_object_set_position (GL_LABEL_OBJECT(object), x, y);
507         g_signal_handlers_unblock_by_func (G_OBJECT(object),
508                                            update_dialog_cb, view_barcode);
509
510         gl_debug (DEBUG_VIEW, "END");
511 }
512
513 /*---------------------------------------------------------------------------*/
514 /* PRIVATE. label object "changed" callback.                                 */
515 /*---------------------------------------------------------------------------*/
516 static void
517 update_dialog_cb (glLabelObject  *object,
518                   glViewBarcode     *view_barcode)
519 {
520         gdouble            x, y;
521         glTextNode         *text_node;
522         glBarcodeStyle     style;
523         gboolean           text_flag;
524         guint              color;
525         gdouble            scale;
526         glMerge            *merge;
527
528         gl_debug (DEBUG_VIEW, "START");
529
530         /* Query properties of object. */
531         text_node = gl_label_barcode_get_data(GL_LABEL_BARCODE(object));
532         gl_label_barcode_get_props (GL_LABEL_BARCODE(object),
533                                     &style, &text_flag, &color, &scale);
534         gl_label_object_get_position (GL_LABEL_OBJECT(object), &x, &y);
535         merge = gl_label_get_merge (GL_LABEL(object->parent));
536
537         /* Block widget handlers to prevent recursion */
538         g_signal_handlers_block_by_func (G_OBJECT(view_barcode->private->bc_data),
539                                          bc_data_changed_cb, view_barcode);
540         g_signal_handlers_block_by_func (G_OBJECT(view_barcode->private->bc_props),
541                                          bc_props_changed_cb, view_barcode);
542         g_signal_handlers_block_by_func (G_OBJECT(view_barcode->private->bc_style),
543                                          bc_style_changed_cb, view_barcode);
544         g_signal_handlers_block_by_func (G_OBJECT(view_barcode->private->position),
545                                          position_changed_cb, view_barcode);
546
547         /* Update widgets in property dialog */
548
549         gl_wdgt_bc_data_set_data (GL_WDGT_BC_DATA(view_barcode->private->bc_data),
550                                   (merge->type != GL_MERGE_NONE),
551                                   text_node);
552         gl_wdgt_bc_data_set_field_defs (GL_WDGT_BC_DATA(view_barcode->private->bc_data),
553                                         merge->field_defs);
554         gl_wdgt_bc_props_set_params (GL_WDGT_BC_PROPS(view_barcode->private->bc_props),
555                                      scale, color);
556         gl_wdgt_bc_style_set_params (GL_WDGT_BC_STYLE(view_barcode->private->bc_style),
557                                      style, text_flag);
558         gl_wdgt_position_set_position (GL_WDGT_POSITION(view_barcode->private->position),
559                                        x, y);
560
561         /* Unblock widget handlers */
562         g_signal_handlers_unblock_by_func (G_OBJECT(view_barcode->private->bc_data),
563                                            bc_data_changed_cb, view_barcode);
564         g_signal_handlers_unblock_by_func (G_OBJECT(view_barcode->private->bc_props),
565                                            bc_props_changed_cb, view_barcode);
566         g_signal_handlers_unblock_by_func (G_OBJECT(view_barcode->private->bc_style),
567                                            bc_style_changed_cb, view_barcode);
568         g_signal_handlers_unblock_by_func (G_OBJECT(view_barcode->private->position),
569                                            position_changed_cb, view_barcode);
570
571         gl_text_node_free (&text_node);
572
573         gl_debug (DEBUG_VIEW, "END");
574 }
575
576 /*---------------------------------------------------------------------------*/
577 /* PRIVATE. label object "moved" callback.                                   */
578 /*---------------------------------------------------------------------------*/
579 static void
580 update_dialog_from_move_cb (glLabelObject *object,
581                             gdouble        dx,
582                             gdouble        dy,
583                             glViewBarcode *view_barcode)
584 {
585         gdouble            x, y;
586
587         gl_debug (DEBUG_VIEW, "START");
588
589         /* Query properties of object. */
590         gl_label_object_get_position (GL_LABEL_OBJECT(object), &x, &y);
591
592         /* Block widget handlers to prevent recursion */
593         g_signal_handlers_block_by_func (G_OBJECT(view_barcode->private->position),
594                                          position_changed_cb, view_barcode);
595
596         /* Update widgets in property dialog */
597         gl_wdgt_position_set_position (GL_WDGT_POSITION(view_barcode->private->position),
598                                        x, y);
599
600         /* Unblock widget handlers */
601         g_signal_handlers_unblock_by_func (G_OBJECT(view_barcode->private->position),
602                                            position_changed_cb, view_barcode);
603
604         gl_debug (DEBUG_VIEW, "END");
605 }
606
607 /*****************************************************************************/
608 /* Return apropos cursor for create object mode.                             */
609 /*****************************************************************************/
610 GdkCursor *
611 gl_view_barcode_get_create_cursor (void)
612 {
613         static GdkCursor *cursor = NULL;
614         GdkPixmap        *pixmap_data, *pixmap_mask;
615         GdkColor         fg = { 0, 0, 0, 0 };
616         GdkColor         bg = { 0, 65535, 65535, 65535 };
617
618         gl_debug (DEBUG_VIEW, "START");
619
620         if (!cursor) {
621                 pixmap_data = gdk_bitmap_create_from_data (NULL,
622                                                            cursor_barcode_bits,
623                                                            cursor_barcode_width,
624                                                            cursor_barcode_height);
625                 pixmap_mask = gdk_bitmap_create_from_data (NULL,
626                                                            cursor_barcode_mask_bits,
627                                                            cursor_barcode_mask_width,
628                                                            cursor_barcode_mask_height);
629                 cursor =
630                     gdk_cursor_new_from_pixmap (pixmap_data, pixmap_mask, &fg,
631                                                 &bg, cursor_barcode_x_hot,
632                                                 cursor_barcode_y_hot);
633         }
634
635         gl_debug (DEBUG_VIEW, "END");
636
637         return cursor;
638 }
639
640 /*****************************************************************************/
641 /* Canvas event handler for creating barcode objects.                            */
642 /*****************************************************************************/
643 int
644 gl_view_barcode_create_event_handler (GnomeCanvas *canvas,
645                                       GdkEvent    *event,
646                                       glView      *view)
647 {
648         static gdouble      x0, y0;
649         static gboolean     dragging = FALSE;
650         static glViewObject *view_barcode;
651         static GObject      *object;
652         gdouble             x, y;
653         glTextNode          *text_node;
654
655         gl_debug (DEBUG_VIEW, "");
656
657         switch (event->type) {
658
659         case GDK_BUTTON_PRESS:
660                 gl_debug (DEBUG_VIEW, "BUTTON_PRESS");
661                 switch (event->button.button) {
662                 case 1:
663                         dragging = TRUE;
664                         gnome_canvas_item_grab (canvas->root,
665                                                 GDK_POINTER_MOTION_MASK |
666                                                 GDK_BUTTON_RELEASE_MASK |
667                                                 GDK_BUTTON_PRESS_MASK,
668                                                 NULL, event->button.time);
669                         gnome_canvas_window_to_world (canvas,
670                                                       event->button.x,
671                                                       event->button.y, &x, &y);
672                         object = gl_label_barcode_new (view->label);
673                         gl_label_object_set_position (GL_LABEL_OBJECT(object),
674                                                      x, y);
675                         text_node = gl_text_node_new_from_text ("123456789");
676                         gl_label_barcode_set_data (GL_LABEL_BARCODE(object),
677                                                    text_node);
678                         gl_label_barcode_set_props (GL_LABEL_BARCODE(object),
679                                                     GL_BARCODE_STYLE_POSTNET,
680                                                     FALSE,
681                                                     gl_color_set_opacity (gl_prefs->default_line_color, 0.5),
682                                                     1.0);
683                         view_barcode = gl_view_barcode_new (GL_LABEL_BARCODE(object),
684                                                             view);
685                         x0 = x;
686                         y0 = y;
687                         return TRUE;
688
689                 default:
690                         return FALSE;
691                 }
692
693         case GDK_BUTTON_RELEASE:
694                 gl_debug (DEBUG_VIEW, "BUTTON_RELEASE");
695                 switch (event->button.button) {
696                 case 1:
697                         dragging = FALSE;
698                         gnome_canvas_item_ungrab (canvas->root, event->button.time);
699                         gnome_canvas_window_to_world (canvas,
700                                                       event->button.x,
701                                                       event->button.y, &x, &y);
702                         gl_label_object_set_position (GL_LABEL_OBJECT(object),
703                                                       x, y);
704                         gl_label_barcode_set_props (GL_LABEL_BARCODE(object),
705                                                     GL_BARCODE_STYLE_POSTNET,
706                                                     FALSE,
707                                                     gl_prefs->default_line_color,
708                                                     1.0);
709                         gl_view_unselect_all (view);
710                         gl_view_object_select (GL_VIEW_OBJECT(view_barcode));
711                         gl_view_arrow_mode (view);
712                         return TRUE;
713
714                 default:
715                         return FALSE;
716                 }
717
718         case GDK_MOTION_NOTIFY:
719                 gl_debug (DEBUG_VIEW, "MOTION_NOTIFY");
720                 if (dragging && (event->motion.state & GDK_BUTTON1_MASK)) {
721                         gnome_canvas_window_to_world (canvas,
722                                                       event->motion.x,
723                                                       event->motion.y, &x, &y);
724                         gl_label_object_set_position (GL_LABEL_OBJECT(object),
725                                                       x, y);
726                         return TRUE;
727                 } else {
728                         return FALSE;
729                 }
730
731         default:
732                 return FALSE;
733         }
734
735 }
736
737 /*--------------------------------------------------------------------------*/
738 /* PRIVATE.  Draw barcode to item (group).                                  */
739 /*--------------------------------------------------------------------------*/
740 static void
741 draw_barcode (glViewBarcode *view_barcode)
742 {
743         glLabelObject    *object;
744         GnomeCanvasItem  *item;
745         glTextNode *text_node;
746         glBarcodeStyle style;
747         gboolean text_flag;
748         guint color;
749         gdouble scale;
750         glBarcodeLine *line;
751         glBarcodeChar *bchar;
752         glBarcode *gbc;
753         GList *li;
754         GList *item_list = NULL;
755         GnomeCanvasPoints *points;
756         gchar *digits, *cstring;
757         GnomeFont *font;
758         GnomeGlyphList *glyphlist;
759         gdouble y_offset;
760
761         gl_debug (DEBUG_VIEW, "START");
762
763         /* Query label object and properties */
764         object = gl_view_object_get_object (GL_VIEW_OBJECT(view_barcode));
765         gl_label_barcode_get_props (GL_LABEL_BARCODE(object),
766                                     &style, &text_flag, &color, &scale);
767         text_node = gl_label_barcode_get_data(GL_LABEL_BARCODE(object));
768         if (text_node->field_flag) {
769                 digits = gl_barcode_default_digits (style);
770         } else {
771                 digits = gl_text_node_expand (text_node, NULL);
772         }
773
774         /* remove previous items from group. */
775         for (li = view_barcode->private->item_list; li!=NULL; li = li->next) {
776                 gl_debug (DEBUG_VIEW, "in loop");
777                 gtk_object_destroy (GTK_OBJECT (li->data));
778         }
779         gl_debug (DEBUG_VIEW, "1");
780         g_list_free (view_barcode->private->item_list);
781         view_barcode->private->item_list = NULL;
782         gl_debug (DEBUG_VIEW, "2");
783
784         /* get Gnome Font */
785         font = gnome_font_find_closest_from_weight_slant (GL_BARCODE_FONT_FAMILY,
786                                                           GL_BARCODE_FONT_WEIGHT,
787                                                           FALSE,
788                                                           10.0);
789
790         gbc = gl_barcode_new (style, text_flag, scale, digits);
791         if (gbc == NULL) {
792
793                 cstring = _("Invalid barcode");
794                 glyphlist = gnome_glyphlist_from_text_sized_dumb (font,
795                                                                   color,
796                                                                   0.0, 0.0,
797                                                                   cstring,
798                                                                   strlen
799                                                                   (cstring));
800                 y_offset = 10.0 - gnome_font_get_descender (font);
801                 item = gl_view_object_item_new (GL_VIEW_OBJECT(view_barcode),
802                                                 gl_canvas_hacktext_get_type (),
803                                                 "x", 0.0,
804                                                 "y", y_offset,
805                                                 "glyphlist", glyphlist, NULL);
806
807                 view_barcode->private->item_list =
808                         g_list_prepend (view_barcode->private->item_list, item);
809         } else {
810
811                 points = gnome_canvas_points_new (2);
812                 for (li = gbc->lines; li != NULL; li = li->next) {
813                         line = (glBarcodeLine *) li->data;
814
815                         points->coords[0] = line->x;
816                         points->coords[1] = line->y;
817                         points->coords[2] = line->x;
818                         points->coords[3] = line->y + line->length;
819
820                         item = gl_view_object_item_new (GL_VIEW_OBJECT(view_barcode),
821                                                         gnome_canvas_line_get_type (),
822                                                         "points", points,
823                                                         "width_units", line->width,
824                                                         "fill_color_rgba", color,
825                                                         NULL);
826                         view_barcode->private->item_list =
827                                 g_list_prepend (view_barcode->private->item_list, item);
828                 }
829                 gnome_canvas_points_free (points);
830
831                 for (li = gbc->chars; li != NULL; li = li->next) {
832                         bchar = (glBarcodeChar *) li->data;
833
834                         font = gnome_font_find_closest_from_weight_slant (
835                                                        GL_BARCODE_FONT_FAMILY,
836                                                        GL_BARCODE_FONT_WEIGHT,
837                                                        FALSE, bchar->fsize);
838                         glyphlist = gnome_glyphlist_from_text_sized_dumb (font,
839                                                                           color,
840                                                                           0.0,
841                                                                           0.0,
842                                                                           &
843                                                                           (bchar->
844                                                                            c),
845                                                                           1);
846                         y_offset =
847                             bchar->fsize - gnome_font_get_descender (font);
848                         item = gl_view_object_item_new (GL_VIEW_OBJECT(view_barcode),
849                                                         gnome_canvas_hacktext_get_type (),
850                                                         "x", bchar->x,
851                                                         "y", bchar->y + y_offset,
852                                                         "glyphlist", glyphlist,
853                                                         NULL);
854
855                         view_barcode->private->item_list =
856                                 g_list_prepend (view_barcode->private->item_list, item);
857
858                 }
859
860         }
861
862         /* clean up */
863         gl_barcode_free (&gbc);
864         g_free (digits);
865
866         gl_debug (DEBUG_VIEW, "END");
867 }
868