grouping separator preference

This commit is contained in:
serso
2011-10-23 16:05:40 +04:00
parent 114a301c64
commit 0afb2cd4d8
14 changed files with 155 additions and 39 deletions

View File

@@ -25,7 +25,7 @@ public class CalculatorDisplay extends TextView {
private boolean valid = true;
@NotNull
private final static TextProcessor<String> textHighlighter = new TextHighlighter(Color.WHITE);
private final static TextProcessor<TextHighlighter.Result> textHighlighter = new TextHighlighter(Color.WHITE);
public CalculatorDisplay(Context context) {
super(context);
@@ -61,7 +61,8 @@ public class CalculatorDisplay extends TextView {
Log.d(this.getClass().getName(), text);
try {
text = textHighlighter.process(text);
TextHighlighter.Result result = textHighlighter.process(text);
text = result.toString();
} catch (ParseException e) {
Log.e(this.getClass().getName(), e.getMessage(), e);
}

View File

@@ -26,7 +26,7 @@ public class CalculatorEditor extends EditText {
private boolean highlightText = true;
@NotNull
private final static TextProcessor<String> textHighlighter = new TextHighlighter(Color.WHITE);
private final static TextProcessor<TextHighlighter.Result> textHighlighter = new TextHighlighter(Color.WHITE);
public CalculatorEditor(Context context) {
super(context);
@@ -69,7 +69,10 @@ public class CalculatorEditor extends EditText {
Log.d(this.getClass().getName(), text);
try {
text = textHighlighter.process(text);
final TextHighlighter.Result result = textHighlighter.process(text);
selectionStart += result.getOffset();
selectionEnd += result.getOffset();
text = result.toString();
} catch (ParseException e) {
Log.e(this.getClass().getName(), e.getMessage(), e);
}

View File

@@ -11,13 +11,51 @@ import org.solovyev.android.calculator.math.MathType;
import org.solovyev.android.calculator.model.NumberBuilder;
import org.solovyev.android.calculator.model.ParseException;
import org.solovyev.android.calculator.model.TextProcessor;
import org.solovyev.common.utils.MutableObject;
/**
* User: serso
* Date: 10/12/11
* Time: 9:47 PM
*/
public class TextHighlighter implements TextProcessor<String> {
public class TextHighlighter implements TextProcessor<TextHighlighter.Result> {
public static class Result implements CharSequence {
@NotNull
private final String string;
private final int offset;
public Result(@NotNull String string, int offset) {
this.string = string;
this.offset = offset;
}
@Override
public int length() {
return string.length();
}
@Override
public char charAt(int i) {
return string.charAt(i);
}
@Override
public CharSequence subSequence(int i, int i1) {
return string.subSequence(i, i1);
}
@Override
public String toString() {
return string;
}
public int getOffset() {
return offset;
}
}
private final int color;
private final int colorRed;
@@ -36,7 +74,7 @@ public class TextHighlighter implements TextProcessor<String> {
@NotNull
@Override
public String process(@NotNull String text) throws ParseException {
public Result process(@NotNull String text) throws ParseException {
final String result;
int maxNumberOfOpenGroupSymbols = 0;
@@ -44,11 +82,15 @@ public class TextHighlighter implements TextProcessor<String> {
final StringBuilder text1 = new StringBuilder();
int numberOffset = 0;
final NumberBuilder numberBuilder = new NumberBuilder();
for (int i = 0; i < text.length(); i++) {
final MathType.Result mathType = MathType.getType(text, i);
MathType.Result mathType = MathType.getType(text, i);
numberBuilder.process(text1, mathType);
final MutableObject<Integer> localNumberOffset = new MutableObject<Integer>(0);
numberBuilder.process(text1, mathType, localNumberOffset);
numberOffset += localNumberOffset.getObject();
switch (mathType.getMathType()) {
case open_group_symbol:
@@ -71,7 +113,9 @@ public class TextHighlighter implements TextProcessor<String> {
}
}
numberBuilder.process(text1);
final MutableObject<Integer> localNumberOffset = new MutableObject<Integer>(0);
numberBuilder.process(text1, localNumberOffset);
numberOffset += localNumberOffset.getObject();
if (maxNumberOfOpenGroupSymbols > 0) {
@@ -90,7 +134,7 @@ public class TextHighlighter implements TextProcessor<String> {
result = text1.toString();
}
return result;
return new Result(result, numberOffset);
}
private int processHighlightedText(@NotNull StringBuilder result, int i, @NotNull String functionName, @NotNull String tag) {

View File

@@ -198,13 +198,21 @@ public enum MathType {
public int processToJscl(@NotNull StringBuilder result, int i, @NotNull String match) {
final String substitute = getSubstituteToJscl(match);
result.append(substitute == null ? match : substitute);
return i + match.length() - 1;
if (match.length() > 1) {
return i + match.length() - 1;
} else {
return i;
}
}
public int processFromJscl(@NotNull StringBuilder result, int i, @NotNull String match) {
final String substitute = getSubstituteFromJscl(match);
result.append(substitute == null ? match : substitute);
return i + match.length() - 1;
if (match.length() > 1) {
return i + match.length() - 1;
} else {
return i;
}
}
@Nullable

View File

@@ -20,6 +20,7 @@ import org.solovyev.common.msg.MessageType;
import org.solovyev.common.utils.CollectionsUtils;
import org.solovyev.common.utils.Formatter;
import org.solovyev.common.utils.MutableObject;
import org.solovyev.common.utils.StringUtils;
import java.math.BigDecimal;
import java.text.DecimalFormat;
@@ -40,6 +41,9 @@ public enum CalculatorEngine {
instance;
private static final String GROUPING_SEPARATOR_P_KEY = "org.solovyev.android.calculator.CalculatorActivity_calc_grouping_separator";
private static final String GROUPING_SEPARATOR_DEFAULT = " ";
private static final String RESULT_PRECISION_P_KEY = "org.solovyev.android.calculator.CalculatorModel_result_precision";
private static final String RESULT_PRECISION_DEFAULT = "5";
@@ -62,6 +66,12 @@ public enum CalculatorEngine {
@NotNull
private DecimalFormatSymbols decimalGroupSymbols = new DecimalFormatSymbols(Locale.getDefault());
{
decimalGroupSymbols.setDecimalSeparator('.');
decimalGroupSymbols.setGroupingSeparator(GROUPING_SEPARATOR_DEFAULT.charAt(0));
}
private boolean useGroupingSeparator = true;
@NotNull
private ThreadKiller threadKiller = new AndroidThreadKiller();
@@ -71,7 +81,7 @@ public enum CalculatorEngine {
if (!value.isInfinite() && !value.isNaN()) {
final DecimalFormat df = new DecimalFormat();
df.setDecimalFormatSymbols(decimalGroupSymbols);
df.setGroupingUsed(true);
df.setGroupingUsed(useGroupingSeparator);
df.setMaximumFractionDigits(instance.getPrecision());
return df.format(new BigDecimal(value).setScale(instance.getPrecision(), BigDecimal.ROUND_HALF_UP).doubleValue());
} else {
@@ -79,11 +89,6 @@ public enum CalculatorEngine {
}
}
{
decimalGroupSymbols.setDecimalSeparator('.');
decimalGroupSymbols.setGroupingSeparator(' ');
}
public String evaluate(@NotNull JsclOperation operation,
@NotNull String expression) throws EvalError, ParseException {
return evaluate(operation, expression, null);
@@ -201,6 +206,14 @@ public enum CalculatorEngine {
final NumberMapper<Integer> integerNumberMapper = new NumberMapper<Integer>(Integer.class);
//noinspection ConstantConditions
this.setPrecision(integerNumberMapper.parseValue(preferences.getString(RESULT_PRECISION_P_KEY, RESULT_PRECISION_DEFAULT)));
final String groupingSeparator = preferences.getString(GROUPING_SEPARATOR_P_KEY, GROUPING_SEPARATOR_DEFAULT);
if (StringUtils.isEmpty(groupingSeparator)) {
this.useGroupingSeparator = false;
} else {
this.useGroupingSeparator = true;
this.decimalGroupSymbols.setGroupingSeparator(groupingSeparator.charAt(0));
}
}
varsRegister.init(context, preferences);
@@ -218,7 +231,8 @@ public enum CalculatorEngine {
}
}
public void setDecimalGroupSymbols(@NotNull DecimalFormatSymbols decimalGroupSymbols) {
//for tests only
void setDecimalGroupSymbols(@NotNull DecimalFormatSymbols decimalGroupSymbols) {
synchronized (lock) {
this.decimalGroupSymbols = decimalGroupSymbols;
}

View File

@@ -14,7 +14,6 @@ import java.util.List;
*/
public class FromJsclSimplifyTextProcessor implements TextProcessor<String> {
@NotNull
@Override
public String process(@NotNull String s) throws ParseException {
@@ -27,14 +26,14 @@ public class FromJsclSimplifyTextProcessor implements TextProcessor<String> {
continue;
}
final MathType.Result mathTypeResult = MathType.getType(s, i);
MathType.Result mathTypeResult = MathType.getType(s, i);
numberBuilder.process(sb, mathTypeResult);
numberBuilder.process(sb, mathTypeResult, null);
i = mathTypeResult.processFromJscl(sb, i);
}
numberBuilder.process(sb);
numberBuilder.process(sb, null);
return removeMultiplicationSigns(sb.toString());
}

View File

@@ -11,6 +11,7 @@ import org.jetbrains.annotations.Nullable;
import org.solovyev.android.calculator.math.MathType;
import org.solovyev.common.utils.CollectionsUtils;
import org.solovyev.common.utils.Finder;
import org.solovyev.common.utils.MutableObject;
/**
* User: serso
@@ -24,21 +25,28 @@ public class NumberBuilder {
@Nullable
private String number = null;
public void process(@NotNull StringBuilder sb, @NotNull MathType.Result mathTypeResult) {
@NotNull
public MathType.Result process(@NotNull StringBuilder sb, @NotNull MathType.Result mathTypeResult, @Nullable MutableObject<Integer> numberOffset) {
number = null;
final MathType.Result possibleResult;
if (mathTypeResult.getMathType() == MathType.digit || mathTypeResult.getMathType() == MathType.dot || mathTypeResult.getMathType() == MathType.power_10) {
if (numberBuilder == null) {
numberBuilder = new StringBuilder();
}
numberBuilder.append(mathTypeResult.getMatch());
replaceSystemVars(sb, number);
possibleResult = replaceSystemVars(sb, number, numberOffset);
} else {
process(sb);
possibleResult = process(sb, numberOffset);
}
return possibleResult == null ? mathTypeResult : possibleResult;
}
public void process(@NotNull StringBuilder sb) {
@Nullable
public MathType.Result process(@NotNull StringBuilder sb, @Nullable MutableObject<Integer> numberOffset) {
if (numberBuilder != null) {
try {
number = numberBuilder.toString();
@@ -52,12 +60,12 @@ public class NumberBuilder {
number = null;
}
replaceSystemVars(sb, number);
return replaceSystemVars(sb, number, numberOffset);
}
@Nullable
private MathType replaceSystemVars(StringBuilder sb, String number) {
MathType result = null;
private MathType.Result replaceSystemVars(StringBuilder sb, String number, @Nullable MutableObject<Integer> numberOffset) {
MathType.Result result = null;
if (number != null) {
final String finalNumber = number;
@@ -71,10 +79,14 @@ public class NumberBuilder {
if (var != null) {
sb.delete(sb.length() - number.length(), sb.length());
sb.append(var.getName());
result = MathType.constant;
result = new MathType.Result(MathType.constant, var.getName());
} else {
sb.delete(sb.length() - number.length(), sb.length());
sb.append(CalculatorEngine.instance.format(Double.valueOf(number)));
final String formattedNumber = CalculatorEngine.instance.format(Double.valueOf(number));
if ( numberOffset != null ) {
numberOffset.setObject(formattedNumber.length() - number.length());
}
sb.append(formattedNumber);
}
}