| /* |
| * Copyright (C) 2012 Google Inc. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); you may not |
| * use this file except in compliance with the License. You may obtain a copy of |
| * the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| * License for the specific language governing permissions and limitations under |
| * the License. |
| */ |
| |
| package com.googlecode.eyesfree.braille.selfbraille; |
| |
| import android.os.Bundle; |
| import android.os.Parcel; |
| import android.os.Parcelable; |
| import android.view.View; |
| import android.view.accessibility.AccessibilityNodeInfo; |
| |
| /** |
| * Represents what should be shown on the braille display for a |
| * part of the accessibility node tree. |
| */ |
| public class WriteData implements Parcelable { |
| |
| private static final String PROP_SELECTION_START = "selectionStart"; |
| private static final String PROP_SELECTION_END = "selectionEnd"; |
| |
| private AccessibilityNodeInfo mAccessibilityNodeInfo; |
| private CharSequence mText; |
| private Bundle mProperties = Bundle.EMPTY; |
| |
| /** |
| * Returns a new {@link WriteData} instance for the given {@code view}. |
| */ |
| public static WriteData forView(View view) { |
| AccessibilityNodeInfo node = AccessibilityNodeInfo.obtain(view); |
| WriteData writeData = new WriteData(); |
| writeData.mAccessibilityNodeInfo = node; |
| return writeData; |
| } |
| |
| public AccessibilityNodeInfo getAccessibilityNodeInfo() { |
| return mAccessibilityNodeInfo; |
| } |
| |
| /** |
| * Sets the text to be displayed when the accessibility node associated |
| * with this instance has focus. If this method is not called (or |
| * {@code text} is {@code null}), this client relinquishes control over |
| * this node. |
| */ |
| public WriteData setText(CharSequence text) { |
| mText = text; |
| return this; |
| } |
| |
| public CharSequence getText() { |
| return mText; |
| } |
| |
| /** |
| * Sets the start position in the text of a text selection or cursor that |
| * should be marked on the display. A negative value (the default) means |
| * no selection will be added. |
| */ |
| public WriteData setSelectionStart(int v) { |
| writableProperties().putInt(PROP_SELECTION_START, v); |
| return this; |
| } |
| |
| /** |
| * @see {@link #setSelectionStart}. |
| */ |
| public int getSelectionStart() { |
| return mProperties.getInt(PROP_SELECTION_START, -1); |
| } |
| |
| /** |
| * Sets the end of the text selection to be marked on the display. This |
| * value should only be non-negative if the selection start is |
| * non-negative. If this value is <= the selection start, the selection |
| * is a cursor. Otherwise, the selection covers the range from |
| * start(inclusive) to end (exclusive). |
| * |
| * @see {@link android.text.Selection}. |
| */ |
| public WriteData setSelectionEnd(int v) { |
| writableProperties().putInt(PROP_SELECTION_END, v); |
| return this; |
| } |
| |
| /** |
| * @see {@link #setSelectionEnd}. |
| */ |
| public int getSelectionEnd() { |
| return mProperties.getInt(PROP_SELECTION_END, -1); |
| } |
| |
| private Bundle writableProperties() { |
| if (mProperties == Bundle.EMPTY) { |
| mProperties = new Bundle(); |
| } |
| return mProperties; |
| } |
| |
| /** |
| * Checks constraints on the fields that must be satisfied before sending |
| * this instance to the self braille service. |
| * @throws IllegalStateException |
| */ |
| public void validate() throws IllegalStateException { |
| if (mAccessibilityNodeInfo == null) { |
| throw new IllegalStateException( |
| "Accessibility node info can't be null"); |
| } |
| int selectionStart = getSelectionStart(); |
| int selectionEnd = getSelectionEnd(); |
| if (mText == null) { |
| if (selectionStart > 0 || selectionEnd > 0) { |
| throw new IllegalStateException( |
| "Selection can't be set without text"); |
| } |
| } else { |
| if (selectionStart < 0 && selectionEnd >= 0) { |
| throw new IllegalStateException( |
| "Selection end without start"); |
| } |
| int textLength = mText.length(); |
| if (selectionStart > textLength || selectionEnd > textLength) { |
| throw new IllegalStateException("Selection out of bounds"); |
| } |
| } |
| } |
| |
| // For Parcelable support. |
| |
| public static final Parcelable.Creator<WriteData> CREATOR = |
| new Parcelable.Creator<WriteData>() { |
| @Override |
| public WriteData createFromParcel(Parcel in) { |
| return new WriteData(in); |
| } |
| |
| @Override |
| public WriteData[] newArray(int size) { |
| return new WriteData[size]; |
| } |
| }; |
| |
| @Override |
| public int describeContents() { |
| return 0; |
| } |
| |
| /** |
| * {@inheritDoc} |
| * <strong>Note:</strong> The {@link AccessibilityNodeInfo} will be |
| * recycled by this method, don't try to use this more than once. |
| */ |
| @Override |
| public void writeToParcel(Parcel out, int flags) { |
| mAccessibilityNodeInfo.writeToParcel(out, flags); |
| // The above call recycles the node, so make sure we don't use it |
| // anymore. |
| mAccessibilityNodeInfo = null; |
| out.writeString(mText.toString()); |
| out.writeBundle(mProperties); |
| } |
| |
| private WriteData() { |
| } |
| |
| private WriteData(Parcel in) { |
| mAccessibilityNodeInfo = |
| AccessibilityNodeInfo.CREATOR.createFromParcel(in); |
| mText = in.readString(); |
| mProperties = in.readBundle(); |
| } |
| } |