diff options
-rw-r--r-- | a11y/e-table/gal-a11y-e-cell-text.c | 217 | ||||
-rw-r--r-- | widgets/table/e-cell-text.c | 180 | ||||
-rw-r--r-- | widgets/table/e-cell-text.h | 15 |
3 files changed, 332 insertions, 80 deletions
diff --git a/a11y/e-table/gal-a11y-e-cell-text.c b/a11y/e-table/gal-a11y-e-cell-text.c index 79c14aa428..e23d1f2feb 100644 --- a/a11y/e-table/gal-a11y-e-cell-text.c +++ b/a11y/e-table/gal-a11y-e-cell-text.c @@ -19,10 +19,6 @@ static AtkObjectClass *parent_class; #define PARENT_TYPE (gal_a11y_e_cell_get_type ()) -/* XXX: these functions are undefined */ -#define e_cell_text_get_selection(a,b,c,d,e) NULL -#define e_cell_text_set_selection(a,b,c,d,e) FALSE - /* Static functions */ static G_CONST_RETURN gchar* ect_get_name (AtkObject * a11y) @@ -39,9 +35,8 @@ ect_get_text (AtkText *text, { GalA11yECell *gaec = GAL_A11Y_E_CELL (text); ECellText *ect = E_CELL_TEXT (gaec->cell_view->ecell); - char *ret_val; - char *full_text = - e_cell_text_get_text (ect, gaec->item->table_model, gaec->model_col, gaec->row); + gchar *ret_val; + gchar *full_text = e_cell_text_get_text (ect, gaec->item->table_model, gaec->model_col, gaec->row); if (end_offset == -1) end_offset = strlen (full_text); @@ -86,10 +81,8 @@ ect_get_character_at_offset (AtkText *text, GalA11yECell *gaec = GAL_A11Y_E_CELL (text); ECellText *ect = E_CELL_TEXT (gaec->cell_view->ecell); gunichar ret_val; - char *full_text; - char *at_offset; - - full_text = e_cell_text_get_text (ect, gaec->item->table_model, gaec->model_col, gaec->row); + gchar *at_offset; + gchar *full_text = e_cell_text_get_text (ect, gaec->item->table_model, gaec->model_col, gaec->row); at_offset = g_utf8_offset_to_pointer (full_text, offset); ret_val = g_utf8_get_char_validated (at_offset, -1); e_cell_text_free_text (ect, full_text); @@ -114,26 +107,22 @@ static gint ect_get_caret_offset (AtkText *text) { GalA11yECell *gaec = GAL_A11Y_E_CELL (text); - int start, end; + ECellText *ect = E_CELL_TEXT (gaec->cell_view->ecell); + gint start, end; + if (e_cell_text_get_selection (gaec->cell_view, gaec->view_col, gaec->row, - &start, &end) - && start == end) { - char *full_text; - int ret_val; - ECellText *ect = E_CELL_TEXT (gaec->cell_view->ecell); - - full_text = e_cell_text_get_text (ect, gaec->item->table_model, gaec->model_col, gaec->row); - ret_val = g_utf8_pointer_to_offset (full_text, full_text + start); + &start, &end)) { + gchar *full_text = e_cell_text_get_text (ect, gaec->item->table_model, gaec->model_col, gaec->row); + end = g_utf8_pointer_to_offset (full_text, full_text + end); e_cell_text_free_text (ect, full_text); - - return ret_val; - } else { - return -1; + + return end; } + else + return -1; } - static AtkAttributeSet* ect_get_run_attributes (AtkText *text, gint offset, @@ -171,9 +160,9 @@ ect_get_character_count (AtkText *text) { GalA11yECell *gaec = GAL_A11Y_E_CELL (text); ECellText *ect = E_CELL_TEXT (gaec->cell_view->ecell); - int ret_val; + gint ret_val; - char *full_text = e_cell_text_get_text (ect, gaec->item->table_model, gaec->model_col, gaec->row); + gchar *full_text = e_cell_text_get_text (ect, gaec->item->table_model, gaec->model_col, gaec->row); ret_val = g_utf8_strlen (full_text, -1); e_cell_text_free_text (ect, full_text); @@ -196,12 +185,12 @@ static gint ect_get_n_selections (AtkText *text) { GalA11yECell *gaec = GAL_A11Y_E_CELL (text); - int selection_start, selection_end; + gint selection_start, selection_end; if (e_cell_text_get_selection (gaec->cell_view, gaec->view_col, gaec->row, &selection_start, - &selection_end) && - selection_start != selection_end) + &selection_end) + && selection_start != selection_end) return 1; return 0; } @@ -215,29 +204,42 @@ ect_get_selection (AtkText *text, { GalA11yECell *gaec = GAL_A11Y_E_CELL (text); ECellText *ect = E_CELL_TEXT (gaec->cell_view->ecell); - int selection_start, selection_end; - if (selection_num == 0 && - e_cell_text_get_selection (gaec->cell_view, - gaec->view_col, gaec->row, - &selection_start, - &selection_end) && - selection_start != selection_end) { - char *ret_val; - char *full_text = - e_cell_text_get_text (ect, gaec->item->table_model, gaec->model_col, gaec->row); + gchar *ret_val; + gint selection_start, selection_end; - ret_val = g_strndup (full_text + selection_start, selection_end - selection_start); + if (selection_num == 0 + && e_cell_text_get_selection (gaec->cell_view, + gaec->view_col, gaec->row, + &selection_start, + &selection_end) + && selection_start != selection_end) { + gint real_start, real_end, len; + gchar *full_text = e_cell_text_get_text (ect, gaec->item->table_model, gaec->model_col, gaec->row); + len = strlen (full_text); + real_start = MIN (selection_start, selection_end); + real_end = MAX (selection_start, selection_end); + real_start = MIN (MAX (0, real_start), len); + real_end = MIN (MAX (0, real_end), len); + + ret_val = g_strndup (full_text + real_start, real_end - real_start); + + real_start = g_utf8_pointer_to_offset (full_text, full_text + real_start); + real_end = g_utf8_pointer_to_offset (full_text, full_text + real_end); if (start_offset) - *start_offset = g_utf8_pointer_to_offset (full_text, full_text + selection_start); + *start_offset = real_start; if (end_offset) - *end_offset = g_utf8_pointer_to_offset (full_text, full_text + selection_end); - + *end_offset = real_end; e_cell_text_free_text (ect, full_text); - - return ret_val; + } else { + if (start_offset) + *start_offset = 0; + if (end_offset) + *end_offset = 0; + ret_val = NULL; } - return NULL; + + return ret_val; } @@ -248,24 +250,34 @@ ect_add_selection (AtkText *text, { GalA11yECell *gaec = GAL_A11Y_E_CELL (text); ECellText *ect = E_CELL_TEXT (gaec->cell_view->ecell); - int selection_start, selection_end; - if (e_cell_text_get_selection (gaec->cell_view, - gaec->view_col, gaec->row, - &selection_start, - &selection_end) && - selection_start == selection_end && - start_offset != end_offset) { - char *full_text; - full_text = e_cell_text_get_text (ect, gaec->item->table_model, gaec->model_col, gaec->row); - start_offset = g_utf8_offset_to_pointer (full_text, start_offset) - full_text; - end_offset = g_utf8_offset_to_pointer (full_text, end_offset) - full_text; + if (start_offset != end_offset) { + gint real_start, real_end, len; + gchar *full_text = + e_cell_text_get_text (ect, gaec->item->table_model, gaec->model_col, gaec->row); + + len = g_utf8_strlen (full_text, -1); + if (end_offset == -1) + end_offset = len; + + real_start = MIN (start_offset, end_offset); + real_end = MAX (start_offset, end_offset); + + real_start = MIN (MAX (0, real_start), len); + real_end = MIN (MAX (0, real_end), len); + + real_start = g_utf8_offset_to_pointer (full_text, real_start) - full_text; + real_end = g_utf8_offset_to_pointer (full_text, real_end) - full_text; e_cell_text_free_text (ect, full_text); - return e_cell_text_set_selection (gaec->cell_view, - gaec->view_col, gaec->row, - start_offset, end_offset); + if (e_cell_text_set_selection (gaec->cell_view, + gaec->view_col, gaec->row, + real_start, real_end)) { + g_signal_emit_by_name (ATK_OBJECT(text), "text_selection_changed"); + return TRUE; + } } + return FALSE; } @@ -274,8 +286,24 @@ static gboolean ect_remove_selection (AtkText *text, gint selection_num) { - /* Unimplemented */ - return FALSE; + GalA11yECell *gaec = GAL_A11Y_E_CELL (text); + ECellText *ect = E_CELL_TEXT (gaec->cell_view->ecell); + gint selection_start, selection_end; + + if (selection_num == 0 + && e_cell_text_get_selection (gaec->cell_view, + gaec->view_col, gaec->row, + &selection_start, + &selection_end) + && selection_start != selection_end + && e_cell_text_set_selection (gaec->cell_view, + gaec->view_col, gaec->row, + selection_end, selection_end)) { + g_signal_emit_by_name (ATK_OBJECT(text), "text_selection_changed"); + return TRUE; + } + else + return FALSE; } @@ -285,8 +313,12 @@ ect_set_selection (AtkText *text, gint start_offset, gint end_offset) { - /* Unimplemented */ - return FALSE; + if (selection_num == 0) { + atk_text_add_selection (text, start_offset, end_offset); + return TRUE; + } + else + return FALSE; } @@ -296,10 +328,19 @@ ect_set_caret_offset (AtkText *text, { GalA11yECell *gaec = GAL_A11Y_E_CELL (text); ECellText *ect = E_CELL_TEXT (gaec->cell_view->ecell); - char *full_text; + gchar *full_text; + gint len; full_text = e_cell_text_get_text (ect, gaec->item->table_model, gaec->model_col, gaec->row); + + len = g_utf8_strlen (full_text, -1); + if (offset == -1) + offset = len; + else + offset = MIN (MAX (0, offset), len); + offset = g_utf8_offset_to_pointer (full_text, offset) - full_text; + e_cell_text_free_text (ect, full_text); return e_cell_text_set_selection (gaec->cell_view, @@ -325,6 +366,7 @@ ect_set_text_contents (AtkEditableText *text, ECellText *ect = E_CELL_TEXT (gaec->cell_view->ecell); e_cell_text_set_value (ect, gaec->item->table_model, gaec->model_col, gaec->row, string); + e_table_item_enter_edit (gaec->item, gaec->view_col, gaec->row); } static void @@ -337,8 +379,8 @@ ect_insert_text (AtkEditableText *text, GalA11yECell *gaec = GAL_A11Y_E_CELL (text); ECellText *ect = E_CELL_TEXT (gaec->cell_view->ecell); - char *full_text = e_cell_text_get_text (ect, gaec->item->table_model, gaec->model_col, gaec->row); - char *result = g_strdup_printf ("%.*s%.*s%s", *position, full_text, length, string, full_text + *position); + gchar *full_text = e_cell_text_get_text (ect, gaec->item->table_model, gaec->model_col, gaec->row); + gchar *result = g_strdup_printf ("%.*s%.*s%s", *position, full_text, length, string, full_text + *position); e_cell_text_set_value (ect, gaec->item->table_model, gaec->model_col, gaec->row, result); @@ -353,32 +395,46 @@ ect_copy_text (AtkEditableText *text, gint start_pos, gint end_pos) { - /* Unimplemented */ + GalA11yECell *gaec = GAL_A11Y_E_CELL (text); + if (start_pos != end_pos + && atk_text_set_selection (text, 0, start_pos, end_pos)) + e_cell_text_copy_clipboard (gaec->cell_view, + gaec->view_col, gaec->row); } static void -ect_cut_text (AtkEditableText *text, - gint start_pos, - gint end_pos) +ect_delete_text (AtkEditableText *text, + gint start_pos, + gint end_pos) { - /* Unimplemented */ + GalA11yECell *gaec = GAL_A11Y_E_CELL (text); + if (start_pos != end_pos + && atk_text_set_selection (text, 0, start_pos, end_pos)) + e_cell_text_delete_selection (gaec->cell_view, + gaec->view_col, gaec->row); } static void -ect_delete_text (AtkEditableText *text, - gint start_pos, - gint end_pos) +ect_cut_text (AtkEditableText *text, + gint start_pos, + gint end_pos) { - /* Unimplemented */ + ect_copy_text (text, start_pos, end_pos); + ect_delete_text (text, start_pos, end_pos); } static void ect_paste_text (AtkEditableText *text, gint position) { - /* Unimplemented */ -} + GalA11yECell *gaec = GAL_A11Y_E_CELL (text); + + e_table_item_enter_edit (gaec->item, gaec->view_col, gaec->row); + if (atk_text_set_caret_offset (text, position)) + e_cell_text_paste_clipboard (gaec->cell_view, + gaec->view_col, gaec->row); +} static void ect_do_action_edit (AtkAction *action) @@ -424,7 +480,7 @@ ect_atk_editable_text_iface_init (AtkEditableTextIface *iface) static void ect_class_init (GalA11yECellTextClass *klass) { - AtkObjectClass *a11y = ATK_OBJECT_CLASS (klass); + AtkObjectClass *a11y = ATK_OBJECT_CLASS (klass); parent_class = g_type_class_ref (PARENT_TYPE); a11y->get_name = ect_get_name; } @@ -487,6 +543,7 @@ gal_a11y_e_cell_text_get_type (void) return type; } + AtkObject * gal_a11y_e_cell_text_new (ETableItem *item, ECellView *cell_view, diff --git a/widgets/table/e-cell-text.c b/widgets/table/e-cell-text.c index 5a0da69a7c..11c5429754 100644 --- a/widgets/table/e-cell-text.c +++ b/widgets/table/e-cell-text.c @@ -2574,3 +2574,183 @@ e_cell_text_get_color (ECellTextView *cell_view, gchar *color_spec) return color; } +/** + * e_cell_text_set_selection: + * @cell_view: the given cell view + * @col: column of the given cell in the view + * @row: row of the given cell in the view + * @start: start offset of the selection + * @end: end offset of the selection + * + * Sets the selection of given text cell. + * If the current editing cell is not the given cell, this function + * will return FALSE; + * + * If success, the [start, end) part of the text will be selected. + * + * This API is most likely to be used by a11y implementations. + * + * Returns: whether the action is successful. + */ +gboolean +e_cell_text_set_selection (ECellView *cell_view, + gint col, + gint row, + gint start, + gint end) +{ + ECellTextView *ectv; + CellEdit *edit; + ETextEventProcessorCommand command1, command2; + + ectv = (ECellTextView *)cell_view; + edit = ectv->edit; + if (!edit) + return FALSE; + + if (edit->view_col != col || edit->row != row) + return FALSE; + + command1.action = E_TEP_MOVE; + command1.position = E_TEP_VALUE; + command1.value = start; + e_cell_text_view_command (edit->tep, &command1, edit); + + command2.action = E_TEP_SELECT; + command2.position = E_TEP_VALUE; + command2.value = end; + e_cell_text_view_command (edit->tep, &command2, edit); + + return TRUE; +} + +/** + * e_cell_text_get_selection: + * @cell_view: the given cell view + * @col: column of the given cell in the view + * @row: row of the given cell in the view + * @start: a pointer to an int value indicates the start offset of the selection + * @end: a pointer to an int value indicates the end offset of the selection + * + * Gets the selection of given text cell. + * If the current editing cell is not the given cell, this function + * will return FALSE; + * + * This API is most likely to be used by a11y implementations. + * + * Returns: whether the action is successful. + */ +gboolean +e_cell_text_get_selection (ECellView *cell_view, + gint col, + gint row, + gint *start, + gint *end) +{ + ECellTextView *ectv; + CellEdit *edit; + + ectv = (ECellTextView *)cell_view; + edit = ectv->edit; + if (!edit) + return FALSE; + + if (edit->view_col != col || edit->row != row) + return FALSE; + + if (start) + *start = edit->selection_start; + if (end) + *end = edit->selection_end; + return TRUE; +} + +/** + * e_cell_text_copy_clipboard: + * @cell_view: the given cell view + * @col: column of the given cell in the view + * @row: row of the given cell in the view + * + * Copys the selected text to clipboard. + * + * This API is most likely to be used by a11y implementations. + */ +void +e_cell_text_copy_clipboard (ECellView *cell_view, gint col, gint row) +{ + ECellTextView *ectv; + CellEdit *edit; + ETextEventProcessorCommand command; + + ectv = (ECellTextView *)cell_view; + edit = ectv->edit; + if (!edit) + return; + + if (edit->view_col != col || edit->row != row) + return; + + command.action = E_TEP_COPY; + command.time = GDK_CURRENT_TIME; + e_cell_text_view_command (edit->tep, &command, edit); +} + +/** + * e_cell_text_paste_clipboard: + * @cell_view: the given cell view + * @col: column of the given cell in the view + * @row: row of the given cell in the view + * + * Pastes the text from the clipboardt. + * + * This API is most likely to be used by a11y implementations. + */ +void +e_cell_text_paste_clipboard (ECellView *cell_view, gint col, gint row) +{ + ECellTextView *ectv; + CellEdit *edit; + ETextEventProcessorCommand command; + + ectv = (ECellTextView *)cell_view; + edit = ectv->edit; + if (!edit) + return; + + if (edit->view_col != col || edit->row != row) + return; + + command.action = E_TEP_PASTE; + command.time = GDK_CURRENT_TIME; + e_cell_text_view_command (edit->tep, &command, edit); +} + +/** + * e_cell_text_delete_selection: + * @cell_view: the given cell view + * @col: column of the given cell in the view + * @row: row of the given cell in the view + * + * Deletes the selected text of the cell. + * + * This API is most likely to be used by a11y implementations. + */ +void +e_cell_text_delete_selection (ECellView *cell_view, gint col, gint row) +{ + ECellTextView *ectv; + CellEdit *edit; + ETextEventProcessorCommand command; + + ectv = (ECellTextView *)cell_view; + edit = ectv->edit; + if (!edit) + return; + + if (edit->view_col != col || edit->row != row) + return; + + command.action = E_TEP_DELETE; + command.position = E_TEP_SELECTION; + e_cell_text_view_command (edit->tep, &command, edit); +} diff --git a/widgets/table/e-cell-text.h b/widgets/table/e-cell-text.h index 6c51f32fd8..5310ffc5f9 100644 --- a/widgets/table/e-cell-text.h +++ b/widgets/table/e-cell-text.h @@ -101,6 +101,21 @@ void e_cell_text_free_text (ECellText *cell, char *text); /* Sets the ETableModel value, based on the given string. */ void e_cell_text_set_value (ECellText *cell, ETableModel *model, int col, int row, const char *text); +/* Sets the selection of given text cell */ +gboolean e_cell_text_set_selection (ECellView *cell_view, gint col, gint row, gint start, gint end); + +/* Gets the selection of given text cell */ +gboolean e_cell_text_get_selection (ECellView *cell_view, gint col, gint row, gint *start, gint *end); + +/* Copys the selected text to the clipboard */ +void e_cell_text_copy_clipboard (ECellView *cell_view, gint col, gint row); + +/* Pastes the text from the clipboard */ +void e_cell_text_paste_clipboard (ECellView *cell_view, gint col, gint row); + +/* Deletes selected text */ +void e_cell_text_delete_selection (ECellView *cell_view, gint col, gint row); + G_END_DECLS #endif /* _E_CELL_TEXT_H_ */ |