diff --git a/app/build.gradle b/app/build.gradle index f7f3a535..2e662abd 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -97,6 +97,7 @@ dependencies { exclude(module: 'xpp3') } compile 'commons-cli:commons-cli:1.2' + compile 'com.squareup:otto:1.3.8' testCompile 'junit:junit:4.12' testCompile 'net.sf.opencsv:opencsv:2.0' testCompile 'org.mockito:mockito-core:1.9.0' 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 5f95f739..e884cf8f 100644 --- a/app/src/main/java/org/solovyev/android/calculator/App.java +++ b/app/src/main/java/org/solovyev/android/calculator/App.java @@ -40,6 +40,7 @@ import android.support.v4.app.FragmentTransaction; import android.text.Spannable; import android.text.SpannableString; import android.text.style.ForegroundColorSpan; +import com.squareup.otto.Bus; import org.solovyev.android.Check; import org.solovyev.android.UiThreadExecutor; import org.solovyev.android.Views; @@ -97,7 +98,7 @@ public final class App { @Nonnull private static volatile DelayedExecutor uiThreadExecutor; @Nonnull - private static volatile JEventListeners, JEvent> eventBus; + private static Bus bus; private static volatile boolean initialized; @Nonnull private static CalculatorBroadcaster broadcaster; @@ -138,7 +139,7 @@ public final class App { App.application = application; App.preferences = PreferenceManager.getDefaultSharedPreferences(application); App.uiThreadExecutor = uiThreadExecutor; - App.eventBus = eventBus; + App.bus = new MyBus(); App.ga = new Ga(application, preferences, eventBus); App.billing = new Billing(application, new Billing.DefaultConfiguration() { @Nonnull @@ -157,7 +158,7 @@ public final class App { } } }); - App.broadcaster = new CalculatorBroadcaster(application, preferences); + App.broadcaster = new CalculatorBroadcaster(application, preferences, bus); App.screenMetrics = new ScreenMetrics(application); App.languages = languages; App.wizards = new CalculatorWizards(application); @@ -195,8 +196,8 @@ public final class App { * @return application's event bus */ @Nonnull - public static JEventListeners, JEvent> getEventBus() { - return eventBus; + public static Bus getBus() { + return bus; } @Nonnull @@ -322,4 +323,20 @@ public final class App { // NOTE: this code is only for monkeyrunner return context.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD) == PackageManager.PERMISSION_GRANTED; } + + private static class MyBus extends Bus { + @Override + public void post(final Object event) { + if (Looper.myLooper() == Looper.getMainLooper()) { + super.post(event); + return; + } + handler.post(new Runnable() { + @Override + public void run() { + MyBus.super.post(event); + } + }); + } + } } \ No newline at end of file diff --git a/app/src/main/java/org/solovyev/android/calculator/CalculatorApplication.java b/app/src/main/java/org/solovyev/android/calculator/CalculatorApplication.java index ac9ea68d..ec66d109 100644 --- a/app/src/main/java/org/solovyev/android/calculator/CalculatorApplication.java +++ b/app/src/main/java/org/solovyev/android/calculator/CalculatorApplication.java @@ -25,7 +25,6 @@ package org.solovyev.android.calculator; import android.content.SharedPreferences; import android.preference.PreferenceManager; import android.util.Log; -import android.util.TimingLogger; import com.squareup.leakcanary.LeakCanary; import org.acra.ACRA; import org.acra.ACRAConfiguration; @@ -89,8 +88,6 @@ public class CalculatorApplication extends android.app.Application implements Sh calculator.addCalculatorEventListener(listener); } - calculator.addCalculatorEventListener(App.getBroadcaster()); - Locator.getInstance().getCalculator().init(); App.getInitializer().execute(new Runnable() { @@ -146,7 +143,7 @@ public class CalculatorApplication extends android.app.Application implements Sh public void onSharedPreferenceChanged(SharedPreferences prefs, String key) { if (Preferences.Onscreen.showAppIcon.getKey().equals(key)) { boolean showAppIcon = Preferences.Onscreen.showAppIcon.getPreference(prefs); - Android.toggleComponent(this, CalculatorOnscreenStartActivity.class, showAppIcon); + Android.enableComponent(this, CalculatorOnscreenStartActivity.class, showAppIcon); Locator.getInstance().getNotifier().showMessage(R.string.cpp_this_change_may_require_reboot, MessageType.info); } } diff --git a/app/src/main/java/org/solovyev/android/calculator/CalculatorBroadcaster.java b/app/src/main/java/org/solovyev/android/calculator/CalculatorBroadcaster.java index 2a319f45..aacb3eee 100644 --- a/app/src/main/java/org/solovyev/android/calculator/CalculatorBroadcaster.java +++ b/app/src/main/java/org/solovyev/android/calculator/CalculatorBroadcaster.java @@ -3,13 +3,15 @@ package org.solovyev.android.calculator; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; +import com.squareup.otto.Bus; +import com.squareup.otto.Subscribe; import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.util.HashMap; import java.util.Map; -public final class CalculatorBroadcaster implements CalculatorEventListener, SharedPreferences.OnSharedPreferenceChangeListener { +public final class CalculatorBroadcaster implements SharedPreferences.OnSharedPreferenceChangeListener { public static final String ACTION_INIT = "org.solovyev.android.calculator.INIT"; public static final String ACTION_EDITOR_STATE_CHANGED = "org.solovyev.android.calculator.EDITOR_STATE_CHANGED"; @@ -22,18 +24,24 @@ public final class CalculatorBroadcaster implements CalculatorEventListener, Sha @Nonnull private final Intents intents = new Intents(); - public CalculatorBroadcaster(@Nonnull Context context, @Nonnull SharedPreferences preferences) { + public CalculatorBroadcaster(@Nonnull Context context, @Nonnull SharedPreferences preferences, @Nonnull Bus bus) { this.context = context; preferences.registerOnSharedPreferenceChangeListener(this); + bus.register(this); + } + + @Subscribe + public void onEditorChanged(@Nonnull Editor.ChangedEvent e) { + sendBroadcastIntent(ACTION_EDITOR_STATE_CHANGED); + } + + @Subscribe + public void onCursorMoved(@Nonnull Editor.CursorMovedEvent e) { + sendBroadcastIntent(ACTION_EDITOR_STATE_CHANGED); } - @Override public void onCalculatorEvent(@Nonnull CalculatorEventData calculatorEventData, @Nonnull CalculatorEventType calculatorEventType, @Nullable Object data) { switch (calculatorEventType) { - case editor_state_changed: - case editor_state_changed_light: - sendBroadcastIntent(ACTION_EDITOR_STATE_CHANGED); - break; case display_state_changed: sendBroadcastIntent(ACTION_DISPLAY_STATE_CHANGED); break; diff --git a/app/src/main/java/org/solovyev/android/calculator/CalculatorEditorChangeEventData.java b/app/src/main/java/org/solovyev/android/calculator/CalculatorEditorChangeEventData.java deleted file mode 100644 index dba17ed6..00000000 --- a/app/src/main/java/org/solovyev/android/calculator/CalculatorEditorChangeEventData.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2013 serso aka se.solovyev - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * Contact details - * - * Email: se.solovyev@gmail.com - * Site: http://se.solovyev.org - */ - -package org.solovyev.android.calculator; - -import javax.annotation.Nonnull; - -/** - * User: Solovyev_S - * Date: 21.09.12 - * Time: 13:46 - */ -public final class CalculatorEditorChangeEventData implements Change { - - @Nonnull - private EditorState oldState; - - @Nonnull - private EditorState newState; - - private CalculatorEditorChangeEventData(@Nonnull EditorState oldState, - @Nonnull EditorState newState) { - this.oldState = oldState; - this.newState = newState; - } - - public static CalculatorEditorChangeEventData newChangeEventData(@Nonnull EditorState oldState, - @Nonnull EditorState newState) { - return new CalculatorEditorChangeEventData(oldState, newState); - } - - @Nonnull - @Override - public EditorState getOldValue() { - return this.oldState; - } - - @Nonnull - @Override - public EditorState getNewValue() { - return this.newState; - } -} diff --git a/app/src/main/java/org/solovyev/android/calculator/CalculatorEventDataImpl.java b/app/src/main/java/org/solovyev/android/calculator/CalculatorEventDataImpl.java index 5410a127..788f5db9 100644 --- a/app/src/main/java/org/solovyev/android/calculator/CalculatorEventDataImpl.java +++ b/app/src/main/java/org/solovyev/android/calculator/CalculatorEventDataImpl.java @@ -25,33 +25,27 @@ package org.solovyev.android.calculator; import javax.annotation.Nonnull; import javax.annotation.Nullable; -/** - * User: Solovyev_S - * Date: 20.09.12 - * Time: 18:18 - */ class CalculatorEventDataImpl implements CalculatorEventData { private static final long NO_SEQUENCE = -1L; private final long eventId; private final Object source; - @Nonnull - private Long sequenceId = NO_SEQUENCE; + private final long sequenceId; - private CalculatorEventDataImpl(long id, @Nonnull Long sequenceId, @Nullable Object source) { + private CalculatorEventDataImpl(long id, long sequenceId, @Nullable Object source) { this.eventId = id; this.sequenceId = sequenceId; this.source = source; } @Nonnull - static CalculatorEventData newInstance(long id, @Nonnull Long sequenceId) { + static CalculatorEventData newInstance(long id, long sequenceId) { return new CalculatorEventDataImpl(id, sequenceId, null); } @Nonnull - static CalculatorEventData newInstance(long id, @Nonnull Long sequenceId, @Nonnull Object source) { + static CalculatorEventData newInstance(long id, long sequenceId, @Nonnull Object source) { return new CalculatorEventDataImpl(id, sequenceId, source); } @@ -78,12 +72,24 @@ class CalculatorEventDataImpl implements CalculatorEventData { @Override public boolean isSameSequence(@Nonnull CalculatorEventData that) { - return !this.sequenceId.equals(NO_SEQUENCE) && this.sequenceId.equals(that.getSequenceId()); + if (this.sequenceId == NO_SEQUENCE) { + return false; + } + if (this.sequenceId == that.getSequenceId()) { + return true; + } + return false; } @Override public boolean isAfterSequence(@Nonnull CalculatorEventData that) { - return !this.sequenceId.equals(NO_SEQUENCE) && this.sequenceId > that.getSequenceId(); + if (this.sequenceId == NO_SEQUENCE) { + return false; + } + if (this.sequenceId > that.getSequenceId()) { + return true; + } + return false; } @Override @@ -94,8 +100,7 @@ class CalculatorEventDataImpl implements CalculatorEventData { CalculatorEventDataImpl that = (CalculatorEventDataImpl) o; if (eventId != that.eventId) return false; - if (!sequenceId.equals(that.sequenceId)) - return false; + if (sequenceId != that.sequenceId) return false; return true; } @@ -103,7 +108,7 @@ class CalculatorEventDataImpl implements CalculatorEventData { @Override public int hashCode() { int result = (int) (eventId ^ (eventId >>> 32)); - result = 31 * result + (sequenceId.hashCode()); + result = 31 * result + (int) (sequenceId ^ (sequenceId >>> 32)); return result; } } diff --git a/app/src/main/java/org/solovyev/android/calculator/CalculatorEventType.java b/app/src/main/java/org/solovyev/android/calculator/CalculatorEventType.java index aa8fe879..39ad6227 100644 --- a/app/src/main/java/org/solovyev/android/calculator/CalculatorEventType.java +++ b/app/src/main/java/org/solovyev/android/calculator/CalculatorEventType.java @@ -78,10 +78,6 @@ public enum CalculatorEventType { ********************************************************************** */ - // @Nonnull org.solovyev.android.calculator.CalculatorEditorChangeEventData - editor_state_changed, - editor_state_changed_light, - // @Nonnull CalculatorDisplayChangeEventData display_state_changed, 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 69fc2dbe..85c09f52 100644 --- a/app/src/main/java/org/solovyev/android/calculator/CalculatorImpl.java +++ b/app/src/main/java/org/solovyev/android/calculator/CalculatorImpl.java @@ -22,6 +22,16 @@ 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.history.HistoryState; import org.solovyev.android.calculator.jscl.JsclOperation; @@ -37,24 +47,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 @@ -102,25 +102,11 @@ public class CalculatorImpl implements Calculator, CalculatorEventListener { private volatile long lastPreferenceCheck = 0L; - /* - ********************************************************************** - * - * CONSTRUCTORS - * - ********************************************************************** - */ - public CalculatorImpl() { + App.getBus().register(this); this.addCalculatorEventListener(this); } - /* - ********************************************************************** - * - * METHODS - * - ********************************************************************** - */ @Nonnull private static String doConversion(@Nonnull Generic generic, @@ -159,15 +145,7 @@ public class CalculatorImpl implements Calculator, CalculatorEventListener { return CalculatorEventDataImpl.newInstance(eventId, eventId, source); } - /* - ********************************************************************** - * - * CALCULATION - * - ********************************************************************** - */ - - @Nonnull + @Nonnull private CalculatorEventData nextEventData(@Nonnull Long sequenceId) { long eventId = counter.incrementAndGet(); return CalculatorEventDataImpl.newInstance(eventId, sequenceId); @@ -497,31 +475,21 @@ public class CalculatorImpl implements Calculator, CalculatorEventListener { return eventData; } - /* - ********************************************************************** - * - * EVENTS HANDLER - * - ********************************************************************** - */ + @Subscribe + public void onEditorChanged(@Nonnull Editor.ChangedEvent e) { + if (!calculateOnFly) { + return; + } + if (TextUtils.equals(e.newState.text, e.oldState.text)) { + return; + } + evaluate(JsclOperation.numeric, e.newState.getTextString(), e.newState.id); + } @Override public void onCalculatorEvent(@Nonnull CalculatorEventData calculatorEventData, @Nonnull CalculatorEventType calculatorEventType, @Nullable Object data) { switch (calculatorEventType) { - case editor_state_changed: - if (calculateOnFly) { - final CalculatorEditorChangeEventData editorChangeEventData = (CalculatorEditorChangeEventData) data; - - final String newText = editorChangeEventData.getNewValue().getTextString(); - final String oldText = editorChangeEventData.getOldValue().getTextString(); - - if (!newText.equals(oldText)) { - evaluate(JsclOperation.numeric, editorChangeEventData.getNewValue().getTextString(), calculatorEventData.getSequenceId()); - } - } - break; - case display_state_changed: onDisplayStateChanged((CalculatorDisplayChangeEventData) data); break; 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 75a84551..52af4769 100644 --- a/app/src/main/java/org/solovyev/android/calculator/Editor.java +++ b/app/src/main/java/org/solovyev/android/calculator/Editor.java @@ -23,8 +23,8 @@ package org.solovyev.android.calculator; import org.solovyev.android.Check; -import org.solovyev.android.calculator.history.HistoryState; import org.solovyev.android.calculator.history.EditorHistoryState; +import org.solovyev.android.calculator.history.HistoryState; import org.solovyev.android.calculator.text.TextProcessor; import org.solovyev.android.calculator.text.TextProcessorEditorResult; import org.solovyev.common.text.Strings; @@ -33,16 +33,32 @@ import javax.annotation.Nonnull; import javax.annotation.Nullable; import static java.lang.Math.min; -import static org.solovyev.android.calculator.CalculatorEditorChangeEventData.newChangeEventData; -import static org.solovyev.android.calculator.CalculatorEventType.editor_state_changed; -import static org.solovyev.android.calculator.CalculatorEventType.editor_state_changed_light; public class Editor implements CalculatorEventListener { private static final String TAG = App.subTag("Editor"); - @Nonnull - private final Calculator calculator; + public static class ChangedEvent { + @Nonnull + public final EditorState oldState; + @Nonnull + public final EditorState newState; + + private ChangedEvent(@Nonnull EditorState oldState, @Nonnull EditorState newState) { + this.oldState = oldState; + this.newState = newState; + } + } + + public static class CursorMovedEvent { + @Nonnull + public final EditorState state; + + public CursorMovedEvent(@Nonnull EditorState state) { + this.state = state; + } + } + @Nonnull private final CalculatorEventHolder lastEventHolder; @Nullable @@ -53,9 +69,8 @@ public class Editor implements CalculatorEventListener { private EditorState state = EditorState.empty(); public Editor(@Nonnull Calculator calculator, @Nullable TextProcessor textProcessor) { - this.calculator = calculator; this.textProcessor = textProcessor; - this.calculator.addCalculatorEventListener(this); + calculator.addCalculatorEventListener(this); this.lastEventHolder = new CalculatorEventHolder(CalculatorUtils.createFirstEventDataId()); } @@ -85,11 +100,7 @@ public class Editor implements CalculatorEventListener { return state; } - public void setState(@Nonnull EditorState state) { - setState(state, true); - } - - private void setState(@Nonnull EditorState newState, boolean majorChanges) { + public void onTextChanged(@Nonnull EditorState newState) { Check.isMainThread(); if (textProcessor != null) { try { @@ -104,17 +115,16 @@ public class Editor implements CalculatorEventListener { if (view != null) { view.setState(newState); } - fireStateChangedEvent(majorChanges, oldState, newState); + App.getBus().post(new ChangedEvent(oldState, newState)); } - private void fireStateChangedEvent(boolean majorChanges, @Nonnull EditorState oldViewState, @Nonnull EditorState newViewState) { + private void onSelectionChanged(@Nonnull EditorState newState) { Check.isMainThread(); - - if (majorChanges) { - calculator.fireCalculatorEvent(editor_state_changed, newChangeEventData(oldViewState, newViewState)); - } else { - calculator.fireCalculatorEvent(editor_state_changed_light, newChangeEventData(oldViewState, newViewState)); + state = newState; + if (view != null) { + view.setState(newState); } + App.getBus().post(new CursorMovedEvent(newState)); } @Override @@ -139,9 +149,9 @@ public class Editor implements CalculatorEventListener { private EditorState newSelectionViewState(int newSelection) { Check.isMainThread(); if (state.selection != newSelection) { - final EditorState result = EditorState.newSelection(state, newSelection); - setState(result, false); - return result; + final EditorState newState = EditorState.forNewSelection(state, newSelection); + onSelectionChanged(newState); + return newState; } else { return state; } @@ -186,7 +196,7 @@ public class Editor implements CalculatorEventListener { final String text = state.getTextString(); if (selection > 0 && text.length() > 0 && selection <= text.length()) { final EditorState newState = EditorState.create(text.substring(0, selection - 1) + text.substring(selection, text.length()), selection - 1); - setState(newState); + onTextChanged(newState); return newState; } else { return state; @@ -203,18 +213,16 @@ public class Editor implements CalculatorEventListener { public EditorState setText(@Nonnull String text) { Check.isMainThread(); final EditorState result = EditorState.create(text, text.length()); - setState(result); + onTextChanged(result); return result; } @Nonnull public EditorState setText(@Nonnull String text, int selection) { Check.isMainThread(); - selection = clamp(selection, text); - - final EditorState result = EditorState.create(text, selection); - setState(result); - return result; + final EditorState state = EditorState.create(text, clamp(selection, text)); + onTextChanged(state); + return state; } @Nonnull @@ -233,7 +241,7 @@ public class Editor implements CalculatorEventListener { int newSelection = clamp(text.length() + selection + selectionOffset, newTextLength); final EditorState newState = EditorState.create(oldText.substring(0, selection) + text + oldText.substring(selection), newSelection); - setState(newState); + onTextChanged(newState); return newState; } @@ -249,8 +257,8 @@ public class Editor implements CalculatorEventListener { Check.isMainThread(); selection = clamp(selection, state.text); - final EditorState result = EditorState.newSelection(state, selection); - setState(result, false); + final EditorState result = EditorState.forNewSelection(state, selection); + onSelectionChanged(result); return result; } 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 d5d03738..cea90fb4 100644 --- a/app/src/main/java/org/solovyev/android/calculator/EditorState.java +++ b/app/src/main/java/org/solovyev/android/calculator/EditorState.java @@ -22,13 +22,16 @@ package org.solovyev.android.calculator; -import java.io.Serializable; +import org.solovyev.android.Check; import javax.annotation.Nonnull; import javax.annotation.Nullable; -public class EditorState implements Serializable { +public class EditorState { + private static long counter; + + public final long id; @Nonnull public final CharSequence text; public final int selection; @@ -40,6 +43,8 @@ public class EditorState implements Serializable { } private EditorState(@Nonnull CharSequence text, int selection) { + Check.isMainThread(); + this.id = counter++; this.text = text; this.selection = selection; } @@ -50,7 +55,7 @@ public class EditorState implements Serializable { } @Nonnull - public static EditorState newSelection(@Nonnull EditorState state, int selection) { + public static EditorState forNewSelection(@Nonnull EditorState state, int selection) { return new EditorState(state.text, selection); } diff --git a/app/src/main/java/org/solovyev/android/calculator/history/CalculatorHistoryImpl.java b/app/src/main/java/org/solovyev/android/calculator/history/CalculatorHistoryImpl.java index 19102e88..061d20e8 100644 --- a/app/src/main/java/org/solovyev/android/calculator/history/CalculatorHistoryImpl.java +++ b/app/src/main/java/org/solovyev/android/calculator/history/CalculatorHistoryImpl.java @@ -22,6 +22,7 @@ package org.solovyev.android.calculator.history; +import com.squareup.otto.Subscribe; import org.solovyev.android.calculator.*; import org.solovyev.common.history.HistoryAction; import org.solovyev.common.history.HistoryHelper; @@ -54,6 +55,7 @@ public class CalculatorHistoryImpl implements CalculatorHistory { public CalculatorHistoryImpl(@Nonnull Calculator calculator) { calculator.addCalculatorEventListener(this); + App.getBus().register(this); } @Override @@ -242,11 +244,16 @@ public class CalculatorHistoryImpl implements CalculatorHistory { this.savedHistory.remove(historyState); } + @Subscribe + public void onEditorChanged(@Nonnull Editor.ChangedEvent e) { + lastEditorViewState = e.newState; + } + @Override public void onCalculatorEvent(@Nonnull CalculatorEventData calculatorEventData, @Nonnull CalculatorEventType calculatorEventType, @Nullable Object data) { - if (calculatorEventType.isOfType(editor_state_changed, display_state_changed, manual_calculation_requested)) { + if (calculatorEventType.isOfType(display_state_changed, manual_calculation_requested)) { final CalculatorEventHolder.Result result = lastEventData.apply(calculatorEventData); @@ -255,10 +262,6 @@ public class CalculatorHistoryImpl implements CalculatorHistory { case manual_calculation_requested: lastEditorViewState = (EditorState) data; break; - case editor_state_changed: - final CalculatorEditorChangeEventData editorChangeData = (CalculatorEditorChangeEventData) data; - lastEditorViewState = editorChangeData.getNewValue(); - break; case display_state_changed: if (result.isSameSequence()) { if (lastEditorViewState != null) { diff --git a/app/src/main/java/org/solovyev/android/calculator/history/History.java b/app/src/main/java/org/solovyev/android/calculator/history/History.java index 7abf636b..eefa6f37 100644 --- a/app/src/main/java/org/solovyev/android/calculator/history/History.java +++ b/app/src/main/java/org/solovyev/android/calculator/history/History.java @@ -31,6 +31,7 @@ import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.io.StringWriter; import java.util.ArrayList; +import java.util.Collection; import java.util.List; @Root @@ -77,6 +78,10 @@ public class History { items.add(state); } + public void addAll(@Nonnull Collection states) { + items.addAll(states); + } + public void clear() { items.clear(); } diff --git a/app/src/main/java/org/solovyev/android/calculator/onscreen/CalculatorOnscreenService.java b/app/src/main/java/org/solovyev/android/calculator/onscreen/CalculatorOnscreenService.java index f66a84ca..2743d895 100644 --- a/app/src/main/java/org/solovyev/android/calculator/onscreen/CalculatorOnscreenService.java +++ b/app/src/main/java/org/solovyev/android/calculator/onscreen/CalculatorOnscreenService.java @@ -33,16 +33,10 @@ import android.support.v4.app.NotificationCompat; import android.util.DisplayMetrics; import android.view.WindowManager; +import com.squareup.otto.Subscribe; +import org.solovyev.android.Check; import org.solovyev.android.Views; -import org.solovyev.android.calculator.App; -import org.solovyev.android.calculator.CalculatorDisplayChangeEventData; -import org.solovyev.android.calculator.CalculatorEditorChangeEventData; -import org.solovyev.android.calculator.CalculatorEventData; -import org.solovyev.android.calculator.CalculatorEventListener; -import org.solovyev.android.calculator.CalculatorEventType; -import org.solovyev.android.calculator.Locator; -import org.solovyev.android.calculator.Preferences; -import org.solovyev.android.calculator.R; +import org.solovyev.android.calculator.*; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -58,13 +52,9 @@ public class CalculatorOnscreenService extends Service implements OnscreenViewLi private static final String SHOW_WINDOW_ACTION = "org.solovyev.android.calculator.onscreen.SHOW_WINDOW"; private static final String SHOW_NOTIFICATION_ACTION = "org.solovyev.android.calculator.onscreen.SHOW_NOTIFICATION"; private static final int NOTIFICATION_ID = 9031988; // my birthday =) - @Nonnull + private CalculatorOnscreenView view; - private boolean compatibilityStart = true; - - private boolean viewCreated = false; - @Nonnull private static Class getIntentListenerClass() { return INTENT_LISTENER_CLASS; @@ -93,98 +83,68 @@ public class CalculatorOnscreenService extends Service implements OnscreenViewLi return null; } - @Override - public void onCreate() { - super.onCreate(); - App.getPreferences().registerOnSharedPreferenceChangeListener(this); - } - private void createView() { - if (!viewCreated) { - final WindowManager wm = ((WindowManager) this.getSystemService(Context.WINDOW_SERVICE)); - - final DisplayMetrics dm = getResources().getDisplayMetrics(); - - int twoThirdWidth = 2 * wm.getDefaultDisplay().getWidth() / 3; - int twoThirdHeight = 2 * wm.getDefaultDisplay().getHeight() / 3; - - twoThirdWidth = Math.min(twoThirdWidth, twoThirdHeight); - twoThirdHeight = Math.max(twoThirdWidth, getHeight(twoThirdWidth)); - - final int baseWidth = Views.toPixels(dm, 300); - final int width0 = Math.min(twoThirdWidth, baseWidth); - final int height0 = Math.min(twoThirdHeight, getHeight(baseWidth)); - - final int width = Math.min(width0, height0); - final int height = Math.max(width0, height0); - - view = CalculatorOnscreenView.create(this, CalculatorOnscreenViewState.create(width, height, -1, -1), this); - view.show(); - - startCalculatorListening(); - view.updateEditorState(Locator.getInstance().getEditor().getState()); - view.updateDisplayState(Locator.getInstance().getDisplay().getViewState()); - - viewCreated = true; + if (view != null) { + return; } + final WindowManager wm = ((WindowManager) this.getSystemService(Context.WINDOW_SERVICE)); + + final DisplayMetrics dm = getResources().getDisplayMetrics(); + + int twoThirdWidth = 2 * wm.getDefaultDisplay().getWidth() / 3; + int twoThirdHeight = 2 * wm.getDefaultDisplay().getHeight() / 3; + + twoThirdWidth = Math.min(twoThirdWidth, twoThirdHeight); + twoThirdHeight = Math.max(twoThirdWidth, getHeight(twoThirdWidth)); + + final int baseWidth = Views.toPixels(dm, 300); + final int width0 = Math.min(twoThirdWidth, baseWidth); + final int height0 = Math.min(twoThirdHeight, getHeight(baseWidth)); + + final int width = Math.min(width0, height0); + final int height = Math.max(width0, height0); + + view = CalculatorOnscreenView.create(this, CalculatorOnscreenViewState.create(width, height, -1, -1), this); + view.show(); + view.updateEditorState(Locator.getInstance().getEditor().getState()); + view.updateDisplayState(Locator.getInstance().getDisplay().getViewState()); + + App.getBus().register(this); + App.getPreferences().registerOnSharedPreferenceChangeListener(this); } private int getHeight(int width) { return 4 * width / 3; } - private void startCalculatorListening() { - Locator.getInstance().getCalculator().addCalculatorEventListener(this); - } - - private void stopCalculatorListening() { - Locator.getInstance().getCalculator().removeCalculatorEventListener(this); - } - @Override public void onDestroy() { - App.getPreferences().unregisterOnSharedPreferenceChangeListener(this); - stopCalculatorListening(); - if (viewCreated) { - this.view.hide(); + if (view != null) { + App.getPreferences().unregisterOnSharedPreferenceChangeListener(this); + App.getBus().unregister(this); + view.hide(); + view = null; } super.onDestroy(); } - @Override - public void onStart(Intent intent, int startId) { - super.onStart(intent, startId); - - if (this.compatibilityStart) { - handleStart(intent); - } - } - @Override public int onStartCommand(Intent intent, int flags, int startId) { - - final int result; - try { - this.compatibilityStart = false; - result = super.onStartCommand(intent, flags, startId); - handleStart(intent); - } finally { - this.compatibilityStart = true; - } - + final int result = super.onStartCommand(intent, flags, startId); + handleStart(intent); return result; } private void handleStart(@Nullable Intent intent) { - if (intent != null) { - - if (isShowWindowIntent(intent)) { - hideNotification(); - createView(); - App.getGa().onFloatingCalculatorOpened(); - } else if (isShowNotificationIntent(intent)) { - showNotification(); - } + if (intent == null) { + return; + } + if (isShowWindowIntent(intent)) { + hideNotification(); + createView(); + App.getGa().onFloatingCalculatorOpened(); + } else if (isShowNotificationIntent(intent)) { + showNotification(); } } @@ -229,10 +189,6 @@ public class CalculatorOnscreenService extends Service implements OnscreenViewLi @Override public void onCalculatorEvent(@Nonnull CalculatorEventData calculatorEventData, @Nonnull CalculatorEventType calculatorEventType, @Nullable Object data) { switch (calculatorEventType) { - case editor_state_changed: - case editor_state_changed_light: - view.updateEditorState(((CalculatorEditorChangeEventData) data).getNewValue()); - break; case display_state_changed: view.updateDisplayState(((CalculatorDisplayChangeEventData) data).getNewValue()); break; @@ -241,12 +197,23 @@ public class CalculatorOnscreenService extends Service implements OnscreenViewLi @Override public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { - if (viewCreated) { - if (Preferences.Gui.theme.isSameKey(key) || Preferences.Onscreen.theme.isSameKey(key)) { - stopSelf(); - CalculatorOnscreenService.showOnscreenView(this); - } + Check.isNotNull(view); + if (Preferences.Gui.theme.isSameKey(key) || Preferences.Onscreen.theme.isSameKey(key)) { + stopSelf(); + CalculatorOnscreenService.showOnscreenView(this); } } + + @Subscribe + public void onEditorChanged(@Nonnull Editor.ChangedEvent e) { + Check.isNotNull(view); + view.updateEditorState(e.newState); + } + + @Subscribe + public void onCursorMoved(@Nonnull Editor.CursorMovedEvent e) { + Check.isNotNull(view); + view.updateEditorState(e.state); + } } diff --git a/app/src/main/java/org/solovyev/android/calculator/onscreen/CalculatorOnscreenView.java b/app/src/main/java/org/solovyev/android/calculator/onscreen/CalculatorOnscreenView.java index cd7652db..8bca7552 100644 --- a/app/src/main/java/org/solovyev/android/calculator/onscreen/CalculatorOnscreenView.java +++ b/app/src/main/java/org/solovyev/android/calculator/onscreen/CalculatorOnscreenView.java @@ -30,27 +30,14 @@ import android.graphics.drawable.Drawable; import android.preference.PreferenceManager; import android.util.DisplayMetrics; import android.util.Log; -import android.view.Gravity; -import android.view.HapticFeedbackConstants; -import android.view.MotionEvent; -import android.view.View; -import android.view.WindowManager; +import android.view.*; import android.widget.ImageView; - -import org.solovyev.android.calculator.AndroidCalculatorDisplayView; -import org.solovyev.android.calculator.App; -import org.solovyev.android.calculator.CalculatorButton; -import org.solovyev.android.calculator.DisplayState; -import org.solovyev.android.calculator.EditorState; -import org.solovyev.android.calculator.EditorView; -import org.solovyev.android.calculator.Preferences; -import org.solovyev.android.calculator.R; +import org.solovyev.android.calculator.*; import org.solovyev.android.prefs.Preference; -import java.util.Locale; - import javax.annotation.Nonnull; import javax.annotation.Nullable; +import java.util.Locale; /** * User: serso @@ -123,24 +110,12 @@ public class CalculatorOnscreenView { ********************************************************************** */ - private boolean minimized = false; + private boolean minimized; + private boolean attached; + private boolean folded; + private boolean initialized; + private boolean shown; - private boolean attached = false; - - private boolean folded = false; - - private boolean initialized = false; - - private boolean hidden = true; - - - /* - ********************************************************************** - * - * CONSTRUCTORS - * - ********************************************************************** - */ private CalculatorOnscreenView() { } @@ -167,14 +142,6 @@ public class CalculatorOnscreenView { return result; } - /* - ********************************************************************** - * - * METHODS - * - ********************************************************************** - */ - public static void persistState(@Nonnull Context context, @Nonnull CalculatorOnscreenViewState state) { final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context); viewStatePreference.putPreference(preferences, state); @@ -195,14 +162,6 @@ public class CalculatorOnscreenView { displayView.setState(displayState); } - /* - ********************************************************************** - * - * LIFECYCLE - * - ********************************************************************** - */ - public void updateEditorState(@Nonnull EditorState editorState) { checkInit(); editorView.setState(editorState); @@ -212,86 +171,86 @@ public class CalculatorOnscreenView { checkInit(); final WindowManager.LayoutParams params = (WindowManager.LayoutParams) root.getLayoutParams(); - params.height = height; - getWindowManager().updateViewLayout(root, params); } private void init() { + if (initialized) { + return; + } - if (!initialized) { - for (final CalculatorButton widgetButton : CalculatorButton.values()) { - final View button = root.findViewById(widgetButton.getButtonId()); - if (button != null) { - button.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - if (widgetButton.onClick()) { - v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY); - } - if (widgetButton == CalculatorButton.app) { - minimize(); - } - } - }); - button.setOnLongClickListener(new View.OnLongClickListener() { - @Override - public boolean onLongClick(View v) { - if (widgetButton.onLongClick()) { - v.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS); - } - return true; - } - }); - } + for (final CalculatorButton widgetButton : CalculatorButton.values()) { + final View button = root.findViewById(widgetButton.getButtonId()); + if (button == null) { + continue; } - - final WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); - - header = root.findViewById(R.id.onscreen_header); - headerTitle = (ImageView) header.findViewById(R.id.onscreen_title); - headerTitleDrawable = headerTitle.getDrawable(); - headerTitle.setImageDrawable(null); - content = root.findViewById(R.id.onscreen_content); - - displayView = (AndroidCalculatorDisplayView) root.findViewById(R.id.calculator_display); - displayView.init(this.context, false); - - editorView = (EditorView) root.findViewById(R.id.calculator_editor); - - final View onscreenFoldButton = root.findViewById(R.id.onscreen_fold_button); - onscreenFoldButton.setOnClickListener(new View.OnClickListener() { + button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - if (folded) { - unfold(); - } else { - fold(); + if (widgetButton.onClick()) { + v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY); + } + if (widgetButton == CalculatorButton.app) { + minimize(); } } }); - - final View onscreenHideButton = root.findViewById(R.id.onscreen_minimize_button); - onscreenHideButton.setOnClickListener(new View.OnClickListener() { + button.setOnLongClickListener(new View.OnLongClickListener() { @Override - public void onClick(View v) { - minimize(); + public boolean onLongClick(View v) { + if (widgetButton.onLongClick()) { + v.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS); + } + return true; } }); - - root.findViewById(R.id.onscreen_close_button).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - hide(); - } - }); - - headerTitle.setOnTouchListener(new WindowDragTouchListener(wm, root)); - - initialized = true; } + final WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); + + header = root.findViewById(R.id.onscreen_header); + headerTitle = (ImageView) header.findViewById(R.id.onscreen_title); + headerTitleDrawable = headerTitle.getDrawable(); + headerTitle.setImageDrawable(null); + content = root.findViewById(R.id.onscreen_content); + + displayView = (AndroidCalculatorDisplayView) root.findViewById(R.id.calculator_display); + displayView.init(this.context, false); + + editorView = (EditorView) root.findViewById(R.id.calculator_editor); + + final View onscreenFoldButton = root.findViewById(R.id.onscreen_fold_button); + onscreenFoldButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (folded) { + unfold(); + } else { + fold(); + } + } + }); + + final View onscreenHideButton = root.findViewById(R.id.onscreen_minimize_button); + onscreenHideButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + minimize(); + } + }); + + root.findViewById(R.id.onscreen_close_button).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + hide(); + } + }); + + headerTitle.setOnTouchListener(new WindowDragTouchListener(wm, root)); + + initialized = true; + } private void checkInit() { @@ -301,12 +260,13 @@ public class CalculatorOnscreenView { } public void show() { - if (hidden) { - init(); - attach(); - - hidden = false; + if (shown) { + return; } + init(); + attach(); + + shown = true; } public void attach() { @@ -376,19 +336,19 @@ public class CalculatorOnscreenView { public void hide() { checkInit(); - - if (!hidden) { - - persistState(context, getCurrentState(!folded)); - - detach(); - - if (viewListener != null) { - viewListener.onViewHidden(); - } - - hidden = true; + if (!shown) { + return; } + + persistState(context, getCurrentState(!folded)); + + detach(); + + if (viewListener != null) { + viewListener.onViewHidden(); + } + + shown = false; } @Nonnull diff --git a/app/src/test/java/org/solovyev/android/calculator/AndroidEditorViewTest.java b/app/src/test/java/org/solovyev/android/calculator/AndroidEditorViewTest.java index a3b44e3b..2748e848 100644 --- a/app/src/test/java/org/solovyev/android/calculator/AndroidEditorViewTest.java +++ b/app/src/test/java/org/solovyev/android/calculator/AndroidEditorViewTest.java @@ -30,6 +30,7 @@ import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.RobolectricGradleTestRunner; +import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; import org.solovyev.common.text.Strings; @@ -62,7 +63,7 @@ public class AndroidEditorViewTest { @Test public void testCreation() throws Exception { - new EditorView(CalculatorApplication.getInstance()); + new EditorView(RuntimeEnvironment.application); } @Test diff --git a/app/src/test/java/org/solovyev/android/calculator/CalculatorBroadcasterTest.java b/app/src/test/java/org/solovyev/android/calculator/CalculatorBroadcasterTest.java deleted file mode 100644 index c3fcdff1..00000000 --- a/app/src/test/java/org/solovyev/android/calculator/CalculatorBroadcasterTest.java +++ /dev/null @@ -1,70 +0,0 @@ -package org.solovyev.android.calculator; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.os.Build; -import org.hamcrest.BaseMatcher; -import org.hamcrest.Description; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mockito; -import org.robolectric.RobolectricGradleTestRunner; -import org.robolectric.annotation.Config; -import org.robolectric.shadows.ShadowPreferenceManager; - -import javax.annotation.Nonnull; - -import static org.mockito.Matchers.argThat; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.robolectric.RuntimeEnvironment.application; -import static org.solovyev.android.calculator.CalculatorBroadcaster.ACTION_DISPLAY_STATE_CHANGED; -import static org.solovyev.android.calculator.CalculatorBroadcaster.ACTION_EDITOR_STATE_CHANGED; -import static org.solovyev.android.calculator.CalculatorEventType.*; - -@Config(constants = BuildConfig.class, sdk = Build.VERSION_CODES.LOLLIPOP) -@RunWith(RobolectricGradleTestRunner.class) -public class CalculatorBroadcasterTest { - - @Nonnull - private CalculatorBroadcaster broadcaster; - - @Before - public void setUp() throws Exception { - broadcaster = new CalculatorBroadcaster(application, ShadowPreferenceManager.getDefaultSharedPreferences(application)); - } - - @Test - public void testShouldSendEditorStateChangedIntent() throws Exception { - assertIntentSent(editor_state_changed, ACTION_EDITOR_STATE_CHANGED); - } - - @Test - public void testShouldSendEditorStateChangedLiteIntent() throws Exception { - assertIntentSent(editor_state_changed_light, ACTION_EDITOR_STATE_CHANGED); - } - - @Test - public void testShouldSendDisplayStateChangedIntent() throws Exception { - assertIntentSent(display_state_changed, ACTION_DISPLAY_STATE_CHANGED); - } - - private void assertIntentSent(@Nonnull CalculatorEventType eventType, final String expectedAction) { - final BroadcastReceiver receiver = Mockito.mock(BroadcastReceiver.class); - application.registerReceiver(receiver, new IntentFilter(expectedAction)); - broadcaster.onCalculatorEvent(CalculatorEventDataImpl.newInstance(1L, 1L), eventType, null); - verify(receiver, times(1)).onReceive(Mockito.any(), argThat(new BaseMatcher() { - @Override - public boolean matches(Object o) { - return ((Intent) o).getAction().equals(expectedAction); - } - - @Override - public void describeTo(Description description) { - } - })); - } -} diff --git a/app/src/test/java/org/solovyev/android/calculator/EditorStateTest.java b/app/src/test/java/org/solovyev/android/calculator/EditorStateTest.java deleted file mode 100644 index 4b873abd..00000000 --- a/app/src/test/java/org/solovyev/android/calculator/EditorStateTest.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2013 serso aka se.solovyev - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * Contact details - * - * Email: se.solovyev@gmail.com - * Site: http://se.solovyev.org - */ - -package org.solovyev.android.calculator; - -import org.junit.Assert; -import org.junit.Test; - -/** - * User: serso - * Date: 10/20/12 - * Time: 12:31 PM - */ -public class EditorStateTest { - - @Test - public void testSerialization() throws Exception { - CalculatorTestUtils.testSerialization(EditorState.empty()); - - EditorState out = CalculatorTestUtils.testSerialization(EditorState.create("treter", 2)); - Assert.assertEquals(2, out.getSelection()); - Assert.assertEquals("treter", out.getText()); - } -} diff --git a/app/src/test/java/org/solovyev/android/calculator/EditorTest.java b/app/src/test/java/org/solovyev/android/calculator/EditorTest.java index 690dfa81..4310ec58 100644 --- a/app/src/test/java/org/solovyev/android/calculator/EditorTest.java +++ b/app/src/test/java/org/solovyev/android/calculator/EditorTest.java @@ -48,52 +48,52 @@ public class EditorTest extends AbstractCalculatorTest { public void testInsert() throws Exception { EditorState viewState = this.editor.getState(); - Assert.assertEquals("", viewState.getText()); - Assert.assertEquals(0, viewState.getSelection()); + Assert.assertEquals("", viewState.getTextString()); + Assert.assertEquals(0, viewState.selection); viewState = this.editor.insert(""); - Assert.assertEquals("", viewState.getText()); - Assert.assertEquals(0, viewState.getSelection()); + Assert.assertEquals("", viewState.getTextString()); + Assert.assertEquals(0, viewState.selection); viewState = this.editor.insert("test"); - Assert.assertEquals("test", viewState.getText()); - Assert.assertEquals(4, viewState.getSelection()); + Assert.assertEquals("test", viewState.getTextString()); + Assert.assertEquals(4, viewState.selection); viewState = this.editor.insert("test"); - Assert.assertEquals("testtest", viewState.getText()); - Assert.assertEquals(8, viewState.getSelection()); + Assert.assertEquals("testtest", viewState.getTextString()); + Assert.assertEquals(8, viewState.selection); viewState = this.editor.insert(""); - Assert.assertEquals("testtest", viewState.getText()); - Assert.assertEquals(8, viewState.getSelection()); + Assert.assertEquals("testtest", viewState.getTextString()); + Assert.assertEquals(8, viewState.selection); viewState = this.editor.insert("1234567890"); - Assert.assertEquals("testtest1234567890", viewState.getText()); - Assert.assertEquals(18, viewState.getSelection()); + Assert.assertEquals("testtest1234567890", viewState.getTextString()); + Assert.assertEquals(18, viewState.selection); viewState = this.editor.moveCursorLeft(); viewState = this.editor.insert("9"); - Assert.assertEquals("testtest12345678990", viewState.getText()); - Assert.assertEquals(18, viewState.getSelection()); + Assert.assertEquals("testtest12345678990", viewState.getTextString()); + Assert.assertEquals(18, viewState.selection); viewState = this.editor.setCursorOnStart(); viewState = this.editor.insert("9"); - Assert.assertEquals("9testtest12345678990", viewState.getText()); - Assert.assertEquals(1, viewState.getSelection()); + Assert.assertEquals("9testtest12345678990", viewState.getTextString()); + Assert.assertEquals(1, viewState.selection); viewState = this.editor.erase(); viewState = this.editor.insert("9"); - Assert.assertEquals("9testtest12345678990", viewState.getText()); - Assert.assertEquals(1, viewState.getSelection()); + Assert.assertEquals("9testtest12345678990", viewState.getTextString()); + Assert.assertEquals(1, viewState.selection); viewState = this.editor.insert("öäü"); - Assert.assertEquals("9öäütesttest12345678990", viewState.getText()); + Assert.assertEquals("9öäütesttest12345678990", viewState.getTextString()); this.editor.setCursorOnEnd(); viewState = this.editor.insert("öäü"); - Assert.assertEquals("9öäütesttest12345678990öäü", viewState.getText()); + Assert.assertEquals("9öäütesttest12345678990öäü", viewState.getTextString()); } @Test @@ -101,39 +101,39 @@ public class EditorTest extends AbstractCalculatorTest { this.editor.setText(""); this.editor.erase(); - Assert.assertEquals("", this.editor.getState().getText()); + Assert.assertEquals("", this.editor.getState().getTextString()); this.editor.setText("test"); this.editor.erase(); - Assert.assertEquals("tes", this.editor.getState().getText()); + Assert.assertEquals("tes", this.editor.getState().getTextString()); this.editor.erase(); - Assert.assertEquals("te", this.editor.getState().getText()); + Assert.assertEquals("te", this.editor.getState().getTextString()); this.editor.erase(); - Assert.assertEquals("t", this.editor.getState().getText()); + Assert.assertEquals("t", this.editor.getState().getTextString()); this.editor.erase(); - Assert.assertEquals("", this.editor.getState().getText()); + Assert.assertEquals("", this.editor.getState().getTextString()); this.editor.erase(); - Assert.assertEquals("", this.editor.getState().getText()); + Assert.assertEquals("", this.editor.getState().getTextString()); this.editor.setText("1234"); this.editor.moveCursorLeft(); this.editor.erase(); - Assert.assertEquals("124", this.editor.getState().getText()); + Assert.assertEquals("124", this.editor.getState().getTextString()); this.editor.erase(); - Assert.assertEquals("14", this.editor.getState().getText()); + Assert.assertEquals("14", this.editor.getState().getTextString()); this.editor.erase(); - Assert.assertEquals("4", this.editor.getState().getText()); + Assert.assertEquals("4", this.editor.getState().getTextString()); this.editor.setText("1"); this.editor.moveCursorLeft(); this.editor.erase(); - Assert.assertEquals("1", this.editor.getState().getText()); + Assert.assertEquals("1", this.editor.getState().getTextString()); } @Test @@ -141,91 +141,91 @@ public class EditorTest extends AbstractCalculatorTest { this.editor.setText(""); EditorState viewState = this.editor.moveSelection(0); - Assert.assertEquals(0, viewState.getSelection()); + Assert.assertEquals(0, viewState.selection); viewState = this.editor.moveSelection(2); - Assert.assertEquals(0, viewState.getSelection()); + Assert.assertEquals(0, viewState.selection); viewState = this.editor.moveSelection(100); - Assert.assertEquals(0, viewState.getSelection()); + Assert.assertEquals(0, viewState.selection); viewState = this.editor.moveSelection(-3); - Assert.assertEquals(0, viewState.getSelection()); + Assert.assertEquals(0, viewState.selection); viewState = this.editor.moveSelection(-100); - Assert.assertEquals(0, viewState.getSelection()); + Assert.assertEquals(0, viewState.selection); viewState = this.editor.setText("0123456789"); viewState = this.editor.moveSelection(0); - Assert.assertEquals(10, viewState.getSelection()); + Assert.assertEquals(10, viewState.selection); viewState = this.editor.moveSelection(1); - Assert.assertEquals(10, viewState.getSelection()); + Assert.assertEquals(10, viewState.selection); viewState = this.editor.moveSelection(-2); - Assert.assertEquals(8, viewState.getSelection()); + Assert.assertEquals(8, viewState.selection); viewState = this.editor.moveSelection(1); - Assert.assertEquals(9, viewState.getSelection()); + Assert.assertEquals(9, viewState.selection); viewState = this.editor.moveSelection(-9); - Assert.assertEquals(0, viewState.getSelection()); + Assert.assertEquals(0, viewState.selection); viewState = this.editor.moveSelection(-10); - Assert.assertEquals(0, viewState.getSelection()); + Assert.assertEquals(0, viewState.selection); viewState = this.editor.moveSelection(2); - Assert.assertEquals(2, viewState.getSelection()); + Assert.assertEquals(2, viewState.selection); viewState = this.editor.moveSelection(2); - Assert.assertEquals(4, viewState.getSelection()); + Assert.assertEquals(4, viewState.selection); viewState = this.editor.moveSelection(-6); - Assert.assertEquals(0, viewState.getSelection()); + Assert.assertEquals(0, viewState.selection); } @Test public void testSetText() throws Exception { EditorState viewState = this.editor.setText("test"); - Assert.assertEquals("test", viewState.getText()); - Assert.assertEquals(4, viewState.getSelection()); + Assert.assertEquals("test", viewState.getTextString()); + Assert.assertEquals(4, viewState.selection); viewState = this.editor.setText("testtest"); - Assert.assertEquals("testtest", viewState.getText()); - Assert.assertEquals(8, viewState.getSelection()); + Assert.assertEquals("testtest", viewState.getTextString()); + Assert.assertEquals(8, viewState.selection); viewState = this.editor.setText(""); - Assert.assertEquals("", viewState.getText()); - Assert.assertEquals(0, viewState.getSelection()); + Assert.assertEquals("", viewState.getTextString()); + Assert.assertEquals(0, viewState.selection); viewState = this.editor.setText("testtest", 0); - Assert.assertEquals("testtest", viewState.getText()); - Assert.assertEquals(0, viewState.getSelection()); + Assert.assertEquals("testtest", viewState.getTextString()); + Assert.assertEquals(0, viewState.selection); viewState = this.editor.setText("testtest", 2); - Assert.assertEquals("testtest", viewState.getText()); - Assert.assertEquals(2, viewState.getSelection()); + Assert.assertEquals("testtest", viewState.getTextString()); + Assert.assertEquals(2, viewState.selection); viewState = this.editor.setText("", 0); - Assert.assertEquals("", viewState.getText()); - Assert.assertEquals(0, viewState.getSelection()); + Assert.assertEquals("", viewState.getTextString()); + Assert.assertEquals(0, viewState.selection); viewState = this.editor.setText("", 3); - Assert.assertEquals("", viewState.getText()); - Assert.assertEquals(0, viewState.getSelection()); + Assert.assertEquals("", viewState.getTextString()); + Assert.assertEquals(0, viewState.selection); viewState = this.editor.setText("", -3); - Assert.assertEquals("", viewState.getText()); - Assert.assertEquals(0, viewState.getSelection()); + Assert.assertEquals("", viewState.getTextString()); + Assert.assertEquals(0, viewState.selection); viewState = this.editor.setText("test"); - Assert.assertEquals("test", viewState.getText()); - Assert.assertEquals(4, viewState.getSelection()); + Assert.assertEquals("test", viewState.getTextString()); + Assert.assertEquals(4, viewState.selection); viewState = this.editor.setText("", 2); - Assert.assertEquals("", viewState.getText()); - Assert.assertEquals(0, viewState.getSelection()); + Assert.assertEquals("", viewState.getTextString()); + Assert.assertEquals(0, viewState.selection); } } 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 12a5a2a2..02d58c1a 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 @@ -32,9 +32,8 @@ import org.solovyev.common.equals.CollectionEqualizer; import org.solovyev.common.history.HistoryHelper; import org.solovyev.common.history.SimpleHistoryHelper; -import java.util.ArrayList; +import javax.annotation.Nonnull; import java.util.Date; -import java.util.List; import static org.junit.Assert.assertEquals; @@ -146,12 +145,12 @@ public class HistoryUtilsTest { state.setTime(date.getTime()); history.addState(state); - assertEquals(emptyHistory, History.toXml(history.getStates())); + assertEquals(emptyHistory, createHistory(history).toXml()); state.setSaved(true); - assertEquals(toXml1, History.toXml(history.getStates())); + assertEquals(toXml1, createHistory(history).toXml()); calculatorDisplay = DisplayState.createValid(JsclOperation.numeric, null, "5/6", 3); @@ -180,13 +179,12 @@ public class HistoryUtilsTest { state.setTime(date.getTime()); history.addState(state); - String xml = History.toXml(history.getStates()); + String xml = createHistory(history).toXml(); assertEquals(toXml2, xml); - final List fromXml = new ArrayList(); final HistoryHelper historyFromXml = SimpleHistoryHelper.newInstance(); - History.fromXml(xml, fromXml); - for (HistoryState historyState : fromXml) { + final History actual = History.fromXml(xml); + for (HistoryState historyState : actual.getItems()) { historyFromXml.addState(historyState); } @@ -202,4 +200,11 @@ public class HistoryUtilsTest { } Assert.assertTrue(Objects.areEqual(history.getStates(), historyFromXml.getStates(), new CollectionEqualizer(null))); } + + @Nonnull + private History createHistory(HistoryHelper history) { + final History result = new History(); + result.addAll(history.getStates()); + return result; + } }