Fix a problem in modest_text_utils_convert_buffer_to_html_start()
[modest] / src / modest-text-utils.c
index afaedef..38f55ad 100644 (file)
@@ -391,7 +391,7 @@ modest_text_utils_remove_duplicate_addresses (const gchar *address_list)
 static void
 modest_text_utils_convert_buffer_to_html_start (GString *html, const gchar *data, gssize n)
 {
-       guint           i;
+       guint           i = 0;
        gboolean        space_seen = FALSE;
        guint           break_dist = 0; /* distance since last break point */
 
@@ -399,7 +399,7 @@ modest_text_utils_convert_buffer_to_html_start (GString *html, const gchar *data
                n = strlen (data);
 
        /* replace with special html chars where needed*/
-       for (i = 0; i != n; ++i)  {
+       while (i != n) {
                char kar = data[i];
                
                if (space_seen && kar != ' ') {
@@ -443,8 +443,25 @@ modest_text_utils_convert_buffer_to_html_start (GString *html, const gchar *data
                                space_seen = TRUE;
                        break;
                default:
-                       g_string_append_c (html, kar);
+                       /* Optimization to copy single ascii
+                        * characters faster */
+                       if (kar > 31 && kar < 127) {
+                               g_string_append_c (html, kar);
+                       } else {
+                               /* Important: copy full UTF-8 characters,
+                                * don't copy them byte by byte */
+                               gunichar c = g_utf8_get_char_validated (data+i, -1);
+                               if (c != (gunichar) -1 && c != (gunichar) -2) {
+                                       const gchar *copyfrom = data + i;
+                                       int len = g_utf8_next_char(copyfrom) - copyfrom;
+                                       g_string_append_len (html, copyfrom, len);
+                                       i += len - 1;
+                               } else {
+                                       g_warning ("%s: non-UTF8 byte found, skipping", __FUNCTION__);
+                               }
+                       }
                }
+               i++;
        }
 }
 
@@ -1631,3 +1648,57 @@ modest_text_utils_is_forbidden_char (const gchar character,
 
        return FALSE; /* it's valid! */
 }
+
+gchar *      
+modest_text_utils_label_get_selection (GtkLabel *label)
+{
+       gint start, end;
+       gchar *selection;
+
+       if (gtk_label_get_selection_bounds (GTK_LABEL (label), &start, &end)) {
+               const gchar *start_offset;
+               const gchar *end_offset;
+               start_offset = gtk_label_get_text (GTK_LABEL (label));
+               start_offset = g_utf8_offset_to_pointer (start_offset, start);
+               end_offset = gtk_label_get_text (GTK_LABEL (label));
+               end_offset = g_utf8_offset_to_pointer (end_offset, end);
+               selection = g_strndup (start_offset, end_offset - start_offset);
+               return selection;
+       } else {
+               return g_strdup ("");
+       }
+}
+
+static gboolean
+_forward_search_image_char (gunichar ch,
+                           gpointer userdata)
+{
+       return (ch == 0xFFFC);
+}
+
+gboolean
+modest_text_utils_buffer_selection_is_valid (GtkTextBuffer *buffer)
+{
+       gboolean result;
+       GtkTextIter start, end;
+
+       g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), FALSE);
+
+       result = gtk_text_buffer_get_has_selection (GTK_TEXT_BUFFER (buffer));
+
+       /* check there are no images in selection */
+       if (result) {
+               gtk_text_buffer_get_selection_bounds (buffer, &start, &end);
+               if (gtk_text_iter_get_char (&start)== 0xFFFC)
+                       result = FALSE;
+               else {
+                       gtk_text_iter_backward_char (&end);
+                       if (gtk_text_iter_forward_find_char (&start, _forward_search_image_char,
+                                                            NULL, &end))
+                               result = FALSE;
+               }
+                                   
+       }
+
+       return result;
+}