Text buffer API
- From: Havoc Pennington <hp redhat com>
- To: gtk-devel-list gnome org
- Subject: Text buffer API
- Date: 10 Jul 2000 14:55:30 -0400
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]