From 233c685a49b87798edcf415b3a82450fc5efd3ac Mon Sep 17 00:00:00 2001 From: Sergey Solovyev Date: Sat, 22 Sep 2012 19:24:27 +0400 Subject: [PATCH] New architecture --- .../android/calculator/Calculator.java | 10 +- .../calculator/CalculatorDisplayImpl.java | 6 +- .../android/calculator/CalculatorEditor.java | 6 +- .../calculator/CalculatorEditorImpl.java | 69 +- ...latorEngine.java => CalculatorEngine.java} | 73 +- .../CalculatorEvaluationEventDataImpl.java | 6 +- .../calculator/CalculatorEventDataId.java | 2 + .../calculator/CalculatorEventDataIdImpl.java | 5 + .../calculator/CalculatorEventDataImpl.java | 6 +- .../android/calculator/CalculatorImpl.java | 61 +- .../calculator/CalculatorKeyboard.java | 4 + .../calculator/CalculatorKeyboardImpl.java | 26 +- .../android/calculator/CalculatorLocator.java | 28 +- .../calculator/CalculatorLocatorImpl.java | 59 +- .../calculator/CalculatorMathRegistry.java | 12 +- .../android/calculator/CalculatorUtils.java | 22 + .../calculator/ToJsclTextProcessor.java | 294 +++--- .../calculator/history/CalculatorHistory.java | 54 +- .../history/CalculatorHistoryImpl.java | 91 +- .../calculator/jscl/JsclOperation.java | 140 +-- .../android/calculator/math/MathType.java | 890 +++++++++--------- .../text/FromJsclSimplifyTextProcessor.java | 188 ++-- .../android/calculator/AndroidCalculator.java | 126 +++ .../AndroidCalculatorDisplayView.java | 3 +- .../AndroidCalculatorEditorView.java | 5 +- .../calculator/CalculatorActivity.java | 83 +- .../CalculatorActivityLauncher.java | 4 +- .../calculator/CalculatorApplication.java | 115 +-- .../calculator/CalculatorDisplayMenuItem.java | 281 +++--- .../CalculatorDisplayOnClickListener.java | 106 +-- .../android/calculator/CalculatorModel.java | 59 +- .../calculator/CalculatorPreferences.java | 18 +- .../CalculatorPreferencesActivity.java | 8 +- .../calculator/ConversionMenuItem.java | 3 +- .../calculator/CursorDragProcessor.java | 15 +- .../android/calculator/EvalDragProcessor.java | 7 +- .../calculator/NumeralBaseButtons.java | 4 +- .../history/AbstractHistoryActivity.java | 4 +- .../history/AndroidCalculatorHistory.java | 167 +++- .../history/AndroidCalculatorHistoryImpl.java | 154 --- .../history/HistoryActivityTab.java | 75 +- .../history/HistoryItemMenuItem.java | 309 +++--- .../history/SavedHistoryActivityTab.java | 75 +- .../edit/AbstractMathEntityListActivity.java | 10 +- .../edit/CalculatorFunctionsActivity.java | 13 +- .../edit/CalculatorOperatorsActivity.java | 15 +- .../math/edit/CalculatorVarsActivity.java | 19 +- .../math/edit/FunctionEditorSaver.java | 12 +- .../math/edit/MathEntityRemover.java | 10 +- .../calculator/math/edit/VarEditorSaver.java | 12 +- .../model/AbstractAndroidMathRegistry.java | 25 +- ...gine.java => AndroidCalculatorEngine.java} | 97 +- .../model/AndroidFunctionsMathRegistry.java | 13 +- .../model/AndroidOperatorsMathRegistry.java | 13 +- .../AndroidPostfixFunctionsRegistry.java | 13 +- .../model/AndroidVarsRegistryImpl.java | 17 +- .../calculator/view/AngleUnitsButton.java | 4 +- .../view/CalculatorAdditionalTitle.java | 7 +- .../view/NumeralBaseConverterDialog.java | 11 +- .../calculator/view/NumeralBasesButton.java | 4 +- .../calculator/view/TextHighlighter.java | 482 +++++----- .../calculator/TextHighlighterTest.java | 273 +++--- .../FromJsclNumericTextProcessorTest.java | 4 +- .../android/calculator/math/MathTypeTest.java | 4 +- ....java => AndroidCalculatorEngineTest.java} | 45 +- .../FromJsclSimplifyTextProcessorTest.java | 141 +-- .../calculator/model/NumeralBaseTest.java | 14 +- .../model/ToJsclTextProcessorTest.java | 331 +++---- 68 files changed, 2787 insertions(+), 2475 deletions(-) rename calculatorpp-core/src/main/java/org/solovyev/android/calculator/{JCalculatorEngine.java => CalculatorEngine.java} (55%) rename calculatorpp/src/main/java/org/solovyev/android/calculator/model/AndroidMathRegistry.java => calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorMathRegistry.java (54%) create mode 100644 calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorUtils.java create mode 100644 calculatorpp/src/main/java/org/solovyev/android/calculator/AndroidCalculator.java delete mode 100644 calculatorpp/src/main/java/org/solovyev/android/calculator/history/AndroidCalculatorHistoryImpl.java rename calculatorpp/src/main/java/org/solovyev/android/calculator/model/{CalculatorEngine.java => AndroidCalculatorEngine.java} (83%) rename calculatorpp/src/test/java/org/solovyev/android/calculator/model/{CalculatorEngineTest.java => AndroidCalculatorEngineTest.java} (89%) 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 index 35817390..b14cf944 100644 --- a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/Calculator.java +++ b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/Calculator.java @@ -4,17 +4,20 @@ import jscl.NumeralBase; import jscl.math.Generic; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.solovyev.android.calculator.history.CalculatorHistoryState; import org.solovyev.android.calculator.jscl.JsclOperation; +import org.solovyev.common.history.HistoryControl; /** * User: Solovyev_S * Date: 20.09.12 * Time: 16:38 */ -public interface Calculator extends CalculatorEventContainer { +public interface Calculator extends CalculatorEventContainer, HistoryControl { - @NotNull - CalculatorEventDataId createFirstEventDataId(); + void evaluate(); + + void simplify(); @NotNull CalculatorEventDataId evaluate(@NotNull JsclOperation operation, @@ -34,4 +37,5 @@ public interface Calculator extends CalculatorEventContainer { @NotNull CalculatorEventDataId fireCalculatorEvent(@NotNull CalculatorEventType calculatorEventType, @Nullable Object data, @NotNull Long sequenceId); + void init(); } diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorDisplayImpl.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorDisplayImpl.java index 7294776b..fe524be4 100644 --- a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorDisplayImpl.java +++ b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorDisplayImpl.java @@ -29,7 +29,7 @@ public class CalculatorDisplayImpl implements CalculatorDisplay { public CalculatorDisplayImpl(@NotNull Calculator calculator) { this.calculator = calculator; - this.lastCalculatorEventData = CalculatorEventDataImpl.newInstance(calculator.createFirstEventDataId()); + this.lastCalculatorEventData = CalculatorEventDataImpl.newInstance(CalculatorUtils.createFirstEventDataId()); this.calculator.addCalculatorEventListener(this); } @@ -138,11 +138,11 @@ public class CalculatorDisplayImpl implements CalculatorDisplay { private void processCalculationCancelled(@NotNull CalculatorEvaluationEventData calculatorEventData) { final String errorMessage = CalculatorMessages.getBundle().getString(CalculatorMessages.syntax_error); - this.setViewState(CalculatorDisplayViewStateImpl.newErrorState(calculatorEventData.getOperation(), errorMessage)); + this.setViewStateForSequence(CalculatorDisplayViewStateImpl.newErrorState(calculatorEventData.getOperation(), errorMessage), calculatorEventData.getSequenceId()); } private void processCalculationResult(@NotNull CalculatorEvaluationEventData calculatorEventData, @NotNull CalculatorOutput data) { final String stringResult = data.getStringResult(); - this.setViewState(CalculatorDisplayViewStateImpl.newValidState(calculatorEventData.getOperation(), data.getResult(), stringResult, 0)); + this.setViewStateForSequence(CalculatorDisplayViewStateImpl.newValidState(calculatorEventData.getOperation(), data.getResult(), stringResult, 0), calculatorEventData.getSequenceId()); } } diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEditor.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEditor.java index 637c0703..9a40aa9d 100644 --- a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEditor.java +++ b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEditor.java @@ -2,13 +2,14 @@ package org.solovyev.android.calculator; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.solovyev.common.gui.CursorControl; /** * User: Solovyev_S * Date: 21.09.12 * Time: 11:47 */ -public interface CalculatorEditor extends CalculatorEventListener/*, CursorControl*/ { +public interface CalculatorEditor extends CalculatorEventListener { void setView(@Nullable CalculatorEditorView view); @@ -48,6 +49,9 @@ public interface CalculatorEditor extends CalculatorEventListener/*, CursorContr @NotNull public CalculatorEditorViewState moveCursorRight(); + @NotNull + CursorControl asCursorControl(); + /* ********************************************************************** diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEditorImpl.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEditorImpl.java index 3b783381..c918c0a7 100644 --- a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEditorImpl.java +++ b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEditorImpl.java @@ -2,6 +2,7 @@ package org.solovyev.android.calculator; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.solovyev.common.gui.CursorControl; /** * User: Solovyev_S @@ -22,6 +23,9 @@ public class CalculatorEditorImpl implements CalculatorEditor { @NotNull private final Calculator calculator; + @NotNull + private final CursorControlAdapter cursorControlAdapter = new CursorControlAdapter(this); + public CalculatorEditorImpl(@NotNull Calculator calculator) { this.calculator = calculator; this.calculator.addCalculatorEventListener(this); @@ -65,12 +69,13 @@ public class CalculatorEditorImpl implements CalculatorEditor { //To change body of implemented methods use File | Settings | File Templates. } - @NotNull - public CalculatorEditorViewState setCursorOnStart() { - synchronized (viewLock) { - return newSelectionViewState(0); - } - } + /* + ********************************************************************** + * + * SELECTION + * + ********************************************************************** + */ @NotNull private CalculatorEditorViewState newSelectionViewState(int newSelection) { @@ -83,6 +88,14 @@ public class CalculatorEditorImpl implements CalculatorEditor { } } + @NotNull + public CalculatorEditorViewState setCursorOnStart() { + synchronized (viewLock) { + return newSelectionViewState(0); + } + } + + @NotNull public CalculatorEditorViewState setCursorOnEnd() { synchronized (viewLock) { @@ -112,6 +125,20 @@ public class CalculatorEditorImpl implements CalculatorEditor { } } + @NotNull + @Override + public CursorControl asCursorControl() { + return cursorControlAdapter; + } + + /* + ********************************************************************** + * + * EDITOR ACTIONS + * + ********************************************************************** + */ + @NotNull @Override public CalculatorEditorViewState erase() { @@ -221,4 +248,34 @@ public class CalculatorEditorImpl implements CalculatorEditor { result = Math.min(result, textLength); return result; } + + private static final class CursorControlAdapter implements CursorControl { + + @NotNull + private final CalculatorEditor calculatorEditor; + + private CursorControlAdapter(@NotNull CalculatorEditor calculatorEditor) { + this.calculatorEditor = calculatorEditor; + } + + @Override + public void setCursorOnStart() { + this.calculatorEditor.setCursorOnStart(); + } + + @Override + public void setCursorOnEnd() { + this.calculatorEditor.setCursorOnEnd(); + } + + @Override + public void moveCursorLeft() { + this.calculatorEditor.moveCursorLeft(); + } + + @Override + public void moveCursorRight() { + this.calculatorEditor.moveCursorRight(); + } + } } diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/JCalculatorEngine.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEngine.java similarity index 55% rename from calculatorpp-core/src/main/java/org/solovyev/android/calculator/JCalculatorEngine.java rename to calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEngine.java index c069e378..9841c250 100644 --- a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/JCalculatorEngine.java +++ b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEngine.java @@ -1,34 +1,39 @@ -package org.solovyev.android.calculator; - -import jscl.MathEngine; -import jscl.math.function.Function; -import jscl.math.function.IConstant; -import jscl.math.operator.Operator; -import org.jetbrains.annotations.NotNull; -import org.solovyev.common.math.MathRegistry; - -/** - * User: Solovyev_S - * Date: 20.09.12 - * Time: 12:43 - */ -public interface JCalculatorEngine { - - @NotNull - String getMultiplicationSign(); - - @NotNull - MathRegistry getVarsRegistry(); - - @NotNull - MathRegistry getFunctionsRegistry(); - - @NotNull - MathRegistry getOperatorsRegistry(); - - @NotNull - MathRegistry getPostfixFunctionsRegistry(); - - @NotNull - MathEngine getEngine(); -} +package org.solovyev.android.calculator; + +import jscl.MathEngine; +import jscl.math.function.Function; +import jscl.math.function.IConstant; +import jscl.math.operator.Operator; +import org.jetbrains.annotations.NotNull; + +/** + * User: Solovyev_S + * Date: 20.09.12 + * Time: 12:43 + */ +public interface CalculatorEngine { + + @NotNull + String getMultiplicationSign(); + + @NotNull + CalculatorMathRegistry getVarsRegistry(); + + @NotNull + CalculatorMathRegistry getFunctionsRegistry(); + + @NotNull + CalculatorMathRegistry getOperatorsRegistry(); + + @NotNull + CalculatorMathRegistry getPostfixFunctionsRegistry(); + + @NotNull + MathEngine getEngine(); + + void init(); + + void reset(); + + void softReset(); +} diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEvaluationEventDataImpl.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEvaluationEventDataImpl.java index 7d551454..3609dd34 100644 --- a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEvaluationEventDataImpl.java +++ b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEvaluationEventDataImpl.java @@ -1,7 +1,6 @@ package org.solovyev.android.calculator; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import org.solovyev.android.calculator.jscl.JsclOperation; /** @@ -60,4 +59,9 @@ public class CalculatorEvaluationEventDataImpl implements CalculatorEvaluationEv public boolean isSameSequence(@NotNull CalculatorEventDataId that) { return this.calculatorEventData.isSameSequence(that); } + + @Override + public boolean isAfterSequence(@NotNull CalculatorEventDataId that) { + return this.calculatorEventData.isAfterSequence(that); + } } 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 index 2b72950b..c6f1db63 100644 --- a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEventDataId.java +++ b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEventDataId.java @@ -19,4 +19,6 @@ public interface CalculatorEventDataId { boolean isAfter(@NotNull CalculatorEventDataId that); boolean isSameSequence(@NotNull CalculatorEventDataId that); + + boolean isAfterSequence(@NotNull CalculatorEventDataId that); } 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 index 149f2f93..7d207bdf 100644 --- a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEventDataIdImpl.java +++ b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEventDataIdImpl.java @@ -47,6 +47,11 @@ class CalculatorEventDataIdImpl implements CalculatorEventDataId { return !this.sequenceId.equals(NO_SEQUENCE) && this.sequenceId.equals(that.getSequenceId()); } + @Override + public boolean isAfterSequence(@NotNull CalculatorEventDataId that) { + return !this.sequenceId.equals(NO_SEQUENCE) && this.sequenceId > that.getSequenceId(); + } + @Override public boolean equals(Object o) { if (this == o) return true; 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 index 81010f2c..2d76a296 100644 --- a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEventDataImpl.java +++ b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEventDataImpl.java @@ -1,7 +1,6 @@ package org.solovyev.android.calculator; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; /** * User: Solovyev_S @@ -43,6 +42,11 @@ class CalculatorEventDataImpl implements CalculatorEventData { return this.calculatorEventDataId.isSameSequence(that); } + @Override + public boolean isAfterSequence(@NotNull CalculatorEventDataId that) { + return this.calculatorEventDataId.isAfterSequence(that); + } + @Override public boolean equals(Object o) { if (this == o) return true; 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 index 2bdc88eb..80c2229a 100644 --- a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorImpl.java +++ b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorImpl.java @@ -8,8 +8,11 @@ import jscl.math.Generic; import jscl.text.ParseInterruptedException; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.solovyev.android.calculator.history.CalculatorHistory; +import org.solovyev.android.calculator.history.CalculatorHistoryState; import org.solovyev.android.calculator.jscl.JsclOperation; import org.solovyev.android.calculator.text.TextProcessor; +import org.solovyev.common.history.HistoryAction; import org.solovyev.common.msg.MessageRegistry; import org.solovyev.common.msg.MessageType; import org.solovyev.common.text.StringUtils; @@ -29,13 +32,11 @@ import java.util.concurrent.atomic.AtomicLong; */ public class CalculatorImpl implements Calculator, CalculatorEventListener { - private static final long FIRST_ID = 0; - @NotNull private final CalculatorEventContainer calculatorEventContainer = new ListCalculatorEventContainer(); @NotNull - private final AtomicLong counter = new AtomicLong(FIRST_ID); + private final AtomicLong counter = new AtomicLong(CalculatorUtils.FIRST_ID); @NotNull private final TextProcessor preprocessor = ToJsclTextProcessor.getInstance(); @@ -93,10 +94,14 @@ public class CalculatorImpl implements Calculator, CalculatorEventListener { ********************************************************************** */ - @NotNull @Override - public CalculatorEventDataId createFirstEventDataId() { - return CalculatorEventDataIdImpl.newInstance(FIRST_ID, FIRST_ID); + public void evaluate() { + this.evaluate(JsclOperation.numeric, getEditor().getViewState().getText()); + } + + @Override + public void simplify() { + this.evaluate(JsclOperation.simplify, getEditor().getViewState().getText()); } @NotNull @@ -144,7 +149,7 @@ public class CalculatorImpl implements Calculator, CalculatorEventListener { fireCalculatorEvent(newConversionEventData(sequenceId), CalculatorEventType.conversion_started, null); - final NumeralBase from = CalculatorLocatorImpl.getInstance().getCalculatorEngine().getEngine().getNumeralBase(); + final NumeralBase from = CalculatorLocatorImpl.getInstance().getEngine().getEngine().getNumeralBase(); if (from != to) { String fromString = generic.toString(); @@ -197,6 +202,12 @@ public class CalculatorImpl implements Calculator, CalculatorEventListener { return eventDataId; } + @Override + public void init() { + CalculatorLocatorImpl.getInstance().getEngine().init(); + CalculatorLocatorImpl.getInstance().getHistory().load(); + } + @NotNull private CalculatorEventData newConversionEventData(@NotNull Long sequenceId) { return CalculatorEventDataImpl.newInstance(nextEventDataId(sequenceId)); @@ -215,7 +226,7 @@ public class CalculatorImpl implements Calculator, CalculatorEventListener { expression = expression.trim(); - if ( StringUtils.isEmpty(expression) ) { + if (StringUtils.isEmpty(expression)) { final CalculatorOutputImpl data = new CalculatorOutputImpl("", operation, Expression.valueOf("")); fireCalculatorEvent(newCalculationEventData(operation, expression, sequenceId), CalculatorEventType.calculation_result, data); } else { @@ -330,12 +341,44 @@ public class CalculatorImpl implements Calculator, CalculatorEventListener { final String newText = changeEventData.getNewState().getText(); final String oldText = changeEventData.getOldState().getText(); - if ( !newText.equals(oldText) ) { + if (!newText.equals(oldText)) { evaluate(JsclOperation.numeric, changeEventData.getNewState().getText(), calculatorEventData.getSequenceId()); } } } + @Override + public void doHistoryAction(@NotNull HistoryAction historyAction) { + final CalculatorHistory history = CalculatorLocatorImpl.getInstance().getHistory(); + if (history.isActionAvailable(historyAction)) { + final CalculatorHistoryState newState = history.doAction(historyAction, getCurrentHistoryState()); + if (newState != null) { + setCurrentHistoryState(newState); + } + } + } + + @Override + public void setCurrentHistoryState(@NotNull CalculatorHistoryState editorHistoryState) { + editorHistoryState.setValuesFromHistory(getEditor(), getDisplay()); + } + + @NotNull + private CalculatorEditor getEditor() { + return CalculatorLocatorImpl.getInstance().getEditor(); + } + + @NotNull + @Override + public CalculatorHistoryState getCurrentHistoryState() { + return CalculatorHistoryState.newInstance(getEditor(), getDisplay()); + } + + @NotNull + private CalculatorDisplay getDisplay() { + return CalculatorLocatorImpl.getInstance().getDisplay(); + } + public static final class ConversionException extends Exception { private ConversionException() { } diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorKeyboard.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorKeyboard.java index dd6af9d0..9219ae1f 100644 --- a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorKeyboard.java +++ b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorKeyboard.java @@ -18,4 +18,8 @@ public interface CalculatorKeyboard { void clearButtonPressed(); void copyButtonPressed(); + + void moveCursorLeft(); + + void moveCursorRight(); } diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorKeyboardImpl.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorKeyboardImpl.java index 8f25e272..4a90ad1d 100644 --- a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorKeyboardImpl.java +++ b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorKeyboardImpl.java @@ -49,14 +49,14 @@ public class CalculatorKeyboardImpl implements CalculatorKeyboard { } } - final CalculatorEditor editor = CalculatorLocatorImpl.getInstance().getCalculatorEditor(); + final CalculatorEditor editor = CalculatorLocatorImpl.getInstance().getEditor(); editor.insert(textToBeInserted.toString(), cursorPositionOffset); } } @Override public void roundBracketsButtonPressed() { - final CalculatorEditor editor = CalculatorLocatorImpl.getInstance().getCalculatorEditor(); + final CalculatorEditor editor = CalculatorLocatorImpl.getInstance().getEditor(); CalculatorEditorViewState viewState = editor.getViewState(); final int cursorPosition = viewState.getSelection(); @@ -72,26 +72,36 @@ public class CalculatorKeyboardImpl implements CalculatorKeyboard { @Override public void pasteButtonPressed() { - final String text = CalculatorLocatorImpl.getInstance().getCalculatorClipboard().getText(); + final String text = CalculatorLocatorImpl.getInstance().getClipboard().getText(); if (text != null) { - CalculatorLocatorImpl.getInstance().getCalculatorEditor().insert(text); + CalculatorLocatorImpl.getInstance().getEditor().insert(text); } } @Override public void clearButtonPressed() { - CalculatorLocatorImpl.getInstance().getCalculatorEditor().clear(); + CalculatorLocatorImpl.getInstance().getEditor().clear(); } @Override public void copyButtonPressed() { - final CalculatorDisplayViewState displayViewState = CalculatorLocatorImpl.getInstance().getCalculatorDisplay().getViewState(); + final CalculatorDisplayViewState displayViewState = CalculatorLocatorImpl.getInstance().getDisplay().getViewState(); if (displayViewState.isValid()) { final CharSequence text = displayViewState.getText(); if (!StringUtils.isEmpty(text)) { - CalculatorLocatorImpl.getInstance().getCalculatorClipboard().setText(text); - CalculatorLocatorImpl.getInstance().getCalculatorNotifier().showMessage(CalculatorMessage.newInfoMessage(CalculatorMessages.result_copied)); + CalculatorLocatorImpl.getInstance().getClipboard().setText(text); + CalculatorLocatorImpl.getInstance().getNotifier().showMessage(CalculatorMessage.newInfoMessage(CalculatorMessages.result_copied)); } } } + + @Override + public void moveCursorLeft() { + CalculatorLocatorImpl.getInstance().getEditor().moveCursorLeft(); + } + + @Override + public void moveCursorRight() { + CalculatorLocatorImpl.getInstance().getEditor().moveCursorRight(); + } } diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorLocator.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorLocator.java index 9a631c3d..8fcb7732 100644 --- a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorLocator.java +++ b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorLocator.java @@ -1,6 +1,7 @@ package org.solovyev.android.calculator; import org.jetbrains.annotations.NotNull; +import org.solovyev.android.calculator.history.CalculatorHistory; /** * User: Solovyev_S @@ -9,30 +10,33 @@ import org.jetbrains.annotations.NotNull; */ public interface CalculatorLocator { - @NotNull - JCalculatorEngine getCalculatorEngine(); + void init(@NotNull Calculator calculator, + @NotNull CalculatorEngine engine, + @NotNull CalculatorClipboard clipboard, + @NotNull CalculatorNotifier notifier, + @NotNull CalculatorHistory history); @NotNull Calculator getCalculator(); @NotNull - CalculatorDisplay getCalculatorDisplay(); + CalculatorEngine getEngine(); @NotNull - CalculatorEditor getCalculatorEditor(); - - void setCalculatorEngine(@NotNull JCalculatorEngine calculatorEngine); + CalculatorDisplay getDisplay(); @NotNull - CalculatorKeyboard getCalculatorKeyboard(); + CalculatorEditor getEditor(); @NotNull - CalculatorClipboard getCalculatorClipboard(); - - void setCalculatorClipboard(@NotNull CalculatorClipboard calculatorClipboard); + CalculatorKeyboard getKeyboard(); @NotNull - CalculatorNotifier getCalculatorNotifier(); + CalculatorClipboard getClipboard(); - void setCalculatorNotifier(@NotNull CalculatorNotifier calculatorNotifier); + @NotNull + CalculatorNotifier getNotifier(); + + @NotNull + CalculatorHistory getHistory(); } diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorLocatorImpl.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorLocatorImpl.java index 3c8ad55f..0431dfb5 100644 --- a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorLocatorImpl.java +++ b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorLocatorImpl.java @@ -1,6 +1,7 @@ package org.solovyev.android.calculator; import org.jetbrains.annotations.NotNull; +import org.solovyev.android.calculator.history.CalculatorHistory; /** * User: Solovyev_S @@ -10,19 +11,22 @@ import org.jetbrains.annotations.NotNull; public class CalculatorLocatorImpl implements CalculatorLocator { @NotNull - private JCalculatorEngine calculatorEngine; + private CalculatorEngine calculatorEngine; @NotNull - private final Calculator calculator = new CalculatorImpl(); + private Calculator calculator; @NotNull - private final CalculatorEditor calculatorEditor = new CalculatorEditorImpl(calculator); + private CalculatorEditor calculatorEditor; @NotNull - private final CalculatorDisplay calculatorDisplay = new CalculatorDisplayImpl(calculator); + private CalculatorDisplay calculatorDisplay; @NotNull - private final CalculatorKeyboard calculatorKeyboard = new CalculatorKeyboardImpl(calculator); + private CalculatorKeyboard calculatorKeyboard; + + @NotNull + private CalculatorHistory calculatorHistory; @NotNull private CalculatorNotifier calculatorNotifier = new DummyCalculatorNotifier(); @@ -36,6 +40,24 @@ public class CalculatorLocatorImpl implements CalculatorLocator { private CalculatorLocatorImpl() { } + @Override + public void init(@NotNull Calculator calculator, + @NotNull CalculatorEngine engine, + @NotNull CalculatorClipboard clipboard, + @NotNull CalculatorNotifier notifier, + @NotNull CalculatorHistory history) { + + this.calculator = calculator; + this.calculatorEngine = engine; + this.calculatorClipboard = clipboard; + this.calculatorNotifier = notifier; + this.calculatorHistory = history; + + calculatorEditor = new CalculatorEditorImpl(this.calculator); + calculatorDisplay = new CalculatorDisplayImpl(this.calculator); + calculatorKeyboard = new CalculatorKeyboardImpl(this.calculator); + } + @NotNull public static CalculatorLocator getInstance() { return instance; @@ -43,7 +65,7 @@ public class CalculatorLocatorImpl implements CalculatorLocator { @NotNull @Override - public JCalculatorEngine getCalculatorEngine() { + public CalculatorEngine getEngine() { return calculatorEngine; } @@ -53,48 +75,39 @@ public class CalculatorLocatorImpl implements CalculatorLocator { return this.calculator; } - @Override - public void setCalculatorEngine(@NotNull JCalculatorEngine calculatorEngine) { - this.calculatorEngine = calculatorEngine; - } - @Override @NotNull - public CalculatorDisplay getCalculatorDisplay() { + public CalculatorDisplay getDisplay() { return calculatorDisplay; } @NotNull @Override - public CalculatorEditor getCalculatorEditor() { + public CalculatorEditor getEditor() { return calculatorEditor; } @Override @NotNull - public CalculatorKeyboard getCalculatorKeyboard() { + public CalculatorKeyboard getKeyboard() { return calculatorKeyboard; } @Override @NotNull - public CalculatorClipboard getCalculatorClipboard() { + public CalculatorClipboard getClipboard() { return calculatorClipboard; } - @Override - public void setCalculatorClipboard(@NotNull CalculatorClipboard calculatorClipboard) { - this.calculatorClipboard = calculatorClipboard; - } - @Override @NotNull - public CalculatorNotifier getCalculatorNotifier() { + public CalculatorNotifier getNotifier() { return calculatorNotifier; } @Override - public void setCalculatorNotifier(@NotNull CalculatorNotifier calculatorNotifier) { - this.calculatorNotifier = calculatorNotifier; + @NotNull + public CalculatorHistory getHistory() { + return calculatorHistory; } } diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/model/AndroidMathRegistry.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorMathRegistry.java similarity index 54% rename from calculatorpp/src/main/java/org/solovyev/android/calculator/model/AndroidMathRegistry.java rename to calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorMathRegistry.java index 4f174a7c..8c340d83 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/model/AndroidMathRegistry.java +++ b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorMathRegistry.java @@ -4,10 +4,8 @@ * or visit http://se.solovyev.org */ -package org.solovyev.android.calculator.model; +package org.solovyev.android.calculator; -import android.content.Context; -import android.content.SharedPreferences; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.solovyev.common.math.MathEntity; @@ -18,15 +16,15 @@ import org.solovyev.common.math.MathRegistry; * Date: 10/30/11 * Time: 1:02 AM */ -public interface AndroidMathRegistry extends MathRegistry { +public interface CalculatorMathRegistry extends MathRegistry { @Nullable - String getDescription(@NotNull Context context, @NotNull String mathEntityName); + String getDescription(@NotNull String mathEntityName); @Nullable String getCategory(@NotNull T mathEntity); - void load(@Nullable Context context, @Nullable SharedPreferences preferences); + void load(); - void save(@NotNull Context context); + void save(); } diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorUtils.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorUtils.java new file mode 100644 index 00000000..85e874cf --- /dev/null +++ b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorUtils.java @@ -0,0 +1,22 @@ +package org.solovyev.android.calculator; + +import org.jetbrains.annotations.NotNull; + +/** + * User: serso + * Date: 9/22/12 + * Time: 7:13 PM + */ +public final class CalculatorUtils { + + static final long FIRST_ID = 0; + + private CalculatorUtils() { + throw new AssertionError(); + } + + @NotNull + public static CalculatorEventDataId createFirstEventDataId() { + return CalculatorEventDataIdImpl.newInstance(FIRST_ID, FIRST_ID); + } +} diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/ToJsclTextProcessor.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/ToJsclTextProcessor.java index efd7ee17..305220f1 100644 --- a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/ToJsclTextProcessor.java +++ b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/ToJsclTextProcessor.java @@ -1,147 +1,147 @@ -/* - * 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 org.solovyev.android.calculator.text.TextProcessor; -import org.solovyev.common.StartsWithFinder; -import org.solovyev.android.calculator.math.MathType; -import org.solovyev.common.collections.CollectionsUtils; -import org.solovyev.common.msg.MessageType; - -import java.util.ArrayList; -import java.util.List; - -public class ToJsclTextProcessor implements TextProcessor { - - @NotNull - private static final Integer MAX_DEPTH = 20; - - @NotNull - private static final TextProcessor instance = new ToJsclTextProcessor(); - - private ToJsclTextProcessor() { - } - - - @NotNull - public static TextProcessor getInstance() { - return instance; - } - - @Override - @NotNull - public PreparedExpression process(@NotNull String s) throws CalculatorParseException { - return processWithDepth(s, 0, new ArrayList()); - } - - private static PreparedExpression processWithDepth(@NotNull String s, int depth, @NotNull List undefinedVars) throws CalculatorParseException { - return replaceVariables(processExpression(s).toString(), depth, undefinedVars); - } - - @NotNull - private static StringBuilder processExpression(@NotNull String s) throws CalculatorParseException { - final StartsWithFinder startsWithFinder = new StartsWithFinder(s, 0); - final StringBuilder result = new StringBuilder(); - - MathType.Result mathTypeResult = null; - MathType.Result mathTypeBefore; - - final LiteNumberBuilder nb = new LiteNumberBuilder(CalculatorLocatorImpl.getInstance().getCalculatorEngine().getEngine()); - for (int i = 0; i < s.length(); i++) { - if (s.charAt(i) == ' ') continue; - startsWithFinder.setI(i); - - mathTypeBefore = mathTypeResult == null ? null : mathTypeResult; - - mathTypeResult = MathType.getType(s, i, nb.isHexMode()); - - nb.process(mathTypeResult); - - if (mathTypeBefore != null) { - - final MathType current = mathTypeResult.getMathType(); - - if (current.isNeedMultiplicationSignBefore(mathTypeBefore.getMathType())) { - result.append("*"); - } - } - - if (mathTypeBefore != null && - (mathTypeBefore.getMathType() == MathType.function || mathTypeBefore.getMathType() == MathType.operator) && - CollectionsUtils.find(MathType.openGroupSymbols, startsWithFinder) != null) { - throw new CalculatorParseException(i, s, new CalculatorMessage(CalculatorMessages.msg_005, MessageType.error, mathTypeBefore.getMatch())); - } - - i = mathTypeResult.processToJscl(result, i); - } - return result; - } - - @NotNull - private static PreparedExpression replaceVariables(@NotNull final String s, int depth, @NotNull List undefinedVars) throws CalculatorParseException { - if (depth >= MAX_DEPTH) { - throw new CalculatorParseException(s, new CalculatorMessage(CalculatorMessages.msg_006, MessageType.error)); - } else { - depth++; - } - - final StartsWithFinder startsWithFinder = new StartsWithFinder(s, 0); - - final StringBuilder result = new StringBuilder(); - for (int i = 0; i < s.length(); i++) { - startsWithFinder.setI(i); - - int offset = 0; - String functionName = CollectionsUtils.find(MathType.function.getTokens(), startsWithFinder); - if (functionName == null) { - String operatorName = CollectionsUtils.find(MathType.operator.getTokens(), startsWithFinder); - if (operatorName == null) { - String varName = CollectionsUtils.find(CalculatorLocatorImpl.getInstance().getCalculatorEngine().getVarsRegistry().getNames(), startsWithFinder); - if (varName != null) { - final IConstant var = CalculatorLocatorImpl.getInstance().getCalculatorEngine().getVarsRegistry().get(varName); - if (var != null) { - if (!var.isDefined()) { - undefinedVars.add(var); - result.append(varName); - offset = varName.length(); - } else { - final String value = var.getValue(); - assert value != null; - - if ( var.getDoubleValue() != null ) { - //result.append(value); - // NOTE: append varName as JSCL engine will convert it to double if needed - result.append(varName); - } else { - result.append("(").append(processWithDepth(value, depth, undefinedVars)).append(")"); - } - offset = varName.length(); - } - } - } - } else { - result.append(operatorName); - offset = operatorName.length(); - } - } else { - result.append(functionName); - offset = functionName.length(); - } - - - if (offset == 0) { - result.append(s.charAt(i)); - } else { - i += offset - 1; - } - } - - return new PreparedExpression(result.toString(), undefinedVars); - } -} +/* + * 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 org.solovyev.android.calculator.text.TextProcessor; +import org.solovyev.common.StartsWithFinder; +import org.solovyev.android.calculator.math.MathType; +import org.solovyev.common.collections.CollectionsUtils; +import org.solovyev.common.msg.MessageType; + +import java.util.ArrayList; +import java.util.List; + +public class ToJsclTextProcessor implements TextProcessor { + + @NotNull + private static final Integer MAX_DEPTH = 20; + + @NotNull + private static final TextProcessor instance = new ToJsclTextProcessor(); + + private ToJsclTextProcessor() { + } + + + @NotNull + public static TextProcessor getInstance() { + return instance; + } + + @Override + @NotNull + public PreparedExpression process(@NotNull String s) throws CalculatorParseException { + return processWithDepth(s, 0, new ArrayList()); + } + + private static PreparedExpression processWithDepth(@NotNull String s, int depth, @NotNull List undefinedVars) throws CalculatorParseException { + return replaceVariables(processExpression(s).toString(), depth, undefinedVars); + } + + @NotNull + private static StringBuilder processExpression(@NotNull String s) throws CalculatorParseException { + final StartsWithFinder startsWithFinder = new StartsWithFinder(s, 0); + final StringBuilder result = new StringBuilder(); + + MathType.Result mathTypeResult = null; + MathType.Result mathTypeBefore; + + final LiteNumberBuilder nb = new LiteNumberBuilder(CalculatorLocatorImpl.getInstance().getEngine().getEngine()); + for (int i = 0; i < s.length(); i++) { + if (s.charAt(i) == ' ') continue; + startsWithFinder.setI(i); + + mathTypeBefore = mathTypeResult == null ? null : mathTypeResult; + + mathTypeResult = MathType.getType(s, i, nb.isHexMode()); + + nb.process(mathTypeResult); + + if (mathTypeBefore != null) { + + final MathType current = mathTypeResult.getMathType(); + + if (current.isNeedMultiplicationSignBefore(mathTypeBefore.getMathType())) { + result.append("*"); + } + } + + if (mathTypeBefore != null && + (mathTypeBefore.getMathType() == MathType.function || mathTypeBefore.getMathType() == MathType.operator) && + CollectionsUtils.find(MathType.openGroupSymbols, startsWithFinder) != null) { + throw new CalculatorParseException(i, s, new CalculatorMessage(CalculatorMessages.msg_005, MessageType.error, mathTypeBefore.getMatch())); + } + + i = mathTypeResult.processToJscl(result, i); + } + return result; + } + + @NotNull + private static PreparedExpression replaceVariables(@NotNull final String s, int depth, @NotNull List undefinedVars) throws CalculatorParseException { + if (depth >= MAX_DEPTH) { + throw new CalculatorParseException(s, new CalculatorMessage(CalculatorMessages.msg_006, MessageType.error)); + } else { + depth++; + } + + final StartsWithFinder startsWithFinder = new StartsWithFinder(s, 0); + + final StringBuilder result = new StringBuilder(); + for (int i = 0; i < s.length(); i++) { + startsWithFinder.setI(i); + + int offset = 0; + String functionName = CollectionsUtils.find(MathType.function.getTokens(), startsWithFinder); + if (functionName == null) { + String operatorName = CollectionsUtils.find(MathType.operator.getTokens(), startsWithFinder); + if (operatorName == null) { + String varName = CollectionsUtils.find(CalculatorLocatorImpl.getInstance().getEngine().getVarsRegistry().getNames(), startsWithFinder); + if (varName != null) { + final IConstant var = CalculatorLocatorImpl.getInstance().getEngine().getVarsRegistry().get(varName); + if (var != null) { + if (!var.isDefined()) { + undefinedVars.add(var); + result.append(varName); + offset = varName.length(); + } else { + final String value = var.getValue(); + assert value != null; + + if ( var.getDoubleValue() != null ) { + //result.append(value); + // NOTE: append varName as JSCL engine will convert it to double if needed + result.append(varName); + } else { + result.append("(").append(processWithDepth(value, depth, undefinedVars)).append(")"); + } + offset = varName.length(); + } + } + } + } else { + result.append(operatorName); + offset = operatorName.length(); + } + } else { + result.append(functionName); + offset = functionName.length(); + } + + + if (offset == 0) { + result.append(s.charAt(i)); + } else { + i += offset - 1; + } + } + + return new PreparedExpression(result.toString(), undefinedVars); + } +} 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 index 517db8d0..9d99943e 100644 --- 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 @@ -1,21 +1,33 @@ -package org.solovyev.android.calculator.history; - -import org.jetbrains.annotations.NotNull; -import org.solovyev.android.calculator.CalculatorEventListener; -import org.solovyev.common.history.HistoryHelper; - -/** - * User: Solovyev_S - * Date: 20.09.12 - * Time: 16:11 - */ -public interface CalculatorHistory extends HistoryHelper, CalculatorEventListener { - - void fromXml(@NotNull String xml); - - String toXml(); - - void clearSavedHistory(); - - void removeSavedHistory(@NotNull CalculatorHistoryState historyState); -} +package org.solovyev.android.calculator.history; + +import org.jetbrains.annotations.NotNull; +import org.solovyev.android.calculator.CalculatorEventListener; +import org.solovyev.common.history.HistoryHelper; + +import java.util.List; + +/** + * User: Solovyev_S + * Date: 20.09.12 + * Time: 16:11 + */ +public interface CalculatorHistory extends HistoryHelper, CalculatorEventListener { + + void load(); + + void save(); + + void fromXml(@NotNull String xml); + + String toXml(); + + void clearSavedHistory(); + + void removeSavedHistory(@NotNull CalculatorHistoryState historyState); + + @NotNull + List getSavedHistory(); + + @NotNull + CalculatorHistoryState addSavedState(@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 index 75154741..c22ece6f 100644 --- 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 @@ -31,29 +31,41 @@ public class CalculatorHistoryImpl implements CalculatorHistory { private final List savedHistory = new ArrayList(); @NotNull - private volatile CalculatorEventDataId lastEventDataId = CalculatorLocatorImpl.getInstance().getCalculator().createFirstEventDataId(); + private volatile CalculatorEventDataId lastEventDataId = CalculatorUtils.createFirstEventDataId(); @Nullable private volatile CalculatorEditorViewState lastEditorViewState; + public CalculatorHistoryImpl(@NotNull Calculator calculator) { + calculator.addCalculatorEventListener(this); + } + @Override public boolean isEmpty() { - return this.history.isEmpty(); + synchronized (history) { + return this.history.isEmpty(); + } } @Override public CalculatorHistoryState getLastHistoryState() { - return this.history.getLastHistoryState(); + synchronized (history) { + return this.history.getLastHistoryState(); + } } @Override public boolean isUndoAvailable() { - return history.isUndoAvailable(); + synchronized (history) { + return history.isUndoAvailable(); + } } @Override public CalculatorHistoryState undo(@Nullable CalculatorHistoryState currentState) { - return history.undo(currentState); + synchronized (history) { + return history.undo(currentState); + } } @Override @@ -63,40 +75,54 @@ public class CalculatorHistoryImpl implements CalculatorHistory { @Override public CalculatorHistoryState redo(@Nullable CalculatorHistoryState currentState) { - return history.redo(currentState); + synchronized (history) { + return history.redo(currentState); + } } @Override public boolean isActionAvailable(@NotNull HistoryAction historyAction) { - return history.isActionAvailable(historyAction); + synchronized (history) { + return history.isActionAvailable(historyAction); + } } @Override public CalculatorHistoryState doAction(@NotNull HistoryAction historyAction, @Nullable CalculatorHistoryState currentState) { - return history.doAction(historyAction, currentState); + synchronized (history) { + return history.doAction(historyAction, currentState); + } } @Override public void addState(@Nullable CalculatorHistoryState currentState) { - history.addState(currentState); + synchronized (history) { + history.addState(currentState); + } } @NotNull @Override public List getStates() { - return history.getStates(); + synchronized (history) { + return history.getStates(); + } } @Override public void clear() { - this.history.clear(); + synchronized (history) { + this.history.clear(); + } } + @Override @NotNull public List getSavedHistory() { return Collections.unmodifiableList(savedHistory); } + @Override @NotNull public CalculatorHistoryState addSavedState(@NotNull CalculatorHistoryState historyState) { if (historyState.isSaved()) { @@ -113,6 +139,16 @@ public class CalculatorHistoryImpl implements CalculatorHistory { } } + @Override + public void load() { + // todo serso: create saved/loader class + } + + @Override + public void save() { + // todo serso: create saved/loader class + } + @Override public void fromXml(@NotNull String xml) { clearSavedHistory(); @@ -148,20 +184,27 @@ public class CalculatorHistoryImpl implements CalculatorHistory { if (calculatorEventData.isAfter(this.lastEventDataId)) { final boolean sameSequence = calculatorEventData.isSameSequence(this.lastEventDataId); - this.lastEventDataId = calculatorEventData; + if (sameSequence || calculatorEventData.isAfterSequence(this.lastEventDataId)) { + this.lastEventDataId = calculatorEventData; - switch (calculatorEventType) { - case editor_state_changed: - final CalculatorEditorChangeEventData changeEventData = (CalculatorEditorChangeEventData) data; - lastEditorViewState = changeEventData.getNewState(); - break; - case display_state_changed: - if (sameSequence) { - - } else { - lastEditorViewState = null; - } - break; + switch (calculatorEventType) { + case editor_state_changed: + final CalculatorEditorChangeEventData editorChangeData = (CalculatorEditorChangeEventData) data; + lastEditorViewState = editorChangeData.getNewState(); + break; + case display_state_changed: + if (sameSequence) { + if (lastEditorViewState != null) { + final CalculatorEditorViewState editorViewState = lastEditorViewState; + final CalculatorDisplayChangeEventData displayChangeData = (CalculatorDisplayChangeEventData) data; + final CalculatorDisplayViewState displayViewState = displayChangeData.getNewState(); + addState(CalculatorHistoryState.newInstance(editorViewState, displayViewState)); + } + } else { + lastEditorViewState = null; + } + break; + } } } } diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/jscl/JsclOperation.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/jscl/JsclOperation.java index 978964b7..08924a95 100644 --- a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/jscl/JsclOperation.java +++ b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/jscl/JsclOperation.java @@ -1,70 +1,70 @@ -/* - * Copyright (c) 2009-2011. Created by serso aka se.solovyev. - * For more information, please, contact se.solovyev@gmail.com - */ - -package org.solovyev.android.calculator.jscl; - - -import jscl.math.Generic; -import jscl.text.ParseException; -import org.jetbrains.annotations.NotNull; -import org.solovyev.android.calculator.CalculatorLocatorImpl; -import org.solovyev.android.calculator.text.DummyTextProcessor; -import org.solovyev.android.calculator.text.FromJsclSimplifyTextProcessor; -import org.solovyev.android.calculator.text.TextProcessor; - -public enum JsclOperation { - - simplify, - elementary, - numeric; - - JsclOperation() { - } - - - @NotNull - public TextProcessor getFromProcessor() { - switch (this) { - case simplify: - return FromJsclSimplifyTextProcessor.instance; - case elementary: - return DummyTextProcessor.instance; - case numeric: - return FromJsclNumericTextProcessor.instance; - default: - throw new UnsupportedOperationException(); - } - } - - @NotNull - public final String evaluate(@NotNull String expression) throws ParseException { - switch (this) { - case simplify: - return CalculatorLocatorImpl.getInstance().getCalculatorEngine().getEngine().simplify(expression); - case elementary: - return CalculatorLocatorImpl.getInstance().getCalculatorEngine().getEngine().elementary(expression); - case numeric: - return CalculatorLocatorImpl.getInstance().getCalculatorEngine().getEngine().evaluate(expression); - default: - throw new UnsupportedOperationException(); - } - } - - @NotNull - public final Generic evaluateGeneric(@NotNull String expression) throws ParseException { - switch (this) { - case simplify: - return CalculatorLocatorImpl.getInstance().getCalculatorEngine().getEngine().simplifyGeneric(expression); - case elementary: - return CalculatorLocatorImpl.getInstance().getCalculatorEngine().getEngine().elementaryGeneric(expression); - case numeric: - return CalculatorLocatorImpl.getInstance().getCalculatorEngine().getEngine().evaluateGeneric(expression); - default: - throw new UnsupportedOperationException(); - } - } - - -} +/* + * Copyright (c) 2009-2011. Created by serso aka se.solovyev. + * For more information, please, contact se.solovyev@gmail.com + */ + +package org.solovyev.android.calculator.jscl; + + +import jscl.math.Generic; +import jscl.text.ParseException; +import org.jetbrains.annotations.NotNull; +import org.solovyev.android.calculator.CalculatorLocatorImpl; +import org.solovyev.android.calculator.text.DummyTextProcessor; +import org.solovyev.android.calculator.text.FromJsclSimplifyTextProcessor; +import org.solovyev.android.calculator.text.TextProcessor; + +public enum JsclOperation { + + simplify, + elementary, + numeric; + + JsclOperation() { + } + + + @NotNull + public TextProcessor getFromProcessor() { + switch (this) { + case simplify: + return FromJsclSimplifyTextProcessor.instance; + case elementary: + return DummyTextProcessor.instance; + case numeric: + return FromJsclNumericTextProcessor.instance; + default: + throw new UnsupportedOperationException(); + } + } + + @NotNull + public final String evaluate(@NotNull String expression) throws ParseException { + switch (this) { + case simplify: + return CalculatorLocatorImpl.getInstance().getEngine().getEngine().simplify(expression); + case elementary: + return CalculatorLocatorImpl.getInstance().getEngine().getEngine().elementary(expression); + case numeric: + return CalculatorLocatorImpl.getInstance().getEngine().getEngine().evaluate(expression); + default: + throw new UnsupportedOperationException(); + } + } + + @NotNull + public final Generic evaluateGeneric(@NotNull String expression) throws ParseException { + switch (this) { + case simplify: + return CalculatorLocatorImpl.getInstance().getEngine().getEngine().simplifyGeneric(expression); + case elementary: + return CalculatorLocatorImpl.getInstance().getEngine().getEngine().elementaryGeneric(expression); + case numeric: + return CalculatorLocatorImpl.getInstance().getEngine().getEngine().evaluateGeneric(expression); + default: + throw new UnsupportedOperationException(); + } + } + + +} diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/math/MathType.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/math/MathType.java index 549ae9fd..ddfe896e 100644 --- a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/math/MathType.java +++ b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/math/MathType.java @@ -1,445 +1,445 @@ -/* - * Copyright (c) 2009-2011. Created by serso aka se.solovyev. - * For more information, please, contact se.solovyev@gmail.com - */ - -package org.solovyev.android.calculator.math; - -import jscl.JsclMathEngine; -import jscl.NumeralBase; -import jscl.math.function.Constants; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.solovyev.android.calculator.CalculatorLocatorImpl; -import org.solovyev.common.JPredicate; -import org.solovyev.common.StartsWithFinder; -import org.solovyev.android.calculator.CalculatorParseException; -import org.solovyev.common.collections.CollectionsUtils; - -import java.util.*; - - -public enum MathType { - - numeral_base(50, true, false, MathGroupType.number) { - - private final List tokens = new ArrayList(10); - { - for (NumeralBase numeralBase : NumeralBase.values()) { - tokens.add(numeralBase.getJsclPrefix()); - } - } - - @NotNull - @Override - public List getTokens() { - return tokens; - } - }, - - dot(200, true, true, MathGroupType.number, ".") { - @Override - public boolean isNeedMultiplicationSignBefore(@NotNull MathType mathTypeBefore) { - return super.isNeedMultiplicationSignBefore(mathTypeBefore) && mathTypeBefore != digit; - } - }, - - grouping_separator(250, false, false, MathGroupType.number, "'", " "){ - @Override - public int processToJscl(@NotNull StringBuilder result, int i, @NotNull String match) throws CalculatorParseException { - return i; - } - }, - - power_10(300, false, false, MathGroupType.number, "E"), - - postfix_function(400, false, true, MathGroupType.function) { - @NotNull - @Override - public List getTokens() { - return CalculatorLocatorImpl.getInstance().getCalculatorEngine().getPostfixFunctionsRegistry().getNames(); - } - }, - - unary_operation(500, false, false, MathGroupType.operation, "-", "="), - binary_operation(600, false, false, MathGroupType.operation, "-", "+", "*", "×", "∙", "/", "^") { - @Override - protected String getSubstituteToJscl(@NotNull String match) { - if (match.equals("×") || match.equals("∙")) { - return "*"; - } else { - return null; - } - } - }, - - open_group_symbol(800, true, false, MathGroupType.other, "[", "(", "{") { - @Override - public boolean isNeedMultiplicationSignBefore(@NotNull MathType mathTypeBefore) { - return super.isNeedMultiplicationSignBefore(mathTypeBefore) && mathTypeBefore != function && mathTypeBefore != operator; - } - - @Override - protected String getSubstituteToJscl(@NotNull String match) { - return "("; - } - }, - - close_group_symbol(900, false, true, MathGroupType.other, "]", ")", "}") { - @Override - public boolean isNeedMultiplicationSignBefore(@NotNull MathType mathTypeBefore) { - return false; - } - - @Override - protected String getSubstituteToJscl(@NotNull String match) { - return ")"; - } - }, - - function(1000, true, true, MathGroupType.function) { - @NotNull - @Override - public List getTokens() { - return CalculatorLocatorImpl.getInstance().getCalculatorEngine().getFunctionsRegistry().getNames(); - } - }, - - operator(1050, true, true, MathGroupType.function) { - @NotNull - @Override - public List getTokens() { - return CalculatorLocatorImpl.getInstance().getCalculatorEngine().getOperatorsRegistry().getNames(); - } - }, - - constant(1100, true, true, MathGroupType.other) { - @NotNull - @Override - public List getTokens() { - return CalculatorLocatorImpl.getInstance().getCalculatorEngine().getVarsRegistry().getNames(); - } - - @Override - protected String getSubstituteFromJscl(@NotNull String match) { - return Constants.INF_2.getName().equals(match) ? MathType.INFINITY : super.getSubstituteFromJscl(match); - } - }, - - digit(1125, true, true, MathGroupType.number) { - - private final List tokens = new ArrayList(16); - { - for (Character character : NumeralBase.hex.getAcceptableCharacters()) { - tokens.add(character.toString()); - } - } - @Override - public boolean isNeedMultiplicationSignBefore(@NotNull MathType mathTypeBefore) { - return super.isNeedMultiplicationSignBefore(mathTypeBefore) && mathTypeBefore != digit && mathTypeBefore != dot /*&& mathTypeBefore != numeral_base*/; - } - - @NotNull - @Override - public List getTokens() { - return tokens; - } - }, - - comma(1150, false, false, MathGroupType.other, ","), - - text(1200, false, false, MathGroupType.other) { - @Override - public int processToJscl(@NotNull StringBuilder result, int i, @NotNull String match) { - if (match.length() > 0) { - result.append(match.charAt(0)); - } - return i; - } - - @Override - public int processFromJscl(@NotNull StringBuilder result, int i, @NotNull String match) { - if (match.length() > 0) { - result.append(match.charAt(0)); - } - return i; - } - }; - - public static enum MathGroupType { - function, - number, - operation, - other - } - - @NotNull - private final List tokens; - - @NotNull - private final Integer priority; - - private final boolean needMultiplicationSignBefore; - - private final boolean needMultiplicationSignAfter; - - @NotNull - private final MathGroupType groupType; - - MathType(@NotNull Integer priority, - boolean needMultiplicationSignBefore, - boolean needMultiplicationSignAfter, - @NotNull MathGroupType groupType, - @NotNull String... tokens) { - this(priority, needMultiplicationSignBefore, needMultiplicationSignAfter, groupType, CollectionsUtils.asList(tokens)); - } - - MathType(@NotNull Integer priority, - boolean needMultiplicationSignBefore, - boolean needMultiplicationSignAfter, - @NotNull MathGroupType groupType, - @NotNull List tokens) { - this.priority = priority; - this.needMultiplicationSignBefore = needMultiplicationSignBefore; - this.needMultiplicationSignAfter = needMultiplicationSignAfter; - this.groupType = groupType; - this.tokens = Collections.unmodifiableList(tokens); - } - - @NotNull - public MathGroupType getGroupType() { - return groupType; - } - - /* public static int getPostfixFunctionStart(@NotNull CharSequence s, int position) throws ParseException { - assert s.length() > position; - - int numberOfOpenGroups = 0; - int result = position; - for (; result >= 0; result--) { - - final MathType mathType = getType(s.toString(), result).getMathType(); - - if (CollectionsUtils.contains(mathType, digit, dot, grouping_separator, power_10)) { - // continue - } else if (mathType == close_group_symbol) { - numberOfOpenGroups++; - } else if (mathType == open_group_symbol) { - if (numberOfOpenGroups > 0) { - numberOfOpenGroups--; - } else { - break; - } - } else { - if (stop(s, numberOfOpenGroups, result)) break; - } - } - - if (numberOfOpenGroups != 0){ - throw new ParseException("Could not find start of prefix function!"); - } - - return result; - } - - public static boolean stop(CharSequence s, int numberOfOpenGroups, int i) { - if (numberOfOpenGroups == 0) { - if (i > 0) { - final EndsWithFinder endsWithFinder = new EndsWithFinder(s); - endsWithFinder.setI(i + 1); - if (!CollectionsUtils.contains(function.getTokens(), FilterType.included, endsWithFinder)) { - MathType type = getType(s.toString(), i).getMathType(); - if (type != constant) { - return true; - } - } - } else { - return true; - } - } - - return false; - }*/ - - @NotNull - public List getTokens() { - return tokens; - } - - private boolean isNeedMultiplicationSignBefore() { - return needMultiplicationSignBefore; - } - - private boolean isNeedMultiplicationSignAfter() { - return needMultiplicationSignAfter; - } - - public boolean isNeedMultiplicationSignBefore(@NotNull MathType mathTypeBefore) { - return needMultiplicationSignBefore && mathTypeBefore.isNeedMultiplicationSignAfter(); - } - - public int processToJscl(@NotNull StringBuilder result, int i, @NotNull String match) throws CalculatorParseException { - final String substitute = getSubstituteToJscl(match); - result.append(substitute == null ? match : substitute); - return returnI(i, match); - } - - protected int returnI(int i, @NotNull String match) { - if (match.length() > 1) { - return i + match.length() - 1; - } else { - return i; - } - } - - public int processFromJscl(@NotNull StringBuilder result, int i, @NotNull String match) { - final String substitute = getSubstituteFromJscl(match); - result.append(substitute == null ? match : substitute); - return returnI(i, match); - } - - @Nullable - protected String getSubstituteFromJscl(@NotNull String match) { - return null; - } - - @Nullable - protected String getSubstituteToJscl(@NotNull String match) { - return null; - } - - public static final List openGroupSymbols = Arrays.asList("[]", "()", "{}"); - - public final static Character POWER_10 = 'E'; - - public static final String IMAGINARY_NUMBER = "i"; - public static final String IMAGINARY_NUMBER_JSCL = "√(-1)"; - - public static final String PI = "π"; - public static final String E = "e"; - public static final String C = "c"; - public static final Double C_VALUE = 299792458d; - public static final String G = "G"; - public static final Double G_VALUE = 6.6738480E-11; - public static final String H_REDUCED = "h"; - public static final Double H_REDUCED_VALUE = 6.6260695729E-34 / ( 2 * Math.PI ); - public final static String NAN = "NaN"; - - public final static String INFINITY = "∞"; - public final static String INFINITY_JSCL = "Infinity"; - - - /** - * Method determines mathematical entity type for text substring starting from ith index - * - * - * @param text analyzed text - * @param i index which points to start of substring - * @param hexMode - * @return math entity type of substring starting from ith index of specified text - */ - @NotNull - public static Result getType(@NotNull String text, int i, boolean hexMode) { - if (i < 0) { - throw new IllegalArgumentException("I must be more or equals to 0."); - } else if (i >= text.length() && i != 0) { - throw new IllegalArgumentException("I must be less than size of text."); - } else if (i == 0 && text.length() == 0) { - return new Result(MathType.text, text); - } - - final StartsWithFinder startsWithFinder = new StartsWithFinder(text, i); - - for (MathType mathType : getMathTypesByPriority()) { - final String s = CollectionsUtils.find(mathType.getTokens(), startsWithFinder); - if (s != null) { - if ( s.length() == 1 ) { - if (hexMode || JsclMathEngine.instance.getNumeralBase() == NumeralBase.hex) { - final Character ch = s.charAt(0); - if ( NumeralBase.hex.getAcceptableCharacters().contains(ch) ) { - return new Result(MathType.digit, s); - } - } - } - return new Result(mathType, s); - } - } - - return new Result(MathType.text, text.substring(i)); - } - - - private static List mathTypesByPriority; - - @NotNull - private static List getMathTypesByPriority() { - if (mathTypesByPriority == null) { - final List result = CollectionsUtils.asList(MathType.values()); - - Collections.sort(result, new Comparator() { - @Override - public int compare(MathType l, MathType r) { - return l.priority.compareTo(r.priority); - } - }); - - mathTypesByPriority = result; - } - - return mathTypesByPriority; - } - - public static class Result { - - @NotNull - private final MathType mathType; - - @NotNull - private final String match; - - public Result(@NotNull MathType mathType, @NotNull String match) { - this.mathType = mathType; - - this.match = match; - } - - public int processToJscl(@NotNull StringBuilder result, int i) throws CalculatorParseException { - return mathType.processToJscl(result, i, match); - } - - public int processFromJscl(@NotNull StringBuilder result, int i) { - return mathType.processFromJscl(result, i, match); - } - - @NotNull - public String getMatch() { - return match; - } - - @NotNull - public MathType getMathType() { - return mathType; - } - } - - private static class EndsWithFinder implements JPredicate { - - private int i; - - @NotNull - private final CharSequence targetString; - - private EndsWithFinder(@NotNull CharSequence targetString) { - this.targetString = targetString; - } - - @Override - public boolean apply(@Nullable String s) { - return targetString.subSequence(0, i).toString().endsWith(s); - } - - public void setI(int i) { - this.i = i; - } - } -} +/* + * Copyright (c) 2009-2011. Created by serso aka se.solovyev. + * For more information, please, contact se.solovyev@gmail.com + */ + +package org.solovyev.android.calculator.math; + +import jscl.JsclMathEngine; +import jscl.NumeralBase; +import jscl.math.function.Constants; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.solovyev.android.calculator.CalculatorLocatorImpl; +import org.solovyev.common.JPredicate; +import org.solovyev.common.StartsWithFinder; +import org.solovyev.android.calculator.CalculatorParseException; +import org.solovyev.common.collections.CollectionsUtils; + +import java.util.*; + + +public enum MathType { + + numeral_base(50, true, false, MathGroupType.number) { + + private final List tokens = new ArrayList(10); + { + for (NumeralBase numeralBase : NumeralBase.values()) { + tokens.add(numeralBase.getJsclPrefix()); + } + } + + @NotNull + @Override + public List getTokens() { + return tokens; + } + }, + + dot(200, true, true, MathGroupType.number, ".") { + @Override + public boolean isNeedMultiplicationSignBefore(@NotNull MathType mathTypeBefore) { + return super.isNeedMultiplicationSignBefore(mathTypeBefore) && mathTypeBefore != digit; + } + }, + + grouping_separator(250, false, false, MathGroupType.number, "'", " "){ + @Override + public int processToJscl(@NotNull StringBuilder result, int i, @NotNull String match) throws CalculatorParseException { + return i; + } + }, + + power_10(300, false, false, MathGroupType.number, "E"), + + postfix_function(400, false, true, MathGroupType.function) { + @NotNull + @Override + public List getTokens() { + return CalculatorLocatorImpl.getInstance().getEngine().getPostfixFunctionsRegistry().getNames(); + } + }, + + unary_operation(500, false, false, MathGroupType.operation, "-", "="), + binary_operation(600, false, false, MathGroupType.operation, "-", "+", "*", "×", "∙", "/", "^") { + @Override + protected String getSubstituteToJscl(@NotNull String match) { + if (match.equals("×") || match.equals("∙")) { + return "*"; + } else { + return null; + } + } + }, + + open_group_symbol(800, true, false, MathGroupType.other, "[", "(", "{") { + @Override + public boolean isNeedMultiplicationSignBefore(@NotNull MathType mathTypeBefore) { + return super.isNeedMultiplicationSignBefore(mathTypeBefore) && mathTypeBefore != function && mathTypeBefore != operator; + } + + @Override + protected String getSubstituteToJscl(@NotNull String match) { + return "("; + } + }, + + close_group_symbol(900, false, true, MathGroupType.other, "]", ")", "}") { + @Override + public boolean isNeedMultiplicationSignBefore(@NotNull MathType mathTypeBefore) { + return false; + } + + @Override + protected String getSubstituteToJscl(@NotNull String match) { + return ")"; + } + }, + + function(1000, true, true, MathGroupType.function) { + @NotNull + @Override + public List getTokens() { + return CalculatorLocatorImpl.getInstance().getEngine().getFunctionsRegistry().getNames(); + } + }, + + operator(1050, true, true, MathGroupType.function) { + @NotNull + @Override + public List getTokens() { + return CalculatorLocatorImpl.getInstance().getEngine().getOperatorsRegistry().getNames(); + } + }, + + constant(1100, true, true, MathGroupType.other) { + @NotNull + @Override + public List getTokens() { + return CalculatorLocatorImpl.getInstance().getEngine().getVarsRegistry().getNames(); + } + + @Override + protected String getSubstituteFromJscl(@NotNull String match) { + return Constants.INF_2.getName().equals(match) ? MathType.INFINITY : super.getSubstituteFromJscl(match); + } + }, + + digit(1125, true, true, MathGroupType.number) { + + private final List tokens = new ArrayList(16); + { + for (Character character : NumeralBase.hex.getAcceptableCharacters()) { + tokens.add(character.toString()); + } + } + @Override + public boolean isNeedMultiplicationSignBefore(@NotNull MathType mathTypeBefore) { + return super.isNeedMultiplicationSignBefore(mathTypeBefore) && mathTypeBefore != digit && mathTypeBefore != dot /*&& mathTypeBefore != numeral_base*/; + } + + @NotNull + @Override + public List getTokens() { + return tokens; + } + }, + + comma(1150, false, false, MathGroupType.other, ","), + + text(1200, false, false, MathGroupType.other) { + @Override + public int processToJscl(@NotNull StringBuilder result, int i, @NotNull String match) { + if (match.length() > 0) { + result.append(match.charAt(0)); + } + return i; + } + + @Override + public int processFromJscl(@NotNull StringBuilder result, int i, @NotNull String match) { + if (match.length() > 0) { + result.append(match.charAt(0)); + } + return i; + } + }; + + public static enum MathGroupType { + function, + number, + operation, + other + } + + @NotNull + private final List tokens; + + @NotNull + private final Integer priority; + + private final boolean needMultiplicationSignBefore; + + private final boolean needMultiplicationSignAfter; + + @NotNull + private final MathGroupType groupType; + + MathType(@NotNull Integer priority, + boolean needMultiplicationSignBefore, + boolean needMultiplicationSignAfter, + @NotNull MathGroupType groupType, + @NotNull String... tokens) { + this(priority, needMultiplicationSignBefore, needMultiplicationSignAfter, groupType, CollectionsUtils.asList(tokens)); + } + + MathType(@NotNull Integer priority, + boolean needMultiplicationSignBefore, + boolean needMultiplicationSignAfter, + @NotNull MathGroupType groupType, + @NotNull List tokens) { + this.priority = priority; + this.needMultiplicationSignBefore = needMultiplicationSignBefore; + this.needMultiplicationSignAfter = needMultiplicationSignAfter; + this.groupType = groupType; + this.tokens = Collections.unmodifiableList(tokens); + } + + @NotNull + public MathGroupType getGroupType() { + return groupType; + } + + /* public static int getPostfixFunctionStart(@NotNull CharSequence s, int position) throws ParseException { + assert s.length() > position; + + int numberOfOpenGroups = 0; + int result = position; + for (; result >= 0; result--) { + + final MathType mathType = getType(s.toString(), result).getMathType(); + + if (CollectionsUtils.contains(mathType, digit, dot, grouping_separator, power_10)) { + // continue + } else if (mathType == close_group_symbol) { + numberOfOpenGroups++; + } else if (mathType == open_group_symbol) { + if (numberOfOpenGroups > 0) { + numberOfOpenGroups--; + } else { + break; + } + } else { + if (stop(s, numberOfOpenGroups, result)) break; + } + } + + if (numberOfOpenGroups != 0){ + throw new ParseException("Could not find start of prefix function!"); + } + + return result; + } + + public static boolean stop(CharSequence s, int numberOfOpenGroups, int i) { + if (numberOfOpenGroups == 0) { + if (i > 0) { + final EndsWithFinder endsWithFinder = new EndsWithFinder(s); + endsWithFinder.setI(i + 1); + if (!CollectionsUtils.contains(function.getTokens(), FilterType.included, endsWithFinder)) { + MathType type = getType(s.toString(), i).getMathType(); + if (type != constant) { + return true; + } + } + } else { + return true; + } + } + + return false; + }*/ + + @NotNull + public List getTokens() { + return tokens; + } + + private boolean isNeedMultiplicationSignBefore() { + return needMultiplicationSignBefore; + } + + private boolean isNeedMultiplicationSignAfter() { + return needMultiplicationSignAfter; + } + + public boolean isNeedMultiplicationSignBefore(@NotNull MathType mathTypeBefore) { + return needMultiplicationSignBefore && mathTypeBefore.isNeedMultiplicationSignAfter(); + } + + public int processToJscl(@NotNull StringBuilder result, int i, @NotNull String match) throws CalculatorParseException { + final String substitute = getSubstituteToJscl(match); + result.append(substitute == null ? match : substitute); + return returnI(i, match); + } + + protected int returnI(int i, @NotNull String match) { + if (match.length() > 1) { + return i + match.length() - 1; + } else { + return i; + } + } + + public int processFromJscl(@NotNull StringBuilder result, int i, @NotNull String match) { + final String substitute = getSubstituteFromJscl(match); + result.append(substitute == null ? match : substitute); + return returnI(i, match); + } + + @Nullable + protected String getSubstituteFromJscl(@NotNull String match) { + return null; + } + + @Nullable + protected String getSubstituteToJscl(@NotNull String match) { + return null; + } + + public static final List openGroupSymbols = Arrays.asList("[]", "()", "{}"); + + public final static Character POWER_10 = 'E'; + + public static final String IMAGINARY_NUMBER = "i"; + public static final String IMAGINARY_NUMBER_JSCL = "√(-1)"; + + public static final String PI = "π"; + public static final String E = "e"; + public static final String C = "c"; + public static final Double C_VALUE = 299792458d; + public static final String G = "G"; + public static final Double G_VALUE = 6.6738480E-11; + public static final String H_REDUCED = "h"; + public static final Double H_REDUCED_VALUE = 6.6260695729E-34 / ( 2 * Math.PI ); + public final static String NAN = "NaN"; + + public final static String INFINITY = "∞"; + public final static String INFINITY_JSCL = "Infinity"; + + + /** + * Method determines mathematical entity type for text substring starting from ith index + * + * + * @param text analyzed text + * @param i index which points to start of substring + * @param hexMode + * @return math entity type of substring starting from ith index of specified text + */ + @NotNull + public static Result getType(@NotNull String text, int i, boolean hexMode) { + if (i < 0) { + throw new IllegalArgumentException("I must be more or equals to 0."); + } else if (i >= text.length() && i != 0) { + throw new IllegalArgumentException("I must be less than size of text."); + } else if (i == 0 && text.length() == 0) { + return new Result(MathType.text, text); + } + + final StartsWithFinder startsWithFinder = new StartsWithFinder(text, i); + + for (MathType mathType : getMathTypesByPriority()) { + final String s = CollectionsUtils.find(mathType.getTokens(), startsWithFinder); + if (s != null) { + if ( s.length() == 1 ) { + if (hexMode || JsclMathEngine.instance.getNumeralBase() == NumeralBase.hex) { + final Character ch = s.charAt(0); + if ( NumeralBase.hex.getAcceptableCharacters().contains(ch) ) { + return new Result(MathType.digit, s); + } + } + } + return new Result(mathType, s); + } + } + + return new Result(MathType.text, text.substring(i)); + } + + + private static List mathTypesByPriority; + + @NotNull + private static List getMathTypesByPriority() { + if (mathTypesByPriority == null) { + final List result = CollectionsUtils.asList(MathType.values()); + + Collections.sort(result, new Comparator() { + @Override + public int compare(MathType l, MathType r) { + return l.priority.compareTo(r.priority); + } + }); + + mathTypesByPriority = result; + } + + return mathTypesByPriority; + } + + public static class Result { + + @NotNull + private final MathType mathType; + + @NotNull + private final String match; + + public Result(@NotNull MathType mathType, @NotNull String match) { + this.mathType = mathType; + + this.match = match; + } + + public int processToJscl(@NotNull StringBuilder result, int i) throws CalculatorParseException { + return mathType.processToJscl(result, i, match); + } + + public int processFromJscl(@NotNull StringBuilder result, int i) { + return mathType.processFromJscl(result, i, match); + } + + @NotNull + public String getMatch() { + return match; + } + + @NotNull + public MathType getMathType() { + return mathType; + } + } + + private static class EndsWithFinder implements JPredicate { + + private int i; + + @NotNull + private final CharSequence targetString; + + private EndsWithFinder(@NotNull CharSequence targetString) { + this.targetString = targetString; + } + + @Override + public boolean apply(@Nullable String s) { + return targetString.subSequence(0, i).toString().endsWith(s); + } + + public void setI(int i) { + this.i = i; + } + } +} diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/text/FromJsclSimplifyTextProcessor.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/text/FromJsclSimplifyTextProcessor.java index 3fc4da64..a6b8e300 100644 --- a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/text/FromJsclSimplifyTextProcessor.java +++ b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/text/FromJsclSimplifyTextProcessor.java @@ -1,94 +1,94 @@ -package org.solovyev.android.calculator.text; - -import jscl.math.Generic; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.solovyev.android.calculator.CalculatorLocatorImpl; -import org.solovyev.android.calculator.math.MathType; -import org.solovyev.android.calculator.CalculatorParseException; - -import java.util.Arrays; -import java.util.List; - -/** - * User: serso - * Date: 10/20/11 - * Time: 2:59 PM - */ -public class FromJsclSimplifyTextProcessor implements TextProcessor { - - public static final FromJsclSimplifyTextProcessor instance = new FromJsclSimplifyTextProcessor(); - - public FromJsclSimplifyTextProcessor() { - } - - @NotNull - @Override - public String process(@NotNull Generic from) throws CalculatorParseException { - return removeMultiplicationSigns(from.toString()); - } - - public String process(@NotNull String s) { - return removeMultiplicationSigns(s); - } - - @NotNull - private String removeMultiplicationSigns(String s) { - final StringBuilder sb = new StringBuilder(); - - MathType.Result mathTypeBefore; - MathType.Result mathType = null; - MathType.Result mathTypeAfter = null; - - for (int i = 0; i < s.length(); i++) { - mathTypeBefore = mathType; - if (mathTypeAfter == null) { - mathType = MathType.getType(s, i, false); - } else { - mathType = mathTypeAfter; - } - - char ch = s.charAt(i); - if (ch == '*') { - if (i + 1 < s.length()) { - mathTypeAfter = MathType.getType(s, i + 1, false); - } else { - mathTypeAfter = null; - } - - if (needMultiplicationSign(mathTypeBefore == null ? null : mathTypeBefore.getMathType(), mathTypeAfter == null ? null : mathTypeAfter.getMathType())) { - sb.append(CalculatorLocatorImpl.getInstance().getCalculatorEngine().getMultiplicationSign()); - } - - } else { - if (mathType.getMathType() == MathType.constant || mathType.getMathType() == MathType.function || mathType.getMathType() == MathType.operator) { - sb.append(mathType.getMatch()); - i += mathType.getMatch().length() - 1; - } else { - sb.append(ch); - } - mathTypeAfter = null; - } - - } - - return sb.toString(); - } - - private final List mathTypes = Arrays.asList(MathType.function, MathType.constant); - - private boolean needMultiplicationSign(@Nullable MathType mathTypeBefore, @Nullable MathType mathTypeAfter) { - if (mathTypeBefore == null || mathTypeAfter == null) { - return true; - } else if (mathTypes.contains(mathTypeBefore) || mathTypes.contains(mathTypeAfter)) { - return false; - } else if ( mathTypeBefore == MathType.close_group_symbol ) { - return false; - } else if ( mathTypeAfter == MathType.open_group_symbol ) { - return false; - } - - return true; - } - -} +package org.solovyev.android.calculator.text; + +import jscl.math.Generic; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.solovyev.android.calculator.CalculatorLocatorImpl; +import org.solovyev.android.calculator.math.MathType; +import org.solovyev.android.calculator.CalculatorParseException; + +import java.util.Arrays; +import java.util.List; + +/** + * User: serso + * Date: 10/20/11 + * Time: 2:59 PM + */ +public class FromJsclSimplifyTextProcessor implements TextProcessor { + + public static final FromJsclSimplifyTextProcessor instance = new FromJsclSimplifyTextProcessor(); + + public FromJsclSimplifyTextProcessor() { + } + + @NotNull + @Override + public String process(@NotNull Generic from) throws CalculatorParseException { + return removeMultiplicationSigns(from.toString()); + } + + public String process(@NotNull String s) { + return removeMultiplicationSigns(s); + } + + @NotNull + private String removeMultiplicationSigns(String s) { + final StringBuilder sb = new StringBuilder(); + + MathType.Result mathTypeBefore; + MathType.Result mathType = null; + MathType.Result mathTypeAfter = null; + + for (int i = 0; i < s.length(); i++) { + mathTypeBefore = mathType; + if (mathTypeAfter == null) { + mathType = MathType.getType(s, i, false); + } else { + mathType = mathTypeAfter; + } + + char ch = s.charAt(i); + if (ch == '*') { + if (i + 1 < s.length()) { + mathTypeAfter = MathType.getType(s, i + 1, false); + } else { + mathTypeAfter = null; + } + + if (needMultiplicationSign(mathTypeBefore == null ? null : mathTypeBefore.getMathType(), mathTypeAfter == null ? null : mathTypeAfter.getMathType())) { + sb.append(CalculatorLocatorImpl.getInstance().getEngine().getMultiplicationSign()); + } + + } else { + if (mathType.getMathType() == MathType.constant || mathType.getMathType() == MathType.function || mathType.getMathType() == MathType.operator) { + sb.append(mathType.getMatch()); + i += mathType.getMatch().length() - 1; + } else { + sb.append(ch); + } + mathTypeAfter = null; + } + + } + + return sb.toString(); + } + + private final List mathTypes = Arrays.asList(MathType.function, MathType.constant); + + private boolean needMultiplicationSign(@Nullable MathType mathTypeBefore, @Nullable MathType mathTypeAfter) { + if (mathTypeBefore == null || mathTypeAfter == null) { + return true; + } else if (mathTypes.contains(mathTypeBefore) || mathTypes.contains(mathTypeAfter)) { + return false; + } else if ( mathTypeBefore == MathType.close_group_symbol ) { + return false; + } else if ( mathTypeAfter == MathType.open_group_symbol ) { + return false; + } + + return true; + } + +} diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/AndroidCalculator.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/AndroidCalculator.java new file mode 100644 index 00000000..d9b64767 --- /dev/null +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/AndroidCalculator.java @@ -0,0 +1,126 @@ +package org.solovyev.android.calculator; + +import android.app.Activity; +import android.content.SharedPreferences; +import jscl.NumeralBase; +import jscl.math.Generic; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.solovyev.android.calculator.history.CalculatorHistoryState; +import org.solovyev.android.calculator.jscl.JsclOperation; +import org.solovyev.common.history.HistoryAction; + +import java.util.List; + +/** + * User: serso + * Date: 9/22/12 + * Time: 5:42 PM + */ +public class AndroidCalculator implements Calculator { + + @NotNull + private final Calculator calculator = new CalculatorImpl(); + + public void init(@NotNull final Activity activity, @NotNull SharedPreferences preferences) { + final AndroidCalculatorEditorView editorView = (AndroidCalculatorEditorView) activity.findViewById(R.id.calculatorEditor); + editorView.init(preferences); + preferences.registerOnSharedPreferenceChangeListener(editorView); + CalculatorLocatorImpl.getInstance().getEditor().setView(editorView); + + final AndroidCalculatorDisplayView displayView = (AndroidCalculatorDisplayView) activity.findViewById(R.id.calculatorDisplay); + displayView.setOnClickListener(new CalculatorDisplayOnClickListener(activity)); + CalculatorLocatorImpl.getInstance().getDisplay().setView(displayView); + } + + + /* + ********************************************************************** + * + * DELETED TO CALCULATOR + * + ********************************************************************** + */ + + @Override + @NotNull + public CalculatorEventDataId evaluate(@NotNull JsclOperation operation, @NotNull String expression) { + return calculator.evaluate(operation, expression); + } + + @Override + @NotNull + public CalculatorEventDataId evaluate(@NotNull JsclOperation operation, @NotNull String expression, @NotNull Long sequenceId) { + return calculator.evaluate(operation, expression, sequenceId); + } + + @Override + @NotNull + public CalculatorEventDataId convert(@NotNull Generic generic, @NotNull NumeralBase to) { + return calculator.convert(generic, to); + } + + @Override + @NotNull + public CalculatorEventDataId fireCalculatorEvent(@NotNull CalculatorEventType calculatorEventType, @Nullable Object data) { + return calculator.fireCalculatorEvent(calculatorEventType, data); + } + + @Override + @NotNull + public CalculatorEventDataId fireCalculatorEvent(@NotNull CalculatorEventType calculatorEventType, @Nullable Object data, @NotNull Long sequenceId) { + return calculator.fireCalculatorEvent(calculatorEventType, data, sequenceId); + } + + @Override + public void init() { + this.calculator.init(); + } + + @Override + public void addCalculatorEventListener(@NotNull CalculatorEventListener calculatorEventListener) { + calculator.addCalculatorEventListener(calculatorEventListener); + } + + @Override + public void removeCalculatorEventListener(@NotNull CalculatorEventListener calculatorEventListener) { + calculator.removeCalculatorEventListener(calculatorEventListener); + } + + @Override + public void fireCalculatorEvent(@NotNull CalculatorEventData calculatorEventData, @NotNull CalculatorEventType calculatorEventType, @Nullable Object data) { + calculator.fireCalculatorEvent(calculatorEventData, calculatorEventType, data); + } + + @Override + public void fireCalculatorEvents(@NotNull List calculatorEvents) { + calculator.fireCalculatorEvents(calculatorEvents); + } + + @Override + public void doHistoryAction(@NotNull HistoryAction historyAction) { + calculator.doHistoryAction(historyAction); + } + + @Override + public void setCurrentHistoryState(@NotNull CalculatorHistoryState editorHistoryState) { + calculator.setCurrentHistoryState(editorHistoryState); + } + + @Override + @NotNull + public CalculatorHistoryState getCurrentHistoryState() { + return calculator.getCurrentHistoryState(); + } + + @Override + public void evaluate() { + calculator.evaluate(); + } + + @Override + public void simplify() { + calculator.simplify(); + } + +} diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/AndroidCalculatorDisplayView.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/AndroidCalculatorDisplayView.java index c354dbc9..dbe4894f 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/AndroidCalculatorDisplayView.java +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/AndroidCalculatorDisplayView.java @@ -12,7 +12,6 @@ import android.text.Html; import android.util.AttributeSet; import android.util.Log; import org.jetbrains.annotations.NotNull; -import org.solovyev.android.calculator.model.CalculatorEngine; import org.solovyev.android.calculator.text.TextProcessor; import org.solovyev.android.calculator.view.TextHighlighter; import org.solovyev.android.view.AutoResizeTextView; @@ -33,7 +32,7 @@ public class AndroidCalculatorDisplayView extends AutoResizeTextView implements */ @NotNull - private final static TextProcessor textHighlighter = new TextHighlighter(Color.WHITE, false, CalculatorEngine.instance.getEngine()); + private final static TextProcessor textHighlighter = new TextHighlighter(Color.WHITE, false, CalculatorLocatorImpl.getInstance().getEngine().getEngine()); /* ********************************************************************** diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/AndroidCalculatorEditorView.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/AndroidCalculatorEditorView.java index ed432b64..b5f0a676 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/AndroidCalculatorEditorView.java +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/AndroidCalculatorEditorView.java @@ -14,7 +14,6 @@ import android.util.AttributeSet; import android.view.ContextMenu; import android.widget.EditText; import org.jetbrains.annotations.NotNull; -import org.solovyev.android.calculator.model.CalculatorEngine; import org.solovyev.android.calculator.text.TextProcessor; import org.solovyev.android.calculator.view.TextHighlighter; import org.solovyev.common.collections.CollectionsUtils; @@ -32,7 +31,7 @@ public class AndroidCalculatorEditorView extends EditText implements SharedPrefe private boolean highlightText = true; @NotNull - private final static TextProcessor textHighlighter = new TextHighlighter(Color.WHITE, true, CalculatorEngine.instance.getEngine()); + private final static TextProcessor textHighlighter = new TextHighlighter(Color.WHITE, true, CalculatorLocatorImpl.getInstance().getEngine().getEngine()); @NotNull private volatile CalculatorEditorViewState viewState = CalculatorEditorViewStateImpl.newDefaultInstance(); @@ -165,7 +164,7 @@ public class AndroidCalculatorEditorView extends EditText implements SharedPrefe synchronized (this) { if (!viewStateChange) { super.onSelectionChanged(selStart, selEnd); - CalculatorLocatorImpl.getInstance().getCalculatorEditor().setSelection(selStart); + CalculatorLocatorImpl.getInstance().getEditor().setSelection(selStart); } } } 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 4744cc61..ca9d4495 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/CalculatorActivity.java +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/CalculatorActivity.java @@ -34,9 +34,8 @@ 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.AndroidCalculatorHistoryImpl; import org.solovyev.android.calculator.history.CalculatorHistoryState; -import org.solovyev.android.calculator.model.CalculatorEngine; +import org.solovyev.android.calculator.model.AndroidCalculatorEngine; import org.solovyev.android.calculator.view.AngleUnitsButton; import org.solovyev.android.calculator.view.CalculatorAdditionalTitle; import org.solovyev.android.calculator.view.NumeralBasesButton; @@ -74,9 +73,6 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster, Sh @NotNull private final Announcer dpclRegister = new Announcer(DragPreferencesChangeListener.class); - @NotNull - private CalculatorModel calculatorModel; - private volatile boolean initialized; @NotNull @@ -138,8 +134,7 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster, Sh vibrator = (Vibrator) this.getSystemService(VIBRATOR_SERVICE); - AndroidCalculatorHistoryImpl.instance.load(this, preferences); - calculatorModel = CalculatorModel.instance.init(this, preferences); + getCalculator().init(this, preferences); dpclRegister.clear(); @@ -147,7 +142,7 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster, Sh setOnDragListeners(dragPreferences, preferences); - final OnDragListener historyOnDragListener = new OnDragListenerVibrator(newOnDragListener(new HistoryDragProcessor(this.calculatorModel), dragPreferences), vibrator, preferences); + final OnDragListener historyOnDragListener = new OnDragListenerVibrator(newOnDragListener(new HistoryDragProcessor(getCalculator()), dragPreferences), vibrator, preferences); ((DragButton) findViewById(R.id.historyButton)).setOnDragListener(historyOnDragListener); ((DragButton) findViewById(R.id.subtractionButton)).setOnDragListener(new OnDragListenerVibrator(newOnDragListener(new SimpleOnDragListener.DragProcessor() { @@ -162,13 +157,13 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster, Sh }, dragPreferences), vibrator, preferences)); - final OnDragListener toPositionOnDragListener = new OnDragListenerVibrator(new SimpleOnDragListener(new CursorDragProcessor(calculatorModel), dragPreferences), vibrator, preferences); + final OnDragListener toPositionOnDragListener = new OnDragListenerVibrator(new SimpleOnDragListener(new CursorDragProcessor(), dragPreferences), vibrator, preferences); ((DragButton) findViewById(R.id.rightButton)).setOnDragListener(toPositionOnDragListener); ((DragButton) findViewById(R.id.leftButton)).setOnDragListener(toPositionOnDragListener); final DragButton equalsButton = (DragButton) findViewById(R.id.equalsButton); if (equalsButton != null) { - equalsButton.setOnDragListener(new OnDragListenerVibrator(newOnDragListener(new EvalDragProcessor(calculatorModel), dragPreferences), vibrator, preferences)); + equalsButton.setOnDragListener(new OnDragListenerVibrator(newOnDragListener(new EvalDragProcessor(), dragPreferences), vibrator, preferences)); } final AngleUnitsButton angleUnitsButton = (AngleUnitsButton) findViewById(R.id.sixDigitButton); @@ -192,7 +187,7 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster, Sh } - CalculatorEngine.instance.softReset(this, preferences); + getEngine().softReset(); initMultiplicationButton(); @@ -227,6 +222,16 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster, Sh preferences.registerOnSharedPreferenceChangeListener(this); } + @NotNull + private AndroidCalculatorEngine getEngine() { + return ((AndroidCalculatorEngine) CalculatorLocatorImpl.getInstance().getEngine()); + } + + @NotNull + private AndroidCalculator getCalculator() { + return ((AndroidCalculator) CalculatorLocatorImpl.getInstance().getCalculator()); + } + private void fixThemeParameters(boolean fixMagicFlames) { if (theme.getThemeType() == CalculatorPreferences.Gui.ThemeType.metro) { @@ -294,7 +299,7 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster, Sh private class AngleUnitsChanger implements SimpleOnDragListener.DragProcessor { - private final DigitButtonDragProcessor processor = new DigitButtonDragProcessor(CalculatorLocatorImpl.getInstance().getCalculatorKeyboard()); + private final DigitButtonDragProcessor processor = new DigitButtonDragProcessor(getKeyboard()); @Override public boolean processDragEvent(@NotNull DragDirection dragDirection, @@ -313,7 +318,7 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster, Sh final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(CalculatorActivity.this); - CalculatorEngine.Preferences.angleUnit.putPreference(preferences, angleUnits); + AndroidCalculatorEngine.Preferences.angleUnit.putPreference(preferences, angleUnits); Toast.makeText(CalculatorActivity.this, CalculatorActivity.this.getString(R.string.c_angle_units_changed_to, angleUnits.name()), Toast.LENGTH_LONG).show(); @@ -348,7 +353,7 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster, Sh final NumeralBase numeralBase = NumeralBase.valueOf(directionText); final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(CalculatorActivity.this); - CalculatorEngine.Preferences.numeralBase.putPreference(preferences, numeralBase); + AndroidCalculatorEngine.Preferences.numeralBase.putPreference(preferences, numeralBase); Toast.makeText(CalculatorActivity.this, CalculatorActivity.this.getString(R.string.c_numeral_base_changed_to, numeralBase.name()), Toast.LENGTH_LONG).show(); @@ -374,7 +379,7 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster, Sh boolean result = false; if (dragDirection == DragDirection.up) { - CalculatorActivityLauncher.createVar(CalculatorActivity.this, CalculatorActivity.this.calculatorModel); + CalculatorActivityLauncher.createVar(CalculatorActivity.this, CalculatorLocatorImpl.getInstance().getDisplay()); result = true; } @@ -383,7 +388,7 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster, Sh } private synchronized void setOnDragListeners(@NotNull SimpleOnDragListener.Preferences dragPreferences, @NotNull SharedPreferences preferences) { - final OnDragListener onDragListener = new OnDragListenerVibrator(newOnDragListener(new DigitButtonDragProcessor(CalculatorLocatorImpl.getInstance().getCalculatorKeyboard()), dragPreferences), vibrator, preferences); + final OnDragListener onDragListener = new OnDragListenerVibrator(newOnDragListener(new DigitButtonDragProcessor(getKeyboard()), dragPreferences), vibrator, preferences); final List dragButtonIds = new ArrayList(); final List buttonIds = new ArrayList(); @@ -527,7 +532,7 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster, Sh @SuppressWarnings({"UnusedDeclaration"}) public void numericButtonClickHandler(@NotNull View v) { - this.calculatorModel.evaluate(); + getCalculator().evaluate(); } @SuppressWarnings({"UnusedDeclaration"}) @@ -537,7 +542,7 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster, Sh @SuppressWarnings({"UnusedDeclaration"}) public void eraseButtonClickHandler(@NotNull View v) { - CalculatorLocatorImpl.getInstance().getCalculatorEditor().erase(); + CalculatorLocatorImpl.getInstance().getEditor().erase(); } @SuppressWarnings({"UnusedDeclaration"}) @@ -547,34 +552,39 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster, Sh @SuppressWarnings({"UnusedDeclaration"}) public void moveLeftButtonClickHandler(@NotNull View v) { - calculatorModel.moveCursorLeft(); + getKeyboard().moveCursorLeft(); } @SuppressWarnings({"UnusedDeclaration"}) public void moveRightButtonClickHandler(@NotNull View v) { - calculatorModel.moveCursorRight(); + getKeyboard().moveCursorRight(); } @SuppressWarnings({"UnusedDeclaration"}) public void pasteButtonClickHandler(@NotNull View v) { - CalculatorLocatorImpl.getInstance().getCalculatorKeyboard().pasteButtonPressed(); + getKeyboard().pasteButtonPressed(); } @SuppressWarnings({"UnusedDeclaration"}) public void copyButtonClickHandler(@NotNull View v) { - calculatorModel.copyResult(this); + getKeyboard().copyButtonPressed(); } - @SuppressWarnings({"UnusedDeclaration"}) + @NotNull + private static CalculatorKeyboard getKeyboard() { + return CalculatorLocatorImpl.getInstance().getKeyboard(); + } + + @SuppressWarnings({"UnusedDeclaration"}) public void clearButtonClickHandler(@NotNull View v) { - CalculatorLocatorImpl.getInstance().getCalculatorKeyboard().clearButtonPressed(); + getKeyboard().clearButtonPressed(); } @SuppressWarnings({"UnusedDeclaration"}) public void digitButtonClickHandler(@NotNull View v) { Log.d(String.valueOf(v.getId()), "digitButtonClickHandler() for: " + v.getId() + ". Pressed: " + v.isPressed()); if (((ColorButton) v).isShowText()) { - CalculatorLocatorImpl.getInstance().getCalculatorKeyboard().digitButtonPressed(((ColorButton) v).getText().toString()); + getKeyboard().digitButtonPressed(((ColorButton) v).getText().toString()); } } @@ -602,7 +612,7 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster, Sh public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { if (useBackAsPrev) { - calculatorModel.doHistoryAction(HistoryAction.undo); + getCalculator().doHistoryAction(HistoryAction.undo); return true; } } @@ -646,8 +656,7 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster, Sh AndroidUtils.restartActivity(this); } - calculatorModel = CalculatorModel.instance.init(this, preferences); - calculatorModel.evaluate(); + getCalculator().evaluate(); } @Override @@ -665,22 +674,22 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster, Sh dpclRegister.announce().onDragPreferencesChange(SimpleOnDragListener.getPreferences(preferences, this)); } - if (CalculatorEngine.Preferences.getPreferenceKeys().contains(key)) { - CalculatorEngine.instance.softReset(this, preferences); + if (AndroidCalculatorEngine.Preferences.getPreferenceKeys().contains(key)) { + CalculatorLocatorImpl.getInstance().getEngine().softReset(); // reevaluate in order to update values (in case of preferences changed from the main window, like numeral bases and angle units) - this.calculatorModel.evaluate(); + this.getCalculator().evaluate(); } if ( CalculatorPreferences.Gui.usePrevAsBack.getKey().equals(key) ) { useBackAsPrev = CalculatorPreferences.Gui.usePrevAsBack.getPreference(preferences); } - if (CalculatorEngine.Preferences.numeralBase.getKey().equals(key)) { + if (AndroidCalculatorEngine.Preferences.numeralBase.getKey().equals(key)) { numeralBaseButtons.toggleNumericDigits(this, preferences); } - if ( CalculatorEngine.Preferences.multiplicationSign.getKey().equals(key) ) { + if ( AndroidCalculatorEngine.Preferences.multiplicationSign.getKey().equals(key) ) { initMultiplicationButton(); } @@ -720,7 +729,7 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster, Sh @NotNull private AndroidCalculatorDisplayView getCalculatorDisplayView() { - return (AndroidCalculatorDisplayView) calculatorModel.getDisplay().getView(); + return (AndroidCalculatorDisplayView) CalculatorLocatorImpl.getInstance().getDisplay().getView(); } private void toggleOrientationChange(@Nullable SharedPreferences preferences) { @@ -735,7 +744,7 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster, Sh private void initMultiplicationButton() { final View multiplicationButton = findViewById(R.id.multiplicationButton); if ( multiplicationButton instanceof Button) { - ((Button) multiplicationButton).setText(CalculatorEngine.instance.getMultiplicationSign()); + ((Button) multiplicationButton).setText(CalculatorLocatorImpl.getInstance().getEngine().getMultiplicationSign()); } } @@ -745,10 +754,10 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster, Sh final boolean result; if ( dragDirection == DragDirection.left ) { - CalculatorLocatorImpl.getInstance().getCalculatorKeyboard().roundBracketsButtonPressed(); + getKeyboard().roundBracketsButtonPressed(); result = true; } else { - result = new DigitButtonDragProcessor(CalculatorLocatorImpl.getInstance().getCalculatorKeyboard()).processDragEvent(dragDirection, dragButton, startPoint2d, motionEvent); + result = new DigitButtonDragProcessor(getKeyboard()).processDragEvent(dragDirection, dragButton, startPoint2d, motionEvent); } return result; diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/CalculatorActivityLauncher.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/CalculatorActivityLauncher.java index 00cccb3b..b11ace1f 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/CalculatorActivityLauncher.java +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/CalculatorActivityLauncher.java @@ -60,8 +60,8 @@ public class CalculatorActivityLauncher { context.startActivity(intent); } - public static void createVar(@NotNull final Context context, @NotNull CalculatorModel calculatorModel) { - final CalculatorDisplayViewState viewState = calculatorModel.getDisplay().getViewState(); + public static void createVar(@NotNull final Context context, @NotNull CalculatorDisplay calculatorDisplay) { + final CalculatorDisplayViewState viewState = calculatorDisplay.getViewState(); if (viewState.isValid() ) { final String varValue = viewState.getText(); if (!StringUtils.isEmpty(varValue)) { diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/CalculatorApplication.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/CalculatorApplication.java index e3943c1f..120db3ad 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/CalculatorApplication.java +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/CalculatorApplication.java @@ -5,7 +5,6 @@ import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.net.Uri; -import android.preference.PreferenceManager; import android.text.method.LinkMovementMethod; import android.view.LayoutInflater; import android.view.View; @@ -13,7 +12,8 @@ import android.widget.TextView; import net.robotmedia.billing.BillingController; import org.jetbrains.annotations.NotNull; import org.solovyev.android.ads.AdsController; -import org.solovyev.android.calculator.model.CalculatorEngine; +import org.solovyev.android.calculator.history.AndroidCalculatorHistory; +import org.solovyev.android.calculator.model.AndroidCalculatorEngine; /** * User: serso @@ -22,75 +22,78 @@ import org.solovyev.android.calculator.model.CalculatorEngine; */ public class CalculatorApplication extends android.app.Application { - private static final String paypalDonateUrl = "https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=se%2esolovyev%40gmail%2ecom&lc=RU&item_name=Android%20Calculator¤cy_code=USD&bn=PP%2dDonationsBF%3abtn_donateCC_LG%2egif%3aNonHosted"; + private static final String paypalDonateUrl = "https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=se%2esolovyev%40gmail%2ecom&lc=RU&item_name=Android%20Calculator¤cy_code=USD&bn=PP%2dDonationsBF%3abtn_donateCC_LG%2egif%3aNonHosted"; - public static final String AD_FREE_PRODUCT_ID = "ad_free"; - public static final String AD_FREE_P_KEY = "org.solovyev.android.calculator_ad_free"; + public static final String AD_FREE_PRODUCT_ID = "ad_free"; + public static final String AD_FREE_P_KEY = "org.solovyev.android.calculator_ad_free"; - public static final String ADMOB_USER_ID = "a14f02cf9c80cbc"; - public static final String REMOTE_STACK_TRACE_URL = "http://calculatorpp.com/crash_reports/upload.php"; + public static final String ADMOB_USER_ID = "a14f02cf9c80cbc"; + public static final String REMOTE_STACK_TRACE_URL = "http://calculatorpp.com/crash_reports/upload.php"; - @NotNull - private static CalculatorApplication instance; + @NotNull + private static CalculatorApplication instance; - public CalculatorApplication() { - instance = this; - } + public CalculatorApplication() { + instance = this; + } - @NotNull - public static CalculatorApplication getInstance() { - return instance; - } + @NotNull + public static CalculatorApplication getInstance() { + return instance; + } - @Override - public void onCreate() { - super.onCreate(); + @Override + public void onCreate() { + super.onCreate(); - CalculatorLocatorImpl.getInstance().setCalculatorEngine(CalculatorEngine.instance); - CalculatorLocatorImpl.getInstance().setCalculatorNotifier(new AndroidCalculatorNotifier(this)); - CalculatorLocatorImpl.getInstance().setCalculatorClipboard(new AndroidCalculatorClipboard(this)); + final AndroidCalculator calculator = new AndroidCalculator(); - AdsController.getInstance().init(ADMOB_USER_ID, AD_FREE_PRODUCT_ID, new BillingController.IConfiguration() { + CalculatorLocatorImpl.getInstance().init(calculator, + new AndroidCalculatorEngine(this), + new AndroidCalculatorClipboard(this), + new AndroidCalculatorNotifier(this), + new AndroidCalculatorHistory(this, calculator)); - @Override - public byte[] getObfuscationSalt() { - return new byte[]{81, -114, 32, -127, -32, -104, -40, -15, -47, 57, -13, -41, -33, 67, -114, 7, -11, 53, 126, 82}; - } + CalculatorLocatorImpl.getInstance().getCalculator().init(); - @Override - public String getPublicKey() { - return CalculatorSecurity.getPK(); - } - }); + AdsController.getInstance().init(ADMOB_USER_ID, AD_FREE_PRODUCT_ID, new BillingController.IConfiguration() { - CalculatorEngine.instance.init(this, PreferenceManager.getDefaultSharedPreferences(this)); + @Override + public byte[] getObfuscationSalt() { + return new byte[]{81, -114, 32, -127, -32, -104, -40, -15, -47, 57, -13, -41, -33, 67, -114, 7, -11, 53, 126, 82}; + } - } + @Override + public String getPublicKey() { + return CalculatorSecurity.getPK(); + } + }); + } - public static void showDonationDialog(@NotNull final Context context) { - final LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(LAYOUT_INFLATER_SERVICE); - final View view = layoutInflater.inflate(R.layout.donate, null); + public static void showDonationDialog(@NotNull final Context context) { + final LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(LAYOUT_INFLATER_SERVICE); + final View view = layoutInflater.inflate(R.layout.donate, null); - final TextView donate = (TextView) view.findViewById(R.id.donateText); - donate.setMovementMethod(LinkMovementMethod.getInstance()); + final TextView donate = (TextView) view.findViewById(R.id.donateText); + donate.setMovementMethod(LinkMovementMethod.getInstance()); - final AlertDialog.Builder builder = new AlertDialog.Builder(context) - .setCancelable(true) - .setNegativeButton(R.string.c_cancel, null) - .setPositiveButton(R.string.c_donate, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - final Intent i = new Intent(Intent.ACTION_VIEW); - i.setData(Uri.parse(paypalDonateUrl)); - context.startActivity(i); - } - }) - .setView(view); + final AlertDialog.Builder builder = new AlertDialog.Builder(context) + .setCancelable(true) + .setNegativeButton(R.string.c_cancel, null) + .setPositiveButton(R.string.c_donate, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + final Intent i = new Intent(Intent.ACTION_VIEW); + i.setData(Uri.parse(paypalDonateUrl)); + context.startActivity(i); + } + }) + .setView(view); - builder.create().show(); - } + builder.create().show(); + } - public static void registerOnRemoteStackTrace() { - //Thread.setDefaultUncaughtExceptionHandler(new CustomExceptionHandler(null, REMOTE_STACK_TRACE_URL)); - } + public static void registerOnRemoteStackTrace() { + //Thread.setDefaultUncaughtExceptionHandler(new CustomExceptionHandler(null, REMOTE_STACK_TRACE_URL)); + } } diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/CalculatorDisplayMenuItem.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/CalculatorDisplayMenuItem.java index bf433c73..85da915b 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/CalculatorDisplayMenuItem.java +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/CalculatorDisplayMenuItem.java @@ -1,141 +1,140 @@ -package org.solovyev.android.calculator; - -import android.content.Context; -import jscl.math.Generic; -import jscl.math.function.Constant; -import jscl.math.function.IConstant; -import org.jetbrains.annotations.NotNull; -import org.solovyev.android.calculator.jscl.JsclOperation; -import org.solovyev.android.calculator.model.CalculatorEngine; -import org.solovyev.android.calculator.view.NumeralBaseConverterDialog; -import org.solovyev.android.menu.LabeledMenuItem; -import org.solovyev.common.collections.CollectionsUtils; - -import java.util.HashSet; -import java.util.Set; - -/** -* User: Solovyev_S -* Date: 21.09.12 -* Time: 10:55 -*/ -public enum CalculatorDisplayMenuItem implements LabeledMenuItem { - - copy(R.string.c_copy) { - @Override - public void onClick(@NotNull CalculatorDisplayViewState data, @NotNull Context context) { - CalculatorModel.copyResult(context, data); - } - }, - - convert_to_bin(R.string.convert_to_bin) { - @Override - public void onClick(@NotNull CalculatorDisplayViewState data, @NotNull Context context) { - ConversionMenuItem.convert_to_bin.onClick(data, context); - } - - @Override - protected boolean isItemVisibleFor(@NotNull Generic generic, @NotNull JsclOperation operation) { - return ConversionMenuItem.convert_to_bin.isItemVisibleFor(generic, operation); - } - }, - - convert_to_dec(R.string.convert_to_dec) { - @Override - public void onClick(@NotNull CalculatorDisplayViewState data, @NotNull Context context) { - ConversionMenuItem.convert_to_dec.onClick(data, context); - } - - @Override - protected boolean isItemVisibleFor(@NotNull Generic generic, @NotNull JsclOperation operation) { - return ConversionMenuItem.convert_to_dec.isItemVisibleFor(generic, operation); - } - }, - - convert_to_hex(R.string.convert_to_hex) { - @Override - public void onClick(@NotNull CalculatorDisplayViewState data, @NotNull Context context) { - ConversionMenuItem.convert_to_hex.onClick(data, context); - } - - @Override - protected boolean isItemVisibleFor(@NotNull Generic generic, @NotNull JsclOperation operation) { - return ConversionMenuItem.convert_to_hex.isItemVisibleFor(generic, operation); - } - }, - - convert(R.string.c_convert) { - @Override - public void onClick(@NotNull CalculatorDisplayViewState data, @NotNull Context context) { - final Generic result = data.getResult(); - if (result != null) { - new NumeralBaseConverterDialog(result.toString()).show(context); - } - } - - @Override - protected boolean isItemVisibleFor(@NotNull Generic generic, @NotNull JsclOperation operation) { - return operation == JsclOperation.numeric && generic.getConstants().isEmpty(); - } - }, - - plot(R.string.c_plot) { - @Override - public void onClick(@NotNull CalculatorDisplayViewState data, @NotNull Context context) { - final Generic generic = data.getResult(); - assert generic != null; - - final Constant constant = CollectionsUtils.getFirstCollectionElement(getNotSystemConstants(generic)); - assert constant != null; - CalculatorActivityLauncher.plotGraph(context, generic, constant); - } - - @Override - protected boolean isItemVisibleFor(@NotNull Generic generic, @NotNull JsclOperation operation) { - boolean result = false; - - if (operation == JsclOperation.simplify) { - if (getNotSystemConstants(generic).size() == 1) { - result = true; - } - } - - return result; - } - - @NotNull - private Set getNotSystemConstants(@NotNull Generic generic) { - final Set notSystemConstants = new HashSet(); - - for (Constant constant : generic.getConstants()) { - IConstant var = CalculatorEngine.instance.getVarsRegistry().get(constant.getName()); - if (var != null && !var.isSystem() && !var.isDefined()) { - notSystemConstants.add(constant); - } - } - - return notSystemConstants; - } - }; - - private final int captionId; - - CalculatorDisplayMenuItem(int captionId) { - this.captionId = captionId; - } - - public final boolean isItemVisible(@NotNull CalculatorDisplayViewState displayViewState) { - //noinspection ConstantConditions - return displayViewState.isValid() && displayViewState.getResult() != null && isItemVisibleFor(displayViewState.getResult(), displayViewState.getOperation()); - } - - protected boolean isItemVisibleFor(@NotNull Generic generic, @NotNull JsclOperation operation) { - return true; - } - - @NotNull - @Override - public String getCaption(@NotNull Context context) { - return context.getString(captionId); - } -} +package org.solovyev.android.calculator; + +import android.content.Context; +import jscl.math.Generic; +import jscl.math.function.Constant; +import jscl.math.function.IConstant; +import org.jetbrains.annotations.NotNull; +import org.solovyev.android.calculator.jscl.JsclOperation; +import org.solovyev.android.calculator.view.NumeralBaseConverterDialog; +import org.solovyev.android.menu.LabeledMenuItem; +import org.solovyev.common.collections.CollectionsUtils; + +import java.util.HashSet; +import java.util.Set; + +/** +* User: Solovyev_S +* Date: 21.09.12 +* Time: 10:55 +*/ +public enum CalculatorDisplayMenuItem implements LabeledMenuItem { + + copy(R.string.c_copy) { + @Override + public void onClick(@NotNull CalculatorDisplayViewState data, @NotNull Context context) { + CalculatorLocatorImpl.getInstance().getKeyboard().copyButtonPressed(); + } + }, + + convert_to_bin(R.string.convert_to_bin) { + @Override + public void onClick(@NotNull CalculatorDisplayViewState data, @NotNull Context context) { + ConversionMenuItem.convert_to_bin.onClick(data, context); + } + + @Override + protected boolean isItemVisibleFor(@NotNull Generic generic, @NotNull JsclOperation operation) { + return ConversionMenuItem.convert_to_bin.isItemVisibleFor(generic, operation); + } + }, + + convert_to_dec(R.string.convert_to_dec) { + @Override + public void onClick(@NotNull CalculatorDisplayViewState data, @NotNull Context context) { + ConversionMenuItem.convert_to_dec.onClick(data, context); + } + + @Override + protected boolean isItemVisibleFor(@NotNull Generic generic, @NotNull JsclOperation operation) { + return ConversionMenuItem.convert_to_dec.isItemVisibleFor(generic, operation); + } + }, + + convert_to_hex(R.string.convert_to_hex) { + @Override + public void onClick(@NotNull CalculatorDisplayViewState data, @NotNull Context context) { + ConversionMenuItem.convert_to_hex.onClick(data, context); + } + + @Override + protected boolean isItemVisibleFor(@NotNull Generic generic, @NotNull JsclOperation operation) { + return ConversionMenuItem.convert_to_hex.isItemVisibleFor(generic, operation); + } + }, + + convert(R.string.c_convert) { + @Override + public void onClick(@NotNull CalculatorDisplayViewState data, @NotNull Context context) { + final Generic result = data.getResult(); + if (result != null) { + new NumeralBaseConverterDialog(result.toString()).show(context); + } + } + + @Override + protected boolean isItemVisibleFor(@NotNull Generic generic, @NotNull JsclOperation operation) { + return operation == JsclOperation.numeric && generic.getConstants().isEmpty(); + } + }, + + plot(R.string.c_plot) { + @Override + public void onClick(@NotNull CalculatorDisplayViewState data, @NotNull Context context) { + final Generic generic = data.getResult(); + assert generic != null; + + final Constant constant = CollectionsUtils.getFirstCollectionElement(getNotSystemConstants(generic)); + assert constant != null; + CalculatorActivityLauncher.plotGraph(context, generic, constant); + } + + @Override + protected boolean isItemVisibleFor(@NotNull Generic generic, @NotNull JsclOperation operation) { + boolean result = false; + + if (operation == JsclOperation.simplify) { + if (getNotSystemConstants(generic).size() == 1) { + result = true; + } + } + + return result; + } + + @NotNull + private Set getNotSystemConstants(@NotNull Generic generic) { + final Set notSystemConstants = new HashSet(); + + for (Constant constant : generic.getConstants()) { + IConstant var = CalculatorLocatorImpl.getInstance().getEngine().getVarsRegistry().get(constant.getName()); + if (var != null && !var.isSystem() && !var.isDefined()) { + notSystemConstants.add(constant); + } + } + + return notSystemConstants; + } + }; + + private final int captionId; + + CalculatorDisplayMenuItem(int captionId) { + this.captionId = captionId; + } + + public final boolean isItemVisible(@NotNull CalculatorDisplayViewState displayViewState) { + //noinspection ConstantConditions + return displayViewState.isValid() && displayViewState.getResult() != null && isItemVisibleFor(displayViewState.getResult(), displayViewState.getOperation()); + } + + protected boolean isItemVisibleFor(@NotNull Generic generic, @NotNull JsclOperation operation) { + return true; + } + + @NotNull + @Override + public String getCaption(@NotNull Context context) { + return context.getString(captionId); + } +} diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/CalculatorDisplayOnClickListener.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/CalculatorDisplayOnClickListener.java index eb84cc82..213f34d2 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/CalculatorDisplayOnClickListener.java +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/CalculatorDisplayOnClickListener.java @@ -1,53 +1,53 @@ -package org.solovyev.android.calculator; - -import android.app.Activity; -import android.view.View; -import org.jetbrains.annotations.NotNull; -import org.solovyev.android.menu.AMenuBuilder; -import org.solovyev.android.menu.MenuImpl; - -import java.util.ArrayList; -import java.util.List; - -/** - * User: Solovyev_S - * Date: 21.09.12 - * Time: 10:58 - */ -public class CalculatorDisplayOnClickListener implements View.OnClickListener { - - @NotNull - private final Activity activity; - - public CalculatorDisplayOnClickListener(@NotNull Activity activity) { - this.activity = activity; - } - - @Override - public void onClick(View v) { - if (v instanceof CalculatorDisplayView) { - final CalculatorDisplay cd = CalculatorLocatorImpl.getInstance().getCalculatorDisplay(); - - final CalculatorDisplayViewState displayViewState = cd.getViewState(); - - if (displayViewState.isValid()) { - final List filteredMenuItems = new ArrayList(CalculatorDisplayMenuItem.values().length); - for (CalculatorDisplayMenuItem menuItem : CalculatorDisplayMenuItem.values()) { - if (menuItem.isItemVisible(displayViewState)) { - filteredMenuItems.add(menuItem); - } - } - - if (!filteredMenuItems.isEmpty()) { - AMenuBuilder.newInstance(activity, MenuImpl.newInstance(filteredMenuItems)).create(displayViewState).show(); - } - - } else { - final String errorMessage = displayViewState.getErrorMessage(); - if (errorMessage != null) { - CalculatorModel.showEvaluationError(activity, errorMessage); - } - } - } - } -} +package org.solovyev.android.calculator; + +import android.app.Activity; +import android.view.View; +import org.jetbrains.annotations.NotNull; +import org.solovyev.android.menu.AMenuBuilder; +import org.solovyev.android.menu.MenuImpl; + +import java.util.ArrayList; +import java.util.List; + +/** + * User: Solovyev_S + * Date: 21.09.12 + * Time: 10:58 + */ +public class CalculatorDisplayOnClickListener implements View.OnClickListener { + + @NotNull + private final Activity activity; + + public CalculatorDisplayOnClickListener(@NotNull Activity activity) { + this.activity = activity; + } + + @Override + public void onClick(View v) { + if (v instanceof CalculatorDisplayView) { + final CalculatorDisplay cd = CalculatorLocatorImpl.getInstance().getDisplay(); + + final CalculatorDisplayViewState displayViewState = cd.getViewState(); + + if (displayViewState.isValid()) { + final List filteredMenuItems = new ArrayList(CalculatorDisplayMenuItem.values().length); + for (CalculatorDisplayMenuItem menuItem : CalculatorDisplayMenuItem.values()) { + if (menuItem.isItemVisible(displayViewState)) { + filteredMenuItems.add(menuItem); + } + } + + if (!filteredMenuItems.isEmpty()) { + AMenuBuilder.newInstance(activity, MenuImpl.newInstance(filteredMenuItems)).create(displayViewState).show(); + } + + } else { + final String errorMessage = displayViewState.getErrorMessage(); + if (errorMessage != null) { + CalculatorModel.showEvaluationError(activity, errorMessage); + } + } + } + } +} 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 b4edb0a9..5c06ae0c 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/CalculatorModel.java +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/CalculatorModel.java @@ -7,32 +7,24 @@ package org.solovyev.android.calculator; import android.app.Activity; import android.app.AlertDialog; -import android.content.Context; import android.content.SharedPreferences; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.widget.TextView; import org.jetbrains.annotations.NotNull; -import org.solovyev.android.CursorControl; -import org.solovyev.android.calculator.history.AndroidCalculatorHistoryImpl; -import org.solovyev.android.calculator.history.CalculatorHistoryState; import org.solovyev.android.calculator.jscl.JsclOperation; -import org.solovyev.android.history.HistoryControl; -import org.solovyev.common.history.HistoryAction; +import org.solovyev.common.gui.CursorControl; /** * User: serso * Date: 9/12/11 * Time: 11:15 PM */ -public enum CalculatorModel implements HistoryControl, CalculatorEngineControl, CursorControl { +public enum CalculatorModel implements CalculatorEngineControl, CursorControl { instance; - // millis to wait before evaluation after user edit action - public static final int EVAL_DELAY_MILLIS = 0; - @NotNull private final CalculatorEditor editor; @@ -40,11 +32,11 @@ public enum CalculatorModel implements HistoryControl, C private final CalculatorDisplay display; private CalculatorModel() { - display = CalculatorLocatorImpl.getInstance().getCalculatorDisplay(); - editor = CalculatorLocatorImpl.getInstance().getCalculatorEditor(); + display = CalculatorLocatorImpl.getInstance().getDisplay(); + editor = CalculatorLocatorImpl.getInstance().getEditor(); } - public CalculatorModel init(@NotNull final Activity activity, @NotNull SharedPreferences preferences) { + public CalculatorModel attachViews(@NotNull final Activity activity, @NotNull SharedPreferences preferences) { Log.d(this.getClass().getName(), "CalculatorModel initialization with activity: " + activity); final AndroidCalculatorEditorView editorView = (AndroidCalculatorEditorView) activity.findViewById(R.id.calculatorEditor); @@ -72,19 +64,6 @@ public enum CalculatorModel implements HistoryControl, C builder.create().show(); } - public void copyResult(@NotNull Context context) { - copyResult(context, display.getViewState()); - } - - public static void copyResult(@NotNull Context context, - @NotNull final CalculatorDisplayViewState viewState) { - CalculatorLocatorImpl.getInstance().getCalculatorKeyboard().copyButtonPressed(); - } - - private void saveHistoryState() { - AndroidCalculatorHistoryImpl.instance.addState(getCurrentHistoryState()); - } - @Override public void setCursorOnStart() { this.editor.setCursorOnStart(); @@ -115,34 +94,6 @@ public enum CalculatorModel implements HistoryControl, C CalculatorLocatorImpl.getInstance().getCalculator().evaluate(JsclOperation.simplify, this.editor.getViewState().getText()); } - @Override - public void doHistoryAction(@NotNull HistoryAction historyAction) { - synchronized (AndroidCalculatorHistoryImpl.instance) { - if (AndroidCalculatorHistoryImpl.instance.isActionAvailable(historyAction)) { - final CalculatorHistoryState newState = AndroidCalculatorHistoryImpl.instance.doAction(historyAction, getCurrentHistoryState()); - if (newState != null) { - setCurrentHistoryState(newState); - } - } - } - } - - @Override - public void setCurrentHistoryState(@NotNull CalculatorHistoryState editorHistoryState) { - synchronized (AndroidCalculatorHistoryImpl.instance) { - Log.d(this.getClass().getName(), "Saved history found: " + editorHistoryState); - - editorHistoryState.setValuesFromHistory(this.editor, this.display); - } - } - - @Override - @NotNull - public CalculatorHistoryState getCurrentHistoryState() { - synchronized (AndroidCalculatorHistoryImpl.instance) { - return CalculatorHistoryState.newInstance(this.editor, display); - } - } @NotNull public CalculatorDisplay getDisplay() { diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/CalculatorPreferences.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/CalculatorPreferences.java index 5dd13993..ba48b4ed 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/CalculatorPreferences.java +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/CalculatorPreferences.java @@ -4,7 +4,7 @@ import android.content.SharedPreferences; import org.jetbrains.annotations.NotNull; import org.solovyev.android.AndroidUtils; import org.solovyev.android.calculator.math.MathType; -import org.solovyev.android.calculator.model.CalculatorEngine; +import org.solovyev.android.calculator.model.AndroidCalculatorEngine; import org.solovyev.android.prefs.BooleanPreference; import org.solovyev.android.prefs.IntegerPreference; import org.solovyev.android.prefs.Preference; @@ -93,7 +93,7 @@ public final class CalculatorPreferences { } static void setDefaultValues(@NotNull SharedPreferences preferences) { - if (!CalculatorEngine.Preferences.groupingSeparator.isSet(preferences)) { + if (!AndroidCalculatorEngine.Preferences.groupingSeparator.isSet(preferences)) { final Locale locale = Locale.getDefault(); if (locale != null) { final DecimalFormatSymbols decimalFormatSymbols = new DecimalFormatSymbols(locale); @@ -105,22 +105,22 @@ public final class CalculatorPreferences { groupingSeparator = " "; } - CalculatorEngine.Preferences.groupingSeparator.putPreference(preferences, groupingSeparator); + AndroidCalculatorEngine.Preferences.groupingSeparator.putPreference(preferences, groupingSeparator); } } - if (!CalculatorEngine.Preferences.angleUnit.isSet(preferences)) { - CalculatorEngine.Preferences.angleUnit.putDefault(preferences); + if (!AndroidCalculatorEngine.Preferences.angleUnit.isSet(preferences)) { + AndroidCalculatorEngine.Preferences.angleUnit.putDefault(preferences); } - if (!CalculatorEngine.Preferences.numeralBase.isSet(preferences)) { - CalculatorEngine.Preferences.numeralBase.putDefault(preferences); + if (!AndroidCalculatorEngine.Preferences.numeralBase.isSet(preferences)) { + AndroidCalculatorEngine.Preferences.numeralBase.putDefault(preferences); } - if (!CalculatorEngine.Preferences.multiplicationSign.isSet(preferences)) { + if (!AndroidCalculatorEngine.Preferences.multiplicationSign.isSet(preferences)) { if ( AndroidUtils.isPhoneModel(AndroidUtils.PhoneModel.samsung_galaxy_s) || AndroidUtils.isPhoneModel(AndroidUtils.PhoneModel.samsung_galaxy_s_2) ) { // workaround ofr samsung galaxy s phones - CalculatorEngine.Preferences.multiplicationSign.putPreference(preferences, "*"); + AndroidCalculatorEngine.Preferences.multiplicationSign.putPreference(preferences, "*"); } } } diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/CalculatorPreferencesActivity.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/CalculatorPreferencesActivity.java index 120ff351..3962a2d4 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/CalculatorPreferencesActivity.java +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/CalculatorPreferencesActivity.java @@ -23,7 +23,7 @@ import net.robotmedia.billing.model.Transaction; import org.jetbrains.annotations.NotNull; import org.solovyev.android.AndroidUtils; import org.solovyev.android.ads.AdsController; -import org.solovyev.android.calculator.model.CalculatorEngine; +import org.solovyev.android.calculator.model.AndroidCalculatorEngine; import org.solovyev.android.view.VibratorContainer; /** @@ -51,7 +51,7 @@ public class CalculatorPreferencesActivity extends PreferenceActivity implements final SharedPreferences preferences = getPreferenceManager().getSharedPreferences(); preferences.registerOnSharedPreferenceChangeListener(this); - onSharedPreferenceChanged(preferences, CalculatorEngine.Preferences.roundResult.getKey()); + onSharedPreferenceChanged(preferences, AndroidCalculatorEngine.Preferences.roundResult.getKey()); onSharedPreferenceChanged(preferences, VibratorContainer.Preferences.hapticFeedbackEnabled.getKey()); final Preference clearBillingInfoPreference = findPreference(CLEAR_BILLING_INFO); @@ -128,8 +128,8 @@ public class CalculatorPreferencesActivity extends PreferenceActivity implements @Override public void onSharedPreferenceChanged(SharedPreferences preferences, String key) { - if (CalculatorEngine.Preferences.roundResult.getKey().equals(key)) { - findPreference(CalculatorEngine.Preferences.precision.getKey()).setEnabled(preferences.getBoolean(key, CalculatorEngine.Preferences.roundResult.getDefaultValue())); + if (AndroidCalculatorEngine.Preferences.roundResult.getKey().equals(key)) { + findPreference(AndroidCalculatorEngine.Preferences.precision.getKey()).setEnabled(preferences.getBoolean(key, AndroidCalculatorEngine.Preferences.roundResult.getDefaultValue())); } else if (VibratorContainer.Preferences.hapticFeedbackEnabled.getKey().equals(key)) { findPreference(VibratorContainer.Preferences.hapticFeedbackDuration.getKey()).setEnabled(VibratorContainer.Preferences.hapticFeedbackEnabled.getPreference(preferences)); } diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/ConversionMenuItem.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/ConversionMenuItem.java index d67ea9c1..e2ead0e1 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/ConversionMenuItem.java +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/ConversionMenuItem.java @@ -5,7 +5,6 @@ import jscl.NumeralBase; import jscl.math.Generic; import org.jetbrains.annotations.NotNull; import org.solovyev.android.calculator.jscl.JsclOperation; -import org.solovyev.android.calculator.model.CalculatorEngine; import org.solovyev.android.menu.AMenuItem; /** @@ -43,7 +42,7 @@ enum ConversionMenuItem implements AMenuItem { @Override public void onClick(@NotNull CalculatorDisplayViewState data, @NotNull Context context) { - final NumeralBase fromNumeralBase = CalculatorEngine.instance.getEngine().getNumeralBase(); + final NumeralBase fromNumeralBase = CalculatorLocatorImpl.getInstance().getEngine().getEngine().getNumeralBase(); final Generic lastResult = data.getResult(); diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/CursorDragProcessor.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/CursorDragProcessor.java index 2a7f62cf..967e8a71 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/CursorDragProcessor.java +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/CursorDragProcessor.java @@ -7,11 +7,10 @@ package org.solovyev.android.calculator; import android.view.MotionEvent; import org.jetbrains.annotations.NotNull; -import org.solovyev.android.CursorControl; -import org.solovyev.android.view.drag.DragDirection; -import org.solovyev.android.view.drag.SimpleOnDragListener; import org.solovyev.android.view.drag.DirectionDragButton; import org.solovyev.android.view.drag.DragButton; +import org.solovyev.android.view.drag.DragDirection; +import org.solovyev.android.view.drag.SimpleOnDragListener; import org.solovyev.common.math.Point2d; /** @@ -21,11 +20,7 @@ import org.solovyev.common.math.Point2d; */ public class CursorDragProcessor implements SimpleOnDragListener.DragProcessor{ - @NotNull - private final CursorControl cursorControl; - - public CursorDragProcessor(@NotNull CursorControl cursorControl) { - this.cursorControl = cursorControl; + public CursorDragProcessor() { } @Override @@ -35,10 +30,10 @@ public class CursorDragProcessor implements SimpleOnDragListener.DragProcessor{ if (dragButton instanceof DirectionDragButton) { String text = ((DirectionDragButton) dragButton).getText(dragDirection); if ("◀◀".equals(text)) { - cursorControl.setCursorOnStart(); + CalculatorLocatorImpl.getInstance().getEditor().setCursorOnStart(); result = true; } else if ("▶▶".equals(text)) { - cursorControl.setCursorOnEnd(); + CalculatorLocatorImpl.getInstance().getEditor().setCursorOnEnd(); result = true; } } diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/EvalDragProcessor.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/EvalDragProcessor.java index 7efb1c6f..a105fea5 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/EvalDragProcessor.java +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/EvalDragProcessor.java @@ -20,11 +20,8 @@ import org.solovyev.common.math.Point2d; * Time: 9:52 PM */ public class EvalDragProcessor implements SimpleOnDragListener.DragProcessor { - @NotNull - private final CalculatorEngineControl calculatorControl; - public EvalDragProcessor(@NotNull CalculatorEngineControl calculatorControl) { - this.calculatorControl = calculatorControl; + public EvalDragProcessor() { } @Override @@ -34,7 +31,7 @@ public class EvalDragProcessor implements SimpleOnDragListener.DragProcessor { if (dragButton instanceof DirectionDragButton) { String text = ((DirectionDragButton) dragButton).getText(dragDirection); if ("≡".equals(text)) { - calculatorControl.simplify(); + CalculatorLocatorImpl.getInstance().getCalculator().simplify(); result = true; } } diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/NumeralBaseButtons.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/NumeralBaseButtons.java index ffc6b4d7..0fcf82a5 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/NumeralBaseButtons.java +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/NumeralBaseButtons.java @@ -4,7 +4,7 @@ import android.app.Activity; import android.content.SharedPreferences; import jscl.NumeralBase; import org.jetbrains.annotations.NotNull; -import org.solovyev.android.calculator.model.CalculatorEngine; +import org.solovyev.android.calculator.model.AndroidCalculatorEngine; /** * User: serso @@ -25,7 +25,7 @@ public class NumeralBaseButtons { public synchronized void toggleNumericDigits(@NotNull Activity activity, @NotNull SharedPreferences preferences) { if (CalculatorPreferences.Gui.hideNumeralBaseDigits.getPreference(preferences)) { - final NumeralBase nb = CalculatorEngine.Preferences.numeralBase.getPreference(preferences); + final NumeralBase nb = AndroidCalculatorEngine.Preferences.numeralBase.getPreference(preferences); this.toggleNumericDigits(activity, nb); } else { // set HEX to show all digits diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/history/AbstractHistoryActivity.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/history/AbstractHistoryActivity.java index 5ac85fc5..649687f1 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/history/AbstractHistoryActivity.java +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/history/AbstractHistoryActivity.java @@ -156,7 +156,7 @@ public abstract class AbstractHistoryActivity extends ListActivity { boolean result = false; try { historyState.setSaved(true); - if ( CollectionsUtils.contains(historyState, AndroidCalculatorHistoryImpl.instance.getSavedHistory(), new Equalizer() { + if ( CollectionsUtils.contains(historyState, CalculatorLocatorImpl.getInstance().getHistory().getSavedHistory(), new Equalizer() { @Override public boolean equals(@Nullable CalculatorHistoryState first, @Nullable CalculatorHistoryState second) { return first != null && second != null && @@ -175,7 +175,7 @@ public abstract class AbstractHistoryActivity extends ListActivity { public static void useHistoryItem(@NotNull final CalculatorHistoryState historyState, @NotNull AbstractHistoryActivity activity) { final EditorHistoryState editorState = historyState.getEditorState(); - CalculatorLocatorImpl.getInstance().getCalculatorEditor().setText(StringUtils.getNotEmpty(editorState.getText(), ""), editorState.getCursorPosition()); + CalculatorLocatorImpl.getInstance().getEditor().setText(StringUtils.getNotEmpty(editorState.getText(), ""), editorState.getCursorPosition()); activity.finish(); } 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 index 2f4dc4b4..6ccf8932 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/history/AndroidCalculatorHistory.java +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/history/AndroidCalculatorHistory.java @@ -1,18 +1,149 @@ -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); -} +/* + * 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.Application; +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.*; +import org.solovyev.common.history.HistoryAction; + +import java.util.List; + +/** + * User: serso + * Date: 10/9/11 + * Time: 6:35 PM + */ +public class AndroidCalculatorHistory implements CalculatorHistory { + + @NotNull + private final CalculatorHistoryImpl calculatorHistory; + + @NotNull + private final Context context; + + public AndroidCalculatorHistory(@NotNull Application application, @NotNull Calculator calculator) { + this.context = application; + calculatorHistory = new CalculatorHistoryImpl(calculator); + } + + @Override + public void load() { + final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context); + if (preferences != null) { + final String value = preferences.getString(context.getString(R.string.p_calc_history), null); + if (value != null) { + calculatorHistory.fromXml(value); + } + } + } + + public void save() { + 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() { + calculatorHistory.clearSavedHistory(); + save(); + } + + public void removeSavedHistory(@NotNull CalculatorHistoryState historyState) { + historyState.setSaved(false); + calculatorHistory.removeSavedHistory(historyState); + save(); + } + + @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 onCalculatorEvent(@NotNull CalculatorEventData calculatorEventData, @NotNull CalculatorEventType calculatorEventType, @Nullable Object data) { + calculatorHistory.onCalculatorEvent(calculatorEventData, calculatorEventType, data); + } +} 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 deleted file mode 100644 index 7f280841..00000000 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/history/AndroidCalculatorHistoryImpl.java +++ /dev/null @@ -1,154 +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.CalculatorEventData; -import org.solovyev.android.calculator.CalculatorEventType; -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); - if (value != 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); - } - - @Override - public void onCalculatorEvent(@NotNull CalculatorEventData calculatorEventData, @NotNull CalculatorEventType calculatorEventType, @Nullable Object data) { - calculatorHistory.onCalculatorEvent(calculatorEventData, calculatorEventType, data); - } -} 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 73f67340..22715d94 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,38 @@ -/* - * 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(); - } -} +/* + * 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.CalculatorLocatorImpl; +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(CalculatorLocatorImpl.getInstance().getHistory().getStates()); + } + + @Override + protected void clearHistory() { + CalculatorLocatorImpl.getInstance().getHistory().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 7cb1c859..9d716715 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,155 @@ -/* - * 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); - } -} +/* + * 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.CalculatorLocatorImpl; +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); + CalculatorLocatorImpl.getInstance().getHistory().removeSavedHistory(historyState); + 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 = CalculatorLocatorImpl.getInstance().getHistory().addSavedState(historyState); + savedHistoryItem.setComment(comment.getText().toString()); + CalculatorLocatorImpl.getInstance().getHistory().save(); + // 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()); + CalculatorLocatorImpl.getInstance().getHistory().save(); + } + 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 6113c89d..60a697ba 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,38 @@ -/* - * 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(); - } -} +/* + * 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.CalculatorLocatorImpl; +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(CalculatorLocatorImpl.getInstance().getHistory().getSavedHistory()); + } + + @Override + protected void clearHistory() { + CalculatorLocatorImpl.getInstance().getHistory().clearSavedHistory(); + getAdapter().clear(); + } +} diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/math/edit/AbstractMathEntityListActivity.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/math/edit/AbstractMathEntityListActivity.java index 158eebb3..36b414f9 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/math/edit/AbstractMathEntityListActivity.java +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/math/edit/AbstractMathEntityListActivity.java @@ -21,7 +21,7 @@ import org.jetbrains.annotations.Nullable; import org.solovyev.android.ads.AdsController; import org.solovyev.android.calculator.CalculatorLocatorImpl; import org.solovyev.android.calculator.R; -import org.solovyev.android.calculator.model.AndroidMathRegistry; +import org.solovyev.android.calculator.CalculatorMathRegistry; import org.solovyev.android.menu.AMenuBuilder; import org.solovyev.android.menu.LabeledMenuItem; import org.solovyev.android.menu.MenuImpl; @@ -106,7 +106,7 @@ public abstract class AbstractMathEntityListActivity exten final int position, final long id) { - CalculatorLocatorImpl.getInstance().getCalculatorKeyboard().digitButtonPressed(((MathEntity) parent.getItemAtPosition(position)).getName()); + CalculatorLocatorImpl.getInstance().getKeyboard().digitButtonPressed(((MathEntity) parent.getItemAtPosition(position)).getName()); AbstractMathEntityListActivity.this.finish(); } @@ -238,15 +238,15 @@ public abstract class AbstractMathEntityListActivity exten protected static class MathEntityDescriptionGetterImpl implements MathEntityDescriptionGetter { @NotNull - private final AndroidMathRegistry mathRegistry; + private final CalculatorMathRegistry mathRegistry; - public MathEntityDescriptionGetterImpl(@NotNull AndroidMathRegistry mathRegistry) { + public MathEntityDescriptionGetterImpl(@NotNull CalculatorMathRegistry mathRegistry) { this.mathRegistry = mathRegistry; } @Override public String getDescription(@NotNull Context context, @NotNull String mathEntityName) { - return this.mathRegistry.getDescription(context, mathEntityName); + return this.mathRegistry.getDescription(mathEntityName); } } diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/math/edit/CalculatorFunctionsActivity.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/math/edit/CalculatorFunctionsActivity.java index 2b374c6d..e54705a9 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/math/edit/CalculatorFunctionsActivity.java +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/math/edit/CalculatorFunctionsActivity.java @@ -14,7 +14,6 @@ import jscl.math.function.Function; import org.jetbrains.annotations.NotNull; import org.solovyev.android.calculator.CalculatorLocatorImpl; import org.solovyev.android.calculator.R; -import org.solovyev.android.calculator.model.CalculatorEngine; import org.solovyev.android.menu.LabeledMenuItem; import org.solovyev.common.text.StringUtils; @@ -33,7 +32,7 @@ public class CalculatorFunctionsActivity extends AbstractMathEntityListActivity< use(R.string.c_use) { @Override public void onClick(@NotNull Function data, @NotNull Context context) { - CalculatorLocatorImpl.getInstance().getCalculatorKeyboard().digitButtonPressed(data.getName()); + CalculatorLocatorImpl.getInstance().getKeyboard().digitButtonPressed(data.getName()); if (context instanceof Activity) { ((Activity) context).finish(); } @@ -51,7 +50,7 @@ public class CalculatorFunctionsActivity extends AbstractMathEntityListActivity< copy_description(R.string.c_copy_description) { @Override public void onClick(@NotNull Function data, @NotNull Context context) { - final String text = CalculatorEngine.instance.getFunctionsRegistry().getDescription(context, data.getName()); + final String text = CalculatorLocatorImpl.getInstance().getEngine().getFunctionsRegistry().getDescription(data.getName()); if (!StringUtils.isEmpty(text)) { final ClipboardManager clipboard = (ClipboardManager) context.getSystemService(Activity.CLIPBOARD_SERVICE); clipboard.setText(text); @@ -110,7 +109,7 @@ public class CalculatorFunctionsActivity extends AbstractMathEntityListActivity< protected List> getMenuItemsOnLongClick(@NotNull Function item) { List> result = new ArrayList>(Arrays.asList(LongClickMenuItem.values())); - if ( StringUtils.isEmpty(CalculatorEngine.instance.getFunctionsRegistry().getDescription(this, item.getName())) ) { + if ( StringUtils.isEmpty(CalculatorLocatorImpl.getInstance().getEngine().getFunctionsRegistry().getDescription(item.getName())) ) { result.remove(LongClickMenuItem.copy_description); } @@ -206,17 +205,17 @@ public class CalculatorFunctionsActivity extends AbstractMathEntityListActivity< @NotNull @Override protected MathEntityDescriptionGetter getDescriptionGetter() { - return new MathEntityDescriptionGetterImpl(CalculatorEngine.instance.getFunctionsRegistry()); + return new MathEntityDescriptionGetterImpl(CalculatorLocatorImpl.getInstance().getEngine().getFunctionsRegistry()); } @NotNull @Override protected List getMathEntities() { - return new ArrayList(CalculatorEngine.instance.getFunctionsRegistry().getEntities()); + return new ArrayList(CalculatorLocatorImpl.getInstance().getEngine().getFunctionsRegistry().getEntities()); } @Override protected String getMathEntityCategory(@NotNull Function function) { - return CalculatorEngine.instance.getFunctionsRegistry().getCategory(function); + return CalculatorLocatorImpl.getInstance().getEngine().getFunctionsRegistry().getCategory(function); } } diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/math/edit/CalculatorOperatorsActivity.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/math/edit/CalculatorOperatorsActivity.java index c431e685..cafb35ab 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/math/edit/CalculatorOperatorsActivity.java +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/math/edit/CalculatorOperatorsActivity.java @@ -7,7 +7,6 @@ import jscl.math.operator.Operator; import org.jetbrains.annotations.NotNull; import org.solovyev.android.calculator.CalculatorLocatorImpl; import org.solovyev.android.calculator.R; -import org.solovyev.android.calculator.model.CalculatorEngine; import org.solovyev.android.menu.LabeledMenuItem; import org.solovyev.common.text.StringUtils; @@ -28,7 +27,7 @@ public class CalculatorOperatorsActivity extends AbstractMathEntityListActivity< use(R.string.c_use) { @Override public void onClick(@NotNull Operator data, @NotNull Context context) { - CalculatorLocatorImpl.getInstance().getCalculatorKeyboard().digitButtonPressed(data.getName()); + CalculatorLocatorImpl.getInstance().getKeyboard().digitButtonPressed(data.getName()); if (context instanceof Activity) { ((Activity) context).finish(); } @@ -82,17 +81,17 @@ public class CalculatorOperatorsActivity extends AbstractMathEntityListActivity< protected List getMathEntities() { final List result = new ArrayList(); - result.addAll(CalculatorEngine.instance.getOperatorsRegistry().getEntities()); - result.addAll(CalculatorEngine.instance.getPostfixFunctionsRegistry().getEntities()); + result.addAll(CalculatorLocatorImpl.getInstance().getEngine().getOperatorsRegistry().getEntities()); + result.addAll(CalculatorLocatorImpl.getInstance().getEngine().getPostfixFunctionsRegistry().getEntities()); return result; } @Override protected String getMathEntityCategory(@NotNull Operator operator) { - String result = CalculatorEngine.instance.getOperatorsRegistry().getCategory(operator); + String result = CalculatorLocatorImpl.getInstance().getEngine().getOperatorsRegistry().getCategory(operator); if (result == null) { - result = CalculatorEngine.instance.getPostfixFunctionsRegistry().getCategory(operator); + result = CalculatorLocatorImpl.getInstance().getEngine().getPostfixFunctionsRegistry().getCategory(operator); } return result; @@ -104,9 +103,9 @@ public class CalculatorOperatorsActivity extends AbstractMathEntityListActivity< @Override public String getDescription(@NotNull Context context, @NotNull String mathEntityName) { - String result = CalculatorEngine.instance.getOperatorsRegistry().getDescription(context, mathEntityName); + String result = CalculatorLocatorImpl.getInstance().getEngine().getOperatorsRegistry().getDescription(mathEntityName); if (StringUtils.isEmpty(result)) { - result = CalculatorEngine.instance.getPostfixFunctionsRegistry().getDescription(context, mathEntityName); + result = CalculatorLocatorImpl.getInstance().getEngine().getPostfixFunctionsRegistry().getDescription(mathEntityName); } return result; diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/math/edit/CalculatorVarsActivity.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/math/edit/CalculatorVarsActivity.java index 18275fce..f680f507 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/math/edit/CalculatorVarsActivity.java +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/math/edit/CalculatorVarsActivity.java @@ -24,7 +24,6 @@ import org.jetbrains.annotations.Nullable; import org.solovyev.android.calculator.CalculatorLocatorImpl; import org.solovyev.android.calculator.R; import org.solovyev.android.calculator.math.MathType; -import org.solovyev.android.calculator.model.CalculatorEngine; import org.solovyev.android.calculator.model.Var; import org.solovyev.android.menu.LabeledMenuItem; import org.solovyev.common.JPredicate; @@ -46,7 +45,7 @@ public class CalculatorVarsActivity extends AbstractMathEntityListActivity(data, null, CalculatorEngine.instance.getVarsRegistry(), ((AbstractMathEntityListActivity) context)).showConfirmationDialog(); + new MathEntityRemover(data, null, CalculatorLocatorImpl.getInstance().getEngine().getVarsRegistry(), ((AbstractMathEntityListActivity) context)).showConfirmationDialog(); } } }, @@ -85,7 +84,7 @@ public class CalculatorVarsActivity extends AbstractMathEntityListActivity getMathEntities() { - final List result = new ArrayList(CalculatorEngine.instance.getVarsRegistry().getEntities()); + final List result = new ArrayList(CalculatorLocatorImpl.getInstance().getEngine().getVarsRegistry().getEntities()); CollectionsUtils.removeAll(result, new JPredicate() { @Override @@ -177,7 +176,7 @@ public class CalculatorVarsActivity extends AbstractMathEntityListActivity activity, @@ -234,7 +233,7 @@ public class CalculatorVarsActivity extends AbstractMathEntityListActivity(varBuilder, var, editView, activity, CalculatorEngine.instance.getVarsRegistry(), new VarEditorSaver.EditorCreator() { + .setPositiveButton(R.string.c_save, new VarEditorSaver(varBuilder, var, editView, activity, CalculatorLocatorImpl.getInstance().getEngine().getVarsRegistry(), new VarEditorSaver.EditorCreator() { @Override public void showEditor(@NotNull AbstractMathEntityListActivity activity, @Nullable IConstant editedInstance, @Nullable String name, @Nullable String value, @Nullable String description) { createEditVariableDialog(activity, editedInstance, name, value, description); @@ -251,7 +250,7 @@ public class CalculatorVarsActivity extends AbstractMathEntityListActivity mathRegistry; + private final CalculatorMathRegistry mathRegistry; @NotNull private final AbstractMathEntityListActivity activity; @@ -64,7 +64,7 @@ public class FunctionEditorSaver implements DialogInterface.OnClickListener{ @Nullable CustomFunction editedInstance, @NotNull View editView, @NotNull AbstractMathEntityListActivity activity, - @NotNull AndroidMathRegistry mathRegistry, + @NotNull CalculatorMathRegistry mathRegistry, @NotNull EditorCreator editorCreator) { this.varBuilder = varBuilder; this.editedInstance = editedInstance; @@ -145,7 +145,7 @@ public class FunctionEditorSaver implements DialogInterface.OnClickListener{ activity.addToAdapter(addedVar); } - mathRegistry.save(activity); + mathRegistry.save(); if (activity.isInCategory(addedVar)) { activity.sort(); @@ -160,7 +160,7 @@ public class FunctionEditorSaver implements DialogInterface.OnClickListener{ if (!StringUtils.isEmpty(name)) { try { assert name != null; - Identifier.parser.parse(Parser.Parameters.newInstance(name, new MutableInt(0), CalculatorEngine.instance.getEngine()), null); + Identifier.parser.parse(Parser.Parameters.newInstance(name, new MutableInt(0), CalculatorLocatorImpl.getInstance().getEngine().getEngine()), null); result = true; } catch (ParseException e) { // not valid name; diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/math/edit/MathEntityRemover.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/math/edit/MathEntityRemover.java index 060c7da8..4e4370cb 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/math/edit/MathEntityRemover.java +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/math/edit/MathEntityRemover.java @@ -12,7 +12,7 @@ import android.widget.TextView; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.solovyev.android.calculator.R; -import org.solovyev.android.calculator.model.AndroidMathRegistry; +import org.solovyev.android.calculator.CalculatorMathRegistry; import org.solovyev.common.math.MathEntity; /** @@ -31,14 +31,14 @@ class MathEntityRemover implements DialogInterface.OnClick private final boolean confirmed; @NotNull - private final AndroidMathRegistry varsRegistry; + private final CalculatorMathRegistry varsRegistry; @NotNull private final AbstractMathEntityListActivity activity; public MathEntityRemover(@NotNull T mathEntity, @Nullable DialogInterface.OnClickListener callbackOnCancel, - @NotNull AndroidMathRegistry varsRegistry, + @NotNull CalculatorMathRegistry varsRegistry, @NotNull AbstractMathEntityListActivity activity) { this(mathEntity, callbackOnCancel, false, varsRegistry, activity); } @@ -46,7 +46,7 @@ class MathEntityRemover implements DialogInterface.OnClick public MathEntityRemover(@NotNull T mathEntity, @Nullable DialogInterface.OnClickListener callbackOnCancel, boolean confirmed, - @NotNull AndroidMathRegistry varsRegistry, + @NotNull CalculatorMathRegistry varsRegistry, @NotNull AbstractMathEntityListActivity activity) { this.mathEntity = mathEntity; this.callbackOnCancel = callbackOnCancel; @@ -65,7 +65,7 @@ class MathEntityRemover implements DialogInterface.OnClick } varsRegistry.remove(mathEntity); - varsRegistry.save(activity); + varsRegistry.save(); if (activity.isInCategory(mathEntity)) { activity.notifyAdapter(); } diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/math/edit/VarEditorSaver.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/math/edit/VarEditorSaver.java index 7755b8ba..dae332b8 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/math/edit/VarEditorSaver.java +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/math/edit/VarEditorSaver.java @@ -16,10 +16,10 @@ import jscl.text.ParseException; import jscl.text.Parser; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.solovyev.android.calculator.CalculatorLocatorImpl; +import org.solovyev.android.calculator.CalculatorMathRegistry; import org.solovyev.android.calculator.R; import org.solovyev.android.calculator.math.MathType; -import org.solovyev.android.calculator.model.AndroidMathRegistry; -import org.solovyev.android.calculator.model.CalculatorEngine; import org.solovyev.android.calculator.model.MathEntityBuilder; import org.solovyev.common.math.MathEntity; import org.solovyev.common.text.StringUtils; @@ -49,7 +49,7 @@ class VarEditorSaver implements DialogInterface.OnClickLis private final T editedInstance; @NotNull - private final AndroidMathRegistry mathRegistry; + private final CalculatorMathRegistry mathRegistry; @NotNull private final AbstractMathEntityListActivity activity; @@ -61,7 +61,7 @@ class VarEditorSaver implements DialogInterface.OnClickLis @Nullable T editedInstance, @NotNull View editView, @NotNull AbstractMathEntityListActivity activity, - @NotNull AndroidMathRegistry mathRegistry, + @NotNull CalculatorMathRegistry mathRegistry, @NotNull EditorCreator editorCreator) { this.varBuilder = varBuilder; this.editedInstance = editedInstance; @@ -142,7 +142,7 @@ class VarEditorSaver implements DialogInterface.OnClickLis activity.addToAdapter(addedVar); } - mathRegistry.save(activity); + mathRegistry.save(); if (activity.isInCategory(addedVar)) { activity.sort(); @@ -157,7 +157,7 @@ class VarEditorSaver implements DialogInterface.OnClickLis if (!StringUtils.isEmpty(name)) { try { assert name != null; - Identifier.parser.parse(Parser.Parameters.newInstance(name, new MutableInt(0), CalculatorEngine.instance.getEngine()), null); + Identifier.parser.parse(Parser.Parameters.newInstance(name, new MutableInt(0), CalculatorLocatorImpl.getInstance().getEngine().getEngine()), null); result = true; } catch (ParseException e) { // not valid name; diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/model/AbstractAndroidMathRegistry.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/model/AbstractAndroidMathRegistry.java index 7b5c9bc6..914c0853 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/model/AbstractAndroidMathRegistry.java +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/model/AbstractAndroidMathRegistry.java @@ -6,6 +6,7 @@ package org.solovyev.android.calculator.model; +import android.app.Application; import android.content.Context; import android.content.SharedPreferences; import android.preference.PreferenceManager; @@ -13,6 +14,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.simpleframework.xml.Serializer; import org.simpleframework.xml.core.Persister; +import org.solovyev.android.calculator.CalculatorMathRegistry; import org.solovyev.android.calculator.R; import org.solovyev.android.calculator.about.TextHelper; import org.solovyev.common.JBuilder; @@ -28,7 +30,7 @@ import java.util.Map; * Date: 10/30/11 * Time: 1:03 AM */ -public abstract class AbstractAndroidMathRegistry implements AndroidMathRegistry { +public abstract class AbstractAndroidMathRegistry implements CalculatorMathRegistry { @NotNull private final MathRegistry mathRegistry; @@ -36,17 +38,25 @@ public abstract class AbstractAndroidMathRegistry mathRegistry, @NotNull String prefix) { + @NotNull + private final Context context; + + protected AbstractAndroidMathRegistry(@NotNull MathRegistry mathRegistry, + @NotNull String prefix, + @NotNull Application application) { this.mathRegistry = mathRegistry; this.prefix = prefix; + this.context = application; } - @NotNull + + + @NotNull protected abstract Map getSubstitutes(); @Nullable @Override - public String getDescription(@NotNull Context context, @NotNull String mathEntityName) { + public String getDescription(@NotNull String mathEntityName) { final String stringName; final Map substitutes = getSubstitutes(); @@ -60,9 +70,10 @@ public abstract class AbstractAndroidMathRegistry preprocessor = ToJsclTextProcessor.getInstance(); @NotNull - private final AndroidMathRegistry varsRegistry = new AndroidVarsRegistryImpl(engine.getConstantsRegistry()); + private final CalculatorMathRegistry varsRegistry; @NotNull - private final AndroidMathRegistry functionsRegistry = new AndroidFunctionsMathRegistry(engine.getFunctionsRegistry()); + private final CalculatorMathRegistry functionsRegistry; @NotNull - private final AndroidMathRegistry operatorsRegistry = new AndroidOperatorsMathRegistry(engine.getOperatorsRegistry()); + private final CalculatorMathRegistry operatorsRegistry; - private final AndroidMathRegistry postfixFunctionsRegistry = new AndroidPostfixFunctionsRegistry(engine.getPostfixFunctionsRegistry()); + private final CalculatorMathRegistry postfixFunctionsRegistry; @Nullable private ThreadKiller threadKiller = new AndroidThreadKiller(); @@ -127,10 +127,20 @@ public enum CalculatorEngine implements JCalculatorEngine { @NotNull private String multiplicationSign = MULTIPLICATION_SIGN_DEFAULT; - CalculatorEngine() { + @NotNull + private final Context context; + + public AndroidCalculatorEngine(@NotNull Application application) { + this.context = application; + this.engine.setRoundResult(true); this.engine.setUseGroupingSeparator(true); - } + + this.varsRegistry = new AndroidVarsRegistryImpl(engine.getConstantsRegistry(), application); + this.functionsRegistry = new AndroidFunctionsMathRegistry(engine.getFunctionsRegistry(), application); + this.operatorsRegistry = new AndroidOperatorsMathRegistry(engine.getOperatorsRegistry(), application); + this.postfixFunctionsRegistry = new AndroidPostfixFunctionsRegistry(engine.getPostfixFunctionsRegistry(), application); + } @Override @NotNull @@ -273,47 +283,54 @@ public enum CalculatorEngine implements JCalculatorEngine { this.getEngine().setRoundResult(roundResult); } - public void init(@Nullable Context context, @Nullable SharedPreferences preferences) { + @Override + public void init() { synchronized (lock) { - reset(context, preferences); + reset(); } } - public void reset(@Nullable Context context, @Nullable SharedPreferences preferences) { + @Override + public void reset() { synchronized (lock) { - softReset(context, preferences); + final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context); - varsRegistry.load(context, preferences); - functionsRegistry.load(context, preferences); - operatorsRegistry.load(context, preferences); - postfixFunctionsRegistry.load(context, preferences); + softReset(preferences); + + varsRegistry.load(); + functionsRegistry.load(); + operatorsRegistry.load(); + postfixFunctionsRegistry.load(); } } - public void softReset(@Nullable Context context, @Nullable SharedPreferences preferences) { + @Override + public void softReset() { synchronized (lock) { - if (preferences != null) { - this.setPrecision(Preferences.precision.getPreference(preferences)); - this.setRoundResult(Preferences.roundResult.getPreference(preferences)); - this.setAngleUnits(getAngleUnitsFromPrefs(preferences)); - this.setNumeralBase(getNumeralBaseFromPrefs(preferences)); - this.setMultiplicationSign(Preferences.multiplicationSign.getPreference(preferences)); - this.setScienceNotation(Preferences.scienceNotation.getPreference(preferences)); - this.setTimeout(Preferences.maxCalculationTime.getPreference(preferences)); - - final String groupingSeparator = Preferences.groupingSeparator.getPreference(preferences); - if (StringUtils.isEmpty(groupingSeparator)) { - this.getEngine().setUseGroupingSeparator(false); - } else { - this.getEngine().setUseGroupingSeparator(true); - this.getEngine().setGroupingSeparator(groupingSeparator.charAt(0)); - } - } + softReset(PreferenceManager.getDefaultSharedPreferences(context)); } } + private void softReset(@NotNull SharedPreferences preferences) { + this.setPrecision(Preferences.precision.getPreference(preferences)); + this.setRoundResult(Preferences.roundResult.getPreference(preferences)); + this.setAngleUnits(getAngleUnitsFromPrefs(preferences)); + this.setNumeralBase(getNumeralBaseFromPrefs(preferences)); + this.setMultiplicationSign(Preferences.multiplicationSign.getPreference(preferences)); + this.setScienceNotation(Preferences.scienceNotation.getPreference(preferences)); + this.setTimeout(Preferences.maxCalculationTime.getPreference(preferences)); - @NotNull + final String groupingSeparator = Preferences.groupingSeparator.getPreference(preferences); + if (StringUtils.isEmpty(groupingSeparator)) { + this.getEngine().setUseGroupingSeparator(false); + } else { + this.getEngine().setUseGroupingSeparator(true); + this.getEngine().setGroupingSeparator(groupingSeparator.charAt(0)); + } + } + + + @NotNull public NumeralBase getNumeralBaseFromPrefs(@NotNull SharedPreferences preferences) { return Preferences.numeralBase.getPreference(preferences); } @@ -332,25 +349,25 @@ public enum CalculatorEngine implements JCalculatorEngine { @Override @NotNull - public AndroidMathRegistry getVarsRegistry() { + public CalculatorMathRegistry getVarsRegistry() { return varsRegistry; } @Override @NotNull - public AndroidMathRegistry getFunctionsRegistry() { + public CalculatorMathRegistry getFunctionsRegistry() { return functionsRegistry; } @Override @NotNull - public AndroidMathRegistry getOperatorsRegistry() { + public CalculatorMathRegistry getOperatorsRegistry() { return operatorsRegistry; } @Override @NotNull - public AndroidMathRegistry getPostfixFunctionsRegistry() { + public CalculatorMathRegistry getPostfixFunctionsRegistry() { return postfixFunctionsRegistry; } diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/model/AndroidFunctionsMathRegistry.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/model/AndroidFunctionsMathRegistry.java index 33bfd7c9..6570398d 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/model/AndroidFunctionsMathRegistry.java +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/model/AndroidFunctionsMathRegistry.java @@ -6,11 +6,9 @@ package org.solovyev.android.calculator.model; -import android.content.Context; -import android.content.SharedPreferences; +import android.app.Application; import jscl.math.function.*; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import org.solovyev.android.calculator.R; import org.solovyev.common.JBuilder; import org.solovyev.common.collections.CollectionsUtils; @@ -115,13 +113,14 @@ public class AndroidFunctionsMathRegistry extends AbstractAndroidMathRegistry functionsRegistry) { - super(functionsRegistry, FUNCTION_DESCRIPTION_PREFIX); + public AndroidFunctionsMathRegistry(@NotNull MathRegistry functionsRegistry, + @NotNull Application application) { + super(functionsRegistry, FUNCTION_DESCRIPTION_PREFIX, application); } @Override - public void load(@Nullable Context context, @Nullable SharedPreferences preferences) { - super.load(context, preferences); + public void load() { + super.load(); add(new CustomFunction.Builder(true, "log", new String[]{"base", "x"}, "ln(x)/ln(base)")); } diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/model/AndroidOperatorsMathRegistry.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/model/AndroidOperatorsMathRegistry.java index d7092ff6..ca73ad28 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/model/AndroidOperatorsMathRegistry.java +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/model/AndroidOperatorsMathRegistry.java @@ -6,11 +6,9 @@ package org.solovyev.android.calculator.model; -import android.content.Context; -import android.content.SharedPreferences; +import android.app.Application; import jscl.math.operator.Operator; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import org.solovyev.common.JBuilder; import org.solovyev.common.math.MathRegistry; @@ -38,8 +36,9 @@ public class AndroidOperatorsMathRegistry extends AbstractAndroidMathRegistry functionsRegistry) { - super(functionsRegistry, OPERATOR_DESCRIPTION_PREFIX); + protected AndroidOperatorsMathRegistry(@NotNull MathRegistry functionsRegistry, + @NotNull Application application) { + super(functionsRegistry, OPERATOR_DESCRIPTION_PREFIX, application); } @NotNull @@ -54,7 +53,7 @@ public class AndroidOperatorsMathRegistry extends AbstractAndroidMathRegistry functionsRegistry) { - super(functionsRegistry, POSTFIX_FUNCTION_DESCRIPTION_PREFIX); + protected AndroidPostfixFunctionsRegistry(@NotNull MathRegistry functionsRegistry, + @NotNull Application application) { + super(functionsRegistry, POSTFIX_FUNCTION_DESCRIPTION_PREFIX, application); } @@ -53,7 +52,7 @@ public class AndroidPostfixFunctionsRegistry extends AbstractAndroidMathRegistry } @Override - public void load(@Nullable Context context, @Nullable SharedPreferences preferences) { + public void load() { // not supported yet } @@ -75,7 +74,7 @@ public class AndroidPostfixFunctionsRegistry extends AbstractAndroidMathRegistry } @Override - public void save(@NotNull Context context) { + public void save() { // not supported yet } diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/model/AndroidVarsRegistryImpl.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/model/AndroidVarsRegistryImpl.java index 26f64dfc..4783d2ec 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/model/AndroidVarsRegistryImpl.java +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/model/AndroidVarsRegistryImpl.java @@ -6,11 +6,9 @@ package org.solovyev.android.calculator.model; -import android.content.Context; -import android.content.SharedPreferences; +import android.app.Application; import jscl.math.function.IConstant; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import org.solovyev.android.calculator.R; import org.solovyev.common.JBuilder; import org.solovyev.common.math.MathRegistry; @@ -35,8 +33,9 @@ class AndroidVarsRegistryImpl extends AbstractAndroidMathRegistry mathRegistry) { - super(mathRegistry, "c_var_description_"); + protected AndroidVarsRegistryImpl(@NotNull MathRegistry mathRegistry, + @NotNull Application application) { + super(mathRegistry, "c_var_description_", application); } @NotNull @@ -45,8 +44,8 @@ class AndroidVarsRegistryImpl extends AbstractAndroidMathRegistry fromUnits, @NotNull Unit toUnits) { String toUnitsValue = toUnits.getValue(); - if (!toUnits.getUnitType().equals(AndroidNumeralBase.valueOf(CalculatorEngine.instance.getEngine().getNumeralBase()))) { + if (!toUnits.getUnitType().equals(AndroidNumeralBase.valueOf(CalculatorLocatorImpl.getInstance().getEngine().getEngine().getNumeralBase()))) { toUnitsValue = ((AndroidNumeralBase) toUnits.getUnitType()).getNumeralBase().getJsclPrefix() + toUnitsValue; } - CalculatorLocatorImpl.getInstance().getCalculatorKeyboard().digitButtonPressed(toUnitsValue); + CalculatorLocatorImpl.getInstance().getKeyboard().digitButtonPressed(toUnitsValue); final AlertDialog alertDialog = alertDialogHolder.getObject(); if (alertDialog != null) { alertDialog.dismiss(); diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/view/NumeralBasesButton.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/view/NumeralBasesButton.java index 6afac4fe..fed468d3 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/view/NumeralBasesButton.java +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/view/NumeralBasesButton.java @@ -12,8 +12,8 @@ import android.graphics.Paint; import android.text.TextPaint; import android.util.AttributeSet; import org.jetbrains.annotations.NotNull; +import org.solovyev.android.calculator.CalculatorLocatorImpl; import org.solovyev.android.calculator.R; -import org.solovyev.android.calculator.model.CalculatorEngine; import org.solovyev.android.view.drag.DirectionDragButton; /** @@ -34,7 +34,7 @@ public class NumeralBasesButton extends DirectionDragButton { super.initDirectionTextPaint(basePaint, directionTextData, resources); final TextPaint directionTextPaint = directionTextData.getPaint(); - if (CalculatorEngine.instance.getEngine().getNumeralBase().name().equals(directionTextData.getText())) { + if (CalculatorLocatorImpl.getInstance().getEngine().getEngine().getNumeralBase().name().equals(directionTextData.getText())) { directionTextPaint.setColor(resources.getColor(R.color.selected_angle_unit_text_color)); } else { directionTextPaint.setColor(resources.getColor(R.color.default_text_color)); 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 c5ad71b9..f10c402f 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 @@ -1,243 +1,239 @@ -/* - * 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.view; - -import jscl.MathContext; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.solovyev.android.calculator.AbstractNumberBuilder; -import org.solovyev.android.calculator.CalculatorParseException; -import org.solovyev.android.calculator.LiteNumberBuilder; -import org.solovyev.android.calculator.NumberBuilder; -import org.solovyev.android.calculator.math.MathType; -import org.solovyev.android.calculator.model.*; -import org.solovyev.android.calculator.text.TextProcessor; -import org.solovyev.common.MutableObject; - -import java.util.HashMap; -import java.util.Map; - -/** - * User: serso - * Date: 10/12/11 - * Time: 9:47 PM - */ -public class TextHighlighter implements TextProcessor { - - private static final Map nbFontAttributes = new HashMap(); - - static { - nbFontAttributes.put("color", "#008000"); - } - - @NotNull - public final MathContext mathContext; - - public static class Result implements CharSequence { - - @NotNull - private final String string; - - private final int offset; - - public Result(@NotNull String string, int offset) { - this.string = string; - this.offset = offset; - } - - @Override - public int length() { - return string.length(); - } - - @Override - public char charAt(int i) { - return string.charAt(i); - } - - @Override - public CharSequence subSequence(int i, int i1) { - return string.subSequence(i, i1); - } - - @Override - public String toString() { - return string; - } - - public int getOffset() { - return offset; - } - } - - private final int color; - private final int colorRed; - private final int colorGreen; - private final int colorBlue; - private final boolean formatNumber; - - public TextHighlighter(int baseColor, boolean formatNumber, @NotNull MathContext mathContext) { - this.color = baseColor; - this.formatNumber = formatNumber; - this.mathContext = mathContext; - //this.colorRed = Color.red(baseColor); - this.colorRed = (baseColor >> 16) & 0xFF; - //this.colorGreen = Color.green(baseColor); - this.colorGreen = (color >> 8) & 0xFF; - //this.colorBlue = Color.blue(baseColor); - this.colorBlue = color & 0xFF; - } - - @NotNull - @Override - public Result process(@NotNull String text) throws CalculatorParseException { - final String result; - - int maxNumberOfOpenGroupSymbols = 0; - int numberOfOpenGroupSymbols = 0; - - final StringBuilder text1 = new StringBuilder(); - - int resultOffset = 0; - - final AbstractNumberBuilder numberBuilder; - if (!formatNumber) { - numberBuilder = new LiteNumberBuilder(CalculatorEngine.instance.getEngine()); - } else { - numberBuilder = new NumberBuilder(CalculatorEngine.instance.getEngine()); - } - for (int i = 0; i < text.length(); i++) { - MathType.Result mathType = MathType.getType(text, i, numberBuilder.isHexMode()); - - if (numberBuilder instanceof NumberBuilder) { - final MutableObject numberOffset = new MutableObject(0); - ((NumberBuilder) numberBuilder).process(text1, mathType, numberOffset); - resultOffset += numberOffset.getObject(); - } else { - ((LiteNumberBuilder) numberBuilder).process(mathType); - } - - final String match = mathType.getMatch(); - switch (mathType.getMathType()) { - case open_group_symbol: - numberOfOpenGroupSymbols++; - maxNumberOfOpenGroupSymbols = Math.max(maxNumberOfOpenGroupSymbols, numberOfOpenGroupSymbols); - text1.append(text.charAt(i)); - break; - case close_group_symbol: - numberOfOpenGroupSymbols--; - text1.append(text.charAt(i)); - break; - case operator: - text1.append(match); - if (match.length() > 1) { - i += match.length() - 1; - } - break; - case function: - i = processHighlightedText(text1, i, match, "i", null); - break; - case constant: - i = processHighlightedText(text1, i, match, "b", null); - break; - case numeral_base: - i = processHighlightedText(text1, i, match, "b", null); - break; - default: - if (mathType.getMathType() == MathType.text || match.length() <= 1) { - text1.append(text.charAt(i)); - } else { - text1.append(match); - i += match.length() - 1; - } - } - } - - if (numberBuilder instanceof NumberBuilder) { - final MutableObject numberOffset = new MutableObject(0); - ((NumberBuilder) numberBuilder).processNumber(text1, numberOffset); - resultOffset += numberOffset.getObject(); - } - - if (maxNumberOfOpenGroupSymbols > 0) { - - final StringBuilder text2 = new StringBuilder(); - - String s = text1.toString(); - int i = processBracketGroup(text2, s, 0, 0, maxNumberOfOpenGroupSymbols); - for (; i < s.length(); i++) { - text2.append(s.charAt(i)); - } - - //Log.d(AndroidCalculatorEditorView.class.getName(), text2.toString()); - - result = text2.toString(); - } else { - result = text1.toString(); - } - - return new Result(result, resultOffset); - } - - private int processHighlightedText(@NotNull StringBuilder result, int i, @NotNull String match, @NotNull String tag, @Nullable Map tagAttributes) { - result.append("<").append(tag); - - if (tagAttributes != null) { - for (Map.Entry entry : tagAttributes.entrySet()) { - // attr1="attr1_value" attr2="attr2_value" - result.append(" ").append(entry.getKey()).append("=\"").append(entry.getValue()).append("\""); - } - } - - result.append(">").append(match).append(""); - if (match.length() > 1) { - return i + match.length() - 1; - } else { - return i; - } - } - - private int processBracketGroup(@NotNull StringBuilder result, @NotNull String s, int i, int numberOfOpenings, int maxNumberOfGroups) { - - result.append(""); - - for (; i < s.length(); i++) { - char ch = s.charAt(i); - - if (MathType.open_group_symbol.getTokens().contains(String.valueOf(ch))) { - result.append(ch); - result.append(""); - i = processBracketGroup(result, s, i + 1, numberOfOpenings + 1, maxNumberOfGroups); - result.append(""); - if (i < s.length() && MathType.close_group_symbol.getTokens().contains(String.valueOf(s.charAt(i)))) { - result.append(s.charAt(i)); - } - } else if (MathType.close_group_symbol.getTokens().contains(String.valueOf(ch))) { - break; - } else { - result.append(ch); - } - } - - result.append(""); - - - return i; - } - - private String getColor(int totalNumberOfOpenings, int numberOfOpenings) { - double c = 0.8; - - int offset = ((int) (255 * c)) * numberOfOpenings / (totalNumberOfOpenings + 1); - - // for tests: - // innt result = Color.rgb(BASE_COLOUR_RED_COMPONENT - offset, BASE_COLOUR_GREEN_COMPONENT - offset, BASE_COLOUR_BLUE_COMPONENT - offset); - int result = (0xFF << 24) | ((colorRed - offset) << 16) | ((colorGreen - offset) << 8) | (colorBlue - offset); - - return "#" + Integer.toHexString(result).substring(2); - } -} +/* + * 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.view; + +import jscl.MathContext; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.solovyev.android.calculator.*; +import org.solovyev.android.calculator.math.MathType; +import org.solovyev.android.calculator.text.TextProcessor; +import org.solovyev.common.MutableObject; + +import java.util.HashMap; +import java.util.Map; + +/** + * User: serso + * Date: 10/12/11 + * Time: 9:47 PM + */ +public class TextHighlighter implements TextProcessor { + + private static final Map nbFontAttributes = new HashMap(); + + static { + nbFontAttributes.put("color", "#008000"); + } + + @NotNull + public final MathContext mathContext; + + public static class Result implements CharSequence { + + @NotNull + private final String string; + + private final int offset; + + public Result(@NotNull String string, int offset) { + this.string = string; + this.offset = offset; + } + + @Override + public int length() { + return string.length(); + } + + @Override + public char charAt(int i) { + return string.charAt(i); + } + + @Override + public CharSequence subSequence(int i, int i1) { + return string.subSequence(i, i1); + } + + @Override + public String toString() { + return string; + } + + public int getOffset() { + return offset; + } + } + + private final int color; + private final int colorRed; + private final int colorGreen; + private final int colorBlue; + private final boolean formatNumber; + + public TextHighlighter(int baseColor, boolean formatNumber, @NotNull MathContext mathContext) { + this.color = baseColor; + this.formatNumber = formatNumber; + this.mathContext = mathContext; + //this.colorRed = Color.red(baseColor); + this.colorRed = (baseColor >> 16) & 0xFF; + //this.colorGreen = Color.green(baseColor); + this.colorGreen = (color >> 8) & 0xFF; + //this.colorBlue = Color.blue(baseColor); + this.colorBlue = color & 0xFF; + } + + @NotNull + @Override + public Result process(@NotNull String text) throws CalculatorParseException { + final String result; + + int maxNumberOfOpenGroupSymbols = 0; + int numberOfOpenGroupSymbols = 0; + + final StringBuilder text1 = new StringBuilder(); + + int resultOffset = 0; + + final AbstractNumberBuilder numberBuilder; + if (!formatNumber) { + numberBuilder = new LiteNumberBuilder(CalculatorLocatorImpl.getInstance().getEngine().getEngine()); + } else { + numberBuilder = new NumberBuilder(CalculatorLocatorImpl.getInstance().getEngine().getEngine()); + } + for (int i = 0; i < text.length(); i++) { + MathType.Result mathType = MathType.getType(text, i, numberBuilder.isHexMode()); + + if (numberBuilder instanceof NumberBuilder) { + final MutableObject numberOffset = new MutableObject(0); + ((NumberBuilder) numberBuilder).process(text1, mathType, numberOffset); + resultOffset += numberOffset.getObject(); + } else { + ((LiteNumberBuilder) numberBuilder).process(mathType); + } + + final String match = mathType.getMatch(); + switch (mathType.getMathType()) { + case open_group_symbol: + numberOfOpenGroupSymbols++; + maxNumberOfOpenGroupSymbols = Math.max(maxNumberOfOpenGroupSymbols, numberOfOpenGroupSymbols); + text1.append(text.charAt(i)); + break; + case close_group_symbol: + numberOfOpenGroupSymbols--; + text1.append(text.charAt(i)); + break; + case operator: + text1.append(match); + if (match.length() > 1) { + i += match.length() - 1; + } + break; + case function: + i = processHighlightedText(text1, i, match, "i", null); + break; + case constant: + i = processHighlightedText(text1, i, match, "b", null); + break; + case numeral_base: + i = processHighlightedText(text1, i, match, "b", null); + break; + default: + if (mathType.getMathType() == MathType.text || match.length() <= 1) { + text1.append(text.charAt(i)); + } else { + text1.append(match); + i += match.length() - 1; + } + } + } + + if (numberBuilder instanceof NumberBuilder) { + final MutableObject numberOffset = new MutableObject(0); + ((NumberBuilder) numberBuilder).processNumber(text1, numberOffset); + resultOffset += numberOffset.getObject(); + } + + if (maxNumberOfOpenGroupSymbols > 0) { + + final StringBuilder text2 = new StringBuilder(); + + String s = text1.toString(); + int i = processBracketGroup(text2, s, 0, 0, maxNumberOfOpenGroupSymbols); + for (; i < s.length(); i++) { + text2.append(s.charAt(i)); + } + + //Log.d(AndroidCalculatorEditorView.class.getName(), text2.toString()); + + result = text2.toString(); + } else { + result = text1.toString(); + } + + return new Result(result, resultOffset); + } + + private int processHighlightedText(@NotNull StringBuilder result, int i, @NotNull String match, @NotNull String tag, @Nullable Map tagAttributes) { + result.append("<").append(tag); + + if (tagAttributes != null) { + for (Map.Entry entry : tagAttributes.entrySet()) { + // attr1="attr1_value" attr2="attr2_value" + result.append(" ").append(entry.getKey()).append("=\"").append(entry.getValue()).append("\""); + } + } + + result.append(">").append(match).append(""); + if (match.length() > 1) { + return i + match.length() - 1; + } else { + return i; + } + } + + private int processBracketGroup(@NotNull StringBuilder result, @NotNull String s, int i, int numberOfOpenings, int maxNumberOfGroups) { + + result.append(""); + + for (; i < s.length(); i++) { + char ch = s.charAt(i); + + if (MathType.open_group_symbol.getTokens().contains(String.valueOf(ch))) { + result.append(ch); + result.append(""); + i = processBracketGroup(result, s, i + 1, numberOfOpenings + 1, maxNumberOfGroups); + result.append(""); + if (i < s.length() && MathType.close_group_symbol.getTokens().contains(String.valueOf(s.charAt(i)))) { + result.append(s.charAt(i)); + } + } else if (MathType.close_group_symbol.getTokens().contains(String.valueOf(ch))) { + break; + } else { + result.append(ch); + } + } + + result.append(""); + + + return i; + } + + private String getColor(int totalNumberOfOpenings, int numberOfOpenings) { + double c = 0.8; + + int offset = ((int) (255 * c)) * numberOfOpenings / (totalNumberOfOpenings + 1); + + // for tests: + // innt result = Color.rgb(BASE_COLOUR_RED_COMPONENT - offset, BASE_COLOUR_GREEN_COMPONENT - offset, BASE_COLOUR_BLUE_COMPONENT - offset); + int result = (0xFF << 24) | ((colorRed - offset) << 16) | ((colorGreen - offset) << 8) | (colorBlue - offset); + + return "#" + Integer.toHexString(result).substring(2); + } +} diff --git a/calculatorpp/src/test/java/org/solovyev/android/calculator/TextHighlighterTest.java b/calculatorpp/src/test/java/org/solovyev/android/calculator/TextHighlighterTest.java index af984177..2551e4e7 100644 --- a/calculatorpp/src/test/java/org/solovyev/android/calculator/TextHighlighterTest.java +++ b/calculatorpp/src/test/java/org/solovyev/android/calculator/TextHighlighterTest.java @@ -1,137 +1,136 @@ -/* - * 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.JsclMathEngine; -import jscl.MathEngine; -import jscl.NumeralBase; -import junit.framework.Assert; -import org.junit.Test; -import org.solovyev.android.calculator.model.CalculatorEngine; -import org.solovyev.android.calculator.text.TextProcessor; -import org.solovyev.android.calculator.view.TextHighlighter; - -import java.util.Date; -import java.util.Random; - -/** - * User: serso - * Date: 10/12/11 - * Time: 10:07 PM - */ -public class TextHighlighterTest { - - @Test - public void testProcess() throws Exception { - TextProcessor textHighlighter = new TextHighlighter(0, false, JsclMathEngine.instance); - - final Random random = new Random(new Date().getTime()); - for (int i = 0; i < 1000; i++) { - final StringBuilder sb = new StringBuilder(); - for (int j = 0; j < 1000; j++) { - sb.append(random.nextBoolean() ? "(" : ")"); - } - try { - textHighlighter.process(sb.toString()); - } catch (Exception e) { - System.out.println(sb.toString()); - throw e; - } - } - - Assert.assertEquals(")(((())())", textHighlighter.process(")(((())())").toString()); - Assert.assertEquals(")", textHighlighter.process(")").toString()); - Assert.assertEquals(")()(", textHighlighter.process(")()(").toString()); - - textHighlighter = new TextHighlighter(0, true, JsclMathEngine.instance); - Assert.assertEquals("1 000 000", textHighlighter.process("1000000").toString()); - Assert.assertEquals("1 000 000", textHighlighter.process("1000000").toString()); - Assert.assertEquals("0.1E3", textHighlighter.process("0.1E3").toString()); - Assert.assertEquals("1E3", textHighlighter.process("1E3").toString()); - Assert.assertEquals("20x:", textHighlighter.process("20x:").toString()); - Assert.assertEquals("20g", textHighlighter.process("20g").toString()); - Assert.assertEquals("22g", textHighlighter.process("22g").toString()); - Assert.assertEquals("20ю", textHighlighter.process("20ю").toString()); - Assert.assertEquals("20ъ", textHighlighter.process("20ъ").toString()); - Assert.assertEquals("3!!", textHighlighter.process("3!!").toString()); - Assert.assertEquals("2", textHighlighter.process("2").toString()); - Assert.assertEquals("21", textHighlighter.process("21").toString()); - Assert.assertEquals("214", textHighlighter.process("214").toString()); - Assert.assertEquals("2 145", textHighlighter.process("2 145").toString()); - Assert.assertEquals("1 000 000E3", textHighlighter.process("1000000E3").toString()); - Assert.assertEquals("-1 000 000E3", textHighlighter.process("-1000000E3").toString()); - Assert.assertEquals("-1 000 000E-3", textHighlighter.process("-1000000E-3").toString()); - Assert.assertEquals("-1 000 000E-30000", textHighlighter.process("-1000000E-30000").toString()); - textHighlighter = new TextHighlighter(0, false, JsclMathEngine.instance); - - textHighlighter.process("cannot calculate 3^10^10 !!!\n" + - " unable to enter 0. FIXED\n" + - " empty display in Xperia Rayo\n" + - " check привиденная FIXED\n" + - " set display result only if text in editor was not changed FIXED\n" + - " shift M text to the left\n" + - " do not show SYNTAX ERROR always (may be show send clock?q) FIXED\n" + - " ln(8)*log(8) => ln(8)*og(8) FIXED\n" + - " copy/paste ln(8)*log(8)\n" + - " 6!^2 ERROR"); - - Assert.assertEquals("sin(2)", textHighlighter.process("sin(2)").toString()); - Assert.assertEquals("atanh(2)", textHighlighter.process("atanh(2)").toString()); - - - Assert.assertEquals("0x:E", textHighlighter.process("0x:E").toString()); - Assert.assertEquals("0x:6F", textHighlighter.process("0x:6F").toString()); - Assert.assertEquals("0x:6F.", textHighlighter.process("0x:6F.").toString()); - Assert.assertEquals("0x:6F.2", textHighlighter.process("0x:6F.2").toString()); - Assert.assertEquals("0x:6F.B", textHighlighter.process("0x:6F.B").toString()); - Assert.assertEquals("0x:006F.B", textHighlighter.process("0x:006F.B").toString()); - Assert.assertEquals("0x:0", textHighlighter.process("0x:0").toString()); - Assert.assertEquals("0x:FF33233FFE", textHighlighter.process("0x:FF33233FFE").toString()); - Assert.assertEquals("0x:FF33 233 FFE", textHighlighter.process("0x:FF33 233 FFE").toString()); - - final MathEngine me = CalculatorEngine.instance.getEngine(); - try { - me.setNumeralBase(NumeralBase.hex); - Assert.assertEquals("E", textHighlighter.process("E").toString()); - Assert.assertEquals(".E", textHighlighter.process(".E").toString()); - Assert.assertEquals("E+", textHighlighter.process("E+").toString()); - Assert.assertEquals("E.", textHighlighter.process("E.").toString()); - Assert.assertEquals(".E.", textHighlighter.process(".E.").toString()); - Assert.assertEquals("6F", textHighlighter.process("6F").toString()); - Assert.assertEquals("6F", textHighlighter.process("6F").toString()); - Assert.assertEquals("6F.", textHighlighter.process("6F.").toString()); - Assert.assertEquals("6F.2", textHighlighter.process("6F.2").toString()); - Assert.assertEquals("6F.B", textHighlighter.process("6F.B").toString()); - Assert.assertEquals("006F.B", textHighlighter.process("006F.B").toString()); - } finally { - me.setNumeralBase(NumeralBase.dec); - } - - Assert.assertEquals("0b:110101", textHighlighter.process("0b:110101").toString()); - Assert.assertEquals("0b:110101.", textHighlighter.process("0b:110101.").toString()); - Assert.assertEquals("0b:110101.101", textHighlighter.process("0b:110101.101").toString()); - Assert.assertEquals("0b:11010100.1", textHighlighter.process("0b:11010100.1").toString()); - Assert.assertEquals("0b:110101.0", textHighlighter.process("0b:110101.0").toString()); - Assert.assertEquals("0b:0", textHighlighter.process("0b:0").toString()); - Assert.assertEquals("0b:1010100101111010101001", textHighlighter.process("0b:1010100101111010101001").toString()); - Assert.assertEquals("0b:101 010 01 0 111 1 0 10101001", textHighlighter.process("0b:101 010 01 0 111 1 0 10101001").toString()); - - try { - me.setNumeralBase(NumeralBase.bin); - Assert.assertEquals("110101", textHighlighter.process("110101").toString()); - Assert.assertEquals("110101.", textHighlighter.process("110101.").toString()); - Assert.assertEquals("110101.101", textHighlighter.process("110101.101").toString()); - Assert.assertEquals("11010100.1", textHighlighter.process("11010100.1").toString()); - Assert.assertEquals("110101.0", textHighlighter.process("110101.0").toString()); - Assert.assertEquals("0", textHighlighter.process("0").toString()); - Assert.assertEquals("1010100101111010101001", textHighlighter.process("1010100101111010101001").toString()); - Assert.assertEquals("101 010 01 0 111 1 0 10101001", textHighlighter.process("101 010 01 0 111 1 0 10101001").toString()); - } finally { - me.setNumeralBase(NumeralBase.dec); - } - } -} +/* + * 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.JsclMathEngine; +import jscl.MathEngine; +import jscl.NumeralBase; +import junit.framework.Assert; +import org.junit.Test; +import org.solovyev.android.calculator.text.TextProcessor; +import org.solovyev.android.calculator.view.TextHighlighter; + +import java.util.Date; +import java.util.Random; + +/** + * User: serso + * Date: 10/12/11 + * Time: 10:07 PM + */ +public class TextHighlighterTest { + + @Test + public void testProcess() throws Exception { + TextProcessor textHighlighter = new TextHighlighter(0, false, JsclMathEngine.instance); + + final Random random = new Random(new Date().getTime()); + for (int i = 0; i < 1000; i++) { + final StringBuilder sb = new StringBuilder(); + for (int j = 0; j < 1000; j++) { + sb.append(random.nextBoolean() ? "(" : ")"); + } + try { + textHighlighter.process(sb.toString()); + } catch (Exception e) { + System.out.println(sb.toString()); + throw e; + } + } + + Assert.assertEquals(")(((())())", textHighlighter.process(")(((())())").toString()); + Assert.assertEquals(")", textHighlighter.process(")").toString()); + Assert.assertEquals(")()(", textHighlighter.process(")()(").toString()); + + textHighlighter = new TextHighlighter(0, true, JsclMathEngine.instance); + Assert.assertEquals("1 000 000", textHighlighter.process("1000000").toString()); + Assert.assertEquals("1 000 000", textHighlighter.process("1000000").toString()); + Assert.assertEquals("0.1E3", textHighlighter.process("0.1E3").toString()); + Assert.assertEquals("1E3", textHighlighter.process("1E3").toString()); + Assert.assertEquals("20x:", textHighlighter.process("20x:").toString()); + Assert.assertEquals("20g", textHighlighter.process("20g").toString()); + Assert.assertEquals("22g", textHighlighter.process("22g").toString()); + Assert.assertEquals("20ю", textHighlighter.process("20ю").toString()); + Assert.assertEquals("20ъ", textHighlighter.process("20ъ").toString()); + Assert.assertEquals("3!!", textHighlighter.process("3!!").toString()); + Assert.assertEquals("2", textHighlighter.process("2").toString()); + Assert.assertEquals("21", textHighlighter.process("21").toString()); + Assert.assertEquals("214", textHighlighter.process("214").toString()); + Assert.assertEquals("2 145", textHighlighter.process("2 145").toString()); + Assert.assertEquals("1 000 000E3", textHighlighter.process("1000000E3").toString()); + Assert.assertEquals("-1 000 000E3", textHighlighter.process("-1000000E3").toString()); + Assert.assertEquals("-1 000 000E-3", textHighlighter.process("-1000000E-3").toString()); + Assert.assertEquals("-1 000 000E-30000", textHighlighter.process("-1000000E-30000").toString()); + textHighlighter = new TextHighlighter(0, false, JsclMathEngine.instance); + + textHighlighter.process("cannot calculate 3^10^10 !!!\n" + + " unable to enter 0. FIXED\n" + + " empty display in Xperia Rayo\n" + + " check привиденная FIXED\n" + + " set display result only if text in editor was not changed FIXED\n" + + " shift M text to the left\n" + + " do not show SYNTAX ERROR always (may be show send clock?q) FIXED\n" + + " ln(8)*log(8) => ln(8)*og(8) FIXED\n" + + " copy/paste ln(8)*log(8)\n" + + " 6!^2 ERROR"); + + Assert.assertEquals("sin(2)", textHighlighter.process("sin(2)").toString()); + Assert.assertEquals("atanh(2)", textHighlighter.process("atanh(2)").toString()); + + + Assert.assertEquals("0x:E", textHighlighter.process("0x:E").toString()); + Assert.assertEquals("0x:6F", textHighlighter.process("0x:6F").toString()); + Assert.assertEquals("0x:6F.", textHighlighter.process("0x:6F.").toString()); + Assert.assertEquals("0x:6F.2", textHighlighter.process("0x:6F.2").toString()); + Assert.assertEquals("0x:6F.B", textHighlighter.process("0x:6F.B").toString()); + Assert.assertEquals("0x:006F.B", textHighlighter.process("0x:006F.B").toString()); + Assert.assertEquals("0x:0", textHighlighter.process("0x:0").toString()); + Assert.assertEquals("0x:FF33233FFE", textHighlighter.process("0x:FF33233FFE").toString()); + Assert.assertEquals("0x:FF33 233 FFE", textHighlighter.process("0x:FF33 233 FFE").toString()); + + final MathEngine me = CalculatorLocatorImpl.getInstance().getEngine().getEngine(); + try { + me.setNumeralBase(NumeralBase.hex); + Assert.assertEquals("E", textHighlighter.process("E").toString()); + Assert.assertEquals(".E", textHighlighter.process(".E").toString()); + Assert.assertEquals("E+", textHighlighter.process("E+").toString()); + Assert.assertEquals("E.", textHighlighter.process("E.").toString()); + Assert.assertEquals(".E.", textHighlighter.process(".E.").toString()); + Assert.assertEquals("6F", textHighlighter.process("6F").toString()); + Assert.assertEquals("6F", textHighlighter.process("6F").toString()); + Assert.assertEquals("6F.", textHighlighter.process("6F.").toString()); + Assert.assertEquals("6F.2", textHighlighter.process("6F.2").toString()); + Assert.assertEquals("6F.B", textHighlighter.process("6F.B").toString()); + Assert.assertEquals("006F.B", textHighlighter.process("006F.B").toString()); + } finally { + me.setNumeralBase(NumeralBase.dec); + } + + Assert.assertEquals("0b:110101", textHighlighter.process("0b:110101").toString()); + Assert.assertEquals("0b:110101.", textHighlighter.process("0b:110101.").toString()); + Assert.assertEquals("0b:110101.101", textHighlighter.process("0b:110101.101").toString()); + Assert.assertEquals("0b:11010100.1", textHighlighter.process("0b:11010100.1").toString()); + Assert.assertEquals("0b:110101.0", textHighlighter.process("0b:110101.0").toString()); + Assert.assertEquals("0b:0", textHighlighter.process("0b:0").toString()); + Assert.assertEquals("0b:1010100101111010101001", textHighlighter.process("0b:1010100101111010101001").toString()); + Assert.assertEquals("0b:101 010 01 0 111 1 0 10101001", textHighlighter.process("0b:101 010 01 0 111 1 0 10101001").toString()); + + try { + me.setNumeralBase(NumeralBase.bin); + Assert.assertEquals("110101", textHighlighter.process("110101").toString()); + Assert.assertEquals("110101.", textHighlighter.process("110101.").toString()); + Assert.assertEquals("110101.101", textHighlighter.process("110101.101").toString()); + Assert.assertEquals("11010100.1", textHighlighter.process("11010100.1").toString()); + Assert.assertEquals("110101.0", textHighlighter.process("110101.0").toString()); + Assert.assertEquals("0", textHighlighter.process("0").toString()); + Assert.assertEquals("1010100101111010101001", textHighlighter.process("1010100101111010101001").toString()); + Assert.assertEquals("101 010 01 0 111 1 0 10101001", textHighlighter.process("101 010 01 0 111 1 0 10101001").toString()); + } finally { + me.setNumeralBase(NumeralBase.dec); + } + } +} diff --git a/calculatorpp/src/test/java/org/solovyev/android/calculator/jscl/FromJsclNumericTextProcessorTest.java b/calculatorpp/src/test/java/org/solovyev/android/calculator/jscl/FromJsclNumericTextProcessorTest.java index c0483701..bb94cae3 100644 --- a/calculatorpp/src/test/java/org/solovyev/android/calculator/jscl/FromJsclNumericTextProcessorTest.java +++ b/calculatorpp/src/test/java/org/solovyev/android/calculator/jscl/FromJsclNumericTextProcessorTest.java @@ -13,7 +13,7 @@ import jscl.math.Generic; import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; -import org.solovyev.android.calculator.model.CalculatorEngine; +import org.solovyev.android.calculator.CalculatorLocatorImpl; /** * User: serso @@ -24,7 +24,7 @@ public class FromJsclNumericTextProcessorTest { @BeforeClass public static void setUp() throws Exception { - CalculatorEngine.instance.init(null, null); + CalculatorLocatorImpl.getInstance().getEngine().init(); } @Test diff --git a/calculatorpp/src/test/java/org/solovyev/android/calculator/math/MathTypeTest.java b/calculatorpp/src/test/java/org/solovyev/android/calculator/math/MathTypeTest.java index b3fef984..3e581663 100644 --- a/calculatorpp/src/test/java/org/solovyev/android/calculator/math/MathTypeTest.java +++ b/calculatorpp/src/test/java/org/solovyev/android/calculator/math/MathTypeTest.java @@ -9,7 +9,7 @@ package org.solovyev.android.calculator.math; import junit.framework.Assert; import org.junit.BeforeClass; import org.junit.Test; -import org.solovyev.android.calculator.model.CalculatorEngine; +import org.solovyev.android.calculator.CalculatorLocatorImpl; /** * User: serso @@ -20,7 +20,7 @@ public class MathTypeTest { @BeforeClass public static void setUp() throws Exception { - CalculatorEngine.instance.init(null, null); + CalculatorLocatorImpl.getInstance().getEngine().init(); } @Test diff --git a/calculatorpp/src/test/java/org/solovyev/android/calculator/model/CalculatorEngineTest.java b/calculatorpp/src/test/java/org/solovyev/android/calculator/model/AndroidCalculatorEngineTest.java similarity index 89% rename from calculatorpp/src/test/java/org/solovyev/android/calculator/model/CalculatorEngineTest.java rename to calculatorpp/src/test/java/org/solovyev/android/calculator/model/AndroidCalculatorEngineTest.java index 375969ef..da53274a 100644 --- a/calculatorpp/src/test/java/org/solovyev/android/calculator/model/CalculatorEngineTest.java +++ b/calculatorpp/src/test/java/org/solovyev/android/calculator/model/AndroidCalculatorEngineTest.java @@ -16,6 +16,7 @@ import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; import org.solovyev.android.calculator.CalculatorEvalException; +import org.solovyev.android.calculator.CalculatorLocatorImpl; import org.solovyev.android.calculator.CalculatorParseException; import org.solovyev.android.calculator.jscl.JsclOperation; @@ -30,18 +31,18 @@ import static junit.framework.Assert.fail; * Time: 9:47 PM */ -public class CalculatorEngineTest { +public class AndroidCalculatorEngineTest { @BeforeClass public static void setUp() throws Exception { - CalculatorEngine.instance.init(null, null); - CalculatorEngine.instance.setPrecision(3); - CalculatorEngine.instance.setThreadKiller(new CalculatorEngine.ThreadKillerImpl()); + CalculatorLocatorImpl.getInstance().getEngine().init(); + ((AndroidCalculatorEngine) CalculatorLocatorImpl.getInstance().getEngine()).setPrecision(3); + ((AndroidCalculatorEngine) CalculatorLocatorImpl.getInstance().getEngine()).setThreadKiller(new AndroidCalculatorEngine.ThreadKillerImpl()); } @Test public void testDegrees() throws Exception { - final CalculatorEngine cm = CalculatorEngine.instance; + final AndroidCalculatorEngine cm = (AndroidCalculatorEngine) CalculatorLocatorImpl.getInstance().getEngine(); final AngleUnit defaultAngleUnit = cm.getEngine().getAngleUnits(); try { @@ -68,7 +69,7 @@ public class CalculatorEngineTest { @Test public void testLongExecution() throws Exception { - final CalculatorEngine cm = CalculatorEngine.instance; + final AndroidCalculatorEngine cm = (AndroidCalculatorEngine) CalculatorLocatorImpl.getInstance().getEngine(); try { cm.evaluate(JsclOperation.numeric, "3^10^10^10"); @@ -111,7 +112,7 @@ public class CalculatorEngineTest { @Test public void testEvaluate() throws Exception { - final CalculatorEngine cm = CalculatorEngine.instance; + final AndroidCalculatorEngine cm = (AndroidCalculatorEngine) CalculatorLocatorImpl.getInstance().getEngine(); Assert.assertEquals("cos(t)+10%", cm.evaluate(JsclOperation.simplify, "cos(t)+10%").getStringResult()); @@ -181,7 +182,7 @@ public class CalculatorEngineTest { } junit.framework.Assert.assertEquals("24i", cm.evaluate(JsclOperation.numeric, "4!i").getStringResult()); - CalculatorEngine.instance.getVarsRegistry().add(new Var.Builder("si", 5d)); + CalculatorLocatorImpl.getInstance().getEngine().getVarsRegistry().add(new Var.Builder("si", 5d)); try { cm.getEngine().setAngleUnits(AngleUnit.rad); @@ -195,14 +196,14 @@ public class CalculatorEngineTest { cm.getEngine().setAngleUnits(defaultAngleUnit); } - CalculatorEngine.instance.getVarsRegistry().add(new Var.Builder("s", 1d)); + CalculatorLocatorImpl.getInstance().getEngine().getVarsRegistry().add(new Var.Builder("s", 1d)); Assert.assertEquals("5", cm.evaluate(JsclOperation.numeric, "si").getStringResult()); - CalculatorEngine.instance.getVarsRegistry().add(new Var.Builder("k", 3.5d)); - CalculatorEngine.instance.getVarsRegistry().add(new Var.Builder("k1", 4d)); + CalculatorLocatorImpl.getInstance().getEngine().getVarsRegistry().add(new Var.Builder("k", 3.5d)); + CalculatorLocatorImpl.getInstance().getEngine().getVarsRegistry().add(new Var.Builder("k1", 4d)); Assert.assertEquals("4", cm.evaluate(JsclOperation.numeric, "k11").getStringResult()); - CalculatorEngine.instance.getVarsRegistry().add(new Var.Builder("t", (String) null)); + CalculatorLocatorImpl.getInstance().getEngine().getVarsRegistry().add(new Var.Builder("t", (String) null)); Assert.assertEquals("11t", cm.evaluate(JsclOperation.numeric, "t11").getStringResult()); Assert.assertEquals("11et", cm.evaluate(JsclOperation.numeric, "t11e").getStringResult()); Assert.assertEquals("∞", cm.evaluate(JsclOperation.numeric, "∞").getStringResult()); @@ -248,10 +249,10 @@ public class CalculatorEngineTest { cm.setTimeout(3000); }*/ - CalculatorEngine.instance.getVarsRegistry().add(new Var.Builder("t", (String) null)); + CalculatorLocatorImpl.getInstance().getEngine().getVarsRegistry().add(new Var.Builder("t", (String) null)); Assert.assertEquals("2t", cm.evaluate(JsclOperation.simplify, "∂(t^2,t)").getStringResult()); Assert.assertEquals("2t", cm.evaluate(JsclOperation.numeric, "∂(t^2,t)").getStringResult()); - CalculatorEngine.instance.getVarsRegistry().add(new Var.Builder("t", "2")); + CalculatorLocatorImpl.getInstance().getEngine().getVarsRegistry().add(new Var.Builder("t", "2")); Assert.assertEquals("2t", cm.evaluate(JsclOperation.simplify, "∂(t^2,t)").getStringResult()); Assert.assertEquals("4", cm.evaluate(JsclOperation.numeric, "∂(t^2,t)").getStringResult()); @@ -265,7 +266,7 @@ public class CalculatorEngineTest { @Test public void testFormatting() throws Exception { - final CalculatorEngine ce = CalculatorEngine.instance; + final AndroidCalculatorEngine ce = (AndroidCalculatorEngine) CalculatorLocatorImpl.getInstance().getEngine(); Assert.assertEquals("12 345", ce.evaluate(JsclOperation.simplify, "12345").getStringResult()); @@ -273,7 +274,7 @@ public class CalculatorEngineTest { @Test public void testI() throws CalculatorParseException, CalculatorEvalException { - final CalculatorEngine cm = CalculatorEngine.instance; + final AndroidCalculatorEngine cm = (AndroidCalculatorEngine) CalculatorLocatorImpl.getInstance().getEngine(); Assert.assertEquals("-i", cm.evaluate(JsclOperation.numeric, "i^3").getStringResult()); for (int i = 0; i < 1000; i++) { @@ -298,7 +299,7 @@ public class CalculatorEngineTest { @Test public void testEmptyFunction() throws Exception { - final CalculatorEngine cm = CalculatorEngine.instance; + final AndroidCalculatorEngine cm = (AndroidCalculatorEngine) CalculatorLocatorImpl.getInstance().getEngine(); try { cm.evaluate(JsclOperation.numeric, "cos(cos(cos(cos(acos(acos(acos(acos(acos(acos(acos(acos(cos(cos(cos(cos(cosh(acos(cos(cos(cos(cos(cos(acos(acos(acos(acos(acos(acos(acos(acos(cos(cos(cos(cos(cosh(acos(cos())))))))))))))))))))))))))))))))))))))"); Assert.fail(); @@ -319,7 +320,7 @@ public class CalculatorEngineTest { cm.getEngine().setAngleUnits(defaultAngleUnit); } - CalculatorEngine.instance.getVarsRegistry().add(new Var.Builder("si", 5d)); + CalculatorLocatorImpl.getInstance().getEngine().getVarsRegistry().add(new Var.Builder("si", 5d)); Assert.assertEquals("5", cm.evaluate(JsclOperation.numeric, "si").getStringResult()); try { @@ -331,7 +332,7 @@ public class CalculatorEngineTest { @Test public void testRounding() throws Exception { - final CalculatorEngine cm = CalculatorEngine.instance; + final AndroidCalculatorEngine cm = (AndroidCalculatorEngine) CalculatorLocatorImpl.getInstance().getEngine(); try { DecimalFormatSymbols decimalGroupSymbols = new DecimalFormatSymbols(Locale.getDefault()); @@ -355,7 +356,7 @@ public class CalculatorEngineTest { @Test public void testComparisonFunction() throws Exception { - final CalculatorEngine cm = CalculatorEngine.instance; + final AndroidCalculatorEngine cm = (AndroidCalculatorEngine) CalculatorLocatorImpl.getInstance().getEngine(); Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "eq(0, 1)").getStringResult()); Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "eq(1, 1)").getStringResult()); @@ -393,7 +394,7 @@ public class CalculatorEngineTest { @Test public void testNumeralSystems() throws Exception { - final CalculatorEngine cm = CalculatorEngine.instance; + final AndroidCalculatorEngine cm = (AndroidCalculatorEngine) CalculatorLocatorImpl.getInstance().getEngine(); Assert.assertEquals("11 259 375", cm.evaluate(JsclOperation.numeric, "0x:ABCDEF").getStringResult()); Assert.assertEquals("30 606 154.462", cm.evaluate(JsclOperation.numeric, "0x:ABCDEF*e").getStringResult()); @@ -427,7 +428,7 @@ public class CalculatorEngineTest { @Test public void testLog() throws Exception { - final CalculatorEngine cm = CalculatorEngine.instance; + final AndroidCalculatorEngine cm = (AndroidCalculatorEngine) CalculatorLocatorImpl.getInstance().getEngine(); Assert.assertEquals("∞", Expression.valueOf("1/0").numeric().toString()); Assert.assertEquals("∞", Expression.valueOf("ln(10)/ln(1)").numeric().toString()); diff --git a/calculatorpp/src/test/java/org/solovyev/android/calculator/model/FromJsclSimplifyTextProcessorTest.java b/calculatorpp/src/test/java/org/solovyev/android/calculator/model/FromJsclSimplifyTextProcessorTest.java index a52ee3af..a9b21894 100644 --- a/calculatorpp/src/test/java/org/solovyev/android/calculator/model/FromJsclSimplifyTextProcessorTest.java +++ b/calculatorpp/src/test/java/org/solovyev/android/calculator/model/FromJsclSimplifyTextProcessorTest.java @@ -1,70 +1,71 @@ -package org.solovyev.android.calculator.model; - -import org.junit.Assert; -import org.junit.BeforeClass; -import org.junit.Test; -import org.solovyev.android.calculator.text.FromJsclSimplifyTextProcessor; - -import java.text.DecimalFormatSymbols; - -/** - * User: serso - * Date: 10/20/11 - * Time: 3:43 PM - */ -public class FromJsclSimplifyTextProcessorTest { - - @BeforeClass - public static void setUp() throws Exception { - CalculatorEngine.instance.init(null, null); - } - - @Test - public void testProcess() throws Exception { - FromJsclSimplifyTextProcessor tp = new FromJsclSimplifyTextProcessor(); - //Assert.assertEquals("(e)", tp.process("(2.718281828459045)")); - //Assert.assertEquals("ee", tp.process("2.718281828459045*2.718281828459045")); - //Assert.assertEquals("((e)(e))", tp.process("((2.718281828459045)*(2.718281828459045))")); - DecimalFormatSymbols decimalGroupSymbols = new DecimalFormatSymbols(); - decimalGroupSymbols.setGroupingSeparator(' '); - CalculatorEngine.instance.setDecimalGroupSymbols(decimalGroupSymbols); - //Assert.assertEquals("123 456 789e", tp.process("123456789*2.718281828459045")); - //Assert.assertEquals("123 456 789e", tp.process("123 456 789 * 2.718281828459045")); - //Assert.assertEquals("t11e", tp.process("t11*2.718281828459045")); - //Assert.assertEquals("e", tp.process("2.718281828459045")); - //Assert.assertEquals("tee", tp.process("t2.718281828459045*2.718281828459045")); - - CalculatorEngine.instance.getVarsRegistry().add(new Var.Builder("t2.718281828459045", "2")); - CalculatorEngine.instance.getVarsRegistry().add(new Var.Builder("t", (String)null)); - //Assert.assertEquals("t2.718281828459045e", tp.process("t2.718281828459045*2.718281828459045")); - //Assert.assertEquals("ee", tp.process("2.718281828459045*2.718281828459045")); - Assert.assertEquals("t×", tp.process("t*")); - Assert.assertEquals("×t", tp.process("*t")); - Assert.assertEquals("t2", tp.process("t*2")); - Assert.assertEquals("2t", tp.process("2*t")); - CalculatorEngine.instance.getVarsRegistry().add(new Var.Builder("t", (String) null)); - Assert.assertEquals("t×", tp.process("t*")); - Assert.assertEquals("×t", tp.process("*t")); - - Assert.assertEquals("t2", tp.process("t*2")); - Assert.assertEquals("2t", tp.process("2*t")); - - Assert.assertEquals("t^2×2", tp.process("t^2*2")); - Assert.assertEquals("2t^2", tp.process("2*t^2")); - - Assert.assertEquals("t^[2×2t]", tp.process("t^[2*2*t]")); - Assert.assertEquals("2t^2[2t]", tp.process("2*t^2[2*t]")); - - CalculatorEngine.instance.getVarsRegistry().add(new Var.Builder("k", (String) null)); - Assert.assertEquals("(t+2k)[k+2t]", tp.process("(t+2*k)*[k+2*t]")); - Assert.assertEquals("(te+2k)e[k+2te]", tp.process("(t*e+2*k)*e*[k+2*t*e]")); - - - Assert.assertEquals("tlog(3)", tp.process("t*log(3)")); - Assert.assertEquals("t√(3)", tp.process("t*√(3)")); - Assert.assertEquals("20x", tp.process("20*x")); - Assert.assertEquals("20x", tp.process("20x")); - Assert.assertEquals("2×0x3", tp.process("2*0x3")); - Assert.assertEquals("2×0x:3", tp.process("2*0x:3")); - } -} +package org.solovyev.android.calculator.model; + +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; +import org.solovyev.android.calculator.CalculatorLocatorImpl; +import org.solovyev.android.calculator.text.FromJsclSimplifyTextProcessor; + +import java.text.DecimalFormatSymbols; + +/** + * User: serso + * Date: 10/20/11 + * Time: 3:43 PM + */ +public class FromJsclSimplifyTextProcessorTest { + + @BeforeClass + public static void setUp() throws Exception { + CalculatorLocatorImpl.getInstance().getEngine().init(); + } + + @Test + public void testProcess() throws Exception { + FromJsclSimplifyTextProcessor tp = new FromJsclSimplifyTextProcessor(); + //Assert.assertEquals("(e)", tp.process("(2.718281828459045)")); + //Assert.assertEquals("ee", tp.process("2.718281828459045*2.718281828459045")); + //Assert.assertEquals("((e)(e))", tp.process("((2.718281828459045)*(2.718281828459045))")); + DecimalFormatSymbols decimalGroupSymbols = new DecimalFormatSymbols(); + decimalGroupSymbols.setGroupingSeparator(' '); + ((AndroidCalculatorEngine) CalculatorLocatorImpl.getInstance().getEngine()).setDecimalGroupSymbols(decimalGroupSymbols); + //Assert.assertEquals("123 456 789e", tp.process("123456789*2.718281828459045")); + //Assert.assertEquals("123 456 789e", tp.process("123 456 789 * 2.718281828459045")); + //Assert.assertEquals("t11e", tp.process("t11*2.718281828459045")); + //Assert.assertEquals("e", tp.process("2.718281828459045")); + //Assert.assertEquals("tee", tp.process("t2.718281828459045*2.718281828459045")); + + CalculatorLocatorImpl.getInstance().getEngine().getVarsRegistry().add(new Var.Builder("t2.718281828459045", "2")); + CalculatorLocatorImpl.getInstance().getEngine().getVarsRegistry().add(new Var.Builder("t", (String)null)); + //Assert.assertEquals("t2.718281828459045e", tp.process("t2.718281828459045*2.718281828459045")); + //Assert.assertEquals("ee", tp.process("2.718281828459045*2.718281828459045")); + Assert.assertEquals("t×", tp.process("t*")); + Assert.assertEquals("×t", tp.process("*t")); + Assert.assertEquals("t2", tp.process("t*2")); + Assert.assertEquals("2t", tp.process("2*t")); + CalculatorLocatorImpl.getInstance().getEngine().getVarsRegistry().add(new Var.Builder("t", (String) null)); + Assert.assertEquals("t×", tp.process("t*")); + Assert.assertEquals("×t", tp.process("*t")); + + Assert.assertEquals("t2", tp.process("t*2")); + Assert.assertEquals("2t", tp.process("2*t")); + + Assert.assertEquals("t^2×2", tp.process("t^2*2")); + Assert.assertEquals("2t^2", tp.process("2*t^2")); + + Assert.assertEquals("t^[2×2t]", tp.process("t^[2*2*t]")); + Assert.assertEquals("2t^2[2t]", tp.process("2*t^2[2*t]")); + + CalculatorLocatorImpl.getInstance().getEngine().getVarsRegistry().add(new Var.Builder("k", (String) null)); + Assert.assertEquals("(t+2k)[k+2t]", tp.process("(t+2*k)*[k+2*t]")); + Assert.assertEquals("(te+2k)e[k+2te]", tp.process("(t*e+2*k)*e*[k+2*t*e]")); + + + Assert.assertEquals("tlog(3)", tp.process("t*log(3)")); + Assert.assertEquals("t√(3)", tp.process("t*√(3)")); + Assert.assertEquals("20x", tp.process("20*x")); + Assert.assertEquals("20x", tp.process("20x")); + Assert.assertEquals("2×0x3", tp.process("2*0x3")); + Assert.assertEquals("2×0x:3", tp.process("2*0x:3")); + } +} 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 5e05495c..8337b46e 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 @@ -11,8 +11,8 @@ import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; import org.solovyev.android.calculator.CalculatorEvalException; +import org.solovyev.android.calculator.CalculatorLocatorImpl; import org.solovyev.android.calculator.CalculatorParseException; -import org.solovyev.android.calculator.jscl.JsclOperation; import org.solovyev.common.Converter; import java.io.InputStreamReader; @@ -28,9 +28,9 @@ public class NumeralBaseTest { @BeforeClass public static void setUp() throws Exception { - CalculatorEngine.instance.init(null, null); - CalculatorEngine.instance.setPrecision(3); - CalculatorEngine.instance.setThreadKiller(new CalculatorEngine.ThreadKillerImpl()); + CalculatorLocatorImpl.getInstance().getEngine().init(); + ((AndroidCalculatorEngine) CalculatorLocatorImpl.getInstance().getEngine()).setPrecision(3); + ((AndroidCalculatorEngine) CalculatorLocatorImpl.getInstance().getEngine()).setThreadKiller(new AndroidCalculatorEngine.ThreadKillerImpl()); } @Test @@ -100,11 +100,11 @@ public class NumeralBaseTest { final String bin = "0b:" + line[2].toUpperCase(); final String decExpression = converter.convert(dec); - final String decResult = CalculatorEngine.instance.evaluate(JsclOperation.numeric, decExpression).getStringResult(); + final String decResult = CalculatorLocatorImpl.getInstance().getEngine().getEngine().evaluate(decExpression); final String hexExpression = converter.convert(hex); - final String hexResult = CalculatorEngine.instance.evaluate(JsclOperation.numeric, hexExpression).getStringResult(); + final String hexResult = CalculatorLocatorImpl.getInstance().getEngine().getEngine().evaluate(hexExpression); final String binExpression = converter.convert(bin); - final String binResult = CalculatorEngine.instance.evaluate(JsclOperation.numeric, binExpression).getStringResult(); + final String binResult = CalculatorLocatorImpl.getInstance().getEngine().getEngine().evaluate(binExpression); Assert.assertEquals("dec-hex: " + decExpression + " : " + hexExpression, decResult, hexResult); Assert.assertEquals("dec-bin: " + decExpression + " : " + binExpression, decResult, binResult); 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 05c4e995..2fccc0f5 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 @@ -1,165 +1,166 @@ -/* - * 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.JsclMathEngine; -import jscl.NumeralBase; -import org.junit.Assert; -import org.junit.BeforeClass; -import org.junit.Test; -import org.solovyev.android.calculator.CalculatorParseException; -import org.solovyev.android.calculator.PreparedExpression; -import org.solovyev.android.calculator.ToJsclTextProcessor; -import org.solovyev.android.calculator.text.TextProcessor; - -/** - * User: serso - * Date: 9/26/11 - * Time: 12:13 PM - */ -public class ToJsclTextProcessorTest { - - @BeforeClass - public static void setUp() throws Exception { - CalculatorEngine.instance.init(null, null); - } - - @Test - public void testSpecialCases() throws CalculatorParseException { - final TextProcessor preprocessor = ToJsclTextProcessor.getInstance(); - Assert.assertEquals( "3^E10", preprocessor.process("3^E10").toString()); - } - - @Test - public void testProcess() throws Exception { - final TextProcessor preprocessor = ToJsclTextProcessor.getInstance(); - - Assert.assertEquals( "", preprocessor.process("").toString()); - Assert.assertEquals( "()", preprocessor.process("[]").toString()); - Assert.assertEquals( "()*()", preprocessor.process("[][]").toString()); - Assert.assertEquals( "()*(1)", preprocessor.process("[][1]").toString()); - Assert.assertEquals( "(0)*(1)", preprocessor.process("[0][1]").toString()); - Assert.assertEquals( "(0)*(1E)", preprocessor.process("[0][1E]").toString()); - Assert.assertEquals( "(0)*(1E1)", preprocessor.process("[0][1E1]").toString()); - Assert.assertEquals( "(0)*(1E-1)", preprocessor.process("[0][1E-1]").toString()); - Assert.assertEquals( "(0)*(1.E-1)", preprocessor.process("[0][1.E-1]").toString()); - Assert.assertEquals( "(0)*(2*E-1)", preprocessor.process("[0][2*E-1]").toString()); - Assert.assertEquals( "(0)*ln(1)*(2*E-1)", preprocessor.process("[0]ln(1)[2*E-1]").toString()); - Assert.assertEquals( "sin(4)*asin(0.5)*√(2)", preprocessor.process("sin(4)asin(0.5)√(2)").toString()); - Assert.assertEquals( "sin(4)*cos(5)", preprocessor.process("sin(4)cos(5)").toString()); - Assert.assertEquals( "π*sin(4)*π*cos(√(5))", preprocessor.process("πsin(4)πcos(√(5))").toString()); - Assert.assertEquals( "π*sin(4)+π*cos(√(5))", preprocessor.process("πsin(4)+πcos(√(5))").toString()); - Assert.assertEquals( "π*sin(4)+π*cos(√(5+(√(-1))))", preprocessor.process("πsin(4)+πcos(√(5+i))").toString()); - Assert.assertEquals( "π*sin(4.01)+π*cos(√(5+(√(-1))))", preprocessor.process("πsin(4.01)+πcos(√(5+i))").toString()); - Assert.assertEquals( "e^π*sin(4.01)+π*cos(√(5+(√(-1))))", preprocessor.process("e^πsin(4.01)+πcos(√(5+i))").toString()); - Assert.assertEquals( "e^π*sin(4.01)+π*cos(√(5+(√(-1))))E2", preprocessor.process("e^πsin(4.01)+πcos(√(5+i))E2").toString()); - Assert.assertEquals( "e^π*sin(4.01)+π*cos(√(5+(√(-1))))E-2", preprocessor.process("e^πsin(4.01)+πcos(√(5+i))E-2").toString()); - Assert.assertEquals( "E2", preprocessor.process("E2").toString()); - Assert.assertEquals( "E-2", preprocessor.process("E-2").toString()); - Assert.assertEquals( "E-1/2", preprocessor.process("E-1/2").toString()); - Assert.assertEquals( "E-1.2", preprocessor.process("E-1.2").toString()); - Assert.assertEquals( "E+1.2", preprocessor.process("E+1.2").toString()); - Assert.assertEquals( "E(-1.2)", preprocessor.process("E(-1.2)").toString()); - Assert.assertEquals( "EE", preprocessor.process("EE").toString()); - - try { - CalculatorEngine.instance.getEngine().setNumeralBase(NumeralBase.hex); - Assert.assertEquals( "22F*exp(F)", preprocessor.process("22Fexp(F)").toString()); - } finally { - CalculatorEngine.instance.getEngine().setNumeralBase(NumeralBase.dec); - } - Assert.assertEquals( "0x:ABCDEF", preprocessor.process("0x:ABCDEF").toString()); - Assert.assertEquals( "0x:ABCDEF", preprocessor.process("0x:A BC DEF").toString()); - Assert.assertEquals( "0x:ABCDEF", preprocessor.process("0x:A BC DEF").toString()); - Assert.assertEquals( "0x:ABCDEF*0*x", preprocessor.process("0x:A BC DEF*0x").toString()); - Assert.assertEquals( "0x:ABCDEF001*0*x", preprocessor.process("0x:A BC DEF001*0x").toString()); - Assert.assertEquals( "0x:ABCDEF001*0*c", preprocessor.process("0x:A BC DEF001*0c").toString()); - Assert.assertEquals( "0x:ABCDEF001*c", preprocessor.process("0x:A BC DEF001*c").toString()); - Assert.assertEquals( "0b:1101", preprocessor.process("0b:1101").toString()); - Assert.assertEquals( "0x:1C", preprocessor.process("0x:1C").toString()); - Assert.assertEquals( "0x:1C", preprocessor.process(" 0x:1C").toString()); - Assert.assertEquals( "0x:1C*0x:1C*sin(0x:1C)-0b:1101+√(0x:1C)+exp(0x:1C)", preprocessor.process("0x:1C*0x:1C * sin(0x:1C) - 0b:1101 + √(0x:1C) + exp ( 0x:1C)").toString()); - Assert.assertEquals( "0x:1C*0x:1C*sin(0x:1C)-0b:1101+√(0x:1C)+exp(0x:1C)", preprocessor.process("0x:1C*0x:1C * sin(0x:1C) - 0b:1101 + √(0x:1C) + exp ( 0x:1C)").toString()); - - try { - preprocessor.process("ln()"); - Assert.fail(); - } catch (CalculatorParseException e) { - } - try { - preprocessor.process("ln()ln()"); - Assert.fail(); - } catch (CalculatorParseException e) { - } - - try { - preprocessor.process("eln()eln()ln()ln()ln()e"); - Assert.fail(); - } catch (CalculatorParseException e) { - } - - try { - preprocessor.process("ln(ln(ln(ln(ln(ln(ln(ln(ln(ln(ln(ln(ln(ln(ln()))))))))))))))"); - Assert.fail(); - } catch (CalculatorParseException e) { - } - - try { - preprocessor.process("cos(cos(cos(cos(acos(acos(acos(acos(acos(acos(acos(acos(cos(cos(cos(cos(cosh(acos(cos(cos(cos(cos(cos(acos(acos(acos(acos(acos(acos(acos(acos(cos(cos(cos(cos(cosh(acos(cos())))))))))))))))))))))))))))))))))))))"); - Assert.fail(); - } catch (CalculatorParseException e) { - } - } - - @Test - public void testDegrees() throws Exception { - final TextProcessor preprocessor = ToJsclTextProcessor.getInstance(); - - Assert.assertEquals( "", preprocessor.process("").toString()); - /* try { - Assert.assertEquals( "π/180", preprocessor.process("°").toString()); - } catch (ParseException e) { - if ( !e.getMessage().startsWith("Could not find start of prefix") ){ - junit.framework.Assert.fail(); - } - } - Assert.assertEquals( "1*π/180", preprocessor.process("1°").toString()); - Assert.assertEquals( "20.0*π/180", preprocessor.process("20.0°").toString()); - Assert.assertEquals( "sin(30*π/180)", preprocessor.process("sin(30°)").toString()); - Assert.assertEquals( "asin(sin(π/6))*π/180", preprocessor.process("asin(sin(π/6))°").toString()); - Assert.assertEquals( "1*π/180*sin(1)", preprocessor.process("1°sin(1)").toString()); - try { - Assert.assertEquals( "1*π/180^sin(1)", preprocessor.process("1°^sin(1)").toString()); - junit.framework.Assert.fail(); - } catch (ParseException e) { - if ( !e.getMessage().equals("Power operation after postfix function is currently unsupported!") ) { - junit.framework.Assert.fail(); - } - }*/ - - } - - @Test - public void testPostfixFunction() throws Exception { - } - - @Test - public void testNumeralBases() throws Exception { - final TextProcessor processor = ToJsclTextProcessor.getInstance(); - - final NumeralBase defaultNumeralBase = JsclMathEngine.instance.getNumeralBase(); - try{ - JsclMathEngine.instance.setNumeralBase(NumeralBase.bin); - Assert.assertEquals("101", JsclMathEngine.instance.evaluate("10+11")); - - JsclMathEngine.instance.setNumeralBase(NumeralBase.hex); - Assert.assertEquals("56CE+CAD", processor.process("56CE+CAD").getExpression()); - } finally { - JsclMathEngine.instance.setNumeralBase(defaultNumeralBase); - } - } -} +/* + * 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.JsclMathEngine; +import jscl.NumeralBase; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; +import org.solovyev.android.calculator.CalculatorLocatorImpl; +import org.solovyev.android.calculator.CalculatorParseException; +import org.solovyev.android.calculator.PreparedExpression; +import org.solovyev.android.calculator.ToJsclTextProcessor; +import org.solovyev.android.calculator.text.TextProcessor; + +/** + * User: serso + * Date: 9/26/11 + * Time: 12:13 PM + */ +public class ToJsclTextProcessorTest { + + @BeforeClass + public static void setUp() throws Exception { + CalculatorLocatorImpl.getInstance().getEngine().init(); + } + + @Test + public void testSpecialCases() throws CalculatorParseException { + final TextProcessor preprocessor = ToJsclTextProcessor.getInstance(); + Assert.assertEquals( "3^E10", preprocessor.process("3^E10").toString()); + } + + @Test + public void testProcess() throws Exception { + final TextProcessor preprocessor = ToJsclTextProcessor.getInstance(); + + Assert.assertEquals( "", preprocessor.process("").toString()); + Assert.assertEquals( "()", preprocessor.process("[]").toString()); + Assert.assertEquals( "()*()", preprocessor.process("[][]").toString()); + Assert.assertEquals( "()*(1)", preprocessor.process("[][1]").toString()); + Assert.assertEquals( "(0)*(1)", preprocessor.process("[0][1]").toString()); + Assert.assertEquals( "(0)*(1E)", preprocessor.process("[0][1E]").toString()); + Assert.assertEquals( "(0)*(1E1)", preprocessor.process("[0][1E1]").toString()); + Assert.assertEquals( "(0)*(1E-1)", preprocessor.process("[0][1E-1]").toString()); + Assert.assertEquals( "(0)*(1.E-1)", preprocessor.process("[0][1.E-1]").toString()); + Assert.assertEquals( "(0)*(2*E-1)", preprocessor.process("[0][2*E-1]").toString()); + Assert.assertEquals( "(0)*ln(1)*(2*E-1)", preprocessor.process("[0]ln(1)[2*E-1]").toString()); + Assert.assertEquals( "sin(4)*asin(0.5)*√(2)", preprocessor.process("sin(4)asin(0.5)√(2)").toString()); + Assert.assertEquals( "sin(4)*cos(5)", preprocessor.process("sin(4)cos(5)").toString()); + Assert.assertEquals( "π*sin(4)*π*cos(√(5))", preprocessor.process("πsin(4)πcos(√(5))").toString()); + Assert.assertEquals( "π*sin(4)+π*cos(√(5))", preprocessor.process("πsin(4)+πcos(√(5))").toString()); + Assert.assertEquals( "π*sin(4)+π*cos(√(5+(√(-1))))", preprocessor.process("πsin(4)+πcos(√(5+i))").toString()); + Assert.assertEquals( "π*sin(4.01)+π*cos(√(5+(√(-1))))", preprocessor.process("πsin(4.01)+πcos(√(5+i))").toString()); + Assert.assertEquals( "e^π*sin(4.01)+π*cos(√(5+(√(-1))))", preprocessor.process("e^πsin(4.01)+πcos(√(5+i))").toString()); + Assert.assertEquals( "e^π*sin(4.01)+π*cos(√(5+(√(-1))))E2", preprocessor.process("e^πsin(4.01)+πcos(√(5+i))E2").toString()); + Assert.assertEquals( "e^π*sin(4.01)+π*cos(√(5+(√(-1))))E-2", preprocessor.process("e^πsin(4.01)+πcos(√(5+i))E-2").toString()); + Assert.assertEquals( "E2", preprocessor.process("E2").toString()); + Assert.assertEquals( "E-2", preprocessor.process("E-2").toString()); + Assert.assertEquals( "E-1/2", preprocessor.process("E-1/2").toString()); + Assert.assertEquals( "E-1.2", preprocessor.process("E-1.2").toString()); + Assert.assertEquals( "E+1.2", preprocessor.process("E+1.2").toString()); + Assert.assertEquals( "E(-1.2)", preprocessor.process("E(-1.2)").toString()); + Assert.assertEquals( "EE", preprocessor.process("EE").toString()); + + try { + CalculatorLocatorImpl.getInstance().getEngine().getEngine().setNumeralBase(NumeralBase.hex); + Assert.assertEquals( "22F*exp(F)", preprocessor.process("22Fexp(F)").toString()); + } finally { + CalculatorLocatorImpl.getInstance().getEngine().getEngine().setNumeralBase(NumeralBase.dec); + } + Assert.assertEquals( "0x:ABCDEF", preprocessor.process("0x:ABCDEF").toString()); + Assert.assertEquals( "0x:ABCDEF", preprocessor.process("0x:A BC DEF").toString()); + Assert.assertEquals( "0x:ABCDEF", preprocessor.process("0x:A BC DEF").toString()); + Assert.assertEquals( "0x:ABCDEF*0*x", preprocessor.process("0x:A BC DEF*0x").toString()); + Assert.assertEquals( "0x:ABCDEF001*0*x", preprocessor.process("0x:A BC DEF001*0x").toString()); + Assert.assertEquals( "0x:ABCDEF001*0*c", preprocessor.process("0x:A BC DEF001*0c").toString()); + Assert.assertEquals( "0x:ABCDEF001*c", preprocessor.process("0x:A BC DEF001*c").toString()); + Assert.assertEquals( "0b:1101", preprocessor.process("0b:1101").toString()); + Assert.assertEquals( "0x:1C", preprocessor.process("0x:1C").toString()); + Assert.assertEquals( "0x:1C", preprocessor.process(" 0x:1C").toString()); + Assert.assertEquals( "0x:1C*0x:1C*sin(0x:1C)-0b:1101+√(0x:1C)+exp(0x:1C)", preprocessor.process("0x:1C*0x:1C * sin(0x:1C) - 0b:1101 + √(0x:1C) + exp ( 0x:1C)").toString()); + Assert.assertEquals( "0x:1C*0x:1C*sin(0x:1C)-0b:1101+√(0x:1C)+exp(0x:1C)", preprocessor.process("0x:1C*0x:1C * sin(0x:1C) - 0b:1101 + √(0x:1C) + exp ( 0x:1C)").toString()); + + try { + preprocessor.process("ln()"); + Assert.fail(); + } catch (CalculatorParseException e) { + } + try { + preprocessor.process("ln()ln()"); + Assert.fail(); + } catch (CalculatorParseException e) { + } + + try { + preprocessor.process("eln()eln()ln()ln()ln()e"); + Assert.fail(); + } catch (CalculatorParseException e) { + } + + try { + preprocessor.process("ln(ln(ln(ln(ln(ln(ln(ln(ln(ln(ln(ln(ln(ln(ln()))))))))))))))"); + Assert.fail(); + } catch (CalculatorParseException e) { + } + + try { + preprocessor.process("cos(cos(cos(cos(acos(acos(acos(acos(acos(acos(acos(acos(cos(cos(cos(cos(cosh(acos(cos(cos(cos(cos(cos(acos(acos(acos(acos(acos(acos(acos(acos(cos(cos(cos(cos(cosh(acos(cos())))))))))))))))))))))))))))))))))))))"); + Assert.fail(); + } catch (CalculatorParseException e) { + } + } + + @Test + public void testDegrees() throws Exception { + final TextProcessor preprocessor = ToJsclTextProcessor.getInstance(); + + Assert.assertEquals( "", preprocessor.process("").toString()); + /* try { + Assert.assertEquals( "π/180", preprocessor.process("°").toString()); + } catch (ParseException e) { + if ( !e.getMessage().startsWith("Could not find start of prefix") ){ + junit.framework.Assert.fail(); + } + } + Assert.assertEquals( "1*π/180", preprocessor.process("1°").toString()); + Assert.assertEquals( "20.0*π/180", preprocessor.process("20.0°").toString()); + Assert.assertEquals( "sin(30*π/180)", preprocessor.process("sin(30°)").toString()); + Assert.assertEquals( "asin(sin(π/6))*π/180", preprocessor.process("asin(sin(π/6))°").toString()); + Assert.assertEquals( "1*π/180*sin(1)", preprocessor.process("1°sin(1)").toString()); + try { + Assert.assertEquals( "1*π/180^sin(1)", preprocessor.process("1°^sin(1)").toString()); + junit.framework.Assert.fail(); + } catch (ParseException e) { + if ( !e.getMessage().equals("Power operation after postfix function is currently unsupported!") ) { + junit.framework.Assert.fail(); + } + }*/ + + } + + @Test + public void testPostfixFunction() throws Exception { + } + + @Test + public void testNumeralBases() throws Exception { + final TextProcessor processor = ToJsclTextProcessor.getInstance(); + + final NumeralBase defaultNumeralBase = JsclMathEngine.instance.getNumeralBase(); + try{ + JsclMathEngine.instance.setNumeralBase(NumeralBase.bin); + Assert.assertEquals("101", JsclMathEngine.instance.evaluate("10+11")); + + JsclMathEngine.instance.setNumeralBase(NumeralBase.hex); + Assert.assertEquals("56CE+CAD", processor.process("56CE+CAD").getExpression()); + } finally { + JsclMathEngine.instance.setNumeralBase(defaultNumeralBase); + } + } +}