aboutsummaryrefslogtreecommitdiffstats
path: root/widgets
diff options
context:
space:
mode:
authorJon Trowbridge <trow@gnu.org>2001-01-30 04:27:38 +0800
committerJon Trowbridge <trow@src.gnome.org>2001-01-30 04:27:38 +0800
commitb0046a3699f814f39e31192e21c17c15b0dd8474 (patch)
tree23e7f567903068db06a80ebcfa4187f264f611fb /widgets
parentba874ca7d0237c07b0630930eeebda613c543640 (diff)
downloadgsoc2013-evolution-b0046a3699f814f39e31192e21c17c15b0dd8474.tar.gz
gsoc2013-evolution-b0046a3699f814f39e31192e21c17c15b0dd8474.tar.zst
gsoc2013-evolution-b0046a3699f814f39e31192e21c17c15b0dd8474.zip
Connect to the model's "position" signal. (e_text_init): Set default value
2001-01-29 Jon Trowbridge <trow@gnu.org> * gal/e-text/e-text.c (e_text_init): Connect to the model's "position" signal. (e_text_init): Set default value for rgba_object as blue. (e_text_destroy): Disconnect model position signal. (fix_selection): Some extra sanity checking to keep the selection from spilling outside of the bounds of the text string as it expands or contracts. Should be obsolete due to the changes to objectify_uris --- but I'll leave this in here for now, in an attempt to avoid non-\0-terminated strings, segfaults, and all of that fun stuff. (e_text_text_model_position): Move our cursor according to the suggestions made by our ETextModel, via the "position" signal. (text_width_with_objects): Check that text is not NULL. (text_draw_with_objects): Accept an extra GdkGC for use in drawing objects. (e_text_set_arg): Properly handle the "position" signal when changing models. (e_text_draw): Initialize the GC for drawing objects, if necessary. (_insert): Comment out the code that adjustes text->selection_*. The cursor is now moved by the ETextModel directly via the position signal, not by the view. * gal/e-text/e-text-model-uri.c (objectify_uris): Add more sophisticated uri recognition via regular expressions. (objectify_uris): Changed to track position changes as model->text expands and contracts along with the objects. Block the objectification of any chunks of text that straddle our current position. (e_text_model_uri_set_text): Added position info to objectify_uris call. (e_text_model_uri_insert): Added position info to objectify_uris call. (e_text_model_uri_insert_length): Added position info to objectify_uris call. (e_text_model_uri_delete): Added position info to objectify_uris call. * gal/e-text/e-text-model.c (e_text_model_class_init): Added a "position" signal that allows the ETextModel to send cursor positioning information back to any view. We need this for text with objects, where the text string can grow and shrink in ways that the view doesn't expect. (e_text_model_real_insert): Added sanity checking of args and a position emission. (e_text_model_real_insert_length): Added sanity checking of args and a position emission. (e_text_model_real_delete): Added sanity checking of args. (e_text_model_suggest_position): A wrapper around the "position" signal emitter. svn path=/trunk/; revision=7894
Diffstat (limited to 'widgets')
-rw-r--r--widgets/text/e-text-model-test.c8
-rw-r--r--widgets/text/e-text-model-uri.c231
-rw-r--r--widgets/text/e-text-model.c51
-rw-r--r--widgets/text/e-text-model.h5
-rw-r--r--widgets/text/e-text.c97
-rw-r--r--widgets/text/e-text.h4
6 files changed, 333 insertions, 63 deletions
diff --git a/widgets/text/e-text-model-test.c b/widgets/text/e-text-model-test.c
index 0c758cd4ba..8f528efce1 100644
--- a/widgets/text/e-text-model-test.c
+++ b/widgets/text/e-text-model-test.c
@@ -38,7 +38,9 @@ main (int argc, gchar **argv)
gnome_init ("ETextModelTest", "0.0", argc, argv);
model = e_text_model_uri_new ();
- e_text_model_set_text (model, "My favorite website is http://www.ximian.com. My next favorite is http://www.gnome.org.");
+ e_text_model_set_text (model, "My favorite website is http://www.ximian.com. My next favorite is www.assbarn.com.");
+
+ describe_model (model);
win = gtk_window_new (GTK_WINDOW_TOPLEVEL);
@@ -52,9 +54,9 @@ main (int argc, gchar **argv)
e_text_get_type (),
"model", model,
"font", "-adobe-helvetica-medium-r-normal--12-120-75-75-p-67-iso8859-1",
- "anchor", GTK_ANCHOR_SOUTH_WEST,
+ "anchor", GTK_ANCHOR_NORTH_WEST,
"line_wrap", TRUE,
- "width", 150.0,
+ "width", 300.0,
"editable", TRUE,
NULL);
diff --git a/widgets/text/e-text-model-uri.c b/widgets/text/e-text-model-uri.c
index bd8dbb18e8..b769d0b70a 100644
--- a/widgets/text/e-text-model-uri.c
+++ b/widgets/text/e-text-model-uri.c
@@ -9,15 +9,21 @@
#include <config.h>
#include <ctype.h>
+#include <sys/types.h>
+#include <regex.h>
#include "e-text-model-uri.h"
static void e_text_model_uri_class_init (ETextModelURIClass *class);
static void e_text_model_uri_init (ETextModelURI *model);
static void e_text_model_uri_destroy (GtkObject *object);
-static void objectify_uris (ETextModelURI *model);
+static void objectify_uris (ETextModelURI *model, gint position);
static void e_text_model_uri_set_text (ETextModel *model, gchar *text);
+static void e_text_model_uri_insert (ETextModel *model, gint position, gchar *text);
+static void e_text_model_uri_insert_length (ETextModel *model, gint position, gchar *text, gint length);
+static void e_text_model_uri_delete (ETextModel *model, gint position, gint length);
+
static const gchar *e_text_model_uri_get_nth_object (ETextModel *model, gint);
static void e_text_model_uri_activate_nth_object (ETextModel *model, gint);
@@ -60,6 +66,10 @@ e_text_model_uri_class_init (ETextModelURIClass *klass)
object_class->destroy = e_text_model_uri_destroy;
model_class->set_text = e_text_model_uri_set_text;
+ model_class->insert = e_text_model_uri_insert;
+ model_class->insert_length = e_text_model_uri_insert_length;
+ model_class->delete = e_text_model_uri_delete;
+
model_class->get_nth_obj = e_text_model_uri_get_nth_object;
model_class->activate_nth_obj = e_text_model_uri_activate_nth_object;
}
@@ -78,66 +88,169 @@ e_text_model_uri_destroy (GtkObject *object)
}
-static gchar *
-extract_uri (gchar **in_str)
+/* URL regexps taken from gnome-terminal */
+static const gchar *url_regexs[3] = {
+ "(((news|telnet|nttp|file|http|ftp|https)://)|(www|ftp))[-A-Za-z0-9\\.]+(:[0-9]*)?/[-A-Za-z0-9_\\$\\.\\+\\!\\*\\(\\),;:@&=\\?/~\\#\\%]*[^]'\\.}>\\) ,\\\"]",
+ "(((news|telnet|nttp|file|http|ftp|https)://)|(www|ftp))[-A-Za-z0-9\\.]+[-A-Za-z0-9](:[0-9]*)?",
+ "mailto:[A-Za-z0-9_]+@[-A-Za-z0-9_]+\\.[-A-Za-z0-9\\.]+[-A-Za-z0-9]"
+};
+
+static void
+objectify_uris (ETextModelURI *model_uri, gint position)
{
- gchar *s = *in_str;
- if (strncmp (s, "http://", 7) == 0) {
- gint periods=0;
- gchar *uri;
+ static gboolean initialized = FALSE;
+ static regex_t re_full, re_part, re_mail;
- s += 7;
+ ETextModel *model = E_TEXT_MODEL (model_uri);
+ regmatch_t match;
+ GList *uris = NULL, *iter;
+ gint i, j, offset, last, len, objN;
+ gchar *in_str, *new_str;
+ gint new_position = position, pos_adjust=0;
- while (*s && (isalnum((gint) *s) || (*s == '.' && periods < 2))) {
- if (*s == '.')
- ++periods;
- ++s;
- }
+ if (model->text == NULL)
+ return;
+
+ if (!initialized) {
- uri = g_strndup (*in_str, s - *in_str);
- *in_str = s;
- return uri;
+ if (regcomp (&re_full, url_regexs[0], REG_EXTENDED))
+ g_error ("Regex compile failed: %s", url_regexs[0]);
+ if (regcomp (&re_part, url_regexs[1], REG_EXTENDED))
+ g_error ("Regex compile failed: %s", url_regexs[1]);
+ if (regcomp (&re_mail, url_regexs[2], REG_EXTENDED))
+ g_error ("Regex compile failed: %s", url_regexs[2]);
- } else {
- *in_str = s+1;
- return NULL;
+
+ initialized = TRUE;
}
-}
-static void
-objectify_uris (ETextModelURI *model_uri)
-{
- ETextModel *model = E_TEXT_MODEL (model_uri);
- gchar *new_text;
- gchar *src, *dest;
- GList *uris = NULL;
+ /*** Expand objects in string, keeping track of position shifts ***/
+
+ objN = e_text_model_object_count (model);
+ if (objN == 0)
+ in_str = g_strdup (model->text);
+ else {
+ gchar *src, *dest;
+
+ /* Calculate length of expanded string. */
+ len = strlen (model->text) - objN;
+ for (i=0; i<objN; ++i)
+ len += strlen (e_text_model_get_nth_object (model, i));
+
+ in_str = g_new0 (gchar, len+1);
+
+ src = model->text;
+ dest = in_str;
+ i = 0; /* object numbers */
+ j = 0; /* string position */
+ while (*src) {
+ if (*src == '\1') {
+ const gchar *src_obj;
+
+ src_obj = e_text_model_get_nth_object (model, i);
+
+ if (j < position)
+ new_position += strlen (src_obj)-1;
+
+ if (src_obj) {
+ while (*src_obj) {
+ *dest = *src_obj;
+ ++dest;
+ ++src_obj;
+ }
+ }
+
+ ++src;
+ ++i;
+ ++j;
+
+ } else {
+
+ *dest = *src;
+ ++src;
+ ++dest;
+ ++j;
+ }
+ }
+ }
- if (model->text == NULL)
- return;
+ len = strlen (in_str);
+ new_str = g_new0 (gchar, len+1);
+
+ offset = 0;
+ j = 0;
+ last = 0;
+ while (offset < len
+ && (regexec (&re_full, in_str+offset, 1, &match, 0) == 0
+ || regexec (&re_part, in_str+offset, 1, &match, 0) == 0
+ || regexec (&re_mail, in_str+offset, 1, &match, 0) == 0)) {
- new_text = g_new0 (gchar, strlen (model->text)+1);
+ gchar *uri_txt;
- src = model->text;
- dest = new_text;
+ if (offset+match.rm_so <= new_position
+ && new_position <= offset+match.rm_eo) {
+
+ /* We don't do transformations that straddle our cursor. */
+ new_str[j] = in_str[offset];
+ ++j;
+ ++offset;
- while (*src) {
- gchar *uri_str;
- gchar *next = src;
- if ( (uri_str = extract_uri (&next)) ) {
- uris = g_list_append (uris, uri_str);
- *dest = '\1';
} else {
- *dest = *src;
+
+ for (i=offset; i<offset+match.rm_so; ++i) {
+ new_str[j] = in_str[i];
+ ++j;
+ }
+
+ new_str[j] = '\1';
+ ++j;
+
+ uri_txt = g_strndup (in_str+offset+match.rm_so,
+ match.rm_eo - match.rm_so);
+ uris = g_list_append (uris, uri_txt);
+
+ if (offset+match.rm_so < new_position)
+ pos_adjust += match.rm_eo - match.rm_so - 1;
+
+ offset += match.rm_eo;
}
- ++dest;
- src = next;
+ }
+ new_position -= pos_adjust;
+
+ /* Copy the last bit over. */
+ while (offset < len) {
+ new_str[j] = in_str[offset];
+ ++j;
+ ++offset;
}
- g_free (model->text);
- model->text = new_text;
+#if 0
+ for (i=0; i<strlen(new_str); ++i) {
+ if (i == new_position)
+ putchar ('#');
+ if (new_str[i] == '\1')
+ g_print ("[\1]");
+ else
+ putchar (new_str[i]);
+ }
+ putchar ('\n');
+#endif
- /* Leaking old list */
+ for (iter = model_uri->uris; iter != NULL; iter = g_list_next (iter))
+ g_free (iter->data);
+ g_list_free (model_uri->uris);
model_uri->uris = uris;
+
+ g_free (in_str);
+
+ if (E_TEXT_MODEL_CLASS(parent_class)->set_text)
+ E_TEXT_MODEL_CLASS(parent_class)->set_text (model, new_str);
+
+ g_free (new_str);
+
+
+ if (new_position != position)
+ e_text_model_suggest_position (model, new_position);
}
static void
@@ -146,7 +259,35 @@ e_text_model_uri_set_text (ETextModel *model, gchar *text)
if (E_TEXT_MODEL_CLASS(parent_class)->set_text)
E_TEXT_MODEL_CLASS(parent_class)->set_text (model, text);
- objectify_uris (E_TEXT_MODEL_URI (model));
+ objectify_uris (E_TEXT_MODEL_URI (model), 0);
+}
+
+static void
+e_text_model_uri_insert (ETextModel *model, gint position, gchar *text)
+{
+ if (E_TEXT_MODEL_CLASS(parent_class)->insert)
+ E_TEXT_MODEL_CLASS(parent_class)->insert (model, position, text);
+
+ objectify_uris (E_TEXT_MODEL_URI (model), position + strlen (text));
+}
+
+static void
+e_text_model_uri_insert_length (ETextModel *model, gint position, gchar *text, gint length)
+{
+
+ if (E_TEXT_MODEL_CLASS(parent_class)->insert_length)
+ E_TEXT_MODEL_CLASS(parent_class)->insert_length (model, position, text, length);
+
+ objectify_uris (E_TEXT_MODEL_URI (model), position + length);
+}
+
+static void
+e_text_model_uri_delete (ETextModel *model, gint position, gint length)
+{
+ if (E_TEXT_MODEL_CLASS(parent_class)->delete)
+ E_TEXT_MODEL_CLASS(parent_class)->delete (model, position, length);
+
+ objectify_uris (E_TEXT_MODEL_URI (model), position);
}
static const gchar *
diff --git a/widgets/text/e-text-model.c b/widgets/text/e-text-model.c
index acd08ecb04..bbd442b46c 100644
--- a/widgets/text/e-text-model.c
+++ b/widgets/text/e-text-model.c
@@ -22,6 +22,7 @@
enum {
E_TEXT_MODEL_CHANGED,
+ E_TEXT_MODEL_POSITION,
E_TEXT_MODEL_LAST_SIGNAL
};
@@ -33,9 +34,9 @@ static void e_text_model_destroy (GtkObject *object);
static gchar *e_text_model_real_get_text(ETextModel *model);
static void e_text_model_real_set_text(ETextModel *model, gchar *text);
-static void e_text_model_real_insert(ETextModel *model, gint postion, gchar *text);
-static void e_text_model_real_insert_length(ETextModel *model, gint postion, gchar *text, gint length);
-static void e_text_model_real_delete(ETextModel *model, gint postion, gint length);
+static void e_text_model_real_insert(ETextModel *model, gint position, gchar *text);
+static void e_text_model_real_insert_length(ETextModel *model, gint position, gchar *text, gint length);
+static void e_text_model_real_delete(ETextModel *model, gint position, gint length);
static gint e_text_model_real_object_count(ETextModel *model);
static const gchar *e_text_model_real_get_nth_object(ETextModel *model, gint n);
@@ -95,6 +96,14 @@ e_text_model_class_init (ETextModelClass *klass)
GTK_SIGNAL_OFFSET (ETextModelClass, changed),
gtk_marshal_NONE__NONE,
GTK_TYPE_NONE, 0);
+
+ e_text_model_signals[E_TEXT_MODEL_POSITION] =
+ gtk_signal_new ("position",
+ GTK_RUN_LAST,
+ object_class->type,
+ GTK_SIGNAL_OFFSET (ETextModelClass, position),
+ gtk_marshal_NONE__INT,
+ GTK_TYPE_NONE, 1, GTK_TYPE_INT);
gtk_object_class_add_signals (object_class, e_text_model_signals, E_TEXT_MODEL_LAST_SIGNAL);
@@ -157,26 +166,42 @@ e_text_model_real_set_text(ETextModel *model, gchar *text)
static void
e_text_model_real_insert(ETextModel *model, gint position, gchar *text)
{
- gchar *temp = g_strdup_printf("%.*s%s%s", position, model->text, text, model->text + position);
+ gchar *temp;
+
+ g_return_if_fail (0<= position && position <= strlen (model->text));
+
+ temp = g_strdup_printf("%.*s%s%s", position, model->text, text, model->text + position);
+
if (model->text)
g_free(model->text);
model->text = temp;
e_text_model_changed(model);
+
+ e_text_model_suggest_position (model, position + strlen(text));
}
static void
e_text_model_real_insert_length(ETextModel *model, gint position, gchar *text, gint length)
{
- gchar *temp = g_strdup_printf("%.*s%.*s%s", position, model->text, length, text, model->text + position);
+ gchar *temp;
+
+ g_return_if_fail (0 <= position && position <= strlen (model->text));
+
+ temp = g_strdup_printf("%.*s%.*s%s", position, model->text, length, text, model->text + position);
+
if (model->text)
g_free(model->text);
model->text = temp;
e_text_model_changed(model);
+
+ e_text_model_suggest_position (model, position + length);
}
static void
e_text_model_real_delete(ETextModel *model, gint position, gint length)
{
+ g_return_if_fail (0 <= position && position <= strlen (model->text));
+
memmove(model->text + position, model->text + position + length, strlen(model->text + position + length) + 1);
e_text_model_changed(model);
}
@@ -271,6 +296,17 @@ e_text_model_delete(ETextModel *model, gint position, gint length)
E_TEXT_MODEL_CLASS(GTK_OBJECT(model)->klass)->delete(model, position, length);
}
+void
+e_text_model_suggest_position(ETextModel *model, gint position)
+{
+ g_return_if_fail (model != NULL);
+ g_return_if_fail (E_IS_TEXT_MODEL (model));
+ g_return_if_fail (0 <= position);
+ g_return_if_fail (position <= strlen (model->text));
+
+ gtk_signal_emit (GTK_OBJECT (model), e_text_model_signals[E_TEXT_MODEL_POSITION], position);
+}
+
gint
e_text_model_object_count(ETextModel *model)
{
@@ -330,11 +366,10 @@ e_text_model_strdup_expanded_text(ETextModel *model)
len -= N; /* Subtract out the \1s that signify the objects. */
for (i=0; i<N; ++i)
- len += strlen (e_text_model_get_nth_object (model ,i));
-
+ len += strlen (e_text_model_get_nth_object (model, i));
/* Next, allocate and build the expanded string. */
- expanded = g_new0 (gchar, len+1);
+ expanded = g_new0 (gchar, len+2);
src = model->text;
dest = expanded;
diff --git a/widgets/text/e-text-model.h b/widgets/text/e-text-model.h
index 7006b24eca..b8029c0e9e 100644
--- a/widgets/text/e-text-model.h
+++ b/widgets/text/e-text-model.h
@@ -43,7 +43,8 @@ struct _ETextModelClass {
GtkObjectClass parent_class;
/* Signal */
- void (* changed) (ETextModel *model);
+ void (* changed) (ETextModel *model);
+ void (* position) (ETextModel *model, gint position);
/* Virtual methods */
char *(* get_text) (ETextModel *model);
@@ -68,6 +69,8 @@ void e_text_model_insert(ETextModel *model, gint position, gchar *text);
void e_text_model_insert_length(ETextModel *model, gint position, gchar *text, gint length);
void e_text_model_delete(ETextModel *model, gint position, gint length);
+void e_text_model_suggest_position(ETextModel *model, gint position);
+
gint e_text_model_object_count(ETextModel *model);
const gchar *e_text_model_get_nth_object(ETextModel *model, gint n);
void e_text_model_activate_nth_object(ETextModel *model, gint n);
diff --git a/widgets/text/e-text.c b/widgets/text/e-text.c
index fbbe77dc0d..1427a078ca 100644
--- a/widgets/text/e-text.c
+++ b/widgets/text/e-text.c
@@ -128,6 +128,7 @@ static void e_text_get_selection(EText *text, GdkAtom selection, guint32 time);
static void e_text_supply_selection (EText *text, guint time, GdkAtom selection, guchar *data, gint length);
static void e_text_text_model_changed(ETextModel *model, EText *text);
+static void e_text_text_model_position(ETextModel *model, gint position, EText *text);
static void _get_tep(EText *text);
@@ -331,6 +332,11 @@ e_text_init (EText *text)
"changed",
GTK_SIGNAL_FUNC(e_text_text_model_changed),
text);
+ text->model_position_signal_id =
+ gtk_signal_connect(GTK_OBJECT(text->model),
+ "position",
+ GTK_SIGNAL_FUNC(e_text_text_model_position),
+ text);
text->anchor = GTK_ANCHOR_CENTER;
text->justification = GTK_JUSTIFY_LEFT;
@@ -387,6 +393,8 @@ e_text_init (EText *text)
text->dbl_timeout = 0;
text->tpl_timeout = 0;
+ text->rgba_object = 0x0000ffff;
+
text->draw_background = FALSE;
e_canvas_item_set_reflow_callback(GNOME_CANVAS_ITEM(text), e_text_reflow);
@@ -406,6 +414,9 @@ e_text_destroy (GtkObject *object)
if (text->model_changed_signal_id)
gtk_signal_disconnect(GTK_OBJECT(text->model),
text->model_changed_signal_id);
+ if (text->model_position_signal_id)
+ gtk_signal_disconnect(GTK_OBJECT(text->model),
+ text->model_position_signal_id);
if (text->model)
gtk_object_unref(GTK_OBJECT(text->model));
@@ -465,16 +476,48 @@ e_text_destroy (GtkObject *object)
}
static void
+fix_selection (EText *text)
+{
+ gint len = strlen (text->text);
+
+ if (text->selection_start > len) {
+ text->selection_start = len;
+ }
+ if (text->selection_end > len) {
+ text->selection_end = len;
+ }
+}
+
+static void
e_text_text_model_changed (ETextModel *model, EText *text)
{
+ gint len;
+
text->text = e_text_model_get_text(model);
+ len = strlen (text->text);
+
+ fix_selection (text);
+
e_text_free_lines(text);
gtk_signal_emit (GTK_OBJECT (text), e_text_signals[E_TEXT_CHANGED]);
+ text->needs_redraw = 1;
text->needs_split_into_lines = 1;
e_canvas_item_request_reflow (GNOME_CANVAS_ITEM(text));
}
static void
+e_text_text_model_position (ETextModel *model, gint position, EText *text)
+{
+ /*
+ For now, something very simple. We can worry about things
+ like preserving a multi-char selection later.
+ */
+
+ text->selection_start = position;
+ text->selection_end = position;
+}
+
+static void
get_bounds_item_relative (EText *text, double *px1, double *py1, double *px2, double *py2)
{
GnomeCanvasItem *item;
@@ -798,6 +841,9 @@ text_width_with_objects (ETextModel *model, gint object_num,
gchar *c;
gint width = 0;
+ if (text == NULL)
+ return 0;
+
while (*text && numbytes > 0) {
c = text;
@@ -849,11 +895,14 @@ static void
text_draw_with_objects (ETextModel *model, gint object_num,
GdkDrawable *drawable,
EFont *font, EFontStyle style,
- GdkGC *gc,
+ GdkGC *gc, GdkGC *obj_gc,
gint x, gint y,
gchar *text, gint numbytes)
{
gchar *c;
+
+ if (text == NULL)
+ return;
while (*text && numbytes > 0) {
@@ -871,16 +920,20 @@ text_draw_with_objects (ETextModel *model, gint object_num,
const gchar *obj_str;
gint start_x = x;
gint len;
+
+ if (obj_gc == NULL)
+ obj_gc = gc;
+
g_assert (object_num < e_text_model_object_count (model));
obj_str = e_text_model_get_nth_object (model, object_num);
len = strlen (obj_str);
- e_font_draw_utf8_text (drawable, font, style, gc, x, y, obj_str, len);
+ e_font_draw_utf8_text (drawable, font, style, obj_gc, x, y, obj_str, len);
x += e_font_utf8_text_width (font, style, obj_str, len);
/* We underline our objects. */
- gdk_draw_line (drawable, gc, start_x, y+1, x, y+1);
+ gdk_draw_line (drawable, obj_gc, start_x, y+1, x, y+1);
++object_num;
++c;
@@ -1169,6 +1222,9 @@ e_text_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
if ( text->model_changed_signal_id )
gtk_signal_disconnect(GTK_OBJECT(text->model),
text->model_changed_signal_id);
+ if ( text->model_position_signal_id )
+ gtk_signal_disconnect(GTK_OBJECT(text->model),
+ text->model_position_signal_id);
gtk_object_unref(GTK_OBJECT(text->model));
text->model = E_TEXT_MODEL(GTK_VALUE_OBJECT (*arg));
gtk_object_ref(GTK_OBJECT(text->model));
@@ -1178,6 +1234,11 @@ e_text_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
"changed",
GTK_SIGNAL_FUNC(e_text_text_model_changed),
text);
+ text->model_position_signal_id =
+ gtk_signal_connect(GTK_OBJECT(text->model),
+ "position",
+ GTK_SIGNAL_FUNC(e_text_text_model_position),
+ text);
e_text_free_lines(text);
@@ -1773,7 +1834,7 @@ e_text_realize (GnomeCanvasItem *item)
(* parent_class->realize) (item);
text->gc = gdk_gc_new (item->canvas->layout.bin_window);
-
+
text->i_cursor = gdk_cursor_new (GDK_XTERM);
text->default_cursor = gdk_cursor_new (GDK_LEFT_PTR);
if (text->font == NULL) {
@@ -1948,6 +2009,16 @@ e_text_draw (GnomeCanvasItem *item, GdkDrawable *drawable,
canvas = GNOME_CANVAS_ITEM(text)->canvas;
fg_gc = GTK_WIDGET(canvas)->style->fg_gc[text->has_selection ? GTK_STATE_SELECTED : GTK_STATE_ACTIVE];
+
+ if (text->rgba_object && text->gc_object == NULL && text->gc) {
+ GdkColor c;
+ c.pixel = gnome_canvas_get_color_pixel (item->canvas, text->rgba_object);
+
+ text->gc_object = gdk_gc_new (item->canvas->layout.bin_window);
+ gdk_gc_copy (text->gc_object, text->gc);
+ gdk_gc_set_foreground (text->gc_object, &c);
+ }
+
if (text->draw_borders || text->draw_background) {
gdouble thisx = item->x1 - x;
@@ -2071,6 +2142,7 @@ e_text_draw (GnomeCanvasItem *item, GdkDrawable *drawable,
drawable,
text->font, E_FONT_PLAIN,
text->gc,
+ text->gc_object,
xpos - x,
ypos - y,
lines->text,
@@ -2079,6 +2151,7 @@ e_text_draw (GnomeCanvasItem *item, GdkDrawable *drawable,
drawable,
text->font, E_FONT_PLAIN,
fg_gc,
+ text->gc_object,
xpos - x + text_width_with_objects (text->model, lines->first_obj,
text->font, E_FONT_PLAIN,
lines->text,
@@ -2090,6 +2163,7 @@ e_text_draw (GnomeCanvasItem *item, GdkDrawable *drawable,
drawable,
text->font, E_FONT_PLAIN,
text->gc,
+ text->gc_object,
xpos - x + text_width_with_objects (text->model, lines->first_obj,
text->font, E_FONT_PLAIN,
lines->text,
@@ -2102,6 +2176,7 @@ e_text_draw (GnomeCanvasItem *item, GdkDrawable *drawable,
drawable,
text->font, E_FONT_PLAIN,
text->gc,
+ text->gc_object,
xpos - x,
ypos - y,
lines->text,
@@ -2128,6 +2203,7 @@ e_text_draw (GnomeCanvasItem *item, GdkDrawable *drawable,
drawable,
text->font, E_FONT_PLAIN,
text->gc,
+ text->gc_object,
xpos - x,
ypos - y,
lines->text,
@@ -2144,6 +2220,7 @@ e_text_draw (GnomeCanvasItem *item, GdkDrawable *drawable,
drawable,
text->font, E_FONT_PLAIN,
text->gc,
+ text->gc_object,
xpos - x,
ypos - y,
lines->text,
@@ -3297,6 +3374,8 @@ _delete_selection(EText *text)
e_text_model_delete(text->model, text->selection_end, text->selection_start - text->selection_end);
text->selection_start = text->selection_end;
}
+
+ fix_selection (text);
}
static void
@@ -3305,8 +3384,13 @@ _insert(EText *text, char *string, int value)
if (value > 0) {
e_text_model_insert_length(text->model, text->selection_start, string, value);
- text->selection_start += value;
- text->selection_end = text->selection_start;
+ /*
+ text->selection_start += value;
+ text->selection_end = text->selection_start;
+ */
+
+ fix_selection (text);
+
}
}
@@ -3315,6 +3399,7 @@ e_text_command(ETextEventProcessor *tep, ETextEventProcessorCommand *command, gp
{
EText *text = E_TEXT(data);
int sel_start, sel_end;
+
switch (command->action) {
case E_TEP_MOVE:
text->selection_start = _get_position(text, command);
diff --git a/widgets/text/e-text.h b/widgets/text/e-text.h
index 5a1e843b7d..568402417c 100644
--- a/widgets/text/e-text.h
+++ b/widgets/text/e-text.h
@@ -110,6 +110,7 @@ struct _EText {
ETextModel *model;
gint model_changed_signal_id;
+ gint model_position_signal_id;
char *text; /* Text to display */
gpointer lines; /* Text split into lines (private field) */
@@ -210,6 +211,9 @@ struct _EText {
gint dbl_timeout; /* Double click timeout */
gint tpl_timeout; /* Triple click timeout */
+
+ guint32 rgba_object; /* RGBA color for objects */
+ GdkGC *gc_object; /* GC for drawing objects */
};
struct _ETextClass {