Don't abort on copy/paste; still broken

master
Yevgen Muntyan 2006-04-24 05:13:52 -05:00
parent e2a5772998
commit 7f0d50c345
4 changed files with 135 additions and 49 deletions

View File

@ -56,6 +56,7 @@ void _moo_text_buffer_apply_syntax_tag (MooTextBuffer *buffer,
void _moo_text_buffer_highlighting_changed (MooTextBuffer *buffer,
int first,
int last);
gboolean _moo_text_buffer_has_placeholders (MooTextBuffer *buffer);
G_END_DECLS

View File

@ -16,6 +16,7 @@
#include "mooedit/mootextiter.h"
#include "mooedit/moohighlighter.h"
#include "mooedit/mootext-private.h"
#include "mooedit/mootexttag.h"
#include "mooutils/moomarshals.h"
#include "mooutils/mooundomanager.h"
#include "mooutils/mooutils-gobject.h"
@ -30,6 +31,7 @@ struct _MooTextBufferPrivate {
MooLang *lang;
gboolean may_apply_tag;
gboolean do_highlight;
gboolean has_placeholders;
gboolean highlight_matching_brackets;
gboolean highlight_mismatching_brackets;
@ -474,7 +476,7 @@ moo_text_buffer_mark_set (GtkTextBuffer *text_buffer,
static void
moo_text_buffer_insert_text (GtkTextBuffer *text_buffer,
moo_text_buffer_insert_text_real (GtkTextBuffer *text_buffer,
GtkTextIter *pos,
const gchar *text,
gint length)
@ -536,6 +538,107 @@ moo_text_buffer_insert_text (GtkTextBuffer *text_buffer,
}
static const char *
find_placeholder (const char *string,
const char *end)
{
const char *p;
if (string >= end)
return NULL;
if (end - string < 6)
return NULL;
for (p = string; p <= end - 6; ++p)
if (!strncmp (p, MOO_PLACEHOLDER_STRING, 6))
return p;
return NULL;
}
static void
moo_text_buffer_insert_text (GtkTextBuffer *text_buffer,
GtkTextIter *pos,
const gchar *text,
gint length)
{
int pos_offset = 0;
const char *ph, *ptr, *end;
GArray *placeholders = NULL;
if (length < 0)
length = strlen (text);
if (!length)
return;
ptr = text;
end = ptr + length;
while ((ph = find_placeholder (ptr, end)))
{
long offset;
if (!placeholders)
placeholders = g_array_new (FALSE, FALSE, sizeof (long));
offset = g_utf8_pointer_to_offset (ptr, ph);
g_array_append_val (placeholders, offset);
ptr = g_utf8_offset_to_pointer (ph, 2);
}
if (placeholders)
pos_offset = gtk_text_iter_get_offset (pos);
moo_text_buffer_insert_text_real (text_buffer, pos, text, length);
if (placeholders)
{
guint i;
GtkTextIter start, end;
gtk_text_buffer_get_iter_at_offset (text_buffer, &start, pos_offset);
MOO_TEXT_BUFFER(text_buffer)->priv->has_placeholders = TRUE;
MOO_TEXT_BUFFER(text_buffer)->priv->may_apply_tag = TRUE;
for (i = 0; i < placeholders->len; ++i)
{
long offset = g_array_index (placeholders, long, i);
gtk_text_iter_forward_chars (&start, offset);
end = start;
gtk_text_iter_forward_chars (&end, 1);
gtk_text_buffer_apply_tag_by_name (text_buffer,
MOO_PLACEHOLDER_START,
&start, &end);
start = end;
gtk_text_iter_forward_chars (&start, 1);
gtk_text_buffer_apply_tag_by_name (text_buffer,
MOO_PLACEHOLDER_END,
&end, &start);
}
MOO_TEXT_BUFFER(text_buffer)->priv->may_apply_tag = FALSE;
g_array_free (placeholders, TRUE);
}
}
gboolean
_moo_text_buffer_has_placeholders (MooTextBuffer *buffer)
{
return buffer->priv->has_placeholders;
}
static void
marks_moved_or_deleted (MooTextBuffer *buffer,
GSList *moved,
@ -913,7 +1016,8 @@ moo_text_buffer_apply_tag (GtkTextBuffer *buffer,
const GtkTextIter *start,
const GtkTextIter *end)
{
if (MOO_IS_SYNTAX_TAG (tag) && !MOO_TEXT_BUFFER(buffer)->priv->may_apply_tag)
if (!MOO_TEXT_BUFFER(buffer)->priv->may_apply_tag)
if (MOO_IS_SYNTAX_TAG (tag) || MOO_IS_TEXT_TAG (tag))
return;
GTK_TEXT_BUFFER_CLASS(moo_text_buffer_parent_class)->apply_tag (buffer, tag, start, end);

View File

@ -33,6 +33,7 @@ G_BEGIN_DECLS
#define MOO_TEXT_UNKNOWN_CHAR 0xFFFC
#define MOO_TEXT_UNKNOWN_CHAR_S "\xEF\xBF\xBC"
#define MOO_PLACEHOLDER_STRING MOO_TEXT_UNKNOWN_CHAR_S MOO_TEXT_UNKNOWN_CHAR_S
#define MOO_PLACEHOLDER_START "moo-placeholder-start"
#define MOO_PLACEHOLDER_END "moo-placeholder-end"

View File

@ -628,6 +628,23 @@ static void moo_text_view_init (MooTextView *view)
}
static void
add_tag (MooTextView *view,
MooTextTagType type,
const char *name)
{
GtkTextBuffer *buffer;
GtkTextTag *tag;
GtkTextTagTable *table;
buffer = get_buffer (view);
tag = _moo_text_tag_new (type, name);
table = gtk_text_buffer_get_tag_table (buffer);
gtk_text_tag_table_add (table, tag);
g_object_unref (tag);
}
static GObject*
moo_text_view_constructor (GType type,
guint n_construct_properties,
@ -690,6 +707,9 @@ moo_text_view_constructor (GType type,
g_signal_connect (view, "notify::overwrite", G_CALLBACK (overwrite_changed), NULL);
add_tag (view, MOO_TEXT_TAG_PLACEHOLDER_START, MOO_PLACEHOLDER_START);
add_tag (view, MOO_TEXT_TAG_PLACEHOLDER_END, MOO_PLACEHOLDER_END);
return object;
}
@ -4054,61 +4074,21 @@ start_quick_search (MooTextView *view)
/* Placeholders
*/
static void
add_tag (MooTextView *view,
MooTextTagType type,
const char *name)
{
GtkTextBuffer *buffer;
GtkTextTag *tag;
GtkTextTagTable *table;
buffer = get_buffer (view);
tag = _moo_text_tag_new (type, name);
table = gtk_text_buffer_get_tag_table (buffer);
gtk_text_tag_table_add (table, tag);
if (GTK_WIDGET (view)->style)
g_object_set (tag, "foreground-gdk",
&GTK_WIDGET(view)->style->base[GTK_STATE_NORMAL],
NULL);
g_object_unref (tag);
}
void
moo_text_view_insert_placeholder (MooTextView *view,
GtkTextIter *iter)
{
GtkTextBuffer *buffer;
g_return_if_fail (MOO_IS_TEXT_VIEW (view));
g_return_if_fail (iter != NULL);
buffer = get_buffer (view);
if (!moo_text_view_lookup_tag (view, MOO_PLACEHOLDER_START))
{
add_tag (view, MOO_TEXT_TAG_PLACEHOLDER_START, MOO_PLACEHOLDER_START);
add_tag (view, MOO_TEXT_TAG_PLACEHOLDER_END, MOO_PLACEHOLDER_END);
}
gtk_text_buffer_insert_with_tags_by_name (buffer, iter,
MOO_TEXT_UNKNOWN_CHAR_S,
-1, MOO_PLACEHOLDER_START,
NULL);
gtk_text_buffer_insert_with_tags_by_name (buffer, iter,
MOO_TEXT_UNKNOWN_CHAR_S,
-1, MOO_PLACEHOLDER_END,
NULL);
gtk_text_buffer_insert (get_buffer (view), iter,
MOO_PLACEHOLDER_STRING, -1);
}
gboolean
_moo_text_view_has_placeholders (MooTextView *view)
{
return moo_text_view_lookup_tag (view, MOO_PLACEHOLDER_START) != NULL;
return _moo_text_buffer_has_placeholders (get_moo_buffer (view));
}