Loading core/java/android/widget/Editor.java +24 −12 Original line number Diff line number Diff line Loading @@ -2395,6 +2395,8 @@ public class Editor { dragSourceEnd += shift; } mUndoInputFilter.setForceMerge(true); try { // Delete original selection mTextView.deleteText_internal(dragSourceStart, dragSourceEnd); Loading @@ -2407,6 +2409,9 @@ public class Editor { mTextView.deleteText_internal(prevCharIdx, prevCharIdx + 1); } } } finally { mUndoInputFilter.setForceMerge(false); } } } Loading Loading @@ -5497,6 +5502,9 @@ public class Editor { // rotates the screen during composition. private boolean mHasComposition; // Whether to merge events into one operation. private boolean mForceMerge; public UndoInputFilter(Editor editor) { mEditor = editor; } Loading @@ -5511,6 +5519,10 @@ public class Editor { mHasComposition = parcel.readInt() != 0; } public void setForceMerge(boolean forceMerge) { mForceMerge = forceMerge; } /** * Signals that a user-triggered edit is starting. */ Loading Loading @@ -5570,7 +5582,7 @@ public class Editor { // Otherwise the user inserted the composition. String newText = TextUtils.substring(source, start, end); EditOperation edit = new EditOperation(mEditor, "", dstart, newText); recordEdit(edit, false /* forceMerge */); recordEdit(edit, mForceMerge); return true; } Loading @@ -5584,7 +5596,7 @@ public class Editor { // the initial input filters run (e.g. a credit card formatter that adds spaces to a // string). This results in multiple filter() calls for what the user considers to be // a single operation. Always undo the whole set of changes in one step. final boolean forceMerge = isInTextWatcher(); final boolean forceMerge = mForceMerge || isInTextWatcher(); // Build a new operation with all the information from this edit. String newText = TextUtils.substring(source, start, end); Loading core/tests/coretests/src/android/widget/TextViewActivityTest.java +7 −0 Original line number Diff line number Diff line Loading @@ -44,6 +44,7 @@ import static android.support.test.espresso.matcher.ViewMatchers.withText; import com.android.frameworks.coretests.R; import android.support.test.espresso.action.EspressoKey; import android.test.ActivityInstrumentationTestCase2; import android.test.suitebuilder.annotation.SmallTest; import android.view.KeyEvent; Loading Loading @@ -172,6 +173,12 @@ public class TextViewActivityTest extends ActivityInstrumentationTestCase2<TextV onView(withId(R.id.textview)).check(hasSelection("")); assertNoSelectionHandles(); onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex("abc ghi.def".length())); // Test undo returns to the original state. onView(withId(R.id.textview)).perform(pressKey( (new EspressoKey.Builder()).withCtrlPressed(true).withKeyCode(KeyEvent.KEYCODE_Z) .build())); onView(withId(R.id.textview)).check(matches(withText(text))); } @SmallTest Loading Loading
core/java/android/widget/Editor.java +24 −12 Original line number Diff line number Diff line Loading @@ -2395,6 +2395,8 @@ public class Editor { dragSourceEnd += shift; } mUndoInputFilter.setForceMerge(true); try { // Delete original selection mTextView.deleteText_internal(dragSourceStart, dragSourceEnd); Loading @@ -2407,6 +2409,9 @@ public class Editor { mTextView.deleteText_internal(prevCharIdx, prevCharIdx + 1); } } } finally { mUndoInputFilter.setForceMerge(false); } } } Loading Loading @@ -5497,6 +5502,9 @@ public class Editor { // rotates the screen during composition. private boolean mHasComposition; // Whether to merge events into one operation. private boolean mForceMerge; public UndoInputFilter(Editor editor) { mEditor = editor; } Loading @@ -5511,6 +5519,10 @@ public class Editor { mHasComposition = parcel.readInt() != 0; } public void setForceMerge(boolean forceMerge) { mForceMerge = forceMerge; } /** * Signals that a user-triggered edit is starting. */ Loading Loading @@ -5570,7 +5582,7 @@ public class Editor { // Otherwise the user inserted the composition. String newText = TextUtils.substring(source, start, end); EditOperation edit = new EditOperation(mEditor, "", dstart, newText); recordEdit(edit, false /* forceMerge */); recordEdit(edit, mForceMerge); return true; } Loading @@ -5584,7 +5596,7 @@ public class Editor { // the initial input filters run (e.g. a credit card formatter that adds spaces to a // string). This results in multiple filter() calls for what the user considers to be // a single operation. Always undo the whole set of changes in one step. final boolean forceMerge = isInTextWatcher(); final boolean forceMerge = mForceMerge || isInTextWatcher(); // Build a new operation with all the information from this edit. String newText = TextUtils.substring(source, start, end); Loading
core/tests/coretests/src/android/widget/TextViewActivityTest.java +7 −0 Original line number Diff line number Diff line Loading @@ -44,6 +44,7 @@ import static android.support.test.espresso.matcher.ViewMatchers.withText; import com.android.frameworks.coretests.R; import android.support.test.espresso.action.EspressoKey; import android.test.ActivityInstrumentationTestCase2; import android.test.suitebuilder.annotation.SmallTest; import android.view.KeyEvent; Loading Loading @@ -172,6 +173,12 @@ public class TextViewActivityTest extends ActivityInstrumentationTestCase2<TextV onView(withId(R.id.textview)).check(hasSelection("")); assertNoSelectionHandles(); onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex("abc ghi.def".length())); // Test undo returns to the original state. onView(withId(R.id.textview)).perform(pressKey( (new EspressoKey.Builder()).withCtrlPressed(true).withKeyCode(KeyEvent.KEYCODE_Z) .build())); onView(withId(R.id.textview)).check(matches(withText(text))); } @SmallTest Loading