* Fixes NB#89889, if the size is < 1Kb then show it as 1Kb
[modest] / src / modest-text-utils.c
index e2802d8..deb2971 100644 (file)
@@ -63,7 +63,7 @@
  * will hang modest
  */
 #define HYPERLINKIFY_MAX_LENGTH (1024*50)
-
+#define SIGNATURE_MARKER "--"
 
 
 /*
@@ -145,8 +145,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);
@@ -215,11 +216,11 @@ modest_text_utils_cite (const gchar *text,
        if (!signature)
                retval = g_strdup ("");
        else if (strcmp(content_type, "text/html") == 0) {
-               tmp_sig = g_strconcat ("\n", signature, NULL);
+               tmp_sig = g_strconcat ("\n", SIGNATURE_MARKER,"\n", signature, NULL);
                retval = modest_text_utils_convert_to_html_body(tmp_sig, -1, TRUE);
                g_free (tmp_sig);
        } else {
-               retval = g_strconcat (text, "\n", signature, NULL);
+               retval = g_strconcat (text, "\n", SIGNATURE_MARKER, "\n", signature, NULL);
        }
 
        return retval;
@@ -278,6 +279,11 @@ modest_text_utils_strftime(char *s, gsize max, const char *fmt, time_t timet)
 {
         struct tm tm;
 
+       /* To prevent possible problems in strftime that could leave
+          garbage in the s variable */
+       if (s)
+               s[0] = '\0';
+
        /* does not work on old maemo glib: 
         *   g_date_set_time_t (&date, timet);
         */
@@ -288,21 +294,33 @@ modest_text_utils_strftime(char *s, gsize max, const char *fmt, time_t timet)
 gchar *
 modest_text_utils_derived_subject (const gchar *subject, const gchar *prefix)
 {
-       gchar *tmp;
+       gchar *tmp, *subject_dup, *retval;
+       gint prefix_len;
 
        g_return_val_if_fail (prefix, NULL);
 
        if (!subject || subject[0] == '\0')
                subject = _("mail_va_no_subject");
 
-       tmp = g_strchug (g_strdup (subject));
+       subject_dup = g_strdup (subject);
+       tmp = g_strchug (subject_dup);
 
-       if (!strncmp (tmp, prefix, strlen (prefix))) {
-               return tmp;
-       } else {
-               g_free (tmp);
-               return g_strdup_printf ("%s %s", prefix, subject);
-       }
+       /* We do not want things like "Re: Re: Re:" or "Fw: Fw:" so
+          delete the previous ones */
+       prefix_len = strlen (prefix);
+       do {
+               if (g_str_has_prefix (tmp, prefix)) {
+                       tmp += prefix_len;
+                       tmp = g_strchug (tmp);
+               } else {
+                       break;
+               }
+       } while (tmp);
+
+       retval = g_strdup_printf ("%s %s", prefix, tmp);
+       g_free (subject_dup);
+
+       return retval;
 }
 
 gchar*
@@ -595,6 +613,7 @@ modest_text_utils_split_addresses_list (const gchar *addresses)
        const gchar *my_addrs = addresses;
        const gchar *end;
        gchar *addr;
+       gboolean after_at = FALSE;
 
        g_return_val_if_fail (addresses, NULL);
        
@@ -609,8 +628,20 @@ modest_text_utils_split_addresses_list (const gchar *addresses)
        /* nope, we are at the start of some address
         * now, let's find the end of the address */
        end = my_addrs + 1;
-       while (end[0] && end[0] != ',' && end[0] != ';')
+       while (end[0] && end[0] != ';' && !(after_at && end[0] == ',')) {
+               if (end[0] == '\"') {
+                       while (end[0] && end[0] != '\"')
+                               ++end;
+               }
+               if (end[0] == '@') {
+                       after_at = TRUE;
+               }
+               if ((end[0] && end[0] == '>')&&(end[1] && end[1] == ',')) {
+                       ++end;
+                       break;
+               }
                ++end;
+       }
 
        /* we got the address; copy it and remove trailing whitespace */
        addr = g_strndup (my_addrs, end - my_addrs);
@@ -740,15 +771,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;
@@ -759,15 +792,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 {
@@ -856,33 +893,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 ("\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) {
@@ -894,7 +923,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);
@@ -912,23 +941,54 @@ 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]));
 
-       attachments_string = quoted_attachments (attachments);
-       q = g_string_append (q, attachments_string);
-       g_free (attachments_string);
+       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) {
                q = g_string_append (q, "\n--\n");
                q = g_string_append (q, signature);
-               q = g_string_append_c (q, '\n');
        }
 
+       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);
+
        return g_string_free (q, FALSE);
 }
 
