/**
 * e_vcard_attribute_has_type:
 * @attr: an #EVCardAttribute
 * @typestr: a string representing the type
 *
 * Checks if @attr has an #EVCardAttributeParam of the specified type.
 *
 * Return value: %TRUE if such a parameter exists, %FALSE otherwise.
 **/
gboolean
e_vcard_attribute_has_type (EVCardAttribute *attr, const char *typestr)
{
	GList *params;
	GList *p;

	g_return_val_if_fail (attr != NULL, FALSE);
	g_return_val_if_fail (typestr != NULL, FALSE);

	params = e_vcard_attribute_get_params (attr);

	for (p = params; p; p = p->next) {
		EVCardAttributeParam *param = p->data;

		if (!g_ascii_strcasecmp (e_vcard_attribute_param_get_name (param), EVC_TYPE)) {
			GList *values = e_vcard_attribute_param_get_values (param);
			GList *v;

			for (v = values; v; v = v->next) {
				if (!g_ascii_strcasecmp ((char*)v->data, typestr))
					return TRUE;
			}
		}
	}

	return FALSE;
}
/**
 * e_vcard_attribute_remove_param_value:
 * @attr: an #EVCardAttribute
 * @param_name: a parameter name
 * @s: a value
 *
 * Removes the value @s from the parameter @param_name on the attribute @attr.
 **/
void
e_vcard_attribute_remove_param_value (EVCardAttribute *attr, const char *param_name, const char *s)
{
	GList *l, *params;
	EVCardAttributeParam *param;

	g_return_if_fail (attr != NULL);
	g_return_if_fail (param_name != NULL);
	g_return_if_fail (s != NULL);

	params = e_vcard_attribute_get_params (attr);

	for (l = params; l; l = l->next) {
		param = l->data;
		if (g_ascii_strcasecmp (e_vcard_attribute_param_get_name (param), param_name) == 0) {
			l = g_list_find_custom (param->values, s, (GCompareFunc)strcmp);
			if (l == NULL) {
				return;
			}

			param->values = g_list_delete_link (param->values, l);
			if (param->values == NULL) {
				e_vcard_attribute_param_free (param);
				attr->params = g_list_remove (attr->params, param);
			}
			break;
		}
	}
	return;
}
Esempio n. 3
0
/*
 * Convenience function to set the type parmeter of a vcard attribute
 *
 * attr: the attribute to modify
 * type: semicolan seperated list of values
 *
 */
void
hito_vcard_attribute_set_type (EVCardAttribute *attr, const gchar *type)
{
  GList *params;
  EVCardAttributeParam *p = NULL;
  gchar **values;
  gint i;

  /* look for the TYPE parameter */
  for (params = e_vcard_attribute_get_params (attr); params;
      params = g_list_next (params))
  {
    if (!strcmp (e_vcard_attribute_param_get_name (params->data), "TYPE"))
    {
      p = params->data;
      break;
    }
  }

  /* we didn't find the TYPE parameter, so create it now */
  if (!p)
  {
    /* if there isn't an existing TYPE and we are not setting a value, we can
     * return straight away */
    if (!type)
      return;

    p = e_vcard_attribute_param_new ("TYPE");
    e_vcard_attribute_add_param (attr, p);
  }

  /* remove the current values */
  e_vcard_attribute_param_remove_values (p);

  /* if type is null, we don't want to add any type parameters */
  if (!type)
    return;

  values = g_strsplit (type, ";", -1);

  for (i = 0; (values[i]); i++)
  {
    e_vcard_attribute_param_add_value (p, values[i]);
  }

  g_strfreev (values);
}
/**
 * e_vcard_attribute_get_param:
 * @attr: an #EVCardAttribute
 * @name: a parameter name
 *
 * Gets the list of values for the paramater @name from @attr. The list and its
 * contents are owned by @attr, and must not be freed.
 *
 * Return value: A list of string elements representing the parameter's values.
 **/
