From a57d4aab57ffb7c449e6fb9118c3d965272c9de0 Mon Sep 17 00:00:00 2001 From: serso Date: Mon, 11 Jan 2016 20:57:19 +0100 Subject: [PATCH] History refactor --- .../android/calculator/AndroidCalculator.java | 18 -- .../org/solovyev/android/calculator/App.java | 5 + .../solovyev/android/calculator/BaseUi.java | 15 +- .../calculator/CalculatorActivity.java | 14 +- .../android/calculator/CalculatorImpl.java | 30 +-- .../solovyev/android/calculator/Display.java | 4 +- .../android/calculator/DisplayState.java | 26 +- .../solovyev/android/calculator/Editor.java | 2 +- .../android/calculator/EditorState.java | 28 ++ .../android/calculator/Preferences.java | 6 - .../history/BaseHistoryFragment.java | 249 +++--------------- .../calculator/history/CalculatorHistory.java | 50 ++-- .../history/HistoryArrayAdapter.java | 64 +---- .../history/HistoryDragProcessor.java | 2 +- .../calculator/history/HistoryList.java | 16 +- .../calculator/history/HistoryState.java | 19 +- .../history/OldBaseHistoryState.java | 28 +- .../history/OldDisplayHistoryState.java | 54 +--- .../history/OldEditorHistoryState.java | 20 +- .../calculator/history/OldHistory.java | 2 +- .../calculator/history/OldHistoryState.java | 24 +- .../solovyev/android/io/BaseFileLoader.java | 48 ++++ .../solovyev/android/io/BaseFileSaver.java | 39 +++ .../org/solovyev/android/io/FileSaver.java | 28 ++ .../main/java/org/solovyev/android/io/Io.java | 22 ++ app/src/main/res/layout/history_item.xml | 40 +-- app/src/main/res/menu/history_menu.xml | 40 --- .../history/CalculatorHistoryTest.java | 8 +- .../calculator/history/HistoryUtilsTest.java | 89 ------- 29 files changed, 320 insertions(+), 670 deletions(-) create mode 100644 app/src/main/java/org/solovyev/android/io/BaseFileLoader.java create mode 100644 app/src/main/java/org/solovyev/android/io/BaseFileSaver.java create mode 100644 app/src/main/java/org/solovyev/android/io/FileSaver.java create mode 100644 app/src/main/java/org/solovyev/android/io/Io.java delete mode 100644 app/src/main/res/menu/history_menu.xml diff --git a/app/src/main/java/org/solovyev/android/calculator/AndroidCalculator.java b/app/src/main/java/org/solovyev/android/calculator/AndroidCalculator.java index dd03e5ad..76bdf00a 100644 --- a/app/src/main/java/org/solovyev/android/calculator/AndroidCalculator.java +++ b/app/src/main/java/org/solovyev/android/calculator/AndroidCalculator.java @@ -27,9 +27,7 @@ import android.content.SharedPreferences; import android.preference.PreferenceManager; import jscl.NumeralBase; import jscl.math.Generic; -import org.solovyev.android.calculator.history.OldHistoryState; import org.solovyev.android.calculator.jscl.JsclOperation; -import org.solovyev.common.history.HistoryAction; import org.solovyev.common.msg.Message; import javax.annotation.Nonnull; @@ -149,22 +147,6 @@ public class AndroidCalculator implements Calculator, CalculatorEventListener, S calculator.fireCalculatorEvents(calculatorEvents); } - @Override - public void doHistoryAction(@Nonnull HistoryAction historyAction) { - calculator.doHistoryAction(historyAction); - } - - @Override - @Nonnull - public OldHistoryState getCurrentHistoryState() { - return calculator.getCurrentHistoryState(); - } - - @Override - public void setCurrentHistoryState(@Nonnull OldHistoryState editorHistoryState) { - calculator.setCurrentHistoryState(editorHistoryState); - } - @Override public void evaluate() { calculator.evaluate(); diff --git a/app/src/main/java/org/solovyev/android/calculator/App.java b/app/src/main/java/org/solovyev/android/calculator/App.java index af8f82a3..f906044f 100644 --- a/app/src/main/java/org/solovyev/android/calculator/App.java +++ b/app/src/main/java/org/solovyev/android/calculator/App.java @@ -335,6 +335,11 @@ public final class App { return Locator.getInstance().getEditor(); } + @Nonnull + public static Display getDisplay() { + return Locator.getInstance().getDisplay(); + } + private static class MyBus extends Bus { @Override public void post(final Object event) { diff --git a/app/src/main/java/org/solovyev/android/calculator/BaseUi.java b/app/src/main/java/org/solovyev/android/calculator/BaseUi.java index 00d4fda4..ff08ee37 100644 --- a/app/src/main/java/org/solovyev/android/calculator/BaseUi.java +++ b/app/src/main/java/org/solovyev/android/calculator/BaseUi.java @@ -33,25 +33,18 @@ import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.widget.TextView; - import org.solovyev.android.Views; -import org.solovyev.android.views.dragbutton.DirectionDragButton; -import org.solovyev.android.views.dragbutton.DragButton; -import org.solovyev.android.views.dragbutton.DragDirection; -import org.solovyev.android.views.dragbutton.DragListener; -import org.solovyev.android.views.dragbutton.SimpleDragListener; -import org.solovyev.android.calculator.history.OldHistoryState; import org.solovyev.android.calculator.history.HistoryDragProcessor; import org.solovyev.android.calculator.view.AngleUnitsButton; import org.solovyev.android.calculator.view.LongClickEraser; import org.solovyev.android.calculator.view.NumeralBasesButton; import org.solovyev.android.calculator.view.ViewsCache; - -import java.util.ArrayList; -import java.util.List; +import org.solovyev.android.views.dragbutton.*; import javax.annotation.Nonnull; import javax.annotation.Nullable; +import java.util.ArrayList; +import java.util.List; import static org.solovyev.android.calculator.Preferences.Gui.Layout.simple; import static org.solovyev.android.calculator.Preferences.Gui.Layout.simple_mobile; @@ -165,7 +158,7 @@ public abstract class BaseUi implements SharedPreferences.OnSharedPreferenceChan final ViewsCache views = ViewsCache.forView(root); setOnDragListeners(views, activity); - HistoryDragProcessor historyDragProcessor = new HistoryDragProcessor<>(); + HistoryDragProcessor historyDragProcessor = new HistoryDragProcessor(); final DragListener historyDragListener = newDragListener(historyDragProcessor, activity); final DragButton historyButton = getButton(views, R.id.cpp_button_history); if (historyButton != null) { diff --git a/app/src/main/java/org/solovyev/android/calculator/CalculatorActivity.java b/app/src/main/java/org/solovyev/android/calculator/CalculatorActivity.java index 45ac6ba5..e1a11bef 100644 --- a/app/src/main/java/org/solovyev/android/calculator/CalculatorActivity.java +++ b/app/src/main/java/org/solovyev/android/calculator/CalculatorActivity.java @@ -32,13 +32,8 @@ import android.os.Bundle; import android.preference.PreferenceManager; import android.support.v7.app.ActionBar; import android.text.method.LinkMovementMethod; -import android.view.KeyEvent; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewConfiguration; -import android.view.Window; +import android.view.*; import android.widget.TextView; - import org.solovyev.android.Activities; import org.solovyev.android.Android; import org.solovyev.android.Threads; @@ -49,7 +44,6 @@ import org.solovyev.android.prefs.Preference; import org.solovyev.android.wizard.Wizard; import org.solovyev.android.wizard.Wizards; import org.solovyev.common.Objects; -import org.solovyev.common.history.HistoryAction; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -59,9 +53,7 @@ import static android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH; import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON; import static org.solovyev.android.calculator.Preferences.Gui.preventScreenFromFading; import static org.solovyev.android.calculator.release.ReleaseNotes.hasReleaseNotes; -import static org.solovyev.android.wizard.WizardUi.continueWizard; -import static org.solovyev.android.wizard.WizardUi.createLaunchIntent; -import static org.solovyev.android.wizard.WizardUi.startWizard; +import static org.solovyev.android.wizard.WizardUi.*; public class CalculatorActivity extends BaseActivity implements SharedPreferences.OnSharedPreferenceChangeListener, CalculatorEventListener { @@ -211,7 +203,7 @@ public class CalculatorActivity extends BaseActivity implements SharedPreference public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { if (useBackAsPrev) { - getCalculator().doHistoryAction(HistoryAction.undo); + Locator.getInstance().getHistory().undo(); return true; } } diff --git a/app/src/main/java/org/solovyev/android/calculator/CalculatorImpl.java b/app/src/main/java/org/solovyev/android/calculator/CalculatorImpl.java index e8aa9645..8b271bea 100644 --- a/app/src/main/java/org/solovyev/android/calculator/CalculatorImpl.java +++ b/app/src/main/java/org/solovyev/android/calculator/CalculatorImpl.java @@ -23,9 +23,15 @@ package org.solovyev.android.calculator; import android.text.TextUtils; - import com.squareup.otto.Subscribe; - +import jscl.AbstractJsclArithmeticException; +import jscl.NumeralBase; +import jscl.NumeralBaseException; +import jscl.math.Generic; +import jscl.math.function.Function; +import jscl.math.function.IConstant; +import jscl.math.operator.Operator; +import jscl.text.ParseInterruptedException; import org.solovyev.android.calculator.history.CalculatorHistory; import org.solovyev.android.calculator.jscl.JsclOperation; import org.solovyev.android.calculator.model.Var; @@ -39,24 +45,14 @@ import org.solovyev.common.text.Strings; import org.solovyev.common.units.ConversionException; import org.solovyev.common.units.Conversions; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; import java.util.ArrayList; import java.util.List; import java.util.concurrent.Executor; import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicLong; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - -import jscl.AbstractJsclArithmeticException; -import jscl.NumeralBase; -import jscl.NumeralBaseException; -import jscl.math.Generic; -import jscl.math.function.Function; -import jscl.math.function.IConstant; -import jscl.math.operator.Operator; -import jscl.text.ParseInterruptedException; - /** * User: Solovyev_S * Date: 20.09.12 @@ -209,7 +205,6 @@ public class CalculatorImpl implements Calculator, CalculatorEventListener { @Override public void init() { Locator.getInstance().getEngine().init(); - Locator.getInstance().getHistory().load(); } @Override @@ -509,11 +504,6 @@ public class CalculatorImpl implements Calculator, CalculatorEventListener { CalculatorVarsRegistry.saveVariable(varsRegistry, builder, ansVar, this, false); } - public void onHistoryChanged(@Nonnull CalculatorHistory.ChangedEvent e) { - getEditor().setState(e.state.getEditor()); - getDisplay().setState(e.state.getDisplay()); - } - @Override public void onCalculatorEvent(@Nonnull CalculatorEventData calculatorEventData, @Nonnull CalculatorEventType calculatorEventType, @Nullable Object data) { diff --git a/app/src/main/java/org/solovyev/android/calculator/Display.java b/app/src/main/java/org/solovyev/android/calculator/Display.java index 0058f09e..ca1ef956 100644 --- a/app/src/main/java/org/solovyev/android/calculator/Display.java +++ b/app/src/main/java/org/solovyev/android/calculator/Display.java @@ -150,7 +150,7 @@ public class Display implements CalculatorEventListener { private void processCalculationResult(@Nonnull CalculatorEvaluationEventData calculatorEventData, @Nonnull CalculatorOutput data) { final String stringResult = data.getStringResult(); - setState(DisplayState.createValid(calculatorEventData.getOperation(), data.getResult(), stringResult, 0, calculatorEventData.getSequenceId())); + setState(DisplayState.createValid(calculatorEventData.getOperation(), data.getResult(), stringResult, calculatorEventData.getSequenceId())); } private void processConversationResult(@Nonnull CalculatorConversionEventData calculatorEventData, @Nonnull String result) { @@ -160,6 +160,6 @@ public class Display implements CalculatorEventListener { } final DisplayState displayState = calculatorEventData.getDisplayState(); - setState(DisplayState.createValid(displayState.getOperation(), displayState.getResult(), result, 0, calculatorEventData.getSequenceId())); + setState(DisplayState.createValid(displayState.getOperation(), displayState.getResult(), result, calculatorEventData.getSequenceId())); } } diff --git a/app/src/main/java/org/solovyev/android/calculator/DisplayState.java b/app/src/main/java/org/solovyev/android/calculator/DisplayState.java index 7e2e9d7a..e7fbd3b4 100644 --- a/app/src/main/java/org/solovyev/android/calculator/DisplayState.java +++ b/app/src/main/java/org/solovyev/android/calculator/DisplayState.java @@ -22,7 +22,9 @@ package org.solovyev.android.calculator; +import android.text.TextUtils; import jscl.math.Generic; +import org.json.JSONObject; import org.solovyev.android.calculator.jscl.JsclOperation; import org.solovyev.common.text.Strings; @@ -31,6 +33,8 @@ import javax.annotation.Nullable; public class DisplayState { + @Nonnull + private static final String JSON_OPERATION = "o"; @Nonnull private JsclOperation operation = JsclOperation.numeric; @@ -45,18 +49,26 @@ public class DisplayState { @Nullable private String errorMessage; - private int selection; - private long sequence; private DisplayState() { } + private DisplayState(@Nonnull JSONObject json) { + operation = JsclOperation.values()[json.optInt(JSON_OPERATION, JsclOperation.numeric.ordinal())]; + } + @Nonnull public static DisplayState empty() { return new DisplayState(); } + + @Nonnull + public static DisplayState create(@Nonnull JSONObject json) { + return new DisplayState(json); + } + @Nonnull public static DisplayState createError(@Nonnull JsclOperation operation, @Nonnull String errorMessage, @@ -73,14 +85,12 @@ public class DisplayState { public static DisplayState createValid(@Nonnull JsclOperation operation, @Nullable Generic result, @Nonnull String stringResult, - int selection, long sequence) { final DisplayState state = new DisplayState(); state.valid = true; state.result = result; state.stringResult = stringResult; state.operation = operation; - state.selection = selection; state.sequence = sequence; return state; } @@ -90,10 +100,6 @@ public class DisplayState { return Strings.getNotEmpty(isValid() ? stringResult : errorMessage, ""); } - public int getSelection() { - return selection; - } - @Nullable public Generic getResult() { return this.result; @@ -121,4 +127,8 @@ public class DisplayState { public long getSequence() { return sequence; } + + public boolean same(@Nonnull DisplayState that) { + return TextUtils.equals(stringResult, that.stringResult) && TextUtils.equals(errorMessage, that.errorMessage) && operation == that.operation; + } } diff --git a/app/src/main/java/org/solovyev/android/calculator/Editor.java b/app/src/main/java/org/solovyev/android/calculator/Editor.java index 6b74ce04..00ac5d7f 100644 --- a/app/src/main/java/org/solovyev/android/calculator/Editor.java +++ b/app/src/main/java/org/solovyev/android/calculator/Editor.java @@ -104,7 +104,7 @@ public class Editor { @Nonnull public EditorState setState(@Nonnull EditorState state) { Check.isMainThread(); - return setText(state.getTextString(), state.selection); + return onTextChanged(state); } @Nonnull diff --git a/app/src/main/java/org/solovyev/android/calculator/EditorState.java b/app/src/main/java/org/solovyev/android/calculator/EditorState.java index 303e4273..36d2914a 100644 --- a/app/src/main/java/org/solovyev/android/calculator/EditorState.java +++ b/app/src/main/java/org/solovyev/android/calculator/EditorState.java @@ -22,6 +22,9 @@ package org.solovyev.android.calculator; +import android.text.TextUtils; +import org.json.JSONException; +import org.json.JSONObject; import org.solovyev.android.Check; import javax.annotation.Nonnull; @@ -30,6 +33,10 @@ import javax.annotation.Nullable; public class EditorState { public static final long NO_SEQUENCE = -1; + @Nonnull + private static final String JSON_TEXT = "t"; + @Nonnull + private static final String JSON_SELECTION = "s"; private static long counter = NO_SEQUENCE + 1; public final long sequence; @@ -50,6 +57,10 @@ public class EditorState { this.selection = selection; } + private EditorState(@Nonnull JSONObject json) { + this(json.optString(JSON_TEXT), json.optInt(JSON_SELECTION)); + } + @Nonnull public static EditorState empty() { return new EditorState(); @@ -65,6 +76,11 @@ public class EditorState { return new EditorState(text, selection); } + @Nonnull + public static EditorState create(@Nonnull JSONObject json) { + return new EditorState(json); + } + @Nonnull public String getTextString() { if (textString == null) { @@ -72,4 +88,16 @@ public class EditorState { } return textString; } + + public boolean same(@Nonnull EditorState that) { + return TextUtils.equals(text, that.text) && selection == that.selection; + } + + @Nonnull + public String toJson() throws JSONException { + final JSONObject json = new JSONObject(); + json.put(JSON_TEXT, getTextString()); + json.put(JSON_SELECTION, selection); + return json.toString(); + } } diff --git a/app/src/main/java/org/solovyev/android/calculator/Preferences.java b/app/src/main/java/org/solovyev/android/calculator/Preferences.java index 55344cf8..8994f66b 100644 --- a/app/src/main/java/org/solovyev/android/calculator/Preferences.java +++ b/app/src/main/java/org/solovyev/android/calculator/Preferences.java @@ -377,10 +377,4 @@ public final class Preferences { public static class Graph { public static final Preference plotImag = BooleanPreference.of("graph_plot_imag", false); } - - public static class History { - public static final Preference showIntermediateCalculations = BooleanPreference.of("history_show_intermediate_calculations", false); - public static final Preference showDatetime = BooleanPreference.of("history_show_datetime", true); - } - } diff --git a/app/src/main/java/org/solovyev/android/calculator/history/BaseHistoryFragment.java b/app/src/main/java/org/solovyev/android/calculator/history/BaseHistoryFragment.java index d2fec4db..79900924 100644 --- a/app/src/main/java/org/solovyev/android/calculator/history/BaseHistoryFragment.java +++ b/app/src/main/java/org/solovyev/android/calculator/history/BaseHistoryFragment.java @@ -26,34 +26,20 @@ import android.app.Activity; import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; -import android.content.Intent; -import android.content.SharedPreferences; import android.os.Bundle; -import android.preference.PreferenceManager; import android.support.v4.app.FragmentActivity; import android.support.v4.app.ListFragment; import android.text.ClipboardManager; -import android.util.Log; -import android.view.ContextMenu; import android.view.*; import android.widget.*; import com.melnykov.fab.FloatingActionButton; import org.solovyev.android.calculator.*; -import org.solovyev.android.calculator.R; import org.solovyev.android.calculator.jscl.JsclOperation; -import org.solovyev.android.menu.*; -import org.solovyev.android.plotter.Check; -import org.solovyev.common.JPredicate; -import org.solovyev.common.collections.Collections; -import org.solovyev.common.equals.Equalizer; -import org.solovyev.common.filter.Filter; -import org.solovyev.common.filter.FilterRulesChain; import org.solovyev.common.text.Strings; import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.util.ArrayList; -import java.util.Comparator; import java.util.List; import static android.view.Menu.NONE; @@ -61,26 +47,6 @@ import static org.solovyev.android.calculator.CalculatorEventType.clear_history_ public abstract class BaseHistoryFragment extends ListFragment implements CalculatorEventListener { - public static final Comparator COMPARATOR = new Comparator() { - @Override - public int compare(OldHistoryState state1, OldHistoryState state2) { - if (state1.isSaved() == state2.isSaved()) { - long l = state2.getTime() - state1.getTime(); - return l > 0l ? 1 : (l < 0l ? -1 : 0); - } else if (state1.isSaved()) { - return -1; - } else if (state2.isSaved()) { - return 1; - } - return 0; - } - }; - @Nonnull - private static final String TAG = "CalculatorHistoryFragment"; - - private final ActivityMenu menu = ListActivityMenu.fromResource(R.menu.history_menu, HistoryMenu.class, AndroidMenuHelper.getInstance(), new HistoryMenuFilter()); - @Nonnull - private final SharedPreferences.OnSharedPreferenceChangeListener preferencesListener = new HistoryOnPreferenceChangeListener(); @Nonnull private final DialogInterface.OnClickListener clearDialogListener = new DialogInterface.OnClickListener() { @Override @@ -103,48 +69,18 @@ public abstract class BaseHistoryFragment extends ListFragment implements Calcul ui = new FragmentUi(fragmentType.getDefaultLayoutId(), fragmentType.getDefaultTitleResId(), false); } - public static boolean isAlreadySaved(@Nonnull OldHistoryState historyState) { - Check.isTrue(!historyState.isSaved()); - - boolean result = false; - try { - historyState.setSaved(true); - if (Collections.contains(historyState, Locator.getInstance().getHistory().getSavedHistory(), new Equalizer() { - @Override - public boolean areEqual(@Nullable OldHistoryState first, @Nullable OldHistoryState second) { - return first != null && second != null && - first.getTime() == second.getTime() && - first.getDisplayState().equals(second.getDisplayState()) && - first.getEditorState().equals(second.getEditorState()); - } - })) { - result = true; - } - } finally { - historyState.setSaved(false); - } - return result; + @Nonnull + public static String getHistoryText(@Nonnull HistoryState state) { + return state.editor.getTextString() + getIdentitySign(state.display.getOperation()) + state.display.getText(); } @Nonnull - public static String getHistoryText(@Nonnull OldHistoryState state) { - final StringBuilder result = new StringBuilder(); - result.append(state.getEditorState().getText()); - result.append(getIdentitySign(state.getDisplayState().getJsclOperation())); - final String expressionResult = state.getDisplayState().getEditorState().getText(); - if (expressionResult != null) { - result.append(expressionResult); - } - return result.toString(); + private static String getIdentitySign(@Nonnull JsclOperation operation) { + return operation == JsclOperation.simplify ? "≡" : "="; } - @Nonnull - private static String getIdentitySign(@Nonnull JsclOperation jsclOperation) { - return jsclOperation == JsclOperation.simplify ? "≡" : "="; - } - - public void useState(@Nonnull final OldHistoryState state) { - App.getEditor().setState(state.getEditorState()); + public void useState(@Nonnull final HistoryState state) { + App.getEditor().setState(state.editor); final FragmentActivity activity = getActivity(); if (!(activity instanceof CalculatorActivity)) { activity.finish(); @@ -156,14 +92,6 @@ public abstract class BaseHistoryFragment extends ListFragment implements Calcul super.onCreate(savedInstanceState); ui.onCreate(this); - - setHasOptionsMenu(true); - - logDebug("onCreate"); - } - - private int logDebug(@Nonnull String msg) { - return Log.d(TAG + ": " + getTag(), msg); } @Override @@ -175,12 +103,9 @@ public abstract class BaseHistoryFragment extends ListFragment implements Calcul public void onViewCreated(View root, Bundle savedInstanceState) { super.onViewCreated(root, savedInstanceState); - final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity()); - final Boolean showDatetime = Preferences.History.showDatetime.getPreference(preferences); - ui.onViewCreated(this, root); - adapter = new HistoryArrayAdapter(this.getActivity(), getItemLayoutId(), org.solovyev.android.calculator.R.id.history_item, new ArrayList(), showDatetime); + adapter = new HistoryArrayAdapter(this.getActivity(), getItemLayoutId(), R.id.history_item, new ArrayList()); setListAdapter(adapter); final ListView lv = getListView(); @@ -200,7 +125,7 @@ public abstract class BaseHistoryFragment extends ListFragment implements Calcul final View view, final int position, final long id) { - useState((OldHistoryState) parent.getItemAtPosition(position)); + useState((HistoryState) parent.getItemAtPosition(position)); } }); @@ -214,16 +139,16 @@ public abstract class BaseHistoryFragment extends ListFragment implements Calcul this.ui.onResume(this); updateAdapter(); - PreferenceManager.getDefaultSharedPreferences(getActivity()).registerOnSharedPreferenceChangeListener(preferencesListener); } @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { super.onCreateContextMenu(menu, v, menuInfo); final AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo; - final OldHistoryState state = (OldHistoryState) getListView().getItemAtPosition(info.position); + final HistoryState state = (HistoryState) getListView().getItemAtPosition(info.position); - if (state.isSaved()) { + // todo serso: fix + if (true) { menu.add(NONE, R.string.c_use, NONE, R.string.c_use); menu.add(NONE, R.string.c_copy_expression, NONE, R.string.c_copy_expression); if (shouldHaveCopyResult(state)) { @@ -237,9 +162,7 @@ public abstract class BaseHistoryFragment extends ListFragment implements Calcul if (shouldHaveCopyResult(state)) { menu.add(NONE, R.string.c_copy_result, NONE, R.string.c_copy_result); } - if (!isAlreadySaved(state)) { - menu.add(NONE, R.string.c_save, NONE, R.string.c_save); - } + menu.add(NONE, R.string.c_save, NONE, R.string.c_save); } } @@ -247,14 +170,14 @@ public abstract class BaseHistoryFragment extends ListFragment implements Calcul public boolean onContextItemSelected(MenuItem item) { final Context context = getActivity(); final AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo(); - final OldHistoryState state = (OldHistoryState) getListView().getItemAtPosition(info.position); + final HistoryState state = (HistoryState) getListView().getItemAtPosition(info.position); switch (item.getItemId()) { case R.string.c_use: useState(state); return true; case R.string.c_copy_expression: - final String editorText = state.getEditorState().getText(); + final String editorText = state.editor.getTextString(); if (!Strings.isEmpty(editorText)) { final ClipboardManager clipboard = (ClipboardManager) context.getSystemService(Activity.CLIPBOARD_SERVICE); clipboard.setText(editorText); @@ -262,7 +185,7 @@ public abstract class BaseHistoryFragment extends ListFragment implements Calcul } return true; case R.string.c_copy_result: - final String displayText = state.getDisplayState().getEditorState().getText(); + final String displayText = state.display.getText(); if (!Strings.isEmpty(displayText)) { final ClipboardManager clipboard = (ClipboardManager) context.getSystemService(Activity.CLIPBOARD_SERVICE); clipboard.setText(displayText); @@ -270,33 +193,23 @@ public abstract class BaseHistoryFragment extends ListFragment implements Calcul } return true; case R.string.c_save: - if (!state.isSaved()) { - createEditHistoryDialog(state, context, true); - } else { - Toast.makeText(context, context.getText(R.string.c_history_already_saved), Toast.LENGTH_LONG).show(); - } + createEditHistoryDialog(state, context, true); return true; case R.string.c_edit: - if (state.isSaved()) { - createEditHistoryDialog(state, context, false); - } else { - Toast.makeText(context, context.getText(R.string.c_history_must_be_saved), Toast.LENGTH_LONG).show(); - } + createEditHistoryDialog(state, context, false); return true; case R.string.c_remove: - if (state.isSaved()) { - getAdapter().remove(state); - Locator.getInstance().getHistory().removeSavedHistory(state); - Toast.makeText(context, context.getText(R.string.c_history_was_removed), Toast.LENGTH_LONG).show(); - getAdapter().notifyDataSetChanged(); - } + getAdapter().remove(state); + Locator.getInstance().getHistory().removeSavedHistory(state); + Toast.makeText(context, context.getText(R.string.c_history_was_removed), Toast.LENGTH_LONG).show(); + getAdapter().notifyDataSetChanged(); return true; } return super.onContextItemSelected(item); } - private void createEditHistoryDialog(@Nonnull final OldHistoryState state, @Nonnull final Context context, final boolean save) { + private void createEditHistoryDialog(@Nonnull final HistoryState state, @Nonnull final Context context, final boolean save) { final LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); final View editView = layoutInflater.inflate(R.layout.history_edit, null); final TextView historyExpression = (TextView) editView.findViewById(R.id.history_edit_expression); @@ -312,8 +225,8 @@ public abstract class BaseHistoryFragment extends ListFragment implements Calcul .setPositiveButton(R.string.c_save, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { - if (save) { - final OldHistoryState savedHistoryItem = Locator.getInstance().getHistory().addSavedState(state); + /*if (save) { + final HistoryState savedHistoryItem = Locator.getInstance().getHistory().addSavedState(state); savedHistoryItem.setComment(comment.getText().toString()); Locator.getInstance().getHistory().save(); // we don't need to add element to the adapter as adapter of another activity must be updated and not this @@ -322,7 +235,7 @@ public abstract class BaseHistoryFragment extends ListFragment implements Calcul state.setComment(comment.getText().toString()); Locator.getInstance().getHistory().save(); } - getAdapter().notifyDataSetChanged(); + getAdapter().notifyDataSetChanged();*/ Toast.makeText(context, context.getText(R.string.c_history_saved), Toast.LENGTH_LONG).show(); } }) @@ -331,16 +244,13 @@ public abstract class BaseHistoryFragment extends ListFragment implements Calcul builder.create().show(); } - private boolean shouldHaveCopyResult(@Nonnull OldHistoryState state) { - return !state.getDisplayState().isValid() || !Strings.isEmpty(state.getDisplayState().getEditorState().getText()); + private boolean shouldHaveCopyResult(@Nonnull HistoryState state) { + return !state.display.isValid() || !Strings.isEmpty(state.display.getText()); } @Override public void onPause() { - PreferenceManager.getDefaultSharedPreferences(getActivity()).unregisterOnSharedPreferenceChangeListener(preferencesListener); - - this.ui.onPause(this); - + ui.onPause(this); super.onPause(); } @@ -352,7 +262,6 @@ public abstract class BaseHistoryFragment extends ListFragment implements Calcul @Override public void onDestroy() { - logDebug("onDestroy"); if (clearDialog != null) { clearDialog.dismiss(); clearDialog = null; @@ -365,13 +274,13 @@ public abstract class BaseHistoryFragment extends ListFragment implements Calcul protected abstract int getItemLayoutId(); private void updateAdapter() { - final List historyList = getHistoryList(); + final List historyList = getHistoryItems(); - final ArrayAdapter adapter = getAdapter(); + final ArrayAdapter adapter = getAdapter(); try { adapter.setNotifyOnChange(false); adapter.clear(); - for (OldHistoryState historyState : historyList) { + for (HistoryState historyState : historyList) { adapter.add(historyState); } } finally { @@ -381,25 +290,6 @@ public abstract class BaseHistoryFragment extends ListFragment implements Calcul adapter.notifyDataSetChanged(); } - @Nonnull - private List getHistoryList() { - final List historyStates = getHistoryItems(); - - java.util.Collections.sort(historyStates, COMPARATOR); - - final FilterRulesChain filterRulesChain = new FilterRulesChain<>(); - filterRulesChain.addFilterRule(new JPredicate() { - @Override - public boolean apply(OldHistoryState object) { - return object == null || Strings.isEmpty(object.getEditorState().getText()); - } - }); - - new Filter<>(filterRulesChain).filter(historyStates.iterator()); - - return historyStates; - } - @Nonnull protected abstract List getHistoryItems(); @@ -417,7 +307,6 @@ public abstract class BaseHistoryFragment extends ListFragment implements Calcul getActivity().runOnUiThread(new Runnable() { @Override public void run() { - logDebug("onCalculatorEvent"); updateAdapter(); } }); @@ -438,78 +327,4 @@ public abstract class BaseHistoryFragment extends ListFragment implements Calcul } } - - @Override - public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { - this.menu.onCreateOptionsMenu(this.getActivity(), menu); - } - - @Override - public void onPrepareOptionsMenu(Menu menu) { - this.menu.onPrepareOptionsMenu(this.getActivity(), menu); - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - return this.menu.onOptionsItemSelected(this.getActivity(), item); - } - - private static enum HistoryMenu implements IdentifiableMenuItem { - - toggle_datetime(R.id.menu_history_toggle_datetime) { - @Override - public void onClick(@Nonnull MenuItem data, @Nonnull Context context) { - final SharedPreferences preferences = App.getPreferences(); - final Boolean showDatetime = Preferences.History.showDatetime.getPreference(preferences); - Preferences.History.showDatetime.putPreference(preferences, !showDatetime); - } - }, - - fullscreen(R.id.menu_history_fullscreen) { - @Override - public void onClick(@Nonnull MenuItem data, @Nonnull Context context) { - context.startActivity(new Intent(context, CalculatorHistoryActivity.class)); - } - }; - - private final int itemId; - - HistoryMenu(int itemId) { - this.itemId = itemId; - } - - @Nonnull - @Override - public Integer getItemId() { - return this.itemId; - } - } - - private class HistoryMenuFilter implements JPredicate> { - - @Override - public boolean apply(@Nullable AMenuItem menuItem) { - boolean result = false; - - if (menuItem instanceof IdentifiableMenuItem) { - switch (((IdentifiableMenuItem) menuItem).getItemId()) { - case R.id.menu_history_fullscreen: - result = !ui.isPane(BaseHistoryFragment.this); - break; - } - } - - return result; - } - } - - private final class HistoryOnPreferenceChangeListener implements SharedPreferences.OnSharedPreferenceChangeListener { - - @Override - public void onSharedPreferenceChanged(SharedPreferences preferences, String key) { - if (Preferences.History.showDatetime.isSameKey(key)) { - getAdapter().setShowDatetime(Preferences.History.showDatetime.getPreference(preferences)); - } - } - } } diff --git a/app/src/main/java/org/solovyev/android/calculator/history/CalculatorHistory.java b/app/src/main/java/org/solovyev/android/calculator/history/CalculatorHistory.java index 9f72396b..14b0ba91 100644 --- a/app/src/main/java/org/solovyev/android/calculator/history/CalculatorHistory.java +++ b/app/src/main/java/org/solovyev/android/calculator/history/CalculatorHistory.java @@ -24,29 +24,21 @@ package org.solovyev.android.calculator.history; import android.content.SharedPreferences; import android.text.TextUtils; - +import com.google.common.base.Strings; import com.squareup.otto.Subscribe; - import org.solovyev.android.Check; -import org.solovyev.android.calculator.App; -import org.solovyev.android.calculator.CalculatorEventType; -import org.solovyev.android.calculator.Display; -import org.solovyev.android.calculator.Editor; -import org.solovyev.android.calculator.EditorState; -import org.solovyev.android.calculator.Locator; +import org.solovyev.android.calculator.*; +import org.solovyev.android.io.FileSaver; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; import java.util.ArrayList; import java.util.Collections; import java.util.LinkedList; import java.util.List; -import java.util.concurrent.atomic.AtomicInteger; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; public class CalculatorHistory { - private final AtomicInteger counter = new AtomicInteger(0); @Nonnull private final HistoryList current = new HistoryList(); @Nonnull @@ -75,8 +67,16 @@ public class CalculatorHistory { // strange, history seems to be broken. Avoid clearing the preference return; } + final List states = new ArrayList<>(); for (OldHistoryState state : history.getItems()) { - state.setSaved(true); + final OldEditorHistoryState oldEditorState = state.getEditorState(); + final OldDisplayHistoryState oldDisplayState = state.getDisplayState(); + final String editorText = oldEditorState.getText(); + final EditorState editor = EditorState.create(Strings.nullToEmpty(editorText), oldEditorState.getCursorPosition()); + final DisplayState display = oldDisplayState.isValid() + ? DisplayState.createValid(oldDisplayState.getJsclOperation(), null, Strings.nullToEmpty(oldDisplayState.getEditorState().getText()), EditorState.NO_SEQUENCE) + : DisplayState.createError(oldDisplayState.getJsclOperation(), "", EditorState.NO_SEQUENCE); + states.add(HistoryState.newBuilder(editor, display).build()); } } @@ -92,7 +92,7 @@ public class CalculatorHistory { public void addCurrentState(@Nonnull HistoryState state) { Check.isMainThread(); - current.addState(state); + current.add(state); Locator.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.history_state_added, state); // todo serso: schedule save } @@ -146,7 +146,7 @@ public class CalculatorHistory { if (state == null) { return; } - App.getBus().post(new ChangedEvent(state)); + onCurrentStateChanged(state); } public void redo() { @@ -154,7 +154,12 @@ public class CalculatorHistory { if (state == null) { return; } - App.getBus().post(new ChangedEvent(state)); + onCurrentStateChanged(state); + } + + private void onCurrentStateChanged(@Nonnull HistoryState state) { + App.getEditor().setState(state.editor); + App.getDisplay().setState(state.display); } @Nonnull @@ -186,13 +191,4 @@ public class CalculatorHistory { addCurrentState(HistoryState.newBuilder(lastEditorState, e.newState).build()); lastEditorState = null; } - - public static final class ChangedEvent { - @Nonnull - public final HistoryState state; - - public ChangedEvent(@Nonnull HistoryState state) { - this.state = state; - } - } -} +} \ No newline at end of file diff --git a/app/src/main/java/org/solovyev/android/calculator/history/HistoryArrayAdapter.java b/app/src/main/java/org/solovyev/android/calculator/history/HistoryArrayAdapter.java index 1f080e3d..98dbfd00 100644 --- a/app/src/main/java/org/solovyev/android/calculator/history/HistoryArrayAdapter.java +++ b/app/src/main/java/org/solovyev/android/calculator/history/HistoryArrayAdapter.java @@ -27,50 +27,32 @@ import android.text.format.DateUtils; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; -import android.widget.ImageView; import android.widget.TextView; - import org.solovyev.android.calculator.R; import org.solovyev.common.text.Strings; -import java.util.List; - import javax.annotation.Nonnull; +import java.util.List; import static android.view.View.GONE; import static android.view.View.VISIBLE; -import static org.solovyev.android.calculator.CalculatorFragmentType.saved_history; -import static org.solovyev.android.calculator.history.BaseHistoryFragment.isAlreadySaved; -/** - * User: serso - * Date: 12/18/11 - * Time: 7:39 PM - */ -public class HistoryArrayAdapter extends ArrayAdapter { +public class HistoryArrayAdapter extends ArrayAdapter { private static final int DATETIME_FORMAT = DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_ABBREV_MONTH | DateUtils.FORMAT_ABBREV_TIME; - private boolean showDatetime; - HistoryArrayAdapter(Context context, int resource, int textViewResourceId, @Nonnull List historyList, boolean showDatetime) { + HistoryArrayAdapter(Context context, int resource, int textViewResourceId, @Nonnull List historyList) { super(context, resource, textViewResourceId, historyList); - this.showDatetime = showDatetime; } @Override public View getView(int position, View convertView, ViewGroup parent) { final ViewGroup result = (ViewGroup) super.getView(position, convertView, parent); - final OldHistoryState state = getItem(position); + final HistoryState state = getItem(position); final TextView time = (TextView) result.findViewById(R.id.history_time); - if (showDatetime) { - time.setVisibility(VISIBLE); - time.setText(DateUtils.formatDateTime(getContext(), state.getTime(), DATETIME_FORMAT)); - } else { - time.setVisibility(GONE); - time.setText(null); - } + time.setText(DateUtils.formatDateTime(getContext(), state.getTime(), DATETIME_FORMAT)); final TextView editor = (TextView) result.findViewById(R.id.history_item); editor.setText(BaseHistoryFragment.getHistoryText(state)); @@ -86,42 +68,6 @@ public class HistoryArrayAdapter extends ArrayAdapter { commentView.setVisibility(GONE); } } - - final ImageView status = (ImageView) result.findViewById(R.id.history_item_status_icon); - if (status != null) { - if (state.isSaved() || isAlreadySaved(state)) { - status.setVisibility(VISIBLE); - status.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - final Context context = getContext(); - if (context instanceof CalculatorHistoryActivity) { - final CalculatorHistoryActivity activity = (CalculatorHistoryActivity) context; - activity.getUi().selectTab(activity, saved_history); - } - } - }); - } else { - status.setVisibility(GONE); - status.setOnClickListener(null); - } - } - return result; } - - @Override - public void notifyDataSetChanged() { - this.setNotifyOnChange(false); - this.sort(BaseHistoryFragment.COMPARATOR); - this.setNotifyOnChange(true); - super.notifyDataSetChanged(); - } - - public void setShowDatetime(boolean showDatetime) { - if (this.showDatetime != showDatetime) { - this.showDatetime = showDatetime; - notifyDataSetChanged(); - } - } } diff --git a/app/src/main/java/org/solovyev/android/calculator/history/HistoryDragProcessor.java b/app/src/main/java/org/solovyev/android/calculator/history/HistoryDragProcessor.java index cc64aa9c..c57287c7 100644 --- a/app/src/main/java/org/solovyev/android/calculator/history/HistoryDragProcessor.java +++ b/app/src/main/java/org/solovyev/android/calculator/history/HistoryDragProcessor.java @@ -32,7 +32,7 @@ import org.solovyev.android.views.dragbutton.SimpleDragListener; import javax.annotation.Nonnull; -public class HistoryDragProcessor implements SimpleDragListener.DragProcessor { +public class HistoryDragProcessor implements SimpleDragListener.DragProcessor { @Override public boolean processDragEvent(@Nonnull DragDirection direction, @Nonnull DragButton button, @Nonnull PointF startPoint, @Nonnull MotionEvent motionEvent) { diff --git a/app/src/main/java/org/solovyev/android/calculator/history/HistoryList.java b/app/src/main/java/org/solovyev/android/calculator/history/HistoryList.java index 3c4563ad..33c3d74d 100644 --- a/app/src/main/java/org/solovyev/android/calculator/history/HistoryList.java +++ b/app/src/main/java/org/solovyev/android/calculator/history/HistoryList.java @@ -2,7 +2,6 @@ package org.solovyev.android.calculator.history; import android.support.annotation.NonNull; import android.support.annotation.Nullable; - import org.solovyev.android.Check; import java.util.Collections; @@ -17,12 +16,15 @@ public class HistoryList { private final List list = new LinkedList<>(); private int current = -1; - public void addState(@NonNull HistoryState e) { + public void add(@NonNull HistoryState state) { Check.isMainThread(); + if (isCurrent(state)) { + return; + } while (current != list.size() - 1) { list.remove(list.size() - 1); } - list.add(e); + list.add(state); current++; if (list.size() > MAX_HISTORY) { current--; @@ -30,6 +32,14 @@ public class HistoryList { } } + private boolean isCurrent(@NonNull HistoryState state) { + final HistoryState current = getCurrent(); + if (current == null) { + return false; + } + return current.same(state); + } + @Nullable public HistoryState getCurrent() { Check.isMainThread(); diff --git a/app/src/main/java/org/solovyev/android/calculator/history/HistoryState.java b/app/src/main/java/org/solovyev/android/calculator/history/HistoryState.java index 0eb2b3f6..7be3c093 100644 --- a/app/src/main/java/org/solovyev/android/calculator/history/HistoryState.java +++ b/app/src/main/java/org/solovyev/android/calculator/history/HistoryState.java @@ -1,7 +1,8 @@ package org.solovyev.android.calculator.history; import android.support.annotation.Nullable; - +import org.json.JSONException; +import org.json.JSONObject; import org.solovyev.android.Check; import org.solovyev.android.calculator.DisplayState; import org.solovyev.android.calculator.EditorState; @@ -11,9 +12,13 @@ import javax.annotation.Nonnull; public class HistoryState { @Nonnull - protected final EditorState editor; + private static final String JSON_EDITOR = "e"; @Nonnull - protected final DisplayState display; + private static final String JSON_DISPLAY = "d"; + @Nonnull + public final EditorState editor; + @Nonnull + public final DisplayState display; protected long time; @Nullable protected String comment; @@ -23,6 +28,10 @@ public class HistoryState { this.display = display; } + private HistoryState(@Nonnull JSONObject json) throws JSONException { + this(EditorState.create(json.getJSONObject(JSON_EDITOR)), DisplayState.create(json.getJSONObject(JSON_DISPLAY))); + } + @Nonnull public static Builder newBuilder(@Nonnull EditorState editor, @Nonnull DisplayState display) { return new Builder(editor, display); @@ -47,6 +56,10 @@ public class HistoryState { return comment; } + public boolean same(@Nonnull HistoryState that) { + return this.editor.same(that.editor) && this.display.same(that.display); + } + public static final class Builder extends HistoryState { private boolean built; diff --git a/app/src/main/java/org/solovyev/android/calculator/history/OldBaseHistoryState.java b/app/src/main/java/org/solovyev/android/calculator/history/OldBaseHistoryState.java index 52805291..4710a5f4 100644 --- a/app/src/main/java/org/solovyev/android/calculator/history/OldBaseHistoryState.java +++ b/app/src/main/java/org/solovyev/android/calculator/history/OldBaseHistoryState.java @@ -23,13 +23,11 @@ package org.solovyev.android.calculator.history; import org.simpleframework.xml.Element; -import org.simpleframework.xml.Transient; - -import java.util.Date; import javax.annotation.Nullable; +import java.util.Date; -public class OldBaseHistoryState implements Cloneable { +class OldBaseHistoryState implements Cloneable { @Element private long time = new Date().getTime(); @@ -38,20 +36,6 @@ public class OldBaseHistoryState implements Cloneable { @Nullable private String comment; - @Transient - private boolean saved; - - @Transient - private int id = 0; - - public int getId() { - return id; - } - - public void setId(int id) { - this.id = id; - } - public long getTime() { return time; } @@ -69,14 +53,6 @@ public class OldBaseHistoryState implements Cloneable { this.comment = comment; } - public boolean isSaved() { - return saved; - } - - public void setSaved(boolean saved) { - this.saved = saved; - } - @SuppressWarnings("CloneDoesntDeclareCloneNotSupportedException") @Override protected OldBaseHistoryState clone() { diff --git a/app/src/main/java/org/solovyev/android/calculator/history/OldDisplayHistoryState.java b/app/src/main/java/org/solovyev/android/calculator/history/OldDisplayHistoryState.java index 5068e5fa..d70db64b 100644 --- a/app/src/main/java/org/solovyev/android/calculator/history/OldDisplayHistoryState.java +++ b/app/src/main/java/org/solovyev/android/calculator/history/OldDisplayHistoryState.java @@ -22,29 +22,19 @@ package org.solovyev.android.calculator.history; -import jscl.math.Generic; import org.simpleframework.xml.Element; import org.simpleframework.xml.Root; import org.simpleframework.xml.Transient; -import org.solovyev.android.calculator.Display; -import org.solovyev.android.calculator.DisplayState; -import org.solovyev.android.calculator.EditorState; import org.solovyev.android.calculator.jscl.JsclOperation; -import org.solovyev.common.text.Strings; import javax.annotation.Nonnull; -import javax.annotation.Nullable; @Root(name = "DisplayHistoryState") -public class OldDisplayHistoryState implements Cloneable { +class OldDisplayHistoryState implements Cloneable { @Transient private boolean valid = true; - @Transient - @Nullable - private String errorMessage = null; - @Element @Nonnull private OldEditorHistoryState editorState; @@ -53,37 +43,10 @@ public class OldDisplayHistoryState implements Cloneable { @Nonnull private JsclOperation jsclOperation; - @Transient - @Nullable - private Generic genericResult; - private OldDisplayHistoryState() { // for xml } - @Nonnull - public static OldDisplayHistoryState newInstance(@Nonnull DisplayState viewState) { - final OldDisplayHistoryState result = new OldDisplayHistoryState(); - - result.editorState = OldEditorHistoryState.create(viewState); - - result.valid = viewState.isValid(); - result.jsclOperation = viewState.getOperation(); - result.genericResult = viewState.getResult(); - result.errorMessage = viewState.getErrorMessage(); - - return result; - } - - public void setValuesFromHistory(@Nonnull Display display) { - if (this.isValid()) { - display.setState(DisplayState.createValid(this.getJsclOperation(), this.getGenericResult(), Strings.getNotEmpty(this.getEditorState().getText(), ""), this.getEditorState().getCursorPosition(), EditorState.NO_SEQUENCE)); - } else { - display.setState(DisplayState.createError(this.getJsclOperation(), Strings.getNotEmpty(this.getErrorMessage(), ""), EditorState.NO_SEQUENCE)); - } - } - - public boolean isValid() { return valid; } @@ -98,17 +61,6 @@ public class OldDisplayHistoryState implements Cloneable { return jsclOperation; } - @Nullable - public String getErrorMessage() { - return errorMessage; - } - - @Nullable - public Generic getGenericResult() { - return genericResult; - } - - @Override public boolean equals(Object o) { if (this == o) return true; @@ -132,9 +84,7 @@ public class OldDisplayHistoryState implements Cloneable { @Override public String toString() { return "CalculatorDisplayHistoryState{" + - "valid=" + valid + - ", errorMessage='" + errorMessage + '\'' + - ", editorHistoryState=" + editorState + + "editorHistoryState=" + editorState + ", jsclOperation=" + jsclOperation + '}'; } diff --git a/app/src/main/java/org/solovyev/android/calculator/history/OldEditorHistoryState.java b/app/src/main/java/org/solovyev/android/calculator/history/OldEditorHistoryState.java index 9ddbfcf6..14bf4713 100644 --- a/app/src/main/java/org/solovyev/android/calculator/history/OldEditorHistoryState.java +++ b/app/src/main/java/org/solovyev/android/calculator/history/OldEditorHistoryState.java @@ -24,16 +24,13 @@ package org.solovyev.android.calculator.history; import org.simpleframework.xml.Element; import org.simpleframework.xml.Root; -import org.solovyev.android.calculator.DisplayState; -import org.solovyev.android.calculator.Editor; import org.solovyev.android.calculator.EditorState; -import org.solovyev.common.text.Strings; import javax.annotation.Nonnull; import javax.annotation.Nullable; @Root(name = "EditorHistoryState") -public class OldEditorHistoryState implements Cloneable { +class OldEditorHistoryState implements Cloneable { @Element private int cursorPosition; @@ -56,21 +53,6 @@ public class OldEditorHistoryState implements Cloneable { return result; } - @Nonnull - public static OldEditorHistoryState create(@Nonnull DisplayState viewState) { - final OldEditorHistoryState result = new OldEditorHistoryState(); - - result.text = viewState.getText(); - result.cursorPosition = viewState.getSelection(); - - return result; - } - - public void setValuesFromHistory(@Nonnull Editor editor) { - editor.setText(Strings.getNotEmpty(this.getText(), "")); - editor.setSelection(this.getCursorPosition()); - } - @Nullable public String getText() { return text; diff --git a/app/src/main/java/org/solovyev/android/calculator/history/OldHistory.java b/app/src/main/java/org/solovyev/android/calculator/history/OldHistory.java index 802d2da6..3eac7988 100644 --- a/app/src/main/java/org/solovyev/android/calculator/history/OldHistory.java +++ b/app/src/main/java/org/solovyev/android/calculator/history/OldHistory.java @@ -35,7 +35,7 @@ import java.util.Collection; import java.util.List; @Root(name = "History") -public class OldHistory { +class OldHistory { @Nonnull @ElementList(type = OldHistoryState.class, name = "historyItems") diff --git a/app/src/main/java/org/solovyev/android/calculator/history/OldHistoryState.java b/app/src/main/java/org/solovyev/android/calculator/history/OldHistoryState.java index 3ea03dbb..5317bcf1 100644 --- a/app/src/main/java/org/solovyev/android/calculator/history/OldHistoryState.java +++ b/app/src/main/java/org/solovyev/android/calculator/history/OldHistoryState.java @@ -24,15 +24,11 @@ package org.solovyev.android.calculator.history; import org.simpleframework.xml.Element; import org.simpleframework.xml.Root; -import org.solovyev.android.calculator.Display; -import org.solovyev.android.calculator.DisplayState; -import org.solovyev.android.calculator.Editor; -import org.solovyev.android.calculator.EditorState; import javax.annotation.Nonnull; @Root(name = "HistoryState") -public class OldHistoryState extends OldBaseHistoryState { +class OldHistoryState extends OldBaseHistoryState { @Element @Nonnull @@ -46,24 +42,6 @@ public class OldHistoryState extends OldBaseHistoryState { // for xml } - private OldHistoryState(@Nonnull OldEditorHistoryState editorState, - @Nonnull OldDisplayHistoryState displayState) { - this.editorState = editorState; - this.displayState = displayState; - } - - @Nonnull - public static OldHistoryState create(@Nonnull Editor editor, - @Nonnull Display display) { - return create(editor.getState(), display.getState()); - } - - @Nonnull - public static OldHistoryState create(@Nonnull EditorState editorState, - @Nonnull DisplayState displayState) { - return new OldHistoryState(OldEditorHistoryState.create(editorState), OldDisplayHistoryState.newInstance(displayState)); - } - @Nonnull public OldEditorHistoryState getEditorState() { return editorState; diff --git a/app/src/main/java/org/solovyev/android/io/BaseFileLoader.java b/app/src/main/java/org/solovyev/android/io/BaseFileLoader.java new file mode 100644 index 00000000..07a775ad --- /dev/null +++ b/app/src/main/java/org/solovyev/android/io/BaseFileLoader.java @@ -0,0 +1,48 @@ +package org.solovyev.android.io; + +import android.content.Context; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.util.Log; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; + +abstract class BaseFileLoader { + + @NonNull + protected final Context context; + + public BaseFileLoader(@NonNull Context context) { + this.context = context; + } + + @Nullable + public CharSequence load() { + BufferedReader reader = null; + try { + final InputStream is = getInputStream(); + if (is == null) { + return null; + } + reader = new BufferedReader(new InputStreamReader(is)); + final StringBuilder result = new StringBuilder(); + String line = reader.readLine(); + while (line != null) { + result.append(line).append("\n"); + line = reader.readLine(); + } + return result; + } catch (IOException e) { + Log.e(getClass().getSimpleName(), e.getMessage(), e); + } finally { + Io.close(reader); + } + return null; + } + + @Nullable + protected abstract InputStream getInputStream() throws IOException; +} diff --git a/app/src/main/java/org/solovyev/android/io/BaseFileSaver.java b/app/src/main/java/org/solovyev/android/io/BaseFileSaver.java new file mode 100644 index 00000000..e5bc1cda --- /dev/null +++ b/app/src/main/java/org/solovyev/android/io/BaseFileSaver.java @@ -0,0 +1,39 @@ +package org.solovyev.android.io; + +import android.support.annotation.NonNull; +import android.util.Log; + +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStreamWriter; + +public abstract class BaseFileSaver implements Runnable { + + @NonNull + private final CharSequence data; + + protected BaseFileSaver(@NonNull CharSequence data) { + this.data = data; + } + + public void save() { + OutputStreamWriter out = null; + try { + out = new OutputStreamWriter(getOutputStream()); + out.write(data.toString()); + } catch (IOException e) { + Log.e("FileSaver", e.getMessage(), e); + } finally { + Io.close(out); + } + } + + @NonNull + protected abstract FileOutputStream getOutputStream() throws FileNotFoundException; + + @Override + public void run() { + save(); + } +} diff --git a/app/src/main/java/org/solovyev/android/io/FileSaver.java b/app/src/main/java/org/solovyev/android/io/FileSaver.java new file mode 100644 index 00000000..47351258 --- /dev/null +++ b/app/src/main/java/org/solovyev/android/io/FileSaver.java @@ -0,0 +1,28 @@ +package org.solovyev.android.io; + +import android.support.annotation.NonNull; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; + +public class FileSaver extends BaseFileSaver { + + @NonNull + private final File file; + + private FileSaver(@NonNull File file, @NonNull CharSequence data) { + super(data); + this.file = file; + } + + public static void save(@NonNull File file, @NonNull CharSequence data) { + final FileSaver fileSaver = new FileSaver(file, data); + fileSaver.save(); + } + + @NonNull + protected FileOutputStream getOutputStream() throws FileNotFoundException { + return new FileOutputStream(file); + } +} diff --git a/app/src/main/java/org/solovyev/android/io/Io.java b/app/src/main/java/org/solovyev/android/io/Io.java new file mode 100644 index 00000000..d07d2cad --- /dev/null +++ b/app/src/main/java/org/solovyev/android/io/Io.java @@ -0,0 +1,22 @@ +package org.solovyev.android.io; + +import android.util.Log; + +import java.io.Closeable; +import java.io.IOException; + +public final class Io { + + private Io() { + } + + public static void close(Closeable closeable) { + try { + if (closeable != null) { + closeable.close(); + } + } catch (IOException e) { + Log.e("Io", e.getMessage(), e); + } + } +} diff --git a/app/src/main/res/layout/history_item.xml b/app/src/main/res/layout/history_item.xml index c1e99f52..53bcf1a3 100644 --- a/app/src/main/res/layout/history_item.xml +++ b/app/src/main/res/layout/history_item.xml @@ -25,36 +25,18 @@ + a:orientation="vertical"> + - - - - - - - - - + \ No newline at end of file diff --git a/app/src/main/res/menu/history_menu.xml b/app/src/main/res/menu/history_menu.xml deleted file mode 100644 index 2d202b98..00000000 --- a/app/src/main/res/menu/history_menu.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/test/java/org/solovyev/android/calculator/history/CalculatorHistoryTest.java b/app/src/test/java/org/solovyev/android/calculator/history/CalculatorHistoryTest.java index 7a52530e..7750d710 100644 --- a/app/src/test/java/org/solovyev/android/calculator/history/CalculatorHistoryTest.java +++ b/app/src/test/java/org/solovyev/android/calculator/history/CalculatorHistoryTest.java @@ -62,13 +62,13 @@ public class CalculatorHistoryTest { addState(calculatorHistory, "2354"); addState(calculatorHistory, "23547"); - final List states = calculatorHistory.getCurrentHistory(); + final List states = calculatorHistory.getCurrentHistory(); Assert.assertEquals(2, states.size()); - Assert.assertEquals("23547", states.get(1).getEditorState().getText()); - Assert.assertEquals("123+3", states.get(0).getEditorState().getText()); + Assert.assertEquals("23547", states.get(1).getEditor().getTextString()); + Assert.assertEquals("123+3", states.get(0).getEditor().getTextString()); } private void addState(@Nonnull CalculatorHistory calculatorHistory, @Nonnull String text) { - calculatorHistory.addCurrentState(OldHistoryState.create(EditorState.create(text, 3), DisplayState.empty())); + calculatorHistory.addCurrentState(HistoryState.newBuilder(EditorState.create(text, 3), DisplayState.empty())); } } diff --git a/app/src/test/java/org/solovyev/android/calculator/history/HistoryUtilsTest.java b/app/src/test/java/org/solovyev/android/calculator/history/HistoryUtilsTest.java index 6a277f0a..b543e2c9 100644 --- a/app/src/test/java/org/solovyev/android/calculator/history/HistoryUtilsTest.java +++ b/app/src/test/java/org/solovyev/android/calculator/history/HistoryUtilsTest.java @@ -22,20 +22,7 @@ package org.solovyev.android.calculator.history; -import org.junit.Assert; import org.junit.Test; -import org.solovyev.android.calculator.DisplayState; -import org.solovyev.android.calculator.EditorState; -import org.solovyev.android.calculator.jscl.JsclOperation; -import org.solovyev.common.Objects; -import org.solovyev.common.equals.CollectionEqualizer; -import org.solovyev.common.history.HistoryHelper; -import org.solovyev.common.history.SimpleHistoryHelper; - -import javax.annotation.Nonnull; -import java.util.Date; - -import static org.junit.Assert.assertEquals; /** * User: serso @@ -131,80 +118,4 @@ public class HistoryUtilsTest { } - @Test - public void testToXml() throws Exception { - final Date date = new Date(100000000); - - HistoryHelper history = SimpleHistoryHelper.newInstance(); - - DisplayState calculatorDisplay = DisplayState.createError(JsclOperation.simplify, "Error", EditorState.NO_SEQUENCE); - - EditorState calculatorEditor = EditorState.create("1+1", 3); - - OldHistoryState state = OldHistoryState.create(calculatorEditor, calculatorDisplay); - state.setTime(date.getTime()); - history.addState(state); - - assertEquals(emptyHistory, createHistory(history).toXml()); - - - state.setSaved(true); - - assertEquals(toXml1, createHistory(history).toXml()); - - calculatorDisplay = DisplayState.createValid(JsclOperation.numeric, null, "5/6", 3, EditorState.NO_SEQUENCE); - - calculatorEditor = EditorState.create("5/6", 2); - - state = OldHistoryState.create(calculatorEditor, calculatorDisplay); - state.setSaved(true); - state.setTime(date.getTime()); - history.addState(state); - - calculatorDisplay = DisplayState.createError(JsclOperation.elementary, "Error", EditorState.NO_SEQUENCE); - - calculatorEditor = EditorState.create("", 1); - - state = OldHistoryState.create(calculatorEditor, calculatorDisplay); - state.setSaved(true); - state.setTime(date.getTime()); - history.addState(state); - - calculatorDisplay = DisplayState.createValid(JsclOperation.numeric, null, "4+5/35sin(41)+dfdsfsdfs", 1, EditorState.NO_SEQUENCE); - - calculatorEditor = EditorState.create("4+5/35sin(41)+dfdsfsdfs", 0); - - state = OldHistoryState.create(calculatorEditor, calculatorDisplay); - state.setSaved(true); - state.setTime(date.getTime()); - history.addState(state); - - String xml = createHistory(history).toXml(); - assertEquals(toXml2, xml); - - final HistoryHelper historyFromXml = SimpleHistoryHelper.newInstance(); - final OldHistory actual = OldHistory.fromXml(xml); - for (OldHistoryState historyState : actual.getItems()) { - historyFromXml.addState(historyState); - } - - assertEquals(history.getStates().size(), historyFromXml.getStates().size()); - - for (OldHistoryState historyState : history.getStates()) { - historyState.setId(0); - historyState.setSaved(true); - } - for (OldHistoryState historyState : historyFromXml.getStates()) { - historyState.setId(0); - historyState.setSaved(true); - } - Assert.assertTrue(Objects.areEqual(history.getStates(), historyFromXml.getStates(), new CollectionEqualizer(null))); - } - - @Nonnull - private OldHistory createHistory(HistoryHelper history) { - final OldHistory result = new OldHistory(); - result.addAll(history.getStates()); - return result; - } }