Constant save refactored

This commit is contained in:
Sergey Solovyev 2012-10-02 01:07:19 +04:00
parent fb42a3ebe9
commit 9b6e3337c5
30 changed files with 1762 additions and 1581 deletions

View File

@ -1,68 +1,71 @@
package org.solovyev.android.calculator; package org.solovyev.android.calculator;
import jscl.NumeralBase; import jscl.NumeralBase;
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.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.common.history.HistoryControl; import org.solovyev.common.history.HistoryControl;
/** /**
* User: Solovyev_S * User: Solovyev_S
* Date: 20.09.12 * Date: 20.09.12
* Time: 16:38 * Time: 16:38
*/ */
public interface Calculator extends CalculatorEventContainer, HistoryControl<CalculatorHistoryState> { public interface Calculator extends CalculatorEventContainer, HistoryControl<CalculatorHistoryState> {
void init(); void init();
/* /*
********************************************************************** **********************************************************************
* *
* CALCULATIONS * CALCULATIONS
* *
********************************************************************** **********************************************************************
*/ */
void evaluate(); void evaluate();
void evaluate(@NotNull Long sequenceId); void evaluate(@NotNull Long sequenceId);
void simplify(); void simplify();
@NotNull @NotNull
CalculatorEventData evaluate(@NotNull JsclOperation operation, CalculatorEventData evaluate(@NotNull JsclOperation operation,
@NotNull String expression); @NotNull String expression);
@NotNull @NotNull
CalculatorEventData evaluate(@NotNull JsclOperation operation, CalculatorEventData evaluate(@NotNull JsclOperation operation,
@NotNull String expression, @NotNull String expression,
@NotNull Long sequenceId); @NotNull Long sequenceId);
/* /*
********************************************************************** **********************************************************************
* *
* CONVERSION * CONVERSION
* *
********************************************************************** **********************************************************************
*/ */
boolean isConversionPossible(@NotNull Generic generic, @NotNull NumeralBase from, @NotNull NumeralBase to); boolean isConversionPossible(@NotNull Generic generic, @NotNull NumeralBase from, @NotNull NumeralBase to);
@NotNull @NotNull
CalculatorEventData convert(@NotNull Generic generic, @NotNull NumeralBase to); CalculatorEventData convert(@NotNull Generic generic, @NotNull NumeralBase to);
/* /*
********************************************************************** **********************************************************************
* *
* EVENTS * EVENTS
* *
********************************************************************** **********************************************************************
*/ */
@NotNull @NotNull
CalculatorEventData fireCalculatorEvent(@NotNull CalculatorEventType calculatorEventType, @Nullable Object data); CalculatorEventData fireCalculatorEvent(@NotNull CalculatorEventType calculatorEventType, @Nullable Object data);
@NotNull @NotNull
CalculatorEventData fireCalculatorEvent(@NotNull CalculatorEventType calculatorEventType, @Nullable Object data, @NotNull Long sequenceId); CalculatorEventData fireCalculatorEvent(@NotNull CalculatorEventType calculatorEventType, @Nullable Object data, @NotNull Object source);
}
@NotNull
CalculatorEventData fireCalculatorEvent(@NotNull CalculatorEventType calculatorEventType, @Nullable Object data, @NotNull Long sequenceId);
}

View File

@ -1,98 +1,103 @@
package org.solovyev.android.calculator; package org.solovyev.android.calculator;
import jscl.NumeralBase; import jscl.NumeralBase;
import jscl.math.Generic; import jscl.math.Generic;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
/** /**
* User: Solovyev_S * User: Solovyev_S
* Date: 24.09.12 * Date: 24.09.12
* Time: 16:48 * Time: 16:48
*/ */
public class CalculatorConversionEventDataImpl implements CalculatorConversionEventData { public class CalculatorConversionEventDataImpl implements CalculatorConversionEventData {
@NotNull @NotNull
private CalculatorEventData calculatorEventData; private CalculatorEventData calculatorEventData;
@NotNull @NotNull
private NumeralBase fromNumeralBase; private NumeralBase fromNumeralBase;
@NotNull @NotNull
private NumeralBase toNumeralBase; private NumeralBase toNumeralBase;
@NotNull @NotNull
private Generic value; private Generic value;
@NotNull @NotNull
private CalculatorDisplayViewState displayState; private CalculatorDisplayViewState displayState;
private CalculatorConversionEventDataImpl() { private CalculatorConversionEventDataImpl() {
} }
@NotNull @NotNull
public static CalculatorConversionEventData newInstance(@NotNull CalculatorEventData calculatorEventData, public static CalculatorConversionEventData newInstance(@NotNull CalculatorEventData calculatorEventData,
@NotNull Generic value, @NotNull Generic value,
@NotNull NumeralBase from, @NotNull NumeralBase from,
@NotNull NumeralBase to, @NotNull NumeralBase to,
@NotNull CalculatorDisplayViewState displayViewState) { @NotNull CalculatorDisplayViewState displayViewState) {
final CalculatorConversionEventDataImpl result = new CalculatorConversionEventDataImpl(); final CalculatorConversionEventDataImpl result = new CalculatorConversionEventDataImpl();
result.calculatorEventData = calculatorEventData; result.calculatorEventData = calculatorEventData;
result.value = value; result.value = value;
result.displayState = displayViewState; result.displayState = displayViewState;
result.fromNumeralBase = from; result.fromNumeralBase = from;
result.toNumeralBase = to; result.toNumeralBase = to;
return result; return result;
} }
@Override @Override
public long getEventId() { public long getEventId() {
return calculatorEventData.getEventId(); return calculatorEventData.getEventId();
} }
@Override @Override
@NotNull @NotNull
public Long getSequenceId() { public Long getSequenceId() {
return calculatorEventData.getSequenceId(); return calculatorEventData.getSequenceId();
} }
@Override @Override
public boolean isAfter(@NotNull CalculatorEventData that) { public Object getSource() {
return calculatorEventData.isAfter(that); return calculatorEventData.getSource();
} }
@Override @Override
public boolean isSameSequence(@NotNull CalculatorEventData that) { public boolean isAfter(@NotNull CalculatorEventData that) {
return calculatorEventData.isSameSequence(that); return calculatorEventData.isAfter(that);
} }
@Override @Override
public boolean isAfterSequence(@NotNull CalculatorEventData that) { public boolean isSameSequence(@NotNull CalculatorEventData that) {
return calculatorEventData.isAfterSequence(that); return calculatorEventData.isSameSequence(that);
} }
@NotNull @Override
@Override public boolean isAfterSequence(@NotNull CalculatorEventData that) {
public CalculatorDisplayViewState getDisplayState() { return calculatorEventData.isAfterSequence(that);
return this.displayState; }
}
@NotNull
@Override @Override
@NotNull public CalculatorDisplayViewState getDisplayState() {
public NumeralBase getFromNumeralBase() { return this.displayState;
return fromNumeralBase; }
}
@Override
@Override @NotNull
@NotNull public NumeralBase getFromNumeralBase() {
public NumeralBase getToNumeralBase() { return fromNumeralBase;
return toNumeralBase; }
}
@Override
@Override @NotNull
@NotNull public NumeralBase getToNumeralBase() {
public Generic getValue() { return toNumeralBase;
return value; }
}
} @Override
@NotNull
public Generic getValue() {
return value;
}
}

View File

@ -1,17 +1,9 @@
package org.solovyev.android.calculator; package org.solovyev.android.calculator;
import org.jetbrains.annotations.NotNull;
/** /**
* User: serso * User: serso
* Date: 9/21/12 * Date: 9/21/12
* Time: 9:49 PM * Time: 9:49 PM
*/ */
public interface CalculatorDisplayChangeEventData { public interface CalculatorDisplayChangeEventData extends Change<CalculatorDisplayViewState> {
@NotNull
CalculatorDisplayViewState getOldState();
@NotNull
CalculatorDisplayViewState getNewState();
} }

View File

@ -22,13 +22,13 @@ public class CalculatorDisplayChangeEventDataImpl implements CalculatorDisplayCh
@NotNull @NotNull
@Override @Override
public CalculatorDisplayViewState getOldState() { public CalculatorDisplayViewState getOldValue() {
return this.oldState; return this.oldState;
} }
@NotNull @NotNull
@Override @Override
public CalculatorDisplayViewState getNewState() { public CalculatorDisplayViewState getNewValue() {
return this.newState; return this.newState;
} }
} }

View File

@ -1,17 +1,9 @@
package org.solovyev.android.calculator; package org.solovyev.android.calculator;
import org.jetbrains.annotations.NotNull; /**
* User: Solovyev_S
/** * Date: 21.09.12
* User: Solovyev_S * Time: 13:46
* Date: 21.09.12 */
* Time: 13:46 public interface CalculatorEditorChangeEventData extends Change<CalculatorEditorViewState>{
*/ }
public interface CalculatorEditorChangeEventData {
@NotNull
CalculatorEditorViewState getOldState();
@NotNull
CalculatorEditorViewState getNewState();
}

View File

@ -23,13 +23,13 @@ public class CalculatorEditorChangeEventDataImpl implements CalculatorEditorChan
@NotNull @NotNull
@Override @Override
public CalculatorEditorViewState getOldState() { public CalculatorEditorViewState getOldValue() {
return this.oldState; return this.oldState;
} }
@NotNull @NotNull
@Override @Override
public CalculatorEditorViewState getNewState() { public CalculatorEditorViewState getNewValue() {
return this.newState; return this.newState;
} }
} }

View File

@ -1,67 +1,72 @@
package org.solovyev.android.calculator; package org.solovyev.android.calculator;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
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();
} }
@NotNull @NotNull
@Override @Override
public Long getSequenceId() { public Long getSequenceId() {
return calculatorEventData.getSequenceId(); return calculatorEventData.getSequenceId();
} }
@Override @Override
public boolean isAfter(@NotNull CalculatorEventData that) { public Object getSource() {
return calculatorEventData.isAfter(that); return calculatorEventData.getSource();
} }
@Override @Override
public boolean isSameSequence(@NotNull CalculatorEventData that) { public boolean isAfter(@NotNull CalculatorEventData that) {
return this.calculatorEventData.isSameSequence(that); return calculatorEventData.isAfter(that);
} }
@Override @Override
public boolean isAfterSequence(@NotNull CalculatorEventData that) { public boolean isSameSequence(@NotNull CalculatorEventData that) {
return this.calculatorEventData.isAfterSequence(that); return this.calculatorEventData.isSameSequence(that);
} }
}
@Override
public boolean isAfterSequence(@NotNull CalculatorEventData that) {
return this.calculatorEventData.isAfterSequence(that);
}
}

View File

@ -1,24 +1,28 @@
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;
/**
* User: Solovyev_S /**
* Date: 20.09.12 * User: Solovyev_S
* Time: 18:18 * Date: 20.09.12
*/ * Time: 18:18
public interface CalculatorEventData { */
public interface CalculatorEventData {
// the higher id => the later event
long getEventId(); // the higher id => the later event
long getEventId();
// the higher id => the later event
@NotNull // the higher id => the later event
Long getSequenceId(); @NotNull
Long getSequenceId();
boolean isAfter(@NotNull CalculatorEventData that);
@Nullable
boolean isSameSequence(@NotNull CalculatorEventData that); Object getSource();
boolean isAfterSequence(@NotNull CalculatorEventData that); boolean isAfter(@NotNull CalculatorEventData that);
}
boolean isSameSequence(@NotNull CalculatorEventData that);
boolean isAfterSequence(@NotNull CalculatorEventData that);
}

View File

