Editor/display changes
This commit is contained in:
parent
4b08fa133e
commit
4e42f6ad6b
@ -1,170 +1,183 @@
|
|||||||
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 static org.solovyev.android.calculator.CalculatorEventType.*;
|
import static org.solovyev.android.calculator.CalculatorEventType.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* User: serso
|
* User: serso
|
||||||
* Date: 9/20/12
|
* Date: 9/20/12
|
||||||
* Time: 8:24 PM
|
* Time: 8:24 PM
|
||||||
*/
|
*/
|
||||||
public class CalculatorDisplayImpl implements CalculatorDisplay {
|
public class CalculatorDisplayImpl implements CalculatorDisplay {
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private CalculatorEventData lastCalculatorEventData;
|
private volatile CalculatorEventData lastCalculatorEventData;
|
||||||
|
|
||||||
@Nullable
|
@NotNull
|
||||||
private CalculatorDisplayView view;
|
private final Object lastCalculatorEventDataLock = new Object();
|
||||||
|
|
||||||
@NotNull
|
@Nullable
|
||||||
private final Object viewLock = new Object();
|
private CalculatorDisplayView view;
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private CalculatorDisplayViewState viewState = CalculatorDisplayViewStateImpl.newDefaultInstance();
|
private final Object viewLock = new Object();
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private final Calculator calculator;
|
private CalculatorDisplayViewState viewState = CalculatorDisplayViewStateImpl.newDefaultInstance();
|
||||||
|
|
||||||
public CalculatorDisplayImpl(@NotNull Calculator calculator) {
|
@NotNull
|
||||||
this.calculator = calculator;
|
private final Calculator calculator;
|
||||||
this.lastCalculatorEventData = CalculatorUtils.createFirstEventDataId();
|
|
||||||
this.calculator.addCalculatorEventListener(this);
|
public CalculatorDisplayImpl(@NotNull Calculator calculator) {
|
||||||
}
|
this.calculator = calculator;
|
||||||
|
this.lastCalculatorEventData = CalculatorUtils.createFirstEventDataId();
|
||||||
@Override
|
this.calculator.addCalculatorEventListener(this);
|
||||||
public void setView(@Nullable CalculatorDisplayView view) {
|
}
|
||||||
synchronized (viewLock) {
|
|
||||||
this.view = view;
|
@Override
|
||||||
|
public void setView(@Nullable CalculatorDisplayView view) {
|
||||||
if (view != null) {
|
synchronized (viewLock) {
|
||||||
this.view.setState(viewState);
|
this.view = view;
|
||||||
}
|
|
||||||
}
|
if (view != null) {
|
||||||
}
|
this.view.setState(viewState);
|
||||||
|
}
|
||||||
@Nullable
|
}
|
||||||
@Override
|
}
|
||||||
public CalculatorDisplayView getView() {
|
|
||||||
return this.view;
|
@Nullable
|
||||||
}
|
@Override
|
||||||
|
public CalculatorDisplayView getView() {
|
||||||
@NotNull
|
return this.view;
|
||||||
@Override
|
}
|
||||||
public CalculatorDisplayViewState getViewState() {
|
|
||||||
return this.viewState;
|
@NotNull
|
||||||
}
|
@Override
|
||||||
|
public CalculatorDisplayViewState getViewState() {
|
||||||
@Override
|
return this.viewState;
|
||||||
public void setViewState(@NotNull CalculatorDisplayViewState newViewState) {
|
}
|
||||||
synchronized (viewLock) {
|
|
||||||
final CalculatorDisplayViewState oldViewState = setViewState0(newViewState);
|
@Override
|
||||||
|
public void setViewState(@NotNull CalculatorDisplayViewState newViewState) {
|
||||||
this.calculator.fireCalculatorEvent(display_state_changed, new CalculatorDisplayChangeEventDataImpl(oldViewState, newViewState));
|
synchronized (viewLock) {
|
||||||
}
|
final CalculatorDisplayViewState oldViewState = setViewState0(newViewState);
|
||||||
}
|
|
||||||
|
this.calculator.fireCalculatorEvent(display_state_changed, new CalculatorDisplayChangeEventDataImpl(oldViewState, newViewState));
|
||||||
private void setViewStateForSequence(@NotNull CalculatorDisplayViewState newViewState, @NotNull Long sequenceId) {
|
}
|
||||||
synchronized (viewLock) {
|
}
|
||||||
final CalculatorDisplayViewState oldViewState = setViewState0(newViewState);
|
|
||||||
|
private void setViewStateForSequence(@NotNull CalculatorDisplayViewState newViewState, @NotNull Long sequenceId) {
|
||||||
this.calculator.fireCalculatorEvent(display_state_changed, new CalculatorDisplayChangeEventDataImpl(oldViewState, newViewState), sequenceId);
|
synchronized (viewLock) {
|
||||||
}
|
final CalculatorDisplayViewState oldViewState = setViewState0(newViewState);
|
||||||
}
|
|
||||||
|
this.calculator.fireCalculatorEvent(display_state_changed, new CalculatorDisplayChangeEventDataImpl(oldViewState, newViewState), sequenceId);
|
||||||
// must be synchronized with viewLock
|
}
|
||||||
@NotNull
|
}
|
||||||
private CalculatorDisplayViewState setViewState0(@NotNull CalculatorDisplayViewState newViewState) {
|
|
||||||
final CalculatorDisplayViewState oldViewState = this.viewState;
|
// must be synchronized with viewLock
|
||||||
|
@NotNull
|
||||||
this.viewState = newViewState;
|
private CalculatorDisplayViewState setViewState0(@NotNull CalculatorDisplayViewState newViewState) {
|
||||||
if (this.view != null) {
|
final CalculatorDisplayViewState oldViewState = this.viewState;
|
||||||
this.view.setState(newViewState);
|
|
||||||
}
|
this.viewState = newViewState;
|
||||||
return oldViewState;
|
if (this.view != null) {
|
||||||
}
|
this.view.setState(newViewState);
|
||||||
|
}
|
||||||
@Override
|
return oldViewState;
|
||||||
@NotNull
|
}
|
||||||
public CalculatorEventData getLastEventData() {
|
|
||||||
return lastCalculatorEventData;
|
@Override
|
||||||
}
|
@NotNull
|
||||||
|
public CalculatorEventData getLastEventData() {
|
||||||
@Override
|
synchronized (lastCalculatorEventDataLock) {
|
||||||
public void onCalculatorEvent(@NotNull CalculatorEventData calculatorEventData,
|
return lastCalculatorEventData;
|
||||||
@NotNull CalculatorEventType calculatorEventType,
|
}
|
||||||
@Nullable Object data) {
|
}
|
||||||
if (calculatorEventType.isOfType(calculation_result, calculation_failed, calculation_cancelled, conversion_result, conversion_failed)) {
|
|
||||||
|
@Override
|
||||||
if (calculatorEventData.isAfter(lastCalculatorEventData)) {
|
public void onCalculatorEvent(@NotNull CalculatorEventData calculatorEventData,
|
||||||
lastCalculatorEventData = calculatorEventData;
|
@NotNull CalculatorEventType calculatorEventType,
|
||||||
}
|
@Nullable Object data) {
|
||||||
|
if (calculatorEventType.isOfType(calculation_result, calculation_failed, calculation_cancelled, conversion_result, conversion_failed)) {
|
||||||
switch (calculatorEventType) {
|
|
||||||
case conversion_failed:
|
boolean processEvent = false;
|
||||||
processConversationFailed((CalculatorConversionEventData) calculatorEventData, (ConversionFailure) data);
|
boolean sameSequence = false;
|
||||||
break;
|
|
||||||
case conversion_result:
|
synchronized (lastCalculatorEventDataLock) {
|
||||||
processConversationResult((CalculatorConversionEventData)calculatorEventData, (String)data);
|
if (calculatorEventData.isAfter(lastCalculatorEventData)) {
|
||||||
break;
|
sameSequence = calculatorEventData.isSameSequence(lastCalculatorEventData);
|
||||||
case calculation_result:
|
lastCalculatorEventData = calculatorEventData;
|
||||||
processCalculationResult((CalculatorEvaluationEventData) calculatorEventData, (CalculatorOutput) data);
|
processEvent = true;
|
||||||
break;
|
}
|
||||||
case calculation_cancelled:
|
}
|
||||||
processCalculationCancelled((CalculatorEvaluationEventData)calculatorEventData);
|
|
||||||
break;
|
if (processEvent) {
|
||||||
case calculation_failed:
|
switch (calculatorEventType) {
|
||||||
processCalculationFailed((CalculatorEvaluationEventData)calculatorEventData, (CalculatorFailure) data);
|
case conversion_failed:
|
||||||
break;
|
processConversationFailed((CalculatorConversionEventData) calculatorEventData, (ConversionFailure) data);
|
||||||
}
|
break;
|
||||||
|
case conversion_result:
|
||||||
}
|
processConversationResult((CalculatorConversionEventData)calculatorEventData, (String)data);
|
||||||
}
|
break;
|
||||||
|
case calculation_result:
|
||||||
private void processConversationFailed(@NotNull CalculatorConversionEventData calculatorEventData,
|
processCalculationResult((CalculatorEvaluationEventData) calculatorEventData, (CalculatorOutput) data);
|
||||||
@NotNull ConversionFailure data) {
|
break;
|
||||||
this.setViewStateForSequence(CalculatorDisplayViewStateImpl.newErrorState(calculatorEventData.getDisplayState().getOperation(), CalculatorMessages.getBundle().getString(CalculatorMessages.syntax_error)), calculatorEventData.getSequenceId());
|
case calculation_cancelled:
|
||||||
|
processCalculationCancelled((CalculatorEvaluationEventData)calculatorEventData);
|
||||||
}
|
break;
|
||||||
|
case calculation_failed:
|
||||||
private void processCalculationFailed(@NotNull CalculatorEvaluationEventData calculatorEventData, @NotNull CalculatorFailure data) {
|
processCalculationFailed((CalculatorEvaluationEventData)calculatorEventData, (CalculatorFailure) data);
|
||||||
|
break;
|
||||||
final CalculatorEvalException calculatorEvalException = data.getCalculationEvalException();
|
}
|
||||||
|
}
|
||||||
final String errorMessage;
|
}
|
||||||
if (calculatorEvalException != null) {
|
}
|
||||||
errorMessage = CalculatorMessages.getBundle().getString(CalculatorMessages.syntax_error);
|
|
||||||
} else {
|
private void processConversationFailed(@NotNull CalculatorConversionEventData calculatorEventData,
|
||||||
final CalculatorParseException calculationParseException = data.getCalculationParseException();
|
@NotNull ConversionFailure data) {
|
||||||
if (calculationParseException != null) {
|
this.setViewStateForSequence(CalculatorDisplayViewStateImpl.newErrorState(calculatorEventData.getDisplayState().getOperation(), CalculatorMessages.getBundle().getString(CalculatorMessages.syntax_error)), calculatorEventData.getSequenceId());
|
||||||
errorMessage = calculationParseException.getLocalizedMessage();
|
|
||||||
} else {
|
}
|
||||||
errorMessage = CalculatorMessages.getBundle().getString(CalculatorMessages.syntax_error);
|
|
||||||
}
|
private void processCalculationFailed(@NotNull CalculatorEvaluationEventData calculatorEventData, @NotNull CalculatorFailure data) {
|
||||||
}
|
|
||||||
|
final CalculatorEvalException calculatorEvalException = data.getCalculationEvalException();
|
||||||
this.setViewStateForSequence(CalculatorDisplayViewStateImpl.newErrorState(calculatorEventData.getOperation(), errorMessage), calculatorEventData.getSequenceId());
|
|
||||||
}
|
final String errorMessage;
|
||||||
|
if (calculatorEvalException != null) {
|
||||||
private void processCalculationCancelled(@NotNull CalculatorEvaluationEventData calculatorEventData) {
|
errorMessage = CalculatorMessages.getBundle().getString(CalculatorMessages.syntax_error);
|
||||||
final String errorMessage = CalculatorMessages.getBundle().getString(CalculatorMessages.syntax_error);
|
} else {
|
||||||
|
final CalculatorParseException calculationParseException = data.getCalculationParseException();
|
||||||
this.setViewStateForSequence(CalculatorDisplayViewStateImpl.newErrorState(calculatorEventData.getOperation(), errorMessage), calculatorEventData.getSequenceId());
|
if (calculationParseException != null) {
|
||||||
}
|
errorMessage = calculationParseException.getLocalizedMessage();
|
||||||
|
} else {
|
||||||
private void processCalculationResult(@NotNull CalculatorEvaluationEventData calculatorEventData, @NotNull CalculatorOutput data) {
|
errorMessage = CalculatorMessages.getBundle().getString(CalculatorMessages.syntax_error);
|
||||||
final String stringResult = data.getStringResult();
|
}
|
||||||
this.setViewStateForSequence(CalculatorDisplayViewStateImpl.newValidState(calculatorEventData.getOperation(), data.getResult(), stringResult, 0), calculatorEventData.getSequenceId());
|
}
|
||||||
}
|
|
||||||
|
this.setViewStateForSequence(CalculatorDisplayViewStateImpl.newErrorState(calculatorEventData.getOperation(), errorMessage), calculatorEventData.getSequenceId());
|
||||||
private void processConversationResult(@NotNull CalculatorConversionEventData calculatorEventData, @NotNull String result) {
|
}
|
||||||
// add prefix
|
|
||||||
if (calculatorEventData.getFromNumeralBase() != calculatorEventData.getToNumeralBase()) {
|
private void processCalculationCancelled(@NotNull CalculatorEvaluationEventData calculatorEventData) {
|
||||||
result = calculatorEventData.getToNumeralBase().getJsclPrefix() + result;
|
final String errorMessage = CalculatorMessages.getBundle().getString(CalculatorMessages.syntax_error);
|
||||||
}
|
|
||||||
|
this.setViewStateForSequence(CalculatorDisplayViewStateImpl.newErrorState(calculatorEventData.getOperation(), errorMessage), calculatorEventData.getSequenceId());
|
||||||
final CalculatorDisplayViewState displayState = calculatorEventData.getDisplayState();
|
}
|
||||||
this.setViewStateForSequence(CalculatorDisplayViewStateImpl.newValidState(displayState.getOperation(), displayState.getResult(), result, 0), calculatorEventData.getSequenceId());
|
|
||||||
}
|
private void processCalculationResult(@NotNull CalculatorEvaluationEventData calculatorEventData, @NotNull CalculatorOutput data) {
|
||||||
}
|
final String stringResult = data.getStringResult();
|
||||||
|
this.setViewStateForSequence(CalculatorDisplayViewStateImpl.newValidState(calculatorEventData.getOperation(), data.getResult(), stringResult, 0), calculatorEventData.getSequenceId());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processConversationResult(@NotNull CalculatorConversionEventData calculatorEventData, @NotNull String result) {
|
||||||
|
// add prefix
|
||||||
|
if (calculatorEventData.getFromNumeralBase() != calculatorEventData.getToNumeralBase()) {
|
||||||
|
result = calculatorEventData.getToNumeralBase().getJsclPrefix() + result;
|
||||||
|
}
|
||||||
|
|
||||||
|
final CalculatorDisplayViewState displayState = calculatorEventData.getDisplayState();
|
||||||
|
this.setViewStateForSequence(CalculatorDisplayViewStateImpl.newValidState(displayState.getOperation(), displayState.getResult(), result, 0), calculatorEventData.getSequenceId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -16,6 +16,9 @@ public interface CalculatorEditor extends CalculatorEventListener {
|
|||||||
@NotNull
|
@NotNull
|
||||||
CalculatorEditorViewState getViewState();
|
CalculatorEditorViewState getViewState();
|
||||||
|
|
||||||
|
// updates state of view (view.setState())
|
||||||
|
void updateViewState();
|
||||||
|
|
||||||
void setViewState(@NotNull CalculatorEditorViewState viewState);
|
void setViewState(@NotNull CalculatorEditorViewState viewState);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -48,8 +48,17 @@ public class CalculatorEditorImpl implements CalculatorEditor {
|
|||||||
return lastViewState;
|
return lastViewState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateViewState() {
|
||||||
|
setViewState(this.lastViewState, false);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setViewState(@NotNull CalculatorEditorViewState newViewState) {
|
public void setViewState(@NotNull CalculatorEditorViewState newViewState) {
|
||||||
|
setViewState(newViewState, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setViewState(CalculatorEditorViewState newViewState, boolean fireEvent) {
|
||||||
synchronized (viewLock) {
|
synchronized (viewLock) {
|
||||||
final CalculatorEditorViewState oldViewState = this.lastViewState;
|
final CalculatorEditorViewState oldViewState = this.lastViewState;
|
||||||
|
|
||||||
@ -58,7 +67,9 @@ public class CalculatorEditorImpl implements CalculatorEditor {
|
|||||||
this.view.setState(newViewState);
|
this.view.setState(newViewState);
|
||||||
}
|
}
|
||||||
|
|
||||||
calculator.fireCalculatorEvent(CalculatorEventType.editor_state_changed, new CalculatorEditorChangeEventDataImpl(oldViewState, newViewState));
|
if (fireEvent) {
|
||||||
|
calculator.fireCalculatorEvent(CalculatorEventType.editor_state_changed, new CalculatorEditorChangeEventDataImpl(oldViewState, newViewState));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,433 +1,436 @@
|
|||||||
package org.solovyev.android.calculator;
|
package org.solovyev.android.calculator;
|
||||||
|
|
||||||
import jscl.AbstractJsclArithmeticException;
|
import jscl.AbstractJsclArithmeticException;
|
||||||
import jscl.NumeralBase;
|
import jscl.NumeralBase;
|
||||||
import jscl.NumeralBaseException;
|
import jscl.NumeralBaseException;
|
||||||
import jscl.math.Generic;
|
import jscl.math.Generic;
|
||||||
import jscl.text.ParseInterruptedException;
|
import jscl.text.ParseInterruptedException;
|
||||||
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.history.CalculatorHistory;
|
import org.solovyev.android.calculator.history.CalculatorHistory;
|
||||||
import org.solovyev.android.calculator.history.CalculatorHistoryState;
|
import org.solovyev.android.calculator.history.CalculatorHistoryState;
|
||||||
import org.solovyev.android.calculator.jscl.JsclOperation;
|
import org.solovyev.android.calculator.jscl.JsclOperation;
|
||||||
import org.solovyev.android.calculator.text.TextProcessor;
|
import org.solovyev.android.calculator.text.TextProcessor;
|
||||||
import org.solovyev.android.calculator.units.CalculatorNumeralBase;
|
import org.solovyev.android.calculator.units.CalculatorNumeralBase;
|
||||||
import org.solovyev.common.history.HistoryAction;
|
import org.solovyev.common.history.HistoryAction;
|
||||||
import org.solovyev.common.msg.MessageRegistry;
|
import org.solovyev.common.msg.MessageRegistry;
|
||||||
import org.solovyev.common.msg.MessageType;
|
import org.solovyev.common.msg.MessageType;
|
||||||
import org.solovyev.common.text.StringUtils;
|
import org.solovyev.common.text.StringUtils;
|
||||||
import org.solovyev.math.units.*;
|
import org.solovyev.math.units.*;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* User: Solovyev_S
|
* User: Solovyev_S
|
||||||
* Date: 20.09.12
|
* Date: 20.09.12
|
||||||
* Time: 16:42
|
* Time: 16:42
|
||||||
*/
|
*/
|
||||||
public class CalculatorImpl implements Calculator, CalculatorEventListener {
|
public class CalculatorImpl implements Calculator, CalculatorEventListener {
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private final CalculatorEventContainer calculatorEventContainer = new ListCalculatorEventContainer();
|
private final CalculatorEventContainer calculatorEventContainer = new ListCalculatorEventContainer();
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private final AtomicLong counter = new AtomicLong(CalculatorUtils.FIRST_ID);
|
private final AtomicLong counter = new AtomicLong(CalculatorUtils.FIRST_ID);
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private final TextProcessor<PreparedExpression, String> preprocessor = ToJsclTextProcessor.getInstance();
|
private final TextProcessor<PreparedExpression, String> preprocessor = ToJsclTextProcessor.getInstance();
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private final Executor threadPoolExecutor = Executors.newFixedThreadPool(10);
|
private final Executor calculationsExecutor = Executors.newFixedThreadPool(10);
|
||||||
|
|
||||||
public CalculatorImpl() {
|
@NotNull
|
||||||
this.addCalculatorEventListener(this);
|
private final Executor eventExecutor = Executors.newFixedThreadPool(1);
|
||||||
}
|
|
||||||
|
public CalculatorImpl() {
|
||||||
@NotNull
|
this.addCalculatorEventListener(this);
|
||||||
private CalculatorEventData nextEventData() {
|
}
|
||||||
long eventId = counter.incrementAndGet();
|
|
||||||
return CalculatorEventDataImpl.newInstance(eventId, eventId);
|
@NotNull
|
||||||
}
|
private CalculatorEventData nextEventData() {
|
||||||
|
long eventId = counter.incrementAndGet();
|
||||||
@NotNull
|
return CalculatorEventDataImpl.newInstance(eventId, eventId);
|
||||||
private CalculatorEventData nextEventData(@NotNull Long sequenceId) {
|
}
|
||||||
long eventId = counter.incrementAndGet();
|
|
||||||
return CalculatorEventDataImpl.newInstance(eventId, sequenceId);
|
@NotNull
|
||||||
}
|
private CalculatorEventData nextEventData(@NotNull Long sequenceId) {
|
||||||
|
long eventId = counter.incrementAndGet();
|
||||||
/*
|
return CalculatorEventDataImpl.newInstance(eventId, sequenceId);
|
||||||
**********************************************************************
|
}
|
||||||
*
|
|
||||||
* CALCULATION
|
/*
|
||||||
*
|
**********************************************************************
|
||||||
**********************************************************************
|
*
|
||||||
*/
|
* CALCULATION
|
||||||
|
*
|
||||||
@Override
|
**********************************************************************
|
||||||
public void evaluate() {
|
*/
|
||||||
final CalculatorEditorViewState viewState = getEditor().getViewState();
|
|
||||||
fireCalculatorEvent(CalculatorEventType.manual_calculation_requested, viewState);
|
@Override
|
||||||
this.evaluate(JsclOperation.numeric, viewState.getText());
|
public void evaluate() {
|
||||||
}
|
final CalculatorEditorViewState viewState = getEditor().getViewState();
|
||||||
|
fireCalculatorEvent(CalculatorEventType.manual_calculation_requested, viewState);
|
||||||
@Override
|
this.evaluate(JsclOperation.numeric, viewState.getText());
|
||||||
public void evaluate(@NotNull Long sequenceId) {
|
}
|
||||||
final CalculatorEditorViewState viewState = getEditor().getViewState();
|
|
||||||
fireCalculatorEvent(CalculatorEventType.manual_calculation_requested, viewState, sequenceId);
|
@Override
|
||||||
this.evaluate(JsclOperation.numeric, viewState.getText(), sequenceId);
|
public void evaluate(@NotNull Long sequenceId) {
|
||||||
}
|
final CalculatorEditorViewState viewState = getEditor().getViewState();
|
||||||
|
fireCalculatorEvent(CalculatorEventType.manual_calculation_requested, viewState, sequenceId);
|
||||||
@Override
|
this.evaluate(JsclOperation.numeric, viewState.getText(), sequenceId);
|
||||||
public void simplify() {
|
}
|
||||||
final CalculatorEditorViewState viewState = getEditor().getViewState();
|
|
||||||
fireCalculatorEvent(CalculatorEventType.manual_calculation_requested, viewState);
|
@Override
|
||||||
this.evaluate(JsclOperation.simplify, viewState.getText());
|
public void simplify() {
|
||||||
}
|
final CalculatorEditorViewState viewState = getEditor().getViewState();
|
||||||
|
fireCalculatorEvent(CalculatorEventType.manual_calculation_requested, viewState);
|
||||||
@NotNull
|
this.evaluate(JsclOperation.simplify, viewState.getText());
|
||||||
@Override
|
}
|
||||||
public CalculatorEventData evaluate(@NotNull final JsclOperation operation,
|
|
||||||
@NotNull final String expression) {
|
@NotNull
|
||||||
|
@Override
|
||||||
final CalculatorEventData eventDataId = nextEventData();
|
public CalculatorEventData evaluate(@NotNull final JsclOperation operation,
|
||||||
|
@NotNull final String expression) {
|
||||||
threadPoolExecutor.execute(new Runnable() {
|
|
||||||
@Override
|
final CalculatorEventData eventDataId = nextEventData();
|
||||||
public void run() {
|
|
||||||
CalculatorImpl.this.evaluate(eventDataId.getSequenceId(), operation, expression, null);
|
calculationsExecutor.execute(new Runnable() {
|
||||||
}
|
@Override
|
||||||
});
|
public void run() {
|
||||||
|
CalculatorImpl.this.evaluate(eventDataId.getSequenceId(), operation, expression, null);
|
||||||
return eventDataId;
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
@NotNull
|
return eventDataId;
|
||||||
@Override
|
}
|
||||||
public CalculatorEventData evaluate(@NotNull final JsclOperation operation, @NotNull final String expression, @NotNull Long sequenceId) {
|
|
||||||
final CalculatorEventData eventDataId = nextEventData(sequenceId);
|
@NotNull
|
||||||
|
@Override
|
||||||
threadPoolExecutor.execute(new Runnable() {
|
public CalculatorEventData evaluate(@NotNull final JsclOperation operation, @NotNull final String expression, @NotNull Long sequenceId) {
|
||||||
@Override
|
final CalculatorEventData eventDataId = nextEventData(sequenceId);
|
||||||
public void run() {
|
|
||||||
CalculatorImpl.this.evaluate(eventDataId.getSequenceId(), operation, expression, null);
|
calculationsExecutor.execute(new Runnable() {
|
||||||
}
|
@Override
|
||||||
});
|
public void run() {
|
||||||
|
CalculatorImpl.this.evaluate(eventDataId.getSequenceId(), operation, expression, null);
|
||||||
return eventDataId;
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
@Override
|
return eventDataId;
|
||||||
public void init() {
|
}
|
||||||
CalculatorLocatorImpl.getInstance().getEngine().init();
|
|
||||||
CalculatorLocatorImpl.getInstance().getHistory().load();
|
@Override
|
||||||
}
|
public void init() {
|
||||||
|
CalculatorLocatorImpl.getInstance().getEngine().init();
|
||||||
@NotNull
|
CalculatorLocatorImpl.getInstance().getHistory().load();
|
||||||
private CalculatorConversionEventData newConversionEventData(@NotNull Long sequenceId,
|
}
|
||||||
@NotNull Generic value,
|
|
||||||
@NotNull NumeralBase from,
|
@NotNull
|
||||||
@NotNull NumeralBase to,
|
private CalculatorConversionEventData newConversionEventData(@NotNull Long sequenceId,
|
||||||
@NotNull CalculatorDisplayViewState displayViewState) {
|
@NotNull Generic value,
|
||||||
return CalculatorConversionEventDataImpl.newInstance(nextEventData(sequenceId), value, from, to, displayViewState);
|
@NotNull NumeralBase from,
|
||||||
}
|
@NotNull NumeralBase to,
|
||||||
|
@NotNull CalculatorDisplayViewState displayViewState) {
|
||||||
private void evaluate(@NotNull Long sequenceId,
|
return CalculatorConversionEventDataImpl.newInstance(nextEventData(sequenceId), value, from, to, displayViewState);
|
||||||
@NotNull JsclOperation operation,
|
}
|
||||||
@NotNull String expression,
|
|
||||||
@Nullable MessageRegistry mr) {
|
private void evaluate(@NotNull Long sequenceId,
|
||||||
|
@NotNull JsclOperation operation,
|
||||||
PreparedExpression preparedExpression = null;
|
@NotNull String expression,
|
||||||
|
@Nullable MessageRegistry mr) {
|
||||||
fireCalculatorEvent(newCalculationEventData(operation, expression, sequenceId), CalculatorEventType.calculation_started, new CalculatorInputImpl(expression, operation));
|
|
||||||
|
PreparedExpression preparedExpression = null;
|
||||||
try {
|
|
||||||
|
fireCalculatorEvent(newCalculationEventData(operation, expression, sequenceId), CalculatorEventType.calculation_started, new CalculatorInputImpl(expression, operation));
|
||||||
expression = expression.trim();
|
|
||||||
|
try {
|
||||||
if (StringUtils.isEmpty(expression)) {
|
|
||||||
fireCalculatorEvent(newCalculationEventData(operation, expression, sequenceId), CalculatorEventType.calculation_result, CalculatorOutputImpl.newEmptyOutput(operation));
|
expression = expression.trim();
|
||||||
} else {
|
|
||||||
preparedExpression = preprocessor.process(expression);
|
if (StringUtils.isEmpty(expression)) {
|
||||||
|
fireCalculatorEvent(newCalculationEventData(operation, expression, sequenceId), CalculatorEventType.calculation_result, CalculatorOutputImpl.newEmptyOutput(operation));
|
||||||
final String jsclExpression = preparedExpression.toString();
|
} else {
|
||||||
|
preparedExpression = preprocessor.process(expression);
|
||||||
try {
|
|
||||||
|
final String jsclExpression = preparedExpression.toString();
|
||||||
final Generic result = operation.evaluateGeneric(jsclExpression, CalculatorLocatorImpl.getInstance().getEngine().getMathEngine());
|
|
||||||
|
try {
|
||||||
// NOTE: toString() method must be called here as ArithmeticOperationException may occur in it (just to avoid later check!)
|
|
||||||
result.toString();
|
final Generic result = operation.evaluateGeneric(jsclExpression, CalculatorLocatorImpl.getInstance().getEngine().getMathEngine());
|
||||||
|
|
||||||
final CalculatorOutput data = CalculatorOutputImpl.newOutput(operation.getFromProcessor().process(result), operation, result);
|
// NOTE: toString() method must be called here as ArithmeticOperationException may occur in it (just to avoid later check!)
|
||||||
fireCalculatorEvent(newCalculationEventData(operation, expression, sequenceId), CalculatorEventType.calculation_result, data);
|
result.toString();
|
||||||
|
|
||||||
} catch (AbstractJsclArithmeticException e) {
|
final CalculatorOutput data = CalculatorOutputImpl.newOutput(operation.getFromProcessor().process(result), operation, result);
|
||||||
handleException(sequenceId, operation, expression, mr, new CalculatorEvalException(e, e, jsclExpression));
|
fireCalculatorEvent(newCalculationEventData(operation, expression, sequenceId), CalculatorEventType.calculation_result, data);
|
||||||
}
|
|
||||||
}
|
} catch (AbstractJsclArithmeticException e) {
|
||||||
|
handleException(sequenceId, operation, expression, mr, new CalculatorEvalException(e, e, jsclExpression));
|
||||||
} catch (ArithmeticException e) {
|
}
|
||||||
handleException(sequenceId, operation, expression, mr, preparedExpression, new CalculatorParseException(expression, new CalculatorMessage(CalculatorMessages.msg_001, MessageType.error, e.getMessage())));
|
}
|
||||||
} catch (StackOverflowError e) {
|
|
||||||
handleException(sequenceId, operation, expression, mr, preparedExpression, new CalculatorParseException(expression, new CalculatorMessage(CalculatorMessages.msg_002, MessageType.error)));
|
} catch (ArithmeticException e) {
|
||||||
} catch (jscl.text.ParseException e) {
|
handleException(sequenceId, operation, expression, mr, preparedExpression, new CalculatorParseException(expression, new CalculatorMessage(CalculatorMessages.msg_001, MessageType.error, e.getMessage())));
|
||||||
handleException(sequenceId, operation, expression, mr, preparedExpression, new CalculatorParseException(e));
|
} catch (StackOverflowError e) {
|
||||||
} catch (ParseInterruptedException e) {
|
handleException(sequenceId, operation, expression, mr, preparedExpression, new CalculatorParseException(expression, new CalculatorMessage(CalculatorMessages.msg_002, MessageType.error)));
|
||||||
|
} catch (jscl.text.ParseException e) {
|
||||||
// do nothing - we ourselves interrupt the calculations
|
handleException(sequenceId, operation, expression, mr, preparedExpression, new CalculatorParseException(e));
|
||||||
fireCalculatorEvent(newCalculationEventData(operation, expression, sequenceId), CalculatorEventType.calculation_cancelled, null);
|
} catch (ParseInterruptedException e) {
|
||||||
|
|
||||||
} catch (CalculatorParseException e) {
|
// do nothing - we ourselves interrupt the calculations
|
||||||
handleException(sequenceId, operation, expression, mr, preparedExpression, e);
|
fireCalculatorEvent(newCalculationEventData(operation, expression, sequenceId), CalculatorEventType.calculation_cancelled, null);
|
||||||
} finally {
|
|
||||||
fireCalculatorEvent(newCalculationEventData(operation, expression, sequenceId), CalculatorEventType.calculation_finished, null);
|
} catch (CalculatorParseException e) {
|
||||||
}
|
handleException(sequenceId, operation, expression, mr, preparedExpression, e);
|
||||||
}
|
} finally {
|
||||||
|
fireCalculatorEvent(newCalculationEventData(operation, expression, sequenceId), CalculatorEventType.calculation_finished, null);
|
||||||
@NotNull
|
}
|
||||||
private CalculatorEventData newCalculationEventData(@NotNull JsclOperation operation,
|
}
|
||||||
@NotNull String expression,
|
|
||||||
@NotNull Long calculationId) {
|
@NotNull
|
||||||
return new CalculatorEvaluationEventDataImpl(nextEventData(calculationId), operation, expression);
|
private CalculatorEventData newCalculationEventData(@NotNull JsclOperation operation,
|
||||||
}
|
@NotNull String expression,
|
||||||
|
@NotNull Long calculationId) {
|
||||||
private void handleException(@NotNull Long sequenceId,
|
return new CalculatorEvaluationEventDataImpl(nextEventData(calculationId), operation, expression);
|
||||||
@NotNull JsclOperation operation,
|
}
|
||||||
@NotNull String expression,
|
|
||||||
@Nullable MessageRegistry mr,
|
private void handleException(@NotNull Long sequenceId,
|
||||||
@Nullable PreparedExpression preparedExpression,
|
@NotNull JsclOperation operation,
|
||||||
@NotNull CalculatorParseException parseException) {
|
@NotNull String expression,
|
||||||
|
@Nullable MessageRegistry mr,
|
||||||
if (operation == JsclOperation.numeric
|
@Nullable PreparedExpression preparedExpression,
|
||||||
&& preparedExpression != null
|
@NotNull CalculatorParseException parseException) {
|
||||||
&& preparedExpression.isExistsUndefinedVar()) {
|
|
||||||
|
if (operation == JsclOperation.numeric
|
||||||
evaluate(sequenceId, JsclOperation.simplify, expression, mr);
|
&& preparedExpression != null
|
||||||
} else {
|
&& preparedExpression.isExistsUndefinedVar()) {
|
||||||
|
|
||||||
fireCalculatorEvent(newCalculationEventData(operation, expression, sequenceId), CalculatorEventType.calculation_failed, new CalculatorFailureImpl(parseException));
|
evaluate(sequenceId, JsclOperation.simplify, expression, mr);
|
||||||
}
|
} else {
|
||||||
}
|
|
||||||
|
fireCalculatorEvent(newCalculationEventData(operation, expression, sequenceId), CalculatorEventType.calculation_failed, new CalculatorFailureImpl(parseException));
|
||||||
private void handleException(@NotNull Long calculationId,
|
}
|
||||||
@NotNull JsclOperation operation,
|
}
|
||||||
@NotNull String expression,
|
|
||||||
@Nullable MessageRegistry mr,
|
private void handleException(@NotNull Long calculationId,
|
||||||
@NotNull CalculatorEvalException evalException) {
|
@NotNull JsclOperation operation,
|
||||||
|
@NotNull String expression,
|
||||||
if (operation == JsclOperation.numeric && evalException.getCause() instanceof NumeralBaseException) {
|
@Nullable MessageRegistry mr,
|
||||||
evaluate(calculationId, JsclOperation.simplify, expression, mr);
|
@NotNull CalculatorEvalException evalException) {
|
||||||
}
|
|
||||||
|
if (operation == JsclOperation.numeric && evalException.getCause() instanceof NumeralBaseException) {
|
||||||
fireCalculatorEvent(newCalculationEventData(operation, expression, calculationId), CalculatorEventType.calculation_failed, new CalculatorFailureImpl(evalException));
|
evaluate(calculationId, JsclOperation.simplify, expression, mr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
fireCalculatorEvent(newCalculationEventData(operation, expression, calculationId), CalculatorEventType.calculation_failed, new CalculatorFailureImpl(evalException));
|
||||||
**********************************************************************
|
}
|
||||||
*
|
|
||||||
* CONVERSION
|
/*
|
||||||
*
|
**********************************************************************
|
||||||
**********************************************************************
|
*
|
||||||
*/
|
* CONVERSION
|
||||||
|
*
|
||||||
@NotNull
|
**********************************************************************
|
||||||
@Override
|
*/
|
||||||
public CalculatorEventData convert(@NotNull final Generic value,
|
|
||||||
@NotNull final NumeralBase to) {
|
@NotNull
|
||||||
final CalculatorEventData eventDataId = nextEventData();
|
@Override
|
||||||
|
public CalculatorEventData convert(@NotNull final Generic value,
|
||||||
final CalculatorDisplayViewState displayViewState = CalculatorLocatorImpl.getInstance().getDisplay().getViewState();
|
@NotNull final NumeralBase to) {
|
||||||
final NumeralBase from = CalculatorLocatorImpl.getInstance().getEngine().getNumeralBase();
|
final CalculatorEventData eventDataId = nextEventData();
|
||||||
|
|
||||||
threadPoolExecutor.execute(new Runnable() {
|
final CalculatorDisplayViewState displayViewState = CalculatorLocatorImpl.getInstance().getDisplay().getViewState();
|
||||||
@Override
|
final NumeralBase from = CalculatorLocatorImpl.getInstance().getEngine().getNumeralBase();
|
||||||
public void run() {
|
|
||||||
final Long sequenceId = eventDataId.getSequenceId();
|
calculationsExecutor.execute(new Runnable() {
|
||||||
|
@Override
|
||||||
fireCalculatorEvent(newConversionEventData(sequenceId, value, from, to, displayViewState), CalculatorEventType.conversion_started, null);
|
public void run() {
|
||||||
try {
|
final Long sequenceId = eventDataId.getSequenceId();
|
||||||
|
|
||||||
final String result = doConversion(value, from, to);
|
fireCalculatorEvent(newConversionEventData(sequenceId, value, from, to, displayViewState), CalculatorEventType.conversion_started, null);
|
||||||
|
try {
|
||||||
fireCalculatorEvent(newConversionEventData(sequenceId, value, from, to, displayViewState), CalculatorEventType.conversion_result, result);
|
|
||||||
|
final String result = doConversion(value, from, to);
|
||||||
} catch (ConversionException e) {
|
|
||||||
fireCalculatorEvent(newConversionEventData(sequenceId, value, from, to, displayViewState), CalculatorEventType.conversion_failed, new ConversionFailureImpl(e));
|
fireCalculatorEvent(newConversionEventData(sequenceId, value, from, to, displayViewState), CalculatorEventType.conversion_result, result);
|
||||||
}
|
|
||||||
}
|
} catch (ConversionException e) {
|
||||||
});
|
fireCalculatorEvent(newConversionEventData(sequenceId, value, from, to, displayViewState), CalculatorEventType.conversion_failed, new ConversionFailureImpl(e));
|
||||||
|
}
|
||||||
return eventDataId;
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
@NotNull
|
return eventDataId;
|
||||||
private static String doConversion(@NotNull Generic generic,
|
}
|
||||||
@NotNull NumeralBase from,
|
|
||||||
@NotNull NumeralBase to) throws ConversionException {
|
@NotNull
|
||||||
final String result;
|
private static String doConversion(@NotNull Generic generic,
|
||||||
|
@NotNull NumeralBase from,
|
||||||
if (from != to) {
|
@NotNull NumeralBase to) throws ConversionException {
|
||||||
String fromString = generic.toString();
|
final String result;
|
||||||
if (!StringUtils.isEmpty(fromString)) {
|
|
||||||
try {
|
if (from != to) {
|
||||||
fromString = ToJsclTextProcessor.getInstance().process(fromString).getExpression();
|
String fromString = generic.toString();
|
||||||
} catch (CalculatorParseException e) {
|
if (!StringUtils.isEmpty(fromString)) {
|
||||||
// ok, problems while processing occurred
|
try {
|
||||||
}
|
fromString = ToJsclTextProcessor.getInstance().process(fromString).getExpression();
|
||||||
}
|
} catch (CalculatorParseException e) {
|
||||||
|
// ok, problems while processing occurred
|
||||||
result = ConversionUtils.doConversion(CalculatorNumeralBase.getConverter(), fromString, CalculatorNumeralBase.valueOf(from), CalculatorNumeralBase.valueOf(to));
|
}
|
||||||
} else {
|
}
|
||||||
result = generic.toString();
|
|
||||||
}
|
result = ConversionUtils.doConversion(CalculatorNumeralBase.getConverter(), fromString, CalculatorNumeralBase.valueOf(from), CalculatorNumeralBase.valueOf(to));
|
||||||
|
} else {
|
||||||
return result;
|
result = generic.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
return result;
|
||||||
public boolean isConversionPossible(@NotNull Generic generic, NumeralBase from, @NotNull NumeralBase to) {
|
}
|
||||||
try {
|
|
||||||
doConversion(generic, from, to);
|
@Override
|
||||||
return true;
|
public boolean isConversionPossible(@NotNull Generic generic, NumeralBase from, @NotNull NumeralBase to) {
|
||||||
} catch (ConversionException e) {
|
try {
|
||||||
return false;
|
doConversion(generic, from, to);
|
||||||
}
|
return true;
|
||||||
}
|
} catch (ConversionException e) {
|
||||||
|
return false;
|
||||||
/*
|
}
|
||||||
**********************************************************************
|
}
|
||||||
*
|
|
||||||
* EVENTS
|
/*
|
||||||
*
|
**********************************************************************
|
||||||
**********************************************************************
|
*
|
||||||
*/
|
* EVENTS
|
||||||
|
*
|
||||||
@Override
|
**********************************************************************
|
||||||
public void addCalculatorEventListener(@NotNull CalculatorEventListener calculatorEventListener) {
|
*/
|
||||||
calculatorEventContainer.addCalculatorEventListener(calculatorEventListener);
|
|
||||||
}
|
@Override
|
||||||
|
public void addCalculatorEventListener(@NotNull CalculatorEventListener calculatorEventListener) {
|
||||||
@Override
|
calculatorEventContainer.addCalculatorEventListener(calculatorEventListener);
|
||||||
public void removeCalculatorEventListener(@NotNull CalculatorEventListener calculatorEventListener) {
|
}
|
||||||
calculatorEventContainer.removeCalculatorEventListener(calculatorEventListener);
|
|
||||||
}
|
@Override
|
||||||
|
public void removeCalculatorEventListener(@NotNull CalculatorEventListener calculatorEventListener) {
|
||||||
@Override
|
calculatorEventContainer.removeCalculatorEventListener(calculatorEventListener);
|
||||||
public void fireCalculatorEvent(@NotNull CalculatorEventData calculatorEventData, @NotNull CalculatorEventType calculatorEventType, @Nullable Object data) {
|
}
|
||||||
calculatorEventContainer.fireCalculatorEvent(calculatorEventData, calculatorEventType, data);
|
|
||||||
}
|
@Override
|
||||||
|
public void fireCalculatorEvent(@NotNull final CalculatorEventData calculatorEventData, @NotNull final CalculatorEventType calculatorEventType, @Nullable final Object data) {
|
||||||
@Override
|
eventExecutor.execute(new Runnable() {
|
||||||
public void fireCalculatorEvents(@NotNull List<CalculatorEvent> calculatorEvents) {
|
@Override
|
||||||
calculatorEventContainer.fireCalculatorEvents(calculatorEvents);
|
public void run() {
|
||||||
}
|
calculatorEventContainer.fireCalculatorEvent(calculatorEventData, calculatorEventType, data);
|
||||||
|
}
|
||||||
@NotNull
|
});
|
||||||
@Override
|
}
|
||||||
public CalculatorEventData fireCalculatorEvent(@NotNull final CalculatorEventType calculatorEventType, @Nullable final Object data) {
|
|
||||||
final CalculatorEventData eventData = nextEventData();
|
@Override
|
||||||
|
public void fireCalculatorEvents(@NotNull final List<CalculatorEvent> calculatorEvents) {
|
||||||
threadPoolExecutor.execute(new Runnable() {
|
eventExecutor.execute(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
fireCalculatorEvent(eventData, calculatorEventType, data);
|
calculatorEventContainer.fireCalculatorEvents(calculatorEvents);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
}
|
||||||
return eventData;
|
|
||||||
}
|
@NotNull
|
||||||
|
@Override
|
||||||
@NotNull
|
public CalculatorEventData fireCalculatorEvent(@NotNull final CalculatorEventType calculatorEventType, @Nullable final Object data) {
|
||||||
@Override
|
final CalculatorEventData eventData = nextEventData();
|
||||||
public CalculatorEventData fireCalculatorEvent(@NotNull final CalculatorEventType calculatorEventType, @Nullable final Object data, @NotNull Long sequenceId) {
|
|
||||||
final CalculatorEventData eventData = nextEventData(sequenceId);
|
fireCalculatorEvent(eventData, calculatorEventType, data);
|
||||||
|
|
||||||
threadPoolExecutor.execute(new Runnable() {
|
return eventData;
|
||||||
@Override
|
}
|
||||||
public void run() {
|
|
||||||
fireCalculatorEvent(eventData, calculatorEventType, data);
|
@NotNull
|
||||||
}
|
@Override
|
||||||
});
|
public CalculatorEventData fireCalculatorEvent(@NotNull final CalculatorEventType calculatorEventType, @Nullable final Object data, @NotNull Long sequenceId) {
|
||||||
|
final CalculatorEventData eventData = nextEventData(sequenceId);
|
||||||
return eventData;
|
|
||||||
}
|
fireCalculatorEvent(eventData, calculatorEventType, data);
|
||||||
|
|
||||||
/*
|
return eventData;
|
||||||
**********************************************************************
|
}
|
||||||
*
|
|
||||||
* EVENTS HANDLER
|
/*
|
||||||
*
|
**********************************************************************
|
||||||
**********************************************************************
|
*
|
||||||
*/
|
* EVENTS HANDLER
|
||||||
|
*
|
||||||
@Override
|
**********************************************************************
|
||||||
public void onCalculatorEvent(@NotNull CalculatorEventData calculatorEventData, @NotNull CalculatorEventType calculatorEventType, @Nullable Object data) {
|
*/
|
||||||
|
|
||||||
switch (calculatorEventType) {
|
@Override
|
||||||
case editor_state_changed:
|
public void onCalculatorEvent(@NotNull CalculatorEventData calculatorEventData, @NotNull CalculatorEventType calculatorEventType, @Nullable Object data) {
|
||||||
final CalculatorEditorChangeEventData changeEventData = (CalculatorEditorChangeEventData) data;
|
|
||||||
|
switch (calculatorEventType) {
|
||||||
final String newText = changeEventData.getNewState().getText();
|
case editor_state_changed:
|
||||||
final String oldText = changeEventData.getOldState().getText();
|
final CalculatorEditorChangeEventData changeEventData = (CalculatorEditorChangeEventData) data;
|
||||||
|
|
||||||
if (!newText.equals(oldText)) {
|
final String newText = changeEventData.getNewState().getText();
|
||||||
evaluate(JsclOperation.numeric, changeEventData.getNewState().getText(), calculatorEventData.getSequenceId());
|
final String oldText = changeEventData.getOldState().getText();
|
||||||
}
|
|
||||||
break;
|
if (!newText.equals(oldText)) {
|
||||||
case engine_preferences_changed:
|
evaluate(JsclOperation.numeric, changeEventData.getNewState().getText(), calculatorEventData.getSequenceId());
|
||||||
evaluate(calculatorEventData.getSequenceId());
|
}
|
||||||
break;
|
break;
|
||||||
}
|
case engine_preferences_changed:
|
||||||
}
|
evaluate(calculatorEventData.getSequenceId());
|
||||||
|
break;
|
||||||
/*
|
}
|
||||||
**********************************************************************
|
}
|
||||||
*
|
|
||||||
* HISTORY
|
/*
|
||||||
*
|
**********************************************************************
|
||||||
**********************************************************************
|
*
|
||||||
*/
|
* HISTORY
|
||||||
|
*
|
||||||
@Override
|
**********************************************************************
|
||||||
public void doHistoryAction(@NotNull HistoryAction historyAction) {
|
*/
|
||||||
final CalculatorHistory history = CalculatorLocatorImpl.getInstance().getHistory();
|
|
||||||
if (history.isActionAvailable(historyAction)) {
|
@Override
|
||||||
final CalculatorHistoryState newState = history.doAction(historyAction, getCurrentHistoryState());
|
public void doHistoryAction(@NotNull HistoryAction historyAction) {
|
||||||
if (newState != null) {
|
final CalculatorHistory history = CalculatorLocatorImpl.getInstance().getHistory();
|
||||||
setCurrentHistoryState(newState);
|
if (history.isActionAvailable(historyAction)) {
|
||||||
}
|
final CalculatorHistoryState newState = history.doAction(historyAction, getCurrentHistoryState());
|
||||||
}
|
if (newState != null) {
|
||||||
}
|
setCurrentHistoryState(newState);
|
||||||
|
}
|
||||||
@Override
|
}
|
||||||
public void setCurrentHistoryState(@NotNull CalculatorHistoryState editorHistoryState) {
|
}
|
||||||
editorHistoryState.setValuesFromHistory(getEditor(), getDisplay());
|
|
||||||
}
|
@Override
|
||||||
|
public void setCurrentHistoryState(@NotNull CalculatorHistoryState editorHistoryState) {
|
||||||
@NotNull
|
editorHistoryState.setValuesFromHistory(getEditor(), getDisplay());
|
||||||
@Override
|
}
|
||||||
public CalculatorHistoryState getCurrentHistoryState() {
|
|
||||||
return CalculatorHistoryState.newInstance(getEditor(), getDisplay());
|
@NotNull
|
||||||
}
|
@Override
|
||||||
|
public CalculatorHistoryState getCurrentHistoryState() {
|
||||||
/*
|
return CalculatorHistoryState.newInstance(getEditor(), getDisplay());
|
||||||
**********************************************************************
|
}
|
||||||
*
|
|
||||||
* OTHER
|
/*
|
||||||
*
|
**********************************************************************
|
||||||
**********************************************************************
|
*
|
||||||
*/
|
* OTHER
|
||||||
|
*
|
||||||
@NotNull
|
**********************************************************************
|
||||||
private CalculatorEditor getEditor() {
|
*/
|
||||||
return CalculatorLocatorImpl.getInstance().getEditor();
|
|
||||||
}
|
@NotNull
|
||||||
|
private CalculatorEditor getEditor() {
|
||||||
@NotNull
|
return CalculatorLocatorImpl.getInstance().getEditor();
|
||||||
private CalculatorDisplay getDisplay() {
|
}
|
||||||
return CalculatorLocatorImpl.getInstance().getDisplay();
|
|
||||||
}
|
@NotNull
|
||||||
}
|
private CalculatorDisplay getDisplay() {
|
||||||
|
return CalculatorLocatorImpl.getInstance().getDisplay();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -8,10 +8,12 @@ package org.solovyev.android.calculator;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
|
import android.text.Editable;
|
||||||
import android.text.Html;
|
import android.text.Html;
|
||||||
|
import android.text.TextWatcher;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.util.Log;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.solovyev.android.calculator.text.TextProcessor;
|
import org.solovyev.android.calculator.text.TextProcessor;
|
||||||
import org.solovyev.android.calculator.view.TextHighlighter;
|
import org.solovyev.android.calculator.view.TextHighlighter;
|
||||||
import org.solovyev.android.view.AutoResizeTextView;
|
import org.solovyev.android.view.AutoResizeTextView;
|
||||||
@ -43,7 +45,12 @@ public class AndroidCalculatorDisplayView extends AutoResizeTextView implements
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private CalculatorDisplayViewState state = CalculatorDisplayViewStateImpl.newDefaultInstance();
|
private volatile CalculatorDisplayViewState state = CalculatorDisplayViewStateImpl.newDefaultInstance();
|
||||||
|
|
||||||
|
private volatile boolean viewStateChange = false;
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private final Object lock = new Object();
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private final Handler handler = new Handler();
|
private final Handler handler = new Handler();
|
||||||
@ -58,14 +65,18 @@ public class AndroidCalculatorDisplayView extends AutoResizeTextView implements
|
|||||||
|
|
||||||
public AndroidCalculatorDisplayView(Context context) {
|
public AndroidCalculatorDisplayView(Context context) {
|
||||||
super(context);
|
super(context);
|
||||||
|
this.addTextChangedListener(new TextWatcherImpl());
|
||||||
}
|
}
|
||||||
|
|
||||||
public AndroidCalculatorDisplayView(Context context, AttributeSet attrs) {
|
public AndroidCalculatorDisplayView(Context context, AttributeSet attrs) {
|
||||||
super(context, attrs);
|
super(context, attrs);
|
||||||
|
this.addTextChangedListener(new TextWatcherImpl());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public AndroidCalculatorDisplayView(Context context, AttributeSet attrs, int defStyle) {
|
public AndroidCalculatorDisplayView(Context context, AttributeSet attrs, int defStyle) {
|
||||||
super(context, attrs, defStyle);
|
super(context, attrs, defStyle);
|
||||||
|
this.addTextChangedListener(new TextWatcherImpl());
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -76,63 +87,103 @@ public class AndroidCalculatorDisplayView extends AutoResizeTextView implements
|
|||||||
**********************************************************************
|
**********************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public boolean isValid() {
|
|
||||||
synchronized (this) {
|
|
||||||
return this.state.isValid();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setState(@NotNull final CalculatorDisplayViewState state) {
|
public void setState(@NotNull final CalculatorDisplayViewState state) {
|
||||||
handler.postDelayed(new Runnable() {
|
final CharSequence text = prepareText(state.getStringResult(), state.isValid());
|
||||||
|
|
||||||
|
handler.post(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
synchronized (AndroidCalculatorDisplayView.this) {
|
synchronized (lock) {
|
||||||
AndroidCalculatorDisplayView.this.state = state;
|
try {
|
||||||
if ( state.isValid() ) {
|
viewStateChange = true;
|
||||||
setTextColor(getResources().getColor(R.color.default_text_color));
|
|
||||||
setText(state.getStringResult());
|
|
||||||
redraw();
|
|
||||||
} else {
|
|
||||||
setTextColor(getResources().getColor(R.color.display_error_text_color));
|
|
||||||
|
|
||||||
// error messages are never shown -> just greyed out text (error message will be shown on click)
|
AndroidCalculatorDisplayView.this.state = state;
|
||||||
//setText(state.getErrorMessage());
|
if (state.isValid()) {
|
||||||
//redraw();
|
setTextColor(getResources().getColor(R.color.default_text_color));
|
||||||
|
setText(text);
|
||||||
|
|
||||||
|
adjustTextSize();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// update text in order to get rid of HTML tags
|
||||||
|
setText(getText().toString());
|
||||||
|
setTextColor(getResources().getColor(R.color.display_error_text_color));
|
||||||
|
|
||||||
|
// error messages are never shown -> just greyed out text (error message will be shown on click)
|
||||||
|
//setText(state.getErrorMessage());
|
||||||
|
//redraw();
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
viewStateChange = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, 1);
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public CalculatorDisplayViewState getState() {
|
public CalculatorDisplayViewState getState() {
|
||||||
synchronized (this) {
|
synchronized (lock) {
|
||||||
return this.state;
|
return this.state;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized void redraw() {
|
@Nullable
|
||||||
if (isValid()) {
|
private static CharSequence prepareText(@Nullable String text, boolean valid) {
|
||||||
String text = getText().toString();
|
CharSequence result;
|
||||||
|
|
||||||
Log.d(this.getClass().getName(), text);
|
if (valid && text != null) {
|
||||||
|
|
||||||
|
//Log.d(this.getClass().getName(), text);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
TextHighlighter.Result result = textHighlighter.process(text);
|
final TextHighlighter.Result processedText = textHighlighter.process(text);
|
||||||
text = result.toString();
|
text = processedText.toString();
|
||||||
|
result = Html.fromHtml(text);
|
||||||
} catch (CalculatorParseException e) {
|
} catch (CalculatorParseException e) {
|
||||||
Log.e(this.getClass().getName(), e.getMessage(), e);
|
result = text;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
Log.d(this.getClass().getName(), text);
|
result = text;
|
||||||
super.setText(Html.fromHtml(text), BufferType.EDITABLE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void adjustTextSize() {
|
||||||
// todo serso: think where to move it (keep in mind org.solovyev.android.view.AutoResizeTextView.resetTextSize())
|
// todo serso: think where to move it (keep in mind org.solovyev.android.view.AutoResizeTextView.resetTextSize())
|
||||||
setAddEllipsis(false);
|
setAddEllipsis(false);
|
||||||
setMinTextSize(10);
|
setMinTextSize(10);
|
||||||
resizeText();
|
resizeText();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void handleTextChange(Editable s) {
|
||||||
|
synchronized (lock) {
|
||||||
|
if (!viewStateChange) {
|
||||||
|
// external text change => need to notify display
|
||||||
|
// todo serso: implement
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final class TextWatcherImpl implements TextWatcher {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterTextChanged(Editable s) {
|
||||||
|
handleTextChange(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,10 +10,15 @@ import android.content.SharedPreferences;
|
|||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
|
import android.text.Editable;
|
||||||
|
import android.text.Html;
|
||||||
|
import android.text.TextWatcher;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
|
import android.util.Log;
|
||||||
import android.view.ContextMenu;
|
import android.view.ContextMenu;
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.solovyev.android.calculator.text.TextProcessor;
|
import org.solovyev.android.calculator.text.TextProcessor;
|
||||||
import org.solovyev.android.calculator.view.TextHighlighter;
|
import org.solovyev.android.calculator.view.TextHighlighter;
|
||||||
import org.solovyev.common.collections.CollectionsUtils;
|
import org.solovyev.common.collections.CollectionsUtils;
|
||||||
@ -25,32 +30,39 @@ import org.solovyev.common.collections.CollectionsUtils;
|
|||||||
*/
|
*/
|
||||||
public class AndroidCalculatorEditorView extends EditText implements SharedPreferences.OnSharedPreferenceChangeListener, CalculatorEditorView {
|
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;
|
||||||
|
|
||||||
private boolean highlightText = true;
|
private boolean highlightText = true;
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private final static TextProcessor<TextHighlighter.Result, String> textHighlighter = new TextHighlighter(Color.WHITE, true);
|
private final static TextProcessor<TextHighlighter.Result, String> textHighlighter = new TextHighlighter(Color.WHITE, false);
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private volatile CalculatorEditorViewState viewState = CalculatorEditorViewStateImpl.newDefaultInstance();
|
private volatile CalculatorEditorViewState viewState = CalculatorEditorViewStateImpl.newDefaultInstance();
|
||||||
|
|
||||||
private volatile boolean viewStateChange = false;
|
private volatile boolean viewStateChange = false;
|
||||||
|
|
||||||
|
// NOTE: static because super constructor calls some overridden methods (like onSelectionChanged and current lock is not yet created)
|
||||||
|
@NotNull
|
||||||
|
private static final Object lock = new Object();
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private final Handler handler = new Handler();
|
private final Handler handler = new Handler();
|
||||||
|
|
||||||
public AndroidCalculatorEditorView(Context context) {
|
public AndroidCalculatorEditorView(Context context) {
|
||||||
super(context);
|
super(context);
|
||||||
}
|
this.addTextChangedListener(new TextWatcherImpl());
|
||||||
|
}
|
||||||
|
|
||||||
public AndroidCalculatorEditorView(Context context, AttributeSet attrs) {
|
public AndroidCalculatorEditorView(Context context, AttributeSet attrs) {
|
||||||
super(context, attrs);
|
super(context, attrs);
|
||||||
|
this.addTextChangedListener(new TextWatcherImpl());
|
||||||
}
|
}
|
||||||
|
|
||||||
public AndroidCalculatorEditorView(Context context, AttributeSet attrs, int defStyle) {
|
public AndroidCalculatorEditorView(Context context, AttributeSet attrs, int defStyle) {
|
||||||
super(context, attrs, defStyle);
|
super(context, attrs, defStyle);
|
||||||
|
this.addTextChangedListener(new TextWatcherImpl());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -59,12 +71,12 @@ public class AndroidCalculatorEditorView extends EditText implements SharedPrefe
|
|||||||
// NOTE: code below can be used carefully and should not be copied without special intention
|
// NOTE: code below can be used carefully and should not be copied without special intention
|
||||||
// The main purpose of code is to disable soft input (virtual keyboard) but leave all the TextEdit functionality, like cursor, scrolling, copy/paste menu etc
|
// The main purpose of code is to disable soft input (virtual keyboard) but leave all the TextEdit functionality, like cursor, scrolling, copy/paste menu etc
|
||||||
|
|
||||||
if ( Build.VERSION.SDK_INT >= 11 ) {
|
if (Build.VERSION.SDK_INT >= 11) {
|
||||||
// fix for missing cursor in android 3 and higher
|
// fix for missing cursor in android 3 and higher
|
||||||
try {
|
try {
|
||||||
// IDEA: return false always except if method was called from TextView.isCursorVisible() method
|
// IDEA: return false always except if method was called from TextView.isCursorVisible() method
|
||||||
for (StackTraceElement stackTraceElement : CollectionsUtils.asList(Thread.currentThread().getStackTrace())) {
|
for (StackTraceElement stackTraceElement : CollectionsUtils.asList(Thread.currentThread().getStackTrace())) {
|
||||||
if ( "isCursorVisible".equals(stackTraceElement.getMethodName()) ) {
|
if ("isCursorVisible".equals(stackTraceElement.getMethodName())) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -78,94 +90,115 @@ public class AndroidCalculatorEditorView extends EditText implements SharedPrefe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreateContextMenu(ContextMenu menu) {
|
protected void onCreateContextMenu(ContextMenu menu) {
|
||||||
super.onCreateContextMenu(menu);
|
super.onCreateContextMenu(menu);
|
||||||
|
|
||||||
menu.removeItem(android.R.id.selectAll);
|
menu.removeItem(android.R.id.selectAll);
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo serso: fix redraw
|
@Nullable
|
||||||
// Now problem is that calculator editor cursor position might be different than position of cursor in view (as some extra spaces can be inserted fur to number formatting)
|
private CharSequence prepareText(@NotNull String text, boolean highlightText) {
|
||||||
/*private synchronized void redraw() {
|
CharSequence result;
|
||||||
String text = getText().toString();
|
|
||||||
|
|
||||||
int selectionStart = getSelectionStart();
|
if (highlightText) {
|
||||||
int selectionEnd = getSelectionEnd();
|
|
||||||
|
|
||||||
if (highlightText) {
|
try {
|
||||||
|
final TextHighlighter.Result processesText = textHighlighter.process(text);
|
||||||
|
|
||||||
Log.d(this.getClass().getName(), text);
|
assert processesText.getOffset() == 0;
|
||||||
|
|
||||||
try {
|
result = Html.fromHtml(processesText.toString());
|
||||||
final TextHighlighter.Result result = textHighlighter.process(text);
|
} catch (CalculatorParseException e) {
|
||||||
selectionStart += result.getOffset();
|
// set raw text
|
||||||
selectionEnd += result.getOffset();
|
result = text;
|
||||||
text = result.toString();
|
|
||||||
} catch (CalculatorParseException e) {
|
|
||||||
Log.e(this.getClass().getName(), e.getMessage(), e);
|
|
||||||
}
|
|
||||||
|
|
||||||
Log.d(this.getClass().getName(), text);
|
Log.e(this.getClass().getName(), e.getMessage(), e);
|
||||||
super.setText(Html.fromHtml(text), BufferType.EDITABLE);
|
}
|
||||||
} else {
|
} else {
|
||||||
super.setText(text, BufferType.EDITABLE);
|
result = text;
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.d(this.getClass().getName(), getText().toString());
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
int length = getText().length();
|
public boolean isHighlightText() {
|
||||||
setSelection(Math.max(Math.min(length, selectionStart), 0), Math.max(Math.min(length, selectionEnd), 0));
|
return highlightText;
|
||||||
}*/
|
}
|
||||||
|
|
||||||
public boolean isHighlightText() {
|
public void setHighlightText(boolean highlightText) {
|
||||||
return highlightText;
|
this.highlightText = highlightText;
|
||||||
}
|
CalculatorLocatorImpl.getInstance().getEditor().updateViewState();
|
||||||
|
}
|
||||||
|
|
||||||
public void setHighlightText(boolean highlightText) {
|
@Override
|
||||||
this.highlightText = highlightText;
|
public void onSharedPreferenceChanged(SharedPreferences preferences, String key) {
|
||||||
//redraw();
|
if (CALC_COLOR_DISPLAY_KEY.equals(key)) {
|
||||||
}
|
this.setHighlightText(preferences.getBoolean(CALC_COLOR_DISPLAY_KEY, CALC_COLOR_DISPLAY_DEFAULT));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
public void init(@NotNull SharedPreferences preferences) {
|
||||||
public void onSharedPreferenceChanged(SharedPreferences preferences, String key) {
|
onSharedPreferenceChanged(preferences, CALC_COLOR_DISPLAY_KEY);
|
||||||
if (CALC_COLOR_DISPLAY_KEY.equals(key)) {
|
}
|
||||||
this.setHighlightText(preferences.getBoolean(CALC_COLOR_DISPLAY_KEY, CALC_COLOR_DISPLAY_DEFAULT));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void init(@NotNull SharedPreferences preferences) {
|
|
||||||
onSharedPreferenceChanged(preferences, CALC_COLOR_DISPLAY_KEY);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setState(@NotNull final CalculatorEditorViewState viewState) {
|
public void setState(@NotNull final CalculatorEditorViewState viewState) {
|
||||||
handler.postDelayed(new Runnable() {
|
|
||||||
|
final CharSequence text = prepareText(viewState.getText(), highlightText);
|
||||||
|
|
||||||
|
handler.post(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
final AndroidCalculatorEditorView editorView = AndroidCalculatorEditorView.this;
|
final AndroidCalculatorEditorView editorView = AndroidCalculatorEditorView.this;
|
||||||
synchronized (editorView) {
|
synchronized (lock) {
|
||||||
try {
|
try {
|
||||||
editorView.viewStateChange = true;
|
editorView.viewStateChange = true;
|
||||||
editorView.viewState = viewState;
|
editorView.viewState = viewState;
|
||||||
editorView.setText(viewState.getText());
|
editorView.setText(text, BufferType.EDITABLE);
|
||||||
editorView.setSelection(viewState.getSelection());
|
editorView.setSelection(viewState.getSelection());
|
||||||
//redraw();
|
|
||||||
} finally {
|
} finally {
|
||||||
editorView.viewStateChange = false;
|
editorView.viewStateChange = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, 1);
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onSelectionChanged(int selStart, int selEnd) {
|
protected void onSelectionChanged(int selStart, int selEnd) {
|
||||||
synchronized (this) {
|
synchronized (lock) {
|
||||||
if (!viewStateChange) {
|
if (!viewStateChange) {
|
||||||
|
// external text change => need to notify editor
|
||||||
super.onSelectionChanged(selStart, selEnd);
|
super.onSelectionChanged(selStart, selEnd);
|
||||||
CalculatorLocatorImpl.getInstance().getEditor().setSelection(selStart);
|
CalculatorLocatorImpl.getInstance().getEditor().setSelection(selStart);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void handleTextChange(Editable s) {
|
||||||
|
synchronized (lock) {
|
||||||
|
if (!viewStateChange) {
|
||||||
|
// external text change => need to notify editor
|
||||||
|
CalculatorLocatorImpl.getInstance().getEditor().setText(String.valueOf(s));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final class TextWatcherImpl implements TextWatcher {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterTextChanged(Editable s) {
|
||||||
|
handleTextChange(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user