]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtktextview.c
Deprecate widget flag: GTK_WIDGET_VISIBLE
[~andy/gtk] / gtk / gtktextview.c
index 0c41e24c2163f5cdc2856f1780baf680fa970467..589e8af8592697bfefe988b63afeeae626211f97 100644 (file)
@@ -138,6 +138,7 @@ enum
   MOVE_VIEWPORT,
   SELECT_ALL,
   TOGGLE_CURSOR_VISIBLE,
+  PREEDIT_CHANGED,
   LAST_SIGNAL
 };
 
@@ -337,6 +338,7 @@ static void gtk_text_view_paste_done_handler     (GtkTextBuffer     *buffer,
 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,
                                                   gint              *y);
 static void gtk_text_view_set_virtual_cursor_pos (GtkTextView       *text_view,
@@ -1046,6 +1048,30 @@ gtk_text_view_class_init (GtkTextViewClass *klass)
                                 _gtk_marshal_VOID__VOID,
                                 G_TYPE_NONE, 0);
 
+  /**
+   * GtkTextView::preedit-changed:
+   * @text_view: the object which received the signal
+   * @preedit: the current preedit string
+   *
+   * If an input method is used, the typed text will not immediately
+   * be committed to the buffer. So if you are interested in the text,
+   * connect to this signal.
+   *
+   * This signal is only emitted if the text at the given position
+   * is actually editable.
+   *
+   * Since: 2.20
+   */
+  signals[PREEDIT_CHANGED] =
+    g_signal_new_class_handler (I_("preedit-changed"),
+                                G_OBJECT_CLASS_TYPE (object_class),
+                                G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+                                NULL,
+                                NULL, NULL,
+                                _gtk_marshal_VOID__STRING,
+                                G_TYPE_NONE, 1,
+                                G_TYPE_STRING);
+
   /*
    * Key bindings
    */
@@ -1363,7 +1389,7 @@ gtk_text_view_new_with_buffer (GtkTextBuffer *buffer)
 /**
  * gtk_text_view_set_buffer:
  * @text_view: a #GtkTextView
- * @buffer: a #GtkTextBuffer
+ * @buffer: (allow-none): a #GtkTextBuffer
  *
  * Sets @buffer as the buffer being displayed by @text_view. The previous
  * buffer displayed by the text view is unreferenced, and a reference is
@@ -1475,7 +1501,7 @@ gtk_text_view_set_buffer (GtkTextView   *text_view,
 
   g_object_notify (G_OBJECT (text_view), "buffer");
   
-  if (GTK_WIDGET_VISIBLE (text_view))
+  if (gtk_widget_get_visible (GTK_WIDGET (text_view)))
     gtk_widget_queue_draw (GTK_WIDGET (text_view));
 
   DV(g_print ("Invalidating due to set_buffer\n"));
@@ -1504,7 +1530,7 @@ get_buffer (GtkTextView *text_view)
  * The reference count on the buffer is not incremented; the caller
  * of this function won't own a new reference.
  *
- * Return value: a #GtkTextBuffer
+ * Return value: (transfer none): a #GtkTextBuffer
  **/
 GtkTextBuffer*
 gtk_text_view_get_buffer (GtkTextView *text_view)
@@ -1865,9 +1891,13 @@ gtk_text_view_scroll_to_iter (GtkTextView   *text_view,
     }
   
   if (retval)
-    DV(g_print (">Actually scrolled ("G_STRLOC")\n"));
+    {
+      DV(g_print (">Actually scrolled ("G_STRLOC")\n"));
+    }
   else
-    DV(g_print (">Didn't end up scrolling ("G_STRLOC")\n"));
+    {
+      DV(g_print (">Didn't end up scrolling ("G_STRLOC")\n"));
+    }
   
   return retval;
 }
