X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=gtk%2Fgtktextview.c;h=47e26bea2f277998f5e79522f504a3a1f243460f;hb=f91c04e2846de010871ee21389eb926dd18e065e;hp=a41a2479bc91d233407745e2c99e18a025a8cec5;hpb=2cc059a0e7ee382606351355780b53ae6a7229d9;p=~andy%2Fgtk diff --git a/gtk/gtktextview.c b/gtk/gtktextview.c index a41a2479b..47e26bea2 100644 --- a/gtk/gtktextview.c +++ b/gtk/gtktextview.c @@ -26,6 +26,7 @@ */ #include "config.h" + #include #define GTK_TEXT_USE_INTERNAL_UNSUPPORTED_API @@ -39,16 +40,30 @@ #include "gtkmenuitem.h" #include "gtkseparatormenuitem.h" #include "gtksettings.h" +#include "gtkselectionprivate.h" #include "gtkstock.h" #include "gtktextbufferrichtext.h" #include "gtktextdisplay.h" #include "gtktextview.h" #include "gtkimmulticontext.h" -#include "gdk/gdkkeysyms.h" #include "gtkprivate.h" #include "gtktextutil.h" #include "gtkwidgetprivate.h" #include "gtkwindow.h" +#include "gtkscrollable.h" +#include "gtktypebuiltins.h" + + +/** + * SECTION:gtktextview + * @Short_description: Widget that displays a GtkTextBuffer + * @Title: GtkTextView + * @See_also: #GtkTextBuffer, #GtkTextIter + * + * You may wish to begin by reading the text widget + * conceptual overview which gives an overview of all the objects and data + * types related to the text widget and how they work together. + */ /* How scrolling, validation, exposes, etc. work. @@ -117,7 +132,7 @@ struct _GtkTextViewPrivate GdkDevice *grab_device; GdkDevice *dnd_device; - guint selection_drag_handler; + gulong selection_drag_handler; guint scroll_timeout; GtkTextWindow *text_window; @@ -209,6 +224,11 @@ struct _GtkTextViewPrivate guint mouse_cursor_obscured : 1; guint scroll_after_paste : 1; + + /* GtkScrollablePolicy needs to be checked when + * driving the scrollable adjustment values */ + guint hscroll_policy : 1; + guint vscroll_policy : 1; }; struct _GtkTextPendingScroll @@ -222,7 +242,6 @@ struct _GtkTextPendingScroll enum { - SET_SCROLL_ADJUSTMENTS, POPULATE_POPUP, MOVE_CURSOR, PAGE_HORIZONTALLY, @@ -258,7 +277,11 @@ enum PROP_BUFFER, PROP_OVERWRITE, PROP_ACCEPTS_TAB, - PROP_IM_MODULE + PROP_IM_MODULE, + PROP_HADJUSTMENT, + PROP_VADJUSTMENT, + PROP_HSCROLL_POLICY, + PROP_VSCROLL_POLICY }; static void gtk_text_view_finalize (GObject *object); @@ -273,18 +296,23 @@ static void gtk_text_view_get_property (GObject *object, static void gtk_text_view_destroy (GtkWidget *widget); static void gtk_text_view_size_request (GtkWidget *widget, GtkRequisition *requisition); +static void gtk_text_view_get_preferred_width (GtkWidget *widget, + gint *minimum, + gint *natural); +static void gtk_text_view_get_preferred_height (GtkWidget *widget, + gint *minimum, + gint *natural); static void gtk_text_view_size_allocate (GtkWidget *widget, GtkAllocation *allocation); static void gtk_text_view_realize (GtkWidget *widget); static void gtk_text_view_unrealize (GtkWidget *widget); -static void gtk_text_view_style_set (GtkWidget *widget, - GtkStyle *previous_style); +static void gtk_text_view_style_updated (GtkWidget *widget); static void gtk_text_view_direction_changed (GtkWidget *widget, GtkTextDirection previous_direction); static void gtk_text_view_grab_notify (GtkWidget *widget, gboolean was_grabbed); -static void gtk_text_view_state_changed (GtkWidget *widget, - GtkStateType previous_state); +static void gtk_text_view_state_flags_changed (GtkWidget *widget, + GtkStateFlags previous_state); static gint gtk_text_view_event (GtkWidget *widget, GdkEvent *event); @@ -308,8 +336,6 @@ static void gtk_text_view_draw_focus (GtkWidget *widget, cairo_t *cr); static gboolean gtk_text_view_focus (GtkWidget *widget, GtkDirectionType direction); -static void gtk_text_view_move_focus (GtkWidget *widget, - GtkDirectionType direction_type); static void gtk_text_view_select_all (GtkWidget *widget, gboolean select); @@ -349,16 +375,13 @@ static void gtk_text_view_drag_data_received (GtkWidget *widget, guint info, guint time); -static void gtk_text_view_set_scroll_adjustments (GtkTextView *text_view, - GtkAdjustment *hadj, - GtkAdjustment *vadj); static gboolean gtk_text_view_popup_menu (GtkWidget *widget); static void gtk_text_view_move_cursor (GtkTextView *text_view, GtkMovementStep step, gint count, gboolean extend_selection); -static gboolean gtk_text_view_move_viewport (GtkTextView *text_view, +static void gtk_text_view_move_viewport (GtkTextView *text_view, GtkScrollStep step, gint count); static void gtk_text_view_set_anchor (GtkTextView *text_view); @@ -379,8 +402,7 @@ static void gtk_text_view_copy_clipboard (GtkTextView *text_view); static void gtk_text_view_paste_clipboard (GtkTextView *text_view); static void gtk_text_view_toggle_overwrite (GtkTextView *text_view); static void gtk_text_view_toggle_cursor_visible (GtkTextView *text_view); -static void gtk_text_view_compat_move_focus(GtkTextView *text_view, - GtkDirectionType direction_type); + static void gtk_text_view_unselect (GtkTextView *text_view); static void gtk_text_view_validate_onscreen (GtkTextView *text_view); @@ -388,8 +410,7 @@ static void gtk_text_view_get_first_para_iter (GtkTextView *text_vi GtkTextIter *iter); static void gtk_text_view_update_layout_width (GtkTextView *text_view); static void gtk_text_view_set_attributes_from_style (GtkTextView *text_view, - GtkTextAttributes *values, - GtkStyle *style); + GtkTextAttributes *values); static void gtk_text_view_ensure_layout (GtkTextView *text_view); static void gtk_text_view_destroy_layout (GtkTextView *text_view); static void gtk_text_view_check_keymap_direction (GtkTextView *text_view); @@ -405,7 +426,7 @@ static void gtk_text_view_pend_cursor_blink (GtkTextView *text_v static void gtk_text_view_stop_cursor_blink (GtkTextView *text_view); static void gtk_text_view_reset_blink_time (GtkTextView *text_view); -static void gtk_text_view_value_changed (GtkAdjustment *adj, +static void gtk_text_view_value_changed (GtkAdjustment *adjustment, GtkTextView *view); static void gtk_text_view_commit_handler (GtkIMContext *context, const gchar *str, @@ -431,8 +452,6 @@ static void gtk_text_view_target_list_notify (GtkTextBuffer *buffer, static void gtk_text_view_paste_done_handler (GtkTextBuffer *buffer, GtkClipboard *clipboard, gpointer data); -static void gtk_text_view_get_cursor_location (GtkTextView *text_view, - GdkRectangle *pos); static void gtk_text_view_get_virtual_cursor_pos (GtkTextView *text_view, GtkTextIter *cursor, gint *x, @@ -441,9 +460,6 @@ static void gtk_text_view_set_virtual_cursor_pos (GtkTextView *text_view, gint x, gint y); -static GtkAdjustment* get_hadjustment (GtkTextView *text_view); -static GtkAdjustment* get_vadjustment (GtkTextView *text_view); - static void gtk_text_view_do_popup (GtkTextView *text_view, GdkEventButton *event); @@ -460,6 +476,13 @@ static void gtk_text_view_update_adjustments (GtkTextView *text_view); static void gtk_text_view_invalidate (GtkTextView *text_view); static void gtk_text_view_flush_first_validate (GtkTextView *text_view); +static void gtk_text_view_set_hadjustment (GtkTextView *text_view, + GtkAdjustment *adjustment); +static void gtk_text_view_set_vadjustment (GtkTextView *text_view, + GtkAdjustment *adjustment); +static void gtk_text_view_set_hadjustment_values (GtkTextView *text_view); +static void gtk_text_view_set_vadjustment_values (GtkTextView *text_view); + static void gtk_text_view_update_im_spot_location (GtkTextView *text_view); /* Container methods */ @@ -535,7 +558,8 @@ static gint text_window_get_height (GtkTextWindow *win); static guint signals[LAST_SIGNAL] = { 0 }; -G_DEFINE_TYPE (GtkTextView, gtk_text_view, GTK_TYPE_CONTAINER) +G_DEFINE_TYPE_WITH_CODE (GtkTextView, gtk_text_view, GTK_TYPE_CONTAINER, + G_IMPLEMENT_INTERFACE (GTK_TYPE_SCROLLABLE, NULL)) static void add_move_binding (GtkBindingSet *binding_set, @@ -577,11 +601,12 @@ gtk_text_view_class_init (GtkTextViewClass *klass) widget_class->destroy = gtk_text_view_destroy; widget_class->realize = gtk_text_view_realize; widget_class->unrealize = gtk_text_view_unrealize; - widget_class->style_set = gtk_text_view_style_set; + widget_class->style_updated = gtk_text_view_style_updated; widget_class->direction_changed = gtk_text_view_direction_changed; widget_class->grab_notify = gtk_text_view_grab_notify; - widget_class->state_changed = gtk_text_view_state_changed; - widget_class->size_request = gtk_text_view_size_request; + widget_class->state_flags_changed = gtk_text_view_state_flags_changed; + widget_class->get_preferred_width = gtk_text_view_get_preferred_width; + widget_class->get_preferred_height = gtk_text_view_get_preferred_height; widget_class->size_allocate = gtk_text_view_size_allocate; widget_class->event = gtk_text_view_event; widget_class->key_press_event = gtk_text_view_key_press_event; @@ -593,14 +618,6 @@ gtk_text_view_class_init (GtkTextViewClass *klass) widget_class->motion_notify_event = gtk_text_view_motion_event; widget_class->draw = gtk_text_view_draw; widget_class->focus = gtk_text_view_focus; - - /* need to override the base class function via override_class_handler, - * because the signal slot is not available in GtkWidgetCLass - */ - g_signal_override_class_handler ("move-focus", - GTK_TYPE_TEXT_VIEW, - G_CALLBACK (gtk_text_view_move_focus)); - widget_class->drag_begin = gtk_text_view_drag_begin; widget_class->drag_end = gtk_text_view_drag_end; widget_class->drag_data_get = gtk_text_view_drag_data_get; @@ -626,8 +643,6 @@ gtk_text_view_class_init (GtkTextViewClass *klass) klass->copy_clipboard = gtk_text_view_copy_clipboard; klass->paste_clipboard = gtk_text_view_paste_clipboard; klass->toggle_overwrite = gtk_text_view_toggle_overwrite; - klass->move_focus = gtk_text_view_compat_move_focus; - klass->set_scroll_adjustments = gtk_text_view_set_scroll_adjustments; /* * Properties @@ -779,6 +794,12 @@ gtk_text_view_class_init (GtkTextViewClass *klass) NULL, GTK_PARAM_READWRITE)); + /* GtkScrollable interface */ + g_object_class_override_property (gobject_class, PROP_HADJUSTMENT, "hadjustment"); + g_object_class_override_property (gobject_class, PROP_VADJUSTMENT, "vadjustment"); + g_object_class_override_property (gobject_class, PROP_HSCROLL_POLICY, "hscroll-policy"); + g_object_class_override_property (gobject_class, PROP_VSCROLL_POLICY, "vscroll-policy"); + /* * Style properties */ @@ -1032,27 +1053,6 @@ gtk_text_view_class_init (GtkTextViewClass *klass) _gtk_marshal_VOID__VOID, G_TYPE_NONE, 0); - /** - * GtkTextView::set-scroll-adjustments - * @horizontal: the horizontal #GtkAdjustment - * @vertical: the vertical #GtkAdjustment - * - * Set the scroll adjustments for the text view. Usually scrolled containers - * like #GtkScrolledWindow will emit this signal to connect two instances - * of #GtkScrollbar to the scroll directions of the #GtkTextView. - */ - signals[SET_SCROLL_ADJUSTMENTS] = - g_signal_new (I_("set-scroll-adjustments"), - G_OBJECT_CLASS_TYPE (gobject_class), - G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, - G_STRUCT_OFFSET (GtkTextViewClass, set_scroll_adjustments), - NULL, NULL, - _gtk_marshal_VOID__OBJECT_OBJECT, - G_TYPE_NONE, 2, - GTK_TYPE_ADJUSTMENT, - GTK_TYPE_ADJUSTMENT); - widget_class->set_scroll_adjustments_signal = signals[SET_SCROLL_ADJUSTMENTS]; - /** * GtkTextView::populate-popup: * @entry: The text view on which the signal is emitted @@ -1618,6 +1618,61 @@ gtk_text_view_get_buffer (GtkTextView *text_view) return get_buffer (text_view); } +/** + * gtk_text_view_get_cursor_locations: + * @text_view: a #GtkTextView + * @iter: (allow-none): a #GtkTextIter + * @strong: (out) (allow-none): location to store the strong + * cursor position (may be %NULL) + * @weak: (out) (allow-none): location to store the weak + * cursor position (may be %NULL) + * + * Given an @iter within a text layout, determine the positions of the + * strong and weak cursors if the insertion point is at that + * iterator. The position of each cursor is stored as a zero-width + * rectangle. The strong cursor location is the location where + * characters of the directionality equal to the base direction of the + * paragraph are inserted. The weak cursor location is the location + * where characters of the directionality opposite to the base + * direction of the paragraph are inserted. + * + * If @iter is %NULL, the actual cursor position is used. + * + * Note that if @iter happens to be the actual cursor position, and + * there is currently an IM preedit sequence being entered, the + * returned locations will be adjusted to account for the preedit + * cursor's offset within the preedit sequence. + * + * The rectangle position is in buffer coordinates; use + * gtk_text_view_buffer_to_window_coords() to convert these + * coordinates to coordinates for one of the windows in the text view. + * + * Since: 3.0 + **/ +void +gtk_text_view_get_cursor_locations (GtkTextView *text_view, + const GtkTextIter *iter, + GdkRectangle *strong, + GdkRectangle *weak) +{ + GtkTextIter insert; + + g_return_if_fail (GTK_IS_TEXT_VIEW (text_view)); + g_return_if_fail (iter == NULL || + gtk_text_iter_get_buffer (iter) == get_buffer (text_view)); + + gtk_text_view_ensure_layout (text_view); + + if (iter) + insert = *iter; + else + gtk_text_buffer_get_iter_at_mark (get_buffer (text_view), &insert, + gtk_text_buffer_get_insert (get_buffer (text_view))); + + gtk_text_layout_get_cursor_locations (text_view->priv->layout, &insert, + strong, weak); +} + /** * gtk_text_view_get_iter_at_location: * @text_view: a #GtkTextView @@ -1767,30 +1822,6 @@ gtk_text_view_get_line_at_y (GtkTextView *text_view, line_top); } -static gboolean -set_adjustment_clamped (GtkAdjustment *adj, gdouble val) -{ - DV (g_print (" Setting adj to raw value %g\n", val)); - - /* We don't really want to clamp to upper; we want to clamp to - upper - page_size which is the highest value the scrollbar - will let us reach. */ - if (val > (adj->upper - adj->page_size)) - val = adj->upper - adj->page_size; - - if (val < adj->lower) - val = adj->lower; - - if (val != adj->value) - { - DV (g_print (" Setting adj to clamped value %g\n", val)); - gtk_adjustment_set_value (adj, val); - return TRUE; - } - else - return FALSE; -} - /** * gtk_text_view_scroll_to_iter: * @text_view: a #GtkTextView @@ -1925,8 +1956,8 @@ gtk_text_view_scroll_to_iter (GtkTextView *text_view, if (scroll_inc != 0) { - retval = set_adjustment_clamped (get_vadjustment (text_view), - current_y_scroll + scroll_inc); + gtk_adjustment_set_value (text_view->priv->vadjustment, + current_y_scroll + scroll_inc); DV (g_print (" vert increment %d\n", scroll_inc)); } @@ -1962,12 +1993,15 @@ gtk_text_view_scroll_to_iter (GtkTextView *text_view, if (scroll_inc != 0) { - retval = set_adjustment_clamped (get_hadjustment (text_view), - current_x_scroll + scroll_inc); + gtk_adjustment_set_value (text_view->priv->hadjustment, + current_x_scroll + scroll_inc); DV (g_print (" horiz increment %d\n", scroll_inc)); } + retval = (current_y_scroll != gtk_adjustment_get_value (text_view->priv->vadjustment)) + || (current_x_scroll != gtk_adjustment_get_value (text_view->priv->hadjustment)); + if (retval) { DV(g_print (">Actually scrolled ("G_STRLOC")\n")); @@ -2090,33 +2124,6 @@ gtk_text_view_flush_scroll (GtkTextView *text_view) return retval; } -static void -gtk_text_view_set_adjustment_upper (GtkAdjustment *adj, gdouble upper) -{ - if (upper != adj->upper) - { - gdouble min = MAX (0.0, upper - adj->page_size); - gboolean value_changed = FALSE; - - adj->upper = upper; - - if (adj->value > min) - { - adj->value = min; - value_changed = TRUE; - } - - gtk_adjustment_changed (adj); - DV(g_print(">Changed adj upper to %g ("G_STRLOC")\n", upper)); - - if (value_changed) - { - DV(g_print(">Changed adj value because upper decreased ("G_STRLOC")\n")); - gtk_adjustment_value_changed (adj); - } - } -} - static void gtk_text_view_update_adjustments (GtkTextView *text_view) { @@ -2141,28 +2148,8 @@ gtk_text_view_update_adjustments (GtkTextView *text_view) priv->width = width; priv->height = height; - gtk_text_view_set_adjustment_upper (get_hadjustment (text_view), - MAX (SCREEN_WIDTH (text_view), width)); - gtk_text_view_set_adjustment_upper (get_vadjustment (text_view), - MAX (SCREEN_HEIGHT (text_view), height)); - - /* hadj/vadj exist since we called get_hadjustment/get_vadjustment above */ - - /* Set up the step sizes; we'll say that a page is - our allocation minus one step, and a step is - 1/10 of our allocation. */ - priv->hadjustment->step_increment = - SCREEN_WIDTH (text_view) / 10.0; - priv->hadjustment->page_increment = - SCREEN_WIDTH (text_view) * 0.9; - - priv->vadjustment->step_increment = - SCREEN_HEIGHT (text_view) / 10.0; - priv->vadjustment->page_increment = - SCREEN_HEIGHT (text_view) * 0.9; - - gtk_adjustment_changed (get_hadjustment (text_view)); - gtk_adjustment_changed (get_vadjustment (text_view)); + gtk_text_view_set_hadjustment_values (text_view); + gtk_text_view_set_vadjustment_values (text_view); } } @@ -2185,13 +2172,13 @@ gtk_text_view_update_im_spot_location (GtkTextView *text_view) if (text_view->priv->layout == NULL) return; - gtk_text_view_get_cursor_location (text_view, &area); + gtk_text_view_get_cursor_locations (text_view, NULL, &area, NULL); area.x -= text_view->priv->xoffset; area.y -= text_view->priv->yoffset; /* Width returned by Pango indicates direction of cursor, - * by it's sign more than the size of cursor. + * by its sign more than the size of cursor. */ area.width = 0; @@ -2359,7 +2346,7 @@ gtk_text_view_move_mark_onscreen (GtkTextView *text_view, /** * gtk_text_view_get_visible_rect: * @text_view: a #GtkTextView - * @visible_rect: rectangle to fill + * @visible_rect: (out): rectangle to fill * * Fills @visible_rect with the currently-visible * region of the buffer, in buffer coordinates. Convert to window coordinates @@ -2411,7 +2398,7 @@ gtk_text_view_set_wrap_mode (GtkTextView *text_view, { priv->wrap_mode = wrap_mode; - if (priv->layout) + if (priv->layout && priv->layout->default_style) { priv->layout->default_style->wrap_mode = wrap_mode; gtk_text_layout_default_style_changed (priv->layout); @@ -2471,7 +2458,7 @@ gtk_text_view_set_editable (GtkTextView *text_view, if (setting && gtk_widget_has_focus (GTK_WIDGET (text_view))) gtk_im_context_focus_in (priv->im_context); - if (priv->layout) + if (priv->layout && priv->layout->default_style) { gtk_text_layout_set_overwrite_mode (priv->layout, priv->overwrite_mode && priv->editable); @@ -2522,7 +2509,7 @@ gtk_text_view_set_pixels_above_lines (GtkTextView *text_view, { priv->pixels_above_lines = pixels_above_lines; - if (priv->layout) + if (priv->layout && priv->layout->default_style) { priv->layout->default_style->pixels_above_lines = pixels_above_lines; gtk_text_layout_default_style_changed (priv->layout); @@ -2571,7 +2558,7 @@ gtk_text_view_set_pixels_below_lines (GtkTextView *text_view, { priv->pixels_below_lines = pixels_below_lines; - if (priv->layout) + if (priv->layout && priv->layout->default_style) { priv->layout->default_style->pixels_below_lines = pixels_below_lines; gtk_text_layout_default_style_changed (priv->layout); @@ -2620,7 +2607,7 @@ gtk_text_view_set_pixels_inside_wrap (GtkTextView *text_view, { priv->pixels_inside_wrap = pixels_inside_wrap; - if (priv->layout) + if (priv->layout && priv->layout->default_style) { priv->layout->default_style->pixels_inside_wrap = pixels_inside_wrap; gtk_text_layout_default_style_changed (priv->layout); @@ -2669,7 +2656,7 @@ gtk_text_view_set_justification (GtkTextView *text_view, { priv->justify = justification; - if (priv->layout) + if (priv->layout && priv->layout->default_style) { priv->layout->default_style->justification = justification; gtk_text_layout_default_style_changed (priv->layout); @@ -2718,7 +2705,7 @@ gtk_text_view_set_left_margin (GtkTextView *text_view, { priv->left_margin = left_margin; - if (priv->layout) + if (priv->layout && priv->layout->default_style) { priv->layout->default_style->left_margin = left_margin; gtk_text_layout_default_style_changed (priv->layout); @@ -2765,7 +2752,7 @@ gtk_text_view_set_right_margin (GtkTextView *text_view, { priv->right_margin = right_margin; - if (priv->layout) + if (priv->layout && priv->layout->default_style) { priv->layout->default_style->right_margin = right_margin; gtk_text_layout_default_style_changed (priv->layout); @@ -2814,7 +2801,7 @@ gtk_text_view_set_indent (GtkTextView *text_view, { priv->indent = indent; - if (priv->layout) + if (priv->layout && priv->layout->default_style) { priv->layout->default_style->indent = indent; gtk_text_layout_default_style_changed (priv->layout); @@ -2865,7 +2852,7 @@ gtk_text_view_set_tabs (GtkTextView *text_view, priv->tabs = tabs ? pango_tab_array_copy (tabs) : NULL; - if (priv->layout) + if (priv->layout && priv->layout->default_style) { /* some unkosher futzing in internal struct details... */ if (priv->layout->default_style->tabs) @@ -3044,10 +3031,11 @@ gtk_text_view_finalize (GObject *object) text_view = GTK_TEXT_VIEW (object); priv = text_view->priv; - g_assert (priv->buffer == NULL); - gtk_text_view_destroy_layout (text_view); gtk_text_view_set_buffer (text_view, NULL); + + /* at this point, no "notify::buffer" handler should recreate the buffer. */ + g_assert (priv->buffer == NULL); cancel_pending_scroll (text_view); @@ -3157,6 +3145,24 @@ gtk_text_view_set_property (GObject *object, gtk_im_multicontext_set_context_id (GTK_IM_MULTICONTEXT (priv->im_context), priv->im_module); break; + case PROP_HADJUSTMENT: + gtk_text_view_set_hadjustment (text_view, g_value_get_object (value)); + break; + + case PROP_VADJUSTMENT: + gtk_text_view_set_vadjustment (text_view, g_value_get_object (value)); + break; + + case PROP_HSCROLL_POLICY: + priv->hscroll_policy = g_value_get_enum (value); + gtk_widget_queue_resize (GTK_WIDGET (text_view)); + break; + + case PROP_VSCROLL_POLICY: + priv->vscroll_policy = g_value_get_enum (value); + gtk_widget_queue_resize (GTK_WIDGET (text_view)); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -3237,6 +3243,22 @@ gtk_text_view_get_property (GObject *object, g_value_set_string (value, priv->im_module); break; + case PROP_HADJUSTMENT: + g_value_set_object (value, priv->hadjustment); + break; + + case PROP_VADJUSTMENT: + g_value_set_object (value, priv->vadjustment); + break; + + case PROP_HSCROLL_POLICY: + g_value_set_enum (value, priv->hscroll_policy); + break; + + case PROP_VSCROLL_POLICY: + g_value_set_enum (value, priv->vscroll_policy); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -3335,6 +3357,31 @@ gtk_text_view_size_request (GtkWidget *widget, priv->cached_size_request = *requisition; } +static void +gtk_text_view_get_preferred_width (GtkWidget *widget, + gint *minimum, + gint *natural) +{ + GtkRequisition requisition; + + gtk_text_view_size_request (widget, &requisition); + + *minimum = *natural = requisition.width; +} + +static void +gtk_text_view_get_preferred_height (GtkWidget *widget, + gint *minimum, + gint *natural) +{ + GtkRequisition requisition; + + gtk_text_view_size_request (widget, &requisition); + + *minimum = *natural = requisition.height; +} + + static void gtk_text_view_compute_child_allocation (GtkTextView *text_view, GtkTextViewChild *vc, @@ -3476,8 +3523,6 @@ gtk_text_view_size_allocate (GtkWidget *widget, GtkAllocation widget_allocation; GtkTextView *text_view; GtkTextViewPrivate *priv; - GtkTextIter first_para; - gint y; gint width, height; GdkRectangle text_rect; GdkRectangle left_rect; @@ -3608,44 +3653,9 @@ gtk_text_view_size_allocate (GtkWidget *widget, /* Note that this will do some layout validation */ gtk_text_view_allocate_children (text_view); - /* Ensure h/v adj exist */ - get_hadjustment (text_view); - get_vadjustment (text_view); - - priv->hadjustment->page_size = SCREEN_WIDTH (text_view); - priv->hadjustment->page_increment = SCREEN_WIDTH (text_view) * 0.9; - priv->hadjustment->step_increment = SCREEN_WIDTH (text_view) * 0.1; - priv->hadjustment->lower = 0; - priv->hadjustment->upper = MAX (SCREEN_WIDTH (text_view), - priv->width); - - if (priv->hadjustment->value > priv->hadjustment->upper - priv->hadjustment->page_size) - gtk_adjustment_set_value (priv->hadjustment, MAX (0, priv->hadjustment->upper - priv->hadjustment->page_size)); - - gtk_adjustment_changed (priv->hadjustment); - - priv->vadjustment->page_size = SCREEN_HEIGHT (text_view); - priv->vadjustment->page_increment = SCREEN_HEIGHT (text_view) * 0.9; - priv->vadjustment->step_increment = SCREEN_HEIGHT (text_view) * 0.1; - priv->vadjustment->lower = 0; - priv->vadjustment->upper = MAX (SCREEN_HEIGHT (text_view), - priv->height); - - /* Now adjust the value of the adjustment to keep the cursor at the - * same place in the buffer - */ - gtk_text_view_get_first_para_iter (text_view, &first_para); - gtk_text_layout_get_line_yrange (priv->layout, &first_para, &y, NULL); - - y += priv->first_para_pixels; - - if (y > priv->vadjustment->upper - priv->vadjustment->page_size) - y = MAX (0, priv->vadjustment->upper - priv->vadjustment->page_size); - - if (y != priv->yoffset) - gtk_adjustment_set_value (priv->vadjustment, y); - - gtk_adjustment_changed (priv->vadjustment); + /* Update adjustments */ + gtk_text_view_set_hadjustment_values (text_view); + gtk_text_view_set_vadjustment_values (text_view); /* The GTK resize loop processes all the pending exposes right * after doing the resize stuff, so the idle sizer won't have a @@ -3898,7 +3908,6 @@ changed_handler (GtkTextLayout *layout, if (old_height != new_height) { - gboolean yoffset_changed = FALSE; GSList *tmp_list; int new_first_para_top; int old_first_para_top; @@ -3924,14 +3933,7 @@ changed_handler (GtkTextLayout *layout, { priv->yoffset += new_first_para_top - old_first_para_top; - get_vadjustment (text_view)->value = priv->yoffset; - yoffset_changed = TRUE; - } - - if (yoffset_changed) - { - DV(g_print ("Changing scroll position (%s)\n", G_STRLOC)); - gtk_adjustment_value_changed (get_vadjustment (text_view)); + gtk_adjustment_set_value (text_view->priv->vadjustment, priv->yoffset); } /* FIXME be smarter about which anchored widgets we update */ @@ -3956,7 +3958,7 @@ changed_handler (GtkTextLayout *layout, * to avoid the optimization which just returns widget->requisition * if a resize hasn't been queued. */ - GTK_WIDGET_GET_CLASS (widget)->size_request (widget, &new_req); + gtk_text_view_size_request (widget, &new_req); if (old_req.width != new_req.width || old_req.height != new_req.height) @@ -3972,11 +3974,14 @@ gtk_text_view_realize (GtkWidget *widget) GtkAllocation allocation; GtkTextView *text_view; GtkTextViewPrivate *priv; + GtkStyleContext *context; + GtkStateFlags state; GdkWindow *window; GdkWindowAttr attributes; gint attributes_mask; GSList *tmp_list; - + GdkRGBA color; + text_view = GTK_TEXT_VIEW (widget); priv = text_view->priv; @@ -4000,11 +4005,11 @@ gtk_text_view_realize (GtkWidget *widget) gtk_widget_set_window (widget, window); gdk_window_set_user_data (window, widget); - /* must come before text_window_realize calls */ - gtk_widget_style_attach (widget); + context = gtk_widget_get_style_context (widget); + state = gtk_widget_get_state_flags (widget); - gdk_window_set_background (window, - >k_widget_get_style (widget)->bg[gtk_widget_get_state (widget)]); + gtk_style_context_get_background_color (context, state, &color); + gdk_window_set_background_rgba (window, &color); text_window_realize (priv->text_window, widget); @@ -4089,42 +4094,47 @@ gtk_text_view_unrealize (GtkWidget *widget) static void gtk_text_view_set_background (GtkTextView *text_view) { - GtkStyle *style; - GtkStateType state; + GtkStyleContext *context; + GtkStateFlags state; GtkWidget *widget; GtkTextViewPrivate *priv; + GdkRGBA color; widget = GTK_WIDGET (text_view); priv = text_view->priv; - style = gtk_widget_get_style (widget); - state = gtk_widget_get_state (widget); + context = gtk_widget_get_style_context (widget); + state = gtk_widget_get_state_flags (widget); - gdk_window_set_background (gtk_widget_get_window (widget), - &style->bg[state]); + /* Set bin window background */ + gtk_style_context_save (context); + gtk_style_context_add_class (context, GTK_STYLE_CLASS_VIEW); - gdk_window_set_background (priv->text_window->bin_window, - &style->base[state]); + gtk_style_context_get_background_color (context, state, &color); + gdk_window_set_background_rgba (priv->text_window->bin_window, &color); + + gtk_style_context_restore (context); + + /* Set lateral panes background */ + gtk_style_context_get_background_color (context, state, &color); + + gdk_window_set_background_rgba (gtk_widget_get_window (widget), &color); if (priv->left_window) - gdk_window_set_background (priv->left_window->bin_window, - &style->bg[state]); + gdk_window_set_background_rgba (priv->left_window->bin_window, &color); + if (priv->right_window) - gdk_window_set_background (priv->right_window->bin_window, - &style->bg[state]); + gdk_window_set_background_rgba (priv->right_window->bin_window, &color); if (priv->top_window) - gdk_window_set_background (priv->top_window->bin_window, - &style->bg[state]); + gdk_window_set_background_rgba (priv->top_window->bin_window, &color); if (priv->bottom_window) - gdk_window_set_background (priv->bottom_window->bin_window, - &style->bg[state]); + gdk_window_set_background_rgba (priv->bottom_window->bin_window, &color); } static void -gtk_text_view_style_set (GtkWidget *widget, - GtkStyle *previous_style) +gtk_text_view_style_updated (GtkWidget *widget) { GtkTextView *text_view; GtkTextViewPrivate *priv; @@ -4133,16 +4143,17 @@ gtk_text_view_style_set (GtkWidget *widget, text_view = GTK_TEXT_VIEW (widget); priv = text_view->priv; + GTK_WIDGET_CLASS (gtk_text_view_parent_class)->style_updated (widget); + if (gtk_widget_get_realized (widget)) { gtk_text_view_set_background (text_view); } - if (priv->layout && previous_style) + if (priv->layout && priv->layout->default_style) { gtk_text_view_set_attributes_from_style (text_view, - priv->layout->default_style, - gtk_widget_get_style (widget)); + priv->layout->default_style); ltr_context = gtk_widget_create_pango_context (widget); pango_context_set_base_dir (ltr_context, PANGO_DIRECTION_LTR); @@ -4162,7 +4173,7 @@ gtk_text_view_direction_changed (GtkWidget *widget, { GtkTextViewPrivate *priv = GTK_TEXT_VIEW (widget)->priv; - if (priv->layout) + if (priv->layout && priv->layout->default_style) { priv->layout->default_style->direction = gtk_widget_get_direction (widget); @@ -4171,8 +4182,8 @@ gtk_text_view_direction_changed (GtkWidget *widget, } static void -gtk_text_view_state_changed (GtkWidget *widget, - GtkStateType previous_state) +gtk_text_view_state_flags_changed (GtkWidget *widget, + GtkStateFlags previous_state) { GtkTextView *text_view = GTK_TEXT_VIEW (widget); GdkCursor *cursor; @@ -4189,7 +4200,7 @@ gtk_text_view_state_changed (GtkWidget *widget, gdk_window_set_cursor (text_view->priv->text_window->bin_window, cursor); if (cursor) - gdk_cursor_unref (cursor); + g_object_unref (cursor); text_view->priv->mouse_cursor_obscured = FALSE; } @@ -4214,7 +4225,7 @@ set_invisible_cursor (GdkWindow *window) gdk_window_set_cursor (window, cursor); - gdk_cursor_unref (cursor); + g_object_unref (cursor); } static void @@ -4238,7 +4249,7 @@ gtk_text_view_unobscure_mouse_cursor (GtkTextView *text_view) cursor = gdk_cursor_new_for_display (gtk_widget_get_display (GTK_WIDGET (text_view)), GDK_XTERM); gdk_window_set_cursor (text_view->priv->text_window->bin_window, cursor); - gdk_cursor_unref (cursor); + g_object_unref (cursor); text_view->priv->mouse_cursor_obscured = FALSE; } } @@ -4893,13 +4904,14 @@ gtk_text_view_draw_focus (GtkWidget *widget, NULL); if (gtk_widget_has_focus (widget) && !interior_focus) - { - gtk_paint_focus (gtk_widget_get_style (widget), cr, - gtk_widget_get_state (widget), - widget, "textview", - 0, 0, - gtk_widget_get_allocated_width (widget), - gtk_widget_get_allocated_height (widget)); + { + GtkStyleContext *context; + + context = gtk_widget_get_style_context (widget); + + gtk_render_focus (context, cr, 0, 0, + gtk_widget_get_allocated_width (widget), + gtk_widget_get_allocated_height (widget)); } } @@ -4932,17 +4944,6 @@ gtk_text_view_focus (GtkWidget *widget, } } -static void -gtk_text_view_move_focus (GtkWidget *widget, - GtkDirectionType direction_type) -{ - GtkTextView *text_view = GTK_TEXT_VIEW (widget); - - if (GTK_TEXT_VIEW_GET_CLASS (text_view)->move_focus) - GTK_TEXT_VIEW_GET_CLASS (text_view)->move_focus (text_view, - direction_type); -} - /* * Container */ @@ -5282,6 +5283,7 @@ gtk_text_view_move_cursor_internal (GtkTextView *text_view, if (!priv->cursor_visible) { GtkScrollStep scroll_step; + gdouble old_xpos, old_ypos; switch (step) { @@ -5316,14 +5318,15 @@ gtk_text_view_move_cursor_internal (GtkTextView *text_view, break; } - if (!gtk_text_view_move_viewport (text_view, scroll_step, count)) + old_xpos = priv->xoffset; + old_ypos = priv->yoffset; + gtk_text_view_move_viewport (text_view, scroll_step, count); + if ((old_xpos != priv->xoffset || old_ypos != priv->yoffset) && + leave_direction != -1 && + !gtk_widget_keynav_failed (GTK_WIDGET (text_view), + leave_direction)) { - if (leave_direction != -1 && - !gtk_widget_keynav_failed (GTK_WIDGET (text_view), - leave_direction)) - { - g_signal_emit_by_name (text_view, "move-focus", leave_direction); - } + g_signal_emit_by_name (text_view, "move-focus", leave_direction); } return; @@ -5518,7 +5521,7 @@ gtk_text_view_move_cursor (GtkTextView *text_view, gtk_text_view_move_cursor_internal (text_view, step, count, extend_selection); } -static gboolean +static void gtk_text_view_move_viewport (GtkTextView *text_view, GtkScrollStep step, gint count) @@ -5531,15 +5534,15 @@ gtk_text_view_move_viewport (GtkTextView *text_view, case GTK_SCROLL_STEPS: case GTK_SCROLL_PAGES: case GTK_SCROLL_ENDS: - adjustment = get_vadjustment (text_view); + adjustment = text_view->priv->vadjustment; break; case GTK_SCROLL_HORIZONTAL_STEPS: case GTK_SCROLL_HORIZONTAL_PAGES: case GTK_SCROLL_HORIZONTAL_ENDS: - adjustment = get_hadjustment (text_view); + adjustment = text_view->priv->hadjustment; break; default: - adjustment = get_vadjustment (text_view); + adjustment = text_view->priv->vadjustment; break; } @@ -5547,22 +5550,22 @@ gtk_text_view_move_viewport (GtkTextView *text_view, { case GTK_SCROLL_STEPS: case GTK_SCROLL_HORIZONTAL_STEPS: - increment = adjustment->step_increment; + increment = gtk_adjustment_get_step_increment (adjustment); break; case GTK_SCROLL_PAGES: case GTK_SCROLL_HORIZONTAL_PAGES: - increment = adjustment->page_increment; + increment = gtk_adjustment_get_page_increment (adjustment); break; case GTK_SCROLL_ENDS: case GTK_SCROLL_HORIZONTAL_ENDS: - increment = adjustment->upper - adjustment->lower; + increment = gtk_adjustment_get_upper (adjustment) - gtk_adjustment_get_lower (adjustment); break; default: increment = 0.0; break; } - return set_adjustment_clamped (adjustment, adjustment->value + count * increment); + gtk_adjustment_set_value (adjustment, gtk_adjustment_get_value (adjustment) + count * increment); } static void @@ -5582,7 +5585,7 @@ gtk_text_view_scroll_pages (GtkTextView *text_view, gboolean extend_selection) { GtkTextViewPrivate *priv; - GtkAdjustment *adj; + GtkAdjustment *adjustment; gint cursor_x_pos, cursor_y_pos; GtkTextMark *insert_mark; GtkTextIter old_insert; @@ -5596,7 +5599,7 @@ gtk_text_view_scroll_pages (GtkTextView *text_view, g_return_val_if_fail (priv->vadjustment != NULL, FALSE); - adj = priv->vadjustment; + adjustment = priv->vadjustment; insert_mark = gtk_text_buffer_get_insert (get_buffer (text_view)); @@ -5617,13 +5620,13 @@ gtk_text_view_scroll_pages (GtkTextView *text_view, if (count < 0) { gtk_text_view_get_first_para_iter (text_view, &anchor); - y0 = adj->page_size; - y1 = adj->page_size + count * adj->page_increment; + y0 = gtk_adjustment_get_page_size (adjustment); + y1 = gtk_adjustment_get_page_size (adjustment) + count * gtk_adjustment_get_page_increment (adjustment); } else { gtk_text_view_get_first_para_iter (text_view, &anchor); - y0 = count * adj->page_increment + adj->page_size; + y0 = count * gtk_adjustment_get_page_increment (adjustment) + gtk_adjustment_get_page_size (adjustment); y1 = 0; } @@ -5632,13 +5635,13 @@ gtk_text_view_scroll_pages (GtkTextView *text_view, new_insert = old_insert; - if (count < 0 && adj->value <= (adj->lower + 1e-12)) + if (count < 0 && gtk_adjustment_get_value (adjustment) <= (gtk_adjustment_get_lower (adjustment) + 1e-12)) { /* already at top, just be sure we are at offset 0 */ gtk_text_buffer_get_start_iter (get_buffer (text_view), &new_insert); move_cursor (text_view, &new_insert, extend_selection); } - else if (count > 0 && adj->value >= (adj->upper - adj->page_size - 1e-12)) + else if (count > 0 && gtk_adjustment_get_value (adjustment) >= (gtk_adjustment_get_upper (adjustment) - gtk_adjustment_get_page_size (adjustment) - 1e-12)) { /* already at bottom, just be sure we are at the end */ gtk_text_buffer_get_end_iter (get_buffer (text_view), &new_insert); @@ -5648,13 +5651,13 @@ gtk_text_view_scroll_pages (GtkTextView *text_view, { gtk_text_view_get_virtual_cursor_pos (text_view, NULL, &cursor_x_pos, &cursor_y_pos); - oldval = adj->value; - newval = adj->value; + oldval = gtk_adjustment_get_value (adjustment); + newval = gtk_adjustment_get_value (adjustment); - newval += count * adj->page_increment; + newval += count * gtk_adjustment_get_page_increment (adjustment); - set_adjustment_clamped (adj, newval); - cursor_y_pos += adj->value - oldval; + gtk_adjustment_set_value (adjustment, newval); + cursor_y_pos += gtk_adjustment_get_value (adjustment) - oldval; gtk_text_layout_get_iter_at_pixel (priv->layout, &new_insert, cursor_x_pos, cursor_y_pos); clamp_iter_onscreen (text_view, &new_insert); @@ -5678,7 +5681,7 @@ gtk_text_view_scroll_hpages (GtkTextView *text_view, gboolean extend_selection) { GtkTextViewPrivate *priv; - GtkAdjustment *adj; + GtkAdjustment *adjustment; gint cursor_x_pos, cursor_y_pos; GtkTextMark *insert_mark; GtkTextIter old_insert; @@ -5691,7 +5694,7 @@ gtk_text_view_scroll_hpages (GtkTextView *text_view, g_return_val_if_fail (priv->hadjustment != NULL, FALSE); - adj = priv->hadjustment; + adjustment = priv->hadjustment; insert_mark = gtk_text_buffer_get_insert (get_buffer (text_view)); @@ -5715,13 +5718,13 @@ gtk_text_view_scroll_hpages (GtkTextView *text_view, new_insert = old_insert; - if (count < 0 && adj->value <= (adj->lower + 1e-12)) + if (count < 0 && gtk_adjustment_get_value (adjustment) <= (gtk_adjustment_get_lower (adjustment) + 1e-12)) { /* already at far left, just be sure we are at offset 0 */ gtk_text_iter_set_line_offset (&new_insert, 0); move_cursor (text_view, &new_insert, extend_selection); } - else if (count > 0 && adj->value >= (adj->upper - adj->page_size - 1e-12)) + else if (count > 0 && gtk_adjustment_get_value (adjustment) >= (gtk_adjustment_get_upper (adjustment) - gtk_adjustment_get_page_size (adjustment) - 1e-12)) { /* already at far right, just be sure we are at the end */ if (!gtk_text_iter_ends_line (&new_insert)) @@ -5732,13 +5735,13 @@ gtk_text_view_scroll_hpages (GtkTextView *text_view, { gtk_text_view_get_virtual_cursor_pos (text_view, NULL, &cursor_x_pos, &cursor_y_pos); - oldval = adj->value; - newval = adj->value; + oldval = gtk_adjustment_get_value (adjustment); + newval = gtk_adjustment_get_value (adjustment); - newval += count * adj->page_increment; + newval += count * gtk_adjustment_get_page_increment (adjustment); - set_adjustment_clamped (adj, newval); - cursor_x_pos += adj->value - oldval; + gtk_adjustment_set_value (adjustment, newval); + cursor_x_pos += gtk_adjustment_get_value (adjustment) - oldval; gtk_text_layout_get_iter_at_pixel (priv->layout, &new_insert, cursor_x_pos, cursor_y_pos); clamp_iter_onscreen (text_view, &new_insert); @@ -6149,36 +6152,6 @@ gtk_text_view_get_accepts_tab (GtkTextView *text_view) return text_view->priv->accepts_tab; } -static void -gtk_text_view_compat_move_focus (GtkTextView *text_view, - GtkDirectionType direction_type) -{ - GSignalInvocationHint *hint = g_signal_get_invocation_hint (text_view); - - /* as of GTK+ 2.12, the "move-focus" signal has been moved to GtkWidget, - * the evil code below makes sure that both emitting the signal and - * calling the virtual function directly continue to work as expetcted - */ - - if (hint->signal_id == g_signal_lookup ("move-focus", GTK_TYPE_WIDGET)) - { - /* if this is a signal emission, chain up */ - - gboolean retval; - - g_signal_chain_from_overridden_handler (text_view, - direction_type, &retval); - } - else - { - /* otherwise emit the signal, since somebody called the virtual - * function directly - */ - - g_signal_emit_by_name (text_view, "move-focus", direction_type); - } -} - /* * Selections */ @@ -6266,12 +6239,12 @@ selection_scan_timeout (gpointer data) #define LOWER_OFFSET_ANCHOR 0.2 static gboolean -check_scroll (gdouble offset, GtkAdjustment *adj) +check_scroll (gdouble offset, GtkAdjustment *adjustment) { if ((offset > UPPER_OFFSET_ANCHOR && - adj->value + adj->page_size < adj->upper) || + gtk_adjustment_get_value (adjustment) + gtk_adjustment_get_page_size (adjustment) < gtk_adjustment_get_upper (adjustment)) || (offset < LOWER_OFFSET_ANCHOR && - adj->value > adj->lower)) + gtk_adjustment_get_value (adjustment) > gtk_adjustment_get_lower (adjustment))) return TRUE; return FALSE; @@ -6599,16 +6572,35 @@ gtk_text_view_end_selection_drag (GtkTextView *text_view) static void gtk_text_view_set_attributes_from_style (GtkTextView *text_view, - GtkTextAttributes *values, - GtkStyle *style) + GtkTextAttributes *values) { - values->appearance.bg_color = style->base[GTK_STATE_NORMAL]; - values->appearance.fg_color = style->text[GTK_STATE_NORMAL]; + GtkStyleContext *context; + GdkRGBA bg_color, fg_color; + GtkStateFlags state; + + context = gtk_widget_get_style_context (GTK_WIDGET (text_view)); + state = gtk_widget_get_state_flags (GTK_WIDGET (text_view)); + + gtk_style_context_save (context); + gtk_style_context_add_class (context, GTK_STYLE_CLASS_VIEW); + + gtk_style_context_get_background_color (context, state, &bg_color); + gtk_style_context_get_color (context, state, &fg_color); + + values->appearance.bg_color.red = CLAMP (bg_color.red * 65535. + 0.5, 0, 65535); + values->appearance.bg_color.green = CLAMP (bg_color.green * 65535. + 0.5, 0, 65535); + values->appearance.bg_color.blue = CLAMP (bg_color.blue * 65535. + 0.5, 0, 65535); + + values->appearance.fg_color.red = CLAMP (fg_color.red * 65535. + 0.5, 0, 65535); + values->appearance.fg_color.green = CLAMP (fg_color.green * 65535. + 0.5, 0, 65535); + values->appearance.fg_color.blue = CLAMP (fg_color.blue * 65535. + 0.5, 0, 65535); if (values->font) pango_font_description_free (values->font); - values->font = pango_font_description_copy (style->font_desc); + values->font = pango_font_description_copy (gtk_style_context_get_font (context, state)); + + gtk_style_context_restore (context); } static void @@ -6702,10 +6694,7 @@ gtk_text_view_ensure_layout (GtkTextView *text_view) style = gtk_text_attributes_new (); - gtk_widget_ensure_style (widget); - gtk_text_view_set_attributes_from_style (text_view, - style, - gtk_widget_get_style (widget)); + gtk_text_view_set_attributes_from_style (text_view, style); style->pixels_above_lines = priv->pixels_above_lines; style->pixels_below_lines = priv->pixels_below_lines; @@ -6853,7 +6842,7 @@ gtk_text_view_reset_im_context (GtkTextView *text_view) * gtk_foo_bar_key_press_event (GtkWidget *widget, * GdkEventKey *event) * { - * if ((key->keyval == GDK_Return || key->keyval == GDK_KP_Enter)) + * if ((key->keyval == GDK_KEY_Return || key->keyval == GDK_KEY_KP_Enter)) * { * if (gtk_text_view_im_context_filter_keypress (GTK_TEXT_VIEW (view), event)) * return TRUE; @@ -6971,7 +6960,7 @@ gtk_text_view_drag_data_get (GtkWidget *widget, { /* Extract the selected text */ str = gtk_text_buffer_serialize (buffer, buffer, - selection_data->target, + gtk_selection_data_get_target (selection_data), &start, &end, &len); } @@ -6979,7 +6968,7 @@ gtk_text_view_drag_data_get (GtkWidget *widget, if (str) { gtk_selection_data_set (selection_data, - selection_data->target, + gtk_selection_data_get_target (selection_data), 8, /* bytes */ (guchar *) str, len); g_free (str); @@ -7092,7 +7081,7 @@ gtk_text_view_drag_motion (GtkWidget *widget, { GtkWidget *source_widget; - suggested_action = context->suggested_action; + suggested_action = gdk_drag_context_get_suggested_action (context); source_widget = gtk_drag_get_source_widget (context); @@ -7101,7 +7090,7 @@ gtk_text_view_drag_motion (GtkWidget *widget, /* Default to MOVE, unless the user has * pressed ctrl or alt to affect available actions */ - if ((context->actions & GDK_ACTION_MOVE) != 0) + if ((gdk_drag_context_get_actions (context) & GDK_ACTION_MOVE) != 0) suggested_action = GDK_ACTION_MOVE; } } @@ -7235,10 +7224,10 @@ gtk_text_view_drag_data_received (GtkWidget *widget, GtkTextIter start, end; gboolean copy_tags = TRUE; - if (selection_data->length != sizeof (src_buffer)) + if (gtk_selection_data_get_length (selection_data) != sizeof (src_buffer)) return; - memcpy (&src_buffer, selection_data->data, sizeof (src_buffer)); + memcpy (&src_buffer, gtk_selection_data_get_data (selection_data), sizeof (src_buffer)); if (src_buffer == NULL) return; @@ -7258,7 +7247,7 @@ gtk_text_view_drag_data_received (GtkWidget *widget, atoms = gtk_text_buffer_get_deserialize_formats (buffer, &n_atoms); - for (list = context->targets; list; list = g_list_next (list)) + for (list = gdk_drag_context_list_targets (context); list; list = g_list_next (list)) { gint i; @@ -7302,17 +7291,17 @@ gtk_text_view_drag_data_received (GtkWidget *widget, } } } - else if (selection_data->length > 0 && + else if (gtk_selection_data_get_length (selection_data) > 0 && info == GTK_TEXT_BUFFER_TARGET_INFO_RICH_TEXT) { gboolean retval; GError *error = NULL; retval = gtk_text_buffer_deserialize (buffer, buffer, - selection_data->target, + gtk_selection_data_get_target (selection_data), &drop_point, - (guint8 *) selection_data->data, - selection_data->length, + (guint8 *) gtk_selection_data_get_data (selection_data), + gtk_selection_data_get_length (selection_data), &error); if (!retval) @@ -7326,7 +7315,7 @@ gtk_text_view_drag_data_received (GtkWidget *widget, done: gtk_drag_finish (context, success, - success && context->action == GDK_ACTION_MOVE, + success && gdk_drag_context_get_selected_action (context) == GDK_ACTION_MOVE, time); if (success) @@ -7349,13 +7338,43 @@ gtk_text_view_drag_data_received (GtkWidget *widget, * Returns: (transfer none): pointer to the horizontal #GtkAdjustment * * Since: 2.22 + * + * Deprecated: 3.0: Use gtk_scrollable_get_hadjustment() **/ GtkAdjustment* gtk_text_view_get_hadjustment (GtkTextView *text_view) { g_return_val_if_fail (GTK_IS_TEXT_VIEW (text_view), NULL); - return get_hadjustment (text_view); + return text_view->priv->hadjustment; +} + +static void +gtk_text_view_set_hadjustment (GtkTextView *text_view, + GtkAdjustment *adjustment) +{ + GtkTextViewPrivate *priv = text_view->priv; + + if (adjustment && priv->hadjustment == adjustment) + return; + + if (priv->hadjustment != NULL) + { + g_signal_handlers_disconnect_by_func (priv->hadjustment, + gtk_text_view_value_changed, + text_view); + g_object_unref (priv->hadjustment); + } + + if (adjustment == NULL) + adjustment = gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0); + + g_signal_connect (adjustment, "value-changed", + G_CALLBACK (gtk_text_view_value_changed), text_view); + priv->hadjustment = g_object_ref_sink (adjustment); + gtk_text_view_set_hadjustment_values (text_view); + + g_object_notify (G_OBJECT (text_view), "hadjustment"); } /** @@ -7367,95 +7386,111 @@ gtk_text_view_get_hadjustment (GtkTextView *text_view) * Returns: (transfer none): pointer to the vertical #GtkAdjustment * * Since: 2.22 + * + * Deprecated: 3.0: Use gtk_scrollable_get_vadjustment() **/ GtkAdjustment* gtk_text_view_get_vadjustment (GtkTextView *text_view) { g_return_val_if_fail (GTK_IS_TEXT_VIEW (text_view), NULL); - return get_vadjustment (text_view); + return text_view->priv->vadjustment; } -static GtkAdjustment* -get_hadjustment (GtkTextView *text_view) +static void +gtk_text_view_set_vadjustment (GtkTextView *text_view, + GtkAdjustment *adjustment) { - if (text_view->priv->hadjustment == NULL) - gtk_text_view_set_scroll_adjustments (text_view, - NULL, /* forces creation */ - text_view->priv->vadjustment); + GtkTextViewPrivate *priv = text_view->priv; - return text_view->priv->hadjustment; + if (adjustment && priv->vadjustment == adjustment) + return; + + if (priv->vadjustment != NULL) + { + g_signal_handlers_disconnect_by_func (priv->vadjustment, + gtk_text_view_value_changed, + text_view); + g_object_unref (priv->vadjustment); + } + + if (adjustment == NULL) + adjustment = gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0); + + g_signal_connect (adjustment, "value-changed", + G_CALLBACK (gtk_text_view_value_changed), text_view); + priv->vadjustment = g_object_ref_sink (adjustment); + gtk_text_view_set_vadjustment_values (text_view); + + g_object_notify (G_OBJECT (text_view), "vadjustment"); } -static GtkAdjustment* -get_vadjustment (GtkTextView *text_view) +static void +gtk_text_view_set_hadjustment_values (GtkTextView *text_view) { - if (text_view->priv->vadjustment == NULL) - gtk_text_view_set_scroll_adjustments (text_view, - text_view->priv->hadjustment, - NULL); /* forces creation */ - return text_view->priv->vadjustment; -} + GtkTextViewPrivate *priv; + gint screen_width; + gdouble old_value; + gdouble new_value; + gdouble new_upper; + + priv = text_view->priv; + screen_width = SCREEN_WIDTH (text_view); + old_value = gtk_adjustment_get_value (priv->hadjustment); + new_upper = MAX (screen_width, priv->width); + + g_object_set (priv->hadjustment, + "lower", 0.0, + "upper", new_upper, + "page-size", (gdouble)screen_width, + "step-increment", screen_width * 0.1, + "page-increment", screen_width * 0.9, + NULL); + + new_value = CLAMP (old_value, 0, new_upper - screen_width); + if (new_value != old_value) + gtk_adjustment_set_value (priv->hadjustment, new_value); +} static void -gtk_text_view_set_scroll_adjustments (GtkTextView *text_view, - GtkAdjustment *hadj, - GtkAdjustment *vadj) +gtk_text_view_set_vadjustment_values (GtkTextView *text_view) { - GtkTextViewPrivate *priv = text_view->priv; - gboolean need_adjust = FALSE; + GtkTextViewPrivate *priv; + GtkTextIter first_para; + gint screen_height; + gint y; + gdouble old_value; + gdouble new_value; + gdouble new_upper; - if (hadj) - g_return_if_fail (GTK_IS_ADJUSTMENT (hadj)); - else - hadj = gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0); - if (vadj) - g_return_if_fail (GTK_IS_ADJUSTMENT (vadj)); - else - vadj = gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0); + priv = text_view->priv; - if (priv->hadjustment && (priv->hadjustment != hadj)) - { - g_signal_handlers_disconnect_by_func (priv->hadjustment, - gtk_text_view_value_changed, - text_view); - g_object_unref (priv->hadjustment); - } + screen_height = SCREEN_HEIGHT (text_view); + old_value = gtk_adjustment_get_value (priv->vadjustment); + new_upper = MAX (screen_height, priv->height); - if (priv->vadjustment && (priv->vadjustment != vadj)) - { - g_signal_handlers_disconnect_by_func (priv->vadjustment, - gtk_text_view_value_changed, - text_view); - g_object_unref (priv->vadjustment); - } + g_object_set (priv->vadjustment, + "lower", 0.0, + "upper", new_upper, + "page-size", (gdouble)screen_height, + "step-increment", screen_height * 0.1, + "page-increment", screen_height * 0.9, + NULL); - if (priv->hadjustment != hadj) - { - priv->hadjustment = hadj; - g_object_ref_sink (priv->hadjustment); - - g_signal_connect (priv->hadjustment, "value-changed", - G_CALLBACK (gtk_text_view_value_changed), - text_view); - need_adjust = TRUE; - } + /* Now adjust the value of the adjustment to keep the cursor at the + * same place in the buffer */ + gtk_text_view_ensure_layout (text_view); + gtk_text_view_get_first_para_iter (text_view, &first_para); + gtk_text_layout_get_line_yrange (priv->layout, &first_para, &y, NULL); - if (priv->vadjustment != vadj) - { - priv->vadjustment = vadj; - g_object_ref_sink (priv->vadjustment); - - g_signal_connect (priv->vadjustment, "value-changed", - G_CALLBACK (gtk_text_view_value_changed), - text_view); - need_adjust = TRUE; - } + y += priv->first_para_pixels; + + new_value = CLAMP (y, 0, new_upper - screen_height); + if (new_value != old_value) + gtk_adjustment_set_value (priv->vadjustment, new_value); + } - if (need_adjust) - gtk_text_view_value_changed (NULL, text_view); -} /* FIXME this adjust_allocation is a big cut-and-paste from * GtkCList, needs to be some "official" way to do this @@ -7533,7 +7568,7 @@ adjust_allocation (GtkWidget *widget, } static void -gtk_text_view_value_changed (GtkAdjustment *adj, +gtk_text_view_value_changed (GtkAdjustment *adjustment, GtkTextView *text_view) { GtkTextViewPrivate *priv; @@ -7544,20 +7579,20 @@ gtk_text_view_value_changed (GtkAdjustment *adj, priv = text_view->priv; - /* Note that we oddly call this function with adj == NULL + /* Note that we oddly call this function with adjustment == NULL * sometimes */ priv->onscreen_validated = FALSE; DV(g_print(">Scroll offset changed %s/%g, onscreen_validated = FALSE ("G_STRLOC")\n", - adj == priv->hadjustment ? "hadj" : adj == priv->vadjustment ? "vadj" : "none", - adj ? adj->value : 0.0)); + adjustment == priv->hadjustment ? "hadjustment" : adjustment == priv->vadjustment ? "vadjustment" : "none", + adjustment ? gtk_adjustment_get_value (adjustment) : 0.0)); - if (adj == priv->hadjustment) + if (adjustment == priv->hadjustment) { - dx = priv->xoffset - (gint)adj->value; - priv->xoffset = adj->value; + dx = priv->xoffset - (gint)gtk_adjustment_get_value (adjustment); + priv->xoffset = gtk_adjustment_get_value (adjustment); /* If the change is due to a size change we need * to invalidate the entire text window because there might be @@ -7571,18 +7606,18 @@ gtk_text_view_value_changed (GtkAdjustment *adj, priv->width_changed = FALSE; } } - else if (adj == priv->vadjustment) + else if (adjustment == priv->vadjustment) { - dy = priv->yoffset - (gint)adj->value; - priv->yoffset = adj->value; + dy = priv->yoffset - (gint)gtk_adjustment_get_value (adjustment); + priv->yoffset = gtk_adjustment_get_value (adjustment); if (priv->layout) { - gtk_text_layout_get_line_at_y (priv->layout, &iter, adj->value, &line_top); + gtk_text_layout_get_line_at_y (priv->layout, &iter, gtk_adjustment_get_value (adjustment), &line_top); gtk_text_buffer_move_mark (get_buffer (text_view), priv->first_para_mark, &iter); - priv->first_para_pixels = adj->value - line_top; + priv->first_para_pixels = gtk_adjustment_get_value (adjustment) - line_top; } } @@ -7903,18 +7938,6 @@ gtk_text_view_target_list_notify (GtkTextBuffer *buffer, gtk_target_list_unref (view_list); } -static void -gtk_text_view_get_cursor_location (GtkTextView *text_view, - GdkRectangle *pos) -{ - GtkTextIter insert; - - gtk_text_buffer_get_iter_at_mark (get_buffer (text_view), &insert, - gtk_text_buffer_get_insert (get_buffer (text_view))); - - gtk_text_layout_get_cursor_locations (text_view->priv->layout, &insert, pos, NULL); -} - static void gtk_text_view_get_virtual_cursor_pos (GtkTextView *text_view, GtkTextIter *cursor, @@ -7965,7 +7988,7 @@ gtk_text_view_set_virtual_cursor_pos (GtkTextView *text_view, return; if (x == -1 || y == -1) - gtk_text_view_get_cursor_location (text_view, &pos); + gtk_text_view_get_cursor_locations (text_view, NULL, &pos, NULL); text_view->priv->virtual_cursor_x = (x == -1) ? pos.x : x; text_view->priv->virtual_cursor_y = (y == -1) ? pos.y + pos.height / 2 : y; @@ -8372,10 +8395,13 @@ static void text_window_realize (GtkTextWindow *win, GtkWidget *widget) { + GtkStyleContext *context; + GtkStateFlags state; GdkWindow *window; GdkWindowAttr attributes; gint attributes_mask; GdkCursor *cursor; + GdkRGBA color; attributes.window_type = GDK_WINDOW_CHILD; attributes.x = win->allocation.x; @@ -8417,6 +8443,9 @@ text_window_realize (GtkTextWindow *win, gdk_window_show (win->bin_window); gdk_window_set_user_data (win->bin_window, win->widget); + context = gtk_widget_get_style_context (widget); + state = gtk_widget_get_state_flags (widget); + if (win->type == GTK_TEXT_WINDOW_TEXT) { if (gtk_widget_is_sensitive (widget)) @@ -8425,20 +8454,24 @@ text_window_realize (GtkTextWindow *win, cursor = gdk_cursor_new_for_display (gdk_window_get_display (window), GDK_XTERM); gdk_window_set_cursor (win->bin_window, cursor); - gdk_cursor_unref (cursor); + g_object_unref (cursor); } gtk_im_context_set_client_window (GTK_TEXT_VIEW (widget)->priv->im_context, win->window); + gtk_style_context_save (context); + gtk_style_context_add_class (context, GTK_STYLE_CLASS_VIEW); - gdk_window_set_background (win->bin_window, - >k_widget_get_style (widget)->base[gtk_widget_get_state (widget)]); + gtk_style_context_get_background_color (context, state, &color); + gdk_window_set_background_rgba (win->bin_window, &color); + + gtk_style_context_restore (context); } else { - gdk_window_set_background (win->bin_window, - >k_widget_get_style (widget)->bg[gtk_widget_get_state (widget)]); + gtk_style_context_get_background_color (context, state, &color); + gdk_window_set_background_rgba (win->bin_window, &color); } g_object_set_qdata (G_OBJECT (win->window), @@ -9360,7 +9393,9 @@ gtk_text_view_add_child_at_anchor (GtkTextView *text_view, * @ypos: Y position of child in window coordinates * * Adds a child at fixed coordinates in one of the text widget's - * windows. The window must have nonzero size (see + * windows. + * + * The window must have nonzero size (see * gtk_text_view_set_border_window_size()). Note that the child * coordinates are given relative to the #GdkWindow in question, and * that these coordinates have no sane relationship to scrolling. When @@ -9370,12 +9405,8 @@ gtk_text_view_add_child_at_anchor (GtkTextView *text_view, * text window), you'll need to compute the child's correct position * in buffer coordinates any time scrolling occurs or buffer changes * occur, and then call gtk_text_view_move_child() to update the - * child's position. Unfortunately there's no good way to detect that - * scrolling has occurred, using the current API; a possible hack - * would be to update all child positions when the scroll adjustments - * change or the text buffer changes. See bug 64518 on - * bugzilla.gnome.org for status of fixing this issue. - **/ + * child's position. + */ void gtk_text_view_add_child_in_window (GtkTextView *text_view, GtkWidget *child,