1 /*
2 *  RAL -- Rubrica Addressbook Library
3 *  file: ref.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 2 of the License, or
10 *  (at your option) any later version.
11 *
12 *  This program is distributed in the hope that it will be useful,
13 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 *  GNU General Public License for more details.
16 *
17 *  You should have received a copy of the GNU General Public License
18 *  along with this program; if not, write to the Free Software
19 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */
21 
22 #include <gtk/gtk.h>
23 #include <gdk-pixbuf/gdk-pixbuf.h>
24 #include <gconf/gconf-client.h>
25 #include <glib/gi18n-lib.h>
26 #include <gdk/gdkkeysyms.h>
27 #include <sys/types.h>
28 #include <unistd.h>
29 
30 #include "libral.h"
31 
32 #include "data_view.h"
33 #include "app.h"
34 #include "types.h"
35 #include "themes.h"
36 #include "preferences.h"
37 
38 static GdkCursor* hand_cursor;
39 static GdkCursor* regular_cursor;
40 static GdkCursor* wait_cursor;
41 
42 static gboolean   over_link;
43 
44 
45 enum {
46   PROP_0,
47   DATA_FONT,
48 };
49 
50 struct _RubricaDataViewPrivate {
51   GtkWidget* text1;      // header
52   GtkWidget* text2;      // body
53 
54   GtkTextBuffer* buf1;   // header's buffer
55   GtkTextBuffer* buf2;   // body's buffer
56 
57   GtkIconTheme*  theme;
58   GtkWidget*     image;
59 
60   gchar* font;
61 
62   gboolean dispose_has_run;
63 };
64 
65 
66 /*    signals enumeration
67  */
68 enum {
69   LAUNCH,
70   LAST_SIGNAL
71 };
72 
73 static guint data_view_signals[LAST_SIGNAL] = {0};
74 
75 #define RUBRICA_DATA_VIEW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
76                                           RUBRICA_DATA_VIEW_TYPE,          \
77                                           RubricaDataViewPrivate))
78 
79 
80 static GObjectClass *parent_class = NULL;
81 
82 
83 static void rubrica_data_view_class_init   (RubricaDataViewClass* klass);
84 static void rubrica_data_view_init         (RubricaDataView* obj);
85 
86 static void rubrica_data_view_finalize     (RubricaDataView* self);
87 static void rubrica_data_view_dispose      (RubricaDataView* self);
88 
89 
90 static void rubrica_data_view_set_property (GObject* obj, guint property_id,
91 					    GValue* value, GParamSpec* spec);
92 static void rubrica_data_view_get_property (GObject* obj, guint property_id,
93 					    GValue* value, GParamSpec* spec);
94 
95 
96 /*  Private
97 */
98 static GtkTextTagTable* rubrica_data_view_create_tag_table(void);
99 
100 
101 static void     insert_link             (GtkTextBuffer *buffer,
102 					 GtkTextIter *iter, gchar *uri,
103 					 RubricaLinkType type);
104 static void     follow_if_link          (GtkWidget *view, GtkTextIter *iter,
105 					 gpointer data);
106 static void     set_cursor              (GtkWidget* view, gint x, gint y);
107 
108 
109 static void clean_buffer                (GtkTextBuffer* buffer);
110 static void data_view_clear_header      (RubricaDataView* view);
111 static void data_view_clear_body        (RubricaDataView* view);
112 
113 static void data_view_set_image         (RubricaDataView* view,
114 					 GdkPixbuf* pixbuf);
115 
116 static void data_view_write_card_header (GtkTextBuffer* buffer, gchar* label,
117 					 gchar* string);
118 static void data_view_write_pixbuf      (GtkTextBuffer* buffer,
119 					 GdkPixbuf* pixbuf, gchar* label);
120 static void data_view_write_bold        (GtkTextBuffer* buffer, gchar* label,
121 					 gchar* string, gboolean bool);
122 static void data_view_write_line        (GtkTextBuffer* buffer, gchar* label,
123 					 gchar* string, gboolean tab);
124 static void data_view_write_link        (GtkTextBuffer* buffer, gchar* label,
125 					 gchar* url, RubricaLinkType link);
126 static void data_view_write             (GtkTextBuffer* buffer, gchar* str);
127 
128 static void write_company_info  (RubricaDataView* view, RCard* card);
129 static void write_personal_data (RubricaDataView* view, RPersonalCard* card);
130 static void write_groups        (RubricaDataView* view, RCard* card);
131 static void write_addresses     (RubricaDataView* view, RCard* card);
132 static void write_work          (RubricaDataView* view, RPersonalCard* card);
133 static void write_net           (RubricaDataView* view, RCard* card);
134 static void write_telephones    (RubricaDataView* view, RCard* card);
135 static void write_notes         (RubricaDataView* view, RPersonalCard* card);
136 static void write_company_notes (RubricaDataView* view, RCompanyCard* card);
137 
138 static void data_view_show_personal_card (RubricaDataView* view, RCard* card);
139 static void data_view_show_company_card  (RubricaDataView* view, RCard* card);
140 
141 
142 /*  Callbacks
143 */
144 static gboolean key_press_event         (GtkWidget *text_view,
145 					 GdkEventKey *event, gpointer data);
146 static gboolean event_after             (GtkWidget *text_view, GdkEvent  *ev,
147 					 gpointer data);
148 static gboolean motion_notify_event     (GtkWidget* view,
149 					 GdkEventMotion *event, gpointer data);
150 static gboolean visibility_notify_event (GtkWidget* view,
151 					 GdkEventVisibility *event,
152 					 gpointer data);
153 
154 
155 void change_font (GtkTextTag *tag, gpointer data);
156 
157 
158 void
change_font(GtkTextTag * tag,gpointer data)159 change_font (GtkTextTag *tag, gpointer data)
160 {
161   PangoFontDescription* pfd;
162   const gchar* font = (gchar*) data;
163   gchar* name;
164 
165   pfd = pango_font_description_from_string (font);
166 
167   g_object_get(tag, "name", &name, NULL);
168   if (g_strrstr(name, "bold"))
169     g_object_set(tag, "font-desc", pfd, "weight", PANGO_WEIGHT_BOLD, NULL);
170   else
171     g_object_set(tag, "font-desc", pfd, NULL);
172 
173   pango_font_description_free (pfd);
174 }
175 
176 GType
rubrica_data_view_get_type()177 rubrica_data_view_get_type()
178 {
179   static GType data_view_type = 0;
180 
181   if (!data_view_type)
182     {
183       static const GTypeInfo data_view_info =
184 	{
185 	  sizeof(RubricaDataViewClass),
186 	  NULL,
187 	  NULL,
188 	  (GClassInitFunc) rubrica_data_view_class_init,
189 	  NULL,
190 	  NULL,
191 	  sizeof(RubricaDataView),
192 	  0,
193 	  (GInstanceInitFunc) rubrica_data_view_init
194 	};
195 
196       data_view_type = g_type_register_static (GTK_TYPE_VBOX,
197 					       "RubricaDataView",
198 					       &data_view_info, 0);
199     }
200 
201   return data_view_type;
202 }
203 
204 
205 static void
rubrica_data_view_dispose(RubricaDataView * self)206 rubrica_data_view_dispose (RubricaDataView* self)
207 {
208   g_return_if_fail(IS_RUBRICA_DATA_VIEW(self));
209 
210   if (self->priv->dispose_has_run)
211     return;
212 
213   self->priv->dispose_has_run = TRUE;
214 }
215 
216 
217 static void
rubrica_data_view_finalize(RubricaDataView * self)218 rubrica_data_view_finalize (RubricaDataView* self)
219 {
220   g_return_if_fail(IS_RUBRICA_DATA_VIEW(self));
221 }
222 
223 
224 static void
rubrica_data_view_class_init(RubricaDataViewClass * klass)225 rubrica_data_view_class_init(RubricaDataViewClass* klass)
226 {
227   GObjectClass *object_class = G_OBJECT_CLASS (klass);
228   GParamSpec* pspec;
229 
230   parent_class = g_type_class_peek_parent (klass);
231 
232   object_class->finalize = (GObjectFinalizeFunc) rubrica_data_view_finalize;
233   object_class->dispose  = (GObjectFinalizeFunc) rubrica_data_view_dispose;
234 
235   object_class->set_property = (gpointer) rubrica_data_view_set_property;
236   object_class->get_property = (gpointer) rubrica_data_view_get_property;
237 
238   g_type_class_add_private (klass, sizeof(RubricaDataViewPrivate));
239 
240   /**
241    * RubricaDataView:data-font
242    *
243    *
244    */
245   pspec = g_param_spec_string("data-font",
246 			      "data font",
247 			      "the font used to display data",
248 			      NULL,
249 			      G_PARAM_READWRITE);
250   g_object_class_install_property(object_class, DATA_FONT, pspec);
251 
252   data_view_signals[LAUNCH] =
253     g_signal_new("launch",
254 		 RUBRICA_DATA_VIEW_TYPE,
255 		 G_SIGNAL_RUN_LAST,
256 		 G_STRUCT_OFFSET(RubricaDataViewClass, launch),
257 		 NULL,
258 		 NULL,
259 		 g_cclosure_marshal_VOID__POINTER,
260 		 G_TYPE_NONE,            /* return type */
261 		 1,                      /* params      */
262 		 G_TYPE_POINTER);        /* params type: error code */
263 }
264 
265 
266 static void
rubrica_data_view_init(RubricaDataView * self)267 rubrica_data_view_init(RubricaDataView* self)
268 {
269   GtkWidget* scrollwin;
270   GtkTextTagTable* tag_table;
271   GtkWidget* vbox;
272   GtkWidget* hbox;
273 
274   hand_cursor    = gdk_cursor_new (GDK_HAND2);
275   regular_cursor = gdk_cursor_new (GDK_XTERM);
276   wait_cursor    = gdk_cursor_new (GDK_WATCH);
277   over_link      = FALSE;
278 
279   gtk_box_set_homogeneous(GTK_BOX(self), FALSE);
280   gtk_box_set_spacing(GTK_BOX(self), 6);
281   gtk_container_set_border_width(GTK_CONTAINER(self), 12);
282 
283   tag_table = rubrica_data_view_create_tag_table();
284 
285   self->priv = RUBRICA_DATA_VIEW_GET_PRIVATE(self);
286 
287   self->priv->buf1  = gtk_text_buffer_new(tag_table);
288   self->priv->buf2  = gtk_text_buffer_new(tag_table);
289   self->priv->text1 = gtk_text_view_new_with_buffer(self->priv->buf1);
290   self->priv->text2 = gtk_text_view_new_with_buffer(self->priv->buf2);
291 
292   self->priv->theme = gtk_icon_theme_get_default();
293   self->priv->image = gtk_image_new();
294   self->priv->font  = NULL;
295 
296   vbox = gtk_vbox_new(FALSE, 0);
297 
298   scrollwin = gtk_scrolled_window_new (NULL, NULL);
299   gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrollwin), vbox);
300   gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwin),
301 				 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
302   gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrollwin),
303 				      GTK_SHADOW_IN);
304   gtk_box_pack_start(GTK_BOX(self), scrollwin, TRUE, TRUE, 0);
305 
306   hbox = gtk_hbox_new(FALSE, 0);
307 
308   gtk_box_pack_start(GTK_BOX(hbox), self->priv->image, FALSE, FALSE, 0);
309   gtk_box_pack_start(GTK_BOX(hbox), self->priv->text1, TRUE, TRUE, 0);
310 
311   gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 0);
312   gtk_box_pack_start(GTK_BOX(vbox), self->priv->text2, TRUE, TRUE, 0);
313 
314   g_object_set(self->priv->text1,
315 	       "cursor-visible", FALSE,
316 	       "editable", FALSE,
317 	       "right-margin", 6,
318 	       "left-margin", 6,
319 	       "wrap-mode", GTK_WRAP_WORD, NULL);
320 
321   g_object_set(self->priv->text2,
322 	       "cursor-visible", FALSE,
323 	       "editable", FALSE,
324 	       "right-margin", 6,
325 	       "left-margin", 6,
326 	       "wrap-mode", GTK_WRAP_WORD, NULL);
327 
328   g_signal_connect (G_OBJECT (self->priv->text2), "key-press-event",
329 		    G_CALLBACK (key_press_event), self);
330 
331   g_signal_connect (G_OBJECT (self->priv->text2), "event-after",
332 		    G_CALLBACK (event_after), self);
333 
334   g_signal_connect (G_OBJECT (self->priv->text2), "motion-notify-event",
335 		    G_CALLBACK (motion_notify_event), self);
336 
337   g_signal_connect (G_OBJECT (self->priv->text2), "visibility-notify-event",
338 		    G_CALLBACK (visibility_notify_event), self);
339 
340   gtk_widget_show(GTK_WIDGET(self));
341   gtk_widget_show(self->priv->image);
342   gtk_widget_show(self->priv->text1);
343   gtk_widget_show(self->priv->text2);
344 
345   gtk_widget_show(vbox);
346   gtk_widget_show(hbox);
347   gtk_widget_show(scrollwin);
348 
349   self->priv->dispose_has_run = FALSE;
350 }
351 
352 
353 static void
rubrica_data_view_set_property(GObject * obj,guint property_id,GValue * value,GParamSpec * spec)354 rubrica_data_view_set_property (GObject* obj, guint property_id,
355 				GValue* value, GParamSpec* spec)
356 {
357   RubricaDataView* self = (RubricaDataView*) obj;
358   RubricaDataViewPrivate* priv = RUBRICA_DATA_VIEW_GET_PRIVATE(self);
359   GtkTextTagTable* table;
360 
361   switch (property_id)
362     {
363     case DATA_FONT:
364       if (priv->font)
365 	g_free(priv->font);
366 
367       priv->font = g_value_dup_string(value);
368       table = gtk_text_buffer_get_tag_table(priv->buf1);
369       gtk_text_tag_table_foreach(table, change_font, priv->font);
370       break;
371 
372     default:
373       break;
374     }
375 }
376 
377 
378 static void
rubrica_data_view_get_property(GObject * obj,guint property_id,GValue * value,GParamSpec * spec)379 rubrica_data_view_get_property (GObject* obj, guint property_id,
380 				GValue* value, GParamSpec* spec)
381 {
382   RubricaDataView* self = (RubricaDataView*) obj;
383   RubricaDataViewPrivate* priv = RUBRICA_DATA_VIEW_GET_PRIVATE(self);
384 
385   switch (property_id)
386     {
387     case DATA_FONT:
388       g_value_set_string(value, priv->font);
389       break;
390 
391      default:
392       break;
393     }
394 }
395 
396 
397 
398 /*   Private
399 */
400 static GtkTextTagTable*
rubrica_data_view_create_tag_table(void)401 rubrica_data_view_create_tag_table(void)
402 {
403   GtkTextTag* tag;
404   GtkTextTagTable* tag_table;
405   PangoFontDescription* pfd;
406   GConfClient* client;
407   const gchar* font = NULL;
408 
409   client = gconf_client_get_default();
410   font   = gconf_client_get_string(client, RUBRICA_GCONF_FONT, NULL);
411 
412   tag_table = gtk_text_tag_table_new();
413 
414   tag = gtk_text_tag_new("tabulato");
415   g_object_set(tag, "left-margin", 25, "right-margin", 25, NULL);
416   gtk_text_tag_table_add(tag_table, tag);
417 
418   if (font)
419     pfd = pango_font_description_from_string (font);
420   else
421     pfd = pango_font_description_from_string ("Serif 10");
422 
423   tag = gtk_text_tag_new("header");
424   g_object_set(tag, "font-desc", pfd, NULL);
425   gtk_text_tag_table_add(tag_table, tag);
426 
427   tag = gtk_text_tag_new("header-bold");
428   g_object_set(tag, "font-desc", pfd, "weight", PANGO_WEIGHT_BOLD, NULL);
429   gtk_text_tag_table_add(tag_table, tag);
430 
431   tag = gtk_text_tag_new("body");
432   g_object_set(tag, "font-desc", pfd, NULL);
433   gtk_text_tag_table_add(tag_table, tag);
434 
435   tag = gtk_text_tag_new("body-bold");
436   g_object_set(tag, "font-desc", pfd, "weight", PANGO_WEIGHT_BOLD, NULL);
437   gtk_text_tag_table_add(tag_table, tag);
438   pango_font_description_free (pfd);
439 
440   g_object_unref(client);
441 
442   return tag_table;
443 }
444 
445 /* Looks at all tags covering the position (x, y) in the text view,
446  * and if one of them is a link, change the cursor to the "hands" cursor
447  * typically used by web browsers.
448  */
449 static void
set_cursor(GtkWidget * text_view,gint x,gint y)450 set_cursor (GtkWidget* text_view, gint x, gint y)
451 {
452   GtkTextIter iter;
453   GSList *tags = NULL, *tagp = NULL;
454   gboolean hovering = FALSE;
455 
456   gtk_text_view_get_iter_at_location (GTK_TEXT_VIEW(text_view), &iter, x, y);
457 
458   tags = gtk_text_iter_get_tags (&iter);
459   for (tagp = tags;  tagp != NULL;  tagp = tagp->next)
460     {
461       GtkTextTag *tag = tagp->data;
462       RubricaLink* link = NULL;
463 
464       link = g_object_get_data (G_OBJECT (tag), "link");
465       if (link)
466         {
467           hovering = TRUE;
468           break;
469         }
470     }
471 
472   if (hovering != over_link)
473     {
474       GdkWindow* window;
475 
476       over_link = hovering;
477 
478       window = gtk_text_view_get_window(GTK_TEXT_VIEW(text_view),
479 					GTK_TEXT_WINDOW_TEXT);
480 
481       if (over_link)
482         gdk_window_set_cursor(window, hand_cursor);
483       else
484         gdk_window_set_cursor(window, regular_cursor);
485     }
486 
487   if (tags)
488     g_slist_free (tags);
489 }
490 
491 
492 static void
insert_link(GtkTextBuffer * buffer,GtkTextIter * iter,gchar * uri,RubricaLinkType type)493 insert_link (GtkTextBuffer *buffer, GtkTextIter *iter, gchar *uri,
494 	     RubricaLinkType type)
495 {
496   GtkTextTag *tag;
497   RubricaLink* link;
498 
499   tag = gtk_text_buffer_create_tag (buffer, NULL,
500 				    "foreground", "blue",
501 				    "underline", PANGO_UNDERLINE_SINGLE,
502 				    NULL);
503 
504   link = g_new0(RubricaLink, 1);
505   link->uri  = g_strdup(uri);
506   link->type = type;
507   g_object_set_data (G_OBJECT (tag), "link", link);
508 
509   gtk_text_buffer_insert_with_tags (buffer, iter, uri, -1, tag, NULL);
510   gtk_text_buffer_insert_with_tags (buffer, iter, "\n", -1, tag, NULL);
511 }
512 
513 
514 
515 /* Looks at all tags covering the position of iter in the text view,
516  * and if one of them is a link, follow it by showing the page identified
517  * by the data attached to it.
518  */
519 static void
follow_if_link(GtkWidget * text_view,GtkTextIter * iter,gpointer data)520 follow_if_link (GtkWidget *text_view, GtkTextIter *iter, gpointer data)
521 {
522   RubricaDataView *view = (RubricaDataView*) data;
523   GSList *tags = NULL;
524   GSList *tagp = NULL;
525 
526   tags = gtk_text_iter_get_tags (iter);
527   for (tagp = tags;  tagp != NULL;  tagp = tagp->next)
528     {
529       RubricaLink* link;
530       GtkTextTag *tag = tagp->data;
531 
532       link = g_object_get_data (G_OBJECT (tag), "link");
533 
534       g_signal_emit_by_name(view, "launch", link, G_TYPE_POINTER);
535     }
536 
537   if (tags)
538     g_slist_free (tags);
539 }
540 
541 
542 /* Links can be activated by pressing Enter.
543  */
544 static gboolean
key_press_event(GtkWidget * text_view,GdkEventKey * event,gpointer data)545 key_press_event (GtkWidget *text_view, GdkEventKey *event, gpointer data)
546 {
547   GtkTextIter iter;
548   GtkTextBuffer *buffer;
549 
550   switch (event->keyval)
551     {
552       case GDK_Return:
553       case GDK_KP_Enter:
554         buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_view));
555         gtk_text_buffer_get_iter_at_mark (buffer, &iter,
556                                           gtk_text_buffer_get_insert (buffer));
557         follow_if_link (text_view, &iter, data);
558         break;
559 
560       default:
561         break;
562     }
563 
564   return FALSE;
565 }
566 
567 
568 /* Links can also be activated by clicking.
569  */
570 static gboolean
event_after(GtkWidget * text_view,GdkEvent * ev,gpointer data)571 event_after (GtkWidget *text_view, GdkEvent  *ev, gpointer data)
572 {
573   GtkTextIter start, end, iter;
574   GtkTextBuffer *buffer;
575   GdkEventButton *event;
576   gint x, y;
577 
578   if (ev->type != GDK_BUTTON_RELEASE)
579     return FALSE;
580 
581   event = (GdkEventButton *)ev;
582 
583   if (event->button != 1)
584     return FALSE;
585 
586   buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_view));
587 
588   /* we shouldn't follow a link if the user has selected something */
589   gtk_text_buffer_get_selection_bounds (buffer, &start, &end);
590   if (gtk_text_iter_get_offset (&start) != gtk_text_iter_get_offset (&end))
591     return FALSE;
592 
593   gtk_text_view_window_to_buffer_coords (GTK_TEXT_VIEW (text_view),
594                                          GTK_TEXT_WINDOW_WIDGET,
595                                          event->x, event->y, &x, &y);
596 
597   gtk_text_view_get_iter_at_location (GTK_TEXT_VIEW (text_view), &iter, x, y);
598 
599   follow_if_link (text_view, &iter, data);
600 
601   return FALSE;
602 }
603 
604 
605 
606 /* Update the cursor image if the pointer moved.
607  */
608 static gboolean
motion_notify_event(GtkWidget * text_view,GdkEventMotion * event,gpointer data)609 motion_notify_event (GtkWidget* text_view, GdkEventMotion *event,
610 		     gpointer data)
611 {
612   RubricaDataView* view = (RubricaDataView*) data;
613   RubricaDataViewPrivate* priv;
614   gint x, y;
615 
616   priv = RUBRICA_DATA_VIEW_GET_PRIVATE(view);
617 
618   gtk_text_view_window_to_buffer_coords (GTK_TEXT_VIEW (text_view),
619                                          GTK_TEXT_WINDOW_WIDGET,
620                                          event->x, event->y, &x, &y);
621 
622   set_cursor (text_view, x, y);
623 
624   gdk_window_get_pointer (text_view->window, NULL, NULL, NULL);
625 
626   return FALSE;
627 }
628 
629 
630 /* Also update the cursor image if the window becomes visible
631  * (e.g. when a window covering it got iconified).
632  */
633 static gboolean
visibility_notify_event(GtkWidget * text_view,GdkEventVisibility * event,gpointer data)634 visibility_notify_event (GtkWidget* text_view, GdkEventVisibility *event,
635 			 gpointer data)
636 {
637   RubricaDataViewPrivate* priv = RUBRICA_DATA_VIEW_GET_PRIVATE(data);
638   gint wx, wy, bx, by;
639 
640   gdk_window_get_pointer (priv->text2->window, &wx, &wy, NULL);
641 
642   gtk_text_view_window_to_buffer_coords (GTK_TEXT_VIEW (priv->text2),
643                                          GTK_TEXT_WINDOW_WIDGET,
644                                          wx, wy, &bx, &by);
645 
646   set_cursor (text_view, bx, by);
647 
648   return FALSE;
649 }
650 
651 
652 static void
clean_buffer(GtkTextBuffer * buffer)653 clean_buffer(GtkTextBuffer* buffer)
654 {
655   GtkTextIter start, end;
656 
657   gtk_text_buffer_get_bounds(buffer, &start, &end);
658   gtk_text_buffer_delete(buffer, &start, &end);
659   gtk_text_buffer_get_iter_at_offset(buffer, &start, 0);
660 }
661 
662 
663 static void
data_view_clear_header(RubricaDataView * view)664 data_view_clear_header(RubricaDataView* view)
665 {
666   RubricaDataViewPrivate* priv = RUBRICA_DATA_VIEW_GET_PRIVATE(view);
667 
668   clean_buffer(priv->buf1);
669 }
670 
671 
672 static void
data_view_clear_body(RubricaDataView * view)673 data_view_clear_body(RubricaDataView* view)
674 {
675   RubricaDataViewPrivate* priv = RUBRICA_DATA_VIEW_GET_PRIVATE(view);
676 
677   clean_buffer(priv->buf2);
678 }
679 
680 
681 static void
data_view_set_image(RubricaDataView * view,GdkPixbuf * pixbuf)682 data_view_set_image(RubricaDataView* view, GdkPixbuf* pixbuf)
683 {
684   RubricaDataViewPrivate* priv;
685 
686   g_return_if_fail(IS_RUBRICA_DATA_VIEW(view));
687   g_return_if_fail(pixbuf != NULL);
688 
689   priv = RUBRICA_DATA_VIEW_GET_PRIVATE(view);
690 
691   gtk_image_set_from_pixbuf(GTK_IMAGE(priv->image), pixbuf);
692   g_object_unref(pixbuf);
693 }
694 
695 
696 static void
data_view_write_card_header(GtkTextBuffer * buffer,gchar * label,gchar * string)697 data_view_write_card_header(GtkTextBuffer* buffer, gchar* label, gchar* string)
698 {
699   GtkTextIter iter;
700 
701   g_return_if_fail(label != NULL);
702   g_return_if_fail(string != NULL);
703 
704   gtk_text_buffer_get_end_iter (buffer, &iter);
705 
706   gtk_text_buffer_insert_with_tags_by_name (buffer, &iter, label, -1,
707 					    "header-bold", NULL);
708   gtk_text_buffer_insert_with_tags_by_name (buffer, &iter, string, -1,
709 					    "header", NULL);
710   gtk_text_buffer_insert(buffer, &iter, "\n", -1);
711 }
712 
713 
714 static void
data_view_write_pixbuf(GtkTextBuffer * buffer,GdkPixbuf * pixbuf,gchar * label)715 data_view_write_pixbuf(GtkTextBuffer* buffer, GdkPixbuf* pixbuf, gchar* label)
716 {
717   GtkTextIter iter;
718 
719   gtk_text_buffer_get_end_iter (buffer, &iter);
720 
721   gtk_text_buffer_insert_pixbuf(buffer, &iter, pixbuf);
722   gtk_text_buffer_insert_with_tags_by_name (buffer, &iter, label, -1,
723 					    "body-bold", NULL);
724   gtk_text_buffer_insert(buffer, &iter, "\n", -1);
725 }
726 
727 
728 static void
data_view_write_bold(GtkTextBuffer * buffer,gchar * label,gchar * string,gboolean bool)729 data_view_write_bold(GtkTextBuffer* buffer, gchar* label, gchar* string,
730 		     gboolean bool)
731 {
732   GtkTextIter iter;
733 
734   gtk_text_buffer_get_end_iter (buffer, &iter);
735 
736   if (bool)
737     gtk_text_buffer_insert_with_tags_by_name (buffer, &iter, label, -1,
738 					      "body-bold", "tabulato", NULL);
739   else
740     gtk_text_buffer_insert_with_tags_by_name (buffer, &iter, label, -1,
741 					      "body-bold", NULL);
742 
743   gtk_text_buffer_insert(buffer, &iter, string, -1);
744   gtk_text_buffer_insert(buffer, &iter, "\n", -1);
745 }
746 
747 
748 static void
data_view_write_line(GtkTextBuffer * buffer,gchar * label,gchar * string,gboolean tab)749 data_view_write_line(GtkTextBuffer* buffer, gchar* label,
750 		     gchar* string, gboolean tab)
751 {
752   if (string && (g_ascii_strcasecmp(string, "") != 0))
753     {
754       gchar* lbl;
755 
756       lbl = g_strdup_printf("%s: ", label);
757 
758       data_view_write_bold(buffer, lbl, string, tab);
759 
760       g_free(lbl);
761     }
762 }
763 
764 
765 static void
data_view_write_link(GtkTextBuffer * buffer,gchar * label,gchar * url,RubricaLinkType link)766 data_view_write_link(GtkTextBuffer* buffer, gchar* label, gchar* url,
767 		     RubricaLinkType link)
768 {
769   GtkTextIter iter;
770   gchar* str;
771 
772   str = g_strdup_printf("%s: ", label);
773 
774   gtk_text_buffer_get_end_iter (buffer, &iter);
775 
776   gtk_text_buffer_insert_with_tags_by_name (buffer, &iter, str, -1,
777 					    "body-bold", "tabulato", NULL);
778   insert_link(buffer, &iter, url, link);
779 }
780 
781 
782 static void
data_view_write(GtkTextBuffer * buffer,gchar * str)783 data_view_write(GtkTextBuffer* buffer, gchar* str)
784 {
785   GtkTextIter iter;
786 
787   g_return_if_fail(str != NULL);
788 
789   gtk_text_buffer_get_end_iter (buffer, &iter);
790   gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, str, -1,
791 					   "body", "tabulato", NULL);
792 }
793 
794 
795 static void
write_company_info(RubricaDataView * view,RCard * card)796 write_company_info(RubricaDataView* view, RCard* card)
797 {
798   RubricaDataViewPrivate* priv;
799   GtkTextBuffer* header;
800   GdkPixbuf* pixbuf = NULL;
801   gchar *name, *logo, *vat;
802   gchar *label, *string;
803 
804   priv = RUBRICA_DATA_VIEW_GET_PRIVATE(view);
805   header = priv->buf1;
806 
807   g_object_get(card, "card-name", &name, "company-logo", &logo,
808 	       "company-vat", &vat, NULL);
809 
810   if (g_file_test(logo, G_FILE_TEST_EXISTS))
811     pixbuf = gdk_pixbuf_new_from_file_at_size(logo, 128, 128, NULL);
812   else
813     pixbuf = gtk_icon_theme_load_icon(priv->theme, "card_photo", 128, 0, NULL);
814 
815   data_view_set_image(view, pixbuf);
816 
817   label  = g_strdup_printf("%s: ", _("Card"));
818   string = g_strdup_printf("%s\n\n", name);
819   data_view_write_card_header(header, label, string);
820   g_free(label);
821   g_free(string);
822 
823   if (vat && (g_ascii_strcasecmp(vat, "") != 0))
824     {
825       /* Translators: VAT (Value Added Tax) */
826       string = g_strdup_printf("%s: ", _("Taxpayer number/VAT"));
827       data_view_write_bold(header, string, vat, FALSE);
828 
829       g_free(string);
830     }
831 }
832 
833 
834 static void
write_personal_data(RubricaDataView * view,RPersonalCard * card)835 write_personal_data(RubricaDataView* view, RPersonalCard* card)
836 {
837   RubricaDataViewPrivate* priv;
838   RDate* date;
839   GtkTextBuffer* header;
840   GdkPixbuf* pixbuf = NULL;
841   RContact* contact;
842   gchar* card_name;
843   gchar *first = NULL, *last = NULL, *middle = NULL;
844   gchar *nick = NULL, *title = NULL, *prefix = NULL;
845   gchar *prof = NULL, *photo = NULL;
846   gchar *label, *string;
847 
848   priv    = RUBRICA_DATA_VIEW_GET_PRIVATE(view);
849   header  = priv->buf1;
850   contact = r_personal_card_get_contact(R_PERSONAL_CARD(card));
851 
852   g_object_get(contact,
853 	       "first-name",  &first,  "last-name", &last,
854 	       "middle-name", &middle, "nick-name", &nick,
855 	       "title",       &title,  "prefix",    &prefix,
856 	       "profession",  &prof,   "photo",     &photo, NULL);
857   g_object_get(R_CARD(card), "card-name", &card_name, NULL);
858 
859   /* display photo */
860   if (g_file_test(photo, G_FILE_TEST_EXISTS))
861     pixbuf = gdk_pixbuf_new_from_file_at_size(photo, 128, 128, NULL);
862   else
863     pixbuf = gtk_icon_theme_load_icon(priv->theme, "card_photo", 128, 0, NULL);
864   data_view_set_image(view, pixbuf);
865 
866   /* display card's name */
867   label  = g_strdup_printf("%s: ", _("Card"));
868   string = g_strdup_printf("%s\n", card_name);
869   data_view_write_card_header(header, label, string);
870   g_free(label);
871   g_free(string);
872 
873   /* display contact's data */
874   if (first || middle || last)
875     {
876       gchar *str;
877 
878       label = g_strdup_printf("%s: ", _("Name"));
879       str   = g_strdup_printf("%s %s %s",
880 			      last   ? last   : "",
881 			      first  ? first  : "",
882 			      middle ? middle : "");
883       data_view_write_bold(header, label, str, FALSE);
884 
885       g_free(label);
886       g_free(str);
887     }
888 
889   data_view_write_line(header, _("Nickname"),   nick,   FALSE);
890   data_view_write_line(header, _("Title"),      title,  FALSE);
891   data_view_write_line(header, _("Prefix"),     prefix, FALSE );
892   data_view_write_line(header, _("Profession"), prof,   FALSE);
893 
894   date = r_contact_get_birthday(contact);
895   if (r_date_is_valid(date))
896     {
897       label = g_strdup_printf("%s: ", _("Birthday"));
898       data_view_write_bold(header, label, r_date_get_human_date(date), FALSE);
899 
900       g_free(label);
901     }
902 }
903 
904 
905 
906 static void
write_groups(RubricaDataView * view,RCard * card)907 write_groups(RubricaDataView* view, RCard* card)
908 {
909   RubricaDataViewPrivate* priv;
910   GtkTextBuffer* body;
911   gpointer group = NULL;
912 
913   priv = RUBRICA_DATA_VIEW_GET_PRIVATE(view);
914   body = priv->buf2;
915 
916   group = r_card_get_group(R_CARD(card));
917   if (group)
918     {
919       data_view_write(body, "\n");
920       data_view_write_bold(body, _("Card's groups"), "", FALSE);
921 
922       for (; group; group = r_card_get_next_group(R_CARD(card)))
923 	{
924 	  gchar *str, *name = NULL;
925 
926 	  g_object_get(R_GROUP(group), "group-name",  &name, NULL);
927 
928 	  str = g_strdup_printf("%s\n", _(name));
929 	  data_view_write(body, str);
930 
931 	  g_free(str);
932 	}
933     }
934 }
935 
936 
937 static void
write_addresses(RubricaDataView * view,RCard * card)938 write_addresses(RubricaDataView* view, RCard* card)
939 {
940   RubricaDataViewPrivate* priv;
941   GtkTextBuffer* body;
942   RAddress* address;
943   GdkPixbuf* pixbuf = NULL;
944 
945   priv = RUBRICA_DATA_VIEW_GET_PRIVATE(view);
946   body = priv->buf2;
947 
948   address = r_card_get_address(R_CARD(card));
949   if (address)
950     {
951       pixbuf = gtk_icon_theme_load_icon (priv->theme, "mailbox", 20, 0, NULL);
952 
953       data_view_write(body, "\n");
954       data_view_write_pixbuf(body, pixbuf, _("Addresses"));
955       g_object_unref(pixbuf);
956 
957       for (; address; address = r_card_get_next_address(R_CARD(card)))
958 	{
959 	  RAddressType type;
960 	  gchar *adtype, *street, *number, *zip;
961 	  gchar *city, *province, *state, *country;
962 
963 	  g_object_get(address, "address-type", &type,
964 		       "street", &street, "street-number", &number,
965 		       "zip", &zip, "city", &city,
966 		       "province", &province, "state", &state,
967 		       "country", &country, NULL);
968 
969 	  if ((street && (g_ascii_strcasecmp(street, "") != 0))   ||
970 	      (zip && (g_ascii_strcasecmp(zip, "") != 0))         ||
971 	      (city && (g_ascii_strcasecmp(city, "") != 0))       ||
972 	      (state && (g_ascii_strcasecmp(state, "") != 0))     ||
973 	      (country && (g_ascii_strcasecmp(country, "") != 0)))
974 	    {
975 	      GString* string;
976 
977 	      string = g_string_new("");
978 
979 	      adtype = r_address_lookup_enum2str(type);
980 	      data_view_write_bold(body, _(adtype), "", TRUE);
981 
982 	      if (street && (g_ascii_strcasecmp(street, "") != 0))
983 		{
984 		  g_string_printf(string, "%s", street);
985 
986 		  if (number && (g_ascii_strcasecmp(number, "") != 0))
987 		    g_string_append_printf(string, ", %s", number);
988 		}
989 
990 	      if ((zip && (g_ascii_strcasecmp(zip, "") != 0))   ||
991 		  (city && (g_ascii_strcasecmp(city, "") != 0)) ||
992 		  (province && (g_ascii_strcasecmp(province, "") != 0)))
993 		{
994 		  g_string_append_printf(string, "\n");
995 
996 		  if (zip && (g_ascii_strcasecmp(zip, "") != 0))
997 		    g_string_append_printf(string, "%s ", zip);
998 
999 		  if (city && (g_ascii_strcasecmp(city, "") != 0))
1000 		    g_string_append_printf(string, "%s", city);
1001 
1002 		  if (province && (g_ascii_strcasecmp(province, "") != 0))
1003 		    g_string_append_printf(string, ", (%s) ", province);
1004 		}
1005 
1006 	      if ((state && (g_ascii_strcasecmp(state, "") != 0))   ||
1007 		  (country && (g_ascii_strcasecmp(country, "") != 0)))
1008 		{
1009 		  g_string_append_printf(string, "\n");
1010 
1011 		  if (state && (g_ascii_strcasecmp(state, "") != 0))
1012 		    g_string_append_printf(string, "%s ", state);
1013 
1014 		  if (country && (g_ascii_strcasecmp(country, "") != 0))
1015 		    g_string_append_printf(string, "%s",country);
1016 		}
1017 
1018 	      data_view_write(body, string->str);
1019 	      data_view_write(body, "\n");
1020 
1021 	      g_string_free(string, TRUE);
1022 	    }
1023 	}
1024     }
1025 }
1026 
1027 
1028 
1029 static void
write_work(RubricaDataView * view,RPersonalCard * card)1030 write_work(RubricaDataView* view, RPersonalCard* card)
1031 {
1032   RubricaDataViewPrivate* priv;
1033   GtkTextBuffer* body;
1034   RWork* work = NULL;
1035   GdkPixbuf* pixbuf = NULL;
1036   gchar *assignment = NULL, *organization = NULL;
1037   gchar *department = NULL, *subdep = NULL, *manager = NULL;
1038   gchar *collaborator = NULL, *mphone = NULL, *cphone = NULL;
1039 
1040   priv = RUBRICA_DATA_VIEW_GET_PRIVATE(view);
1041   body = priv->buf2;
1042 
1043   work = r_personal_card_get_work(R_PERSONAL_CARD(card));
1044   if (work && r_work_have_data(work))
1045     {
1046       g_object_get(work,
1047 		   "assignment",         &assignment,
1048 		   "organization",       &organization,
1049 		   "department",         &department,
1050 		   "sub-department",     &subdep,
1051 		   "manager-name",       &manager,
1052 		   "collaborator",       &collaborator,
1053 		   "manager-phone",      &mphone,
1054 		   "collaborator-phone", &cphone, NULL);
1055 
1056       pixbuf = gtk_icon_theme_load_icon (priv->theme, "role", 20, 0, NULL);
1057 
1058       data_view_write(body, "\n");
1059       data_view_write_pixbuf(body, pixbuf, _("Work"));
1060       g_object_unref(pixbuf);
1061       data_view_write_line(body, _("Assignment"), assignment, TRUE);
1062       data_view_write_line(body, _("Organization"), organization, TRUE);
1063       data_view_write_line(body, _("Department"), department, TRUE);
1064       data_view_write_line(body, _("Subdepartment"), subdep, TRUE);
1065       data_view_write_line(body, _("Manager"), manager, TRUE);
1066       data_view_write_line(body, _("Manager's telephone"), collaborator, TRUE);
1067       data_view_write_line(body, _("Collaborator"), mphone, TRUE);
1068       data_view_write_line(body, _("Collaborator's telephone"), cphone, TRUE);
1069     }
1070 }
1071 
1072 
1073 
1074 static void
write_net(RubricaDataView * view,RCard * card)1075 write_net (RubricaDataView* view, RCard* card)
1076 {
1077   RubricaDataViewPrivate* priv;
1078   GtkTextBuffer* body;
1079   GdkPixbuf* pixbuf = NULL;
1080   RNetAddress* net = NULL;
1081   RNetAddressType type;
1082   RubricaLinkType linktype = UNKNOWN_LINK;
1083   gchar* url;
1084 
1085   priv = RUBRICA_DATA_VIEW_GET_PRIVATE(view);
1086   body = priv->buf2;
1087 
1088   net = r_card_get_net_address(R_CARD(card));
1089   if (net)
1090     {
1091       pixbuf = gtk_icon_theme_load_icon (priv->theme, "net", 20, 0, NULL);
1092 
1093       data_view_write(body, "\n");
1094       data_view_write_pixbuf(body, pixbuf, _("Net"));
1095       g_object_unref(pixbuf);
1096 
1097       for (; net; net = r_card_get_next_net_address(R_CARD(card)))
1098 	{
1099 	  gchar* ttype;
1100 	  g_object_get(R_NET_ADDRESS(net),
1101 		       "url", &url, "url-type", &type, NULL);
1102 
1103 	  switch(type)
1104 	    {
1105 	    case R_NET_ADDRESS_WEB:
1106 	      linktype = WEB_LINK;
1107 	      break;
1108 
1109 	    case R_NET_ADDRESS_EMAIL:
1110 	      linktype = EMAIL_LINK;
1111 	      break;
1112 
1113 	    case R_NET_ADDRESS_EKIGA:
1114 	      linktype = TELEPHONE_LINK;
1115 	      break;
1116 
1117 	    case R_NET_ADDRESS_IRC_AIM:
1118 	      linktype = IRC_LINK;
1119 	      break;
1120 
1121 	    case R_NET_ADDRESS_IRC_ICQ:
1122 	      linktype = IRC_LINK;
1123 	      break;
1124 
1125 	    case R_NET_ADDRESS_IRC_JABBER:
1126 	      linktype = IRC_LINK;
1127 	      break;
1128 
1129 	    case R_NET_ADDRESS_IRC_YAHOO:
1130 	      linktype = IRC_LINK;
1131 	      break;
1132 
1133 	    case R_NET_ADDRESS_IRC_MSN:
1134 	      linktype = IRC_LINK;
1135 	      break;
1136 
1137 
1138 	    default:
1139 	      break;
1140 	    }
1141 
1142 	  ttype = r_net_address_decode_type(type);
1143 	  data_view_write_link(body, _(ttype), url, linktype);
1144 	}
1145     }
1146 }
1147 
1148 
1149 static void
write_telephones(RubricaDataView * view,RCard * card)1150 write_telephones(RubricaDataView* view, RCard* card)
1151 {
1152   RubricaDataViewPrivate* priv;
1153   GtkTextBuffer* body;
1154   RTelephone* tel = NULL;
1155   GdkPixbuf* pixbuf = NULL;
1156 
1157   priv = RUBRICA_DATA_VIEW_GET_PRIVATE(view);
1158   body = priv->buf2;
1159 
1160   tel = r_card_get_telephone(R_CARD(card));
1161   if (tel)
1162     {
1163       pixbuf = gtk_icon_theme_load_icon (priv->theme, "phone", 20, 0, NULL);
1164 
1165       data_view_write(body, "\n");
1166       data_view_write_pixbuf(body, pixbuf, _("Telephone"));
1167       g_object_unref(pixbuf);
1168 
1169       for (; tel; tel = r_card_get_next_telephone(R_CARD(card)))
1170 	{
1171 	  RTelephoneType ttype;
1172 	  gchar* num;
1173 
1174 	  g_object_get(R_TELEPHONE(tel),
1175 		       "telephone-number", &num,
1176 		       "telephone-type",   &ttype, NULL);
1177 
1178 	  data_view_write_link(body, _(r_telephone_lookup_enum2str(ttype)),
1179 			       num, TELEPHONE_LINK);
1180 	}
1181     }
1182 }
1183 
1184 
1185 
1186 static void
write_notes(RubricaDataView * view,RPersonalCard * card)1187 write_notes(RubricaDataView* view, RPersonalCard* card)
1188 {
1189   RubricaDataViewPrivate* priv;
1190   GtkTextBuffer* body;
1191   RNotes* notes;
1192   GdkPixbuf* pixbuf = NULL;
1193   gchar *partner, *other_notes, *pubkey;
1194   gboolean has_partner;
1195 
1196   priv  = RUBRICA_DATA_VIEW_GET_PRIVATE(view);
1197   body  = priv->buf2;
1198   notes = r_personal_card_get_notes(R_PERSONAL_CARD(card));
1199 
1200   if (notes && r_notes_have_data(notes))
1201     {
1202       g_object_get(notes,
1203 		   "has-partner",  &has_partner,
1204 		   "partner-name", &partner,
1205 		   "other-notes",  &other_notes,
1206 		   "pubkey",       &pubkey, NULL);
1207 
1208       pixbuf = gtk_icon_theme_load_icon (priv->theme, "notes", 20, 0, NULL);
1209 
1210       data_view_write(body, "\n");
1211       data_view_write_pixbuf(body, pixbuf, _("Notes"));
1212       g_object_unref(pixbuf);
1213 
1214       if (has_partner)
1215 	{
1216 	  data_view_write(body, _("Contact has a partner"));
1217 	  data_view_write(body, "\n");
1218 
1219 	  data_view_write_line(body, _("partner's name"), partner, TRUE);
1220 
1221 	  if (r_notes_know_birthday(notes))
1222 	    {
1223 	      data_view_write_line(body, _("partner's birthday"),
1224 				   r_notes_get_birth_date(notes), TRUE);
1225 	    }
1226 
1227 	  if (r_notes_know_anniversary(notes))
1228 	    {
1229 	      data_view_write_line(body, _("anniversary"),
1230 				   r_notes_get_anniversary_date(notes), TRUE);
1231 	    }
1232 	}
1233 
1234       data_view_write_line(body, _("Public key"), pubkey, TRUE);
1235       data_view_write_line(body, _("Other notes"), other_notes, TRUE);
1236     }
1237 }
1238 
1239 
1240 static void
write_company_notes(RubricaDataView * view,RCompanyCard * card)1241 write_company_notes(RubricaDataView* view, RCompanyCard* card)
1242 {
1243   RubricaDataViewPrivate* priv;
1244   GtkTextBuffer* body;
1245   gchar* text = NULL;
1246 
1247   priv = RUBRICA_DATA_VIEW_GET_PRIVATE(view);
1248   body = priv->buf2;
1249 
1250   g_object_get(card, "company-notes", &text, NULL);
1251   if (text)
1252     {
1253       GdkPixbuf* pixbuf = NULL;
1254 
1255       pixbuf = gtk_icon_theme_load_icon (priv->theme, "notes", 20, 0, NULL);
1256       data_view_write(body, "\n");
1257       data_view_write_pixbuf(body, pixbuf, _("Notes"));
1258       data_view_write(body, "\n");
1259       g_object_unref(pixbuf);
1260 
1261       data_view_write(body, text);
1262     }
1263 }
1264 
1265 
1266 
1267 static void
data_view_show_personal_card(RubricaDataView * view,RCard * card)1268 data_view_show_personal_card(RubricaDataView* view, RCard* card)
1269 {
1270   RubricaDataViewPrivate* priv;
1271 
1272   priv = RUBRICA_DATA_VIEW_GET_PRIVATE(view);
1273 
1274   /* Clean header and body buffers */
1275   data_view_clear_header(view);
1276   data_view_clear_body(view);
1277 
1278   write_personal_data (view, R_PERSONAL_CARD(card));
1279   write_groups        (view, card);
1280   write_addresses     (view, card);
1281   write_work          (view, R_PERSONAL_CARD(card));
1282   write_net           (view, card);
1283   write_telephones    (view, card);
1284   write_notes         (view, R_PERSONAL_CARD(card));
1285 }
1286 
1287 
1288 
1289 static void
data_view_show_company_card(RubricaDataView * view,RCard * card)1290 data_view_show_company_card(RubricaDataView* view, RCard* card)
1291 {
1292   RubricaDataViewPrivate* priv;
1293 
1294   priv = RUBRICA_DATA_VIEW_GET_PRIVATE(view);
1295 
1296   data_view_clear_header(view);
1297   data_view_clear_body(view);
1298 
1299   write_company_info  (view, card);
1300   write_groups        (view, card);
1301   write_addresses     (view, card);
1302   write_net           (view, card);
1303   write_telephones    (view, card);
1304   write_company_notes (view, R_COMPANY_CARD(card));
1305 }
1306 
1307 
1308 
1309 
1310 
1311 
1312 /*   Public
1313 */
1314 /**
1315  * rubrica_data_view_new
1316  *
1317  * create a #RubricaDataView
1318  *
1319  * returns: a new #RubricaDataView*
1320  */
1321 GtkWidget*
rubrica_data_view_new()1322 rubrica_data_view_new()
1323 {
1324   GtkWidget* view;
1325 
1326   view = GTK_WIDGET(g_object_new(RUBRICA_DATA_VIEW_TYPE, NULL));
1327 
1328   return view;
1329 }
1330 
1331 
1332 void
rubrica_data_view_show_card(RubricaDataView * view,RCard * card)1333 rubrica_data_view_show_card (RubricaDataView* view, RCard* card)
1334 {
1335   g_return_if_fail(IS_RUBRICA_DATA_VIEW(view));
1336   g_return_if_fail(IS_R_CARD(card));
1337 
1338   if (r_card_is_personal(card))
1339     data_view_show_personal_card(view, card);
1340   else
1341     data_view_show_company_card(view, card);
1342 }
1343