aboutsummaryrefslogtreecommitdiffstats
path: root/widgets/e-table/e-cell-text.c
diff options
context:
space:
mode:
Diffstat (limited to 'widgets/e-table/e-cell-text.c')
-rw-r--r--widgets/e-table/e-cell-text.c241
1 files changed, 124 insertions, 117 deletions
diff --git a/widgets/e-table/e-cell-text.c b/widgets/e-table/e-cell-text.c
index accc4ba3b4..8a6f9d96e2 100644
--- a/widgets/e-table/e-cell-text.c
+++ b/widgets/e-table/e-cell-text.c
@@ -46,12 +46,11 @@
/* This defines a line of text */
struct line {
char *text; /* Line's text UTF-8, it is a pointer into the text->text string */
- int length; /* Line's length in characters */
+ int length; /* Line's length in BYTES */
int width; /* Line's width in pixels */
- int ellipsis_length; /* Length before adding ellipsis */
+ int ellipsis_length; /* Length before adding ellipsis in BYTES */
};
-
/* Object argument IDs */
enum {
ARG_0,
@@ -132,7 +131,7 @@ typedef struct {
typedef struct _CurrentCell{
ECellTextView *text_view;
int width;
- char *text;
+ char *text;
int model_col, view_col, row;
ECellTextLineBreaks *breaks;
} CurrentCell;
@@ -153,8 +152,8 @@ struct _CellEdit {
to the other offsets. */
/* This needs to be reworked a bit once we get line wrapping. */
- int selection_start; /* Start of selection - IN CHARS */
- int selection_end; /* End of selection - IN CHARS */
+ int selection_start; /* Start of selection - IN BYTES */
+ int selection_end; /* End of selection - IN BYTES */
gboolean select_by_word; /* Current selection is by word */
/* This section is for drag scrolling and blinking cursor. */
@@ -176,9 +175,9 @@ struct _CellEdit {
GtkWidget *invisible; /* For selection handling */
gboolean has_selection; /* TRUE if we have the selection */
gchar *primary_selection; /* Primary selection text */
- gint primary_length; /* Primary selection text length */
+ gint primary_length; /* Primary selection text length in BYTES */
gchar *clipboard_selection; /* Clipboard selection text */
- gint clipboard_length; /* Clipboard selection text length*/
+ gint clipboard_length; /* Clipboard selection text length in BYTES */
guint pointer_in : 1;
guint default_cursor_shown : 1;
@@ -438,7 +437,7 @@ ect_draw (ECellView *ecell_view, GdkDrawable *drawable,
GdkRectangle sel_rect;
GdkGC *fg_gc;
EFont *font = text_view->font;
- const int height = e_font_ascent (text_view->font) + e_font_descent (text_view->font);
+ const int height = e_font_height (text_view->font);
CellEdit *edit = text_view->edit;
gboolean edit_display = FALSE;
ECellTextLineBreaks *linebreaks;
@@ -451,7 +450,6 @@ ect_draw (ECellView *ecell_view, GdkDrawable *drawable,
style = E_FONT_BOLD;
if (edit){
-
if ((edit->cell.view_col == view_col) && (edit->cell.row == row)) {
edit_display = TRUE;
fg_gc = canvas->style->fg_gc[edit->has_selection ? GTK_STATE_SELECTED : GTK_STATE_ACTIVE];
@@ -473,7 +471,6 @@ ect_draw (ECellView *ecell_view, GdkDrawable *drawable,
gdk_gc_set_clip_rectangle (fg_gc, &rect);
clip_rect = ▭
-
if (selected){
background = &canvas->style->bg [GTK_STATE_SELECTED];
foreground = &canvas->style->text [GTK_STATE_SELECTED];
@@ -534,9 +531,9 @@ ect_draw (ECellView *ecell_view, GdkDrawable *drawable,
xpos = get_line_xpos (cell, lines);
xpos -= edit->xofs_edit;
- /* All values are IN CHARS */
+ /* start_char, end_char, sel_start and sel_end are IN BYTES */
- start_char = unicode_index_to_offset (cell->text, lines->text - cell->text);
+ start_char = lines->text - cell->text;
end_char = start_char + lines->length;
sel_start = edit->selection_start;
@@ -556,7 +553,7 @@ ect_draw (ECellView *ecell_view, GdkDrawable *drawable,
sel_rect.x = xpos + x1 + e_font_utf8_text_width (font, style, lines->text, sel_start - start_char);
sel_rect.y = ypos + y1 - e_font_ascent (font);
sel_rect.width = e_font_utf8_text_width (font, style,
- lines->text + unicode_offset_to_index (lines->text, sel_start - start_char),
+ lines->text + sel_start - start_char,
sel_end - sel_start);
sel_rect.height = height;
gtk_paint_flat_box (canvas->style,
@@ -577,12 +574,12 @@ ect_draw (ECellView *ecell_view, GdkDrawable *drawable,
e_font_draw_utf8_text (drawable, font, style, fg_gc,
xpos + x1 + e_font_utf8_text_width (font, style, lines->text, sel_start - start_char),
ypos + y1,
- lines->text + unicode_offset_to_index (lines->text, sel_start - start_char),
+ lines->text + sel_start - start_char,
sel_end - sel_start);
e_font_draw_utf8_text (drawable, font, style, text_view->gc,
xpos + x1 + e_font_utf8_text_width (font, style, lines->text, sel_end - start_char),
ypos + y1,
- lines->text + unicode_offset_to_index (lines->text, sel_end - start_char),
+ lines->text + sel_end - start_char,
end_char - sel_end);
#if 0 /* Do Bold in EFont directly */
/* Draw 1,0 moved image, to simulate bold font */
@@ -672,7 +669,7 @@ ect_draw (ECellView *ecell_view, GdkDrawable *drawable,
xpos + x1 + lines->width - text_view->ellipsis_width,
ypos + y1,
ect->ellipsis ? ect->ellipsis : "...",
- ect->ellipsis ? unicode_strlen (ect->ellipsis, -1) : 3);
+ ect->ellipsis ? strlen (ect->ellipsis) : 3);
#if 0
if (bold) {
e_font_draw_ucs2_text (drawable,
@@ -865,7 +862,7 @@ ect_edit_select_all (ECellTextView *text_view)
g_assert (text_view->edit);
text_view->edit->selection_start = 0;
- text_view->edit->selection_end = unicode_strlen (text_view->edit->cell.text, -1);
+ text_view->edit->selection_end = strlen (text_view->edit->cell.text);
}
/*
@@ -1090,7 +1087,7 @@ ect_height (ECellView *ecell_view, int model_col, int view_col, int row)
gint value;
string = (*ect->filter)(e_table_model_value_at (ecell_view->e_table_model, model_col, row));
- value = (e_font_ascent (font) + e_font_descent (font)) * number_of_lines(string) + TEXT_PAD;
+ value = e_font_height (font) * number_of_lines(string) + TEXT_PAD;
g_free(string);
@@ -1101,7 +1098,7 @@ ect_height (ECellView *ecell_view, int model_col, int view_col, int row)
string = e_table_model_value_at (ecell_view->e_table_model, model_col, row);
- value = (e_font_ascent (font) + e_font_descent (font)) * number_of_lines (string) + TEXT_PAD;
+ value = e_font_height (font) * number_of_lines (string) + TEXT_PAD;
return value;
}
@@ -1203,7 +1200,7 @@ ect_print (ECellView *ecell_view, GnomePrintContext *context,
int model_col, int view_col, int row,
double width, double height)
{
- GnomeFont *font = gnome_font_new("Helvetica", 12);
+ GnomeFont *font = gnome_font_new ("Helvetica", 12);
char *string;
ECellText *ect = E_CELL_TEXT(ecell_view->ecell);
if (ect->filter) {
@@ -1421,12 +1418,13 @@ get_line_ypos (CurrentCell *cell, struct line *line)
font = text_view->font;
y = text_view->yofs + ect->y;
- y += (line - lines) * (e_font_ascent (font) + e_font_descent (font));
+ y += (line - lines) * e_font_height (font);
return y;
}
/* fixme: Handle Font attributes */
+/* position is in BYTES */
static void
_get_xy_from_position (CurrentCell *cell, gint position, gint *xp, gint *yp)
@@ -1449,16 +1447,16 @@ _get_xy_from_position (CurrentCell *cell, gint position, gint *xp, gint *yp)
x = get_line_xpos (cell, lines);
y = get_line_ypos (cell, lines);
for (j = 0, lines = linebreaks->lines; j < linebreaks->num_lines; lines++, j++) {
- if (lines->text > cell->text + unicode_offset_to_index (cell->text, position))
+ if (lines->text > cell->text + position)
break;
- y += e_font_ascent (font) + e_font_descent (font);
+ y += e_font_height (font);
}
lines --;
y -= e_font_descent (font);
x += e_font_utf8_text_width (font, E_FONT_PLAIN,
lines->text,
- position - unicode_index_to_offset (cell->text, lines->text - cell->text));
+ position - (lines->text - cell->text));
if ((CellEdit *) cell == cell->text_view->edit){
x -= ((CellEdit *)cell)->xofs_edit;
y -= ((CellEdit *)cell)->yofs_edit;
@@ -1500,7 +1498,7 @@ _get_position_from_xy (CurrentCell *cell, gint x, gint y)
ypos = get_line_ypos (cell, linebreaks->lines);
j = 0;
while (y > ypos) {
- ypos += e_font_ascent (font) + e_font_descent (font);
+ ypos += e_font_height (font);
j ++;
}
j--;
@@ -1513,10 +1511,10 @@ _get_position_from_xy (CurrentCell *cell, gint x, gint y)
lines += j;
xpos = get_line_xpos (cell, lines);
- for (i = 0, p = lines->text; i < lines->length; i++, p = unicode_next_utf8 (p)) {
+ for (p = lines->text; p < lines->text + lines->length; p = unicode_next_utf8 (p)) {
gint charwidth;
- charwidth = e_font_utf8_text_width (font, E_FONT_PLAIN, p, 1);
+ charwidth = e_font_utf8_char_width (font, E_FONT_PLAIN, p);
xpos += charwidth / 2;
if (xpos > x) {
@@ -1525,7 +1523,7 @@ _get_position_from_xy (CurrentCell *cell, gint x, gint y)
xpos += (charwidth + 1) / 2;
}
- return_val = lines->text + i - cell->text;
+ return_val = p - cell->text;
unref_lines (cell);
@@ -1605,7 +1603,6 @@ _blink_scroll_timeout (gpointer data)
static int
_get_position (ECellTextView *text_view, ETextEventProcessorCommand *command)
{
- int i;
int length;
int x, y;
CellEdit *edit = text_view->edit;
@@ -1630,73 +1627,100 @@ _get_position (ECellTextView *text_view, ETextEventProcessorCommand *command)
/* fixme: this probably confuses TEP */
case E_TEP_END_OF_BUFFER:
- return unicode_strlen (cell->text, -1);
+ return strlen (cell->text);
case E_TEP_START_OF_LINE:
- for (i = edit->selection_end - 2, p = cell->text + unicode_offset_to_index (cell->text, i);
- i > 0;
- i--, p = unicode_previous_utf8 (cell->text, p))
- unicode_get_utf8 (p, &unival);
- if (unival == '\n') {
- i++;
- break;
- }
- return i;
+
+ if (edit->selection_end < 1) return 0;
+
+ p = unicode_previous_utf8 (cell->text, cell->text + edit->selection_end);
+
+ if (p == cell->text) return 0;
+
+ p = unicode_previous_utf8 (cell->text, p);
+
+ while (p && p > cell->text) {
+ if (*p == '\n') return p - cell->text + 1;
+ p = unicode_previous_utf8 (cell->text, p);
+ }
+
+ return 0;
+
case E_TEP_END_OF_LINE:
- length = unicode_strlen (cell->text, -1);
+
+ length = strlen (cell->text);
if (edit->selection_end >= length) return length;
- for (i = edit->selection_end + 1, p = cell->text + unicode_offset_to_index (cell->text, i);
- i < length;
- i++, p = unicode_next_utf8 (p))
- unicode_get_utf8 (p, &unival);
- if (unival == '\n') {
- break;
- }
- return i;
+
+ p = unicode_next_utf8 (cell->text + edit->selection_end);
+
+ while (*p) {
+ if (*p == '\n') return p - cell->text;
+ p = unicode_next_utf8 (p);
+ }
+
+ return p - cell->text;
case E_TEP_FORWARD_CHARACTER:
- length = unicode_strlen (cell->text, -1);
- i = edit->selection_end + 1;
- if (i > length)
- i = length;
- return i;
+
+ length = strlen (cell->text);
+ if (edit->selection_end >= length) return length;
+
+ p = unicode_next_utf8 (cell->text + edit->selection_end);
+
+ return p - cell->text;
+
case E_TEP_BACKWARD_CHARACTER:
- i = edit->selection_end - 1;
- if (i < 0)
- i = 0;
- return i;
+
+ if (edit->selection_end < 1) return 0;
+
+ p = unicode_previous_utf8 (cell->text, cell->text + edit->selection_end);
+
+ if (p == NULL) return 0;
+
+ return p - cell->text;
case E_TEP_FORWARD_WORD:
- length = unicode_strlen (cell->text, -1);
+
+ length = strlen (cell->text);
if (edit->selection_end >= length) return length;
- for (i = edit->selection_end + 1, p = cell->text + unicode_offset_to_index (cell->text, i);
- i < length;
- i++, p = unicode_next_utf8 (p))
- unicode_get_utf8 (p, &unival);
- if (unicode_isspace (unival)) { /* fixme: */
- break;
- }
- return i;
+
+ p = unicode_next_utf8 (cell->text + edit->selection_end);
+
+ while (*p) {
+ unicode_get_utf8 (p, &unival);
+ if (unicode_isspace (unival)) return p - cell->text;
+ p = unicode_next_utf8 (p);
+ }
+
+ return p - cell->text;
+
case E_TEP_BACKWARD_WORD:
- for (i = edit->selection_end - 2, p = cell->text + unicode_offset_to_index (cell->text, i);
- i > 0;
- i--, p = unicode_previous_utf8 (cell->text, p))
- unicode_get_utf8 (p, &unival);
- if (unicode_isspace (unival)) { /* fixme: */
- i++;
- break;
+
+ if (edit->selection_end < 1) return 0;
+
+ p = unicode_previous_utf8 (cell->text, cell->text + edit->selection_end);
+
+ if (p == cell->text) return 0;
+
+ p = unicode_previous_utf8 (cell->text, p);
+
+ while (p && p > cell->text) {
+ unicode_get_utf8 (p, &unival);
+ if (unicode_isspace (unival)) {
+ return (unicode_next_utf8 (p) - cell->text);
}
- if (i < 0)
- i = 0;
- return i;
+ p = unicode_previous_utf8 (cell->text, p);
+ }
+
+ return 0;
case E_TEP_FORWARD_LINE:
_get_xy_from_position (cell, edit->selection_end, &x, &y);
- y += e_font_ascent (font) + e_font_descent (font);
+ y += e_font_height (font);
return _get_position_from_xy (cell, x, y);
case E_TEP_BACKWARD_LINE:
_get_xy_from_position (cell, edit->selection_end, &x, &y);
- y -= e_font_ascent (font) + e_font_descent (font);
+ y -= e_font_height (font);
return _get_position_from_xy (cell, x, y);
case E_TEP_FORWARD_PARAGRAPH:
@@ -1728,8 +1752,8 @@ _delete_selection (ECellTextView *text_view)
edit->selection_end ^= edit->selection_start;
}
- sp = cell->text + unicode_offset_to_index (cell->text, edit->selection_start);
- ep = cell->text + unicode_offset_to_index (cell->text, edit->selection_end);
+ sp = cell->text + edit->selection_start;
+ ep = cell->text + edit->selection_end;
length = strlen (ep) + 1;
memmove (sp, ep, length);
@@ -1738,31 +1762,22 @@ _delete_selection (ECellTextView *text_view)
}
/* fixme: */
-/* NB! We expect value to be length IN CHARS */
+/* NB! We expect value to be length IN BYTES */
static void
_insert (ECellTextView *text_view, char *string, int value)
{
CellEdit *edit = text_view->edit;
CurrentCell *cell = CURRENT_CELL(edit);
- gint bytes, preselbytes, postselbytes, insbytes;
- gchar *preselptr, *postselptr, *temp;
+ char *temp;
if (value <= 0) return;
- bytes = strlen (cell->text);
- preselptr = cell->text + unicode_offset_to_index (cell->text, edit->selection_start);
- preselbytes = preselptr - cell->text;
- postselptr = cell->text + unicode_offset_to_index (cell->text, edit->selection_end);
- postselbytes = bytes - (postselptr - cell->text);
-
- insbytes = string + unicode_offset_to_index (string, value) - string;
+ temp = g_new (gchar, strlen (cell->text) + value + 1);
- temp = g_new (gchar, bytes + insbytes + 1);
-
- strncpy (temp, cell->text, preselbytes);
- strncpy (temp + preselbytes, string, insbytes);
- strcpy (temp + preselbytes + insbytes, preselptr);
+ strncpy (temp, cell->text, edit->selection_start);
+ strncpy (temp + edit->selection_start, string, value);
+ strcpy (temp + edit->selection_start + value, cell->text + edit->selection_end);
g_free (cell->text);
@@ -1802,7 +1817,7 @@ e_cell_text_view_command (ETextEventProcessor *tep, ETextEventProcessorCommand *
sel_end = MAX(edit->selection_start, edit->selection_end);
if (sel_start != sel_end) {
e_cell_text_view_supply_selection (edit, command->time, GDK_SELECTION_PRIMARY,
- cell->text + unicode_offset_to_index (cell->text, sel_start),
+ cell->text + sel_start,
sel_end - sel_start);
} else if (edit->timer) {
g_timer_reset (edit->timer);
@@ -1837,7 +1852,7 @@ e_cell_text_view_command (ETextEventProcessor *tep, ETextEventProcessorCommand *
sel_end = MAX(edit->selection_start, edit->selection_end);
if (sel_start != sel_end) {
e_cell_text_view_supply_selection (edit, command->time, clipboard_atom,
- cell->text + unicode_offset_to_index (cell->text, sel_start),
+ cell->text + sel_start,
sel_end - sel_start);
}
if (edit->timer) {
@@ -1888,14 +1903,14 @@ e_cell_text_view_command (ETextEventProcessor *tep, ETextEventProcessorCommand *
linebreaks = cell->breaks;
for (lines = linebreaks->lines, i = 0; i < linebreaks->num_lines ; i++, lines ++) {
- if (unicode_index_to_offset (cell->text, lines->text - cell->text) > edit->selection_end) {
+ if ((lines->text - cell->text) > edit->selection_end) {
break;
}
}
lines --;
x = e_font_utf8_text_width (font, E_FONT_PLAIN,
lines->text,
- edit->selection_end - unicode_index_to_offset (cell->text, lines->text - cell->text));
+ edit->selection_end - (lines->text - cell->text));
if (x < edit->xofs_edit) {
@@ -2025,23 +2040,20 @@ static void e_cell_text_view_supply_selection (CellEdit *edit, guint time, GdkAt
{
gboolean successful;
GtkWidget *invisible;
- gint bytes;
invisible = e_cell_text_view_get_invisible (edit);
- bytes = unicode_offset_to_index (data, length);
-
if (selection == GDK_SELECTION_PRIMARY){
if (edit->primary_selection) {
g_free (edit->primary_selection);
}
- edit->primary_selection = g_strndup (data, bytes);
+ edit->primary_selection = g_strndup (data, length);
edit->primary_length = length;
} else if (selection == clipboard_atom) {
if (edit->clipboard_selection) {
g_free (edit->clipboard_selection);
}
- edit->clipboard_selection = g_strndup (data, bytes);
+ edit->clipboard_selection = g_strndup (data, length);
edit->clipboard_length = length;
}
@@ -2083,14 +2095,11 @@ number_of_lines (char *text)
{
int num_lines = 0;
gchar *p;
- int unival;
if (!text) return 0;
for (p = text; *p; p = unicode_next_utf8 (p)) {
- unicode_get_utf8 (p, &unival);
- if (unival == '\n')
- num_lines++;
+ if (*p == '\n') num_lines++;
}
num_lines++;
@@ -2103,8 +2112,7 @@ split_into_lines (CurrentCell *cell)
{
char *p;
struct line *lines;
- int len;
- int unival;
+ gint len;
char *text = cell->text;
ECellTextLineBreaks *linebreaks = cell->breaks;
@@ -2137,9 +2145,8 @@ split_into_lines (CurrentCell *cell)
len = 0;
for (p = text; *p; p = unicode_next_utf8 (p)) {
if (len == 0) lines->text = p;
- unicode_get_utf8 (p, &unival);
- if (unival == '\n') {
- lines->length = len;
+ if (*p == '\n') {
+ lines->length = p - lines->text;
lines++;
len = 0;
} else
@@ -2148,8 +2155,8 @@ split_into_lines (CurrentCell *cell)
if (len == 0)
lines->text = p;
- lines->length = len;
-
+ lines->length = p - lines->text;
+
calc_line_widths (cell);
}
@@ -2178,7 +2185,7 @@ calc_ellipsis (ECellTextView *text_view)
text_view->ellipsis_width =
e_font_utf8_text_width (font, E_FONT_PLAIN,
ect->ellipsis ? ect->ellipsis : "...",
- ect->ellipsis ? unicode_strlen (ect->ellipsis, -1) : 3);
+ ect->ellipsis ? strlen (ect->ellipsis) : 3);
}
/* Calculates the line widths (in pixels) of the text's splitted lines */