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