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
This commit is contained in:
Owen Taylor 1998-03-10 03:17:02 +00:00 committed by Tim Janik
parent 990bddfe16
commit 2f50a3044e
17 changed files with 583 additions and 314 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

42
TODO
View File

@ -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 (???)
Entry and Text widget widgets (???)
- When inserting or deleting large chunks of text, do a freeze/thaw
automatically, to avoid scrolling around for ever on screen.
- 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.
that.

View File

@ -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:

View File

@ -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",
editable_signals[ACTIVATE] =
gtk_signal_new ("activate",
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",
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,
@ -241,53 +174,6 @@ gtk_editable_init (GtkEditable *editable)
NULL);
}
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)
{
@ -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

View File

@ -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);
};

View File

@ -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)
{

View File

@ -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);

View File

@ -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)
{

View File

@ -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

View File

@ -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 (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 (length < 0)
length = strlen (chars);
if (length == 0)
return;
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);
}
else
{
/* gtk_toggle_insert(text) -- IMPLEMENT */
}
break;
case GDK_Delete:
if (editable->selection_start_pos != editable->selection_end_pos)
if (event->state & GDK_CONTROL_MASK)
gtk_text_delete_forward_word (text);
else if (event->state & GDK_SHIFT_MASK)
{
gtk_editable_delete_selection (editable);
break;
}
if (text->has_cursor && !LAST_INDEX(text, text->cursor_mark))
{
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
@ -3125,6 +3291,18 @@ gtk_text_move_backward_character (GtkText *text)
move_cursor_hor (text, -1);
}
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)
{
@ -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");

View File

@ -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