X-Git-Url: http://git.maemo.org/git/?p=modest;a=blobdiff_plain;f=src%2Fmodest-text-utils.c;h=2223fd1b0a880373e4c3c6dbf117d1e53277b70e;hp=49372cce87bd729c610b36afa48fd9613783b2f2;hb=4d39841513a3a7f7aa9d38ab97cb9fcc9171e80b;hpb=fbb2640f53123b35a81e15c7e3a70ce601d40bed diff --git a/src/modest-text-utils.c b/src/modest-text-utils.c index 49372cc..2223fd1 100644 --- a/src/modest-text-utils.c +++ b/src/modest-text-utils.c @@ -63,8 +63,6 @@ * will hang modest */ #define HYPERLINKIFY_MAX_LENGTH (1024*50) -#define SIGNATURE_MARKER "--" - /* * we need these regexps to find URLs in plain text e-mails @@ -109,14 +107,14 @@ struct _url_match_t { /* note: match MARK_AMP_URI_STR as well, because after txt->html, a '&' will look like $(MARK_AMP_URI_STR)"amp;" */ #define MAIL_VIEWER_URL_MATCH_PATTERNS { \ - { "(file|rtsp|http|ftp|https|mms|mmsh|rtsp|rdp|lastfm)://[-a-z0-9_$.+!*(),;:@%=?/~#" MARK_AMP_URI_STR \ - "]+[-a-z0-9_$%" MARK_AMP_URI_STR "=?/~#]", \ + { "(feed:|)(file|rtsp|http|ftp|https|mms|mmsh|webcal|feed|rtsp|rdp|lastfm|sip)://[-a-z0-9_$.+!*(),;:@%=\?/~#&" MARK_AMP_URI_STR \ + "]+[-a-z0-9_$%&" MARK_AMP_URI_STR "=?/~#]", \ NULL, NULL },\ { "www\\.[-a-z0-9_$.+!*(),;:@%=?/~#" MARK_AMP_URI_STR "]+[-a-z0-9_$%" MARK_AMP_URI_STR "=?/~#]",\ NULL, "http://" }, \ { "ftp\\.[-a-z0-9_$.+!*(),;:@%=?/~#" MARK_AMP_URI_STR "]+[-a-z0-9_$%" MARK_AMP_URI_STR "=?/~#]",\ NULL, "ftp://" },\ - { "(jabberto|voipto|sipto|sip|chatto|xmpp):[-_a-z@0-9.+]+", \ + { "(jabberto|voipto|sipto|sip|chatto|skype|xmpp):[-_a-z@0-9.+]+", \ NULL, NULL}, \ { "mailto:[-_a-z0-9.\\+]+@[-_a-z0-9.]+", \ NULL, NULL},\ @@ -145,8 +143,9 @@ static GSList* get_url_matches (GString *txt, gint offset); static GString* get_next_line (const char *b, const gsize blen, const gchar * iter); static int get_indent_level (const char *l); -static void unquote_line (GString * l); -static void append_quoted (GString * buf, const int indent, const GString * str, +static void unquote_line (GString * l, const gchar *quote_symbol); +static void append_quoted (GString * buf, const gchar *quote_symbol, + const int indent, const GString * str, const int cutpoint); static int get_breakpoint_utf8 (const gchar * s, const gint indent, const gint limit); static int get_breakpoint_ascii (const gchar * s, const gint indent, const gint limit); @@ -212,14 +211,17 @@ modest_text_utils_cite (const gchar *text, g_return_val_if_fail (text, NULL); g_return_val_if_fail (content_type, NULL); - if (!signature) - retval = g_strdup (""); - else if (strcmp(content_type, "text/html") == 0) { - tmp_sig = g_strconcat ("\n", SIGNATURE_MARKER,"\n", signature, NULL); - retval = modest_text_utils_convert_to_html_body(tmp_sig, -1, TRUE); + if (!signature) { + tmp_sig = g_strdup (text); + } else { + tmp_sig = g_strconcat (text, "\n", MODEST_TEXT_UTILS_SIGNATURE_MARKER, "\n", signature, NULL); + } + + if (strcmp (content_type, "text/html") == 0) { + retval = modest_text_utils_convert_to_html_body (tmp_sig, -1, TRUE); g_free (tmp_sig); } else { - retval = g_strconcat (text, "\n", SIGNATURE_MARKER, "\n", signature, NULL); + retval = tmp_sig; } return retval; @@ -282,6 +284,8 @@ modest_text_utils_strftime(char *s, gsize max, const char *fmt, time_t timet) garbage in the s variable */ if (s) s[0] = '\0'; + else + return 0; /* does not work on old maemo glib: * g_date_set_time_t (&date, timet); @@ -412,6 +416,9 @@ modest_text_utils_remove_duplicate_addresses (const gchar *address_list) g_slist_foreach (addresses, (GFunc)g_free, NULL); g_slist_free (addresses); + if (new_list == NULL) + new_list = g_strdup (""); + return new_list; } @@ -431,7 +438,7 @@ modest_text_utils_convert_buffer_to_html_start (GString *html, const gchar *data guchar kar = data[i]; if (space_seen && kar != ' ') { - g_string_append_c (html, ' '); + g_string_append (html, " "); space_seen = FALSE; } @@ -762,7 +769,7 @@ get_indent_level (const char *l) /* if we hit the signature marker "-- ", we return -(indent + 1). This * stops reformatting. */ - if (strcmp (l, "-- ") == 0) { + if (strcmp (l, MODEST_TEXT_UTILS_SIGNATURE_MARKER) == 0) { return -1 - indent; } else { return indent; @@ -770,15 +777,17 @@ get_indent_level (const char *l) } static void -unquote_line (GString * l) +unquote_line (GString * l, const gchar *quote_symbol) { gchar *p; + gint quote_len; p = l->str; + quote_len = strlen (quote_symbol); while (p[0]) { - if (p[0] == '>') { - if (p[1] == ' ') { - p++; + if (g_str_has_prefix (p, quote_symbol)) { + if (p[quote_len] == ' ') { + p += quote_len; } } else { break; @@ -789,15 +798,19 @@ unquote_line (GString * l) } static void -append_quoted (GString * buf, int indent, const GString * str, +append_quoted (GString * buf, const gchar *quote_symbol, + int indent, const GString * str, const int cutpoint) { int i; + gchar *quote_concat; indent = indent < 0 ? abs (indent) - 1 : indent; + quote_concat = g_strconcat (quote_symbol, " ", NULL); for (i = 0; i <= indent; i++) { - g_string_append (buf, "> "); + g_string_append (buf, quote_concat); } + g_free (quote_concat); if (cutpoint > 0) { g_string_append_len (buf, str->str, cutpoint); } else { @@ -886,40 +899,25 @@ quoted_attachments (GList *attachments) } -static gchar * -modest_text_utils_quote_plain_text (const gchar *text, - const gchar *cite, - const gchar *signature, - GList *attachments, - int limit) +static GString * +modest_text_utils_quote_body (GString *output, const gchar *text, + const gchar *quote_symbol, + int limit) { + const gchar *iter; - gint indent, breakpoint, rem_indent = 0; - GString *q, *l, *remaining; gsize len; - gchar *attachments_string = NULL; - - q = g_string_new (""); - - if (signature != NULL) { - q = g_string_append (q, "\n--\n"); - q = g_string_append (q, signature); - } - - q = g_string_append (q, "\n"); - q = g_string_append (q, cite); - q = g_string_append_c (q, '\n'); - - /* remaining will store the rest of the line if we have to break it */ - remaining = g_string_new (""); + gint indent, breakpoint, rem_indent = 0; + GString *l, *remaining; iter = text; len = strlen(text); + remaining = g_string_new (""); do { l = get_next_line (text, len, iter); iter = iter + l->len + 1; indent = get_indent_level (l->str); - unquote_line (l); + unquote_line (l, quote_symbol); if (remaining->len) { if (l->len && indent == rem_indent) { @@ -931,7 +929,7 @@ modest_text_utils_quote_plain_text (const gchar *text, get_breakpoint (remaining->str, rem_indent, limit); - append_quoted (q, rem_indent, + append_quoted (output, quote_symbol, rem_indent, remaining, breakpoint); g_string_erase (remaining, 0, breakpoint); @@ -949,10 +947,36 @@ modest_text_utils_quote_plain_text (const gchar *text, g_string_erase (remaining, 0, 1); } rem_indent = indent; - append_quoted (q, indent, l, breakpoint); + append_quoted (output, quote_symbol, indent, l, breakpoint); g_string_free (l, TRUE); } while ((iter < text + len) || (remaining->str[0])); + return output; +} + +static gchar * +modest_text_utils_quote_plain_text (const gchar *text, + const gchar *cite, + const gchar *signature, + GList *attachments, + int limit) +{ + GString *q; + gchar *attachments_string = NULL; + + q = g_string_new (""); + + if (signature != NULL) { + g_string_append_printf (q, "\n%s\n", MODEST_TEXT_UTILS_SIGNATURE_MARKER); + q = g_string_append (q, signature); + } + + q = g_string_append (q, "\n"); + q = g_string_append (q, cite); + q = g_string_append_c (q, '\n'); + + q = modest_text_utils_quote_body (q, text, ">", limit); + attachments_string = quoted_attachments (attachments); q = g_string_append (q, attachments_string); g_free (attachments_string); @@ -987,13 +1011,17 @@ modest_text_utils_quote_html (const gchar *text, "\n
\n"); if (text || cite || signature) { + GString *quoted_text; g_string_append (result_string, "
\n");
 		if (signature) {
-			quote_html_add_to_gstring (result_string, SIGNATURE_MARKER);
+			quote_html_add_to_gstring (result_string, MODEST_TEXT_UTILS_SIGNATURE_MARKER);
 			quote_html_add_to_gstring (result_string, signature);
 		}
 		quote_html_add_to_gstring (result_string, cite);
