summaryrefslogtreecommitdiffstats
path: root/core/java/android/widget/TextView.java
diff options
context:
space:
mode:
authorSvetoslav <svetoslavganov@google.com>2013-01-30 23:02:08 -0800
committerSvetoslav <svetoslavganov@google.com>2013-01-30 23:47:17 -0800
commit7c51284d8019ed04ab296be84839d8a90ac042fa (patch)
tree54a952cca4a44f64918ecdcbd4f5c7f2f778f7c6 /core/java/android/widget/TextView.java
parent8c47e856b067057b5fcbb6eccfc79d1da4cff8f1 (diff)
downloadframeworks_base-7c51284d8019ed04ab296be84839d8a90ac042fa.zip
frameworks_base-7c51284d8019ed04ab296be84839d8a90ac042fa.tar.gz
frameworks_base-7c51284d8019ed04ab296be84839d8a90ac042fa.tar.bz2
Add accessibility actions for text editing.
Currently text editing is pretty hard (certain operations even impossible) for a blind person. To address the issue this change adds APIs that enable an accessibility service to perform basic text editing operations such as copy, paste, cut, set selection, extend selection while moving at a given granularity. The new APIs enable an accessibility service to expose a gesture driven efficient text editing facility. bug:8098384 Change-Id: I82b200138a3fdf4c0c316b774fc08a096ced29d0
Diffstat (limited to 'core/java/android/widget/TextView.java')
-rw-r--r--core/java/android/widget/TextView.java115
1 files changed, 104 insertions, 11 deletions
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index f8db622..2f02780 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -7985,6 +7985,80 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
| AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH
| AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
}
+ if (isFocused()) {
+ if (canSelectText()) {
+ info.addAction(AccessibilityNodeInfo.ACTION_SET_SELECTION);
+ }
+ if (canCopy()) {
+ info.addAction(AccessibilityNodeInfo.ACTION_COPY);
+ }
+ if (canPaste()) {
+ info.addAction(AccessibilityNodeInfo.ACTION_PASTE);
+ }
+ if (canCut()) {
+ info.addAction(AccessibilityNodeInfo.ACTION_CUT);
+ }
+ }
+ }
+
+ @Override
+ public boolean performAccessibilityAction(int action, Bundle arguments) {
+ switch (action) {
+ case AccessibilityNodeInfo.ACTION_COPY: {
+ if (isFocused() && canCopy()) {
+ if (onTextContextMenuItem(ID_COPY)) {
+ notifyAccessibilityStateChanged();
+ return true;
+ }
+ }
+ } return false;
+ case AccessibilityNodeInfo.ACTION_PASTE: {
+ if (isFocused() && canPaste()) {
+ if (onTextContextMenuItem(ID_PASTE)) {
+ notifyAccessibilityStateChanged();
+ return true;
+ }
+ }
+ } return false;
+ case AccessibilityNodeInfo.ACTION_CUT: {
+ if (isFocused() && canCut()) {
+ if (onTextContextMenuItem(ID_CUT)) {
+ notifyAccessibilityStateChanged();
+ return true;
+ }
+ }
+ } return false;
+ case AccessibilityNodeInfo.ACTION_SET_SELECTION: {
+ if (isFocused() && canSelectText()) {
+ final int start = (arguments != null) ? arguments.getInt(
+ AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_START_INT, -1) : -1;
+ final int end = (arguments != null) ? arguments.getInt(
+ AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_END_INT, -1) : -1;
+ CharSequence text = getIterableTextForAccessibility();
+ if (text == null) {
+ return false;
+ }
+ // No arguments clears the selection.
+ if (start == end && end == -1) {
+ Selection.removeSelection((Spannable) text);
+ notifyAccessibilityStateChanged();
+ return true;
+ }
+ if (start >= 0 && start <= end && end <= text.length()) {
+ Selection.setSelection((Spannable) text, start, end);
+ // Make sure selection mode is engaged.
+ if (mEditor != null) {
+ mEditor.startSelectionActionMode();
+ }
+ notifyAccessibilityStateChanged();
+ return true;
+ }
+ }
+ } return false;
+ default: {
+ return super.performAccessibilityAction(action, arguments);
+ }
+ }
}
@Override
@@ -8554,32 +8628,51 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
* @hide
*/
@Override
- public int getAccessibilityCursorPosition() {
+ public int getAccessibilitySelectionStart() {
+ if (TextUtils.isEmpty(getContentDescription())) {
+ final int selectionStart = getSelectionStart();
+ if (selectionStart >= 0) {
+ return selectionStart;
+ }
+ }
+ return ACCESSIBILITY_CURSOR_POSITION_UNDEFINED;
+ }
+
+ /**
+ * @hide
+ */
+ public boolean isAccessibilitySelectionExtendable() {
+ return true;
+ }
+
+ /**
+ * @hide
+ */
+ @Override
+ public int getAccessibilitySelectionEnd() {
if (TextUtils.isEmpty(getContentDescription())) {
final int selectionEnd = getSelectionEnd();
if (selectionEnd >= 0) {
return selectionEnd;
}
}
- return super.getAccessibilityCursorPosition();
+ return ACCESSIBILITY_CURSOR_POSITION_UNDEFINED;
}
/**
* @hide
*/
@Override
- public void setAccessibilityCursorPosition(int index) {
- if (getAccessibilityCursorPosition() == index) {
+ public void setAccessibilitySelection(int start, int end) {
+ if (getAccessibilitySelectionStart() == start
+ && getAccessibilitySelectionEnd() == end) {
return;
}
- if (TextUtils.isEmpty(getContentDescription())) {
- if (index >= 0 && index <= mText.length()) {
- Selection.setSelection((Spannable) mText, index);
- } else {
- Selection.removeSelection((Spannable) mText);
- }
+ CharSequence text = getIterableTextForAccessibility();
+ if (start >= 0 && start <= end && end <= text.length()) {
+ Selection.setSelection((Spannable) text, start, end);
} else {
- super.setAccessibilityCursorPosition(index);
+ Selection.removeSelection((Spannable) text);
}
}