GList *
e_vcard_attribute_get_param (EVCardAttribute *attr, const char *name)
{
	GList *params, *p;

	g_return_val_if_fail (attr != NULL, NULL);
	g_return_val_if_fail (name != NULL, NULL);

	params = e_vcard_attribute_get_params (attr);

	for (p = params; p; p = p->next) {
		EVCardAttributeParam *param = p->data;
		if (g_ascii_strcasecmp (e_vcard_attribute_param_get_name (param), name) == 0) {
			return e_vcard_attribute_param_get_values (param);
		}
	}

	return NULL;
}
Esempio n. 5
0
static GtkWidget *
contacts_type_edit_widget_new (EVCardAttribute *attr, gboolean multi_line,
	gboolean *changed)
{
	const TypeTuple *types;

	types = contacts_get_field_types (e_vcard_attribute_get_name (attr));
	if (types) {
		guint i;
		GtkWidget *combo = gtk_combo_box_entry_new_text ();
		GtkWidget *align;
		gchar *first_type = "";
		EVCardAttributeParam *param;
		EContactTypeChangeData *data;
		/* Retrieve all types, but we only look at the first one
		 * TODO: A sane way of selecting multiple types, to conform
		 * with spec? (Almost no other vCard-using apps do this,
		 * so not high priority)
		 */
		GList *contact_types = contacts_get_types (
			e_vcard_attribute_get_params (attr));
			
		if (contact_types) {
			param = (EVCardAttributeParam *)contact_types->data;
			GList *values =
				e_vcard_attribute_param_get_values (param);
			first_type = values ? (gchar *)values->data : "";
			g_list_free (contact_types);
		} else {
			param = e_vcard_attribute_param_new ("TYPE");
			e_vcard_attribute_add_param_with_value (
				attr, param, "");
		}
		data = g_new (EContactTypeChangeData, 1);
		data->param = param;
		data->attr_name = e_vcard_attribute_get_name (attr);
		data->changed = changed;
		
		for (i = 0; types[i].index; i++) {
			gtk_combo_box_append_text (
				GTK_COMBO_BOX (combo), _(types[i].value));
			/* Note: We use a case-insensitive search here, as
			 * specified in the spec (as the types are predefined,
			 * we can use non-locale-friendly strcasecmp)
			 */
			if (first_type) {
				if (g_ascii_strcasecmp (types[i].index, first_type) == 0) {
					first_type = NULL;
					gtk_combo_box_set_active (
						GTK_COMBO_BOX (combo), i);
				}
			}
		}
		/* Support custom types, as per spec */
		if ((first_type) && (g_ascii_strncasecmp (first_type, "X-", 2) == 0)) {
			gtk_entry_set_text (
				GTK_ENTRY (GTK_BIN (combo)->child),
				(const gchar *)(first_type+2));
			first_type = NULL;
		}
		if (first_type)
			gtk_combo_box_set_active (GTK_COMBO_BOX (combo), i-1);
		gtk_widget_show (combo);
		if (/*(e_vcard_attribute_is_single_valued (attr)) &&*/
		    (multi_line == FALSE))
			align = gtk_alignment_new (0, 0.5, 0, 0);
		else
			align = gtk_alignment_new (0, 0, 0, 0);
		/* TODO: Find something better than this? */
		gtk_widget_set_size_request (combo, 80, -1);
		gtk_container_add (GTK_CONTAINER (align), combo);

		/* Connect signal for changes */		
		g_signal_connect (G_OBJECT (combo), "changed",
				  G_CALLBACK (contacts_type_entry_changed),
				  data);
		
		/* Free change data structure on destruction */
		g_signal_connect_swapped (G_OBJECT (align), "destroy", 
					  G_CALLBACK (g_free), data);
				  
		return align;
	}
	
	return NULL;
}
static void
vcard_import_contact (VCardImporter *gci,
                      EContact *contact)
{
	EContactPhoto *photo;
	GList *attrs, *attr;
	gchar *uid = NULL;

	/* Apple's addressbook.app exports PHOTO's without a TYPE
	 * param, so let's figure out the format here if there's a
	 * PHOTO attribute missing a TYPE param.
	 *
	 * this is sort of a hack, as EContact sets the type for us if
	 * we use the setter.  so let's e_contact_get + e_contact_set
	 * on E_CONTACT_PHOTO.
	*/
	photo = e_contact_get (contact, E_CONTACT_PHOTO);
	if (photo) {
		e_contact_set (contact, E_CONTACT_PHOTO, photo);
		e_contact_photo_free (photo);
	}

	/* Deal with our XML EDestination stuff in EMAIL attributes, if there is any. */
	attrs = e_contact_get_attributes (contact, E_CONTACT_EMAIL);
	for (attr = attrs; attr; attr = attr->next) {
		EVCardAttribute *a = attr->data;
		GList *v = e_vcard_attribute_get_values (a);

		if (v && v->data) {
			if (!strncmp ((gchar *)v->data, "<?xml", 5)) {
				EDestination *dest = e_destination_import ((gchar *) v->data);

				e_destination_export_to_vcard_attribute (dest, a);

				g_object_unref (dest);

			}
		}
	}
	e_contact_set_attributes (contact, E_CONTACT_EMAIL, attrs);

	/* Deal with TEL attributes that don't conform to what we need.
	 *
	 * 1. if there's no location (HOME/WORK/OTHER), default to OTHER.
	 * 2. if there's *only* a location specified, default to VOICE.
	 */
	attrs = e_vcard_get_attributes (E_VCARD (contact));
	for (attr = attrs; attr; attr = attr->next) {
		EVCardAttribute *a = attr->data;
		gboolean location_only = TRUE;
		gboolean no_location = TRUE;
		gboolean is_work_home = FALSE;
		GList *params, *param;

		if (g_ascii_strcasecmp (e_vcard_attribute_get_name (a),
					EVC_TEL))
			continue;

		params = e_vcard_attribute_get_params (a);
		for (param = params; param; param = param->next) {
			EVCardAttributeParam *p = param->data;
			GList *vs, *v;

			if (g_ascii_strcasecmp (e_vcard_attribute_param_get_name (p),
						EVC_TYPE))
				continue;

			vs = e_vcard_attribute_param_get_values (p);
			for (v = vs; v; v = v->next) {
				is_work_home = is_work_home ||
					!g_ascii_strcasecmp ((gchar *)v->data, "WORK") ||
					!g_ascii_strcasecmp ((gchar *)v->data, "HOME");

				if (!g_ascii_strcasecmp ((gchar *)v->data, "WORK") ||
				    !g_ascii_strcasecmp ((gchar *)v->data, "HOME") ||
				    !g_ascii_strcasecmp ((gchar *)v->data, "OTHER"))
					no_location = FALSE;
				else
					location_only = FALSE;
			}
		}

		if (is_work_home) {
			/* only WORK and HOME phone numbers require locations,
			 * the rest should be kept as is */
			if (location_only) {
				/* add VOICE */
				e_vcard_attribute_add_param_with_value (a,
									e_vcard_attribute_param_new (EVC_TYPE),
									"VOICE");
			}
			if (no_location) {
				/* add OTHER */
				e_vcard_attribute_add_param_with_value (a,
									e_vcard_attribute_param_new (EVC_TYPE),
									"OTHER");
			}
		}
	}

	/* Deal with ADR and EMAIL attributes that don't conform to what
	 * we need.  If HOME or WORK isn't specified, add TYPE=OTHER. */
	attrs = e_vcard_get_attributes (E_VCARD (contact));
	for (attr = attrs; attr; attr = attr->next) {
		EVCardAttribute *a = attr->data;
		gboolean no_location = TRUE;
		GList *params, *param;

		if (g_ascii_strcasecmp (e_vcard_attribute_get_name (a), EVC_ADR) &&
		    g_ascii_strcasecmp (e_vcard_attribute_get_name (a), EVC_EMAIL))
			continue;

		params = e_vcard_attribute_get_params (a);
		for (param = params; param; param = param->next) {
			EVCardAttributeParam *p = param->data;
			GList *vs, *v;

			if (g_ascii_strcasecmp (e_vcard_attribute_param_get_name (p),
						EVC_TYPE))
				continue;

			vs = e_vcard_attribute_param_get_values (p);
			for (v = vs; v; v = v->next) {
				if (!g_ascii_strcasecmp ((gchar *)v->data, "WORK") ||
				    !g_ascii_strcasecmp ((gchar *)v->data, "HOME"))
					no_location = FALSE;
			}
		}

		if (no_location) {
			/* add OTHER */
			e_vcard_attribute_add_param_with_value (a,
								e_vcard_attribute_param_new (EVC_TYPE),
								"OTHER");
		}
	}

	/* Work around the fact that these fields no longer show up in the UI */
	add_to_notes (contact, E_CONTACT_OFFICE);
	add_to_notes (contact, E_CONTACT_SPOUSE);
	add_to_notes (contact, E_CONTACT_BLOG_URL);

	/* FIXME Error checking */
	if (e_book_client_add_contact_sync (gci->book_client, contact, &uid, NULL, NULL) && uid) {
		e_contact_set (contact, E_CONTACT_UID, uid);
		g_free (uid);
	}
}
Esempio n. 7
0
static const gchar *
get_phone_location (EVCardAttribute *attr)
{
	struct _locations {
		EContactField field_id;
		const gchar *attr_type;
	} locations[] = {
		{ E_CONTACT_PHONE_ASSISTANT, EVC_X_ASSISTANT },
		{ E_CONTACT_PHONE_CALLBACK, EVC_X_CALLBACK },
		{ E_CONTACT_PHONE_CAR, "CAR" },
		{ E_CONTACT_PHONE_COMPANY, EVC_X_COMPANY },
		{ E_CONTACT_PHONE_ISDN, "ISDN" },
		{ E_CONTACT_PHONE_MOBILE, "CELL" },
		{ E_CONTACT_PHONE_OTHER_FAX, "FAX" },
		{ E_CONTACT_PHONE_PAGER, "PAGER" },
		{ E_CONTACT_PHONE_PRIMARY, "PREF" },
		{ E_CONTACT_PHONE_RADIO, EVC_X_RADIO },
		{ E_CONTACT_PHONE_TELEX, EVC_X_TELEX },
		{ E_CONTACT_PHONE_TTYTDD, EVC_X_TTYTDD }
	};
	GList *params, *plink;
	GList *values = NULL, *vlink;
	gboolean done = FALSE;
	const gchar *location = NULL;
	gint ii;

	params = e_vcard_attribute_get_params (attr);

	for (plink = params; plink; plink = g_list_next (plink)) {
		EVCardAttributeParam *param = plink->data;

		if (!g_ascii_strcasecmp (e_vcard_attribute_param_get_name (param), EVC_TYPE)) {
			values = e_vcard_attribute_param_get_values (param);
			break;
		}
	}

	for (vlink = values; vlink && !done; vlink = g_list_next (vlink)) {
		const gchar *value = vlink->data;

		if (!value)
			continue;

		for (ii = 0; ii < G_N_ELEMENTS (locations); ii++) {
			if (!g_ascii_strcasecmp (value, locations[ii].attr_type)) {
				if (location) {
					/* if more than one is set, then fallback to the "Other Phone" */
					location = NULL;
					done = TRUE;
					break;
				}

				location = e_contact_pretty_name (locations[ii].field_id);
			}
		}
	}

	if (!location)
		location = e_contact_pretty_name (E_CONTACT_PHONE_OTHER);

	if (!location)
		location = _("Phone");

	return location;
}