Text buffer API



Hi,

I just finished a lot of API cleanup on the text widget, and I don't
know if I've ever posted the full API for review, so I'm going to do
so now, at my own peril. ;-) I'll do one object per mail, to keep
things manageable. Don't comment on code formatting, I have to
reindent the whole thing after I merge my branch to HEAD.

This first API is the text buffer, which is the "model" in the
model-view text widget architecture. Most manipulation of the buffer
goes via iterators, I'll post that header next.

Summary of signals:
 insert_text is a virtual function (also a signal) that inserts
 text in its default handler. The default handler also resets
 the passed-in iterator to point to the end of the inserted
 text. 

 delete_text is a virtual function/signal that deletes text in 
 a range. It resets both iterators to point to the same spot, 
 where the deleted text used to exist. (The default handler does 
 all the work)

 changed is a simple signal emitted after a change is made. This 
 is emitted from the default handler for insert_text and delete_text.

 modified_changed is emitted if the "modified" bit gets flipped 
 on or off. This is used to enable/disable a "save" menu item,
 for example.

 mark_set is a notification signal emitted after a mark is created or
 moved. It isn't a virtual function because in general the widget
 would break if you tried to override or intercept the mark-setting
 process.

 mark_deleted is notification if a mark disappears. It's
 notification-only for the same reason as mark_set

 apply_tag is a vfunc/signal whose default handler applies the 
 given tag to the given range of text.

 remove_tag is a vfunc/signal that removes all appearances of a tag
 in the given range.

Stuff that appears in the API:
 The "interactive" functions take into account whether the text being
 modified is editable or not. The default_editable argument for these 
 indicates whether untagged text is editable. (Tags can change the 
 editability of specific text ranges, so for example you can have 
 uneditable headers in your buffer.)

 A "slice" is a string that contains the Unicode unknown character as
 a stand-in for pixmaps or widgets found in the buffer. This 
 means that byte/char offsets in the returned string correspond 
 to offsets in the text buffer. If you get_text() instead of 
 get_slice(), you get only textual characters, but the offsets
 don't match the buffer. 

 "hidden characters" are enclosed in a tag that makes the characters
 invisible. Sometimes you want operations to impact these characters, 
 sometimes you don't.

 The place_cursor() function moves the cursor and the selection
 boundary at the same time; otherwise it would be very inefficient 
 to move the cursor from one end of the buffer to the other, because
 the whole buffer would be selected after you moved the cursor, but 
 before you moved the other end of the selection. (The selected area 
 of the buffer is the region between the cursor and a mark called
 selection_bound; if there's no selection, the two marks are in the 
 same place)

 find_string and find_regexp are going to be deleted; I made 
 find_string into gtk_text_iter_forward_search(), and find_regexp()
 won't make it in to 2.0 it looks like, since we can't find a 
 regexp implementation that supports Unicode.

So, that's it, I'll append this header.

Havoc
 
#ifndef GTK_TEXT_BUFFER_H
#define GTK_TEXT_BUFFER_H

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

/*
 * This is the PUBLIC representation of a text buffer.
 * GtkTextBTree is the PRIVATE internal representation of it.
 */

#include <gtk/gtkwidget.h>
#include <gtk/gtktexttagtable.h>
#include <gtk/gtktextiter.h>
#include <gtk/gtktextmark.h>

typedef struct _GtkTextBTree GtkTextBTree;

#define GTK_TYPE_TEXT_BUFFER            (gtk_text_buffer_get_type())
#define GTK_TEXT_BUFFER(obj)            (GTK_CHECK_CAST ((obj), GTK_TYPE_TEXT_BUFFER, GtkTextBuffer))
#define GTK_TEXT_BUFFER_CLASS(klass)    (GTK_CHECK_CLASS_CAST ((klass), GTK_TYPE_TEXT_BUFFER, GtkTextBufferClass))
#define GTK_IS_TEXT_BUFFER(obj)         (GTK_CHECK_TYPE ((obj), GTK_TYPE_TEXT_BUFFER))
#define GTK_IS_TEXT_BUFFER_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GTK_TYPE_TEXT_BUFFER))
#define GTK_TEXT_BUFFER_GET_CLASS(obj)  (GTK_CHECK_GET_CLASS ((obj), GTK_TYPE_TEXT_BUFFER, GtkTextBufferClass))

typedef struct _GtkTextBufferClass GtkTextBufferClass;

struct _GtkTextBuffer {
  GtkObject parent_instance;

  GtkTextTagTable *tag_table;
  GtkTextBTree *btree;

  /* Text currently pasted to the clipboard */
  gchar *clipboard_text;

  /* Whether the buffer has been modified since last save */
  gboolean modified;

