diff options
-rw-r--r-- | core/java/android/view/inputmethod/ExtractedText.java | 2 | ||||
-rw-r--r-- | core/java/android/widget/Editor.java | 187 | ||||
-rw-r--r-- | core/java/android/widget/SpellChecker.java | 5 | ||||
-rw-r--r-- | core/java/android/widget/TextView.java | 19 |
4 files changed, 81 insertions, 132 deletions
diff --git a/core/java/android/view/inputmethod/ExtractedText.java b/core/java/android/view/inputmethod/ExtractedText.java index 662ba3f..3b2508c 100644 --- a/core/java/android/view/inputmethod/ExtractedText.java +++ b/core/java/android/view/inputmethod/ExtractedText.java @@ -45,7 +45,7 @@ public class ExtractedText implements Parcelable { /** * If the content is a report of a partial text change, this is the offset * where the change ends. Note that the actual text may be larger or - * smaller than the difference between this and {@link #partialEndOffset}, + * smaller than the difference between this and {@link #partialStartOffset}, * meaning a reduction or increase, respectively, in the total text. */ public int partialEndOffset; diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java index cbff58c..d16e9da 100644 --- a/core/java/android/widget/Editor.java +++ b/core/java/android/widget/Editor.java @@ -47,7 +47,6 @@ import android.text.SpannableStringBuilder; import android.text.Spanned; import android.text.StaticLayout; import android.text.TextUtils; -import android.text.TextWatcher; import android.text.method.KeyListener; import android.text.method.MetaKeyKeyListener; import android.text.method.MovementMethod; @@ -183,8 +182,6 @@ public class Editor { Editor(TextView textView) { mTextView = textView; - mEasyEditSpanController = new EasyEditSpanController(); - mTextView.addTextChangedListener(mEasyEditSpanController); } void onAttachedToWindow() { @@ -1120,7 +1117,7 @@ public class Editor { if (contentChanged || ims.mSelectionModeChanged) { ims.mContentChanged = false; ims.mSelectionModeChanged = false; - final ExtractedTextRequest req = ims.mExtracting; + final ExtractedTextRequest req = ims.mExtractedTextRequest; if (req != null) { InputMethodManager imm = InputMethodManager.peekInstance(); if (imm != null) { @@ -1132,13 +1129,14 @@ public class Editor { ims.mChangedStart = EXTRACT_NOTHING; } if (extractTextInternal(req, ims.mChangedStart, ims.mChangedEnd, - ims.mChangedDelta, ims.mTmpExtracted)) { + ims.mChangedDelta, ims.mExtractedText)) { if (TextView.DEBUG_EXTRACT) Log.v(TextView.LOG_TAG, "Reporting extracted start=" + - ims.mTmpExtracted.partialStartOffset + - " end=" + ims.mTmpExtracted.partialEndOffset + - ": " + ims.mTmpExtracted.text); - imm.updateExtractedText(mTextView, req.token, ims.mTmpExtracted); + ims.mExtractedText.partialStartOffset + + " end=" + ims.mExtractedText.partialEndOffset + + ": " + ims.mExtractedText.text); + + imm.updateExtractedText(mTextView, req.token, ims.mExtractedText); ims.mChangedStart = EXTRACT_UNKNOWN; ims.mChangedEnd = EXTRACT_UNKNOWN; ims.mChangedDelta = 0; @@ -1734,138 +1732,92 @@ public class Editor { } } + public void addSpanWatchers(Spannable text) { + final int textLength = text.length(); + + if (mKeyListener != null) { + text.setSpan(mKeyListener, 0, textLength, Spanned.SPAN_INCLUSIVE_INCLUSIVE); + } + + if (mEasyEditSpanController == null) { + mEasyEditSpanController = new EasyEditSpanController(); + } + text.setSpan(mEasyEditSpanController, 0, textLength, Spanned.SPAN_INCLUSIVE_INCLUSIVE); + } + /** * Controls the {@link EasyEditSpan} monitoring when it is added, and when the related * pop-up should be displayed. */ - class EasyEditSpanController implements TextWatcher { + class EasyEditSpanController implements SpanWatcher { private static final int DISPLAY_TIMEOUT_MS = 3000; // 3 secs private EasyEditPopupWindow mPopupWindow; - private EasyEditSpan mEasyEditSpan; - private Runnable mHidePopup; - public void hide() { - if (mPopupWindow != null) { - mPopupWindow.hide(); - mTextView.removeCallbacks(mHidePopup); - } - removeSpans(mTextView.getText()); - mEasyEditSpan = null; - } - - public void beforeTextChanged(CharSequence s, int start, int count, int after) { - // Intentionally empty - } - - public void afterTextChanged(Editable s) { - // Intentionally empty - } + @Override + public void onSpanAdded(Spannable text, Object span, int start, int end) { + if (span instanceof EasyEditSpan) { + if (mPopupWindow == null) { + mPopupWindow = new EasyEditPopupWindow(); + mHidePopup = new Runnable() { + @Override + public void run() { + hide(); + } + }; + } - /** - * Monitors the changes in the text. - * - * <p>{@link SpanWatcher#onSpanAdded(Spannable, Object, int, int)} cannot be used, - * as the notifications are not sent when a spannable (with spans) is inserted. - */ - public void onTextChanged(CharSequence buffer, int start, int before, int after) { - adjustSpans(buffer, start, after); + // Make sure there is only at most one EasyEditSpan in the text + if (mPopupWindow.mEasyEditSpan != null) { + text.removeSpan(mPopupWindow.mEasyEditSpan); + } - if (mTextView.getWindowVisibility() != View.VISIBLE) { - // The window is not visible yet, ignore the text change. - return; - } + mPopupWindow.setEasyEditSpan((EasyEditSpan) span); - if (mTextView.getLayout() == null) { - // The view has not been layout yet, ignore the text change - return; - } - - InputMethodManager imm = InputMethodManager.peekInstance(); - if (!(mTextView instanceof ExtractEditText) && imm != null && imm.isFullscreenMode()) { - // The input is in extract mode. We do not have to handle the easy edit in the - // original TextView, as the ExtractEditText will do - return; - } + if (mTextView.getWindowVisibility() != View.VISIBLE) { + // The window is not visible yet, ignore the text change. + return; + } - // Remove the current easy edit span, as the text changed, and remove the pop-up - // (if any) - if (mEasyEditSpan != null) { - if (buffer instanceof Spannable) { - ((Spannable) buffer).removeSpan(mEasyEditSpan); + if (mTextView.getLayout() == null) { + // The view has not been laid out yet, ignore the text change + return; } - mEasyEditSpan = null; - } - if (mPopupWindow != null && mPopupWindow.isShowing()) { - mPopupWindow.hide(); - } - // Display the new easy edit span (if any). - if (buffer instanceof Spanned) { - mEasyEditSpan = getSpan((Spanned) buffer); - if (mEasyEditSpan != null) { - if (mPopupWindow == null) { - mPopupWindow = new EasyEditPopupWindow(); - mHidePopup = new Runnable() { - @Override - public void run() { - hide(); - } - }; - } - mPopupWindow.show(mEasyEditSpan); - mTextView.removeCallbacks(mHidePopup); - mTextView.postDelayed(mHidePopup, DISPLAY_TIMEOUT_MS); + if (extractedTextModeWillBeStarted()) { + // The input is in extract mode. Do not handle the easy edit in + // the original TextView, as the ExtractEditText will do + return; } + + mPopupWindow.show(); + mTextView.removeCallbacks(mHidePopup); + mTextView.postDelayed(mHidePopup, DISPLAY_TIMEOUT_MS); } } - /** - * Adjusts the spans by removing all of them except the last one. - */ - private void adjustSpans(CharSequence buffer, int start, int after) { - // This method enforces that only one easy edit span is attached to the text. - // A better way to enforce this would be to listen for onSpanAdded, but this method - // cannot be used in this scenario as no notification is triggered when a text with - // spans is inserted into a text. - if (buffer instanceof Spannable) { - Spannable spannable = (Spannable) buffer; - EasyEditSpan[] spans = spannable.getSpans(start, start + after, EasyEditSpan.class); - if (spans.length > 0) { - // Assuming there was only one EasyEditSpan before, we only need check to - // check for a duplicate if a new one is found in the modified interval - spans = spannable.getSpans(0, spannable.length(), EasyEditSpan.class); - for (int i = 1; i < spans.length; i++) { - spannable.removeSpan(spans[i]); - } - } + @Override + public void onSpanRemoved(Spannable text, Object span, int start, int end) { + if (mPopupWindow != null && span == mPopupWindow.mEasyEditSpan) { + hide(); } } - /** - * Removes all the {@link EasyEditSpan} currently attached. - */ - private void removeSpans(CharSequence buffer) { - if (buffer instanceof Spannable) { - Spannable spannable = (Spannable) buffer; - EasyEditSpan[] spans = spannable.getSpans(0, spannable.length(), - EasyEditSpan.class); - for (int i = 0; i < spans.length; i++) { - spannable.removeSpan(spans[i]); - } + @Override + public void onSpanChanged(Spannable text, Object span, int previousStart, int previousEnd, + int newStart, int newEnd) { + if (mPopupWindow != null && span == mPopupWindow.mEasyEditSpan) { + text.removeSpan(mPopupWindow.mEasyEditSpan); } } - private EasyEditSpan getSpan(Spanned spanned) { - EasyEditSpan[] easyEditSpans = spanned.getSpans(0, spanned.length(), - EasyEditSpan.class); - if (easyEditSpans.length == 0) { - return null; - } else { - return easyEditSpans[0]; + public void hide() { + if (mPopupWindow != null) { + mPopupWindow.hide(); + mTextView.removeCallbacks(mHidePopup); } } } @@ -1910,9 +1862,8 @@ public class Editor { mContentView.addView(mDeleteTextView); } - public void show(EasyEditSpan easyEditSpan) { + public void setEasyEditSpan(EasyEditSpan easyEditSpan) { mEasyEditSpan = easyEditSpan; - super.show(); } @Override @@ -3738,8 +3689,8 @@ public class Editor { Rect mCursorRectInWindow = new Rect(); RectF mTmpRectF = new RectF(); float[] mTmpOffset = new float[2]; - ExtractedTextRequest mExtracting; - final ExtractedText mTmpExtracted = new ExtractedText(); + ExtractedTextRequest mExtractedTextRequest; + final ExtractedText mExtractedText = new ExtractedText(); int mBatchEditNesting; boolean mCursorChanged; boolean mSelectionModeChanged; diff --git a/core/java/android/widget/SpellChecker.java b/core/java/android/widget/SpellChecker.java index c725b64..f033072 100644 --- a/core/java/android/widget/SpellChecker.java +++ b/core/java/android/widget/SpellChecker.java @@ -207,6 +207,7 @@ public class SpellChecker implements SpellCheckerSessionListener { public void spellCheck(int start, int end) { final Locale locale = mTextView.getTextServicesLocale(); + final boolean isSessionActive = isSessionActive(); if (mCurrentLocale == null || (!(mCurrentLocale.equals(locale)))) { setLocale(locale); // Re-check the entire text @@ -214,13 +215,13 @@ public class SpellChecker implements SpellCheckerSessionListener { end = mTextView.getText().length(); } else { final boolean spellCheckerActivated = mTextServicesManager.isSpellCheckerEnabled(); - if (isSessionActive() != spellCheckerActivated) { + if (isSessionActive != spellCheckerActivated) { // Spell checker has been turned of or off since last spellCheck resetSession(); } } - if (!isSessionActive()) return; + if (!isSessionActive) return; // Find first available SpellParser from pool final int length = mSpellParsers.length; diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index 9867e47..5164c7a 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -3176,22 +3176,19 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener if (text instanceof Spannable && !mAllowTransformationLengthChange) { Spannable sp = (Spannable) text; - // Remove any ChangeWatchers that might have come - // from other TextViews. + // Remove any ChangeWatchers that might have come from other TextViews. final ChangeWatcher[] watchers = sp.getSpans(0, sp.length(), ChangeWatcher.class); final int count = watchers.length; - for (int i = 0; i < count; i++) + for (int i = 0; i < count; i++) { sp.removeSpan(watchers[i]); + } - if (mChangeWatcher == null) - mChangeWatcher = new ChangeWatcher(); + if (mChangeWatcher == null) mChangeWatcher = new ChangeWatcher(); sp.setSpan(mChangeWatcher, 0, textLength, Spanned.SPAN_INCLUSIVE_INCLUSIVE | (CHANGE_WATCHER_PRIORITY << Spanned.SPAN_PRIORITY_SHIFT)); - if (mEditor != null && getEditor().mKeyListener != null) { - sp.setSpan(getEditor().mKeyListener, 0, textLength, Spanned.SPAN_INCLUSIVE_INCLUSIVE); - } + if (mEditor != null) mEditor.addSpanWatchers(sp); if (mTransformation != null) { sp.setSpan(mTransformation, 0, textLength, Spanned.SPAN_INCLUSIVE_INCLUSIVE); @@ -5231,7 +5228,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener */ public void setExtracting(ExtractedTextRequest req) { if (getEditor().mInputMethodState != null) { - getEditor().mInputMethodState.mExtracting = req; + getEditor().mInputMethodState.mExtractedTextRequest = req; } // This would stop a possible selection mode, but no such mode is started in case // extracted mode will start. Some text is selected though, and will trigger an action mode @@ -6876,7 +6873,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener if (what instanceof ParcelableSpan) { // If this is a span that can be sent to a remote process, // the current extract editor would be interested in it. - if (ims != null && ims.mExtracting != null) { + if (ims != null && ims.mExtractedTextRequest != null) { if (ims.mBatchEditNesting != 0) { if (oldStart >= 0) { if (ims.mChangedStart > oldStart) { @@ -6897,7 +6894,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } else { if (DEBUG_EXTRACT) Log.v(LOG_TAG, "Span change outside of batch: " + oldStart + "-" + oldEnd + "," - + newStart + "-" + newEnd + what); + + newStart + "-" + newEnd + " " + what); ims.mContentChanged = true; } } |