Wed, 31 Dec 2014 07:22:50 +0100
Correct previous dual key logic pending first delivery installment.
michael@0 | 1 | /* |
michael@0 | 2 | * Copyright (C) 2012 Google Inc. |
michael@0 | 3 | * |
michael@0 | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not |
michael@0 | 5 | * use this file except in compliance with the License. You may obtain a copy of |
michael@0 | 6 | * the License at |
michael@0 | 7 | * |
michael@0 | 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
michael@0 | 9 | * |
michael@0 | 10 | * Unless required by applicable law or agreed to in writing, software |
michael@0 | 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
michael@0 | 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
michael@0 | 13 | * License for the specific language governing permissions and limitations under |
michael@0 | 14 | * the License. |
michael@0 | 15 | */ |
michael@0 | 16 | |
michael@0 | 17 | package com.googlecode.eyesfree.braille.selfbraille; |
michael@0 | 18 | |
michael@0 | 19 | import android.os.Bundle; |
michael@0 | 20 | import android.os.Parcel; |
michael@0 | 21 | import android.os.Parcelable; |
michael@0 | 22 | import android.view.View; |
michael@0 | 23 | import android.view.accessibility.AccessibilityNodeInfo; |
michael@0 | 24 | |
michael@0 | 25 | /** |
michael@0 | 26 | * Represents what should be shown on the braille display for a |
michael@0 | 27 | * part of the accessibility node tree. |
michael@0 | 28 | */ |
michael@0 | 29 | public class WriteData implements Parcelable { |
michael@0 | 30 | |
michael@0 | 31 | private static final String PROP_SELECTION_START = "selectionStart"; |
michael@0 | 32 | private static final String PROP_SELECTION_END = "selectionEnd"; |
michael@0 | 33 | |
michael@0 | 34 | private AccessibilityNodeInfo mAccessibilityNodeInfo; |
michael@0 | 35 | private CharSequence mText; |
michael@0 | 36 | private Bundle mProperties = Bundle.EMPTY; |
michael@0 | 37 | |
michael@0 | 38 | /** |
michael@0 | 39 | * Returns a new {@link WriteData} instance for the given {@code view}. |
michael@0 | 40 | */ |
michael@0 | 41 | public static WriteData forView(View view) { |
michael@0 | 42 | AccessibilityNodeInfo node = AccessibilityNodeInfo.obtain(view); |
michael@0 | 43 | WriteData writeData = new WriteData(); |
michael@0 | 44 | writeData.mAccessibilityNodeInfo = node; |
michael@0 | 45 | return writeData; |
michael@0 | 46 | } |
michael@0 | 47 | |
michael@0 | 48 | public static WriteData forInfo(AccessibilityNodeInfo info){ |
michael@0 | 49 | WriteData writeData = new WriteData(); |
michael@0 | 50 | writeData.mAccessibilityNodeInfo = info; |
michael@0 | 51 | return writeData; |
michael@0 | 52 | } |
michael@0 | 53 | |
michael@0 | 54 | |
michael@0 | 55 | public AccessibilityNodeInfo getAccessibilityNodeInfo() { |
michael@0 | 56 | return mAccessibilityNodeInfo; |
michael@0 | 57 | } |
michael@0 | 58 | |
michael@0 | 59 | /** |
michael@0 | 60 | * Sets the text to be displayed when the accessibility node associated |
michael@0 | 61 | * with this instance has focus. If this method is not called (or |
michael@0 | 62 | * {@code text} is {@code null}), this client relinquishes control over |
michael@0 | 63 | * this node. |
michael@0 | 64 | */ |
michael@0 | 65 | public WriteData setText(CharSequence text) { |
michael@0 | 66 | mText = text; |
michael@0 | 67 | return this; |
michael@0 | 68 | } |
michael@0 | 69 | |
michael@0 | 70 | public CharSequence getText() { |
michael@0 | 71 | return mText; |
michael@0 | 72 | } |
michael@0 | 73 | |
michael@0 | 74 | /** |
michael@0 | 75 | * Sets the start position in the text of a text selection or cursor that |
michael@0 | 76 | * should be marked on the display. A negative value (the default) means |
michael@0 | 77 | * no selection will be added. |
michael@0 | 78 | */ |
michael@0 | 79 | public WriteData setSelectionStart(int v) { |
michael@0 | 80 | writableProperties().putInt(PROP_SELECTION_START, v); |
michael@0 | 81 | return this; |
michael@0 | 82 | } |
michael@0 | 83 | |
michael@0 | 84 | /** |
michael@0 | 85 | * @see {@link #setSelectionStart}. |
michael@0 | 86 | */ |
michael@0 | 87 | public int getSelectionStart() { |
michael@0 | 88 | return mProperties.getInt(PROP_SELECTION_START, -1); |
michael@0 | 89 | } |
michael@0 | 90 | |
michael@0 | 91 | /** |
michael@0 | 92 | * Sets the end of the text selection to be marked on the display. This |
michael@0 | 93 | * value should only be non-negative if the selection start is |
michael@0 | 94 | * non-negative. If this value is <= the selection start, the selection |
michael@0 | 95 | * is a cursor. Otherwise, the selection covers the range from |
michael@0 | 96 | * start(inclusive) to end (exclusive). |
michael@0 | 97 | * |
michael@0 | 98 | * @see {@link android.text.Selection}. |
michael@0 | 99 | */ |
michael@0 | 100 | public WriteData setSelectionEnd(int v) { |
michael@0 | 101 | writableProperties().putInt(PROP_SELECTION_END, v); |
michael@0 | 102 | return this; |
michael@0 | 103 | } |
michael@0 | 104 | |
michael@0 | 105 | /** |
michael@0 | 106 | * @see {@link #setSelectionEnd}. |
michael@0 | 107 | */ |
michael@0 | 108 | public int getSelectionEnd() { |
michael@0 | 109 | return mProperties.getInt(PROP_SELECTION_END, -1); |
michael@0 | 110 | } |
michael@0 | 111 | |
michael@0 | 112 | private Bundle writableProperties() { |
michael@0 | 113 | if (mProperties == Bundle.EMPTY) { |
michael@0 | 114 | mProperties = new Bundle(); |
michael@0 | 115 | } |
michael@0 | 116 | return mProperties; |
michael@0 | 117 | } |
michael@0 | 118 | |
michael@0 | 119 | /** |
michael@0 | 120 | * Checks constraints on the fields that must be satisfied before sending |
michael@0 | 121 | * this instance to the self braille service. |
michael@0 | 122 | * @throws IllegalStateException |
michael@0 | 123 | */ |
michael@0 | 124 | public void validate() throws IllegalStateException { |
michael@0 | 125 | if (mAccessibilityNodeInfo == null) { |
michael@0 | 126 | throw new IllegalStateException( |
michael@0 | 127 | "Accessibility node info can't be null"); |
michael@0 | 128 | } |
michael@0 | 129 | int selectionStart = getSelectionStart(); |
michael@0 | 130 | int selectionEnd = getSelectionEnd(); |
michael@0 | 131 | if (mText == null) { |
michael@0 | 132 | if (selectionStart > 0 || selectionEnd > 0) { |
michael@0 | 133 | throw new IllegalStateException( |
michael@0 | 134 | "Selection can't be set without text"); |
michael@0 | 135 | } |
michael@0 | 136 | } else { |
michael@0 | 137 | if (selectionStart < 0 && selectionEnd >= 0) { |
michael@0 | 138 | throw new IllegalStateException( |
michael@0 | 139 | "Selection end without start"); |
michael@0 | 140 | } |
michael@0 | 141 | int textLength = mText.length(); |
michael@0 | 142 | if (selectionStart > textLength || selectionEnd > textLength) { |
michael@0 | 143 | throw new IllegalStateException("Selection out of bounds"); |
michael@0 | 144 | } |
michael@0 | 145 | } |
michael@0 | 146 | } |
michael@0 | 147 | |
michael@0 | 148 | // For Parcelable support. |
michael@0 | 149 | |
michael@0 | 150 | public static final Parcelable.Creator<WriteData> CREATOR = |
michael@0 | 151 | new Parcelable.Creator<WriteData>() { |
michael@0 | 152 | @Override |
michael@0 | 153 | public WriteData createFromParcel(Parcel in) { |
michael@0 | 154 | return new WriteData(in); |
michael@0 | 155 | } |
michael@0 | 156 | |
michael@0 | 157 | @Override |
michael@0 | 158 | public WriteData[] newArray(int size) { |
michael@0 | 159 | return new WriteData[size]; |
michael@0 | 160 | } |
michael@0 | 161 | }; |
michael@0 | 162 | |
michael@0 | 163 | @Override |
michael@0 | 164 | public int describeContents() { |
michael@0 | 165 | return 0; |
michael@0 | 166 | } |
michael@0 | 167 | |
michael@0 | 168 | /** |
michael@0 | 169 | * {@inheritDoc} |
michael@0 | 170 | * <strong>Note:</strong> The {@link AccessibilityNodeInfo} will be |
michael@0 | 171 | * recycled by this method, don't try to use this more than once. |
michael@0 | 172 | */ |
michael@0 | 173 | @Override |
michael@0 | 174 | public void writeToParcel(Parcel out, int flags) { |
michael@0 | 175 | mAccessibilityNodeInfo.writeToParcel(out, flags); |
michael@0 | 176 | // The above call recycles the node, so make sure we don't use it |
michael@0 | 177 | // anymore. |
michael@0 | 178 | mAccessibilityNodeInfo = null; |
michael@0 | 179 | out.writeString(mText.toString()); |
michael@0 | 180 | out.writeBundle(mProperties); |
michael@0 | 181 | } |
michael@0 | 182 | |
michael@0 | 183 | private WriteData() { |
michael@0 | 184 | } |
michael@0 | 185 | |
michael@0 | 186 | private WriteData(Parcel in) { |
michael@0 | 187 | mAccessibilityNodeInfo = |
michael@0 | 188 | AccessibilityNodeInfo.CREATOR.createFromParcel(in); |
michael@0 | 189 | mText = in.readString(); |
michael@0 | 190 | mProperties = in.readBundle(); |
michael@0 | 191 | } |
michael@0 | 192 | } |