@ -1,75 +1,89 @@
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;
/**
* User: Solovyev_S /**
* Date: 20.09.12 * User: Solovyev_S
* Time: 18:18 * Date: 20.09.12
*/ * Time: 18:18
class CalculatorEventDataImpl implements CalculatorEventData { */
class CalculatorEventDataImpl implements CalculatorEventData {
private static final long NO_SEQUENCE = -1L;
private static final long NO_SEQUENCE = -1L;
private final long eventId;
private final long eventId;
@NotNull
private Long sequenceId = NO_SEQUENCE; @NotNull
private Long sequenceId = NO_SEQUENCE;
private CalculatorEventDataImpl(long id, @NotNull Long sequenceId) {
this.eventId = id; private final Object source;
this.sequenceId = sequenceId;
} private CalculatorEventDataImpl(long id, @NotNull Long sequenceId, @Nullable Object source) {
this.eventId = id;
@NotNull this.sequenceId = sequenceId;
static CalculatorEventData newInstance(long id, @NotNull Long sequenceId) { this.source = source;
return new CalculatorEventDataImpl(id, sequenceId); }
}
@NotNull
@Override static CalculatorEventData newInstance(long id, @NotNull Long sequenceId) {
public long getEventId() { return new CalculatorEventDataImpl(id, sequenceId, null);
return this.eventId; }
}
@NotNull
@NotNull static CalculatorEventData newInstance(long id, @NotNull Long sequenceId, @NotNull Object source) {
@Override return new CalculatorEventDataImpl(id, sequenceId, source);
public Long getSequenceId() { }
return this.sequenceId;
} @Override
public long getEventId() {
@Override return this.eventId;
public boolean isAfter(@NotNull CalculatorEventData that) { }
return this.eventId > that.getEventId();
} @NotNull
@Override
@Override public Long getSequenceId() {
public boolean isSameSequence(@NotNull CalculatorEventData that) { return this.sequenceId;
return !this.sequenceId.equals(NO_SEQUENCE) && this.sequenceId.equals(that.getSequenceId()); }
}
@Override
@Override public Object getSource() {
public boolean isAfterSequence(@NotNull CalculatorEventData that) { return this.source;
return !this.sequenceId.equals(NO_SEQUENCE) && this.sequenceId > that.getSequenceId(); }
}
@Override
@Override public boolean isAfter(@NotNull CalculatorEventData that) {
public boolean equals(Object o) { return this.eventId > that.getEventId();
if (this == o) return true; }
if (!(o instanceof CalculatorEventDataImpl)) return false;
@Override
CalculatorEventDataImpl that = (CalculatorEventDataImpl) o; public boolean isSameSequence(@NotNull CalculatorEventData that) {
return !this.sequenceId.equals(NO_SEQUENCE) && this.sequenceId.equals(that.getSequenceId());
if (eventId != that.eventId) return false; }
if (!sequenceId.equals(that.sequenceId))
return false; @Override
public boolean isAfterSequence(@NotNull CalculatorEventData that) {
return true; return !this.sequenceId.equals(NO_SEQUENCE) && this.sequenceId > that.getSequenceId();
} }
@Override @Override
public int hashCode() { public boolean equals(Object o) {
int result = (int) (eventId ^ (eventId >>> 32)); if (this == o) return true;
result = 31 * result + (sequenceId.hashCode()); if (!(o instanceof CalculatorEventDataImpl)) return false;
return result;
} CalculatorEventDataImpl that = (CalculatorEventDataImpl) o;
}
if (eventId != that.eventId) return false;
if (!sequenceId.equals(that.sequenceId))
return false;
return true;
}
@Override
public int hashCode() {
int result = (int) (eventId ^ (eventId >>> 32));
result = 31 * result + (sequenceId.hashCode());
return result;
}
}

View File

