--- gtk+-2.6.4/gtk/gtktextview.c 2005-03-01 08:28:56.000000000 +0200 +++ gtk+-2.6.4/gtk/gtktextview.c 2005-04-06 16:19:38.152738264 +0300 @@ -99,6 +99,11 @@ #define SPACE_FOR_CURSOR 1 +typedef struct _GtkTextViewPrivate GtkTextViewPrivate; + +#define GTK_TEXT_VIEW_GET_PRIVATE(obj) ( G_TYPE_INSTANCE_GET_PRIVATE ((obj),\ + GTK_TYPE_TEXT_VIEW, GtkTextViewPrivate) ) + struct _GtkTextPendingScroll { GtkTextMark *mark; @@ -145,6 +150,8 @@ PROP_BUFFER, PROP_OVERWRITE, PROP_ACCEPTS_TAB, + PROP_AUTOCAP, + PROP_INPUT_MODE, LAST_PROP }; @@ -343,6 +350,13 @@ static void gtk_text_view_update_im_spot_location (GtkTextView *text_view); +static void gtk_text_view_set_autocap (GtkTextView *text_view, + gboolean autocap); +static gboolean gtk_text_view_get_autocap (GtkTextView *text_view); +static void gtk_text_view_set_input_mode (GtkTextView *text_view, + gint mode); +static gint gtk_text_view_get_input_mode (GtkTextView *text_view); + /* Container methods */ static void gtk_text_view_add (GtkContainer *container, GtkWidget *child); @@ -412,6 +426,10 @@ static gint text_window_get_width (GtkTextWindow *win); static gint text_window_get_height (GtkTextWindow *win); +struct _GtkTextViewPrivate +{ + guint release_selection : 1; +}; static const GtkTargetEntry target_table[] = { { "GTK_TEXT_BUFFER_CONTENTS", GTK_TARGET_SAME_APP, 0 }, @@ -481,6 +499,7 @@ parent_class = g_type_class_peek_parent (klass); + g_type_class_add_private( klass, sizeof(GtkTextViewPrivate) ); /* Default handlers and virtual methods */ gobject_class->set_property = gtk_text_view_set_property; @@ -667,6 +686,24 @@ TRUE, G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, + PROP_AUTOCAP, + g_param_spec_boolean ("autocap", + P_("auto capitalization"), + P_("Enable autocap support"), + TRUE, + G_PARAM_READABLE | G_PARAM_WRITABLE)); + + g_object_class_install_property (gobject_class, + PROP_INPUT_MODE, + g_param_spec_int ("input_mode", + P_("input mode"), + P_("Define widget's input mode"), + 0, + 9, /* keep me updated */ + 0, + G_PARAM_READABLE | G_PARAM_WRITABLE)); + /* * Style properties */ @@ -676,6 +713,14 @@ P_("Color with which to draw error-indication underlines"), GDK_TYPE_COLOR, G_PARAM_READABLE)); + + gtk_widget_class_install_style_property (widget_class, + g_param_spec_boolean ("autocap", + _("auto capitalization"), + _("Enable autocap support"), + TRUE, + G_PARAM_READABLE)); + /* * Signals @@ -1040,8 +1085,9 @@ gtk_text_view_init (GtkTextView *text_view) { GtkWidget *widget; - + GtkTextViewPrivate *priv = NULL; widget = GTK_WIDGET (text_view); + priv = GTK_TEXT_VIEW_GET_PRIVATE(text_view); GTK_WIDGET_SET_FLAGS (widget, GTK_CAN_FOCUS); @@ -1057,6 +1103,8 @@ text_view->tabs = NULL; text_view->editable = TRUE; + priv->release_selection = TRUE; + gtk_drag_dest_set (widget, 0, target_table, G_N_ELEMENTS (target_table), @@ -1070,6 +1118,10 @@ * to it; so we create it here and destroy it in finalize (). */ text_view->im_context = gtk_im_multicontext_new (); + /* Set default stuff. */ + gtk_text_view_set_autocap (text_view, TRUE); + gtk_text_view_set_input_mode (text_view, 0); /* alpha-numeric-special */ + g_object_set (G_OBJECT (text_view->im_context), "use-show-hide", TRUE, NULL); g_signal_connect (text_view->im_context, "commit", G_CALLBACK (gtk_text_view_commit_handler), text_view); @@ -2664,6 +2716,14 @@ gtk_text_view_set_accepts_tab (text_view, g_value_get_boolean (value)); break; + case PROP_AUTOCAP: + gtk_text_view_set_autocap (text_view, g_value_get_boolean (value)); + break; + + case PROP_INPUT_MODE: + gtk_text_view_set_input_mode (text_view, g_value_get_int (value)); + break; + default: g_assert_not_reached (); break; @@ -2738,6 +2798,14 @@ g_value_set_boolean (value, text_view->accepts_tab); break; + case PROP_AUTOCAP: + g_value_set_boolean (value, gtk_text_view_get_autocap (text_view)); + break; + + case PROP_INPUT_MODE: + g_value_set_int (value, gtk_text_view_get_input_mode (text_view)); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -3916,7 +3984,7 @@ GtkTextView *text_view = GTK_TEXT_VIEW (widget); GtkTextMark *insert; GtkTextIter iter; - + if (text_view->layout == NULL || get_buffer (text_view) == NULL) return FALSE; @@ -4039,6 +4107,9 @@ if (event->window != text_view->text_window->bin_window) return FALSE; + if (text_view->editable) + gtk_im_context_show (text_view->im_context); + if (event->button == 1) { if (text_view->drag_start_x >= 0) @@ -4083,7 +4154,15 @@ static gint gtk_text_view_focus_in_event (GtkWidget *widget, GdkEventFocus *event) { + /*gboolean have_selection; + GtkTextIter sel_start, sel_end;*/ + GtkTextView *text_view = GTK_TEXT_VIEW (widget); + + /*have_selection = gtk_text_buffer_get_selection_bounds(text_view->buffer, &sel_start, &sel_end); + + if(!have_selection) + gtk_text_view_move_cursor(text_view, GTK_MOVEMENT_BUFFER_ENDS, 1, FALSE);*//*FIXME some other way to place the cursor in the end*/ gtk_widget_queue_draw (widget); @@ -4100,8 +4179,10 @@ G_CALLBACK (keymap_direction_changed), text_view); gtk_text_view_check_keymap_direction (text_view); + /* Keyboard hack */ text_view->need_im_reset = TRUE; gtk_im_context_focus_in (GTK_TEXT_VIEW (widget)->im_context); + gtk_text_view_reset_im_context (text_view); return FALSE; } @@ -4110,6 +4191,14 @@ gtk_text_view_focus_out_event (GtkWidget *widget, GdkEventFocus *event) { GtkTextView *text_view = GTK_TEXT_VIEW (widget); + GtkTextViewPrivate *priv = GTK_TEXT_VIEW_GET_PRIVATE(text_view); + /*{ + GtkTextIter start; + GtkTextIter end; + + gtk_text_buffer_get_bounds(text_view->buffer, &start, &end); + gtk_text_buffer_select_range(text_view->buffer, &start, &start); + }*//*FIXME need a hack here to take away the focus*/ gtk_widget_queue_draw (widget); @@ -4125,8 +4214,11 @@ keymap_direction_changed, text_view); - text_view->need_im_reset = TRUE; - gtk_im_context_focus_out (GTK_TEXT_VIEW (widget)->im_context); + /* This is commented out to disable unselect feature. + When the decition of this has been made, we can either remove this patch + or to leave it. + if( priv->release_selection ) + gtk_text_view_unselect( text_view );*/ return FALSE; } @@ -5082,7 +5174,8 @@ GtkTextIter end; gboolean leave_one = FALSE; - gtk_text_view_reset_im_context (text_view); + /*gtk_text_view_reset_im_context (text_view);*/ /*backspace should not clear + the word completion*/ if (type == GTK_DELETE_CHARS) { @@ -5200,7 +5293,8 @@ { GtkTextIter insert; - gtk_text_view_reset_im_context (text_view); + /*gtk_text_view_reset_im_context (text_view);*/ /*backspace should not clear + the word completion*/ /* Backspace deletes the selection, if one exists */ if (gtk_text_buffer_delete_selection (get_buffer (text_view), TRUE, @@ -5928,11 +6022,11 @@ static void gtk_text_view_reset_im_context (GtkTextView *text_view) { - if (text_view->need_im_reset) +/* if (text_view->need_im_reset) { - text_view->need_im_reset = FALSE; + text_view->need_im_reset = FALSE;*/ gtk_im_context_reset (text_view->im_context); - } +/* }*/ } /* @@ -6665,18 +6759,23 @@ { GtkTextIter start; GtkTextIter end; - gint pos; + gint pos, endpos; gchar *text; - gtk_text_buffer_get_iter_at_mark (text_view->buffer, &start, + gtk_text_buffer_get_iter_at_line (text_view->buffer, &start, 0); + gtk_text_buffer_get_iter_at_mark (text_view->buffer, &end, gtk_text_buffer_get_insert (text_view->buffer)); - end = start; - pos = gtk_text_iter_get_line_index (&start); - gtk_text_iter_set_line_offset (&start, 0); + pos = gtk_text_iter_get_line_index (&end); + gtk_text_iter_forward_to_line_end (&end); + endpos = gtk_text_iter_get_line_index (&end); text = gtk_text_iter_get_slice (&start, &end); + if (text) + pos = strlen (text) - (endpos - pos); /* want bytes, not characters */ + else + pos = 0; gtk_im_context_set_surrounding (context, text, -1, pos); g_free (text); @@ -6726,8 +6825,8 @@ need_reset = TRUE; } - if (need_reset) - gtk_text_view_reset_im_context (text_view); + /*if (need_reset) + gtk_text_view_reset_im_context (text_view);*//*FIXME need a hack here*/ } static void @@ -6957,6 +7056,13 @@ } static void +block_selection_change( GtkMenuShell *menushell, gpointer user_data ) +{ + GtkTextViewPrivate *priv = GTK_TEXT_VIEW_GET_PRIVATE(user_data); + priv->release_selection = TRUE; +} + +static void unichar_chosen_func (const char *text, gpointer data) { @@ -7064,7 +7170,12 @@ signals[POPULATE_POPUP], 0, text_view->popup_menu); - + { + GtkTextViewPrivate *priv = GTK_TEXT_VIEW_GET_PRIVATE(text_view); + g_signal_connect( GTK_WIDGET(text_view->popup_menu), "selection-done", + G_CALLBACK(block_selection_change), text_view ); + priv->release_selection = FALSE; + } if (info->button) gtk_menu_popup (GTK_MENU (text_view->popup_menu), NULL, NULL, NULL, NULL, @@ -8301,3 +8412,81 @@ return gtk_text_layout_move_iter_visually (text_view->layout, iter, count); } + +/* + * gtk_text_view_set_autocap: + * @entry: a #GtkTextView + * @autocap: autocap + * + * Sets autocapitalization of the widget. + */ +static void +gtk_text_view_set_autocap (GtkTextView *text_view, + gboolean autocap) +{ + g_return_if_fail (GTK_IS_TEXT_VIEW (text_view)); + + if (gtk_text_view_get_autocap (text_view) != autocap) + { + g_object_set (G_OBJECT (text_view->im_context), "autocap", autocap, NULL); + g_object_notify (G_OBJECT (text_view), "autocap"); + } +} + +/* + * gtk_text_view_get_autocap: + * @entry: a #GtkTextView + * + * Gets autocapitalization state of the widget. + * + * Return value: a state + */ +static gboolean +gtk_text_view_get_autocap (GtkTextView *text_view) +{ + gboolean autocap; + g_return_val_if_fail (GTK_IS_TEXT_VIEW (text_view), FALSE); + + g_object_get (G_OBJECT (text_view->im_context), "autocap", &autocap, NULL); + + return autocap; +} + +/* + * gtk_text_view_set_input_mode: + * @text_view: a #GtkTextView + * @mode: input mode + * + * Sets autocapitalization of the widget. + */ +static void +gtk_text_view_set_input_mode (GtkTextView *text_view, + gint mode) +{ + g_return_if_fail (GTK_IS_TEXT_VIEW (text_view)); + + if (gtk_text_view_get_input_mode (text_view) != mode) + { + g_object_set (G_OBJECT (text_view->im_context), "input_mode", mode, NULL); + g_object_notify (G_OBJECT (text_view), "input_mode"); + } +} + +/* + * gtk_text_view_get_input_mode: + * @text_view: a #GtkTextView + * + * Gets input mode of the widget. + * + * Return value: input mode + */ +static gint +gtk_text_view_get_input_mode (GtkTextView *text_view) +{ + gint mode; + g_return_val_if_fail (GTK_IS_TEXT_VIEW (text_view), FALSE); + + g_object_get (G_OBJECT (text_view->im_context), "input_mode", &mode, NULL); + + return mode; +}