diff options
author | Owen Taylor <owt1@cornell.edu> | 1998-03-10 03:17:02 +0000 |
---|---|---|
committer | Tim Janik <timj@src.gnome.org> | 1998-03-10 03:17:02 +0000 |
commit | 2f50a3044ed8bf7783e8362d956b6f77010795cd (patch) | |
tree | ade65b5ee1804697cc26df7b59ed317bc99807cb | |
parent | 990bddfe1688861332443d89a4796a710e18ae39 (diff) | |
download | gdk-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-- | ChangeLog | 22 | ||||
-rw-r--r-- | ChangeLog.pre-2-0 | 22 | ||||
-rw-r--r-- | ChangeLog.pre-2-10 | 22 | ||||
-rw-r--r-- | ChangeLog.pre-2-2 | 22 | ||||
-rw-r--r-- | ChangeLog.pre-2-4 | 22 | ||||
-rw-r--r-- | ChangeLog.pre-2-6 | 22 | ||||
-rw-r--r-- | ChangeLog.pre-2-8 | 22 | ||||
-rw-r--r-- | TODO | 42 | ||||
-rw-r--r-- | docs/text_widget.txt | 10 | ||||
-rw-r--r-- | gtk/gtkeditable.c | 165 | ||||
-rw-r--r-- | gtk/gtkeditable.h | 1 | ||||
-rw-r--r-- | gtk/gtkentry.c | 107 | ||||
-rw-r--r-- | gtk/gtkentry.h | 3 | ||||
-rw-r--r-- | gtk/gtkmenuitem.c | 6 | ||||
-rw-r--r-- | gtk/gtkspinbutton.c | 16 | ||||
-rw-r--r-- | gtk/gtktext.c | 389 | ||||
-rw-r--r-- | gtk/gtktext.h | 4 |
17 files changed, 583 insertions, 314 deletions
@@ -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 @@ -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 = >K_WIDGET (text)->style->text[GTK_STATE_NORMAL]; - if (back == NULL) - back = >K_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 = >K_WIDGET (text)->style->text[GTK_STATE_NORMAL]; + if (back == NULL) + back = >K_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 |