-		quote_html_add_to_gstring (result_string, text);
+		quoted_text = g_string_new ("");
+		quoted_text = modest_text_utils_quote_body (quoted_text, (text) ? text : "", ">", limit);
+		quote_html_add_to_gstring (result_string, quoted_text->str);
+		g_string_free (quoted_text, TRUE);
 		if (attachments) {
 			gchar *attachments_string = quoted_attachments (attachments);
 			quote_html_add_to_gstring (result_string, attachments_string);
@@ -1015,6 +1043,7 @@ cmp_offsets_reverse (const url_match_t *match1, const url_match_t *match2)
 
 static gint url_matches_block = 0;
 static url_match_pattern_t patterns[] = MAIL_VIEWER_URL_MATCH_PATTERNS;
+static GMutex *url_patterns_mutex = NULL;
 
 
 static gboolean
@@ -1049,17 +1078,25 @@ free_patterns ()
 void
 modest_text_utils_hyperlinkify_begin (void)
 {
+
+	if (url_patterns_mutex == NULL) {
+		url_patterns_mutex = g_mutex_new ();
+	}
+	g_mutex_lock (url_patterns_mutex);
 	if (url_matches_block == 0)
 		compile_patterns ();
 	url_matches_block ++;
+	g_mutex_unlock (url_patterns_mutex);
 }
 
 void
 modest_text_utils_hyperlinkify_end (void)
 {
+	g_mutex_lock (url_patterns_mutex);
 	url_matches_block--;
 	if (url_matches_block <= 0)
 		free_patterns ();
+	g_mutex_unlock (url_patterns_mutex);
 }
 
 
@@ -1225,18 +1262,50 @@ modest_text_utils_get_display_address (gchar *address)
 		
 	for (i = 0; address[i]; ++i) {
 		if (address[i] == '<') {
-			if (G_UNLIKELY(i == 0))
-				return; /* there's nothing else, leave it */
-			else {
+			if (G_UNLIKELY(i == 0)) {
+				break; /* there's nothing else, leave it */
+			}else {
 				address[i] = '\0'; /* terminate the string here */
-				return;
+				break;
 			}
 		}
 	}
+
+	g_strchomp (address);
 }
 
 
+gchar *
+modest_text_utils_get_display_addresses (const gchar *recipients)
+{
+	gchar *addresses;
+	GSList *recipient_list;
+
+	addresses = NULL;
+	recipient_list = modest_text_utils_split_addresses_list (recipients);
+	if (recipient_list) {
+		GString *add_string = g_string_sized_new (strlen (recipients));
+		GSList *iter = recipient_list;
+		gboolean first = TRUE;
+
+		while (iter) {
+			/* Strings are changed in place */
+			modest_text_utils_get_display_address ((gchar *) iter->data);
+			if (G_UNLIKELY (first)) {
+				g_string_append_printf (add_string, "%s", (gchar *) iter->data);
+				first = FALSE;
+			} else {
+				g_string_append_printf (add_string, ", %s", (gchar *) iter->data);
+			}
+			iter = g_slist_next (iter);
+		}
+		g_slist_foreach (recipient_list, (GFunc) g_free, NULL);
+		g_slist_free (recipient_list);
+		addresses = g_string_free (add_string, FALSE);
+	}
 
+	return addresses;
+}
 
 
 gchar *
@@ -1365,10 +1434,17 @@ modest_text_utils_get_display_date (time_t date)
 	/* if it's today, show the time, if it's not today, show the date instead */
 
 	/* TODO: take into account the system config for 24/12h */
+#ifdef MODEST_TOOLKIT_HILDON2
 	if (day == date_day) /* is the date today? */
 		modest_text_utils_strftime (date_buf, DATE_BUF_SIZE, _HL("wdgt_va_24h_time"), date);
 	else 
 		modest_text_utils_strftime (date_buf, DATE_BUF_SIZE, _HL("wdgt_va_date"), date); 
+#else
+	if (day == date_day) /* is the date today? */
+		modest_text_utils_strftime (date_buf, DATE_BUF_SIZE, "%X", date);
+	else 
+		modest_text_utils_strftime (date_buf, DATE_BUF_SIZE, "%x", date); 
+#endif
 
 	return date_buf; /* this is a static buffer, don't free! */
 }
