]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtktextview.c
Silently return NULL if the widget is not realized. (#316023, Guillaume
[~andy/gtk] / gtk / gtktextview.c
index 9a1aa7300721b0640f7fb4bc5a95a08dcde88c73..d5e5be18caa44129f6dd3ab07539dc31f2c0db0b 100644 (file)
@@ -441,7 +441,7 @@ gtk_text_view_get_type (void)
        (GInstanceInitFunc) gtk_text_view_init,
       };
 
-      our_type = g_type_register_static (GTK_TYPE_CONTAINER, "GtkTextView",
+      our_type = g_type_register_static (GTK_TYPE_CONTAINER, I_("GtkTextView"),
                                         &our_info, 0);
     }
 
@@ -698,7 +698,7 @@ gtk_text_view_class_init (GtkTextViewClass *klass)
    *
    */
   signals[MOVE_CURSOR] = 
-    g_signal_new ("move_cursor",
+    g_signal_new (I_("move_cursor"),
                  G_OBJECT_CLASS_TYPE (gobject_class), 
                  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, 
                  G_STRUCT_OFFSET (GtkTextViewClass, move_cursor),
@@ -710,7 +710,7 @@ gtk_text_view_class_init (GtkTextViewClass *klass)
                  G_TYPE_BOOLEAN);
 
   signals[PAGE_HORIZONTALLY] =
-    g_signal_new ("page_horizontally",
+    g_signal_new (I_("page_horizontally"),
                  G_OBJECT_CLASS_TYPE (gobject_class),
                  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
                  G_STRUCT_OFFSET (GtkTextViewClass, page_horizontally),
@@ -721,7 +721,7 @@ gtk_text_view_class_init (GtkTextViewClass *klass)
                  G_TYPE_BOOLEAN);
   
   signals[MOVE_VIEWPORT] =
-    _gtk_binding_signal_new ("move_viewport",
+    _gtk_binding_signal_new (I_("move_viewport"),
                             G_OBJECT_CLASS_TYPE (gobject_class),
                             G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
                             G_CALLBACK (gtk_text_view_move_viewport),
@@ -732,7 +732,7 @@ gtk_text_view_class_init (GtkTextViewClass *klass)
                             G_TYPE_INT);
 
   signals[SET_ANCHOR] =
-    g_signal_new ("set_anchor",
+    g_signal_new (I_("set_anchor"),
                  G_OBJECT_CLASS_TYPE (gobject_class),
                  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
                  G_STRUCT_OFFSET (GtkTextViewClass, set_anchor),
@@ -741,7 +741,7 @@ gtk_text_view_class_init (GtkTextViewClass *klass)
                  G_TYPE_NONE, 0);
 
   signals[INSERT_AT_CURSOR] =
-    g_signal_new ("insert_at_cursor",
+    g_signal_new (I_("insert_at_cursor"),
                  G_OBJECT_CLASS_TYPE (gobject_class),
                  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
                  G_STRUCT_OFFSET (GtkTextViewClass, insert_at_cursor),
@@ -751,7 +751,7 @@ gtk_text_view_class_init (GtkTextViewClass *klass)
                  G_TYPE_STRING);
 
   signals[DELETE_FROM_CURSOR] =
-    g_signal_new ("delete_from_cursor",
+    g_signal_new (I_("delete_from_cursor"),
                  G_OBJECT_CLASS_TYPE (gobject_class),
                  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
                  G_STRUCT_OFFSET (GtkTextViewClass, delete_from_cursor),
@@ -762,7 +762,7 @@ gtk_text_view_class_init (GtkTextViewClass *klass)
                  G_TYPE_INT);
 
   signals[BACKSPACE] =
-    g_signal_new ("backspace",
+    g_signal_new (I_("backspace"),
                  G_OBJECT_CLASS_TYPE (gobject_class),
                  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
                  G_STRUCT_OFFSET (GtkTextViewClass, backspace),
@@ -771,7 +771,7 @@ gtk_text_view_class_init (GtkTextViewClass *klass)
                  G_TYPE_NONE, 0);
 
   signals[CUT_CLIPBOARD] =
-    g_signal_new ("cut_clipboard",
+    g_signal_new (I_("cut_clipboard"),
                  G_OBJECT_CLASS_TYPE (gobject_class),
                  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
                  G_STRUCT_OFFSET (GtkTextViewClass, cut_clipboard),
@@ -780,7 +780,7 @@ gtk_text_view_class_init (GtkTextViewClass *klass)
                  G_TYPE_NONE, 0);
 
   signals[COPY_CLIPBOARD] =
-    g_signal_new ("copy_clipboard",
+    g_signal_new (I_("copy_clipboard"),
                  G_OBJECT_CLASS_TYPE (gobject_class),
                  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
                  G_STRUCT_OFFSET (GtkTextViewClass, copy_clipboard),
@@ -789,7 +789,7 @@ gtk_text_view_class_init (GtkTextViewClass *klass)
                  G_TYPE_NONE, 0);
 
   signals[PASTE_CLIPBOARD] =
-    g_signal_new ("paste_clipboard",
+    g_signal_new (I_("paste_clipboard"),
                  G_OBJECT_CLASS_TYPE (gobject_class),
                  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
                  G_STRUCT_OFFSET (GtkTextViewClass, paste_clipboard),
@@ -798,7 +798,7 @@ gtk_text_view_class_init (GtkTextViewClass *klass)
                  G_TYPE_NONE, 0);
 
   signals[TOGGLE_OVERWRITE] =
-    g_signal_new ("toggle_overwrite",
+    g_signal_new (I_("toggle_overwrite"),
                  G_OBJECT_CLASS_TYPE (gobject_class),
                  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
                  G_STRUCT_OFFSET (GtkTextViewClass, toggle_overwrite),
@@ -807,7 +807,7 @@ gtk_text_view_class_init (GtkTextViewClass *klass)
                  G_TYPE_NONE, 0);
 
   signals[MOVE_FOCUS] =
-    g_signal_new ("move_focus",
+    g_signal_new (I_("move_focus"),
                  G_OBJECT_CLASS_TYPE (gobject_class),
                  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
                  G_STRUCT_OFFSET (GtkTextViewClass, move_focus),
@@ -817,7 +817,7 @@ gtk_text_view_class_init (GtkTextViewClass *klass)
                  GTK_TYPE_DIRECTION_TYPE);
   
   signals[SET_SCROLL_ADJUSTMENTS] =
-    g_signal_new ("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),
@@ -829,7 +829,7 @@ gtk_text_view_class_init (GtkTextViewClass *klass)
   widget_class->set_scroll_adjustments_signal = signals[SET_SCROLL_ADJUSTMENTS];
 
   signals[POPULATE_POPUP] =
-    g_signal_new ("populate_popup",
+    g_signal_new (I_("populate_popup"),
                  G_OBJECT_CLASS_TYPE (gobject_class),
                  G_SIGNAL_RUN_LAST,
                  G_STRUCT_OFFSET (GtkTextViewClass, populate_popup),
@@ -839,7 +839,7 @@ gtk_text_view_class_init (GtkTextViewClass *klass)
                  GTK_TYPE_MENU);
   
   signals[SELECT_ALL] =
-    _gtk_binding_signal_new ("select_all",
+    _gtk_binding_signal_new (I_("select_all"),
                             G_OBJECT_CLASS_TYPE (object_class),
                             G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
                             G_CALLBACK (gtk_text_view_select_all),
@@ -966,6 +966,10 @@ gtk_text_view_class_init (GtkTextViewClass *klass)
                                 "select_all", 1,
                                 G_TYPE_BOOLEAN, FALSE);
 
+  gtk_binding_entry_add_signal (binding_set, GDK_a, GDK_SHIFT_MASK | GDK_CONTROL_MASK,
+                                "select_all", 1,
+                                G_TYPE_BOOLEAN, FALSE);
+
   /* Deleting text */
   gtk_binding_entry_add_signal (binding_set, GDK_Delete, 0,
                                "delete_from_cursor", 2,
@@ -3881,6 +3885,7 @@ gtk_text_view_key_press_event (GtkWidget *widget, GdkEventKey *event)
       /* this won't actually insert the newline if the cursor isn't
        * editable
        */
+      gtk_text_view_reset_im_context (text_view);
       gtk_text_view_commit_text (text_view, "\n");
 
       obscure = TRUE;
@@ -3896,6 +3901,7 @@ gtk_text_view_key_press_event (GtkWidget *widget, GdkEventKey *event)
        */
       if (text_view->accepts_tab && text_view->editable)
        {
+         gtk_text_view_reset_im_context (text_view);
          gtk_text_view_commit_text (text_view, "\t");
          obscure = TRUE;
        }
@@ -4070,7 +4076,8 @@ gtk_text_view_button_release_event (GtkWidget *widget, GdkEventButton *event)
                                             event->y + text_view->yoffset);
 
          gtk_text_buffer_place_cursor (get_buffer (text_view), &iter);
-
+         gtk_text_view_check_cursor_blink (text_view);
+         
           text_view->pending_place_cursor_button = 0;
           
           return FALSE;
@@ -4450,14 +4457,23 @@ cursor_blinks (GtkTextView *text_view)
 #endif
   if (gtk_debug_flags & GTK_DEBUG_UPDATES)
     return FALSE;
-  
+
   if (text_view->editable)
     {
-      g_object_get (settings, "gtk-cursor-blink", &blink, NULL);
-      return blink;
+      GtkTextMark *insert;
+      GtkTextIter iter;
+      
+      insert = gtk_text_buffer_get_insert (get_buffer (text_view));
+      gtk_text_buffer_get_iter_at_mark (get_buffer (text_view), &iter, insert);
+      
+      if (gtk_text_iter_editable (&iter, text_view->editable))
+       {
+         g_object_get (settings, "gtk-cursor-blink", &blink, NULL);
+         return blink;
+       }
     }
-  else
-    return FALSE;
+
+  return FALSE;
 }
 
 static gint
@@ -4545,42 +4561,34 @@ 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 (text_view) &&
+      cursor_blinks (text_view))
     {
-      if (cursor_blinks (text_view))
+      if (text_view->blink_timeout == 0)
        {
-         if (text_view->blink_timeout == 0)
-           {
-             gtk_text_layout_set_cursor_visible (text_view->layout, TRUE);
-             
-             text_view->blink_timeout = g_timeout_add (get_cursor_time (text_view) * CURSOR_OFF_MULTIPLIER,
-                                                       blink_cb,
-                                                       text_view);
-           }
+         gtk_text_layout_set_cursor_visible (text_view->layout, TRUE);
+         
+         text_view->blink_timeout = g_timeout_add (get_cursor_time (text_view) * CURSOR_OFF_MULTIPLIER,
+                                                   blink_cb,
+                                                   text_view);
        }
-      else
-       gtk_text_layout_set_cursor_visible (text_view->layout, TRUE);   
     }
   else
     {
       gtk_text_view_stop_cursor_blink (text_view);
+      gtk_text_layout_set_cursor_visible (text_view->layout, TRUE);    
     }
 }
 
 static void
-gtk_text_view_pend_cursor_blink(GtkTextView *text_view)
+gtk_text_view_pend_cursor_blink (GtkTextView *text_view)
 {
   if (text_view->layout != NULL &&
       text_view->cursor_visible &&
       GTK_WIDGET_HAS_FOCUS (text_view) &&
       cursor_blinks (text_view))
     {
-      if (text_view->blink_timeout != 0)
-       {
-         g_source_remove (text_view->blink_timeout);
-         text_view->blink_timeout = 0;
-       }
-      
+      gtk_text_view_stop_cursor_blink (text_view);
       gtk_text_layout_set_cursor_visible (text_view->layout, TRUE);
       
       text_view->blink_timeout = g_timeout_add (get_cursor_time (text_view) * CURSOR_PEND_MULTIPLIER,
@@ -4626,8 +4634,9 @@ move_cursor (GtkTextView       *text_view,
                                        "insert",
                                        new_location);
   else
-    gtk_text_buffer_place_cursor (get_buffer (text_view),
-                                  new_location);
+      gtk_text_buffer_place_cursor (get_buffer (text_view),
+                                   new_location);
+  gtk_text_view_check_cursor_blink (text_view);
 }
 
 static void
@@ -4684,12 +4693,14 @@ gtk_text_view_move_cursor_internal (GtkTextView     *text_view,
   if (step == GTK_MOVEMENT_PAGES)
     {
       gtk_text_view_scroll_pages (text_view, count, extend_selection);
+      gtk_text_view_check_cursor_blink (text_view);
       gtk_text_view_pend_cursor_blink (text_view);
       return;
     }
   else if (step == GTK_MOVEMENT_HORIZONTAL_PAGES)
     {
       gtk_text_view_scroll_hpages (text_view, count, extend_selection);
+      gtk_text_view_check_cursor_blink (text_view);
       gtk_text_view_pend_cursor_blink (text_view);
       return;
     }
@@ -4719,7 +4730,7 @@ gtk_text_view_move_cursor_internal (GtkTextView     *text_view,
       else if (count > 0) 
        {
          if (!gtk_text_iter_forward_visible_word_ends (&newplace, count))
-           gtk_text_iter_forward_to_end (&newplace);
+           gtk_text_iter_forward_to_line_end (&newplace);
        }
       break;
 
@@ -4729,15 +4740,14 @@ gtk_text_view_move_cursor_internal (GtkTextView     *text_view,
         if (gtk_text_view_move_iter_by_lines (text_view, &newplace, count))
           gtk_text_layout_move_iter_to_x (text_view->layout, &newplace, cursor_x_pos);
         else
-          /* we currently do not have a backward_to_start, use offset */
-          gtk_text_iter_set_offset (&newplace, 0);
+          gtk_text_iter_set_line_offset (&newplace, 0);
       }
       if (count > 0)
       {
         if (gtk_text_view_move_iter_by_lines (text_view, &newplace, count))
           gtk_text_layout_move_iter_to_x (text_view->layout, &newplace, cursor_x_pos);
         else
-          gtk_text_iter_forward_to_end (&newplace);
+          gtk_text_iter_forward_to_line_end (&newplace);
       }
       break;
 
@@ -4807,11 +4817,10 @@ gtk_text_view_move_cursor_internal (GtkTextView     *text_view,
                                                                     "insert"));
 
       if (step == GTK_MOVEMENT_DISPLAY_LINES)
-        {
-          gtk_text_view_set_virtual_cursor_pos (text_view, cursor_x_pos, -1);
-        }
+        gtk_text_view_set_virtual_cursor_pos (text_view, cursor_x_pos, -1);
     }
 
+  gtk_text_view_check_cursor_blink (text_view);
   gtk_text_view_pend_cursor_blink (text_view);
 }
 
@@ -5732,7 +5741,8 @@ gtk_text_view_start_selection_drag (GtkTextView       *text_view,
     }
 
   gtk_text_buffer_select_range (buffer, &end, &start);
-
+  gtk_text_view_check_cursor_blink (text_view);
+  
   text_view->selection_drag_handler = g_signal_connect (text_view,
                                                         "motion_notify_event",
                                                         G_CALLBACK (selection_motion_event_handler),
@@ -5977,17 +5987,62 @@ gtk_text_view_reset_im_context (GtkTextView *text_view)
     }
 }
 
+static gchar*
+_gtk_text_view_get_selected_text (GtkTextView *text_view)
+{
+  GtkTextBuffer *buffer;
+  GtkTextIter    start, end;
+  gchar         *text = NULL;
+
+  buffer = gtk_text_view_get_buffer (text_view);
+
+  if (gtk_text_buffer_get_selection_bounds (buffer, &start, &end))
+    text = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
+
+  return text;
+}
+
 /*
  * DND feature
  */
 
+static void
+drag_begin_cb (GtkWidget      *widget,
+               GdkDragContext *context,
+               gpointer        data)
+{
+  GtkTextView *text_view;
+  gchar *text;
+  GdkPixmap *pixmap = NULL;
+
+  g_signal_handlers_disconnect_by_func (widget, drag_begin_cb, NULL);
+
+  text_view = GTK_TEXT_VIEW (widget);
+
+  text   = _gtk_text_view_get_selected_text (text_view);
+  pixmap = _gtk_text_util_create_drag_icon (widget, text, -1);
+
+  if (pixmap)
+    gtk_drag_set_icon_pixmap (context,
+                              gdk_drawable_get_colormap (pixmap),
+                              pixmap,
+                              NULL,
+                              -2, -2);
+  else
+    gtk_drag_set_icon_default (context);
+  
+  if (pixmap)
+    g_object_unref (pixmap);
+  g_free (text);
+}
+
 static void
 gtk_text_view_start_selection_dnd (GtkTextView       *text_view,
                                    const GtkTextIter *iter,
                                    GdkEventMotion    *event)
 {
   GdkDragContext *context;
-  GtkTargetList *target_list;
+  GtkTargetList  *target_list;
 
   text_view->drag_start_x = -1;
   text_view->drag_start_y = -1;
@@ -5997,13 +6052,13 @@ gtk_text_view_start_selection_dnd (GtkTextView       *text_view,
                                      G_N_ELEMENTS (target_table));
   gtk_target_list_add_text_targets (target_list, 0);
 
+  g_signal_connect (text_view, "drag-begin", 
+                    G_CALLBACK (drag_begin_cb), NULL);
   context = gtk_drag_begin (GTK_WIDGET (text_view), target_list,
                             GDK_ACTION_COPY | GDK_ACTION_MOVE,
                             1, (GdkEvent*)event);
 
   gtk_target_list_unref (target_list);
-
-  gtk_drag_set_icon_default (context);
 }
 
 static void
@@ -6033,12 +6088,12 @@ gtk_text_view_drag_data_get (GtkWidget        *widget,
 
   text_view = GTK_TEXT_VIEW (widget);
 
-  if (selection_data->target == gdk_atom_intern ("GTK_TEXT_BUFFER_CONTENTS", FALSE))
+  if (selection_data->target == gdk_atom_intern_static_string ("GTK_TEXT_BUFFER_CONTENTS"))
     {
       GtkTextBuffer *buffer = gtk_text_view_get_buffer (text_view);
 
       gtk_selection_data_set (selection_data,
-                              gdk_atom_intern ("GTK_TEXT_BUFFER_CONTENTS", FALSE),
+                              gdk_atom_intern_static_string ("GTK_TEXT_BUFFER_CONTENTS"),
                               8, /* bytes */
                               (void*)&buffer,
                               sizeof (buffer));
@@ -6285,7 +6340,7 @@ gtk_text_view_drag_data_received (GtkWidget        *widget,
 
   gtk_text_buffer_begin_user_action (buffer);
 
-  if (selection_data->target == gdk_atom_intern ("GTK_TEXT_BUFFER_CONTENTS", FALSE))
+  if (selection_data->target == gdk_atom_intern_static_string ("GTK_TEXT_BUFFER_CONTENTS"))
     {
       GtkTextBuffer *src_buffer = NULL;
       GtkTextIter start, end;
@@ -6857,7 +6912,7 @@ append_action_signal (GtkTextView  *text_view,
 {
   GtkWidget *menuitem = gtk_image_menu_item_new_from_stock (stock_id, NULL);
 
-  g_object_set_data (G_OBJECT (menuitem), "gtk-signal", (char *)signal);
+  g_object_set_data (G_OBJECT (menuitem), I_("gtk-signal"), (char *)signal);
   g_signal_connect (menuitem, "activate",
                    G_CALLBACK (activate_cb), text_view);
 
@@ -7080,7 +7135,7 @@ popup_targets_received (GtkClipboard     *clipboard,
       gtk_widget_show (menuitem);
       gtk_menu_shell_append (GTK_MENU_SHELL (text_view->popup_menu), menuitem);
 
-      menuitem = gtk_menu_item_new_with_mnemonic (_("Select _All"));
+      menuitem = gtk_image_menu_item_new_from_stock (GTK_STOCK_SELECT_ALL, NULL);
       g_signal_connect (menuitem, "activate",
                        G_CALLBACK (select_all_cb), text_view);
       gtk_widget_show (menuitem);
@@ -7163,7 +7218,7 @@ gtk_text_view_do_popup (GtkTextView    *text_view,
 
   gtk_clipboard_request_contents (gtk_widget_get_clipboard (GTK_WIDGET (text_view),
                                                            GDK_SELECTION_CLIPBOARD),
-                                 gdk_atom_intern ("TARGETS", FALSE),
+                                 gdk_atom_intern_static_string ("TARGETS"),
                                  popup_targets_received,
                                  info);
 }
@@ -8045,7 +8100,7 @@ text_view_child_new_anchored (GtkWidget          *child,
   g_object_ref (vc->anchor);
 
   g_object_set_data (G_OBJECT (child),
-                     "gtk-text-view-child",
+                     I_("gtk-text-view-child"),
                      vc);
 
   gtk_text_child_anchor_register_child (anchor, child, layout);
@@ -8076,7 +8131,7 @@ text_view_child_new_window (GtkWidget          *child,
   vc->y = y;
 
   g_object_set_data (G_OBJECT (child),
-                     "gtk-text-view-child",
+                     I_("gtk-text-view-child"),
                      vc);
   
   return vc;
@@ -8086,7 +8141,7 @@ static void
 text_view_child_free (GtkTextViewChild *child)
 {
   g_object_set_data (G_OBJECT (child->widget),
-                     "gtk-text-view-child", NULL);
+                     I_("gtk-text-view-child"), NULL);
 
   if (child->anchor)
     {