android_calculator-4: Extend history functionality
This commit is contained in:
parent
8d6d6bc044
commit
38152fe80d
@ -28,6 +28,7 @@
|
||||
<string name="p_calc_round_result">true</string>
|
||||
|
||||
<string name="p_calc_vars">org.solovyev.android.calculator.CalculatorModel_vars</string>
|
||||
<string name="p_calc_history">org.solovyev.android.calculator.CalculatorModel_history</string>
|
||||
|
||||
<string name="p_calc_angle_units_key">org.solovyev.android.calculator.CalculatorActivity_angle_units</string>
|
||||
<string name="p_calc_angle_units">deg</string>
|
||||
|
@ -299,4 +299,7 @@ Check the \'Round result\' preference in application settings - it should be tur
|
||||
<string name="c_swipe_distance">Swipe distance for buttons</string>
|
||||
<string name="c_swipe_distance_summary">Sets swipe distance for buttons that support additional swipe actions</string>
|
||||
|
||||
<string name="c_comment">Comment</string>
|
||||
<string name="c_history_item_saved">Saved</string>
|
||||
|
||||
</resources>
|
||||
|
@ -1,27 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2011. Created by serso aka se.solovyev.
|
||||
* For more information, please, contact se.solovyev@gmail.com
|
||||
* or visit http://se.solovyev.org
|
||||
*/
|
||||
|
||||
package org.solovyev.android.calculator;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* User: serso
|
||||
* Date: 10/15/11
|
||||
* Time: 1:45 PM
|
||||
*/
|
||||
public class AbstractHistoryState {
|
||||
|
||||
@NotNull
|
||||
private final Date time = new Date();
|
||||
|
||||
@NotNull
|
||||
public Date getTime() {
|
||||
return time;
|
||||
}
|
||||
}
|
@ -26,6 +26,7 @@ import jscl.AngleUnit;
|
||||
import jscl.NumeralBase;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.solovyev.android.calculator.history.CalculatorHistoryState;
|
||||
import org.solovyev.android.calculator.math.MathType;
|
||||
import org.solovyev.android.calculator.model.CalculatorEngine;
|
||||
import org.solovyev.android.view.FontSizeAdjuster;
|
||||
|
@ -24,7 +24,7 @@ import org.solovyev.android.view.AutoResizeTextView;
|
||||
* Date: 9/17/11
|
||||
* Time: 10:58 PM
|
||||
*/
|
||||
public class CalculatorDisplay extends AutoResizeTextView {
|
||||
public class CalculatorDisplay extends AutoResizeTextView implements ICalculatorDisplay{
|
||||
|
||||
private boolean valid = true;
|
||||
|
||||
@ -52,10 +52,12 @@ public class CalculatorDisplay extends AutoResizeTextView {
|
||||
super(context, attrs, defStyle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid() {
|
||||
return valid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValid(boolean valid) {
|
||||
this.valid = valid;
|
||||
if (valid) {
|
||||
@ -63,19 +65,23 @@ public class CalculatorDisplay extends AutoResizeTextView {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public String getErrorMessage() {
|
||||
return errorMessage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setErrorMessage(@Nullable String errorMessage) {
|
||||
this.errorMessage = errorMessage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setJsclOperation(@NotNull JsclOperation jsclOperation) {
|
||||
this.jsclOperation = jsclOperation;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public JsclOperation getJsclOperation() {
|
||||
return jsclOperation;
|
||||
@ -111,12 +117,24 @@ public class CalculatorDisplay extends AutoResizeTextView {
|
||||
resizeText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setGenericResult(@Nullable Generic genericResult) {
|
||||
this.genericResult = genericResult;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Generic getGenericResult() {
|
||||
return genericResult;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSelection() {
|
||||
return this.getSelectionStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSelection(int selection) {
|
||||
// not supported by TextView
|
||||
}
|
||||
}
|
||||
|
@ -1,83 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2011. Created by serso aka se.solovyev.
|
||||
* For more information, please, contact se.solovyev@gmail.com
|
||||
* or visit http://se.solovyev.org
|
||||
*/
|
||||
|
||||
package org.solovyev.android.calculator;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.solovyev.common.utils.history.HistoryAction;
|
||||
import org.solovyev.common.utils.history.HistoryHelper;
|
||||
import org.solovyev.common.utils.history.SimpleHistoryHelper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* User: serso
|
||||
* Date: 10/9/11
|
||||
* Time: 6:35 PM
|
||||
*/
|
||||
public enum CalculatorHistory implements HistoryHelper<CalculatorHistoryState> {
|
||||
|
||||
instance;
|
||||
|
||||
private final HistoryHelper<CalculatorHistoryState> historyHelper = new SimpleHistoryHelper<CalculatorHistoryState>();
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return this.historyHelper.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CalculatorHistoryState getLastHistoryState() {
|
||||
return this.historyHelper.getLastHistoryState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUndoAvailable() {
|
||||
return historyHelper.isUndoAvailable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CalculatorHistoryState undo(@Nullable CalculatorHistoryState currentState) {
|
||||
return historyHelper.undo(currentState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRedoAvailable() {
|
||||
return historyHelper.isRedoAvailable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CalculatorHistoryState redo(@Nullable CalculatorHistoryState currentState) {
|
||||
return historyHelper.redo(currentState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActionAvailable(@NotNull HistoryAction historyAction) {
|
||||
return historyHelper.isActionAvailable(historyAction);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CalculatorHistoryState doAction(@NotNull HistoryAction historyAction, @Nullable CalculatorHistoryState currentState) {
|
||||
return historyHelper.doAction(historyAction, currentState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addState(@Nullable CalculatorHistoryState currentState) {
|
||||
historyHelper.addState(currentState);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<CalculatorHistoryState> getStates() {
|
||||
return historyHelper.getStates();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
this.historyHelper.clear();
|
||||
}
|
||||
}
|
@ -6,13 +6,20 @@
|
||||
|
||||
package org.solovyev.android.calculator;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.app.ListActivity;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.os.Bundle;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.view.*;
|
||||
import android.widget.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.solovyev.android.calculator.history.CalculatorHistory;
|
||||
import org.solovyev.android.calculator.history.CalculatorHistoryState;
|
||||
import org.solovyev.android.calculator.history.EditorHistoryState;
|
||||
import org.solovyev.android.calculator.jscl.JsclOperation;
|
||||
import org.solovyev.android.view.prefs.ResourceCache;
|
||||
import org.solovyev.common.utils.Filter;
|
||||
import org.solovyev.common.utils.FilterRule;
|
||||
import org.solovyev.common.utils.FilterRulesChain;
|
||||
@ -31,6 +38,9 @@ import java.util.List;
|
||||
*/
|
||||
public class CalculatorHistoryActivity extends ListActivity {
|
||||
|
||||
@NotNull
|
||||
private HistoryArrayAdapter adapter;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
@ -43,7 +53,8 @@ public class CalculatorHistoryActivity extends ListActivity {
|
||||
this.finish();
|
||||
}
|
||||
|
||||
setListAdapter(new HistoryArrayAdapter(this, R.layout.history, R.id.history_item, historyList));
|
||||
adapter = new HistoryArrayAdapter(this, R.layout.history, R.id.history_item, historyList);
|
||||
setListAdapter(adapter);
|
||||
|
||||
final ListView lv = getListView();
|
||||
lv.setTextFilterEnabled(true);
|
||||
@ -70,15 +81,62 @@ public class CalculatorHistoryActivity extends ListActivity {
|
||||
CalculatorHistoryActivity.this.finish();
|
||||
}
|
||||
});
|
||||
|
||||
lv.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
|
||||
@Override
|
||||
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
final CalculatorHistoryState historyState = (CalculatorHistoryState) parent.getItemAtPosition(position);
|
||||
|
||||
final Context context = CalculatorHistoryActivity.this;
|
||||
|
||||
final CharSequence[] items = {context.getText(R.string.c_save), context.getText(R.string.c_remove)};
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||
builder.setItems(items, new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int item) {
|
||||
if (item == 0) {
|
||||
if (!historyState.isSaved()) {
|
||||
historyState.setSaved(true);
|
||||
CalculatorHistory.instance.getSavedHistory().addState(historyState);
|
||||
CalculatorHistory.instance.save(context);
|
||||
CalculatorHistoryActivity.this.adapter.notifyDataSetChanged();
|
||||
Toast.makeText(context, "History item was successfully saved!", Toast.LENGTH_LONG).show();
|
||||
} else {
|
||||
Toast.makeText(context, "History item was already saved!", Toast.LENGTH_LONG).show();
|
||||
}
|
||||
} else if (item == 1) {
|
||||
if (historyState.isSaved()) {
|
||||
historyState.setSaved(false);
|
||||
CalculatorHistory.instance.save(context);
|
||||
CalculatorHistory.instance.getSavedHistory().clear();
|
||||
CalculatorHistory.instance.load(context, PreferenceManager.getDefaultSharedPreferences(context));
|
||||
CalculatorHistoryActivity.this.adapter.notifyDataSetChanged();
|
||||
Toast.makeText(context, "History item was removed!", Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
builder.create().show();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static List<CalculatorHistoryState> getHistoryList() {
|
||||
final List<CalculatorHistoryState> calculatorHistoryStates = new ArrayList<CalculatorHistoryState>(CalculatorHistory.instance.getStates());
|
||||
calculatorHistoryStates.addAll(CalculatorHistory.instance.getSavedHistory().getStates());
|
||||
|
||||
Collections.sort(calculatorHistoryStates, new Comparator<CalculatorHistoryState>() {
|
||||
@Override
|
||||
public int compare(CalculatorHistoryState state1, CalculatorHistoryState state2) {
|
||||
if ( state1.isSaved() == state2.isSaved() ) {
|
||||
return state2.getTime().compareTo(state1.getTime());
|
||||
} else if ( state1.isSaved() ) {
|
||||
return -1;
|
||||
} else if ( state2.isSaved() ) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
|
||||
@ -111,7 +169,21 @@ public class CalculatorHistoryActivity extends ListActivity {
|
||||
time.setText(new SimpleDateFormat().format(state.getTime()));
|
||||
|
||||
final TextView editor = (TextView) result.findViewById(R.id.history_item);
|
||||
editor.setText(state.getEditorState().getText() + getIdentitySign(state.getDisplayState().getJsclOperation()) + state.getDisplayState().getEditorHistoryState().getText());
|
||||
final StringBuilder historyText = new StringBuilder();
|
||||
historyText.append(state.getEditorState().getText());
|
||||
historyText.append(getIdentitySign(state.getDisplayState().getJsclOperation()));
|
||||
historyText.append(state.getDisplayState().getEditorState().getText());
|
||||
final String comment = state.getComment();
|
||||
if (!StringUtils.isEmpty(comment)) {
|
||||
historyText.append("\n");
|
||||
historyText.append(ResourceCache.instance.getCaption("c_comment")).append(": ");
|
||||
historyText.append(comment);
|
||||
}
|
||||
if ( state.isSaved() ) {
|
||||
historyText.append("\n");
|
||||
historyText.append(ResourceCache.instance.getCaption("c_history_item_saved"));
|
||||
}
|
||||
editor.setText(historyText);
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -147,6 +219,7 @@ public class CalculatorHistoryActivity extends ListActivity {
|
||||
|
||||
private void clearHistory() {
|
||||
CalculatorHistory.instance.clear();
|
||||
|
||||
Toast.makeText(this, R.string.c_history_is_empty, Toast.LENGTH_SHORT).show();
|
||||
this.finish();
|
||||
}
|
||||
|
@ -22,6 +22,9 @@ import jscl.math.Generic;
|
||||
import jscl.math.function.Constant;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.solovyev.android.calculator.history.CalculatorHistory;
|
||||
import org.solovyev.android.calculator.history.CalculatorHistoryState;
|
||||
import org.solovyev.android.calculator.history.TextViewEditorAdapter;
|
||||
import org.solovyev.android.calculator.jscl.JsclOperation;
|
||||
import org.solovyev.android.calculator.math.MathType;
|
||||
import org.solovyev.android.calculator.model.CalculatorEngine;
|
||||
@ -335,8 +338,8 @@ public enum CalculatorModel implements CursorControl, HistoryControl<CalculatorH
|
||||
public void setCurrentHistoryState(@NotNull CalculatorHistoryState editorHistoryState) {
|
||||
synchronized (CalculatorHistory.instance) {
|
||||
Log.d(this.getClass().getName(), "Saved history found: " + editorHistoryState);
|
||||
setValuesFromHistory(this.editor, editorHistoryState.getEditorState());
|
||||
setValuesFromHistory(this.display, editorHistoryState.getDisplayState());
|
||||
|
||||
editorHistoryState.setValuesFromHistory(new TextViewEditorAdapter(this.editor), this.display);
|
||||
|
||||
final String expression = this.editor.getText().toString();
|
||||
if ( !StringUtils.isEmpty(expression) ) {
|
||||
@ -350,37 +353,14 @@ public enum CalculatorModel implements CursorControl, HistoryControl<CalculatorH
|
||||
}
|
||||
}
|
||||
|
||||
private void setValuesFromHistory(@NotNull CalculatorDisplay display, CalculatorDisplayHistoryState editorHistoryState) {
|
||||
setValuesFromHistory(display, editorHistoryState.getEditorHistoryState());
|
||||
display.setValid(editorHistoryState.isValid());
|
||||
display.setErrorMessage(editorHistoryState.getErrorMessage());
|
||||
display.setJsclOperation(editorHistoryState.getJsclOperation());
|
||||
display.setGenericResult(editorHistoryState.getGenericResult());
|
||||
}
|
||||
|
||||
private void setValuesFromHistory(@NotNull TextView editText, EditorHistoryState editorHistoryState) {
|
||||
editText.setText(editorHistoryState.getText());
|
||||
if (editText instanceof EditText) {
|
||||
((EditText) editText).setSelection(editorHistoryState.getCursorPosition());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public CalculatorHistoryState getCurrentHistoryState() {
|
||||
synchronized (CalculatorHistory.instance) {
|
||||
return new CalculatorHistoryState(getEditorHistoryState(this.editor), getCalculatorDisplayHistoryState(this.display));
|
||||
return CalculatorHistoryState.newInstance(new TextViewEditorAdapter(this.editor), this.display);
|
||||
}
|
||||
}
|
||||
|
||||
private EditorHistoryState getEditorHistoryState(@NotNull TextView textView) {
|
||||
return EditorHistoryState.newInstance(textView);
|
||||
}
|
||||
|
||||
private CalculatorDisplayHistoryState getCalculatorDisplayHistoryState(@NotNull CalculatorDisplay display) {
|
||||
return CalculatorDisplayHistoryState.newInstance(display);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public CalculatorDisplay getDisplay() {
|
||||
return display;
|
||||
|
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2011. Created by serso aka se.solovyev.
|
||||
* For more information, please, contact se.solovyev@gmail.com
|
||||
* or visit http://se.solovyev.org
|
||||
*/
|
||||
|
||||
package org.solovyev.android.calculator;
|
||||
|
||||
import jscl.math.Generic;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.solovyev.android.calculator.history.Editor;
|
||||
import org.solovyev.android.calculator.jscl.JsclOperation;
|
||||
|
||||
/**
|
||||
* User: serso
|
||||
* Date: 12/17/11
|
||||
* Time: 9:45 PM
|
||||
*/
|
||||
public interface ICalculatorDisplay extends Editor{
|
||||
|
||||
boolean isValid();
|
||||
|
||||
void setValid(boolean valid);
|
||||
|
||||
@Nullable
|
||||
String getErrorMessage();
|
||||
|
||||
void setErrorMessage(@Nullable String errorMessage);
|
||||
|
||||
void setJsclOperation(@NotNull JsclOperation jsclOperation);
|
||||
|
||||
@NotNull
|
||||
JsclOperation getJsclOperation();
|
||||
|
||||
void setGenericResult(@Nullable Generic genericResult);
|
||||
|
||||
@Nullable
|
||||
Generic getGenericResult();
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2011. Created by serso aka se.solovyev.
|
||||
* For more information, please, contact se.solovyev@gmail.com
|
||||
* or visit http://se.solovyev.org
|
||||
*/
|
||||
|
||||
package org.solovyev.android.calculator.history;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.simpleframework.xml.Element;
|
||||
import org.simpleframework.xml.Transient;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* User: serso
|
||||
* Date: 10/15/11
|
||||
* Time: 1:45 PM
|
||||
*/
|
||||
public class AbstractHistoryState {
|
||||
|
||||
@Element
|
||||
@NotNull
|
||||
private Date time = new Date();
|
||||
|
||||
@Element(required = false)
|
||||
@Nullable
|
||||
private String comment;
|
||||
|
||||
@Transient
|
||||
private boolean saved;
|
||||
|
||||
@NotNull
|
||||
public Date getTime() {
|
||||
return time;
|
||||
}
|
||||
|
||||
public void setTime(@NotNull Date time) {
|
||||
this.time = time;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getComment() {
|
||||
return comment;
|
||||
}
|
||||
|
||||
public void setComment(@Nullable String comment) {
|
||||
this.comment = comment;
|
||||
}
|
||||
|
||||
public boolean isSaved() {
|
||||
return saved;
|
||||
}
|
||||
|
||||
public void setSaved(boolean saved) {
|
||||
this.saved = saved;
|
||||
}
|
||||
}
|
@ -3,11 +3,15 @@
|
||||
* For more information, please, contact se.solovyev@gmail.com
|
||||
*/
|
||||
|
||||
package org.solovyev.android.calculator;
|
||||
package org.solovyev.android.calculator.history;
|
||||
|
||||
import jscl.math.Generic;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.simpleframework.xml.Element;
|
||||
import org.simpleframework.xml.Root;
|
||||
import org.simpleframework.xml.Transient;
|
||||
import org.solovyev.android.calculator.ICalculatorDisplay;
|
||||
import org.solovyev.android.calculator.jscl.JsclOperation;
|
||||
|
||||
/**
|
||||
@ -15,30 +19,38 @@ import org.solovyev.android.calculator.jscl.JsclOperation;
|
||||
* Date: 9/17/11
|
||||
* Time: 11:05 PM
|
||||
*/
|
||||
|
||||
@Root
|
||||
public class CalculatorDisplayHistoryState {
|
||||
|
||||
@Transient
|
||||
private boolean valid = true;
|
||||
|
||||
@Transient
|
||||
@Nullable
|
||||
private String errorMessage = null;
|
||||
|
||||
@Element
|
||||
@NotNull
|
||||
private EditorHistoryState editorHistoryState;
|
||||
private EditorHistoryState editorState;
|
||||
|
||||
@Element
|
||||
@NotNull
|
||||
private JsclOperation jsclOperation;
|
||||
|
||||
@Transient
|
||||
@Nullable
|
||||
private Generic genericResult;
|
||||
|
||||
private CalculatorDisplayHistoryState() {
|
||||
// for xml
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static CalculatorDisplayHistoryState newInstance(@NotNull CalculatorDisplay display) {
|
||||
public static CalculatorDisplayHistoryState newInstance(@NotNull ICalculatorDisplay display) {
|
||||
final CalculatorDisplayHistoryState result = new CalculatorDisplayHistoryState();
|
||||
|
||||
result.editorHistoryState = EditorHistoryState.newInstance(display);
|
||||
result.editorState = EditorHistoryState.newInstance(display);
|
||||
result.valid = display.isValid();
|
||||
result.jsclOperation = display.getJsclOperation();
|
||||
result.genericResult = display.getGenericResult();
|
||||
@ -47,13 +59,22 @@ public class CalculatorDisplayHistoryState {
|
||||
return result;
|
||||
}
|
||||
|
||||
public void setValuesFromHistory(@NotNull ICalculatorDisplay display) {
|
||||
this.getEditorState().setValuesFromHistory(display);
|
||||
display.setValid(this.isValid());
|
||||
display.setErrorMessage(this.getErrorMessage());
|
||||
display.setJsclOperation(this.getJsclOperation());
|
||||
display.setGenericResult(this.getGenericResult());
|
||||
}
|
||||
|
||||
|
||||
public boolean isValid() {
|
||||
return valid;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public EditorHistoryState getEditorHistoryState() {
|
||||
return editorHistoryState;
|
||||
public EditorHistoryState getEditorState() {
|
||||
return editorState;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@ -71,6 +92,7 @@ public class CalculatorDisplayHistoryState {
|
||||
return genericResult;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
@ -78,9 +100,7 @@ public class CalculatorDisplayHistoryState {
|
||||
|
||||
CalculatorDisplayHistoryState that = (CalculatorDisplayHistoryState) o;
|
||||
|
||||
if (valid != that.valid) return false;
|
||||
if (!editorHistoryState.equals(that.editorHistoryState)) return false;
|
||||
if (errorMessage != null ? !errorMessage.equals(that.errorMessage) : that.errorMessage != null) return false;
|
||||
if (!editorState.equals(that.editorState)) return false;
|
||||
if (jsclOperation != that.jsclOperation) return false;
|
||||
|
||||
return true;
|
||||
@ -88,9 +108,7 @@ public class CalculatorDisplayHistoryState {
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = (valid ? 1 : 0);
|
||||
result = 31 * result + (errorMessage != null ? errorMessage.hashCode() : 0);
|
||||
result = 31 * result + editorHistoryState.hashCode();
|
||||
int result = editorState.hashCode();
|
||||
result = 31 * result + jsclOperation.hashCode();
|
||||
return result;
|
||||
}
|
||||
@ -100,7 +118,7 @@ public class CalculatorDisplayHistoryState {
|
||||
return "CalculatorDisplayHistoryState{" +
|
||||
"valid=" + valid +
|
||||
", errorMessage='" + errorMessage + '\'' +
|
||||
", editorHistoryState=" + editorHistoryState +
|
||||
", editorHistoryState=" + editorState +
|
||||
", jsclOperation=" + jsclOperation +
|
||||
'}';
|
||||
}
|
@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2011. Created by serso aka se.solovyev.
|
||||
* For more information, please, contact se.solovyev@gmail.com
|
||||
* or visit http://se.solovyev.org
|
||||
*/
|
||||
|
||||
package org.solovyev.android.calculator.history;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.preference.PreferenceManager;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.solovyev.android.calculator.R;
|
||||
import org.solovyev.common.utils.history.HistoryAction;
|
||||
import org.solovyev.common.utils.history.HistoryHelper;
|
||||
import org.solovyev.common.utils.history.SimpleHistoryHelper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* User: serso
|
||||
* Date: 10/9/11
|
||||
* Time: 6:35 PM
|
||||
*/
|
||||
public enum CalculatorHistory implements HistoryHelper<CalculatorHistoryState> {
|
||||
|
||||
instance;
|
||||
|
||||
@NotNull
|
||||
private final HistoryHelper<CalculatorHistoryState> history = new SimpleHistoryHelper<CalculatorHistoryState>();
|
||||
|
||||
@NotNull
|
||||
private final HistoryHelper<CalculatorHistoryState> savedHistory = new SimpleHistoryHelper<CalculatorHistoryState>();
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return this.history.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CalculatorHistoryState getLastHistoryState() {
|
||||
return this.history.getLastHistoryState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUndoAvailable() {
|
||||
return history.isUndoAvailable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CalculatorHistoryState undo(@Nullable CalculatorHistoryState currentState) {
|
||||
return history.undo(currentState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRedoAvailable() {
|
||||
return history.isRedoAvailable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CalculatorHistoryState redo(@Nullable CalculatorHistoryState currentState) {
|
||||
return history.redo(currentState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActionAvailable(@NotNull HistoryAction historyAction) {
|
||||
return history.isActionAvailable(historyAction);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CalculatorHistoryState doAction(@NotNull HistoryAction historyAction, @Nullable CalculatorHistoryState currentState) {
|
||||
return history.doAction(historyAction, currentState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addState(@Nullable CalculatorHistoryState currentState) {
|
||||
history.addState(currentState);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<CalculatorHistoryState> getStates() {
|
||||
return history.getStates();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
this.history.clear();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public HistoryHelper<CalculatorHistoryState> getSavedHistory() {
|
||||
return savedHistory;
|
||||
}
|
||||
|
||||
public void load(@Nullable Context context, @Nullable SharedPreferences preferences) {
|
||||
if (context != null && preferences != null) {
|
||||
final String value = preferences.getString(context.getString(R.string.p_calc_history), null);
|
||||
HistoryUtils.fromXml(value, this.savedHistory);
|
||||
}
|
||||
}
|
||||
|
||||
public void save(@NotNull Context context) {
|
||||
final SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
final SharedPreferences.Editor editor = settings.edit();
|
||||
|
||||
editor.putString(context.getString(R.string.p_calc_history), HistoryUtils.toXml(this.savedHistory));
|
||||
|
||||
editor.commit();
|
||||
}
|
||||
|
||||
}
|
@ -3,29 +3,46 @@
|
||||
* For more information, please, contact se.solovyev@gmail.com
|
||||
*/
|
||||
|
||||
package org.solovyev.android.calculator;
|
||||
package org.solovyev.android.calculator.history;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.simpleframework.xml.Element;
|
||||
import org.simpleframework.xml.Root;
|
||||
import org.solovyev.android.calculator.ICalculatorDisplay;
|
||||
|
||||
/**
|
||||
* User: serso
|
||||
* Date: 9/11/11
|
||||
* Time: 12:16 AM
|
||||
*/
|
||||
|
||||
@Root
|
||||
public class CalculatorHistoryState extends AbstractHistoryState {
|
||||
|
||||
@Element
|
||||
@NotNull
|
||||
private EditorHistoryState editorState;
|
||||
|
||||
@Element
|
||||
@NotNull
|
||||
private CalculatorDisplayHistoryState displayState;
|
||||
|
||||
public CalculatorHistoryState(@NotNull EditorHistoryState editorState,
|
||||
private CalculatorHistoryState() {
|
||||
// for xml
|
||||
}
|
||||
|
||||
private CalculatorHistoryState(@NotNull EditorHistoryState editorState,
|
||||
@NotNull CalculatorDisplayHistoryState displayState) {
|
||||
this.editorState = editorState;
|
||||
this.displayState = displayState;
|
||||
}
|
||||
|
||||
public static CalculatorHistoryState newInstance(@NotNull Editor editor, @NotNull ICalculatorDisplay display) {
|
||||
final EditorHistoryState editorHistoryState = EditorHistoryState.newInstance(editor);
|
||||
final CalculatorDisplayHistoryState displayHistoryState = CalculatorDisplayHistoryState.newInstance(display);
|
||||
return new CalculatorHistoryState(editorHistoryState, displayHistoryState);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public EditorHistoryState getEditorState() {
|
||||
return editorState;
|
||||
@ -71,4 +88,9 @@ public class CalculatorHistoryState extends AbstractHistoryState{
|
||||
result = 31 * result + displayState.hashCode();
|
||||
return result;
|
||||
}
|
||||
|
||||
public void setValuesFromHistory(@NotNull Editor editor, @NotNull ICalculatorDisplay display) {
|
||||
this.getEditorState().setValuesFromHistory(editor);
|
||||
this.getDisplayState().setValuesFromHistory(display);
|
||||
}
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2011. Created by serso aka se.solovyev.
|
||||
* For more information, please, contact se.solovyev@gmail.com
|
||||
* or visit http://se.solovyev.org
|
||||
*/
|
||||
|
||||
package org.solovyev.android.calculator.history;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* User: serso
|
||||
* Date: 12/17/11
|
||||
* Time: 9:37 PM
|
||||
*/
|
||||
public interface Editor {
|
||||
|
||||
@Nullable
|
||||
CharSequence getText();
|
||||
|
||||
void setText(@Nullable CharSequence text);
|
||||
|
||||
int getSelection();
|
||||
|
||||
void setSelection(int selection);
|
||||
|
||||
}
|
@ -3,33 +3,42 @@
|
||||
* For more information, please, contact se.solovyev@gmail.com
|
||||
*/
|
||||
|
||||
package org.solovyev.android.calculator;
|
||||
package org.solovyev.android.calculator.history;
|
||||
|
||||
import android.widget.TextView;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.simpleframework.xml.Element;
|
||||
import org.simpleframework.xml.Root;
|
||||
|
||||
@Root
|
||||
public class EditorHistoryState {
|
||||
|
||||
@Element
|
||||
private int cursorPosition;
|
||||
|
||||
@Element(required = false)
|
||||
@Nullable
|
||||
private String text;
|
||||
|
||||
private EditorHistoryState() {
|
||||
// for xml
|
||||
}
|
||||
|
||||
|
||||
@NotNull
|
||||
public static EditorHistoryState newInstance(@NotNull TextView textView) {
|
||||
public static EditorHistoryState newInstance(@NotNull Editor editor) {
|
||||
final EditorHistoryState result = new EditorHistoryState();
|
||||
|
||||
result.text = String.valueOf(textView.getText());
|
||||
result.cursorPosition = textView.getSelectionStart();
|
||||
result.text = String.valueOf(editor.getText());
|
||||
result.cursorPosition = editor.getSelection();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public void setValuesFromHistory(@NotNull Editor editor) {
|
||||
editor.setText(this.getText());
|
||||
editor.setSelection(this.getCursorPosition());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getText() {
|
||||
return text;
|
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2011. Created by serso aka se.solovyev.
|
||||
* For more information, please, contact se.solovyev@gmail.com
|
||||
* or visit http://se.solovyev.org
|
||||
*/
|
||||
|
||||
package org.solovyev.android.calculator.history;
|
||||
|
||||
import org.simpleframework.xml.ElementList;
|
||||
import org.simpleframework.xml.Root;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* User: serso
|
||||
* Date: 12/17/11
|
||||
* Time: 9:30 PM
|
||||
*/
|
||||
|
||||
@Root
|
||||
public class History {
|
||||
|
||||
@ElementList
|
||||
private List<CalculatorHistoryState> historyItems = new ArrayList<CalculatorHistoryState>();
|
||||
|
||||
public History() {
|
||||
}
|
||||
|
||||
public List<CalculatorHistoryState> getHistoryItems() {
|
||||
return historyItems;
|
||||
}
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2011. Created by serso aka se.solovyev.
|
||||
* For more information, please, contact se.solovyev@gmail.com
|
||||
* or visit http://se.solovyev.org
|
||||
*/
|
||||
|
||||
package org.solovyev.android.calculator.history;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.simpleframework.xml.Serializer;
|
||||
import org.simpleframework.xml.core.Persister;
|
||||
import org.solovyev.common.utils.history.HistoryHelper;
|
||||
|
||||
import java.io.StringWriter;
|
||||
|
||||
/**
|
||||
* User: serso
|
||||
* Date: 12/17/11
|
||||
* Time: 9:59 PM
|
||||
*/
|
||||
class HistoryUtils {
|
||||
|
||||
// not intended for instantiation
|
||||
private HistoryUtils() {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
public static void fromXml(@Nullable String xml, @NotNull HistoryHelper<CalculatorHistoryState> calculatorHistory) {
|
||||
if (xml != null) {
|
||||
final Serializer serializer = new Persister();
|
||||
try {
|
||||
final History history = serializer.read(History.class, xml);
|
||||
for (CalculatorHistoryState historyItem : history.getHistoryItems()) {
|
||||
calculatorHistory.addState(historyItem);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String toXml(@NotNull HistoryHelper<CalculatorHistoryState> calculatorHistory) {
|
||||
final History history = new History();
|
||||
for (CalculatorHistoryState historyState : calculatorHistory.getStates()) {
|
||||
if (historyState.isSaved()) {
|
||||
history.getHistoryItems().add(historyState);
|
||||
}
|
||||
}
|
||||
|
||||
final StringWriter xml = new StringWriter();
|
||||
final Serializer serializer = new Persister();
|
||||
try {
|
||||
serializer.write(history, xml);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return xml.toString();
|
||||
}
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2011. Created by serso aka se.solovyev.
|
||||
* For more information, please, contact se.solovyev@gmail.com
|
||||
* or visit http://se.solovyev.org
|
||||
*/
|
||||
|
||||
package org.solovyev.android.calculator.history;
|
||||
|
||||
import android.widget.EditText;
|
||||
import android.widget.TextView;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* User: serso
|
||||
* Date: 12/17/11
|
||||
* Time: 9:39 PM
|
||||
*/
|
||||
public class TextViewEditorAdapter implements Editor {
|
||||
|
||||
@NotNull
|
||||
private final TextView textView;
|
||||
|
||||
public TextViewEditorAdapter(@NotNull TextView textView) {
|
||||
this.textView = textView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getText() {
|
||||
return textView.getText().toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setText(@Nullable CharSequence text) {
|
||||
textView.setText(text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSelection() {
|
||||
return textView.getSelectionStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSelection(int selection) {
|
||||
if ( textView instanceof EditText ) {
|
||||
((EditText) textView).setSelection(selection);
|
||||
}
|
||||
}
|
||||
}
|
@ -18,6 +18,8 @@ import org.solovyev.android.calculator.model.TextProcessor;
|
||||
*/
|
||||
class FromJsclNumericTextProcessor implements TextProcessor<String, Generic> {
|
||||
|
||||
public static final FromJsclNumericTextProcessor instance = new FromJsclNumericTextProcessor();
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String process(@NotNull Generic numeric) throws CalculatorParseException {
|
||||
|
@ -16,66 +16,55 @@ import org.solovyev.android.calculator.model.TextProcessor;
|
||||
|
||||
public enum JsclOperation {
|
||||
|
||||
simplify(new FromJsclSimplifyTextProcessor()) {
|
||||
@NotNull
|
||||
@Override
|
||||
public String evaluate(@NotNull String expression) throws ParseException {
|
||||
return CalculatorEngine.instance.getEngine().simplify(expression);
|
||||
simplify,
|
||||
elementary,
|
||||
numeric;
|
||||
|
||||
JsclOperation() {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Generic evaluateGeneric(@NotNull String expression) throws ParseException {
|
||||
return CalculatorEngine.instance.getEngine().simplifyGeneric(expression);
|
||||
}
|
||||
},
|
||||
|
||||
elementary(DummyTextProcessor.instance) {
|
||||
@NotNull
|
||||
@Override
|
||||
public String evaluate(@NotNull String expression) throws ParseException {
|
||||
return CalculatorEngine.instance.getEngine().elementary(expression);
|
||||
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Generic evaluateGeneric(@NotNull String expression) throws ParseException {
|
||||
return CalculatorEngine.instance.getEngine().elementaryGeneric(expression);
|
||||
}
|
||||
},
|
||||
|
||||
numeric(new FromJsclNumericTextProcessor()) {
|
||||
@NotNull
|
||||
@Override
|
||||
public String evaluate(@NotNull String expression) throws ParseException {
|
||||
return CalculatorEngine.instance.getEngine().evaluate(expression);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Generic evaluateGeneric(@NotNull String expression) throws ParseException {
|
||||
return CalculatorEngine.instance.getEngine().evaluateGeneric(expression);
|
||||
}
|
||||
};
|
||||
|
||||
@NotNull
|
||||
private final TextProcessor<String, Generic> fromProcessor;
|
||||
|
||||
JsclOperation(@NotNull TextProcessor<String, Generic> fromProcessor) {
|
||||
this.fromProcessor = fromProcessor;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public TextProcessor<String, Generic> getFromProcessor() {
|
||||
return fromProcessor;
|
||||
switch (this) {
|
||||
case simplify:
|
||||
return FromJsclSimplifyTextProcessor.instance;
|
||||
case elementary:
|
||||
return DummyTextProcessor.instance;
|
||||
case numeric:
|
||||
return FromJsclNumericTextProcessor.instance;
|
||||
default:
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public abstract String evaluate(@NotNull String expression) throws ParseException;
|
||||
public final String evaluate(@NotNull String expression) throws ParseException {
|
||||
switch (this) {
|
||||
case simplify:
|
||||
return CalculatorEngine.instance.getEngine().simplify(expression);
|
||||
case elementary:
|
||||
return CalculatorEngine.instance.getEngine().elementary(expression);
|
||||
case numeric:
|
||||
return CalculatorEngine.instance.getEngine().evaluate(expression);
|
||||
default:
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public abstract Generic evaluateGeneric(@NotNull String expression) throws ParseException;
|
||||
public final Generic evaluateGeneric(@NotNull String expression) throws ParseException {
|
||||
switch (this) {
|
||||
case simplify:
|
||||
return CalculatorEngine.instance.getEngine().simplifyGeneric(expression);
|
||||
case elementary:
|
||||
return CalculatorEngine.instance.getEngine().elementaryGeneric(expression);
|
||||
case numeric:
|
||||
return CalculatorEngine.instance.getEngine().evaluateGeneric(expression);
|
||||
default:
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ import org.solovyev.common.math.MathRegistry;
|
||||
*/
|
||||
public interface AndroidVarsRegistry extends MathRegistry<Var>{
|
||||
|
||||
void init(@Nullable Context context, @Nullable SharedPreferences preferences);
|
||||
void load(@Nullable Context context, @Nullable SharedPreferences preferences);
|
||||
|
||||
void save(@NotNull Context context);
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ class AndroidVarsRegistryImpl implements AndroidVarsRegistry {
|
||||
this.mathRegistry = mathRegistry;
|
||||
}
|
||||
|
||||
public synchronized void init(@Nullable Context context, @Nullable SharedPreferences preferences) {
|
||||
public synchronized void load(@Nullable Context context, @Nullable SharedPreferences preferences) {
|
||||
|
||||
if (context != null && preferences != null) {
|
||||
final String value = preferences.getString(context.getString(R.string.p_calc_vars), null);
|
||||
|
@ -283,7 +283,7 @@ public enum CalculatorEngine {
|
||||
}
|
||||
}
|
||||
|
||||
varsRegister.init(context, preferences);
|
||||
varsRegister.load(context, preferences);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -15,6 +15,8 @@ import java.util.List;
|
||||
*/
|
||||
public class FromJsclSimplifyTextProcessor implements TextProcessor<String, Generic> {
|
||||
|
||||
public static final FromJsclSimplifyTextProcessor instance = new FromJsclSimplifyTextProcessor();
|
||||
|
||||
public FromJsclSimplifyTextProcessor() {
|
||||
}
|
||||
|
||||
|
29
src/main/java/org/solovyev/common/SameEqualizer.java
Normal file
29
src/main/java/org/solovyev/common/SameEqualizer.java
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2011. Created by serso aka se.solovyev.
|
||||
* For more information, please, contact se.solovyev@gmail.com
|
||||
* or visit http://se.solovyev.org
|
||||
*/
|
||||
|
||||
package org.solovyev.common;
|
||||
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.solovyev.common.utils.Equalizer;
|
||||
|
||||
/**
|
||||
* User: serso
|
||||
* Date: 12/17/11
|
||||
* Time: 11:11 PM
|
||||
*/
|
||||
public enum SameEqualizer implements Equalizer {
|
||||
|
||||
instance;
|
||||
|
||||
private SameEqualizer() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object first, @Nullable Object second) {
|
||||
return first == second;
|
||||
}
|
||||
}
|
@ -0,0 +1,306 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2011. Created by serso aka se.solovyev.
|
||||
* For more information, please, contact se.solovyev@gmail.com
|
||||
* or visit http://se.solovyev.org
|
||||
*/
|
||||
|
||||
package org.solovyev.android.calculator.history;
|
||||
|
||||
import jscl.math.Generic;
|
||||
import junit.framework.Assert;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.junit.Test;
|
||||
import org.solovyev.android.calculator.ICalculatorDisplay;
|
||||
import org.solovyev.android.calculator.jscl.JsclOperation;
|
||||
import org.solovyev.common.utils.CollectionEqualizer;
|
||||
import org.solovyev.common.utils.EqualsTool;
|
||||
import org.solovyev.common.utils.history.HistoryHelper;
|
||||
import org.solovyev.common.utils.history.SimpleHistoryHelper;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* User: serso
|
||||
* Date: 12/17/11
|
||||
* Time: 10:01 PM
|
||||
*/
|
||||
public class HistoryUtilsTest {
|
||||
|
||||
@Test
|
||||
public void testFromXml() throws Exception {
|
||||
|
||||
}
|
||||
|
||||
private static final String emptyHistory = "<history>\n" +
|
||||
" <historyItems class=\"java.util.ArrayList\"/>\n" +
|
||||
"</history>";
|
||||
|
||||
private static final String toXml1 = "<history>\n" +
|
||||
" <historyItems class=\"java.util.ArrayList\">\n" +
|
||||
" <calculatorHistoryState>\n" +
|
||||
" <time>1970-01-02 06:46:40.0 MSK</time>\n" +
|
||||
" <editorState>\n" +
|
||||
" <cursorPosition>3</cursorPosition>\n" +
|
||||
" <text>1+1</text>\n" +
|
||||
" </editorState>\n" +
|
||||
" <displayState>\n" +
|
||||
" <editorState>\n" +
|
||||
" <cursorPosition>1</cursorPosition>\n" +
|
||||
" <text>Error</text>\n" +
|
||||
" </editorState>\n" +
|
||||
" <jsclOperation>simplify</jsclOperation>\n" +
|
||||
" </displayState>\n" +
|
||||
" </calculatorHistoryState>\n" +
|
||||
" </historyItems>\n" +
|
||||
"</history>";
|
||||
|
||||
private static final String toXml2 = "<history>\n" +
|
||||
" <historyItems class=\"java.util.ArrayList\">\n" +
|
||||
" <calculatorHistoryState>\n" +
|
||||
" <time>1970-01-02 06:46:40.0 MSK</time>\n" +
|
||||
" <editorState>\n" +
|
||||
" <cursorPosition>3</cursorPosition>\n" +
|
||||
" <text>1+1</text>\n" +
|
||||
" </editorState>\n" +
|
||||
" <displayState>\n" +
|
||||
" <editorState>\n" +
|
||||
" <cursorPosition>1</cursorPosition>\n" +
|
||||
" <text>Error</text>\n" +
|
||||
" </editorState>\n" +
|
||||
" <jsclOperation>simplify</jsclOperation>\n" +
|
||||
" </displayState>\n" +
|
||||
" </calculatorHistoryState>\n" +
|
||||
" <calculatorHistoryState>\n" +
|
||||
" <time>1970-01-02 06:46:40.0 MSK</time>\n" +
|
||||
" <editorState>\n" +
|
||||
" <cursorPosition>2</cursorPosition>\n" +
|
||||
" <text>5/6</text>\n" +
|
||||
" </editorState>\n" +
|
||||
" <displayState>\n" +
|
||||
" <editorState>\n" +
|
||||
" <cursorPosition>3</cursorPosition>\n" +
|
||||
" <text>5/6</text>\n" +
|
||||
" </editorState>\n" +
|
||||
" <jsclOperation>numeric</jsclOperation>\n" +
|
||||
" </displayState>\n" +
|
||||
" </calculatorHistoryState>\n" +
|
||||
" <calculatorHistoryState>\n" +
|
||||
" <time>1970-01-02 06:46:40.0 MSK</time>\n" +
|
||||
" <editorState>\n" +
|
||||
" <cursorPosition>1</cursorPosition>\n" +
|
||||
" <text>null</text>\n" +
|
||||
" </editorState>\n" +
|
||||
" <displayState>\n" +
|
||||
" <editorState>\n" +
|
||||
" <cursorPosition>1</cursorPosition>\n" +
|
||||
" <text>Error</text>\n" +
|
||||
" </editorState>\n" +
|
||||
" <jsclOperation>elementary</jsclOperation>\n" +
|
||||
" </displayState>\n" +
|
||||
" </calculatorHistoryState>\n" +
|
||||
" <calculatorHistoryState>\n" +
|
||||
" <time>1970-01-02 06:46:40.0 MSK</time>\n" +
|
||||
" <editorState>\n" +
|
||||
" <cursorPosition>0</cursorPosition>\n" +
|
||||
" <text>4+5/35sin(41)+dfdsfsdfs</text>\n" +
|
||||
" </editorState>\n" +
|
||||
" <displayState>\n" +
|
||||
" <editorState>\n" +
|
||||
" <cursorPosition>1</cursorPosition>\n" +
|
||||
" <text>4+5/35sin(41)+dfdsfsdfs</text>\n" +
|
||||
" </editorState>\n" +
|
||||
" <jsclOperation>numeric</jsclOperation>\n" +
|
||||
" </displayState>\n" +
|
||||
" </calculatorHistoryState>\n" +
|
||||
" </historyItems>\n" +
|
||||
"</history>";
|
||||
|
||||
@Test
|
||||
public void testToXml() throws Exception {
|
||||
final Date date = new Date(100000000);
|
||||
|
||||
HistoryHelper<CalculatorHistoryState> history = new SimpleHistoryHelper<CalculatorHistoryState>();
|
||||
|
||||
ICalculatorDisplay calculatorDisplay = new TestCalculatorDisplay();
|
||||
calculatorDisplay.setErrorMessage("error_msg1");
|
||||
calculatorDisplay.setText("Error");
|
||||
calculatorDisplay.setSelection(1);
|
||||
calculatorDisplay.setJsclOperation(JsclOperation.simplify);
|
||||
|
||||
Editor calculatorEditor = new TestEditor();
|
||||
calculatorEditor.setSelection(3);
|
||||
calculatorEditor.setText("1+1");
|
||||
|
||||
CalculatorHistoryState state = CalculatorHistoryState.newInstance(calculatorEditor, calculatorDisplay);
|
||||
state.setTime(date);
|
||||
history.addState(state);
|
||||
|
||||
Assert.assertEquals(emptyHistory, HistoryUtils.toXml(history));
|
||||
|
||||
|
||||
state.setSaved(true);
|
||||
|
||||
Assert.assertEquals(toXml1, HistoryUtils.toXml(history));
|
||||
|
||||
calculatorDisplay = new TestCalculatorDisplay();
|
||||
calculatorDisplay.setErrorMessage(null);
|
||||
calculatorDisplay.setText("5/6");
|
||||
calculatorDisplay.setSelection(3);
|
||||
calculatorDisplay.setJsclOperation(JsclOperation.numeric);
|
||||
|
||||
calculatorEditor = new TestEditor();
|
||||
calculatorEditor.setSelection(2);
|
||||
calculatorEditor.setText("5/6");
|
||||
|
||||
state = CalculatorHistoryState.newInstance(calculatorEditor, calculatorDisplay);
|
||||
state.setSaved(true);
|
||||
state.setTime(date);
|
||||
history.addState(state);
|
||||
|
||||
calculatorDisplay = new TestCalculatorDisplay();
|
||||
calculatorDisplay.setErrorMessage("error_msg2");
|
||||
calculatorDisplay.setText("Error");
|
||||
calculatorDisplay.setSelection(1);
|
||||
calculatorDisplay.setJsclOperation(JsclOperation.elementary);
|
||||
|
||||
calculatorEditor = new TestEditor();
|
||||
calculatorEditor.setSelection(1);
|
||||
calculatorEditor.setText(null);
|
||||
|
||||
state = CalculatorHistoryState.newInstance(calculatorEditor, calculatorDisplay);
|
||||
state.setSaved(true);
|
||||
state.setTime(date);
|
||||
history.addState(state);
|
||||
|
||||
calculatorDisplay = new TestCalculatorDisplay();
|
||||
calculatorDisplay.setErrorMessage(null);
|
||||
calculatorDisplay.setText("4+5/35sin(41)+dfdsfsdfs");
|
||||
calculatorDisplay.setSelection(1);
|
||||
calculatorDisplay.setJsclOperation(JsclOperation.numeric);
|
||||
|
||||
calculatorEditor = new TestEditor();
|
||||
calculatorEditor.setSelection(0);
|
||||
calculatorEditor.setText("4+5/35sin(41)+dfdsfsdfs");
|
||||
|
||||
state = CalculatorHistoryState.newInstance(calculatorEditor, calculatorDisplay);
|
||||
state.setSaved(true);
|
||||
state.setTime(date);
|
||||
history.addState(state);
|
||||
|
||||
String xml = HistoryUtils.toXml(history);
|
||||
Assert.assertEquals(toXml2, xml);
|
||||
|
||||
final HistoryHelper<CalculatorHistoryState> historyFromXml = new SimpleHistoryHelper<CalculatorHistoryState>();
|
||||
HistoryUtils.fromXml(xml, historyFromXml);
|
||||
|
||||
Assert.assertEquals(history.getStates().size(), historyFromXml.getStates().size());
|
||||
|
||||
Assert.assertTrue(EqualsTool.areEqual(history.getStates(), historyFromXml.getStates(), new CollectionEqualizer<CalculatorHistoryState>(null)));
|
||||
}
|
||||
|
||||
|
||||
private static class TestCalculatorDisplay implements ICalculatorDisplay {
|
||||
|
||||
@NotNull
|
||||
private final TestEditor testEditor = new TestEditor();
|
||||
|
||||
private boolean valid;
|
||||
|
||||
private String errorMessage;
|
||||
|
||||
private JsclOperation operation;
|
||||
|
||||
private Generic genericResult;
|
||||
|
||||
@Override
|
||||
public boolean isValid() {
|
||||
return this.valid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValid(boolean valid) {
|
||||
this.valid = valid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getErrorMessage() {
|
||||
return this.errorMessage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setErrorMessage(@Nullable String errorMessage) {
|
||||
this.errorMessage = errorMessage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setJsclOperation(@NotNull JsclOperation jsclOperation) {
|
||||
this.operation = jsclOperation;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public JsclOperation getJsclOperation() {
|
||||
return this.operation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setGenericResult(@Nullable Generic genericResult) {
|
||||
this.genericResult = genericResult;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Generic getGenericResult() {
|
||||
return this.genericResult;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getText() {
|
||||
return this.testEditor.getText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setText(@Nullable CharSequence text) {
|
||||
this.testEditor.setText(text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSelection() {
|
||||
return this.testEditor.getSelection();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSelection(int selection) {
|
||||
this.testEditor.setSelection(selection);
|
||||
}
|
||||
}
|
||||
|
||||
private static class TestEditor implements Editor {
|
||||
|
||||
@Nullable
|
||||
private CharSequence text;
|
||||
|
||||
private int selection;
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public CharSequence getText() {
|
||||
return this.text;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setText(@Nullable CharSequence text) {
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSelection() {
|
||||
return this.selection;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSelection(int selection) {
|
||||
this.selection = selection;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user