+static void
+quote_html_add_to_gstring (GString *string,
+                          const gchar *text)
+{
+       if (text && strcmp (text, "")) {
+               gchar *html_text = modest_text_utils_convert_to_html_body (text, -1, TRUE);
+               g_string_append_printf (string, "%s<br/>", html_text);
+               g_free (html_text);
+       }
+}
+
 static gchar*
 modest_text_utils_quote_html (const gchar *text, 
                              const gchar *cite, 
@@ -936,38 +996,37 @@ modest_text_utils_quote_html (const gchar *text,
                              GList *attachments,
                              int limit)
 {
-       gchar *result = NULL;
-       gchar *signature_result = NULL;
-       const gchar *format = \
-               "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n" \
-               "<html>\n" \
-               "<body>\n" \
-               "<pre>%s<br/>%s<br/>%s</pre>\n" \
-               "<br/>--<br/>%s<br/>\n" \
-               "</body>\n" \
-               "</html>\n";
-       gchar *attachments_string = NULL;
-       gchar *q_attachments_string = NULL;
-       gchar *q_cite = NULL;
-       gchar *html_text = NULL;
-
-       if (signature == NULL)
-               signature_result = g_strdup ("");
-       else
-               signature_result = modest_text_utils_convert_to_html_body (signature, -1, TRUE);
+       GString *result_string;
+
+       result_string = 
+               g_string_new ( \
+                             "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n" \
+                             "<html>\n"                                \
+                             "<body>\n<br/>\n");
+
+       if (text || cite || signature) {
+               GString *quoted_text;
+               g_string_append (result_string, "<pre>\n");
+               if (signature) {
+                       quote_html_add_to_gstring (result_string, SIGNATURE_MARKER);
+                       quote_html_add_to_gstring (result_string, signature);
+               }
+               quote_html_add_to_gstring (result_string, cite);
+               quoted_text = g_string_new ("");
+               quoted_text = modest_text_utils_quote_body (quoted_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);
+                       g_free (attachments_string);
+               }
+               g_string_append (result_string, "</pre>");
+       }
+       g_string_append (result_string, "</body>");
+       g_string_append (result_string, "</html>");
 
-       attachments_string = quoted_attachments (attachments);
-       q_attachments_string = modest_text_utils_convert_to_html_body (attachments_string, -1, TRUE);
-       q_cite = modest_text_utils_convert_to_html_body (cite, -1, TRUE);
-       html_text = modest_text_utils_convert_to_html_body (text, -1, TRUE);
-       result = g_strdup_printf (format, q_cite, html_text, q_attachments_string, signature_result);
-       g_free (q_cite);
-       g_free (html_text);
-       g_free (attachments_string);
-       g_free (q_attachments_string);
-       g_free (signature_result);
-       
-       return result;
+       return g_string_free (result_string, FALSE);
 }
 
 static gint 
@@ -976,7 +1035,7 @@ cmp_offsets_reverse (const url_match_t *match1, const url_match_t *match2)
        return match2->offset - match1->offset;
 }
 
-static gboolean url_matches_block = 0;
+static gint url_matches_block = 0;
 static url_match_pattern_t patterns[] = MAIL_VIEWER_URL_MATCH_PATTERNS;
 
 
@@ -1250,7 +1309,7 @@ modest_text_utils_get_subject_prefix_len (const gchar *sub)
                int c = prefix_len + 1;
                while (sub[c] && sub[c] != ']')
                        ++c;
-               if (sub[c])
+               if (!sub[c])
                        return 0; /* no end to the ']' found */
                else
                        prefix_len = c + 1;
@@ -1285,7 +1344,8 @@ modest_text_utils_utf8_strcmp (const gchar* s1, const gchar *s2, gboolean insens
        if (!insensitive) {
 
                /* optimization: shortcut if first char is ascii */ 
-               if (((s1[0] & 0xf0)== 0) && ((s2[0] & 0xf0) == 0)) 
+               if (((s1[0] & 0x80)== 0) && ((s2[0] & 0x80) == 0) &&
+                   (s1[0] != s2[0])) 
                        return s1[0] - s2[0];
                
                return g_utf8_collate (s1, s2);
@@ -1294,8 +1354,9 @@ modest_text_utils_utf8_strcmp (const gchar* s1, const gchar *s2, gboolean insens
                gint result;
                gchar *n1, *n2;
 
-               /* optimization: short cut iif first char is ascii */ 
-               if (((s1[0] & 0xf0) == 0) && ((s2[0] & 0xf0) == 0)) 
+               /* optimization: shortcut if first char is ascii */ 
+               if (((s1[0] & 0x80) == 0) && ((s2[0] & 0x80) == 0) &&
+                   (tolower(s1[0]) != tolower (s2[0]))) 
                        return tolower(s1[0]) - tolower(s2[0]);
                
                n1 = g_utf8_strdown (s1, -1);
@@ -1325,10 +1386,11 @@ 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 */
        if (day == date_day) /* is the date today? */
-               modest_text_utils_strftime (date_buf, DATE_BUF_SIZE, "%X", date);
+               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, "%x", date); 
+               modest_text_utils_strftime (date_buf, DATE_BUF_SIZE, _HL("wdgt_va_date"), date); 
 
        return date_buf; /* this is a static buffer, don't free! */
 }
@@ -1373,10 +1435,8 @@ modest_text_utils_validate_folder_name (const gchar *folder_name)
 
        /* Cannot contain Windows port numbers. I'd like to use GRegex
           but it's still not available in Maemo. sergio */
-       if (g_str_has_prefix (folder_name, "LTP") ||
-           g_str_has_prefix (folder_name, "ltp") ||
-           g_str_has_prefix (folder_name, "COM") ||
-           g_str_has_prefix (folder_name, "com")) {
+       if (!g_ascii_strncasecmp (folder_name, "LPT", 3) ||
+           !g_ascii_strncasecmp (folder_name, "COM", 3)) {
                glong val;
                gchar *endptr;
 
@@ -1596,9 +1656,9 @@ modest_text_utils_get_display_size (guint64 size)
        const guint GB=1024 * MB;
 
        if (size == 0)
-               return g_strdup_printf(_FM("sfil_li_size_kb"), 0);
-       if (0 < size && size < KB)
-               return g_strdup_printf (_FM("sfil_li_size_kb"), 1);
+               return g_strdup_printf (_FM("sfil_li_size_kb"));
+       if (0 <= size && size < KB)
+               return g_strdup_printf (_FM("sfil_li_size_1kb_99kb"), 1);
        else if (KB <= size && size < 100 * KB)
                return g_strdup_printf (_FM("sfil_li_size_1kb_99kb"), size / KB);
        else if (100*KB <= size && size < MB)