@@ -1633,18 +1709,20 @@ modest_text_utils_get_display_size (guint64 size)
 	const guint MB=1024 * KB;
 	const guint GB=1024 * MB;
 
+	if (size == 0)
+		return g_strdup_printf (_FM("sfil_li_size_kb"), (int) 0);
 	if (0 <= size && size < KB)
-		return g_strdup_printf (_FM("sfil_li_size_kb"), 1);
+		return g_strdup_printf (_FM("sfil_li_size_1kb_99kb"), (int) 1);
 	else if (KB <= size && size < 100 * KB)
-		return g_strdup_printf (_FM("sfil_li_size_1kb_99kb"), size / KB);
+		return g_strdup_printf (_FM("sfil_li_size_1kb_99kb"), (int) size / KB);
 	else if (100*KB <= size && size < MB)
-		return g_strdup_printf (_FM("sfil_li_size_100kb_1mb"), (float) size / MB);
+		return g_strdup_printf (_FM("sfil_li_size_100kb_1mb"), (int) size / KB);
 	else if (MB <= size && size < 10*MB)
 		return g_strdup_printf (_FM("sfil_li_size_1mb_10mb"), (float) size / MB);
 	else if (10*MB <= size && size < GB)
-		return g_strdup_printf (_FM("sfil_li_size_10mb_1gb"), size / MB);
+		return g_strdup_printf (_FM("sfil_li_size_10mb_1gb"), (float) size / MB);
 	else