  /* We use this for selections */
  GtkWidget *selection_widget;
  gboolean have_selection;
  gboolean selection_handlers_installed;
  gboolean paste_interactive;
  gboolean paste_default_editable;
};

struct _GtkTextBufferClass {
  GtkObjectClass parent_class;

  void (* insert_text)     (GtkTextBuffer *buffer,
                            GtkTextIter *pos,
                            const gchar *text,
                            gint length);


  void (* delete_text)     (GtkTextBuffer *buffer,
                            GtkTextIter *start,
                            GtkTextIter *end);

  /* Only for text changed, marks/tags don't cause this
     to be emitted */
  void (* changed)         (GtkTextBuffer *buffer);


  /* New value for the modified flag */
  void (* modified_changed)   (GtkTextBuffer *buffer);

  /* Mark moved or created */
  void (* mark_set)           (GtkTextBuffer *buffer,
                               const GtkTextIter *location,
                               GtkTextMark *mark);

  void (* mark_deleted)       (GtkTextBuffer *buffer,
                               GtkTextMark *mark);

  void (* apply_tag)          (GtkTextBuffer *buffer,
                               GtkTextTag *tag,
                               const GtkTextIter *start_char,
                               const GtkTextIter *end_char);

  void (* remove_tag)         (GtkTextBuffer *buffer,
                               GtkTextTag *tag,
                               const GtkTextIter *start_char,
                               const GtkTextIter *end_char);

};

GtkType        gtk_text_buffer_get_type       (void);



/* table is NULL to create a new one */
GtkTextBuffer *gtk_text_buffer_new            (GtkTextTagTable *table);
gint           gtk_text_buffer_get_line_count (GtkTextBuffer   *buffer);
gint           gtk_text_buffer_get_char_count (GtkTextBuffer   *buffer);


GtkTextTagTable* gtk_text_buffer_get_tag_table (GtkTextBuffer  *buffer);

/* Insert into the buffer */
void gtk_text_buffer_insert            (GtkTextBuffer *buffer,
                                        GtkTextIter   *iter,
                                        const gchar   *text,
                                        gint           len);
void gtk_text_buffer_insert_at_cursor  (GtkTextBuffer *buffer,
                                        const gchar   *text,
                                        gint           len);

gboolean gtk_text_buffer_insert_interactive           (GtkTextBuffer *buffer,
                                                       GtkTextIter   *iter,
                                                       const gchar   *text,
                                                       gint           len,
                                                       gboolean       default_editable);
gboolean gtk_text_buffer_insert_interactive_at_cursor (GtkTextBuffer *buffer,
                                                       const gchar   *text,
                                                       gint           len,
                                                       gboolean       default_editable);


/* Delete from the buffer */
void     gtk_text_buffer_delete             (GtkTextBuffer *buffer,
                                             GtkTextIter   *start_iter,
                                             GtkTextIter   *end_iter);
gboolean gtk_text_buffer_delete_interactive (GtkTextBuffer *buffer,
                                             GtkTextIter   *start_iter,
                                             GtkTextIter   *end_iter,
                                             gboolean       default_editable);



/* Obtain strings from the buffer */
gchar          *gtk_text_buffer_get_text            (GtkTextBuffer     *buffer,
                                                     const GtkTextIter *start_iter,
                                                     const GtkTextIter *end_iter,
                                                     gboolean           include_hidden_chars);

gchar          *gtk_text_buffer_get_slice           (GtkTextBuffer     *buffer,
                                                     const GtkTextIter *start_iter,
                                                     const GtkTextIter *end_iter,
                                                     gboolean           include_hidden_chars);

/* Insert a pixmap */
void gtk_text_buffer_insert_pixmap         (GtkTextBuffer *buffer,
                                            GtkTextIter   *iter,
                                            GdkPixmap     *pixmap,
                                            GdkBitmap     *mask);

/* Mark manipulation */
GtkTextMark   *gtk_text_buffer_create_mark (GtkTextBuffer     *buffer,
                                            const gchar       *mark_name,
                                            const GtkTextIter *where,
                                            gboolean           left_gravity);
void           gtk_text_buffer_move_mark   (GtkTextBuffer     *buffer,
                                            GtkTextMark       *mark,
                                            const GtkTextIter *where);
void           gtk_text_buffer_delete_mark (GtkTextBuffer     *buffer,
                                            GtkTextMark       *mark);
GtkTextMark   *gtk_text_buffer_get_mark    (GtkTextBuffer     *buffer,
                                            const gchar       *name);


/* efficiently move insert and selection_bound to same location */
void gtk_text_buffer_place_cursor (GtkTextBuffer     *buffer,
                                   const GtkTextIter *where);



/* Tag manipulation */
void gtk_text_buffer_apply_tag             (GtkTextBuffer     *buffer,
                                            GtkTextTag        *tag,
                                            const GtkTextIter *start_index,
                                            const GtkTextIter *end_index);