@ -106,7 +106,16 @@ public enum CalculatorEventType {
use_function, use_function,
// @NotNull Operator // @NotNull Operator
use_operator; use_operator,
// @NotNull IConstant
constant_added,
// @NotNull Change<IConstant>
constant_changed,
// @NotNull IConstant
constant_removed;
public boolean isOfType(@NotNull CalculatorEventType... types) { public boolean isOfType(@NotNull CalculatorEventType... types) {
for (CalculatorEventType type : types) { for (CalculatorEventType type : types) {

View File

@ -60,6 +60,12 @@ public class CalculatorImpl implements Calculator, CalculatorEventListener {
return CalculatorEventDataImpl.newInstance(eventId, eventId); return CalculatorEventDataImpl.newInstance(eventId, eventId);
} }
@NotNull
private CalculatorEventData nextEventData(@NotNull Object source) {
long eventId = counter.incrementAndGet();
return CalculatorEventDataImpl.newInstance(eventId, eventId, source);
}
@NotNull @NotNull
private CalculatorEventData nextEventData(@NotNull Long sequenceId) { private CalculatorEventData nextEventData(@NotNull Long sequenceId) {
long eventId = counter.incrementAndGet(); long eventId = counter.incrementAndGet();
@ -353,6 +359,16 @@ public class CalculatorImpl implements Calculator, CalculatorEventListener {
return eventData; return eventData;
} }
@NotNull
@Override
public CalculatorEventData fireCalculatorEvent(@NotNull final CalculatorEventType calculatorEventType, @Nullable final Object data, @NotNull Object source) {
final CalculatorEventData eventData = nextEventData(source);
fireCalculatorEvent(eventData, calculatorEventType, data);
return eventData;
}
@NotNull @NotNull
@Override @Override
public CalculatorEventData fireCalculatorEvent(@NotNull final CalculatorEventType calculatorEventType, @Nullable final Object data, @NotNull Long sequenceId) { public CalculatorEventData fireCalculatorEvent(@NotNull final CalculatorEventType calculatorEventType, @Nullable final Object data, @NotNull Long sequenceId) {
@ -378,11 +394,11 @@ public class CalculatorImpl implements Calculator, CalculatorEventListener {
case editor_state_changed: case editor_state_changed:
final CalculatorEditorChangeEventData changeEventData = (CalculatorEditorChangeEventData) data; final CalculatorEditorChangeEventData changeEventData = (CalculatorEditorChangeEventData) data;
final String newText = changeEventData.getNewState().getText(); final String newText = changeEventData.getNewValue().getText();
final String oldText = changeEventData.getOldState().getText(); final String oldText = changeEventData.getOldValue().getText();
if (!newText.equals(oldText)) { if (!newText.equals(oldText)) {
evaluate(JsclOperation.numeric, changeEventData.getNewState().getText(), calculatorEventData.getSequenceId()); evaluate(JsclOperation.numeric, changeEventData.getNewValue().getText(), calculatorEventData.getSequenceId());
} }
break; break;

View File

@ -1,7 +1,11 @@
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.solovyev.common.msg.Message; import org.solovyev.common.msg.Message;
import org.solovyev.common.msg.MessageType;
import java.util.List;
/** /**
* User: serso * User: serso
@ -11,4 +15,8 @@ import org.solovyev.common.msg.Message;
public interface CalculatorNotifier { public interface CalculatorNotifier {
void showMessage(@NotNull Message message); void showMessage(@NotNull Message message);
void showMessage(@NotNull Integer messageCode, @NotNull MessageType messageType, @NotNull List<Object> parameters);
void showMessage(@NotNull Integer messageCode, @NotNull MessageType messageType, @Nullable Object... parameters);
} }

View File

@ -0,0 +1,18 @@
package org.solovyev.android.calculator;
import org.jetbrains.annotations.NotNull;
/**
* User: serso
* Date: 10/1/12
* Time: 11:16 PM
*/
public interface Change<T> {
@NotNull
T getOldValue();
@NotNull
T getNewValue();
}

View File

@ -0,0 +1,42 @@
package org.solovyev.android.calculator;
import org.jetbrains.annotations.NotNull;
/**
* User: serso
* Date: 10/1/12
* Time: 11:18 PM
*/
public class ChangeImpl<T> implements Change<T> {
@NotNull
private T oldValue;
@NotNull
private T newValue;
private ChangeImpl() {
}
@NotNull
public static <T> Change<T> newInstance(@NotNull T oldValue, @NotNull T newValue) {
final ChangeImpl<T> result = new ChangeImpl<T>();
result.oldValue = oldValue;
result.newValue = newValue;
return result;
}
@NotNull
@Override
public T getOldValue() {
return this.oldValue;
}
@NotNull
@Override
public T getNewValue() {
return this.newValue;
}
}

View File

@ -1,7 +1,11 @@
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.solovyev.common.msg.Message; import org.solovyev.common.msg.Message;
import org.solovyev.common.msg.MessageType;
import java.util.List;
/** /**
* User: serso * User: serso
@ -13,4 +17,12 @@ public class DummyCalculatorNotifier implements CalculatorNotifier {
@Override @Override
public void showMessage(@NotNull Message message) { public void showMessage(@NotNull Message message) {
} }
@Override
public void showMessage(@NotNull Integer messageCode, @NotNull MessageType messageType, @NotNull List<Object> parameters) {
}
@Override
public void showMessage(@NotNull Integer messageCode, @NotNull MessageType messageType, @Nullable Object... parameters) {
}
} }

View File

@ -1,234 +1,234 @@
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.solovyev.android.calculator.*; 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;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import static org.solovyev.android.calculator.CalculatorEventType.display_state_changed; import static org.solovyev.android.calculator.CalculatorEventType.display_state_changed;
import static org.solovyev.android.calculator.CalculatorEventType.editor_state_changed; import static org.solovyev.android.calculator.CalculatorEventType.editor_state_changed;
import static org.solovyev.android.calculator.CalculatorEventType.manual_calculation_requested; import static org.solovyev.android.calculator.CalculatorEventType.manual_calculation_requested;
/** /**
* User: Solovyev_S * User: Solovyev_S
* Date: 20.09.12 * Date: 20.09.12
* Time: 16:12 * Time: 16:12
*/ */
public class CalculatorHistoryImpl implements CalculatorHistory { public class CalculatorHistoryImpl implements CalculatorHistory {
private final AtomicInteger counter = new AtomicInteger(0); private final AtomicInteger counter = new AtomicInteger(0);
@NotNull @NotNull
private final HistoryHelper<CalculatorHistoryState> history = new SimpleHistoryHelper<CalculatorHistoryState>(); private final HistoryHelper<CalculatorHistoryState> history = new SimpleHistoryHelper<CalculatorHistoryState>();
@NotNull @NotNull
private final List<CalculatorHistoryState> savedHistory = new ArrayList<CalculatorHistoryState>(); private final List<CalculatorHistoryState> savedHistory = new ArrayList<CalculatorHistoryState>();
@NotNull @NotNull
private volatile CalculatorEventData lastEventData = CalculatorUtils.createFirstEventDataId(); private volatile CalculatorEventData lastEventData = CalculatorUtils.createFirstEventDataId();
@NotNull @NotNull
private final Object lastEventDataLock = new Object(); private final Object lastEventDataLock = new Object();
@Nullable @Nullable
private volatile CalculatorEditorViewState lastEditorViewState; private volatile CalculatorEditorViewState lastEditorViewState;
public CalculatorHistoryImpl(@NotNull Calculator calculator) { public CalculatorHistoryImpl(@NotNull Calculator calculator) {
calculator.addCalculatorEventListener(this); calculator.addCalculatorEventListener(this);
} }
@Override @Override
public boolean isEmpty() { public boolean isEmpty() {
synchronized (history) { synchronized (history) {
return this.history.isEmpty(); return this.history.isEmpty();
} }
} }
@Override @Override
public CalculatorHistoryState getLastHistoryState() { public CalculatorHistoryState getLastHistoryState() {
synchronized (history) { synchronized (history) {
return this.history.getLastHistoryState(); return this.history.getLastHistoryState();
} }
} }
@Override @Override
public boolean isUndoAvailable() { public boolean isUndoAvailable() {
synchronized (history) { synchronized (history) {
return history.isUndoAvailable(); return history.isUndoAvailable();
} }
} }
@Override @Override
public CalculatorHistoryState undo(@Nullable CalculatorHistoryState currentState) { public CalculatorHistoryState undo(@Nullable CalculatorHistoryState currentState) {
synchronized (history) { synchronized (history) {
return history.undo(currentState); return history.undo(currentState);
} }
} }
@Override @Override
public boolean isRedoAvailable() { public boolean isRedoAvailable() {
return history.isRedoAvailable(); return history.isRedoAvailable();
} }
@Override @Override
public CalculatorHistoryState redo(@Nullable CalculatorHistoryState currentState) { public CalculatorHistoryState redo(@Nullable CalculatorHistoryState currentState) {
synchronized (history) { synchronized (history) {
return history.redo(currentState); return history.redo(currentState);
} }
} }
@Override @Override
public boolean isActionAvailable(@NotNull HistoryAction historyAction) { public boolean isActionAvailable(@NotNull HistoryAction historyAction) {
synchronized (history) { synchronized (history) {
return history.isActionAvailable(historyAction); return history.isActionAvailable(historyAction);
} }
} }
@Override @Override
public CalculatorHistoryState doAction(@NotNull HistoryAction historyAction, @Nullable CalculatorHistoryState currentState) { public CalculatorHistoryState doAction(@NotNull HistoryAction historyAction, @Nullable CalculatorHistoryState currentState) {
synchronized (history) { synchronized (history) {
return history.doAction(historyAction, currentState); return history.doAction(historyAction, currentState);
} }
} }
@Override @Override
public void addState(@Nullable CalculatorHistoryState currentState) { public void addState(@Nullable CalculatorHistoryState currentState) {
synchronized (history) { synchronized (history) {
history.addState(currentState); history.addState(currentState);
CalculatorLocatorImpl.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.history_state_added, currentState); CalculatorLocatorImpl.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.history_state_added, currentState);
} }
} }
@NotNull @NotNull
@Override @Override
public List<CalculatorHistoryState> getStates() { public List<CalculatorHistoryState> getStates() {
synchronized (history) { synchronized (history) {
return history.getStates(); return history.getStates();
} }
} }
@Override @Override
public void clear() { public void clear() {
synchronized (history) { synchronized (history) {
this.history.clear(); this.history.clear();
} }
} }
@Override @Override
@NotNull @NotNull
public List<CalculatorHistoryState> getSavedHistory() { public List<CalculatorHistoryState> getSavedHistory() {
return Collections.unmodifiableList(savedHistory); return Collections.unmodifiableList(savedHistory);
} }
@Override @Override
@NotNull @NotNull
public CalculatorHistoryState addSavedState(@NotNull CalculatorHistoryState historyState) { public CalculatorHistoryState addSavedState(@NotNull CalculatorHistoryState historyState) {
if (historyState.isSaved()) { if (historyState.isSaved()) {
return historyState; return historyState;
} else { } else {
final CalculatorHistoryState savedState = historyState.clone(); final CalculatorHistoryState savedState = historyState.clone();
savedState.setId(counter.incrementAndGet()); savedState.setId(counter.incrementAndGet());
savedState.setSaved(true); savedState.setSaved(true);
savedHistory.add(savedState); savedHistory.add(savedState);
return savedState; return savedState;
} }
} }
@Override @Override
public void load() { public void load() {
// todo serso: create saved/loader class // todo serso: create saved/loader class
} }
@Override @Override
public void save() { public void save() {
// todo serso: create saved/loader class // todo serso: create saved/loader class
} }
@Override @Override
public void fromXml(@NotNull String xml) { public void fromXml(@NotNull String xml) {
clearSavedHistory(); clearSavedHistory();
HistoryUtils.fromXml(xml, this.savedHistory); HistoryUtils.fromXml(xml, this.savedHistory);
for (CalculatorHistoryState historyState : savedHistory) { for (CalculatorHistoryState historyState : savedHistory) {
historyState.setSaved(true); historyState.setSaved(true);
historyState.setId(counter.incrementAndGet()); historyState.setId(counter.incrementAndGet());
} }
} }
@Override @Override
public String toXml() { public String toXml() {
return HistoryUtils.toXml(this.savedHistory); return HistoryUtils.toXml(this.savedHistory);
} }
@Override @Override
public void clearSavedHistory() { public void clearSavedHistory() {
this.savedHistory.clear(); this.savedHistory.clear();
} }
@Override @Override
public void removeSavedHistory(@NotNull CalculatorHistoryState historyState) { public void removeSavedHistory(@NotNull CalculatorHistoryState historyState) {
this.savedHistory.remove(historyState); this.savedHistory.remove(historyState);
} }
@Override @Override
public void onCalculatorEvent(@NotNull CalculatorEventData calculatorEventData, public void onCalculatorEvent(@NotNull CalculatorEventData calculatorEventData,
@NotNull CalculatorEventType calculatorEventType, @NotNull CalculatorEventType calculatorEventType,
@Nullable Object data) { @Nullable Object data) {
if (calculatorEventType.isOfType(editor_state_changed, display_state_changed, manual_calculation_requested)) { if (calculatorEventType.isOfType(editor_state_changed, display_state_changed, manual_calculation_requested)) {
boolean sameSequence = false; boolean sameSequence = false;
boolean afterSequence = false; boolean afterSequence = false;
boolean processEvent = false; boolean processEvent = false;
synchronized (this.lastEventDataLock) { synchronized (this.lastEventDataLock) {
if (calculatorEventData.isAfter(this.lastEventData)) { if (calculatorEventData.isAfter(this.lastEventData)) {
sameSequence = calculatorEventData.isSameSequence(this.lastEventData); sameSequence = calculatorEventData.isSameSequence(this.lastEventData);
if (!sameSequence) { if (!sameSequence) {
afterSequence = calculatorEventData.isAfterSequence(this.lastEventData); afterSequence = calculatorEventData.isAfterSequence(this.lastEventData);
processEvent = afterSequence; processEvent = afterSequence;
} else { } else {
processEvent = true; processEvent = true;
} }
} }
} }
if (processEvent) { if (processEvent) {
this.lastEventData = calculatorEventData; this.lastEventData = calculatorEventData;
switch (calculatorEventType) { switch (calculatorEventType) {
case manual_calculation_requested: case manual_calculation_requested:
lastEditorViewState = (CalculatorEditorViewState) data; lastEditorViewState = (CalculatorEditorViewState) data;
break; break;
case editor_state_changed: case editor_state_changed:
final CalculatorEditorChangeEventData editorChangeData = (CalculatorEditorChangeEventData) data; final CalculatorEditorChangeEventData editorChangeData = (CalculatorEditorChangeEventData) data;
lastEditorViewState = editorChangeData.getNewState(); lastEditorViewState = editorChangeData.getNewValue();
break; break;
case display_state_changed: case display_state_changed:
if (sameSequence) { if (sameSequence) {
if (lastEditorViewState != null) { if (lastEditorViewState != null) {
final CalculatorEditorViewState editorViewState = lastEditorViewState; final CalculatorEditorViewState editorViewState = lastEditorViewState;
final CalculatorDisplayChangeEventData displayChangeData = (CalculatorDisplayChangeEventData) data; final CalculatorDisplayChangeEventData displayChangeData = (CalculatorDisplayChangeEventData) data;
final CalculatorDisplayViewState displayViewState = displayChangeData.getNewState(); final CalculatorDisplayViewState displayViewState = displayChangeData.getNewValue();
addState(CalculatorHistoryState.newInstance(editorViewState, displayViewState)); addState(CalculatorHistoryState.newInstance(editorViewState, displayViewState));
} }
} else { } else {
lastEditorViewState = null; lastEditorViewState = null;
} }
break; break;
} }
} }
} }
} }
} }

View File

@ -5,7 +5,7 @@
xmlns:c="http://schemas.android.com/apk/res/org.solovyev.android.calculator" xmlns:c="http://schemas.android.com/apk/res/org.solovyev.android.calculator"
a:layout_width="fill_parent" a:layout_width="fill_parent"
a:layout_height="fill_parent" a:layout_height="fill_parent"
a:id="@+id/ad_parent_view" a:id="@+id/main_layout"
a:orientation="vertical" a:orientation="vertical"
a:layout_gravity="center" a:layout_gravity="center"
a:background="#ff000000"> a:background="#ff000000">

View File

@ -1,77 +1,77 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout <LinearLayout
xmlns:a="http://schemas.android.com/apk/res/android" xmlns:a="http://schemas.android.com/apk/res/android"
a:layout_width="fill_parent" a:layout_width="fill_parent"
a:layout_height="fill_parent" a:layout_height="fill_parent"
a:id="@+id/ad_parent_view" a:id="@+id/main_layout"
a:orientation="vertical" a:orientation="vertical"
a:layout_gravity="center" a:layout_gravity="center"
a:background="#ff000000"> a:background="#ff000000">
<include layout="@layout/calc_editor"/> <include layout="@layout/calc_editor"/>
<LinearLayout a:layout_weight="1" a:layout_width="fill_parent" a:layout_height="0dp"> <LinearLayout a:layout_weight="1" a:layout_width="fill_parent" a:layout_height="0dp">
<include layout="@layout/calc_equals_button" <include layout="@layout/calc_equals_button"
a:layout_weight="1" a:layout_weight="1"
a:layout_width="0dp" a:layout_width="0dp"
a:layout_height="fill_parent"/> a:layout_height="fill_parent"/>
<include layout="@layout/calc_display" <include layout="@layout/calc_display"
a:layout_weight="4" a:layout_weight="4"
a:layout_width="0dp" a:layout_width="0dp"
a:layout_height="fill_parent"/> a:layout_height="fill_parent"/>
</LinearLayout> </LinearLayout>
<LinearLayout a:layout_weight="1" a:layout_width="fill_parent" a:layout_height="0dp"> <LinearLayout a:layout_weight="1" a:layout_width="fill_parent" a:layout_height="0dp">
<include layout="@layout/calc_one_digit_button"/> <include layout="@layout/calc_one_digit_button"/>
<include layout="@layout/calc_two_digit_button"/> <include layout="@layout/calc_two_digit_button"/>
<include layout="@layout/calc_three_digit_button"/> <include layout="@layout/calc_three_digit_button"/>
<include layout="@layout/calc_multiplication_button"/> <include layout="@layout/calc_multiplication_button"/>
<include layout="@layout/calc_clear_button"/> <include layout="@layout/calc_clear_button"/>
</LinearLayout> </LinearLayout>
<LinearLayout a:layout_weight="1" a:layout_width="fill_parent" a:layout_height="0dp"> <LinearLayout a:layout_weight="1" a:layout_width="fill_parent" a:layout_height="0dp">
<include layout="@layout/calc_four_digit_button"/> <include layout="@layout/calc_four_digit_button"/>
<include layout="@layout/calc_five_digit_button"/> <include layout="@layout/calc_five_digit_button"/>
<include layout="@layout/calc_six_digit_button"/> <include layout="@layout/calc_six_digit_button"/>
<include layout="@layout/calc_division_button"/> <include layout="@layout/calc_division_button"/>
<include layout="@layout/calc_erase_button"/> <include layout="@layout/calc_erase_button"/>
</LinearLayout> </LinearLayout>
<LinearLayout a:layout_weight="1" a:layout_width="fill_parent" a:layout_height="0dp"> <LinearLayout a:layout_weight="1" a:layout_width="fill_parent" a:layout_height="0dp">
<include layout="@layout/calc_seven_digit_button"/> <include layout="@layout/calc_seven_digit_button"/>
<include layout="@layout/calc_eight_digit_button"/> <include layout="@layout/calc_eight_digit_button"/>
<include layout="@layout/calc_nine_digit_button"/> <include layout="@layout/calc_nine_digit_button"/>
<include layout="@layout/calc_plus_button"/> <include layout="@layout/calc_plus_button"/>
<include layout="@layout/calc_copy_button"/> <include layout="@layout/calc_copy_button"/>
</LinearLayout> </LinearLayout>
<LinearLayout a:layout_weight="1" a:layout_width="fill_parent" a:layout_height="0dp"> <LinearLayout a:layout_weight="1" a:layout_width="fill_parent" a:layout_height="0dp">
<include layout="@layout/calc_round_brackets_button"/> <include layout="@layout/calc_round_brackets_button"/>
<include layout="@layout/calc_zero_digit_button"/> <include layout="@layout/calc_zero_digit_button"/>
<include layout="@layout/calc_dot_button"/> <include layout="@layout/calc_dot_button"/>
<include layout="@layout/calc_subtraction_button"/> <include layout="@layout/calc_subtraction_button"/>
<include layout="@layout/calc_paste_button"/> <include layout="@layout/calc_paste_button"/>
</LinearLayout> </LinearLayout>
<LinearLayout a:layout_weight="1" a:layout_width="fill_parent" a:layout_height="0dp"> <LinearLayout a:layout_weight="1" a:layout_width="fill_parent" a:layout_height="0dp">
<include layout="@layout/calc_left_button"/> <include layout="@layout/calc_left_button"/>
<include layout="@layout/calc_right_button"/> <include layout="@layout/calc_right_button"/>
<include layout="@layout/calc_vars_button"/> <include layout="@layout/calc_vars_button"/>
<include layout="@layout/calc_functions_button"/> <include layout="@layout/calc_functions_button"/>
<include layout="@layout/calc_history_button"/> <include layout="@layout/calc_history_button"/>
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>

View File

@ -7,53 +7,75 @@
--> -->
<ScrollView xmlns:a="http://schemas.android.com/apk/res/android" <ScrollView xmlns:a="http://schemas.android.com/apk/res/android"
a:layout_width="fill_parent" a:layout_height="wrap_content"
a:layout_height="fill_parent"> a:layout_width="match_parent"
a:minWidth="200dp">
<LinearLayout xmlns:a="http://schemas.android.com/apk/res/android" <LinearLayout a:layout_height="wrap_content"
a:id="@+id/var_edit" a:layout_width="match_parent"
a:orientation="vertical" a:orientation="vertical">
a:layout_width="fill_parent"
a:layout_height="fill_parent"
a:scrollbars="vertical"
a:scrollbarAlwaysDrawVerticalTrack="true">
<TextView a:layout_height="fill_parent" <TextView a:layout_height="wrap_content"
a:layout_width="wrap_content" a:layout_width="match_parent"
a:padding="6dp" a:padding="6dp"
style="@style/default_text_size" style="@style/default_text_size"
a:text="@string/c_var_name"/> a:text="@string/c_var_name"/>
<EditText a:id="@+id/var_edit_name" <EditText a:id="@+id/var_edit_name"
a:layout_width="fill_parent" a:layout_height="wrap_content"
a:layout_height="wrap_content" a:layout_width="match_parent"
style="@style/default_text_size"> style="@style/default_text_size"
</EditText> a:inputType="text"/>
<TextView a:layout_height="fill_parent" <TextView a:layout_height="wrap_content"
a:layout_width="wrap_content" a:layout_width="match_parent"
style="@style/default_text_size" style="@style/default_text_size"
a:padding="6dp" a:padding="6dp"
a:text="@string/c_var_value"/> a:text="@string/c_var_value"/>
<EditText a:id="@+id/var_edit_value" <EditText a:id="@+id/var_edit_value"
a:layout_width="fill_parent" a:layout_height="wrap_content"
a:layout_height="wrap_content" a:layout_width="match_parent"
style="@style/default_text_size"> style="@style/default_text_size"
</EditText> a:inputType="text"/>
<TextView a:layout_height="fill_parent" <TextView a:layout_height="wrap_content"
a:layout_width="wrap_content" a:layout_width="match_parent"
a:padding="6dp" a:padding="6dp"
style="@style/default_text_size" style="@style/default_text_size"
a:text="@string/c_var_description"/> a:text="@string/c_var_description"/>
<EditText a:id="@+id/var_edit_description" <EditText a:id="@+id/var_edit_description"
a:layout_width="fill_parent" a:layout_height="wrap_content"
a:layout_height="wrap_content" a:layout_width="match_parent"
style="@style/default_text_size"> style="@style/default_text_size"
</EditText> a:inputType="text"/>
</LinearLayout> <LinearLayout
a:layout_height="wrap_content"
a:layout_width="match_parent">
<Button a:id="@+id/cancel_button"
a:layout_height="wrap_content"
a:layout_width="0dp"
a:layout_weight="1"
a:text="@string/c_cancel"/>
<Button a:id="@+id/remove_button"
a:layout_height="wrap_content"
a:layout_width="0dp"
a:layout_weight="1"
a:text="@string/c_remove"/>
<Button a:id="@+id/save_button"
a:layout_height="wrap_content"
a:layout_width="0dp"
a:layout_weight="1"
a:text="@string/c_save"/>
</LinearLayout>
</LinearLayout>
</ScrollView> </ScrollView>

View File

@ -1,167 +1,173 @@
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.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.widget.TextView; import android.widget.TextView;
import jscl.NumeralBase; import jscl.NumeralBase;
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.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.common.history.HistoryAction; import org.solovyev.common.history.HistoryAction;
import java.util.List; import java.util.List;
/** /**
* User: serso * User: serso
* Date: 9/22/12 * Date: 9/22/12
* Time: 5:42 PM * Time: 5:42 PM
*/ */
public class AndroidCalculator implements Calculator { public class AndroidCalculator implements Calculator {
@NotNull @NotNull
private final Calculator calculator = new CalculatorImpl(); private final Calculator calculator = new CalculatorImpl();
public static void showEvaluationError(@NotNull Context context, @NotNull final String errorMessage) { public static void showEvaluationError(@NotNull Context context, @NotNull final String errorMessage) {
final LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE); final LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
final View errorMessageView = layoutInflater.inflate(R.layout.display_error_message, null); final View errorMessageView = layoutInflater.inflate(R.layout.display_error_message, null);
((TextView) errorMessageView.findViewById(R.id.error_message_text_view)).setText(errorMessage); ((TextView) errorMessageView.findViewById(R.id.error_message_text_view)).setText(errorMessage);
final AlertDialog.Builder builder = new AlertDialog.Builder(context) final AlertDialog.Builder builder = new AlertDialog.Builder(context)
.setPositiveButton(R.string.c_cancel, null) .setPositiveButton(R.string.c_cancel, null)
.setView(errorMessageView); .setView(errorMessageView);
builder.create().show(); builder.create().show();
} }
public void init(@NotNull final Activity activity) { public void init(@NotNull final Activity activity) {
setEditor(activity); setEditor(activity);
setDisplay(activity); setDisplay(activity);
} }
public void setDisplay(@NotNull Activity activity) { public void setDisplay(@NotNull Activity activity) {
final AndroidCalculatorDisplayView displayView = (AndroidCalculatorDisplayView) activity.findViewById(R.id.calculatorDisplay); final AndroidCalculatorDisplayView displayView = (AndroidCalculatorDisplayView) activity.findViewById(R.id.calculatorDisplay);
setDisplay(activity, displayView); setDisplay(activity, displayView);
} }
public void setDisplay(@NotNull Context context, @NotNull AndroidCalculatorDisplayView displayView) { public void setDisplay(@NotNull Context context, @NotNull AndroidCalculatorDisplayView displayView) {
displayView.init(context); displayView.init(context);
CalculatorLocatorImpl.getInstance().getDisplay().setView(displayView); CalculatorLocatorImpl.getInstance().getDisplay().setView(displayView);
} }
public void setEditor(@NotNull Activity activity) { public void setEditor(@NotNull Activity activity) {
final AndroidCalculatorEditorView editorView = (AndroidCalculatorEditorView) activity.findViewById(R.id.calculatorEditor); final AndroidCalculatorEditorView editorView = (AndroidCalculatorEditorView) activity.findViewById(R.id.calculatorEditor);
setEditor(activity, editorView); setEditor(activity, editorView);
} }
public void setEditor(@NotNull Context context, @NotNull AndroidCalculatorEditorView editorView) { public void setEditor(@NotNull Context context, @NotNull AndroidCalculatorEditorView editorView) {
editorView.init(context); editorView.init(context);
CalculatorLocatorImpl.getInstance().getEditor().setView(editorView); CalculatorLocatorImpl.getInstance().getEditor().setView(editorView);
} }
/* /*
********************************************************************** **********************************************************************
* *
* DELEGATED TO CALCULATOR * DELEGATED TO CALCULATOR
* *
********************************************************************** **********************************************************************
*/ */
@Override @Override
@NotNull @NotNull
public CalculatorEventData evaluate(@NotNull JsclOperation operation, @NotNull String expression) { public CalculatorEventData evaluate(@NotNull JsclOperation operation, @NotNull String expression) {
return calculator.evaluate(operation, expression); return calculator.evaluate(operation, expression);
} }
@Override @Override
@NotNull @NotNull
public CalculatorEventData evaluate(@NotNull JsclOperation operation, @NotNull String expression, @NotNull Long sequenceId) { public CalculatorEventData evaluate(@NotNull JsclOperation operation, @NotNull String expression, @NotNull Long sequenceId) {
return calculator.evaluate(operation, expression, sequenceId); return calculator.evaluate(operation, expression, sequenceId);
} }
@Override @Override
public boolean isConversionPossible(@NotNull Generic generic, @NotNull NumeralBase from, @NotNull NumeralBase to) { public boolean isConversionPossible(@NotNull Generic generic, @NotNull NumeralBase from, @NotNull NumeralBase to) {
return calculator.isConversionPossible(generic, from, to); return calculator.isConversionPossible(generic, from, to);
} }
@Override @Override
@NotNull @NotNull
public CalculatorEventData convert(@NotNull Generic generic, @NotNull NumeralBase to) { public CalculatorEventData convert(@NotNull Generic generic, @NotNull NumeralBase to) {
return calculator.convert(generic, to); return calculator.convert(generic, to);
} }
@Override @Override
@NotNull @NotNull
public CalculatorEventData fireCalculatorEvent(@NotNull CalculatorEventType calculatorEventType, @Nullable Object data) { public CalculatorEventData fireCalculatorEvent(@NotNull CalculatorEventType calculatorEventType, @Nullable Object data) {
return calculator.fireCalculatorEvent(calculatorEventType, data); return calculator.fireCalculatorEvent(calculatorEventType, data);
} }
@Override @NotNull
@NotNull @Override
public CalculatorEventData fireCalculatorEvent(@NotNull CalculatorEventType calculatorEventType, @Nullable Object data, @NotNull Long sequenceId) { public CalculatorEventData fireCalculatorEvent(@NotNull CalculatorEventType calculatorEventType, @Nullable Object data, @NotNull Object source) {
return calculator.fireCalculatorEvent(calculatorEventType, data, sequenceId); return calculator.fireCalculatorEvent(calculatorEventType, data, source);
} }
@Override @Override
public void init() { @NotNull
this.calculator.init(); public CalculatorEventData fireCalculatorEvent(@NotNull CalculatorEventType calculatorEventType, @Nullable Object data, @NotNull Long sequenceId) {
} return calculator.fireCalculatorEvent(calculatorEventType, data, sequenceId);
}
@Override
public void addCalculatorEventListener(@NotNull CalculatorEventListener calculatorEventListener) { @Override
calculator.addCalculatorEventListener(calculatorEventListener); public void init() {
} this.calculator.init();
}
@Override
public void removeCalculatorEventListener(@NotNull CalculatorEventListener calculatorEventListener) { @Override
calculator.removeCalculatorEventListener(calculatorEventListener); public void addCalculatorEventListener(@NotNull CalculatorEventListener calculatorEventListener) {
} calculator.addCalculatorEventListener(calculatorEventListener);
}
@Override
public void fireCalculatorEvent(@NotNull CalculatorEventData calculatorEventData, @NotNull CalculatorEventType calculatorEventType, @Nullable Object data) { @Override
calculator.fireCalculatorEvent(calculatorEventData, calculatorEventType, data); public void removeCalculatorEventListener(@NotNull CalculatorEventListener calculatorEventListener) {
} calculator.removeCalculatorEventListener(calculatorEventListener);
}
@Override
public void fireCalculatorEvents(@NotNull List<CalculatorEvent> calculatorEvents) { @Override
calculator.fireCalculatorEvents(calculatorEvents); public void fireCalculatorEvent(@NotNull CalculatorEventData calculatorEventData, @NotNull CalculatorEventType calculatorEventType, @Nullable Object data) {
} calculator.fireCalculatorEvent(calculatorEventData, calculatorEventType, data);
}
@Override
public void doHistoryAction(@NotNull HistoryAction historyAction) { @Override
calculator.doHistoryAction(historyAction); public void fireCalculatorEvents(@NotNull List<CalculatorEvent> calculatorEvents) {
} calculator.fireCalculatorEvents(calculatorEvents);
}
@Override
public void setCurrentHistoryState(@NotNull CalculatorHistoryState editorHistoryState) { @Override
calculator.setCurrentHistoryState(editorHistoryState); public void doHistoryAction(@NotNull HistoryAction historyAction) {
} calculator.doHistoryAction(historyAction);
}
@Override
@NotNull @Override
public CalculatorHistoryState getCurrentHistoryState() { public void setCurrentHistoryState(@NotNull CalculatorHistoryState editorHistoryState) {
return calculator.getCurrentHistoryState(); calculator.setCurrentHistoryState(editorHistoryState);
} }
@Override @Override
public void evaluate() { @NotNull
calculator.evaluate(); public CalculatorHistoryState getCurrentHistoryState() {
} return calculator.getCurrentHistoryState();
}
@Override
public void evaluate(@NotNull Long sequenceId) { @Override
calculator.evaluate(sequenceId); public void evaluate() {
} calculator.evaluate();
}
@Override
public void simplify() { @Override
calculator.simplify(); public void evaluate(@NotNull Long sequenceId) {
} calculator.evaluate(sequenceId);
}
}
@Override
public void simplify() {
calculator.simplify();
}
}

View File

@ -1,10 +1,14 @@
package org.solovyev.android.calculator; package org.solovyev.android.calculator;
import android.app.Application; import android.app.Application;
import android.content.Context;
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.solovyev.android.msg.AndroidMessage;
import org.solovyev.common.msg.Message; import org.solovyev.common.msg.Message;
import org.solovyev.common.msg.MessageType;
import java.util.List;
/** /**
* User: serso * User: serso
@ -14,14 +18,24 @@ import org.solovyev.common.msg.Message;
public class AndroidCalculatorNotifier implements CalculatorNotifier { public class AndroidCalculatorNotifier implements CalculatorNotifier {
@NotNull @NotNull
private final Context context; private final Application application;
public AndroidCalculatorNotifier(@NotNull Application application) { public AndroidCalculatorNotifier(@NotNull Application application) {
this.context = application; this.application = application;
} }
@Override @Override
public void showMessage(@NotNull Message message) { public void showMessage(@NotNull Message message) {
Toast.makeText(context, message.getLocalizedMessage(), Toast.LENGTH_SHORT).show(); Toast.makeText(application, message.getLocalizedMessage(), Toast.LENGTH_SHORT).show();
}
@Override
public void showMessage(@NotNull Integer messageCode, @NotNull MessageType messageType, @NotNull List<Object> parameters) {
showMessage(new AndroidMessage(messageCode, messageType, application, parameters));
}
@Override
public void showMessage(@NotNull Integer messageCode, @NotNull MessageType messageType, @Nullable Object... parameters) {
showMessage(new AndroidMessage(messageCode, messageType, application, parameters));
} }
} }

View File

@ -5,6 +5,8 @@ import android.content.SharedPreferences;
import android.os.Bundle; import android.os.Bundle;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.support.v4.app.Fragment; import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.View;
import com.actionbarsherlock.app.ActionBar; import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.app.SherlockFragmentActivity; import com.actionbarsherlock.app.SherlockFragmentActivity;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@ -76,7 +78,12 @@ public class CalculatorActivityHelperImpl extends AbstractCalculatorHelper imple
activity.setContentView(layoutId); activity.setContentView(layoutId);
CalculatorButtons.processButtons(true, theme, activity.getWindow().getDecorView()); final View root = activity.findViewById(R.id.main_layout);
if (root != null) {
CalculatorButtons.processButtons(true, theme, root);
} else {
Log.e(CalculatorActivityHelperImpl.class.getSimpleName(), "Root is null for " + activity.getClass().getName());
}
if (savedInstanceState != null) { if (savedInstanceState != null) {
navPosition = savedInstanceState.getInt(SELECTED_NAV, 0); navPosition = savedInstanceState.getInt(SELECTED_NAV, 0);
@ -92,7 +99,11 @@ public class CalculatorActivityHelperImpl extends AbstractCalculatorHelper imple
actionBar.setDisplayHomeAsUpEnabled(homeIcon); actionBar.setDisplayHomeAsUpEnabled(homeIcon);
actionBar.setHomeButtonEnabled(false); actionBar.setHomeButtonEnabled(false);
actionBar.setDisplayShowHomeEnabled(true); actionBar.setDisplayShowHomeEnabled(true);
actionBar.setDisplayShowTitleEnabled(true); if (activity instanceof CalculatorActivity) {
actionBar.setDisplayShowTitleEnabled(false);
} else {
actionBar.setDisplayShowTitleEnabled(true);
}
actionBar.setIcon(R.drawable.icon_action_bar); actionBar.setIcon(R.drawable.icon_action_bar);
} }

View File

@ -2,7 +2,7 @@ package org.solovyev.android.calculator;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.widget.Toast; import com.actionbarsherlock.app.SherlockFragmentActivity;
import jscl.math.Generic; import jscl.math.Generic;
import jscl.math.function.Constant; import jscl.math.function.Constant;
import org.achartengine.ChartFactory; import org.achartengine.ChartFactory;
@ -13,6 +13,7 @@ import org.solovyev.android.calculator.history.CalculatorHistoryFragmentActivity
import org.solovyev.android.calculator.math.edit.*; import org.solovyev.android.calculator.math.edit.*;
import org.solovyev.android.calculator.plot.CalculatorPlotActivity; import org.solovyev.android.calculator.plot.CalculatorPlotActivity;
import org.solovyev.android.calculator.plot.CalculatorPlotFragment; import org.solovyev.android.calculator.plot.CalculatorPlotFragment;
import org.solovyev.common.msg.MessageType;
import org.solovyev.common.text.StringUtils; import org.solovyev.common.text.StringUtils;
/** /**
@ -64,17 +65,21 @@ public class CalculatorActivityLauncher {
final String varValue = viewState.getText(); final String varValue = viewState.getText();
if (!StringUtils.isEmpty(varValue)) { if (!StringUtils.isEmpty(varValue)) {
if (CalculatorVarsFragment.isValidValue(varValue)) { if (CalculatorVarsFragment.isValidValue(varValue)) {
final Intent intent = new Intent(context, CalculatorVarsFragmentActivity.class); if (context instanceof SherlockFragmentActivity) {
intent.putExtra(CalculatorVarsFragment.CREATE_VAR_EXTRA_STRING, varValue); VarEditDialogFragment.createEditVariableDialog(VarEditDialogFragment.Input.newFromValue(varValue), ((SherlockFragmentActivity) context).getSupportFragmentManager());
context.startActivity(intent); } else {
} else { final Intent intent = new Intent(context, CalculatorVarsFragmentActivity.class);
Toast.makeText(context, R.string.c_not_valid_result, Toast.LENGTH_SHORT).show(); intent.putExtra(CalculatorVarsFragment.CREATE_VAR_EXTRA_STRING, varValue);
context.startActivity(intent);
}
} else {
CalculatorLocatorImpl.getInstance().getNotifier().showMessage(R.string.c_not_valid_result, MessageType.error);
} }
} else { } else {
Toast.makeText(context, R.string.c_empty_var_error, Toast.LENGTH_SHORT).show(); CalculatorLocatorImpl.getInstance().getNotifier().showMessage(R.string.c_empty_var_error, MessageType.error);
} }
} else { } else {
Toast.makeText(context, R.string.c_not_valid_result, Toast.LENGTH_SHORT).show(); CalculatorLocatorImpl.getInstance().getNotifier().showMessage(R.string.c_not_valid_result, MessageType.error);
} }
} }
} }

View File

@ -10,6 +10,7 @@ import android.app.Activity;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@ -37,7 +38,7 @@ import java.util.List;
* Date: 12/21/11 * Date: 12/21/11
* Time: 9:24 PM * Time: 9:24 PM
*/ */
public abstract class AbstractMathEntityListFragment<T extends MathEntity> extends SherlockListFragment { public abstract class AbstractMathEntityListFragment<T extends MathEntity> extends SherlockListFragment implements CalculatorEventListener {
/* /*
********************************************************************** **********************************************************************
@ -49,7 +50,7 @@ public abstract class AbstractMathEntityListFragment<T extends MathEntity> exten
public static final String MATH_ENTITY_CATEGORY_EXTRA_STRING = "org.solovyev.android.calculator.CalculatorVarsActivity_math_entity_category"; public static final String MATH_ENTITY_CATEGORY_EXTRA_STRING = "org.solovyev.android.calculator.CalculatorVarsActivity_math_entity_category";
protected final static List<Character> acceptableChars = Arrays.asList(StringUtils.toObject("1234567890abcdefghijklmnopqrstuvwxyzйцукенгшщзхъфывапролджэячсмитьбюё_".toCharArray())); protected final static List<Character> acceptableChars = Arrays.asList(StringUtils.toObject("1234567890abcdefghijklmnopqrstuvwxyzйцукенгшщзхъфывапролджэячсмитьбюё_".toCharArray()));
/* /*
@ -62,13 +63,15 @@ public abstract class AbstractMathEntityListFragment<T extends MathEntity> exten
@Nullable @Nullable
private MathEntityArrayAdapter<T> adapter; private MathEntityArrayAdapter<T> adapter;
@Nullable @Nullable
private String category; private String category;
@NotNull @NotNull
private CalculatorFragmentHelper fragmentHelper; private CalculatorFragmentHelper fragmentHelper;
@NotNull
private final Handler uiHandler = new Handler();
protected int getLayoutId() { protected int getLayoutId() {
return R.layout.math_entities_fragment; return R.layout.math_entities_fragment;
@ -79,13 +82,13 @@ public abstract class AbstractMathEntityListFragment<T extends MathEntity> exten
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
final Bundle bundle = getArguments(); final Bundle bundle = getArguments();
if ( bundle != null ) { if (bundle != null) {
category = bundle.getString(MATH_ENTITY_CATEGORY_EXTRA_STRING); category = bundle.getString(MATH_ENTITY_CATEGORY_EXTRA_STRING);
} }
fragmentHelper = CalculatorApplication.getInstance().createFragmentHelper(getLayoutId(), getTitleResId()); fragmentHelper = CalculatorApplication.getInstance().createFragmentHelper(getLayoutId(), getTitleResId());
fragmentHelper.onCreate(this); fragmentHelper.onCreate(this);
} }
@Override @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
@ -107,7 +110,7 @@ public abstract class AbstractMathEntityListFragment<T extends MathEntity> exten
final int position, final int position,
final long id) { final long id) {
final AMenuItem<T> onClick = getOnClickAction(); final AMenuItem<T> onClick = getOnClickAction();
if ( onClick != null ) { if (onClick != null) {
onClick.onClick(((T) parent.getItemAtPosition(position)), getActivity()); onClick.onClick(((T) parent.getItemAtPosition(position)), getActivity());
} }
} }
@ -140,10 +143,10 @@ public abstract class AbstractMathEntityListFragment<T extends MathEntity> exten
fragmentHelper.onDestroy(this); fragmentHelper.onDestroy(this);
super.onDestroy(); super.onDestroy();
} }
@NotNull @NotNull
protected abstract List<LabeledMenuItem<T>> getMenuItemsOnLongClick(@NotNull T item); protected abstract List<LabeledMenuItem<T>> getMenuItemsOnLongClick(@NotNull T item);
@Override @Override
public void onPause() { public void onPause() {
@ -175,7 +178,7 @@ public abstract class AbstractMathEntityListFragment<T extends MathEntity> exten
} }
}).filter(result.iterator()); }).filter(result.iterator());
return result; return result;
} }
protected boolean isInCategory(@Nullable T t) { protected boolean isInCategory(@Nullable T t) {
@ -187,34 +190,34 @@ public abstract class AbstractMathEntityListFragment<T extends MathEntity> exten
@NotNull @NotNull
protected abstract List<T> getMathEntities(); protected abstract List<T> getMathEntities();
@Nullable @Nullable
abstract String getMathEntityCategory(@NotNull T t); abstract String getMathEntityCategory(@NotNull T t);
protected void sort() { protected void sort() {
final MathEntityArrayAdapter<T> localAdapter = adapter; final MathEntityArrayAdapter<T> localAdapter = adapter;
if (localAdapter != null) { if (localAdapter != null) {
localAdapter.sort(new Comparator<T>() { localAdapter.sort(new Comparator<T>() {
@Override @Override
public int compare(T function1, T function2) { public int compare(T function1, T function2) {
return function1.getName().compareTo(function2.getName()); return function1.getName().compareTo(function2.getName());
} }
}); });
localAdapter.notifyDataSetChanged(); localAdapter.notifyDataSetChanged();
} }
} }
protected static class MathEntityArrayAdapter<T extends MathEntity> extends ArrayAdapter<T> { protected static class MathEntityArrayAdapter<T extends MathEntity> extends ArrayAdapter<T> {
@NotNull @NotNull
private final MathEntityDescriptionGetter descriptionGetter; private final MathEntityDescriptionGetter descriptionGetter;
private MathEntityArrayAdapter(@NotNull MathEntityDescriptionGetter descriptionGetter, private MathEntityArrayAdapter(@NotNull MathEntityDescriptionGetter descriptionGetter,
@NotNull Context context, @NotNull Context context,
int resource, int resource,
int textViewResourceId, int textViewResourceId,
@NotNull List<T> objects) { @NotNull List<T> objects) {
super(context, resource, textViewResourceId, objects); super(context, resource, textViewResourceId, objects);
this.descriptionGetter = descriptionGetter; this.descriptionGetter = descriptionGetter;
@ -243,12 +246,12 @@ public abstract class AbstractMathEntityListFragment<T extends MathEntity> exten
text.setText(String.valueOf(mathEntity)); text.setText(String.valueOf(mathEntity));
final String mathEntityDescription = descriptionGetter.getDescription(getContext(), mathEntity.getName()); final String mathEntityDescription = descriptionGetter.getDescription(getContext(), mathEntity.getName());
final TextView description = (TextView) result.findViewById(R.id.math_entity_description);
if (!StringUtils.isEmpty(mathEntityDescription)) { if (!StringUtils.isEmpty(mathEntityDescription)) {
final TextView description = (TextView) result.findViewById(R.id.math_entity_description);
description.setVisibility(View.VISIBLE); description.setVisibility(View.VISIBLE);
description.setText(mathEntityDescription); description.setText(mathEntityDescription);
} else { } else {
final TextView description = (TextView) result.findViewById(R.id.math_entity_description);
description.setVisibility(View.GONE); description.setVisibility(View.GONE);
} }
} }
@ -275,23 +278,28 @@ public abstract class AbstractMathEntityListFragment<T extends MathEntity> exten
String getDescription(@NotNull Context context, @NotNull String mathEntityName); String getDescription(@NotNull Context context, @NotNull String mathEntityName);
} }
public void addToAdapter(@NotNull T mathEntity) { public void addToAdapter(@NotNull T mathEntity) {
if (this.adapter != null) { if (this.adapter != null) {
this.adapter.add(mathEntity); this.adapter.add(mathEntity);
} }
} }
public void removeFromAdapter(@NotNull T mathEntity) { public void removeFromAdapter(@NotNull T mathEntity) {
if (this.adapter != null) { if (this.adapter != null) {
this.adapter.remove(mathEntity); this.adapter.remove(mathEntity);
} }
} }
public void notifyAdapter() { public void notifyAdapter() {
if (this.adapter != null) { if (this.adapter != null) {
this.adapter.notifyDataSetChanged(); this.adapter.notifyDataSetChanged();
} }
} }
@NotNull
protected Handler getUiHandler() {
return uiHandler;
}
/* /*
********************************************************************** **********************************************************************
@ -336,4 +344,8 @@ public abstract class AbstractMathEntityListFragment<T extends MathEntity> exten
static void putCategory(@NotNull Bundle bundle, @NotNull String categoryId) { static void putCategory(@NotNull Bundle bundle, @NotNull String categoryId) {
bundle.putString(MATH_ENTITY_CATEGORY_EXTRA_STRING, categoryId); bundle.putString(MATH_ENTITY_CATEGORY_EXTRA_STRING, categoryId);
} }
@Override
public void onCalculatorEvent(@NotNull CalculatorEventData calculatorEventData, @NotNull CalculatorEventType calculatorEventType, @Nullable Object data) {
}
} }

View File

@ -1,229 +1,279 @@
/* /*
* 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
*/ */
package org.solovyev.android.calculator.math.edit; package org.solovyev.android.calculator.math.edit;
import android.app.Activity; import android.content.Context;
import android.content.Context; import android.os.Bundle;
import android.os.Bundle; import android.view.View;
import android.text.ClipboardManager; import com.actionbarsherlock.app.SherlockFragmentActivity;
import android.view.View; import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.Menu; import com.actionbarsherlock.view.MenuInflater;
import com.actionbarsherlock.view.MenuInflater; import com.actionbarsherlock.view.MenuItem;
import com.actionbarsherlock.view.MenuItem; import jscl.math.function.IConstant;
import jscl.math.function.IConstant; 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.android.calculator.CalculatorEventType; import org.solovyev.android.calculator.math.MathType;
import org.solovyev.android.calculator.CalculatorLocatorImpl; import org.solovyev.android.menu.AMenuItem;
import org.solovyev.android.calculator.R; import org.solovyev.android.menu.LabeledMenuItem;
import org.solovyev.android.calculator.math.MathType; import org.solovyev.common.JPredicate;
import org.solovyev.android.menu.AMenuItem; import org.solovyev.common.collections.CollectionsUtils;
import org.solovyev.android.menu.LabeledMenuItem; import org.solovyev.common.text.StringUtils;
import org.solovyev.common.JPredicate;
import org.solovyev.common.collections.CollectionsUtils; import java.util.ArrayList;
import org.solovyev.common.text.StringUtils; import java.util.Arrays;
import java.util.List;
import java.util.ArrayList;
import java.util.Arrays; /**
import java.util.List; * User: serso
* Date: 9/28/11
/** * Time: 10:55 PM
* User: serso */
* Date: 9/28/11 public class CalculatorVarsFragment extends AbstractMathEntityListFragment<IConstant> {
* Time: 10:55 PM
*/ public static final String CREATE_VAR_EXTRA_STRING = "create_var";
public class CalculatorVarsFragment extends AbstractMathEntityListFragment<IConstant> {
@Override
public static final String CREATE_VAR_EXTRA_STRING = "org.solovyev.android.calculator.math.edit.CalculatorVarsTabActivity_create_var"; protected int getLayoutId() {
return R.layout.vars_fragment;
@Override }
protected int getLayoutId() {
return R.layout.vars_fragment; @Override
} public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@Override
public void onCreate(Bundle savedInstanceState) { final Bundle bundle = getArguments();
super.onCreate(savedInstanceState); if (bundle != null) {
final String varValue = bundle.getString(CREATE_VAR_EXTRA_STRING);
final Bundle bundle = getArguments(); if (!StringUtils.isEmpty(varValue)) {
if (bundle != null) { VarEditDialogFragment.createEditVariableDialog(VarEditDialogFragment.Input.newFromValue(varValue), this.getActivity().getSupportFragmentManager());
final String varValue = bundle.getString(CREATE_VAR_EXTRA_STRING);
if (!StringUtils.isEmpty(varValue)) { // in order to stop intent for other tabs
VarEditDialogFragment.createEditVariableDialog(this, VarEditDialogFragment.Input.newFromValue(varValue)); bundle.remove(CREATE_VAR_EXTRA_STRING);
}
// in order to stop intent for other tabs }
bundle.remove(CREATE_VAR_EXTRA_STRING);
} setHasOptionsMenu(true);
} }
setHasOptionsMenu(true); @Override
} protected int getTitleResId() {
return R.string.c_vars;
@Override }
protected int getTitleResId() {
return R.string.c_vars; @Override
} protected AMenuItem<IConstant> getOnClickAction() {
return LongClickMenuItem.use;
@Override }
protected AMenuItem<IConstant> getOnClickAction() {
return LongClickMenuItem.use; @NotNull
} @Override
protected List<LabeledMenuItem<IConstant>> getMenuItemsOnLongClick(@NotNull IConstant item) {
@NotNull final List<LabeledMenuItem<IConstant>> result = new ArrayList<LabeledMenuItem<IConstant>>(Arrays.asList(LongClickMenuItem.values()));
@Override
protected List<LabeledMenuItem<IConstant>> getMenuItemsOnLongClick(@NotNull IConstant item) { if (item.isSystem()) {
final List<LabeledMenuItem<IConstant>> result = new ArrayList<LabeledMenuItem<IConstant>>(Arrays.asList(LongClickMenuItem.values())); result.remove(LongClickMenuItem.edit);
result.remove(LongClickMenuItem.remove);
if ( item.isSystem() ) { }
result.remove(LongClickMenuItem.edit);
result.remove(LongClickMenuItem.remove); if (StringUtils.isEmpty(CalculatorLocatorImpl.getInstance().getEngine().getVarsRegistry().getDescription(item.getName()))) {
} result.remove(LongClickMenuItem.copy_description);
}
if ( StringUtils.isEmpty(CalculatorLocatorImpl.getInstance().getEngine().getVarsRegistry().getDescription(item.getName())) ) {
result.remove(LongClickMenuItem.copy_description); if (StringUtils.isEmpty(item.getValue())) {
} result.remove(LongClickMenuItem.copy_value);
}
if ( StringUtils.isEmpty(item.getValue()) ) {
result.remove(LongClickMenuItem.copy_value); return result;
} }
return result; @NotNull
} @Override
protected MathEntityDescriptionGetter getDescriptionGetter() {
@NotNull return new MathEntityDescriptionGetterImpl(CalculatorLocatorImpl.getInstance().getEngine().getVarsRegistry());
@Override }
protected MathEntityDescriptionGetter getDescriptionGetter() {
return new MathEntityDescriptionGetterImpl(CalculatorLocatorImpl.getInstance().getEngine().getVarsRegistry()); @SuppressWarnings({"UnusedDeclaration"})
} public void addVarButtonClickHandler(@NotNull View v) {
VarEditDialogFragment.createEditVariableDialog(VarEditDialogFragment.Input.newInstance(), this.getActivity().getSupportFragmentManager());
@SuppressWarnings({"UnusedDeclaration"}) }
public void addVarButtonClickHandler(@NotNull View v) {
VarEditDialogFragment.createEditVariableDialog(this, VarEditDialogFragment.Input.newInstance()); @NotNull
} @Override
protected List<IConstant> getMathEntities() {
@NotNull final List<IConstant> result = new ArrayList<IConstant>(CalculatorLocatorImpl.getInstance().getEngine().getVarsRegistry().getEntities());
@Override
protected List<IConstant> getMathEntities() { CollectionsUtils.removeAll(result, new JPredicate<IConstant>() {
final List<IConstant> result = new ArrayList<IConstant>(CalculatorLocatorImpl.getInstance().getEngine().getVarsRegistry().getEntities()); @Override
public boolean apply(@Nullable IConstant var) {
CollectionsUtils.removeAll(result, new JPredicate<IConstant>() { return var != null && CollectionsUtils.contains(var.getName(), MathType.INFINITY_JSCL, MathType.NAN);
@Override }
public boolean apply(@Nullable IConstant var) { });
return var != null && CollectionsUtils.contains(var.getName(), MathType.INFINITY_JSCL, MathType.NAN);
} return result;
}); }
return result; @Override
} protected String getMathEntityCategory(@NotNull IConstant var) {
return CalculatorLocatorImpl.getInstance().getEngine().getVarsRegistry().getCategory(var);
@Override }
protected String getMathEntityCategory(@NotNull IConstant var) {
return CalculatorLocatorImpl.getInstance().getEngine().getVarsRegistry().getCategory(var); public static boolean isValidValue(@NotNull String value) {
} // now every string might be constant
return true;
public static boolean isValidValue(@NotNull String value) { }
// now every string might be constant
return true; /*
} **********************************************************************
*
/* * MENU
********************************************************************** *
* **********************************************************************
* MENU */
*
********************************************************************** @Override
*/ public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.var_menu, menu);
@Override }
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.var_menu, menu); @Override
} public boolean onOptionsItemSelected(MenuItem item) {
boolean result;
@Override
public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) {
boolean result; case R.id.var_menu_add_var:
VarEditDialogFragment.createEditVariableDialog(VarEditDialogFragment.Input.newInstance(), this.getActivity().getSupportFragmentManager());
switch (item.getItemId()) { result = true;
case R.id.var_menu_add_var: break;
VarEditDialogFragment.createEditVariableDialog(this, VarEditDialogFragment.Input.newInstance()); default:
result = true; result = super.onOptionsItemSelected(item);
break; }
default:
result = super.onOptionsItemSelected(item); return result;
} }
return result; @Override
} public void onCalculatorEvent(@NotNull CalculatorEventData calculatorEventData, @NotNull CalculatorEventType calculatorEventType, @Nullable Object data) {
super.onCalculatorEvent(calculatorEventData, calculatorEventType, data);
/*
********************************************************************** switch (calculatorEventType) {
* case constant_added:
* STATIC processConstantAdded((IConstant) data);
* break;
**********************************************************************
*/ case constant_changed:
processConstantChanged((Change<IConstant>) data);
private static enum LongClickMenuItem implements LabeledMenuItem<IConstant>{ break;
use(R.string.c_use) {
@Override case constant_removed:
public void onClick(@NotNull IConstant data, @NotNull Context context) { processConstantRemoved((IConstant) data);
CalculatorLocatorImpl.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.use_constant, data); break;
} }
}, }
edit(R.string.c_edit) { private void processConstantRemoved(@NotNull final IConstant constant) {
@Override if (this.isInCategory(constant)) {
public void onClick(@NotNull IConstant data, @NotNull Context context) { getUiHandler().post(new Runnable() {
/*if (context instanceof AbstractMathEntityListFragment) { @Override
createEditVariableDialog((AbstractMathEntityListFragment<IConstant>)context, data, data.getName(), StringUtils.getNotEmpty(data.getValue(), ""), data.getDescription()); public void run() {
}*/ removeFromAdapter(constant);
} notifyAdapter();
}, }
});
remove(R.string.c_remove) { }
@Override }
public void onClick(@NotNull IConstant data, @NotNull Context context) {
/*if (context instanceof AbstractMathEntityListFragment) { private void processConstantChanged(@NotNull final Change<IConstant> change) {
new MathEntityRemover<IConstant>(data, null, CalculatorLocatorImpl.getInstance().getEngine().getVarsRegistry(), ((AbstractMathEntityListFragment<IConstant>) context)).showConfirmationDialog(); final IConstant newConstant = change.getNewValue();
}*/ if (this.isInCategory(newConstant)) {
} getUiHandler().post(new Runnable() {
}, @Override
public void run() {
copy_value(R.string.c_copy_value) { removeFromAdapter(change.getOldValue());
@Override addToAdapter(newConstant);
public void onClick(@NotNull IConstant data, @NotNull Context context) { sort();
final String text = data.getValue(); }
if (!StringUtils.isEmpty(text)) { });
final ClipboardManager clipboard = (ClipboardManager) context.getSystemService(Activity.CLIPBOARD_SERVICE); }
clipboard.setText(text); }
}
} private void processConstantAdded(@NotNull final IConstant constant) {
}, if (this.isInCategory(constant)) {
getUiHandler().post(new Runnable() {
copy_description(R.string.c_copy_description) { @Override
@Override public void run() {
public void onClick(@NotNull IConstant data, @NotNull Context context) { addToAdapter(constant);
final String text = CalculatorLocatorImpl.getInstance().getEngine().getVarsRegistry().getDescription(data.getName()); sort();
if (!StringUtils.isEmpty(text)) { }
final ClipboardManager clipboard = (ClipboardManager) context.getSystemService(Activity.CLIPBOARD_SERVICE); });
clipboard.setText(text); }
} }
}
}; /*
private final int captionId; **********************************************************************
*
LongClickMenuItem(int captionId) { * STATIC
this.captionId = captionId; *
} **********************************************************************
*/
@NotNull
@Override private static enum LongClickMenuItem implements LabeledMenuItem<IConstant> {
public String getCaption(@NotNull Context context) { use(R.string.c_use) {
return context.getString(captionId); @Override
} public void onClick(@NotNull IConstant data, @NotNull Context context) {
} CalculatorLocatorImpl.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.use_constant, data);
} }
},
edit(R.string.c_edit) {
@Override
public void onClick(@NotNull IConstant constant, @NotNull Context context) {
VarEditDialogFragment.createEditVariableDialog(VarEditDialogFragment.Input.newFromConstant(constant), ((SherlockFragmentActivity) context).getSupportFragmentManager());
}
},
remove(R.string.c_remove) {
@Override
public void onClick(@NotNull IConstant constant, @NotNull Context context) {
new MathEntityRemover<IConstant>(constant, null, CalculatorLocatorImpl.getInstance().getEngine().getVarsRegistry(), context, context).showConfirmationDialog();
}
},
copy_value(R.string.c_copy_value) {
@Override
public void onClick(@NotNull IConstant data, @NotNull Context context) {
final String text = data.getValue();
if (!StringUtils.isEmpty(text)) {
assert text != null;
CalculatorLocatorImpl.getInstance().getClipboard().setText(text);
}
}
},
copy_description(R.string.c_copy_description) {
@Override
public void onClick(@NotNull IConstant data, @NotNull Context context) {
final String text = CalculatorLocatorImpl.getInstance().getEngine().getVarsRegistry().getDescription(data.getName());
if (!StringUtils.isEmpty(text)) {
assert text != null;
CalculatorLocatorImpl.getInstance().getClipboard().setText(text);
}
}
};
private final int captionId;
LongClickMenuItem(int captionId) {
this.captionId = captionId;
}
@NotNull
@Override
public String getCaption(@NotNull Context context) {
return context.getString(captionId);
}
}
}

