12995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard/*
22995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard * Copyright (C) 2013 The Android Open Source Project
32995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard *
42995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard * Licensed under the Apache License, Version 2.0 (the "License"); you may not
52995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard * use this file except in compliance with the License. You may obtain a copy of
62995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard * the License at
72995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard *
82995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard * http://www.apache.org/licenses/LICENSE-2.0
92995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard *
102995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard * Unless required by applicable law or agreed to in writing, software
112995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
122995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
132995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard * License for the specific language governing permissions and limitations under
142995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard * the License.
152995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard */
162995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard
17e28eba5074664d5716b8e58b8d0a235746b261ebKen Wakasapackage com.android.inputmethod.latin.utils;
182995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard
194beeb9253a06482299e0c67467531d30436a02fcJean Chalardimport com.android.inputmethod.latin.common.StringUtils;
204beeb9253a06482299e0c67467531d30436a02fcJean Chalard
212995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalardimport java.util.Locale;
222995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard
232995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard/**
242995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard * The status of the current recapitalize process.
252995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard */
262995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalardpublic class RecapitalizeStatus {
278094bf45d73a5f7257076afc97d91d6708ee03c4Jean Chalard    public static final int NOT_A_RECAPITALIZE_MODE = -1;
282995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard    public static final int CAPS_MODE_ORIGINAL_MIXED_CASE = 0;
292995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard    public static final int CAPS_MODE_ALL_LOWER = 1;
302995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard    public static final int CAPS_MODE_FIRST_WORD_UPPER = 2;
312995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard    public static final int CAPS_MODE_ALL_UPPER = 3;
322995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard    // When adding a new mode, don't forget to update the CAPS_MODE_LAST constant.
332995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard    public static final int CAPS_MODE_LAST = CAPS_MODE_ALL_UPPER;
342995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard
352995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard    private static final int[] ROTATION_STYLE = {
362995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard        CAPS_MODE_ORIGINAL_MIXED_CASE,
372995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard        CAPS_MODE_ALL_LOWER,
382995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard        CAPS_MODE_FIRST_WORD_UPPER,
392995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard        CAPS_MODE_ALL_UPPER
402995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard    };
41b794e904a3586ac5f2d31fb24d5a1a8f9aa964b8Jean Chalard
42c93cf1c398fbea8bde4b568dae1fbe2f8d9b4180Tadashi G. Takaoka    private static final int getStringMode(final String string, final int[] sortedSeparators) {
432995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard        if (StringUtils.isIdenticalAfterUpcase(string)) {
442995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard            return CAPS_MODE_ALL_UPPER;
452995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard        } else if (StringUtils.isIdenticalAfterDowncase(string)) {
462995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard            return CAPS_MODE_ALL_LOWER;
47c93cf1c398fbea8bde4b568dae1fbe2f8d9b4180Tadashi G. Takaoka        } else if (StringUtils.isIdenticalAfterCapitalizeEachWord(string, sortedSeparators)) {
482995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard            return CAPS_MODE_FIRST_WORD_UPPER;
492995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard        } else {
502995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard            return CAPS_MODE_ORIGINAL_MIXED_CASE;
512995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard        }
522995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard    }
532995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard
549dc3ae84eecb8adbcac7d31a5ceab1d3ab95cd53Tadashi G. Takaoka    public static String modeToString(final int recapitalizeMode) {
559dc3ae84eecb8adbcac7d31a5ceab1d3ab95cd53Tadashi G. Takaoka        switch (recapitalizeMode) {
569dc3ae84eecb8adbcac7d31a5ceab1d3ab95cd53Tadashi G. Takaoka        case NOT_A_RECAPITALIZE_MODE: return "undefined";
579dc3ae84eecb8adbcac7d31a5ceab1d3ab95cd53Tadashi G. Takaoka        case CAPS_MODE_ORIGINAL_MIXED_CASE: return "mixedCase";
589dc3ae84eecb8adbcac7d31a5ceab1d3ab95cd53Tadashi G. Takaoka        case CAPS_MODE_ALL_LOWER: return "allLower";
599dc3ae84eecb8adbcac7d31a5ceab1d3ab95cd53Tadashi G. Takaoka        case CAPS_MODE_FIRST_WORD_UPPER: return "firstWordUpper";
609dc3ae84eecb8adbcac7d31a5ceab1d3ab95cd53Tadashi G. Takaoka        case CAPS_MODE_ALL_UPPER: return "allUpper";
619dc3ae84eecb8adbcac7d31a5ceab1d3ab95cd53Tadashi G. Takaoka        default: return "unknown<" + recapitalizeMode + ">";
629dc3ae84eecb8adbcac7d31a5ceab1d3ab95cd53Tadashi G. Takaoka        }
639dc3ae84eecb8adbcac7d31a5ceab1d3ab95cd53Tadashi G. Takaoka    }
649dc3ae84eecb8adbcac7d31a5ceab1d3ab95cd53Tadashi G. Takaoka
652995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard    /**
66b794e904a3586ac5f2d31fb24d5a1a8f9aa964b8Jean Chalard     * We store the location of the cursor and the string that was there before the recapitalize
672995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard     * action was done, and the location of the cursor and the string that was there after.
682995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard     */
692995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard    private int mCursorStartBefore;
702995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard    private String mStringBefore;
712995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard    private int mCursorStartAfter;
722995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard    private int mCursorEndAfter;
732995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard    private int mRotationStyleCurrentIndex;
74b794e904a3586ac5f2d31fb24d5a1a8f9aa964b8Jean Chalard    private boolean mSkipOriginalMixedCaseMode;
75b794e904a3586ac5f2d31fb24d5a1a8f9aa964b8Jean Chalard    private Locale mLocale;
76c93cf1c398fbea8bde4b568dae1fbe2f8d9b4180Tadashi G. Takaoka    private int[] mSortedSeparators;
772995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard    private String mStringAfter;
784a1113b6b065931322df8bba375864274a898acfJean Chalard    private boolean mIsStarted;
79c84b10840e1439a0432dc92cca29a5f6af1646fbJean Chalard    private boolean mIsEnabled = true;
80b794e904a3586ac5f2d31fb24d5a1a8f9aa964b8Jean Chalard
81c93cf1c398fbea8bde4b568dae1fbe2f8d9b4180Tadashi G. Takaoka    private static final int[] EMPTY_STORTED_SEPARATORS = {};
82c93cf1c398fbea8bde4b568dae1fbe2f8d9b4180Tadashi G. Takaoka
83b794e904a3586ac5f2d31fb24d5a1a8f9aa964b8Jean Chalard    public RecapitalizeStatus() {
84b794e904a3586ac5f2d31fb24d5a1a8f9aa964b8Jean Chalard        // By default, initialize with dummy values that won't match any real recapitalize.
854a1113b6b065931322df8bba375864274a898acfJean Chalard        start(-1, -1, "", Locale.getDefault(), EMPTY_STORTED_SEPARATORS);
864a1113b6b065931322df8bba375864274a898acfJean Chalard        stop();
87b794e904a3586ac5f2d31fb24d5a1a8f9aa964b8Jean Chalard    }
882995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard
894a1113b6b065931322df8bba375864274a898acfJean Chalard    public void start(final int cursorStart, final int cursorEnd, final String string,
90c93cf1c398fbea8bde4b568dae1fbe2f8d9b4180Tadashi G. Takaoka            final Locale locale, final int[] sortedSeparators) {
91c84b10840e1439a0432dc92cca29a5f6af1646fbJean Chalard        if (!mIsEnabled) {
92c84b10840e1439a0432dc92cca29a5f6af1646fbJean Chalard            return;
93c84b10840e1439a0432dc92cca29a5f6af1646fbJean Chalard        }
942995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard        mCursorStartBefore = cursorStart;
952995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard        mStringBefore = string;
962995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard        mCursorStartAfter = cursorStart;
972995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard        mCursorEndAfter = cursorEnd;
982995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard        mStringAfter = string;
99c93cf1c398fbea8bde4b568dae1fbe2f8d9b4180Tadashi G. Takaoka        final int initialMode = getStringMode(mStringBefore, sortedSeparators);
1002995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard        mLocale = locale;
101c93cf1c398fbea8bde4b568dae1fbe2f8d9b4180Tadashi G. Takaoka        mSortedSeparators = sortedSeparators;
1022995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard        if (CAPS_MODE_ORIGINAL_MIXED_CASE == initialMode) {
1032995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard            mRotationStyleCurrentIndex = 0;
1042995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard            mSkipOriginalMixedCaseMode = false;
1052995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard        } else {
1062995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard            // Find the current mode in the array.
1072995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard            int currentMode;
1082995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard            for (currentMode = ROTATION_STYLE.length - 1; currentMode > 0; --currentMode) {
1092995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard                if (ROTATION_STYLE[currentMode] == initialMode) {
1102995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard                    break;
1112995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard                }
1122995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard            }
1132995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard            mRotationStyleCurrentIndex = currentMode;
1142995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard            mSkipOriginalMixedCaseMode = true;
1152995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard        }
1164a1113b6b065931322df8bba375864274a898acfJean Chalard        mIsStarted = true;
117b794e904a3586ac5f2d31fb24d5a1a8f9aa964b8Jean Chalard    }
118b794e904a3586ac5f2d31fb24d5a1a8f9aa964b8Jean Chalard
1194a1113b6b065931322df8bba375864274a898acfJean Chalard    public void stop() {
1204a1113b6b065931322df8bba375864274a898acfJean Chalard        mIsStarted = false;
121b794e904a3586ac5f2d31fb24d5a1a8f9aa964b8Jean Chalard    }
122b794e904a3586ac5f2d31fb24d5a1a8f9aa964b8Jean Chalard
1234a1113b6b065931322df8bba375864274a898acfJean Chalard    public boolean isStarted() {
1244a1113b6b065931322df8bba375864274a898acfJean Chalard        return mIsStarted;
1252995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard    }
1262995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard
127c84b10840e1439a0432dc92cca29a5f6af1646fbJean Chalard    public void enable() {
128c84b10840e1439a0432dc92cca29a5f6af1646fbJean Chalard        mIsEnabled = true;
129c84b10840e1439a0432dc92cca29a5f6af1646fbJean Chalard    }
130c84b10840e1439a0432dc92cca29a5f6af1646fbJean Chalard
131c84b10840e1439a0432dc92cca29a5f6af1646fbJean Chalard    public void disable() {
132c84b10840e1439a0432dc92cca29a5f6af1646fbJean Chalard        mIsEnabled = false;
133c84b10840e1439a0432dc92cca29a5f6af1646fbJean Chalard    }
134c84b10840e1439a0432dc92cca29a5f6af1646fbJean Chalard
135c84b10840e1439a0432dc92cca29a5f6af1646fbJean Chalard    public boolean mIsEnabled() {
136c84b10840e1439a0432dc92cca29a5f6af1646fbJean Chalard        return mIsEnabled;
137c84b10840e1439a0432dc92cca29a5f6af1646fbJean Chalard    }
138c84b10840e1439a0432dc92cca29a5f6af1646fbJean Chalard
1392995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard    public boolean isSetAt(final int cursorStart, final int cursorEnd) {
1402995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard        return cursorStart == mCursorStartAfter && cursorEnd == mCursorEndAfter;
1412995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard    }
1422995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard
1432995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard    /**
1442995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard     * Rotate through the different possible capitalization modes.
1452995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard     */
1462995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard    public void rotate() {
1472995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard        final String oldResult = mStringAfter;
1482995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard        int count = 0; // Protection against infinite loop.
1492995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard        do {
1502995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard            mRotationStyleCurrentIndex = (mRotationStyleCurrentIndex + 1) % ROTATION_STYLE.length;
1512995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard            if (CAPS_MODE_ORIGINAL_MIXED_CASE == ROTATION_STYLE[mRotationStyleCurrentIndex]
1522995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard                    && mSkipOriginalMixedCaseMode) {
1532995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard                mRotationStyleCurrentIndex =
1542995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard                        (mRotationStyleCurrentIndex + 1) % ROTATION_STYLE.length;
1552995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard            }
1562995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard            ++count;
1572995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard            switch (ROTATION_STYLE[mRotationStyleCurrentIndex]) {
158b794e904a3586ac5f2d31fb24d5a1a8f9aa964b8Jean Chalard            case CAPS_MODE_ORIGINAL_MIXED_CASE:
159b794e904a3586ac5f2d31fb24d5a1a8f9aa964b8Jean Chalard                mStringAfter = mStringBefore;
160b794e904a3586ac5f2d31fb24d5a1a8f9aa964b8Jean Chalard                break;
161b794e904a3586ac5f2d31fb24d5a1a8f9aa964b8Jean Chalard            case CAPS_MODE_ALL_LOWER:
162b794e904a3586ac5f2d31fb24d5a1a8f9aa964b8Jean Chalard                mStringAfter = mStringBefore.toLowerCase(mLocale);
163b794e904a3586ac5f2d31fb24d5a1a8f9aa964b8Jean Chalard                break;
164b794e904a3586ac5f2d31fb24d5a1a8f9aa964b8Jean Chalard            case CAPS_MODE_FIRST_WORD_UPPER:
165c93cf1c398fbea8bde4b568dae1fbe2f8d9b4180Tadashi G. Takaoka                mStringAfter = StringUtils.capitalizeEachWord(mStringBefore, mSortedSeparators,
166b794e904a3586ac5f2d31fb24d5a1a8f9aa964b8Jean Chalard                        mLocale);
167b794e904a3586ac5f2d31fb24d5a1a8f9aa964b8Jean Chalard                break;
168b794e904a3586ac5f2d31fb24d5a1a8f9aa964b8Jean Chalard            case CAPS_MODE_ALL_UPPER:
169b794e904a3586ac5f2d31fb24d5a1a8f9aa964b8Jean Chalard                mStringAfter = mStringBefore.toUpperCase(mLocale);
170b794e904a3586ac5f2d31fb24d5a1a8f9aa964b8Jean Chalard                break;
171b794e904a3586ac5f2d31fb24d5a1a8f9aa964b8Jean Chalard            default:
172b794e904a3586ac5f2d31fb24d5a1a8f9aa964b8Jean Chalard                mStringAfter = mStringBefore;
1732995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard            }
174b794e904a3586ac5f2d31fb24d5a1a8f9aa964b8Jean Chalard        } while (mStringAfter.equals(oldResult) && count < ROTATION_STYLE.length + 1);
1752995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard        mCursorEndAfter = mCursorStartAfter + mStringAfter.length();
1762995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard    }
1772995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard
1782995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard    /**
1792995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard     * Remove leading/trailing whitespace from the considered string.
1802995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard     */
1812995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard    public void trim() {
1822995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard        final int len = mStringBefore.length();
1832995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard        int nonWhitespaceStart = 0;
1842995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard        for (; nonWhitespaceStart < len;
1852995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard                nonWhitespaceStart = mStringBefore.offsetByCodePoints(nonWhitespaceStart, 1)) {
1862995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard            final int codePoint = mStringBefore.codePointAt(nonWhitespaceStart);
1872995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard            if (!Character.isWhitespace(codePoint)) break;
1882995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard        }
1892995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard        int nonWhitespaceEnd = len;
1902995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard        for (; nonWhitespaceEnd > 0;
1912995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard                nonWhitespaceEnd = mStringBefore.offsetByCodePoints(nonWhitespaceEnd, -1)) {
1922995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard            final int codePoint = mStringBefore.codePointBefore(nonWhitespaceEnd);
1932995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard            if (!Character.isWhitespace(codePoint)) break;
1942995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard        }
1952a81943d162383cc6e9d9429bf3f7949c994a8baJean Chalard        // If nonWhitespaceStart >= nonWhitespaceEnd, that means the selection contained only
1962a81943d162383cc6e9d9429bf3f7949c994a8baJean Chalard        // whitespace, so we leave it as is.
1972a81943d162383cc6e9d9429bf3f7949c994a8baJean Chalard        if ((0 != nonWhitespaceStart || len != nonWhitespaceEnd)
1982a81943d162383cc6e9d9429bf3f7949c994a8baJean Chalard                && nonWhitespaceStart < nonWhitespaceEnd) {
199b794e904a3586ac5f2d31fb24d5a1a8f9aa964b8Jean Chalard            mCursorEndAfter = mCursorStartBefore + nonWhitespaceEnd;
2002995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard            mCursorStartBefore = mCursorStartAfter = mCursorStartBefore + nonWhitespaceStart;
2012995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard            mStringAfter = mStringBefore =
2022995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard                    mStringBefore.substring(nonWhitespaceStart, nonWhitespaceEnd);
2032995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard        }
2042995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard    }
2052995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard
2062995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard    public String getRecapitalizedString() {
2072995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard        return mStringAfter;
2082995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard    }
2092995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard
2102995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard    public int getNewCursorStart() {
2112995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard        return mCursorStartAfter;
2122995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard    }
2132995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard
2142995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard    public int getNewCursorEnd() {
2152995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard        return mCursorEndAfter;
2162995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard    }
2178094bf45d73a5f7257076afc97d91d6708ee03c4Jean Chalard
2188094bf45d73a5f7257076afc97d91d6708ee03c4Jean Chalard    public int getCurrentMode() {
2198094bf45d73a5f7257076afc97d91d6708ee03c4Jean Chalard        return ROTATION_STYLE[mRotationStyleCurrentIndex];
2208094bf45d73a5f7257076afc97d91d6708ee03c4Jean Chalard    }
2212995abe7aadd483aa57a9b088740d46ac07bbe46Jean Chalard}
222