@@ -2341,13 +2371,13 @@ gtk_text_view_set_editable (GtkTextView *text_view,
       if (!setting)
        {
          gtk_text_view_reset_im_context(text_view);
-         if (GTK_WIDGET_HAS_FOCUS (text_view))
+         if (gtk_widget_has_focus (GTK_WIDGET (text_view)))
            gtk_im_context_focus_out (text_view->im_context);
        }
 
       text_view->editable = setting;
 
-      if (setting && GTK_WIDGET_HAS_FOCUS (text_view))
+      if (setting && gtk_widget_has_focus (GTK_WIDGET (text_view)))
        gtk_im_context_focus_in (text_view->im_context);
 
       if (text_view->layout)
@@ -2776,7 +2806,7 @@ gtk_text_view_set_cursor_visible (GtkTextView *text_view,
     {
       text_view->cursor_visible = setting;
 
-      if (GTK_WIDGET_HAS_FOCUS (text_view))
+      if (gtk_widget_has_focus (GTK_WIDGET (text_view)))
         {
           if (text_view->layout)
             {
@@ -2996,7 +3026,7 @@ gtk_text_view_set_property (GObject         *object,
       
     case PROP_IM_MODULE:
       g_free (priv->im_module);
-      priv->im_module = g_strdup (g_value_get_string (value));
+      priv->im_module = g_value_dup_string (value);
       if (GTK_IS_IM_MULTICONTEXT (text_view->im_context))
         gtk_im_multicontext_set_context_id (GTK_IM_MULTICONTEXT (text_view->im_context), priv->im_module);
       break;
@@ -3982,7 +4012,7 @@ gtk_text_view_state_changed (GtkWidget      *widget,
     {
       gtk_text_view_set_background (text_view);
 
-      if (GTK_WIDGET_IS_SENSITIVE (widget))
+      if (gtk_widget_is_sensitive (widget))
         cursor = gdk_cursor_new_for_display (gtk_widget_get_display (widget), GDK_XTERM);
       else
         cursor = NULL;
@@ -3995,7 +4025,7 @@ gtk_text_view_state_changed (GtkWidget      *widget,
       text_view->mouse_cursor_obscured = FALSE;
     }
 
-  if (!GTK_WIDGET_IS_SENSITIVE (widget))
+  if (!gtk_widget_is_sensitive (widget))
     {
       /* Clear any selection */
       gtk_text_view_unselect (text_view);
@@ -4649,9 +4679,9 @@ gtk_text_view_draw_focus (GtkWidget *widget)
                        "interior-focus", &interior_focus,
                        NULL);
   
-  if (GTK_WIDGET_DRAWABLE (widget))
+  if (gtk_widget_is_drawable (widget))
     {
-      if (GTK_WIDGET_HAS_FOCUS (widget) && !interior_focus)
+      if (gtk_widget_has_focus (widget) && !interior_focus)
         {          
           gtk_paint_focus (widget->style, widget->window, GTK_WIDGET_STATE (widget), 
                            NULL, widget, "textview",
@@ -4858,7 +4888,7 @@ blink_cb (gpointer data)
   text_view = GTK_TEXT_VIEW (data);
   priv = GTK_TEXT_VIEW_GET_PRIVATE (text_view);
 
-  if (!GTK_WIDGET_HAS_FOCUS (text_view))
+  if (!gtk_widget_has_focus (GTK_WIDGET (text_view)))
     {
       g_warning ("GtkTextView - did not receive focus-out-event. If you\n"
                  "connect a handler to this signal, it must return\n"
@@ -4928,7 +4958,7 @@ gtk_text_view_check_cursor_blink (GtkTextView *text_view)
 {
   if (text_view->layout != NULL &&
       text_view->cursor_visible &&
-      GTK_WIDGET_HAS_FOCUS (text_view))
+      gtk_widget_has_focus (GTK_WIDGET (text_view)))
     {
       if (cursor_blinks (text_view))
        {
@@ -4959,7 +4989,7 @@ gtk_text_view_pend_cursor_blink (GtkTextView *text_view)
 {
   if (text_view->layout != NULL &&
       text_view->cursor_visible &&
-      GTK_WIDGET_HAS_FOCUS (text_view) &&
+      gtk_widget_has_focus (GTK_WIDGET (text_view)) &&
       cursor_blinks (text_view))
     {
       gtk_text_view_stop_cursor_blink (text_view);
@@ -5031,6 +5061,7 @@ gtk_text_view_move_cursor_internal (GtkTextView     *text_view,
 {
   GtkTextIter insert;
   GtkTextIter newplace;
+  gboolean cancel_selection = FALSE;
   gint cursor_x_pos = 0;
   GtkDirectionType leave_direction = -1;
 
@@ -5107,20 +5138,46 @@ gtk_text_view_move_cursor_internal (GtkTextView     *text_view,
 
   gtk_text_buffer_get_iter_at_mark (get_buffer (text_view), &insert,
                                     gtk_text_buffer_get_insert (get_buffer (text_view)));
+
+  if (! extend_selection)
+    {
+      GtkTextIter sel_bound;
+
+      gtk_text_buffer_get_iter_at_mark (get_buffer (text_view), &sel_bound,
+                                        gtk_text_buffer_get_selection_bound (get_buffer (text_view)));
+
+      /* if we move forward, assume the cursor is at the end of the selection;
+       * if we move backward, assume the cursor is at the start
+       */
+      if (count > 0)
+        gtk_text_iter_order (&sel_bound, &insert);
+      else
+        gtk_text_iter_order (&insert, &sel_bound);
+
+      /* if we actually have a selection, just move *to* the beginning/end
+       * of the selection and not *from* there on LOGICAL_POSITIONS
+       * and VISUAL_POSITIONS movement
+       */
+      if (! gtk_text_iter_equal (&sel_bound, &insert))
+        cancel_selection = TRUE;
+    }
+
   newplace = insert;
 
   if (step == GTK_MOVEMENT_DISPLAY_LINES)
-    gtk_text_view_get_virtual_cursor_pos (text_view, &cursor_x_pos, NULL);
+    gtk_text_view_get_virtual_cursor_pos (text_view, &insert, &cursor_x_pos, NULL);
 
   switch (step)
     {
     case GTK_MOVEMENT_LOGICAL_POSITIONS:
-      gtk_text_iter_forward_visible_cursor_positions (&newplace, count);
+      if (! cancel_selection)
+        gtk_text_iter_forward_visible_cursor_positions (&newplace, count);
       break;
 
     case GTK_MOVEMENT_VISUAL_POSITIONS:
-      gtk_text_layout_move_iter_visually (text_view->layout,
-                                          &newplace, count);
+      if (! cancel_selection)
+        gtk_text_layout_move_iter_visually (text_view->layout,
+                                            &newplace, count);
       break;
 
     case GTK_MOVEMENT_WORDS:
@@ -5229,7 +5286,7 @@ gtk_text_view_move_cursor_internal (GtkTextView     *text_view,
           g_signal_emit_by_name (text_view, "move-focus", leave_direction);
         }
     }
-  else
+  else if (! cancel_selection)
     {
       gtk_widget_error_bell (GTK_WIDGET (text_view));
     }
@@ -5382,7 +5439,7 @@ gtk_text_view_scroll_pages (GtkTextView *text_view,
     }
   else
     {
-      gtk_text_view_get_virtual_cursor_pos (text_view, &cursor_x_pos, &cursor_y_pos);
+      gtk_text_view_get_virtual_cursor_pos (text_view, NULL, &cursor_x_pos, &cursor_y_pos);
 
       oldval = adj->value;
       newval = adj->value;
@@ -5463,7 +5520,7 @@ gtk_text_view_scroll_hpages (GtkTextView *text_view,
     }
   else
     {
-      gtk_text_view_get_virtual_cursor_pos (text_view, &cursor_x_pos, &cursor_y_pos);
+      gtk_text_view_get_virtual_cursor_pos (text_view, NULL, &cursor_x_pos, &cursor_y_pos);
 
       oldval = adj->value;
       newval = adj->value;
@@ -6368,7 +6425,7 @@ gtk_text_view_ensure_layout (GtkTextView *text_view)
       if (get_buffer (text_view))
         gtk_text_layout_set_buffer (text_view->layout, get_buffer (text_view));
 
-      if ((GTK_WIDGET_HAS_FOCUS (text_view) && text_view->cursor_visible))
+      if ((gtk_widget_has_focus (widget) && text_view->cursor_visible))
         gtk_text_view_pend_cursor_blink (text_view);
       else
         gtk_text_layout_set_cursor_visible (text_view->layout, FALSE);
@@ -7051,7 +7108,7 @@ typedef struct
 
 /* The window to which widget->window is relative */
 #define ALLOCATION_WINDOW(widget)              \
-   (GTK_WIDGET_NO_WINDOW (widget) ?            \
+   (!gtk_widget_get_has_window (widget) ?              \
     (widget)->window :                          \
      gdk_window_get_parent ((widget)->window))
 
@@ -7067,7 +7124,7 @@ adjust_allocation_recurse (GtkWidget *widget,
    */
   if (!GTK_WIDGET_REALIZED (widget))
     {
-      if (GTK_WIDGET_VISIBLE (widget))
+      if (gtk_widget_get_visible (widget))
        {
          GdkRectangle tmp_rectangle = widget->allocation;
          tmp_rectangle.x += scroll_data->dx;
@@ -7341,9 +7398,11 @@ gtk_text_view_preedit_changed_handler (GtkIMContext *context,
       goto out;
     }
 
+  g_signal_emit (text_view, signals[PREEDIT_CHANGED], 0, str);
+
   if (text_view->layout)
     gtk_text_layout_set_preedit_string (text_view->layout, str, attrs, cursor_pos);
-  if (GTK_WIDGET_HAS_FOCUS (text_view))
+  if (gtk_widget_has_focus (GTK_WIDGET (text_view)))
     gtk_text_view_scroll_mark_onscreen (text_view,
                                        gtk_text_buffer_get_insert (get_buffer (text_view)));
 
@@ -7480,14 +7539,22 @@ gtk_text_view_get_cursor_location  (GtkTextView   *text_view,
 
 static void
 gtk_text_view_get_virtual_cursor_pos (GtkTextView *text_view,
+                                      GtkTextIter *cursor,
                                       gint        *x,
                                       gint        *y)
 {
+  GtkTextIter insert;
   GdkRectangle pos;
 
+  if (cursor)
+    insert = *cursor;
+  else
+    gtk_text_buffer_get_iter_at_mark (get_buffer (text_view), &insert,
+                                      gtk_text_buffer_get_insert (get_buffer (text_view)));
+
   if ((x && text_view->virtual_cursor_x == -1) ||
       (y && text_view->virtual_cursor_y == -1))
-    gtk_text_view_get_cursor_location (text_view, &pos);
+    gtk_text_layout_get_cursor_locations (text_view->layout, &insert, &pos, NULL);
 
   if (x)
     {
@@ -7963,7 +8030,7 @@ text_window_realize (GtkTextWindow *win,
 
   if (win->type == GTK_TEXT_WINDOW_TEXT)
     {
-      if (GTK_WIDGET_IS_SENSITIVE (widget))
+      if (gtk_widget_is_sensitive (widget))
         {
           /* I-beam cursor */
           cursor = gdk_cursor_new_for_display (gdk_drawable_get_display (widget->window),
@@ -8195,7 +8262,7 @@ text_window_get_height (GtkTextWindow *win)
  * height is 0, and are nonexistent before the widget has been
  * realized.
  *
- * Return value: a #GdkWindow, or %NULL
+ * Return value: (transfer none): a #GdkWindow, or %NULL
  **/
 GdkWindow*
 gtk_text_view_get_window (GtkTextView *text_view,
@@ -8958,7 +9025,8 @@ gtk_text_view_move_child (GtkTextView *text_view,
   vc->x = xpos;
   vc->y = ypos;
 
-  if (GTK_WIDGET_VISIBLE (child) && GTK_WIDGET_VISIBLE (text_view))
+  if (gtk_widget_get_visible (child) &&
+      gtk_widget_get_visible (GTK_WIDGET (text_view)))
     gtk_widget_queue_resize (child);
 }