View File

@ -7,12 +7,16 @@
package org.solovyev.android.calculator.math.edit; package org.solovyev.android.calculator.math.edit;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.view.View;
import android.widget.TextView; import android.widget.TextView;
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.R; import org.solovyev.android.calculator.CalculatorEventType;
import org.solovyev.android.calculator.CalculatorLocatorImpl;
import org.solovyev.android.calculator.CalculatorMathRegistry; import org.solovyev.android.calculator.CalculatorMathRegistry;
import org.solovyev.android.calculator.R;
import org.solovyev.common.math.MathEntity; import org.solovyev.common.math.MathEntity;
/** /**
@ -20,7 +24,7 @@ import org.solovyev.common.math.MathEntity;
* Date: 12/22/11 * Date: 12/22/11
* Time: 9:36 PM * Time: 9:36 PM
*/ */
class MathEntityRemover<T extends MathEntity> implements DialogInterface.OnClickListener { class MathEntityRemover<T extends MathEntity> implements View.OnClickListener, DialogInterface.OnClickListener {
@NotNull @NotNull
private final T mathEntity; private final T mathEntity;
@ -33,56 +37,64 @@ class MathEntityRemover<T extends MathEntity> implements DialogInterface.OnClick
@NotNull @NotNull
private final CalculatorMathRegistry<? super T> varsRegistry; private final CalculatorMathRegistry<? super T> varsRegistry;
@NotNull @NotNull
private final AbstractMathEntityListFragment<T> fragment; private Context context;
public MathEntityRemover(@NotNull T mathEntity, @NotNull
@Nullable DialogInterface.OnClickListener callbackOnCancel, private final Object source;
@NotNull CalculatorMathRegistry<? super T> varsRegistry,
@NotNull AbstractMathEntityListFragment<T> fragment) { public MathEntityRemover(@NotNull T mathEntity,
this(mathEntity, callbackOnCancel, false, varsRegistry, fragment); @Nullable DialogInterface.OnClickListener callbackOnCancel,
@NotNull CalculatorMathRegistry<? super T> varsRegistry,
@NotNull Context context,
@NotNull Object source) {
this(mathEntity, callbackOnCancel, false, varsRegistry, context, source);
} }
public MathEntityRemover(@NotNull T mathEntity, public MathEntityRemover(@NotNull T mathEntity,
@Nullable DialogInterface.OnClickListener callbackOnCancel, @Nullable DialogInterface.OnClickListener callbackOnCancel,
boolean confirmed, boolean confirmed,
@NotNull CalculatorMathRegistry<? super T> varsRegistry, @NotNull CalculatorMathRegistry<? super T> varsRegistry,
@NotNull AbstractMathEntityListFragment<T> fragment) { @NotNull Context context,
@NotNull Object source) {
this.mathEntity = mathEntity; this.mathEntity = mathEntity;
this.callbackOnCancel = callbackOnCancel; this.callbackOnCancel = callbackOnCancel;
this.confirmed = confirmed; this.confirmed = confirmed;
this.varsRegistry = varsRegistry; this.varsRegistry = varsRegistry;
this.fragment = fragment; this.context = context;
} this.source = source;
}
@Override
public void onClick(DialogInterface dialog, int which) {
if (!confirmed) {
showConfirmationDialog();
} else {
if (fragment.isInCategory(mathEntity)) {
fragment.removeFromAdapter(mathEntity);
}
varsRegistry.remove(mathEntity);
varsRegistry.save();
if (fragment.isInCategory(mathEntity)) {
fragment.notifyAdapter();
}
}
}
public void showConfirmationDialog() { public void showConfirmationDialog() {
final TextView question = new TextView(fragment.getActivity()); final TextView question = new TextView(context);
question.setText(String.format(fragment.getString(R.string.c_var_removal_confirmation_question), mathEntity.getName())); question.setText(String.format(context.getString(R.string.c_var_removal_confirmation_question), mathEntity.getName()));
question.setPadding(6, 6, 6, 6); question.setPadding(6, 6, 6, 6);
final AlertDialog.Builder builder = new AlertDialog.Builder(fragment.getActivity()) final AlertDialog.Builder builder = new AlertDialog.Builder(context)
.setCancelable(true) .setCancelable(true)
.setView(question) .setView(question)
.setTitle(R.string.c_var_removal_confirmation) .setTitle(R.string.c_var_removal_confirmation)
.setNegativeButton(R.string.c_no, callbackOnCancel) .setNegativeButton(R.string.c_no, callbackOnCancel)
.setPositiveButton(R.string.c_yes, new MathEntityRemover<T>(mathEntity, callbackOnCancel, true, varsRegistry, fragment)); .setPositiveButton(R.string.c_yes, new MathEntityRemover<T>(mathEntity, callbackOnCancel, true, varsRegistry, context, source));
builder.create().show(); builder.create().show();
} }
@Override
public void onClick(@Nullable View v) {
if (!confirmed) {
showConfirmationDialog();
} else {
varsRegistry.remove(mathEntity);
varsRegistry.save();
CalculatorLocatorImpl.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.constant_removed, mathEntity, source);
}
}
@Override
public void onClick(DialogInterface dialog, int which) {
onClick(null);
}
} }

