From 7e26b3519948768b6c55caa56245e9153fca0b0f Mon Sep 17 00:00:00 2001 From: serso Date: Mon, 2 May 2016 14:20:27 +0200 Subject: [PATCH] Store grouping separator in integer preference and remove boolean from Engine --- .../solovyev/android/calculator/Engine.java | 22 ++++---- .../android/calculator/Preferences.java | 10 ++-- .../android/calculator/history/History.java | 15 +++--- .../preferences/NumberFormatPreference.java | 13 ++--- .../android/prefs/CharacterPreference.java | 27 ++++++++++ .../solovyev/android/calculator/Tests.java | 1 - jscl/src/main/java/jscl/JsclMathEngine.java | 53 +++++++++++-------- jscl/src/main/java/jscl/MathContext.java | 14 ++--- .../test/java/jscl/JsclMathEngineTest.java | 9 ++-- .../test/java/jscl/math/ExpressionTest.java | 32 ++++++----- 10 files changed, 119 insertions(+), 77 deletions(-) create mode 100644 app/src/main/java/org/solovyev/android/prefs/CharacterPreference.java diff --git a/app/src/main/java/org/solovyev/android/calculator/Engine.java b/app/src/main/java/org/solovyev/android/calculator/Engine.java index 2820e4a0..ae17c886 100644 --- a/app/src/main/java/org/solovyev/android/calculator/Engine.java +++ b/app/src/main/java/org/solovyev/android/calculator/Engine.java @@ -33,6 +33,7 @@ import org.solovyev.android.calculator.functions.FunctionsRegistry; import org.solovyev.android.calculator.operators.OperatorsRegistry; import org.solovyev.android.calculator.operators.PostfixFunctionsRegistry; import org.solovyev.android.prefs.BooleanPreference; +import org.solovyev.android.prefs.CharacterPreference; import org.solovyev.android.prefs.IntegerPreference; import org.solovyev.android.prefs.Preference; import org.solovyev.android.prefs.StringPreference; @@ -93,7 +94,7 @@ public class Engine implements SharedPreferences.OnSharedPreferenceChangeListene this.mathEngine = mathEngine; this.mathEngine.setRoundResult(true); - this.mathEngine.setUseGroupingSeparator(true); + this.mathEngine.setGroupingSeparator(JsclMathEngine.GROUPING_SEPARATOR_DEFAULT); } private static void migratePreference(@Nonnull SharedPreferences preferences, @Nonnull BooleanPreference preference, @Nonnull String oldKey, @Nonnull SharedPreferences.Editor editor) { @@ -110,6 +111,15 @@ public class Engine implements SharedPreferences.OnSharedPreferenceChangeListene editor.putString(preference.getKey(), preferences.getString(oldKey, null)); } + private static void migratePreference(@Nonnull SharedPreferences preferences, @Nonnull CharacterPreference preference, @Nonnull String oldKey, @Nonnull SharedPreferences.Editor editor) { + if (!preferences.contains(oldKey)) { + return; + } + final String s = preferences.getString(oldKey, null); + editor.putInt(preference.getKey(), TextUtils.isEmpty(s) ? 0 : s.charAt(0)); + } + + public static boolean isValidName(@Nullable String name) { if (!TextUtils.isEmpty(name)) { try { @@ -212,14 +222,8 @@ public class Engine implements SharedPreferences.OnSharedPreferenceChangeListene mathEngine.setPrecision(Preferences.Output.precision.getPreference(preferences)); mathEngine.setScienceNotation(Preferences.Output.scientificNotation.getPreference(preferences)); mathEngine.setRoundResult(Preferences.Output.round.getPreference(preferences)); + mathEngine.setGroupingSeparator(Preferences.Output.separator.getPreference(preferences)); - final String groupingSeparator = Preferences.Output.separator.getPreference(preferences); - if (TextUtils.isEmpty(groupingSeparator)) { - mathEngine.setUseGroupingSeparator(false); - } else { - mathEngine.setUseGroupingSeparator(true); - mathEngine.setGroupingSeparator(groupingSeparator.charAt(0)); - } bus.post(ChangedEvent.INSTANCE); } @@ -290,7 +294,7 @@ public class Engine implements SharedPreferences.OnSharedPreferenceChangeListene public static final BooleanPreference scientificNotation = BooleanPreference.of("engine.output.scientificNotation", false); public static final BooleanPreference round = BooleanPreference.of("engine.output.round", true); public static final StringPreference notation = StringPreference.ofEnum("engine.output.notation", Notation.dec, Notation.class); - public static final StringPreference separator = StringPreference.of("engine.output.separator", String.valueOf(JsclMathEngine.GROUPING_SEPARATOR_DEFAULT)); + public static final CharacterPreference separator = CharacterPreference.of("engine.output.separator", JsclMathEngine.GROUPING_SEPARATOR_DEFAULT); } } diff --git a/app/src/main/java/org/solovyev/android/calculator/Preferences.java b/app/src/main/java/org/solovyev/android/calculator/Preferences.java index ceb7629a..a51da55c 100644 --- a/app/src/main/java/org/solovyev/android/calculator/Preferences.java +++ b/app/src/main/java/org/solovyev/android/calculator/Preferences.java @@ -114,15 +114,15 @@ public final class Preferences { final Locale locale = Locale.getDefault(); if (locale != null) { final DecimalFormatSymbols decimalFormatSymbols = new DecimalFormatSymbols(locale); - int index = MathType.grouping_separator.getTokens().indexOf(String.valueOf(decimalFormatSymbols.getGroupingSeparator())); - final String groupingSeparator; + final int index = MathType.grouping_separator.getTokens().indexOf(String.valueOf(decimalFormatSymbols.getGroupingSeparator())); + final char separator; if (index >= 0) { - groupingSeparator = MathType.grouping_separator.getTokens().get(index); + separator = MathType.grouping_separator.getTokens().get(index).charAt(0); } else { - groupingSeparator = String.valueOf(JsclMathEngine.GROUPING_SEPARATOR_DEFAULT); + separator = JsclMathEngine.GROUPING_SEPARATOR_DEFAULT; } - Engine.Preferences.Output.separator.putPreference(editor, groupingSeparator); + Engine.Preferences.Output.separator.putPreference(editor, separator); } } diff --git a/app/src/main/java/org/solovyev/android/calculator/history/History.java b/app/src/main/java/org/solovyev/android/calculator/history/History.java index 16d5fbac..bb7ef9cf 100644 --- a/app/src/main/java/org/solovyev/android/calculator/history/History.java +++ b/app/src/main/java/org/solovyev/android/calculator/history/History.java @@ -125,15 +125,15 @@ public class History { private static boolean isIntermediate(@Nonnull String olderText, @Nonnull String newerText, - @NonNull String groupingSeparator) { + char separator) { if (TextUtils.isEmpty(olderText)) { return true; } if (TextUtils.isEmpty(newerText)) { return false; } - olderText = trimGroupingSeparators(olderText, groupingSeparator); - newerText = trimGroupingSeparators(newerText, groupingSeparator); + olderText = trimGroupingSeparators(olderText, separator); + newerText = trimGroupingSeparators(newerText, separator); final int diff = newerText.length() - olderText.length(); if (diff >= 1) { @@ -148,11 +148,10 @@ public class History { } @NonNull - static String trimGroupingSeparators(@NonNull String text, @NonNull String groupingSeparator) { - if (TextUtils.isEmpty(groupingSeparator)) { + static String trimGroupingSeparators(@NonNull String text, char separator) { + if (separator == 0) { return text; } - Check.isTrue(groupingSeparator.length() == 1); final StringBuilder sb = new StringBuilder(text.length()); for (int i = 0; i < text.length(); i++) { if (i == 0 || i == text.length() - 1) { @@ -160,7 +159,7 @@ public class History { sb.append(text.charAt(i)); continue; } - if (Character.isDigit(text.charAt(i - 1)) && text.charAt(i) == groupingSeparator.charAt(0) && Character.isDigit(text.charAt(i + 1))) { + if (Character.isDigit(text.charAt(i - 1)) && text.charAt(i) == separator && Character.isDigit(text.charAt(i + 1))) { // grouping separator => skip continue; } @@ -312,7 +311,7 @@ public class History { final List result = new LinkedList<>(); - final String separator = Preferences.Output.separator.getPreference(preferences); + final char separator = Preferences.Output.separator.getPreference(preferences); final List states = recent.asList(); final int statesCount = states.size(); diff --git a/app/src/main/java/org/solovyev/android/calculator/preferences/NumberFormatPreference.java b/app/src/main/java/org/solovyev/android/calculator/preferences/NumberFormatPreference.java index e4cbaee7..484dc9ca 100644 --- a/app/src/main/java/org/solovyev/android/calculator/preferences/NumberFormatPreference.java +++ b/app/src/main/java/org/solovyev/android/calculator/preferences/NumberFormatPreference.java @@ -20,6 +20,7 @@ import org.solovyev.android.views.DiscreteSeekBar; import butterknife.Bind; import butterknife.ButterKnife; +import jscl.JsclMathEngine; import static org.solovyev.android.calculator.Engine.Preferences.Output; @@ -31,7 +32,7 @@ public class NumberFormatPreference extends DialogPreference { DiscreteSeekBar precisionSeekBar; @Bind(R.id.nf_separator_spinner) Spinner separatorSpinner; - ArrayAdapter> separatorAdapter; + ArrayAdapter> separatorAdapter; { setPersistent(false); @@ -108,12 +109,12 @@ public class NumberFormatPreference extends DialogPreference { } @NonNull - private ArrayAdapter> makeSeparatorAdapter() { + private ArrayAdapter> makeSeparatorAdapter() { final Context context = getContext(); - final ArrayAdapter> adapter = App.makeSimpleSpinnerAdapter(context); - adapter.add(Named.create("", R.string.p_grouping_separator_no, context)); - adapter.add(Named.create("'", R.string.p_grouping_separator_apostrophe, context)); - adapter.add(Named.create(" ", R.string.p_grouping_separator_space, context)); + final ArrayAdapter> adapter = App.makeSimpleSpinnerAdapter(context); + adapter.add(Named.create(JsclMathEngine.GROUPING_SEPARATOR_NO, R.string.p_grouping_separator_no, context)); + adapter.add(Named.create('\'', R.string.p_grouping_separator_apostrophe, context)); + adapter.add(Named.create(' ', R.string.p_grouping_separator_space, context)); return adapter; } } diff --git a/app/src/main/java/org/solovyev/android/prefs/CharacterPreference.java b/app/src/main/java/org/solovyev/android/prefs/CharacterPreference.java new file mode 100644 index 00000000..5f6780ab --- /dev/null +++ b/app/src/main/java/org/solovyev/android/prefs/CharacterPreference.java @@ -0,0 +1,27 @@ +package org.solovyev.android.prefs; + +import android.content.SharedPreferences; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +public class CharacterPreference extends AbstractPreference { + private CharacterPreference(@Nonnull String key, @Nullable Character defaultValue) { + super(key, defaultValue); + } + + public static CharacterPreference of(@Nonnull String key, @Nullable Character defaultValue) { + return new CharacterPreference(key, defaultValue); + } + + @Nullable + @Override + protected Character getPersistedValue(@Nonnull SharedPreferences preferences) { + return (char) preferences.getInt(getKey(), 0); + } + + @Override + protected void putPersistedValue(@Nonnull SharedPreferences.Editor editor, @Nonnull Character value) { + editor.putInt(getKey(), value); + } +} diff --git a/app/src/test/java/org/solovyev/android/calculator/Tests.java b/app/src/test/java/org/solovyev/android/calculator/Tests.java index fb8f5108..574534e5 100644 --- a/app/src/test/java/org/solovyev/android/calculator/Tests.java +++ b/app/src/test/java/org/solovyev/android/calculator/Tests.java @@ -23,7 +23,6 @@ public class Tests { @NonNull public static Engine makeEngine() { final JsclMathEngine mathEngine = JsclMathEngine.getInstance(); - mathEngine.setUseGroupingSeparator(true); mathEngine.setGroupingSeparator(' '); final Engine engine = new Engine(mathEngine); engine.postfixFunctionsRegistry = new PostfixFunctionsRegistry(mathEngine); diff --git a/jscl/src/main/java/jscl/JsclMathEngine.java b/jscl/src/main/java/jscl/JsclMathEngine.java index 6c26d3d9..00550d93 100644 --- a/jscl/src/main/java/jscl/JsclMathEngine.java +++ b/jscl/src/main/java/jscl/JsclMathEngine.java @@ -1,32 +1,42 @@ package jscl; -import jscl.math.Expression; -import jscl.math.Generic; -import jscl.math.NotIntegerException; -import jscl.math.function.*; -import jscl.math.operator.Operator; -import jscl.math.operator.Percent; -import jscl.math.operator.Rand; -import jscl.math.operator.matrix.OperatorsRegistry; -import jscl.text.ParseException; import org.solovyev.common.NumberFormatter; import org.solovyev.common.math.MathRegistry; import org.solovyev.common.msg.MessageRegistry; import org.solovyev.common.msg.Messages; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; import java.math.BigDecimal; import java.math.BigInteger; import java.util.List; -import static midpcalc.Real.NumberFormat.*; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +import jscl.math.Expression; +import jscl.math.Generic; +import jscl.math.NotIntegerException; +import jscl.math.function.Constants; +import jscl.math.function.ConstantsRegistry; +import jscl.math.function.Function; +import jscl.math.function.FunctionsRegistry; +import jscl.math.function.IConstant; +import jscl.math.function.PostfixFunctionsRegistry; +import jscl.math.operator.Operator; +import jscl.math.operator.Percent; +import jscl.math.operator.Rand; +import jscl.math.operator.matrix.OperatorsRegistry; +import jscl.text.ParseException; + +import static midpcalc.Real.NumberFormat.FSE_ENG; +import static midpcalc.Real.NumberFormat.FSE_NONE; +import static midpcalc.Real.NumberFormat.FSE_SCI; public class JsclMathEngine implements MathEngine { public static final AngleUnit DEFAULT_ANGLE_UNITS = AngleUnit.deg; public static final NumeralBase DEFAULT_NUMERAL_BASE = NumeralBase.dec; public static final char GROUPING_SEPARATOR_DEFAULT = ' '; + public static final char GROUPING_SEPARATOR_NO = 0; public static final int MAX_FRACTION_DIGITS = 20; @Nonnull private static JsclMathEngine instance = new JsclMathEngine(); @@ -39,11 +49,10 @@ public class JsclMathEngine implements MathEngine { return new NumberFormatter(); } }; - private char groupingSeparator = GROUPING_SEPARATOR_DEFAULT; + private char groupingSeparator = GROUPING_SEPARATOR_NO; private boolean roundResult = false; private int numberFormat = FSE_NONE; private int precision = 5; - private boolean useGroupingSeparator = false; @Nonnull private AngleUnit angleUnits = DEFAULT_ANGLE_UNITS; @Nonnull @@ -172,7 +181,7 @@ public class JsclMathEngine implements MathEngine { private NumberFormatter prepareNumberFormatter(@Nonnull NumeralBase nb) { final NumberFormatter nf = numberFormatter.get(); - nf.setGroupingSeparator(useGroupingSeparator ? getGroupingSeparatorChar(nb) : NumberFormatter.NO_GROUPING); + nf.setGroupingSeparator(hasGroupingSeparator() ? getGroupingSeparatorChar(nb) : NumberFormatter.NO_GROUPING); nf.setPrecision(roundResult ? precision : NumberFormatter.NO_ROUNDING); switch (numberFormat) { case FSE_ENG: @@ -272,7 +281,7 @@ public class JsclMathEngine implements MathEngine { @Nonnull public String addGroupingSeparators(@Nonnull NumeralBase nb, @Nonnull String ungroupedDoubleValue) { - if (useGroupingSeparator) { + if (hasGroupingSeparator()) { final String groupingSeparator = getGroupingSeparator(nb); final int dotIndex = ungroupedDoubleValue.indexOf("."); @@ -299,6 +308,10 @@ public class JsclMathEngine implements MathEngine { } } + private boolean hasGroupingSeparator() { + return groupingSeparator != JsclMathEngine.GROUPING_SEPARATOR_NO; + } + @Nonnull private String getGroupingSeparator(@Nonnull NumeralBase nb) { return nb == NumeralBase.dec ? String.valueOf(groupingSeparator) : " "; @@ -342,10 +355,6 @@ public class JsclMathEngine implements MathEngine { this.precision = precision; } - public void setUseGroupingSeparator(boolean useGroupingSeparator) { - this.useGroupingSeparator = useGroupingSeparator; - } - public void setScienceNotation(boolean scienceNotation) { setNumberFormat(scienceNotation ? FSE_SCI : FSE_NONE); } @@ -361,7 +370,7 @@ public class JsclMathEngine implements MathEngine { return this.groupingSeparator; } - public void setGroupingSeparator(char groupingSeparator) { - this.groupingSeparator = groupingSeparator; + public void setGroupingSeparator(char separator) { + this.groupingSeparator = separator; } } diff --git a/jscl/src/main/java/jscl/MathContext.java b/jscl/src/main/java/jscl/MathContext.java index 4f280149..1b298121 100644 --- a/jscl/src/main/java/jscl/MathContext.java +++ b/jscl/src/main/java/jscl/MathContext.java @@ -1,12 +1,14 @@ package jscl; +import org.solovyev.common.math.MathRegistry; + +import java.math.BigInteger; + +import javax.annotation.Nonnull; + import jscl.math.function.Function; import jscl.math.function.IConstant; import jscl.math.operator.Operator; -import org.solovyev.common.math.MathRegistry; - -import javax.annotation.Nonnull; -import java.math.BigInteger; public interface MathContext { @@ -40,9 +42,7 @@ public interface MathContext { void setPrecision(int precision); - void setUseGroupingSeparator(boolean useGroupingSeparator); - - void setGroupingSeparator(char groupingSeparator); + void setGroupingSeparator(char separator); @Nonnull String format(double value); diff --git a/jscl/src/test/java/jscl/JsclMathEngineTest.java b/jscl/src/test/java/jscl/JsclMathEngineTest.java index ae3cb0c7..b6336305 100644 --- a/jscl/src/test/java/jscl/JsclMathEngineTest.java +++ b/jscl/src/test/java/jscl/JsclMathEngineTest.java @@ -1,9 +1,10 @@ package jscl; -import midpcalc.Real; import org.junit.Before; import org.junit.Test; +import midpcalc.Real; + import static org.junit.Assert.assertEquals; /** @@ -23,7 +24,7 @@ public class JsclMathEngineTest { @Test public void testFormat() throws Exception { try { - me.setUseGroupingSeparator(true); + me.setGroupingSeparator(' '); assertEquals("1", me.format(1d, NumeralBase.bin)); assertEquals("10", me.format(2d, NumeralBase.bin)); assertEquals("11", me.format(3d, NumeralBase.bin)); @@ -60,7 +61,7 @@ public class JsclMathEngineTest { assertEquals("6.CCDA6A054226DB6E-19", me.format(0.00000000000000000000009d, NumeralBase.hex)); assertEquals("A.E15D766ED03E2BEE-20", me.format(0.000000000000000000000009d, NumeralBase.hex)); } finally { - me.setUseGroupingSeparator(false); + me.setGroupingSeparator(JsclMathEngine.GROUPING_SEPARATOR_NO); } assertEquals("1", me.format(1d, NumeralBase.bin)); @@ -93,7 +94,6 @@ public class JsclMathEngineTest { @Test public void testBinShouldAlwaysUseSpaceAsGroupingSeparator() throws Exception { me.setGroupingSeparator('\''); - me.setUseGroupingSeparator(true); assertEquals("100 0000 0000", me.format(1024d, NumeralBase.bin)); } @@ -101,7 +101,6 @@ public class JsclMathEngineTest { @Test public void testHexShouldAlwaysUseSpaceAsGroupingSeparator() throws Exception { me.setGroupingSeparator('\''); - me.setUseGroupingSeparator(true); assertEquals("4 00", me.format(1024d, NumeralBase.hex)); } diff --git a/jscl/src/test/java/jscl/math/ExpressionTest.java b/jscl/src/test/java/jscl/math/ExpressionTest.java index 8ea51f24..416d754a 100644 --- a/jscl/src/test/java/jscl/math/ExpressionTest.java +++ b/jscl/src/test/java/jscl/math/ExpressionTest.java @@ -1,5 +1,18 @@ package jscl.math; +import org.junit.Test; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLConnection; +import java.util.Set; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + import jscl.AngleUnit; import jscl.JsclMathEngine; import jscl.MathEngine; @@ -8,19 +21,10 @@ import jscl.math.function.Constant; import jscl.math.function.ExtendedConstant; import jscl.math.function.IConstant; import jscl.text.ParseException; -import org.junit.Test; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.net.MalformedURLException; -import java.net.URL; -import java.net.URLConnection; -import java.util.Set; - -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; public class ExpressionTest { @@ -786,7 +790,7 @@ public class ExpressionTest { public void testFormat() throws Exception { final JsclMathEngine me = JsclMathEngine.getInstance(); try { - me.setUseGroupingSeparator(true); + me.setGroupingSeparator(' '); assertEquals("123 456.7891011", Expression.valueOf("123456.7891011").numeric().toString()); assertEquals("123 456.7891011", Expression.valueOf("123456.7891011").simplify().toString()); assertEquals("123 456.7891011123", Expression.valueOf("123456.7891011123123123123123").simplify().toString()); @@ -831,7 +835,7 @@ public class ExpressionTest { assertEquals("0.3333333333", Expression.valueOf("1/3").numeric().toString()); } finally { - me.setUseGroupingSeparator(false); + me.setGroupingSeparator(JsclMathEngine.GROUPING_SEPARATOR_NO); me.setScienceNotation(false); me.setRoundResult(false); }