void gtk_text_buffer_remove_tag            (GtkTextBuffer     *buffer,
                                            GtkTextTag        *tag,
                                            const GtkTextIter *start_index,
                                            const GtkTextIter *end_index);
void gtk_text_buffer_apply_tag_by_name     (GtkTextBuffer     *buffer,
                                            const gchar       *name,
                                            const GtkTextIter *start_index,
                                            const GtkTextIter *end_index);
void gtk_text_buffer_remove_tag_by_name    (GtkTextBuffer     *buffer,
                                            const gchar       *name,
                                            const GtkTextIter *start_index,
                                            const GtkTextIter *end_index);




/* You can either ignore the return value, or use it to
 * set the attributes of the tag. tag_name can be NULL
 */
GtkTextTag    *gtk_text_buffer_create_tag (GtkTextBuffer *buffer,
                                           const gchar   *tag_name);

/* Obtain iterators pointed at various places, then you can move the
   iterator around using the GtkTextIter operators */
void gtk_text_buffer_get_iter_at_line_offset (GtkTextBuffer *buffer,
                                              GtkTextIter   *iter,
                                              gint           line_number,
                                              gint           char_offset);
void gtk_text_buffer_get_iter_at_offset      (GtkTextBuffer *buffer,
                                              GtkTextIter   *iter,
                                              gint           char_offset);
void gtk_text_buffer_get_iter_at_line        (GtkTextBuffer *buffer,
                                              GtkTextIter   *iter,
                                              gint           line_number);
void gtk_text_buffer_get_last_iter           (GtkTextBuffer *buffer,
                                              GtkTextIter   *iter);
void gtk_text_buffer_get_bounds              (GtkTextBuffer *buffer,
                                              GtkTextIter   *start,
                                              GtkTextIter   *end);
void gtk_text_buffer_get_iter_at_mark        (GtkTextBuffer *buffer,
                                              GtkTextIter   *iter,
                                              GtkTextMark   *mark);



/* There's no get_first_iter because you just get the iter for
   line or char 0 */

GSList         *gtk_text_buffer_get_tags (GtkTextBuffer     *buffer,
                                          const GtkTextIter *iter);


/* Used to keep track of whether the buffer needs saving; anytime the
   buffer contents change, the modified flag is turned on. Whenever
   you save, turn it off. Tags and marks do not affect the modified
   flag, but if you would like them to you can connect a handler to
   the tag/mark signals and call set_modified in your handler */

gboolean        gtk_text_buffer_modified                (GtkTextBuffer *buffer);
void            gtk_text_buffer_set_modified            (GtkTextBuffer *buffer,
                                                         gboolean       setting);
void            gtk_text_buffer_set_clipboard_contents  (GtkTextBuffer *buffer,
                                                         const gchar   *text);
const gchar    *gtk_text_buffer_get_clipboard_contents  (GtkTextBuffer *buffer);


void            gtk_text_buffer_paste_primary_selection (GtkTextBuffer *buffer,
                                                         GtkTextIter   *override_location,
                                                         guint32        time,
                                                         gboolean       interactive,
                                                         gboolean       default_editable);
gboolean        gtk_text_buffer_delete_selection        (GtkTextBuffer *buffer,
                                                         gboolean       interactive,
                                                         gboolean       default_editable);
void            gtk_text_buffer_cut                     (GtkTextBuffer *buffer,
                                                         guint32        time,
                                                         gboolean       interactive,
                                                         gboolean       default_editable);
void            gtk_text_buffer_copy                    (GtkTextBuffer *buffer,
                                                         guint32        time);
void            gtk_text_buffer_paste_clipboard         (GtkTextBuffer *buffer,
                                                         guint32        time,
                                                         gboolean       interactive,
                                                         gboolean       default_editable);
gboolean        gtk_text_buffer_get_selection_bounds    (GtkTextBuffer *buffer,
                                                         GtkTextIter   *start,
                                                         GtkTextIter   *end);


/* This function is not implemented. */
gboolean gtk_text_buffer_find_string(GtkTextBuffer *buffer,
                                     GtkTextIter *iter,
                                     const gchar *str,
                                     const GtkTextIter *start,
                                     const GtkTextIter *end);

#if 0
/* Waiting on glib 1.4 regexp facility */
gboolean gtk_text_buffer_find_regexp(GtkTextBuffer *buffer,
                                     GRegexp *regexp,
                                     const GtkTextIter *start,
                                     const GtkTextIter *end);
#endif

/* INTERNAL private stuff */
void            gtk_text_buffer_spew                   (GtkTextBuffer      *buffer);

GtkTextBTree*   _gtk_text_buffer_get_btree             (GtkTextBuffer      *buffer);

#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif
 
 
 




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]