summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOwen Taylor <owt1@cornell.edu>1998-03-10 03:17:02 +0000
committerTim Janik <timj@src.gnome.org>1998-03-10 03:17:02 +0000
commit2f50a3044ed8bf7783e8362d956b6f77010795cd (patch)
treeade65b5ee1804697cc26df7b59ed317bc99807cb
parent990bddfe1688861332443d89a4796a710e18ae39 (diff)
downloadgdk-pixbuf-2f50a3044ed8bf7783e8362d956b6f77010795cd.tar.gz
commiting changes from owen:
Mon Mar 9 20:38:15 1998 Owen Taylor <owt1@cornell.edu> * gtk/gtkentry.c gtk/gtkeditable.c gtk/gtkspinbutton.c: Moved "activate" to editable class. Made the vfuncs in gtkeditable just vfuncs not signals. * gtkentry.[ch] gtktext.[ch]: Made behavior when pressing multiple buttons at once more rational. * gtkentry.c gtktext.c: Unified and rationalized key bindings. (Now are basically emacs+CUA) * gtktext.c: - Last position now always shares the property of the preceding character - Freeze the widget when inserting large amounts of text. - Selecting lines now selects the _whole_ line. - Fixed bug with displaying the cursor - Ctrl-Home/End now move the cursor to the _absolute home/end * gtkmenuitem.c: Remove necessary code out of a g_return_if_fail -timj
-rw-r--r--ChangeLog22
-rw-r--r--ChangeLog.pre-2-022
-rw-r--r--ChangeLog.pre-2-1022
-rw-r--r--ChangeLog.pre-2-222
-rw-r--r--ChangeLog.pre-2-422
-rw-r--r--ChangeLog.pre-2-622
-rw-r--r--ChangeLog.pre-2-822
-rw-r--r--TODO42
-rw-r--r--docs/text_widget.txt10
-rw-r--r--gtk/gtkeditable.c165
-rw-r--r--gtk/gtkeditable.h1
-rw-r--r--gtk/gtkentry.c107
-rw-r--r--gtk/gtkentry.h3
-rw-r--r--gtk/gtkmenuitem.c6
-rw-r--r--gtk/gtkspinbutton.c16
-rw-r--r--gtk/gtktext.c389
-rw-r--r--gtk/gtktext.h4
17 files changed, 583 insertions, 314 deletions
diff --git a/ChangeLog b/ChangeLog
index 21d28413d..980e20b48 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,25 @@
+Mon Mar 9 20:38:15 1998 Owen Taylor <owt1@cornell.edu>
+
+ * gtk/gtkentry.c gtk/gtkeditable.c gtk/gtkspinbutton.c:
+ Moved "activate" to editable class. Made the vfuncs in
+ gtkeditable just vfuncs not signals.
+
+ * gtkentry.[ch] gtktext.[ch]: Made behavior when pressing
+ multiple buttons at once more rational.
+
+ * gtkentry.c gtktext.c: Unified and rationalized key
+ bindings. (Now are basically emacs+CUA)
+
+ * gtktext.c:
+ - Last position now always shares the property of the preceding
+ character
+ - Freeze the widget when inserting large amounts of text.
+ - Selecting lines now selects the _whole_ line.
+ - Fixed bug with displaying the cursor
+ - Ctrl-Home/End now move the cursor to the _absolute home/end
+
+ * gtkmenuitem.c: Remove necessary code out of a g_return_if_fail
+
1998-03-09 Federico Mena Quintero <federico@nuclecu.unam.mx>
* gtk/gtkclist.c (gtk_clist_set_foreground): We now accept the
diff --git a/ChangeLog.pre-2-0 b/ChangeLog.pre-2-0
index 21d28413d..980e20b48 100644
--- a/ChangeLog.pre-2-0
+++ b/ChangeLog.pre-2-0
@@ -1,3 +1,25 @@
+Mon Mar 9 20:38:15 1998 Owen Taylor <owt1@cornell.edu>
+
+ * gtk/gtkentry.c gtk/gtkeditable.c gtk/gtkspinbutton.c:
+ Moved "activate" to editable class. Made the vfuncs in
+ gtkeditable just vfuncs not signals.
+
+ * gtkentry.[ch] gtktext.[ch]: Made behavior when pressing
+ multiple buttons at once more rational.
+
+ * gtkentry.c gtktext.c: Unified and rationalized key
+ bindings. (Now are basically emacs+CUA)
+
+ * gtktext.c:
+ - Last position now always shares the property of the preceding
+ character
+ - Freeze the widget when inserting large amounts of text.
+ - Selecting lines now selects the _whole_ line.
+ - Fixed bug with displaying the cursor
+ - Ctrl-Home/End now move the cursor to the _absolute home/end
+
+ * gtkmenuitem.c: Remove necessary code out of a g_return_if_fail
+
1998-03-09 Federico Mena Quintero <federico@nuclecu.unam.mx>
* gtk/gtkclist.c (gtk_clist_set_foreground): We now accept the
diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10
index 21d28413d..980e20b48 100644
--- a/ChangeLog.pre-2-10
+++ b/ChangeLog.pre-2-10
@@ -1,3 +1,25 @@
+Mon Mar 9 20:38:15 1998 Owen Taylor <owt1@cornell.edu>
+
+ * gtk/gtkentry.c gtk/gtkeditable.c gtk/gtkspinbutton.c:
+ Moved "activate" to editable class. Made the vfuncs in
+ gtkeditable just vfuncs not signals.
+
+ * gtkentry.[ch] gtktext.[ch]: Made behavior when pressing
+ multiple buttons at once more rational.
+
+ * gtkentry.c gtktext.c: Unified and rationalized key
+ bindings. (Now are basically emacs+CUA)
+
+ * gtktext.c:
+ - Last position now always shares the property of the preceding
+ character
+ - Freeze the widget when inserting large amounts of text.
+ - Selecting lines now selects the _whole_ line.
+ - Fixed bug with displaying the cursor
+ - Ctrl-Home/End now move the cursor to the _absolute home/end
+
+ * gtkmenuitem.c: Remove necessary code out of a g_return_if_fail
+
1998-03-09 Federico Mena Quintero <federico@nuclecu.unam.mx>
* gtk/gtkclist.c (gtk_clist_set_foreground): We now accept the
diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2
index 21d28413d..980e20b48 100644
--- a/ChangeLog.pre-2-2
+++ b/ChangeLog.pre-2-2
@@ -1,3 +1,25 @@
+Mon Mar 9 20:38:15 1998 Owen Taylor <owt1@cornell.edu>
+
+ * gtk/gtkentry.c gtk/gtkeditable.c gtk/gtkspinbutton.c:
+ Moved "activate" to editable class. Made the vfuncs in
+ gtkeditable just vfuncs not signals.
+
+ * gtkentry.[ch] gtktext.[ch]: Made behavior when pressing
+ multiple buttons at once more rational.
+
+ * gtkentry.c gtktext.c: Unified and rationalized key
+ bindings. (Now are basically emacs+CUA)
+
+ * gtktext.c:
+ - Last position now always shares the property of the preceding
+ character
+ - Freeze the widget when inserting large amounts of text.
+ - Selecting lines now selects the _whole_ line.
+ - Fixed bug with displaying the cursor
+ - Ctrl-Home/End now move the cursor to the _absolute home/end
+
+ * gtkmenuitem.c: Remove necessary code out of a g_return_if_fail
+
1998-03-09 Federico Mena Quintero <federico@nuclecu.unam.mx>
* gtk/gtkclist.c (gtk_clist_set_foreground): We now accept the
diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4
index 21d28413d..980e20b48 100644
--- a/ChangeLog.pre-2-4
+++ b/ChangeLog.pre-2-4
@@ -1,3 +1,25 @@
+Mon Mar 9 20:38:15 1998 Owen Taylor <owt1@cornell.edu>
+
+ * gtk/gtkentry.c gtk/gtkeditable.c gtk/gtkspinbutton.c:
+ Moved "activate" to editable class. Made the vfuncs in
+ gtkeditable just vfuncs not signals.
+
+ * gtkentry.[ch] gtktext.[ch]: Made behavior when pressing
+ multiple buttons at once more rational.
+
+ * gtkentry.c gtktext.c: Unified and rationalized key
+ bindings. (Now are basically emacs+CUA)
+
+ * gtktext.c:
+ - Last position now always shares the property of the preceding
+ character
+ - Freeze the widget when inserting large amounts of text.
+ - Selecting lines now selects the _whole_ line.
+ - Fixed bug with displaying the cursor
+ - Ctrl-Home/End now move the cursor to the _absolute home/end
+
+ * gtkmenuitem.c: Remove necessary code out of a g_return_if_fail
+
1998-03-09 Federico Mena Quintero <federico@nuclecu.unam.mx>
* gtk/gtkclist.c (gtk_clist_set_foreground): We now accept the
diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6
index 21d28413d..980e20b48 100644
--- a/ChangeLog.pre-2-6
+++ b/ChangeLog.pre-2-6
@@ -1,3 +1,25 @@
+Mon Mar 9 20:38:15 1998 Owen Taylor <owt1@cornell.edu>
+
+ * gtk/gtkentry.c gtk/gtkeditable.c gtk/gtkspinbutton.c:
+ Moved "activate" to editable class. Made the vfuncs in
+ gtkeditable just vfuncs not signals.
+
+ * gtkentry.[ch] gtktext.[ch]: Made behavior when pressing
+ multiple buttons at once more rational.
+
+ * gtkentry.c gtktext.c: Unified and rationalized key
+ bindings. (Now are basically emacs+CUA)
+
+ * gtktext.c:
+ - Last position now always shares the property of the preceding
+ character
+ - Freeze the widget when inserting large amounts of text.
+ - Selecting lines now selects the _whole_ line.
+ - Fixed bug with displaying the cursor
+ - Ctrl-Home/End now move the cursor to the _absolute home/end
+
+ * gtkmenuitem.c: Remove necessary code out of a g_return_if_fail
+
1998-03-09 Federico Mena Quintero <federico@nuclecu.unam.mx>
* gtk/gtkclist.c (gtk_clist_set_foreground): We now accept the
diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8
index 21d28413d..980e20b48 100644
--- a/ChangeLog.pre-2-8
+++ b/ChangeLog.pre-2-8
@@ -1,3 +1,25 @@
+Mon Mar 9 20:38:15 1998 Owen Taylor <owt1@cornell.edu>
+
+ * gtk/gtkentry.c gtk/gtkeditable.c gtk/gtkspinbutton.c:
+ Moved "activate" to editable class. Made the vfuncs in
+ gtkeditable just vfuncs not signals.
+
+ * gtkentry.[ch] gtktext.[ch]: Made behavior when pressing
+ multiple buttons at once more rational.
+
+ * gtkentry.c gtktext.c: Unified and rationalized key
+ bindings. (Now are basically emacs+CUA)
+
+ * gtktext.c:
+ - Last position now always shares the property of the preceding
+ character
+ - Freeze the widget when inserting large amounts of text.
+ - Selecting lines now selects the _whole_ line.
+ - Fixed bug with displaying the cursor
+ - Ctrl-Home/End now move the cursor to the _absolute home/end
+
+ * gtkmenuitem.c: Remove necessary code out of a g_return_if_fail
+
1998-03-09 Federico Mena Quintero <federico@nuclecu.unam.mx>
* gtk/gtkclist.c (gtk_clist_set_foreground): We now accept the
diff --git a/TODO b/TODO
index 6dfd3aaa4..ffb1e5a8c 100644
--- a/TODO
+++ b/TODO
@@ -159,45 +159,17 @@ TODO AFTER GTK 1.0
Bugs:
- - In Entry and Text widget, you can ungrab while still
- dragging by pressing button-1, pressing button 3, releaseing 3,
- then releasing 1.
+ - Who knows?
- - When selecting on a Text or Entry widget, the selection isn't
- claimed until you release the button, and that shows by the
- color of the selection. (Which is the real problem - it probably
- is OK/better to delay claiming the selection) [fixed]
-
- - Related to the above, when you Shift/arrow to select text, the
- selected text doesn't show that you have the selection immediately.
-
- - Selecting an entire line with triple-click doesn't work right -
- it should select the wrapped portion too.
-
- - Selecting an entire line should probably select the newline as
- well, so when the selection is cut/deleted, the newline goes
- along.
-
- - Inserting text in a different property - problems? Shouldn't
- split the last position off in any case.
-
- - Do something about the bg pixmap situation. (It will produce
- garbage when editing is enabled)
-
- - "Copy" removes selection
-
Improvements:
- - Finish making the key bindings consistent between the Entry
- and Text widgets
-
- Unify the key binding support in some fashion between the
- two widgets (???)
-
- - When inserting or deleting large chunks of text, do a freeze/thaw
- automatically, to avoid scrolling around for ever on screen.
+ Entry and Text widget widgets (???)
- - Jump scroll on large insertions/deletions
+ - Figure out a way not to recompute the geometry on insertions/deletions
+ which are large, but not a significant fraction of the
+ entire text. (e.g., compute the changes as when the widget
+ is not frozen, but without the actual scrolling)
- Prune the line start cache. But since it is only 68 bytes
per line, and it is a lot faster when lines are in the cache,
@@ -254,4 +226,4 @@ TODO AFTER GTK 1.0
* gtk_rc_add_[name/class]_style are broken for bg pixmaps, because
styles are broken for bg pixmaps, and RC styles only hack around
- that. \ No newline at end of file
+ that.
diff --git a/docs/text_widget.txt b/docs/text_widget.txt
index 83d3b31e5..599431f2f 100644
--- a/docs/text_widget.txt
+++ b/docs/text_widget.txt
@@ -161,6 +161,16 @@ this index. If you see or add a special case in the code for this
end-of-buffer case, make sure to use LAST_INDEX if you can. Very
often, the last index is treated as a newline.
+[ One way the last index is special is that, although it is always
+ part of some property, it will never be part of a property of
+ length 1 unless there are no other characters in the text. That
+ is, its properties are always that of the preceding character,
+ if any.
+
+ There is a fair bit of special case code to mantain this condition -
+ which is needed so that user has control over the properties of
+ characters inserted at the last position. OWT 2/9/98 ]
+
Tab stops are variable width. A list of tab stops is contained in the
GtkText structure:
diff --git a/gtk/gtkeditable.c b/gtk/gtkeditable.c
index 974b542d3..81cc887a3 100644
--- a/gtk/gtkeditable.c
+++ b/gtk/gtkeditable.c
@@ -32,45 +32,11 @@
#define INNER_BORDER 2
enum {
- INSERT_TEXT,
- DELETE_TEXT,
- UPDATE_TEXT,
- GET_CHARS,
- SET_SELECTION,
+ ACTIVATE,
CHANGED,
LAST_SIGNAL
};
-
-typedef void (*GtkEditableSignal1) (GtkObject *object,
- gpointer arg1,
- gint arg2,
- gpointer arg3,
- gpointer data);
-typedef void (*GtkEditableSignal2) (GtkObject *object,
- gint arg1,
- gint arg2,
- gpointer data);
-
-typedef gpointer (*GtkEditableSignal3) (GtkObject *object,
- gint arg1,
- gint arg2,
- gpointer data);
-
-
-static void gtk_editable_marshal_signal_1 (GtkObject *object,
- GtkSignalFunc func,
- gpointer func_data,
- GtkArg *args);
-static void gtk_editable_marshal_signal_2 (GtkObject *object,
- GtkSignalFunc func,
- gpointer func_data,
- GtkArg *args);
-static void gtk_editable_marshal_signal_3 (GtkObject *object,
- GtkSignalFunc func,
- gpointer func_data,
- GtkArg *args);
-
static void gtk_editable_class_init (GtkEditableClass *klass);
static void gtk_editable_init (GtkEditable *editable);
static void gtk_editable_finalize (GtkObject *object);
@@ -127,47 +93,14 @@ gtk_editable_class_init (GtkEditableClass *class)
parent_class = gtk_type_class (gtk_widget_get_type ());
- editable_signals[INSERT_TEXT] =
- gtk_signal_new ("insert_text",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (GtkEditableClass, insert_text),
- gtk_editable_marshal_signal_1,
- GTK_TYPE_NONE, 3,
- GTK_TYPE_STRING, GTK_TYPE_INT,
- GTK_TYPE_POINTER);
- editable_signals[DELETE_TEXT] =
- gtk_signal_new ("delete_text",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (GtkEditableClass, delete_text),
- gtk_editable_marshal_signal_2,
- GTK_TYPE_NONE, 2,
- GTK_TYPE_INT, GTK_TYPE_INT);
- editable_signals[UPDATE_TEXT] =
- gtk_signal_new ("update_text",
+ editable_signals[ACTIVATE] =
+ gtk_signal_new ("activate",
GTK_RUN_LAST,
object_class->type,
- GTK_SIGNAL_OFFSET (GtkEditableClass, update_text),
- gtk_editable_marshal_signal_2,
- GTK_TYPE_NONE, 2,
- GTK_TYPE_INT, GTK_TYPE_INT);
- editable_signals[GET_CHARS] =
- gtk_signal_new ("get_chars",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (GtkEditableClass, get_chars),
- gtk_editable_marshal_signal_3,
- GTK_TYPE_POINTER, 2,
- GTK_TYPE_INT, GTK_TYPE_INT);
- editable_signals[SET_SELECTION] =
- gtk_signal_new ("set_selection",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (GtkEditableClass, set_selection),
- gtk_editable_marshal_signal_2,
- GTK_TYPE_NONE, 2,
- GTK_TYPE_INT, GTK_TYPE_INT);
+ GTK_SIGNAL_OFFSET (GtkEditableClass, activate),
+ gtk_signal_default_marshaller,
+ GTK_TYPE_NONE, 0);
+
editable_signals[CHANGED] =
gtk_signal_new ("changed",
GTK_RUN_LAST,
@@ -242,53 +175,6 @@ gtk_editable_init (GtkEditable *editable)
}
static void
-gtk_editable_marshal_signal_1 (GtkObject *object,
- GtkSignalFunc func,
- gpointer func_data,
- GtkArg *args)
-{
- GtkEditableSignal1 rfunc;
-
- rfunc = (GtkEditableSignal1) func;
-
- (* rfunc) (object, GTK_VALUE_STRING (args[0]), GTK_VALUE_INT (args[1]),
- GTK_VALUE_POINTER (args[2]), func_data);
-}
-
-static void
-gtk_editable_marshal_signal_2 (GtkObject *object,
- GtkSignalFunc func,
- gpointer func_data,
- GtkArg *args)
-{
- GtkEditableSignal2 rfunc;
-
- rfunc = (GtkEditableSignal2) func;
-
- (* rfunc) (object, GTK_VALUE_INT (args[0]), GTK_VALUE_INT (args[1]),
- func_data);
-}
-
-static void
-gtk_editable_marshal_signal_3 (GtkObject *object,
- GtkSignalFunc func,
- gpointer func_data,
- GtkArg *args)
-{
- GtkEditableSignal3 rfunc;
- gpointer *return_val;
-
- rfunc = (GtkEditableSignal3) func;
-
- return_val = GTK_RETLOC_POINTER (args[2]);
-
- *return_val = (* rfunc) (object,
- GTK_VALUE_INT (args[0]),
- GTK_VALUE_INT (args[1]),
- func_data);
-}
-
-static void
gtk_editable_finalize (GtkObject *object)
{
GtkEditable *editable;
@@ -315,12 +201,16 @@ gtk_editable_insert_text (GtkEditable *editable,
gint new_text_length,
gint *position)
{
+ GtkEditableClass *klass;
+
gchar buf[64];
gchar *text;
g_return_if_fail (editable != NULL);
g_return_if_fail (GTK_IS_EDITABLE (editable));
+ klass = GTK_EDITABLE_CLASS (GTK_OBJECT (editable)->klass);
+
if (new_text_length <= 64)
text = buf;
else
@@ -328,8 +218,7 @@ gtk_editable_insert_text (GtkEditable *editable,
strncpy (text, new_text, new_text_length);
- gtk_signal_emit (GTK_OBJECT (editable), editable_signals[INSERT_TEXT],
- text, new_text_length, position);
+ klass->insert_text (editable, text, new_text_length, position);
gtk_signal_emit (GTK_OBJECT (editable), editable_signals[CHANGED]);
if (new_text_length > 64)
@@ -341,11 +230,14 @@ gtk_editable_delete_text (GtkEditable *editable,
gint start_pos,
gint end_pos)
{
+ GtkEditableClass *klass;
+
g_return_if_fail (editable != NULL);
g_return_if_fail (GTK_IS_EDITABLE (editable));
- gtk_signal_emit (GTK_OBJECT (editable), editable_signals[DELETE_TEXT],
- start_pos, end_pos);
+ klass = GTK_EDITABLE_CLASS (GTK_OBJECT (editable)->klass);
+
+ klass->delete_text (editable, start_pos, end_pos);
gtk_signal_emit (GTK_OBJECT (editable), editable_signals[CHANGED]);
}
@@ -354,11 +246,14 @@ gtk_editable_update_text (GtkEditable *editable,
gint start_pos,
gint end_pos)
{
+ GtkEditableClass *klass;
+
g_return_if_fail (editable != NULL);
g_return_if_fail (GTK_IS_EDITABLE (editable));
- gtk_signal_emit (GTK_OBJECT (editable), editable_signals[UPDATE_TEXT],
- start_pos, end_pos);
+ klass = GTK_EDITABLE_CLASS (GTK_OBJECT (editable)->klass);
+
+ klass->update_text (editable, start_pos, end_pos);
}
gchar *
@@ -366,15 +261,14 @@ gtk_editable_get_chars (GtkEditable *editable,
gint start,
gint end)
{
- gchar *retval = NULL;
-
+ GtkEditableClass *klass;
+
g_return_val_if_fail (editable != NULL, NULL);
g_return_val_if_fail (GTK_IS_EDITABLE (editable), NULL);
- gtk_signal_emit (GTK_OBJECT (editable), editable_signals[GET_CHARS],
- start, end, &retval);
+ klass = GTK_EDITABLE_CLASS (GTK_OBJECT (editable)->klass);
- return retval;
+ return klass->get_chars (editable, start, end);
}
static void
@@ -382,11 +276,14 @@ gtk_editable_set_selection (GtkEditable *editable,
gint start_pos,
gint end_pos)
{
+ GtkEditableClass *klass;
+
g_return_if_fail (editable != NULL);
g_return_if_fail (GTK_IS_EDITABLE (editable));
- gtk_signal_emit (GTK_OBJECT (editable), editable_signals[SET_SELECTION],
- start_pos, end_pos);
+ klass = GTK_EDITABLE_CLASS (GTK_OBJECT (editable)->klass);
+
+ klass->set_selection (editable, start_pos, end_pos);
}
static gint
diff --git a/gtk/gtkeditable.h b/gtk/gtkeditable.h
index 893f8edf8..a2fd4a1b6 100644
--- a/gtk/gtkeditable.h
+++ b/gtk/gtkeditable.h
@@ -73,6 +73,7 @@ struct _GtkEditableClass
void (* set_selection)(GtkEditable *editable,
gint start_pos,
gint end_pos);
+ void (* activate) (GtkEditable *editable);
void (* changed) (GtkEditable *editable);
};
diff --git a/gtk/gtkentry.c b/gtk/gtkentry.c
index 979e9d9e6..70c68003e 100644
--- a/gtk/gtkentry.c
+++ b/gtk/gtkentry.c
@@ -31,11 +31,6 @@
#define DRAW_TIMEOUT 20
#define INNER_BORDER 2
-enum {
- ACTIVATE,
- LAST_SIGNAL
-};
-
static void gtk_entry_class_init (GtkEntryClass *klass);
static void gtk_entry_init (GtkEntry *entry);
static void gtk_entry_finalize (GtkObject *object);
@@ -111,7 +106,6 @@ static void gtk_entry_set_selection (GtkEditable *editable,
gint end);
static GtkWidgetClass *parent_class = NULL;
-static guint entry_signals[LAST_SIGNAL] = { 0 };
static GdkAtom ctext_atom = GDK_NONE;
static GtkTextFunction control_keys[26] =
@@ -212,16 +206,6 @@ gtk_entry_class_init (GtkEntryClass *class)
parent_class = gtk_type_class (gtk_editable_get_type ());
- entry_signals[ACTIVATE] =
- gtk_signal_new ("activate",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (GtkEntryClass, activate),
- gtk_signal_default_marshaller,
- GTK_TYPE_NONE, 0);
-
- gtk_object_class_add_signals (object_class, entry_signals, LAST_SIGNAL);
-
object_class->finalize = gtk_entry_finalize;
widget_class->realize = gtk_entry_realize;
@@ -244,7 +228,7 @@ gtk_entry_class_init (GtkEntryClass *class)
editable_class->get_chars = gtk_entry_get_chars;
editable_class->set_selection = gtk_entry_set_selection;
editable_class->changed = (void (*)(GtkEditable *)) gtk_entry_adjust_scroll;
- class->activate = NULL;
+ editable_class->activate = NULL;
}
static void
@@ -260,6 +244,7 @@ gtk_entry_init (GtkEntry *entry)
entry->text_max_length = 0;
entry->scroll_offset = 0;
entry->timer = 0;
+ entry->button = 0;
entry->visible = 1;
gtk_entry_grow_text (entry);
@@ -720,6 +705,18 @@ gtk_entry_button_press (GtkWidget *widget,
entry = GTK_ENTRY (widget);
editable = GTK_EDITABLE (widget);
+ if (entry->button)
+ {
+ GdkEventButton release_event = *event;
+
+ release_event.type = GDK_BUTTON_RELEASE;
+ release_event.button = entry->button;
+
+ gtk_entry_button_release (widget, &release_event);
+ }
+
+ entry->button = event->button;
+
if (!GTK_WIDGET_HAS_FOCUS (widget))
gtk_widget_grab_focus (widget);
@@ -788,11 +785,16 @@ gtk_entry_button_release (GtkWidget *widget,
g_return_val_if_fail (GTK_IS_ENTRY (widget), FALSE);
g_return_val_if_fail (event != NULL, FALSE);
+ entry = GTK_ENTRY (widget);
+ editable = GTK_EDITABLE (widget);
+
+ if (entry->button != event->button)
+ return FALSE;
+
+ entry->button = 0;
+
if (event->button == 1)
{
- entry = GTK_ENTRY (widget);
- editable = GTK_EDITABLE (widget);
-
gtk_grab_remove (widget);
editable->has_selection = FALSE;
@@ -832,6 +834,9 @@ gtk_entry_motion_notify (GtkWidget *widget,
entry = GTK_ENTRY (widget);
+ if (entry->button == 0)
+ return FALSE;
+
x = event->x;
if (event->is_hint || (entry->text_area != event->window))
gdk_window_get_pointer (entry->text_area, &x, NULL, NULL);
@@ -853,7 +858,8 @@ gtk_entry_key_press (GtkWidget *widget,
gint return_val;
gint key;
- gint tmp_pos;
+ guint initial_pos;
+ guint tmp_pos;
gint extend_selection;
gint extend_start;
@@ -868,6 +874,8 @@ gtk_entry_key_press (GtkWidget *widget,
if(editable->editable == FALSE)
return FALSE;
+ initial_pos = editable->current_pos;
+
extend_selection = event->state & GDK_SHIFT_MASK;
extend_start = FALSE;
@@ -886,9 +894,7 @@ gtk_entry_key_press (GtkWidget *widget,
{
case GDK_BackSpace:
return_val = TRUE;
- if (editable->selection_start_pos != editable->selection_end_pos)
- gtk_editable_delete_selection (editable);
- else if (event->state & GDK_CONTROL_MASK)
+ if (event->state & GDK_CONTROL_MASK)
gtk_delete_backward_word (entry);
else
gtk_delete_backward_character (entry);
@@ -897,28 +903,31 @@ gtk_entry_key_press (GtkWidget *widget,
return_val = TRUE;
gtk_delete_line (entry);
break;
- case GDK_Insert:
- return_val = TRUE;
- if (event->state & GDK_SHIFT_MASK)
- {
- extend_selection = FALSE;
- gtk_editable_paste_clipboard (editable, event->time);
- }
- else if (event->state & GDK_CONTROL_MASK)
- {
- gtk_editable_copy_clipboard (editable, event->time);
- }
- else
- {
- /* gtk_toggle_insert(entry) -- IMPLEMENT */
- }
- break;
+ case GDK_Insert:
+ return_val = TRUE;
+ if (event->state & GDK_SHIFT_MASK)
+ {
+ extend_selection = FALSE;
+ gtk_editable_paste_clipboard (editable, event->time);
+ }
+ else if (event->state & GDK_CONTROL_MASK)
+ {
+ gtk_editable_copy_clipboard (editable, event->time);
+ }
+ else
+ {
+ /* gtk_toggle_insert(entry) -- IMPLEMENT */
+ }
+ break;
case GDK_Delete:
return_val = TRUE;
if (event->state & GDK_CONTROL_MASK)
- gtk_delete_line (entry);
+ gtk_delete_forward_word (entry);
else if (event->state & GDK_SHIFT_MASK)
- gtk_editable_cut_clipboard (editable, event->time);
+ {
+ extend_selection = FALSE;
+ gtk_editable_cut_clipboard (editable, event->time);
+ }
else
gtk_delete_forward_character (entry);
break;
@@ -932,15 +941,21 @@ gtk_entry_key_press (GtkWidget *widget,
break;
case GDK_Left:
return_val = TRUE;
- gtk_move_backward_character (entry);
+ if (event->state & GDK_CONTROL_MASK)
+ gtk_move_backward_word (entry);
+ else
+ gtk_move_backward_character (entry);
break;
case GDK_Right:
return_val = TRUE;
- gtk_move_forward_character (entry);
+ if (event->state & GDK_CONTROL_MASK)
+ gtk_move_forward_word (entry);
+ else
+ gtk_move_forward_character (entry);
break;
case GDK_Return:
return_val = TRUE;
- gtk_signal_emit (GTK_OBJECT (entry), entry_signals[ACTIVATE]);
+ gtk_signal_emit_by_name (GTK_OBJECT (entry), "activate");
break;
/* The next two keys should not be inserted literally. Any others ??? */
case GDK_Tab:
@@ -990,7 +1005,7 @@ gtk_entry_key_press (GtkWidget *widget,
break;
}
- if (return_val)
+ if (return_val && (editable->current_pos != initial_pos))
{
if (extend_selection)
{
diff --git a/gtk/gtkentry.h b/gtk/gtkentry.h
index eb45b45d2..5974934eb 100644
--- a/gtk/gtkentry.h
+++ b/gtk/gtkentry.h
@@ -51,13 +51,12 @@ struct _GtkEntry
gint16 scroll_offset;
guint visible : 1;
guint32 timer;
+ guint button;
};
struct _GtkEntryClass
{
GtkEditableClass parent_class;
-
- void (* activate) (GtkEntry *entry);
};
guint gtk_entry_get_type (void);
diff --git a/gtk/gtkmenuitem.c b/gtk/gtkmenuitem.c
index 582d33c27..3d228d864 100644
--- a/gtk/gtkmenuitem.c
+++ b/gtk/gtkmenuitem.c
@@ -698,7 +698,11 @@ gtk_menu_item_position_menu (GtkMenu *menu,
screen_width = gdk_screen_width ();
screen_height = gdk_screen_height ();
- g_return_if_fail (gdk_window_get_origin (GTK_WIDGET (menu_item)->window, &tx, &ty));
+ if (!gdk_window_get_origin (GTK_WIDGET (menu_item)->window, &tx, &ty))
+ {
+ g_warning ("Menu not on screen");
+ return;
+ }
switch (menu_item->submenu_placement)
{
diff --git a/gtk/gtkspinbutton.c b/gtk/gtkspinbutton.c
index c779c0920..69d97f3bd 100644
--- a/gtk/gtkspinbutton.c
+++ b/gtk/gtkspinbutton.c
@@ -74,7 +74,7 @@ static gint gtk_spin_button_key_press (GtkWidget *widget,
GdkEventKey *event);
static void gtk_spin_button_update (GtkSpinButton *spin_button);
static void gtk_spin_button_changed (GtkEditable *editable);
-static void gtk_spin_button_activate (GtkEntry *entry);
+static void gtk_spin_button_activate (GtkEditable *editable);
static GtkWidgetClass *parent_class = NULL;
@@ -110,11 +110,9 @@ gtk_spin_button_class_init (GtkSpinButtonClass *class)
GtkObjectClass *object_class;
GtkWidgetClass *widget_class;
GtkEditableClass *editable_class;
- GtkEntryClass *entry_class;
object_class = (GtkObjectClass*) class;
widget_class = (GtkWidgetClass*) class;
- entry_class = (GtkEntryClass*) class;
editable_class = (GtkEditableClass*) class;
parent_class = gtk_type_class (gtk_entry_get_type ());
@@ -138,7 +136,7 @@ gtk_spin_button_class_init (GtkSpinButtonClass *class)
widget_class->focus_out_event = gtk_spin_button_focus_out;
editable_class->changed = gtk_spin_button_changed;
- entry_class->activate = gtk_spin_button_activate;
+ editable_class->activate = gtk_spin_button_activate;
}
static void
@@ -942,13 +940,13 @@ gtk_spin_button_changed (GtkEditable *editable)
}
static void
-gtk_spin_button_activate (GtkEntry *entry)
+gtk_spin_button_activate (GtkEditable *editable)
{
- g_return_if_fail (entry != NULL);
- g_return_if_fail (GTK_IS_SPIN_BUTTON (entry));
+ g_return_if_fail (editable != NULL);
+ g_return_if_fail (GTK_IS_SPIN_BUTTON (editable));
- if (GTK_EDITABLE(entry)->editable)
- gtk_spin_button_update (GTK_SPIN_BUTTON (entry));
+ if (editable->editable)
+ gtk_spin_button_update (GTK_SPIN_BUTTON (editable));
}
void
diff --git a/gtk/gtktext.c b/gtk/gtktext.c
index 705412bc3..c1f3c830e 100644
--- a/gtk/gtktext.c
+++ b/gtk/gtktext.c
@@ -41,6 +41,8 @@
#define SCROLL_PIXELS 5
#define KEY_SCROLL_PIXELS 10
#define SCROLL_TIME 100
+#define FREEZE_LENGTH 1024
+/* Freeze text when inserting or deleting more than this many characters */
#define SET_PROPERTY_MARK(m, p, o) do { \
(m)->property = (p); \
@@ -224,7 +226,7 @@ static void find_line_containing_point (GtkText* text, guint point,
static TextProperty* new_text_property (GdkFont* font, GdkColor* fore, GdkColor* back, guint length);
/* Display */
-static void compute_lines_pixels (GtkText* text, gint char_count,
+static void compute_lines_pixels (GtkText* text, guint char_count,
guint *lines, guint *pixels);
static gint total_line_height (GtkText* text,
@@ -237,7 +239,7 @@ static LineParams find_line_params (GtkText* text,
static void recompute_geometry (GtkText* text);
static void insert_expose (GtkText* text, guint old_pixels, gint nchars, guint new_line_count);
static void delete_expose (GtkText* text,
- gint nchars,
+ guint nchars,
guint old_lines,
guint old_pixels);
static void clear_area (GtkText *text, GdkRectangle *area);
@@ -283,6 +285,9 @@ static void gtk_text_move_forward_word (GtkText *text);
static void gtk_text_move_backward_word (GtkText *text);
static void gtk_text_move_beginning_of_line (GtkText *text);
static void gtk_text_move_end_of_line (GtkText *text);
+static void gtk_text_move_next_line (GtkText *text);
+static void gtk_text_move_previous_line (GtkText *text);
+
static void gtk_text_delete_forward_character (GtkText *text);
static void gtk_text_delete_backward_character (GtkText *text);
static void gtk_text_delete_forward_word (GtkText *text);
@@ -359,9 +364,9 @@ static GtkTextFunction control_keys[26] =
(GtkTextFunction)gtk_text_delete_to_line_end, /* k */
NULL, /* l */
NULL, /* m */
- NULL, /* n */
+ (GtkTextFunction)gtk_text_move_next_line, /* n */
NULL, /* o */
- NULL, /* p */
+ (GtkTextFunction)gtk_text_move_previous_line, /* p */
NULL, /* q */
NULL, /* r */
NULL, /* s */
@@ -492,6 +497,7 @@ gtk_text_init (GtkText *text)
text->line_wrap = TRUE;
text->timer = 0;
+ text->button = 0;
GTK_EDITABLE(text)->editable = FALSE;
}
@@ -654,13 +660,15 @@ gtk_text_insert (GtkText *text,
GdkColor *fore,
GdkColor *back,
const char *chars,
- gint length)
+ gint nchars)
{
gint i;
GtkEditable *editable = GTK_EDITABLE (text);
+ gboolean frozen = FALSE;
gint new_line_count = 1;
guint old_height = 0;
+ guint length;
g_return_if_fail (text != NULL);
g_return_if_fail (GTK_IS_TEXT (text));
@@ -668,17 +676,25 @@ gtk_text_insert (GtkText *text,
/* This must be because we need to have the style set up. */
g_assert (GTK_WIDGET_REALIZED(text));
- if (fore == NULL)
- fore = &GTK_WIDGET (text)->style->text[GTK_STATE_NORMAL];
- if (back == NULL)
- back = &GTK_WIDGET (text)->style->base[GTK_STATE_NORMAL];
-
- if (length < 0)
+ if (nchars < 0)
length = strlen (chars);
+ else
+ length = nchars;
if (length == 0)
return;
+ if (!text->freeze && (length > FREEZE_LENGTH))
+ {
+ gtk_text_freeze (text);
+ frozen = TRUE;
+ }
+
+ if (fore == NULL)
+ fore = &GTK_WIDGET (text)->style->text[GTK_STATE_NORMAL];
+ if (back == NULL)
+ back = &GTK_WIDGET (text)->style->base[GTK_STATE_NORMAL];
+
if (!text->freeze && (text->line_start_cache != NULL))
{
find_line_containing_point (text, text->point.index, TRUE);
@@ -695,6 +711,9 @@ gtk_text_insert (GtkText *text,
editable->selection_start_pos += length;
if (text->point.index < editable->selection_end_pos)
editable->selection_end_pos += length;
+ /* We'll reset the cursor later anyways if we aren't frozen */
+ if (text->point.index < text->cursor_mark.index)
+ text->cursor_mark.index += length;
move_gap_to_point (text);
@@ -714,6 +733,9 @@ gtk_text_insert (GtkText *text,
if (!text->freeze && (text->line_start_cache != NULL))
insert_expose (text, old_height, length, new_line_count);
+
+ if (frozen)
+ gtk_text_thaw (text);
}
gint
@@ -736,7 +758,8 @@ gtk_text_forward_delete (GtkText *text,
guint nchars)
{
guint old_lines, old_height;
- GtkEditable *editable = GTK_EDITABLE (text);
+ GtkEditable *editable = GTK_EDITABLE (text);
+ gboolean frozen = FALSE;
g_return_val_if_fail (text != NULL, 0);
g_return_val_if_fail (GTK_IS_TEXT (text), 0);
@@ -744,6 +767,12 @@ gtk_text_forward_delete (GtkText *text,
if (text->point.index + nchars > TEXT_LENGTH (text) || nchars <= 0)
return FALSE;
+ if (!text->freeze && (nchars > FREEZE_LENGTH))
+ {
+ gtk_text_freeze (text);
+ frozen = TRUE;
+ }
+
if (!text->freeze && (text->line_start_cache != NULL))
{
find_line_containing_point (text, text->point.index, TRUE);
@@ -768,6 +797,10 @@ gtk_text_forward_delete (GtkText *text,
editable->selection_start_pos -= nchars;
if (text->point.index < editable->selection_end_pos)
editable->selection_end_pos -= nchars;
+ /* We'll reset the cursor later anyways if we aren't frozen */
+ if (text->point.index < text->cursor_mark.index)
+ text->cursor_mark.index -= nchars;
+
move_gap_to_point (text);
@@ -778,6 +811,9 @@ gtk_text_forward_delete (GtkText *text,
if (!text->freeze && (text->line_start_cache != NULL))
delete_expose (text, nchars, old_lines, old_height);
+ if (frozen)
+ gtk_text_thaw (text);
+
return TRUE;
}
@@ -1307,20 +1343,31 @@ gtk_text_button_press (GtkWidget *widget,
text = GTK_TEXT (widget);
editable = GTK_EDITABLE (widget);
+
+ if (text->button)
+ {
+ GdkEventButton release_event = *event;
+
+ release_event.type = GDK_BUTTON_RELEASE;
+ release_event.button = text->button;
+
+ gtk_text_button_release (widget, &release_event);
+ }
+
+ text->button = event->button;
if (!GTK_WIDGET_HAS_FOCUS (widget))
gtk_widget_grab_focus (widget);
- if (event->type == GDK_BUTTON_PRESS && event->button != 2)
- gtk_grab_add (widget);
-
if (event->button == 1)
{
switch (event->type)
{
case GDK_BUTTON_PRESS:
+ gtk_grab_add (widget);
+
undraw_cursor (text, FALSE);
- find_mouse_cursor (text, event->x, event->y);
+ find_mouse_cursor (text, (gint)event->x, (gint)event->y);
draw_cursor (text, FALSE);
/* Set it now, so we display things right. We'll unset it
@@ -1352,7 +1399,7 @@ gtk_text_button_press (GtkWidget *widget,
editable->has_selection)
{
undraw_cursor (text, FALSE);
- find_mouse_cursor (text, event->x, event->y);
+ find_mouse_cursor (text, (gint)event->x, (gint)event->y);
draw_cursor (text, FALSE);
}
@@ -1362,6 +1409,8 @@ gtk_text_button_press (GtkWidget *widget,
}
else
{
+ gtk_grab_add (widget);
+
undraw_cursor (text, FALSE);
find_mouse_cursor (text, event->x, event->y);
draw_cursor (text, FALSE);
@@ -1391,6 +1440,13 @@ gtk_text_button_release (GtkWidget *widget,
text = GTK_TEXT (widget);
+ gtk_grab_remove (widget);
+
+ if (text->button != event->button)
+ return FALSE;
+
+ text->button = 0;
+
if (text->timer)
{
gtk_timeout_remove (text->timer);
@@ -1429,7 +1485,7 @@ gtk_text_button_release (GtkWidget *widget,
undraw_cursor (text, FALSE);
find_cursor (text, TRUE);
draw_cursor (text, FALSE);
-
+
return FALSE;
}
@@ -1456,7 +1512,8 @@ gtk_text_motion_notify (GtkWidget *widget,
gdk_window_get_pointer (text->text_area, &x, &y, &mask);
}
- if (!(mask & (GDK_BUTTON1_MASK | GDK_BUTTON3_MASK)))
+ if ((text->button == 0) ||
+ !(mask & (GDK_BUTTON1_MASK | GDK_BUTTON3_MASK)))
return FALSE;
gdk_window_get_size (text->text_area, NULL, &height);
@@ -1552,16 +1609,26 @@ gtk_text_key_press (GtkWidget *widget,
key = event->keyval;
return_val = TRUE;
- if (GTK_EDITABLE(text)->editable == FALSE)
+ if ((GTK_EDITABLE(text)->editable == FALSE) || !text->has_cursor)
{
switch (event->keyval)
{
- case GDK_Home: scroll_int (text, -text->vadj->value); break;
- case GDK_End: scroll_int (text, +text->vadj->upper); break;
+ case GDK_Home:
+ if (event->state & GDK_CONTROL_MASK)
+ scroll_int (text, -text->vadj->value);
+ break;
+ case GDK_End:
+ if (event->state & GDK_CONTROL_MASK)
+ scroll_int (text, +text->vadj->upper);
+ break;
case GDK_Page_Up: scroll_int (text, -text->vadj->page_increment); break;
case GDK_Page_Down: scroll_int (text, +text->vadj->page_increment); break;
case GDK_Up: scroll_int (text, -KEY_SCROLL_PIXELS); break;
case GDK_Down: scroll_int (text, +KEY_SCROLL_PIXELS); break;
+ case GDK_Return:
+ if (event->state & GDK_CONTROL_MASK)
+ gtk_signal_emit_by_name (GTK_OBJECT (text), "activate");
+ break;
default:
return_val = FALSE;
break;
@@ -1571,6 +1638,7 @@ gtk_text_key_press (GtkWidget *widget,
{
gint extend_selection;
gint extend_start;
+ guint initial_pos = editable->current_pos;
text->point = find_mark (text, text->cursor_mark.index);
@@ -1592,54 +1660,79 @@ gtk_text_key_press (GtkWidget *widget,
switch (event->keyval)
{
- case GDK_Home: move_cursor_buffer_ver (text, -1); break;
- case GDK_End: move_cursor_buffer_ver (text, +1); break;
+ case GDK_Home:
+ if (event->state & GDK_CONTROL_MASK)
+ move_cursor_buffer_ver (text, -1);
+ else
+ gtk_text_move_beginning_of_line (text);
+ break;
+ case GDK_End:
+ if (event->state & GDK_CONTROL_MASK)
+ move_cursor_buffer_ver (text, +1);
+ else
+ gtk_text_move_end_of_line (text);
+ break;
case GDK_Page_Up: move_cursor_page_ver (text, -1); break;
case GDK_Page_Down: move_cursor_page_ver (text, +1); break;
+ /* CUA has Ctrl-Up/Ctrl-Down as paragraph up down */
case GDK_Up: move_cursor_ver (text, -1); break;
case GDK_Down: move_cursor_ver (text, +1); break;
- case GDK_Left: move_cursor_hor (text, -1); break;
- case GDK_Right: move_cursor_hor (text, +1); break;
+ case GDK_Left:
+ if (event->state & GDK_CONTROL_MASK)
+ gtk_text_move_backward_word (text);
+ else
+ move_cursor_hor (text, -1);
+ break;
+ case GDK_Right:
+ if (event->state & GDK_CONTROL_MASK)
+ gtk_text_move_forward_word (text);
+ else
+ move_cursor_hor (text, +1);
+ break;
case GDK_BackSpace:
- if (editable->selection_start_pos != editable->selection_end_pos)
+ if (event->state & GDK_CONTROL_MASK)
+ gtk_text_delete_backward_word (text);
+ else
+ gtk_text_delete_backward_character (text);
+ break;
+ case GDK_Clear:
+ gtk_text_delete_line (text);
+ break;
+ case GDK_Insert:
+ if (event->state & GDK_SHIFT_MASK)
{
- gtk_editable_delete_selection (editable);
- break;
+ extend_selection = FALSE;
+ gtk_editable_paste_clipboard (editable, event->time);
}
- if (text->has_cursor && text->cursor_mark.index != 0)
+ else if (event->state & GDK_CONTROL_MASK)
{
- if (event->state & GDK_CONTROL_MASK)
- gtk_text_delete_backward_word (text);
- else
- gtk_text_backward_delete (text, 1);
+ gtk_editable_copy_clipboard (editable, event->time);
}
- break;
- case GDK_Delete:
- if (editable->selection_start_pos != editable->selection_end_pos)
+ else
{
- gtk_editable_delete_selection (editable);
- break;
+ /* gtk_toggle_insert(text) -- IMPLEMENT */
}
- if (text->has_cursor && !LAST_INDEX(text, text->cursor_mark))
+ break;
+ case GDK_Delete:
+ if (event->state & GDK_CONTROL_MASK)
+ gtk_text_delete_forward_word (text);
+ else if (event->state & GDK_SHIFT_MASK)
{
- if (event->state & GDK_CONTROL_MASK)
- gtk_text_delete_forward_word (text);
- else
- gtk_text_forward_delete (text, 1);
+ extend_selection = FALSE;
+ gtk_editable_cut_clipboard (editable, event->time);
}
+ else
+ gtk_text_delete_forward_character (text);
break;
case GDK_Tab:
- if (!text->has_cursor)
- break;
-
gtk_text_insert_1_at_point (text, '\t');
break;
case GDK_Return:
- if (!text->has_cursor)
- break;
-
- gtk_text_insert_1_at_point (text, '\n');
+ if (event->state & GDK_CONTROL_MASK)
+ gtk_signal_emit_by_name (GTK_OBJECT (text), "activate");
+ else
+ gtk_text_insert_1_at_point (text, '\n');
break;
case GDK_Escape:
/* Don't insert literally */
@@ -1649,9 +1742,6 @@ gtk_text_key_press (GtkWidget *widget,
default:
return_val = FALSE;
- if (!text->has_cursor)
- break;
-
if (event->state & GDK_CONTROL_MASK)
{
if ((key >= 'A') && (key <= 'Z'))
@@ -1695,7 +1785,7 @@ gtk_text_key_press (GtkWidget *widget,
return_val = FALSE;
}
- if (return_val)
+ if (return_val && (editable->current_pos != initial_pos))
{
if (extend_selection)
{
@@ -1983,31 +2073,32 @@ fetch_lines_forward (GtkText* text, gint line_count)
* starting from the point
*/
static void
-compute_lines_pixels (GtkText* text, gint char_count,
+compute_lines_pixels (GtkText* text, guint char_count,
guint *lines, guint *pixels)
{
GList *line = text->current_line;
+ gint chars_left = char_count;
*lines = 0;
*pixels = 0;
- /* If char_count == 0, that means we're joining two lines in a
+ /* If chars_left == 0, that means we're joining two lines in a
* deletion, so add in the values for the next line as well
*/
- for (; line && char_count >= 0; line = line->next)
+ for (; line && chars_left >= 0; line = line->next)
{
*pixels += LINE_HEIGHT(CACHE_DATA(line));
if (line == text->current_line)
- char_count -= CACHE_DATA(line).end.index - text->point.index + 1;
+ chars_left -= CACHE_DATA(line).end.index - text->point.index + 1;
else
- char_count -= CACHE_DATA(line).end.index -CACHE_DATA(line).start.index + 1;
+ chars_left -= CACHE_DATA(line).end.index -CACHE_DATA(line).start.index + 1;
if (!text->line_wrap || !CACHE_DATA(line).wraps)
*lines += 1;
else
- if (char_count < 0)
- char_count = 0; /* force another loop */
+ if (chars_left < 0)
+ chars_left = 0; /* force another loop */
if (!line->next)
fetch_lines_forward (text, 1);
@@ -2034,7 +2125,7 @@ total_line_height (GtkText* text, GList* line, gint line_count)
}
static void
-swap_lines (GtkText* text, GList* old, GList* new, gint old_line_count)
+swap_lines (GtkText* text, GList* old, GList* new, guint old_line_count)
{
if (old == text->line_start_cache)
{
@@ -2104,9 +2195,15 @@ correct_cache_delete (GtkText* text, gint nchars, gint lines)
start->index -= nchars;
end->index -= nchars;
- if (start->property == text->point.property)
+ if (LAST_INDEX (text, text->point) &&
+ start->index == text->point.index)
+ *start = text->point;
+ else if (start->property == text->point.property)
start->offset = start->index - (text->point.index - text->point.offset);
+ if (LAST_INDEX (text, text->point) &&
+ end->index == text->point.index)
+ *end = text->point;
if (end->property == text->point.property)
end->offset = end->index - (text->point.index - text->point.offset);
@@ -2116,7 +2213,7 @@ correct_cache_delete (GtkText* text, gint nchars, gint lines)
}
static void
-delete_expose (GtkText* text, gint nchars, guint old_lines, guint old_pixels)
+delete_expose (GtkText* text, guint nchars, guint old_lines, guint old_pixels)
{
gint pixel_height;
guint new_pixels = 0;
@@ -2199,7 +2296,10 @@ correct_cache_insert (GtkText* text, gint nchars)
GtkPropertyMark *start = &CACHE_DATA(cache).start;
GtkPropertyMark *end = &CACHE_DATA(cache).end;
- if (start->index >= text->point.index - nchars)
+ if (LAST_INDEX (text, text->point) &&
+ start->index == text->point.index)
+ *start = text->point;
+ else if (start->index >= text->point.index - nchars)
{
if (start->property == text->point.property)
move_mark_n(start, nchars);
@@ -2207,6 +2307,9 @@ correct_cache_insert (GtkText* text, gint nchars)
start->index += nchars;
}
+ if (LAST_INDEX (text, text->point) &&
+ end->index == text->point.index)
+ *end = text->point;
if (end->index >= text->point.index - nchars)
{
if (end->property == text->point.property)
@@ -2451,6 +2554,15 @@ insert_text_property (GtkText* text, GdkFont* font,
backward_prop->length += len;
}
+ else if ((MARK_NEXT_LIST_PTR(mark) == NULL) &&
+ (forward_prop->length == 1))
+ {
+ /* Next property just has last position, take it over */
+ forward_prop->font = get_text_font (font);
+ forward_prop->fore_color = *fore;
+ forward_prop->back_color = *back;
+ forward_prop->length += len;
+ }
else
{
/* Splice a new property into the list. */
@@ -2478,6 +2590,22 @@ insert_text_property (GtkText* text, GdkFont* font,
{
forward_prop->length += len;
}
+ else if ((MARK_NEXT_LIST_PTR(mark) == NULL) &&
+ (MARK_OFFSET(mark) == forward_prop->length - 1))
+ {
+ /* Inserting before only the last position in the text */
+
+ GList* new_prop;
+ forward_prop->length -= 1;
+
+ new_prop = g_list_alloc();
+ new_prop->data = new_text_property (font, fore, back, len+1);
+ new_prop->prev = MARK_LIST_PTR(mark);
+ new_prop->next = NULL;
+ MARK_NEXT_LIST_PTR(mark) = new_prop;
+
+ SET_PROPERTY_MARK (mark, new_prop, 0);
+ }
else
{
GList* new_prop = g_list_alloc();
@@ -2543,6 +2671,7 @@ delete_text_property (GtkText* text, guint nchars)
text->point.offset = 0;
g_mem_chunk_free (text_property_chunk, prop);
+ g_list_free_1 (tmp);
prop = MARK_CURRENT_PROPERTY (&text->point);
@@ -2557,6 +2686,26 @@ delete_text_property (GtkText* text, guint nchars)
text->point.offset = 0;
}
}
+
+ /* Check to see if we have just the single final position remaining
+ * along in a property; if so, combine it with the previous property
+ */
+ if (LAST_INDEX (text, text->point) &&
+ (MARK_OFFSET (&text->point) == 0) &&
+ (MARK_PREV_LIST_PTR(&text->point) != NULL))
+ {
+ tmp = MARK_LIST_PTR (&text->point);
+ prop = MARK_CURRENT_PROPERTY(&text->point);
+
+ MARK_LIST_PTR (&text->point) = MARK_PREV_LIST_PTR (&text->point);
+ MARK_CURRENT_PROPERTY(&text->point)->length += 1;
+ MARK_NEXT_LIST_PTR(&text->point) = NULL;
+
+ text->point.offset = MARK_CURRENT_PROPERTY(&text->point)->length - 1;
+
+ g_mem_chunk_free (text_property_chunk, prop);
+ g_list_free_1 (tmp);
+ }
}
static void
@@ -2859,8 +3008,9 @@ find_cursor_at_line (GtkText* text, const LineParams* start_line, gint pixel_hei
text->cursor_char_offset = start_line->font_descent;
text->cursor_mark = mark;
- ch = GTK_TEXT_INDEX (text, mark.index);
-
+ ch = LAST_INDEX (text, mark) ?
+ LINE_DELIM : GTK_TEXT_INDEX (text, mark.index);
+
if (!isspace(ch))
text->cursor_char = ch;
else
@@ -2922,7 +3072,8 @@ find_mouse_cursor_at_line (GtkText *text, const LineParams* lp,
for (;;)
{
- gchar ch = GTK_TEXT_INDEX (text, mark.index);
+ gchar ch = LAST_INDEX (text, mark) ?
+ LINE_DELIM : GTK_TEXT_INDEX (text, mark.index);
if (button_x < pixel_width || mark.index == lp->end.index)
{
@@ -3025,10 +3176,25 @@ remove_cache_line (GtkText* text, GList* member)
static void
move_cursor_buffer_ver (GtkText *text, int dir)
{
+ undraw_cursor (text, FALSE);
+
if (dir > 0)
- scroll_int (text, text->vadj->upper);
+ {
+ scroll_int (text, text->vadj->upper);
+ text->cursor_mark = find_this_line_start_mark (text,
+ TEXT_LENGTH (text),
+ &text->cursor_mark);
+ }
else
- scroll_int (text, - text->vadj->value);
+ {
+ scroll_int (text, - text->vadj->value);
+ text->cursor_mark = find_this_line_start_mark (text,
+ 0,
+ &text->cursor_mark);
+ }
+
+ find_cursor (text, TRUE);
+ draw_cursor (text, FALSE);
}
static void
@@ -3126,6 +3292,18 @@ gtk_text_move_backward_character (GtkText *text)
}
static void
+gtk_text_move_next_line (GtkText *text)
+{
+ move_cursor_ver (text, 1);
+}
+
+static void
+gtk_text_move_previous_line (GtkText *text)
+{
+ move_cursor_ver (text, -1);
+}
+
+static void
gtk_text_move_forward_word (GtkText *text)
{
undraw_cursor (text, FALSE);
@@ -3163,7 +3341,11 @@ static void
gtk_text_move_beginning_of_line (GtkText *text)
{
undraw_cursor (text, FALSE);
- text->cursor_mark = CACHE_DATA(text->current_line).start;
+
+ while ((text->cursor_mark.index > 0) &&
+ (GTK_TEXT_INDEX (text, text->cursor_mark.index - 1) != LINE_DELIM))
+ decrement_mark (&text->cursor_mark);
+
find_cursor (text, TRUE);
draw_cursor (text, FALSE);
}
@@ -3172,7 +3354,11 @@ static void
gtk_text_move_end_of_line (GtkText *text)
{
undraw_cursor (text, FALSE);
- text->cursor_mark = CACHE_DATA(text->current_line).end;
+
+ while (!LAST_INDEX (text, text->cursor_mark) &&
+ (GTK_TEXT_INDEX (text, text->cursor_mark.index) != LINE_DELIM))
+ advance_mark (&text->cursor_mark);
+
find_cursor (text, TRUE);
draw_cursor (text, FALSE);
}
@@ -3221,7 +3407,8 @@ gtk_text_delete_forward_word (GtkText *text)
{
old_pos = text->cursor_mark.index;
gtk_text_move_forward_word (text);
- gtk_text_backward_delete (text, old_pos - text->cursor_mark.index);
+ gtk_text_set_point (text, text->cursor_mark.index);
+ gtk_text_backward_delete (text, text->cursor_mark.index - old_pos);
gtk_editable_changed (editable);
}
}
@@ -3240,7 +3427,8 @@ gtk_text_delete_backward_word (GtkText *text)
{
old_pos = text->point.index;
gtk_text_move_backward_word (text);
- gtk_text_forward_delete (text, text->point.index - old_pos);
+ gtk_text_set_point (text, text->cursor_mark.index);
+ gtk_text_forward_delete (text, old_pos - text->cursor_mark.index);
gtk_editable_changed (editable);
}
}
@@ -3248,10 +3436,18 @@ gtk_text_delete_backward_word (GtkText *text)
static void
gtk_text_delete_line (GtkText *text)
{
- gtk_text_set_point (text, CACHE_DATA(text->current_line).start.index);
- gtk_text_forward_delete (text,
- CACHE_DATA(text->current_line).end.index -
- CACHE_DATA(text->current_line).start.index + 1);
+ gint start_pos;
+ gint end_pos;
+
+ gtk_text_move_beginning_of_line (text);
+ start_pos = text->cursor_mark.index;
+
+ gtk_text_move_end_of_line (text);
+ gtk_text_move_forward_character (text);
+ end_pos = text->cursor_mark.index;
+
+ gtk_text_set_point (text, start_pos);
+ gtk_text_forward_delete (text, end_pos - start_pos);
gtk_editable_changed (GTK_EDITABLE (text));
}
@@ -3259,9 +3455,19 @@ gtk_text_delete_line (GtkText *text)
static void
gtk_text_delete_to_line_end (GtkText *text)
{
- gtk_text_forward_delete (text,
- MAX(CACHE_DATA(text->current_line).end.index -
- text->point.index, 1));
+ gint start_pos;
+ gint end_pos;
+
+ start_pos = text->cursor_mark.index;
+
+ gtk_text_move_end_of_line (text);
+
+ if (start_pos == text->cursor_mark.index)
+ gtk_text_move_forward_character (text);
+ end_pos = text->cursor_mark.index;
+
+ gtk_text_set_point (text, start_pos);
+ gtk_text_forward_delete (text, end_pos - start_pos);
gtk_editable_changed (GTK_EDITABLE (text));
}
@@ -3287,9 +3493,20 @@ gtk_text_select_word (GtkText *text)
static void
gtk_text_select_line (GtkText *text)
{
- gtk_text_set_selection (GTK_EDITABLE (text),
- CACHE_DATA(text->current_line).end.index,
- CACHE_DATA(text->current_line).start.index);
+ gint start_pos;
+ gint end_pos;
+
+ GtkEditable *editable;
+ editable = GTK_EDITABLE (text);
+
+ gtk_text_move_beginning_of_line (text);
+ start_pos = text->cursor_mark.index;
+
+ gtk_text_move_end_of_line (text);
+ gtk_text_move_forward_character (text);
+ end_pos = text->cursor_mark.index;
+
+ gtk_text_set_selection (editable, start_pos, end_pos);
}
/**********************************************************************/
@@ -4480,7 +4697,7 @@ gtk_text_show_props (GtkText *text,
proplen += p->length;
- g_print ("[%d,%p,%p,%p,%p] ", p->length, p, p->font, p->fore_color, p->back_color);
+ g_print ("[%d,%p,%p,%ld,%ld] ", p->length, p, p->font, p->fore_color.pixel, p->back_color.pixel);
}
g_print ("\n");
diff --git a/gtk/gtktext.h b/gtk/gtktext.h
index 19c507a1e..82aa25e7a 100644
--- a/gtk/gtktext.h
+++ b/gtk/gtktext.h
@@ -145,7 +145,9 @@ struct _GtkText
gint default_tab_width;
/* Timer used for auto-scrolling off ends */
- guint32 timer;
+ gint timer;
+
+ guint button; /* currently pressed mouse button */
};
struct _GtkTextClass