Calculator editor
This commit is contained in:
parent
9f4b0ba4f9
commit
30fbc24f81
@ -0,0 +1,19 @@
|
|||||||
|
package org.solovyev.android.calculator;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* User: Solovyev_S
|
||||||
|
* Date: 21.09.12
|
||||||
|
* Time: 11:47
|
||||||
|
*/
|
||||||
|
public interface CalculatorEditor extends CalculatorEventListener/*, CursorControl*/ {
|
||||||
|
|
||||||
|
void setView(@Nullable CalculatorEditorView view);
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
CalculatorEditorViewState getViewState();
|
||||||
|
|
||||||
|
void setViewState(@NotNull CalculatorEditorViewState viewState);
|
||||||
|
}
|
@ -0,0 +1,87 @@
|
|||||||
|
package org.solovyev.android.calculator;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* User: Solovyev_S
|
||||||
|
* Date: 21.09.12
|
||||||
|
* Time: 11:53
|
||||||
|
*/
|
||||||
|
public class CalculatorEditorImpl implements CalculatorEditor {
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private CalculatorEditorView view;
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private final Object viewLock = new Object();
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private CalculatorEditorViewState lastViewState = CalculatorEditorViewStateImpl.newDefaultInstance();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setView(@Nullable CalculatorEditorView view) {
|
||||||
|
synchronized (viewLock) {
|
||||||
|
this.view = view;
|
||||||
|
|
||||||
|
if ( view != null ) {
|
||||||
|
view.setState(lastViewState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public CalculatorEditorViewState getViewState() {
|
||||||
|
return lastViewState;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setViewState(@NotNull CalculatorEditorViewState viewState) {
|
||||||
|
synchronized (viewLock) {
|
||||||
|
this.lastViewState = viewState;
|
||||||
|
if (this.view != null) {
|
||||||
|
this.view.setState(viewState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCalculatorEvent(@NotNull CalculatorEventData calculatorEventData,
|
||||||
|
@NotNull CalculatorEventType calculatorEventType,
|
||||||
|
@Nullable Object data) {
|
||||||
|
//To change body of implemented methods use File | Settings | File Templates.
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCursorOnStart() {
|
||||||
|
synchronized (viewLock) {
|
||||||
|
newSelectionViewState(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void newSelectionViewState(int newSelection) {
|
||||||
|
setViewState(CalculatorEditorViewStateImpl.newSelection(this.lastViewState, newSelection));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCursorOnEnd() {
|
||||||
|
synchronized (viewLock) {
|
||||||
|
newSelectionViewState(this.lastViewState.getText().length());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void moveCursorLeft() {
|
||||||
|
synchronized (viewLock) {
|
||||||
|
if (this.lastViewState.getSelection() > 0) {
|
||||||
|
newSelectionViewState(this.lastViewState.getSelection() - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void moveCursorRight() {
|
||||||
|
synchronized (viewLock) {
|
||||||
|
if (this.lastViewState.getSelection() < this.lastViewState.getText().length()) {
|
||||||
|
newSelectionViewState(this.lastViewState.getSelection() + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
package org.solovyev.android.calculator;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* User: Solovyev_S
|
||||||
|
* Date: 21.09.12
|
||||||
|
* Time: 11:48
|
||||||
|
*/
|
||||||
|
public interface CalculatorEditorView {
|
||||||
|
|
||||||
|
void setState(@NotNull CalculatorEditorViewState viewState);
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
package org.solovyev.android.calculator;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* User: Solovyev_S
|
||||||
|
* Date: 21.09.12
|
||||||
|
* Time: 11:48
|
||||||
|
*/
|
||||||
|
public interface CalculatorEditorViewState {
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
String getText();
|
||||||
|
|
||||||
|
int getSelection();
|
||||||
|
}
|
@ -0,0 +1,49 @@
|
|||||||
|
package org.solovyev.android.calculator;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* User: Solovyev_S
|
||||||
|
* Date: 21.09.12
|
||||||
|
* Time: 12:02
|
||||||
|
*/
|
||||||
|
public class CalculatorEditorViewStateImpl implements CalculatorEditorViewState {
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private String text = "";
|
||||||
|
|
||||||
|
private int selection = 0;
|
||||||
|
|
||||||
|
private CalculatorEditorViewStateImpl() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public CalculatorEditorViewStateImpl(@NotNull CalculatorEditorViewState viewState) {
|
||||||
|
this.text = viewState.getText();
|
||||||
|
this.selection = viewState.getSelection();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public String getText() {
|
||||||
|
return this.text;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSelection() {
|
||||||
|
return this.selection;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static CalculatorEditorViewState newDefaultInstance() {
|
||||||
|
return new CalculatorEditorViewStateImpl();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static CalculatorEditorViewState newSelection(@NotNull CalculatorEditorViewState viewState, int newSelection) {
|
||||||
|
final CalculatorEditorViewStateImpl result = new CalculatorEditorViewStateImpl(viewState);
|
||||||
|
|
||||||
|
result.selection = newSelection;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
@ -1,58 +1,63 @@
|
|||||||
package org.solovyev.android.calculator;
|
package org.solovyev.android.calculator;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.solovyev.android.calculator.jscl.JsclOperation;
|
import org.solovyev.android.calculator.jscl.JsclOperation;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* User: serso
|
* User: serso
|
||||||
* Date: 9/20/12
|
* Date: 9/20/12
|
||||||
* Time: 10:01 PM
|
* Time: 10:01 PM
|
||||||
*/
|
*/
|
||||||
public class CalculatorEvaluationEventDataImpl implements CalculatorEvaluationEventData {
|
public class CalculatorEvaluationEventDataImpl implements CalculatorEvaluationEventData {
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private final CalculatorEventData calculatorEventData;
|
private final CalculatorEventData calculatorEventData;
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private final JsclOperation operation;
|
private final JsclOperation operation;
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private final String expression;
|
private final String expression;
|
||||||
|
|
||||||
public CalculatorEvaluationEventDataImpl(@NotNull CalculatorEventData calculatorEventData,
|
public CalculatorEvaluationEventDataImpl(@NotNull CalculatorEventData calculatorEventData,
|
||||||
@NotNull JsclOperation operation,
|
@NotNull JsclOperation operation,
|
||||||
@NotNull String expression) {
|
@NotNull String expression) {
|
||||||
this.calculatorEventData = calculatorEventData;
|
this.calculatorEventData = calculatorEventData;
|
||||||
this.operation = operation;
|
this.operation = operation;
|
||||||
this.expression = expression;
|
this.expression = expression;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public JsclOperation getOperation() {
|
public JsclOperation getOperation() {
|
||||||
return this.operation;
|
return this.operation;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String getExpression() {
|
public String getExpression() {
|
||||||
return this.expression;
|
return this.expression;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getEventId() {
|
public long getEventId() {
|
||||||
return calculatorEventData.getEventId();
|
return calculatorEventData.getEventId();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Nullable
|
@Nullable
|
||||||
public Long getSequenceId() {
|
public Long getSequenceId() {
|
||||||
return calculatorEventData.getSequenceId();
|
return calculatorEventData.getSequenceId();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isAfter(@NotNull CalculatorEventDataId calculatorEventDataId) {
|
public boolean isAfter(@NotNull CalculatorEventDataId that) {
|
||||||
return calculatorEventData.isAfter(calculatorEventDataId);
|
return calculatorEventData.isAfter(that);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@Override
|
||||||
|
public boolean isSameSequence(@NotNull CalculatorEventDataId that) {
|
||||||
|
return this.calculatorEventData.isSameSequence(that);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,21 +1,23 @@
|
|||||||
package org.solovyev.android.calculator;
|
package org.solovyev.android.calculator;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* User: Solovyev_S
|
* User: Solovyev_S
|
||||||
* Date: 20.09.12
|
* Date: 20.09.12
|
||||||
* Time: 18:18
|
* Time: 18:18
|
||||||
*/
|
*/
|
||||||
public interface CalculatorEventDataId {
|
public interface CalculatorEventDataId {
|
||||||
|
|
||||||
// the higher id => the later event
|
// the higher id => the later event
|
||||||
long getEventId();
|
long getEventId();
|
||||||
|
|
||||||
// the higher id => the later event
|
// the higher id => the later event
|
||||||
@Nullable
|
@Nullable
|
||||||
Long getSequenceId();
|
Long getSequenceId();
|
||||||
|
|
||||||
boolean isAfter(@NotNull CalculatorEventDataId calculatorEventDataId);
|
boolean isAfter(@NotNull CalculatorEventDataId that);
|
||||||
}
|
|
||||||
|
boolean isSameSequence(@NotNull CalculatorEventDataId that);
|
||||||
|
}
|
||||||
|
@ -1,64 +1,69 @@
|
|||||||
package org.solovyev.android.calculator;
|
package org.solovyev.android.calculator;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* User: Solovyev_S
|
* User: Solovyev_S
|
||||||
* Date: 20.09.12
|
* Date: 20.09.12
|
||||||
* Time: 18:18
|
* Time: 18:18
|
||||||
*/
|
*/
|
||||||
class CalculatorEventDataIdImpl implements CalculatorEventDataId {
|
class CalculatorEventDataIdImpl implements CalculatorEventDataId {
|
||||||
|
|
||||||
private final long eventId;
|
private final long eventId;
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private final Long sequenceId;
|
private final Long sequenceId;
|
||||||
|
|
||||||
private CalculatorEventDataIdImpl(long id, @Nullable Long sequenceId) {
|
private CalculatorEventDataIdImpl(long id, @Nullable Long sequenceId) {
|
||||||
this.eventId = id;
|
this.eventId = id;
|
||||||
this.sequenceId = sequenceId;
|
this.sequenceId = sequenceId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
static CalculatorEventDataId newInstance(long id, @Nullable Long sequenceId) {
|
static CalculatorEventDataId newInstance(long id, @Nullable Long sequenceId) {
|
||||||
return new CalculatorEventDataIdImpl(id, sequenceId);
|
return new CalculatorEventDataIdImpl(id, sequenceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getEventId() {
|
public long getEventId() {
|
||||||
return this.eventId;
|
return this.eventId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public Long getSequenceId() {
|
public Long getSequenceId() {
|
||||||
return this.sequenceId;
|
return this.sequenceId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isAfter(@NotNull CalculatorEventDataId calculatorEventDataId) {
|
public boolean isAfter(@NotNull CalculatorEventDataId that) {
|
||||||
return this.eventId > calculatorEventDataId.getEventId();
|
return this.eventId > that.getEventId();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean isSameSequence(@NotNull CalculatorEventDataId that) {
|
||||||
if (this == o) return true;
|
return this.sequenceId != null && this.sequenceId.equals(that.getSequenceId());
|
||||||
if (!(o instanceof CalculatorEventDataIdImpl)) return false;
|
}
|
||||||
|
|
||||||
CalculatorEventDataIdImpl that = (CalculatorEventDataIdImpl) o;
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
if (eventId != that.eventId) return false;
|
if (this == o) return true;
|
||||||
if (sequenceId != null ? !sequenceId.equals(that.sequenceId) : that.sequenceId != null)
|
if (!(o instanceof CalculatorEventDataIdImpl)) return false;
|
||||||
return false;
|
|
||||||
|
CalculatorEventDataIdImpl that = (CalculatorEventDataIdImpl) o;
|
||||||
return true;
|
|
||||||
}
|
if (eventId != that.eventId) return false;
|
||||||
|
if (sequenceId != null ? !sequenceId.equals(that.sequenceId) : that.sequenceId != null)
|
||||||
@Override
|
return false;
|
||||||
public int hashCode() {
|
|
||||||
int result = (int) (eventId ^ (eventId >>> 32));
|
return true;
|
||||||
result = 31 * result + (sequenceId != null ? sequenceId.hashCode() : 0);
|
}
|
||||||
return result;
|
|
||||||
}
|
@Override
|
||||||
}
|
public int hashCode() {
|
||||||
|
int result = (int) (eventId ^ (eventId >>> 32));
|
||||||
|
result = 31 * result + (sequenceId != null ? sequenceId.hashCode() : 0);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,57 +1,62 @@
|
|||||||
package org.solovyev.android.calculator;
|
package org.solovyev.android.calculator;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* User: Solovyev_S
|
* User: Solovyev_S
|
||||||
* Date: 20.09.12
|
* Date: 20.09.12
|
||||||
* Time: 16:54
|
* Time: 16:54
|
||||||
*/
|
*/
|
||||||
class CalculatorEventDataImpl implements CalculatorEventData {
|
class CalculatorEventDataImpl implements CalculatorEventData {
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private CalculatorEventDataId calculatorEventDataId;
|
private CalculatorEventDataId calculatorEventDataId;
|
||||||
|
|
||||||
private CalculatorEventDataImpl(@NotNull CalculatorEventDataId calculatorEventDataId) {
|
private CalculatorEventDataImpl(@NotNull CalculatorEventDataId calculatorEventDataId) {
|
||||||
this.calculatorEventDataId = calculatorEventDataId;
|
this.calculatorEventDataId = calculatorEventDataId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static CalculatorEventData newInstance(@NotNull CalculatorEventDataId calculatorEventDataId) {
|
public static CalculatorEventData newInstance(@NotNull CalculatorEventDataId calculatorEventDataId) {
|
||||||
return new CalculatorEventDataImpl(calculatorEventDataId);
|
return new CalculatorEventDataImpl(calculatorEventDataId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getEventId() {
|
public long getEventId() {
|
||||||
return calculatorEventDataId.getEventId();
|
return calculatorEventDataId.getEventId();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Nullable
|
@Nullable
|
||||||
public Long getSequenceId() {
|
public Long getSequenceId() {
|
||||||
return calculatorEventDataId.getSequenceId();
|
return calculatorEventDataId.getSequenceId();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isAfter(@NotNull CalculatorEventDataId calculatorEventDataId) {
|
public boolean isAfter(@NotNull CalculatorEventDataId that) {
|
||||||
return this.calculatorEventDataId.isAfter(calculatorEventDataId);
|
return this.calculatorEventDataId.isAfter(that);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean isSameSequence(@NotNull CalculatorEventDataId that) {
|
||||||
if (this == o) return true;
|
return this.calculatorEventDataId.isSameSequence(that);
|
||||||
if (!(o instanceof CalculatorEventDataImpl)) return false;
|
}
|
||||||
|
|
||||||
CalculatorEventDataImpl that = (CalculatorEventDataImpl) o;
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
if (!calculatorEventDataId.equals(that.calculatorEventDataId)) return false;
|
if (this == o) return true;
|
||||||
|
if (!(o instanceof CalculatorEventDataImpl)) return false;
|
||||||
return true;
|
|
||||||
}
|
CalculatorEventDataImpl that = (CalculatorEventDataImpl) o;
|
||||||
|
|
||||||
@Override
|
if (!calculatorEventDataId.equals(that.calculatorEventDataId)) return false;
|
||||||
public int hashCode() {
|
|
||||||
return calculatorEventDataId.hashCode();
|
return true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return calculatorEventDataId.hashCode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,22 +1,25 @@
|
|||||||
package org.solovyev.android.calculator;
|
package org.solovyev.android.calculator;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* User: Solovyev_S
|
* User: Solovyev_S
|
||||||
* Date: 20.09.12
|
* Date: 20.09.12
|
||||||
* Time: 12:45
|
* Time: 12:45
|
||||||
*/
|
*/
|
||||||
public interface CalculatorLocator {
|
public interface CalculatorLocator {
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
JCalculatorEngine getCalculatorEngine();
|
JCalculatorEngine getCalculatorEngine();
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
Calculator getCalculator();
|
Calculator getCalculator();
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
CalculatorDisplay getCalculatorDisplay();
|
CalculatorDisplay getCalculatorDisplay();
|
||||||
|
|
||||||
void setCalculatorEngine(@NotNull JCalculatorEngine calculatorEngine);
|
@NotNull
|
||||||
}
|
CalculatorEditor getCalculatorEditor();
|
||||||
|
|
||||||
|
void setCalculatorEngine(@NotNull JCalculatorEngine calculatorEngine);
|
||||||
|
}
|
||||||
|
@ -1,54 +1,63 @@
|
|||||||
package org.solovyev.android.calculator;
|
package org.solovyev.android.calculator;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* User: Solovyev_S
|
* User: Solovyev_S
|
||||||
* Date: 20.09.12
|
* Date: 20.09.12
|
||||||
* Time: 12:45
|
* Time: 12:45
|
||||||
*/
|
*/
|
||||||
public class CalculatorLocatorImpl implements CalculatorLocator {
|
public class CalculatorLocatorImpl implements CalculatorLocator {
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private JCalculatorEngine calculatorEngine;
|
private JCalculatorEngine calculatorEngine;
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private CalculatorDisplay calculatorDisplay = new CalculatorDisplayImpl();
|
private final CalculatorDisplay calculatorDisplay = new CalculatorDisplayImpl();
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private Calculator calculator = new CalculatorImpl();
|
private final CalculatorEditor calculatorEditor = new CalculatorEditorImpl();
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private static final CalculatorLocator instance = new CalculatorLocatorImpl();
|
private final Calculator calculator = new CalculatorImpl();
|
||||||
|
|
||||||
private CalculatorLocatorImpl() {
|
@NotNull
|
||||||
}
|
private static final CalculatorLocator instance = new CalculatorLocatorImpl();
|
||||||
|
|
||||||
@NotNull
|
private CalculatorLocatorImpl() {
|
||||||
public static CalculatorLocator getInstance() {
|
}
|
||||||
return instance;
|
|
||||||
}
|
@NotNull
|
||||||
|
public static CalculatorLocator getInstance() {
|
||||||
@NotNull
|
return instance;
|
||||||
@Override
|
}
|
||||||
public JCalculatorEngine getCalculatorEngine() {
|
|
||||||
return calculatorEngine;
|
@NotNull
|
||||||
}
|
@Override
|
||||||
|
public JCalculatorEngine getCalculatorEngine() {
|
||||||
@NotNull
|
return calculatorEngine;
|
||||||
@Override
|
}
|
||||||
public Calculator getCalculator() {
|
|
||||||
return this.calculator;
|
@NotNull
|
||||||
}
|
@Override
|
||||||
|
public Calculator getCalculator() {
|
||||||
@Override
|
return this.calculator;
|
||||||
public void setCalculatorEngine(@NotNull JCalculatorEngine calculatorEngine) {
|
}
|
||||||
this.calculatorEngine = calculatorEngine;
|
|
||||||
}
|
@Override
|
||||||
|
public void setCalculatorEngine(@NotNull JCalculatorEngine calculatorEngine) {
|
||||||
@Override
|
this.calculatorEngine = calculatorEngine;
|
||||||
@NotNull
|
}
|
||||||
public CalculatorDisplay getCalculatorDisplay() {
|
|
||||||
return calculatorDisplay;
|
@Override
|
||||||
}
|
@NotNull
|
||||||
}
|
public CalculatorDisplay getCalculatorDisplay() {
|
||||||
|
return calculatorDisplay;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public CalculatorEditor getCalculatorEditor() {
|
||||||
|
return calculatorEditor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,144 +1,142 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2009-2011. Created by serso aka se.solovyev.
|
* Copyright (c) 2009-2011. Created by serso aka se.solovyev.
|
||||||
* For more information, please, contact se.solovyev@gmail.com
|
* For more information, please, contact se.solovyev@gmail.com
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.solovyev.android.calculator.history;
|
package org.solovyev.android.calculator.history;
|
||||||
|
|
||||||
import jscl.math.Generic;
|
import jscl.math.Generic;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.simpleframework.xml.Element;
|
import org.simpleframework.xml.Element;
|
||||||
import org.simpleframework.xml.Root;
|
import org.simpleframework.xml.Root;
|
||||||
import org.simpleframework.xml.Transient;
|
import org.simpleframework.xml.Transient;
|
||||||
import org.solovyev.android.calculator.CalculatorDisplay;
|
import org.solovyev.android.calculator.CalculatorDisplay;
|
||||||
import org.solovyev.android.calculator.CalculatorDisplayViewState;
|
import org.solovyev.android.calculator.CalculatorDisplayViewState;
|
||||||
import org.solovyev.android.calculator.CalculatorDisplayViewStateImpl;
|
import org.solovyev.android.calculator.CalculatorDisplayViewStateImpl;
|
||||||
import org.solovyev.android.calculator.jscl.JsclOperation;
|
import org.solovyev.android.calculator.jscl.JsclOperation;
|
||||||
import org.solovyev.common.text.StringUtils;
|
import org.solovyev.common.text.StringUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* User: serso
|
* User: serso
|
||||||
* Date: 9/17/11
|
* Date: 9/17/11
|
||||||
* Time: 11:05 PM
|
* Time: 11:05 PM
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@Root
|
@Root
|
||||||
public class CalculatorDisplayHistoryState implements Cloneable {
|
public class CalculatorDisplayHistoryState implements Cloneable {
|
||||||
|
|
||||||
@Transient
|
@Transient
|
||||||
private boolean valid = true;
|
private boolean valid = true;
|
||||||
|
|
||||||
@Transient
|
@Transient
|
||||||
@Nullable
|
@Nullable
|
||||||
private String errorMessage = null;
|
private String errorMessage = null;
|
||||||
|
|
||||||
@Element
|
@Element
|
||||||
@NotNull
|
@NotNull
|
||||||
private EditorHistoryState editorState;
|
private EditorHistoryState editorState;
|
||||||
|
|
||||||
@Element
|
@Element
|
||||||
@NotNull
|
@NotNull
|
||||||
private JsclOperation jsclOperation;
|
private JsclOperation jsclOperation;
|
||||||
|
|
||||||
@Transient
|
@Transient
|
||||||
@Nullable
|
@Nullable
|
||||||
private Generic genericResult;
|
private Generic genericResult;
|
||||||
|
|
||||||
private CalculatorDisplayHistoryState() {
|
private CalculatorDisplayHistoryState() {
|
||||||
// for xml
|
// for xml
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static CalculatorDisplayHistoryState newInstance(@NotNull CalculatorDisplay display) {
|
public static CalculatorDisplayHistoryState newInstance(@NotNull CalculatorDisplayViewState viewState) {
|
||||||
final CalculatorDisplayHistoryState result = new CalculatorDisplayHistoryState();
|
final CalculatorDisplayHistoryState result = new CalculatorDisplayHistoryState();
|
||||||
|
|
||||||
result.editorState = EditorHistoryState.newInstance(display.getViewState());
|
result.editorState = EditorHistoryState.newInstance(viewState);
|
||||||
|
|
||||||
final CalculatorDisplayViewState displayViewState = display.getViewState();
|
result.valid = viewState.isValid();
|
||||||
|
result.jsclOperation = viewState.getOperation();
|
||||||
result.valid = displayViewState.isValid();
|
result.genericResult = viewState.getResult();
|
||||||
result.jsclOperation = displayViewState.getOperation();
|
result.errorMessage = viewState.getErrorMessage();
|
||||||
result.genericResult = displayViewState.getResult();
|
|
||||||
result.errorMessage = displayViewState.getErrorMessage();
|
return result;
|
||||||
|
}
|
||||||
return result;
|
|
||||||
}
|
public void setValuesFromHistory(@NotNull CalculatorDisplay display) {
|
||||||
|
if ( this.isValid() ) {
|
||||||
public void setValuesFromHistory(@NotNull CalculatorDisplay display) {
|
display.setViewState(CalculatorDisplayViewStateImpl.newValidState(this.getJsclOperation(), this.getGenericResult(), StringUtils.getNotEmpty(this.getEditorState().getText(), ""), this.getEditorState().getCursorPosition()));
|
||||||
if ( this.isValid() ) {
|
} else {
|
||||||
display.setViewState(CalculatorDisplayViewStateImpl.newValidState(this.getJsclOperation(), this.getGenericResult(), StringUtils.getNotEmpty(this.getEditorState().getText(), ""), this.getEditorState().getCursorPosition()));
|
display.setViewState(CalculatorDisplayViewStateImpl.newErrorState(this.getJsclOperation(), StringUtils.getNotEmpty(this.getErrorMessage(), "")));
|
||||||
} else {
|
}
|
||||||
display.setViewState(CalculatorDisplayViewStateImpl.newErrorState(this.getJsclOperation(), StringUtils.getNotEmpty(this.getErrorMessage(), "")));
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
public boolean isValid() {
|
||||||
|
return valid;
|
||||||
public boolean isValid() {
|
}
|
||||||
return valid;
|
|
||||||
}
|
@NotNull
|
||||||
|
public EditorHistoryState getEditorState() {
|
||||||
@NotNull
|
return editorState;
|
||||||
public EditorHistoryState getEditorState() {
|
}
|
||||||
return editorState;
|
|
||||||
}
|
@NotNull
|
||||||
|
public JsclOperation getJsclOperation() {
|
||||||
@NotNull
|
return jsclOperation;
|
||||||
public JsclOperation getJsclOperation() {
|
}
|
||||||
return jsclOperation;
|
|
||||||
}
|
@Nullable
|
||||||
|
public String getErrorMessage() {
|
||||||
@Nullable
|
return errorMessage;
|
||||||
public String getErrorMessage() {
|
}
|
||||||
return errorMessage;
|
|
||||||
}
|
@Nullable
|
||||||
|
public Generic getGenericResult() {
|
||||||
@Nullable
|
return genericResult;
|
||||||
public Generic getGenericResult() {
|
}
|
||||||
return genericResult;
|
|
||||||
}
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
@Override
|
if (this == o) return true;
|
||||||
public boolean equals(Object o) {
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
if (this == o) return true;
|
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
CalculatorDisplayHistoryState that = (CalculatorDisplayHistoryState) o;
|
||||||
|
|
||||||
CalculatorDisplayHistoryState that = (CalculatorDisplayHistoryState) o;
|
if (!editorState.equals(that.editorState)) return false;
|
||||||
|
if (jsclOperation != that.jsclOperation) return false;
|
||||||
if (!editorState.equals(that.editorState)) return false;
|
|
||||||
if (jsclOperation != that.jsclOperation) return false;
|
return true;
|
||||||
|
}
|
||||||
return true;
|
|
||||||
}
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
@Override
|
int result = editorState.hashCode();
|
||||||
public int hashCode() {
|
result = 31 * result + jsclOperation.hashCode();
|
||||||
int result = editorState.hashCode();
|
return result;
|
||||||
result = 31 * result + jsclOperation.hashCode();
|
}
|
||||||
return result;
|
|
||||||
}
|
@Override
|
||||||
|
public String toString() {
|
||||||
@Override
|
return "CalculatorDisplayHistoryState{" +
|
||||||
public String toString() {
|
"valid=" + valid +
|
||||||
return "CalculatorDisplayHistoryState{" +
|
", errorMessage='" + errorMessage + '\'' +
|
||||||
"valid=" + valid +
|
", editorHistoryState=" + editorState +
|
||||||
", errorMessage='" + errorMessage + '\'' +
|
", jsclOperation=" + jsclOperation +
|
||||||
", editorHistoryState=" + editorState +
|
'}';
|
||||||
", jsclOperation=" + jsclOperation +
|
}
|
||||||
'}';
|
|
||||||
}
|
@Override
|
||||||
|
protected CalculatorDisplayHistoryState clone() {
|
||||||
@Override
|
try {
|
||||||
protected CalculatorDisplayHistoryState clone() {
|
final CalculatorDisplayHistoryState clone = (CalculatorDisplayHistoryState) super.clone();
|
||||||
try {
|
|
||||||
final CalculatorDisplayHistoryState clone = (CalculatorDisplayHistoryState) super.clone();
|
clone.editorState = this.editorState.clone();
|
||||||
|
|
||||||
clone.editorState = this.editorState.clone();
|
return clone;
|
||||||
|
} catch (CloneNotSupportedException e) {
|
||||||
return clone;
|
throw new RuntimeException(e);
|
||||||
} catch (CloneNotSupportedException e) {
|
}
|
||||||
throw new RuntimeException(e);
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package org.solovyev.android.calculator.history;
|
package org.solovyev.android.calculator.history;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.solovyev.android.calculator.CalculatorEventListener;
|
||||||
import org.solovyev.common.history.HistoryHelper;
|
import org.solovyev.common.history.HistoryHelper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -8,7 +9,7 @@ import org.solovyev.common.history.HistoryHelper;
|
|||||||
* Date: 20.09.12
|
* Date: 20.09.12
|
||||||
* Time: 16:11
|
* Time: 16:11
|
||||||
*/
|
*/
|
||||||
public interface CalculatorHistory extends HistoryHelper<CalculatorHistoryState> {
|
public interface CalculatorHistory extends HistoryHelper<CalculatorHistoryState>, CalculatorEventListener {
|
||||||
|
|
||||||
void fromXml(@NotNull String xml);
|
void fromXml(@NotNull String xml);
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ package org.solovyev.android.calculator.history;
|
|||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.solovyev.android.calculator.*;
|
||||||
import org.solovyev.common.history.HistoryAction;
|
import org.solovyev.common.history.HistoryAction;
|
||||||
import org.solovyev.common.history.HistoryHelper;
|
import org.solovyev.common.history.HistoryHelper;
|
||||||
import org.solovyev.common.history.SimpleHistoryHelper;
|
import org.solovyev.common.history.SimpleHistoryHelper;
|
||||||
@ -26,6 +27,9 @@ public class CalculatorHistoryImpl implements CalculatorHistory {
|
|||||||
@NotNull
|
@NotNull
|
||||||
private final List<CalculatorHistoryState> savedHistory = new ArrayList<CalculatorHistoryState>();
|
private final List<CalculatorHistoryState> savedHistory = new ArrayList<CalculatorHistoryState>();
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private CalculatorEventDataId lastEventDataId = CalculatorLocatorImpl.getInstance().getCalculator().createFirstEventDataId();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isEmpty() {
|
public boolean isEmpty() {
|
||||||
return this.history.isEmpty();
|
return this.history.isEmpty();
|
||||||
@ -128,4 +132,26 @@ public class CalculatorHistoryImpl implements CalculatorHistory {
|
|||||||
public void removeSavedHistory(@NotNull CalculatorHistoryState historyState) {
|
public void removeSavedHistory(@NotNull CalculatorHistoryState historyState) {
|
||||||
this.savedHistory.remove(historyState);
|
this.savedHistory.remove(historyState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCalculatorEvent(@NotNull CalculatorEventData calculatorEventData,
|
||||||
|
@NotNull CalculatorEventType calculatorEventType,
|
||||||
|
@Nullable Object data) {
|
||||||
|
if (calculatorEventType.isOfType(CalculatorEventType.calculation_started, CalculatorEventType.calculation_result, CalculatorEventType.calculation_failed)) {
|
||||||
|
|
||||||
|
if ( calculatorEventData.isAfter(this.lastEventDataId) ) {
|
||||||
|
|
||||||
|
switch (calculatorEventType) {
|
||||||
|
case calculation_started:
|
||||||
|
CalculatorHistoryState.newInstance()
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
CalculatorLocatorImpl.getInstance().getCalculatorDisplay().get
|
||||||
|
CalculatorHistoryState.newInstance(new TextViewEditorAdapter(this.editor), display);
|
||||||
|
|
||||||
|
this.lastEventDataId = calculatorEventData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,111 +1,115 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2009-2011. Created by serso aka se.solovyev.
|
* Copyright (c) 2009-2011. Created by serso aka se.solovyev.
|
||||||
* For more information, please, contact se.solovyev@gmail.com
|
* For more information, please, contact se.solovyev@gmail.com
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.solovyev.android.calculator.history;
|
package org.solovyev.android.calculator.history;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.simpleframework.xml.Element;
|
import org.simpleframework.xml.Element;
|
||||||
import org.simpleframework.xml.Root;
|
import org.simpleframework.xml.Root;
|
||||||
import org.solovyev.android.calculator.CalculatorDisplay;
|
import org.solovyev.android.calculator.CalculatorDisplay;
|
||||||
import org.solovyev.android.calculator.Editor;
|
import org.solovyev.android.calculator.CalculatorEditor;
|
||||||
|
import org.solovyev.android.calculator.Editor;
|
||||||
/**
|
|
||||||
* User: serso
|
/**
|
||||||
* Date: 9/11/11
|
* User: serso
|
||||||
* Time: 12:16 AM
|
* Date: 9/11/11
|
||||||
*/
|
* Time: 12:16 AM
|
||||||
|
*/
|
||||||
@Root
|
|
||||||
public class CalculatorHistoryState extends AbstractHistoryState {
|
@Root
|
||||||
|
public class CalculatorHistoryState extends AbstractHistoryState {
|
||||||
@Element
|
|
||||||
@NotNull
|
@Element
|
||||||
private EditorHistoryState editorState;
|
@NotNull
|
||||||
|
private EditorHistoryState editorState;
|
||||||
@Element
|
|
||||||
@NotNull
|
@Element
|
||||||
private CalculatorDisplayHistoryState displayState;
|
@NotNull
|
||||||
|
private CalculatorDisplayHistoryState displayState;
|
||||||
private CalculatorHistoryState() {
|
|
||||||
// for xml
|
private CalculatorHistoryState() {
|
||||||
}
|
// for xml
|
||||||
|
}
|
||||||
private CalculatorHistoryState(@NotNull EditorHistoryState editorState,
|
|
||||||
@NotNull CalculatorDisplayHistoryState displayState) {
|
private CalculatorHistoryState(@NotNull EditorHistoryState editorState,
|
||||||
this.editorState = editorState;
|
@NotNull CalculatorDisplayHistoryState displayState) {
|
||||||
this.displayState = displayState;
|
this.editorState = editorState;
|
||||||
}
|
this.displayState = displayState;
|
||||||
|
}
|
||||||
public static CalculatorHistoryState newInstance(@NotNull Editor editor, @NotNull CalculatorDisplay display) {
|
|
||||||
final EditorHistoryState editorHistoryState = EditorHistoryState.newInstance(editor);
|
public static CalculatorHistoryState newInstance(@NotNull CalculatorEditor editor,
|
||||||
final CalculatorDisplayHistoryState displayHistoryState = CalculatorDisplayHistoryState.newInstance(display);
|
@NotNull CalculatorDisplay display) {
|
||||||
return new CalculatorHistoryState(editorHistoryState, displayHistoryState);
|
final EditorHistoryState editorHistoryState = EditorHistoryState.newInstance(editor.getViewState());
|
||||||
}
|
|
||||||
|
final CalculatorDisplayHistoryState displayHistoryState = CalculatorDisplayHistoryState.newInstance(display.getViewState());
|
||||||
@NotNull
|
|
||||||
public EditorHistoryState getEditorState() {
|
return new CalculatorHistoryState(editorHistoryState, displayHistoryState);
|
||||||
return editorState;
|
}
|
||||||
}
|
|
||||||
|
@NotNull
|
||||||
public void setEditorState(@NotNull EditorHistoryState editorState) {
|
public EditorHistoryState getEditorState() {
|
||||||
this.editorState = editorState;
|
return editorState;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
public void setEditorState(@NotNull EditorHistoryState editorState) {
|
||||||
public CalculatorDisplayHistoryState getDisplayState() {
|
this.editorState = editorState;
|
||||||
return displayState;
|
}
|
||||||
}
|
|
||||||
|
@NotNull
|
||||||
public void setDisplayState(@NotNull CalculatorDisplayHistoryState displayState) {
|
public CalculatorDisplayHistoryState getDisplayState() {
|
||||||
this.displayState = displayState;
|
return displayState;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void setDisplayState(@NotNull CalculatorDisplayHistoryState displayState) {
|
||||||
public String toString() {
|
this.displayState = displayState;
|
||||||
return "CalculatorHistoryState{" +
|
}
|
||||||
"editorState=" + editorState +
|
|
||||||
", displayState=" + displayState +
|
@Override
|
||||||
'}';
|
public String toString() {
|
||||||
}
|
return "CalculatorHistoryState{" +
|
||||||
|
"editorState=" + editorState +
|
||||||
@Override
|
", displayState=" + displayState +
|
||||||
public boolean equals(Object o) {
|
'}';
|
||||||
if (this == o) return true;
|
}
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
|
||||||
|
@Override
|
||||||
CalculatorHistoryState that = (CalculatorHistoryState) o;
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
if (this.isSaved() != that.isSaved()) return false;
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
if (this.getId() != that.getId()) return false;
|
|
||||||
if (!displayState.equals(that.displayState)) return false;
|
CalculatorHistoryState that = (CalculatorHistoryState) o;
|
||||||
if (!editorState.equals(that.editorState)) return false;
|
|
||||||
|
if (this.isSaved() != that.isSaved()) return false;
|
||||||
return true;
|
if (this.getId() != that.getId()) return false;
|
||||||
}
|
if (!displayState.equals(that.displayState)) return false;
|
||||||
|
if (!editorState.equals(that.editorState)) return false;
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
return true;
|
||||||
int result = Boolean.valueOf(isSaved()).hashCode();
|
}
|
||||||
result = 31 * result + getId();
|
|
||||||
result = 31 * result + editorState.hashCode();
|
@Override
|
||||||
result = 31 * result + displayState.hashCode();
|
public int hashCode() {
|
||||||
return result;
|
int result = Boolean.valueOf(isSaved()).hashCode();
|
||||||
}
|
result = 31 * result + getId();
|
||||||
|
result = 31 * result + editorState.hashCode();
|
||||||
public void setValuesFromHistory(@NotNull Editor editor, @NotNull CalculatorDisplay display) {
|
result = 31 * result + displayState.hashCode();
|
||||||
this.getEditorState().setValuesFromHistory(editor);
|
return result;
|
||||||
this.getDisplayState().setValuesFromHistory(display);
|
}
|
||||||
}
|
|
||||||
|
public void setValuesFromHistory(@NotNull Editor editor, @NotNull CalculatorDisplay display) {
|
||||||
@Override
|
this.getEditorState().setValuesFromHistory(editor);
|
||||||
protected CalculatorHistoryState clone() {
|
this.getDisplayState().setValuesFromHistory(display);
|
||||||
final CalculatorHistoryState clone = (CalculatorHistoryState)super.clone();
|
}
|
||||||
|
|
||||||
clone.editorState = this.editorState.clone();
|
@Override
|
||||||
clone.displayState = this.displayState.clone();
|
protected CalculatorHistoryState clone() {
|
||||||
|
final CalculatorHistoryState clone = (CalculatorHistoryState)super.clone();
|
||||||
return clone;
|
|
||||||
}
|
clone.editorState = this.editorState.clone();
|
||||||
}
|
clone.displayState = this.displayState.clone();
|
||||||
|
|
||||||
|
return clone;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,99 +1,100 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2009-2011. Created by serso aka se.solovyev.
|
* Copyright (c) 2009-2011. Created by serso aka se.solovyev.
|
||||||
* For more information, please, contact se.solovyev@gmail.com
|
* For more information, please, contact se.solovyev@gmail.com
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.solovyev.android.calculator.history;
|
package org.solovyev.android.calculator.history;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.simpleframework.xml.Element;
|
import org.simpleframework.xml.Element;
|
||||||
import org.simpleframework.xml.Root;
|
import org.simpleframework.xml.Root;
|
||||||
import org.solovyev.android.calculator.CalculatorDisplayViewState;
|
import org.solovyev.android.calculator.CalculatorDisplayViewState;
|
||||||
import org.solovyev.android.calculator.Editor;
|
import org.solovyev.android.calculator.CalculatorEditorViewState;
|
||||||
|
import org.solovyev.android.calculator.Editor;
|
||||||
@Root
|
|
||||||
public class EditorHistoryState implements Cloneable{
|
@Root
|
||||||
|
public class EditorHistoryState implements Cloneable{
|
||||||
@Element
|
|
||||||
private int cursorPosition;
|
@Element
|
||||||
|
private int cursorPosition;
|
||||||
@Element(required = false)
|
|
||||||
@Nullable
|
@Element(required = false)
|
||||||
private String text;
|
@Nullable
|
||||||
|
private String text;
|
||||||
private EditorHistoryState() {
|
|
||||||
// for xml
|
private EditorHistoryState() {
|
||||||
}
|
// for xml
|
||||||
|
}
|
||||||
@NotNull
|
|
||||||
public static EditorHistoryState newInstance(@NotNull Editor editor) {
|
@NotNull
|
||||||
final EditorHistoryState result = new EditorHistoryState();
|
public static EditorHistoryState newInstance(@NotNull CalculatorEditorViewState viewState) {
|
||||||
|
final EditorHistoryState result = new EditorHistoryState();
|
||||||
result.text = String.valueOf(editor.getText());
|
|
||||||
result.cursorPosition = editor.getSelection();
|
result.text = String.valueOf(viewState.getText());
|
||||||
|
result.cursorPosition = viewState.getSelection();
|
||||||
return result;
|
|
||||||
}
|
return result;
|
||||||
|
}
|
||||||
@NotNull
|
|
||||||
public static EditorHistoryState newInstance(@NotNull CalculatorDisplayViewState viewState) {
|
@NotNull
|
||||||
final EditorHistoryState result = new EditorHistoryState();
|
public static EditorHistoryState newInstance(@NotNull CalculatorDisplayViewState viewState) {
|
||||||
|
final EditorHistoryState result = new EditorHistoryState();
|
||||||
result.text = viewState.getText();
|
|
||||||
result.cursorPosition = viewState.getSelection();
|
result.text = viewState.getText();
|
||||||
|
result.cursorPosition = viewState.getSelection();
|
||||||
return result;
|
|
||||||
}
|
return result;
|
||||||
|
}
|
||||||
public void setValuesFromHistory(@NotNull Editor editor) {
|
|
||||||
editor.setText(this.getText());
|
public void setValuesFromHistory(@NotNull Editor editor) {
|
||||||
editor.setSelection(this.getCursorPosition());
|
editor.setText(this.getText());
|
||||||
}
|
editor.setSelection(this.getCursorPosition());
|
||||||
|
}
|
||||||
@Nullable
|
|
||||||
public String getText() {
|
@Nullable
|
||||||
return text;
|
public String getText() {
|
||||||
}
|
return text;
|
||||||
|
}
|
||||||
public int getCursorPosition() {
|
|
||||||
return cursorPosition;
|
public int getCursorPosition() {
|
||||||
}
|
return cursorPosition;
|
||||||
|
}
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
@Override
|
||||||
if (this == o) return true;
|
public boolean equals(Object o) {
|
||||||
if (!(o instanceof EditorHistoryState)) return false;
|
if (this == o) return true;
|
||||||
|
if (!(o instanceof EditorHistoryState)) return false;
|
||||||
EditorHistoryState that = (EditorHistoryState) o;
|
|
||||||
|
EditorHistoryState that = (EditorHistoryState) o;
|
||||||
if (cursorPosition != that.cursorPosition) return false;
|
|
||||||
if (text != null ? !text.equals(that.text) : that.text != null) return false;
|
if (cursorPosition != that.cursorPosition) return false;
|
||||||
|
if (text != null ? !text.equals(that.text) : that.text != null) return false;
|
||||||
return true;
|
|
||||||
}
|
return true;
|
||||||
|
}
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
@Override
|
||||||
int result = cursorPosition;
|
public int hashCode() {
|
||||||
result = 31 * result + (text != null ? text.hashCode() : 0);
|
int result = cursorPosition;
|
||||||
return result;
|
result = 31 * result + (text != null ? text.hashCode() : 0);
|
||||||
}
|
return result;
|
||||||
|
}
|
||||||
@Override
|
|
||||||
public String toString() {
|
@Override
|
||||||
return "EditorHistoryState{" +
|
public String toString() {
|
||||||
"cursorPosition=" + cursorPosition +
|
return "EditorHistoryState{" +
|
||||||
", text='" + text + '\'' +
|
"cursorPosition=" + cursorPosition +
|
||||||
'}';
|
", text='" + text + '\'' +
|
||||||
}
|
'}';
|
||||||
|
}
|
||||||
@Override
|
|
||||||
protected EditorHistoryState clone() {
|
@Override
|
||||||
try {
|
protected EditorHistoryState clone() {
|
||||||
return (EditorHistoryState)super.clone();
|
try {
|
||||||
} catch (CloneNotSupportedException e) {
|
return (EditorHistoryState)super.clone();
|
||||||
throw new UnsupportedOperationException(e);
|
} catch (CloneNotSupportedException e) {
|
||||||
}
|
throw new UnsupportedOperationException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
@ -1,22 +1,22 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
~ Copyright (c) 2009-2011. Created by serso aka se.solovyev.
|
~ Copyright (c) 2009-2011. Created by serso aka se.solovyev.
|
||||||
~ For more information, please, contact se.solovyev@gmail.com
|
~ For more information, please, contact se.solovyev@gmail.com
|
||||||
~ or visit http://se.solovyev.org
|
~ or visit http://se.solovyev.org
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<LinearLayout xmlns:a="http://schemas.android.com/apk/res/android"
|
<LinearLayout xmlns:a="http://schemas.android.com/apk/res/android"
|
||||||
a:layout_weight="2"
|
a:layout_weight="2"
|
||||||
a:layout_width="fill_parent"
|
a:layout_width="fill_parent"
|
||||||
a:layout_height="0dp">
|
a:layout_height="0dp">
|
||||||
|
|
||||||
<org.solovyev.android.calculator.CalculatorEditor
|
<org.solovyev.android.calculator.AndroidCalculatorEditorView
|
||||||
a:id="@+id/calculatorEditor"
|
a:id="@+id/calculatorEditor"
|
||||||
style="@style/editor_style"
|
style="@style/editor_style"
|
||||||
a:textIsSelectable="true"
|
a:textIsSelectable="true"
|
||||||
a:singleLine="false"
|
a:singleLine="false"
|
||||||
a:scrollbars="vertical"
|
a:scrollbars="vertical"
|
||||||
a:hint ="@string/c_calc_editor_hint"/>
|
a:hint ="@string/c_calc_editor_hint"/>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
@ -1,235 +1,150 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2009-2011. Created by serso aka se.solovyev.
|
* Copyright (c) 2009-2011. Created by serso aka se.solovyev.
|
||||||
* For more information, please, contact se.solovyev@gmail.com
|
* For more information, please, contact se.solovyev@gmail.com
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.solovyev.android.calculator;
|
package org.solovyev.android.calculator;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.text.Html;
|
import android.os.Handler;
|
||||||
import android.util.AttributeSet;
|
import android.text.Html;
|
||||||
import android.util.Log;
|
import android.util.AttributeSet;
|
||||||
import jscl.math.Generic;
|
import android.util.Log;
|
||||||
import jscl.math.function.Constant;
|
import jscl.math.Generic;
|
||||||
import jscl.math.function.IConstant;
|
import jscl.math.function.Constant;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import jscl.math.function.IConstant;
|
||||||
import org.solovyev.android.calculator.jscl.JsclOperation;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.solovyev.android.calculator.model.CalculatorEngine;
|
import org.solovyev.android.calculator.jscl.JsclOperation;
|
||||||
import org.solovyev.android.calculator.text.TextProcessor;
|
import org.solovyev.android.calculator.model.CalculatorEngine;
|
||||||
import org.solovyev.android.calculator.view.NumeralBaseConverterDialog;
|
import org.solovyev.android.calculator.text.TextProcessor;
|
||||||
import org.solovyev.android.calculator.view.TextHighlighter;
|
import org.solovyev.android.calculator.view.NumeralBaseConverterDialog;
|
||||||
import org.solovyev.android.menu.LabeledMenuItem;
|
import org.solovyev.android.calculator.view.TextHighlighter;
|
||||||
import org.solovyev.android.view.AutoResizeTextView;
|
import org.solovyev.android.menu.LabeledMenuItem;
|
||||||
import org.solovyev.common.collections.CollectionsUtils;
|
import org.solovyev.android.view.AutoResizeTextView;
|
||||||
|
import org.solovyev.common.collections.CollectionsUtils;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
/**
|
|
||||||
* User: serso
|
/**
|
||||||
* Date: 9/17/11
|
* User: serso
|
||||||
* Time: 10:58 PM
|
* Date: 9/17/11
|
||||||
*/
|
* Time: 10:58 PM
|
||||||
public class AndroidCalculatorDisplayView extends AutoResizeTextView implements CalculatorDisplayView {
|
*/
|
||||||
|
public class AndroidCalculatorDisplayView extends AutoResizeTextView implements CalculatorDisplayView {
|
||||||
public static enum MenuItem implements LabeledMenuItem<CalculatorDisplayViewState> {
|
|
||||||
|
/*
|
||||||
copy(R.string.c_copy) {
|
**********************************************************************
|
||||||
@Override
|
*
|
||||||
public void onClick(@NotNull CalculatorDisplayViewState data, @NotNull Context context) {
|
* STATIC FIELDS
|
||||||
CalculatorModel.copyResult(context, data);
|
*
|
||||||
}
|
**********************************************************************
|
||||||
},
|
*/
|
||||||
|
|
||||||
convert_to_bin(R.string.convert_to_bin) {
|
@NotNull
|
||||||
@Override
|
private final static TextProcessor<TextHighlighter.Result, String> textHighlighter = new TextHighlighter(Color.WHITE, false, CalculatorEngine.instance.getEngine());
|
||||||
public void onClick(@NotNull CalculatorDisplayViewState data, @NotNull Context context) {
|
|
||||||
ConversionMenuItem.convert_to_bin.onClick(data, context);
|
/*
|
||||||
}
|
**********************************************************************
|
||||||
|
*
|
||||||
@Override
|
* FIELDS
|
||||||
protected boolean isItemVisibleFor(@NotNull Generic generic, @NotNull JsclOperation operation) {
|
*
|
||||||
return ConversionMenuItem.convert_to_bin.isItemVisibleFor(generic, operation);
|
**********************************************************************
|
||||||
}
|
*/
|
||||||
},
|
|
||||||
|
@NotNull
|
||||||
convert_to_dec(R.string.convert_to_dec) {
|
private CalculatorDisplayViewState state = CalculatorDisplayViewStateImpl.newDefaultInstance();
|
||||||
@Override
|
|
||||||
public void onClick(@NotNull CalculatorDisplayViewState data, @NotNull Context context) {
|
@NotNull
|
||||||
ConversionMenuItem.convert_to_dec.onClick(data, context);
|
private final Object lock = new Object();
|
||||||
}
|
|
||||||
|
@NotNull
|
||||||
@Override
|
private final Handler handler = new Handler();
|
||||||
protected boolean isItemVisibleFor(@NotNull Generic generic, @NotNull JsclOperation operation) {
|
|
||||||
return ConversionMenuItem.convert_to_dec.isItemVisibleFor(generic, operation);
|
/*
|
||||||
}
|
**********************************************************************
|
||||||
},
|
*
|
||||||
|
* CONSTRUCTORS
|
||||||
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);
|
|
||||||
}
|
public AndroidCalculatorDisplayView(Context context) {
|
||||||
|
super(context);
|
||||||
@Override
|
}
|
||||||
protected boolean isItemVisibleFor(@NotNull Generic generic, @NotNull JsclOperation operation) {
|
|
||||||
return ConversionMenuItem.convert_to_hex.isItemVisibleFor(generic, operation);
|
public AndroidCalculatorDisplayView(Context context, AttributeSet attrs) {
|
||||||
}
|
super(context, attrs);
|
||||||
},
|
}
|
||||||
|
|
||||||
convert(R.string.c_convert) {
|
public AndroidCalculatorDisplayView(Context context, AttributeSet attrs, int defStyle) {
|
||||||
@Override
|
super(context, attrs, defStyle);
|
||||||
public void onClick(@NotNull CalculatorDisplayViewState data, @NotNull Context context) {
|
}
|
||||||
final Generic result = data.getResult();
|
|
||||||
if (result != null) {
|
/*
|
||||||
new NumeralBaseConverterDialog(result.toString()).show(context);
|
**********************************************************************
|
||||||
}
|
*
|
||||||
}
|
* METHODS
|
||||||
|
*
|
||||||
@Override
|
**********************************************************************
|
||||||
protected boolean isItemVisibleFor(@NotNull Generic generic, @NotNull JsclOperation operation) {
|
*/
|
||||||
return operation == JsclOperation.numeric && generic.getConstants().isEmpty();
|
|
||||||
}
|
public boolean isValid() {
|
||||||
},
|
synchronized (lock) {
|
||||||
|
return this.state.isValid();
|
||||||
plot(R.string.c_plot) {
|
}
|
||||||
@Override
|
}
|
||||||
public void onClick(@NotNull CalculatorDisplayViewState data, @NotNull Context context) {
|
|
||||||
final Generic generic = data.getResult();
|
@Override
|
||||||
assert generic != null;
|
public void setState(@NotNull final CalculatorDisplayViewState state) {
|
||||||
|
handler.postDelayed(new Runnable() {
|
||||||
final Constant constant = CollectionsUtils.getFirstCollectionElement(getNotSystemConstants(generic));
|
@Override
|
||||||
assert constant != null;
|
public void run() {
|
||||||
CalculatorActivityLauncher.plotGraph(context, generic, constant);
|
synchronized (lock) {
|
||||||
}
|
AndroidCalculatorDisplayView.this.state = state;
|
||||||
|
if ( state.isValid() ) {
|
||||||
@Override
|
setTextColor(getResources().getColor(R.color.default_text_color));
|
||||||
protected boolean isItemVisibleFor(@NotNull Generic generic, @NotNull JsclOperation operation) {
|
setText(state.getStringResult());
|
||||||
boolean result = false;
|
redraw();
|
||||||
|
} else {
|
||||||
if (operation == JsclOperation.simplify) {
|
setTextColor(getResources().getColor(R.color.display_error_text_color));
|
||||||
if (getNotSystemConstants(generic).size() == 1) {
|
setText(state.getErrorMessage());
|
||||||
result = true;
|
redraw();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return result;
|
}, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private Set<Constant> getNotSystemConstants(@NotNull Generic generic) {
|
@Override
|
||||||
final Set<Constant> notSystemConstants = new HashSet<Constant>();
|
public CalculatorDisplayViewState getState() {
|
||||||
|
synchronized (lock) {
|
||||||
for (Constant constant : generic.getConstants()) {
|
return this.state;
|
||||||
IConstant var = CalculatorEngine.instance.getVarsRegistry().get(constant.getName());
|
}
|
||||||
if (var != null && !var.isSystem() && !var.isDefined()) {
|
}
|
||||||
notSystemConstants.add(constant);
|
|
||||||
}
|
private synchronized void redraw() {
|
||||||
}
|
if (isValid()) {
|
||||||
|
String text = getText().toString();
|
||||||
return notSystemConstants;
|
|
||||||
}
|
Log.d(this.getClass().getName(), text);
|
||||||
};
|
|
||||||
|
try {
|
||||||
private final int captionId;
|
TextHighlighter.Result result = textHighlighter.process(text);
|
||||||
|
text = result.toString();
|
||||||
MenuItem(int captionId) {
|
} catch (CalculatorParseException e) {
|
||||||
this.captionId = captionId;
|
Log.e(this.getClass().getName(), e.getMessage(), e);
|
||||||
}
|
}
|
||||||
|
|
||||||
public final boolean isItemVisible(@NotNull CalculatorDisplayViewState displayViewState) {
|
Log.d(this.getClass().getName(), text);
|
||||||
//noinspection ConstantConditions
|
super.setText(Html.fromHtml(text), BufferType.EDITABLE);
|
||||||
return displayViewState.isValid() && displayViewState.getResult() != null && isItemVisibleFor(displayViewState.getResult(), displayViewState.getOperation());
|
}
|
||||||
}
|
|
||||||
|
// todo serso: think where to move it (keep in mind org.solovyev.android.view.AutoResizeTextView.resetTextSize())
|
||||||
protected boolean isItemVisibleFor(@NotNull Generic generic, @NotNull JsclOperation operation) {
|
setAddEllipsis(false);
|
||||||
return true;
|
setMinTextSize(10);
|
||||||
}
|
resizeText();
|
||||||
|
}
|
||||||
@NotNull
|
}
|
||||||
@Override
|
|
||||||
public String getCaption(@NotNull Context context) {
|
|
||||||
return context.getString(captionId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private CalculatorDisplayViewState state = CalculatorDisplayViewStateImpl.newDefaultInstance();
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private final static TextProcessor<TextHighlighter.Result, String> textHighlighter = new TextHighlighter(Color.WHITE, false, CalculatorEngine.instance.getEngine());
|
|
||||||
|
|
||||||
public AndroidCalculatorDisplayView(Context context) {
|
|
||||||
super(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
public AndroidCalculatorDisplayView(Context context, AttributeSet attrs) {
|
|
||||||
super(context, attrs);
|
|
||||||
}
|
|
||||||
|
|
||||||
public AndroidCalculatorDisplayView(Context context, AttributeSet attrs, int defStyle) {
|
|
||||||
super(context, attrs, defStyle);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isValid() {
|
|
||||||
return this.state.isValid();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setState(@NotNull CalculatorDisplayViewState state) {
|
|
||||||
this.state = state;
|
|
||||||
if ( state.isValid() ) {
|
|
||||||
setTextColor(getResources().getColor(R.color.default_text_color));
|
|
||||||
setText(state.getStringResult());
|
|
||||||
} else {
|
|
||||||
setTextColor(getResources().getColor(R.color.display_error_text_color));
|
|
||||||
setText(state.getErrorMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Override
|
|
||||||
public CalculatorDisplayViewState getState() {
|
|
||||||
return this.state;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setText(CharSequence text, BufferType type) {
|
|
||||||
super.setText(text, type);
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized void redraw() {
|
|
||||||
if (isValid()) {
|
|
||||||
String text = getText().toString();
|
|
||||||
|
|
||||||
Log.d(this.getClass().getName(), text);
|
|
||||||
|
|
||||||
try {
|
|
||||||
TextHighlighter.Result result = textHighlighter.process(text);
|
|
||||||
text = result.toString();
|
|
||||||
} catch (CalculatorParseException e) {
|
|
||||||
Log.e(this.getClass().getName(), e.getMessage(), e);
|
|
||||||
}
|
|
||||||
|
|
||||||
Log.d(this.getClass().getName(), text);
|
|
||||||
super.setText(Html.fromHtml(text), BufferType.EDITABLE);
|
|
||||||
}
|
|
||||||
|
|
||||||
// todo serso: think where to move it (keep in mind org.solovyev.android.view.AutoResizeTextView.resetTextSize())
|
|
||||||
setAddEllipsis(false);
|
|
||||||
setMinTextSize(10);
|
|
||||||
resizeText();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getSelection() {
|
|
||||||
return this.getSelectionStart();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setSelection(int selection) {
|
|
||||||
// not supported by TextView
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -25,7 +25,7 @@ import org.solovyev.common.collections.CollectionsUtils;
|
|||||||
* Date: 9/17/11
|
* Date: 9/17/11
|
||||||
* Time: 12:25 AM
|
* Time: 12:25 AM
|
||||||
*/
|
*/
|
||||||
public class CalculatorEditor extends EditText implements SharedPreferences.OnSharedPreferenceChangeListener {
|
public class AndroidCalculatorEditorView extends EditText implements SharedPreferences.OnSharedPreferenceChangeListener, CalculatorEditorView {
|
||||||
|
|
||||||
private static final String CALC_COLOR_DISPLAY_KEY = "org.solovyev.android.calculator.CalculatorModel_color_display";
|
private static final String CALC_COLOR_DISPLAY_KEY = "org.solovyev.android.calculator.CalculatorModel_color_display";
|
||||||
private static final boolean CALC_COLOR_DISPLAY_DEFAULT = true;
|
private static final boolean CALC_COLOR_DISPLAY_DEFAULT = true;
|
||||||
@ -35,39 +35,16 @@ public class CalculatorEditor extends EditText implements SharedPreferences.OnSh
|
|||||||
@NotNull
|
@NotNull
|
||||||
private final static TextProcessor<TextHighlighter.Result, String> textHighlighter = new TextHighlighter(Color.WHITE, true, CalculatorEngine.instance.getEngine());
|
private final static TextProcessor<TextHighlighter.Result, String> textHighlighter = new TextHighlighter(Color.WHITE, true, CalculatorEngine.instance.getEngine());
|
||||||
|
|
||||||
public CalculatorEditor(Context context) {
|
public AndroidCalculatorEditorView(Context context) {
|
||||||
super(context);
|
super(context);
|
||||||
init();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public CalculatorEditor(Context context, AttributeSet attrs) {
|
public AndroidCalculatorEditorView(Context context, AttributeSet attrs) {
|
||||||
super(context, attrs);
|
super(context, attrs);
|
||||||
init();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void init() {
|
public AndroidCalculatorEditorView(Context context, AttributeSet attrs, int defStyle) {
|
||||||
// NOTE: in this solution cursor is missing
|
super(context, attrs, defStyle);
|
||||||
|
|
||||||
/*this.setOnTouchListener(new OnTouchListener() {
|
|
||||||
@Override
|
|
||||||
public boolean onTouch(View v, MotionEvent event) {
|
|
||||||
final TextView textView = (TextView)v;
|
|
||||||
// backup the input type
|
|
||||||
int inputType = textView.getInputType();
|
|
||||||
|
|
||||||
// disable soft input
|
|
||||||
textView.setInputType(InputType.TYPE_NULL);
|
|
||||||
|
|
||||||
// call native handler
|
|
||||||
textView.onTouchEvent(event);
|
|
||||||
|
|
||||||
// restore input type
|
|
||||||
textView.setInputType(inputType);
|
|
||||||
|
|
||||||
// consume touch even
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
});*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -95,11 +72,6 @@ public class CalculatorEditor extends EditText implements SharedPreferences.OnSh
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public CalculatorEditor(Context context, AttributeSet attrs, int defStyle) {
|
|
||||||
super(context, attrs, defStyle);
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreateContextMenu(ContextMenu menu) {
|
protected void onCreateContextMenu(ContextMenu menu) {
|
||||||
super.onCreateContextMenu(menu);
|
super.onCreateContextMenu(menu);
|
||||||
@ -107,11 +79,6 @@ public class CalculatorEditor extends EditText implements SharedPreferences.OnSh
|
|||||||
menu.removeItem(android.R.id.selectAll);
|
menu.removeItem(android.R.id.selectAll);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setText(CharSequence text, BufferType type) {
|
|
||||||
super.setText(text, type);
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized void redraw() {
|
public synchronized void redraw() {
|
||||||
String text = getText().toString();
|
String text = getText().toString();
|
||||||
|
|
@ -0,0 +1,141 @@
|
|||||||
|
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<CalculatorDisplayViewState> {
|
||||||
|
|
||||||
|
copy(R.string.c_copy) {
|
||||||
|
@Override
|
||||||
|
public void onClick(@NotNull CalculatorDisplayViewState data, @NotNull Context context) {
|
||||||
|
CalculatorModel.copyResult(context, data);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
convert_to_bin(R.string.convert_to_bin) {
|
||||||
|
@Override
|
||||||
|
public void onClick(@NotNull CalculatorDisplayViewState data, @NotNull Context context) {
|
||||||
|
ConversionMenuItem.convert_to_bin.onClick(data, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isItemVisibleFor(@NotNull Generic generic, @NotNull JsclOperation operation) {
|
||||||
|
return ConversionMenuItem.convert_to_bin.isItemVisibleFor(generic, operation);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
convert_to_dec(R.string.convert_to_dec) {
|
||||||
|
@Override
|
||||||
|
public void onClick(@NotNull CalculatorDisplayViewState data, @NotNull Context context) {
|
||||||
|
ConversionMenuItem.convert_to_dec.onClick(data, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isItemVisibleFor(@NotNull Generic generic, @NotNull JsclOperation operation) {
|
||||||
|
return ConversionMenuItem.convert_to_dec.isItemVisibleFor(generic, operation);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
convert_to_hex(R.string.convert_to_hex) {
|
||||||
|
@Override
|
||||||
|
public void onClick(@NotNull CalculatorDisplayViewState data, @NotNull Context context) {
|
||||||
|
ConversionMenuItem.convert_to_hex.onClick(data, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isItemVisibleFor(@NotNull Generic generic, @NotNull JsclOperation operation) {
|
||||||
|
return ConversionMenuItem.convert_to_hex.isItemVisibleFor(generic, operation);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
convert(R.string.c_convert) {
|
||||||
|
@Override
|
||||||
|
public void onClick(@NotNull CalculatorDisplayViewState data, @NotNull Context context) {
|
||||||
|
final Generic result = data.getResult();
|
||||||
|
if (result != null) {
|
||||||
|
new NumeralBaseConverterDialog(result.toString()).show(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isItemVisibleFor(@NotNull Generic generic, @NotNull JsclOperation operation) {
|
||||||
|
return operation == JsclOperation.numeric && generic.getConstants().isEmpty();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
plot(R.string.c_plot) {
|
||||||
|
@Override
|
||||||
|
public void onClick(@NotNull CalculatorDisplayViewState data, @NotNull Context context) {
|
||||||
|
final Generic generic = data.getResult();
|
||||||
|
assert generic != null;
|
||||||
|
|
||||||
|
final Constant constant = CollectionsUtils.getFirstCollectionElement(getNotSystemConstants(generic));
|
||||||
|
assert constant != null;
|
||||||
|
CalculatorActivityLauncher.plotGraph(context, generic, constant);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isItemVisibleFor(@NotNull Generic generic, @NotNull JsclOperation operation) {
|
||||||
|
boolean result = false;
|
||||||
|
|
||||||
|
if (operation == JsclOperation.simplify) {
|
||||||
|
if (getNotSystemConstants(generic).size() == 1) {
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private Set<Constant> getNotSystemConstants(@NotNull Generic generic) {
|
||||||
|
final Set<Constant> notSystemConstants = new HashSet<Constant>();
|
||||||
|
|
||||||
|
for (Constant constant : generic.getConstants()) {
|
||||||
|
IConstant var = CalculatorEngine.instance.getVarsRegistry().get(constant.getName());
|
||||||
|
if (var != null && !var.isSystem() && !var.isDefined()) {
|
||||||
|
notSystemConstants.add(constant);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return notSystemConstants;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private final int captionId;
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +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<CalculatorDisplayMenuItem> filteredMenuItems = new ArrayList<CalculatorDisplayMenuItem>(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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,411 +1,356 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2009-2011. Created by serso aka se.solovyev.
|
* Copyright (c) 2009-2011. Created by serso aka se.solovyev.
|
||||||
* For more information, please, contact se.solovyev@gmail.com
|
* For more information, please, contact se.solovyev@gmail.com
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.solovyev.android.calculator;
|
package org.solovyev.android.calculator;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.text.ClipboardManager;
|
import android.text.ClipboardManager;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.solovyev.android.CursorControl;
|
import org.solovyev.android.CursorControl;
|
||||||
import org.solovyev.android.calculator.history.AndroidCalculatorHistoryImpl;
|
import org.solovyev.android.calculator.history.AndroidCalculatorHistoryImpl;
|
||||||
import org.solovyev.android.calculator.history.CalculatorHistoryState;
|
import org.solovyev.android.calculator.history.CalculatorHistoryState;
|
||||||
import org.solovyev.android.calculator.history.TextViewEditorAdapter;
|
import org.solovyev.android.calculator.history.TextViewEditorAdapter;
|
||||||
import org.solovyev.android.calculator.jscl.JsclOperation;
|
import org.solovyev.android.calculator.jscl.JsclOperation;
|
||||||
import org.solovyev.android.calculator.math.MathType;
|
import org.solovyev.android.calculator.math.MathType;
|
||||||
import org.solovyev.android.calculator.model.CalculatorEngine;
|
import org.solovyev.android.calculator.model.CalculatorEngine;
|
||||||
import org.solovyev.android.history.HistoryControl;
|
import org.solovyev.android.history.HistoryControl;
|
||||||
import org.solovyev.android.menu.AMenuBuilder;
|
import org.solovyev.common.MutableObject;
|
||||||
import org.solovyev.android.menu.MenuImpl;
|
import org.solovyev.common.history.HistoryAction;
|
||||||
import org.solovyev.common.MutableObject;
|
import org.solovyev.common.msg.Message;
|
||||||
import org.solovyev.common.history.HistoryAction;
|
import org.solovyev.common.text.StringUtils;
|
||||||
import org.solovyev.common.msg.Message;
|
|
||||||
import org.solovyev.common.text.StringUtils;
|
/**
|
||||||
|
* User: serso
|
||||||
import java.util.ArrayList;
|
* Date: 9/12/11
|
||||||
import java.util.List;
|
* Time: 11:15 PM
|
||||||
|
*/
|
||||||
/**
|
public enum CalculatorModel implements HistoryControl<CalculatorHistoryState>, CalculatorEngineControl {
|
||||||
* User: serso
|
|
||||||
* Date: 9/12/11
|
instance;
|
||||||
* Time: 11:15 PM
|
|
||||||
*/
|
// millis to wait before evaluation after user edit action
|
||||||
public enum CalculatorModel implements CursorControl, HistoryControl<CalculatorHistoryState>, CalculatorEngineControl {
|
public static final int EVAL_DELAY_MILLIS = 0;
|
||||||
|
|
||||||
instance;
|
@NotNull
|
||||||
|
private final CalculatorEditor editor;
|
||||||
// millis to wait before evaluation after user edit action
|
|
||||||
public static final int EVAL_DELAY_MILLIS = 0;
|
@NotNull
|
||||||
|
private final CalculatorDisplay display;
|
||||||
@NotNull
|
|
||||||
private CalculatorEditor editor;
|
@NotNull
|
||||||
|
private CalculatorEngine calculatorEngine;
|
||||||
@NotNull
|
|
||||||
private AndroidCalculatorDisplayView display;
|
private CalculatorModel() {
|
||||||
|
display = CalculatorLocatorImpl.getInstance().getCalculatorDisplay();
|
||||||
@NotNull
|
editor = CalculatorLocatorImpl.getInstance().getCalculatorEditor();
|
||||||
private CalculatorEngine calculatorEngine;
|
}
|
||||||
|
|
||||||
public CalculatorModel init(@NotNull final Activity activity, @NotNull SharedPreferences preferences, @NotNull CalculatorEngine calculator) {
|
public CalculatorModel init(@NotNull final Activity activity, @NotNull SharedPreferences preferences, @NotNull CalculatorEngine calculator) {
|
||||||
Log.d(this.getClass().getName(), "CalculatorModel initialization with activity: " + activity);
|
Log.d(this.getClass().getName(), "CalculatorModel initialization with activity: " + activity);
|
||||||
this.calculatorEngine = calculator;
|
this.calculatorEngine = calculator;
|
||||||
|
|
||||||
this.editor = (CalculatorEditor) activity.findViewById(R.id.calculatorEditor);
|
final AndroidCalculatorEditorView editorView = (AndroidCalculatorEditorView) activity.findViewById(R.id.calculatorEditor);
|
||||||
this.editor.init(preferences);
|
editorView.init(preferences);
|
||||||
preferences.registerOnSharedPreferenceChangeListener(editor);
|
preferences.registerOnSharedPreferenceChangeListener(editorView);
|
||||||
|
editor.setView(editorView);
|
||||||
this.display = (AndroidCalculatorDisplayView) activity.findViewById(R.id.calculatorDisplay);
|
|
||||||
this.display.setOnClickListener(new CalculatorDisplayOnClickListener(activity));
|
final AndroidCalculatorDisplayView displayView = (AndroidCalculatorDisplayView) activity.findViewById(R.id.calculatorDisplay);
|
||||||
|
displayView.setOnClickListener(new CalculatorDisplayOnClickListener(activity));
|
||||||
final CalculatorHistoryState lastState = AndroidCalculatorHistoryImpl.instance.getLastHistoryState();
|
display.setView(displayView);
|
||||||
if (lastState == null) {
|
|
||||||
saveHistoryState();
|
final CalculatorHistoryState lastState = AndroidCalculatorHistoryImpl.instance.getLastHistoryState();
|
||||||
} else {
|
if (lastState == null) {
|
||||||
setCurrentHistoryState(lastState);
|
saveHistoryState();
|
||||||
}
|
} else {
|
||||||
|
setCurrentHistoryState(lastState);
|
||||||
|
}
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
return this;
|
||||||
private static void showEvaluationError(@NotNull Activity activity, @NotNull final String errorMessage) {
|
}
|
||||||
final LayoutInflater layoutInflater = (LayoutInflater) activity.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
|
|
||||||
|
public static void showEvaluationError(@NotNull Activity activity, @NotNull final String errorMessage) {
|
||||||
final View errorMessageView = layoutInflater.inflate(R.layout.display_error_message, null);
|
final LayoutInflater layoutInflater = (LayoutInflater) activity.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
|
||||||
((TextView) errorMessageView.findViewById(R.id.error_message_text_view)).setText(errorMessage);
|
|
||||||
|
final View errorMessageView = layoutInflater.inflate(R.layout.display_error_message, null);
|
||||||
final AlertDialog.Builder builder = new AlertDialog.Builder(activity)
|
((TextView) errorMessageView.findViewById(R.id.error_message_text_view)).setText(errorMessage);
|
||||||
.setPositiveButton(R.string.c_cancel, null)
|
|
||||||
.setView(errorMessageView);
|
final AlertDialog.Builder builder = new AlertDialog.Builder(activity)
|
||||||
|
.setPositiveButton(R.string.c_cancel, null)
|
||||||
builder.create().show();
|
.setView(errorMessageView);
|
||||||
}
|
|
||||||
|
builder.create().show();
|
||||||
public void copyResult(@NotNull Context context) {
|
}
|
||||||
copyResult(context, display);
|
|
||||||
}
|
public void copyResult(@NotNull Context context) {
|
||||||
|
copyResult(context, display.getViewState());
|
||||||
public static void copyResult(@NotNull Context context, @NotNull final CalculatorDisplayViewState viewState) {
|
}
|
||||||
if (viewState.isValid()) {
|
|
||||||
final CharSequence text = viewState.getText();
|
public static void copyResult(@NotNull Context context, @NotNull final CalculatorDisplayViewState viewState) {
|
||||||
if (!StringUtils.isEmpty(text)) {
|
if (viewState.isValid()) {
|
||||||
final ClipboardManager clipboard = (ClipboardManager) context.getSystemService(Activity.CLIPBOARD_SERVICE);
|
final CharSequence text = viewState.getText();
|
||||||
clipboard.setText(text.toString());
|
if (!StringUtils.isEmpty(text)) {
|
||||||
Toast.makeText(context, context.getText(R.string.c_result_copied), Toast.LENGTH_SHORT).show();
|
final ClipboardManager clipboard = (ClipboardManager) context.getSystemService(Activity.CLIPBOARD_SERVICE);
|
||||||
}
|
clipboard.setText(text.toString());
|
||||||
}
|
Toast.makeText(context, context.getText(R.string.c_result_copied), Toast.LENGTH_SHORT).show();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
private void saveHistoryState() {
|
}
|
||||||
AndroidCalculatorHistoryImpl.instance.addState(getCurrentHistoryState());
|
|
||||||
}
|
private void saveHistoryState() {
|
||||||
|
AndroidCalculatorHistoryImpl.instance.addState(getCurrentHistoryState());
|
||||||
public void setCursorOnStart() {
|
}
|
||||||
editor.setSelection(0);
|
|
||||||
}
|
public void doTextOperation(@NotNull TextOperation operation) {
|
||||||
|
doTextOperation(operation, true);
|
||||||
public void setCursorOnEnd() {
|
}
|
||||||
editor.setSelection(editor.getText().length());
|
|
||||||
}
|
public void doTextOperation(@NotNull TextOperation operation, boolean delayEvaluate) {
|
||||||
|
doTextOperation(operation, delayEvaluate, JsclOperation.numeric, false);
|
||||||
public void moveCursorLeft() {
|
}
|
||||||
if (editor.getSelectionStart() > 0) {
|
|
||||||
editor.setSelection(editor.getSelectionStart() - 1);
|
public void doTextOperation(@NotNull TextOperation operation, boolean delayEvaluate, @NotNull JsclOperation jsclOperation, boolean forceEval) {
|
||||||
}
|
final String editorStateBefore = this.editor.getText().toString();
|
||||||
}
|
|
||||||
|
Log.d(CalculatorModel.class.getName(), "Editor state changed before '" + editorStateBefore + "'");
|
||||||
public void moveCursorRight() {
|
operation.doOperation(this.editor);
|
||||||
if (editor.getSelectionStart() < editor.getText().length()) {
|
//Log.d(CalculatorModel.class.getName(), "Doing text operation" + StringUtils.fromStackTrace(Thread.currentThread().getStackTrace()));
|
||||||
editor.setSelection(editor.getSelectionStart() + 1);
|
|
||||||
}
|
final String editorStateAfter = this.editor.getText().toString();
|
||||||
}
|
if (forceEval ||!editorStateBefore.equals(editorStateAfter)) {
|
||||||
|
|
||||||
public void doTextOperation(@NotNull TextOperation operation) {
|
editor.redraw();
|
||||||
doTextOperation(operation, true);
|
|
||||||
}
|
evaluate(delayEvaluate, editorStateAfter, jsclOperation, null);
|
||||||
|
}
|
||||||
public void doTextOperation(@NotNull TextOperation operation, boolean delayEvaluate) {
|
}
|
||||||
doTextOperation(operation, delayEvaluate, JsclOperation.numeric, false);
|
|
||||||
}
|
@NotNull
|
||||||
|
private final static MutableObject<Runnable> pendingOperation = new MutableObject<Runnable>();
|
||||||
public void doTextOperation(@NotNull TextOperation operation, boolean delayEvaluate, @NotNull JsclOperation jsclOperation, boolean forceEval) {
|
|
||||||
final String editorStateBefore = this.editor.getText().toString();
|
private void evaluate(boolean delayEvaluate,
|
||||||
|
@NotNull final String expression,
|
||||||
Log.d(CalculatorModel.class.getName(), "Editor state changed before '" + editorStateBefore + "'");
|
@NotNull final JsclOperation operation,
|
||||||
operation.doOperation(this.editor);
|
@Nullable CalculatorHistoryState historyState) {
|
||||||
//Log.d(CalculatorModel.class.getName(), "Doing text operation" + StringUtils.fromStackTrace(Thread.currentThread().getStackTrace()));
|
|
||||||
|
final CalculatorHistoryState localHistoryState;
|
||||||
final String editorStateAfter = this.editor.getText().toString();
|
if (historyState == null) {
|
||||||
if (forceEval ||!editorStateBefore.equals(editorStateAfter)) {
|
//this.display.setText("");
|
||||||
|
localHistoryState = getCurrentHistoryState();
|
||||||
editor.redraw();
|
} else {
|
||||||
|
this.display.setText(historyState.getDisplayState().getEditorState().getText());
|
||||||
evaluate(delayEvaluate, editorStateAfter, jsclOperation, null);
|
localHistoryState = historyState;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
pendingOperation.setObject(new Runnable() {
|
||||||
@NotNull
|
@Override
|
||||||
private final static MutableObject<Runnable> pendingOperation = new MutableObject<Runnable>();
|
public void run() {
|
||||||
|
// allow only one runner at one time
|
||||||
private void evaluate(boolean delayEvaluate,
|
synchronized (pendingOperation) {
|
||||||
@NotNull final String expression,
|
//lock all operations with history
|
||||||
@NotNull final JsclOperation operation,
|
if (pendingOperation.getObject() == this) {
|
||||||
@Nullable CalculatorHistoryState historyState) {
|
// actually nothing shall be logged while text operations are done
|
||||||
|
evaluate(expression, operation, this);
|
||||||
final CalculatorHistoryState localHistoryState;
|
|
||||||
if (historyState == null) {
|
if (pendingOperation.getObject() == this) {
|
||||||
//this.display.setText("");
|
// todo serso: of course there is small probability that someone will set pendingOperation after if statement but before .setObject(null)
|
||||||
localHistoryState = getCurrentHistoryState();
|
pendingOperation.setObject(null);
|
||||||
} else {
|
localHistoryState.setDisplayState(getCurrentHistoryState().getDisplayState());
|
||||||
this.display.setText(historyState.getDisplayState().getEditorState().getText());
|
}
|
||||||
localHistoryState = historyState;
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
pendingOperation.setObject(new Runnable() {
|
});
|
||||||
@Override
|
|
||||||
public void run() {
|
if (delayEvaluate) {
|
||||||
// allow only one runner at one time
|
if (historyState == null) {
|
||||||
synchronized (pendingOperation) {
|
AndroidCalculatorHistoryImpl.instance.addState(localHistoryState);
|
||||||
//lock all operations with history
|
}
|
||||||
if (pendingOperation.getObject() == this) {
|
// todo serso: this is not correct - operation is processing still in the same thread
|
||||||
// actually nothing shall be logged while text operations are done
|
new Handler().postDelayed(pendingOperation.getObject(), EVAL_DELAY_MILLIS);
|
||||||
evaluate(expression, operation, this);
|
} else {
|
||||||
|
pendingOperation.getObject().run();
|
||||||
if (pendingOperation.getObject() == this) {
|
if (historyState == null) {
|
||||||
// todo serso: of course there is small probability that someone will set pendingOperation after if statement but before .setObject(null)
|
AndroidCalculatorHistoryImpl.instance.addState(localHistoryState);
|
||||||
pendingOperation.setObject(null);
|
}
|
||||||
localHistoryState.setDisplayState(getCurrentHistoryState().getDisplayState());
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
@Override
|
||||||
}
|
public void evaluate() {
|
||||||
});
|
evaluate(false, this.editor.getText().toString(), JsclOperation.numeric, null);
|
||||||
|
}
|
||||||
if (delayEvaluate) {
|
|
||||||
if (historyState == null) {
|
public void evaluate(@NotNull JsclOperation operation) {
|
||||||
AndroidCalculatorHistoryImpl.instance.addState(localHistoryState);
|
evaluate(false, this.editor.getText().toString(), operation, null);
|
||||||
}
|
}
|
||||||
// todo serso: this is not correct - operation is processing still in the same thread
|
|
||||||
new Handler().postDelayed(pendingOperation.getObject(), EVAL_DELAY_MILLIS);
|
@Override
|
||||||
} else {
|
public void simplify() {
|
||||||
pendingOperation.getObject().run();
|
evaluate(false, this.editor.getText().toString(), JsclOperation.simplify, null);
|
||||||
if (historyState == null) {
|
}
|
||||||
AndroidCalculatorHistoryImpl.instance.addState(localHistoryState);
|
|
||||||
}
|
private void evaluate(@Nullable final String expression,
|
||||||
}
|
@NotNull JsclOperation operation,
|
||||||
}
|
@NotNull Runnable currentRunner) {
|
||||||
|
|
||||||
@Override
|
if (!StringUtils.isEmpty(expression)) {
|
||||||
public void evaluate() {
|
try {
|
||||||
evaluate(false, this.editor.getText().toString(), JsclOperation.numeric, null);
|
Log.d(CalculatorModel.class.getName(), "Trying to evaluate '" + operation + "': " + expression /*+ StringUtils.fromStackTrace(Thread.currentThread().getStackTrace())*/);
|
||||||
}
|
final CalculatorOutput result = calculatorEngine.evaluate(operation, expression);
|
||||||
|
|
||||||
public void evaluate(@NotNull JsclOperation operation) {
|
// todo serso: second condition might replaced with expression.equals(this.editor.getText().toString()) ONLY if expression will be formatted with text highlighter
|
||||||
evaluate(false, this.editor.getText().toString(), operation, null);
|
if (currentRunner == pendingOperation.getObject() && this.editor.getText().length() > 0) {
|
||||||
}
|
display.setText(result.getStringResult());
|
||||||
|
} else {
|
||||||
@Override
|
display.setText("");
|
||||||
public void simplify() {
|
}
|
||||||
evaluate(false, this.editor.getText().toString(), JsclOperation.simplify, null);
|
display.setJsclOperation(result.getOperation());
|
||||||
}
|
display.setGenericResult(result.getResult());
|
||||||
|
} catch (CalculatorParseException e) {
|
||||||
private void evaluate(@Nullable final String expression,
|
handleEvaluationException(expression, display, operation, e);
|
||||||
@NotNull JsclOperation operation,
|
} catch (CalculatorEvalException e) {
|
||||||
@NotNull Runnable currentRunner) {
|
handleEvaluationException(expression, display, operation, e);
|
||||||
|
}
|
||||||
if (!StringUtils.isEmpty(expression)) {
|
} else {
|
||||||
try {
|
this.display.setText("");
|
||||||
Log.d(CalculatorModel.class.getName(), "Trying to evaluate '" + operation + "': " + expression /*+ StringUtils.fromStackTrace(Thread.currentThread().getStackTrace())*/);
|
this.display.setJsclOperation(operation);
|
||||||
final CalculatorOutput result = calculatorEngine.evaluate(operation, expression);
|
this.display.setGenericResult(null);
|
||||||
|
}
|
||||||
// todo serso: second condition might replaced with expression.equals(this.editor.getText().toString()) ONLY if expression will be formatted with text highlighter
|
|
||||||
if (currentRunner == pendingOperation.getObject() && this.editor.getText().length() > 0) {
|
|
||||||
display.setText(result.getStringResult());
|
|
||||||
} else {
|
this.display.redraw();
|
||||||
display.setText("");
|
}
|
||||||
}
|
|
||||||
display.setJsclOperation(result.getOperation());
|
private void handleEvaluationException(@NotNull String expression,
|
||||||
display.setGenericResult(result.getResult());
|
@NotNull AndroidCalculatorDisplayView localDisplay,
|
||||||
} catch (CalculatorParseException e) {
|
@NotNull JsclOperation operation,
|
||||||
handleEvaluationException(expression, display, operation, e);
|
@NotNull Message e) {
|
||||||
} catch (CalculatorEvalException e) {
|
Log.d(CalculatorModel.class.getName(), "Evaluation failed for : " + expression + ". Error message: " + e);
|
||||||
handleEvaluationException(expression, display, operation, e);
|
if ( StringUtils.isEmpty(localDisplay.getText()) ) {
|
||||||
}
|
// if previous display state was empty -> show error
|
||||||
} else {
|
localDisplay.setText(R.string.c_syntax_error);
|
||||||
this.display.setText("");
|
} else {
|
||||||
this.display.setJsclOperation(operation);
|
// show previous result instead of error caption (actually previous result will be greyed)
|
||||||
this.display.setGenericResult(null);
|
}
|
||||||
}
|
localDisplay.setJsclOperation(operation);
|
||||||
|
localDisplay.setGenericResult(null);
|
||||||
|
localDisplay.setValid(false);
|
||||||
|
localDisplay.setErrorMessage(e.getLocalizedMessage());
|
||||||
this.display.redraw();
|
}
|
||||||
}
|
|
||||||
|
public void clear() {
|
||||||
private void handleEvaluationException(@NotNull String expression,
|
if (!StringUtils.isEmpty(editor.getText()) || !StringUtils.isEmpty(display.getText())) {
|
||||||
@NotNull AndroidCalculatorDisplayView localDisplay,
|
editor.getText().clear();
|
||||||
@NotNull JsclOperation operation,
|
display.setText("");
|
||||||
@NotNull Message e) {
|
saveHistoryState();
|
||||||
Log.d(CalculatorModel.class.getName(), "Evaluation failed for : " + expression + ". Error message: " + e);
|
}
|
||||||
if ( StringUtils.isEmpty(localDisplay.getText()) ) {
|
}
|
||||||
// if previous display state was empty -> show error
|
|
||||||
localDisplay.setText(R.string.c_syntax_error);
|
public void processDigitButtonAction(@Nullable final String text) {
|
||||||
} else {
|
processDigitButtonAction(text, true);
|
||||||
// show previous result instead of error caption (actually previous result will be greyed)
|
}
|
||||||
}
|
|
||||||
localDisplay.setJsclOperation(operation);
|
public void processDigitButtonAction(@Nullable final String text, boolean delayEvaluate) {
|
||||||
localDisplay.setGenericResult(null);
|
|
||||||
localDisplay.setValid(false);
|
if (!StringUtils.isEmpty(text)) {
|
||||||
localDisplay.setErrorMessage(e.getLocalizedMessage());
|
doTextOperation(new CalculatorModel.TextOperation() {
|
||||||
}
|
|
||||||
|
@Override
|
||||||
public void clear() {
|
public void doOperation(@NotNull EditText editor) {
|
||||||
if (!StringUtils.isEmpty(editor.getText()) || !StringUtils.isEmpty(display.getText())) {
|
int cursorPositionOffset = 0;
|
||||||
editor.getText().clear();
|
final StringBuilder textToBeInserted = new StringBuilder(text);
|
||||||
display.setText("");
|
|
||||||
saveHistoryState();
|
final MathType.Result mathType = MathType.getType(text, 0, false);
|
||||||
}
|
switch (mathType.getMathType()) {
|
||||||
}
|
case function:
|
||||||
|
textToBeInserted.append("()");
|
||||||
public void processDigitButtonAction(@Nullable final String text) {
|
cursorPositionOffset = -1;
|
||||||
processDigitButtonAction(text, true);
|
break;
|
||||||
}
|
case operator:
|
||||||
|
textToBeInserted.append("()");
|
||||||
public void processDigitButtonAction(@Nullable final String text, boolean delayEvaluate) {
|
cursorPositionOffset = -1;
|
||||||
|
break;
|
||||||
if (!StringUtils.isEmpty(text)) {
|
case comma:
|
||||||
doTextOperation(new CalculatorModel.TextOperation() {
|
textToBeInserted.append(" ");
|
||||||
|
break;
|
||||||
@Override
|
}
|
||||||
public void doOperation(@NotNull EditText editor) {
|
|
||||||
int cursorPositionOffset = 0;
|
if (cursorPositionOffset == 0) {
|
||||||
final StringBuilder textToBeInserted = new StringBuilder(text);
|
if (MathType.openGroupSymbols.contains(text)) {
|
||||||
|
cursorPositionOffset = -1;
|
||||||
final MathType.Result mathType = MathType.getType(text, 0, false);
|
}
|
||||||
switch (mathType.getMathType()) {
|
}
|
||||||
case function:
|
|
||||||
textToBeInserted.append("()");
|
editor.getText().insert(editor.getSelectionStart(), textToBeInserted.toString());
|
||||||
cursorPositionOffset = -1;
|
editor.setSelection(editor.getSelectionStart() + cursorPositionOffset, editor.getSelectionEnd() + cursorPositionOffset);
|
||||||
break;
|
}
|
||||||
case operator:
|
}, delayEvaluate);
|
||||||
textToBeInserted.append("()");
|
}
|
||||||
cursorPositionOffset = -1;
|
}
|
||||||
break;
|
|
||||||
case comma:
|
public static interface TextOperation {
|
||||||
textToBeInserted.append(" ");
|
|
||||||
break;
|
void doOperation(@NotNull EditText editor);
|
||||||
}
|
|
||||||
|
}
|
||||||
if (cursorPositionOffset == 0) {
|
|
||||||
if (MathType.openGroupSymbols.contains(text)) {
|
@Override
|
||||||
cursorPositionOffset = -1;
|
public void doHistoryAction(@NotNull HistoryAction historyAction) {
|
||||||
}
|
synchronized (AndroidCalculatorHistoryImpl.instance) {
|
||||||
}
|
if (AndroidCalculatorHistoryImpl.instance.isActionAvailable(historyAction)) {
|
||||||
|
final CalculatorHistoryState newState = AndroidCalculatorHistoryImpl.instance.doAction(historyAction, getCurrentHistoryState());
|
||||||
editor.getText().insert(editor.getSelectionStart(), textToBeInserted.toString());
|
if (newState != null) {
|
||||||
editor.setSelection(editor.getSelectionStart() + cursorPositionOffset, editor.getSelectionEnd() + cursorPositionOffset);
|
setCurrentHistoryState(newState);
|
||||||
}
|
}
|
||||||
}, delayEvaluate);
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static interface TextOperation {
|
@Override
|
||||||
|
public void setCurrentHistoryState(@NotNull CalculatorHistoryState editorHistoryState) {
|
||||||
void doOperation(@NotNull EditText editor);
|
synchronized (AndroidCalculatorHistoryImpl.instance) {
|
||||||
|
Log.d(this.getClass().getName(), "Saved history found: " + editorHistoryState);
|
||||||
}
|
|
||||||
|
editorHistoryState.setValuesFromHistory(new TextViewEditorAdapter(this.editor), this.display);
|
||||||
@Override
|
|
||||||
public void doHistoryAction(@NotNull HistoryAction historyAction) {
|
final String expression = this.editor.getText().toString();
|
||||||
synchronized (AndroidCalculatorHistoryImpl.instance) {
|
if ( !StringUtils.isEmpty(expression) ) {
|
||||||
if (AndroidCalculatorHistoryImpl.instance.isActionAvailable(historyAction)) {
|
if ( StringUtils.isEmpty(this.display.getText().toString()) ) {
|
||||||
final CalculatorHistoryState newState = AndroidCalculatorHistoryImpl.instance.doAction(historyAction, getCurrentHistoryState());
|
evaluate(false, expression, this.display.getJsclOperation(), editorHistoryState);
|
||||||
if (newState != null) {
|
}
|
||||||
setCurrentHistoryState(newState);
|
}
|
||||||
}
|
|
||||||
}
|
editor.redraw();
|
||||||
}
|
//display.redraw();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
@Override
|
|
||||||
public void setCurrentHistoryState(@NotNull CalculatorHistoryState editorHistoryState) {
|
@Override
|
||||||
synchronized (AndroidCalculatorHistoryImpl.instance) {
|
@NotNull
|
||||||
Log.d(this.getClass().getName(), "Saved history found: " + editorHistoryState);
|
public CalculatorHistoryState getCurrentHistoryState() {
|
||||||
|
synchronized (AndroidCalculatorHistoryImpl.instance) {
|
||||||
editorHistoryState.setValuesFromHistory(new TextViewEditorAdapter(this.editor), this.display);
|
return CalculatorHistoryState.newInstance(new TextViewEditorAdapter(this.editor), display);
|
||||||
|
}
|
||||||
final String expression = this.editor.getText().toString();
|
}
|
||||||
if ( !StringUtils.isEmpty(expression) ) {
|
|
||||||
if ( StringUtils.isEmpty(this.display.getText().toString()) ) {
|
@NotNull
|
||||||
evaluate(false, expression, this.display.getJsclOperation(), editorHistoryState);
|
public CalculatorDisplay getDisplay() {
|
||||||
}
|
return display;
|
||||||
}
|
}
|
||||||
|
|
||||||
editor.redraw();
|
}
|
||||||
display.redraw();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@NotNull
|
|
||||||
public CalculatorHistoryState getCurrentHistoryState() {
|
|
||||||
synchronized (AndroidCalculatorHistoryImpl.instance) {
|
|
||||||
return CalculatorHistoryState.newInstance(new TextViewEditorAdapter(this.editor), this.display);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public AndroidCalculatorDisplayView getDisplay() {
|
|
||||||
return display;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static 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<AndroidCalculatorDisplayView.MenuItem> filteredMenuItems = new ArrayList<AndroidCalculatorDisplayView.MenuItem>(AndroidCalculatorDisplayView.MenuItem.values().length);
|
|
||||||
for (AndroidCalculatorDisplayView.MenuItem menuItem : AndroidCalculatorDisplayView.MenuItem.values()) {
|
|
||||||
if (menuItem.isItemVisible(displayViewState)) {
|
|
||||||
filteredMenuItems.add(menuItem);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!filteredMenuItems.isEmpty()) {
|
|
||||||
AMenuBuilder.newInstance(activity, MenuImpl.newInstance(filteredMenuItems)).create(cd).show();
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
final String errorMessage = displayViewState.getErrorMessage();
|
|
||||||
if (errorMessage != null) {
|
|
||||||
showEvaluationError(activity, errorMessage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -11,6 +11,8 @@ import android.content.SharedPreferences;
|
|||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
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.android.calculator.R;
|
||||||
import org.solovyev.common.history.HistoryAction;
|
import org.solovyev.common.history.HistoryAction;
|
||||||
|
|
||||||
@ -142,4 +144,9 @@ public enum AndroidCalculatorHistoryImpl implements AndroidCalculatorHistory {
|
|||||||
public void removeSavedHistory(@NotNull CalculatorHistoryState historyState) {
|
public void removeSavedHistory(@NotNull CalculatorHistoryState historyState) {
|
||||||
calculatorHistory.removeSavedHistory(historyState);
|
calculatorHistory.removeSavedHistory(historyState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCalculatorEvent(@NotNull CalculatorEventData calculatorEventData, @NotNull CalculatorEventType calculatorEventType, @Nullable Object data) {
|
||||||
|
calculatorHistory.onCalculatorEvent(calculatorEventData, calculatorEventType, data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -173,7 +173,7 @@ public class TextHighlighter implements TextProcessor<TextHighlighter.Result, St
|
|||||||
text2.append(s.charAt(i));
|
text2.append(s.charAt(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
//Log.d(CalculatorEditor.class.getName(), text2.toString());
|
//Log.d(AndroidCalculatorEditorView.class.getName(), text2.toString());
|
||||||
|
|
||||||
result = text2.toString();
|
result = text2.toString();
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
Reference in New Issue
Block a user