atspi: add AtspiText and AtspiEditableText interface support.

Summary:
Added reference interface implementation for elm_entry widget. Tests added.
Updated at-spi-constants.h header to version 2.12.0.

Reviewers: raster, seoz

CC: raster

Differential Revision: https://phab.enlightenment.org/D806
This commit is contained in:
Lukasz Stanislawski 2014-06-10 16:18:17 +09:00 committed by Carsten Haitzler (Rasterman)
parent bc608f73c5
commit 139c871a72
11 changed files with 2427 additions and 165 deletions

View File

@ -190,7 +190,7 @@ typedef enum {
* enumeration.
*
* Enumeration used by #AtspiMatchRule to specify
* how to interpret #AtspiAccesible objects.
* how to interpret #AtspiAccessible objects.
*
**/
typedef enum {
@ -331,6 +331,8 @@ typedef enum {
* #atspi_text_get_text_at_offset, #atspi_text_get_text_after_offset, and
* #atspi_text_get_text_before_offset.
*
* This enumerationis deprecated since 2.9.90 and should not be used. Use
* AtspiTextGranularity with #atspi_text_get_string_at_offset instead.
**/
typedef enum {
ATSPI_TEXT_BOUNDARY_CHAR,
@ -342,6 +344,34 @@ typedef enum {
ATSPI_TEXT_BOUNDARY_LINE_END,
} AtspiTextBoundaryType;
/**
*AtspiTextGranularity:
*@ATSPI_TEXT_GRANULARITY_CHAR: Granularity is defined by the boundaries between characters
* (including non-printing characters)
*@ATSPI_TEXT_GRANULARITY_WORD: Granularity is defined by the boundaries of a word,
* starting at the beginning of the current word and finishing at the beginning of
* the following one, if present.
*@ATSPI_TEXT_GRANULARITY_SENTENCE: Granularity is defined by the boundaries of a sentence,
* starting at the beginning of the current sentence and finishing at the beginning of
* the following one, if present.
*@ATSPI_TEXT_GRANULARITY_LINE: Granularity is defined by the boundaries of a line,
* starting at the beginning of the current line and finishing at the beginning of
* the following one, if present.
*@ATSPI_TEXT_GRANULARITY_PARAGRAPH: Granularity is defined by the boundaries of a paragraph,
* starting at the beginning of the current paragraph and finishing at the beginning of
* the following one, if present.
*
* Text granularity types used for specifying the granularity of the region of
* text we are interested in.
**/
typedef enum {
ATSPI_TEXT_GRANULARITY_CHAR,
ATSPI_TEXT_GRANULARITY_WORD,
ATSPI_TEXT_GRANULARITY_SENTENCE,
ATSPI_TEXT_GRANULARITY_LINE,
ATSPI_TEXT_GRANULARITY_PARAGRAPH
} AtspiTextGranularity;
/**
* ATSPI_TEXT_BOUNDARY_TYPE_COUNT:
*
@ -523,6 +553,14 @@ typedef enum {
* @ATSPI_STATE_VISITED: This state indicates that the object (typically a
* hyperlink) has already been activated or invoked, with the result that
* some backing data has been downloaded or rendered.
*@ATSPI_STATE_CHECKABLE: Indicates this object has the potential to
* be checked, such as a checkbox or toggle-able table cell. @Since:
* 2.12
*@ATSPI_STATE_HAS_POPUP: Indicates that the object has a popup
* context menu or sub-level menu which may or may not be
* showing. This means that activation renders conditional content.
* Note that ordinary tooltips are not considered popups in this
* context. @Since: 2.12
* @ATSPI_STATE_LAST_DEFINED: This value of the enumeration should not be used
* as a parameter, it indicates the number of items in the #AtspiStateType
* enumeration.
@ -574,6 +612,8 @@ typedef enum {
ATSPI_STATE_SELECTABLE_TEXT,
ATSPI_STATE_IS_DEFAULT,
ATSPI_STATE_VISITED,
ATSPI_STATE_CHECKABLE,
ATSPI_STATE_HAS_POPUP,
ATSPI_STATE_LAST_DEFINED,
} AtspiStateType;
@ -645,13 +685,14 @@ typedef enum {
* map, the #AtspiDeviceEventController instance has a limited ability to
* generate such keysyms on-the-fly. Reliability of GenerateKeyboardEvent
* calls using out-of-keymap keysyms will vary from system to system, and on
* the number of different out-of-keymap being generated in quick succession.
* the number of different out-of-keymap keysyms being generated in quick
* succession.
* In practice this is rarely significant, since the keysyms of interest to
* AT clients and keyboard emulators are usually part of the current keymap,
* i.e. present on the system keyboard for the current locale (even if a
* physical hardware keyboard is not connected.
* i.e., present on the system keyboard for the current locale (even if a
* physical hardware keyboard is not connected).
* @ATSPI_KEY_STRING: A string is converted to its equivalent keyboard events
* and emitted. If the string consists of complex character or composed
* and emitted. If the string consists of complex characters or composed
* characters which are not in the current keymap, string emission is
* subject to the out-of-keymap limitations described for
* @ATSPI_KEY_SYM. In practice this limitation primarily effects
@ -1000,7 +1041,7 @@ typedef enum {
* contains a view of document content. #AtspiDocument frames may occur within
* another #AtspiDocument instance, in which case the second document may be
* said to be embedded in the containing instance. HTML frames are often
* @ATSPI_ROLE_DOCUMENT_FRAME: Either this object, or a singleton descendant,
* ATSPI_ROLE_DOCUMENT_FRAME: Either this object, or a singleton descendant,
* should implement the #AtspiDocument interface.
* @ATSPI_ROLE_HEADING: The object serves as a heading for content which
* follows it in a document. The 'heading level' of the heading, if
@ -1064,6 +1105,46 @@ typedef enum {
* particular application.
* @ATSPI_ROLE_INFO_BAR: An object designed to present a message to the user
* within an existing window.
*@ATSPI_ROLE_LEVEL_BAR: A bar that serves as a level indicator to, for
* instance, show the strength of a password or the state of a battery.
* Since: 2.8
*@ATSPI_ROLE_TITLE_BAR: A bar that serves as the title of a window or a
* dialog. @Since: 2.12
*@ATSPI_ROLE_BLOCK_QUOTE: An object which contains a text section
* that is quoted from another source. @Since: 2.12
*@ATSPI_ROLE_AUDIO: An object which represents an audio
* element. @Since: 2.12
*@ATSPI_ROLE_VIDEO: An object which represents a video
* element. @Since: 2.12
*@ATSPI_ROLE_DEFINITION: A definition of a term or concept. @Since: 2.12
*@ATSPI_ROLE_ARTICLE: A section of a page that consists of a
* composition that forms an independent part of a document, page, or
* site. Examples: A blog entry, a news story, a forum post. @Since:
* 2.12
*@ATSPI_ROLE_LANDMARK: A region of a web page intended as a
* navigational landmark. This is designed to allow Assistive
* Technologies to provide quick navigation among key regions within a
* document. @Since: 2.12
*@ATSPI_ROLE_LOG: A text widget or container holding log content, such
* as chat history and error logs. In this role there is a
* relationship between the arrival of new items in the log and the
* reading order. The log contains a meaningful sequence and new
* information is added only to the end of the log, not at arbitrary
* points. @Since: 2.12
*@ATSPI_ROLE_MARQUEE: A container where non-essential information
* changes frequently. Common usages of marquee include stock tickers
* and ad banners. The primary difference between a marquee and a log
* is that logs usually have a meaningful order or sequence of
* important content changes. @Since: 2.12
*@ATSPI_ROLE_MATH: A text widget or container that holds a mathematical
* expression. @Since: 2.12
*@ATSPI_ROLE_RATING: A widget whose purpose is to display a rating,
* such as the number of stars associated with a song in a media
* player. Objects of this role should also implement
* AtspiValue. @Since: 2.12
*@ATSPI_ROLE_TIMER: An object containing a numerical counter which
* indicates an amount of elapsed time from a start point, or the time
* remaining until an end point. @Since: 2.12
* @ATSPI_ROLE_LAST_DEFINED: Not a valid role, used for finding end of
* enumeration.
*
@ -1175,6 +1256,19 @@ typedef enum {
ATSPI_ROLE_IMAGE_MAP,
ATSPI_ROLE_NOTIFICATION,
ATSPI_ROLE_INFO_BAR,
ATSPI_ROLE_LEVEL_BAR,
ATSPI_ROLE_TITLE_BAR,
ATSPI_ROLE_BLOCK_QUOTE,
ATSPI_ROLE_AUDIO,
ATSPI_ROLE_VIDEO,
ATSPI_ROLE_DEFINITION,
ATSPI_ROLE_ARTICLE,
ATSPI_ROLE_LANDMARK,
ATSPI_ROLE_LOG,
ATSPI_ROLE_MARQUEE,
ATSPI_ROLE_MATH,
ATSPI_ROLE_RATING,
ATSPI_ROLE_TIMER,
ATSPI_ROLE_LAST_DEFINED,
} AtspiRole;
@ -1197,10 +1291,7 @@ typedef enum
ATSPI_CACHE_INTERFACES = 1 << 6,
ATSPI_CACHE_ATTRIBUTES = 1 << 7,
ATSPI_CACHE_ALL = 0x3fffffff,
ATSPI_CACHE_DEFAULT = ATSPI_CACHE_PARENT | ATSPI_CACHE_CHILDREN |
ATSPI_CACHE_NAME | ATSPI_CACHE_DESCRIPTION |
ATSPI_CACHE_STATES | ATSPI_CACHE_ROLE |
ATSPI_CACHE_INTERFACES,
ATSPI_CACHE_DEFAULT = ATSPI_CACHE_PARENT | ATSPI_CACHE_CHILDREN | ATSPI_CACHE_NAME | ATSPI_CACHE_DESCRIPTION | ATSPI_CACHE_STATES | ATSPI_CACHE_ROLE | ATSPI_CACHE_INTERFACES,
ATSPI_CACHE_UNDEFINED = 0x40000000,
} AtspiCache;
@ -1231,6 +1322,7 @@ typedef enum
#define ATSPI_DBUS_INTERFACE_IMAGE "org.a11y.atspi.Image"
#define ATSPI_DBUS_INTERFACE_SELECTION "org.a11y.atspi.Selection"
#define ATSPI_DBUS_INTERFACE_TABLE "org.a11y.atspi.Table"
#define ATSPI_DBUS_INTERFACE_TABLE_CELL "org.a11y.atspi.TableCell"
#define ATSPI_DBUS_INTERFACE_TEXT "org.a11y.atspi.Text"
#define ATSPI_DBUS_INTERFACE_VALUE "org.a11y.atspi.Value"
#define ATSPI_DBUS_INTERFACE_SOCKET "org.a11y.atspi.Socket"

View File

@ -49,6 +49,7 @@ includesdir = $(includedir)/elementary-@VMAJ@
includesunstable_HEADERS = \
elm_gen_common.h \
elm_interface_atspi_accessible.h \
elm_interface_atspi_text.h \
elm_interface_fileselector.h \
elm_interface_scrollable.h \
elm_widget.h \
@ -452,9 +453,11 @@ elm_index.c \
elm_interface_atspi_accessible.c \
elm_interface_atspi_action.c \
elm_interface_atspi_component.c \
elm_interface_atspi_editable_text.c \
elm_interface_atspi_image.c \
elm_interface_atspi_value.c \
elm_interface_atspi_selection.c \
elm_interface_atspi_text.c \
elm_interface_atspi_value.c \
elm_interface_atspi_widget.c \
elm_interface_atspi_widget_action.c \
elm_interface_atspi_window.c \
@ -660,16 +663,20 @@ BUILT_SOURCES = \
elm_interface_atspi_action.eo.h \
elm_interface_atspi_component.eo.c \
elm_interface_atspi_component.eo.h \
elm_interface_atspi_editable_text.eo.c \
elm_interface_atspi_editable_text.eo.h \
elm_interface_atspi_image.eo.c \
elm_interface_atspi_image.eo.h \
elm_interface_atspi_selection.eo.c \
elm_interface_atspi_selection.eo.h \
elm_interface_atspi_text.eo.c \
elm_interface_atspi_text.eo.h \
elm_interface_atspi_value.eo.c \
elm_interface_atspi_value.eo.h \
elm_interface_atspi_widget.eo.c \
elm_interface_atspi_widget.eo.h \
elm_interface_atspi_widget_action.eo.c \
elm_interface_atspi_widget_action.eo.h \
elm_interface_atspi_selection.eo.c \
elm_interface_atspi_selection.eo.h \
elm_interface_atspi_window.eo.c \
elm_interface_atspi_window.eo.h \
elm_interface_fileselector.eo.c \
@ -795,9 +802,11 @@ elementaryeolianfiles_DATA = \
elm_interface_atspi_accessible.eo \
elm_interface_atspi_action.eo \
elm_interface_atspi_component.eo \
elm_interface_atspi_editable_text.eo \
elm_interface_atspi_image.eo \
elm_interface_atspi_value.eo \
elm_interface_atspi_selection.eo \
elm_interface_atspi_text.eo \
elm_interface_atspi_value.eo \
elm_interface_atspi_widget.eo \
elm_interface_atspi_widget_action.eo \
elm_interface_atspi_window.eo \
@ -889,9 +898,11 @@ nodist_includesunstable_HEADERS = \
elm_interface_atspi_accessible.eo.h \
elm_interface_atspi_action.eo.h \
elm_interface_atspi_component.eo.h \
elm_interface_atspi_editable_text.eo.h \
elm_interface_atspi_image.eo.h \
elm_interface_atspi_value.eo.h \
elm_interface_atspi_selection.eo.h \
elm_interface_atspi_text.eo.h \
elm_interface_atspi_value.eo.h \
elm_interface_atspi_widget.eo.h \
elm_interface_atspi_widget_action.eo.h \
elm_interface_atspi_window.eo.h \

File diff suppressed because it is too large Load Diff

View File

@ -9,6 +9,16 @@
#define MY_CLASS ELM_ENTRY_CLASS
#define ELM_INTERFACE_ATSPI_ACCESSIBLE_PROTECTED
#define ELM_INTERFACE_ATSPI_TEXT_PROTECTED
#define ELM_INTERFACE_ATSPI_EDITABLE_TEXT_PROTECTED
#include "elm_interface_atspi_accessible.h"
#include "elm_interface_atspi_accessible.eo.h"
#include "elm_interface_atspi_text.h"
#include "elm_interface_atspi_text.eo.h"
#include "elm_interface_atspi_editable_text.eo.h"
#define MY_CLASS_NAME "Elm_Entry"
#define MY_CLASS_NAME_LEGACY "elm_entry"
@ -1888,6 +1898,24 @@ _entry_changed_user_signal_cb(void *data,
{
evas_object_smart_callback_call(data, SIG_CHANGED_USER, NULL);
}
if (_elm_config->atspi_mode)
{
Elm_Atspi_Text_Change_Info atspi_info;
if (edje_info && edje_info->insert)
{
atspi_info.content = edje_info->change.insert.content;
atspi_info.pos = edje_info->change.insert.pos;
atspi_info.len = edje_info->change.insert.plain_length;
eo_do(data, eo_event_callback_call(ELM_INTERFACE_ATSPI_TEXT_EVENT_ACCESS_TEXT_INSERTED, &atspi_info));
}
else if (edje_info && !edje_info->insert)
{
atspi_info.content = edje_info->change.del.content;
atspi_info.pos = MIN(edje_info->change.del.start, edje_info->change.del.end);
atspi_info.len = abs(edje_info->change.del.end - edje_info->change.del.start);
eo_do(data, eo_event_callback_call(ELM_INTERFACE_ATSPI_TEXT_EVENT_ACCESS_TEXT_REMOVED, &atspi_info));
}
}
}
static void
@ -1970,6 +1998,8 @@ _entry_selection_changed_signal_cb(void *data,
evas_object_smart_callback_call(data, SIG_SELECTION_CHANGED, NULL);
_selection_store(ELM_SEL_TYPE_PRIMARY, data);
_update_selection_handler(data);
if (_elm_config->atspi_mode)
eo_do(data, eo_event_callback_call(ELM_INTERFACE_ATSPI_TEXT_EVENT_ACCESS_TEXT_SELECTION_CHANGED, NULL));
}
static void
@ -2073,6 +2103,8 @@ _entry_cursor_changed_signal_cb(void *data,
if (elm_widget_focus_get(data))
edje_object_signal_emit(sd->entry_edje, "elm,action,show,cursor", "elm");
_cursor_geometry_recalc(data);
if (_elm_config->atspi_mode)
eo_do(data, eo_event_callback_call(ELM_INTERFACE_ATSPI_TEXT_EVENT_ACCESS_TEXT_CARET_MOVED, NULL));
}
static void
@ -2082,6 +2114,8 @@ _entry_cursor_changed_manual_signal_cb(void *data,
const char *source EINA_UNUSED)
{
evas_object_smart_callback_call(data, SIG_CURSOR_CHANGED_MANUAL, NULL);
if (_elm_config->atspi_mode)
eo_do(data, eo_event_callback_call(ELM_INTERFACE_ATSPI_TEXT_EVENT_ACCESS_TEXT_CARET_MOVED, NULL));
}
static void
@ -3625,7 +3659,8 @@ _elm_entry_eo_base_constructor(Eo *obj, Elm_Entry_Data *_pd EINA_UNUSED)
eo_do_super(obj, MY_CLASS, eo_constructor());
eo_do(obj,
evas_obj_type_set(MY_CLASS_NAME_LEGACY),
evas_obj_smart_callbacks_descriptions_set(_smart_callbacks));
evas_obj_smart_callbacks_descriptions_set(_smart_callbacks),
elm_interface_atspi_accessible_role_set(ELM_ATSPI_ROLE_TEXT));
}
EOLIAN static void
@ -4951,5 +4986,545 @@ _elm_entry_class_constructor(Eo_Class *klass)
evas_smart_legacy_type_register(MY_CLASS_NAME_LEGACY, klass);
}
// ATSPI Accessibility
EOLIAN static Eina_Unicode
_elm_entry_elm_interface_atspi_text_character_get(Eo *obj, Elm_Entry_Data *_pd EINA_UNUSED, int offset)
{
char *txt;
int index = 0;
Eina_Unicode ret = 0;
if (offset < 0) return ret;
txt = _elm_util_mkup_to_text(elm_entry_entry_get(obj));
if (!txt) return ret;
ret = eina_unicode_utf8_next_get(txt, &index);
while (offset--) ret = eina_unicode_utf8_next_get(txt, &index);
free(txt);
return ret;
}
EOLIAN static int
_elm_entry_elm_interface_atspi_text_character_count_get(Eo *obj, Elm_Entry_Data *_pd EINA_UNUSED)
{
char *txt;
int ret = -1;
txt = _elm_util_mkup_to_text(elm_entry_entry_get(obj));
if (!txt) return ret;
ret = eina_unicode_utf8_get_len(txt);
free(txt);
return ret;
}
EOLIAN static char*
_elm_entry_elm_interface_atspi_text_string_get(Eo *obj, Elm_Entry_Data *_pd EINA_UNUSED, Elm_Atspi_Text_Granularity granularity, int *start_offset, int *end_offset)
{
Evas_Textblock_Cursor *cur = NULL, *cur2 = NULL;
Evas_Object *tblk;
char *ret = NULL;
tblk = elm_entry_textblock_get(obj);
if (!tblk) goto fail;
cur = evas_object_textblock_cursor_new(tblk);
cur2 = evas_object_textblock_cursor_new(tblk);
if (!cur2 || !cur2) goto fail;
evas_textblock_cursor_pos_set(cur, *start_offset);
if (evas_textblock_cursor_pos_get(cur) != *start_offset) goto fail;
switch (granularity)
{
case ELM_ATSPI_TEXT_GRANULARITY_CHAR:
break;
case ELM_ATSPI_TEXT_GRANULARITY_WORD:
evas_textblock_cursor_word_start(cur);
break;
case ELM_ATSPI_TEXT_GRANULARITY_SENTENCE:
// TODO - add sentence support in textblock first
break;
case ELM_ATSPI_TEXT_GRANULARITY_LINE:
evas_textblock_cursor_line_char_first(cur);
break;
case ELM_ATSPI_TEXT_GRANULARITY_PARAGRAPH:
evas_textblock_cursor_paragraph_char_first(cur);
break;
}
*start_offset = evas_textblock_cursor_pos_get(cur);
evas_textblock_cursor_copy(cur, cur2);
switch (granularity)
{
case ELM_ATSPI_TEXT_GRANULARITY_CHAR:
evas_textblock_cursor_char_next(cur2);
break;
case ELM_ATSPI_TEXT_GRANULARITY_WORD:
evas_textblock_cursor_word_end(cur2);
// since word_end sets cursor position ON (before) last
// char of word, we need to manually advance cursor to get
// proper string from function range_text_get
evas_textblock_cursor_char_next(cur2);
break;
case ELM_ATSPI_TEXT_GRANULARITY_SENTENCE:
// TODO - add sentence support in textblock first
break;
case ELM_ATSPI_TEXT_GRANULARITY_LINE:
evas_textblock_cursor_line_char_last(cur2);
break;
case ELM_ATSPI_TEXT_GRANULARITY_PARAGRAPH:
evas_textblock_cursor_paragraph_char_last(cur2);
break;
}
if (end_offset) *end_offset = evas_textblock_cursor_pos_get(cur2);
ret = evas_textblock_cursor_range_text_get(cur, cur2, EVAS_TEXTBLOCK_TEXT_PLAIN);
evas_textblock_cursor_free(cur);
evas_textblock_cursor_free(cur2);
return ret;
fail:
if (start_offset) *start_offset = -1;
if (end_offset) *end_offset = -1;
if (cur) evas_textblock_cursor_free(cur);
if (cur2) evas_textblock_cursor_free(cur2);
return NULL;
}
EOLIAN static char*
_elm_entry_elm_interface_atspi_text_text_get(Eo *obj, Elm_Entry_Data *_pd EINA_UNUSED, int start_offset, int end_offset)
{
Evas_Textblock_Cursor *cur = NULL, *cur2 = NULL;
Evas_Object *tblk;
char *ret = NULL;
tblk = elm_entry_textblock_get(obj);
if (!tblk) goto fail;
cur = evas_object_textblock_cursor_new(tblk);
cur2 = evas_object_textblock_cursor_new(tblk);
if (!cur2 || !cur2) goto fail;
evas_textblock_cursor_pos_set(cur, start_offset);
if (evas_textblock_cursor_pos_get(cur) != start_offset) goto fail;
evas_textblock_cursor_pos_set(cur2, end_offset);
if (evas_textblock_cursor_pos_get(cur2) != end_offset) goto fail;
ret = evas_textblock_cursor_range_text_get(cur, cur2, EVAS_TEXTBLOCK_TEXT_PLAIN);
evas_textblock_cursor_free(cur);
evas_textblock_cursor_free(cur2);
return ret;
fail:
if (cur) evas_textblock_cursor_free(cur);
if (cur2) evas_textblock_cursor_free(cur2);
return NULL;
}
EOLIAN static int
_elm_entry_elm_interface_atspi_text_caret_offset_get(Eo *obj, Elm_Entry_Data *_pd EINA_UNUSED)
{
return elm_entry_cursor_pos_get(obj);
}
EOLIAN static Eina_Bool
_elm_entry_elm_interface_atspi_text_caret_offset_set(Eo *obj, Elm_Entry_Data *_pd EINA_UNUSED, int offset)
{
elm_entry_cursor_pos_set(obj, offset);
return EINA_TRUE;
}
EOLIAN static int
_elm_entry_elm_interface_atspi_text_selections_count_get(Eo *obj, Elm_Entry_Data *_pd EINA_UNUSED)
{
return elm_entry_selection_get(obj) ? 1 : 0;
}
EOLIAN static void
_elm_entry_elm_interface_atspi_text_selection_get(Eo *obj, Elm_Entry_Data *_pd EINA_UNUSED, int selection_number, int *start_offset, int *end_offset)
{
*start_offset = *end_offset = -1;
if (!elm_entry_selection_get(obj)) return;
if (selection_number != 0) return;
*start_offset = edje_object_part_text_cursor_pos_get(_pd->entry_edje, "elm.text", EDJE_CURSOR_SELECTION_BEGIN);
*end_offset = edje_object_part_text_cursor_pos_get(_pd->entry_edje, "elm.text", EDJE_CURSOR_SELECTION_END);
}
EOLIAN static Eina_Bool
_elm_entry_elm_interface_atspi_text_selection_set(Eo *obj, Elm_Entry_Data *_pd EINA_UNUSED, int selection_number, int start_offset, int end_offset)
{
if (selection_number != 0) return EINA_FALSE;
elm_entry_select_region_set(obj, start_offset, end_offset);
return EINA_TRUE;
}
EOLIAN static Eina_Bool
_elm_entry_elm_interface_atspi_text_selection_remove(Eo *obj, Elm_Entry_Data *pd EINA_UNUSED, int selection_number)
{
if (selection_number != 0) return EINA_FALSE;
elm_entry_select_none(obj);
return EINA_TRUE;
}
EOLIAN static Eina_Bool
_elm_entry_elm_interface_atspi_text_selection_add(Eo *obj, Elm_Entry_Data *pd EINA_UNUSED, int start_offset, int end_offset)
{
elm_entry_select_region_set(obj, start_offset, end_offset);
return EINA_TRUE;
}
EOLIAN static Eina_List*
_elm_entry_elm_interface_atspi_text_bounded_ranges_get(Eo *obj EINA_UNUSED, Elm_Entry_Data *_pd EINA_UNUSED, Eina_Bool screen_coods EINA_UNUSED, Eina_Rectangle rect EINA_UNUSED, Elm_Atspi_Text_Clip_Type xclip EINA_UNUSED, Elm_Atspi_Text_Clip_Type yclip EINA_UNUSED)
{
return NULL;
}
EOLIAN static int
_elm_entry_elm_interface_atspi_text_offset_at_point_get(Eo *obj, Elm_Entry_Data *_pd EINA_UNUSED, Eina_Bool screen_coods, int x, int y)
{
Evas_Object *txtblk;
Evas_Textblock_Cursor *cur;
int ret;
txtblk = elm_entry_textblock_get(obj);
if (!txtblk) return -1;
cur = evas_object_textblock_cursor_new(txtblk);
if (!cur) return -1;
if (screen_coods)
{
int ee_x, ee_y;
Ecore_Evas *ee= ecore_evas_ecore_evas_get(evas_object_evas_get(obj));
ecore_evas_geometry_get(ee, &ee_x, &ee_y, NULL, NULL);
x -= ee_x;
y -= ee_y;
}
if (!evas_textblock_cursor_char_coord_set(cur, x, y))
{
evas_textblock_cursor_free(cur);
return -1;
}
ret = evas_textblock_cursor_pos_get(cur);
evas_textblock_cursor_free(cur);
return ret;
}
EOLIAN static Eina_Bool
_elm_entry_elm_interface_atspi_text_character_extents_get(Eo *obj, Elm_Entry_Data *_pd EINA_UNUSED, int offset, Eina_Bool screen_coods, Eina_Rectangle *rect)
{
Evas_Object *txtblk;
Evas_Textblock_Cursor *cur;
int ret;
txtblk = elm_entry_textblock_get(obj);
if (!txtblk) return EINA_FALSE;
cur = evas_object_textblock_cursor_new(txtblk);
if (!cur) return EINA_FALSE;
evas_textblock_cursor_pos_set(cur, offset);
ret = evas_textblock_cursor_char_geometry_get(cur, &rect->x, &rect->y, &rect->w, &rect->h);
evas_textblock_cursor_free(cur);
if (ret == -1) return EINA_FALSE;
if (screen_coods)
{
int ee_x, ee_y;
Ecore_Evas *ee= ecore_evas_ecore_evas_get(evas_object_evas_get(obj));
ecore_evas_geometry_get(ee, &ee_x, &ee_y, NULL, NULL);
rect->x += ee_x;
rect->y += ee_y;
}
return EINA_TRUE;
}
EOLIAN static Eina_Bool
_elm_entry_elm_interface_atspi_text_range_extents_get(Eo *obj, Elm_Entry_Data *_pd EINA_UNUSED, Eina_Bool screen_coods, int start_offset, int end_offset, Eina_Rectangle *rect)
{
Evas_Object *txtblk;
Evas_Textblock_Cursor *cur1, *cur2;
int ret;
int x1, x2, y1, y2;
txtblk = elm_entry_textblock_get(obj);
if (!txtblk) return EINA_FALSE;
cur1 = evas_object_textblock_cursor_new(txtblk);
if (!cur1) return EINA_FALSE;
cur2 = evas_object_textblock_cursor_new(txtblk);
if (!cur2)
{
evas_textblock_cursor_free(cur1);
return EINA_FALSE;
}
evas_textblock_cursor_pos_set(cur1, start_offset);
evas_textblock_cursor_pos_set(cur2, end_offset);
ret = evas_textblock_cursor_char_geometry_get(cur1, &x1, &y1, NULL, NULL);
ret += evas_textblock_cursor_char_geometry_get(cur2, &x2, &y2, NULL, NULL);
evas_textblock_cursor_free(cur1);
evas_textblock_cursor_free(cur2);
if (ret != 0) return EINA_FALSE;
rect->x = x1 < x2 ? x1 : x2;
rect->y = y1 < y2 ? y1 : y2;
rect->w = abs(x1 - x2);
rect->h = abs(y1 - y2);
if (screen_coods)
{
int ee_x, ee_y;
Ecore_Evas *ee= ecore_evas_ecore_evas_get(evas_object_evas_get(obj));
ecore_evas_geometry_get(ee, &ee_x, &ee_y, NULL, NULL);
rect->x += ee_x;
rect->y += ee_y;
}
return EINA_TRUE;
}
static Elm_Atspi_Text_Attribute*
_textblock_node_format_to_atspi_text_attr(const Evas_Object_Textblock_Node_Format *format)
{
Elm_Atspi_Text_Attribute *ret = NULL;
const char *txt;
txt = evas_textblock_node_format_text_get(format);
if (!txt) return NULL;
if (txt[0] == '-') return NULL; // skip closing format
if (!strncmp(txt, "+ ", 2))
{
const char *tmp = &txt[2];
while (*tmp != '\0' && *tmp != '=') tmp++;
if (*tmp++ != '=') return NULL;
ret = calloc(1, sizeof(Elm_Atspi_Text_Attribute));
if (!ret) return NULL;
ret->value = eina_stringshare_add(tmp);
int size = &txt[2] - tmp + 1;
ret->name = eina_stringshare_add_length(&txt[2], size > 0 ? size : -size);
}
return ret;
}
EOLIAN static Eina_Bool
_elm_entry_elm_interface_atspi_text_attribute_get(Eo *obj, Elm_Entry_Data *_pd EINA_UNUSED, const char *attr_name EINA_UNUSED, int *start_offset, int *end_offset, char **value)
{
Evas_Object *txtblk;
Evas_Textblock_Cursor *cur1, *cur2;
Eina_List *formats, *l;
Evas_Object_Textblock_Node_Format *format;
Elm_Atspi_Text_Attribute *attr;
txtblk = elm_entry_textblock_get(obj);
if (!txtblk) return EINA_FALSE;
cur1 = evas_object_textblock_cursor_new(txtblk);
if (!cur1) return EINA_FALSE;
cur2 = evas_object_textblock_cursor_new(txtblk);
if (!cur2)
{
evas_textblock_cursor_free(cur1);
return EINA_FALSE;
}
evas_textblock_cursor_pos_set(cur1, *start_offset);
evas_textblock_cursor_pos_set(cur2, *end_offset);
formats = evas_textblock_cursor_range_formats_get(cur1, cur2);
evas_textblock_cursor_free(cur1);
evas_textblock_cursor_free(cur2);
if (!formats) return EINA_FALSE;
EINA_LIST_FOREACH(formats, l , format)
{
attr = _textblock_node_format_to_atspi_text_attr(format);
if (!attr) continue;
if (!strcmp(attr->name, attr_name))
{
*value = attr->value ? strdup(attr->value) : NULL;
elm_atspi_text_text_attribute_free(attr);
return EINA_TRUE;
}
elm_atspi_text_text_attribute_free(attr);
}
return EINA_FALSE;
}
EOLIAN static Eina_List*
_elm_entry_elm_interface_atspi_text_attributes_get(Eo *obj, Elm_Entry_Data *_pd EINA_UNUSED, int *start_offset, int *end_offset)
{
Evas_Object *txtblk;
Evas_Textblock_Cursor *cur1, *cur2;
Eina_List *formats, *ret = NULL, *l;
Evas_Object_Textblock_Node_Format *format;
Elm_Atspi_Text_Attribute *attr;
txtblk = elm_entry_textblock_get(obj);
if (!txtblk) return NULL;
cur1 = evas_object_textblock_cursor_new(txtblk);
if (!cur1) return NULL;
cur2 = evas_object_textblock_cursor_new(txtblk);
if (!cur2)
{
evas_textblock_cursor_free(cur1);
return NULL;
}
evas_textblock_cursor_pos_set(cur1, *start_offset);
evas_textblock_cursor_pos_set(cur2, *end_offset);
formats = evas_textblock_cursor_range_formats_get(cur1, cur2);
evas_textblock_cursor_free(cur1);
evas_textblock_cursor_free(cur2);
if (!formats) return EINA_FALSE;
EINA_LIST_FOREACH(formats, l , format)
{
attr = _textblock_node_format_to_atspi_text_attr(format);
if (!attr) continue;
ret = eina_list_append(ret, attr);
}
return ret;
}
EOLIAN static Eina_List*
_elm_entry_elm_interface_atspi_text_default_attributes_get(Eo *obj EINA_UNUSED, Elm_Entry_Data *_pd EINA_UNUSED)
{
Evas_Object *txtblk;
Eina_List *ret = NULL;
const Evas_Object_Textblock_Node_Format *format;
Elm_Atspi_Text_Attribute *attr;
txtblk = elm_entry_textblock_get(obj);
if (!txtblk) return NULL;
format = evas_textblock_node_format_first_get(txtblk);
if (!format) return EINA_FALSE;
do
{
attr = _textblock_node_format_to_atspi_text_attr(format);
if (!attr) continue;
ret = eina_list_append(ret, attr);
}
while ((format = evas_textblock_node_format_next_get(format)) != NULL);
return ret;
}
EOLIAN static Eina_Bool
_elm_entry_elm_interface_atspi_editable_text_content_set(Eo *obj, Elm_Entry_Data *_pd EINA_UNUSED, const char *content)
{
elm_entry_entry_set(obj, content);
return EINA_TRUE;
}
EOLIAN static Eina_Bool
_elm_entry_elm_interface_atspi_editable_text_insert(Eo *obj, Elm_Entry_Data *_pd EINA_UNUSED, const char *string, int position)
{
elm_entry_cursor_pos_set(obj, position);
elm_entry_entry_insert(obj, string);
return EINA_TRUE;
}
EOLIAN static Eina_Bool
_elm_entry_elm_interface_atspi_editable_text_copy(Eo *obj, Elm_Entry_Data *_pd EINA_UNUSED, int start, int end)
{
elm_entry_select_region_set(obj, start, end);
elm_entry_selection_copy(obj);
return EINA_TRUE;
}
EOLIAN static Eina_Bool
_elm_entry_elm_interface_atspi_editable_text_delete(Eo *obj, Elm_Entry_Data *_pd EINA_UNUSED, int start_offset, int end_offset)
{
Evas_Object *txtblk;
Evas_Textblock_Cursor *cur1, *cur2;
txtblk = elm_entry_textblock_get(obj);
if (!txtblk) return EINA_FALSE;
cur1 = evas_object_textblock_cursor_new(txtblk);
if (!cur1) return EINA_FALSE;
cur2 = evas_object_textblock_cursor_new(txtblk);
if (!cur2)
{
evas_textblock_cursor_free(cur1);
return EINA_FALSE;
}
evas_textblock_cursor_pos_set(cur1, start_offset);
evas_textblock_cursor_pos_set(cur2, end_offset);
evas_textblock_cursor_range_delete(cur1, cur2);
evas_textblock_cursor_free(cur1);
evas_textblock_cursor_free(cur2);
elm_entry_calc_force(obj);
return EINA_TRUE;
}
EOLIAN static Eina_Bool
_elm_entry_elm_interface_atspi_editable_text_paste(Eo *obj, Elm_Entry_Data *_pd EINA_UNUSED, int position)
{
elm_entry_cursor_pos_set(obj, position);
elm_entry_selection_paste(obj);
return EINA_TRUE;
}
EOLIAN static Eina_Bool
_elm_entry_elm_interface_atspi_editable_text_cut(Eo *obj, Elm_Entry_Data *_pd EINA_UNUSED, int start, int end)
{
elm_entry_select_region_set(obj, start, end);
elm_entry_selection_cut(obj);
return EINA_TRUE;
}
#include "elm_entry.eo.c"

View File

@ -1,4 +1,5 @@
class Elm_Entry (Elm_Layout, Elm_Interface_Scrollable, Evas_Clickable_Interface)
class Elm_Entry (Elm_Layout, Elm_Interface_Scrollable, Evas_Clickable_Interface,
Elm_Interface_Atspi_Text, Elm_Interface_Atspi_Editable_Text)
{
eo_prefix: elm_obj_entry;
properties {
@ -1185,6 +1186,30 @@ class Elm_Entry (Elm_Layout, Elm_Interface_Scrollable, Evas_Clickable_Interface)
Elm_Layout::content_aliases::get;
Elm_Interface_Scrollable::policy::set;
Elm_Interface_Scrollable::bounce_allow::set;
Elm_Interface_Atspi_Text::text::get;
Elm_Interface_Atspi_Text::string::get;
Elm_Interface_Atspi_Text::attribute::get;
Elm_Interface_Atspi_Text::attributes::get;
Elm_Interface_Atspi_Text::default_attributes::get;
Elm_Interface_Atspi_Text::caret_offset::get;
Elm_Interface_Atspi_Text::caret_offset::set;
Elm_Interface_Atspi_Text::character::get;
Elm_Interface_Atspi_Text::character_extents::get;
Elm_Interface_Atspi_Text::character_count::get;
Elm_Interface_Atspi_Text::offset_at_point::get;
Elm_Interface_Atspi_Text::bounded_ranges::get;
Elm_Interface_Atspi_Text::range_extents::get;
Elm_Interface_Atspi_Text::selection::get;
Elm_Interface_Atspi_Text::selections_count::get;
Elm_Interface_Atspi_Text::selection_add;
Elm_Interface_Atspi_Text::selection_remove;
Elm_Interface_Atspi_Text::selection::set;
Elm_Interface_Atspi_Editable_Text::content::set;
Elm_Interface_Atspi_Editable_Text::insert;
Elm_Interface_Atspi_Editable_Text::copy;
Elm_Interface_Atspi_Editable_Text::cut;
Elm_Interface_Atspi_Editable_Text::delete;
Elm_Interface_Atspi_Editable_Text::paste;
}
events {
language,changed;

View File

@ -0,0 +1,12 @@
#ifdef HAVE_CONFIG_H
#include "elementary_config.h"
#endif
#include <Elementary.h>
#include "elm_widget.h"
#include "elm_priv.h"
#define ELM_INTERFACE_ATSPI_EDITABLE_TEXT_PROTECTED
#include "elm_interface_atspi_editable_text.eo.h"
#include "elm_interface_atspi_editable_text.eo.c"

View File

@ -0,0 +1,60 @@
interface Elm_Interface_Atspi_Editable_Text ()
{
legacy_prefix: null;
eo_prefix: elm_interface_atspi_editable_text;
data: null;
properties {
protected content {
set {
return Eina_Bool;
}
values {
const char *string;
}
}
}
methods {
protected insert {
params {
@in const char *string;
@in int position;
}
return Eina_Bool;
}
protected copy {
params {
@in int start;
@in int end;
}
return Eina_Bool;
}
protected cut {
params {
@in int start;
@in int end;
}
return Eina_Bool;
}
protected delete {
params {
@in int start;
@in int end;
}
return Eina_Bool;
}
protected paste {
params {
@in int position;
}
return Eina_Bool;
}
}
implements {
virtual::content::set;
virtual::insert;
virtual::copy;
virtual::cut;
virtual::delete;
virtual::paste;
}
}

View File

@ -0,0 +1,23 @@
#ifdef HAVE_CONFIG_H
#include "elementary_config.h"
#endif
#include <Elementary.h>
#include "elm_widget.h"
#include "elm_priv.h"
#define ELM_INTERFACE_ATSPI_TEXT_PROTECTED
#include "elm_interface_atspi_text.h"
#include "elm_interface_atspi_text.eo.h"
EAPI void
elm_atspi_text_text_attribute_free(Elm_Atspi_Text_Attribute *attr)
{
if (!attr) return;
if (attr->name) eina_stringshare_del(attr->name);
if (attr->value) eina_stringshare_del(attr->value);
free(attr);
}
#include "elm_interface_atspi_text.eo.c"

View File

@ -0,0 +1,223 @@
interface Elm_Interface_Atspi_Text ()
{
legacy_prefix: null;
eo_prefix: elm_interface_atspi_text;
data: null;
properties {
protected character {
get {
/*@ Gets single character present in accessible widget's text
at given offset. */
}
keys {
int offset; /*@ Position in text. */
}
values {
Eina_Unicode character; /*@ Character at offset. 0 when out-of
bounds offset has been given.
Codepoints between DC80 and DCFF indicates
that string includes invalid UTF8 chars. */
}
}
protected string {
get {
/*@ Gets string, start and end offset in text according to
given initial offset and granulatity. */
}
keys {
@in Elm_Atspi_Text_Granularity granularity;
@inout int *start_offset @nonull; /*@ Offset indicating start of string
according to given granularity.
-1 in case of error. */
@out int *end_offset; /*@ Offset indicating end of string according
to given granularity. -1 in case of error. */
}
values {
char *string; /*@ Newly allocated UTF-8 encoded string.
Must be free by a user. */
}
}
protected text {
get {
/*@ Gets text of accessible widget. */
}
keys {
int start_offset; /*@ Position in text. */
int end_offset; /*@ End offset of text. */
}
values {
char *text; /*@ UTF-8 encoded text. */
}
}
protected caret_offset {
get {
/*@ Gets offset position of caret (cursor) */
}
set {
return Eina_Bool; /*@ EINA_TRUE if caret was successfully moved,
EINA_FASLE otherwise. */
}
values {
int offset;
}
}
protected attribute {
get {
/*@ Indicate if a text attribute with a given name is set */
return Eina_Bool;
}
keys {
@in const char *name @nonull; /*@ text attribute name */
@inout int *start_offset @nonull; /*@ Position in text from which
given attribute is set. */
@out int *end_offset; /*@ Position in text to which given attribute
is set. */
}
values {
char *value; /* Value of text attribute. Should be free() */
}
}
protected attributes {
get {
/* Gets list of all text attributes. */
}
keys {
@inout int *start_offset @nonull;
@out int *end_offset;
}
values {
@own Eina_List *attributes;
}
}
protected default_attributes {
get {
}
values {
@own Eina_List *attributes;
}
}
protected character_extents {
get {
return Eina_Bool;
}
keys {
int offset;
Eina_Bool screen_coords;
}
values {
Eina_Rectangle rect;
}
}
protected character_count {
get {
}
values {
int count;
}
}
protected offset_at_point {
get {
}
keys {
Eina_Bool screen_coords;
int x;
int y;
}
values {
int offset;
}
}
protected bounded_ranges {
get {
}
keys {
Eina_Bool screen_coords;
Eina_Rectangle rect;
Elm_Atspi_Text_Clip_Type xclip;
Elm_Atspi_Text_Clip_Type yclip;
}
values {
Eina_List *ranges;
}
}
protected range_extents {
get {
return Eina_Bool;
}
keys {
Eina_Bool screen_coords; /*@ If true x and y values will be relative
to screen origin, otherwise relative to
canvas */
int start_offset;
int end_offset;
}
values {
Eina_Rectangle rect;
}
}
protected selections_count {
get {
}
values {
int count;
}
}
protected selection {
get {
}
set {
return Eina_Bool;
}
keys {
int selection_number;
}
values {
int start_offset;
int end_offset;
}
}
}
methods {
protected selection_add {
params {
@in int start_offset;
@in int end_offset;
}
return Eina_Bool;
}
protected selection_remove {
params {
@in int selection_number;
}
return Eina_Bool;
}
}
events {
access,text,bounds,changed;
access,text,attributes,changed;
access,text,caret,moved;
access,text,inserted;
access,text,removed;
access,text,selection,changed;
}
implements {
virtual::text::get;
virtual::string::get;
virtual::attribute::get;
virtual::attributes::get;
virtual::default_attributes::get;
virtual::caret_offset::get;
virtual::caret_offset::set;
virtual::character::get;
virtual::character_extents::get;
virtual::character_count::get;
virtual::offset_at_point::get;
virtual::bounded_ranges::get;
virtual::range_extents::get;
virtual::selection::get;
virtual::selections_count::get;
virtual::selection_add;
virtual::selection_remove;
virtual::selection::set;
}
}