View File

@ -1,277 +1,224 @@
package org.solovyev.android.calculator.math.edit; package org.solovyev.android.calculator.math.edit;
import android.app.Activity; import android.os.Bundle;
import android.app.AlertDialog; import android.support.v4.app.DialogFragment;
import android.content.DialogInterface; import android.support.v4.app.Fragment;
import android.os.Bundle; import android.support.v4.app.FragmentManager;
import android.support.v4.app.*; import android.support.v4.app.FragmentTransaction;
import android.text.Editable; import android.text.Editable;
import android.text.TextWatcher; import android.text.TextWatcher;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.EditText; import android.view.WindowManager;
import android.widget.Toast; import android.widget.EditText;
import jscl.math.function.IConstant; import android.widget.Toast;
import org.jetbrains.annotations.NotNull; import jscl.math.function.IConstant;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.NotNull;
import org.solovyev.android.calculator.CalculatorLocatorImpl; import org.jetbrains.annotations.Nullable;
import org.solovyev.android.calculator.R; import org.solovyev.android.calculator.*;
import org.solovyev.android.calculator.model.Var; import org.solovyev.android.calculator.model.Var;
import org.solovyev.common.text.StringUtils;
/**
/** * User: Solovyev_S
* User: Solovyev_S * Date: 01.10.12
* Date: 01.10.12 * Time: 17:41
* Time: 17:41 */
*/ public class VarEditDialogFragment extends DialogFragment implements CalculatorEventListener {
public class VarEditDialogFragment extends DialogFragment {
@NotNull
@NotNull private final Input input;
private final Input input;
public VarEditDialogFragment() {
public VarEditDialogFragment() { this(Input.newInstance());
this(Input.newInstance()); }
}
public VarEditDialogFragment(@NotNull Input input) {
public VarEditDialogFragment(@NotNull Input input) { this.input = input;
this.input = input; }
}
public static void createEditVariableDialog(@NotNull Input input, @NotNull FragmentManager fm) {
public static void createEditVariableDialog(@NotNull final AbstractMathEntityListFragment<IConstant> fragment, final FragmentTransaction ft = fm.beginTransaction();
@NotNull Input input) {
Fragment prev = fm.findFragmentByTag("constant-editor");
final FragmentManager fm = fragment.getActivity().getSupportFragmentManager(); if (prev != null) {
final FragmentTransaction ft = fm.beginTransaction(); ft.remove(prev);
}
Fragment prev = fm.findFragmentByTag("constant-editor"); ft.addToBackStack(null);
if (prev != null) {
ft.remove(prev); // Create and show the dialog.
} final DialogFragment newFragment = new VarEditDialogFragment(input);
ft.addToBackStack(null); newFragment.show(ft, "constant-editor");
// Create and show the dialog. }
final DialogFragment newFragment = new VarEditDialogFragment(input);
newFragment.show(ft, "constant-editor"); @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
} return inflater.inflate(R.layout.var_edit, container, false);
}
public static void createEditVariableDialog0(@NotNull final AbstractMathEntityListFragment<IConstant> fragment,
@Nullable final IConstant var, @Override
@Nullable final String name, public void onResume() {
@Nullable final String value, super.onResume();
@Nullable final String description) {
final FragmentActivity activity = fragment.getActivity(); CalculatorLocatorImpl.getInstance().getCalculator().addCalculatorEventListener(this);
}
if (var == null || !var.isSystem()) {
@Override
final LayoutInflater layoutInflater = (LayoutInflater) activity.getSystemService(Activity.LAYOUT_INFLATER_SERVICE); public void onPause() {
final View result = layoutInflater.inflate(R.layout.var_edit, null); CalculatorLocatorImpl.getInstance().getCalculator().removeCalculatorEventListener(this);
final String errorMsg = fragment.getString(R.string.c_char_is_not_accepted); super.onPause();
}
final EditText editName = (EditText) result.findViewById(R.id.var_edit_name);
editName.setText(name); @Override
editName.addTextChangedListener(new TextWatcher() { public void onViewCreated(@NotNull View root, Bundle savedInstanceState) {
super.onViewCreated(root, savedInstanceState);
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) { final String errorMsg = this.getString(R.string.c_char_is_not_accepted);
}
final EditText editName = (EditText) root.findViewById(R.id.var_edit_name);
@Override editName.setText(input.getName());
public void onTextChanged(CharSequence s, int start, int before, int count) { editName.addTextChangedListener(new TextWatcher() {
}
@Override
@Override public void beforeTextChanged(CharSequence s, int start, int count, int after) {
public void afterTextChanged(Editable s) { }
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i); @Override
if (!AbstractMathEntityListFragment.acceptableChars.contains(c)) { public void onTextChanged(CharSequence s, int start, int before, int count) {
s.delete(i, i + 1); }
Toast.makeText(activity, String.format(errorMsg, c), Toast.LENGTH_SHORT).show();
} @Override
} public void afterTextChanged(Editable s) {
} for (int i = 0; i < s.length(); i++) {
}); char c = s.charAt(i);
if (!AbstractMathEntityListFragment.acceptableChars.contains(c)) {
final EditText editValue = (EditText) result.findViewById(R.id.var_edit_value); s.delete(i, i + 1);
if (!StringUtils.isEmpty(value)) { Toast.makeText(getActivity(), String.format(errorMsg, c), Toast.LENGTH_SHORT).show();
editValue.setText(value); }
} }
}
final EditText editDescription = (EditText) result.findViewById(R.id.var_edit_description); });
editDescription.setText(description);
// show soft keyboard automatically
final Var.Builder varBuilder; editName.requestFocus();
if (var != null) { getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
varBuilder = new Var.Builder(var);
} else { final EditText editValue = (EditText) root.findViewById(R.id.var_edit_value);
varBuilder = new Var.Builder(); editValue.setText(input.getValue());
}
final EditText editDescription = (EditText) root.findViewById(R.id.var_edit_description);
final AlertDialog.Builder builder = new AlertDialog.Builder(activity) editDescription.setText(input.getDescription());
.setCancelable(true)
.setNegativeButton(R.string.c_cancel, null) final Var.Builder varBuilder;
.setPositiveButton(R.string.c_save, new VarEditorSaver<IConstant>(varBuilder, var, result, fragment, CalculatorLocatorImpl.getInstance().getEngine().getVarsRegistry(), new VarEditorSaver.EditorCreator<IConstant>() { final IConstant constant = input.getConstant();
@Override if (constant != null) {
public void showEditor(@NotNull AbstractMathEntityListFragment<IConstant> activity, @Nullable IConstant editedInstance, @Nullable String name, @Nullable String value, @Nullable String description) { varBuilder = new Var.Builder(constant);
createEditVariableDialog(activity, Input.newInstance(editedInstance, name, value, description)); } else {
} varBuilder = new Var.Builder();
})) }
.setView(result);
root.findViewById(R.id.cancel_button).setOnClickListener(new View.OnClickListener() {
if (var != null) { @Override
// EDIT mode public void onClick(View v) {
dismiss();
builder.setTitle(R.string.c_var_edit_var); }
builder.setNeutralButton(R.string.c_remove, new MathEntityRemover<IConstant>(var, new DialogInterface.OnClickListener() { });
@Override
public void onClick(DialogInterface dialog, int which) { root.findViewById(R.id.save_button).setOnClickListener(new VarEditorSaver<IConstant>(varBuilder, constant, root, CalculatorLocatorImpl.getInstance().getEngine().getVarsRegistry(), this));
createEditVariableDialog(fragment, Input.newInstance(var, name, value, description));
} if ( constant == null ) {
}, CalculatorLocatorImpl.getInstance().getEngine().getVarsRegistry(), fragment)); // CREATE MODE
} else { getDialog().setTitle(R.string.c_var_create_var);
// CREATE mode
root.findViewById(R.id.remove_button).setVisibility(View.GONE);
builder.setTitle(R.string.c_var_create_var); } else {
} // EDIT MODE
getDialog().setTitle(R.string.c_var_edit_var);
builder.create().show();
} else { root.findViewById(R.id.remove_button).setOnClickListener(new MathEntityRemover<IConstant>(constant, null, CalculatorLocatorImpl.getInstance().getEngine().getVarsRegistry(), getActivity(), this));
Toast.makeText(activity, fragment.getString(R.string.c_sys_var_cannot_be_changed), Toast.LENGTH_LONG).show(); }
} }
}
@Override
@Override public void onCalculatorEvent(@NotNull CalculatorEventData calculatorEventData, @NotNull CalculatorEventType calculatorEventType, @Nullable Object data) {
public void onCreate(Bundle savedInstanceState) { switch (calculatorEventType) {
super.onCreate(savedInstanceState); case constant_removed:
} case constant_added:
case constant_changed:
@Override if ( calculatorEventData.getSource() == this ) {
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { dismiss();
final View result = inflater.inflate(R.layout.var_edit, container, false); }
break;
return result; }
} }
@Override public static class Input {
public void onViewCreated(@NotNull View root, Bundle savedInstanceState) {
super.onViewCreated(root, savedInstanceState); @Nullable
private IConstant constant;
final String errorMsg = this.getString(R.string.c_char_is_not_accepted);
@Nullable
final EditText editName = (EditText) root.findViewById(R.id.var_edit_name); private String name;
editName.setText(input.getName());
editName.addTextChangedListener(new TextWatcher() { @Nullable
private String value;
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) { @Nullable
} private String description;
@Override private Input() {
public void onTextChanged(CharSequence s, int start, int before, int count) { }
}
@NotNull
@Override public static Input newInstance() {
public void afterTextChanged(Editable s) { return new Input();
for (int i = 0; i < s.length(); i++) { }
char c = s.charAt(i);
if (!AbstractMathEntityListFragment.acceptableChars.contains(c)) { @NotNull
s.delete(i, i + 1); public static Input newFromConstant(@NotNull IConstant constant) {
Toast.makeText(getActivity(), String.format(errorMsg, c), Toast.LENGTH_SHORT).show(); final Input result = new Input();
} result.constant = constant;
} return result;
} }
});
@NotNull
final EditText editValue = (EditText) root.findViewById(R.id.var_edit_value); public static Input newFromValue(@Nullable String value) {
editValue.setText(input.getValue()); final Input result = new Input();
result.value = value;
final EditText editDescription = (EditText) root.findViewById(R.id.var_edit_description); return result;
editDescription.setText(input.getDescription()); }
final Var.Builder varBuilder; @NotNull
final IConstant constant = input.getConstant(); public static Input newInstance(@Nullable IConstant constant, @Nullable String name, @Nullable String value, @Nullable String description) {
if (constant != null) { final Input result = new Input();
varBuilder = new Var.Builder(constant); result.constant = constant;
} else { result.name = name;
varBuilder = new Var.Builder(); result.value = value;
} result.description = description;
return result;
if ( constant == null ) { }
// CREATE MODE
getDialog().setTitle(R.string.c_var_create_var); @Nullable
} else { public IConstant getConstant() {
// EDIT MODE return constant;
getDialog().setTitle(R.string.c_var_edit_var); }
}
} @Nullable
public String getName() {
public static class Input { return name == null ? (constant == null ? null : constant.getName()) : name;
}
@Nullable
private IConstant constant; @Nullable
public String getValue() {
@Nullable return value == null ? (constant == null ? null : constant.getValue()) : value;
private String name; }
@Nullable @Nullable
private String value; public String getDescription() {
return description == null ? (constant == null ? null : constant.getDescription()) : description;
@Nullable }
private String description; }
}
private Input() {
}
@NotNull
public static Input newInstance() {
return new Input();
}
@NotNull
public static Input newFromConstant(@NotNull IConstant constant) {
final Input result = new Input();
result.constant = constant;
return result;
}
@NotNull
public static Input newFromValue(@Nullable String value) {
final Input result = new Input();
result.value = value;
return result;
}
@NotNull
public static Input newInstance(@Nullable IConstant constant, @Nullable String name, @Nullable String value, @Nullable String description) {
final Input result = new Input();
result.constant = constant;
result.name = name;
result.value = value;
result.description = description;
return result;
}
@Nullable
public IConstant getConstant() {
return constant;
}
@Nullable
public String getName() {
return name == null ? (constant == null ? null : constant.getName()) : name;
}
@Nullable
public String getValue() {
return value == null ? (constant == null ? null : constant.getValue()) : value;
}
@Nullable
public String getDescription() {
return description == null ? (constant == null ? null : constant.getDescription()) : description;
}
}
}

