static void text_change_apply(struct TextObjectChange *change, Object *obj) { Text *text = change->text; switch (change->type) { case TYPE_INSERT_CHAR: text->cursor_pos = change->pos; text->cursor_row = change->row; text_insert_char(text, change->ch); break; case TYPE_DELETE_BACKWARD: text->cursor_pos = change->pos+1; text->cursor_row = change->row; text_delete_backward(text); break; case TYPE_DELETE_FORWARD: text->cursor_pos = change->pos; text->cursor_row = change->row; text_delete_forward(text); break; case TYPE_SPLIT_ROW: text->cursor_pos = change->pos; text->cursor_row = change->row; text_split_line(text); break; case TYPE_JOIN_ROW: text_join_lines(text, change->row); break; } }
static void text_change_apply(struct TextObjectChange *change, DiaObject *obj) { Text *text = change->text; /* remember previous position/size */ if (change->obj->ops->get_props) change->obj->ops->get_props(change->obj, change->props); switch (change->type) { case TYPE_INSERT_CHAR: text->cursor_pos = change->pos; text->cursor_row = change->row; text_insert_char(text, change->ch); break; case TYPE_DELETE_BACKWARD: text->cursor_pos = change->pos+1; text->cursor_row = change->row; text_delete_backward(text); break; case TYPE_DELETE_FORWARD: text->cursor_pos = change->pos; text->cursor_row = change->row; text_delete_forward(text); break; case TYPE_SPLIT_ROW: text->cursor_pos = change->pos; text->cursor_row = change->row; text_split_line(text); break; case TYPE_JOIN_ROW: text_join_lines(text, change->row); break; case TYPE_DELETE_ALL: set_string(text, ""); text->cursor_pos = 0; text->cursor_row = 0; break; } }
static int text_key_event(Focus *focus, guint keyval, char *str, int strlen, ObjectChange **change) { Text *text; int return_val; int row; return_val = FALSE; *change = NULL; text = (Text *)focus->user_data; /* printf("Got an %d '%s' (%d)\n", keyval, str, strlen); */ switch(keyval) { case GDK_Up: text->cursor_row--; if (text->cursor_row<0) text->cursor_row = 0; if (text->cursor_pos > text->strlen[text->cursor_row]) text->cursor_pos = text->strlen[text->cursor_row]; break; case GDK_Down: text->cursor_row++; if (text->cursor_row >= text->numlines) text->cursor_row = text->numlines - 1; if (text->cursor_pos > text->strlen[text->cursor_row]) text->cursor_pos = text->strlen[text->cursor_row]; break; case GDK_Left: text->cursor_pos--; if (text->cursor_pos<0) text->cursor_pos = 0; break; case GDK_Right: text->cursor_pos++; if (text->cursor_pos > text->strlen[text->cursor_row]) text->cursor_pos = text->strlen[text->cursor_row]; break; case GDK_Delete: return_val = TRUE; row = text->cursor_row; if (text->cursor_pos >= text->strlen[row]) { if (row+1 < text->numlines) { *change = text_create_change(text, TYPE_JOIN_ROW, 'Q', text->cursor_pos, row); } else { return_val = FALSE; break; } } else { *change = text_create_change(text, TYPE_DELETE_FORWARD, text->line[row][text->cursor_pos], text->cursor_pos, text->cursor_row); } text_delete_forward(text); break; case GDK_BackSpace: return_val = TRUE; row = text->cursor_row; if (text->cursor_pos <= 0) { if (row > 0) { *change = text_create_change(text, TYPE_JOIN_ROW, 'Q', text->strlen[row-1], row-1); } else { return_val = FALSE; break; } } else { *change = text_create_change(text, TYPE_DELETE_BACKWARD, text->line[row][text->cursor_pos-1], text->cursor_pos-1, text->cursor_row); } text_delete_backward(text); break; case GDK_Return: return_val = TRUE; *change = text_create_change(text, TYPE_SPLIT_ROW, 'Q', text->cursor_pos, text->cursor_row); text_split_line(text); break; default: if (strlen>0) { return_val = TRUE; *change = text_create_change(text, TYPE_INSERT_CHAR, str[0], text->cursor_pos, text->cursor_row); text_insert_char(text, str[0]); } break; } return return_val; }
static int text_key_event(Focus *focus, guint keystate, guint keyval, const gchar *str, int strlen, ObjectChange **change) { Text *text; int return_val = FALSE; int row, i; const char *utf; gunichar c; *change = NULL; text = focus->text; switch(keyval) { case GDK_Up: case GDK_KP_Up: text->cursor_row--; if (text->cursor_row<0) text->cursor_row = 0; if (text->cursor_pos > text_get_line_strlen(text, text->cursor_row)) text->cursor_pos = text_get_line_strlen(text, text->cursor_row); break; case GDK_Down: case GDK_KP_Down: text->cursor_row++; if (text->cursor_row >= text->numlines) text->cursor_row = text->numlines - 1; if (text->cursor_pos > text_get_line_strlen(text, text->cursor_row)) text->cursor_pos = text_get_line_strlen(text, text->cursor_row); break; case GDK_Left: case GDK_KP_Left: if (keystate & GDK_CONTROL_MASK) text_move_cursor(text, WORD_START); else text->cursor_pos--; if (text->cursor_pos<0) text->cursor_pos = 0; break; case GDK_Right: case GDK_KP_Right: if (keystate & GDK_CONTROL_MASK) text_move_cursor(text, WORD_END); else text->cursor_pos++; if (text->cursor_pos > text_get_line_strlen(text, text->cursor_row)) text->cursor_pos = text_get_line_strlen(text, text->cursor_row); break; case GDK_Home: case GDK_KP_Home: text->cursor_pos = 0; break; case GDK_End: case GDK_KP_End: text->cursor_pos = text_get_line_strlen(text, text->cursor_row); break; case GDK_Delete: case GDK_KP_Delete: return_val = text_delete_key_handler(focus, change); break; case GDK_BackSpace: return_val = TRUE; row = text->cursor_row; if (text->cursor_pos <= 0) { if (row > 0) { *change = text_create_change(text, TYPE_JOIN_ROW, 'Q', text_get_line_strlen(text, row-1), row-1, focus->obj); } else { return_val = FALSE; break; } } else { utf = text_get_line(text, row); for (i = 0; i < (text->cursor_pos - 1); i++) utf = g_utf8_next_char (utf); c = g_utf8_get_char (utf); *change = text_create_change (text, TYPE_DELETE_BACKWARD, c, text->cursor_pos - 1, text->cursor_row, focus->obj); } text_delete_backward(text); break; case GDK_Return: case GDK_KP_Enter: return_val = TRUE; *change = text_create_change(text, TYPE_SPLIT_ROW, 'Q', text->cursor_pos, text->cursor_row, focus->obj); text_split_line(text); break; case GDK_Shift_L: case GDK_Shift_R: case GDK_Control_L: case GDK_Control_R: case GDK_Alt_L: case GDK_Alt_R: case GDK_Meta_L: case GDK_Meta_R: return_val = FALSE; /* no text change for modifiers */ break; default: if (str || (strlen>0)) { if (str && *str == '\r') break; /* avoid putting junk into our string */ return_val = TRUE; *change = change_list_create(); for (utf = str; utf && *utf && strlen > 0 ; utf = g_utf8_next_char (utf), strlen--) { ObjectChange *step; c = g_utf8_get_char (utf); step = text_create_change (text, TYPE_INSERT_CHAR, c, text->cursor_pos, text->cursor_row, focus->obj); change_list_add (*change, step); text_insert_char (text, c); } } break; } return return_val; }