View File

@ -0,0 +1,53 @@
typedef enum _Elm_Atspi_Text_Granulatity Elm_Atspi_Text_Granularity;
enum _Elm_Atspi_Text_Granulatity
{
ELM_ATSPI_TEXT_GRANULARITY_CHAR,
ELM_ATSPI_TEXT_GRANULARITY_WORD,
ELM_ATSPI_TEXT_GRANULARITY_SENTENCE,
ELM_ATSPI_TEXT_GRANULARITY_LINE,
ELM_ATSPI_TEXT_GRANULARITY_PARAGRAPH
};
typedef struct _Elm_Atspi_Text_Attribute Elm_Atspi_Text_Attribute;
struct _Elm_Atspi_Text_Attribute
{
const char *name;
const char *value;
};
typedef struct _Elm_Atspi_Text_Range Elm_Atspi_Text_Range;
struct _Elm_Atspi_Text_Range
{
int start_offset;
int end_offset;
char *content;
};
typedef enum _Elm_Atspi_Text_Clip_Type Elm_Atspi_Text_Clip_Type;
enum _Elm_Atspi_Text_Clip_Type
{
ELM_ATSPI_TEXT_CLIP_NONE,
ELM_ATSPI_TEXT_CLIP_MIN,
ELM_ATSPI_TEXT_CLIP_MAX,
ELM_ATSPI_TEXT_CLIP_BOTH
};
/**
* @brief Free Elm_Atspi_Text_Attribute structure
*/
void elm_atspi_text_text_attribute_free(Elm_Atspi_Text_Attribute *attr);
typedef struct _Elm_Atspi_Text_Change_Info Elm_Atspi_Text_Change_Info;
struct _Elm_Atspi_Text_Change_Info
{
const char *content;
Eina_Bool inserted;
size_t pos;
size_t len;
};

