r1327@localhost: muntyan | 2005-12-10 13:57:46 -0600
Made moving/deleting line marks more safe
This commit is contained in:
parent
ce6049cb8c
commit
b7fea6f2cd
@ -57,6 +57,8 @@ static void moo_line_mark_changed (MooLineMark *mark);
|
||||
static void update_background_gc (MooLineMark *mark);
|
||||
static void update_pixbuf (MooLineMark *mark);
|
||||
|
||||
static void moo_line_mark_deleted_real (MooLineMark *mark);
|
||||
|
||||
|
||||
enum {
|
||||
CHANGED,
|
||||
@ -73,8 +75,6 @@ enum {
|
||||
PROP_BACKGROUND_SET,
|
||||
PROP_PIXBUF,
|
||||
PROP_STOCK_ID,
|
||||
PROP_BUFFER,
|
||||
PROP_LINE,
|
||||
PROP_NAME,
|
||||
PROP_VISIBLE
|
||||
};
|
||||
@ -93,6 +93,8 @@ moo_line_mark_class_init (MooLineMarkClass *klass)
|
||||
gobject_class->get_property = moo_line_mark_get_property;
|
||||
gobject_class->finalize = moo_line_mark_finalize;
|
||||
|
||||
klass->deleted = moo_line_mark_deleted_real;
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_BACKGROUND,
|
||||
g_param_spec_string ("background",
|
||||
@ -117,22 +119,6 @@ moo_line_mark_class_init (MooLineMarkClass *klass)
|
||||
FALSE,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_BUFFER,
|
||||
g_param_spec_object ("buffer",
|
||||
"buffer",
|
||||
"buffer",
|
||||
MOO_TYPE_TEXT_BUFFER,
|
||||
G_PARAM_READABLE));
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_LINE,
|
||||
g_param_spec_int ("line",
|
||||
"line",
|
||||
"line",
|
||||
0, 10000000, 0,
|
||||
G_PARAM_READABLE));
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_NAME,
|
||||
g_param_spec_string ("name",
|
||||
@ -269,14 +255,6 @@ moo_line_mark_get_property (GObject *object,
|
||||
g_value_set_boolean (value, mark->priv->background_set != 0);
|
||||
break;
|
||||
|
||||
case PROP_BUFFER:
|
||||
g_value_set_object (value, mark->priv->buffer);
|
||||
break;
|
||||
|
||||
case PROP_LINE:
|
||||
g_value_set_int (value, mark->priv->line_no);
|
||||
break;
|
||||
|
||||
case PROP_NAME:
|
||||
g_value_set_string (value, mark->priv->name);
|
||||
break;
|
||||
@ -431,20 +409,12 @@ _moo_line_mark_set_line (MooLineMark *mark,
|
||||
int line_no,
|
||||
guint stamp)
|
||||
{
|
||||
gboolean moved = FALSE;
|
||||
|
||||
g_assert (MOO_IS_LINE_MARK (mark));
|
||||
g_assert (mark->priv->buffer != NULL);
|
||||
|
||||
if (mark->priv->line_no != line_no)
|
||||
moved = TRUE;
|
||||
g_assert (!line || mark->priv->buffer != NULL);
|
||||
|
||||
mark->priv->line = line;
|
||||
mark->priv->line_no = line_no;
|
||||
mark->priv->stamp = stamp;
|
||||
|
||||
if (moved)
|
||||
g_object_notify (G_OBJECT (mark), "line");
|
||||
}
|
||||
|
||||
|
||||
@ -463,9 +433,12 @@ _moo_line_mark_set_buffer (MooLineMark *mark,
|
||||
{
|
||||
g_assert (MOO_IS_LINE_MARK (mark));
|
||||
g_assert (!buffer || mark->priv->buffer == NULL);
|
||||
|
||||
mark->priv->buffer = buffer;
|
||||
mark->priv->line_buf = line_buf;
|
||||
g_object_notify (G_OBJECT (mark), "buffer");
|
||||
|
||||
if (!buffer)
|
||||
_moo_line_mark_set_line (mark, NULL, -1, 0);
|
||||
}
|
||||
|
||||
|
||||
@ -477,15 +450,26 @@ moo_line_mark_get_buffer (MooLineMark *mark)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
moo_line_mark_deleted_real (MooLineMark *mark)
|
||||
{
|
||||
_moo_line_mark_set_buffer (mark, NULL, NULL);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_moo_line_mark_deleted (MooLineMark *mark)
|
||||
{
|
||||
g_assert (MOO_IS_LINE_MARK (mark));
|
||||
mark->priv->buffer = NULL;
|
||||
mark->priv->line_buf = NULL;
|
||||
mark->priv->line = NULL;
|
||||
mark->priv->line_no = -1;
|
||||
g_object_notify (G_OBJECT (mark), "buffer");
|
||||
MOO_LINE_MARK_GET_CLASS (mark)->deleted (mark);
|
||||
}
|
||||
|
||||
|
||||
gboolean
|
||||
moo_line_mark_get_deleted (MooLineMark *mark)
|
||||
{
|
||||
g_return_val_if_fail (MOO_IS_LINE_MARK (mark), TRUE);
|
||||
return mark->priv->buffer == NULL;
|
||||
}
|
||||
|
||||
|
||||
|
@ -43,7 +43,12 @@ struct _MooLineMark
|
||||
struct _MooLineMarkClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
|
||||
/* signal */
|
||||
void (*changed) (MooLineMark *mark);
|
||||
|
||||
/* method */
|
||||
void (*deleted) (MooLineMark *mark);
|
||||
};
|
||||
|
||||
|
||||
@ -62,6 +67,8 @@ int moo_line_mark_get_line (MooLineMark *mark);
|
||||
MooTextBuffer *moo_line_mark_get_buffer (MooLineMark *mark);
|
||||
gboolean moo_line_mark_get_visible (MooLineMark *mark);
|
||||
|
||||
gboolean moo_line_mark_get_deleted (MooLineMark *mark);
|
||||
|
||||
void moo_line_mark_set_stock_id (MooLineMark *mark,
|
||||
const char *stock_id);
|
||||
void moo_line_mark_set_pixbuf (MooLineMark *mark,
|
||||
|
@ -478,7 +478,7 @@ moo_text_buffer_insert_text (GtkTextBuffer *text_buffer,
|
||||
first_line, last_line - first_line,
|
||||
tag);
|
||||
|
||||
/* XXX btree can do it better */
|
||||
/* XXX btree can do it better ? i guess it can't */
|
||||
if (starts_line && ins_line)
|
||||
{
|
||||
GSList *l, *marks;
|
||||
@ -503,6 +503,36 @@ moo_text_buffer_insert_text (GtkTextBuffer *text_buffer,
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
marks_moved_or_deleted (MooTextBuffer *buffer,
|
||||
GSList *moved,
|
||||
GSList *deleted)
|
||||
{
|
||||
GSList *l;
|
||||
|
||||
if (!moved && !deleted)
|
||||
return;
|
||||
|
||||
g_slist_foreach (moved, (GFunc) g_object_ref, NULL);
|
||||
g_slist_foreach (deleted, (GFunc) g_object_ref, NULL);
|
||||
|
||||
for (l = deleted; l != NULL; l = l->next)
|
||||
_moo_line_mark_set_buffer (l->data, NULL, NULL);
|
||||
|
||||
for (l = deleted; l != NULL; l = l->next)
|
||||
{
|
||||
line_mark_deleted (buffer, l->data);
|
||||
g_object_unref (l->data);
|
||||
}
|
||||
|
||||
for (l = moved; l != NULL; l = l->next)
|
||||
if (!moo_line_mark_get_deleted (l->data))
|
||||
line_mark_moved (buffer, l->data);
|
||||
|
||||
g_slist_foreach (deleted, (GFunc) g_object_unref, NULL);
|
||||
g_slist_foreach (moved, (GFunc) g_object_unref, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
moo_text_buffer_delete_range (GtkTextBuffer *text_buffer,
|
||||
GtkTextIter *start,
|
||||
@ -511,7 +541,7 @@ moo_text_buffer_delete_range (GtkTextBuffer *text_buffer,
|
||||
MooTextBuffer *buffer = MOO_TEXT_BUFFER (text_buffer);
|
||||
int first_line, last_line;
|
||||
gboolean starts_line;
|
||||
GSList *deleted_marks = NULL, *moved_marks = NULL, *l;
|
||||
GSList *deleted_marks = NULL, *moved_marks = NULL;
|
||||
|
||||
gtk_text_iter_order (start, end);
|
||||
|
||||
@ -556,18 +586,14 @@ moo_text_buffer_delete_range (GtkTextBuffer *text_buffer,
|
||||
first_line);
|
||||
}
|
||||
|
||||
/* XXX */
|
||||
for (l = deleted_marks; l != NULL; l = l->next)
|
||||
line_mark_deleted (buffer, l->data);
|
||||
for (l = deleted_marks; l != NULL; l = l->next)
|
||||
g_object_unref (l->data);
|
||||
/* It would be better if marks were moved/deleted before deleting text, but it
|
||||
could cause problems with invalidated iters. if they were deleted after
|
||||
deleting text, it would be even worse since our btree and gtk btree would not
|
||||
be syncronized when callbacks are called. So doing it here is safest (though
|
||||
not most simple or clean) */
|
||||
marks_moved_or_deleted (buffer, moved_marks, deleted_marks);
|
||||
g_slist_free (deleted_marks);
|
||||
|
||||
while (moved_marks)
|
||||
{
|
||||
line_mark_moved (buffer, moved_marks->data);
|
||||
moved_marks = g_slist_delete_link (moved_marks, moved_marks);
|
||||
}
|
||||
g_slist_free (moved_marks);
|
||||
|
||||
if (last_line - first_line < 2)
|
||||
_moo_text_buffer_ensure_highlight (buffer, first_line, last_line);
|
||||
@ -1742,14 +1768,10 @@ moo_text_buffer_remove_line_mark (MooTextBuffer *buffer,
|
||||
g_return_if_fail (MOO_IS_LINE_MARK (mark));
|
||||
g_return_if_fail (moo_line_mark_get_buffer (mark) == buffer);
|
||||
|
||||
g_object_freeze_notify (G_OBJECT (mark));
|
||||
|
||||
line = moo_line_mark_get_line (mark);
|
||||
moo_line_buffer_remove_mark (buffer->priv->line_buf, mark);
|
||||
|
||||
line_mark_deleted (buffer, mark);
|
||||
|
||||
g_object_thaw_notify (G_OBJECT (mark));
|
||||
g_object_unref (mark);
|
||||
}
|
||||
|
||||
@ -1766,6 +1788,7 @@ static void
|
||||
line_mark_deleted (MooTextBuffer *buffer,
|
||||
MooLineMark *mark)
|
||||
{
|
||||
_moo_line_mark_set_buffer (mark, NULL, NULL);
|
||||
_moo_line_mark_deleted (mark);
|
||||
g_signal_emit (buffer, signals[LINE_MARK_DELETED], 0, mark);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user