-		return g_strdup_printf (_FM("sfil_li_size_1gb_or_greater"), (float) size / GB);	
+		return g_strdup_printf (_FM("sfil_li_size_1gb_or_greater"), (float) size / GB);
 }
 
 static gchar *
@@ -1661,11 +1739,11 @@ get_email_from_address (const gchar * address)
 		return g_strndup (left_limit + 1, (right_limit - left_limit) - 1);
 }
 
-gchar *      
+gchar *
 modest_text_utils_get_color_string (GdkColor *color)
 {
 	g_return_val_if_fail (color, NULL);
-	
+
 	return g_strdup_printf ("#%x%x%x%x%x%x%x%x%x%x%x%x",
 				(color->red >> 12)   & 0xf, (color->red >> 8)   & 0xf,
 				(color->red >>  4)   & 0xf, (color->red)        & 0xf,
@@ -1797,6 +1875,17 @@ modest_text_utils_buffer_selection_is_valid (GtkTextBuffer *buffer)
 	return result;
 }
 
+static void
+remove_quotes (gchar **quotes)
+{
+	if (g_str_has_prefix (*quotes, "\"") && g_str_has_suffix (*quotes, "\"")) {
+		gchar *result;
+		result = g_strndup ((*quotes)+1, strlen (*quotes) - 2);
+		g_free (*quotes);
+		*quotes = result;
+	}
+}
+
 gchar *
 modest_text_utils_escape_mnemonics (const gchar *text)
 {
@@ -1816,3 +1905,53 @@ modest_text_utils_escape_mnemonics (const gchar *text)
 	
 	return g_string_free (result, FALSE);
 }
+
+gchar *
+modest_text_utils_simplify_recipients (const gchar *recipients)
+{
+	GSList *addresses, *node;
+	GString *result;
+	gboolean is_first = TRUE;
+
+	if (recipients == NULL)
+		return g_strdup ("");
+
+	addresses = modest_text_utils_split_addresses_list (recipients);
+	result = g_string_new ("");
+
+	for (node = addresses; node != NULL; node = g_slist_next (node)) {
+		const gchar *address = (const gchar *) node->data;
+		gchar *left_limit, *right_limit;
+		left_limit = strstr (address, "<");
+		right_limit = g_strrstr (address, ">");
+
+		if (is_first)
+			is_first = FALSE;
+		else
+			result = g_string_append (result, ", ");
+
+		if ((left_limit == NULL)||(right_limit == NULL)|| (left_limit > right_limit)) {
+			result = g_string_append (result, address);
+		} else {
+			gchar *name_side;
+			gchar *email_side;
+			name_side = g_strndup (address, left_limit - address);
+			name_side = g_strstrip (name_side);
+			remove_quotes (&name_side);
+			email_side = get_email_from_address (address);
+			if (name_side && email_side && !strcmp (name_side, email_side)) {
+				result = g_string_append (result, email_side);
+			} else {
+				result = g_string_append (result, address);
+			}
+			g_free (name_side);
+			g_free (email_side);
+		}
+
+	}
+	g_slist_foreach (addresses, (GFunc)g_free, NULL);
+	g_slist_free (addresses);
+
+	return g_string_free (result, FALSE);
+
+}