Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 24a929d7 authored by Hans Boehm's avatar Hans Boehm Committed by Android Git Automerger
Browse files

am fc231ad6: am 70f49ecd: am 9d75c1ac: am 8a4f81c5: More correctly pronounce...

am fc231ad6: am 70f49ecd: am 9d75c1ac: am 8a4f81c5: More correctly pronounce advanced operators in Talkback

* commit 'fc231ad6':
  More correctly pronounce advanced operators in Talkback
parents fa234632 fc231ad6
Loading
Loading
Loading
Loading
+13 −14
Original line number Diff line number Diff line
@@ -14,8 +14,6 @@
 * limitations under the License.
 */

// TODO: Better indication of when the result is known to be exact.
// TODO: Check and possibly fix accessability issues.
// TODO: Copy & more general paste in formula?  Note that this requires
//       great care: Currently the text version of a displayed formula
//       is not directly useful for re-evaluating the formula later, since
@@ -44,8 +42,10 @@ import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.view.ViewPager;
import android.text.SpannableString;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.style.ForegroundColorSpan;
import android.text.TextUtils;
import android.util.Property;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;
@@ -210,9 +210,13 @@ public class Calculator extends Activity
    private View mCurrentButton;
    private Animator mCurrentAnimator;

    private String mUnprocessedChars = null;   // Characters that were recently entered
                                               // at the end of the display that have not yet
    // Characters that were recently entered at the end of the display that have not yet
    // been added to the underlying expression.
    private String mUnprocessedChars = null;

    // Color to highlight unprocessed characters from physical keyboard.
    // TODO: should probably match this to the error color?
    private ForegroundColorSpan mUnprocessedColorSpan = new ForegroundColorSpan(Color.RED);

    @Override
    protected void onCreate(Bundle savedInstanceState) {
@@ -536,18 +540,13 @@ public class Calculator extends Activity
    }

    void redisplayFormula() {
        String formula = mEvaluator.getExpr().toString(this);
        SpannableStringBuilder formula = mEvaluator.getExpr().toSpannableStringBuilder(this);
        if (mUnprocessedChars != null) {
            // Add and highlight characters we couldn't process.
            SpannableString formatted = new SpannableString(formula + mUnprocessedChars);
            // TODO: should probably match this to the error color.
            formatted.setSpan(new ForegroundColorSpan(Color.RED),
                              formula.length(), formatted.length(),
            formula.append(mUnprocessedChars, mUnprocessedColorSpan,
                    Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            mFormulaText.changeTextTo(formatted);
        } else {
            mFormulaText.changeTextTo(formula);
        }
        mFormulaText.changeTextTo(formula);
    }

    @Override
+33 −12
Original line number Diff line number Diff line
@@ -21,6 +21,11 @@ import com.hp.creals.CR;
import com.hp.creals.UnaryCRFunction;

import android.content.Context;
import android.text.SpannableString;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.style.TtsSpan;
import android.text.style.TtsSpan.TextBuilder;
import android.util.Log;

import java.math.BigInteger;
@@ -46,11 +51,19 @@ class CalculatorExpr {

    private static abstract class Token {
        abstract TokenKind kind();

        /**
         * Write kind as Byte followed by data needed by subclass constructor.
         */
        abstract void write(DataOutput out) throws IOException;
                // Implementation writes kind as Byte followed by
                // data read by constructor.
        abstract String toString(Context context);
                // We need the context to convert button ids to strings.

        /**
         * Return a textual representation of the token.
         * The result is suitable for either display as part od the formula or TalkBack use.
         * It may be a SpannableString that includes added TalkBack information.
         * @param context context used for converting button ids to strings
         */
        abstract CharSequence toCharSequence(Context context);
    }

    // An operator token
@@ -68,9 +81,17 @@ class CalculatorExpr {
            out.writeInt(mId);
        }
        @Override
        public String toString(Context context) {
        public CharSequence toCharSequence(Context context) {
            String desc = KeyMaps.toDescriptiveString(context, mId);
            if (desc != null) {
                SpannableString result = new SpannableString(KeyMaps.toString(context, mId));
                Object descSpan = new TtsSpan.TextBuilder(desc).build();
                result.setSpan(descSpan, 0, result.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                return result;
            } else {
                return KeyMaps.toString(context, mId);
            }
        }
        @Override
        TokenKind kind() { return TokenKind.OPERATOR; }
    }
@@ -193,7 +214,7 @@ class CalculatorExpr {
        }

        @Override
        String toString(Context context) {
        CharSequence toCharSequence(Context context) {
            return toString();
        }

@@ -323,7 +344,7 @@ class CalculatorExpr {
            }
        }
        @Override
        String toString(Context context) {
        CharSequence toCharSequence(Context context) {
            return KeyMaps.translateResult(mShortRep);
        }
        @Override
@@ -1019,11 +1040,11 @@ class CalculatorExpr {
    }

    // Produce a string representation of the expression itself
    String toString(Context context) {
        StringBuilder sb = new StringBuilder();
    SpannableStringBuilder toSpannableStringBuilder(Context context) {
        SpannableStringBuilder ssb = new SpannableStringBuilder();
        for (Token t: mExpr) {
            sb.append(t.toString(context));
            ssb.append(t.toCharSequence(context));
        }
        return sb.toString();
        return ssb;
    }
}
+15 −4
Original line number Diff line number Diff line
@@ -224,11 +224,22 @@ public class CalculatorText extends AlignedTextView implements View.OnLongClickL
     * Otherwise, e.g. after deletion, announce the entire new text.
     */
    public void changeTextTo(CharSequence newText) {
        CharSequence oldText = getText();
        final CharSequence oldText = getText();
        if (startsWith(newText, oldText)) {
            int newLen = newText.length();
            int oldLen = oldText.length();
            if (oldLen != newLen) {
            final int newLen = newText.length();
            final int oldLen = oldText.length();
            if (newLen == oldLen + 1) {
                // The algorithm for pronouncing a single character doesn't seem
                // to respect our hints.  Don't give it the choice.
                final char c = newText.charAt(oldLen);
                final int id = KeyMaps.keyForChar(c);
                final String descr = KeyMaps.toDescriptiveString(getContext(), id);
                if (descr != null) {
                    announceForAccessibility(descr);
                } else {
                    announceForAccessibility(String.valueOf(c));
                }
            } else if (newLen > oldLen) {
                announceForAccessibility(newText.subSequence(oldLen, newLen));
            }
        } else {
+51 −0
Original line number Diff line number Diff line
@@ -114,6 +114,57 @@ public class KeyMaps {
        }
    }

    /**
     * Map key id to corresponding (internationalized) descriptive string that can be used
     * to correctly read back a formula.
     * Only used for operators and individual characters; not used inside constants.
     * Returns null when we don't need a descriptive string.
     * Pure function.
     */
    public static String toDescriptiveString(Context context, int id) {
        switch(id) {
            case R.id.op_fact:
                return context.getString(R.string.desc_op_fact);
            case R.id.fun_sin:
                return context.getString(R.string.desc_fun_sin)
                        + " " + context.getString(R.string.desc_lparen);
            case R.id.fun_cos:
                return context.getString(R.string.desc_fun_cos)
                        + " " + context.getString(R.string.desc_lparen);
            case R.id.fun_tan:
                return context.getString(R.string.desc_fun_tan)
                        + " " + context.getString(R.string.desc_lparen);
            case R.id.fun_arcsin:
                return context.getString(R.string.desc_fun_arcsin)
                        + " " + context.getString(R.string.desc_lparen);
            case R.id.fun_arccos:
                return context.getString(R.string.desc_fun_arccos)
                        + " " + context.getString(R.string.desc_lparen);
            case R.id.fun_arctan:
                return context.getString(R.string.desc_fun_arctan)
                        + " " + context.getString(R.string.desc_lparen);
            case R.id.fun_ln:
                return context.getString(R.string.desc_fun_ln)
                        + " " + context.getString(R.string.desc_lparen);
            case R.id.fun_log:
                return context.getString(R.string.desc_fun_log)
                        + " " + context.getString(R.string.desc_lparen);
            case R.id.fun_exp:
                return context.getString(R.string.desc_fun_exp)
                        + " " + context.getString(R.string.desc_lparen);
            case R.id.lparen:
                return context.getString(R.string.desc_lparen);
            case R.id.rparen:
                return context.getString(R.string.desc_rparen);
            case R.id.op_pow:
                return context.getString(R.string.desc_op_pow);
            case R.id.dec_point:
                return context.getString(R.string.desc_dec_point);
            default:
                return null;
        }
    }

    /**
     * Does a button id correspond to a binary operator?
     * Pure function.