View File

@ -5,6 +5,10 @@
#include <Elementary.h>
#include "elm_suite.h"
#define ELM_INTERFACE_ATSPI_TEXT_PROTECTED
#include "elm_interface_atspi_text.h"
#include "elm_interface_atspi_text.eo.h"
START_TEST (elm_entry_del)
{
Evas_Object *win, *entry;
@ -19,7 +23,342 @@ START_TEST (elm_entry_del)
}
END_TEST
START_TEST (elm_entry_atspi_text_char_get)
{
Evas_Object *win, *entry;
Eina_Unicode *expected;
Eina_Unicode val;
const char *txt = "ĄA11Y Ł TEST";
const char *mtxt = "<b>ĄA11Y</b> <title>Ł</> TEST";
elm_init(1, NULL);
win = elm_win_add(NULL, "entry", ELM_WIN_BASIC);
entry = elm_entry_add(win);
elm_object_text_set(entry, mtxt);
expected = eina_unicode_utf8_to_unicode(txt, NULL);
eo_do(entry, val = elm_interface_atspi_text_character_get(-1));
ck_assert(val == 0);
eo_do(entry, val = elm_interface_atspi_text_character_get(0));
ck_assert(val == expected[0]);
eo_do(entry, val = elm_interface_atspi_text_character_get(1));
ck_assert(val == expected[1]);
eo_do(entry, val = elm_interface_atspi_text_character_get(2));
ck_assert(val == expected[2]);
eo_do(entry, val = elm_interface_atspi_text_character_get(6));
ck_assert(val == expected[6]);
eo_do(entry, val = elm_interface_atspi_text_character_get(26));
ck_assert(val == 0);
free(expected);
elm_shutdown();
}
END_TEST
START_TEST (elm_entry_atspi_text_char_count)
{
Evas_Object *win, *entry;
int val;
const char *mtxt = "<b>AĄ11Y</b> <title>Ł</> TEST";
elm_init(1, NULL);
win = elm_win_add(NULL, "entry", ELM_WIN_BASIC);
entry = elm_entry_add(win);
elm_object_text_set(entry, mtxt);
eo_do(entry, val = elm_interface_atspi_text_character_count_get());
ck_assert(val == 12);
elm_shutdown();
}
END_TEST
START_TEST (elm_entry_atspi_text_string_get_char)
{
Evas_Object *win, *entry;
char *val;
int start, end;
const char *txt = "Lorem ipśum dolor sit amęt";
elm_init(1, NULL);
win = elm_win_add(NULL, "entry", ELM_WIN_BASIC);
entry = elm_entry_add(win);
elm_object_text_set(entry, txt);
start = 1;
eo_do(entry, val = elm_interface_atspi_text_string_get(ELM_ATSPI_TEXT_GRANULARITY_CHAR, &start, &end));
ck_assert_str_eq(val, "o");
ck_assert(start == 1);
ck_assert(end == 2);
if (val) free(val);
start = 8;
eo_do(entry, val = elm_interface_atspi_text_string_get(ELM_ATSPI_TEXT_GRANULARITY_CHAR, &start, &end));
ck_assert_str_eq(val, "ś");
ck_assert(start == 8);
ck_assert(end == 9);
if (val) free(val);
start = 11;
eo_do(entry, val = elm_interface_atspi_text_string_get(ELM_ATSPI_TEXT_GRANULARITY_CHAR, &start, &end));
ck_assert_str_eq(val, " ");
ck_assert(start == 11);
ck_assert(end == 12);
if (val) free(val);
start = 111;
eo_do(entry, val = elm_interface_atspi_text_string_get(ELM_ATSPI_TEXT_GRANULARITY_CHAR, &start, &end));
ck_assert(start == -1);
ck_assert(end == -1);
ck_assert(val == NULL);
elm_shutdown();
}
END_TEST
START_TEST (elm_entry_atspi_text_string_get_word)
{
Evas_Object *win, *entry;
char *val;
int start, end;
const char *txt = "Lorem ipśum dolor sit amęt";
elm_init(1, NULL);
win = elm_win_add(NULL, "entry", ELM_WIN_BASIC);
entry = elm_entry_add(win);
elm_object_text_set(entry, txt);
start = 1;
eo_do(entry, val = elm_interface_atspi_text_string_get(ELM_ATSPI_TEXT_GRANULARITY_WORD, &start, &end));
ck_assert_str_eq(val, "Lorem");
ck_assert(start == 0);
ck_assert(end == 5);
if (val) free(val);
start = 6;
eo_do(entry, val = elm_interface_atspi_text_string_get(ELM_ATSPI_TEXT_GRANULARITY_WORD, &start, &end));
ck_assert_str_eq(val, "ipśum");
ck_assert(start == 6);
ck_assert(end == 11);
if (val) free(val);
start = 19;
eo_do(entry, val = elm_interface_atspi_text_string_get(ELM_ATSPI_TEXT_GRANULARITY_WORD, &start, &end));
ck_assert_str_eq(val, "dolor");
ck_assert(start == 14);
ck_assert(end == 19);
if (val) free(val);
start = 111;
eo_do(entry, val = elm_interface_atspi_text_string_get(ELM_ATSPI_TEXT_GRANULARITY_WORD, &start, &end));
ck_assert(start == -1);
ck_assert(end == -1);
ck_assert(val == NULL);
if (val) free(val);
elm_shutdown();
}
END_TEST
START_TEST (elm_entry_atspi_text_string_get_paragraph)
{
Evas_Object *win, *entry;
char *val;
int start, end;
const char *txt = "Lorem ipśum<br> dolor sit\n amęt";
elm_init(1, NULL);
win = elm_win_add(NULL, "entry", ELM_WIN_BASIC);
entry = elm_entry_add(win);
elm_object_text_set(entry, txt);
start = 1;
eo_do(entry, val = elm_interface_atspi_text_string_get(ELM_ATSPI_TEXT_GRANULARITY_PARAGRAPH, &start, &end));
ck_assert_str_eq(val, "Lorem ipśum");
ck_assert(start == 0);
ck_assert(end == 11);
if (val) free(val);
start = 22;
eo_do(entry, val = elm_interface_atspi_text_string_get(ELM_ATSPI_TEXT_GRANULARITY_PARAGRAPH, &start, &end));
ck_assert_str_eq(val, " dolor sit");
ck_assert(start == 11);
ck_assert(end == 22);
if (val) free(val);
start = 27;
eo_do(entry, val = elm_interface_atspi_text_string_get(ELM_ATSPI_TEXT_GRANULARITY_PARAGRAPH, &start, &end));
ck_assert_str_eq(val, " amęt");
ck_assert(start == 23);
ck_assert(end == 27);
if (val) free(val);
start = 111;
eo_do(entry, val = elm_interface_atspi_text_string_get(ELM_ATSPI_TEXT_GRANULARITY_WORD, &start, &end));
ck_assert(start == -1);
ck_assert(end == -1);
ck_assert(val == NULL);
if (val) free(val);
elm_shutdown();
}
END_TEST
START_TEST (elm_entry_atspi_text_string_get_line)
{
Evas_Object *win, *entry;
char *val;
int start, end;
const char *txt = "Lorem ipśum<br> dolor sit\n amęt";
elm_init(1, NULL);
win = elm_win_add(NULL, "entry", ELM_WIN_BASIC);
entry = elm_entry_add(win);
elm_object_text_set(entry, txt);
start = 1;
eo_do(entry, val = elm_interface_atspi_text_string_get(ELM_ATSPI_TEXT_GRANULARITY_LINE, &start, &end));
ck_assert_str_eq(val, "Lorem ipśum");
ck_assert(start == 0);
ck_assert(end == 11);
if (val) free(val);
start = 13;
eo_do(entry, val = elm_interface_atspi_text_string_get(ELM_ATSPI_TEXT_GRANULARITY_LINE, &start, &end));
ck_assert_str_eq(val, " dolor sit");
ck_assert(start == 11);
ck_assert(end == 23);
if (val) free(val);
elm_shutdown();
}
END_TEST
START_TEST (elm_entry_atspi_text_text_get)
{
Evas_Object *win, *entry;
char *val;
const char *txt = "Lorem ipśum<br> dolor sit\n amęt";
const char *txtnom = "Lorem ipśum dolor sit\n amęt";
elm_init(1, NULL);
win = elm_win_add(NULL, "entry", ELM_WIN_BASIC);
entry = elm_entry_add(win);
elm_object_text_set(entry, txt);
eo_do(entry, val = elm_interface_atspi_text_text_get(0, sizeof(txtnom)/sizeof(txtnom[0])));
ck_assert_str_eq(val, txtnom);
if (val) free(val);
elm_shutdown();
}
END_TEST
START_TEST (elm_entry_atspi_text_selections)
{
Evas_Object *win, *entry;
int val, start, end;
const char *str;
Eina_Bool ret;
const char *txt = "Lorem ipśum<br> dolor sit\n amęt";
elm_init(1, NULL);
win = elm_win_add(NULL, "entry", ELM_WIN_BASIC);
entry = elm_entry_add(win);
elm_object_text_set(entry, txt);
eo_do(entry, val = elm_interface_atspi_text_selections_count_get());
ck_assert(val == 0);
elm_entry_select_region_set(entry, 2, 4);
eo_do(entry, val = elm_interface_atspi_text_selections_count_get());
ck_assert(val == 1);
eo_do(entry, elm_interface_atspi_text_selection_get(0, &start, &end));
ck_assert(start == 2);
ck_assert(end == 4);
elm_entry_select_region_set(entry, 6, 10);
eo_do(entry, val = elm_interface_atspi_text_selections_count_get());
ck_assert(val == 1);
eo_do(entry, elm_interface_atspi_text_selection_get(0, &start, &end));
ck_assert(start == 6);
ck_assert(end == 10);
elm_entry_select_none(entry);
eo_do(entry, ret = elm_interface_atspi_text_selection_add(2, 5));
ck_assert(ret == EINA_TRUE);
str = elm_entry_selection_get(entry);
ck_assert_str_eq(str, "rem");
eo_do(entry, ret = elm_interface_atspi_text_selection_remove(0));
ck_assert(ret == EINA_TRUE);
str = elm_entry_selection_get(entry);
ck_assert(str == NULL);
elm_shutdown();
}
END_TEST
START_TEST (elm_entry_atspi_text_attributes)
{
Evas_Object *win, *entry;
Eina_List *formats;
const char txt[] = "<font_weight=Bold>Lorem ipśum<br></> dolor sit\n amęt";
int start = 0, end = sizeof(txt);
Elm_Atspi_Text_Attribute *attr;
elm_init(1, NULL);
win = elm_win_add(NULL, "entry", ELM_WIN_BASIC);
entry = elm_entry_add(win);
elm_object_text_set(entry, txt);
eo_do(entry, formats = elm_interface_atspi_text_attributes_get(&start, &end));
EINA_LIST_FREE(formats, attr)
{
elm_atspi_text_text_attribute_free(attr);
}
eo_do(entry, formats = elm_interface_atspi_text_default_attributes_get());
EINA_LIST_FREE(formats, attr)
{
elm_atspi_text_text_attribute_free(attr);
}
elm_shutdown();
}
END_TEST
void elm_test_entry(TCase *tc)
{
tcase_add_test(tc, elm_entry_del);
tcase_add_test(tc, elm_entry_atspi_text_char_get);
tcase_add_test(tc, elm_entry_atspi_text_char_count);
tcase_add_test(tc, elm_entry_atspi_text_string_get_char);
tcase_add_test(tc, elm_entry_atspi_text_string_get_word);
tcase_add_test(tc, elm_entry_atspi_text_string_get_paragraph);
tcase_add_test(tc, elm_entry_atspi_text_string_get_line);
tcase_add_test(tc, elm_entry_atspi_text_text_get);
tcase_add_test(tc, elm_entry_atspi_text_selections);
tcase_add_test(tc, elm_entry_atspi_text_attributes);
}