View File

@ -6,22 +6,19 @@
package org.solovyev.android.calculator.math.edit; package org.solovyev.android.calculator.math.edit;
import android.content.DialogInterface;
import android.view.View; import android.view.View;
import android.widget.EditText; import android.widget.EditText;
import android.widget.Toast;
import jscl.text.Identifier; import jscl.text.Identifier;
import jscl.text.MutableInt; import jscl.text.MutableInt;
import jscl.text.ParseException; import jscl.text.ParseException;
import jscl.text.Parser; import jscl.text.Parser;
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.CalculatorLocatorImpl; import org.solovyev.android.calculator.*;
import org.solovyev.android.calculator.CalculatorMathRegistry;
import org.solovyev.android.calculator.R;
import org.solovyev.android.calculator.math.MathType; import org.solovyev.android.calculator.math.MathType;
import org.solovyev.android.calculator.model.MathEntityBuilder; import org.solovyev.android.calculator.model.MathEntityBuilder;
import org.solovyev.common.math.MathEntity; import org.solovyev.common.math.MathEntity;
import org.solovyev.common.msg.MessageType;
import org.solovyev.common.text.StringUtils; import org.solovyev.common.text.StringUtils;
/** /**
@ -29,18 +26,7 @@ import org.solovyev.common.text.StringUtils;
* Date: 12/22/11 * Date: 12/22/11
* Time: 9:52 PM * Time: 9:52 PM
*/ */
class VarEditorSaver<T extends MathEntity> implements DialogInterface.OnClickListener { class VarEditorSaver<T extends MathEntity> implements View.OnClickListener {
public static interface EditorCreator<T extends MathEntity> {
void showEditor(@NotNull AbstractMathEntityListFragment<T> activity,
@Nullable T editedInstance,
@Nullable String name,
@Nullable String value,
@Nullable String description);
}
@NotNull
private final EditorCreator<T> editorCreator;
@NotNull @NotNull
private final MathEntityBuilder<? extends T> varBuilder; private final MathEntityBuilder<? extends T> varBuilder;
@ -51,105 +37,95 @@ class VarEditorSaver<T extends MathEntity> implements DialogInterface.OnClickLis
@NotNull @NotNull
private final CalculatorMathRegistry<T> mathRegistry; private final CalculatorMathRegistry<T> mathRegistry;
@NotNull @NotNull
private final AbstractMathEntityListFragment<T> fragment; private final Object source;
@NotNull @NotNull
private View editView; private View editView;
public VarEditorSaver(@NotNull MathEntityBuilder<? extends T> varBuilder, public VarEditorSaver(@NotNull MathEntityBuilder<? extends T> varBuilder,
@Nullable T editedInstance, @Nullable T editedInstance,
@NotNull View editView, @NotNull View editView,
@NotNull AbstractMathEntityListFragment<T> fragment, @NotNull CalculatorMathRegistry<T> mathRegistry,
@NotNull CalculatorMathRegistry<T> mathRegistry, @NotNull Object source) {
@NotNull EditorCreator<T> editorCreator) {
this.varBuilder = varBuilder; this.varBuilder = varBuilder;
this.editedInstance = editedInstance; this.editedInstance = editedInstance;
this.editView = editView; this.editView = editView;
this.fragment = fragment;
this.mathRegistry = mathRegistry; this.mathRegistry = mathRegistry;
this.editorCreator = editorCreator; this.source = source;
} }
@Override @Override
public void onClick(DialogInterface dialog, int which) { public void onClick(View v) {
if (which == DialogInterface.BUTTON_POSITIVE) { final Integer error;
final Integer error;
final EditText editName = (EditText) editView.findViewById(R.id.var_edit_name); final EditText editName = (EditText) editView.findViewById(R.id.var_edit_name);
String name = editName.getText().toString(); String name = editName.getText().toString();
final EditText editValue = (EditText) editView.findViewById(R.id.var_edit_value); final EditText editValue = (EditText) editView.findViewById(R.id.var_edit_value);
String value = editValue.getText().toString(); String value = editValue.getText().toString();
final EditText editDescription = (EditText) editView.findViewById(R.id.var_edit_description); final EditText editDescription = (EditText) editView.findViewById(R.id.var_edit_description);
String description = editDescription.getText().toString(); String description = editDescription.getText().toString();
if (isValidName(name)) { if (isValidName(name)) {
boolean canBeSaved = false; boolean canBeSaved = false;
final T entityFromRegistry = mathRegistry.get(name); final T entityFromRegistry = mathRegistry.get(name);
if (entityFromRegistry == null) { if (entityFromRegistry == null) {
canBeSaved = true; canBeSaved = true;
} else if (editedInstance != null && entityFromRegistry.getId().equals(editedInstance.getId())) { } else if (editedInstance != null && entityFromRegistry.getId().equals(editedInstance.getId())) {
canBeSaved = true; canBeSaved = true;
} }
if (canBeSaved) { if (canBeSaved) {
final MathType.Result mathType = MathType.getType(name, 0, false); final MathType.Result mathType = MathType.getType(name, 0, false);
if (mathType.getMathType() == MathType.text || mathType.getMathType() == MathType.constant) { if (mathType.getMathType() == MathType.text || mathType.getMathType() == MathType.constant) {
if (StringUtils.isEmpty(value)) { if (StringUtils.isEmpty(value)) {
// value is empty => undefined variable // value is empty => undefined variable
varBuilder.setName(name); varBuilder.setName(name);
varBuilder.setDescription(description); varBuilder.setDescription(description);
varBuilder.setValue(null); varBuilder.setValue(null);
error = null; error = null;
} else { } else {
// value is not empty => must be a number // value is not empty => must be a number
boolean valid = CalculatorVarsFragment.isValidValue(value); boolean valid = CalculatorVarsFragment.isValidValue(value);
if (valid) { if (valid) {
varBuilder.setName(name); varBuilder.setName(name);
varBuilder.setDescription(description); varBuilder.setDescription(description);
varBuilder.setValue(value); varBuilder.setValue(value);
error = null; error = null;
} else { } else {
error = R.string.c_value_is_not_a_number; error = R.string.c_value_is_not_a_number;
} }
} }
} else { } else {
error = R.string.c_var_name_clashes; error = R.string.c_var_name_clashes;
} }
} else { } else {
error = R.string.c_var_already_exists; error = R.string.c_var_already_exists;
} }
} else { } else {
error = R.string.c_name_is_not_valid; error = R.string.c_name_is_not_valid;
} }
if (error != null) { if (error != null) {
Toast.makeText(fragment.getActivity(), fragment.getString(error), Toast.LENGTH_LONG).show(); CalculatorLocatorImpl.getInstance().getNotifier().showMessage(error, MessageType.error);
editorCreator.showEditor(fragment, editedInstance, name, value, description); } else {
} else { final T addedVar = mathRegistry.add(varBuilder);
final T addedVar = mathRegistry.add(varBuilder); mathRegistry.save();
if (fragment.isInCategory(addedVar)) {
if (editedInstance != null) {
fragment.removeFromAdapter(editedInstance);
}
fragment.addToAdapter(addedVar);
}
mathRegistry.save(); if (editedInstance == null) {
CalculatorLocatorImpl.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.constant_added, addedVar, source);
if (fragment.isInCategory(addedVar)) { } else {
fragment.sort(); CalculatorLocatorImpl.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.constant_changed, ChangeImpl.newInstance(editedInstance, addedVar), source);
} }
} }
} }
}
boolean isValidName(@Nullable String name) { boolean isValidName(@Nullable String name) {
boolean result = false; boolean result = false;

View File

@ -9,6 +9,7 @@ package org.solovyev.android.calculator.model;
import android.app.Application; import android.app.Application;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.res.Resources;
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;
@ -16,7 +17,6 @@ import org.simpleframework.xml.Serializer;
import org.simpleframework.xml.core.Persister; import org.simpleframework.xml.core.Persister;
import org.solovyev.android.calculator.CalculatorMathRegistry; import org.solovyev.android.calculator.CalculatorMathRegistry;
import org.solovyev.android.calculator.R; import org.solovyev.android.calculator.R;
import org.solovyev.android.calculator.about.TextHelper;
import org.solovyev.common.JBuilder; import org.solovyev.common.JBuilder;
import org.solovyev.common.math.MathEntity; import org.solovyev.common.math.MathEntity;
import org.solovyev.common.math.MathRegistry; import org.solovyev.common.math.MathRegistry;
@ -67,7 +67,13 @@ public abstract class AbstractAndroidMathRegistry<T extends MathEntity, P extend
stringName = prefix + substitute; stringName = prefix + substitute;
} }
return new TextHelper(context.getResources(), R.class.getPackage().getName()).getText(stringName); final Resources resources = context.getResources();
final int stringId = resources.getIdentifier(stringName, "string", R.class.getPackage().getName());
try {
return resources.getString(stringId);
} catch (Resources.NotFoundException e) {
return null;
}
} }
public synchronized void load() { public synchronized void load() {

View File

@ -398,7 +398,7 @@ public class CalculatorPlotFragment extends SherlockFragment implements Calculat
if ( calculatorEventData.isAfter(this.lastCalculatorEventData) ) { if ( calculatorEventData.isAfter(this.lastCalculatorEventData) ) {
this.lastCalculatorEventData = calculatorEventData; this.lastCalculatorEventData = calculatorEventData;
createInputFromDisplayState(((CalculatorDisplayChangeEventData) data).getNewState()); createInputFromDisplayState(((CalculatorDisplayChangeEventData) data).getNewValue());
uiHandler.post(new Runnable() { uiHandler.post(new Runnable() {
@Override @Override