diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/model/AbstractNumberBuilder.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/AbstractNumberBuilder.java similarity index 95% rename from calculatorpp/src/main/java/org/solovyev/android/calculator/model/AbstractNumberBuilder.java rename to calculatorpp-core/src/main/java/org/solovyev/android/calculator/AbstractNumberBuilder.java index d4dac24b..a95e6703 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/model/AbstractNumberBuilder.java +++ b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/AbstractNumberBuilder.java @@ -1,85 +1,85 @@ -/* - * 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.model; - -import jscl.MathEngine; -import jscl.NumeralBase; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.solovyev.android.calculator.math.MathType; -import org.solovyev.common.text.StringUtils; - -/** - * User: serso - * Date: 12/15/11 - * Time: 9:01 PM - */ -public abstract class AbstractNumberBuilder { - - @NotNull - protected final MathEngine engine; - - @Nullable - protected StringBuilder numberBuilder = null; - - @Nullable - protected NumeralBase nb; - - protected AbstractNumberBuilder(@NotNull MathEngine engine) { - this.engine = engine; - this.nb = engine.getNumeralBase(); - } - - /** - * Method determines if we can continue to process current number - * - * @param mathTypeResult current math type result - * @return true if we can continue of processing of current number, if false - new number should be constructed - */ - protected boolean canContinue(@NotNull MathType.Result mathTypeResult) { - boolean result = mathTypeResult.getMathType().getGroupType() == MathType.MathGroupType.number && - !spaceBefore(mathTypeResult) && - numeralBaseCheck(mathTypeResult) && - numeralBaseInTheStart(mathTypeResult.getMathType()) || isSignAfterE(mathTypeResult); - return result; - } - - private boolean spaceBefore(@NotNull MathType.Result mathTypeResult) { - return numberBuilder == null && StringUtils.isEmpty(mathTypeResult.getMatch().trim()); - } - - private boolean numeralBaseInTheStart(@NotNull MathType mathType) { - return mathType != MathType.numeral_base || numberBuilder == null; - } - - private boolean numeralBaseCheck(@NotNull MathType.Result mathType) { - return mathType.getMathType() != MathType.digit || getNumeralBase().getAcceptableCharacters().contains(mathType.getMatch().charAt(0)); - } - - private boolean isSignAfterE(@NotNull MathType.Result mathTypeResult) { - if (!isHexMode()) { - if ("-".equals(mathTypeResult.getMatch()) || "+".equals(mathTypeResult.getMatch())) { - final StringBuilder localNb = numberBuilder; - if (localNb != null && localNb.length() > 0) { - if (localNb.charAt(localNb.length() - 1) == MathType.POWER_10) { - return true; - } - } - } - } - return false; - } - - public boolean isHexMode() { - return nb == NumeralBase.hex || (nb == null && engine.getNumeralBase() == NumeralBase.hex); - } - - @NotNull - protected NumeralBase getNumeralBase() { - return nb == null ? engine.getNumeralBase() : nb; - } -} +/* + * 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.MathEngine; +import jscl.NumeralBase; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.solovyev.android.calculator.math.MathType; +import org.solovyev.common.text.StringUtils; + +/** + * User: serso + * Date: 12/15/11 + * Time: 9:01 PM + */ +public abstract class AbstractNumberBuilder { + + @NotNull + protected final MathEngine engine; + + @Nullable + protected StringBuilder numberBuilder = null; + + @Nullable + protected NumeralBase nb; + + protected AbstractNumberBuilder(@NotNull MathEngine engine) { + this.engine = engine; + this.nb = engine.getNumeralBase(); + } + + /** + * Method determines if we can continue to process current number + * + * @param mathTypeResult current math type result + * @return true if we can continue of processing of current number, if false - new number should be constructed + */ + protected boolean canContinue(@NotNull MathType.Result mathTypeResult) { + boolean result = mathTypeResult.getMathType().getGroupType() == MathType.MathGroupType.number && + !spaceBefore(mathTypeResult) && + numeralBaseCheck(mathTypeResult) && + numeralBaseInTheStart(mathTypeResult.getMathType()) || isSignAfterE(mathTypeResult); + return result; + } + + private boolean spaceBefore(@NotNull MathType.Result mathTypeResult) { + return numberBuilder == null && StringUtils.isEmpty(mathTypeResult.getMatch().trim()); + } + + private boolean numeralBaseInTheStart(@NotNull MathType mathType) { + return mathType != MathType.numeral_base || numberBuilder == null; + } + + private boolean numeralBaseCheck(@NotNull MathType.Result mathType) { + return mathType.getMathType() != MathType.digit || getNumeralBase().getAcceptableCharacters().contains(mathType.getMatch().charAt(0)); + } + + private boolean isSignAfterE(@NotNull MathType.Result mathTypeResult) { + if (!isHexMode()) { + if ("-".equals(mathTypeResult.getMatch()) || "+".equals(mathTypeResult.getMatch())) { + final StringBuilder localNb = numberBuilder; + if (localNb != null && localNb.length() > 0) { + if (localNb.charAt(localNb.length() - 1) == MathType.POWER_10) { + return true; + } + } + } + } + return false; + } + + public boolean isHexMode() { + return nb == NumeralBase.hex || (nb == null && engine.getNumeralBase() == NumeralBase.hex); + } + + @NotNull + protected NumeralBase getNumeralBase() { + return nb == null ? engine.getNumeralBase() : nb; + } +} diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/Calculator.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/Calculator.java new file mode 100644 index 00000000..b310b90c --- /dev/null +++ b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/Calculator.java @@ -0,0 +1,9 @@ +package org.solovyev.android.calculator; + +/** + * User: Solovyev_S + * Date: 20.09.12 + * Time: 16:38 + */ +public interface Calculator extends CalculatorEventContainer { +} diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/model/CalculatorEvalException.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEvalException.java similarity index 92% rename from calculatorpp/src/main/java/org/solovyev/android/calculator/model/CalculatorEvalException.java rename to calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEvalException.java index 5c4e4416..8aba31d2 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/model/CalculatorEvalException.java +++ b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEvalException.java @@ -1,73 +1,72 @@ -/* - * 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.model; - -import jscl.AbstractJsclArithmeticException; -import org.jetbrains.annotations.NotNull; -import org.solovyev.common.exceptions.SersoException; -import org.solovyev.common.msg.Message; -import org.solovyev.common.msg.MessageType; - -import java.util.List; -import java.util.Locale; - -/** - * User: serso - * Date: 12/8/11 - * Time: 1:27 AM - */ -public class CalculatorEvalException extends SersoException implements Message { - - @NotNull - private final Message message; - - @NotNull - private final String expression; - - public CalculatorEvalException(@NotNull Message message, @NotNull Throwable cause, String expression) { - super(cause); - this.message = message; - this.expression = expression; - } - - - @NotNull - public String getExpression() { - return expression; - } - - @NotNull - @Override - public String getMessageCode() { - return this.message.getMessageCode(); - } - - @NotNull - @Override - public List getParameters() { - return this.message.getParameters(); - } - - @NotNull - @Override - public MessageType getMessageType() { - return this.message.getMessageType(); - } - - @Override - @NotNull - public String getLocalizedMessage() { - return this.message.getLocalizedMessage(Locale.getDefault()); - } - - @NotNull - @Override - public String getLocalizedMessage(@NotNull Locale locale) { - return this.message.getLocalizedMessage(locale); - } -} - +/* + * 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.solovyev.common.exceptions.SersoException; +import org.solovyev.common.msg.Message; +import org.solovyev.common.msg.MessageType; + +import java.util.List; +import java.util.Locale; + +/** + * User: serso + * Date: 12/8/11 + * Time: 1:27 AM + */ +public class CalculatorEvalException extends SersoException implements Message { + + @NotNull + private final Message message; + + @NotNull + private final String expression; + + public CalculatorEvalException(@NotNull Message message, @NotNull Throwable cause, String expression) { + super(cause); + this.message = message; + this.expression = expression; + } + + + @NotNull + public String getExpression() { + return expression; + } + + @NotNull + @Override + public String getMessageCode() { + return this.message.getMessageCode(); + } + + @NotNull + @Override + public List getParameters() { + return this.message.getParameters(); + } + + @NotNull + @Override + public MessageType getMessageType() { + return this.message.getMessageType(); + } + + @Override + @NotNull + public String getLocalizedMessage() { + return this.message.getLocalizedMessage(Locale.getDefault()); + } + + @NotNull + @Override + public String getLocalizedMessage(@NotNull Locale locale) { + return this.message.getLocalizedMessage(locale); + } +} + diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEventContainer.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEventContainer.java new file mode 100644 index 00000000..20d918d6 --- /dev/null +++ b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEventContainer.java @@ -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 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; + } + } +} diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEventData.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEventData.java new file mode 100644 index 00000000..5d3b348b --- /dev/null +++ b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEventData.java @@ -0,0 +1,11 @@ +package org.solovyev.android.calculator; + +import org.jetbrains.annotations.Nullable; + +/** + * User: Solovyev_S + * Date: 20.09.12 + * Time: 16:51 + */ +public interface CalculatorEventData extends CalculatorEventDataId { +} diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEventDataId.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEventDataId.java new file mode 100644 index 00000000..58d8dc11 --- /dev/null +++ b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEventDataId.java @@ -0,0 +1,17 @@ +package org.solovyev.android.calculator; + +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(); + + @Nullable + Long getCalculationId(); +} diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEventDataIdImpl.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEventDataIdImpl.java new file mode 100644 index 00000000..1767719f --- /dev/null +++ b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEventDataIdImpl.java @@ -0,0 +1,61 @@ +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 class CalculatorEventDataIdImpl implements CalculatorEventDataId { + + private final long eventId; + + @Nullable + private final Long calculationId; + + private CalculatorEventDataIdImpl(long id, + @Nullable Long calculationId) { + this.eventId = id; + this.calculationId = calculationId; + } + + @NotNull + public static CalculatorEventDataId newInstance(long id, + @Nullable Long calculationId) { + return new CalculatorEventDataIdImpl(id, calculationId); + } + + @Override + public long getEventId() { + return this.eventId; + } + + @Nullable + @Override + public Long getCalculationId() { + return this.calculationId; + } + + @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 (calculationId != null ? !calculationId.equals(that.calculationId) : that.calculationId != null) + return false; + + return true; + } + + @Override + public int hashCode() { + int result = (int) (eventId ^ (eventId >>> 32)); + result = 31 * result + (calculationId != null ? calculationId.hashCode() : 0); + return result; + } +} diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEventDataImpl.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEventDataImpl.java new file mode 100644 index 00000000..18c9a317 --- /dev/null +++ b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEventDataImpl.java @@ -0,0 +1,47 @@ +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; + + CalculatorEventDataImpl(@NotNull CalculatorEventDataId calculatorEventDataId) { + this.calculatorEventDataId = calculatorEventDataId; + } + + @Override + public long getEventId() { + return calculatorEventDataId.getEventId(); + } + + @Override + @Nullable + public Long getCalculationId() { + return calculatorEventDataId.getCalculationId(); + } + + @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(); + } +} diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEventListener.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEventListener.java new file mode 100644 index 00000000..ea4a34f6 --- /dev/null +++ b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEventListener.java @@ -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); + +} diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEventType.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEventType.java new file mode 100644 index 00000000..7df859e9 --- /dev/null +++ b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEventType.java @@ -0,0 +1,9 @@ +package org.solovyev.android.calculator; + +/** + * User: Solovyev_S + * Date: 20.09.12 + * Time: 16:40 + */ +public enum CalculatorEventType { +} diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorImpl.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorImpl.java new file mode 100644 index 00000000..c98d1712 --- /dev/null +++ b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorImpl.java @@ -0,0 +1,168 @@ +package org.solovyev.android.calculator; + +import jscl.AbstractJsclArithmeticException; +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 java.util.List; +import java.util.concurrent.*; +import java.util.concurrent.atomic.AtomicLong; + +/** + * User: Solovyev_S + * Date: 20.09.12 + * Time: 16:42 + */ +public class CalculatorImpl implements Calculator { + + @NotNull + private final CalculatorEventContainer calculatorEventContainer = new ListCalculatorEventContainer(); + + @NotNull + private static final Calculator instance = new CalculatorImpl(); + + @NotNull + private final AtomicLong counter = new AtomicLong(0); + + @NotNull + private final Object lock = new Object(); + + @NotNull + private final TextProcessor preprocessor = ToJsclTextProcessor.getInstance(); + + @NotNull + private final Executor threadPoolExecutor = Executors.newFixedThreadPool(10); + + private CalculatorImpl() { + } + + @NotNull + public static Calculator getInstance() { + return instance; + } + + @NotNull + private CalculatorEventDataId nextCalculatorEventDataId() { + long eventId = counter.incrementAndGet(); + return CalculatorEventDataIdImpl.newInstance(eventId, eventId); + } + + /* + ********************************************************************** + * + * CALCULATION + * + ********************************************************************** + */ + + public void evaluate(@NotNull JsclOperation operation, + @NotNull String expression) { + evaluate(operation, expression, null); + } + + public void 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, operation, expression, mr); + } + }); + } + + private void evaluate(@NotNull CalculatorEventDataId eventDataId, + @NotNull JsclOperation operation, + @NotNull String expression, + @Nullable MessageRegistry mr) { + synchronized (lock) { + PreparedExpression preparedExpression = null; + + try { + preparedExpression = preprocessor.process(expression); + + final String jsclExpression = preparedExpression.toString(); + try { + + final Generic genericResult = operation.evaluateGeneric(jsclExpression); + + // NOTE: toString() method must be called here as ArithmeticOperationException may occur in it (just to avoid later check!) + genericResult.toString(); + + //return new Result(operation.getFromProcessor().process(genericResult), operation, genericResult); + } catch (AbstractJsclArithmeticException e) { + handleException(eventDataId, operation, expression, mr, preparedExpression, null, new CalculatorEvalException(e, e, jsclExpression)); + } + + } catch (ArithmeticException e) { + //final AndroidMessage androidMessage = new AndroidMessage(R.string.msg_1, MessageType.error, CalculatorApplication.getInstance(), e.getMessage()); + handleException(operation, expression, mr, preparedExpression, new CalculatorParseException(jsclExpression, androidMessage)); + } catch (StackOverflowError e) { + //final AndroidMessage androidMessage = new AndroidMessage(R.string.msg_2, MessageType.error, CalculatorApplication.getInstance()); + handleException(eventDataId, operation, expression, mr, preparedExpression, new CalculatorParseException(e), null); + } catch (jscl.text.ParseException e) { + //System.out.println(e.getMessage()); + handleException(eventDataId, operation, expression, mr, preparedExpression, new CalculatorParseException(e), null); + } catch (ParseInterruptedException e) { + // do nothing - we ourselves interrupt the calculations + } catch (CalculatorParseException e) { + handleException(eventDataId, operation, expression, mr, preparedExpression, e, null); + } + } + } + + private void handleException(@NotNull CalculatorEventDataId eventDataId, + @NotNull JsclOperation operation, + @NotNull String expression, + @Nullable MessageRegistry mr, + @Nullable PreparedExpression preparedExpression, + @Nullable CalculatorParseException parseException, + @Nullable CalculatorEvalException evalException) { + if (operation == JsclOperation.numeric && (preparedExpression != null && preparedExpression.isExistsUndefinedVar() || (evalException != null && evalException.getCause() instanceof NumeralBaseException))) { + evaluate(eventDataId, JsclOperation.simplify, expression, mr); + } + + if (parseException != null) { + throw parseException; + } else { + throw 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 calculatorEvents) { + calculatorEventContainer.fireCalculatorEvents(calculatorEvents); + } +} diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/ICalculatorDisplay.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/JCalculatorDisplay.java similarity index 90% rename from calculatorpp-core/src/main/java/org/solovyev/android/calculator/ICalculatorDisplay.java rename to calculatorpp-core/src/main/java/org/solovyev/android/calculator/JCalculatorDisplay.java index 96a61018..1594893a 100644 --- a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/ICalculatorDisplay.java +++ b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/JCalculatorDisplay.java @@ -17,7 +17,7 @@ import org.solovyev.android.calculator.jscl.JsclOperation; * Date: 12/17/11 * Time: 9:45 PM */ -public interface ICalculatorDisplay extends Editor{ +public interface JCalculatorDisplay extends Editor{ boolean isValid(); diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/ListCalculatorEventContainer.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/ListCalculatorEventContainer.java new file mode 100644 index 00000000..09f18ce8 --- /dev/null +++ b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/ListCalculatorEventContainer.java @@ -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 listeners = new ListListenersContainer(); + + @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 calculatorEvents) { + final List 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()); + } + } + } +} diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/model/LiteNumberBuilder.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/LiteNumberBuilder.java similarity index 93% rename from calculatorpp/src/main/java/org/solovyev/android/calculator/model/LiteNumberBuilder.java rename to calculatorpp-core/src/main/java/org/solovyev/android/calculator/LiteNumberBuilder.java index 606e742f..8d02d869 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/model/LiteNumberBuilder.java +++ b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/LiteNumberBuilder.java @@ -1,55 +1,55 @@ -/* - * 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.model; - -import jscl.MathEngine; -import jscl.NumeralBase; -import org.jetbrains.annotations.NotNull; -import org.solovyev.android.calculator.math.MathType; - -/** - * User: serso - * Date: 12/15/11 - * Time: 8:33 PM - */ - -public class LiteNumberBuilder extends AbstractNumberBuilder { - - public LiteNumberBuilder(@NotNull MathEngine engine) { - super(engine); - this.nb = engine.getNumeralBase(); - } - - public void process(@NotNull MathType.Result mathTypeResult) { - if (canContinue(mathTypeResult)) { - // let's continue building number - if (numberBuilder == null) { - // if new number => create new builder - numberBuilder = new StringBuilder(); - } - - if (mathTypeResult.getMathType() != MathType.numeral_base) { - // just add matching string - numberBuilder.append(mathTypeResult.getMatch()); - } else { - // set explicitly numeral base (do not include it into number) - nb = NumeralBase.getByPrefix(mathTypeResult.getMatch()); - } - - } else { - // process current number (and go to the next one) - if (numberBuilder != null) { - numberBuilder = null; - - // must set default numeral base (exit numeral base mode) - nb = engine.getNumeralBase(); - } - } - } - -} - +/* + * 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.MathEngine; +import jscl.NumeralBase; +import org.jetbrains.annotations.NotNull; +import org.solovyev.android.calculator.math.MathType; + +/** + * User: serso + * Date: 12/15/11 + * Time: 8:33 PM + */ + +public class LiteNumberBuilder extends AbstractNumberBuilder { + + public LiteNumberBuilder(@NotNull MathEngine engine) { + super(engine); + this.nb = engine.getNumeralBase(); + } + + public void process(@NotNull MathType.Result mathTypeResult) { + if (canContinue(mathTypeResult)) { + // let's continue building number + if (numberBuilder == null) { + // if new number => create new builder + numberBuilder = new StringBuilder(); + } + + if (mathTypeResult.getMathType() != MathType.numeral_base) { + // just add matching string + numberBuilder.append(mathTypeResult.getMatch()); + } else { + // set explicitly numeral base (do not include it into number) + nb = NumeralBase.getByPrefix(mathTypeResult.getMatch()); + } + + } else { + // process current number (and go to the next one) + if (numberBuilder != null) { + numberBuilder = null; + + // must set default numeral base (exit numeral base mode) + nb = engine.getNumeralBase(); + } + } + } + +} + diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/model/NumberBuilder.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/NumberBuilder.java similarity index 94% rename from calculatorpp/src/main/java/org/solovyev/android/calculator/model/NumberBuilder.java rename to calculatorpp-core/src/main/java/org/solovyev/android/calculator/NumberBuilder.java index 33dac4ee..24183e24 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/model/NumberBuilder.java +++ b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/NumberBuilder.java @@ -1,202 +1,203 @@ -/* - * 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.model; - -import jscl.MathContext; -import jscl.MathEngine; -import jscl.NumeralBase; -import jscl.math.numeric.Real; -import jscl.text.*; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.solovyev.android.calculator.math.MathType; -import org.solovyev.common.MutableObject; - -import java.util.ArrayList; -import java.util.List; - -/** - * User: serso - * Date: 10/23/11 - * Time: 2:57 PM - */ -public class NumberBuilder extends AbstractNumberBuilder { - - public NumberBuilder(@NotNull MathEngine engine) { - super(engine); - } - - /** - * Method replaces number in text according to some rules (e.g. formatting) - * - * @param text text where number can be replaced - * @param mathTypeResult math type result of current token - * @param offset offset between new number length and old number length (newNumberLength - oldNumberLength) - * - * - * @return new math type result (as one can be changed due to substituting of number with constant) - */ - @NotNull - public MathType.Result process(@NotNull StringBuilder text, @NotNull MathType.Result mathTypeResult, @Nullable MutableObject offset) { - final MathType.Result possibleResult; - if (canContinue(mathTypeResult)) { - // let's continue building number - if (numberBuilder == null) { - // if new number => create new builder - numberBuilder = new StringBuilder(); - } - - if (mathTypeResult.getMathType() != MathType.numeral_base) { - // just add matching string - numberBuilder.append(mathTypeResult.getMatch()); - } else { - // set explicitly numeral base (do not include it into number) - nb = NumeralBase.getByPrefix(mathTypeResult.getMatch()); - } - - possibleResult = null; - } else { - // process current number (and go to the next one) - possibleResult = processNumber(text, offset); - } - - return possibleResult == null ? mathTypeResult : possibleResult; - } - - /** - * Method replaces number in text according to some rules (e.g. formatting) - * - * @param text text where number can be replaced - * @param offset offset between new number length and old number length (newNumberLength - oldNumberLength) - * - * @return new math type result (as one can be changed due to substituting of number with constant) - */ - @Nullable - public MathType.Result processNumber(@NotNull StringBuilder text, @Nullable MutableObject offset) { - // total number of trimmed chars - int trimmedChars = 0; - - String number = null; - - // save numeral base (as later it might be replaced) - final NumeralBase localNb = getNumeralBase(); - - if (numberBuilder != null) { - try { - number = numberBuilder.toString(); - - // let's get rid of unnecessary characters (grouping separators, + after E) - final List tokens = new ArrayList(); - tokens.addAll(MathType.grouping_separator.getTokens()); - // + after E can be omitted: 10+E = 10E (NOTE: - cannot be omitted ) - tokens.add("+"); - for (String groupingSeparator : tokens) { - final String trimmedNumber = number.replace(groupingSeparator, ""); - trimmedChars += number.length() - trimmedNumber.length(); - number = trimmedNumber; - } - - // check if number still valid - toDouble(number, getNumeralBase(), engine); - - } catch (NumberFormatException e) { - // number is not valid => stop - number = null; - } - - numberBuilder = null; - - // must set default numeral base (exit numeral base mode) - nb = engine.getNumeralBase(); - } - - return replaceNumberInText(text, number, trimmedChars, offset, localNb, engine); - } - - @Nullable - private static MathType.Result replaceNumberInText(@NotNull StringBuilder text, - @Nullable String number, - int trimmedChars, - @Nullable MutableObject offset, - @NotNull NumeralBase nb, - @NotNull final MathEngine engine) { - MathType.Result result = null; - - if (number != null) { - // in any case remove old number from text - final int oldNumberLength = number.length() + trimmedChars; - text.delete(text.length() - oldNumberLength, text.length()); - - final String newNumber = formatNumber(number, nb, engine); - if (offset != null) { - // register offset between old number and new number - offset.setObject(newNumber.length() - oldNumberLength); - } - text.append(newNumber); - } - - return result; - } - - @NotNull - private static String formatNumber(@NotNull String number, @NotNull NumeralBase nb, @NotNull MathEngine engine) { - String result; - - int indexOfDot = number.indexOf('.'); - - if (indexOfDot < 0) { - int indexOfE; - if (nb == NumeralBase.hex) { - indexOfE = -1; - } else { - indexOfE = number.indexOf(MathType.POWER_10); - } - if (indexOfE < 0) { - result = engine.addGroupingSeparators(nb, number); - } else { - final String partBeforeE; - if (indexOfE != 0) { - partBeforeE = engine.addGroupingSeparators(nb, number.substring(0, indexOfE)); - } else { - partBeforeE = ""; - } - result = partBeforeE + number.substring(indexOfE); - } - } else { - final String integerPart; - if (indexOfDot != 0) { - integerPart = engine.addGroupingSeparators(nb, number.substring(0, indexOfDot)); - } else { - integerPart = ""; - } - result = integerPart + number.substring(indexOfDot); - } - - return result; - } - - @NotNull - private static Double toDouble(@NotNull String s, @NotNull NumeralBase nb, @NotNull final MathContext mc) throws NumberFormatException { - final NumeralBase defaultNb = mc.getNumeralBase(); - try { - mc.setNumeralBase(nb); - - try { - return JsclIntegerParser.parser.parse(Parser.Parameters.newInstance(s, new MutableInt(0), mc), null).content().doubleValue(); - } catch (ParseException e) { - try { - return ((Real) DoubleParser.parser.parse(Parser.Parameters.newInstance(s, new MutableInt(0), mc), null).content()).doubleValue(); - } catch (ParseException e1) { - throw new NumberFormatException(); - } - } - - } finally { - mc.setNumeralBase(defaultNb); - } - } -} +/* + * 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.MathContext; +import jscl.MathEngine; +import jscl.NumeralBase; +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; + +import java.util.ArrayList; +import java.util.List; + +/** + * User: serso + * Date: 10/23/11 + * Time: 2:57 PM + */ +public class NumberBuilder extends AbstractNumberBuilder { + + public NumberBuilder(@NotNull MathEngine engine) { + super(engine); + } + + /** + * Method replaces number in text according to some rules (e.g. formatting) + * + * @param text text where number can be replaced + * @param mathTypeResult math type result of current token + * @param offset offset between new number length and old number length (newNumberLength - oldNumberLength) + * + * + * @return new math type result (as one can be changed due to substituting of number with constant) + */ + @NotNull + public MathType.Result process(@NotNull StringBuilder text, @NotNull MathType.Result mathTypeResult, @Nullable MutableObject offset) { + final MathType.Result possibleResult; + if (canContinue(mathTypeResult)) { + // let's continue building number + if (numberBuilder == null) { + // if new number => create new builder + numberBuilder = new StringBuilder(); + } + + if (mathTypeResult.getMathType() != MathType.numeral_base) { + // just add matching string + numberBuilder.append(mathTypeResult.getMatch()); + } else { + // set explicitly numeral base (do not include it into number) + nb = NumeralBase.getByPrefix(mathTypeResult.getMatch()); + } + + possibleResult = null; + } else { + // process current number (and go to the next one) + possibleResult = processNumber(text, offset); + } + + return possibleResult == null ? mathTypeResult : possibleResult; + } + + /** + * Method replaces number in text according to some rules (e.g. formatting) + * + * @param text text where number can be replaced + * @param offset offset between new number length and old number length (newNumberLength - oldNumberLength) + * + * @return new math type result (as one can be changed due to substituting of number with constant) + */ + @Nullable + public MathType.Result processNumber(@NotNull StringBuilder text, @Nullable MutableObject offset) { + // total number of trimmed chars + int trimmedChars = 0; + + String number = null; + + // toXml numeral base (as later it might be replaced) + final NumeralBase localNb = getNumeralBase(); + + if (numberBuilder != null) { + try { + number = numberBuilder.toString(); + + // let's get rid of unnecessary characters (grouping separators, + after E) + final List tokens = new ArrayList(); + tokens.addAll(MathType.grouping_separator.getTokens()); + // + after E can be omitted: 10+E = 10E (NOTE: - cannot be omitted ) + tokens.add("+"); + for (String groupingSeparator : tokens) { + final String trimmedNumber = number.replace(groupingSeparator, ""); + trimmedChars += number.length() - trimmedNumber.length(); + number = trimmedNumber; + } + + // check if number still valid + toDouble(number, getNumeralBase(), engine); + + } catch (NumberFormatException e) { + // number is not valid => stop + number = null; + } + + numberBuilder = null; + + // must set default numeral base (exit numeral base mode) + nb = engine.getNumeralBase(); + } + + return replaceNumberInText(text, number, trimmedChars, offset, localNb, engine); + } + + @Nullable + private static MathType.Result replaceNumberInText(@NotNull StringBuilder text, + @Nullable String number, + int trimmedChars, + @Nullable MutableObject offset, + @NotNull NumeralBase nb, + @NotNull final MathEngine engine) { + MathType.Result result = null; + + if (number != null) { + // in any case remove old number from text + final int oldNumberLength = number.length() + trimmedChars; + text.delete(text.length() - oldNumberLength, text.length()); + + final String newNumber = formatNumber(number, nb, engine); + if (offset != null) { + // register offset between old number and new number + offset.setObject(newNumber.length() - oldNumberLength); + } + text.append(newNumber); + } + + return result; + } + + @NotNull + private static String formatNumber(@NotNull String number, @NotNull NumeralBase nb, @NotNull MathEngine engine) { + String result; + + int indexOfDot = number.indexOf('.'); + + if (indexOfDot < 0) { + int indexOfE; + if (nb == NumeralBase.hex) { + indexOfE = -1; + } else { + indexOfE = number.indexOf(MathType.POWER_10); + } + if (indexOfE < 0) { + result = engine.addGroupingSeparators(nb, number); + } else { + final String partBeforeE; + if (indexOfE != 0) { + partBeforeE = engine.addGroupingSeparators(nb, number.substring(0, indexOfE)); + } else { + partBeforeE = ""; + } + result = partBeforeE + number.substring(indexOfE); + } + } else { + final String integerPart; + if (indexOfDot != 0) { + integerPart = engine.addGroupingSeparators(nb, number.substring(0, indexOfDot)); + } else { + integerPart = ""; + } + result = integerPart + number.substring(indexOfDot); + } + + return result; + } + + @NotNull + private static Double toDouble(@NotNull String s, @NotNull NumeralBase nb, @NotNull final MathContext mc) throws NumberFormatException { + final NumeralBase defaultNb = mc.getNumeralBase(); + try { + mc.setNumeralBase(nb); + + try { + return JsclIntegerParser.parser.parse(Parser.Parameters.newInstance(s, new MutableInt(0), mc), null).content().doubleValue(); + } catch (ParseException e) { + try { + return ((Real) DoubleParser.parser.parse(Parser.Parameters.newInstance(s, new MutableInt(0), mc), null).content()).doubleValue(); + } catch (ParseException e1) { + throw new NumberFormatException(); + } + } + + } finally { + mc.setNumeralBase(defaultNb); + } + } +} diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/model/PreparedExpression.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/PreparedExpression.java similarity index 91% rename from calculatorpp/src/main/java/org/solovyev/android/calculator/model/PreparedExpression.java rename to calculatorpp-core/src/main/java/org/solovyev/android/calculator/PreparedExpression.java index 879b99f0..976de25d 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/model/PreparedExpression.java +++ b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/PreparedExpression.java @@ -1,65 +1,65 @@ -/* - * 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.model; - -import jscl.math.function.IConstant; -import org.jetbrains.annotations.NotNull; - -import java.util.List; - -/** - * User: serso - * Date: 10/18/11 - * Time: 10:07 PM - */ -public class PreparedExpression implements CharSequence{ - - @NotNull - private String expression; - - @NotNull - private List undefinedVars; - - public PreparedExpression(@NotNull String expression, @NotNull List undefinedVars) { - this.expression = expression; - this.undefinedVars = undefinedVars; - } - - @NotNull - public String getExpression() { - return expression; - } - - public boolean isExistsUndefinedVar() { - return !this.undefinedVars.isEmpty(); - } - - @NotNull - public List getUndefinedVars() { - return undefinedVars; - } - - @Override - public int length() { - return expression.length(); - } - - @Override - public char charAt(int i) { - return expression.charAt(i); - } - - @Override - public CharSequence subSequence(int i, int i1) { - return expression.subSequence(i, i1); - } - - @Override - public String toString() { - return this.expression; - } -} +/* + * 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.function.IConstant; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +/** + * User: serso + * Date: 10/18/11 + * Time: 10:07 PM + */ +public class PreparedExpression implements CharSequence{ + + @NotNull + private String expression; + + @NotNull + private List undefinedVars; + + public PreparedExpression(@NotNull String expression, @NotNull List undefinedVars) { + this.expression = expression; + this.undefinedVars = undefinedVars; + } + + @NotNull + public String getExpression() { + return expression; + } + + public boolean isExistsUndefinedVar() { + return !this.undefinedVars.isEmpty(); + } + + @NotNull + public List getUndefinedVars() { + return undefinedVars; + } + + @Override + public int length() { + return expression.length(); + } + + @Override + public char charAt(int i) { + return expression.charAt(i); + } + + @Override + public CharSequence subSequence(int i, int i1) { + return expression.subSequence(i, i1); + } + + @Override + public String toString() { + return this.expression; + } +} diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/model/ToJsclTextProcessor.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/ToJsclTextProcessor.java similarity index 95% rename from calculatorpp/src/main/java/org/solovyev/android/calculator/model/ToJsclTextProcessor.java rename to calculatorpp-core/src/main/java/org/solovyev/android/calculator/ToJsclTextProcessor.java index 630ad312..e83002f4 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/model/ToJsclTextProcessor.java +++ b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/ToJsclTextProcessor.java @@ -4,12 +4,13 @@ * 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; diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/history/CalculatorDisplayHistoryState.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/history/CalculatorDisplayHistoryState.java index b637e901..356f953a 100644 --- a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/history/CalculatorDisplayHistoryState.java +++ b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/history/CalculatorDisplayHistoryState.java @@ -11,7 +11,7 @@ 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.JCalculatorDisplay; import org.solovyev.android.calculator.jscl.JsclOperation; /** @@ -47,7 +47,7 @@ public class CalculatorDisplayHistoryState implements Cloneable { } @NotNull - public static CalculatorDisplayHistoryState newInstance(@NotNull ICalculatorDisplay display) { + public static CalculatorDisplayHistoryState newInstance(@NotNull JCalculatorDisplay display) { final CalculatorDisplayHistoryState result = new CalculatorDisplayHistoryState(); result.editorState = EditorHistoryState.newInstance(display); @@ -59,7 +59,7 @@ public class CalculatorDisplayHistoryState implements Cloneable { return result; } - public void setValuesFromHistory(@NotNull ICalculatorDisplay display) { + public void setValuesFromHistory(@NotNull JCalculatorDisplay display) { this.getEditorState().setValuesFromHistory(display); display.setValid(this.isValid()); display.setErrorMessage(this.getErrorMessage()); diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/history/CalculatorHistory.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/history/CalculatorHistory.java new file mode 100644 index 00000000..c7f8f828 --- /dev/null +++ b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/history/CalculatorHistory.java @@ -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 { + + void fromXml(@NotNull String xml); + + String toXml(); + + void clearSavedHistory(); + + void removeSavedHistory(@NotNull CalculatorHistoryState historyState); +} diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/history/CalculatorHistoryImpl.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/history/CalculatorHistoryImpl.java new file mode 100644 index 00000000..fc881c5c --- /dev/null +++ b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/history/CalculatorHistoryImpl.java @@ -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 history = new SimpleHistoryHelper(); + + @NotNull + private final List savedHistory = new ArrayList(); + + @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 getStates() { + return history.getStates(); + } + + @Override + public void clear() { + this.history.clear(); + } + + @NotNull + public List 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); + } +} diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/history/CalculatorHistoryState.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/history/CalculatorHistoryState.java index a90b457a..a7d37aaa 100644 --- a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/history/CalculatorHistoryState.java +++ b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/history/CalculatorHistoryState.java @@ -9,7 +9,7 @@ import org.jetbrains.annotations.NotNull; import org.simpleframework.xml.Element; import org.simpleframework.xml.Root; import org.solovyev.android.calculator.Editor; -import org.solovyev.android.calculator.ICalculatorDisplay; +import org.solovyev.android.calculator.JCalculatorDisplay; /** * User: serso @@ -38,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 JCalculatorDisplay display) { final EditorHistoryState editorHistoryState = EditorHistoryState.newInstance(editor); final CalculatorDisplayHistoryState displayHistoryState = CalculatorDisplayHistoryState.newInstance(display); return new CalculatorHistoryState(editorHistoryState, displayHistoryState); @@ -94,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 JCalculatorDisplay display) { this.getEditorState().setValuesFromHistory(editor); this.getDisplayState().setValuesFromHistory(display); } diff --git a/calculatorpp-core/src/main/java/org/solovyev/common/utils/ListListenersContainer.java b/calculatorpp-core/src/main/java/org/solovyev/common/utils/ListListenersContainer.java new file mode 100644 index 00000000..fa286f42 --- /dev/null +++ b/calculatorpp-core/src/main/java/org/solovyev/common/utils/ListListenersContainer.java @@ -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 { + + @NotNull + private final List> listeners = new ArrayList>(); + + public void addListener(@NotNull final T listener) { + synchronized (listeners) { + boolean contains = Iterables.any(listeners, new WeakReferencePredicate(listener)); + + if (!contains) { + listeners.add(new WeakReference(listener)); + } + } + } + + public void removeListener(@NotNull T listener) { + synchronized (listeners) { + Iterables.removeIf(listeners, new WeakReferencePredicate(listener)); + } + } + + @NotNull + public List getListeners() { + final List localListeners; + + synchronized (listeners) { + localListeners = new ArrayList(listeners.size()); + + // copy listeners and remove garbage collected references + for ( Iterator> it = listeners.iterator(); it.hasNext(); ) { + final WeakReference r = it.next(); + final T t = r.get(); + if ( t == null ) { + it.remove(); + } else { + localListeners.add(t); + } + } + } + + return localListeners; + } + + private static class WeakReferencePredicate implements Predicate> { + + @NotNull + private final T t; + + public WeakReferencePredicate(T t) { + this.t = t; + } + + @Override + public boolean apply(@Nullable WeakReference r) { + final T t = r != null ? r.get() : null; + return this.t.equals(t); + } + } +} diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/CalculatorActivity.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/CalculatorActivity.java index 608a3aa4..d7a3c0c3 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/CalculatorActivity.java +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/CalculatorActivity.java @@ -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(); diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/CalculatorDisplay.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/CalculatorDisplay.java index 54fc4e6f..c0e4e4ce 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/CalculatorDisplay.java +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/CalculatorDisplay.java @@ -19,7 +19,7 @@ import org.jetbrains.annotations.Nullable; 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.model.ToJsclTextProcessor; +import org.solovyev.android.calculator.ToJsclTextProcessor; import org.solovyev.android.calculator.view.NumeralBaseConverterDialog; import org.solovyev.android.calculator.view.TextHighlighter; import org.solovyev.android.calculator.view.UnitConverterViewBuilder; @@ -37,7 +37,7 @@ import java.util.Set; * Date: 9/17/11 * Time: 10:58 PM */ -public class CalculatorDisplay extends AutoResizeTextView implements ICalculatorDisplay{ +public class CalculatorDisplay extends AutoResizeTextView implements JCalculatorDisplay { private static enum ConversionMenuItem implements AMenuItem { convert_to_bin(NumeralBase.bin), diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/CalculatorModel.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/CalculatorModel.java index 6d544a8f..2329cc0a 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/CalculatorModel.java +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/CalculatorModel.java @@ -20,13 +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.history.HistoryControl; import org.solovyev.android.menu.AMenuBuilder; import org.solovyev.android.menu.MenuImpl; @@ -70,7 +69,7 @@ public enum CalculatorModel implements CursorControl, HistoryControl COMPARATOR = new Comparator() { - @Override - public int compare(CalculatorHistoryState state1, CalculatorHistoryState state2) { - if (state1.isSaved() == state2.isSaved()) { - long l = state2.getTime() - state1.getTime(); - return l > 0l ? 1 : (l < 0l ? -1 : 0); - } else if (state1.isSaved()) { - return -1; - } else if (state2.isSaved()) { - return 1; - } - return 0; - } - }; - - - @NotNull - private ArrayAdapter adapter; - - @Nullable - private AdView adView; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - setContentView(R.layout.history_activity); - - adView = AdsController.getInstance().inflateAd(this); - - adapter = new HistoryArrayAdapter(this, getLayoutId(), R.id.history_item, new ArrayList()); - setListAdapter(adapter); - - final ListView lv = getListView(); - lv.setTextFilterEnabled(true); - - lv.setOnItemClickListener(new AdapterView.OnItemClickListener() { - public void onItemClick(final AdapterView parent, - final View view, - final int position, - final long id) { - - useHistoryItem((CalculatorHistoryState) parent.getItemAtPosition(position), AbstractHistoryActivity.this); - } - }); - - lv.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { - @Override - public boolean onItemLongClick(AdapterView parent, View view, final int position, long id) { - final CalculatorHistoryState historyState = (CalculatorHistoryState) parent.getItemAtPosition(position); - - final Context context = AbstractHistoryActivity.this; - - final HistoryItemMenuData data = new HistoryItemMenuData(historyState, adapter); - - final List menuItems = CollectionsUtils.asList(HistoryItemMenuItem.values()); - - if (historyState.isSaved()) { - menuItems.remove(HistoryItemMenuItem.save); - } else { - if (isAlreadySaved(historyState)) { - menuItems.remove(HistoryItemMenuItem.save); - } - menuItems.remove(HistoryItemMenuItem.remove); - menuItems.remove(HistoryItemMenuItem.edit); - } - - if (historyState.getDisplayState().isValid() && StringUtils.isEmpty(historyState.getDisplayState().getEditorState().getText())) { - menuItems.remove(HistoryItemMenuItem.copy_result); - } - - final AMenuBuilder menuBuilder = AMenuBuilder.newInstance(context, MenuImpl.newInstance(menuItems)); - menuBuilder.create(data).show(); - - return true; - } - }); - } - - @Override - protected void onDestroy() { - if ( this.adView != null ) { - this.adView.destroy(); - } - super.onDestroy(); - } - - protected abstract int getLayoutId(); - - @Override - protected void onResume() { - super.onResume(); - - final List historyList = getHistoryList(); - try { - this.adapter.setNotifyOnChange(false); - this.adapter.clear(); - for (CalculatorHistoryState historyState : historyList) { - this.adapter.add(historyState); - } - } finally { - this.adapter.setNotifyOnChange(true); - } - - this.adapter.notifyDataSetChanged(); - } - - public static boolean isAlreadySaved(@NotNull CalculatorHistoryState historyState) { - assert !historyState.isSaved(); - - boolean result = false; - try { - historyState.setSaved(true); - if ( CollectionsUtils.contains(historyState, CalculatorHistory.instance.getSavedHistory(), new Equalizer() { - @Override - public boolean equals(@Nullable CalculatorHistoryState first, @Nullable CalculatorHistoryState second) { - return first != null && second != null && - first.getTime() == second.getTime() && - first.getDisplayState().equals(second.getDisplayState()) && - first.getEditorState().equals(second.getEditorState()); - } - }) ) { - result = true; - } - } finally { - historyState.setSaved(false); - } - return result; - } - - public static void useHistoryItem(@NotNull final CalculatorHistoryState historyState, @NotNull AbstractHistoryActivity activity) { - - // before evaluating history item - clear display (in order to get Error message in display if evaluation fail) - CalculatorModel.instance.getDisplay().setText(""); - CalculatorModel.instance.doTextOperation(new CalculatorModel.TextOperation() { - @Override - public void doOperation(@NotNull EditText editor) { - final EditorHistoryState editorState = historyState.getEditorState(); - editor.setText(editorState.getText()); - editor.setSelection(editorState.getCursorPosition()); - } - }, false, historyState.getDisplayState().getJsclOperation(), true); - - CalculatorModel.instance.setCursorOnEnd(); - - activity.finish(); - } - - @NotNull - private List getHistoryList() { - final List calculatorHistoryStates = getHistoryItems(); - - Collections.sort(calculatorHistoryStates, COMPARATOR); - - final FilterRulesChain filterRulesChain = new FilterRulesChain(); - filterRulesChain.addFilterRule(new FilterRule() { - @Override - public boolean isFiltered(CalculatorHistoryState object) { - return object == null || StringUtils.isEmpty(object.getEditorState().getText()); - } - }); - - new Filter(filterRulesChain).filter(calculatorHistoryStates.iterator()); - - return calculatorHistoryStates; - } - - @NotNull - protected abstract List getHistoryItems(); - - @NotNull - public static String getHistoryText(@NotNull CalculatorHistoryState state) { - final StringBuilder result = new StringBuilder(); - result.append(state.getEditorState().getText()); - result.append(getIdentitySign(state.getDisplayState().getJsclOperation())); - final String expressionResult = state.getDisplayState().getEditorState().getText(); - if (expressionResult != null) { - result.append(expressionResult); - } - return result.toString(); - } - - @NotNull - private static String getIdentitySign(@NotNull JsclOperation jsclOperation) { - return jsclOperation == JsclOperation.simplify ? "≡" : "="; - } - - @Override - public boolean onCreateOptionsMenu(android.view.Menu menu) { - final MenuInflater menuInflater = getMenuInflater(); - menuInflater.inflate(R.menu.history_menu, menu); - return true; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - boolean result; - - switch (item.getItemId()) { - case R.id.history_menu_clear_history: - clearHistory(); - result = true; - break; - default: - result = super.onOptionsItemSelected(item); - } - - return result; - } - - protected abstract void clearHistory(); - - @NotNull - protected ArrayAdapter getAdapter() { - return adapter; - } -} +/* + * 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.app.ListActivity; +import android.content.Context; +import android.os.Bundle; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.EditText; +import android.widget.ListView; +import com.google.ads.AdView; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.solovyev.android.ads.AdsController; +import org.solovyev.android.calculator.CalculatorModel; +import org.solovyev.android.calculator.R; +import org.solovyev.android.calculator.jscl.JsclOperation; +import org.solovyev.android.menu.AMenuBuilder; +import org.solovyev.android.menu.MenuImpl; +import org.solovyev.common.collections.CollectionsUtils; +import org.solovyev.common.equals.Equalizer; +import org.solovyev.common.filter.Filter; +import org.solovyev.common.filter.FilterRule; +import org.solovyev.common.filter.FilterRulesChain; +import org.solovyev.common.text.StringUtils; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +/** + * User: serso + * Date: 10/15/11 + * Time: 1:13 PM + */ +public abstract class AbstractHistoryActivity extends ListActivity { + + public static final Comparator COMPARATOR = new Comparator() { + @Override + public int compare(CalculatorHistoryState state1, CalculatorHistoryState state2) { + if (state1.isSaved() == state2.isSaved()) { + long l = state2.getTime() - state1.getTime(); + return l > 0l ? 1 : (l < 0l ? -1 : 0); + } else if (state1.isSaved()) { + return -1; + } else if (state2.isSaved()) { + return 1; + } + return 0; + } + }; + + + @NotNull + private ArrayAdapter adapter; + + @Nullable + private AdView adView; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setContentView(R.layout.history_activity); + + adView = AdsController.getInstance().inflateAd(this); + + adapter = new HistoryArrayAdapter(this, getLayoutId(), R.id.history_item, new ArrayList()); + setListAdapter(adapter); + + final ListView lv = getListView(); + lv.setTextFilterEnabled(true); + + lv.setOnItemClickListener(new AdapterView.OnItemClickListener() { + public void onItemClick(final AdapterView parent, + final View view, + final int position, + final long id) { + + useHistoryItem((CalculatorHistoryState) parent.getItemAtPosition(position), AbstractHistoryActivity.this); + } + }); + + lv.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { + @Override + public boolean onItemLongClick(AdapterView parent, View view, final int position, long id) { + final CalculatorHistoryState historyState = (CalculatorHistoryState) parent.getItemAtPosition(position); + + final Context context = AbstractHistoryActivity.this; + + final HistoryItemMenuData data = new HistoryItemMenuData(historyState, adapter); + + final List menuItems = CollectionsUtils.asList(HistoryItemMenuItem.values()); + + if (historyState.isSaved()) { + menuItems.remove(HistoryItemMenuItem.save); + } else { + if (isAlreadySaved(historyState)) { + menuItems.remove(HistoryItemMenuItem.save); + } + menuItems.remove(HistoryItemMenuItem.remove); + menuItems.remove(HistoryItemMenuItem.edit); + } + + if (historyState.getDisplayState().isValid() && StringUtils.isEmpty(historyState.getDisplayState().getEditorState().getText())) { + menuItems.remove(HistoryItemMenuItem.copy_result); + } + + final AMenuBuilder menuBuilder = AMenuBuilder.newInstance(context, MenuImpl.newInstance(menuItems)); + menuBuilder.create(data).show(); + + return true; + } + }); + } + + @Override + protected void onDestroy() { + if ( this.adView != null ) { + this.adView.destroy(); + } + super.onDestroy(); + } + + protected abstract int getLayoutId(); + + @Override + protected void onResume() { + super.onResume(); + + final List historyList = getHistoryList(); + try { + this.adapter.setNotifyOnChange(false); + this.adapter.clear(); + for (CalculatorHistoryState historyState : historyList) { + this.adapter.add(historyState); + } + } finally { + this.adapter.setNotifyOnChange(true); + } + + this.adapter.notifyDataSetChanged(); + } + + public static boolean isAlreadySaved(@NotNull CalculatorHistoryState historyState) { + assert !historyState.isSaved(); + + boolean result = false; + try { + historyState.setSaved(true); + if ( CollectionsUtils.contains(historyState, AndroidCalculatorHistoryImpl.instance.getSavedHistory(), new Equalizer() { + @Override + public boolean equals(@Nullable CalculatorHistoryState first, @Nullable CalculatorHistoryState second) { + return first != null && second != null && + first.getTime() == second.getTime() && + first.getDisplayState().equals(second.getDisplayState()) && + first.getEditorState().equals(second.getEditorState()); + } + }) ) { + result = true; + } + } finally { + historyState.setSaved(false); + } + return result; + } + + public static void useHistoryItem(@NotNull final CalculatorHistoryState historyState, @NotNull AbstractHistoryActivity activity) { + + // before evaluating history item - clear display (in order to get Error message in display if evaluation fail) + CalculatorModel.instance.getDisplay().setText(""); + CalculatorModel.instance.doTextOperation(new CalculatorModel.TextOperation() { + @Override + public void doOperation(@NotNull EditText editor) { + final EditorHistoryState editorState = historyState.getEditorState(); + editor.setText(editorState.getText()); + editor.setSelection(editorState.getCursorPosition()); + } + }, false, historyState.getDisplayState().getJsclOperation(), true); + + CalculatorModel.instance.setCursorOnEnd(); + + activity.finish(); + } + + @NotNull + private List getHistoryList() { + final List calculatorHistoryStates = getHistoryItems(); + + Collections.sort(calculatorHistoryStates, COMPARATOR); + + final FilterRulesChain filterRulesChain = new FilterRulesChain(); + filterRulesChain.addFilterRule(new FilterRule() { + @Override + public boolean isFiltered(CalculatorHistoryState object) { + return object == null || StringUtils.isEmpty(object.getEditorState().getText()); + } + }); + + new Filter(filterRulesChain).filter(calculatorHistoryStates.iterator()); + + return calculatorHistoryStates; + } + + @NotNull + protected abstract List getHistoryItems(); + + @NotNull + public static String getHistoryText(@NotNull CalculatorHistoryState state) { + final StringBuilder result = new StringBuilder(); + result.append(state.getEditorState().getText()); + result.append(getIdentitySign(state.getDisplayState().getJsclOperation())); + final String expressionResult = state.getDisplayState().getEditorState().getText(); + if (expressionResult != null) { + result.append(expressionResult); + } + return result.toString(); + } + + @NotNull + private static String getIdentitySign(@NotNull JsclOperation jsclOperation) { + return jsclOperation == JsclOperation.simplify ? "≡" : "="; + } + + @Override + public boolean onCreateOptionsMenu(android.view.Menu menu) { + final MenuInflater menuInflater = getMenuInflater(); + menuInflater.inflate(R.menu.history_menu, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + boolean result; + + switch (item.getItemId()) { + case R.id.history_menu_clear_history: + clearHistory(); + result = true; + break; + default: + result = super.onOptionsItemSelected(item); + } + + return result; + } + + protected abstract void clearHistory(); + + @NotNull + protected ArrayAdapter getAdapter() { + return adapter; + } +} diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/history/AndroidCalculatorHistory.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/history/AndroidCalculatorHistory.java new file mode 100644 index 00000000..2f4dc4b4 --- /dev/null +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/history/AndroidCalculatorHistory.java @@ -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); +} diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/history/AndroidCalculatorHistoryImpl.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/history/AndroidCalculatorHistoryImpl.java new file mode 100644 index 00000000..b5cba95f --- /dev/null +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/history/AndroidCalculatorHistoryImpl.java @@ -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 getStates() { + return calculatorHistory.getStates(); + } + + @Override + public void clear() { + calculatorHistory.clear(); + } + + @NotNull + public List 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); + } +} diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/history/CalculatorHistory.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/history/CalculatorHistory.java deleted file mode 100644 index c4967038..00000000 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/history/CalculatorHistory.java +++ /dev/null @@ -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 { - - instance; - - // todo serso: not synchronized - private int counter = 0; - - @NotNull - private final HistoryHelper history = new SimpleHistoryHelper(); - - @NotNull - private final List savedHistory = new ArrayList (); - - @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 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 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); - } -} diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/history/HistoryActivityTab.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/history/HistoryActivityTab.java index 56dacc14..73f67340 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/history/HistoryActivityTab.java +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/history/HistoryActivityTab.java @@ -1,37 +1,37 @@ -/* - * 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 org.jetbrains.annotations.NotNull; -import org.solovyev.android.calculator.R; - -import java.util.ArrayList; -import java.util.List; - -/** - * User: serso - * Date: 12/18/11 - * Time: 7:39 PM - */ -public class HistoryActivityTab extends AbstractHistoryActivity { - @Override - protected int getLayoutId() { - return R.layout.history; - } - - @NotNull - @Override - protected List getHistoryItems() { - return new ArrayList(CalculatorHistory.instance.getStates()); - } - - @Override - protected void clearHistory() { - CalculatorHistory.instance.clear(); - getAdapter().clear(); - } -} +/* + * 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 org.jetbrains.annotations.NotNull; +import org.solovyev.android.calculator.R; + +import java.util.ArrayList; +import java.util.List; + +/** + * User: serso + * Date: 12/18/11 + * Time: 7:39 PM + */ +public class HistoryActivityTab extends AbstractHistoryActivity { + @Override + protected int getLayoutId() { + return R.layout.history; + } + + @NotNull + @Override + protected List getHistoryItems() { + return new ArrayList(AndroidCalculatorHistoryImpl.instance.getStates()); + } + + @Override + protected void clearHistory() { + AndroidCalculatorHistoryImpl.instance.clear(); + getAdapter().clear(); + } +} diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/history/HistoryItemMenuItem.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/history/HistoryItemMenuItem.java index 3811c198..7cb1c859 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/history/HistoryItemMenuItem.java +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/history/HistoryItemMenuItem.java @@ -1,154 +1,154 @@ -/* - * 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.app.Activity; -import android.app.AlertDialog; -import android.content.Context; -import android.content.DialogInterface; -import android.text.ClipboardManager; -import android.util.Log; -import android.view.LayoutInflater; -import android.view.View; -import android.widget.EditText; -import android.widget.TextView; -import android.widget.Toast; -import org.jetbrains.annotations.NotNull; -import org.solovyev.android.calculator.R; -import org.solovyev.android.menu.LabeledMenuItem; -import org.solovyev.common.text.StringUtils; - -/** -* User: serso -* Date: 12/18/11 -* Time: 3:09 PM -*/ -public enum HistoryItemMenuItem implements LabeledMenuItem { - - use(R.string.c_use) { - @Override - public void onClick(@NotNull HistoryItemMenuData data, @NotNull Context context) { - if (context instanceof AbstractHistoryActivity) { - AbstractHistoryActivity.useHistoryItem(data.getHistoryState(), (AbstractHistoryActivity) context); - } else { - Log.e(HistoryItemMenuItem.class.getName(), AbstractHistoryActivity.class + " must be passed as context!"); - } - } - }, - - copy_expression(R.string.c_copy_expression) { - @Override - public void onClick(@NotNull HistoryItemMenuData data, @NotNull Context context) { - final CalculatorHistoryState calculatorHistoryState = data.getHistoryState(); - final String text = calculatorHistoryState.getEditorState().getText(); - if (!StringUtils.isEmpty(text)) { - final ClipboardManager clipboard = (ClipboardManager) context.getSystemService(Activity.CLIPBOARD_SERVICE); - clipboard.setText(text); - Toast.makeText(context, context.getText(R.string.c_expression_copied), Toast.LENGTH_SHORT).show(); - } - } - }, - - copy_result(R.string.c_copy_result) { - @Override - public void onClick(@NotNull HistoryItemMenuData data, @NotNull Context context) { - final CalculatorHistoryState calculatorHistoryState = data.getHistoryState(); - final String text = calculatorHistoryState.getDisplayState().getEditorState().getText(); - if (!StringUtils.isEmpty(text)) { - final ClipboardManager clipboard = (ClipboardManager) context.getSystemService(Activity.CLIPBOARD_SERVICE); - clipboard.setText(text); - Toast.makeText(context, context.getText(R.string.c_result_copied), Toast.LENGTH_SHORT).show(); - } - } - }, - - save(R.string.c_save) { - @Override - public void onClick(@NotNull final HistoryItemMenuData data, @NotNull final Context context) { - final CalculatorHistoryState historyState = data.getHistoryState(); - if (!historyState.isSaved()) { - createEditHistoryDialog(data, context, true); - } else { - Toast.makeText(context, context.getText(R.string.c_history_already_saved), Toast.LENGTH_LONG).show(); - } - } - }, - - edit(R.string.c_edit) { - @Override - public void onClick(@NotNull final HistoryItemMenuData data, @NotNull final Context context) { - final CalculatorHistoryState historyState = data.getHistoryState(); - if (historyState.isSaved()) { - createEditHistoryDialog(data, context, false); - } else { - Toast.makeText(context, context.getText(R.string.c_history_must_be_saved), Toast.LENGTH_LONG).show(); - } - } - }, - - remove(R.string.c_remove) { - @Override - public void onClick(@NotNull HistoryItemMenuData data, @NotNull Context context) { - final CalculatorHistoryState historyState = data.getHistoryState(); - if (historyState.isSaved()) { - data.getAdapter().remove(historyState); - CalculatorHistory.instance.removeSavedHistory(historyState, context); - Toast.makeText(context, context.getText(R.string.c_history_was_removed), Toast.LENGTH_LONG).show(); - data.getAdapter().notifyDataSetChanged(); - } - } - }; - - private static void createEditHistoryDialog(@NotNull final HistoryItemMenuData data, @NotNull final Context context, final boolean save) { - final CalculatorHistoryState historyState = data.getHistoryState(); - - final LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); - final View editView = layoutInflater.inflate(R.layout.history_edit, null); - final TextView historyExpression = (TextView)editView.findViewById(R.id.history_edit_expression); - historyExpression.setText(AbstractHistoryActivity.getHistoryText(historyState)); - - final EditText comment = (EditText)editView.findViewById(R.id.history_edit_comment); - comment.setText(historyState.getComment()); - - final AlertDialog.Builder builder = new AlertDialog.Builder(context) - .setTitle(save ? R.string.c_save_history : R.string.c_edit_history) - .setCancelable(true) - .setNegativeButton(R.string.c_cancel, null) - .setPositiveButton(R.string.c_save, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - if (save) { - final CalculatorHistoryState savedHistoryItem = CalculatorHistory.instance.addSavedState(historyState); - savedHistoryItem.setComment(comment.getText().toString()); - CalculatorHistory.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); - } - data.getAdapter().notifyDataSetChanged(); - Toast.makeText(context, context.getText(R.string.c_history_saved), Toast.LENGTH_LONG).show(); - } - }) - .setView(editView); - - builder.create().show(); - } - - private final int captionId; - - private HistoryItemMenuItem(int captionId) { - this.captionId = captionId; - } - - @NotNull - @Override - public String getCaption(@NotNull Context context) { - return context.getString(captionId); - } -} +/* + * 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.app.Activity; +import android.app.AlertDialog; +import android.content.Context; +import android.content.DialogInterface; +import android.text.ClipboardManager; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.EditText; +import android.widget.TextView; +import android.widget.Toast; +import org.jetbrains.annotations.NotNull; +import org.solovyev.android.calculator.R; +import org.solovyev.android.menu.LabeledMenuItem; +import org.solovyev.common.text.StringUtils; + +/** +* User: serso +* Date: 12/18/11 +* Time: 3:09 PM +*/ +public enum HistoryItemMenuItem implements LabeledMenuItem { + + use(R.string.c_use) { + @Override + public void onClick(@NotNull HistoryItemMenuData data, @NotNull Context context) { + if (context instanceof AbstractHistoryActivity) { + AbstractHistoryActivity.useHistoryItem(data.getHistoryState(), (AbstractHistoryActivity) context); + } else { + Log.e(HistoryItemMenuItem.class.getName(), AbstractHistoryActivity.class + " must be passed as context!"); + } + } + }, + + copy_expression(R.string.c_copy_expression) { + @Override + public void onClick(@NotNull HistoryItemMenuData data, @NotNull Context context) { + final CalculatorHistoryState calculatorHistoryState = data.getHistoryState(); + final String text = calculatorHistoryState.getEditorState().getText(); + if (!StringUtils.isEmpty(text)) { + final ClipboardManager clipboard = (ClipboardManager) context.getSystemService(Activity.CLIPBOARD_SERVICE); + clipboard.setText(text); + Toast.makeText(context, context.getText(R.string.c_expression_copied), Toast.LENGTH_SHORT).show(); + } + } + }, + + copy_result(R.string.c_copy_result) { + @Override + public void onClick(@NotNull HistoryItemMenuData data, @NotNull Context context) { + final CalculatorHistoryState calculatorHistoryState = data.getHistoryState(); + final String text = calculatorHistoryState.getDisplayState().getEditorState().getText(); + if (!StringUtils.isEmpty(text)) { + final ClipboardManager clipboard = (ClipboardManager) context.getSystemService(Activity.CLIPBOARD_SERVICE); + clipboard.setText(text); + Toast.makeText(context, context.getText(R.string.c_result_copied), Toast.LENGTH_SHORT).show(); + } + } + }, + + save(R.string.c_save) { + @Override + public void onClick(@NotNull final HistoryItemMenuData data, @NotNull final Context context) { + final CalculatorHistoryState historyState = data.getHistoryState(); + if (!historyState.isSaved()) { + createEditHistoryDialog(data, context, true); + } else { + Toast.makeText(context, context.getText(R.string.c_history_already_saved), Toast.LENGTH_LONG).show(); + } + } + }, + + edit(R.string.c_edit) { + @Override + public void onClick(@NotNull final HistoryItemMenuData data, @NotNull final Context context) { + final CalculatorHistoryState historyState = data.getHistoryState(); + if (historyState.isSaved()) { + createEditHistoryDialog(data, context, false); + } else { + Toast.makeText(context, context.getText(R.string.c_history_must_be_saved), Toast.LENGTH_LONG).show(); + } + } + }, + + remove(R.string.c_remove) { + @Override + public void onClick(@NotNull HistoryItemMenuData data, @NotNull Context context) { + final CalculatorHistoryState historyState = data.getHistoryState(); + if (historyState.isSaved()) { + data.getAdapter().remove(historyState); + AndroidCalculatorHistoryImpl.instance.removeSavedHistory(historyState, context); + Toast.makeText(context, context.getText(R.string.c_history_was_removed), Toast.LENGTH_LONG).show(); + data.getAdapter().notifyDataSetChanged(); + } + } + }; + + private static void createEditHistoryDialog(@NotNull final HistoryItemMenuData data, @NotNull final Context context, final boolean save) { + final CalculatorHistoryState historyState = data.getHistoryState(); + + final LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); + final View editView = layoutInflater.inflate(R.layout.history_edit, null); + final TextView historyExpression = (TextView)editView.findViewById(R.id.history_edit_expression); + historyExpression.setText(AbstractHistoryActivity.getHistoryText(historyState)); + + final EditText comment = (EditText)editView.findViewById(R.id.history_edit_comment); + comment.setText(historyState.getComment()); + + final AlertDialog.Builder builder = new AlertDialog.Builder(context) + .setTitle(save ? R.string.c_save_history : R.string.c_edit_history) + .setCancelable(true) + .setNegativeButton(R.string.c_cancel, null) + .setPositiveButton(R.string.c_save, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + if (save) { + final CalculatorHistoryState savedHistoryItem = AndroidCalculatorHistoryImpl.instance.addSavedState(historyState); + savedHistoryItem.setComment(comment.getText().toString()); + 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()); + AndroidCalculatorHistoryImpl.instance.save(context); + } + data.getAdapter().notifyDataSetChanged(); + Toast.makeText(context, context.getText(R.string.c_history_saved), Toast.LENGTH_LONG).show(); + } + }) + .setView(editView); + + builder.create().show(); + } + + private final int captionId; + + private HistoryItemMenuItem(int captionId) { + this.captionId = captionId; + } + + @NotNull + @Override + public String getCaption(@NotNull Context context) { + return context.getString(captionId); + } +} diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/history/SavedHistoryActivityTab.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/history/SavedHistoryActivityTab.java index 373f2af9..6113c89d 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/history/SavedHistoryActivityTab.java +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/history/SavedHistoryActivityTab.java @@ -1,37 +1,37 @@ -/* - * 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 org.jetbrains.annotations.NotNull; -import org.solovyev.android.calculator.R; - -import java.util.ArrayList; -import java.util.List; - -/** - * User: serso - * Date: 12/18/11 - * Time: 7:40 PM - */ -public class SavedHistoryActivityTab extends AbstractHistoryActivity { - @Override - protected int getLayoutId() { - return R.layout.saved_history; - } - - @NotNull - @Override - protected List getHistoryItems() { - return new ArrayList(CalculatorHistory.instance.getSavedHistory()); - } - - @Override - protected void clearHistory() { - CalculatorHistory.instance.clearSavedHistory(this); - getAdapter().clear(); - } -} +/* + * 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 org.jetbrains.annotations.NotNull; +import org.solovyev.android.calculator.R; + +import java.util.ArrayList; +import java.util.List; + +/** + * User: serso + * Date: 12/18/11 + * Time: 7:40 PM + */ +public class SavedHistoryActivityTab extends AbstractHistoryActivity { + @Override + protected int getLayoutId() { + return R.layout.saved_history; + } + + @NotNull + @Override + protected List getHistoryItems() { + return new ArrayList(AndroidCalculatorHistoryImpl.instance.getSavedHistory()); + } + + @Override + protected void clearHistory() { + AndroidCalculatorHistoryImpl.instance.clearSavedHistory(this); + getAdapter().clear(); + } +} diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/model/CalculatorEngine.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/model/CalculatorEngine.java index fb385c9a..00d4da93 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/model/CalculatorEngine.java +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/model/CalculatorEngine.java @@ -15,10 +15,7 @@ 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.CalculatorParseException; -import org.solovyev.android.calculator.JCalculatorEngine; -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; diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/plot/CalculatorPlotActivity.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/plot/CalculatorPlotActivity.java index 0e2040eb..c38714bc 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/plot/CalculatorPlotActivity.java +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/plot/CalculatorPlotActivity.java @@ -36,8 +36,8 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.solovyev.android.calculator.R; import org.solovyev.android.calculator.CalculatorParseException; -import org.solovyev.android.calculator.model.PreparedExpression; -import org.solovyev.android.calculator.model.ToJsclTextProcessor; +import org.solovyev.android.calculator.PreparedExpression; +import org.solovyev.android.calculator.ToJsclTextProcessor; import org.solovyev.common.MutableObject; import java.io.Serializable; diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/view/NumeralBaseConverterDialog.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/view/NumeralBaseConverterDialog.java index 4c94fe06..78f3a0bd 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/view/NumeralBaseConverterDialog.java +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/view/NumeralBaseConverterDialog.java @@ -13,7 +13,7 @@ import org.solovyev.android.calculator.CalculatorModel; import org.solovyev.android.calculator.R; import org.solovyev.android.calculator.model.CalculatorEngine; import org.solovyev.android.calculator.CalculatorParseException; -import org.solovyev.android.calculator.model.ToJsclTextProcessor; +import org.solovyev.android.calculator.ToJsclTextProcessor; import org.solovyev.common.MutableObject; import org.solovyev.common.text.StringUtils; diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/view/TextHighlighter.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/view/TextHighlighter.java index 2ebf22da..0d616fcc 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/view/TextHighlighter.java +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/view/TextHighlighter.java @@ -9,7 +9,10 @@ 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; diff --git a/calculatorpp/src/test/java/org/solovyev/android/calculator/history/HistoryUtilsTest.java b/calculatorpp/src/test/java/org/solovyev/android/calculator/history/HistoryUtilsTest.java index c05f2a32..7d427a1d 100644 --- a/calculatorpp/src/test/java/org/solovyev/android/calculator/history/HistoryUtilsTest.java +++ b/calculatorpp/src/test/java/org/solovyev/android/calculator/history/HistoryUtilsTest.java @@ -12,7 +12,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.junit.Test; import org.solovyev.android.calculator.Editor; -import org.solovyev.android.calculator.ICalculatorDisplay; +import org.solovyev.android.calculator.JCalculatorDisplay; import org.solovyev.android.calculator.jscl.JsclOperation; import org.solovyev.common.equals.CollectionEqualizer; import org.solovyev.common.equals.EqualsTool; @@ -125,7 +125,7 @@ public class HistoryUtilsTest { HistoryHelper history = new SimpleHistoryHelper(); - ICalculatorDisplay calculatorDisplay = new TestCalculatorDisplay(); + JCalculatorDisplay calculatorDisplay = new TestCalculatorDisplay(); calculatorDisplay.setErrorMessage("error_msg1"); calculatorDisplay.setText("Error"); calculatorDisplay.setSelection(1); @@ -215,7 +215,7 @@ public class HistoryUtilsTest { } - private static class TestCalculatorDisplay implements ICalculatorDisplay { + private static class TestCalculatorDisplay implements JCalculatorDisplay { @NotNull private final TestEditor testEditor = new TestEditor(); diff --git a/calculatorpp/src/test/java/org/solovyev/android/calculator/model/CalculatorEngineTest.java b/calculatorpp/src/test/java/org/solovyev/android/calculator/model/CalculatorEngineTest.java index 187c504d..8bd96dcd 100644 --- a/calculatorpp/src/test/java/org/solovyev/android/calculator/model/CalculatorEngineTest.java +++ b/calculatorpp/src/test/java/org/solovyev/android/calculator/model/CalculatorEngineTest.java @@ -15,6 +15,7 @@ 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; diff --git a/calculatorpp/src/test/java/org/solovyev/android/calculator/model/NumeralBaseTest.java b/calculatorpp/src/test/java/org/solovyev/android/calculator/model/NumeralBaseTest.java index b7046569..bd658b31 100644 --- a/calculatorpp/src/test/java/org/solovyev/android/calculator/model/NumeralBaseTest.java +++ b/calculatorpp/src/test/java/org/solovyev/android/calculator/model/NumeralBaseTest.java @@ -10,6 +10,7 @@ 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; diff --git a/calculatorpp/src/test/java/org/solovyev/android/calculator/model/ToJsclTextProcessorTest.java b/calculatorpp/src/test/java/org/solovyev/android/calculator/model/ToJsclTextProcessorTest.java index 57f2bb1d..05c4e995 100644 --- a/calculatorpp/src/test/java/org/solovyev/android/calculator/model/ToJsclTextProcessorTest.java +++ b/calculatorpp/src/test/java/org/solovyev/android/calculator/model/ToJsclTextProcessorTest.java @@ -12,6 +12,8 @@ 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; /**