android_calculator-4: Extend history functionality

This commit is contained in:
Sergey Solovyev 2011-12-18 02:16:30 +04:00
parent 38152fe80d
commit 9d785e4b1e
9 changed files with 138 additions and 43 deletions

View File

@ -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.CalculatorHistory;
import org.solovyev.android.calculator.history.CalculatorHistoryState;
import org.solovyev.android.calculator.math.MathType;
import org.solovyev.android.calculator.model.CalculatorEngine;
@ -90,6 +91,7 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster, Sh
vibrator = (Vibrator) this.getSystemService(VIBRATOR_SERVICE);
CalculatorHistory.instance.load(this, preferences);
calculatorModel = CalculatorModel.instance.init(this, preferences, CalculatorEngine.instance);
dpclRegister.clear();

View File

@ -38,6 +38,21 @@ import java.util.List;
*/
public class CalculatorHistoryActivity extends ListActivity {
private static final Comparator<CalculatorHistoryState> COMPARATOR = 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;
}
};
@NotNull
private HistoryArrayAdapter adapter;
@ -84,7 +99,7 @@ public class CalculatorHistoryActivity extends ListActivity {
lv.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
public boolean onItemLongClick(AdapterView<?> parent, View view, final int position, long id) {
final CalculatorHistoryState historyState = (CalculatorHistoryState) parent.getItemAtPosition(position);
final Context context = CalculatorHistoryActivity.this;
@ -96,23 +111,23 @@ public class CalculatorHistoryActivity extends ListActivity {
public void onClick(DialogInterface dialog, int item) {
if (item == 0) {
if (!historyState.isSaved()) {
historyState.setSaved(true);
CalculatorHistory.instance.getSavedHistory().addState(historyState);
final CalculatorHistoryState savedHistoryItem = CalculatorHistory.instance.addSavedState(historyState);
CalculatorHistory.instance.save(context);
adapter.add(savedHistoryItem);
adapter.sort(COMPARATOR);
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) {
adapter.remove(historyState);
adapter.sort(COMPARATOR);
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();
CalculatorHistory.instance.removeSavedHistory(historyState, context, PreferenceManager.getDefaultSharedPreferences(context));
Toast.makeText(context, "History item was removed!", Toast.LENGTH_LONG).show();
}
CalculatorHistoryActivity.this.adapter.notifyDataSetChanged();
}
}
});
@ -124,21 +139,9 @@ public class CalculatorHistoryActivity extends ListActivity {
private static List<CalculatorHistoryState> getHistoryList() {
final List<CalculatorHistoryState> calculatorHistoryStates = new ArrayList<CalculatorHistoryState>(CalculatorHistory.instance.getStates());
calculatorHistoryStates.addAll(CalculatorHistory.instance.getSavedHistory().getStates());
calculatorHistoryStates.addAll(CalculatorHistory.instance.getSavedHistory());
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;
}
});
Collections.sort(calculatorHistoryStates, COMPARATOR);
final FilterRulesChain<CalculatorHistoryState> filterRulesChain = new FilterRulesChain<CalculatorHistoryState>();
filterRulesChain.addFilterRule(new FilterRule<CalculatorHistoryState>() {
@ -218,9 +221,18 @@ public class CalculatorHistoryActivity extends ListActivity {
}
private void clearHistory() {
final List<CalculatorHistoryState> historyStates = new ArrayList<CalculatorHistoryState>(CalculatorHistory.instance.getStates());
CalculatorHistory.instance.clear();
for (CalculatorHistoryState historyState : historyStates) {
adapter.remove(historyState);
}
Toast.makeText(this, R.string.c_history_is_empty, Toast.LENGTH_SHORT).show();
this.finish();
if (adapter.getCount() > 0) {
adapter.sort(COMPARATOR);
adapter.notifyDataSetChanged();
} else {
Toast.makeText(this, R.string.c_history_is_empty, Toast.LENGTH_SHORT).show();
this.finish();
}
}
}

View File

@ -18,7 +18,7 @@ import java.util.Date;
* Date: 10/15/11
* Time: 1:45 PM
*/
public class AbstractHistoryState {
public class AbstractHistoryState implements Cloneable{
@Element
@NotNull
@ -56,4 +56,18 @@ public class AbstractHistoryState {
public void setSaved(boolean saved) {
this.saved = saved;
}
@Override
protected AbstractHistoryState clone() {
AbstractHistoryState clone;
try {
clone = (AbstractHistoryState)super.clone();
clone.time = new Date(this.time.getTime());
} catch (CloneNotSupportedException e) {
throw new UnsupportedOperationException(e);
}
return clone;
}
}

View File

@ -21,7 +21,7 @@ import org.solovyev.android.calculator.jscl.JsclOperation;
*/
@Root
public class CalculatorDisplayHistoryState {
public class CalculatorDisplayHistoryState implements Cloneable {
@Transient
private boolean valid = true;
@ -122,4 +122,17 @@ public class CalculatorDisplayHistoryState {
", jsclOperation=" + jsclOperation +
'}';
}
@Override
protected CalculatorDisplayHistoryState clone() {
try {
final CalculatorDisplayHistoryState clone = (CalculatorDisplayHistoryState) super.clone();
clone.editorState = this.editorState.clone();
return clone;
} catch (CloneNotSupportedException e) {
throw new RuntimeException(e);
}
}
}

View File

@ -16,6 +16,8 @@ import org.solovyev.common.utils.history.HistoryAction;
import org.solovyev.common.utils.history.HistoryHelper;
import org.solovyev.common.utils.history.SimpleHistoryHelper;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
@ -31,7 +33,7 @@ public enum CalculatorHistory implements HistoryHelper<CalculatorHistoryState> {
private final HistoryHelper<CalculatorHistoryState> history = new SimpleHistoryHelper<CalculatorHistoryState>();
@NotNull
private final HistoryHelper<CalculatorHistoryState> savedHistory = new SimpleHistoryHelper<CalculatorHistoryState>();
private final List<CalculatorHistoryState> savedHistory = new ArrayList<CalculatorHistoryState> ();
@Override
public boolean isEmpty() {
@ -89,15 +91,13 @@ public enum CalculatorHistory implements HistoryHelper<CalculatorHistoryState> {
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);
for (CalculatorHistoryState historyState : savedHistory) {
historyState.setSaved(true);
}
}
}
@ -110,4 +110,31 @@ public enum CalculatorHistory implements HistoryHelper<CalculatorHistoryState> {
editor.commit();
}
@NotNull
public List<CalculatorHistoryState> getSavedHistory() {
return Collections.unmodifiableList(savedHistory);
}
@NotNull
public CalculatorHistoryState addSavedState(@NotNull CalculatorHistoryState historyState) {
if (historyState.isSaved()) {
return historyState;
} else {
final CalculatorHistoryState savedState = historyState.clone();
savedState.setSaved(true);
savedHistory.add(savedState);
return savedState;
}
}
public void removeSavedHistory(@NotNull CalculatorHistoryState historyState, @NotNull Context context, @NotNull SharedPreferences preferences) {
historyState.setSaved(false);
save(context);
this.savedHistory.clear();
load(context, preferences);
}
}

View File

@ -76,6 +76,7 @@ public class CalculatorHistoryState extends AbstractHistoryState {
CalculatorHistoryState that = (CalculatorHistoryState) o;
if (this.isSaved() != that.isSaved()) return false;
if (!displayState.equals(that.displayState)) return false;
if (!editorState.equals(that.editorState)) return false;
@ -84,7 +85,8 @@ public class CalculatorHistoryState extends AbstractHistoryState {
@Override
public int hashCode() {
int result = editorState.hashCode();
int result = Boolean.valueOf(isSaved()).hashCode();
result = 31 * result + editorState.hashCode();
result = 31 * result + displayState.hashCode();
return result;
}
@ -93,4 +95,14 @@ public class CalculatorHistoryState extends AbstractHistoryState {
this.getEditorState().setValuesFromHistory(editor);
this.getDisplayState().setValuesFromHistory(display);
}
@Override
protected CalculatorHistoryState clone() {
final CalculatorHistoryState clone = (CalculatorHistoryState)super.clone();
clone.editorState = this.editorState.clone();
clone.displayState = this.displayState.clone();
return clone;
}
}

View File

@ -11,7 +11,7 @@ import org.simpleframework.xml.Element;
import org.simpleframework.xml.Root;
@Root
public class EditorHistoryState {
public class EditorHistoryState implements Cloneable{
@Element
private int cursorPosition;
@ -75,4 +75,13 @@ public class EditorHistoryState {
", text='" + text + '\'' +
'}';
}
@Override
protected EditorHistoryState clone() {
try {
return (EditorHistoryState)super.clone();
} catch (CloneNotSupportedException e) {
throw new UnsupportedOperationException(e);
}
}
}

View File

@ -10,9 +10,9 @@ 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;
import java.util.List;
/**
* User: serso
@ -26,13 +26,13 @@ class HistoryUtils {
throw new AssertionError();
}
public static void fromXml(@Nullable String xml, @NotNull HistoryHelper<CalculatorHistoryState> calculatorHistory) {
public static void fromXml(@Nullable String xml, @NotNull List<CalculatorHistoryState> historyItems) {
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);
historyItems.add(historyItem);
}
} catch (Exception e) {
throw new RuntimeException(e);
@ -41,9 +41,9 @@ class HistoryUtils {
}
@NotNull
public static String toXml(@NotNull HistoryHelper<CalculatorHistoryState> calculatorHistory) {
public static String toXml(@NotNull List<CalculatorHistoryState> historyItems) {
final History history = new History();
for (CalculatorHistoryState historyState : calculatorHistory.getStates()) {
for (CalculatorHistoryState historyState : historyItems) {
if (historyState.isSaved()) {
history.getHistoryItems().add(historyState);
}

View File

@ -18,7 +18,9 @@ import org.solovyev.common.utils.EqualsTool;
import org.solovyev.common.utils.history.HistoryHelper;
import org.solovyev.common.utils.history.SimpleHistoryHelper;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* User: serso
@ -136,12 +138,12 @@ public class HistoryUtilsTest {
state.setTime(date);
history.addState(state);
Assert.assertEquals(emptyHistory, HistoryUtils.toXml(history));
Assert.assertEquals(emptyHistory, HistoryUtils.toXml(history.getStates()));
state.setSaved(true);
Assert.assertEquals(toXml1, HistoryUtils.toXml(history));
Assert.assertEquals(toXml1, HistoryUtils.toXml(history.getStates()));
calculatorDisplay = new TestCalculatorDisplay();
calculatorDisplay.setErrorMessage(null);
@ -188,11 +190,15 @@ public class HistoryUtilsTest {
state.setTime(date);
history.addState(state);
String xml = HistoryUtils.toXml(history);
String xml = HistoryUtils.toXml(history.getStates());
Assert.assertEquals(toXml2, xml);
final List<CalculatorHistoryState> fromXml = new ArrayList<CalculatorHistoryState>();
final HistoryHelper<CalculatorHistoryState> historyFromXml = new SimpleHistoryHelper<CalculatorHistoryState>();
HistoryUtils.fromXml(xml, historyFromXml);
HistoryUtils.fromXml(xml, fromXml);
for (CalculatorHistoryState historyState : fromXml) {
historyFromXml.addState(historyState);
}
Assert.assertEquals(history.getStates().size(), historyFromXml.getStates().size());