]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtktextbuffer.c
Use a priv pointer for cheap access to the priv struct. (#327725,
[~andy/gtk] / gtk / gtktextbuffer.c
index 1bb9ec9fa60268c03bdac2587b3a1da006bbeef0..e65c71bf3afa93b63d49dcc9833918cd0fd03c54 100644 (file)
@@ -41,6 +41,7 @@
 #include "gtkintl.h"
 #include "gtkalias.h"
 
+
 typedef struct _ClipboardRequest ClipboardRequest;
 
 struct _ClipboardRequest
@@ -72,7 +73,11 @@ enum {
   PROP_0,
 
   /* Construct */
-  PROP_TAG_TABLE
+  PROP_TAG_TABLE,
+  
+  /* Normal */
+  PROP_TEXT,
+  PROP_HAS_SELECTION
 };
 
 enum {
@@ -110,6 +115,9 @@ static void gtk_text_buffer_real_remove_tag            (GtkTextBuffer     *buffe
                                                         const GtkTextIter *start_char,
                                                         const GtkTextIter *end_char);
 static void gtk_text_buffer_real_changed               (GtkTextBuffer     *buffer);
+static void gtk_text_buffer_real_mark_set              (GtkTextBuffer     *buffer,
+                                                        const GtkTextIter *iter,
+                                                        GtkTextMark       *mark);
 
 static GtkTextBTree* get_btree (GtkTextBuffer *buffer);
 static void          free_log_attr_cache (GtkTextLogAttrCache *cache);
@@ -152,7 +160,7 @@ gtk_text_buffer_get_type (void)
         (GInstanceInitFunc) gtk_text_buffer_init
       };
 
-      our_type = g_type_register_static (G_TYPE_OBJECT, "GtkTextBuffer",
+      our_type = g_type_register_static (G_TYPE_OBJECT, I_("GtkTextBuffer"),
                                          &our_info, 0);
     }
 
@@ -177,6 +185,7 @@ gtk_text_buffer_class_init (GtkTextBufferClass *klass)
   klass->apply_tag = gtk_text_buffer_real_apply_tag;
   klass->remove_tag = gtk_text_buffer_real_remove_tag;
   klass->changed = gtk_text_buffer_real_changed;
+  klass->mark_set = gtk_text_buffer_real_mark_set;
 
   /* Construct */
   g_object_class_install_property (object_class,
@@ -187,8 +196,41 @@ gtk_text_buffer_class_init (GtkTextBufferClass *klass)
                                                         GTK_TYPE_TEXT_TAG_TABLE,
                                                         GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
 
+  /* Normal properties*/
+  
+  /**
+   * GtkTextBuffer:text:
+   *
+   * The text content of the buffer. Without child widgets and images,
+   * see gtk_text_buffer_get_text () for more information.
+   *
+   * Since: 2.8
+   */
+  g_object_class_install_property (object_class,
+                                   PROP_TEXT,
+                                   g_param_spec_string ("text",
+                                                        P_("Text"),
+                                                        P_("Current text of the buffer"),
+                                                       "",
+                                                        GTK_PARAM_READWRITE));
+
+  /**
+   * GtkTextBuffer:has-selection:
+   *
+   * Whether the buffer has some text currently selected.
+   *
+   * Since: 2.10
+   */
+  g_object_class_install_property (object_class,
+                                   PROP_HAS_SELECTION,
+                                   g_param_spec_boolean ("has-selection",
+                                                         P_("Has selection"),
+                                                         P_("Whether the buffer has some text currently selected"),
+                                                         FALSE,
+                                                         G_PARAM_READABLE));
+
   signals[INSERT_TEXT] =
-    g_signal_new ("insert_text",
+    g_signal_new (I_("insert_text"),
                   G_OBJECT_CLASS_TYPE (object_class),
                   G_SIGNAL_RUN_LAST,
                   G_STRUCT_OFFSET (GtkTextBufferClass, insert_text),
@@ -201,7 +243,7 @@ gtk_text_buffer_class_init (GtkTextBufferClass *klass)
                   G_TYPE_INT);
 
   signals[INSERT_PIXBUF] =
-    g_signal_new ("insert_pixbuf",
+    g_signal_new (I_("insert_pixbuf"),
                   G_OBJECT_CLASS_TYPE (object_class),
                   G_SIGNAL_RUN_LAST,
                   G_STRUCT_OFFSET (GtkTextBufferClass, insert_pixbuf),
@@ -213,7 +255,7 @@ gtk_text_buffer_class_init (GtkTextBufferClass *klass)
                   GDK_TYPE_PIXBUF);
 
   signals[INSERT_CHILD_ANCHOR] =
-    g_signal_new ("insert_child_anchor",
+    g_signal_new (I_("insert_child_anchor"),
                   G_OBJECT_CLASS_TYPE (object_class),
                   G_SIGNAL_RUN_LAST,
                   G_STRUCT_OFFSET (GtkTextBufferClass, insert_child_anchor),
@@ -238,7 +280,7 @@ gtk_text_buffer_class_init (GtkTextBufferClass *klass)
    * those don't have access to the deleted text.
    */
   signals[DELETE_RANGE] =
-    g_signal_new ("delete_range",
+    g_signal_new (I_("delete_range"),
                   G_OBJECT_CLASS_TYPE (object_class),
                   G_SIGNAL_RUN_LAST,
                   G_STRUCT_OFFSET (GtkTextBufferClass, delete_range),
@@ -250,7 +292,7 @@ gtk_text_buffer_class_init (GtkTextBufferClass *klass)
                   GTK_TYPE_TEXT_ITER | G_SIGNAL_TYPE_STATIC_SCOPE);
 
   signals[CHANGED] =
-    g_signal_new ("changed",
+    g_signal_new (I_("changed"),
                   G_OBJECT_CLASS_TYPE (object_class),
                   G_SIGNAL_RUN_LAST,                   
                   G_STRUCT_OFFSET (GtkTextBufferClass, changed),
@@ -260,7 +302,7 @@ gtk_text_buffer_class_init (GtkTextBufferClass *klass)
                   0);
 
   signals[MODIFIED_CHANGED] =
-    g_signal_new ("modified_changed",
+    g_signal_new (I_("modified_changed"),
                   G_OBJECT_CLASS_TYPE (object_class),
                   G_SIGNAL_RUN_LAST,
                   G_STRUCT_OFFSET (GtkTextBufferClass, modified_changed),
@@ -270,7 +312,7 @@ gtk_text_buffer_class_init (GtkTextBufferClass *klass)
                   0);
 
   signals[MARK_SET] =
-    g_signal_new ("mark_set",
+    g_signal_new (I_("mark_set"),
                   G_OBJECT_CLASS_TYPE (object_class),
                   G_SIGNAL_RUN_LAST,                   
                   G_STRUCT_OFFSET (GtkTextBufferClass, mark_set),
@@ -282,7 +324,7 @@ gtk_text_buffer_class_init (GtkTextBufferClass *klass)
                   GTK_TYPE_TEXT_MARK);
 
   signals[MARK_DELETED] =
-    g_signal_new ("mark_deleted",
+    g_signal_new (I_("mark_deleted"),
                   G_OBJECT_CLASS_TYPE (object_class),
                   G_SIGNAL_RUN_LAST,                   
                   G_STRUCT_OFFSET (GtkTextBufferClass, mark_deleted),
@@ -293,7 +335,7 @@ gtk_text_buffer_class_init (GtkTextBufferClass *klass)
                   GTK_TYPE_TEXT_MARK);
   
   signals[APPLY_TAG] =
-    g_signal_new ("apply_tag",
+    g_signal_new (I_("apply_tag"),
                   G_OBJECT_CLASS_TYPE (object_class),
                   G_SIGNAL_RUN_LAST,
                   G_STRUCT_OFFSET (GtkTextBufferClass, apply_tag),
@@ -306,7 +348,7 @@ gtk_text_buffer_class_init (GtkTextBufferClass *klass)
                   GTK_TYPE_TEXT_ITER);
 
   signals[REMOVE_TAG] =
-    g_signal_new ("remove_tag",
+    g_signal_new (I_("remove_tag"),
                   G_OBJECT_CLASS_TYPE (object_class),
                   G_SIGNAL_RUN_LAST,
                   G_STRUCT_OFFSET (GtkTextBufferClass, remove_tag),
@@ -319,7 +361,7 @@ gtk_text_buffer_class_init (GtkTextBufferClass *klass)
                   GTK_TYPE_TEXT_ITER);
 
   signals[BEGIN_USER_ACTION] =
-    g_signal_new ("begin_user_action",
+    g_signal_new (I_("begin_user_action"),
                   G_OBJECT_CLASS_TYPE (object_class),
                   G_SIGNAL_RUN_LAST,                   
                   G_STRUCT_OFFSET (GtkTextBufferClass, begin_user_action),
@@ -329,7 +371,7 @@ gtk_text_buffer_class_init (GtkTextBufferClass *klass)
                   0);
 
   signals[END_USER_ACTION] =
-    g_signal_new ("end_user_action",
+    g_signal_new (I_("end_user_action"),
                   G_OBJECT_CLASS_TYPE (object_class),
                   G_SIGNAL_RUN_LAST,                   
                   G_STRUCT_OFFSET (GtkTextBufferClass, end_user_action),
@@ -386,6 +428,11 @@ gtk_text_buffer_set_property (GObject         *object,
     case PROP_TAG_TABLE:
       set_table (text_buffer, g_value_get_object (value));
       break;
+      
+    case PROP_TEXT:
+      gtk_text_buffer_set_text (text_buffer, 
+                               g_value_get_string (value), -1);
+      break;
 
     default:
       break;
@@ -407,6 +454,22 @@ gtk_text_buffer_get_property (GObject         *object,
     case PROP_TAG_TABLE:
       g_value_set_object (value, get_table (text_buffer));
       break;
+      
+    case PROP_TEXT:
+    {
+      GtkTextIter start, end;
+      
+      gtk_text_buffer_get_start_iter (text_buffer, &start);
+      gtk_text_buffer_get_end_iter (text_buffer, &end);
+           
+      g_value_set_string (value,
+                         gtk_text_buffer_get_text (text_buffer, &start, &end, FALSE));
+      break;
+    }
+
+    case PROP_HAS_SELECTION:
+      g_value_set_boolean (value, text_buffer->has_selection);
+      break;
 
     default:
       break;
@@ -524,8 +587,12 @@ gtk_text_buffer_set_text (GtkTextBuffer *buffer,
       gtk_text_buffer_get_iter_at_offset (buffer, &start, 0);
       gtk_text_buffer_insert (buffer, &start, text, len);
     }
+  
+  g_object_notify (G_OBJECT (buffer), "text");
 }
 
+
 /*
  * Insertion
  */
@@ -813,7 +880,6 @@ insert_range_untagged (GtkTextBuffer     *buffer,
   GtkTextIter range_start;
   GtkTextIter range_end;
   GtkTextIter start, end;
-  GtkTextBuffer *src_buffer;
   Range *r;
   
   if (gtk_text_iter_equal (orig_start, orig_end))
@@ -822,8 +888,6 @@ insert_range_untagged (GtkTextBuffer     *buffer,
   start = *orig_start;
   end = *orig_end;
   
-  src_buffer = gtk_text_iter_get_buffer (&start);
-  
   range_start = start;
   range_end = start;
   
@@ -929,13 +993,10 @@ insert_range_not_inside_self (GtkTextBuffer     *buffer,
   GtkTextIter end = *orig_end;
   GtkTextIter range_start;
   GtkTextIter range_end;
-  GtkTextBuffer *src_buffer;
   
   if (gtk_text_iter_equal (orig_start, orig_end))
     return;
   
-  src_buffer = gtk_text_iter_get_buffer (orig_start);
-  
   gtk_text_iter_order (&start, &end);
 
   range_start = start;
@@ -2160,6 +2221,28 @@ gtk_text_buffer_real_changed (GtkTextBuffer *buffer)
   gtk_text_buffer_set_modified (buffer, TRUE);
 }
 
+static void
+gtk_text_buffer_real_mark_set (GtkTextBuffer *buffer,
+                               const GtkTextIter *iter,
+                               GtkTextMark *mark)
+{
+  if (mark == gtk_text_buffer_get_insert (buffer) ||
+      mark == gtk_text_buffer_get_selection_bound (buffer))
+    {
+      gboolean has_selection;
+
+      has_selection = gtk_text_buffer_get_selection_bounds (buffer,
+                                                            NULL,
+                                                            NULL);
+
+      if (has_selection != buffer->has_selection)
+        {
+          buffer->has_selection = has_selection;
+          g_object_notify (G_OBJECT (buffer), "has-selection");
+        }
+    }
+}
+
 static void
 gtk_text_buffer_emit_tag (GtkTextBuffer *buffer,
                           GtkTextTag *tag,
@@ -2662,6 +2745,24 @@ gtk_text_buffer_set_modified (GtkTextBuffer      *buffer,
     }
 }
 
+/**
+ * gtk_text_buffer_get_has_selection:
+ * @buffer: a #GtkTextBuffer 
+ * 
+ * Indicates whether the buffer has some text currently selected.
+ * 
+ * Return value: %TRUE if the there is text selected
+ *
+ * Since: 2.10
+ **/
+gboolean
+gtk_text_buffer_get_has_selection (GtkTextBuffer *buffer)
+{
+  g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), FALSE);
+
+  return buffer->has_selection;
+}
+
 
 /*
  * Assorted other stuff
@@ -2740,13 +2841,13 @@ clipboard_get_selection_cb (GtkClipboard     *clipboard,
   if (gtk_text_buffer_get_selection_bounds (buffer, &start, &end))
     {
       if (selection_data->target ==
-          gdk_atom_intern ("GTK_TEXT_BUFFER_CONTENTS", FALSE))
+          gdk_atom_intern_static_string ("GTK_TEXT_BUFFER_CONTENTS"))
         {
           /* Provide the address of the buffer; this will only be
            * used within-process
            */
           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));
@@ -2769,7 +2870,7 @@ create_clipboard_contents_buffer (GtkTextBuffer *buffer)
 
   contents = gtk_text_buffer_new (gtk_text_buffer_get_tag_table (buffer));
 
-  g_object_set_data (G_OBJECT (contents), "gtk-text-buffer-clipboard", GINT_TO_POINTER (1));
+  g_object_set_data (G_OBJECT (contents), I_("gtk-text-buffer-clipboard"), GINT_TO_POINTER (1));
   
   return contents;
 }
@@ -2788,13 +2889,13 @@ clipboard_get_contents_cb (GtkClipboard     *clipboard,
   g_assert (contents); /* This should never be called unless we own the clipboard */
 
   if (selection_data->target ==
-      gdk_atom_intern ("GTK_TEXT_BUFFER_CONTENTS", FALSE))
+      gdk_atom_intern_static_string ("GTK_TEXT_BUFFER_CONTENTS"))
     {
       /* Provide the address of the clipboard buffer; this will only
        * be used within-process. OK to supply a NULL value for contents.
        */
       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*)&contents,
                               sizeof (contents));
@@ -2892,6 +2993,13 @@ post_paste_cleanup (ClipboardRequest *request_data)
     }
 }
 
+static void
+free_clipboard_request (ClipboardRequest *request_data)
+{
+  g_object_unref (request_data->buffer);
+  g_free (request_data);
+}
+
 /* Called when we request a paste and receive the text data
  */
 static void
@@ -2924,8 +3032,7 @@ clipboard_text_received (GtkClipboard *clipboard,
        gtk_text_buffer_end_user_action (buffer);
     }
 
-  g_object_unref (buffer);
-  g_free (request_data);
+  free_clipboard_request (request_data);
 }
 
 static GtkTextBuffer*
@@ -2945,7 +3052,7 @@ selection_data_get_buffer (GtkSelectionData *selection_data,
   if (gdk_window_get_window_type (owner) == GDK_WINDOW_FOREIGN)
     return NULL;
  
-  if (selection_data->type != gdk_atom_intern ("GTK_TEXT_BUFFER_CONTENTS", FALSE))
+  if (selection_data->type != gdk_atom_intern_static_string ("GTK_TEXT_BUFFER_CONTENTS"))
     return NULL;
 
   if (selection_data->length != sizeof (src_buffer))
@@ -3027,7 +3134,8 @@ paste_from_buffer (ClipboardRequest    *request_data,
     gtk_text_buffer_end_user_action (buffer);
 
   g_object_unref (src_buffer);
-  g_free (request_data);
+
+  free_clipboard_request (request_data);
 }
 
 static void
@@ -3248,8 +3356,7 @@ gtk_text_buffer_paste_clipboard (GtkTextBuffer *buffer,
                                  "gtk_paste_point_override",
                                  override_location, FALSE);
 
-  data->buffer = buffer;
-  g_object_ref (buffer);
+  data->buffer = g_object_ref (buffer);
   data->interactive = TRUE;
   data->default_editable = default_editable;
 
@@ -3268,7 +3375,7 @@ gtk_text_buffer_paste_clipboard (GtkTextBuffer *buffer,
     data->replace_selection = TRUE;
 
   gtk_clipboard_request_contents (clipboard,
-                                 gdk_atom_intern ("GTK_TEXT_BUFFER_CONTENTS", FALSE),
+                                 gdk_atom_intern_static_string ("GTK_TEXT_BUFFER_CONTENTS"),
                                  clipboard_clipboard_buffer_received, data);
 }