Error messages added
This commit is contained in:
parent
0d0c4ae3cc
commit
5df4222e2f
@ -269,5 +269,26 @@ Check the \'Round result\' preference in application settings - it should be tur
|
||||
</string>
|
||||
|
||||
|
||||
<string name="msg_msg_1">Arithmetic error occurred: {0}</string>
|
||||
<string name="msg_msg_2">Too complex expression</string>
|
||||
<string name="msg_msg_3">Too long execution time - check the expression</string>
|
||||
<string name="msg_msg_4">Evaluation was cancelled</string>
|
||||
<string name="msg_msg_5">No parameters are specified for function: {0}</string>
|
||||
<string name="msg_msg_6">Infinite loop is detected in expression</string>
|
||||
|
||||
<string name="msg_jscl_msg_1">Premature end of processing</string>
|
||||
<string name="msg_jscl_msg_2">There is no operator with name: {0}</string>
|
||||
<string name="msg_jscl_msg_3">Operator name is not valid: {0}</string>
|
||||
<string name="msg_jscl_msg_4">Postfix function with name {0} doesn\'\'t exist</string>
|
||||
<string name="msg_jscl_msg_5">Constant name must start with character</string>
|
||||
<string name="msg_jscl_msg_6">Cannot be implicit function - usual function or operator with same name is defined: {0}</string>
|
||||
<string name="msg_jscl_msg_7">Digit is expected</string>
|
||||
<string name="msg_jscl_msg_8">Invalid number: {0}</string>
|
||||
<string name="msg_jscl_msg_9">First letter of number must be digit</string>
|
||||
<string name="msg_jscl_msg_10">Expected characters are {0} or {1}</string>
|
||||
<string name="msg_jscl_msg_11">Expected characters are {0}</string>
|
||||
<string name="msg_jscl_msg_12">Expected character is {0}</string>
|
||||
<string name="msg_jscl_msg_13">Function name is not valid: {0}</string>
|
||||
<string name="msg_jscl_msg_14">Expected number of parameters differs from actual {0}</string>
|
||||
|
||||
</resources>
|
||||
|
@ -22,13 +22,14 @@ import android.view.*;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.TextView;
|
||||
import jscl.AngleUnits;
|
||||
import jscl.AngleUnit;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.solovyev.android.calculator.math.MathType;
|
||||
import org.solovyev.android.calculator.model.CalculatorEngine;
|
||||
import org.solovyev.android.msg.AndroidMessageRegistry;
|
||||
import org.solovyev.android.view.FontSizeAdjuster;
|
||||
import org.solovyev.android.view.prefs.ResourceCache;
|
||||
import org.solovyev.android.view.widgets.*;
|
||||
import org.solovyev.common.BooleanMapper;
|
||||
import org.solovyev.common.utils.Announcer;
|
||||
@ -38,7 +39,10 @@ import org.solovyev.common.utils.history.HistoryAction;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.text.DecimalFormatSymbols;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
public class CalculatorActivity extends Activity implements FontSizeAdjuster, SharedPreferences.OnSharedPreferenceChangeListener {
|
||||
|
||||
@ -58,12 +62,6 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster, Sh
|
||||
@NotNull
|
||||
private String layoutName;
|
||||
|
||||
// ids of drag buttons in R.class
|
||||
private List<Integer> dragButtonIds = null;
|
||||
|
||||
// ids of buttons in R.class
|
||||
private List<Integer> buttonIds = null;
|
||||
|
||||
@Nullable
|
||||
private Vibrator vibrator;
|
||||
|
||||
@ -82,6 +80,7 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster, Sh
|
||||
super.onCreate(savedInstanceState);
|
||||
setLayout(preferences);
|
||||
|
||||
ResourceCache.instance.initCaptions(R.string.class, this);
|
||||
firstTimeInit(preferences);
|
||||
|
||||
vibrator = (Vibrator) this.getSystemService(VIBRATOR_SERVICE);
|
||||
@ -150,7 +149,7 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster, Sh
|
||||
if ( directionText != null ) {
|
||||
try {
|
||||
|
||||
final AngleUnits angleUnits = AngleUnits.valueOf(directionText);
|
||||
final AngleUnit angleUnits = AngleUnit.valueOf(directionText);
|
||||
|
||||
final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(CalculatorActivity.this);
|
||||
final SharedPreferences.Editor editor = preferences.edit();
|
||||
@ -214,7 +213,7 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster, Sh
|
||||
private synchronized void setOnDragListeners(@NotNull SimpleOnDragListener.Preferences dragPreferences, @NotNull SharedPreferences preferences) {
|
||||
final OnDragListener onDragListener = new OnDragListenerVibrator(newOnDragListener(new DigitButtonDragProcessor(calculatorModel), dragPreferences), vibrator, preferences);
|
||||
|
||||
for (Integer dragButtonId : dragButtonIds) {
|
||||
for (Integer dragButtonId : ResourceCache.instance.getDragButtonIds()) {
|
||||
((DragButton) findViewById(dragButtonId)).setOnDragListener(onDragListener);
|
||||
}
|
||||
}
|
||||
@ -288,26 +287,7 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster, Sh
|
||||
|
||||
private synchronized void firstTimeInit(@NotNull SharedPreferences preferences) {
|
||||
if (!initialized) {
|
||||
dragButtonIds = new ArrayList<Integer>();
|
||||
buttonIds = new ArrayList<Integer>();
|
||||
|
||||
for (Field field : R.id.class.getDeclaredFields()) {
|
||||
int modifiers = field.getModifiers();
|
||||
if (Modifier.isFinal(modifiers) && Modifier.isStatic(modifiers)) {
|
||||
try {
|
||||
int viewId = field.getInt(R.id.class);
|
||||
final View view = findViewById(viewId);
|
||||
if (view instanceof DragButton) {
|
||||
dragButtonIds.add(viewId);
|
||||
}
|
||||
if (view instanceof Button) {
|
||||
buttonIds.add(viewId);
|
||||
}
|
||||
} catch (IllegalAccessException e) {
|
||||
Log.e(CalculatorActivity.class.getName(), e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
ResourceCache.instance.init(R.id.class, this);
|
||||
|
||||
CalculatorEngine.instance.init(this, preferences);
|
||||
initialized = true;
|
||||
|
@ -11,6 +11,7 @@ import android.text.Html;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.solovyev.android.calculator.jscl.JsclOperation;
|
||||
import org.solovyev.android.calculator.model.ParseException;
|
||||
import org.solovyev.android.calculator.model.TextProcessor;
|
||||
@ -25,6 +26,9 @@ public class CalculatorDisplay extends AutoResizeTextView {
|
||||
|
||||
private boolean valid = true;
|
||||
|
||||
@Nullable
|
||||
private String errorMessage;
|
||||
|
||||
@NotNull
|
||||
private JsclOperation jsclOperation = JsclOperation.numeric;
|
||||
|
||||
@ -49,6 +53,18 @@ public class CalculatorDisplay extends AutoResizeTextView {
|
||||
|
||||
public void setValid(boolean valid) {
|
||||
this.valid = valid;
|
||||
if (valid) {
|
||||
errorMessage = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getErrorMessage() {
|
||||
return errorMessage;
|
||||
}
|
||||
|
||||
public void setErrorMessage(@Nullable String errorMessage) {
|
||||
this.errorMessage = errorMessage;
|
||||
}
|
||||
|
||||
public void setJsclOperation(@NotNull JsclOperation jsclOperation) {
|
||||
|
@ -6,6 +6,7 @@
|
||||
package org.solovyev.android.calculator;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.solovyev.android.calculator.jscl.JsclOperation;
|
||||
|
||||
/**
|
||||
@ -17,6 +18,9 @@ public class CalculatorDisplayHistoryState {
|
||||
|
||||
private boolean valid = true;
|
||||
|
||||
@Nullable
|
||||
private String errorMessage = null;
|
||||
|
||||
@NotNull
|
||||
private EditorHistoryState editorHistoryState;
|
||||
|
||||
@ -33,6 +37,7 @@ public class CalculatorDisplayHistoryState {
|
||||
result.editorHistoryState = EditorHistoryState.newInstance(display);
|
||||
result.valid = display.isValid();
|
||||
result.jsclOperation = display.getJsclOperation();
|
||||
result.errorMessage = display.getErrorMessage();
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -51,6 +56,11 @@ public class CalculatorDisplayHistoryState {
|
||||
return jsclOperation;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getErrorMessage() {
|
||||
return errorMessage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
@ -60,6 +70,7 @@ public class CalculatorDisplayHistoryState {
|
||||
|
||||
if (valid != that.valid) return false;
|
||||
if (!editorHistoryState.equals(that.editorHistoryState)) return false;
|
||||
if (errorMessage != null ? !errorMessage.equals(that.errorMessage) : that.errorMessage != null) return false;
|
||||
if (jsclOperation != that.jsclOperation) return false;
|
||||
|
||||
return true;
|
||||
@ -68,6 +79,7 @@ public class CalculatorDisplayHistoryState {
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = (valid ? 1 : 0);
|
||||
result = 31 * result + (errorMessage != null ? errorMessage.hashCode() : 0);
|
||||
result = 31 * result + editorHistoryState.hashCode();
|
||||
result = 31 * result + jsclOperation.hashCode();
|
||||
return result;
|
||||
@ -77,8 +89,9 @@ public class CalculatorDisplayHistoryState {
|
||||
public String toString() {
|
||||
return "CalculatorDisplayHistoryState{" +
|
||||
"valid=" + valid +
|
||||
"jsclOperation=" + jsclOperation +
|
||||
", errorMessage='" + errorMessage + '\'' +
|
||||
", editorHistoryState=" + editorHistoryState +
|
||||
", jsclOperation=" + jsclOperation +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@
|
||||
package org.solovyev.android.calculator;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Handler;
|
||||
@ -63,7 +64,17 @@ public enum CalculatorModel implements CursorControl, HistoryControl<CalculatorH
|
||||
this.display.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
copyResult(activity);
|
||||
if (v instanceof CalculatorDisplay) {
|
||||
final CalculatorDisplay cd = (CalculatorDisplay)v;
|
||||
if (cd.isValid()) {
|
||||
copyResult(activity, cd);
|
||||
} else {
|
||||
final String errorMessage = cd.getErrorMessage();
|
||||
if ( errorMessage != null ) {
|
||||
showEvaluationError(activity, errorMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@ -79,9 +90,23 @@ public enum CalculatorModel implements CursorControl, HistoryControl<CalculatorH
|
||||
return this;
|
||||
}
|
||||
|
||||
private static void showEvaluationError(@NotNull Activity activity, @NotNull final String errorMessage) {
|
||||
final TextView errorMessageTextView = new TextView(activity);
|
||||
errorMessageTextView.setText(errorMessage);
|
||||
final AlertDialog.Builder builder = new AlertDialog.Builder(activity)
|
||||
.setPositiveButton(R.string.c_cancel, null)
|
||||
.setView(errorMessageTextView);
|
||||
|
||||
builder.create().show();
|
||||
}
|
||||
|
||||
public void copyResult(@NotNull Context context) {
|
||||
copyResult(context, display);
|
||||
}
|
||||
|
||||
private void copyResult(@NotNull Context context, @NotNull final CalculatorDisplay display) {
|
||||
if (display.isValid()) {
|
||||
final CharSequence text = display.getText();
|
||||
final CharSequence text = this.display.getText();
|
||||
if (!StringUtils.isEmpty(text)) {
|
||||
final ClipboardManager clipboard = (ClipboardManager) context.getSystemService(Activity.CLIPBOARD_SERVICE);
|
||||
clipboard.setText(text.toString());
|
||||
@ -229,11 +254,12 @@ public enum CalculatorModel implements CursorControl, HistoryControl<CalculatorH
|
||||
private void handleEvaluationException(@NotNull String expression,
|
||||
@NotNull CalculatorDisplay localDisplay,
|
||||
@NotNull JsclOperation operation,
|
||||
@NotNull Exception e) {
|
||||
@NotNull ParseException e) {
|
||||
Log.d(CalculatorModel.class.getName(), "Evaluation failed for : " + expression + ". Error message: " + e.getMessage());
|
||||
localDisplay.setText(R.string.c_syntax_error);
|
||||
localDisplay.setJsclOperation(operation);
|
||||
localDisplay.setValid(false);
|
||||
localDisplay.setErrorMessage(e.getLocalizedMessage());
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
@ -327,6 +353,7 @@ public enum CalculatorModel implements CursorControl, HistoryControl<CalculatorH
|
||||
private void setValuesFromHistory(@NotNull CalculatorDisplay display, CalculatorDisplayHistoryState editorHistoryState) {
|
||||
setValuesFromHistory(display, editorHistoryState.getEditorHistoryState());
|
||||
display.setValid(editorHistoryState.isValid());
|
||||
display.setErrorMessage(editorHistoryState.getErrorMessage());
|
||||
display.setJsclOperation(editorHistoryState.getJsclOperation());
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
package org.solovyev.android.calculator.jscl;
|
||||
|
||||
import jscl.text.Messages;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.solovyev.android.calculator.math.MathType;
|
||||
@ -38,7 +39,7 @@ class FromJsclNumericTextProcessor implements TextProcessor<String> {
|
||||
result = createResultForComplexNumber(result.replace(MathType.IMAGINARY_NUMBER_JSCL, MathType.IMAGINARY_NUMBER));
|
||||
} catch (NumberFormatException e1) {
|
||||
// throw original one
|
||||
throw new ParseException(e);
|
||||
throw new ParseException(new jscl.text.ParseException(Messages.msg_8, 0, result, result));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,7 @@ package org.solovyev.android.calculator.model;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import jscl.AngleUnits;
|
||||
import jscl.AngleUnit;
|
||||
import jscl.JsclMathEngine;
|
||||
import jscl.MathEngine;
|
||||
import jscl.math.function.Function;
|
||||
@ -191,13 +191,13 @@ public enum CalculatorEngine {
|
||||
calculationResult.setObject(finalOperation.evaluate(jsclExpression));
|
||||
} catch (ArithmeticException e) {
|
||||
//System.out.println(e.getMessage());
|
||||
exception.setObject(new ParseException(e.getMessage(), e));
|
||||
exception.setObject(new ParseException(Messages.msg_1, jsclExpression, e.getMessage()));
|
||||
} catch (StackOverflowError e) {
|
||||
//System.out.println(StringUtils.fromStackTrace(e.getStackTrace()));
|
||||
exception.setObject(new ParseException(e.getMessage(), e));
|
||||
exception.setObject(new ParseException(Messages.msg_2, jsclExpression));
|
||||
} catch (jscl.text.ParseException e) {
|
||||
//System.out.println(e.getMessage());
|
||||
exception.setObject(new ParseException(e.getMessage(), e));
|
||||
exception.setObject(new ParseException(e));
|
||||
} catch (ParseInterruptedException e) {
|
||||
//System.out.println(e.getMessage());
|
||||
// do nothing - we ourselves interrupt the calculations
|
||||
@ -232,11 +232,11 @@ public enum CalculatorEngine {
|
||||
}
|
||||
|
||||
if (calculationResultLocal == null) {
|
||||
throw new ParseException("Too long calculation for: " + jsclExpression);
|
||||
throw new ParseException(Messages.msg_3, jsclExpression);
|
||||
}
|
||||
|
||||
} catch (InterruptedException e) {
|
||||
throw new ParseException(e);
|
||||
throw new ParseException(Messages.msg_4, jsclExpression);
|
||||
}
|
||||
|
||||
result = String.valueOf(calculationResult.getObject()).trim();
|
||||
@ -274,7 +274,7 @@ public enum CalculatorEngine {
|
||||
//noinspection ConstantConditions
|
||||
this.setPrecision(integerNumberMapper.parseValue(preferences.getString(RESULT_PRECISION_P_KEY, RESULT_PRECISION_DEFAULT)));
|
||||
this.setRoundResult(preferences.getBoolean(ROUND_RESULT_P_KEY, ROUND_RESULT_DEFAULT));
|
||||
this.setDefaultAngleUnits(AngleUnits.valueOf(preferences.getString(ANGLE_UNITS_P_KEY, ANGLE_UNITS_DEFAULT)));
|
||||
this.setDefaultAngleUnits(AngleUnit.valueOf(preferences.getString(ANGLE_UNITS_P_KEY, ANGLE_UNITS_DEFAULT)));
|
||||
|
||||
final String groupingSeparator = preferences.getString(GROUPING_SEPARATOR_P_KEY, GROUPING_SEPARATOR_DEFAULT);
|
||||
if (StringUtils.isEmpty(groupingSeparator)) {
|
||||
@ -326,8 +326,8 @@ public enum CalculatorEngine {
|
||||
this.timeout = timeout;
|
||||
}
|
||||
|
||||
public void setDefaultAngleUnits(@NotNull AngleUnits angleUnits) {
|
||||
getEngine().setDefaultAngleUnits(angleUnits);
|
||||
public void setDefaultAngleUnits(@NotNull AngleUnit angleUnits) {
|
||||
getEngine().setDefaultAngleUnit(angleUnits);
|
||||
}
|
||||
|
||||
// for tests only
|
||||
|
@ -0,0 +1,34 @@
|
||||
package org.solovyev.android.calculator.model;
|
||||
|
||||
/**
|
||||
* User: serso
|
||||
* Date: 11/25/11
|
||||
* Time: 1:40 PM
|
||||
*/
|
||||
public final class Messages {
|
||||
|
||||
|
||||
// not intended for instantiation
|
||||
private Messages() {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
/** Arithmetic error occurred: {0} */
|
||||
public static final String msg_1 = "msg_1";
|
||||
|
||||
/** Too complex expression */
|
||||
public static final String msg_2 = "msg_2";
|
||||
|
||||
/** Too long execution time - check the expression */
|
||||
public static final String msg_3 = "msg_3";
|
||||
|
||||
/** Evaluation was cancelled */
|
||||
public static final String msg_4 = "msg_4";
|
||||
|
||||
/** No parameters are specified for function: {0} */
|
||||
public static final String msg_5 = "msg_5";
|
||||
|
||||
/** Infinite loop is detected in expression */
|
||||
public static final String msg_6 = "msg_6";
|
||||
|
||||
}
|
@ -6,7 +6,17 @@
|
||||
|
||||
package org.solovyev.android.calculator.model;
|
||||
|
||||
import android.content.Context;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.solovyev.android.view.prefs.ResourceCache;
|
||||
import org.solovyev.common.exceptions.SersoException;
|
||||
import org.solovyev.common.utils.CollectionsUtils;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* User: serso
|
||||
@ -15,18 +25,75 @@ import org.solovyev.common.exceptions.SersoException;
|
||||
*/
|
||||
public class ParseException extends SersoException {
|
||||
|
||||
public ParseException() {
|
||||
@NotNull
|
||||
private final String messageId;
|
||||
|
||||
@NotNull
|
||||
private final List<Object> parameters;
|
||||
|
||||
@NotNull
|
||||
private final String expression;
|
||||
|
||||
@Nullable
|
||||
private final Integer position;
|
||||
|
||||
public ParseException(@NotNull jscl.text.ParseException jsclParseException) {
|
||||
this.messageId = "jscl_" + jsclParseException.getMessageId();
|
||||
this.expression = jsclParseException.getExpression();
|
||||
this.position = jsclParseException.getPosition();
|
||||
this.parameters = jsclParseException.getParameters();
|
||||
}
|
||||
|
||||
public ParseException(String message) {
|
||||
super(message);
|
||||
public ParseException(@NotNull String messageId, @Nullable Integer position, @NotNull String expression, Object... parameters) {
|
||||
this.messageId = messageId;
|
||||
this.expression = expression;
|
||||
this.position = position;
|
||||
|
||||
if (CollectionsUtils.isEmpty(parameters)) {
|
||||
this.parameters = Collections.emptyList();
|
||||
} else {
|
||||
this.parameters = Arrays.asList(parameters);
|
||||
}
|
||||
}
|
||||
|
||||
public ParseException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
public ParseException(@NotNull String messageId, @NotNull String expression, Object... parameters) {
|
||||
this(messageId, null, expression, parameters);
|
||||
}
|
||||
|
||||
public ParseException(Throwable cause) {
|
||||
super(cause);
|
||||
@NotNull
|
||||
public String getMessageId() {
|
||||
return messageId;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<Object> getParameters() {
|
||||
return parameters;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getExpression() {
|
||||
return expression;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Integer getPosition() {
|
||||
return position;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public String getLocalizedMessage() {
|
||||
String result = null;
|
||||
|
||||
final String message = ResourceCache.instance.getCaption("msg_" + getMessageId());
|
||||
if (message != null) {
|
||||
if ( parameters.size() > 0 ) {
|
||||
result = MessageFormat.format(message, parameters.toArray(new Object[parameters.size()]));
|
||||
} else {
|
||||
result = message;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ class ToJsclTextProcessor implements TextProcessor<PreparedExpression> {
|
||||
}
|
||||
|
||||
if ((mathTypeBefore == MathType.function || mathTypeBefore == MathType.operator) && CollectionsUtils.find(MathType.openGroupSymbols, startsWithFinder) != null) {
|
||||
throw new ParseException("Empty function: " + mathTypeResult.getMatch());
|
||||
throw new ParseException(Messages.msg_5, i, s, mathTypeResult.getMatch());
|
||||
}
|
||||
|
||||
i = mathTypeResult.processToJscl(result, i);
|
||||
@ -66,7 +66,7 @@ class ToJsclTextProcessor implements TextProcessor<PreparedExpression> {
|
||||
@NotNull
|
||||
private static PreparedExpression replaceVariables(@NotNull final String s, int depth, @NotNull List<Var> undefinedVars) throws ParseException {
|
||||
if (depth >= MAX_DEPTH) {
|
||||
throw new ParseException("Infinite loop in expression: " + s);
|
||||
throw new ParseException(Messages.msg_6, s);
|
||||
} else {
|
||||
depth++;
|
||||
}
|
||||
|
@ -0,0 +1,98 @@
|
||||
package org.solovyev.android.view.prefs;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.solovyev.android.calculator.R;
|
||||
import org.solovyev.android.view.widgets.DragButton;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* User: serso
|
||||
* Date: 11/25/11
|
||||
* Time: 1:52 PM
|
||||
*/
|
||||
public enum ResourceCache {
|
||||
|
||||
instance;
|
||||
|
||||
// ids of drag buttons in R.class
|
||||
private List<Integer> dragButtonIds = null;
|
||||
|
||||
// ids of buttons in R.class
|
||||
private List<Integer> buttonIds = null;
|
||||
|
||||
private static final Map<String, Map<String, String>> captions = new HashMap<String, Map<String, String>>();
|
||||
|
||||
public List<Integer> getDragButtonIds() {
|
||||
return dragButtonIds;
|
||||
}
|
||||
|
||||
public List<Integer> getButtonIds() {
|
||||
return buttonIds;
|
||||
}
|
||||
|
||||
public void initCaptions(@NotNull Class<?> resourceClass, @NotNull Activity activity) {
|
||||
final Locale locale = Locale.getDefault();
|
||||
|
||||
if (!captions.containsKey(locale.getLanguage())) {
|
||||
|
||||
final Map<String, String> captionsByLanguage = new HashMap<String, String>();
|
||||
|
||||
for (Field field : resourceClass.getDeclaredFields()) {
|
||||
int modifiers = field.getModifiers();
|
||||
if (Modifier.isFinal(modifiers) && Modifier.isStatic(modifiers)) {
|
||||
try {
|
||||
int captionId = field.getInt(resourceClass);
|
||||
captionsByLanguage.put(field.getName(), activity.getString(captionId));
|
||||
} catch (IllegalAccessException e) {
|
||||
Log.e(ResourceCache.class.getName(), e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
captions.put(locale.getLanguage(), captionsByLanguage);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getCaption(@NotNull String captionId) {
|
||||
final Locale locale = Locale.getDefault();
|
||||
|
||||
final Map<String, String> captionsByLanguage = captions.get(locale.getLanguage());
|
||||
if (captionsByLanguage != null) {
|
||||
return captionsByLanguage.get(captionId);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void init(@NotNull Class<?> resourceClass, @NotNull Activity activity) {
|
||||
dragButtonIds = new ArrayList<Integer>();
|
||||
buttonIds = new ArrayList<Integer>();
|
||||
|
||||
for (Field field : resourceClass.getDeclaredFields()) {
|
||||
int modifiers = field.getModifiers();
|
||||
if (Modifier.isFinal(modifiers) && Modifier.isStatic(modifiers)) {
|
||||
try {
|
||||
int viewId = field.getInt(resourceClass);
|
||||
final View view = activity.findViewById(viewId);
|
||||
if (view instanceof DragButton) {
|
||||
dragButtonIds.add(viewId);
|
||||
}
|
||||
if (view instanceof Button) {
|
||||
buttonIds.add(viewId);
|
||||
}
|
||||
} catch (IllegalAccessException e) {
|
||||
Log.e(ResourceCache.class.getName(), e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -34,7 +34,7 @@ public class AngleUnitsButton extends DirectionDragButton {
|
||||
|
||||
if (result != null) {
|
||||
final Resources resources = getResources();
|
||||
if ( CalculatorEngine.instance.getEngine().getDefaultAngleUnits().name().equals(getDirectionText(direction)) ) {
|
||||
if ( CalculatorEngine.instance.getEngine().getDefaultAngleUnit().name().equals(getDirectionText(direction)) ) {
|
||||
result.setColor(resources.getColor(R.color.selected_angle_unit_text_color));
|
||||
} else {
|
||||
result.setColor(resources.getColor(R.color.default_text_color));
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
package org.solovyev.android.calculator.model;
|
||||
|
||||
import jscl.AngleUnits;
|
||||
import jscl.AngleUnit;
|
||||
import jscl.math.Expression;
|
||||
import org.junit.Assert;
|
||||
import org.junit.BeforeClass;
|
||||
@ -40,7 +40,7 @@ public class CalculatorEngineTest {
|
||||
cm.evaluate(JsclOperation.numeric, "3^10^10^10");
|
||||
Assert.fail();
|
||||
} catch (ParseException e) {
|
||||
if (e.getMessage().startsWith("Too long calculation")) {
|
||||
if (e.getMessageId().equals(Messages.msg_3)) {
|
||||
|
||||
} else {
|
||||
System.out.print(e.getCause().getMessage());
|
||||
@ -52,7 +52,7 @@ public class CalculatorEngineTest {
|
||||
cm.evaluate(JsclOperation.numeric, "9999999!");
|
||||
Assert.fail();
|
||||
} catch (ParseException e) {
|
||||
if (e.getMessage().startsWith("Too long calculation")) {
|
||||
if (e.getMessageId().equals(Messages.msg_3)) {
|
||||
|
||||
} else {
|
||||
System.out.print(e.getCause().getMessage());
|
||||
@ -85,27 +85,27 @@ public class CalculatorEngineTest {
|
||||
Assert.assertEquals("1", cm.evaluate(JsclOperation.simplify, "eq( 1, 1)").getResult());
|
||||
Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "lg(10)").getResult());
|
||||
Assert.assertEquals("4", cm.evaluate(JsclOperation.numeric, "2+2").getResult());
|
||||
final AngleUnits defaultAngleUnits = cm.getEngine().getDefaultAngleUnits();
|
||||
final AngleUnit defaultAngleUnit = cm.getEngine().getDefaultAngleUnit();
|
||||
try {
|
||||
cm.getEngine().setDefaultAngleUnits(AngleUnits.rad);
|
||||
cm.getEngine().setDefaultAngleUnit(AngleUnit.rad);
|
||||
Assert.assertEquals("-0.757", cm.evaluate(JsclOperation.numeric, "sin(4)").getResult());
|
||||
Assert.assertEquals("0.524", cm.evaluate(JsclOperation.numeric, "asin(0.5)").getResult());
|
||||
Assert.assertEquals("-0.396", cm.evaluate(JsclOperation.numeric, "sin(4)asin(0.5)").getResult());
|
||||
Assert.assertEquals("-0.56", cm.evaluate(JsclOperation.numeric, "sin(4)asin(0.5)√(2)").getResult());
|
||||
Assert.assertEquals("-0.56", cm.evaluate(JsclOperation.numeric, "sin(4)asin(0.5)√(2)").getResult());
|
||||
} finally {
|
||||
cm.getEngine().setDefaultAngleUnits(defaultAngleUnits);
|
||||
cm.getEngine().setDefaultAngleUnit(defaultAngleUnit);
|
||||
}
|
||||
Assert.assertEquals("7.389", cm.evaluate(JsclOperation.numeric, "e^2").getResult());
|
||||
Assert.assertEquals("7.389", cm.evaluate(JsclOperation.numeric, "exp(1)^2").getResult());
|
||||
Assert.assertEquals("7.389", cm.evaluate(JsclOperation.numeric, "exp(2)").getResult());
|
||||
Assert.assertEquals("2+i", cm.evaluate(JsclOperation.numeric, "2*1+√(-1)").getResult());
|
||||
try {
|
||||
cm.getEngine().setDefaultAngleUnits(AngleUnits.rad);
|
||||
cm.getEngine().setDefaultAngleUnit(AngleUnit.rad);
|
||||
Assert.assertEquals("0.921+3.142i", cm.evaluate(JsclOperation.numeric, "ln(5cosh(38π√(2cos(2))))").getResult());
|
||||
Assert.assertEquals("-3.41+3.41i", cm.evaluate(JsclOperation.numeric, "(5tan(2i)+2i)/(1-i)").getResult());
|
||||
} finally {
|
||||
cm.getEngine().setDefaultAngleUnits(defaultAngleUnits);
|
||||
cm.getEngine().setDefaultAngleUnit(defaultAngleUnit);
|
||||
}
|
||||
Assert.assertEquals("7.389i", cm.evaluate(JsclOperation.numeric, "iexp(2)").getResult());
|
||||
Assert.assertEquals("2+7.389i", cm.evaluate(JsclOperation.numeric, "2+iexp(2)").getResult());
|
||||
@ -143,14 +143,14 @@ public class CalculatorEngineTest {
|
||||
CalculatorEngine.instance.getVarsRegister().add(new Var.Builder("si", 5d));
|
||||
|
||||
try {
|
||||
cm.getEngine().setDefaultAngleUnits(AngleUnits.rad);
|
||||
cm.getEngine().setDefaultAngleUnit(AngleUnit.rad);
|
||||
Assert.assertEquals("-0.959", cm.evaluate(JsclOperation.numeric, "sin(5)").getResult());
|
||||
Assert.assertEquals("-4.795", cm.evaluate(JsclOperation.numeric, "sin(5)si").getResult());
|
||||
Assert.assertEquals("-23.973", cm.evaluate(JsclOperation.numeric, "sisin(5)si").getResult());
|
||||
Assert.assertEquals("-23.973", cm.evaluate(JsclOperation.numeric, "si*sin(5)si").getResult());
|
||||
Assert.assertEquals("-3.309", cm.evaluate(JsclOperation.numeric, "sisin(5si)si").getResult());
|
||||
} finally {
|
||||
cm.getEngine().setDefaultAngleUnits(defaultAngleUnits);
|
||||
cm.getEngine().setDefaultAngleUnit(defaultAngleUnit);
|
||||
}
|
||||
|
||||
CalculatorEngine.instance.getVarsRegister().add(new Var.Builder("s", 1d));
|
||||
@ -242,12 +242,12 @@ public class CalculatorEngineTest {
|
||||
} catch (ParseException e) {
|
||||
}
|
||||
|
||||
final AngleUnits defaultAngleUnits = cm.getEngine().getDefaultAngleUnits();
|
||||
final AngleUnit defaultAngleUnit = cm.getEngine().getDefaultAngleUnit();
|
||||
try {
|
||||
cm.getEngine().setDefaultAngleUnits(AngleUnits.rad);
|
||||
cm.getEngine().setDefaultAngleUnit(AngleUnit.rad);
|
||||
Assert.assertEquals("0.739", cm.evaluate(JsclOperation.numeric, "cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(1))))))))))))))))))))))))))))))))))))").getResult());
|
||||
} finally {
|
||||
cm.getEngine().setDefaultAngleUnits(defaultAngleUnits);
|
||||
cm.getEngine().setDefaultAngleUnit(defaultAngleUnit);
|
||||
}
|
||||
|
||||
CalculatorEngine.instance.getVarsRegister().add(new Var.Builder("si", 5d));
|
||||
@ -317,9 +317,9 @@ public class CalculatorEngineTest {
|
||||
public void testDegrees() throws Exception {
|
||||
final CalculatorEngine cm = CalculatorEngine.instance;
|
||||
|
||||
final AngleUnits defaultAngleUnits = cm.getEngine().getDefaultAngleUnits();
|
||||
final AngleUnit defaultAngleUnit = cm.getEngine().getDefaultAngleUnit();
|
||||
try {
|
||||
cm.getEngine().setDefaultAngleUnits(AngleUnits.rad);
|
||||
cm.getEngine().setDefaultAngleUnit(AngleUnit.rad);
|
||||
cm.setPrecision(3);
|
||||
try {
|
||||
Assert.assertEquals("0.017", cm.evaluate(JsclOperation.numeric, "°"));
|
||||
@ -340,7 +340,7 @@ public class CalculatorEngineTest {
|
||||
|
||||
Assert.assertEquals("∂(cos(t), t, t,1°)", cm.evaluate(JsclOperation.simplify, "∂(cos(t),t,t,1°)").getResult());
|
||||
} finally {
|
||||
cm.getEngine().setDefaultAngleUnits(defaultAngleUnits);
|
||||
cm.getEngine().setDefaultAngleUnit(defaultAngleUnit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user