Пример #1
0
static void
contacts_type_entry_changed (GtkWidget *widget, EContactTypeChangeData *data)
{
	GList *v = contacts_entries_get_values (widget, NULL);
	
	if (v) {
		guint i;
		const TypeTuple *types =
			contacts_get_field_types (data->attr_name);
		const gchar *type = (const gchar *)v->data;
		gboolean custom_type = TRUE;
		
		for (i = 0; types[i].index; i++) {
			if (g_ascii_strcasecmp (type, types[i].index) == 0)
				custom_type = FALSE;
		}
		
		e_vcard_attribute_param_remove_values (data->param);
		/* Prefix a 'X-' to non-standard types, as per vCard spec */
		if (custom_type) {
			gchar *new_type = g_strdup_printf ("X-%s", type);
			e_vcard_attribute_param_add_value (
				data->param, (const char *)new_type);
			g_free (new_type);
		} else
			e_vcard_attribute_param_add_value (
				data->param, (const char *)v->data);



		g_list_foreach (v, (GFunc)g_free, NULL);
		g_list_free (v);
		*data->changed = TRUE;
	}
}
/**
 * e_vcard_attribute_add_param_with_value:
 * @attr: an #EVCardAttribute
 * @param: an #EVCardAttributeParam
 * @value: a string value
 *
 * Adds @value to @param, then adds @param to @attr.
 **/
void
e_vcard_attribute_add_param_with_value (EVCardAttribute *attr,
					EVCardAttributeParam *param, const char *value)
{
	g_return_if_fail (attr != NULL);
	g_return_if_fail (param != NULL);

	e_vcard_attribute_param_add_value (param, value);

	e_vcard_attribute_add_param (attr, param);
}
/**
 * e_vcard_attribute_param_copy:
 * @param: an #EVCardAttributeParam
 *
 * Makes a copy of @param.
 *
 * Return value: a new #EVCardAttributeParam identical to @param.
 **/
EVCardAttributeParam*
e_vcard_attribute_param_copy (EVCardAttributeParam *param)
{
	EVCardAttributeParam *p;
	GList *l;

	g_return_val_if_fail (param != NULL, NULL);

	p = e_vcard_attribute_param_new (e_vcard_attribute_param_get_name (param));

	for (l = param->values; l; l = l->next) {
		e_vcard_attribute_param_add_value (p, l->data);
	}

	return p;
}
Пример #4
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_param_add_values:
 * @param: an #EVCardAttributeParam
 * @Varargs: a %NULL-terminated list of strings
 *
 * Adds a list of values to @param.
 **/
