static void cache_cb(EBook *book, EBookStatus estatus, GList *contacts, void *user_data) { struct query_context *data = user_data; GList *l; if (estatus == E_BOOK_ERROR_CANCELLED) { error("E-Book operation was cancelled: status %d", estatus); goto fail; } data->completed = TRUE; if (estatus != E_BOOK_ERROR_OK) { error("E-Book query failed: status %d", estatus); goto done; } for (l = contacts; l; l = g_list_next(l)) { EContact *contact = E_CONTACT(l->data); EVCard *evcard = E_VCARD(contact); EVCardAttribute *attrib; char *uid, *tel, *name; name = evcard_name_attribute_to_string(evcard); if (!name) continue; attrib = e_vcard_get_attribute(evcard, EVC_UID); if (!attrib) continue; uid = e_vcard_attribute_get_value(attrib); if (!uid) continue; attrib = e_vcard_get_attribute(evcard, EVC_TEL); if (!attrib) continue; tel = e_vcard_attribute_get_value(attrib); data->entry_cb(uid, PHONEBOOK_INVALID_HANDLE, name, NULL, tel, data->user_data); g_free(name); g_free(uid); g_free(tel); } done: data->ready_cb(data->user_data); fail: if (data->completed) g_free(data); }
GdkPixbuf * hito_vcard_get_photo_pixbuf (EVCard *card) { GdkPixbuf *ret; GList *list = NULL; list = hito_vcard_get_named_attributes (card, EVC_PHOTO); if (list) { GdkPixbufLoader *ploader; guchar *buf; gsize size; const gchar *value; gchar *type, *type_up; int cmp = 0; value = e_vcard_attribute_get_value ((EVCardAttribute *)list->data); if (!value) { g_list_free (list); return NULL; } type = hito_vcard_attribute_get_type (list->data); if (type) { type_up = g_ascii_strup (type, -1); cmp = strcmp (type_up, "URL"); g_free (type); g_free (type_up); /* TODO: we can't deal with images from URLs yet */ if (!cmp) { g_list_free (list); return NULL; } } buf = g_base64_decode (value, &size); ploader = gdk_pixbuf_loader_new (); g_signal_connect (G_OBJECT (ploader), "size-prepared", G_CALLBACK (contact_photo_size), NULL); gdk_pixbuf_loader_write (ploader, buf, size, NULL); gdk_pixbuf_loader_close (ploader, NULL); ret = g_object_ref (gdk_pixbuf_loader_get_pixbuf (ploader)); g_object_unref (ploader); g_list_free (list); return ret; } else { return NULL; } }
static void verify_commit (EContact *contact) { EVCardAttribute *attr; gchar *email_value; g_assert ((attr = e_vcard_get_attribute (E_VCARD (contact), EVC_EMAIL))); g_assert (e_vcard_attribute_is_single_valued (attr)); email_value = e_vcard_attribute_get_value (attr); g_assert (!g_strcmp0 (email_value, EMAIL_ADD)); }
static gboolean compare_single_value (EVCard *vcard, const gchar *attrname, const gchar *expected_value) { EVCardAttribute *attr; gchar *str; g_return_val_if_fail (vcard != NULL, FALSE); g_return_val_if_fail (attrname != NULL, FALSE); g_return_val_if_fail (expected_value != NULL, FALSE); attr = e_vcard_get_attribute (vcard, attrname); g_return_val_if_fail (attr != NULL, FALSE); str = e_vcard_attribute_get_value (attr); g_return_val_if_fail (str != NULL, FALSE); g_return_val_if_fail (g_strcmp0 (str, expected_value) == 0, FALSE); g_free (str); return TRUE; }
static void accum_sip (GString *buffer, EContact *contact, EABContactFormatterSIPType use_sip_type, const gchar *icon, guint html_flags) { const gchar *html_label = _("SIP"); GList *sip_attr_list, *l; GString *val = g_string_new (""); gchar *tmp; sip_attr_list = e_contact_get_attributes (contact, E_CONTACT_SIP); for (l = sip_attr_list; l; l = g_list_next (l)) { EVCardAttribute *attr = l->data; gchar *sip; const gchar *str; EABContactFormatterSIPType sip_type; if (e_vcard_attribute_has_type (attr, "HOME")) sip_type = EAB_CONTACT_FORMATTER_SIP_TYPE_HOME; else if (e_vcard_attribute_has_type (attr, "WORK")) sip_type = EAB_CONTACT_FORMATTER_SIP_TYPE_WORK; else sip_type = EAB_CONTACT_FORMATTER_SIP_TYPE_OTHER; if (sip_type != use_sip_type) continue; sip = e_vcard_attribute_get_value (attr); if (!sip || !*sip) { g_free (sip); continue; } tmp = maybe_create_url (sip, html_flags); if (tmp) str = tmp; else str = sip; if ((html_flags & E_TEXT_TO_HTML_CONVERT_URLS) != 0) { gchar *value = e_text_to_html (str, html_flags); if (value && *value) { if (val->len) g_string_append (val, "<br>"); g_string_append (val, value); } g_free (value); } else { if (val->len) g_string_append (val, "<br>"); g_string_append (val, str); } g_free (tmp); g_free (sip); } if (val->str && *val->str) { if ((html_flags & E_TEXT_TO_HTML_CONVERT_URLS) != 0) html_flags = 0; render_table_row (buffer, html_label, val->str, icon, html_flags); } g_string_free (val, TRUE); g_list_free_full (sip_attr_list, (GDestroyNotify) e_vcard_attribute_free); }
void *phonebook_create_cache(const char *name, phonebook_entry_cb entry_cb, phonebook_cache_ready_cb ready_cb, void *user_data, int *err) { struct query_context *data; EBookQuery *query; GSList *l; EContact *me; EVCard *evcard; GError *gerr = NULL; EBook *eb; EVCardAttribute *attrib; char *uid, *tel, *cname; if (g_strcmp0(PB_CONTACTS_FOLDER, name) != 0) { if (err) *err = -ENOENT; return NULL; } DBG(""); query = e_book_query_any_field_contains(""); data = g_new0(struct query_context, 1); data->entry_cb = entry_cb; data->ready_cb = ready_cb; data->user_data = user_data; data->query = query; data->ebooks = open_ebooks(); /* Add 0.vcf */ if (e_book_get_self(&me, &eb, &gerr) == FALSE) { g_error_free(gerr); goto next; } evcard = E_VCARD(me); cname = evcard_name_attribute_to_string(evcard); if (!cname) cname = g_strdup(""); attrib = e_vcard_get_attribute(evcard, EVC_UID); uid = e_vcard_attribute_get_value(attrib); if (!uid) uid = g_strdup(""); attrib = e_vcard_get_attribute(evcard, EVC_TEL); if (attrib) tel = e_vcard_attribute_get_value(attrib); else tel = g_strdup(""); data->entry_cb(uid, 0, cname, NULL, tel, data->user_data); data->count++; g_free(cname); g_free(uid); g_free(tel); g_object_unref(eb); next: for (l = data->ebooks; l != NULL; l = g_slist_next(l)) { EBook *ebook = l->data; if (e_book_is_opened(ebook) == FALSE) continue; if (e_book_get_contacts_async(ebook, query, cache_cb, data) == TRUE) data->queued_calls++; } if (err) *err = (data->queued_calls == 0 ? -ENOENT : 0); return data; }
static void cache_cb(EBook *book, const GError *gerr, GList *contacts, void *user_data) { struct query_context *data = user_data; GList *l; data->queued_calls--; if (data->canceled) goto canceled; if (gerr != NULL) { error("E-Book operation failed: %s", gerr->message); goto done; } DBG(""); for (l = contacts; l; l = g_list_next(l)) { EContact *contact = E_CONTACT(l->data); EVCard *evcard = E_VCARD(contact); EVCardAttribute *attrib; char *uid, *tel, *name; name = evcard_name_attribute_to_string(evcard); if (!name) continue; attrib = e_vcard_get_attribute(evcard, EVC_UID); if (!attrib) continue; uid = e_vcard_attribute_get_value(attrib); if (!uid) continue; attrib = e_vcard_get_attribute(evcard, EVC_TEL); if (attrib) tel = e_vcard_attribute_get_value(attrib); else tel = g_strdup(""); data->entry_cb(uid, PHONEBOOK_INVALID_HANDLE, name, NULL, tel, data->user_data); g_free(name); g_free(uid); g_free(tel); } g_list_free_full(contacts, g_object_unref); done: if (data->queued_calls == 0) data->ready_cb(data->user_data); return; canceled: if (data->queued_calls == 0) free_query_context(data); }
/* This function returns a GtkEntry derived from field_id for a particular * contact. * Returns GtkWidget * on success, NULL on failure * TODO: Lots of duplicated code here, perhaps add a few bits to utils? */ static GtkWidget * contacts_edit_widget_new (EContact *contact, EVCardAttribute *attr, gboolean multi_line, gboolean *changed) { GtkWidget *type_edit; EContactChangeData *data; const gchar *attr_name = e_vcard_attribute_get_name (attr); /* Create data structure for changes */ data = g_new0 (EContactChangeData, 1); data->contact = contact; data->attr = attr; data->changed = changed; /* Create widget */ if (!e_vcard_attribute_is_single_valued (attr)) { /* Handle structured fields */ GtkWidget *adr_table; guint field; GList *values = e_vcard_attribute_get_values (attr); adr_table = gtk_table_new (1, 2, FALSE); gtk_table_set_col_spacings (GTK_TABLE (adr_table), 6); gtk_table_set_row_spacings (GTK_TABLE (adr_table), 6); gtk_container_set_border_width (GTK_CONTAINER (adr_table), 6); /* Set widget that contains attribute data */ data->widget = adr_table; /* Add type editor */ type_edit = contacts_type_edit_widget_new (attr, multi_line, changed); if (type_edit) { GtkWidget *label = gtk_label_new (NULL); gtk_label_set_use_markup (GTK_LABEL (label), TRUE); gtk_label_set_markup (GTK_LABEL (label), /* TODO: make nicer for i18n */ _("<b>Type:</b>")); gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5); gtk_table_attach (GTK_TABLE (adr_table), label, 0, 1, 0, 1, GTK_FILL, GTK_FILL, 0, 0); gtk_table_attach (GTK_TABLE (adr_table), type_edit, 1, 2, 0, 1, GTK_FILL, GTK_FILL, 0, 0); gtk_widget_show (label); gtk_widget_show (type_edit); } /* Create sub-fields */ for (field = 0; values; values = values->next, field++) { /* If no information exists, assume field is * single-lined. * TODO: It may be more intelligent in the future * to look at the value and search for new-line * characters. */ gboolean multiline = FALSE; GtkWidget *label = NULL, *entry; const ContactsStructuredField *sfield = contacts_get_structured_field (attr_name, field); const gchar *string = (const gchar *)values->data; /* If we have the information, label the field */ if (sfield) { gchar *label_markup; if (sfield->priority == 0) continue; label = gtk_label_new (NULL); multiline = sfield->multiline; gtk_label_set_use_markup (GTK_LABEL (label), TRUE); label_markup = g_strdup_printf ( /** Translators, the first * argument is the field's * name, ex. <b>Country:</b> */ _("<b>%s:</b>"), gettext(sfield->subfield_name)); gtk_label_set_markup (GTK_LABEL (label), label_markup); g_free (label_markup); gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_RIGHT); if (!multiline) gtk_misc_set_alignment ( GTK_MISC (label), 1, 0.5); else gtk_misc_set_alignment ( GTK_MISC (label), 1, 0); gtk_table_attach (GTK_TABLE (adr_table), label, 0, 1, field + 1, field + 2, GTK_FILL, GTK_FILL, 0, 0); gtk_widget_show (label); } /* This code is pretty much a verbatim copy of the * code below to handle single-valued fields */ if (multiline) { GtkTextBuffer *buffer; GtkTextView *view; view = GTK_TEXT_VIEW (gtk_text_view_new ()); gtk_widget_set_name (GTK_WIDGET (view), attr_name); buffer = gtk_text_view_get_buffer (view); gtk_text_buffer_set_text (buffer, string ? string : "", -1); gtk_text_view_set_editable (view, TRUE); gtk_text_view_set_accepts_tab (view, FALSE); entry = gtk_frame_new (NULL); gtk_frame_set_shadow_type (GTK_FRAME (entry), GTK_SHADOW_IN); gtk_container_add (GTK_CONTAINER (entry), GTK_WIDGET (view)); gtk_widget_show (GTK_WIDGET (view)); /* Connect signal for changes */ g_signal_connect (G_OBJECT (buffer), "changed", G_CALLBACK (contacts_entry_changed), data); } else { entry = gtk_entry_new (); gtk_widget_set_name (entry, attr_name); gtk_entry_set_text (GTK_ENTRY (entry), string ? string : ""); /* Connect signal for changes */ g_signal_connect (G_OBJECT (entry), "changed", G_CALLBACK (contacts_entry_changed), data); } gtk_widget_show (entry); /* Hide the label when the entry is hidden */ g_signal_connect_swapped (G_OBJECT (entry), "hide", G_CALLBACK (gtk_widget_hide), label); gtk_table_attach (GTK_TABLE (adr_table), entry, 1, 2, field + 1, field + 2, GTK_FILL | GTK_EXPAND, GTK_FILL, 0, 0); } } else if (multi_line) { /* Handle single-valued fields that span multiple lines */ gchar *string = e_vcard_attribute_get_value (attr); GtkWidget *container = NULL; GtkTextView *view = GTK_TEXT_VIEW (gtk_text_view_new ()); GtkTextBuffer *buffer = gtk_text_view_get_buffer (view); gtk_widget_set_name (GTK_WIDGET (view), attr_name); gtk_text_buffer_set_text (buffer, string ? string : "", -1); gtk_text_view_set_editable (view, TRUE); gtk_text_view_set_accepts_tab (view, FALSE); g_free (string); container = gtk_frame_new (NULL); gtk_frame_set_shadow_type ( GTK_FRAME (container), GTK_SHADOW_IN); gtk_container_add (GTK_CONTAINER (container), GTK_WIDGET (view)); gtk_widget_show (GTK_WIDGET (view)); /* if (type_edit) { gtk_widget_show (type_edit); gtk_widget_show (window); container = gtk_hbox_new (FALSE, 6); gtk_box_pack_start (GTK_BOX (container), type_edit, FALSE, TRUE, 0); gtk_box_pack_end (GTK_BOX (container), window, TRUE, TRUE, 0); }*/ /* Set widget that contains attribute data */ data->widget = container; /* Connect signal for changes */ g_signal_connect (G_OBJECT (buffer), "changed", G_CALLBACK (contacts_entry_changed), data); } else { /* Handle simple single-valued single-line fields */ gchar *string = e_vcard_attribute_get_value (attr); GtkWidget *entry, *container = NULL; entry = gtk_entry_new (); gtk_entry_set_text (GTK_ENTRY (entry), string ? string : ""); gtk_widget_set_name (entry, attr_name); g_free (string); /* if (type_edit) { gtk_widget_show (type_edit); gtk_widget_show (entry); container = gtk_hbox_new (FALSE, 6); gtk_box_pack_start (GTK_BOX (container), type_edit, FALSE, TRUE, 0); gtk_box_pack_end (GTK_BOX (container), entry, TRUE, TRUE, 0); }*/ /* Set widget that contains attribute data */ data->widget = container ? container : entry; /* Connect signal for changes */ g_signal_connect (G_OBJECT (entry), "changed", G_CALLBACK (contacts_entry_changed), data); } /* Free change data structure on destruction */ g_signal_connect_swapped (G_OBJECT (data->widget), "destroy", G_CALLBACK (g_free), data); gtk_widget_set_name (data->widget, attr_name); return data->widget; }
static gboolean check_if_same (EContact *contact, EContact *match) { EContactField field; gchar *string = NULL, *string1 = NULL; gboolean res = TRUE; for (field = E_CONTACT_FULL_NAME; res && field != (E_CONTACT_LAST_SIMPLE_STRING -1); field++) { if (field == E_CONTACT_EMAIL_1) { GList *email_attr_list1, *email_attr_list2, *iter1, *iter2; gint num_of_email1, num_of_email2; email_attr_list1 = e_contact_get_attributes (contact, E_CONTACT_EMAIL); num_of_email1 = g_list_length (email_attr_list1); email_attr_list2 = e_contact_get_attributes (match, E_CONTACT_EMAIL); num_of_email2 = g_list_length (email_attr_list2); if (num_of_email1 != num_of_email2) { res = FALSE; break; } else { /* Do pairwise-comparisons on all of the e-mail addresses. */ iter1 = email_attr_list1; while (iter1) { gboolean match = FALSE; EVCardAttribute *attr; gchar *email_address1; attr = iter1->data; email_address1 = e_vcard_attribute_get_value (attr); iter2 = email_attr_list2; while ( iter2 && match == FALSE) { gchar *email_address2; attr = iter2->data; email_address2 = e_vcard_attribute_get_value (attr); if (g_ascii_strcasecmp (email_address1, email_address2) == 0) { match = TRUE; } g_free (email_address2); iter2 = g_list_next (iter2); } g_free (email_address1); iter1 = g_list_next (iter1); if (match == FALSE) { res = FALSE; break; } } } g_list_free_full (email_attr_list1, (GDestroyNotify) e_vcard_attribute_free); g_list_free_full (email_attr_list2, (GDestroyNotify) e_vcard_attribute_free); } else if (field > E_CONTACT_FIRST_EMAIL_ID && field <= E_CONTACT_LAST_EMAIL_ID) { /* nothing to do, all emails are checked above */ } else { string = (gchar *) e_contact_get_const (contact, field); string1 = (gchar *) e_contact_get_const (match, field); if ((string && *string) && (string1 && *string1) && (g_ascii_strcasecmp (string1, string))) { res = FALSE; break; /*if the field entry exist in either of the contacts,we'll have to give the choice and thus merge button should be sensitive*/ } else if ((string && *string) && !(string1 && *string1)) { res = FALSE; break; } } } return res; }
static void create_dropdowns_for_multival_attr(GList *match_attr_list, GList *contact_attr_list, GList **use_attr_list, gint *row, GtkTable *table, gchar *label_str) { GtkWidget *label, *hbox, *dropdown; GList *miter, *citer; GHashTable *match_attrs; /* attr in the 'match' contact from address book */ match_attrs = g_hash_table_new_full (camel_strcase_hash, camel_strcase_equal, g_free, NULL); for (miter = match_attr_list; miter; miter = g_list_next (miter)) { EVCardAttribute *attr = miter->data; gchar *value; value = e_vcard_attribute_get_value (attr); if (value && *value) { g_hash_table_insert (match_attrs, value, attr); *use_attr_list = g_list_prepend (*use_attr_list, attr); } else { g_free (value); } } *use_attr_list = g_list_reverse (*use_attr_list); for (citer = contact_attr_list; citer; citer = g_list_next (citer)) { EVCardAttribute *attr = citer->data; gchar *value; value = e_vcard_attribute_get_value (attr); if (value && *value) { if (!g_hash_table_lookup (match_attrs, value)) { dropdown_data *data; /* the attr is not set in both contacts */ *use_attr_list = g_list_append (*use_attr_list, attr); /* remove to avoid collisions with match UI_SLOTs */ e_vcard_attribute_remove_param (attr, EVOLUTION_UI_SLOT_PARAM); (*row)++; label = gtk_label_new (label_str); hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); gtk_box_pack_start (GTK_BOX (hbox), (GtkWidget *) label, FALSE, FALSE, 0); gtk_table_attach_defaults (table, (GtkWidget *) hbox, 0, 1, *row, *row + 1); dropdown = gtk_combo_box_text_new (); gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (dropdown), value); data = g_new0 (dropdown_data, 1); gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (dropdown), ""); gtk_combo_box_set_active (GTK_COMBO_BOX (dropdown), 0); data->email_attr_list_item = g_list_last (*use_attr_list); data->email_attr = attr; g_signal_connect ( dropdown, "changed", G_CALLBACK (attr_dropdown_changed), data); g_object_set_data_full (G_OBJECT (dropdown), "eab-contact-merging::dropdown-data", data, g_free); hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); gtk_box_pack_start (GTK_BOX (hbox), (GtkWidget *) dropdown, FALSE, FALSE, 0); gtk_table_attach_defaults (table, (GtkWidget *) hbox, 1, 2, *row, *row + 1); gtk_widget_show ((GtkWidget *) dropdown); } } g_free (value); } g_hash_table_destroy (match_attrs); }
static void render_contact_column (EABContactFormatter *formatter, EContact *contact, GString *buffer) { GString *accum, *email; GList *email_list, *l, *email_attr_list, *al, *phone_attr_list; gint email_num = 0; const gchar *nl; guint32 phone_flags = 0, sip_flags = 0; if (formatter->priv->supports_tel) phone_flags = E_TEXT_TO_HTML_CONVERT_URLS | E_TEXT_TO_HTML_HIDE_URL_SCHEME | E_TEXT_TO_HTML_URL_IS_WHOLE_TEXT | E_CREATE_TEL_URL; if (formatter->priv->supports_sip) sip_flags = E_TEXT_TO_HTML_CONVERT_URLS | E_TEXT_TO_HTML_HIDE_URL_SCHEME | E_TEXT_TO_HTML_URL_IS_WHOLE_TEXT | E_CREATE_SIP_URL; email = g_string_new (""); nl = ""; email_list = e_contact_get (contact, E_CONTACT_EMAIL); email_attr_list = e_contact_get_attributes (contact, E_CONTACT_EMAIL); for (l = email_list, al = email_attr_list; l && al; l = l->next, al = al->next) { gchar *name = NULL, *mail = NULL; gchar *attr_str = (gchar *) get_email_location ((EVCardAttribute *) al->data); if (!eab_parse_qp_email (l->data, &name, &mail)) mail = e_text_to_html (l->data, 0); g_string_append_printf ( email, "%s%s%s<a href=\"internal-mailto:%d\">%s</a>%s " "<span class=\"header\">(%s)</span>", nl, name ? name : "", name ? " <" : "", email_num, mail, name ? ">" : "", attr_str ? attr_str : ""); email_num++; nl = "<br>"; g_free (name); g_free (mail); } g_list_foreach (email_list, (GFunc) g_free, NULL); g_list_foreach (email_attr_list, (GFunc) e_vcard_attribute_free, NULL); g_list_free (email_list); g_list_free (email_attr_list); accum = g_string_new (""); if (email->len) render_table_row (accum, _("Email"), email->str, NULL, 0); phone_attr_list = e_contact_get_attributes (contact, E_CONTACT_TEL); for (l = phone_attr_list; l; l = g_list_next (l)) { EVCardAttribute *attr = l->data; if (!e_vcard_attribute_has_type (attr, "WORK") && !e_vcard_attribute_has_type (attr, "HOME")) { guint32 html_flags = phone_flags; const gchar *attr_str, *str; gchar *phone, *tmp_value, *label; phone = e_vcard_attribute_get_value (attr); if (!phone || !*phone) { g_free (phone); continue; } attr_str = get_phone_location (attr); label = e_text_to_html (attr_str, E_TEXT_TO_HTML_CONVERT_ALL_SPACES); tmp_value = maybe_create_url (phone, html_flags); if (tmp_value) str = tmp_value; else str = phone; render_table_row (accum, label, str, NULL, html_flags); g_free (tmp_value); g_free (phone); g_free (label); } } g_list_free_full (phone_attr_list, (GDestroyNotify) e_vcard_attribute_free); accum_sip (accum, contact, EAB_CONTACT_FORMATTER_SIP_TYPE_OTHER, NULL, sip_flags); accum_attribute (accum, contact, _("Nickname"), E_CONTACT_NICKNAME, NULL, 0); accum_attribute_multival (accum, contact, _("AIM"), E_CONTACT_IM_AIM, AIM_ICON, 0); accum_attribute_multival (accum, contact, _("GroupWise"), E_CONTACT_IM_GROUPWISE, GROUPWISE_ICON, 0); accum_attribute_multival (accum, contact, _("ICQ"), E_CONTACT_IM_ICQ, ICQ_ICON, 0); accum_attribute_multival (accum, contact, _("Jabber"), E_CONTACT_IM_JABBER, JABBER_ICON, 0); accum_attribute_multival (accum, contact, _("MSN"), E_CONTACT_IM_MSN, MSN_ICON, 0); accum_attribute_multival (accum, contact, _("Yahoo"), E_CONTACT_IM_YAHOO, YAHOO_ICON, 0); accum_attribute_multival (accum, contact, _("Gadu-Gadu"), E_CONTACT_IM_GADUGADU, GADUGADU_ICON, 0); accum_attribute_multival (accum, contact, _("Skype"), E_CONTACT_IM_SKYPE, SKYPE_ICON, 0); accum_attribute_multival (accum, contact, _("Twitter"), E_CONTACT_IM_TWITTER, TWITTER_ICON, 0); if (accum->len) g_string_append_printf ( buffer, "<div class=\"column\" id=\"contact-internet\">" "<table border=\"0\" cellspacing=\"5\">%s</table>" "</div>", accum->str); g_string_free (accum, TRUE); g_string_free (email, TRUE); }