X-Git-Url: http://git.maemo.org/git/?a=blobdiff_plain;f=src%2Fwidgets%2Fmodest-recpt-editor.c;h=8a933585c6f0fe35be9d3a271e7d9bca531e0504;hb=2713ea765f9dbd409320c2c43462ed539f628720;hp=6e46a138c85f39a4ab81f68d97e66bfe9e12e512;hpb=7751b2edd7406c961e3972e05121cd6fac267d76;p=modest diff --git a/src/widgets/modest-recpt-editor.c b/src/widgets/modest-recpt-editor.c index 6e46a13..8a93358 100644 --- a/src/widgets/modest-recpt-editor.c +++ b/src/widgets/modest-recpt-editor.c @@ -31,10 +31,7 @@ #include -#include -#include -#include -#include +#include #include #include @@ -115,7 +112,7 @@ static gunichar iter_previous_char (GtkTextIter *iter); /* static gunichar iter_next_char (GtkTextIter *iter); */ static GtkTextTag *prev_iter_has_recipient (GtkTextIter *iter); /* static GtkTextTag *next_iter_has_recipient (GtkTextIter *iter); */ -static void select_tag_of_iter (GtkTextIter *iter, GtkTextTag *tag); +static void select_tag_of_iter (GtkTextIter *iter, GtkTextTag *tag, gboolean grow, gboolean left_not_right); static gboolean quote_opened (GtkTextIter *iter); static gboolean is_valid_insert (const gchar *text, gint len); static gchar *create_valid_text (const gchar *text, gint len); @@ -146,11 +143,7 @@ modest_recpt_editor_set_recipients (ModestRecptEditor *recpt_editor, const gchar g_return_if_fail (MODEST_IS_RECPT_EDITOR (recpt_editor)); priv = MODEST_RECPT_EDITOR_GET_PRIVATE (recpt_editor); -#ifdef MODEST_TOOLKIT_HILDON2 - buffer = hildon_text_view_get_buffer (HILDON_TEXT_VIEW (priv->text_view)); -#else - buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->text_view)); -#endif + buffer = modest_text_view_get_buffer (priv->text_view); valid_recipients = create_valid_text (recipients, -1); g_signal_handlers_block_by_func (buffer, modest_recpt_editor_on_insert_text, recpt_editor); @@ -178,11 +171,7 @@ modest_recpt_editor_add_recipients (ModestRecptEditor *recpt_editor, const gchar if (recipients == NULL) return; -#ifdef MODEST_TOOLKIT_HILDON2 - buffer = hildon_text_view_get_buffer (HILDON_TEXT_VIEW (priv->text_view)); -#else - buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->text_view)); -#endif + buffer = modest_text_view_get_buffer (priv->text_view); if (gtk_text_buffer_get_char_count (buffer) > 0) { string_to_add = g_strconcat (";\n", recipients, NULL); @@ -218,11 +207,7 @@ modest_recpt_editor_add_resolved_recipient (ModestRecptEditor *recpt_editor, GSL g_return_if_fail (MODEST_IS_RECPT_EDITOR (recpt_editor)); priv = MODEST_RECPT_EDITOR_GET_PRIVATE (recpt_editor); -#ifdef MODEST_TOOLKIT_HILDON2 - buffer = hildon_text_view_get_buffer (HILDON_TEXT_VIEW (priv->text_view)); -#else - buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->text_view)); -#endif + buffer = modest_text_view_get_buffer (priv->text_view); g_signal_handlers_block_by_func (buffer, modest_recpt_editor_on_insert_text, recpt_editor); g_signal_handlers_block_by_func (buffer, modest_recpt_editor_on_insert_text_after, recpt_editor); @@ -296,11 +281,7 @@ modest_recpt_editor_replace_with_resolved_recipients (ModestRecptEditor *recpt_e g_return_if_fail (MODEST_IS_RECPT_EDITOR (recpt_editor)); priv = MODEST_RECPT_EDITOR_GET_PRIVATE (recpt_editor); -#ifdef MODEST_TOOLKIT_HILDON2 - buffer = hildon_text_view_get_buffer (HILDON_TEXT_VIEW (priv->text_view)); -#else - buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->text_view)); -#endif + buffer = modest_text_view_get_buffer (priv->text_view); g_signal_handlers_block_by_func (buffer, modest_recpt_editor_on_insert_text, recpt_editor); g_signal_handlers_block_by_func (buffer, modest_recpt_editor_on_insert_text_after, recpt_editor); @@ -362,11 +343,7 @@ modest_recpt_editor_get_recipients (ModestRecptEditor *recpt_editor) priv->recipients = NULL; } -#ifdef MODEST_TOOKIT_HILDON2 - buffer = hildon_text_view_get_buffer (HILDON_TEXT_VIEW (priv->text_view)); -#else - buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->text_view)); -#endif + buffer = modest_text_view_get_buffer (priv->text_view); gtk_text_buffer_get_start_iter (buffer, &start); gtk_text_buffer_get_end_iter (buffer, &end); @@ -406,11 +383,7 @@ modest_recpt_editor_instance_init (GTypeInstance *instance, gpointer g_class) #endif gtk_container_add (GTK_CONTAINER (priv->abook_button), abook_icon); -#ifdef MODEST_TOOLKIT_HILDON2 - priv->text_view = hildon_text_view_new (); -#else - priv->text_view = gtk_text_view_new (); -#endif + priv->text_view = modest_toolkit_factory_create_text_view (modest_runtime_get_toolkit_factory ()); /* Auto-capitalization is the default, so let's turn it off: */ #ifdef MAEMO_CHANGES hildon_gtk_text_view_set_input_mode (GTK_TEXT_VIEW (priv->text_view), @@ -446,11 +419,7 @@ modest_recpt_editor_instance_init (GTypeInstance *instance, gpointer g_class) gtk_widget_set_size_request (priv->text_view, 75, -1); -#ifdef MODEST_TOOLKIT_HILDON2 - buffer = hildon_text_view_get_buffer (HILDON_TEXT_VIEW (priv->text_view)); -#else - buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->text_view)); -#endif + buffer = modest_text_view_get_buffer (priv->text_view); g_signal_connect (G_OBJECT (priv->abook_button), "clicked", G_CALLBACK (modest_recpt_editor_on_abook_clicked), instance); g_signal_connect (G_OBJECT (priv->text_view), "key-press-event", G_CALLBACK (modest_recpt_editor_on_key_press_event), instance); g_signal_connect (G_OBJECT (priv->text_view), "focus-in-event", G_CALLBACK (modest_recpt_editor_on_focus_in), instance); @@ -492,11 +461,7 @@ modest_recpt_editor_get_buffer (ModestRecptEditor *recpt_editor) g_return_val_if_fail (MODEST_IS_RECPT_EDITOR (recpt_editor), NULL); priv = MODEST_RECPT_EDITOR_GET_PRIVATE (recpt_editor); -#ifdef MODEST_TOOLKIT_HILDON2 - return hildon_text_view_get_buffer (HILDON_TEXT_VIEW (priv->text_view)); -#else - return gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->text_view)); -#endif + return modest_text_view_get_buffer (priv->text_view); } static void @@ -514,42 +479,60 @@ modest_recpt_editor_on_mark_set (GtkTextBuffer *buffer, ModestRecptEditor *recpt_editor) { ModestRecptEditorPrivate *priv; - GtkTextIter start, end; + GtkTextIter insert_iter, selection_iter; GtkTextMark *selection_bound; + GtkTextMark *insert; GtkTextTag *tag; gboolean selection_changed = FALSE; + gboolean select_to_left; priv = MODEST_RECPT_EDITOR_GET_PRIVATE (recpt_editor); buffer = modest_recpt_editor_get_buffer (recpt_editor); selection_bound = gtk_text_buffer_get_selection_bound (buffer); + insert = gtk_text_buffer_get_insert (buffer); - if (mark != selection_bound) + if (mark != selection_bound && mark != insert) return; - gtk_text_buffer_get_selection_bounds (buffer, &start, &end); + gtk_text_buffer_get_iter_at_mark (buffer, &insert_iter, insert); + gtk_text_buffer_get_iter_at_mark (buffer, &selection_iter, selection_bound); + + select_to_left = gtk_text_iter_get_offset (&selection_iter) > gtk_text_iter_get_offset (&insert_iter); - tag = iter_has_recipient (&start); - if (tag != NULL) - if (!gtk_text_iter_begins_tag (&start, tag)) { - gtk_text_iter_backward_to_tag_toggle (&start, tag); + tag = iter_has_recipient (&insert_iter); + if (tag) { + if (select_to_left) { + if (!gtk_text_iter_begins_tag (&insert_iter, tag)) { + gtk_text_iter_backward_to_tag_toggle (&insert_iter, tag); + selection_changed = TRUE; + } + } else { + gtk_text_iter_forward_to_tag_toggle (&insert_iter, tag); selection_changed = TRUE; } - - tag = iter_has_recipient (&end); - if (tag != NULL) - if (!gtk_text_iter_ends_tag (&end, tag)) { - gtk_text_iter_forward_to_tag_toggle (&end, tag); + } + + tag = iter_has_recipient (&selection_iter); + if (tag != NULL) { + if (select_to_left) { + gtk_text_iter_forward_to_tag_toggle (&selection_iter, tag); selection_changed = TRUE; + } else { + if (!gtk_text_iter_begins_tag (&selection_iter, tag)) { + gtk_text_iter_backward_to_tag_toggle (&selection_iter, tag); + selection_changed = TRUE; + } } - + } + if (selection_changed) { /* We block this signal handler in order to prevent a stack overflow caused by recursive calls to this handler as the select_range call could issue a "mark-set" signal */ g_signal_handler_block (buffer, priv->on_mark_set_handler); - gtk_text_buffer_select_range (buffer, &start, &end); + gtk_text_buffer_select_range (buffer, &insert_iter, &selection_iter); g_signal_handler_unblock (buffer, priv->on_mark_set_handler); } } @@ -778,17 +761,40 @@ iter_previous_char (GtkTextIter *iter) /* } */ static void -select_tag_of_iter (GtkTextIter *iter, GtkTextTag *tag) +select_tag_of_iter (GtkTextIter *iter, GtkTextTag *tag, gboolean grow, gboolean left_not_right) { GtkTextIter start, end; start = *iter; - if (!gtk_text_iter_begins_tag (&start, tag)) + if (!gtk_text_iter_begins_tag (&start, tag)) { gtk_text_iter_backward_to_tag_toggle (&start, tag); + } else { + if (!left_not_right) { + gtk_text_buffer_select_range (gtk_text_iter_get_buffer (iter), &start, &start); + return; + } + } end = *iter; - if (!gtk_text_iter_ends_tag (&end, tag)) + if (!gtk_text_iter_ends_tag (&end, tag)) { gtk_text_iter_forward_to_tag_toggle (&end, tag); - gtk_text_buffer_select_range (gtk_text_iter_get_buffer (iter), &start, &end); + } else { + if (left_not_right) { + gtk_text_buffer_select_range (gtk_text_iter_get_buffer (iter), &end, &end); + return; + } + } + if (grow) { + if (left_not_right) + gtk_text_buffer_select_range (gtk_text_iter_get_buffer (iter), &start, &end); + else + gtk_text_buffer_select_range (gtk_text_iter_get_buffer (iter), &end, &start); + } else { + if (left_not_right) + gtk_text_buffer_select_range (gtk_text_iter_get_buffer (iter), &start, &start); + else + gtk_text_buffer_select_range (gtk_text_iter_get_buffer (iter), &end, &end); + } + *iter = left_not_right?start:end; } static gboolean @@ -826,12 +832,11 @@ modest_recpt_editor_on_key_press_event (GtkTextView *text_view, GtkTextBuffer * buffer; GtkTextIter location, selection_loc; GtkTextTag *tag; + gboolean shift_pressed; + gboolean select_to_left; + gboolean has_selection; -#ifdef MODEST_TOOLKIT_HILDON2 - buffer = hildon_text_view_get_buffer (HILDON_TEXT_VIEW (text_view)); -#else - buffer = gtk_text_view_get_buffer (text_view); -#endif + buffer = modest_text_view_get_buffer (text_view); insert = gtk_text_buffer_get_insert (buffer); selection = gtk_text_buffer_get_selection_bound (buffer); @@ -857,33 +862,67 @@ modest_recpt_editor_on_key_press_event (GtkTextView *text_view, gtk_text_buffer_get_iter_at_mark (buffer, &location, insert); gtk_text_buffer_get_iter_at_mark (buffer, &selection_loc, selection); + select_to_left = gtk_text_iter_get_offset (&selection_loc) > gtk_text_iter_get_offset (&location); + has_selection = gtk_text_iter_get_offset (&selection_loc) != gtk_text_iter_get_offset (&location); + shift_pressed = key->state & GDK_SHIFT_MASK; + switch (key->keyval) { case GDK_Left: case GDK_KP_Left: { gboolean cursor_ready = FALSE; + GtkTextIter prev_location; + gboolean moved = TRUE; + + prev_location = location; while (!cursor_ready) { - if (iter_previous_char (&location) == '\n') { - gtk_text_iter_backward_char (&location); + if (moved && (iter_previous_char (&location) == '\n')) { + moved = gtk_text_iter_backward_char (&location); } else { cursor_ready = TRUE; } } tag = iter_has_recipient (&location); + if (has_selection && gtk_text_iter_ends_tag (&prev_location, tag)) { + gtk_text_iter_backward_to_tag_toggle (&prev_location, tag); + location = prev_location; + cursor_ready = FALSE; + moved = TRUE; + while (moved && !cursor_ready) { + if (iter_previous_char (&location) == '\n') { + moved = gtk_text_iter_backward_char (&location); + } else { + cursor_ready = TRUE; + } + } + } + if ((tag != NULL)&& (gtk_text_iter_is_start (&location) || !(gtk_text_iter_begins_tag (&location, tag)))) { - select_tag_of_iter (&location, tag); + if (has_selection) { + gtk_text_buffer_select_range (buffer, &location, &location); + } else { + select_tag_of_iter (&location, tag, select_to_left, TRUE); + } gtk_text_view_scroll_to_mark (GTK_TEXT_VIEW (text_view), insert, 0.0, FALSE, 0.0, 1.0); + + if (shift_pressed) { + gtk_text_buffer_select_range (buffer, &location, &selection_loc); + } return TRUE; } gtk_text_iter_backward_char (&location); tag = iter_has_recipient (&location); if (tag != NULL) - select_tag_of_iter (&location, tag); + select_tag_of_iter (&location, tag, select_to_left, TRUE); else { gtk_text_buffer_place_cursor (buffer, &location); } gtk_text_view_scroll_to_mark (GTK_TEXT_VIEW (text_view), insert, 0.0, FALSE, 0.0, 1.0); + if (shift_pressed) { + gtk_text_buffer_select_range (buffer, &location, &selection_loc); + } + return TRUE; } break; @@ -891,34 +930,47 @@ modest_recpt_editor_on_key_press_event (GtkTextView *text_view, case GDK_KP_Right: { gboolean cursor_moved = FALSE; + gboolean moved = TRUE; tag = iter_has_recipient (&location); if ((tag != NULL)&&(!gtk_text_iter_ends_tag (&location, tag))) { gtk_text_iter_forward_to_tag_toggle (&location, tag); - while (gtk_text_iter_get_char (&location) == '\n') - gtk_text_iter_forward_char (&location); + moved = TRUE; + while (moved && (gtk_text_iter_get_char (&location) == '\n')) + moved = gtk_text_iter_forward_char (&location); gtk_text_buffer_place_cursor (buffer, &location); gtk_text_view_scroll_to_mark (GTK_TEXT_VIEW (text_view), insert, 0.0, FALSE, 0.0, 1.0); + + if (shift_pressed) { + gtk_text_buffer_select_range (buffer, &location, &selection_loc); + } return TRUE; } - while (gtk_text_iter_get_char (&location) == '\n') { - gtk_text_iter_forward_char (&location); + moved = TRUE; + while (moved && (gtk_text_iter_get_char (&location) == '\n')) { + moved = gtk_text_iter_forward_char (&location); cursor_moved = TRUE; } if (!cursor_moved) gtk_text_iter_forward_char (&location); - while (gtk_text_iter_get_char (&location) == '\n') { - gtk_text_iter_forward_char (&location); + + moved = TRUE; + while (moved && (gtk_text_iter_get_char (&location) == '\n')) { + moved = gtk_text_iter_forward_char (&location); cursor_moved = TRUE; } tag = iter_has_recipient (&location); if (tag != NULL) - select_tag_of_iter (&location, tag); + select_tag_of_iter (&location, tag, !select_to_left, FALSE); else gtk_text_buffer_place_cursor (buffer, &location); gtk_text_view_scroll_to_mark (GTK_TEXT_VIEW (text_view), insert, 0.0, FALSE, 0.0, 1.0); + + if (shift_pressed) { + gtk_text_buffer_select_range (buffer, &location, &selection_loc); + } return TRUE; } break; @@ -974,7 +1026,7 @@ modest_recpt_editor_on_key_press_event (GtkTextView *text_view, GtkTextIter iter_in_tag; iter_in_tag = location; gtk_text_iter_backward_char (&iter_in_tag); - select_tag_of_iter (&iter_in_tag, tag); + select_tag_of_iter (&iter_in_tag, tag, FALSE, TRUE); gtk_text_buffer_delete_selection (buffer, TRUE, TRUE); return TRUE; } @@ -986,6 +1038,21 @@ modest_recpt_editor_on_key_press_event (GtkTextView *text_view, } } +static void _discard_chars (GtkTextIter *start, GtkTextIter *end) +{ + while (!gtk_text_iter_equal (start, end)) { + gunichar c = gtk_text_iter_get_char (start); + + if (c == '\n' || c == ';' || c == ',' || c == ' ') { + if (!gtk_text_iter_forward_char (start)) + break; + } else { + break; + } + + } +} + /* NOTE: before calling this function be sure that both modest_recpt_editor_on_insert_text and modest_recpt_editor_on_insert_text_after won't be triggered during @@ -998,11 +1065,7 @@ modest_recpt_editor_add_tags (ModestRecptEditor *editor, { ModestRecptEditorPrivate *priv = MODEST_RECPT_EDITOR_GET_PRIVATE (editor); -#ifdef MODEST_TOOLKIT_HILDON2 - GtkTextBuffer *buffer = hildon_text_view_get_buffer (HILDON_TEXT_VIEW (priv->text_view)); -#else - GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->text_view)); -#endif + GtkTextBuffer *buffer = modest_text_view_get_buffer (priv->text_view); GtkTextTag *tag; GtkTextIter start, end; gchar * buffer_contents; @@ -1024,6 +1087,7 @@ modest_recpt_editor_add_tags (ModestRecptEditor *editor, /* Formatting the buffer content by applying tag */ gtk_text_buffer_get_bounds (buffer, &start, &end); + _discard_chars (&start, &end); while (gtk_text_iter_forward_search(&start, ";", GTK_TEXT_SEARCH_TEXT_ONLY | GTK_TEXT_SEARCH_VISIBLE_ONLY, @@ -1033,6 +1097,7 @@ modest_recpt_editor_add_tags (ModestRecptEditor *editor, gtk_text_buffer_apply_tag(buffer, tag, &start, &start_match); offset = gtk_text_iter_get_offset (&end_match); gtk_text_buffer_get_iter_at_offset(buffer, &start, offset); + _discard_chars (&start, &end); } g_free (buffer_contents); }