Merge branch 'master' into dev
This commit is contained in:
commit
e41bc58e9f
46
calculatorpp-core/pom.xml
Normal file
46
calculatorpp-core/pom.xml
Normal file
@ -0,0 +1,46 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>org.solovyev.android</groupId>
|
||||
<artifactId>calculatorpp-parent</artifactId>
|
||||
<version>1.3.1</version>
|
||||
</parent>
|
||||
|
||||
<groupId>org.solovyev.android</groupId>
|
||||
<artifactId>calculatorpp-core</artifactId>
|
||||
<version>1.3.1</version>
|
||||
<name>Calculator++ Application Core</name>
|
||||
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.intellij</groupId>
|
||||
<artifactId>annotations</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.solovyev</groupId>
|
||||
<artifactId>jscl</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.simpleframework</groupId>
|
||||
<artifactId>simple-xml</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
|
||||
</project>
|
@ -4,7 +4,7 @@
|
||||
* or visit http://se.solovyev.org
|
||||
*/
|
||||
|
||||
package org.solovyev.android.calculator.model;
|
||||
package org.solovyev.android.calculator;
|
||||
|
||||
import jscl.MathEngine;
|
||||
import jscl.NumeralBase;
|
@ -0,0 +1,30 @@
|
||||
package org.solovyev.android.calculator;
|
||||
|
||||
import jscl.NumeralBase;
|
||||
import jscl.math.Generic;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.solovyev.android.calculator.jscl.JsclOperation;
|
||||
import org.solovyev.common.msg.MessageRegistry;
|
||||
|
||||
/**
|
||||
* User: Solovyev_S
|
||||
* Date: 20.09.12
|
||||
* Time: 16:38
|
||||
*/
|
||||
public interface Calculator extends CalculatorEventContainer {
|
||||
|
||||
@NotNull
|
||||
CalculatorEventDataId createFirstEventDataId();
|
||||
|
||||
void evaluate(@NotNull JsclOperation operation,
|
||||
@NotNull String expression);
|
||||
|
||||
@NotNull
|
||||
CalculatorEventDataId evaluate(@NotNull JsclOperation operation,
|
||||
@NotNull String expression,
|
||||
@Nullable MessageRegistry mr);
|
||||
|
||||
@NotNull
|
||||
CalculatorEventDataId convert(@NotNull Generic generic, @NotNull NumeralBase to);
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2011. Created by serso aka se.solovyev.
|
||||
* For more information, please, contact se.solovyev@gmail.com
|
||||
* or visit http://se.solovyev.org
|
||||
*/
|
||||
|
||||
package org.solovyev.android.calculator;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* User: serso
|
||||
* Date: 12/17/11
|
||||
* Time: 9:45 PM
|
||||
*/
|
||||
public interface CalculatorDisplay extends CalculatorEventListener {
|
||||
|
||||
void setView(@Nullable CalculatorDisplayView view);
|
||||
|
||||
@NotNull
|
||||
CalculatorDisplayViewState getViewState();
|
||||
|
||||
void setViewState(@NotNull CalculatorDisplayViewState viewState);
|
||||
|
||||
@NotNull
|
||||
CalculatorEventData getLastEventData();
|
||||
}
|
@ -0,0 +1,147 @@
|
||||
package org.solovyev.android.calculator;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import static org.solovyev.android.calculator.CalculatorEventType.*;
|
||||
|
||||
/**
|
||||
* User: serso
|
||||
* Date: 9/20/12
|
||||
* Time: 8:24 PM
|
||||
*/
|
||||
public class CalculatorDisplayImpl implements CalculatorDisplay {
|
||||
|
||||
@NotNull
|
||||
private CalculatorEventData lastCalculatorEventData = CalculatorEventDataImpl.newInstance(CalculatorLocatorImpl.getInstance().getCalculator().createFirstEventDataId());
|
||||
|
||||
@Nullable
|
||||
private CalculatorDisplayView view;
|
||||
|
||||
@NotNull
|
||||
private final Object viewLock = new Object();
|
||||
|
||||
@NotNull
|
||||
private CalculatorDisplayViewState lastViewState = CalculatorDisplayViewStateImpl.newDefaultInstance();
|
||||
|
||||
@Override
|
||||
public void setView(@Nullable CalculatorDisplayView view) {
|
||||
synchronized (viewLock) {
|
||||
this.view = view;
|
||||
|
||||
if (view != null) {
|
||||
this.view.setState(lastViewState);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public CalculatorDisplayViewState getViewState() {
|
||||
return this.lastViewState;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setViewState(@NotNull CalculatorDisplayViewState viewState) {
|
||||
synchronized (viewLock) {
|
||||
this.lastViewState = viewState;
|
||||
if (this.view != null) {
|
||||
this.view.setState(viewState);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* @Override
|
||||
@Nullable
|
||||
public CharSequence getText() {
|
||||
synchronized (viewLock) {
|
||||
return view != null ? view.getText() : null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setText(@Nullable CharSequence text) {
|
||||
synchronized (viewLock) {
|
||||
if (view != null) {
|
||||
view.setText(text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSelection() {
|
||||
synchronized (viewLock) {
|
||||
return view != null ? view.getSelection() : 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSelection(int selection) {
|
||||
synchronized (viewLock) {
|
||||
if (view != null) {
|
||||
view.setSelection(selection);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public CalculatorEventData getLastEventData() {
|
||||
return lastCalculatorEventData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCalculatorEvent(@NotNull CalculatorEventData calculatorEventData,
|
||||
@NotNull CalculatorEventType calculatorEventType,
|
||||
@Nullable Object data) {
|
||||
if (calculatorEventType.isOfType(calculation_result, calculation_failed, calculation_cancelled)) {
|
||||
|
||||
if (calculatorEventData.isAfter(lastCalculatorEventData)) {
|
||||
lastCalculatorEventData = calculatorEventData;
|
||||
}
|
||||
|
||||
switch (calculatorEventType) {
|
||||
case calculation_result:
|
||||
processCalculationResult((CalculatorEvaluationEventData)calculatorEventData, (CalculatorOutput) data);
|
||||
break;
|
||||
case calculation_cancelled:
|
||||
processCalculationCancelled((CalculatorEvaluationEventData)calculatorEventData);
|
||||
break;
|
||||
case calculation_failed:
|
||||
processCalculationFailed((CalculatorEvaluationEventData)calculatorEventData, (CalculatorFailure) data);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void processCalculationFailed(@NotNull CalculatorEvaluationEventData calculatorEventData, @NotNull CalculatorFailure data) {
|
||||
|
||||
final CalculatorEvalException calculatorEvalException = data.getCalculationEvalException();
|
||||
|
||||
final String errorMessage;
|
||||
if (calculatorEvalException != null) {
|
||||
errorMessage = CalculatorMessages.getBundle().getString(CalculatorMessages.syntax_error);
|
||||
} else {
|
||||
final CalculatorParseException calculationParseException = data.getCalculationParseException();
|
||||
if (calculationParseException != null) {
|
||||
errorMessage = calculationParseException.getLocalizedMessage();
|
||||
} else {
|
||||
errorMessage = CalculatorMessages.getBundle().getString(CalculatorMessages.syntax_error);
|
||||
}
|
||||
}
|
||||
|
||||
this.setViewState(CalculatorDisplayViewStateImpl.newErrorState(calculatorEventData.getOperation(), errorMessage));
|
||||
}
|
||||
|
||||
private void processCalculationCancelled(@NotNull CalculatorEvaluationEventData calculatorEventData) {
|
||||
final String errorMessage = CalculatorMessages.getBundle().getString(CalculatorMessages.syntax_error);
|
||||
|
||||
this.setViewState(CalculatorDisplayViewStateImpl.newErrorState(calculatorEventData.getOperation(), errorMessage));
|
||||
}
|
||||
|
||||
private void processCalculationResult(@NotNull CalculatorEvaluationEventData calculatorEventData, @NotNull CalculatorOutput data) {
|
||||
final String stringResult = data.getStringResult();
|
||||
this.setViewState(CalculatorDisplayViewStateImpl.newValidState(calculatorEventData.getOperation(), data.getResult(), stringResult, 0));
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package org.solovyev.android.calculator;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* User: serso
|
||||
* Date: 9/20/12
|
||||
* Time: 8:25 PM
|
||||
*/
|
||||
public interface CalculatorDisplayView {
|
||||
|
||||
void setState(@NotNull CalculatorDisplayViewState state);
|
||||
|
||||
@NotNull
|
||||
CalculatorDisplayViewState getState();
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
package org.solovyev.android.calculator;
|
||||
|
||||
import jscl.math.Generic;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.solovyev.android.calculator.jscl.JsclOperation;
|
||||
|
||||
/**
|
||||
* User: serso
|
||||
* Date: 9/20/12
|
||||
* Time: 9:50 PM
|
||||
*/
|
||||
public interface CalculatorDisplayViewState {
|
||||
|
||||
@NotNull
|
||||
String getText();
|
||||
|
||||
int getSelection();
|
||||
|
||||
@Nullable
|
||||
Generic getResult();
|
||||
|
||||
boolean isValid();
|
||||
|
||||
@Nullable
|
||||
String getErrorMessage();
|
||||
|
||||
@NotNull
|
||||
JsclOperation getOperation();
|
||||
|
||||
@Nullable
|
||||
String getStringResult();
|
||||
}
|
@ -0,0 +1,104 @@
|
||||
package org.solovyev.android.calculator;
|
||||
|
||||
import jscl.math.Generic;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.solovyev.android.calculator.jscl.JsclOperation;
|
||||
import org.solovyev.common.text.StringUtils;
|
||||
|
||||
/**
|
||||
* User: serso
|
||||
* Date: 9/20/12
|
||||
* Time: 9:50 PM
|
||||
*/
|
||||
public class CalculatorDisplayViewStateImpl implements CalculatorDisplayViewState {
|
||||
|
||||
@NotNull
|
||||
private JsclOperation operation = JsclOperation.numeric;
|
||||
|
||||
@Nullable
|
||||
private Generic result;
|
||||
|
||||
@Nullable
|
||||
private String stringResult = "";
|
||||
|
||||
private boolean valid = true;
|
||||
|
||||
@Nullable
|
||||
private String errorMessage;
|
||||
|
||||
private int selection = 0;
|
||||
|
||||
private CalculatorDisplayViewStateImpl() {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static CalculatorDisplayViewState newDefaultInstance() {
|
||||
return new CalculatorDisplayViewStateImpl();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static CalculatorDisplayViewState newErrorState(@NotNull JsclOperation operation,
|
||||
@NotNull String errorMessage) {
|
||||
final CalculatorDisplayViewStateImpl calculatorDisplayState = new CalculatorDisplayViewStateImpl();
|
||||
calculatorDisplayState.valid = false;
|
||||
calculatorDisplayState.errorMessage = errorMessage;
|
||||
calculatorDisplayState.operation = operation;
|
||||
return calculatorDisplayState;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static CalculatorDisplayViewState newValidState(@NotNull JsclOperation operation,
|
||||
@Nullable Generic result,
|
||||
@NotNull String stringResult,
|
||||
int selection) {
|
||||
final CalculatorDisplayViewStateImpl calculatorDisplayState = new CalculatorDisplayViewStateImpl();
|
||||
calculatorDisplayState.valid = true;
|
||||
calculatorDisplayState.result = result;
|
||||
calculatorDisplayState.stringResult = stringResult;
|
||||
calculatorDisplayState.operation = operation;
|
||||
calculatorDisplayState.selection = selection;
|
||||
|
||||
return calculatorDisplayState;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getText() {
|
||||
return StringUtils.getNotEmpty(isValid() ? stringResult : errorMessage, "");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSelection() {
|
||||
return selection;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Generic getResult() {
|
||||
return this.result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid() {
|
||||
return this.valid;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getErrorMessage() {
|
||||
return this.errorMessage;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public String getStringResult() {
|
||||
return stringResult;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public JsclOperation getOperation() {
|
||||
return this.operation;
|
||||
}
|
||||
}
|
@ -4,9 +4,8 @@
|
||||
* or visit http://se.solovyev.org
|
||||
*/
|
||||
|
||||
package org.solovyev.android.calculator.model;
|
||||
package org.solovyev.android.calculator;
|
||||
|
||||
import jscl.AbstractJsclArithmeticException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.solovyev.common.exceptions.SersoException;
|
||||
import org.solovyev.common.msg.Message;
|
@ -0,0 +1,18 @@
|
||||
package org.solovyev.android.calculator;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.solovyev.android.calculator.jscl.JsclOperation;
|
||||
|
||||
/**
|
||||
* User: serso
|
||||
* Date: 9/20/12
|
||||
* Time: 10:00 PM
|
||||
*/
|
||||
public interface CalculatorEvaluationEventData extends CalculatorEventData{
|
||||
|
||||
@NotNull
|
||||
JsclOperation getOperation();
|
||||
|
||||
@NotNull
|
||||
String getExpression();
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
package org.solovyev.android.calculator;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.solovyev.android.calculator.jscl.JsclOperation;
|
||||
|
||||
/**
|
||||
* User: serso
|
||||
* Date: 9/20/12
|
||||
* Time: 10:01 PM
|
||||
*/
|
||||
public class CalculatorEvaluationEventDataImpl implements CalculatorEvaluationEventData {
|
||||
|
||||
@NotNull
|
||||
private final CalculatorEventData calculatorEventData;
|
||||
|
||||
@NotNull
|
||||
private final JsclOperation operation;
|
||||
|
||||
@NotNull
|
||||
private final String expression;
|
||||
|
||||
public CalculatorEvaluationEventDataImpl(@NotNull CalculatorEventData calculatorEventData,
|
||||
@NotNull JsclOperation operation,
|
||||
@NotNull String expression) {
|
||||
this.calculatorEventData = calculatorEventData;
|
||||
this.operation = operation;
|
||||
this.expression = expression;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public JsclOperation getOperation() {
|
||||
return this.operation;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getExpression() {
|
||||
return this.expression;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEventId() {
|
||||
return calculatorEventData.getEventId();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Long getSequenceId() {
|
||||
return calculatorEventData.getSequenceId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAfter(@NotNull CalculatorEventDataId calculatorEventDataId) {
|
||||
return calculatorEventData.isAfter(calculatorEventDataId);
|
||||
}
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
package org.solovyev.android.calculator;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* User: Solovyev_S
|
||||
* Date: 20.09.12
|
||||
* Time: 16:39
|
||||
*/
|
||||
public interface CalculatorEventContainer {
|
||||
|
||||
void addCalculatorEventListener(@NotNull CalculatorEventListener calculatorEventListener);
|
||||
|
||||
void removeCalculatorEventListener(@NotNull CalculatorEventListener calculatorEventListener);
|
||||
|
||||
void fireCalculatorEvent(@NotNull CalculatorEventData calculatorEventData, @NotNull CalculatorEventType calculatorEventType, @Nullable Object data);
|
||||
|
||||
void fireCalculatorEvents(@NotNull List<CalculatorEvent> calculatorEvents);
|
||||
|
||||
public static class CalculatorEvent {
|
||||
|
||||
@NotNull
|
||||
private CalculatorEventData calculatorEventData;
|
||||
|
||||
@NotNull
|
||||
private CalculatorEventType calculatorEventType;
|
||||
|
||||
@Nullable
|
||||
private Object data;
|
||||
|
||||
public CalculatorEvent(@NotNull CalculatorEventData calculatorEventData,
|
||||
@NotNull CalculatorEventType calculatorEventType,
|
||||
@Nullable Object data) {
|
||||
this.calculatorEventData = calculatorEventData;
|
||||
this.calculatorEventType = calculatorEventType;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public CalculatorEventData getCalculatorEventData() {
|
||||
return calculatorEventData;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public CalculatorEventType getCalculatorEventType() {
|
||||
return calculatorEventType;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Object getData() {
|
||||
return data;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
package org.solovyev.android.calculator;
|
||||
|
||||
/**
|
||||
* User: Solovyev_S
|
||||
* Date: 20.09.12
|
||||
* Time: 16:51
|
||||
*/
|
||||
public interface CalculatorEventData extends CalculatorEventDataId {
|
||||
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package org.solovyev.android.calculator;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* User: Solovyev_S
|
||||
* Date: 20.09.12
|
||||
* Time: 18:18
|
||||
*/
|
||||
public interface CalculatorEventDataId {
|
||||
|
||||
// the higher id => the later event
|
||||
long getEventId();
|
||||
|
||||
// the higher id => the later event
|
||||
@Nullable
|
||||
Long getSequenceId();
|
||||
|
||||
boolean isAfter(@NotNull CalculatorEventDataId calculatorEventDataId);
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
package org.solovyev.android.calculator;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* User: Solovyev_S
|
||||
* Date: 20.09.12
|
||||
* Time: 18:18
|
||||
*/
|
||||
class CalculatorEventDataIdImpl implements CalculatorEventDataId {
|
||||
|
||||
private final long eventId;
|
||||
|
||||
@Nullable
|
||||
private final Long sequenceId;
|
||||
|
||||
private CalculatorEventDataIdImpl(long id, @Nullable Long sequenceId) {
|
||||
this.eventId = id;
|
||||
this.sequenceId = sequenceId;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
static CalculatorEventDataId newInstance(long id, @Nullable Long sequenceId) {
|
||||
return new CalculatorEventDataIdImpl(id, sequenceId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEventId() {
|
||||
return this.eventId;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Long getSequenceId() {
|
||||
return this.sequenceId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAfter(@NotNull CalculatorEventDataId calculatorEventDataId) {
|
||||
return this.eventId > calculatorEventDataId.getEventId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof CalculatorEventDataIdImpl)) return false;
|
||||
|
||||
CalculatorEventDataIdImpl that = (CalculatorEventDataIdImpl) o;
|
||||
|
||||
if (eventId != that.eventId) return false;
|
||||
if (sequenceId != null ? !sequenceId.equals(that.sequenceId) : that.sequenceId != null)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = (int) (eventId ^ (eventId >>> 32));
|
||||
result = 31 * result + (sequenceId != null ? sequenceId.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
package org.solovyev.android.calculator;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* User: Solovyev_S
|
||||
* Date: 20.09.12
|
||||
* Time: 16:54
|
||||
*/
|
||||
class CalculatorEventDataImpl implements CalculatorEventData {
|
||||
|
||||
@NotNull
|
||||
private CalculatorEventDataId calculatorEventDataId;
|
||||
|
||||
private CalculatorEventDataImpl(@NotNull CalculatorEventDataId calculatorEventDataId) {
|
||||
this.calculatorEventDataId = calculatorEventDataId;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static CalculatorEventData newInstance(@NotNull CalculatorEventDataId calculatorEventDataId) {
|
||||
return new CalculatorEventDataImpl(calculatorEventDataId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEventId() {
|
||||
return calculatorEventDataId.getEventId();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Long getSequenceId() {
|
||||
return calculatorEventDataId.getSequenceId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAfter(@NotNull CalculatorEventDataId calculatorEventDataId) {
|
||||
return this.calculatorEventDataId.isAfter(calculatorEventDataId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof CalculatorEventDataImpl)) return false;
|
||||
|
||||
CalculatorEventDataImpl that = (CalculatorEventDataImpl) o;
|
||||
|
||||
if (!calculatorEventDataId.equals(that.calculatorEventDataId)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return calculatorEventDataId.hashCode();
|
||||
}
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package org.solovyev.android.calculator;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.EventListener;
|
||||
|
||||
/**
|
||||
* User: Solovyev_S
|
||||
* Date: 20.09.12
|
||||
* Time: 16:39
|
||||
*/
|
||||
public interface CalculatorEventListener extends EventListener {
|
||||
|
||||
void onCalculatorEvent(@NotNull CalculatorEventData calculatorEventData, @NotNull CalculatorEventType calculatorEventType, @Nullable Object data);
|
||||
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
package org.solovyev.android.calculator;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* User: Solovyev_S
|
||||
* Date: 20.09.12
|
||||
* Time: 16:40
|
||||
*/
|
||||
public enum CalculatorEventType {
|
||||
|
||||
/*
|
||||
**********************************************************************
|
||||
*
|
||||
* org.solovyev.android.calculator.CalculatorEvaluationEventData
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
// @NotNull org.solovyev.android.calculator.CalculatorInput
|
||||
calculation_started,
|
||||
|
||||
// @NotNull org.solovyev.android.calculator.CalculatorOutput
|
||||
calculation_result,
|
||||
|
||||
calculation_cancelled,
|
||||
|
||||
calculation_finished,
|
||||
|
||||
// @NotNull org.solovyev.android.calculator.CalculatorFailure
|
||||
calculation_failed,
|
||||
|
||||
/*
|
||||
**********************************************************************
|
||||
*
|
||||
* CONVERSION
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
conversion_started,
|
||||
|
||||
// @NotNull String conversion result
|
||||
conversion_finished;
|
||||
|
||||
public boolean isOfType(@NotNull CalculatorEventType... types) {
|
||||
for (CalculatorEventType type : types) {
|
||||
if ( this == type ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package org.solovyev.android.calculator;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* User: serso
|
||||
* Date: 9/20/12
|
||||
* Time: 7:33 PM
|
||||
*/
|
||||
public interface CalculatorFailure {
|
||||
|
||||
@NotNull
|
||||
Exception getException();
|
||||
|
||||
@Nullable
|
||||
CalculatorParseException getCalculationParseException();
|
||||
|
||||
@Nullable
|
||||
CalculatorEvalException getCalculationEvalException();
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
package org.solovyev.android.calculator;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* User: serso
|
||||
* Date: 9/20/12
|
||||
* Time: 7:34 PM
|
||||
*/
|
||||
public class CalculatorFailureImpl implements CalculatorFailure {
|
||||
|
||||
@NotNull
|
||||
private Exception exception;
|
||||
|
||||
public CalculatorFailureImpl(@NotNull Exception exception) {
|
||||
this.exception = exception;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Exception getException() {
|
||||
return this.exception;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CalculatorParseException getCalculationParseException() {
|
||||
return exception instanceof CalculatorParseException ? (CalculatorParseException)exception : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CalculatorEvalException getCalculationEvalException() {
|
||||
return exception instanceof CalculatorEvalException ? (CalculatorEvalException)exception : null;
|
||||
}
|
||||
}
|
@ -0,0 +1,291 @@
|
||||
package org.solovyev.android.calculator;
|
||||
|
||||
import jscl.AbstractJsclArithmeticException;
|
||||
import jscl.NumeralBase;
|
||||
import jscl.NumeralBaseException;
|
||||
import jscl.math.Generic;
|
||||
import jscl.text.ParseInterruptedException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.solovyev.android.calculator.jscl.JsclOperation;
|
||||
import org.solovyev.android.calculator.text.TextProcessor;
|
||||
import org.solovyev.common.msg.MessageRegistry;
|
||||
import org.solovyev.common.msg.MessageType;
|
||||
import org.solovyev.common.text.StringUtils;
|
||||
import org.solovyev.math.units.UnitConverter;
|
||||
import org.solovyev.math.units.UnitImpl;
|
||||
import org.solovyev.math.units.UnitType;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
/**
|
||||
* User: Solovyev_S
|
||||
* Date: 20.09.12
|
||||
* Time: 16:42
|
||||
*/
|
||||
public class CalculatorImpl implements Calculator {
|
||||
|
||||
private static final long FIRST_ID = 0;
|
||||
|
||||
@NotNull
|
||||
private final CalculatorEventContainer calculatorEventContainer = new ListCalculatorEventContainer();
|
||||
|
||||
@NotNull
|
||||
private final AtomicLong counter = new AtomicLong(FIRST_ID);
|
||||
|
||||
@NotNull
|
||||
private final Object lock = new Object();
|
||||
|
||||
@NotNull
|
||||
private final TextProcessor<PreparedExpression, String> preprocessor = ToJsclTextProcessor.getInstance();
|
||||
|
||||
@NotNull
|
||||
private final Executor threadPoolExecutor = Executors.newFixedThreadPool(10);
|
||||
|
||||
public CalculatorImpl() {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String doConversion(@NotNull UnitConverter<String> converter,
|
||||
@Nullable String from,
|
||||
@NotNull UnitType<String> fromUnitType,
|
||||
@NotNull UnitType<String> toUnitType) throws ConversionException{
|
||||
final String result;
|
||||
|
||||
if (StringUtils.isEmpty(from)) {
|
||||
result = "";
|
||||
} else {
|
||||
|
||||
String to = null;
|
||||
try {
|
||||
if (converter.isSupported(fromUnitType, toUnitType)) {
|
||||
to = converter.convert(UnitImpl.newInstance(from, fromUnitType), toUnitType).getValue();
|
||||
}
|
||||
} catch (RuntimeException e) {
|
||||
throw new ConversionException(e);
|
||||
}
|
||||
|
||||
result = to;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private CalculatorEventDataId nextCalculatorEventDataId() {
|
||||
long eventId = counter.incrementAndGet();
|
||||
return CalculatorEventDataIdImpl.newInstance(eventId, eventId);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private CalculatorEventDataId nextEventDataId(@NotNull Long sequenceId) {
|
||||
long eventId = counter.incrementAndGet();
|
||||
return CalculatorEventDataIdImpl.newInstance(eventId, sequenceId);
|
||||
}
|
||||
|
||||
/*
|
||||
**********************************************************************
|
||||
*
|
||||
* CALCULATION
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public CalculatorEventDataId createFirstEventDataId() {
|
||||
return CalculatorEventDataIdImpl.newInstance(FIRST_ID, FIRST_ID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void evaluate(@NotNull JsclOperation operation,
|
||||
@NotNull String expression) {
|
||||
evaluate(operation, expression, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public CalculatorEventDataId evaluate(@NotNull final JsclOperation operation,
|
||||
@NotNull final String expression,
|
||||
@Nullable final MessageRegistry mr) {
|
||||
|
||||
final CalculatorEventDataId eventDataId = nextCalculatorEventDataId();
|
||||
|
||||
threadPoolExecutor.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
CalculatorImpl.this.evaluate(eventDataId.getSequenceId(), operation, expression, mr);
|
||||
}
|
||||
});
|
||||
|
||||
return eventDataId;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public CalculatorEventDataId convert(@NotNull final Generic generic,
|
||||
@NotNull final NumeralBase to) {
|
||||
final CalculatorEventDataId eventDataId = nextCalculatorEventDataId();
|
||||
|
||||
threadPoolExecutor.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final Long sequenceId = eventDataId.getSequenceId();
|
||||
assert sequenceId != null;
|
||||
|
||||
fireCalculatorEvent(newConversionEventData(sequenceId), CalculatorEventType.conversion_started, null);
|
||||
|
||||
final NumeralBase from = CalculatorLocatorImpl.getInstance().getCalculatorEngine().getEngine().getNumeralBase();
|
||||
|
||||
if (from != to) {
|
||||
String fromString = generic.toString();
|
||||
if (!StringUtils.isEmpty(fromString)) {
|
||||
try {
|
||||
fromString = ToJsclTextProcessor.getInstance().process(fromString).getExpression();
|
||||
} catch (CalculatorParseException e) {
|
||||
// ok, problems while processing occurred
|
||||
}
|
||||
}
|
||||
|
||||
// todo serso: continue
|
||||
//doConversion(AndroidNumeralBase.getConverter(), fromString, AndroidNumeralBase.valueOf(fromString), AndroidNumeralBase.valueOf(to));
|
||||
} else {
|
||||
fireCalculatorEvent(newConversionEventData(sequenceId), CalculatorEventType.conversion_finished, generic.toString());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return eventDataId;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private CalculatorEventData newConversionEventData(@NotNull Long sequenceId) {
|
||||
return CalculatorEventDataImpl.newInstance(nextEventDataId(sequenceId));
|
||||
}
|
||||
|
||||
private void evaluate(@NotNull Long sequenceId,
|
||||
@NotNull JsclOperation operation,
|
||||
@NotNull String expression,
|
||||
@Nullable MessageRegistry mr) {
|
||||
synchronized (lock) {
|
||||
|
||||
PreparedExpression preparedExpression = null;
|
||||
|
||||
fireCalculatorEvent(newCalculationEventData(operation, expression, sequenceId), CalculatorEventType.calculation_started, new CalculatorInputImpl(expression, operation));
|
||||
|
||||
try {
|
||||
preparedExpression = preprocessor.process(expression);
|
||||
|
||||
final String jsclExpression = preparedExpression.toString();
|
||||
|
||||
try {
|
||||
|
||||
final Generic result = operation.evaluateGeneric(jsclExpression);
|
||||
|
||||
// NOTE: toString() method must be called here as ArithmeticOperationException may occur in it (just to avoid later check!)
|
||||
result.toString();
|
||||
|
||||
final CalculatorOutputImpl data = new CalculatorOutputImpl(operation.getFromProcessor().process(result), operation, result);
|
||||
fireCalculatorEvent(newCalculationEventData(operation, expression, sequenceId), CalculatorEventType.calculation_result, data);
|
||||
|
||||
} catch (AbstractJsclArithmeticException e) {
|
||||
handleException(sequenceId, operation, expression, mr, new CalculatorEvalException(e, e, jsclExpression));
|
||||
}
|
||||
|
||||
} catch (ArithmeticException e) {
|
||||
handleException(sequenceId, operation, expression, mr, preparedExpression, new CalculatorParseException(expression, new CalculatorMessage(CalculatorMessages.msg_001, MessageType.error, e.getMessage())));
|
||||
} catch (StackOverflowError e) {
|
||||
handleException(sequenceId, operation, expression, mr, preparedExpression, new CalculatorParseException(expression, new CalculatorMessage(CalculatorMessages.msg_002, MessageType.error)));
|
||||
} catch (jscl.text.ParseException e) {
|
||||
handleException(sequenceId, operation, expression, mr, preparedExpression, new CalculatorParseException(e));
|
||||
} catch (ParseInterruptedException e) {
|
||||
|
||||
// do nothing - we ourselves interrupt the calculations
|
||||
fireCalculatorEvent(newCalculationEventData(operation, expression, sequenceId), CalculatorEventType.calculation_cancelled, null);
|
||||
|
||||
} catch (CalculatorParseException e) {
|
||||
handleException(sequenceId, operation, expression, mr, preparedExpression, e);
|
||||
} finally {
|
||||
fireCalculatorEvent(newCalculationEventData(operation, expression, sequenceId), CalculatorEventType.calculation_finished, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private CalculatorEventData newCalculationEventData(@NotNull JsclOperation operation,
|
||||
@NotNull String expression,
|
||||
@NotNull Long calculationId) {
|
||||
return new CalculatorEvaluationEventDataImpl(CalculatorEventDataImpl.newInstance(nextEventDataId(calculationId)), operation, expression);
|
||||
}
|
||||
|
||||
private void handleException(@NotNull Long calculationId,
|
||||
@NotNull JsclOperation operation,
|
||||
@NotNull String expression,
|
||||
@Nullable MessageRegistry mr,
|
||||
@Nullable PreparedExpression preparedExpression,
|
||||
@NotNull CalculatorParseException parseException) {
|
||||
|
||||
if (operation == JsclOperation.numeric
|
||||
&& preparedExpression != null
|
||||
&& preparedExpression.isExistsUndefinedVar()) {
|
||||
|
||||
evaluate(calculationId, JsclOperation.simplify, expression, mr);
|
||||
|
||||
}
|
||||
|
||||
fireCalculatorEvent(newCalculationEventData(operation, expression, calculationId), CalculatorEventType.calculation_failed, new CalculatorFailureImpl(parseException));
|
||||
}
|
||||
|
||||
private void handleException(@NotNull Long calculationId,
|
||||
@NotNull JsclOperation operation,
|
||||
@NotNull String expression,
|
||||
@Nullable MessageRegistry mr,
|
||||
@NotNull CalculatorEvalException evalException) {
|
||||
|
||||
if (operation == JsclOperation.numeric && evalException.getCause() instanceof NumeralBaseException) {
|
||||
evaluate(calculationId, JsclOperation.simplify, expression, mr);
|
||||
}
|
||||
|
||||
fireCalculatorEvent(newCalculationEventData(operation, expression, calculationId), CalculatorEventType.calculation_failed, new CalculatorFailureImpl(evalException));
|
||||
}
|
||||
|
||||
/*
|
||||
**********************************************************************
|
||||
*
|
||||
* EVENTS
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
@Override
|
||||
public void addCalculatorEventListener(@NotNull CalculatorEventListener calculatorEventListener) {
|
||||
calculatorEventContainer.addCalculatorEventListener(calculatorEventListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeCalculatorEventListener(@NotNull CalculatorEventListener calculatorEventListener) {
|
||||
calculatorEventContainer.removeCalculatorEventListener(calculatorEventListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fireCalculatorEvent(@NotNull CalculatorEventData calculatorEventData, @NotNull CalculatorEventType calculatorEventType, @Nullable Object data) {
|
||||
calculatorEventContainer.fireCalculatorEvent(calculatorEventData, calculatorEventType, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fireCalculatorEvents(@NotNull List<CalculatorEvent> calculatorEvents) {
|
||||
calculatorEventContainer.fireCalculatorEvents(calculatorEvents);
|
||||
}
|
||||
|
||||
public static final class ConversionException extends Exception {
|
||||
private ConversionException() {
|
||||
}
|
||||
|
||||
private ConversionException(Throwable throwable) {
|
||||
super(throwable);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package org.solovyev.android.calculator;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.solovyev.android.calculator.jscl.JsclOperation;
|
||||
|
||||
/**
|
||||
* User: serso
|
||||
* Date: 9/20/12
|
||||
* Time: 7:25 PM
|
||||
*/
|
||||
public interface CalculatorInput {
|
||||
|
||||
@NotNull
|
||||
String getExpression();
|
||||
|
||||
@NotNull
|
||||
JsclOperation getOperation();
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
package org.solovyev.android.calculator;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.solovyev.android.calculator.jscl.JsclOperation;
|
||||
|
||||
/**
|
||||
* User: serso
|
||||
* Date: 9/20/12
|
||||
* Time: 7:26 PM
|
||||
*/
|
||||
public class CalculatorInputImpl implements CalculatorInput {
|
||||
|
||||
@NotNull
|
||||
private String expression;
|
||||
|
||||
@NotNull
|
||||
private JsclOperation operation;
|
||||
|
||||
public CalculatorInputImpl(@NotNull String expression, @NotNull JsclOperation operation) {
|
||||
this.expression = expression;
|
||||
this.operation = operation;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public String getExpression() {
|
||||
return expression;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public JsclOperation getOperation() {
|
||||
return operation;
|
||||
}
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package org.solovyev.android.calculator;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* User: Solovyev_S
|
||||
* Date: 20.09.12
|
||||
* Time: 12:45
|
||||
*/
|
||||
public interface CalculatorLocator {
|
||||
|
||||
@NotNull
|
||||
JCalculatorEngine getCalculatorEngine();
|
||||
|
||||
@NotNull
|
||||
Calculator getCalculator();
|
||||
|
||||
@NotNull
|
||||
CalculatorDisplay getCalculatorDisplay();
|
||||
|
||||
void setCalculatorEngine(@NotNull JCalculatorEngine calculatorEngine);
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
package org.solovyev.android.calculator;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* User: Solovyev_S
|
||||
* Date: 20.09.12
|
||||
* Time: 12:45
|
||||
*/
|
||||
public class CalculatorLocatorImpl implements CalculatorLocator {
|
||||
|
||||
@NotNull
|
||||
private JCalculatorEngine calculatorEngine;
|
||||
|
||||
@NotNull
|
||||
private CalculatorDisplay calculatorDisplay = new CalculatorDisplayImpl();
|
||||
|
||||
@NotNull
|
||||
private Calculator calculator = new CalculatorImpl();
|
||||
|
||||
@NotNull
|
||||
private static final CalculatorLocator instance = new CalculatorLocatorImpl();
|
||||
|
||||
private CalculatorLocatorImpl() {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static CalculatorLocator getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public JCalculatorEngine getCalculatorEngine() {
|
||||
return calculatorEngine;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Calculator getCalculator() {
|
||||
return this.calculator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCalculatorEngine(@NotNull JCalculatorEngine calculatorEngine) {
|
||||
this.calculatorEngine = calculatorEngine;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public CalculatorDisplay getCalculatorDisplay() {
|
||||
return calculatorDisplay;
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
package org.solovyev.android.calculator;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.solovyev.common.msg.AbstractMessage;
|
||||
import org.solovyev.common.msg.MessageType;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
/**
|
||||
* User: serso
|
||||
* Date: 9/20/12
|
||||
* Time: 8:06 PM
|
||||
*/
|
||||
public class CalculatorMessage extends AbstractMessage {
|
||||
|
||||
protected CalculatorMessage(@NotNull String messageCode, @NotNull MessageType messageType, @org.jetbrains.annotations.Nullable Object... parameters) {
|
||||
super(messageCode, messageType, parameters);
|
||||
}
|
||||
|
||||
protected CalculatorMessage(@NotNull String messageCode, @NotNull MessageType messageType, @NotNull List<?> parameters) {
|
||||
super(messageCode, messageType, parameters);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getMessagePattern(@NotNull Locale locale) {
|
||||
final ResourceBundle rb = CalculatorMessages.getBundle(locale);
|
||||
return rb.getString(getMessageCode());
|
||||
}
|
||||
}
|
@ -0,0 +1,69 @@
|
||||
package org.solovyev.android.calculator;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
/**
|
||||
* User: serso
|
||||
* Date: 9/20/12
|
||||
* Time: 8:10 PM
|
||||
*/
|
||||
public final class CalculatorMessages {
|
||||
|
||||
@NotNull
|
||||
private static final Map<Locale, ResourceBundle> bundlesByLocale = new HashMap<Locale, ResourceBundle>();
|
||||
|
||||
private CalculatorMessages() {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static ResourceBundle getBundle() {
|
||||
return getBundle(Locale.getDefault());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static ResourceBundle getBundle(@NotNull Locale locale) {
|
||||
synchronized (bundlesByLocale) {
|
||||
ResourceBundle result = bundlesByLocale.get(locale);
|
||||
if (result == null) {
|
||||
result = ResourceBundle.getBundle("org/solovyev/android/calculator/messages", locale);
|
||||
bundlesByLocale.put(locale, result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/* Arithmetic error occurred: {0} */
|
||||
@NotNull
|
||||
public static final String msg_001 = "msg_1";
|
||||
|
||||
/* Too complex expression*/
|
||||
@NotNull
|
||||
public static final String msg_002 = "msg_2";
|
||||
|
||||
/* Too long execution time - check the expression*/
|
||||
@NotNull
|
||||
public static final String msg_003 = "msg_3";
|
||||
|
||||
/* Evaluation was cancelled*/
|
||||
@NotNull
|
||||
public static final String msg_004 = "msg_4";
|
||||
|
||||
/* No parameters are specified for function: {0}*/
|
||||
@NotNull
|
||||
public static final String msg_005 = "msg_5";
|
||||
|
||||
/* Infinite loop is detected in expression*/
|
||||
@NotNull
|
||||
public static final String msg_006 = "msg_6";
|
||||
|
||||
/* Error */
|
||||
@NotNull
|
||||
public static final String syntax_error = "syntax_error";
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package org.solovyev.android.calculator;
|
||||
|
||||
import jscl.math.Generic;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.solovyev.android.calculator.jscl.JsclOperation;
|
||||
|
||||
/**
|
||||
* User: serso
|
||||
* Date: 9/20/12
|
||||
* Time: 7:29 PM
|
||||
*/
|
||||
public interface CalculatorOutput {
|
||||
|
||||
@NotNull
|
||||
String getStringResult();
|
||||
|
||||
@NotNull
|
||||
JsclOperation getOperation();
|
||||
|
||||
@NotNull
|
||||
Generic getResult();
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
package org.solovyev.android.calculator;
|
||||
|
||||
import jscl.math.Generic;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.solovyev.android.calculator.jscl.JsclOperation;
|
||||
|
||||
/**
|
||||
* User: serso
|
||||
* Date: 9/20/12
|
||||
* Time: 7:28 PM
|
||||
*/
|
||||
public class CalculatorOutputImpl implements CalculatorOutput {
|
||||
|
||||
@NotNull
|
||||
private Generic result;
|
||||
|
||||
@NotNull
|
||||
private String stringResult;
|
||||
|
||||
@NotNull
|
||||
private JsclOperation operation;
|
||||
|
||||
public CalculatorOutputImpl(@NotNull String stringResult, @NotNull JsclOperation operation, @NotNull Generic result) {
|
||||
this.stringResult = stringResult;
|
||||
this.operation = operation;
|
||||
this.result = result;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public String getStringResult() {
|
||||
return stringResult;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public JsclOperation getOperation() {
|
||||
return operation;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public Generic getResult() {
|
||||
return result;
|
||||
}
|
||||
}
|
@ -4,12 +4,10 @@
|
||||
* or visit http://se.solovyev.org
|
||||
*/
|
||||
|
||||
package org.solovyev.android.calculator.model;
|
||||
package org.solovyev.android.calculator;
|
||||
|
||||
import android.app.Application;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.solovyev.android.msg.AndroidMessage;
|
||||
import org.solovyev.common.exceptions.SersoException;
|
||||
import org.solovyev.common.msg.Message;
|
||||
import org.solovyev.common.msg.MessageType;
|
||||
@ -39,14 +37,17 @@ public class CalculatorParseException extends SersoException implements Message
|
||||
this.position = jsclParseException.getPosition();
|
||||
}
|
||||
|
||||
public CalculatorParseException(@NotNull Integer messageId, @NotNull Application application, @Nullable Integer position, @NotNull String expression, Object... parameters) {
|
||||
this.message = new AndroidMessage(messageId, MessageType.error, application, parameters);
|
||||
public CalculatorParseException(@Nullable Integer position,
|
||||
@NotNull String expression,
|
||||
@NotNull Message message) {
|
||||
this.message = message;
|
||||
this.expression = expression;
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
public CalculatorParseException(@NotNull Integer messageId, @NotNull Application application, @NotNull String expression, Object... parameters) {
|
||||
this(messageId, application, null, expression, parameters);
|
||||
public CalculatorParseException(@NotNull String expression,
|
||||
@NotNull Message message) {
|
||||
this(null, expression, message);
|
||||
}
|
||||
|
||||
@NotNull
|
@ -4,7 +4,7 @@
|
||||
* or visit http://se.solovyev.org
|
||||
*/
|
||||
|
||||
package org.solovyev.android.calculator.history;
|
||||
package org.solovyev.android.calculator;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
@ -0,0 +1,34 @@
|
||||
package org.solovyev.android.calculator;
|
||||
|
||||
import jscl.MathEngine;
|
||||
import jscl.math.function.Function;
|
||||
import jscl.math.function.IConstant;
|
||||
import jscl.math.operator.Operator;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.solovyev.common.math.MathRegistry;
|
||||
|
||||
/**
|
||||
* User: Solovyev_S
|
||||
* Date: 20.09.12
|
||||
* Time: 12:43
|
||||
*/
|
||||
public interface JCalculatorEngine {
|
||||
|
||||
@NotNull
|
||||
String getMultiplicationSign();
|
||||
|
||||
@NotNull
|
||||
MathRegistry<IConstant> getVarsRegistry();
|
||||
|
||||
@NotNull
|
||||
MathRegistry<Function> getFunctionsRegistry();
|
||||
|
||||
@NotNull
|
||||
MathRegistry<Operator> getOperatorsRegistry();
|
||||
|
||||
@NotNull
|
||||
MathRegistry<Operator> getPostfixFunctionsRegistry();
|
||||
|
||||
@NotNull
|
||||
MathEngine getEngine();
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
package org.solovyev.android.calculator;
|
||||
|
||||
import android.util.Log;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.solovyev.common.utils.ListListenersContainer;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* User: Solovyev_S
|
||||
* Date: 20.09.12
|
||||
* Time: 16:42
|
||||
*/
|
||||
public class ListCalculatorEventContainer implements CalculatorEventContainer {
|
||||
|
||||
@NotNull
|
||||
private static final String TAG = "CalculatorEventData";
|
||||
|
||||
@NotNull
|
||||
private final ListListenersContainer<CalculatorEventListener> listeners = new ListListenersContainer<CalculatorEventListener>();
|
||||
|
||||
@Override
|
||||
public void addCalculatorEventListener(@NotNull CalculatorEventListener calculatorEventListener) {
|
||||
listeners.addListener(calculatorEventListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeCalculatorEventListener(@NotNull CalculatorEventListener calculatorEventListener) {
|
||||
listeners.removeListener(calculatorEventListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fireCalculatorEvent(@NotNull CalculatorEventData calculatorEventData, @NotNull CalculatorEventType calculatorEventType, @Nullable Object data) {
|
||||
fireCalculatorEvents(Arrays.asList(new CalculatorEvent(calculatorEventData, calculatorEventType, data)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fireCalculatorEvents(@NotNull List<CalculatorEvent> calculatorEvents) {
|
||||
final List<CalculatorEventListener> listeners = this.listeners.getListeners();
|
||||
|
||||
for (CalculatorEvent e : calculatorEvents) {
|
||||
Log.d(TAG, "Event: " + e.getCalculatorEventType() + " with data: " + e.getData());
|
||||
for (CalculatorEventListener listener : listeners) {
|
||||
listener.onCalculatorEvent(e.getCalculatorEventData(), e.getCalculatorEventType(), e.getData());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -4,7 +4,7 @@
|
||||
* or visit http://se.solovyev.org
|
||||
*/
|
||||
|
||||
package org.solovyev.android.calculator.model;
|
||||
package org.solovyev.android.calculator;
|
||||
|
||||
import jscl.MathEngine;
|
||||
import jscl.NumeralBase;
|
@ -4,7 +4,7 @@
|
||||
* or visit http://se.solovyev.org
|
||||
*/
|
||||
|
||||
package org.solovyev.android.calculator.model;
|
||||
package org.solovyev.android.calculator;
|
||||
|
||||
import jscl.MathContext;
|
||||
import jscl.MathEngine;
|
||||
@ -13,6 +13,7 @@ import jscl.math.numeric.Real;
|
||||
import jscl.text.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.solovyev.android.calculator.AbstractNumberBuilder;
|
||||
import org.solovyev.android.calculator.math.MathType;
|
||||
import org.solovyev.common.MutableObject;
|
||||
|
||||
@ -82,7 +83,7 @@ public class NumberBuilder extends AbstractNumberBuilder {
|
||||
|
||||
String number = null;
|
||||
|
||||
// save numeral base (as later it might be replaced)
|
||||
// toXml numeral base (as later it might be replaced)
|
||||
final NumeralBase localNb = getNumeralBase();
|
||||
|
||||
if (numberBuilder != null) {
|
@ -4,7 +4,7 @@
|
||||
* or visit http://se.solovyev.org
|
||||
*/
|
||||
|
||||
package org.solovyev.android.calculator.model;
|
||||
package org.solovyev.android.calculator;
|
||||
|
||||
import jscl.math.function.IConstant;
|
||||
import org.jetbrains.annotations.NotNull;
|
@ -4,15 +4,20 @@
|
||||
* or visit http://se.solovyev.org
|
||||
*/
|
||||
|
||||
package org.solovyev.android.calculator.model;
|
||||
package org.solovyev.android.calculator;
|
||||
|
||||
import jscl.math.function.IConstant;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.solovyev.android.calculator.CalculatorApplication;
|
||||
import org.solovyev.android.calculator.CalculatorParseException;
|
||||
import org.solovyev.android.calculator.PreparedExpression;
|
||||
import org.solovyev.android.calculator.R;
|
||||
import org.solovyev.android.calculator.text.TextProcessor;
|
||||
import org.solovyev.android.msg.AndroidMessage;
|
||||
import org.solovyev.common.StartsWithFinder;
|
||||
import org.solovyev.android.calculator.math.MathType;
|
||||
import org.solovyev.common.collections.CollectionsUtils;
|
||||
import org.solovyev.common.msg.MessageType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@ -75,7 +80,8 @@ public class ToJsclTextProcessor implements TextProcessor<PreparedExpression, St
|
||||
if (mathTypeBefore != null &&
|
||||
(mathTypeBefore.getMathType() == MathType.function || mathTypeBefore.getMathType() == MathType.operator) &&
|
||||
CollectionsUtils.find(MathType.openGroupSymbols, startsWithFinder) != null) {
|
||||
throw new CalculatorParseException(R.string.msg_5, CalculatorApplication.getInstance(), i, s, mathTypeBefore.getMatch());
|
||||
final AndroidMessage androidMessage = new AndroidMessage(R.string.msg_5, MessageType.error, CalculatorApplication.getInstance(), mathTypeBefore.getMatch());
|
||||
throw new CalculatorParseException(i, s, androidMessage);
|
||||
}
|
||||
|
||||
i = mathTypeResult.processToJscl(result, i);
|
||||
@ -86,7 +92,8 @@ public class ToJsclTextProcessor implements TextProcessor<PreparedExpression, St
|
||||
@NotNull
|
||||
private static PreparedExpression replaceVariables(@NotNull final String s, int depth, @NotNull List<IConstant> undefinedVars) throws CalculatorParseException {
|
||||
if (depth >= MAX_DEPTH) {
|
||||
throw new CalculatorParseException(R.string.msg_6, CalculatorApplication.getInstance(), s);
|
||||
final AndroidMessage androidMessage = new AndroidMessage(R.string.msg_6, MessageType.error, CalculatorApplication.getInstance());
|
||||
throw new CalculatorParseException(s, androidMessage);
|
||||
} else {
|
||||
depth++;
|
||||
}
|
@ -6,7 +6,6 @@
|
||||
|
||||
package org.solovyev.android.calculator.history;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.simpleframework.xml.Element;
|
||||
import org.simpleframework.xml.Transient;
|
@ -11,8 +11,11 @@ import org.jetbrains.annotations.Nullable;
|
||||
import org.simpleframework.xml.Element;
|
||||
import org.simpleframework.xml.Root;
|
||||
import org.simpleframework.xml.Transient;
|
||||
import org.solovyev.android.calculator.ICalculatorDisplay;
|
||||
import org.solovyev.android.calculator.CalculatorDisplay;
|
||||
import org.solovyev.android.calculator.CalculatorDisplayViewState;
|
||||
import org.solovyev.android.calculator.CalculatorDisplayViewStateImpl;
|
||||
import org.solovyev.android.calculator.jscl.JsclOperation;
|
||||
import org.solovyev.common.text.StringUtils;
|
||||
|
||||
/**
|
||||
* User: serso
|
||||
@ -47,24 +50,27 @@ public class CalculatorDisplayHistoryState implements Cloneable {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static CalculatorDisplayHistoryState newInstance(@NotNull ICalculatorDisplay display) {
|
||||
public static CalculatorDisplayHistoryState newInstance(@NotNull CalculatorDisplay display) {
|
||||
final CalculatorDisplayHistoryState result = new CalculatorDisplayHistoryState();
|
||||
|
||||
result.editorState = EditorHistoryState.newInstance(display);
|
||||
result.valid = display.isValid();
|
||||
result.jsclOperation = display.getJsclOperation();
|
||||
result.genericResult = display.getGenericResult();
|
||||
result.errorMessage = display.getErrorMessage();
|
||||
result.editorState = EditorHistoryState.newInstance(display.getViewState());
|
||||
|
||||
final CalculatorDisplayViewState displayViewState = display.getViewState();
|
||||
|
||||
result.valid = displayViewState.isValid();
|
||||
result.jsclOperation = displayViewState.getOperation();
|
||||
result.genericResult = displayViewState.getResult();
|
||||
result.errorMessage = displayViewState.getErrorMessage();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public void setValuesFromHistory(@NotNull ICalculatorDisplay display) {
|
||||
this.getEditorState().setValuesFromHistory(display);
|
||||
display.setValid(this.isValid());
|
||||
display.setErrorMessage(this.getErrorMessage());
|
||||
display.setJsclOperation(this.getJsclOperation());
|
||||
display.setGenericResult(this.getGenericResult());
|
||||
public void setValuesFromHistory(@NotNull CalculatorDisplay display) {
|
||||
if ( this.isValid() ) {
|
||||
display.setViewState(CalculatorDisplayViewStateImpl.newValidState(this.getJsclOperation(), this.getGenericResult(), StringUtils.getNotEmpty(this.getEditorState().getText(), ""), this.getEditorState().getCursorPosition()));
|
||||
} else {
|
||||
display.setViewState(CalculatorDisplayViewStateImpl.newErrorState(this.getJsclOperation(), StringUtils.getNotEmpty(this.getErrorMessage(), "")));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,20 @@
|
||||
package org.solovyev.android.calculator.history;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.solovyev.common.history.HistoryHelper;
|
||||
|
||||
/**
|
||||
* User: Solovyev_S
|
||||
* Date: 20.09.12
|
||||
* Time: 16:11
|
||||
*/
|
||||
public interface CalculatorHistory extends HistoryHelper<CalculatorHistoryState> {
|
||||
|
||||
void fromXml(@NotNull String xml);
|
||||
|
||||
String toXml();
|
||||
|
||||
void clearSavedHistory();
|
||||
|
||||
void removeSavedHistory(@NotNull CalculatorHistoryState historyState);
|
||||
}
|
@ -0,0 +1,131 @@
|
||||
package org.solovyev.android.calculator.history;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.solovyev.common.history.HistoryAction;
|
||||
import org.solovyev.common.history.HistoryHelper;
|
||||
import org.solovyev.common.history.SimpleHistoryHelper;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
* User: Solovyev_S
|
||||
* Date: 20.09.12
|
||||
* Time: 16:12
|
||||
*/
|
||||
public class CalculatorHistoryImpl implements CalculatorHistory {
|
||||
|
||||
private final AtomicInteger counter = new AtomicInteger(0);
|
||||
|
||||
@NotNull
|
||||
private final HistoryHelper<CalculatorHistoryState> history = new SimpleHistoryHelper<CalculatorHistoryState>();
|
||||
|
||||
@NotNull
|
||||
private final List<CalculatorHistoryState> savedHistory = new ArrayList<CalculatorHistoryState>();
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return this.history.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CalculatorHistoryState getLastHistoryState() {
|
||||
return this.history.getLastHistoryState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUndoAvailable() {
|
||||
return history.isUndoAvailable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CalculatorHistoryState undo(@Nullable CalculatorHistoryState currentState) {
|
||||
return history.undo(currentState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRedoAvailable() {
|
||||
return history.isRedoAvailable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CalculatorHistoryState redo(@Nullable CalculatorHistoryState currentState) {
|
||||
return history.redo(currentState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActionAvailable(@NotNull HistoryAction historyAction) {
|
||||
return history.isActionAvailable(historyAction);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CalculatorHistoryState doAction(@NotNull HistoryAction historyAction, @Nullable CalculatorHistoryState currentState) {
|
||||
return history.doAction(historyAction, currentState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addState(@Nullable CalculatorHistoryState currentState) {
|
||||
history.addState(currentState);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<CalculatorHistoryState> getStates() {
|
||||
return history.getStates();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
this.history.clear();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<CalculatorHistoryState> getSavedHistory() {
|
||||
return Collections.unmodifiableList(savedHistory);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public CalculatorHistoryState addSavedState(@NotNull CalculatorHistoryState historyState) {
|
||||
if (historyState.isSaved()) {
|
||||
return historyState;
|
||||
} else {
|
||||
final CalculatorHistoryState savedState = historyState.clone();
|
||||
|
||||
savedState.setId(counter.incrementAndGet());
|
||||
savedState.setSaved(true);
|
||||
|
||||
savedHistory.add(savedState);
|
||||
|
||||
return savedState;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fromXml(@NotNull String xml) {
|
||||
clearSavedHistory();
|
||||
|
||||
HistoryUtils.fromXml(xml, this.savedHistory);
|
||||
for (CalculatorHistoryState historyState : savedHistory) {
|
||||
historyState.setSaved(true);
|
||||
historyState.setId(counter.incrementAndGet());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toXml() {
|
||||
return HistoryUtils.toXml(this.savedHistory);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearSavedHistory() {
|
||||
this.savedHistory.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeSavedHistory(@NotNull CalculatorHistoryState historyState) {
|
||||
this.savedHistory.remove(historyState);
|
||||
}
|
||||
}
|
@ -8,7 +8,8 @@ package org.solovyev.android.calculator.history;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.simpleframework.xml.Element;
|
||||
import org.simpleframework.xml.Root;
|
||||
import org.solovyev.android.calculator.ICalculatorDisplay;
|
||||
import org.solovyev.android.calculator.CalculatorDisplay;
|
||||
import org.solovyev.android.calculator.Editor;
|
||||
|
||||
/**
|
||||
* User: serso
|
||||
@ -37,7 +38,7 @@ public class CalculatorHistoryState extends AbstractHistoryState {
|
||||
this.displayState = displayState;
|
||||
}
|
||||
|
||||
public static CalculatorHistoryState newInstance(@NotNull Editor editor, @NotNull ICalculatorDisplay display) {
|
||||
public static CalculatorHistoryState newInstance(@NotNull Editor editor, @NotNull CalculatorDisplay display) {
|
||||
final EditorHistoryState editorHistoryState = EditorHistoryState.newInstance(editor);
|
||||
final CalculatorDisplayHistoryState displayHistoryState = CalculatorDisplayHistoryState.newInstance(display);
|
||||
return new CalculatorHistoryState(editorHistoryState, displayHistoryState);
|
||||
@ -93,7 +94,7 @@ public class CalculatorHistoryState extends AbstractHistoryState {
|
||||
return result;
|
||||
}
|
||||
|
||||
public void setValuesFromHistory(@NotNull Editor editor, @NotNull ICalculatorDisplay display) {
|
||||
public void setValuesFromHistory(@NotNull Editor editor, @NotNull CalculatorDisplay display) {
|
||||
this.getEditorState().setValuesFromHistory(editor);
|
||||
this.getDisplayState().setValuesFromHistory(display);
|
||||
}
|
@ -9,6 +9,8 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.simpleframework.xml.Element;
|
||||
import org.simpleframework.xml.Root;
|
||||
import org.solovyev.android.calculator.CalculatorDisplayViewState;
|
||||
import org.solovyev.android.calculator.Editor;
|
||||
|
||||
@Root
|
||||
public class EditorHistoryState implements Cloneable{
|
||||
@ -34,6 +36,16 @@ public class EditorHistoryState implements Cloneable{
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static EditorHistoryState newInstance(@NotNull CalculatorDisplayViewState viewState) {
|
||||
final EditorHistoryState result = new EditorHistoryState();
|
||||
|
||||
result.text = viewState.getText();
|
||||
result.cursorPosition = viewState.getSelection();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public void setValuesFromHistory(@NotNull Editor editor) {
|
||||
editor.setText(this.getText());
|
||||
editor.setSelection(this.getCursorPosition());
|
@ -8,8 +8,8 @@ package org.solovyev.android.calculator.jscl;
|
||||
|
||||
import jscl.math.Generic;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.solovyev.android.calculator.model.CalculatorParseException;
|
||||
import org.solovyev.android.calculator.model.TextProcessor;
|
||||
import org.solovyev.android.calculator.CalculatorParseException;
|
||||
import org.solovyev.android.calculator.text.TextProcessor;
|
||||
|
||||
/**
|
||||
* User: serso
|
@ -9,10 +9,10 @@ package org.solovyev.android.calculator.jscl;
|
||||
import jscl.math.Generic;
|
||||
import jscl.text.ParseException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.solovyev.android.calculator.model.CalculatorEngine;
|
||||
import org.solovyev.android.calculator.model.DummyTextProcessor;
|
||||
import org.solovyev.android.calculator.model.FromJsclSimplifyTextProcessor;
|
||||
import org.solovyev.android.calculator.model.TextProcessor;
|
||||
import org.solovyev.android.calculator.CalculatorLocatorImpl;
|
||||
import org.solovyev.android.calculator.text.DummyTextProcessor;
|
||||
import org.solovyev.android.calculator.text.FromJsclSimplifyTextProcessor;
|
||||
import org.solovyev.android.calculator.text.TextProcessor;
|
||||
|
||||
public enum JsclOperation {
|
||||
|
||||
@ -42,11 +42,11 @@ public enum JsclOperation {
|
||||
public final String evaluate(@NotNull String expression) throws ParseException {
|
||||
switch (this) {
|
||||
case simplify:
|
||||
return CalculatorEngine.instance.getEngine().simplify(expression);
|
||||
return CalculatorLocatorImpl.getInstance().getCalculatorEngine().getEngine().simplify(expression);
|
||||
case elementary:
|
||||
return CalculatorEngine.instance.getEngine().elementary(expression);
|
||||
return CalculatorLocatorImpl.getInstance().getCalculatorEngine().getEngine().elementary(expression);
|
||||
case numeric:
|
||||
return CalculatorEngine.instance.getEngine().evaluate(expression);
|
||||
return CalculatorLocatorImpl.getInstance().getCalculatorEngine().getEngine().evaluate(expression);
|
||||
default:
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
@ -56,11 +56,11 @@ public enum JsclOperation {
|
||||
public final Generic evaluateGeneric(@NotNull String expression) throws ParseException {
|
||||
switch (this) {
|
||||
case simplify:
|
||||
return CalculatorEngine.instance.getEngine().simplifyGeneric(expression);
|
||||
return CalculatorLocatorImpl.getInstance().getCalculatorEngine().getEngine().simplifyGeneric(expression);
|
||||
case elementary:
|
||||
return CalculatorEngine.instance.getEngine().elementaryGeneric(expression);
|
||||
return CalculatorLocatorImpl.getInstance().getCalculatorEngine().getEngine().elementaryGeneric(expression);
|
||||
case numeric:
|
||||
return CalculatorEngine.instance.getEngine().evaluateGeneric(expression);
|
||||
return CalculatorLocatorImpl.getInstance().getCalculatorEngine().getEngine().evaluateGeneric(expression);
|
||||
default:
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
@ -10,10 +10,10 @@ import jscl.NumeralBase;
|
||||
import jscl.math.function.Constants;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.solovyev.android.calculator.CalculatorLocatorImpl;
|
||||
import org.solovyev.common.JPredicate;
|
||||
import org.solovyev.common.StartsWithFinder;
|
||||
import org.solovyev.android.calculator.model.CalculatorEngine;
|
||||
import org.solovyev.android.calculator.model.CalculatorParseException;
|
||||
import org.solovyev.android.calculator.CalculatorParseException;
|
||||
import org.solovyev.common.collections.CollectionsUtils;
|
||||
|
||||
import java.util.*;
|
||||
@ -26,10 +26,7 @@ public enum MathType {
|
||||
private final List<String> tokens = new ArrayList<String>(10);
|
||||
{
|
||||
for (NumeralBase numeralBase : NumeralBase.values()) {
|
||||
final String jsclPrefix = numeralBase.getJsclPrefix();
|
||||
if (jsclPrefix != null) {
|
||||
tokens.add(jsclPrefix);
|
||||
}
|
||||
tokens.add(numeralBase.getJsclPrefix());
|
||||
}
|
||||
}
|
||||
|
||||
@ -60,7 +57,7 @@ public enum MathType {
|
||||
@NotNull
|
||||
@Override
|
||||
public List<String> getTokens() {
|
||||
return CalculatorEngine.instance.getPostfixFunctionsRegistry().getNames();
|
||||
return CalculatorLocatorImpl.getInstance().getCalculatorEngine().getPostfixFunctionsRegistry().getNames();
|
||||
}
|
||||
},
|
||||
|
||||
@ -104,7 +101,7 @@ public enum MathType {
|
||||
@NotNull
|
||||
@Override
|
||||
public List<String> getTokens() {
|
||||
return CalculatorEngine.instance.getFunctionsRegistry().getNames();
|
||||
return CalculatorLocatorImpl.getInstance().getCalculatorEngine().getFunctionsRegistry().getNames();
|
||||
}
|
||||
},
|
||||
|
||||
@ -112,7 +109,7 @@ public enum MathType {
|
||||
@NotNull
|
||||
@Override
|
||||
public List<String> getTokens() {
|
||||
return CalculatorEngine.instance.getOperatorsRegistry().getNames();
|
||||
return CalculatorLocatorImpl.getInstance().getCalculatorEngine().getOperatorsRegistry().getNames();
|
||||
}
|
||||
},
|
||||
|
||||
@ -120,7 +117,7 @@ public enum MathType {
|
||||
@NotNull
|
||||
@Override
|
||||
public List<String> getTokens() {
|
||||
return CalculatorEngine.instance.getVarsRegistry().getNames();
|
||||
return CalculatorLocatorImpl.getInstance().getCalculatorEngine().getVarsRegistry().getNames();
|
||||
}
|
||||
|
||||
@Override
|
@ -4,10 +4,11 @@
|
||||
* or visit http://se.solovyev.org
|
||||
*/
|
||||
|
||||
package org.solovyev.android.calculator.model;
|
||||
package org.solovyev.android.calculator.text;
|
||||
|
||||
import jscl.math.Generic;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.solovyev.android.calculator.CalculatorParseException;
|
||||
|
||||
/**
|
||||
* User: serso
|
@ -1,9 +1,11 @@
|
||||
package org.solovyev.android.calculator.model;
|
||||
package org.solovyev.android.calculator.text;
|
||||
|
||||
import jscl.math.Generic;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.solovyev.android.calculator.CalculatorLocatorImpl;
|
||||
import org.solovyev.android.calculator.math.MathType;
|
||||
import org.solovyev.android.calculator.CalculatorParseException;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
@ -55,7 +57,7 @@ public class FromJsclSimplifyTextProcessor implements TextProcessor<String, Gene
|
||||
}
|
||||
|
||||
if (needMultiplicationSign(mathTypeBefore == null ? null : mathTypeBefore.getMathType(), mathTypeAfter == null ? null : mathTypeAfter.getMathType())) {
|
||||
sb.append(CalculatorEngine.instance.getMultiplicationSign());
|
||||
sb.append(CalculatorLocatorImpl.getInstance().getCalculatorEngine().getMultiplicationSign());
|
||||
}
|
||||
|
||||
} else {
|
@ -1,6 +1,7 @@
|
||||
package org.solovyev.android.calculator.model;
|
||||
package org.solovyev.android.calculator.text;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.solovyev.android.calculator.CalculatorParseException;
|
||||
|
||||
/**
|
||||
* User: serso
|
@ -0,0 +1,77 @@
|
||||
package org.solovyev.common.utils;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.Iterables;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* User: Solovyev_S
|
||||
* Date: 20.09.12
|
||||
* Time: 16:43
|
||||
*/
|
||||
// todo serso: move to common
|
||||
public class ListListenersContainer<T> {
|
||||
|
||||
@NotNull
|
||||
private final List<WeakReference<T>> listeners = new ArrayList<WeakReference<T>>();
|
||||
|
||||
public void addListener(@NotNull final T listener) {
|
||||
synchronized (listeners) {
|
||||
boolean contains = Iterables.any(listeners, new WeakReferencePredicate<T>(listener));
|
||||
|
||||
if (!contains) {
|
||||
listeners.add(new WeakReference<T>(listener));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void removeListener(@NotNull T listener) {
|
||||
synchronized (listeners) {
|
||||
Iterables.removeIf(listeners, new WeakReferencePredicate<T>(listener));
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<T> getListeners() {
|
||||
final List<T> localListeners;
|
||||
|
||||
synchronized (listeners) {
|
||||
localListeners = new ArrayList<T>(listeners.size());
|
||||
|
||||
// copy listeners and remove garbage collected references
|
||||
for ( Iterator<WeakReference<T>> it = listeners.iterator(); it.hasNext(); ) {
|
||||
final WeakReference<T> r = it.next();
|
||||
final T t = r.get();
|
||||
if ( t == null ) {
|
||||
it.remove();
|
||||
} else {
|
||||
localListeners.add(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return localListeners;
|
||||
}
|
||||
|
||||
private static class WeakReferencePredicate<T> implements Predicate<WeakReference<T>> {
|
||||
|
||||
@NotNull
|
||||
private final T t;
|
||||
|
||||
public WeakReferencePredicate(T t) {
|
||||
this.t = t;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(@Nullable WeakReference<T> r) {
|
||||
final T t = r != null ? r.get() : null;
|
||||
return this.t.equals(t);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package org.solovyev.android;
|
||||
package org.solovyev.math.units;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
@ -1,4 +1,4 @@
|
||||
package org.solovyev.android;
|
||||
package org.solovyev.math.units;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
@ -1,4 +1,4 @@
|
||||
package org.solovyev.android;
|
||||
package org.solovyev.math.units;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
@ -1,4 +1,4 @@
|
||||
package org.solovyev.android;
|
||||
package org.solovyev.math.units;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
@ -0,0 +1,8 @@
|
||||
msg_1=Arithmetic error occurred: {0}
|
||||
msg_2=Too complex expression
|
||||
msg_3=Too long execution time - check the expression
|
||||
msg_4=Evaluation was cancelled
|
||||
msg_5=No parameters are specified for function: {0}
|
||||
msg_6=Infinite loop is detected in expression
|
||||
|
||||
syntax_error=Error
|
@ -22,7 +22,6 @@
|
||||
<dependency>
|
||||
<groupId>com.intellij</groupId>
|
||||
<artifactId>annotations</artifactId>
|
||||
<version>7.0.3</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
|
@ -19,6 +19,13 @@
|
||||
<dependencies>
|
||||
|
||||
<!-- OWN -->
|
||||
|
||||
<dependency>
|
||||
<groupId>org.solovyev.android</groupId>
|
||||
<artifactId>calculatorpp-core</artifactId>
|
||||
<version>1.3.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.solovyev</groupId>
|
||||
<artifactId>common-core</artifactId>
|
||||
@ -75,13 +82,6 @@
|
||||
<dependency>
|
||||
<groupId>org.solovyev</groupId>
|
||||
<artifactId>jscl</artifactId>
|
||||
<version>0.0.2</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>xercesImpl</artifactId>
|
||||
<groupId>xerces</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<!--OTHER-->
|
||||
@ -92,13 +92,6 @@
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.8.2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>net.sf.opencsv</groupId>
|
||||
<artifactId>opencsv</artifactId>
|
||||
@ -109,17 +102,6 @@
|
||||
<dependency>
|
||||
<groupId>org.simpleframework</groupId>
|
||||
<artifactId>simple-xml</artifactId>
|
||||
<version>2.6.1</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>stax-api</artifactId>
|
||||
<groupId>stax</groupId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<artifactId>xpp3</artifactId>
|
||||
<groupId>xpp3</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@ -147,10 +129,15 @@
|
||||
<version>11.0.2</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.intellij</groupId>
|
||||
<artifactId>annotations</artifactId>
|
||||
<version>7.0.3</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
@ -9,12 +9,11 @@
|
||||
|
||||
# Project target.
|
||||
target=android-15
|
||||
android.library.reference.1=../calculatorpp-service
|
||||
android.library.reference.2=gen-external-apklibs/org.solovyev.android_android-common-core_1.0.0
|
||||
android.library.reference.3=gen-external-apklibs/org.solovyev.android_android-common-ads_1.0.0
|
||||
android.library.reference.4=gen-external-apklibs/org.solovyev.android_android-common-view_1.0.0
|
||||
android.library.reference.5=gen-external-apklibs/org.solovyev.android_android-common-preferences_1.0.0
|
||||
android.library.reference.6=gen-external-apklibs/org.solovyev.android_android-common-other_1.0.0
|
||||
android.library.reference.7=gen-external-apklibs/org.solovyev.android_android-common-menu_1.0.0
|
||||
android.library.reference.1=gen-external-apklibs/org.solovyev.android_android-common-core_1.0.0
|
||||
android.library.reference.2=gen-external-apklibs/org.solovyev.android_android-common-ads_1.0.0
|
||||
android.library.reference.3=gen-external-apklibs/org.solovyev.android_android-common-view_1.0.0
|
||||
android.library.reference.4=gen-external-apklibs/org.solovyev.android_android-common-preferences_1.0.0
|
||||
android.library.reference.5=gen-external-apklibs/org.solovyev.android_android-common-other_1.0.0
|
||||
android.library.reference.6=gen-external-apklibs/org.solovyev.android_android-common-menu_1.0.0
|
||||
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
~ or visit http://se.solovyev.org
|
||||
-->
|
||||
|
||||
<org.solovyev.android.calculator.CalculatorDisplay
|
||||
<org.solovyev.android.calculator.AndroidCalculatorDisplayView
|
||||
xmlns:a="http://schemas.android.com/apk/res/android"
|
||||
a:id="@+id/calculatorDisplay"
|
||||
style="@style/display_style"
|
||||
|
@ -0,0 +1,235 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2011. Created by serso aka se.solovyev.
|
||||
* For more information, please, contact se.solovyev@gmail.com
|
||||
*/
|
||||
|
||||
package org.solovyev.android.calculator;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
import android.text.Html;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import jscl.math.Generic;
|
||||
import jscl.math.function.Constant;
|
||||
import jscl.math.function.IConstant;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.solovyev.android.calculator.jscl.JsclOperation;
|
||||
import org.solovyev.android.calculator.model.CalculatorEngine;
|
||||
import org.solovyev.android.calculator.text.TextProcessor;
|
||||
import org.solovyev.android.calculator.view.NumeralBaseConverterDialog;
|
||||
import org.solovyev.android.calculator.view.TextHighlighter;
|
||||
import org.solovyev.android.menu.LabeledMenuItem;
|
||||
import org.solovyev.android.view.AutoResizeTextView;
|
||||
import org.solovyev.common.collections.CollectionsUtils;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* User: serso
|
||||
* Date: 9/17/11
|
||||
* Time: 10:58 PM
|
||||
*/
|
||||
public class AndroidCalculatorDisplayView extends AutoResizeTextView implements CalculatorDisplayView {
|
||||
|
||||
public static enum MenuItem implements LabeledMenuItem<CalculatorDisplayViewState> {
|
||||
|
||||
copy(R.string.c_copy) {
|
||||
@Override
|
||||
public void onClick(@NotNull CalculatorDisplayViewState data, @NotNull Context context) {
|
||||
CalculatorModel.copyResult(context, data);
|
||||
}
|
||||
},
|
||||
|
||||
convert_to_bin(R.string.convert_to_bin) {
|
||||
@Override
|
||||
public void onClick(@NotNull CalculatorDisplayViewState data, @NotNull Context context) {
|
||||
ConversionMenuItem.convert_to_bin.onClick(data, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isItemVisibleFor(@NotNull Generic generic, @NotNull JsclOperation operation) {
|
||||
return ConversionMenuItem.convert_to_bin.isItemVisibleFor(generic, operation);
|
||||
}
|
||||
},
|
||||
|
||||
convert_to_dec(R.string.convert_to_dec) {
|
||||
@Override
|
||||
public void onClick(@NotNull CalculatorDisplayViewState data, @NotNull Context context) {
|
||||
ConversionMenuItem.convert_to_dec.onClick(data, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isItemVisibleFor(@NotNull Generic generic, @NotNull JsclOperation operation) {
|
||||
return ConversionMenuItem.convert_to_dec.isItemVisibleFor(generic, operation);
|
||||
}
|
||||
},
|
||||
|
||||
convert_to_hex(R.string.convert_to_hex) {
|
||||
@Override
|
||||
public void onClick(@NotNull CalculatorDisplayViewState data, @NotNull Context context) {
|
||||
ConversionMenuItem.convert_to_hex.onClick(data, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isItemVisibleFor(@NotNull Generic generic, @NotNull JsclOperation operation) {
|
||||
return ConversionMenuItem.convert_to_hex.isItemVisibleFor(generic, operation);
|
||||
}
|
||||
},
|
||||
|
||||
convert(R.string.c_convert) {
|
||||
@Override
|
||||
public void onClick(@NotNull CalculatorDisplayViewState data, @NotNull Context context) {
|
||||
final Generic result = data.getResult();
|
||||
if (result != null) {
|
||||
new NumeralBaseConverterDialog(result.toString()).show(context);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isItemVisibleFor(@NotNull Generic generic, @NotNull JsclOperation operation) {
|
||||
return operation == JsclOperation.numeric && generic.getConstants().isEmpty();
|
||||
}
|
||||
},
|
||||
|
||||
plot(R.string.c_plot) {
|
||||
@Override
|
||||
public void onClick(@NotNull CalculatorDisplayViewState data, @NotNull Context context) {
|
||||
final Generic generic = data.getResult();
|
||||
assert generic != null;
|
||||
|
||||
final Constant constant = CollectionsUtils.getFirstCollectionElement(getNotSystemConstants(generic));
|
||||
assert constant != null;
|
||||
CalculatorActivityLauncher.plotGraph(context, generic, constant);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isItemVisibleFor(@NotNull Generic generic, @NotNull JsclOperation operation) {
|
||||
boolean result = false;
|
||||
|
||||
if (operation == JsclOperation.simplify) {
|
||||
if (getNotSystemConstants(generic).size() == 1) {
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Set<Constant> getNotSystemConstants(@NotNull Generic generic) {
|
||||
final Set<Constant> notSystemConstants = new HashSet<Constant>();
|
||||
|
||||
for (Constant constant : generic.getConstants()) {
|
||||
IConstant var = CalculatorEngine.instance.getVarsRegistry().get(constant.getName());
|
||||
if (var != null && !var.isSystem() && !var.isDefined()) {
|
||||
notSystemConstants.add(constant);
|
||||
}
|
||||
}
|
||||
|
||||
return notSystemConstants;
|
||||
}
|
||||
};
|
||||
|
||||
private final int captionId;
|
||||
|
||||
MenuItem(int captionId) {
|
||||
this.captionId = captionId;
|
||||
}
|
||||
|
||||
public final boolean isItemVisible(@NotNull CalculatorDisplayViewState displayViewState) {
|
||||
//noinspection ConstantConditions
|
||||
return displayViewState.isValid() && displayViewState.getResult() != null && isItemVisibleFor(displayViewState.getResult(), displayViewState.getOperation());
|
||||
}
|
||||
|
||||
protected boolean isItemVisibleFor(@NotNull Generic generic, @NotNull JsclOperation operation) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getCaption(@NotNull Context context) {
|
||||
return context.getString(captionId);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private CalculatorDisplayViewState state = CalculatorDisplayViewStateImpl.newDefaultInstance();
|
||||
|
||||
@NotNull
|
||||
private final static TextProcessor<TextHighlighter.Result, String> textHighlighter = new TextHighlighter(Color.WHITE, false, CalculatorEngine.instance.getEngine());
|
||||
|
||||
public AndroidCalculatorDisplayView(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public AndroidCalculatorDisplayView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public AndroidCalculatorDisplayView(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
}
|
||||
|
||||
public boolean isValid() {
|
||||
return this.state.isValid();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setState(@NotNull CalculatorDisplayViewState state) {
|
||||
this.state = state;
|
||||
if ( state.isValid() ) {
|
||||
setTextColor(getResources().getColor(R.color.default_text_color));
|
||||
setText(state.getStringResult());
|
||||
} else {
|
||||
setTextColor(getResources().getColor(R.color.display_error_text_color));
|
||||
setText(state.getErrorMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public CalculatorDisplayViewState getState() {
|
||||
return this.state;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setText(CharSequence text, BufferType type) {
|
||||
super.setText(text, type);
|
||||
}
|
||||
|
||||
public synchronized void redraw() {
|
||||
if (isValid()) {
|
||||
String text = getText().toString();
|
||||
|
||||
Log.d(this.getClass().getName(), text);
|
||||
|
||||
try {
|
||||
TextHighlighter.Result result = textHighlighter.process(text);
|
||||
text = result.toString();
|
||||
} catch (CalculatorParseException e) {
|
||||
Log.e(this.getClass().getName(), e.getMessage(), e);
|
||||
}
|
||||
|
||||
Log.d(this.getClass().getName(), text);
|
||||
super.setText(Html.fromHtml(text), BufferType.EDITABLE);
|
||||
}
|
||||
|
||||
// todo serso: think where to move it (keep in mind org.solovyev.android.view.AutoResizeTextView.resetTextSize())
|
||||
setAddEllipsis(false);
|
||||
setMinTextSize(10);
|
||||
resizeText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSelection() {
|
||||
return this.getSelectionStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSelection(int selection) {
|
||||
// not supported by TextView
|
||||
}
|
||||
}
|
@ -3,10 +3,10 @@ package org.solovyev.android.calculator;
|
||||
import android.app.Activity;
|
||||
import jscl.NumeralBase;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.solovyev.android.Unit;
|
||||
import org.solovyev.android.UnitConverter;
|
||||
import org.solovyev.android.UnitImpl;
|
||||
import org.solovyev.android.UnitType;
|
||||
import org.solovyev.math.units.Unit;
|
||||
import org.solovyev.math.units.UnitConverter;
|
||||
import org.solovyev.math.units.UnitImpl;
|
||||
import org.solovyev.math.units.UnitType;
|
||||
import org.solovyev.android.view.drag.DirectionDragButton;
|
||||
import org.solovyev.android.view.drag.DragDirection;
|
||||
|
||||
|
@ -32,7 +32,7 @@ import org.solovyev.android.AndroidUtils;
|
||||
import org.solovyev.android.FontSizeAdjuster;
|
||||
import org.solovyev.android.LocalBinder;
|
||||
import org.solovyev.android.calculator.about.CalculatorReleaseNotesActivity;
|
||||
import org.solovyev.android.calculator.history.CalculatorHistory;
|
||||
import org.solovyev.android.calculator.history.AndroidCalculatorHistoryImpl;
|
||||
import org.solovyev.android.calculator.history.CalculatorHistoryState;
|
||||
import org.solovyev.android.calculator.model.CalculatorEngine;
|
||||
import org.solovyev.android.calculator.view.AngleUnitsButton;
|
||||
@ -136,7 +136,7 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster, Sh
|
||||
|
||||
vibrator = (Vibrator) this.getSystemService(VIBRATOR_SERVICE);
|
||||
|
||||
CalculatorHistory.instance.load(this, preferences);
|
||||
AndroidCalculatorHistoryImpl.instance.load(this, preferences);
|
||||
calculatorModel = CalculatorModel.instance.init(this, preferences, CalculatorEngine.instance);
|
||||
|
||||
dpclRegister.clear();
|
||||
|
@ -46,6 +46,8 @@ public class CalculatorApplication extends android.app.Application {
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
|
||||
CalculatorLocatorImpl.getInstance().setCalculatorEngine(CalculatorEngine.instance);
|
||||
|
||||
AdsController.getInstance().init(ADMOB_USER_ID, AD_FREE_PRODUCT_ID, new BillingController.IConfiguration() {
|
||||
|
||||
@Override
|
||||
|
@ -1,348 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2011. Created by serso aka se.solovyev.
|
||||
* For more information, please, contact se.solovyev@gmail.com
|
||||
*/
|
||||
|
||||
package org.solovyev.android.calculator;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
import android.text.Html;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import jscl.NumeralBase;
|
||||
import jscl.math.Generic;
|
||||
import jscl.math.function.Constant;
|
||||
import jscl.math.function.IConstant;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.solovyev.android.calculator.jscl.JsclOperation;
|
||||
import org.solovyev.android.calculator.model.CalculatorEngine;
|
||||
import org.solovyev.android.calculator.model.CalculatorParseException;
|
||||
import org.solovyev.android.calculator.model.TextProcessor;
|
||||
import org.solovyev.android.calculator.model.ToJsclTextProcessor;
|
||||
import org.solovyev.android.calculator.view.NumeralBaseConverterDialog;
|
||||
import org.solovyev.android.calculator.view.TextHighlighter;
|
||||
import org.solovyev.android.calculator.view.UnitConverterViewBuilder;
|
||||
import org.solovyev.android.menu.AMenuItem;
|
||||
import org.solovyev.android.menu.LabeledMenuItem;
|
||||
import org.solovyev.android.view.AutoResizeTextView;
|
||||
import org.solovyev.common.collections.CollectionsUtils;
|
||||
import org.solovyev.common.text.StringUtils;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* User: serso
|
||||
* Date: 9/17/11
|
||||
* Time: 10:58 PM
|
||||
*/
|
||||
public class CalculatorDisplay extends AutoResizeTextView implements ICalculatorDisplay{
|
||||
|
||||
private static enum ConversionMenuItem implements AMenuItem<CalculatorDisplay> {
|
||||
convert_to_bin(NumeralBase.bin),
|
||||
convert_to_dec(NumeralBase.dec),
|
||||
convert_to_hex(NumeralBase.hex);
|
||||
|
||||
@NotNull
|
||||
private final NumeralBase toNumeralBase;
|
||||
|
||||
private ConversionMenuItem(@NotNull NumeralBase toNumeralBase) {
|
||||
this.toNumeralBase = toNumeralBase;
|
||||
}
|
||||
|
||||
protected boolean isItemVisibleFor(@NotNull Generic generic, @NotNull JsclOperation operation) {
|
||||
boolean result = false;
|
||||
|
||||
if (operation == JsclOperation.numeric) {
|
||||
if (generic.getConstants().isEmpty()) {
|
||||
try {
|
||||
convert(generic);
|
||||
|
||||
// conversion possible => return true
|
||||
result = true;
|
||||
|
||||
} catch (UnitConverterViewBuilder.ConversionException e) {
|
||||
// conversion is not possible => return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(@NotNull CalculatorDisplay data, @NotNull Context context) {
|
||||
final NumeralBase fromNumeralBase = CalculatorEngine.instance.getEngine().getNumeralBase();
|
||||
|
||||
String to;
|
||||
try {
|
||||
to = convert(data.getGenericResult());
|
||||
|
||||
// add prefix
|
||||
if (fromNumeralBase != toNumeralBase) {
|
||||
to = toNumeralBase.getJsclPrefix() + to;
|
||||
}
|
||||
} catch (UnitConverterViewBuilder.ConversionException e) {
|
||||
to = context.getString(R.string.c_error);
|
||||
}
|
||||
|
||||
data.setText(to);
|
||||
data.redraw();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private String convert(@NotNull Generic generic) throws UnitConverterViewBuilder.ConversionException {
|
||||
final NumeralBase fromNumeralBase = CalculatorEngine.instance.getEngine().getNumeralBase();
|
||||
|
||||
if (fromNumeralBase != toNumeralBase) {
|
||||
String from = generic.toString();
|
||||
if (!StringUtils.isEmpty(from)) {
|
||||
try {
|
||||
from = ToJsclTextProcessor.getInstance().process(from).getExpression();
|
||||
} catch (CalculatorParseException e) {
|
||||
// ok, problems while processing occurred
|
||||
}
|
||||
}
|
||||
|
||||
return UnitConverterViewBuilder.doConversion(AndroidNumeralBase.getConverter(), from, AndroidNumeralBase.valueOf(fromNumeralBase), AndroidNumeralBase.valueOf(toNumeralBase));
|
||||
} else {
|
||||
return generic.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static enum MenuItem implements LabeledMenuItem<CalculatorDisplay> {
|
||||
|
||||
copy(R.string.c_copy) {
|
||||
@Override
|
||||
public void onClick(@NotNull CalculatorDisplay data, @NotNull Context context) {
|
||||
CalculatorModel.copyResult(context, data);
|
||||
}
|
||||
},
|
||||
|
||||
convert_to_bin(R.string.convert_to_bin) {
|
||||
@Override
|
||||
public void onClick(@NotNull CalculatorDisplay data, @NotNull Context context) {
|
||||
ConversionMenuItem.convert_to_bin.onClick(data, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isItemVisibleFor(@NotNull Generic generic, @NotNull JsclOperation operation) {
|
||||
return ConversionMenuItem.convert_to_bin.isItemVisibleFor(generic, operation);
|
||||
}
|
||||
},
|
||||
|
||||
convert_to_dec(R.string.convert_to_dec) {
|
||||
@Override
|
||||
public void onClick(@NotNull CalculatorDisplay data, @NotNull Context context) {
|
||||
ConversionMenuItem.convert_to_dec.onClick(data, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isItemVisibleFor(@NotNull Generic generic, @NotNull JsclOperation operation) {
|
||||
return ConversionMenuItem.convert_to_dec.isItemVisibleFor(generic, operation);
|
||||
}
|
||||
},
|
||||
|
||||
convert_to_hex(R.string.convert_to_hex) {
|
||||
@Override
|
||||
public void onClick(@NotNull CalculatorDisplay data, @NotNull Context context) {
|
||||
ConversionMenuItem.convert_to_hex.onClick(data, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isItemVisibleFor(@NotNull Generic generic, @NotNull JsclOperation operation) {
|
||||
return ConversionMenuItem.convert_to_hex.isItemVisibleFor(generic, operation);
|
||||
}
|
||||
},
|
||||
|
||||
convert(R.string.c_convert) {
|
||||
@Override
|
||||
public void onClick(@NotNull CalculatorDisplay data, @NotNull Context context) {
|
||||
new NumeralBaseConverterDialog(data.getGenericResult().toString()).show(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isItemVisibleFor(@NotNull Generic generic, @NotNull JsclOperation operation) {
|
||||
return operation == JsclOperation.numeric && generic.getConstants().isEmpty();
|
||||
}
|
||||
},
|
||||
|
||||
plot(R.string.c_plot) {
|
||||
@Override
|
||||
public void onClick(@NotNull CalculatorDisplay data, @NotNull Context context) {
|
||||
final Generic generic = data.getGenericResult();
|
||||
assert generic != null;
|
||||
|
||||
final Constant constant = CollectionsUtils.getFirstCollectionElement(getNotSystemConstants(generic));
|
||||
assert constant != null;
|
||||
CalculatorActivityLauncher.plotGraph(context, generic, constant);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isItemVisibleFor(@NotNull Generic generic, @NotNull JsclOperation operation) {
|
||||
boolean result = false;
|
||||
|
||||
if (operation == JsclOperation.simplify) {
|
||||
if (getNotSystemConstants(generic).size() == 1) {
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Set<Constant> getNotSystemConstants(@NotNull Generic generic) {
|
||||
final Set<Constant> notSystemConstants = new HashSet<Constant>();
|
||||
|
||||
for (Constant constant : generic.getConstants()) {
|
||||
IConstant var = CalculatorEngine.instance.getVarsRegistry().get(constant.getName());
|
||||
if (var != null && !var.isSystem() && !var.isDefined()) {
|
||||
notSystemConstants.add(constant);
|
||||
}
|
||||
}
|
||||
|
||||
return notSystemConstants;
|
||||
}
|
||||
};
|
||||
|
||||
private final int captionId;
|
||||
|
||||
MenuItem(int captionId) {
|
||||
this.captionId = captionId;
|
||||
}
|
||||
|
||||
public final boolean isItemVisible(@NotNull CalculatorDisplay display) {
|
||||
//noinspection ConstantConditions
|
||||
return display.isValid() && display.getGenericResult() != null && isItemVisibleFor(display.getGenericResult(), display.getJsclOperation());
|
||||
}
|
||||
|
||||
protected boolean isItemVisibleFor(@NotNull Generic generic, @NotNull JsclOperation operation) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getCaption(@NotNull Context context) {
|
||||
return context.getString(captionId);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean valid = true;
|
||||
|
||||
@Nullable
|
||||
private String errorMessage;
|
||||
|
||||
@NotNull
|
||||
private JsclOperation jsclOperation = JsclOperation.numeric;
|
||||
|
||||
@NotNull
|
||||
private final static TextProcessor<TextHighlighter.Result, String> textHighlighter = new TextHighlighter(Color.WHITE, false, CalculatorEngine.instance.getEngine());
|
||||
|
||||
@Nullable
|
||||
private Generic genericResult;
|
||||
|
||||
public CalculatorDisplay(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public CalculatorDisplay(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public CalculatorDisplay(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid() {
|
||||
return valid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValid(boolean valid) {
|
||||
this.valid = valid;
|
||||
if (valid) {
|
||||
errorMessage = null;
|
||||
setTextColor(getResources().getColor(R.color.default_text_color));
|
||||
} else {
|
||||
setTextColor(getResources().getColor(R.color.display_error_text_color));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public String getErrorMessage() {
|
||||
return errorMessage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setErrorMessage(@Nullable String errorMessage) {
|
||||
this.errorMessage = errorMessage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setJsclOperation(@NotNull JsclOperation jsclOperation) {
|
||||
this.jsclOperation = jsclOperation;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public JsclOperation getJsclOperation() {
|
||||
return jsclOperation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setText(CharSequence text, BufferType type) {
|
||||
super.setText(text, type);
|
||||
|
||||
setValid(true);
|
||||
}
|
||||
|
||||
public synchronized void redraw() {
|
||||
if (isValid()) {
|
||||
String text = getText().toString();
|
||||
|
||||
Log.d(this.getClass().getName(), text);
|
||||
|
||||
try {
|
||||
TextHighlighter.Result result = textHighlighter.process(text);
|
||||
text = result.toString();
|
||||
} catch (CalculatorParseException e) {
|
||||
Log.e(this.getClass().getName(), e.getMessage(), e);
|
||||
}
|
||||
|
||||
Log.d(this.getClass().getName(), text);
|
||||
super.setText(Html.fromHtml(text), BufferType.EDITABLE);
|
||||
}
|
||||
|
||||
// todo serso: think where to move it (keep in mind org.solovyev.android.view.AutoResizeTextView.resetTextSize())
|
||||
setAddEllipsis(false);
|
||||
setMinTextSize(10);
|
||||
resizeText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setGenericResult(@Nullable Generic genericResult) {
|
||||
this.genericResult = genericResult;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Generic getGenericResult() {
|
||||
return genericResult;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSelection() {
|
||||
return this.getSelectionStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSelection(int selection) {
|
||||
// not supported by TextView
|
||||
}
|
||||
}
|
@ -16,8 +16,7 @@ import android.view.ContextMenu;
|
||||
import android.widget.EditText;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.solovyev.android.calculator.model.CalculatorEngine;
|
||||
import org.solovyev.android.calculator.model.CalculatorParseException;
|
||||
import org.solovyev.android.calculator.model.TextProcessor;
|
||||
import org.solovyev.android.calculator.text.TextProcessor;
|
||||
import org.solovyev.android.calculator.view.TextHighlighter;
|
||||
import org.solovyev.common.collections.CollectionsUtils;
|
||||
|
||||
|
@ -20,14 +20,12 @@ import android.widget.Toast;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.solovyev.android.CursorControl;
|
||||
import org.solovyev.android.calculator.history.CalculatorHistory;
|
||||
import org.solovyev.android.calculator.history.AndroidCalculatorHistoryImpl;
|
||||
import org.solovyev.android.calculator.history.CalculatorHistoryState;
|
||||
import org.solovyev.android.calculator.history.TextViewEditorAdapter;
|
||||
import org.solovyev.android.calculator.jscl.JsclOperation;
|
||||
import org.solovyev.android.calculator.math.MathType;
|
||||
import org.solovyev.android.calculator.model.CalculatorEngine;
|
||||
import org.solovyev.android.calculator.model.CalculatorEvalException;
|
||||
import org.solovyev.android.calculator.model.CalculatorParseException;
|
||||
import org.solovyev.android.history.HistoryControl;
|
||||
import org.solovyev.android.menu.AMenuBuilder;
|
||||
import org.solovyev.android.menu.MenuImpl;
|
||||
@ -55,7 +53,7 @@ public enum CalculatorModel implements CursorControl, HistoryControl<CalculatorH
|
||||
private CalculatorEditor editor;
|
||||
|
||||
@NotNull
|
||||
private CalculatorDisplay display;
|
||||
private AndroidCalculatorDisplayView display;
|
||||
|
||||
@NotNull
|
||||
private CalculatorEngine calculatorEngine;
|
||||
@ -68,10 +66,10 @@ public enum CalculatorModel implements CursorControl, HistoryControl<CalculatorH
|
||||
this.editor.init(preferences);
|
||||
preferences.registerOnSharedPreferenceChangeListener(editor);
|
||||
|
||||
this.display = (CalculatorDisplay) activity.findViewById(R.id.calculatorDisplay);
|
||||
this.display = (AndroidCalculatorDisplayView) activity.findViewById(R.id.calculatorDisplay);
|
||||
this.display.setOnClickListener(new CalculatorDisplayOnClickListener(activity));
|
||||
|
||||
final CalculatorHistoryState lastState = CalculatorHistory.instance.getLastHistoryState();
|
||||
final CalculatorHistoryState lastState = AndroidCalculatorHistoryImpl.instance.getLastHistoryState();
|
||||
if (lastState == null) {
|
||||
saveHistoryState();
|
||||
} else {
|
||||
@ -99,9 +97,9 @@ public enum CalculatorModel implements CursorControl, HistoryControl<CalculatorH
|
||||
copyResult(context, display);
|
||||
}
|
||||
|
||||
public static void copyResult(@NotNull Context context, @NotNull final CalculatorDisplay display) {
|
||||
if (display.isValid()) {
|
||||
final CharSequence text = display.getText();
|
||||
public static void copyResult(@NotNull Context context, @NotNull final CalculatorDisplayViewState viewState) {
|
||||
if (viewState.isValid()) {
|
||||
final CharSequence text = viewState.getText();
|
||||
if (!StringUtils.isEmpty(text)) {
|
||||
final ClipboardManager clipboard = (ClipboardManager) context.getSystemService(Activity.CLIPBOARD_SERVICE);
|
||||
clipboard.setText(text.toString());
|
||||
@ -111,7 +109,7 @@ public enum CalculatorModel implements CursorControl, HistoryControl<CalculatorH
|
||||
}
|
||||
|
||||
private void saveHistoryState() {
|
||||
CalculatorHistory.instance.addState(getCurrentHistoryState());
|
||||
AndroidCalculatorHistoryImpl.instance.addState(getCurrentHistoryState());
|
||||
}
|
||||
|
||||
public void setCursorOnStart() {
|
||||
@ -197,14 +195,14 @@ public enum CalculatorModel implements CursorControl, HistoryControl<CalculatorH
|
||||
|
||||
if (delayEvaluate) {
|
||||
if (historyState == null) {
|
||||
CalculatorHistory.instance.addState(localHistoryState);
|
||||
AndroidCalculatorHistoryImpl.instance.addState(localHistoryState);
|
||||
}
|
||||
// todo serso: this is not correct - operation is processing still in the same thread
|
||||
new Handler().postDelayed(pendingOperation.getObject(), EVAL_DELAY_MILLIS);
|
||||
} else {
|
||||
pendingOperation.getObject().run();
|
||||
if (historyState == null) {
|
||||
CalculatorHistory.instance.addState(localHistoryState);
|
||||
AndroidCalculatorHistoryImpl.instance.addState(localHistoryState);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -230,16 +228,16 @@ public enum CalculatorModel implements CursorControl, HistoryControl<CalculatorH
|
||||
if (!StringUtils.isEmpty(expression)) {
|
||||
try {
|
||||
Log.d(CalculatorModel.class.getName(), "Trying to evaluate '" + operation + "': " + expression /*+ StringUtils.fromStackTrace(Thread.currentThread().getStackTrace())*/);
|
||||
final CalculatorEngine.Result result = calculatorEngine.evaluate(operation, expression);
|
||||
final CalculatorOutput result = calculatorEngine.evaluate(operation, expression);
|
||||
|
||||
// todo serso: second condition might replaced with expression.equals(this.editor.getText().toString()) ONLY if expression will be formatted with text highlighter
|
||||
if (currentRunner == pendingOperation.getObject() && this.editor.getText().length() > 0) {
|
||||
display.setText(result.getResult());
|
||||
display.setText(result.getStringResult());
|
||||
} else {
|
||||
display.setText("");
|
||||
}
|
||||
display.setJsclOperation(result.getUserOperation());
|
||||
display.setGenericResult(result.getGenericResult());
|
||||
display.setJsclOperation(result.getOperation());
|
||||
display.setGenericResult(result.getResult());
|
||||
} catch (CalculatorParseException e) {
|
||||
handleEvaluationException(expression, display, operation, e);
|
||||
} catch (CalculatorEvalException e) {
|
||||
@ -257,7 +255,7 @@ public enum CalculatorModel implements CursorControl, HistoryControl<CalculatorH
|
||||
}
|
||||
|
||||
private void handleEvaluationException(@NotNull String expression,
|
||||
@NotNull CalculatorDisplay localDisplay,
|
||||
@NotNull AndroidCalculatorDisplayView localDisplay,
|
||||
@NotNull JsclOperation operation,
|
||||
@NotNull Message e) {
|
||||
Log.d(CalculatorModel.class.getName(), "Evaluation failed for : " + expression + ". Error message: " + e);
|
||||
@ -331,9 +329,9 @@ public enum CalculatorModel implements CursorControl, HistoryControl<CalculatorH
|
||||
|
||||
@Override
|
||||
public void doHistoryAction(@NotNull HistoryAction historyAction) {
|
||||
synchronized (CalculatorHistory.instance) {
|
||||
if (CalculatorHistory.instance.isActionAvailable(historyAction)) {
|
||||
final CalculatorHistoryState newState = CalculatorHistory.instance.doAction(historyAction, getCurrentHistoryState());
|
||||
synchronized (AndroidCalculatorHistoryImpl.instance) {
|
||||
if (AndroidCalculatorHistoryImpl.instance.isActionAvailable(historyAction)) {
|
||||
final CalculatorHistoryState newState = AndroidCalculatorHistoryImpl.instance.doAction(historyAction, getCurrentHistoryState());
|
||||
if (newState != null) {
|
||||
setCurrentHistoryState(newState);
|
||||
}
|
||||
@ -343,7 +341,7 @@ public enum CalculatorModel implements CursorControl, HistoryControl<CalculatorH
|
||||
|
||||
@Override
|
||||
public void setCurrentHistoryState(@NotNull CalculatorHistoryState editorHistoryState) {
|
||||
synchronized (CalculatorHistory.instance) {
|
||||
synchronized (AndroidCalculatorHistoryImpl.instance) {
|
||||
Log.d(this.getClass().getName(), "Saved history found: " + editorHistoryState);
|
||||
|
||||
editorHistoryState.setValuesFromHistory(new TextViewEditorAdapter(this.editor), this.display);
|
||||
@ -363,13 +361,13 @@ public enum CalculatorModel implements CursorControl, HistoryControl<CalculatorH
|
||||
@Override
|
||||
@NotNull
|
||||
public CalculatorHistoryState getCurrentHistoryState() {
|
||||
synchronized (CalculatorHistory.instance) {
|
||||
synchronized (AndroidCalculatorHistoryImpl.instance) {
|
||||
return CalculatorHistoryState.newInstance(new TextViewEditorAdapter(this.editor), this.display);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public CalculatorDisplay getDisplay() {
|
||||
public AndroidCalculatorDisplayView getDisplay() {
|
||||
return display;
|
||||
}
|
||||
|
||||
@ -384,13 +382,15 @@ public enum CalculatorModel implements CursorControl, HistoryControl<CalculatorH
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (v instanceof CalculatorDisplay) {
|
||||
final CalculatorDisplay cd = (CalculatorDisplay) v;
|
||||
if (v instanceof CalculatorDisplayView) {
|
||||
final CalculatorDisplay cd = CalculatorLocatorImpl.getInstance().getCalculatorDisplay();
|
||||
|
||||
if (cd.isValid()) {
|
||||
final List<CalculatorDisplay.MenuItem> filteredMenuItems = new ArrayList<CalculatorDisplay.MenuItem>(CalculatorDisplay.MenuItem.values().length);
|
||||
for (CalculatorDisplay.MenuItem menuItem : CalculatorDisplay.MenuItem.values()) {
|
||||
if (menuItem.isItemVisible(cd)) {
|
||||
final CalculatorDisplayViewState displayViewState = cd.getViewState();
|
||||
|
||||
if (displayViewState.isValid()) {
|
||||
final List<AndroidCalculatorDisplayView.MenuItem> filteredMenuItems = new ArrayList<AndroidCalculatorDisplayView.MenuItem>(AndroidCalculatorDisplayView.MenuItem.values().length);
|
||||
for (AndroidCalculatorDisplayView.MenuItem menuItem : AndroidCalculatorDisplayView.MenuItem.values()) {
|
||||
if (menuItem.isItemVisible(displayViewState)) {
|
||||
filteredMenuItems.add(menuItem);
|
||||
}
|
||||
}
|
||||
@ -400,7 +400,7 @@ public enum CalculatorModel implements CursorControl, HistoryControl<CalculatorH
|
||||
}
|
||||
|
||||
} else {
|
||||
final String errorMessage = cd.getErrorMessage();
|
||||
final String errorMessage = displayViewState.getErrorMessage();
|
||||
if (errorMessage != null) {
|
||||
showEvaluationError(activity, errorMessage);
|
||||
}
|
||||
|
@ -0,0 +1,63 @@
|
||||
package org.solovyev.android.calculator;
|
||||
|
||||
import android.content.Context;
|
||||
import jscl.NumeralBase;
|
||||
import jscl.math.Generic;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.solovyev.android.calculator.jscl.JsclOperation;
|
||||
import org.solovyev.android.calculator.model.CalculatorEngine;
|
||||
import org.solovyev.android.menu.AMenuItem;
|
||||
|
||||
/**
|
||||
* User: serso
|
||||
* Date: 9/21/12
|
||||
* Time: 12:11 AM
|
||||
*/
|
||||
enum ConversionMenuItem implements AMenuItem<CalculatorDisplayViewState> {
|
||||
|
||||
convert_to_bin(NumeralBase.bin),
|
||||
convert_to_dec(NumeralBase.dec),
|
||||
convert_to_hex(NumeralBase.hex);
|
||||
|
||||
@NotNull
|
||||
private final NumeralBase toNumeralBase;
|
||||
|
||||
ConversionMenuItem(@NotNull NumeralBase toNumeralBase) {
|
||||
this.toNumeralBase = toNumeralBase;
|
||||
}
|
||||
|
||||
protected boolean isItemVisibleFor(@NotNull Generic generic, @NotNull JsclOperation operation) {
|
||||
boolean result = false;
|
||||
|
||||
if (operation == JsclOperation.numeric) {
|
||||
if (generic.getConstants().isEmpty()) {
|
||||
try {
|
||||
convert(generic);
|
||||
|
||||
// conversion possible => return true
|
||||
result = true;
|
||||
|
||||
} catch (CalculatorImpl.ConversionException e) {
|
||||
// conversion is not possible => return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(@NotNull CalculatorDisplayViewState data, @NotNull Context context) {
|
||||
final NumeralBase fromNumeralBase = CalculatorEngine.instance.getEngine().getNumeralBase();
|
||||
|
||||
final Generic lastResult = data.getResult();
|
||||
|
||||
if (lastResult != null) {
|
||||
convert(lastResult);
|
||||
}
|
||||
}
|
||||
|
||||
private void convert(@NotNull Generic generic) {
|
||||
CalculatorLocatorImpl.getInstance().getCalculator().convert(generic, this.toNumeralBase);
|
||||
}
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2011. Created by serso aka se.solovyev.
|
||||
* For more information, please, contact se.solovyev@gmail.com
|
||||
* or visit http://se.solovyev.org
|
||||
*/
|
||||
|
||||
package org.solovyev.android.calculator;
|
||||
|
||||
import jscl.math.Generic;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.solovyev.android.calculator.history.Editor;
|
||||
import org.solovyev.android.calculator.jscl.JsclOperation;
|
||||
|
||||
/**
|
||||
* User: serso
|
||||
* Date: 12/17/11
|
||||
* Time: 9:45 PM
|
||||
*/
|
||||
public interface ICalculatorDisplay extends Editor{
|
||||
|
||||
boolean isValid();
|
||||
|
||||
void setValid(boolean valid);
|
||||
|
||||
@Nullable
|
||||
String getErrorMessage();
|
||||
|
||||
void setErrorMessage(@Nullable String errorMessage);
|
||||
|
||||
void setJsclOperation(@NotNull JsclOperation jsclOperation);
|
||||
|
||||
@NotNull
|
||||
JsclOperation getJsclOperation();
|
||||
|
||||
void setGenericResult(@Nullable Generic genericResult);
|
||||
|
||||
@Nullable
|
||||
Generic getGenericResult();
|
||||
}
|
@ -157,7 +157,7 @@ public abstract class AbstractHistoryActivity extends ListActivity {
|
||||
boolean result = false;
|
||||
try {
|
||||
historyState.setSaved(true);
|
||||
if ( CollectionsUtils.contains(historyState, CalculatorHistory.instance.getSavedHistory(), new Equalizer<CalculatorHistoryState>() {
|
||||
if ( CollectionsUtils.contains(historyState, AndroidCalculatorHistoryImpl.instance.getSavedHistory(), new Equalizer<CalculatorHistoryState>() {
|
||||
@Override
|
||||
public boolean equals(@Nullable CalculatorHistoryState first, @Nullable CalculatorHistoryState second) {
|
||||
return first != null && second != null &&
|
||||
|
@ -0,0 +1,18 @@
|
||||
package org.solovyev.android.calculator.history;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* User: Solovyev_S
|
||||
* Date: 20.09.12
|
||||
* Time: 16:07
|
||||
*/
|
||||
public interface AndroidCalculatorHistory extends CalculatorHistory {
|
||||
|
||||
void load(@Nullable Context context, @Nullable SharedPreferences preferences);
|
||||
|
||||
void save(@NotNull Context context);
|
||||
}
|
@ -0,0 +1,145 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2011. Created by serso aka se.solovyev.
|
||||
* For more information, please, contact se.solovyev@gmail.com
|
||||
* or visit http://se.solovyev.org
|
||||
*/
|
||||
|
||||
package org.solovyev.android.calculator.history;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.preference.PreferenceManager;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.solovyev.android.calculator.R;
|
||||
import org.solovyev.common.history.HistoryAction;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* User: serso
|
||||
* Date: 10/9/11
|
||||
* Time: 6:35 PM
|
||||
*/
|
||||
public enum AndroidCalculatorHistoryImpl implements AndroidCalculatorHistory {
|
||||
|
||||
instance;
|
||||
|
||||
@NotNull
|
||||
private final CalculatorHistoryImpl calculatorHistory = new CalculatorHistoryImpl();
|
||||
|
||||
@Override
|
||||
public void load(@Nullable Context context, @Nullable SharedPreferences preferences) {
|
||||
if (context != null && preferences != null) {
|
||||
final String value = preferences.getString(context.getString(R.string.p_calc_history), null);
|
||||
calculatorHistory.fromXml(value);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(@NotNull Context context) {
|
||||
final SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
final SharedPreferences.Editor editor = settings.edit();
|
||||
|
||||
editor.putString(context.getString(R.string.p_calc_history), calculatorHistory.toXml());
|
||||
|
||||
editor.commit();
|
||||
}
|
||||
|
||||
public void clearSavedHistory(@NotNull Context context) {
|
||||
calculatorHistory.clearSavedHistory();
|
||||
save(context);
|
||||
}
|
||||
|
||||
public void removeSavedHistory(@NotNull CalculatorHistoryState historyState, @NotNull Context context) {
|
||||
historyState.setSaved(false);
|
||||
calculatorHistory.removeSavedHistory(historyState);
|
||||
save(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return calculatorHistory.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CalculatorHistoryState getLastHistoryState() {
|
||||
return calculatorHistory.getLastHistoryState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUndoAvailable() {
|
||||
return calculatorHistory.isUndoAvailable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CalculatorHistoryState undo(@Nullable CalculatorHistoryState currentState) {
|
||||
return calculatorHistory.undo(currentState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRedoAvailable() {
|
||||
return calculatorHistory.isRedoAvailable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CalculatorHistoryState redo(@Nullable CalculatorHistoryState currentState) {
|
||||
return calculatorHistory.redo(currentState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActionAvailable(@NotNull HistoryAction historyAction) {
|
||||
return calculatorHistory.isActionAvailable(historyAction);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CalculatorHistoryState doAction(@NotNull HistoryAction historyAction, @Nullable CalculatorHistoryState currentState) {
|
||||
return calculatorHistory.doAction(historyAction, currentState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addState(@Nullable CalculatorHistoryState currentState) {
|
||||
calculatorHistory.addState(currentState);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<CalculatorHistoryState> getStates() {
|
||||
return calculatorHistory.getStates();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
calculatorHistory.clear();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<CalculatorHistoryState> getSavedHistory() {
|
||||
return calculatorHistory.getSavedHistory();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public CalculatorHistoryState addSavedState(@NotNull CalculatorHistoryState historyState) {
|
||||
return calculatorHistory.addSavedState(historyState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fromXml(@NotNull String xml) {
|
||||
calculatorHistory.fromXml(xml);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toXml() {
|
||||
return calculatorHistory.toXml();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearSavedHistory() {
|
||||
calculatorHistory.clearSavedHistory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeSavedHistory(@NotNull CalculatorHistoryState historyState) {
|
||||
calculatorHistory.removeSavedHistory(historyState);
|
||||
}
|
||||
}
|
@ -1,149 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2011. Created by serso aka se.solovyev.
|
||||
* For more information, please, contact se.solovyev@gmail.com
|
||||
* or visit http://se.solovyev.org
|
||||
*/
|
||||
|
||||
package org.solovyev.android.calculator.history;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.preference.PreferenceManager;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.solovyev.android.calculator.R;
|
||||
import org.solovyev.common.history.HistoryAction;
|
||||
import org.solovyev.common.history.HistoryHelper;
|
||||
import org.solovyev.common.history.SimpleHistoryHelper;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* User: serso
|
||||
* Date: 10/9/11
|
||||
* Time: 6:35 PM
|
||||
*/
|
||||
public enum CalculatorHistory implements HistoryHelper<CalculatorHistoryState> {
|
||||
|
||||
instance;
|
||||
|
||||
// todo serso: not synchronized
|
||||
private int counter = 0;
|
||||
|
||||
@NotNull
|
||||
private final HistoryHelper<CalculatorHistoryState> history = new SimpleHistoryHelper<CalculatorHistoryState>();
|
||||
|
||||
@NotNull
|
||||
private final List<CalculatorHistoryState> savedHistory = new ArrayList<CalculatorHistoryState> ();
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return this.history.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CalculatorHistoryState getLastHistoryState() {
|
||||
return this.history.getLastHistoryState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUndoAvailable() {
|
||||
return history.isUndoAvailable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CalculatorHistoryState undo(@Nullable CalculatorHistoryState currentState) {
|
||||
return history.undo(currentState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRedoAvailable() {
|
||||
return history.isRedoAvailable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CalculatorHistoryState redo(@Nullable CalculatorHistoryState currentState) {
|
||||
return history.redo(currentState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActionAvailable(@NotNull HistoryAction historyAction) {
|
||||
return history.isActionAvailable(historyAction);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CalculatorHistoryState doAction(@NotNull HistoryAction historyAction, @Nullable CalculatorHistoryState currentState) {
|
||||
return history.doAction(historyAction, currentState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addState(@Nullable CalculatorHistoryState currentState) {
|
||||
history.addState(currentState);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<CalculatorHistoryState> getStates() {
|
||||
return history.getStates();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
this.history.clear();
|
||||
}
|
||||
|
||||
public void load(@Nullable Context context, @Nullable SharedPreferences preferences) {
|
||||
if (context != null && preferences != null) {
|
||||
final String value = preferences.getString(context.getString(R.string.p_calc_history), null);
|
||||
this.savedHistory.clear();
|
||||
HistoryUtils.fromXml(value, this.savedHistory);
|
||||
for (CalculatorHistoryState historyState : savedHistory) {
|
||||
historyState.setSaved(true);
|
||||
historyState.setId(counter++);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void save(@NotNull Context context) {
|
||||
final SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
final SharedPreferences.Editor editor = settings.edit();
|
||||
|
||||
editor.putString(context.getString(R.string.p_calc_history), HistoryUtils.toXml(this.savedHistory));
|
||||
|
||||
editor.commit();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<CalculatorHistoryState> getSavedHistory() {
|
||||
return Collections.unmodifiableList(savedHistory);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public CalculatorHistoryState addSavedState(@NotNull CalculatorHistoryState historyState) {
|
||||
if (historyState.isSaved()) {
|
||||
return historyState;
|
||||
} else {
|
||||
final CalculatorHistoryState savedState = historyState.clone();
|
||||
|
||||
savedState.setId(counter++);
|
||||
savedState.setSaved(true);
|
||||
|
||||
savedHistory.add(savedState);
|
||||
|
||||
return savedState;
|
||||
}
|
||||
}
|
||||
|
||||
public void clearSavedHistory(@NotNull Context context) {
|
||||
this.savedHistory.clear();
|
||||
save(context);
|
||||
}
|
||||
|
||||
public void removeSavedHistory(@NotNull CalculatorHistoryState historyState, @NotNull Context context) {
|
||||
historyState.setSaved(false);
|
||||
this.savedHistory.remove(historyState);
|
||||
save(context);
|
||||
}
|
||||
}
|
@ -26,12 +26,12 @@ public class HistoryActivityTab extends AbstractHistoryActivity {
|
||||
@NotNull
|
||||
@Override
|
||||
protected List<CalculatorHistoryState> getHistoryItems() {
|
||||
return new ArrayList<CalculatorHistoryState>(CalculatorHistory.instance.getStates());
|
||||
return new ArrayList<CalculatorHistoryState>(AndroidCalculatorHistoryImpl.instance.getStates());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void clearHistory() {
|
||||
CalculatorHistory.instance.clear();
|
||||
AndroidCalculatorHistoryImpl.instance.clear();
|
||||
getAdapter().clear();
|
||||
}
|
||||
}
|
||||
|
@ -96,7 +96,7 @@ public enum HistoryItemMenuItem implements LabeledMenuItem<HistoryItemMenuData>
|
||||
final CalculatorHistoryState historyState = data.getHistoryState();
|
||||
if (historyState.isSaved()) {
|
||||
data.getAdapter().remove(historyState);
|
||||
CalculatorHistory.instance.removeSavedHistory(historyState, context);
|
||||
AndroidCalculatorHistoryImpl.instance.removeSavedHistory(historyState, context);
|
||||
Toast.makeText(context, context.getText(R.string.c_history_was_removed), Toast.LENGTH_LONG).show();
|
||||
data.getAdapter().notifyDataSetChanged();
|
||||
}
|
||||
@ -122,14 +122,14 @@ public enum HistoryItemMenuItem implements LabeledMenuItem<HistoryItemMenuData>
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
if (save) {
|
||||
final CalculatorHistoryState savedHistoryItem = CalculatorHistory.instance.addSavedState(historyState);
|
||||
final CalculatorHistoryState savedHistoryItem = AndroidCalculatorHistoryImpl.instance.addSavedState(historyState);
|
||||
savedHistoryItem.setComment(comment.getText().toString());
|
||||
CalculatorHistory.instance.save(context);
|
||||
AndroidCalculatorHistoryImpl.instance.save(context);
|
||||
// we don't need to add element to the adapter as adapter of another activity must be updated and not this
|
||||
//data.getAdapter().add(savedHistoryItem);
|
||||
} else {
|
||||
historyState.setComment(comment.getText().toString());
|
||||
CalculatorHistory.instance.save(context);
|
||||
AndroidCalculatorHistoryImpl.instance.save(context);
|
||||
}
|
||||
data.getAdapter().notifyDataSetChanged();
|
||||
Toast.makeText(context, context.getText(R.string.c_history_saved), Toast.LENGTH_LONG).show();
|
||||
|
@ -26,12 +26,12 @@ public class SavedHistoryActivityTab extends AbstractHistoryActivity {
|
||||
@NotNull
|
||||
@Override
|
||||
protected List<CalculatorHistoryState> getHistoryItems() {
|
||||
return new ArrayList<CalculatorHistoryState>(CalculatorHistory.instance.getSavedHistory());
|
||||
return new ArrayList<CalculatorHistoryState>(AndroidCalculatorHistoryImpl.instance.getSavedHistory());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void clearHistory() {
|
||||
CalculatorHistory.instance.clearSavedHistory(this);
|
||||
AndroidCalculatorHistoryImpl.instance.clearSavedHistory(this);
|
||||
getAdapter().clear();
|
||||
}
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ import android.widget.EditText;
|
||||
import android.widget.TextView;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.solovyev.android.calculator.Editor;
|
||||
|
||||
/**
|
||||
* User: serso
|
||||
|
@ -15,14 +15,16 @@ import jscl.math.operator.Operator;
|
||||
import jscl.text.ParseInterruptedException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.solovyev.android.calculator.CalculatorApplication;
|
||||
import org.solovyev.android.calculator.R;
|
||||
import org.solovyev.android.calculator.*;
|
||||
import org.solovyev.android.calculator.jscl.JsclOperation;
|
||||
import org.solovyev.android.calculator.text.TextProcessor;
|
||||
import org.solovyev.android.msg.AndroidMessage;
|
||||
import org.solovyev.android.prefs.BooleanPreference;
|
||||
import org.solovyev.android.prefs.Preference;
|
||||
import org.solovyev.android.prefs.StringPreference;
|
||||
import org.solovyev.common.MutableObject;
|
||||
import org.solovyev.common.msg.MessageRegistry;
|
||||
import org.solovyev.common.msg.MessageType;
|
||||
import org.solovyev.common.text.EnumMapper;
|
||||
import org.solovyev.common.text.NumberMapper;
|
||||
import org.solovyev.common.text.StringUtils;
|
||||
@ -40,7 +42,7 @@ import java.util.concurrent.TimeUnit;
|
||||
* Time: 11:38 PM
|
||||
*/
|
||||
|
||||
public enum CalculatorEngine {
|
||||
public enum CalculatorEngine implements JCalculatorEngine {
|
||||
|
||||
instance;
|
||||
|
||||
@ -130,6 +132,7 @@ public enum CalculatorEngine {
|
||||
this.engine.setUseGroupingSeparator(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public String getMultiplicationSign() {
|
||||
return multiplicationSign;
|
||||
@ -139,45 +142,12 @@ public enum CalculatorEngine {
|
||||
this.multiplicationSign = multiplicationSign;
|
||||
}
|
||||
|
||||
public static class Result {
|
||||
|
||||
@NotNull
|
||||
private Generic genericResult;
|
||||
|
||||
@NotNull
|
||||
private String result;
|
||||
|
||||
@NotNull
|
||||
private JsclOperation userOperation;
|
||||
|
||||
public Result(@NotNull String result, @NotNull JsclOperation userOperation, @NotNull Generic genericResult) {
|
||||
this.result = result;
|
||||
this.userOperation = userOperation;
|
||||
this.genericResult = genericResult;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getResult() {
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JsclOperation getUserOperation() {
|
||||
return userOperation;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Generic getGenericResult() {
|
||||
return genericResult;
|
||||
}
|
||||
}
|
||||
|
||||
public Result evaluate(@NotNull JsclOperation operation,
|
||||
public CalculatorOutput evaluate(@NotNull JsclOperation operation,
|
||||
@NotNull String expression) throws CalculatorParseException, CalculatorEvalException {
|
||||
return evaluate(operation, expression, null);
|
||||
}
|
||||
|
||||
public Result evaluate(@NotNull final JsclOperation operation,
|
||||
public CalculatorOutput evaluate(@NotNull final JsclOperation operation,
|
||||
@NotNull String expression,
|
||||
@Nullable MessageRegistry mr) throws CalculatorParseException, CalculatorEvalException {
|
||||
synchronized (lock) {
|
||||
@ -229,10 +199,12 @@ public enum CalculatorEngine {
|
||||
evalException.setObject(new CalculatorEvalException(e, e, jsclExpression));
|
||||
} catch (ArithmeticException e) {
|
||||
//System.out.println(e.getMessage());
|
||||
parseException.setObject(new CalculatorParseException(R.string.msg_1, CalculatorApplication.getInstance(), jsclExpression, e.getMessage()));
|
||||
final AndroidMessage androidMessage = new AndroidMessage(R.string.msg_1, MessageType.error, CalculatorApplication.getInstance(), e.getMessage());
|
||||
parseException.setObject(new CalculatorParseException(jsclExpression, androidMessage));
|
||||
} catch (StackOverflowError e) {
|
||||
//System.out.println(StringUtils.fromStackTrace(e.getStackTrace()));
|
||||
parseException.setObject(new CalculatorParseException(R.string.msg_2, CalculatorApplication.getInstance(), jsclExpression));
|
||||
final AndroidMessage androidMessage = new AndroidMessage(R.string.msg_2, MessageType.error, CalculatorApplication.getInstance());
|
||||
parseException.setObject(new CalculatorParseException(jsclExpression, androidMessage));
|
||||
} catch (jscl.text.ParseException e) {
|
||||
//System.out.println(e.getMessage());
|
||||
parseException.setObject(new CalculatorParseException(e));
|
||||
@ -278,16 +250,18 @@ public enum CalculatorEngine {
|
||||
}
|
||||
|
||||
if (calculationResultLocal == null) {
|
||||
throw new CalculatorParseException(R.string.msg_3, CalculatorApplication.getInstance(), jsclExpression);
|
||||
final AndroidMessage androidMessage = new AndroidMessage(R.string.msg_3, MessageType.error, CalculatorApplication.getInstance());
|
||||
throw new CalculatorParseException(jsclExpression, androidMessage);
|
||||
}
|
||||
|
||||
} catch (InterruptedException e) {
|
||||
throw new CalculatorParseException(R.string.msg_4, CalculatorApplication.getInstance(), jsclExpression);
|
||||
final AndroidMessage androidMessage = new AndroidMessage(R.string.msg_4, MessageType.error, CalculatorApplication.getInstance());
|
||||
throw new CalculatorParseException(jsclExpression, androidMessage);
|
||||
}
|
||||
|
||||
final Generic genericResult = calculationResult.getObject();
|
||||
|
||||
return new Result(operation.getFromProcessor().process(genericResult), operation, genericResult);
|
||||
return new CalculatorOutputImpl(operation.getFromProcessor().process(genericResult), operation, genericResult);
|
||||
}
|
||||
}
|
||||
|
||||
@ -356,26 +330,31 @@ public enum CalculatorEngine {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public AndroidMathRegistry<IConstant> getVarsRegistry() {
|
||||
return varsRegistry;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public AndroidMathRegistry<Function> getFunctionsRegistry() {
|
||||
return functionsRegistry;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public AndroidMathRegistry<Operator> getOperatorsRegistry() {
|
||||
return operatorsRegistry;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public AndroidMathRegistry<Operator> getPostfixFunctionsRegistry() {
|
||||
return postfixFunctionsRegistry;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public MathEngine getEngine() {
|
||||
return engine;
|
||||
|
@ -35,9 +35,9 @@ import org.achartengine.tools.ZoomListener;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.solovyev.android.calculator.R;
|
||||
import org.solovyev.android.calculator.model.CalculatorParseException;
|
||||
import org.solovyev.android.calculator.model.PreparedExpression;
|
||||
import org.solovyev.android.calculator.model.ToJsclTextProcessor;
|
||||
import org.solovyev.android.calculator.CalculatorParseException;
|
||||
import org.solovyev.android.calculator.PreparedExpression;
|
||||
import org.solovyev.android.calculator.ToJsclTextProcessor;
|
||||
import org.solovyev.common.MutableObject;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
@ -6,14 +6,14 @@ import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.solovyev.android.Unit;
|
||||
import org.solovyev.android.UnitImpl;
|
||||
import org.solovyev.math.units.Unit;
|
||||
import org.solovyev.math.units.UnitImpl;
|
||||
import org.solovyev.android.calculator.AndroidNumeralBase;
|
||||
import org.solovyev.android.calculator.CalculatorModel;
|
||||
import org.solovyev.android.calculator.R;
|
||||
import org.solovyev.android.calculator.model.CalculatorEngine;
|
||||
import org.solovyev.android.calculator.model.CalculatorParseException;
|
||||
import org.solovyev.android.calculator.model.ToJsclTextProcessor;
|
||||
import org.solovyev.android.calculator.CalculatorParseException;
|
||||
import org.solovyev.android.calculator.ToJsclTextProcessor;
|
||||
import org.solovyev.common.MutableObject;
|
||||
import org.solovyev.common.text.StringUtils;
|
||||
|
||||
|
@ -9,8 +9,13 @@ package org.solovyev.android.calculator.view;
|
||||
import jscl.MathContext;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.solovyev.android.calculator.AbstractNumberBuilder;
|
||||
import org.solovyev.android.calculator.CalculatorParseException;
|
||||
import org.solovyev.android.calculator.LiteNumberBuilder;
|
||||
import org.solovyev.android.calculator.NumberBuilder;
|
||||
import org.solovyev.android.calculator.math.MathType;
|
||||
import org.solovyev.android.calculator.model.*;
|
||||
import org.solovyev.android.calculator.text.TextProcessor;
|
||||
import org.solovyev.common.MutableObject;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
@ -10,14 +10,14 @@ import android.view.ViewGroup;
|
||||
import android.widget.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.solovyev.android.Unit;
|
||||
import org.solovyev.android.UnitConverter;
|
||||
import org.solovyev.android.UnitImpl;
|
||||
import org.solovyev.android.UnitType;
|
||||
import org.solovyev.android.calculator.CalculatorImpl;
|
||||
import org.solovyev.math.units.Unit;
|
||||
import org.solovyev.math.units.UnitConverter;
|
||||
import org.solovyev.math.units.UnitImpl;
|
||||
import org.solovyev.math.units.UnitType;
|
||||
import org.solovyev.android.calculator.R;
|
||||
import org.solovyev.android.view.ViewBuilder;
|
||||
import org.solovyev.android.view.ViewFromLayoutBuilder;
|
||||
import org.solovyev.common.text.StringUtils;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@ -173,47 +173,12 @@ public class UnitConverterViewBuilder implements ViewBuilder<View> {
|
||||
|
||||
final String from = fromEditText.getText().toString();
|
||||
try {
|
||||
toEditText.setText(doConversion(converter, from, getFromUnitType(main), getToUnitType(main)));
|
||||
} catch (ConversionException e) {
|
||||
toEditText.setText(CalculatorImpl.doConversion(converter, from, getFromUnitType(main), getToUnitType(main)));
|
||||
} catch (CalculatorImpl.ConversionException e) {
|
||||
toEditText.setText(context.getString(R.string.c_error));
|
||||
}
|
||||
}
|
||||
|
||||
public static final class ConversionException extends Exception {
|
||||
private ConversionException() {
|
||||
}
|
||||
|
||||
private ConversionException(Throwable throwable) {
|
||||
super(throwable);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String doConversion(@NotNull UnitConverter<String> converter,
|
||||
@Nullable String from,
|
||||
@NotNull UnitType<String> fromUnitType,
|
||||
@NotNull UnitType<String> toUnitType) throws ConversionException{
|
||||
final String result;
|
||||
|
||||
if (StringUtils.isEmpty(from)) {
|
||||
result = "";
|
||||
} else {
|
||||
|
||||
String to = null;
|
||||
try {
|
||||
if (converter.isSupported(fromUnitType, toUnitType)) {
|
||||
to = converter.convert(UnitImpl.newInstance(from, fromUnitType), toUnitType).getValue();
|
||||
}
|
||||
} catch (RuntimeException e) {
|
||||
throw new ConversionException(e);
|
||||
}
|
||||
|
||||
result = to;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Unit<String> getToUnit(@NotNull View main) {
|
||||
final EditText toUnits = (EditText) main.findViewById(R.id.units_to);
|
||||
|
@ -4,6 +4,8 @@ import junit.framework.Assert;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.junit.Test;
|
||||
import org.solovyev.android.calculator.AndroidNumeralBase;
|
||||
import org.solovyev.math.units.Unit;
|
||||
import org.solovyev.math.units.UnitConverter;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Random;
|
||||
|
@ -12,7 +12,7 @@ import jscl.NumeralBase;
|
||||
import junit.framework.Assert;
|
||||
import org.junit.Test;
|
||||
import org.solovyev.android.calculator.model.CalculatorEngine;
|
||||
import org.solovyev.android.calculator.model.TextProcessor;
|
||||
import org.solovyev.android.calculator.text.TextProcessor;
|
||||
import org.solovyev.android.calculator.view.TextHighlighter;
|
||||
|
||||
import java.util.Date;
|
||||
|
@ -11,7 +11,8 @@ import junit.framework.Assert;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.junit.Test;
|
||||
import org.solovyev.android.calculator.ICalculatorDisplay;
|
||||
import org.solovyev.android.calculator.CalculatorDisplay;
|
||||
import org.solovyev.android.calculator.Editor;
|
||||
import org.solovyev.android.calculator.jscl.JsclOperation;
|
||||
import org.solovyev.common.equals.CollectionEqualizer;
|
||||
import org.solovyev.common.equals.EqualsTool;
|
||||
@ -124,7 +125,7 @@ public class HistoryUtilsTest {
|
||||
|
||||
HistoryHelper<CalculatorHistoryState> history = new SimpleHistoryHelper<CalculatorHistoryState>();
|
||||
|
||||
ICalculatorDisplay calculatorDisplay = new TestCalculatorDisplay();
|
||||
CalculatorDisplay calculatorDisplay = new TestCalculatorDisplay();
|
||||
calculatorDisplay.setErrorMessage("error_msg1");
|
||||
calculatorDisplay.setText("Error");
|
||||
calculatorDisplay.setSelection(1);
|
||||
@ -214,7 +215,7 @@ public class HistoryUtilsTest {
|
||||
}
|
||||
|
||||
|
||||
private static class TestCalculatorDisplay implements ICalculatorDisplay {
|
||||
private static class TestCalculatorDisplay implements CalculatorDisplay {
|
||||
|
||||
@NotNull
|
||||
private final TestEditor testEditor = new TestEditor();
|
||||
|
@ -15,6 +15,8 @@ import jscl.math.function.CustomFunction;
|
||||
import org.junit.Assert;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.solovyev.android.calculator.CalculatorEvalException;
|
||||
import org.solovyev.android.calculator.CalculatorParseException;
|
||||
import org.solovyev.android.calculator.jscl.JsclOperation;
|
||||
|
||||
import java.text.DecimalFormatSymbols;
|
||||
@ -52,13 +54,13 @@ public class CalculatorEngineTest {
|
||||
|
||||
}
|
||||
|
||||
Assert.assertEquals("0.017", cm.evaluate(JsclOperation.numeric, "1°").getResult());
|
||||
Assert.assertEquals("0.349", cm.evaluate(JsclOperation.numeric, "20.0°").getResult());
|
||||
Assert.assertEquals("0.5", cm.evaluate(JsclOperation.numeric, "sin(30°)").getResult());
|
||||
Assert.assertEquals("0.524", cm.evaluate(JsclOperation.numeric, "asin(sin(30°))").getResult());
|
||||
Assert.assertEquals("∂(cos(t), t, t, 1°)", cm.evaluate(JsclOperation.numeric, "∂(cos(t),t,t,1°)").getResult());
|
||||
Assert.assertEquals("0.017", cm.evaluate(JsclOperation.numeric, "1°").getStringResult());
|
||||
Assert.assertEquals("0.349", cm.evaluate(JsclOperation.numeric, "20.0°").getStringResult());
|
||||
Assert.assertEquals("0.5", cm.evaluate(JsclOperation.numeric, "sin(30°)").getStringResult());
|
||||
Assert.assertEquals("0.524", cm.evaluate(JsclOperation.numeric, "asin(sin(30°))").getStringResult());
|
||||
Assert.assertEquals("∂(cos(t), t, t, 1°)", cm.evaluate(JsclOperation.numeric, "∂(cos(t),t,t,1°)").getStringResult());
|
||||
|
||||
Assert.assertEquals("∂(cos(t), t, t, 1°)", cm.evaluate(JsclOperation.simplify, "∂(cos(t),t,t,1°)").getResult());
|
||||
Assert.assertEquals("∂(cos(t), t, t, 1°)", cm.evaluate(JsclOperation.simplify, "∂(cos(t),t,t,1°)").getStringResult());
|
||||
} finally {
|
||||
cm.getEngine().setAngleUnits(defaultAngleUnit);
|
||||
}
|
||||
@ -111,120 +113,120 @@ public class CalculatorEngineTest {
|
||||
public void testEvaluate() throws Exception {
|
||||
final CalculatorEngine cm = CalculatorEngine.instance;
|
||||
|
||||
Assert.assertEquals("cos(t)+10%", cm.evaluate(JsclOperation.simplify, "cos(t)+10%").getResult());
|
||||
Assert.assertEquals("cos(t)+10%", cm.evaluate(JsclOperation.simplify, "cos(t)+10%").getStringResult());
|
||||
|
||||
final Generic expression = cm.getEngine().simplifyGeneric("cos(t)+10%");
|
||||
expression.substitute(new Constant("t"), Expression.valueOf(100d));
|
||||
|
||||
Assert.assertEquals("it", cm.evaluate(JsclOperation.simplify, "it").getResult());
|
||||
Assert.assertEquals("10%", cm.evaluate(JsclOperation.simplify, "10%").getResult());
|
||||
Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "eq(0, 1)").getResult());
|
||||
Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "eq(1, 1)").getResult());
|
||||
Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "eq( 1, 1)").getResult());
|
||||
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());
|
||||
Assert.assertEquals("it", cm.evaluate(JsclOperation.simplify, "it").getStringResult());
|
||||
Assert.assertEquals("10%", cm.evaluate(JsclOperation.simplify, "10%").getStringResult());
|
||||
Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "eq(0, 1)").getStringResult());
|
||||
Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "eq(1, 1)").getStringResult());
|
||||
Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "eq( 1, 1)").getStringResult());
|
||||
Assert.assertEquals("1", cm.evaluate(JsclOperation.simplify, "eq( 1, 1)").getStringResult());
|
||||
Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "lg(10)").getStringResult());
|
||||
Assert.assertEquals("4", cm.evaluate(JsclOperation.numeric, "2+2").getStringResult());
|
||||
final AngleUnit defaultAngleUnit = cm.getEngine().getAngleUnits();
|
||||
try {
|
||||
cm.getEngine().setAngleUnits(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());
|
||||
Assert.assertEquals("-0.757", cm.evaluate(JsclOperation.numeric, "sin(4)").getStringResult());
|
||||
Assert.assertEquals("0.524", cm.evaluate(JsclOperation.numeric, "asin(0.5)").getStringResult());
|
||||
Assert.assertEquals("-0.396", cm.evaluate(JsclOperation.numeric, "sin(4)asin(0.5)").getStringResult());
|
||||
Assert.assertEquals("-0.56", cm.evaluate(JsclOperation.numeric, "sin(4)asin(0.5)√(2)").getStringResult());
|
||||
Assert.assertEquals("-0.56", cm.evaluate(JsclOperation.numeric, "sin(4)asin(0.5)√(2)").getStringResult());
|
||||
} finally {
|
||||
cm.getEngine().setAngleUnits(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());
|
||||
Assert.assertEquals("7.389", cm.evaluate(JsclOperation.numeric, "e^2").getStringResult());
|
||||
Assert.assertEquals("7.389", cm.evaluate(JsclOperation.numeric, "exp(1)^2").getStringResult());
|
||||
Assert.assertEquals("7.389", cm.evaluate(JsclOperation.numeric, "exp(2)").getStringResult());
|
||||
Assert.assertEquals("2+i", cm.evaluate(JsclOperation.numeric, "2*1+√(-1)").getStringResult());
|
||||
try {
|
||||
cm.getEngine().setAngleUnits(AngleUnit.rad);
|
||||
Assert.assertEquals("0.921+Πi", 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());
|
||||
Assert.assertEquals("0.921+Πi", cm.evaluate(JsclOperation.numeric, "ln(5cosh(38π√(2cos(2))))").getStringResult());
|
||||
Assert.assertEquals("-3.41+3.41i", cm.evaluate(JsclOperation.numeric, "(5tan(2i)+2i)/(1-i)").getStringResult());
|
||||
} finally {
|
||||
cm.getEngine().setAngleUnits(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());
|
||||
Assert.assertEquals("2+7.389i", cm.evaluate(JsclOperation.numeric, "2+√(-1)exp(2)").getResult());
|
||||
Assert.assertEquals("2-2.5i", cm.evaluate(JsclOperation.numeric, "2-2.5i").getResult());
|
||||
Assert.assertEquals("-2-2.5i", cm.evaluate(JsclOperation.numeric, "-2-2.5i").getResult());
|
||||
Assert.assertEquals("-2+2.5i", cm.evaluate(JsclOperation.numeric, "-2+2.5i").getResult());
|
||||
Assert.assertEquals("-2+2.1i", cm.evaluate(JsclOperation.numeric, "-2+2.1i").getResult());
|
||||
Assert.assertEquals("-0.1-0.2i", cm.evaluate(JsclOperation.numeric, "(1-i)/(2+6i)").getResult());
|
||||
Assert.assertEquals("7.389i", cm.evaluate(JsclOperation.numeric, "iexp(2)").getStringResult());
|
||||
Assert.assertEquals("2+7.389i", cm.evaluate(JsclOperation.numeric, "2+iexp(2)").getStringResult());
|
||||
Assert.assertEquals("2+7.389i", cm.evaluate(JsclOperation.numeric, "2+√(-1)exp(2)").getStringResult());
|
||||
Assert.assertEquals("2-2.5i", cm.evaluate(JsclOperation.numeric, "2-2.5i").getStringResult());
|
||||
Assert.assertEquals("-2-2.5i", cm.evaluate(JsclOperation.numeric, "-2-2.5i").getStringResult());
|
||||
Assert.assertEquals("-2+2.5i", cm.evaluate(JsclOperation.numeric, "-2+2.5i").getStringResult());
|
||||
Assert.assertEquals("-2+2.1i", cm.evaluate(JsclOperation.numeric, "-2+2.1i").getStringResult());
|
||||
Assert.assertEquals("-0.1-0.2i", cm.evaluate(JsclOperation.numeric, "(1-i)/(2+6i)").getStringResult());
|
||||
|
||||
junit.framework.Assert.assertEquals("24", cm.evaluate(JsclOperation.numeric, "4!").getResult());
|
||||
junit.framework.Assert.assertEquals("24", cm.evaluate(JsclOperation.numeric, "(2+2)!").getResult());
|
||||
junit.framework.Assert.assertEquals("120", cm.evaluate(JsclOperation.numeric, "(2+2+1)!").getResult());
|
||||
junit.framework.Assert.assertEquals("24", cm.evaluate(JsclOperation.numeric, "(2.0+2.0)!").getResult());
|
||||
junit.framework.Assert.assertEquals("24", cm.evaluate(JsclOperation.numeric, "4.0!").getResult());
|
||||
junit.framework.Assert.assertEquals("720", cm.evaluate(JsclOperation.numeric, "(3!)!").getResult());
|
||||
junit.framework.Assert.assertEquals("24", cm.evaluate(JsclOperation.numeric, "4!").getStringResult());
|
||||
junit.framework.Assert.assertEquals("24", cm.evaluate(JsclOperation.numeric, "(2+2)!").getStringResult());
|
||||
junit.framework.Assert.assertEquals("120", cm.evaluate(JsclOperation.numeric, "(2+2+1)!").getStringResult());
|
||||
junit.framework.Assert.assertEquals("24", cm.evaluate(JsclOperation.numeric, "(2.0+2.0)!").getStringResult());
|
||||
junit.framework.Assert.assertEquals("24", cm.evaluate(JsclOperation.numeric, "4.0!").getStringResult());
|
||||
junit.framework.Assert.assertEquals("720", cm.evaluate(JsclOperation.numeric, "(3!)!").getStringResult());
|
||||
junit.framework.Assert.assertEquals("36", Expression.valueOf("3!^2").numeric().toString());
|
||||
junit.framework.Assert.assertEquals("3", Expression.valueOf("cubic(27)").numeric().toString());
|
||||
try {
|
||||
junit.framework.Assert.assertEquals("√(-1)!", cm.evaluate(JsclOperation.numeric, "i!").getResult());
|
||||
junit.framework.Assert.assertEquals("√(-1)!", cm.evaluate(JsclOperation.numeric, "i!").getStringResult());
|
||||
fail();
|
||||
} catch (CalculatorParseException e) {
|
||||
}
|
||||
|
||||
junit.framework.Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "(π/π)!").getResult());
|
||||
junit.framework.Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "(π/π)!").getStringResult());
|
||||
|
||||
try {
|
||||
junit.framework.Assert.assertEquals("i", cm.evaluate(JsclOperation.numeric, "(-1)i!").getResult());
|
||||
junit.framework.Assert.assertEquals("i", cm.evaluate(JsclOperation.numeric, "(-1)i!").getStringResult());
|
||||
fail();
|
||||
} catch (CalculatorParseException e) {
|
||||
|
||||
}
|
||||
junit.framework.Assert.assertEquals("24i", cm.evaluate(JsclOperation.numeric, "4!i").getResult());
|
||||
junit.framework.Assert.assertEquals("24i", cm.evaluate(JsclOperation.numeric, "4!i").getStringResult());
|
||||
|
||||
CalculatorEngine.instance.getVarsRegistry().add(new Var.Builder("si", 5d));
|
||||
|
||||
try {
|
||||
cm.getEngine().setAngleUnits(AngleUnit.rad);
|
||||
Assert.assertEquals("0.451", cm.evaluate(JsclOperation.numeric, "acos(0.8999999999999811)").getResult());
|
||||
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());
|
||||
Assert.assertEquals("0.451", cm.evaluate(JsclOperation.numeric, "acos(0.8999999999999811)").getStringResult());
|
||||
Assert.assertEquals("-0.959", cm.evaluate(JsclOperation.numeric, "sin(5)").getStringResult());
|
||||
Assert.assertEquals("-4.795", cm.evaluate(JsclOperation.numeric, "sin(5)si").getStringResult());
|
||||
Assert.assertEquals("-23.973", cm.evaluate(JsclOperation.numeric, "sisin(5)si").getStringResult());
|
||||
Assert.assertEquals("-23.973", cm.evaluate(JsclOperation.numeric, "si*sin(5)si").getStringResult());
|
||||
Assert.assertEquals("-3.309", cm.evaluate(JsclOperation.numeric, "sisin(5si)si").getStringResult());
|
||||
} finally {
|
||||
cm.getEngine().setAngleUnits(defaultAngleUnit);
|
||||
}
|
||||
|
||||
CalculatorEngine.instance.getVarsRegistry().add(new Var.Builder("s", 1d));
|
||||
Assert.assertEquals("5", cm.evaluate(JsclOperation.numeric, "si").getResult());
|
||||
Assert.assertEquals("5", cm.evaluate(JsclOperation.numeric, "si").getStringResult());
|
||||
|
||||
CalculatorEngine.instance.getVarsRegistry().add(new Var.Builder("k", 3.5d));
|
||||
CalculatorEngine.instance.getVarsRegistry().add(new Var.Builder("k1", 4d));
|
||||
Assert.assertEquals("4", cm.evaluate(JsclOperation.numeric, "k11").getResult());
|
||||
Assert.assertEquals("4", cm.evaluate(JsclOperation.numeric, "k11").getStringResult());
|
||||
|
||||
CalculatorEngine.instance.getVarsRegistry().add(new Var.Builder("t", (String) null));
|
||||
Assert.assertEquals("11t", cm.evaluate(JsclOperation.numeric, "t11").getResult());
|
||||
Assert.assertEquals("11et", cm.evaluate(JsclOperation.numeric, "t11e").getResult());
|
||||
Assert.assertEquals("∞", cm.evaluate(JsclOperation.numeric, "∞").getResult());
|
||||
Assert.assertEquals("∞", cm.evaluate(JsclOperation.numeric, "Infinity").getResult());
|
||||
Assert.assertEquals("11∞t", cm.evaluate(JsclOperation.numeric, "t11∞").getResult());
|
||||
Assert.assertEquals("-t+t^3", cm.evaluate(JsclOperation.numeric, "t(t-1)(t+1)").getResult());
|
||||
Assert.assertEquals("11t", cm.evaluate(JsclOperation.numeric, "t11").getStringResult());
|
||||
Assert.assertEquals("11et", cm.evaluate(JsclOperation.numeric, "t11e").getStringResult());
|
||||
Assert.assertEquals("∞", cm.evaluate(JsclOperation.numeric, "∞").getStringResult());
|
||||
Assert.assertEquals("∞", cm.evaluate(JsclOperation.numeric, "Infinity").getStringResult());
|
||||
Assert.assertEquals("11∞t", cm.evaluate(JsclOperation.numeric, "t11∞").getStringResult());
|
||||
Assert.assertEquals("-t+t^3", cm.evaluate(JsclOperation.numeric, "t(t-1)(t+1)").getStringResult());
|
||||
|
||||
Assert.assertEquals("100", cm.evaluate(JsclOperation.numeric, "0.1E3").getResult());
|
||||
Assert.assertEquals("3.957", cm.evaluate(JsclOperation.numeric, "ln(8)lg(8)+ln(8)").getResult());
|
||||
Assert.assertEquals("100", cm.evaluate(JsclOperation.numeric, "0.1E3").getStringResult());
|
||||
Assert.assertEquals("3.957", cm.evaluate(JsclOperation.numeric, "ln(8)lg(8)+ln(8)").getStringResult());
|
||||
|
||||
Assert.assertEquals("0.933", cm.evaluate(JsclOperation.numeric, "0x:E/0x:F").getResult());
|
||||
Assert.assertEquals("0.933", cm.evaluate(JsclOperation.numeric, "0x:E/0x:F").getStringResult());
|
||||
|
||||
try {
|
||||
cm.getEngine().setNumeralBase(NumeralBase.hex);
|
||||
Assert.assertEquals("E/F", cm.evaluate(JsclOperation.numeric, "0x:E/0x:F").getResult());
|
||||
Assert.assertEquals("E/F", cm.evaluate(JsclOperation.simplify, "0x:E/0x:F").getResult());
|
||||
Assert.assertEquals("E/F", cm.evaluate(JsclOperation.numeric, "E/F").getResult());
|
||||
Assert.assertEquals("E/F", cm.evaluate(JsclOperation.simplify, "E/F").getResult());
|
||||
Assert.assertEquals("E/F", cm.evaluate(JsclOperation.numeric, "0x:E/0x:F").getStringResult());
|
||||
Assert.assertEquals("E/F", cm.evaluate(JsclOperation.simplify, "0x:E/0x:F").getStringResult());
|
||||
Assert.assertEquals("E/F", cm.evaluate(JsclOperation.numeric, "E/F").getStringResult());
|
||||
Assert.assertEquals("E/F", cm.evaluate(JsclOperation.simplify, "E/F").getStringResult());
|
||||
} finally {
|
||||
cm.getEngine().setNumeralBase(NumeralBase.dec);
|
||||
}
|
||||
|
||||
Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "((((((0))))))").getResult());
|
||||
Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((0))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))").getResult());
|
||||
Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "((((((0))))))").getStringResult());
|
||||
Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((0))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))").getStringResult());
|
||||
|
||||
|
||||
/* Assert.assertEquals("0.524", cm.evaluate(JsclOperation.numeric, "30°").getResult());
|
||||
@ -247,11 +249,11 @@ public class CalculatorEngineTest {
|
||||
}*/
|
||||
|
||||
CalculatorEngine.instance.getVarsRegistry().add(new Var.Builder("t", (String) null));
|
||||
Assert.assertEquals("2t", cm.evaluate(JsclOperation.simplify, "∂(t^2,t)").getResult());
|
||||
Assert.assertEquals("2t", cm.evaluate(JsclOperation.numeric, "∂(t^2,t)").getResult());
|
||||
Assert.assertEquals("2t", cm.evaluate(JsclOperation.simplify, "∂(t^2,t)").getStringResult());
|
||||
Assert.assertEquals("2t", cm.evaluate(JsclOperation.numeric, "∂(t^2,t)").getStringResult());
|
||||
CalculatorEngine.instance.getVarsRegistry().add(new Var.Builder("t", "2"));
|
||||
Assert.assertEquals("2t", cm.evaluate(JsclOperation.simplify, "∂(t^2,t)").getResult());
|
||||
Assert.assertEquals("4", cm.evaluate(JsclOperation.numeric, "∂(t^2,t)").getResult());
|
||||
Assert.assertEquals("2t", cm.evaluate(JsclOperation.simplify, "∂(t^2,t)").getStringResult());
|
||||
Assert.assertEquals("4", cm.evaluate(JsclOperation.numeric, "∂(t^2,t)").getStringResult());
|
||||
|
||||
Assert.assertEquals("-x+x*ln(x)", cm.getEngine().simplify("∫(ln(x), x)"));
|
||||
Assert.assertEquals("-(x-x*ln(x))/(ln(2)+ln(5))", cm.getEngine().simplify("∫(log(10, x), x)"));
|
||||
@ -265,7 +267,7 @@ public class CalculatorEngineTest {
|
||||
public void testFormatting() throws Exception {
|
||||
final CalculatorEngine ce = CalculatorEngine.instance;
|
||||
|
||||
Assert.assertEquals("12 345", ce.evaluate(JsclOperation.simplify, "12345").getResult());
|
||||
Assert.assertEquals("12 345", ce.evaluate(JsclOperation.simplify, "12345").getStringResult());
|
||||
|
||||
}
|
||||
|
||||
@ -273,7 +275,7 @@ public class CalculatorEngineTest {
|
||||
public void testI() throws CalculatorParseException, CalculatorEvalException {
|
||||
final CalculatorEngine cm = CalculatorEngine.instance;
|
||||
|
||||
Assert.assertEquals("-i", cm.evaluate(JsclOperation.numeric, "i^3").getResult());
|
||||
Assert.assertEquals("-i", cm.evaluate(JsclOperation.numeric, "i^3").getStringResult());
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
double real = (Math.random()-0.5) * 1000;
|
||||
double imag = (Math.random()-0.5) * 1000;
|
||||
@ -287,7 +289,7 @@ public class CalculatorEngineTest {
|
||||
sb.append(imag);
|
||||
sb.append("^").append(exp);
|
||||
try {
|
||||
cm.evaluate(JsclOperation.numeric, sb.toString()).getResult();
|
||||
cm.evaluate(JsclOperation.numeric, sb.toString()).getStringResult();
|
||||
} catch (Throwable e) {
|
||||
fail(sb.toString());
|
||||
}
|
||||
@ -302,7 +304,7 @@ public class CalculatorEngineTest {
|
||||
Assert.fail();
|
||||
} catch (CalculatorParseException e) {
|
||||
}
|
||||
Assert.assertEquals("0.34+1.382i", cm.evaluate(JsclOperation.numeric, "ln(ln(ln(ln(ln(ln(ln(ln(ln(ln(ln(ln(ln(ln(ln(100)))))))))))))))").getResult());
|
||||
Assert.assertEquals("0.34+1.382i", cm.evaluate(JsclOperation.numeric, "ln(ln(ln(ln(ln(ln(ln(ln(ln(ln(ln(ln(ln(ln(ln(100)))))))))))))))").getStringResult());
|
||||
try {
|
||||
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())))))))))))))))))))))))))))))))))))");
|
||||
Assert.fail();
|
||||
@ -312,13 +314,13 @@ public class CalculatorEngineTest {
|
||||
final AngleUnit defaultAngleUnit = cm.getEngine().getAngleUnits();
|
||||
try {
|
||||
cm.getEngine().setAngleUnits(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());
|
||||
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))))))))))))))))))))))))))))))))))))").getStringResult());
|
||||
} finally {
|
||||
cm.getEngine().setAngleUnits(defaultAngleUnit);
|
||||
}
|
||||
|
||||
CalculatorEngine.instance.getVarsRegistry().add(new Var.Builder("si", 5d));
|
||||
Assert.assertEquals("5", cm.evaluate(JsclOperation.numeric, "si").getResult());
|
||||
Assert.assertEquals("5", cm.evaluate(JsclOperation.numeric, "si").getStringResult());
|
||||
|
||||
try {
|
||||
cm.evaluate(JsclOperation.numeric, "sin");
|
||||
@ -337,11 +339,11 @@ public class CalculatorEngineTest {
|
||||
decimalGroupSymbols.setGroupingSeparator('\'');
|
||||
cm.setDecimalGroupSymbols(decimalGroupSymbols);
|
||||
cm.setPrecision(2);
|
||||
Assert.assertEquals("12'345'678.9", cm.evaluate(JsclOperation.numeric, "1.23456789E7").getResult());
|
||||
Assert.assertEquals("12'345'678.9", cm.evaluate(JsclOperation.numeric, "1.23456789E7").getStringResult());
|
||||
cm.setPrecision(10);
|
||||
Assert.assertEquals("12'345'678.9", cm.evaluate(JsclOperation.numeric, "1.23456789E7").getResult());
|
||||
Assert.assertEquals("123'456'789", cm.evaluate(JsclOperation.numeric, "1.234567890E8").getResult());
|
||||
Assert.assertEquals("1'234'567'890.1", cm.evaluate(JsclOperation.numeric, "1.2345678901E9").getResult());
|
||||
Assert.assertEquals("12'345'678.9", cm.evaluate(JsclOperation.numeric, "1.23456789E7").getStringResult());
|
||||
Assert.assertEquals("123'456'789", cm.evaluate(JsclOperation.numeric, "1.234567890E8").getStringResult());
|
||||
Assert.assertEquals("1'234'567'890.1", cm.evaluate(JsclOperation.numeric, "1.2345678901E9").getStringResult());
|
||||
} finally {
|
||||
cm.setPrecision(3);
|
||||
DecimalFormatSymbols decimalGroupSymbols = new DecimalFormatSymbols(Locale.getDefault());
|
||||
@ -355,36 +357,36 @@ public class CalculatorEngineTest {
|
||||
public void testComparisonFunction() throws Exception {
|
||||
final CalculatorEngine cm = CalculatorEngine.instance;
|
||||
|
||||
Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "eq(0, 1)").getResult());
|
||||
Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "eq(1, 1)").getResult());
|
||||
Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "eq(1, 1.0)").getResult());
|
||||
Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "eq(1, 1.000000000000001)").getResult());
|
||||
Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "eq(1, 0)").getResult());
|
||||
Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "eq(0, 1)").getStringResult());
|
||||
Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "eq(1, 1)").getStringResult());
|
||||
Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "eq(1, 1.0)").getStringResult());
|
||||
Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "eq(1, 1.000000000000001)").getStringResult());
|
||||
Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "eq(1, 0)").getStringResult());
|
||||
|
||||
Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "lt(0, 1)").getResult());
|
||||
Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "lt(1, 1)").getResult());
|
||||
Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "lt(1, 0)").getResult());
|
||||
Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "lt(0, 1)").getStringResult());
|
||||
Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "lt(1, 1)").getStringResult());
|
||||
Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "lt(1, 0)").getStringResult());
|
||||
|
||||
Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "gt(0, 1)").getResult());
|
||||
Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "gt(1, 1)").getResult());
|
||||
Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "gt(1, 0)").getResult());
|
||||
Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "gt(0, 1)").getStringResult());
|
||||
Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "gt(1, 1)").getStringResult());
|
||||
Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "gt(1, 0)").getStringResult());
|
||||
|
||||
Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "ne(0, 1)").getResult());
|
||||
Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "ne(1, 1)").getResult());
|
||||
Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "ne(1, 0)").getResult());
|
||||
Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "ne(0, 1)").getStringResult());
|
||||
Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "ne(1, 1)").getStringResult());
|
||||
Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "ne(1, 0)").getStringResult());
|
||||
|
||||
Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "le(0, 1)").getResult());
|
||||
Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "le(1, 1)").getResult());
|
||||
Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "le(1, 0)").getResult());
|
||||
Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "le(0, 1)").getStringResult());
|
||||
Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "le(1, 1)").getStringResult());
|
||||
Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "le(1, 0)").getStringResult());
|
||||
|
||||
Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "ge(0, 1)").getResult());
|
||||
Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "ge(1, 1)").getResult());
|
||||
Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "ge(1, 0)").getResult());
|
||||
Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "ge(0, 1)").getStringResult());
|
||||
Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "ge(1, 1)").getStringResult());
|
||||
Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "ge(1, 0)").getStringResult());
|
||||
|
||||
Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "ap(0, 1)").getResult());
|
||||
Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "ap(1, 1)").getResult());
|
||||
Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "ap(0, 1)").getStringResult());
|
||||
Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "ap(1, 1)").getStringResult());
|
||||
//Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "ap(1, 1.000000000000001)").getResult());
|
||||
Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "ap(1, 0)").getResult());
|
||||
Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "ap(1, 0)").getStringResult());
|
||||
|
||||
}
|
||||
|
||||
@ -393,17 +395,17 @@ public class CalculatorEngineTest {
|
||||
public void testNumeralSystems() throws Exception {
|
||||
final CalculatorEngine cm = CalculatorEngine.instance;
|
||||
|
||||
Assert.assertEquals("11 259 375", cm.evaluate(JsclOperation.numeric, "0x:ABCDEF").getResult());
|
||||
Assert.assertEquals("30 606 154.462", cm.evaluate(JsclOperation.numeric, "0x:ABCDEF*e").getResult());
|
||||
Assert.assertEquals("30 606 154.462", cm.evaluate(JsclOperation.numeric, "e*0x:ABCDEF").getResult());
|
||||
Assert.assertEquals("e", cm.evaluate(JsclOperation.numeric, "e*0x:ABCDEF/0x:ABCDEF").getResult());
|
||||
Assert.assertEquals("30 606 154.462", cm.evaluate(JsclOperation.numeric, "0x:ABCDEF*e*0x:ABCDEF/0x:ABCDEF").getResult());
|
||||
Assert.assertEquals("30 606 154.462", cm.evaluate(JsclOperation.numeric, "c+0x:ABCDEF*e*0x:ABCDEF/0x:ABCDEF-c+0x:C-0x:C").getResult());
|
||||
Assert.assertEquals("1 446 257 064 651.832", cm.evaluate(JsclOperation.numeric, "28*28 * sin(28) - 0b:1101 + √(28) + exp ( 28) ").getResult());
|
||||
Assert.assertEquals("13", cm.evaluate(JsclOperation.numeric, "0b:1101").getResult());
|
||||
Assert.assertEquals("11 259 375", cm.evaluate(JsclOperation.numeric, "0x:ABCDEF").getStringResult());
|
||||
Assert.assertEquals("30 606 154.462", cm.evaluate(JsclOperation.numeric, "0x:ABCDEF*e").getStringResult());
|
||||
Assert.assertEquals("30 606 154.462", cm.evaluate(JsclOperation.numeric, "e*0x:ABCDEF").getStringResult());
|
||||
Assert.assertEquals("e", cm.evaluate(JsclOperation.numeric, "e*0x:ABCDEF/0x:ABCDEF").getStringResult());
|
||||
Assert.assertEquals("30 606 154.462", cm.evaluate(JsclOperation.numeric, "0x:ABCDEF*e*0x:ABCDEF/0x:ABCDEF").getStringResult());
|
||||
Assert.assertEquals("30 606 154.462", cm.evaluate(JsclOperation.numeric, "c+0x:ABCDEF*e*0x:ABCDEF/0x:ABCDEF-c+0x:C-0x:C").getStringResult());
|
||||
Assert.assertEquals("1 446 257 064 651.832", cm.evaluate(JsclOperation.numeric, "28*28 * sin(28) - 0b:1101 + √(28) + exp ( 28) ").getStringResult());
|
||||
Assert.assertEquals("13", cm.evaluate(JsclOperation.numeric, "0b:1101").getStringResult());
|
||||
|
||||
try {
|
||||
cm.evaluate(JsclOperation.numeric, "0b:π").getResult();
|
||||
cm.evaluate(JsclOperation.numeric, "0b:π").getStringResult();
|
||||
Assert.fail();
|
||||
} catch (CalculatorParseException e) {
|
||||
// ok
|
||||
@ -412,12 +414,12 @@ public class CalculatorEngineTest {
|
||||
final NumeralBase defaultNumeralBase = cm.getEngine().getNumeralBase();
|
||||
try{
|
||||
cm.getEngine().setNumeralBase(NumeralBase.bin);
|
||||
Assert.assertEquals("101", cm.evaluate(JsclOperation.numeric, "10+11").getResult());
|
||||
Assert.assertEquals("10/11", cm.evaluate(JsclOperation.numeric, "10/11").getResult());
|
||||
Assert.assertEquals("101", cm.evaluate(JsclOperation.numeric, "10+11").getStringResult());
|
||||
Assert.assertEquals("10/11", cm.evaluate(JsclOperation.numeric, "10/11").getStringResult());
|
||||
|
||||
cm.getEngine().setNumeralBase(NumeralBase.hex);
|
||||
Assert.assertEquals("63 7B", cm.evaluate(JsclOperation.numeric, "56CE+CAD").getResult());
|
||||
Assert.assertEquals("E", cm.evaluate(JsclOperation.numeric, "E").getResult());
|
||||
Assert.assertEquals("63 7B", cm.evaluate(JsclOperation.numeric, "56CE+CAD").getStringResult());
|
||||
Assert.assertEquals("E", cm.evaluate(JsclOperation.numeric, "E").getStringResult());
|
||||
} finally {
|
||||
cm.setNumeralBase(defaultNumeralBase);
|
||||
}
|
||||
@ -432,12 +434,12 @@ public class CalculatorEngineTest {
|
||||
|
||||
// logarithm
|
||||
Assert.assertEquals("ln(x)/ln(base)", ((CustomFunction) cm.getFunctionsRegistry().get("log")).getContent());
|
||||
Assert.assertEquals("∞", cm.evaluate(JsclOperation.numeric, "log(1, 10)").getResult());
|
||||
Assert.assertEquals("3.322", cm.evaluate(JsclOperation.numeric, "log(2, 10)").getResult());
|
||||
Assert.assertEquals("1.431", cm.evaluate(JsclOperation.numeric, "log(5, 10)").getResult());
|
||||
Assert.assertEquals("0.96", cm.evaluate(JsclOperation.numeric, "log(11, 10)").getResult());
|
||||
Assert.assertEquals("1/(bln(a))", cm.evaluate(JsclOperation.simplify, "∂(log(a, b), b)").getResult());
|
||||
Assert.assertEquals("-ln(b)/(aln(a)^2)", cm.evaluate(JsclOperation.simplify, "∂(log(a, b), a)").getResult());
|
||||
Assert.assertEquals("∞", cm.evaluate(JsclOperation.numeric, "log(1, 10)").getStringResult());
|
||||
Assert.assertEquals("3.322", cm.evaluate(JsclOperation.numeric, "log(2, 10)").getStringResult());
|
||||
Assert.assertEquals("1.431", cm.evaluate(JsclOperation.numeric, "log(5, 10)").getStringResult());
|
||||
Assert.assertEquals("0.96", cm.evaluate(JsclOperation.numeric, "log(11, 10)").getStringResult());
|
||||
Assert.assertEquals("1/(bln(a))", cm.evaluate(JsclOperation.simplify, "∂(log(a, b), b)").getStringResult());
|
||||
Assert.assertEquals("-ln(b)/(aln(a)^2)", cm.evaluate(JsclOperation.simplify, "∂(log(a, b), a)").getStringResult());
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package org.solovyev.android.calculator.model;
|
||||
import org.junit.Assert;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.solovyev.android.calculator.text.FromJsclSimplifyTextProcessor;
|
||||
|
||||
import java.text.DecimalFormatSymbols;
|
||||
|
||||
|
@ -10,6 +10,8 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.junit.Assert;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.solovyev.android.calculator.CalculatorEvalException;
|
||||
import org.solovyev.android.calculator.CalculatorParseException;
|
||||
import org.solovyev.android.calculator.jscl.JsclOperation;
|
||||
import org.solovyev.common.Converter;
|
||||
|
||||
@ -98,11 +100,11 @@ public class NumeralBaseTest {
|
||||
final String bin = "0b:" + line[2].toUpperCase();
|
||||
|
||||
final String decExpression = converter.convert(dec);
|
||||
final String decResult = CalculatorEngine.instance.evaluate(JsclOperation.numeric, decExpression).getResult();
|
||||
final String decResult = CalculatorEngine.instance.evaluate(JsclOperation.numeric, decExpression).getStringResult();
|
||||
final String hexExpression = converter.convert(hex);
|
||||
final String hexResult = CalculatorEngine.instance.evaluate(JsclOperation.numeric, hexExpression).getResult();
|
||||
final String hexResult = CalculatorEngine.instance.evaluate(JsclOperation.numeric, hexExpression).getStringResult();
|
||||
final String binExpression = converter.convert(bin);
|
||||
final String binResult = CalculatorEngine.instance.evaluate(JsclOperation.numeric, binExpression).getResult();
|
||||
final String binResult = CalculatorEngine.instance.evaluate(JsclOperation.numeric, binExpression).getStringResult();
|
||||
|
||||
Assert.assertEquals("dec-hex: " + decExpression + " : " + hexExpression, decResult, hexResult);
|
||||
Assert.assertEquals("dec-bin: " + decExpression + " : " + binExpression, decResult, binResult);
|
||||
|
@ -11,6 +11,10 @@ import jscl.NumeralBase;
|
||||
import org.junit.Assert;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.solovyev.android.calculator.CalculatorParseException;
|
||||
import org.solovyev.android.calculator.PreparedExpression;
|
||||
import org.solovyev.android.calculator.ToJsclTextProcessor;
|
||||
import org.solovyev.android.calculator.text.TextProcessor;
|
||||
|
||||
/**
|
||||
* User: serso
|
||||
|
37
pom.xml
37
pom.xml
@ -15,6 +15,7 @@
|
||||
<module>calculatorpp</module>
|
||||
<module>calculatorpp-service</module>
|
||||
<module>calculatorpp-test</module>
|
||||
<module>calculatorpp-core</module>
|
||||
</modules>
|
||||
|
||||
<properties>
|
||||
@ -71,6 +72,18 @@
|
||||
<version>1.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.solovyev</groupId>
|
||||
<artifactId>jscl</artifactId>
|
||||
<version>0.0.2</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>xercesImpl</artifactId>
|
||||
<groupId>xerces</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.solovyev.android</groupId>
|
||||
<artifactId>android-common-other</artifactId>
|
||||
@ -81,7 +94,13 @@
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.8.1</version>
|
||||
<version>4.8.2</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.intellij</groupId>
|
||||
<artifactId>annotations</artifactId>
|
||||
<version>7.0.3</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@ -103,6 +122,22 @@
|
||||
<version>11.0.2</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.simpleframework</groupId>
|
||||
<artifactId>simple-xml</artifactId>
|
||||
<version>2.6.1</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>stax-api</artifactId>
|
||||
<groupId>stax</groupId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<artifactId>xpp3</artifactId>
|
||||
<groupId>xpp3</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user