コード例 #1
0
EABContactMatchType
eab_contact_compare_file_as (EContact *contact1,
                             EContact *contact2)
{
	EABContactMatchType match_type;
	gchar *a, *b;

	g_return_val_if_fail (E_IS_CONTACT (contact1), EAB_CONTACT_MATCH_NOT_APPLICABLE);
	g_return_val_if_fail (E_IS_CONTACT (contact2), EAB_CONTACT_MATCH_NOT_APPLICABLE);

	a = e_contact_get (contact1, E_CONTACT_FILE_AS);
	b = e_contact_get (contact2, E_CONTACT_FILE_AS);

	if (a == NULL || b == NULL) {
		g_free (a);
		g_free (b);
		return EAB_CONTACT_MATCH_NOT_APPLICABLE;
	}

	if (!strcmp (a, b))
		match_type = EAB_CONTACT_MATCH_EXACT;
	else if (g_utf8_validate (a, -1, NULL) && g_utf8_validate (b, -1, NULL) &&
		 !g_utf8_collate (a, b))
		match_type = EAB_CONTACT_MATCH_PARTIAL;
	else
		match_type = EAB_CONTACT_MATCH_NONE;

	g_free (a);
	g_free (b);
	return match_type;
}
コード例 #2
0
EABContactMatchType
eab_contact_compare_nickname (EContact *contact1,
                              EContact *contact2)
{
	g_return_val_if_fail (contact1 && E_IS_CONTACT (contact1), EAB_CONTACT_MATCH_NOT_APPLICABLE);
	g_return_val_if_fail (contact2 && E_IS_CONTACT (contact2), EAB_CONTACT_MATCH_NOT_APPLICABLE);

	return EAB_CONTACT_MATCH_NOT_APPLICABLE;
}
コード例 #3
0
EABContactMatchType
eab_contact_compare_telephone (EContact *contact1,
                               EContact *contact2)
{
	g_return_val_if_fail (contact1 && E_IS_CONTACT (contact1), EAB_CONTACT_MATCH_NOT_APPLICABLE);
	g_return_val_if_fail (contact2 && E_IS_CONTACT (contact2), EAB_CONTACT_MATCH_NOT_APPLICABLE);

	/* Unimplemented */

	return EAB_CONTACT_MATCH_NOT_APPLICABLE;
}
コード例 #4
0
EABContactMatchType
eab_contact_compare_email (EContact *contact1,
                           EContact *contact2)
{
	EABContactMatchType match = EAB_CONTACT_MATCH_NOT_APPLICABLE;
	GList *contact1_email, *contact2_email;
	GList *i1, *i2;

	g_return_val_if_fail (contact1 && E_IS_CONTACT (contact1), EAB_CONTACT_MATCH_NOT_APPLICABLE);
	g_return_val_if_fail (contact2 && E_IS_CONTACT (contact2), EAB_CONTACT_MATCH_NOT_APPLICABLE);

	contact1_email = e_contact_get (contact1, E_CONTACT_EMAIL);
	contact2_email = e_contact_get (contact2, E_CONTACT_EMAIL);

	if (contact1_email == NULL || contact2_email == NULL) {
		g_list_foreach (contact1_email, (GFunc) g_free, NULL);
		g_list_free (contact1_email);

		g_list_foreach (contact2_email, (GFunc) g_free, NULL);
		g_list_free (contact2_email);
		return EAB_CONTACT_MATCH_NOT_APPLICABLE;
	}

	i1 = contact1_email;

	/* Do pairwise-comparisons on all of the e-mail addresses.  If
	 * we find an exact match, there is no reason to keep
	 * checking. */
	while (i1 && match != EAB_CONTACT_MATCH_EXACT) {
		gchar *addr1 = (gchar *) i1->data;

		i2 = contact2_email;
		while (i2 && match != EAB_CONTACT_MATCH_EXACT) {
			gchar *addr2 = (gchar *) i2->data;

			match = combine_comparisons (match, compare_email_addresses (addr1, addr2));

			i2 = i2->next;
		}

		i1 = i1->next;
	}

	g_list_foreach (contact1_email, (GFunc) g_free, NULL);
	g_list_free (contact1_email);

	g_list_foreach (contact2_email, (GFunc) g_free, NULL);
	g_list_free (contact2_email);

	return match;
}
コード例 #5
0
static void eds_contacts_added_cb(EBookView *view, const GList *contacts, gpointer data)
{
  const GList *walk;
  GList **address_list = (GList**) data;

  for(walk = contacts; walk; walk = walk->next) {
    const char *name;
    GList *email_list, *email_entry;
    EContact *contact = walk->data;

    if(!E_IS_CONTACT(contact))
      continue;

    name = e_contact_get_const(contact, E_CONTACT_FULL_NAME);
    email_list = e_contact_get(contact, E_CONTACT_EMAIL);
    for(email_entry = email_list; email_entry; email_entry = email_entry->next) {
      address_entry *ae;
      const char *email_address = email_entry->data;

      ae = g_new0(address_entry, 1);
      ae->name = g_strdup(name);
      ae->address = g_strdup(email_address);
      ae->grp_emails = NULL;
      *address_list = g_list_prepend(*address_list, ae);

      addr_compl_add_address1(name, ae);
      if(email_address && *email_address != '\0')
        addr_compl_add_address1(email_address, ae);
    }
  }
}
コード例 #6
0
void
cursor_slot_set_from_contact (CursorSlot *slot,
                              EContact *contact)
{
	CursorSlotPrivate *priv;
	const gchar *family_name, *given_name;
	gchar *str;

	g_return_if_fail (CURSOR_IS_SLOT (slot));
	g_return_if_fail (contact == NULL || E_IS_CONTACT (contact));

	priv = slot->priv;

	if (!contact) {
		gtk_widget_hide (priv->area);
		return;
	}

	family_name = (const gchar *) e_contact_get_const (contact, E_CONTACT_FAMILY_NAME);
	given_name = (const gchar *) e_contact_get_const (contact, E_CONTACT_GIVEN_NAME);

	str = g_strdup_printf ("%s, %s", family_name, given_name);
	gtk_label_set_text (priv->name_label, str);
	g_free (str);

	str = make_string_from_list (contact, E_CONTACT_EMAIL);
	gtk_label_set_markup (priv->emails_label, str);
	g_free (str);

	str = make_string_from_list (contact, E_CONTACT_TEL);
	gtk_label_set_markup (priv->telephones_label, str);
	g_free (str);

	gtk_widget_show (priv->area);
}
コード例 #7
0
ファイル: hito-category-group.c プロジェクト: shr-project/shr
static gboolean
includes_contact (HitoGroup *group, EContact *contact)
{
  HitoCategoryGroupPrivate *priv;
  GList *categories, *l;
  gboolean visible = FALSE;

  g_return_val_if_fail (HITO_IS_CATEGORY_GROUP (group), FALSE);
  g_return_val_if_fail (E_IS_CONTACT (contact), FALSE);

  priv = GET_PRIVATE (group);

  categories = e_contact_get (contact, E_CONTACT_CATEGORY_LIST);
  for (l = categories; l ; l = l->next) {
    /* TODO: strmp? or funky decomposition compare? */
    if (strcmp (priv->name, l->data) == 0) {
      visible = TRUE;
      break;
    }
  }
  g_list_foreach (categories, (GFunc)g_free, NULL);
  g_list_free (categories);

  return visible;
}
コード例 #8
0
/**
 * e_contact_locate_match_full:
 * @registry: an #ESourceRegistry
 * @book: The book to look in.  If this is NULL, use the default
 * addressbook.
 * @contact: The contact to compare to.
 * @avoid: A list of contacts to not match.  These will not show up in the search.
 * @cb: The function to call.
 * @closure: The closure to add to the call.
 *
 * Look for the best match and return it using the EABContactMatchQueryCallback.
 **/
