1 /* 2 * Copyright (C) 2021 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.view.inputmethod; 18 19 import android.annotation.IntRange; 20 import android.annotation.NonNull; 21 22 import java.util.Objects; 23 24 /** 25 * An immutable data snapshot of text editing state. 26 */ 27 public final class TextSnapshot { 28 @NonNull 29 private final SurroundingText mSurroundingText; 30 @IntRange(from = -1) 31 private final int mCompositionStart; 32 @IntRange(from = -1) 33 private final int mCompositionEnd; 34 private final int mCursorCapsMode; 35 36 /** 37 * Creates a new instance of {@link TextSnapshot} 38 * 39 * @param surroundingText {@link SurroundingText} of the current edit field. 40 * @param compositionStart The start index of the composing text. 41 * {@code -1} if there is no composing text. 42 * @param compositionEnd The end index of the composing text. 43 * {@code -1} if there is no composing text. 44 * @param cursorCapsMode The capitalization mode of the first character being edited in the 45 * text. See {@link EditorInfo#initialCapsMode}. 46 * @throws NullPointerException if {@code surroundingText} is {@code null}. 47 * @throws IllegalArgumentException if {@code compositionStart} and/or {@code compositionEnd} 48 * is less than {@code -1}. 49 */ TextSnapshot(@onNull SurroundingText surroundingText, @IntRange(from = -1) int compositionStart, @IntRange(from = -1) int compositionEnd, int cursorCapsMode)50 public TextSnapshot(@NonNull SurroundingText surroundingText, 51 @IntRange(from = -1) int compositionStart, @IntRange(from = -1) int compositionEnd, 52 int cursorCapsMode) { 53 Objects.requireNonNull(surroundingText); 54 mSurroundingText = surroundingText; 55 if (compositionStart < -1) { 56 throw new IllegalArgumentException("compositionStart must be -1 or higher but was " 57 + compositionStart); 58 } 59 if (compositionEnd < -1) { 60 throw new IllegalArgumentException("compositionEnd must be -1 or higher but was " 61 + compositionEnd); 62 } 63 if (compositionStart == -1 && compositionEnd != -1) { 64 throw new IllegalArgumentException("compositionEnd must be -1 if compositionStart is " 65 + "-1 but was " + compositionEnd); 66 } 67 if (compositionStart != -1 && compositionEnd == -1) { 68 throw new IllegalArgumentException("compositionStart must be -1 if compositionEnd is " 69 + "-1 but was " + compositionStart); 70 } 71 if (compositionStart > compositionEnd) { 72 throw new IllegalArgumentException("compositionStart=" + compositionStart + " must be" 73 + " equal to or greater than compositionEnd=" + compositionEnd); 74 } 75 mCompositionStart = compositionStart; 76 mCompositionEnd = compositionEnd; 77 mCursorCapsMode = cursorCapsMode; 78 } 79 80 /** 81 * @return {@link SurroundingText} of the current edit field. 82 */ 83 @NonNull getSurroundingText()84 public SurroundingText getSurroundingText() { 85 return mSurroundingText; 86 } 87 88 /** 89 * @return The start index of the selection range. {@code -1} if it is not available. 90 */ 91 @IntRange(from = -1) getSelectionStart()92 public int getSelectionStart() { 93 if (mSurroundingText.getOffset() < 0) { 94 return -1; 95 } 96 return mSurroundingText.getSelectionStart() + mSurroundingText.getOffset(); 97 } 98 99 /** 100 * @return The end index of the selection range. {@code -1} if it is not available. 101 */ 102 @IntRange(from = -1) getSelectionEnd()103 public int getSelectionEnd() { 104 if (mSurroundingText.getOffset() < 0) { 105 return -1; 106 } 107 return mSurroundingText.getSelectionEnd() + mSurroundingText.getOffset(); 108 } 109 110 /** 111 * @return The end index of the composing text. {@code -1} if there is no composing text. 112 */ 113 @IntRange(from = -1) getCompositionStart()114 public int getCompositionStart() { 115 return mCompositionStart; 116 } 117 118 /** 119 * @return The end index of the composing text. {@code -1} if there is no composing text. 120 */ 121 @IntRange(from = -1) getCompositionEnd()122 public int getCompositionEnd() { 123 return mCompositionEnd; 124 } 125 126 /** 127 * The capitalization mode of the first character being edited in the text. 128 * 129 * <p>Values may be any combination of the following values:</p> 130 * <ul> 131 * <li>{@link android.text.TextUtils#CAP_MODE_CHARACTERS TextUtils.CAP_MODE_CHARACTERS}</li> 132 * <li>{@link android.text.TextUtils#CAP_MODE_WORDS TextUtils.CAP_MODE_WORDS}</li> 133 * <li>{@link android.text.TextUtils#CAP_MODE_SENTENCES TextUtils.CAP_MODE_SENTENCES}</li> 134 * </ul> 135 * 136 * <p>You should generally just take a non-zero value to mean "start out in caps mode" though. 137 * </p> 138 * @see EditorInfo#initialCapsMode 139 */ getCursorCapsMode()140 public int getCursorCapsMode() { 141 return mCursorCapsMode; 142 } 143 } 144 145