void
e_vcard_attribute_param_add_values (EVCardAttributeParam *param,
				    ...)
{
	va_list ap;
	char *v;

	g_return_if_fail (param != NULL);

	va_start (ap, param);

	while ((v = va_arg (ap, char*))) {
		e_vcard_attribute_param_add_value (param, v);
	}

	va_end (ap);
}
static void
read_attribute_params (EVCardAttribute *attr, char **p, gboolean *quoted_printable)
{
	char *lp;
	GString *str;
	EVCardAttributeParam *param = NULL;
	gboolean in_quote = FALSE;

	str = g_string_new ("");
	for( lp =  skip_newline( *p, *quoted_printable );
	     *lp != '\n' && *lp != '\r' && *lp != '\0';
	     lp = skip_newline( lp, *quoted_printable ) ) {

		if (*lp == '"') {
			in_quote = !in_quote;
			lp = g_utf8_next_char (lp);
		}
		else if (in_quote || g_unichar_isalnum (g_utf8_get_char (lp)) || *lp == '-' || *lp == '_') {
			g_string_append_unichar (str, g_utf8_get_char (lp));
			lp = g_utf8_next_char (lp);
		}
		/* accumulate until we hit the '=' or ';'.  If we hit
		 * a '=' the string contains the parameter name.  if
		 * we hit a ';' the string contains the parameter
		 * value and the name is either ENCODING (if value ==
		 * QUOTED-PRINTABLE) or TYPE (in any other case.)
		 */
		else if (*lp == '=') {
			if (str->len > 0) {
				param = e_vcard_attribute_param_new (str->str);
				g_string_assign (str, "");
				lp = g_utf8_next_char (lp);
			}
			else {
				skip_until (&lp, ":;");
				if (*lp == ';') {
					lp = g_utf8_next_char (lp);

				} else if (*lp == ':') {
					/* do nothing */

				} else {
					skip_to_next_line( &lp );
					break;
				}
			}
		}
		else if (*lp == ';' || *lp == ':' || *lp == ',') {
			gboolean colon = (*lp == ':');
			gboolean comma = (*lp == ',');

			if (param) {
				if (str->len > 0) {
					e_vcard_attribute_param_add_value (param, str->str);
					g_string_assign (str, "");
					if (!colon)
						lp = g_utf8_next_char (lp);
				}
				else {
					/* we've got a parameter of the form:
					 * PARAM=(.*,)?[:;]
					 * so what we do depends on if there are already values
					 * for the parameter.  If there are, we just finish
					 * this parameter and skip past the offending character
					 * (unless it's the ':'). If there aren't values, we free
					 * the parameter then skip past the character.
					 */
					if (!param->values) {
						e_vcard_attribute_param_free (param);
						param = NULL;
						if (!colon)
							lp = g_utf8_next_char (lp);
					}
				}

				if (param
				    && !g_ascii_strcasecmp (param->name, "encoding")
				    && !g_ascii_strcasecmp (param->values->data, "quoted-printable")) {
					*quoted_printable = TRUE;
					e_vcard_attribute_param_free (param);
					param = NULL;
				}
			}
			else {
				if (str->len > 0) {
					char *param_name;
					if (!g_ascii_strcasecmp (str->str,
								 "quoted-printable")) {
						param_name = "ENCODING";
						*quoted_printable = TRUE;
					}
					/* apple's broken addressbook app outputs naked BASE64
					   parameters, which aren't even vcard 3.0 compliant. */
					else if (!g_ascii_strcasecmp (str->str,
								      "base64")) {
						param_name = "ENCODING";
						g_string_assign (str, "b");
					}
					else {
						param_name = "TYPE";
					}

					if (param_name) {
						param = e_vcard_attribute_param_new (param_name);
						e_vcard_attribute_param_add_value (param, str->str);
					}
					g_string_assign (str, "");
					if (!colon)
						lp = g_utf8_next_char (lp);
				}
				else {
					/* we've got an attribute with a truly empty
					   attribute parameter.  So it's of the form:

					   ATTR;[PARAM=value;]*;[PARAM=value;]*:

					   (note the extra ';')

					   the only thing to do here is, well.. nothing.
					   we skip over the character if it's not a colon,
					   and the rest is handled for us: We'll either
					   continue through the loop again if we hit a ';',
					   or we'll break out correct below if it was a ':' */
					if (!colon)
						lp = g_utf8_next_char (lp);
				}
			}
			if (param && !comma) {
				e_vcard_attribute_add_param (attr, param);
				param = NULL;
			}
			if (colon)
				break;
		}
		else {
			g_warning ("invalid character found in parameter spec");
			g_string_assign (str, "");
			/*			skip_until (&lp, ":;"); */

			skip_to_next_line( &lp );
		}
	}

	if (str)
		g_string_free (str, TRUE);

	*p = lp;
}
/**
 * e_vcard_attribute_add_param:
 * @attr: an #EVCardAttribute
 * @param: an #EVCardAttributeParam to add
 *
 * Adds @param to @attr's list of parameters.
 * It tests for duplicities, only new parameters are added,
 * when a new parameter already exists in attr, then those
 * values are merged, also without creating duplicities.
 * When we will not add whole param, then it's freed here.
 **/
void
e_vcard_attribute_add_param (EVCardAttribute *attr,
			     EVCardAttributeParam *param)
{
	gboolean contains;
	GList *params, *p;
	const char *par_name;

	g_return_if_fail (attr != NULL);
	g_return_if_fail (param != NULL);

	contains = FALSE;
	params = attr->params;
	par_name = param->name;

	for (p = params; p; p = p->next) {
		EVCardAttributeParam *param2 = p->data;
		if (g_ascii_strcasecmp (param2->name, par_name) == 0) {
			/* param2 has same name as our new param;
			   better merge them than have more parameters
			   with same name within one attribute.
			*/
			GList *vals,*v;

			vals = param->values;

			for (v = vals; v; v = v->next) {
				const char *my_value;
				GList *vals2,*v2;

				my_value = (const char *)v->data;
				vals2 = param2->values;

				for (v2 = vals2; v2; v2 = v2->next) {
					if (g_ascii_strcasecmp ((const char *)v2->data, my_value) == 0) {
						break;
					}
				}

				if (!v2) {
					/* we did loop through all values and none of them was my_value */
					e_vcard_attribute_param_add_value (param2, my_value);
				}
			}

			contains = TRUE;
			break;
		}
	}

	if (!contains) {
		attr->params = g_list_prepend (attr->params, param);
	}

	/* we handle our special encoding stuff here */

	if (!g_ascii_strcasecmp (param->name, EVC_ENCODING)) {
		if (attr->encoding_set) {
			g_warning ("ENCODING specified twice");
			if (contains) {
				e_vcard_attribute_param_free (param);
			}
			return;
		}

		if (param->values && param->values->data) {
			if (!g_ascii_strcasecmp ((char*)param->values->data, "b") ||
			    !g_ascii_strcasecmp ((char*)param->values->data, "BASE64"))
				attr->encoding = EVC_ENCODING_BASE64;
			else if (!g_ascii_strcasecmp ((char*)param->values->data, EVC_QUOTEDPRINTABLE))
				attr->encoding = EVC_ENCODING_QP;
			else {
				g_warning ("Unknown value `%s' for ENCODING parameter.  values will be treated as raw",
					   (char*)param->values->data);
			}

			attr->encoding_set = TRUE;
		}
		else {
			g_warning ("ENCODING parameter added with no value");
		}
	}

	if (contains) {
		e_vcard_attribute_param_free (param);
	}
}