void
eab_contact_locate_match_full (ESourceRegistry *registry,
                               EBookClient *book_client,
                               EContact *contact,
                               GList *avoid,
                               EABContactMatchQueryCallback cb,
                               gpointer closure)
{
	MatchSearchInfo *info;
	ESource *source;

	g_return_if_fail (E_IS_SOURCE_REGISTRY (registry));
	g_return_if_fail (E_IS_CONTACT (contact));
	g_return_if_fail (cb != NULL);

	info = g_new0 (MatchSearchInfo, 1);
	info->contact = g_object_ref (contact);
	info->cb = cb;
	info->closure = closure;
	info->avoid = g_list_copy (avoid);
	g_list_foreach (info->avoid, (GFunc) g_object_ref, NULL);

	if (book_client) {
		use_common_book_client (g_object_ref (book_client), info);
		return;
	}

	source = e_source_registry_ref_default_address_book (registry);

	e_book_client_connect (source, 30, NULL, book_client_connect_cb, info);

	g_object_unref (source);
}
コード例 #9
0
ファイル: client-test-utils.c プロジェクト: Pecisk/eds-gtasks
static gboolean
contacts_are_equal_shallow (EContact *a,
                            EContact *b)
{
	const gchar *uid_a, *uid_b;

        /* Avoid warnings if one or more are NULL, to make this function
         * "NULL-friendly" */
	if (!a && !b)
		return TRUE;

	if (!E_IS_CONTACT (a) || !E_IS_CONTACT (b))
		return FALSE;

	uid_a = e_contact_get_const (a, E_CONTACT_UID);
	uid_b = e_contact_get_const (b, E_CONTACT_UID);

	return g_strcmp0 (uid_a, uid_b) == 0;
}
コード例 #10
0
EABContactMatchType
eab_contact_compare (EContact *contact1,
                     EContact *contact2)
{
	EABContactMatchType result;

	g_return_val_if_fail (contact1 && E_IS_CONTACT (contact1), EAB_CONTACT_MATCH_NOT_APPLICABLE);
	g_return_val_if_fail (contact2 && E_IS_CONTACT (contact2), EAB_CONTACT_MATCH_NOT_APPLICABLE);

	result = EAB_CONTACT_MATCH_NONE;
	if (!e_contact_get (contact1, E_CONTACT_IS_LIST)) {
		result = combine_comparisons (result, eab_contact_compare_name      (contact1, contact2));
		result = combine_comparisons (result, eab_contact_compare_nickname  (contact1, contact2));
		if (!e_contact_get (contact2, E_CONTACT_IS_LIST))
			result = combine_comparisons (result, eab_contact_compare_email (contact1, contact2));
		result = combine_comparisons (result, eab_contact_compare_address   (contact1, contact2));
		result = combine_comparisons (result, eab_contact_compare_telephone (contact1, contact2));
	}
	result = combine_comparisons (result, eab_contact_compare_file_as   (contact1, contact2));

	return result;
}
コード例 #11
0
void
kolab_util_backend_modtime_set_on_econtact (EContact *econtact)
{
	time_t rawtime;
	struct tm *ts = NULL;
	gchar *buf = NULL;

	g_assert (E_IS_CONTACT (econtact));

	time (&rawtime);
	ts = gmtime (&rawtime);
	buf = g_new0 (gchar, 21);
	strftime (buf, 21, "%Y-%m-%dT%H:%M:%SZ", ts); /* same as in contact-i-to-e.c */
	e_contact_set (econtact, E_CONTACT_REV, buf);
	g_free (buf);
} /* kolab_util_backend_modtime_set_on_econtact () */
コード例 #12
0
static void
book_shell_content_check_state_foreach (gint row,
                                        gpointer user_data)
{
    EContact *contact;

    struct {
        EAddressbookModel *model;
        GList *list;
    } *foreach_data = user_data;

    contact = e_addressbook_model_get_contact (foreach_data->model, row);
    g_return_if_fail (E_IS_CONTACT (contact));

    foreach_data->list = g_list_prepend (foreach_data->list, contact);
}
コード例 #13
0
static void
container_object_added_cb (ScalixContainer * container,
                           ScalixObject * object, gpointer data)
{
    EBookBackend *backend;

    backend = E_BOOK_BACKEND (data);

    if (!E_IS_CONTACT (object)) {
        g_warning ("Invalid object\n");
        return;
    }

    e_book_backend_notify_update (backend, E_CONTACT (object));
    e_book_backend_notify_complete (backend);
}
コード例 #14
0
static void
container_object_removed_cb (ScalixContainer * container,
                             ScalixObject * object, gpointer data)
{
    EBookBackend *backend;
    EContact *contact;
    const char *uid;

    backend = E_BOOK_BACKEND (data);

    if (!E_IS_CONTACT (object)) {
        g_warning ("Invalid object");
        return;
    }

    contact = E_CONTACT (object);
    uid = e_contact_get_const (contact, E_CONTACT_UID);

    g_assert (uid != NULL);

    e_book_backend_notify_remove (backend, uid);
    e_book_backend_notify_complete (backend);
}
コード例 #15
0
ファイル: contacts.c プロジェクト: shr-project/shr
/* Calbacks */
static void
moko_contacts_add_contact (MokoContacts *contacts, EContact *e_contact)
{
  MokoContactsPrivate *priv;
  MokoContact *m_contact = NULL;
  const gchar *name, *uid;
  GList *attributes, *params, *numbers;

  g_return_if_fail (MOKO_IS_CONTACTS (contacts));
  g_return_if_fail (E_IS_CONTACT (e_contact));
  priv = contacts->priv;

  uid = e_contact_get_const (e_contact, E_CONTACT_UID);
  if (g_hash_table_lookup (priv->uids, uid))
	  return;
  
  name = e_contact_get_const (e_contact, E_CONTACT_FULL_NAME);
  if (!name || (g_utf8_strlen (name, -1) <= 0))
    name = "Unknown";
  
  /* Create the contact & append to the list */
  m_contact = g_new0 (MokoContact, 1);
  m_contact->name = g_strdup (name);
  m_contact->uid = g_strdup (uid);
  m_contact->photo = NULL;

  priv->contacts = g_list_append (priv->contacts, m_contact);
  g_hash_table_insert (priv->uids,
                       g_strdup (uid), 
                       m_contact);

  /* Now go through the numbers,creating MokoNumber for them */
  for (attributes = e_vcard_get_attributes (E_VCARD(e_contact)); attributes; attributes = attributes->next)
  {
    MokoContactEntry  *entry;
    const gchar *phone;
    const char *attr;

    attr = e_vcard_attribute_get_name (attributes->data);
    if (!strcmp (attr, EVC_TEL))
    {
      for (numbers = e_vcard_attribute_get_values (attributes->data); numbers; numbers = numbers->next)
      {
        phone = numbers->data;
        if (phone)
        {
          entry = g_new0 (MokoContactEntry, 1);

          params = e_vcard_attribute_get_param (attributes->data, "TYPE");
          if (params)
            entry->desc = g_strdup (params->data);

          entry->number = normalize (phone);
          entry->contact = m_contact;

          priv->entries = g_list_append (priv->entries, (gpointer)entry);
          g_hash_table_insert (priv->prefixes, 
                               g_strdup (entry->number), 
                               (gpointer)entry);
          add_number (&priv->start, entry);
        }
      }
    }
  }
}
コード例 #16
0
GtkWidget *
evolution_contact_importer_get_preview_widget (const GSList *contacts)
{
	GtkWidget *preview;
	GtkTreeView *tree_view;
	GtkTreeSelection *selection;
	GtkListStore *store;
	GtkTreeIter iter;
	const GSList *c;

	if (!contacts)
		return NULL;

	store = gtk_list_store_new (2, G_TYPE_STRING, E_TYPE_CONTACT);

	for (c = contacts; c; c = c->next) {
		const gchar *description;
		gchar *free_description = NULL;
		EContact *contact = (EContact *) c->data;

		if (!contact || !E_IS_CONTACT (contact))
			continue;

		description = e_contact_get_const (contact, E_CONTACT_FILE_AS);
		if (!description)
			description = e_contact_get_const (contact, E_CONTACT_UID);
		if (!description)
			description = e_contact_get_const (contact, E_CONTACT_FULL_NAME);
		if (!description) {
			description = e_contact_get_const (contact, E_CONTACT_EMAIL_1);
			if (description) {
				const gchar *at = strchr (description, '@');
				if (at) {
					free_description = g_strndup (
						description,
						(gsize) (at - description));
					description = free_description;
				}
			}
		}

		gtk_list_store_append (store, &iter);
		gtk_list_store_set (store, &iter,
			0, description ? description : "",
			1, contact,
			-1 );

		g_free (free_description);
	}

	if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter)) {
		g_object_unref (store);
		return NULL;
	}

	preview = e_web_view_preview_new ();
	gtk_widget_show (preview);

	tree_view = e_web_view_preview_get_tree_view (E_WEB_VIEW_PREVIEW (preview));
	g_return_val_if_fail (tree_view != NULL, NULL);

	gtk_tree_view_set_model (tree_view, GTK_TREE_MODEL (store));
	g_object_unref (store);

	gtk_tree_view_insert_column_with_attributes (tree_view, -1, _("Contact"),
		gtk_cell_renderer_text_new (), "text", 0, NULL);

	if (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL) > 1)
		e_web_view_preview_show_tree_view (E_WEB_VIEW_PREVIEW (preview));

	selection = gtk_tree_view_get_selection (tree_view);
	gtk_tree_selection_select_iter (selection, &iter);
	g_signal_connect (
		selection, "changed",
		G_CALLBACK (preview_selection_changed_cb), preview);

	preview_selection_changed_cb (selection, E_WEB_VIEW_PREVIEW (preview));

	return preview;
}
コード例 #17
0
EABContactMatchType
eab_contact_compare_name (EContact *contact1,
                          EContact *contact2)
{
	EContactName *a, *b;
	gint matches = 0, possible = 0;
	gboolean family_match = FALSE;

	g_return_val_if_fail (E_IS_CONTACT (contact1), EAB_CONTACT_MATCH_NOT_APPLICABLE);
	g_return_val_if_fail (E_IS_CONTACT (contact2), EAB_CONTACT_MATCH_NOT_APPLICABLE);

	a = e_contact_get (contact1, E_CONTACT_NAME);
	b = e_contact_get (contact2, E_CONTACT_NAME);

	if (a == NULL || b == NULL) {
		g_free (a);
		g_free (b);
		return EAB_CONTACT_MATCH_NOT_APPLICABLE;
	}

	if (a->given && b->given && *a->given && *b->given) {
		++possible;
		if (name_fragment_match_with_synonyms (a->given, b->given, FALSE /* both inputs are complete */)) {
			++matches;
		}
	}

	if (a->additional && b->additional && *a->additional && *b->additional) {
		++possible;
		if (name_fragment_match_with_synonyms (a->additional, b->additional, FALSE /* both inputs are complete */)) {
			++matches;
		}
	}

	if (a->family && b->family && *a->family && *b->family) {
		++possible;
		/* We don't allow "loose matching" (i.e. John vs. Jon) on family names */
		if (!e_utf8_casefold_collate (a->family, b->family)) {
			++matches;
			family_match = TRUE;
		}
	}

	e_contact_name_free (a);
	e_contact_name_free (b);

	/* Now look at the # of matches and try to intelligently map
	 * an EAB_CONTACT_MATCH_* type to it.  Special consideration is given
	 * to family-name matches. */

	if (possible == 0)
		return EAB_CONTACT_MATCH_NOT_APPLICABLE;

	if (possible == 1)
		return family_match ? EAB_CONTACT_MATCH_VAGUE : EAB_CONTACT_MATCH_NONE;

	if (possible == matches)
		return family_match ? EAB_CONTACT_MATCH_EXACT : EAB_CONTACT_MATCH_PARTIAL;

	if (possible == matches + 1)
		return family_match ? EAB_CONTACT_MATCH_VAGUE : EAB_CONTACT_MATCH_NONE;

	return EAB_CONTACT_MATCH_NONE;
}
コード例 #18
0
EABContactMatchType
eab_contact_compare_name_to_string_full (EContact *contact,
                                         const gchar *str,
                                         gboolean allow_partial_matches,
                                         gint *matched_parts_out,
                                         EABContactMatchPart *first_matched_part_out,
                                         gint *matched_character_count_out)
{
	gchar **namev, **givenv = NULL, **addv = NULL, **familyv = NULL;

	gint matched_parts = EAB_CONTACT_MATCH_PART_NONE;
	EABContactMatchPart first_matched_part = EAB_CONTACT_MATCH_PART_NONE;
	EABContactMatchPart this_part_match = EAB_CONTACT_MATCH_PART_NOT_APPLICABLE;
	EABContactMatchType match_type;
	EContactName *contact_name;

	gint match_count = 0, matched_character_count = 0, fragment_count;
	gint i, j;
	gchar *str_cpy, *s;

	g_return_val_if_fail (E_IS_CONTACT (contact), EAB_CONTACT_MATCH_NOT_APPLICABLE);

	if (!e_contact_get_const (contact, E_CONTACT_FULL_NAME))
		return EAB_CONTACT_MATCH_NOT_APPLICABLE;
	if (str == NULL)
		return EAB_CONTACT_MATCH_NOT_APPLICABLE;

	str_cpy = s = g_strdup (str);
	while (*s) {
		if (*s == ',' || *s == '"')
			*s = ' ';
		++s;
	}
	namev = g_strsplit (str_cpy, " ", 0);
	g_free (str_cpy);

	contact_name = e_contact_get (contact, E_CONTACT_NAME);

	if (contact_name->given)
		givenv = g_strsplit (contact_name->given, " ", 0);
	if (contact_name->additional)
		addv = g_strsplit (contact_name->additional, " ", 0);
	if (contact_name->family)
		familyv = g_strsplit (contact_name->family, " ", 0);

	e_contact_name_free (contact_name);

	fragment_count = 0;
	for (i = 0; givenv && givenv[i]; ++i)
		++fragment_count;
	for (i = 0; addv && addv[i]; ++i)
		++fragment_count;
	for (i = 0; familyv && familyv[i]; ++i)
		++fragment_count;

	for (i = 0; namev[i] && this_part_match != EAB_CONTACT_MATCH_PART_NONE; ++i) {

		if (*namev[i]) {

			this_part_match = EAB_CONTACT_MATCH_PART_NONE;

			/* When we are allowing partials, we are strict about the matches we allow.
			 * Does this make sense?  Not really, but it does the right thing for the purposes
			 * of completion. */

			if (givenv && this_part_match == EAB_CONTACT_MATCH_PART_NONE) {
				for (j = 0; givenv[j]; ++j) {
					if (name_fragment_match_with_synonyms (givenv[j], namev[i], allow_partial_matches)) {

						this_part_match = EAB_CONTACT_MATCH_PART_GIVEN_NAME;

						/* We remove a piece of a name once it has been matched against, so
						 * that "john john" won't match "john doe". */
						g_free (givenv[j]);
						givenv[j] = g_strdup ("");
						break;
					}
				}
			}

			if (addv && this_part_match == EAB_CONTACT_MATCH_PART_NONE) {
				for (j = 0; addv[j]; ++j) {
					if (name_fragment_match_with_synonyms (addv[j], namev[i], allow_partial_matches)) {

						this_part_match = EAB_CONTACT_MATCH_PART_ADDITIONAL_NAME;

						g_free (addv[j]);
						addv[j] = g_strdup ("");
						break;
					}
				}
			}

			if (familyv && this_part_match == EAB_CONTACT_MATCH_PART_NONE) {
				for (j = 0; familyv[j]; ++j) {
					if (allow_partial_matches ? name_fragment_match_with_synonyms (familyv[j], namev[i], allow_partial_matches)
					    : !e_utf8_casefold_collate (familyv[j], namev[i])) {

						this_part_match = EAB_CONTACT_MATCH_PART_FAMILY_NAME;

						g_free (familyv[j]);
						familyv[j] = g_strdup ("");
						break;
					}
				}
			}

			if (this_part_match != EAB_CONTACT_MATCH_PART_NONE) {
				++match_count;
				matched_character_count += g_utf8_strlen (namev[i], -1);
				matched_parts |= this_part_match;
				if (first_matched_part == EAB_CONTACT_MATCH_PART_NONE)
					first_matched_part = this_part_match;
			}
		}
	}

	match_type = EAB_CONTACT_MATCH_NONE;

	if (this_part_match != EAB_CONTACT_MATCH_PART_NONE) {

		if (match_count > 0)
			match_type = EAB_CONTACT_MATCH_VAGUE;

		if (fragment_count == match_count) {

			match_type = EAB_CONTACT_MATCH_EXACT;

		} else if (fragment_count == match_count + 1) {

			match_type = EAB_CONTACT_MATCH_PARTIAL;

		}
	}

	if (matched_parts_out)
		*matched_parts_out = matched_parts;
	if (first_matched_part_out)
		*first_matched_part_out = first_matched_part;
	if (matched_character_count_out)
		*matched_character_count_out = matched_character_count;

	g_strfreev (namev);
	g_strfreev (givenv);
	g_strfreev (addv);
	g_strfreev (familyv);

	return match_type;
}