1 /*
2  *  Program: Rubrica
3  *  file: print.c
4  *
5  *  Copyright (C) Nicola Fragale <nicolafragale@libero.it>
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License as published by
9  *  the Free Software Foundation; either version 3 of the License
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19  */
20 #include <math.h>
21 #include <string.h>
22 #include <gtk/gtk.h>
23 #include <glib/gi18n-lib.h>
24 #include <libral.h>
25 
26 #include "app.h"
27 #include "print.h"
28 
29 
30 #define HEADER_HEIGHT 20.0
31 #define HEADER_GAP 8.5
32 
33 
34 enum {
35   PROP_0,
36   PRINTING_ADDRESSBOOK,
37   PRINTING_CARDS,
38   PRINTING_FONT,
39   PRINTING_FONT_SIZE,
40 };
41 
42 
43 
44 struct _RubricaPrintPrivate {
45   RAbook* book;
46   GList* ids;
47 
48   gchar* font;
49   gdouble font_size;
50 
51   gint lines_per_page;
52   gint chars_per_line;
53   gint total_lines;
54   gint total_pages;
55   gchar** lines;
56 
57   gboolean dispose_has_run;
58 };
59 
60 
61 #define RUBRICA_PRINT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o),   \
62                                       RUBRICA_PRINT_TYPE,                \
63                                       RubricaPrintPrivate))
64 
65 
66 static GObjectClass *parent_class = NULL;
67 
68 
69 static void rubrica_print_class_init   (RubricaPrintClass* klass);
70 static void rubrica_print_init         (RubricaPrint* obj);
71 
72 static void rubrica_print_finalize     (RubricaPrint* self);
73 static void rubrica_print_dispose      (RubricaPrint* self);
74 
75 
76 static void rubrica_print_set_property (GObject* obj, guint property_id,
77 					const GValue* value, GParamSpec* spec);
78 static void rubrica_print_get_property (GObject* obj, guint property_id,
79 					GValue* value, GParamSpec* spec);
80 
81 static void write_header  (RCard* card, GString* buffer);
82 static void write_groups  (RCard* card, GString* buffer);
83 static void write_address (RCard* card, GString* buffer);
84 static void write_work    (RCard* card, GString* buffer);
85 static void write_net     (RCard* card, GString* buffer);
86 static void write_phone   (RCard* card, GString* buffer);
87 static void write_notes   (RCard* card, GString* buffer);
88 
89 
90 static void begin_print   (GtkPrintOperation* operation,
91 			   GtkPrintContext* context, gpointer data);
92 static void draw_page     (GtkPrintOperation* operation,
93 			   GtkPrintContext* context, gint page_nr,
94 			   gpointer data);
95 static void end_print     (GtkPrintOperation* operation,
96 			   GtkPrintContext* context, gpointer data);
97 
98 
99 
100 
101 GType
rubrica_print_get_type()102 rubrica_print_get_type()
103 {
104   static GType print_type = 0;
105 
106   if (!print_type)
107     {
108       static const GTypeInfo print_info =
109 	{
110 	  sizeof(RubricaPrintClass),
111 	  NULL,
112 	  NULL,
113 	  (GClassInitFunc) rubrica_print_class_init,
114 	  NULL,
115 	  NULL,
116 	  sizeof(RubricaPrint),
117 	  0,
118 	  (GInstanceInitFunc) rubrica_print_init
119 	};
120 
121       print_type = g_type_register_static (G_TYPE_OBJECT, "RubricaPrint",
122 					   &print_info, 0);
123     }
124 
125   return print_type;
126 }
127 
128 
129 static void
rubrica_print_dispose(RubricaPrint * self)130 rubrica_print_dispose (RubricaPrint* self)
131 {
132   g_return_if_fail(IS_RUBRICA_PRINT(self));
133 
134   if (self->priv->dispose_has_run)
135     return;
136 
137   self->priv->dispose_has_run = TRUE;
138 }
139 
140 
141 static void
rubrica_print_finalize(RubricaPrint * self)142 rubrica_print_finalize (RubricaPrint* self)
143 {
144   g_return_if_fail(IS_RUBRICA_PRINT(self));
145 
146 }
147 
148 
149 static void
rubrica_print_class_init(RubricaPrintClass * klass)150 rubrica_print_class_init(RubricaPrintClass* klass)
151 {
152   GObjectClass *object_class = G_OBJECT_CLASS (klass);
153   GParamSpec* pspec;
154 
155   parent_class = g_type_class_peek_parent (klass);
156 
157   object_class->finalize     = (GObjectFinalizeFunc) rubrica_print_finalize;
158   object_class->dispose      = (GObjectFinalizeFunc) rubrica_print_dispose;
159 
160   object_class->set_property = (gpointer) rubrica_print_set_property;
161   object_class->get_property = (gpointer) rubrica_print_get_property;
162 
163   g_type_class_add_private (klass, sizeof(RubricaPrintPrivate));
164 
165   /* class property
166    */
167   pspec = g_param_spec_pointer("printing-addressbook",
168 			       "printing addressbook",
169 			       "the addressbook to print from",
170 			       G_PARAM_READWRITE);
171   g_object_class_install_property(object_class, PRINTING_ADDRESSBOOK, pspec);
172 
173   pspec = g_param_spec_pointer("printing-cards",
174 			       "printing cards",
175 			       "list of cards to print",
176 			       G_PARAM_READWRITE);
177   g_object_class_install_property(object_class, PRINTING_CARDS, pspec);
178 
179 
180   /**
181    * RubricaPrint:printing-font
182    *
183    * the font that will be used to print
184    */
185   pspec = g_param_spec_string("printing-font",
186 			      "printing font",
187 			      "the font that will be used to print",
188 			      NULL,
189 			      G_PARAM_READWRITE);
190   g_object_class_install_property(object_class, PRINTING_FONT, pspec);
191 
192   /**
193    * RubricaPrint:printing-font
194    *
195    * the font that will be used to print
196    */
197   pspec = g_param_spec_int("printing-font-size",
198 			   "printing font size",
199 			   "the font's size",
200 			   0,
201 			   1000,
202 			   12,
203 			   G_PARAM_READWRITE);
204   g_object_class_install_property(object_class, PRINTING_FONT_SIZE, pspec);
205 }
206 
207 
208 static void
rubrica_print_init(RubricaPrint * self)209 rubrica_print_init(RubricaPrint* self)
210 {
211   RubricaPrintPrivate* priv;
212 
213   priv = RUBRICA_PRINT_GET_PRIVATE(self);
214 
215   self->operation = NULL;
216   priv->book      = NULL;
217   priv->ids       = NULL;
218 
219   priv->font      = NULL;
220   priv->font_size = 0L;
221 
222   priv->lines_per_page = 0;
223   priv->total_lines    = 0;
224   priv->total_pages    = 0;
225   priv->lines          = NULL;
226 
227   priv->dispose_has_run = FALSE;
228 }
229 
230 
231 static void
rubrica_print_set_property(GObject * obj,guint property_id,const GValue * value,GParamSpec * spec)232 rubrica_print_set_property (GObject* obj, guint property_id,
233 			    const GValue* value, GParamSpec* spec)
234 {
235   RubricaPrint* self = (RubricaPrint*) obj;
236   RubricaPrintPrivate* priv = RUBRICA_PRINT_GET_PRIVATE(self);
237 
238 
239     switch (property_id)
240     {
241     case PRINTING_ADDRESSBOOK:
242       priv->book = g_value_get_pointer(value);
243       break;
244 
245     case PRINTING_CARDS:
246       priv->ids = g_value_get_pointer(value);
247       break;
248 
249     case PRINTING_FONT:
250       if (priv->font)
251 	g_free(priv->font);
252       priv->font = g_strdup(g_value_get_string(value));
253       break;
254 
255     case PRINTING_FONT_SIZE:
256       priv->font_size = g_value_get_int(value);
257       break;
258 
259     default:
260       break;
261     }
262 }
263 
264 
265 static void
rubrica_print_get_property(GObject * obj,guint property_id,GValue * value,GParamSpec * spec)266 rubrica_print_get_property (GObject* obj, guint property_id,
267 			    GValue* value, GParamSpec* spec)
268 {
269   RubricaPrint* self = (RubricaPrint*) obj;
270   RubricaPrintPrivate* priv = RUBRICA_PRINT_GET_PRIVATE(self);
271 
272   switch (property_id)
273     {
274     case PRINTING_ADDRESSBOOK:
275       g_value_set_pointer(value, priv->book);
276       break;
277 
278     case PRINTING_CARDS:
279       g_value_set_pointer(value, priv->ids);
280       break;
281 
282     case PRINTING_FONT:
283       g_value_set_string(value, priv->font);
284       break;
285 
286     case PRINTING_FONT_SIZE:
287       g_value_set_int(value, priv->font_size);
288       break;
289 
290     default:
291       break;
292     }
293 }
294 
295 
296 
297 static void
write_header(RCard * card,GString * buffer)298 write_header(RCard* card, GString* buffer)
299 {
300   RContact* contact;
301   gchar* card_name;
302   gchar *first = NULL, *last = NULL, *middle = NULL;
303   gchar *nick = NULL, *title = NULL, *prefix = NULL;
304   gchar *prof = NULL;
305 
306   contact = r_personal_card_get_contact(R_PERSONAL_CARD(card));
307 
308   g_object_get(card, "card-name", &card_name, NULL);
309   g_object_get(contact,
310 	       "first-name",  &first,  "last-name", &last,
311 	       "middle-name", &middle, NULL);
312 
313   g_string_append_printf(buffer, "<b><u>%s</u></b>: %s\n ",
314 			 _("Card"), card_name);
315 
316   if (first || middle || last)
317     g_string_append_printf(buffer, "\t%s: %s %s %s\n", _("Name"),
318 			   last   ? last   : "", first  ? first  : "",
319 			   middle ? middle : "");
320 
321   if(r_contact_check(contact, "nick-name", &nick))
322     g_string_append_printf(buffer, "\t%s: %s\n", _("Nickname"), nick);
323 
324   if(r_contact_check(contact, "title", &title))
325     g_string_append_printf(buffer, "\t%s: %s\n", _("Title"), title);
326 
327   if(r_contact_check(contact, "prefix", &prefix))
328     g_string_append_printf(buffer, "\t%s: %s\n", _("Prefix"), prefix);
329 
330   if(r_contact_check(contact, "profession", &prof))
331     g_string_append_printf(buffer, "\t%s: %s\n", _("Profession"), prof);
332 }
333 
334 
335 static void
write_groups(RCard * card,GString * buffer)336 write_groups(RCard* card, GString* buffer)
337 {
338   gpointer group = NULL;
339 
340   group = r_card_get_group(R_CARD(card));
341   if (group)
342     {
343       g_string_append_printf(buffer, "\t<b>%s:</b>\n", _("Card's groups"));
344 
345       for(;group; group = r_card_get_next_group(R_CARD(card)))
346 	{
347 	  gchar *name = NULL;
348 
349 	  g_object_get(R_GROUP(group), "group-name",  &name, NULL);
350 	  g_string_append_printf(buffer, "\t\t%s\n", name);
351 	}
352     }
353 }
354 
355 
356 static void
write_address(RCard * card,GString * buffer)357 write_address(RCard* card, GString* buffer)
358 {
359   RAddress* address;
360 
361   address = r_card_get_address(R_CARD(card));
362   if (address)
363     {
364       g_string_append_printf(buffer, "\t<b>%s:</b>\n", _("Addresses"));
365 
366       for  (; address; address = r_card_get_next_address(R_CARD(card)))
367 	{
368 	  RAddressType type;
369 	  gchar *adtype, *street, *number, *zip;
370 	  gchar *city, *province, *state, *country;
371 
372 	  g_object_get(address, "address-type", &type,
373 		       "street", &street, "street-number", &number,
374 		       "zip", &zip, "city", &city,
375 		       "province", &province, "state", &state,
376 		       "country", &country, NULL);
377 
378 	  if ((street && (g_ascii_strcasecmp(street, "") != 0))   ||
379 	      (zip && (g_ascii_strcasecmp(zip, "") != 0))         ||
380 	      (city && (g_ascii_strcasecmp(city, "") != 0))       ||
381 	      (state && (g_ascii_strcasecmp(state, "") != 0))     ||
382 	      (country && (g_ascii_strcasecmp(country, "") != 0)))
383 	    {
384 	      adtype = r_address_lookup_enum2str(type);
385 	      g_string_append_printf(buffer, "\t\t<b>%s</b>\n", adtype);
386 
387 	      if (street && (g_ascii_strcasecmp(street, "") != 0))
388 		{
389 		  g_string_append_printf(buffer, "\t\t%s", street);
390 
391 		  if (number && (g_ascii_strcasecmp(number, "") != 0))
392 		    g_string_append_printf(buffer, ", %s\n", number);
393 		  else
394 		    g_string_append_printf(buffer, "\n");
395 		}
396 
397 	      if ((zip && (g_ascii_strcasecmp(zip, "") != 0))   ||
398 		  (city && (g_ascii_strcasecmp(city, "") != 0)) ||
399 		  (province && (g_ascii_strcasecmp(province, "") != 0)))
400 		{
401 		  gboolean comma = FALSE;
402 
403 		  g_string_append_printf(buffer, "\t\t");
404 
405 		  if (zip && (g_ascii_strcasecmp(zip, "") != 0))
406 		    {
407 		      g_string_append_printf(buffer, "%s ", zip);
408 		      comma = TRUE;
409 		    }
410 
411 		  if (city && (g_ascii_strcasecmp(city, "") != 0))
412 		    {
413 		      g_string_append_printf(buffer, "%s", city);
414 		      comma = TRUE;
415 		    }
416 
417 		  if (province && (g_ascii_strcasecmp(province, "") != 0))
418 		    {
419 		      if (comma)
420 			g_string_append_printf(buffer, ", (%s) ", province);
421 		      else
422 			g_string_append_printf(buffer, "%s", province);
423 		    }
424 
425 		  g_string_append_printf(buffer, "\n");
426 		}
427 
428 	      if ((state && (g_ascii_strcasecmp(state, "") != 0))   ||
429 		  (country && (g_ascii_strcasecmp(country, "") != 0)))
430 		{
431 		  g_string_append_printf(buffer, "\t\t");
432 
433 		  if (state && (g_ascii_strcasecmp(state, "") != 0))
434 		    g_string_append_printf(buffer, "%s ", state);
435 
436 		  if (country && (g_ascii_strcasecmp(country, "") != 0))
437 		    g_string_append_printf(buffer, "%s",country);
438 
439 		  g_string_append_printf(buffer, "\n");
440 		}
441 	    }
442 	}
443     }
444 }
445 
446 
447 static void
write_work(RCard * card,GString * buffer)448 write_work(RCard* card, GString* buffer)
449 {
450   RWork* work = NULL;
451   gchar *assignment = NULL, *organization = NULL;
452   gchar *department = NULL, *subdep = NULL, *manager = NULL;
453   gchar *collaborator = NULL, *mphone = NULL, *cphone = NULL;
454 
455   work = r_personal_card_get_work(R_PERSONAL_CARD(card));
456   if (work && r_work_have_data(work))
457     {
458       g_string_append_printf(buffer, "\t<b>%s:</b>\n", _("Work"));
459 
460       if(r_work_check(work, "assignment", &assignment))
461 	g_string_append_printf(buffer, "\t\t%s: %s\n",
462 			       _("Assignment"), assignment);
463 
464       if(r_work_check(work, "organization", &organization))
465 	g_string_append_printf(buffer, "\t\t%s: %s\n",
466 			       _("Organization"), organization );
467 
468       if(r_work_check(work, "department", &department))
469 	g_string_append_printf(buffer, "\t\t%s: %s\n",
470 			       _("Department"), department);
471 
472       if(r_work_check(work, "sub-department", &subdep))
473 	g_string_append_printf(buffer, "\t\t%s: %s\n",
474 			       _("Sub department"), subdep);
475 
476       if(r_work_check(work, "manager-name", &manager))
477 	g_string_append_printf(buffer, "\t\t%s: %s\n", _("Manager"), manager);
478 
479       if(r_work_check(work, "collaborator", &collaborator))
480 	g_string_append_printf(buffer, "\t\t%s: %s\n",
481 			       _("Collaborator"), collaborator);
482 
483       if(r_work_check(work, "manager-phone", &mphone))
484 	g_string_append_printf(buffer, "\t\t%s: %s\n",
485 			       _("Manager phone"), mphone );
486 
487       if(r_work_check(work, "collaborator-phone", &cphone))
488 	g_string_append_printf(buffer, "\t\t%s: %s\n",
489 			       _("Collaborator phone"), cphone);
490     }
491 }
492 
493 
494 static void
write_net(RCard * card,GString * buffer)495 write_net(RCard* card, GString* buffer)
496 {
497   RNetAddress* net = NULL;
498   RNetAddressType type;
499   gchar* url;
500 
501   net = r_card_get_net_address(R_CARD(card));
502   if (net)
503     g_string_append_printf(buffer, "\t<b>%s:</b>\n", _("Net"));
504 
505   for (; net; net = r_card_get_next_net_address(R_CARD(card)))
506     {
507       gchar* ttype;
508 
509       g_object_get(R_NET_ADDRESS(net), "url", &url, "url-type", &type, NULL);
510       ttype = r_net_address_decode_type(type);
511 
512       g_string_append_printf(buffer,
513 			     "\t\t%s: <span foreground=\"blue\">"
514 			     "<u>%s</u></span>\n", ttype, url);
515     }
516 }
517 
518 
519 static void
write_phone(RCard * card,GString * buffer)520 write_phone(RCard* card, GString* buffer)
521 {
522   RTelephone* tel = NULL;
523 
524   tel = r_card_get_telephone(R_CARD(card));
525   if (tel)
526     g_string_append_printf(buffer, "\t<b>%s</b>:\n", _("Telephone"));
527 
528   for (; tel; tel = r_card_get_next_telephone(R_CARD(card)))
529     {
530       RTelephoneType ttype;
531       gchar* num;
532 
533       g_object_get(R_TELEPHONE(tel),
534 		   "telephone-number", &num,
535 		   "telephone-type",   &ttype, NULL);
536 
537       g_string_append_printf(buffer, "\t\t%s: %s\n",
538 			     r_telephone_lookup_enum2str(ttype), num);
539     }
540 }
541 
542 
543 static void
write_notes(RCard * card,GString * buffer)544 write_notes(RCard* card, GString* buffer)
545 {
546   RNotes* notes;
547   gchar *partner, *other_notes, *pubkey;
548   gboolean has_partner;
549 
550   notes = r_personal_card_get_notes(R_PERSONAL_CARD(card));
551   if (notes && r_notes_have_data(notes))
552     {
553       g_string_append_printf(buffer, "\t<b>%s</b>:\n", _("Notes"));
554 
555       g_object_get(notes,
556 		   "has-partner",  &has_partner,
557 		   "partner-name", &partner,
558 		   "other-notes",  &other_notes,
559 		   "pubkey",       &pubkey, NULL);
560 
561       if (has_partner)
562 	{
563 	  g_string_append_printf(buffer, "\t\t%s\n",
564 				 _("Contact has a partner"));
565 
566 	  g_string_append_printf(buffer, "\t\t%s: %s\n",
567 				 _("partner's name"), partner);
568 
569 	  if (r_notes_know_birthday(notes))
570 	    g_string_append_printf(buffer, "\t\t%s: %s\n",
571 				   _("partner's birthday"),
572 				   r_notes_get_birth_date(notes));
573 
574 	  if (r_notes_know_anniversary(notes))
575 	    g_string_append_printf(buffer, "\t\t%s: %s\n",
576 				   _("anniversary"),
577 				   r_notes_get_anniversary_date(notes));
578 	}
579 
580       if (pubkey)
581 	g_string_append_printf(buffer, "\t\t%s: %s\n", _("Public key"),
582 			       pubkey);
583 
584       if(other_notes)
585 	g_string_append_printf(buffer, "\t\t%s: %s\n",
586 			       _("Other notes"), other_notes);
587     }
588 }
589 
590 
591 static void
begin_print(GtkPrintOperation * operation,GtkPrintContext * context,gpointer data)592 begin_print(GtkPrintOperation* operation, GtkPrintContext* context,
593 	    gpointer data)
594 {
595   RubricaPrint* print = (RubricaPrint*) data;
596   RubricaPrintPrivate* priv = RUBRICA_PRINT_GET_PRIVATE(print);
597   GList *alias = NULL;
598   GString* buffer;
599   gdouble height, width;
600   gint total_lines, lines_in_page;
601   gchar** tmp;
602 
603   height = gtk_print_context_get_height(context) - HEADER_HEIGHT - HEADER_GAP;
604   width  = gtk_print_context_get_width(context);
605 
606   priv->lines_per_page = floor(height / (priv->font_size + 3));
607   priv->chars_per_line = floor(width / (priv->font_size));
608 
609   buffer = g_string_new(NULL);
610   alias  = priv->ids;
611   total_lines = 0;
612   lines_in_page = 0;
613   for (; alias; alias = alias->next)
614     {
615       glong id = (glong) alias->data;
616       RCard* card = NULL;
617 
618       card = r_abook_get_card_by_id(priv->book, id);
619       if (card)
620 	{
621 	  write_header(card, buffer);
622 	  write_groups(card, buffer);
623 	  write_address(card, buffer);
624 	  write_work(card, buffer);
625 	  write_net(card, buffer);
626 	  write_phone(card, buffer);
627 	  write_notes(card, buffer);
628 	  g_string_append_printf(buffer, "\n");
629 	}
630     }
631 
632   priv->lines = g_strsplit(buffer->str, "\n", 0);
633   tmp = priv->lines;
634   for(; *tmp; tmp++)
635     priv->total_lines++;
636 
637   priv->total_pages = (priv->total_lines - 1) / priv->lines_per_page + 1;
638 
639   gtk_print_operation_set_n_pages(print->operation, priv->total_pages);
640 
641   g_print("\nLinee per pagina: %d", priv->lines_per_page);
642   g_print("\nPagine totali: %d", priv->total_pages);
643 
644   g_string_free(buffer, TRUE);
645 }
646 
647 
escape_string(gchar * str)648 gchar* escape_string(gchar* str)
649 {
650   gchar* ret, *tmp, *tmp2;
651   gint len;
652   gint found = 0, i = 0;
653 
654   len = strlen(str);
655   for (; i < len; i++)
656     if (str[i] == '&')
657       found++;
658 
659   tmp2 = ret = g_malloc0(sizeof(char) * (len + found*5 +1));
660   for(tmp = str; *tmp; tmp++)
661     {
662       if (*tmp != '&')
663 	{
664 	  *tmp2 = *tmp;
665 	  tmp2++;
666 	}
667       else
668 	{
669 	  *tmp2++ = '&';
670 	  *tmp2++ = 'a';
671 	  *tmp2++ = 'm';
672 	  *tmp2++ = 'p';
673 	  *tmp2++ = ';';
674 	}
675     }
676 
677   return ret;
678 }
679 
680 static void
draw_page(GtkPrintOperation * operation,GtkPrintContext * context,gint page_nr,gpointer data)681 draw_page (GtkPrintOperation* operation, GtkPrintContext* context,
682 	   gint page_nr, gpointer data)
683 {
684   RubricaPrint* print = (RubricaPrint*) data;
685   RubricaPrintPrivate* priv = RUBRICA_PRINT_GET_PRIVATE(print);
686   PangoFontDescription* desc;
687   PangoAttrList* attr_list;
688   PangoLayout *layout;
689   cairo_t *cr;
690   gdouble width, text_height;
691   gint text_width, layout_height;
692   gchar* page_str, *text;
693   gint i, line;
694   GError* error = NULL;
695 
696   cr     = gtk_print_context_get_cairo_context(context);
697   width  = gtk_print_context_get_width(context);
698   layout = gtk_print_context_create_pango_layout(context);
699   desc   = pango_font_description_from_string(priv->font);
700   pango_font_description_set_size(desc, priv->font_size * PANGO_SCALE);
701 
702   /* header: nome del file e numero di pagina */
703   pango_layout_set_font_description(layout, desc);
704   //  pango_layout_set_text(layout, priv->file, -1);
705   pango_layout_set_width(layout, -1);
706   pango_layout_set_alignment(layout, PANGO_ALIGN_LEFT);
707   pango_layout_get_size(layout, NULL, &layout_height);
708   text_height = (gdouble) layout_height / PANGO_SCALE;
709 
710   cairo_move_to(cr, 0, (HEADER_HEIGHT - text_height) /2);
711   pango_cairo_show_layout(cr, layout);
712 
713   page_str = g_strdup_printf("%d di %d", page_nr +1, priv->total_pages);
714   pango_layout_set_text(layout, page_str, -1);
715   pango_layout_get_size(layout, &text_width, NULL);
716   pango_layout_set_alignment(layout, PANGO_ALIGN_RIGHT);
717 
718   cairo_move_to(cr, width - (text_width / PANGO_SCALE),
719 		(HEADER_HEIGHT - text_height) /2);
720   pango_cairo_show_layout(cr, layout);
721 
722   /* disegna le pagine */
723   cairo_move_to(cr, 0, HEADER_HEIGHT + HEADER_GAP);
724   line = page_nr * priv->lines_per_page;
725   for (i = 0; i < priv->lines_per_page && line < priv->total_lines; i++)
726     {
727       gchar* buf;
728 
729       buf = escape_string(priv->lines[line]);
730       pango_parse_markup(buf, -1, 0, &attr_list, &text, NULL, &error);
731       g_free(buf);
732 
733       if (!error)
734 	{
735 	  g_print("\ntesto: %s", text);
736 	  pango_layout_set_text(layout, text, -1);
737 	  pango_cairo_show_layout(cr, layout);
738 	  cairo_rel_move_to(cr, 0, priv->font_size + 3);
739 	  line++;
740 	}
741       else
742 	{
743 	  g_warning("\n%s", error->message);
744 	  error = NULL;
745 	}
746     }
747 
748   g_free(page_str);
749   g_object_unref(layout);
750   pango_font_description_free(desc);
751 }
752 
753 
754 
755 static void
end_print(GtkPrintOperation * operation,GtkPrintContext * context,gpointer data)756 end_print(GtkPrintOperation* operation, GtkPrintContext* context,
757 	  gpointer data)
758 {
759   RubricaPrint* print = (RubricaPrint*) data;
760   RubricaPrintPrivate* priv = RUBRICA_PRINT_GET_PRIVATE(print);
761 
762   g_list_free(priv->ids);
763   priv->ids = NULL;
764 }
765 
766 
767 RubricaPrint*
rubrica_print_new(void)768 rubrica_print_new (void)
769 {
770   RubricaPrint* print;
771 
772   print = g_object_new(rubrica_print_get_type(), NULL);
773 
774   print->operation = gtk_print_operation_new();
775 
776   g_signal_connect(G_OBJECT(print->operation), "begin_print",
777 		   G_CALLBACK(begin_print), print);
778 
779   g_signal_connect(G_OBJECT(print->operation), "draw_page",
780 		   G_CALLBACK(draw_page), print);
781 
782   g_signal_connect(G_OBJECT(print->operation), "end_print",
783 		   G_CALLBACK(end_print), print);
784 
785   return print;
786 }
787 
788