From 7350a9ed0c8fff8d3d644c0814ee447ff88da40b Mon Sep 17 00:00:00 2001 From: serso Date: Thu, 11 Feb 2016 16:26:18 +0100 Subject: [PATCH] Numeral bases --- .../android/calculator/Calculator.java | 112 ++++------- .../CalculatorConversionEventDataImpl.java | 126 ------------ .../calculator/CalculatorEventType.java | 2 - .../android/calculator/ConversionFailure.java | 36 ---- .../calculator/ConversionFailureImpl.java | 46 ----- .../calculator/ConversionMenuItem.java | 77 -------- ...idNumeralBase.java => CppNumeralBase.java} | 33 ++-- .../solovyev/android/calculator/Display.java | 167 +++------------- .../android/calculator/DisplayFragment.java | 180 +++++++++++++++++- .../calculations/BaseConversionEvent.java | 14 ++ .../calculations/ConversionFailedEvent.java | 12 ++ .../calculations/ConversionFinishedEvent.java | 21 ++ .../converter/ConverterFragment.java | 35 +++- .../calculator/keyboard/KeyboardUi.java | 36 ++-- .../units/CalculatorNumeralBase.java | 119 ------------ .../android/AndroidNumeralBaseTest.java | 110 ----------- jscl/src/main/java/jscl/math/Expression.java | 18 +- jscl/src/main/java/jscl/math/Generic.java | 14 +- jscl/src/main/java/jscl/math/JsclInteger.java | 15 +- .../main/java/jscl/math/NumericWrapper.java | 22 ++- jscl/src/main/java/jscl/math/Rational.java | 17 +- .../main/java/jscl/math/numeric/Numeric.java | 18 +- .../src/main/java/jscl/math/numeric/Real.java | 15 ++ 23 files changed, 442 insertions(+), 803 deletions(-) delete mode 100644 app/src/main/java/org/solovyev/android/calculator/CalculatorConversionEventDataImpl.java delete mode 100644 app/src/main/java/org/solovyev/android/calculator/ConversionFailure.java delete mode 100644 app/src/main/java/org/solovyev/android/calculator/ConversionFailureImpl.java delete mode 100644 app/src/main/java/org/solovyev/android/calculator/ConversionMenuItem.java rename app/src/main/java/org/solovyev/android/calculator/{AndroidNumeralBase.java => CppNumeralBase.java} (78%) create mode 100644 app/src/main/java/org/solovyev/android/calculator/calculations/BaseConversionEvent.java create mode 100644 app/src/main/java/org/solovyev/android/calculator/calculations/ConversionFailedEvent.java create mode 100644 app/src/main/java/org/solovyev/android/calculator/calculations/ConversionFinishedEvent.java delete mode 100644 app/src/main/java/org/solovyev/android/calculator/units/CalculatorNumeralBase.java delete mode 100644 app/src/test/java/org/solovyev/android/AndroidNumeralBaseTest.java diff --git a/app/src/main/java/org/solovyev/android/calculator/Calculator.java b/app/src/main/java/org/solovyev/android/calculator/Calculator.java index e80597c2..41051cd5 100644 --- a/app/src/main/java/org/solovyev/android/calculator/Calculator.java +++ b/app/src/main/java/org/solovyev/android/calculator/Calculator.java @@ -30,12 +30,14 @@ import android.util.Log; import com.squareup.otto.Bus; import com.squareup.otto.Subscribe; +import org.solovyev.android.Check; import org.solovyev.android.calculator.calculations.CalculationCancelledEvent; import org.solovyev.android.calculator.calculations.CalculationFailedEvent; import org.solovyev.android.calculator.calculations.CalculationFinishedEvent; +import org.solovyev.android.calculator.calculations.ConversionFailedEvent; +import org.solovyev.android.calculator.calculations.ConversionFinishedEvent; import org.solovyev.android.calculator.functions.FunctionsRegistry; import org.solovyev.android.calculator.jscl.JsclOperation; -import org.solovyev.android.calculator.units.CalculatorNumeralBase; import org.solovyev.android.calculator.variables.CppVariable; import org.solovyev.common.msg.ListMessageRegistry; import org.solovyev.common.msg.Message; @@ -43,8 +45,17 @@ import org.solovyev.common.msg.MessageRegistry; import org.solovyev.common.msg.MessageType; import org.solovyev.common.text.Strings; import org.solovyev.common.units.ConversionException; -import org.solovyev.common.units.Conversions; +import jscl.JsclArithmeticException; +import jscl.JsclMathEngine; +import jscl.NumeralBase; +import jscl.NumeralBaseException; +import jscl.math.Generic; +import jscl.math.function.Constants; +import jscl.math.function.IConstant; +import jscl.text.ParseInterruptedException; + +import java.math.BigInteger; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -58,15 +69,6 @@ import javax.inject.Inject; import javax.inject.Named; import javax.inject.Singleton; -import jscl.JsclArithmeticException; -import jscl.JsclMathEngine; -import jscl.NumeralBase; -import jscl.NumeralBaseException; -import jscl.math.Generic; -import jscl.math.function.Constants; -import jscl.math.function.IConstant; -import jscl.text.ParseInterruptedException; - @Singleton public class Calculator implements SharedPreferences.OnSharedPreferenceChangeListener { @@ -111,28 +113,12 @@ public class Calculator implements SharedPreferences.OnSharedPreferenceChangeLis @Nonnull - private static String doConversion(@Nonnull Generic generic, - @Nonnull NumeralBase from, - @Nonnull NumeralBase to) throws ConversionException { - final String result; - - if (from != to) { - String fromString = generic.toString(); - if (!Strings.isEmpty(fromString)) { - try { - fromString = ToJsclTextProcessor.getInstance().process(fromString).getValue(); - } catch (ParseException e) { - // ok, problems while processing occurred - } - } - - - result = Conversions.doConversion(CalculatorNumeralBase.getConverter(), fromString, CalculatorNumeralBase.valueOf(from), CalculatorNumeralBase.valueOf(to)); - } else { - result = generic.toString(); + private static String convert(@Nonnull Generic generic, @Nonnull NumeralBase to) throws ConversionException { + final BigInteger value = generic.toBigInteger(); + if (value == null) { + throw new ConversionException(); } - - return result; + return to.toString(value); } @Nonnull @@ -142,12 +128,6 @@ public class Calculator implements SharedPreferences.OnSharedPreferenceChangeLis } @Nonnull - private CalculatorEventData nextEventData(@Nonnull Object source) { - long eventId = nextSequence(); - return CalculatorEventDataImpl.newInstance(eventId, eventId, source); - } - - @Nonnull private CalculatorEventData nextEventData(@Nonnull Long sequenceId) { long eventId = nextSequence(); return CalculatorEventDataImpl.newInstance(eventId, sequenceId); @@ -211,15 +191,6 @@ public class Calculator implements SharedPreferences.OnSharedPreferenceChangeLis } } - @Nonnull - private CalculatorConversionEventData newConversionEventData(@Nonnull Long sequenceId, - @Nonnull Generic value, - @Nonnull NumeralBase from, - @Nonnull NumeralBase to, - @Nonnull DisplayState displayViewState) { - return CalculatorConversionEventDataImpl.newInstance(nextEventData(sequenceId), value, from, to, displayViewState); - } - private void evaluateAsync(long sequence, @Nonnull JsclOperation o, @Nonnull String e) { evaluateAsync(sequence, o, e, new ListMessageRegistry()); } @@ -240,7 +211,7 @@ public class Calculator implements SharedPreferences.OnSharedPreferenceChangeLis pe = prepare(e); try { - Locator.getInstance().getEngine().getMathEngine().setMessageRegistry(mr); + mathEngine.setMessageRegistry(mr); final Generic result = o.evaluateGeneric(pe.value, mathEngine); @@ -325,38 +296,33 @@ public class Calculator implements SharedPreferences.OnSharedPreferenceChangeLis bus.post(new CalculationFailedEvent(operation, e, sequence, parseException)); } - @Nonnull - public CalculatorEventData convert(@Nonnull final Generic value, - @Nonnull final NumeralBase to) { - final CalculatorEventData eventDataId = nextEventData(); - - final DisplayState displayViewState = App.getDisplay().getState(); - final NumeralBase from = Locator.getInstance().getEngine().getMathEngine().getNumeralBase(); + public void convert(@Nonnull final DisplayState state, @Nonnull final NumeralBase to) { + final Generic value = state.getResult(); + Check.isNotNull(value); + final NumeralBase from = mathEngine.getNumeralBase(); + if (from == to) { + return; + } background.execute(new Runnable() { @Override public void run() { - final Long sequenceId = eventDataId.getSequenceId(); - - fireCalculatorEvent(newConversionEventData(sequenceId, value, from, to, displayViewState), CalculatorEventType.conversion_started, null); try { - - final String result = doConversion(value, from, to); - - fireCalculatorEvent(newConversionEventData(sequenceId, value, from, to, displayViewState), CalculatorEventType.conversion_result, result); - + final String result = convert(value, to); + bus.post(new ConversionFinishedEvent(result, to, state)); } catch (ConversionException e) { - fireCalculatorEvent(newConversionEventData(sequenceId, value, from, to, displayViewState), CalculatorEventType.conversion_failed, new ConversionFailureImpl(e)); + bus.post(new ConversionFailedEvent(state)); } } }); - - return eventDataId; } - public boolean isConversionPossible(@Nonnull Generic generic, NumeralBase from, @Nonnull NumeralBase to) { + public boolean canConvert(@Nonnull Generic generic, @NonNull NumeralBase from, @Nonnull NumeralBase to) { + if(from == to) { + return false; + } try { - doConversion(generic, from, to); + convert(generic, to); return true; } catch (ConversionException e) { return false; @@ -389,15 +355,6 @@ public class Calculator implements SharedPreferences.OnSharedPreferenceChangeLis return eventData; } - @Nonnull - public CalculatorEventData fireCalculatorEvent(@Nonnull final CalculatorEventType calculatorEventType, @Nullable final Object data, @Nonnull Object source) { - final CalculatorEventData eventData = nextEventData(source); - - fireCalculatorEvent(eventData, calculatorEventType, data); - - return eventData; - } - @Subscribe public void onEditorChanged(@Nonnull Editor.ChangedEvent e) { if (!calculateOnFly) { @@ -476,4 +433,5 @@ public class Calculator implements SharedPreferences.OnSharedPreferenceChangeLis public static long nextSequence() { return SEQUENCER.incrementAndGet(); } + } diff --git a/app/src/main/java/org/solovyev/android/calculator/CalculatorConversionEventDataImpl.java b/app/src/main/java/org/solovyev/android/calculator/CalculatorConversionEventDataImpl.java deleted file mode 100644 index 6e8c1bb0..00000000 --- a/app/src/main/java/org/solovyev/android/calculator/CalculatorConversionEventDataImpl.java +++ /dev/null @@ -1,126 +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; - -import jscl.NumeralBase; -import jscl.math.Generic; - -/** - * User: Solovyev_S - * Date: 24.09.12 - * Time: 16:48 - */ -public class CalculatorConversionEventDataImpl implements CalculatorConversionEventData { - - @Nonnull - private CalculatorEventData calculatorEventData; - - @Nonnull - private NumeralBase fromNumeralBase; - - @Nonnull - private NumeralBase toNumeralBase; - - @Nonnull - private Generic value; - - @Nonnull - private DisplayState displayState; - - private CalculatorConversionEventDataImpl() { - } - - @Nonnull - public static CalculatorConversionEventData newInstance(@Nonnull CalculatorEventData calculatorEventData, - @Nonnull Generic value, - @Nonnull NumeralBase from, - @Nonnull NumeralBase to, - @Nonnull DisplayState displayViewState) { - final CalculatorConversionEventDataImpl result = new CalculatorConversionEventDataImpl(); - - result.calculatorEventData = calculatorEventData; - result.value = value; - result.displayState = displayViewState; - result.fromNumeralBase = from; - result.toNumeralBase = to; - - return result; - } - - @Override - public long getEventId() { - return calculatorEventData.getEventId(); - } - - @Override - @Nonnull - public Long getSequenceId() { - return calculatorEventData.getSequenceId(); - } - - @Override - public Object getSource() { - return calculatorEventData.getSource(); - } - - @Override - public boolean isAfter(@Nonnull CalculatorEventData that) { - return calculatorEventData.isAfter(that); - } - - @Override - public boolean isSameSequence(@Nonnull CalculatorEventData that) { - return calculatorEventData.isSameSequence(that); - } - - @Override - public boolean isAfterSequence(@Nonnull CalculatorEventData that) { - return calculatorEventData.isAfterSequence(that); - } - - @Nonnull - @Override - public DisplayState getDisplayState() { - return this.displayState; - } - - @Override - @Nonnull - public NumeralBase getFromNumeralBase() { - return fromNumeralBase; - } - - @Override - @Nonnull - public NumeralBase getToNumeralBase() { - return toNumeralBase; - } - - @Override - @Nonnull - public Generic getValue() { - return value; - } -} 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 a4ba8362..9011a234 100644 --- a/app/src/main/java/org/solovyev/android/calculator/CalculatorEventType.java +++ b/app/src/main/java/org/solovyev/android/calculator/CalculatorEventType.java @@ -39,8 +39,6 @@ public enum CalculatorEventType { * ********************************************************************** */ - conversion_started, - // @Nonnull String conversion result conversion_result, diff --git a/app/src/main/java/org/solovyev/android/calculator/ConversionFailure.java b/app/src/main/java/org/solovyev/android/calculator/ConversionFailure.java deleted file mode 100644 index aa22ad78..00000000 --- a/app/src/main/java/org/solovyev/android/calculator/ConversionFailure.java +++ /dev/null @@ -1,36 +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: 24.09.12 - * Time: 16:12 - */ -public interface ConversionFailure { - - @Nonnull - Exception getException(); -} diff --git a/app/src/main/java/org/solovyev/android/calculator/ConversionFailureImpl.java b/app/src/main/java/org/solovyev/android/calculator/ConversionFailureImpl.java deleted file mode 100644 index fba1d178..00000000 --- a/app/src/main/java/org/solovyev/android/calculator/ConversionFailureImpl.java +++ /dev/null @@ -1,46 +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: 24.09.12 - * Time: 16:12 - */ -public class ConversionFailureImpl implements ConversionFailure { - - @Nonnull - private Exception exception; - - public ConversionFailureImpl(@Nonnull Exception exception) { - this.exception = exception; - } - - @Nonnull - @Override - public Exception getException() { - return this.exception; - } -} diff --git a/app/src/main/java/org/solovyev/android/calculator/ConversionMenuItem.java b/app/src/main/java/org/solovyev/android/calculator/ConversionMenuItem.java deleted file mode 100644 index 8342aa8a..00000000 --- a/app/src/main/java/org/solovyev/android/calculator/ConversionMenuItem.java +++ /dev/null @@ -1,77 +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 android.content.Context; - -import org.solovyev.android.calculator.jscl.JsclOperation; -import org.solovyev.android.menu.AMenuItem; - -import javax.annotation.Nonnull; - -import jscl.NumeralBase; -import jscl.math.Generic; - -/** - * User: serso - * Date: 9/21/12 - * Time: 12:11 AM - */ -enum ConversionMenuItem implements AMenuItem { - - convert_to_bin(NumeralBase.bin), - convert_to_dec(NumeralBase.dec), - convert_to_hex(NumeralBase.hex); - - @Nonnull - private final NumeralBase toNumeralBase; - - ConversionMenuItem(@Nonnull NumeralBase toNumeralBase) { - this.toNumeralBase = toNumeralBase; - } - - protected boolean isItemVisibleFor(@Nonnull Generic generic, @Nonnull JsclOperation operation) { - boolean result = false; - - if (operation == JsclOperation.numeric) { - if (generic.getConstants().isEmpty()) { - // conversion possible => return true - final NumeralBase fromNumeralBase = Locator.getInstance().getEngine().getMathEngine().getNumeralBase(); - if (fromNumeralBase != toNumeralBase) { - result = Locator.getInstance().getCalculator().isConversionPossible(generic, fromNumeralBase, this.toNumeralBase); - } - } - } - - return result; - } - - @Override - public void onClick(@Nonnull DisplayState data, @Nonnull Context context) { - final Generic result = data.getResult(); - - if (result != null) { - Locator.getInstance().getCalculator().convert(result, this.toNumeralBase); - } - } -} diff --git a/app/src/main/java/org/solovyev/android/calculator/AndroidNumeralBase.java b/app/src/main/java/org/solovyev/android/calculator/CppNumeralBase.java similarity index 78% rename from app/src/main/java/org/solovyev/android/calculator/AndroidNumeralBase.java rename to app/src/main/java/org/solovyev/android/calculator/CppNumeralBase.java index d62e74f9..014bacf9 100644 --- a/app/src/main/java/org/solovyev/android/calculator/AndroidNumeralBase.java +++ b/app/src/main/java/org/solovyev/android/calculator/CppNumeralBase.java @@ -22,17 +22,17 @@ package org.solovyev.android.calculator; -import jscl.NumeralBase; import org.solovyev.android.calculator.keyboard.KeyboardUi; -import org.solovyev.android.calculator.units.CalculatorNumeralBase; import org.solovyev.android.views.dragbutton.DirectionDragButton; import org.solovyev.android.views.dragbutton.DragDirection; +import jscl.NumeralBase; + import javax.annotation.Nonnull; -public enum AndroidNumeralBase { +public enum CppNumeralBase { - bin(CalculatorNumeralBase.bin) { + bin(NumeralBase.bin) { @Override public void toggleButtons(boolean show, @Nonnull KeyboardUi ui) { toggleButton(show, ui.button0); @@ -40,7 +40,7 @@ public enum AndroidNumeralBase { } }, - oct(CalculatorNumeralBase.oct) { + oct(NumeralBase.oct) { @Override public void toggleButtons(boolean show, @Nonnull KeyboardUi ui) { bin.toggleButtons(show, ui); @@ -53,7 +53,7 @@ public enum AndroidNumeralBase { } }, - dec(CalculatorNumeralBase.dec) { + dec(NumeralBase.dec) { @Override public void toggleButtons(boolean show, @Nonnull KeyboardUi ui) { oct.toggleButtons(show, ui); @@ -62,7 +62,7 @@ public enum AndroidNumeralBase { } }, - hex(CalculatorNumeralBase.hex) { + hex(NumeralBase.hex) { @Override public void toggleButtons(boolean show, @Nonnull KeyboardUi ui) { dec.toggleButtons(show, ui); @@ -81,17 +81,17 @@ public enum AndroidNumeralBase { }; @Nonnull - private final CalculatorNumeralBase calculatorNumeralBase; + public final NumeralBase numeralBase; - AndroidNumeralBase(@Nonnull CalculatorNumeralBase calculatorNumeralBase) { - this.calculatorNumeralBase = calculatorNumeralBase; + CppNumeralBase(@Nonnull NumeralBase numeralBase) { + this.numeralBase = numeralBase; } @Nonnull - public static AndroidNumeralBase valueOf(@Nonnull NumeralBase nb) { - for (AndroidNumeralBase androidNumeralBase : values()) { - if (androidNumeralBase.calculatorNumeralBase.getNumeralBase() == nb) { - return androidNumeralBase; + public static CppNumeralBase valueOf(@Nonnull NumeralBase nb) { + for (CppNumeralBase cppNumeralBase : values()) { + if (cppNumeralBase.numeralBase == nb) { + return cppNumeralBase; } } @@ -104,9 +104,4 @@ public enum AndroidNumeralBase { button.setShowText(show); button.invalidate(); } - - @Nonnull - public NumeralBase getNumeralBase() { - return calculatorNumeralBase.getNumeralBase(); - } } 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 9b414138..172dada7 100644 --- a/app/src/main/java/org/solovyev/android/calculator/Display.java +++ b/app/src/main/java/org/solovyev/android/calculator/Display.java @@ -22,19 +22,9 @@ package org.solovyev.android.calculator; -import static org.solovyev.android.calculator.BaseFragment.addMenu; -import static org.solovyev.android.calculator.CalculatorEventType.conversion_failed; -import static org.solovyev.android.calculator.CalculatorEventType.conversion_result; - -import android.app.Activity; import android.app.Application; import android.content.Context; -import android.support.v7.app.AlertDialog; -import android.view.ContextMenu; -import android.view.LayoutInflater; -import android.view.MenuItem; -import android.view.View; -import android.widget.TextView; +import android.support.annotation.NonNull; import com.squareup.otto.Bus; import com.squareup.otto.Subscribe; @@ -43,11 +33,11 @@ import org.solovyev.android.Check; import org.solovyev.android.calculator.calculations.CalculationCancelledEvent; import org.solovyev.android.calculator.calculations.CalculationFailedEvent; import org.solovyev.android.calculator.calculations.CalculationFinishedEvent; +import org.solovyev.android.calculator.calculations.ConversionFailedEvent; +import org.solovyev.android.calculator.calculations.ConversionFinishedEvent; import org.solovyev.android.calculator.errors.FixableErrorsActivity; -import org.solovyev.android.calculator.jscl.JsclOperation; import dagger.Lazy; -import jscl.math.Generic; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -55,10 +45,8 @@ import javax.inject.Inject; import javax.inject.Singleton; @Singleton -public class Display implements CalculatorEventListener, View.OnClickListener, View.OnCreateContextMenuListener, MenuItem.OnMenuItemClickListener { +public class Display { - @Nonnull - private final CalculatorEventHolder lastEvent; @Nonnull private final Bus bus; @Inject @@ -75,10 +63,8 @@ public class Display implements CalculatorEventListener, View.OnClickListener, V private DisplayState state = DisplayState.empty(); @Inject - public Display(@Nonnull Calculator calculator, @Nonnull Bus bus) { + public Display(@Nonnull Bus bus) { this.bus = bus; - lastEvent = new CalculatorEventHolder(CalculatorUtils.createFirstEventDataId()); - calculator.addCalculatorEventListener(this); bus.register(this); } @@ -87,12 +73,13 @@ public class Display implements CalculatorEventListener, View.OnClickListener, V copy(); } - private void copy() { + void copy() { if (!state.valid) { return; } clipboard.get().setText(state.text); - notifier.get().showMessage(CalculatorMessage.newInfoMessage(CalculatorMessages.result_copied)); + notifier.get().showMessage( + CalculatorMessage.newInfoMessage(CalculatorMessages.result_copied)); } @Subscribe @@ -124,6 +111,22 @@ public class Display implements CalculatorEventListener, View.OnClickListener, V setState(DisplayState.createError(e.operation, error, e.sequence)); } + @Subscribe + public void onConversionFinished(@NonNull ConversionFinishedEvent e) { + if (e.state.sequence != state.sequence) return; + final String result = e.numeralBase.getJsclPrefix() + e.result; + setState(DisplayState.createValid(e.state.getOperation(), e.state.getResult(), result, + e.state.sequence)); + } + + @Subscribe + public void onConversionFailed(@NonNull ConversionFailedEvent e) { + if (e.state.sequence != state.sequence) return; + setState(DisplayState.createError(e.state.getOperation(), + CalculatorMessages.getBundle().getString(CalculatorMessages.syntax_error), + e.state.sequence)); + } + public void clearView(@Nonnull DisplayView view) { Check.isMainThread(); if (this.view != view) { @@ -135,7 +138,6 @@ public class Display implements CalculatorEventListener, View.OnClickListener, V public void setView(@Nonnull DisplayView view) { Check.isMainThread(); this.view = view; - this.view.setOnClickListener(this); this.view.setState(state); } @@ -156,127 +158,6 @@ public class Display implements CalculatorEventListener, View.OnClickListener, V bus.post(new ChangedEvent(oldState, newState)); } - @Override - public void onCalculatorEvent(@Nonnull CalculatorEventData calculatorEventData, - @Nonnull CalculatorEventType calculatorEventType, - @Nullable Object data) { - if (calculatorEventType.isOfType(conversion_result, conversion_failed)) { - - final CalculatorEventHolder.Result result = lastEvent.apply(calculatorEventData); - - if (result.isNewAfter()) { - switch (calculatorEventType) { - case conversion_failed: - processConversationFailed((CalculatorConversionEventData) calculatorEventData); - break; - case conversion_result: - processConversationResult((CalculatorConversionEventData) calculatorEventData, (String) data); - break; - } - } - } - } - - private void processConversationFailed(@Nonnull CalculatorConversionEventData calculatorEventData) { - setState(DisplayState.createError(calculatorEventData.getDisplayState().getOperation(), CalculatorMessages.getBundle().getString(CalculatorMessages.syntax_error), calculatorEventData.getSequenceId())); - - } - - private void processConversationResult(@Nonnull CalculatorConversionEventData calculatorEventData, @Nonnull String result) { - // add prefix - if (calculatorEventData.getFromNumeralBase() != calculatorEventData.getToNumeralBase()) { - result = calculatorEventData.getToNumeralBase().getJsclPrefix() + result; - } - - final DisplayState displayState = calculatorEventData.getDisplayState(); - setState(DisplayState.createValid(displayState.getOperation(), displayState.getResult(), result, calculatorEventData.getSequenceId())); - } - - @Override - public void onClick(View v) { - if (state.valid) { - v.setOnCreateContextMenuListener(this); - v.showContextMenu(); - v.setOnCreateContextMenuListener(null); - } else { - showEvaluationError(v.getContext(), state.text); - } - } - - public static void showEvaluationError(@Nonnull Context context, @Nonnull final String errorMessage) { - final LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE); - - final View errorMessageView = layoutInflater.inflate(R.layout.display_error_message, null); - ((TextView) errorMessageView.findViewById(R.id.error_message_text_view)).setText(errorMessage); - - final AlertDialog.Builder builder = new AlertDialog.Builder(context, App.getTheme().alertDialogTheme) - .setPositiveButton(R.string.c_cancel, null) - .setView(errorMessageView); - - builder.create().show(); - } - - - @Override - public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { - if (!state.valid) { - return; - } - addMenu(menu, R.string.c_copy, this); - - final Generic result = state.getResult(); - final JsclOperation operation = state.getOperation(); - if (result != null) { - if (ConversionMenuItem.convert_to_bin.isItemVisibleFor(result, operation)) { - addMenu(menu, R.string.convert_to_bin, this); - } - if (ConversionMenuItem.convert_to_dec.isItemVisibleFor(result, operation)) { - addMenu(menu, R.string.convert_to_dec, this); - } - if (ConversionMenuItem.convert_to_hex.isItemVisibleFor(result, operation)) { - addMenu(menu, R.string.convert_to_hex, this); - } - if (operation == JsclOperation.numeric && result.getConstants().isEmpty()) { - addMenu(menu, R.string.c_convert, this); - } - if (Locator.getInstance().getPlotter().isPlotPossibleFor(result)) { - addMenu(menu, R.string.c_plot, this); - } - } - } - - @Override - public boolean onMenuItemClick(MenuItem item) { - final Generic result = state.getResult(); - switch (item.getItemId()) { - case R.string.c_copy: - copy(); - return true; - case R.string.convert_to_bin: - ConversionMenuItem.convert_to_bin.onClick(state, App.getApplication()); - return true; - case R.string.convert_to_dec: - ConversionMenuItem.convert_to_dec.onClick(state, App.getApplication()); - return true; - case R.string.convert_to_hex: - ConversionMenuItem.convert_to_hex.onClick(state, App.getApplication()); - return true; - case R.string.c_convert: - if (result != null) { - // FIXME: 2016-02-10 - //new NumeralBaseConverterDialog(result.toString()).show(App.getApplication()); - } - return true; - case R.string.c_plot: - if (result != null) { - Locator.getInstance().getPlotter().plot(result); - } - return true; - default: - return false; - } - } - public static class CopyOperation { } diff --git a/app/src/main/java/org/solovyev/android/calculator/DisplayFragment.java b/app/src/main/java/org/solovyev/android/calculator/DisplayFragment.java index 811499aa..9705bd4b 100644 --- a/app/src/main/java/org/solovyev/android/calculator/DisplayFragment.java +++ b/app/src/main/java/org/solovyev/android/calculator/DisplayFragment.java @@ -22,18 +22,65 @@ package org.solovyev.android.calculator; +import android.app.Activity; +import android.content.Context; import android.content.SharedPreferences; import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.support.annotation.StringRes; +import android.support.v7.app.AlertDialog; +import android.view.ContextMenu; import android.view.LayoutInflater; +import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; +import android.widget.TextView; + +import com.squareup.otto.Bus; + +import org.solovyev.android.calculator.converter.ConverterFragment; +import org.solovyev.android.calculator.jscl.JsclOperation; + import butterknife.Bind; import butterknife.ButterKnife; +import jscl.NumeralBase; +import jscl.math.Generic; import javax.annotation.Nonnull; import javax.inject.Inject; -public class DisplayFragment extends BaseFragment { +public class DisplayFragment extends BaseFragment implements View.OnClickListener, + MenuItem.OnMenuItemClickListener { + + private enum ConversionMenuItem { + + to_bin(NumeralBase.bin, R.string.convert_to_bin), + to_dec(NumeralBase.dec, R.string.convert_to_dec), + to_hex(NumeralBase.hex, R.string.convert_to_hex); + + @Nonnull + public final NumeralBase toNumeralBase; + public final int title; + + ConversionMenuItem(@Nonnull NumeralBase toNumeralBase, @StringRes int title) { + this.toNumeralBase = toNumeralBase; + this.title = title; + } + + @Nullable + public static ConversionMenuItem getByTitle(int title) { + switch (title) { + case R.string.convert_to_bin: + return to_bin; + case R.string.convert_to_dec: + return to_dec; + case R.string.convert_to_hex: + return to_hex; + } + return null; + } + } @Bind(R.id.calculator_display) DisplayView displayView; @@ -41,12 +88,10 @@ public class DisplayFragment extends BaseFragment { SharedPreferences preferences; @Inject Display display; - - @Override - protected void inject(@Nonnull AppComponent component) { - super.inject(component); - component.inject(this); - } + @Inject + Bus bus; + @Inject + Calculator calculator; @Nonnull @Override @@ -60,10 +105,18 @@ public class DisplayFragment extends BaseFragment { } @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + protected void inject(@Nonnull AppComponent component) { + super.inject(component); + component.inject(this); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { final View view = super.onCreateView(inflater, container, savedInstanceState); ButterKnife.bind(this, view); display.setView(displayView); + displayView.setOnClickListener(this); return view; } @@ -72,4 +125,115 @@ public class DisplayFragment extends BaseFragment { display.clearView(displayView); super.onDestroyView(); } + + @Override + public void onCreateContextMenu(ContextMenu menu, View v, + ContextMenu.ContextMenuInfo menuInfo) { + final DisplayState state = display.getState(); + if (!state.valid) { + return; + } + addMenu(menu, R.string.c_copy, this); + + final Generic result = state.getResult(); + final JsclOperation operation = state.getOperation(); + if (result != null) { + if (operation == JsclOperation.numeric && result.getConstants().isEmpty()) { + for (ConversionMenuItem item : ConversionMenuItem.values()) { + if (isMenuItemVisible(item, result)) { + addMenu(menu, item.title, this); + } + } + if (result.toDouble() != null) { + addMenu(menu, R.string.c_convert, this); + } + } + if (Locator.getInstance().getPlotter().isPlotPossibleFor(result)) { + addMenu(menu, R.string.c_plot, this); + } + } + } + + protected boolean isMenuItemVisible(@NonNull ConversionMenuItem menuItem, + @Nonnull Generic generic) { + final NumeralBase fromNumeralBase = + Locator.getInstance().getEngine().getMathEngine().getNumeralBase(); + if (fromNumeralBase != menuItem.toNumeralBase) { + return calculator.canConvert(generic, fromNumeralBase, menuItem.toNumeralBase); + } + + return false; + } + + @Override + public void onClick(View v) { + final DisplayState state = display.getState(); + if (state.valid) { + v.setOnCreateContextMenuListener(this); + v.showContextMenu(); + v.setOnCreateContextMenuListener(null); + } else { + showEvaluationError(v.getContext(), state.text); + } + } + + public static void showEvaluationError(@Nonnull Context context, + @Nonnull final String errorMessage) { + final LayoutInflater layoutInflater = + (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE); + + final View errorMessageView = layoutInflater.inflate(R.layout.display_error_message, null); + ((TextView) errorMessageView.findViewById(R.id.error_message_text_view)) + .setText(errorMessage); + + final AlertDialog.Builder builder = + new AlertDialog.Builder(context, App.getTheme().alertDialogTheme) + .setPositiveButton(R.string.c_cancel, null) + .setView(errorMessageView); + + builder.create().show(); + } + + @Override + public boolean onMenuItemClick(MenuItem item) { + final DisplayState state = display.getState(); + final Generic result = state.getResult(); + switch (item.getItemId()) { + case R.string.c_copy: + display.copy(); + return true; + case R.string.convert_to_bin: + case R.string.convert_to_dec: + case R.string.convert_to_hex: + final ConversionMenuItem menuItem = ConversionMenuItem.getByTitle(item.getItemId()); + if (menuItem == null) { + return false; + } + if (result != null) { + calculator.convert(state, menuItem.toNumeralBase); + } + return true; + case R.string.c_convert: + ConverterFragment.show(getActivity(), getValue(result)); + return true; + case R.string.c_plot: + if (result != null) { + Locator.getInstance().getPlotter().plot(result); + } + return true; + default: + return false; + } + } + + private static double getValue(@Nullable Generic result) { + if (result == null) { + return 1d; + } + final Double value = result.toDouble(); + if (value == null) { + return 1d; + } + return value; + } } diff --git a/app/src/main/java/org/solovyev/android/calculator/calculations/BaseConversionEvent.java b/app/src/main/java/org/solovyev/android/calculator/calculations/BaseConversionEvent.java new file mode 100644 index 00000000..2d011639 --- /dev/null +++ b/app/src/main/java/org/solovyev/android/calculator/calculations/BaseConversionEvent.java @@ -0,0 +1,14 @@ +package org.solovyev.android.calculator.calculations; + +import android.support.annotation.NonNull; + +import org.solovyev.android.calculator.DisplayState; + +public class BaseConversionEvent { + @NonNull + public final DisplayState state; + + public BaseConversionEvent(@NonNull DisplayState state) { + this.state = state; + } +} diff --git a/app/src/main/java/org/solovyev/android/calculator/calculations/ConversionFailedEvent.java b/app/src/main/java/org/solovyev/android/calculator/calculations/ConversionFailedEvent.java new file mode 100644 index 00000000..62636d8d --- /dev/null +++ b/app/src/main/java/org/solovyev/android/calculator/calculations/ConversionFailedEvent.java @@ -0,0 +1,12 @@ +package org.solovyev.android.calculator.calculations; + +import android.support.annotation.NonNull; + +import org.solovyev.android.calculator.DisplayState; + +public class ConversionFailedEvent extends BaseConversionEvent { + + public ConversionFailedEvent(@NonNull DisplayState state) { + super(state); + } +} diff --git a/app/src/main/java/org/solovyev/android/calculator/calculations/ConversionFinishedEvent.java b/app/src/main/java/org/solovyev/android/calculator/calculations/ConversionFinishedEvent.java new file mode 100644 index 00000000..7c207923 --- /dev/null +++ b/app/src/main/java/org/solovyev/android/calculator/calculations/ConversionFinishedEvent.java @@ -0,0 +1,21 @@ +package org.solovyev.android.calculator.calculations; + +import android.support.annotation.NonNull; + +import org.solovyev.android.calculator.DisplayState; + +import jscl.NumeralBase; + +public class ConversionFinishedEvent extends BaseConversionEvent { + @NonNull + public final String result; + @NonNull + public final NumeralBase numeralBase; + + public ConversionFinishedEvent(@NonNull String result, @NonNull NumeralBase numeralBase, + @NonNull DisplayState state) { + super(state); + this.result = result; + this.numeralBase = numeralBase; + } +} diff --git a/app/src/main/java/org/solovyev/android/calculator/converter/ConverterFragment.java b/app/src/main/java/org/solovyev/android/calculator/converter/ConverterFragment.java index 6eaf8c70..1a96824a 100644 --- a/app/src/main/java/org/solovyev/android/calculator/converter/ConverterFragment.java +++ b/app/src/main/java/org/solovyev/android/calculator/converter/ConverterFragment.java @@ -13,19 +13,33 @@ import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.View; import android.view.inputmethod.EditorInfo; -import android.widget.*; -import butterknife.Bind; -import butterknife.ButterKnife; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.EditText; +import android.widget.ImageButton; +import android.widget.Spinner; +import android.widget.TextView; + import org.solovyev.android.calculator.App; import org.solovyev.android.calculator.BaseDialogFragment; import org.solovyev.android.calculator.R; +import butterknife.Bind; +import butterknife.ButterKnife; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + import javax.annotation.Nonnull; import javax.measure.unit.Dimension; import javax.measure.unit.NonSI; import javax.measure.unit.SI; import javax.measure.unit.Unit; -import java.util.*; public class ConverterFragment extends BaseDialogFragment implements AdapterView.OnItemSelectedListener, View.OnFocusChangeListener, TextView.OnEditorActionListener, View.OnClickListener { @@ -36,6 +50,7 @@ public class ConverterFragment extends BaseDialogFragment private static final Map>> units = new HashMap<>(); private static final String STATE_SELECTION_FROM = "selection.from"; private static final String STATE_SELECTION_TO = "selection.to"; + private static final String EXTRA_VALUE = "value"; static { for (Unit unit : SI.getInstance().getUnits()) { @@ -88,7 +103,15 @@ public class ConverterFragment extends BaseDialogFragment } public static void show(@Nonnull FragmentActivity activity) { - App.showDialog(new ConverterFragment(), "converter", + show(activity, 1d); + } + + public static void show(@Nonnull FragmentActivity activity, double value) { + final ConverterFragment fragment = new ConverterFragment(); + final Bundle args = new Bundle(1); + args.putDouble(EXTRA_VALUE, value); + fragment.setArguments(args); + App.showDialog(fragment, "converter", activity.getSupportFragmentManager()); } @@ -134,7 +157,7 @@ public class ConverterFragment extends BaseDialogFragment swapButton.setOnClickListener(this); if (savedInstanceState == null) { - editTextFrom.setText("1"); + editTextFrom.setText(String.valueOf(getArguments().getDouble(EXTRA_VALUE, 1f))); dimensionsSpinner.setSelection(0); } else { pendingFromSelection = savedInstanceState.getInt(STATE_SELECTION_FROM, View.NO_ID); diff --git a/app/src/main/java/org/solovyev/android/calculator/keyboard/KeyboardUi.java b/app/src/main/java/org/solovyev/android/calculator/keyboard/KeyboardUi.java index 876634b6..9285c63f 100644 --- a/app/src/main/java/org/solovyev/android/calculator/keyboard/KeyboardUi.java +++ b/app/src/main/java/org/solovyev/android/calculator/keyboard/KeyboardUi.java @@ -1,5 +1,14 @@ package org.solovyev.android.calculator.keyboard; +import static jscl.NumeralBase.hex; +import static org.solovyev.android.calculator.Engine.Preferences.angleUnit; +import static org.solovyev.android.calculator.Engine.Preferences.multiplicationSign; +import static org.solovyev.android.calculator.Engine.Preferences.numeralBase; +import static org.solovyev.android.calculator.Preferences.Gui.hideNumeralBaseDigits; +import static org.solovyev.android.views.dragbutton.DragDirection.down; +import static org.solovyev.android.views.dragbutton.DragDirection.left; +import static org.solovyev.android.views.dragbutton.DragDirection.up; + import android.app.Activity; import android.app.Application; import android.content.SharedPreferences; @@ -11,11 +20,12 @@ import android.view.MotionEvent; import android.view.View; import android.widget.Button; import android.widget.ImageButton; -import butterknife.Bind; -import butterknife.ButterKnife; -import jscl.AngleUnit; -import jscl.NumeralBase; -import org.solovyev.android.calculator.*; + +import org.solovyev.android.calculator.ActivityLauncher; +import org.solovyev.android.calculator.CalculatorEventType; +import org.solovyev.android.calculator.CppNumeralBase; +import org.solovyev.android.calculator.Engine; +import org.solovyev.android.calculator.R; import org.solovyev.android.calculator.buttons.CppSpecialButton; import org.solovyev.android.calculator.history.History; import org.solovyev.android.calculator.view.AngleUnitsButton; @@ -23,14 +33,14 @@ import org.solovyev.android.views.dragbutton.DirectionDragButton; import org.solovyev.android.views.dragbutton.DragButton; import org.solovyev.android.views.dragbutton.DragDirection; +import butterknife.Bind; +import butterknife.ButterKnife; +import jscl.AngleUnit; +import jscl.NumeralBase; + import javax.annotation.Nonnull; import javax.inject.Inject; -import static jscl.NumeralBase.hex; -import static org.solovyev.android.calculator.Engine.Preferences.*; -import static org.solovyev.android.calculator.Preferences.Gui.hideNumeralBaseDigits; -import static org.solovyev.android.views.dragbutton.DragDirection.*; - public class KeyboardUi extends BaseKeyboardUi { @Bind(R.id.cpp_button_0) @@ -100,18 +110,18 @@ public class KeyboardUi extends BaseKeyboardUi { toggleNumericDigits(numeralBase.getPreference(preferences)); } else { // set HEX to show all digits - AndroidNumeralBase.valueOf(hex).toggleButtons(true, this); + CppNumeralBase.valueOf(hex).toggleButtons(true, this); } } public void toggleNumericDigits(@Nonnull NumeralBase currentNumeralBase) { for (NumeralBase numeralBase : NumeralBase.values()) { if (currentNumeralBase != numeralBase) { - AndroidNumeralBase.valueOf(numeralBase).toggleButtons(false, this); + CppNumeralBase.valueOf(numeralBase).toggleButtons(false, this); } } - AndroidNumeralBase.valueOf(currentNumeralBase).toggleButtons(true, this); + CppNumeralBase.valueOf(currentNumeralBase).toggleButtons(true, this); } public void onCreateView(@Nonnull Activity activity, @Nonnull View view) { diff --git a/app/src/main/java/org/solovyev/android/calculator/units/CalculatorNumeralBase.java b/app/src/main/java/org/solovyev/android/calculator/units/CalculatorNumeralBase.java deleted file mode 100644 index 9a04408a..00000000 --- a/app/src/main/java/org/solovyev/android/calculator/units/CalculatorNumeralBase.java +++ /dev/null @@ -1,119 +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.units; - -import org.solovyev.common.units.Unit; -import org.solovyev.common.units.UnitConverter; -import org.solovyev.common.units.UnitImpl; -import org.solovyev.common.units.UnitType; - -import java.math.BigInteger; - -import javax.annotation.Nonnull; - -import jscl.NumeralBase; - -/** - * User: Solovyev_S - * Date: 24.09.12 - * Time: 16:05 - */ -public enum CalculatorNumeralBase implements UnitType { - - - bin(NumeralBase.bin), - - oct(NumeralBase.oct), - - dec(NumeralBase.dec), - - hex(NumeralBase.hex); - - @Nonnull - private static final CalculatorNumeralBase.Converter converter = new CalculatorNumeralBase.Converter(); - @Nonnull - private final NumeralBase numeralBase; - - CalculatorNumeralBase(@Nonnull NumeralBase numeralBase) { - this.numeralBase = numeralBase; - } - - @Nonnull - public static CalculatorNumeralBase.Converter getConverter() { - return converter; - } - - @Nonnull - public static CalculatorNumeralBase valueOf(@Nonnull NumeralBase nb) { - for (CalculatorNumeralBase calculatorNumeralBase : values()) { - if (calculatorNumeralBase.numeralBase == nb) { - return calculatorNumeralBase; - } - } - - throw new IllegalArgumentException(nb + " is not supported numeral base!"); - } - - @Nonnull - public NumeralBase getNumeralBase() { - return numeralBase; - } - - @Nonnull - @Override - public Class getUnitValueClass() { - return String.class; - } - - @Nonnull - public Unit createUnit(@Nonnull String value) { - return UnitImpl.newInstance(value, this); - } - - public static class Converter implements UnitConverter { - - private Converter() { - } - - @Override - public boolean isSupported(@Nonnull UnitType from, @Nonnull UnitType to) { - return CalculatorNumeralBase.class.isAssignableFrom(from.getClass()) && CalculatorNumeralBase.class.isAssignableFrom(to.getClass()); - } - - @Nonnull - @Override - public Unit convert(@Nonnull Unit from, @Nonnull UnitType toType) { - if (!isSupported(from.getUnitType(), toType)) { - throw new IllegalArgumentException("Types are not supported!"); - } - - final CalculatorNumeralBase fromTypeAndroid = (CalculatorNumeralBase) from.getUnitType(); - final NumeralBase fromNumeralBase = fromTypeAndroid.numeralBase; - final NumeralBase toNumeralBase = ((CalculatorNumeralBase) toType).numeralBase; - final String fromValue = (String) from.getValue(); - - final BigInteger decBigInteger = fromNumeralBase.toBigInteger(fromValue); - return UnitImpl.newInstance(toNumeralBase.toString(decBigInteger), toType); - } - } -} diff --git a/app/src/test/java/org/solovyev/android/AndroidNumeralBaseTest.java b/app/src/test/java/org/solovyev/android/AndroidNumeralBaseTest.java deleted file mode 100644 index 250782f2..00000000 --- a/app/src/test/java/org/solovyev/android/AndroidNumeralBaseTest.java +++ /dev/null @@ -1,110 +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; - -import android.os.Build; -import org.junit.Assert; -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.robolectric.RobolectricGradleTestRunner; -import org.robolectric.annotation.Config; -import org.solovyev.android.calculator.BuildConfig; -import org.solovyev.android.calculator.CalculatorTestUtils; -import org.solovyev.android.calculator.units.CalculatorNumeralBase; -import org.solovyev.common.units.Unit; -import org.solovyev.common.units.UnitConverter; - -import javax.annotation.Nonnull; -import java.util.Date; -import java.util.Random; - -import static org.junit.Assert.assertTrue; - -/** - * User: serso - * Date: 4/21/12 - * Time: 8:24 PM - */ -@Config(constants = BuildConfig.class, sdk = Build.VERSION_CODES.LOLLIPOP) -@RunWith(RobolectricGradleTestRunner.class) -public class AndroidNumeralBaseTest { - - @Nonnull - private final UnitConverter c = CalculatorNumeralBase.getConverter(); - - @BeforeClass - public static void staticSetUp() throws Exception { - CalculatorTestUtils.staticSetUp(); - } - - @Test - public void testIsSupported() throws Exception { - assertTrue(c.isSupported(CalculatorNumeralBase.bin, CalculatorNumeralBase.dec)); - } - - @Test - public void testConvertFromDec() throws Exception { - - Assert.assertEquals("101", c.convert(CalculatorNumeralBase.dec.createUnit("5"), CalculatorNumeralBase.bin).getValue()); - Assert.assertEquals("1", c.convert(CalculatorNumeralBase.dec.createUnit("1"), CalculatorNumeralBase.bin).getValue()); - Assert.assertEquals("0", c.convert(CalculatorNumeralBase.dec.createUnit("0"), CalculatorNumeralBase.bin).getValue()); - Assert.assertEquals("1111100111", c.convert(CalculatorNumeralBase.dec.createUnit("999"), CalculatorNumeralBase.bin).getValue()); - - Assert.assertEquals("A23", c.convert(CalculatorNumeralBase.dec.createUnit("2595"), CalculatorNumeralBase.hex).getValue()); - Assert.assertEquals("AEE", c.convert(CalculatorNumeralBase.dec.createUnit("2798"), CalculatorNumeralBase.hex).getValue()); - Assert.assertEquals("15", c.convert(CalculatorNumeralBase.dec.createUnit("21"), CalculatorNumeralBase.hex).getValue()); - Assert.assertEquals("0", c.convert(CalculatorNumeralBase.dec.createUnit("0"), CalculatorNumeralBase.hex).getValue()); - Assert.assertEquals("3E7", c.convert(CalculatorNumeralBase.dec.createUnit("999"), CalculatorNumeralBase.hex).getValue()); - - Assert.assertEquals("76", c.convert(CalculatorNumeralBase.dec.createUnit("62"), CalculatorNumeralBase.oct).getValue()); - Assert.assertEquals("12", c.convert(CalculatorNumeralBase.dec.createUnit("10"), CalculatorNumeralBase.oct).getValue()); - Assert.assertEquals("15", c.convert(CalculatorNumeralBase.dec.createUnit("13"), CalculatorNumeralBase.oct).getValue()); - Assert.assertEquals("0", c.convert(CalculatorNumeralBase.dec.createUnit("0"), CalculatorNumeralBase.oct).getValue()); - Assert.assertEquals("10445", c.convert(CalculatorNumeralBase.dec.createUnit("4389"), CalculatorNumeralBase.oct).getValue()); - } - - @Test - public void testRandomConvert() throws Exception { - final Random random = new Random(new Date().getTime()); - for (int i = 0; i < 100000; i++) { - final String value = String.valueOf(random.nextInt()); - Assert.assertEquals(value, convertChain(value, CalculatorNumeralBase.dec, CalculatorNumeralBase.oct, CalculatorNumeralBase.oct, CalculatorNumeralBase.bin, CalculatorNumeralBase.dec)); - Assert.assertEquals(value, convertChain(value, CalculatorNumeralBase.dec, CalculatorNumeralBase.bin, CalculatorNumeralBase.hex, CalculatorNumeralBase.dec, CalculatorNumeralBase.dec)); - Assert.assertEquals(value, convertChain(value, CalculatorNumeralBase.dec, CalculatorNumeralBase.dec, CalculatorNumeralBase.hex, CalculatorNumeralBase.oct, CalculatorNumeralBase.dec)); - Assert.assertEquals(value, convertChain(value, CalculatorNumeralBase.dec, CalculatorNumeralBase.hex, CalculatorNumeralBase.bin, CalculatorNumeralBase.oct, CalculatorNumeralBase.dec)); - - } - } - - @Nonnull - private String convertChain(@Nonnull String value, @Nonnull CalculatorNumeralBase baseAndroid, @Nonnull CalculatorNumeralBase... typeAndroids) { - Unit unit = baseAndroid.createUnit(value); - - for (CalculatorNumeralBase typeAndroid : typeAndroids) { - unit = CalculatorNumeralBase.getConverter().convert(unit, typeAndroid); - } - - return unit.getValue(); - } -} diff --git a/jscl/src/main/java/jscl/math/Expression.java b/jscl/src/main/java/jscl/math/Expression.java index d6f1c08c..7aa2446d 100644 --- a/jscl/src/main/java/jscl/math/Expression.java +++ b/jscl/src/main/java/jscl/math/Expression.java @@ -2,15 +2,6 @@ package jscl.math; import org.solovyev.common.Converter; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - import jscl.math.function.Constant; import jscl.math.function.Fraction; import jscl.math.function.Inverse; @@ -25,6 +16,15 @@ import jscl.text.ParserUtils; import jscl.text.msg.Messages; import jscl.util.ArrayUtils; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + public class Expression extends Generic { protected static final Converter FACTORIZE_CONVERTER = new Converter() { diff --git a/jscl/src/main/java/jscl/math/Generic.java b/jscl/src/main/java/jscl/math/Generic.java index c6b5a005..0c3addc1 100644 --- a/jscl/src/main/java/jscl/math/Generic.java +++ b/jscl/src/main/java/jscl/math/Generic.java @@ -4,12 +4,22 @@ import jscl.math.function.Constant; import jscl.mathml.MathML; import jscl.text.ParserUtils; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; +import java.math.BigInteger; import java.util.Set; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + public abstract class Generic implements Arithmetic, Comparable { + public BigInteger toBigInteger() { + return null; + } + + public Double toDouble() { + return null; + } + @Nonnull public Generic subtract(@Nonnull Generic that) { return add(that.negate()); diff --git a/jscl/src/main/java/jscl/math/JsclInteger.java b/jscl/src/main/java/jscl/math/JsclInteger.java index 1ddf8e58..0c0034da 100644 --- a/jscl/src/main/java/jscl/math/JsclInteger.java +++ b/jscl/src/main/java/jscl/math/JsclInteger.java @@ -4,12 +4,13 @@ import jscl.JsclMathEngine; import jscl.math.function.Constant; import jscl.mathml.MathML; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; import java.math.BigInteger; import java.util.Collections; import java.util.Set; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + public final class JsclInteger extends Generic { public static final JsclInteger factory = new JsclInteger(BigInteger.valueOf(0)); @@ -364,4 +365,14 @@ public final class JsclInteger extends Generic { e1.appendChild(element.text(String.valueOf(content))); element.appendChild(e1); } + + @Override + public BigInteger toBigInteger() { + return content; + } + + @Override + public Double toDouble() { + return content.doubleValue(); + } } diff --git a/jscl/src/main/java/jscl/math/NumericWrapper.java b/jscl/src/main/java/jscl/math/NumericWrapper.java index 1c0ea0d4..f0be0556 100644 --- a/jscl/src/main/java/jscl/math/NumericWrapper.java +++ b/jscl/src/main/java/jscl/math/NumericWrapper.java @@ -4,13 +4,19 @@ import jscl.JsclMathEngine; import jscl.math.function.Constant; import jscl.math.function.Constants; import jscl.math.function.IConstant; -import jscl.math.numeric.*; +import jscl.math.numeric.Complex; +import jscl.math.numeric.INumeric; +import jscl.math.numeric.Numeric; +import jscl.math.numeric.Real; +import jscl.math.numeric.Vector; import jscl.mathml.MathML; -import javax.annotation.Nonnull; +import java.math.BigInteger; import java.util.Collections; import java.util.Set; +import javax.annotation.Nonnull; + public final class NumericWrapper extends Generic implements INumeric { @Nonnull @@ -415,7 +421,7 @@ public final class NumericWrapper extends Generic implements INumeric, INumeric, Comparable { @@ -325,4 +327,12 @@ public abstract class Numeric implements Arithmetic, INumeric, protected String toString(final double value) { return JsclMathEngine.getInstance().format(value, JsclMathEngine.getInstance().getNumeralBase()); } + + public BigInteger toBigInteger() { + return null; + } + + public Double toDouble() { + return null; + } } diff --git a/jscl/src/main/java/jscl/math/numeric/Real.java b/jscl/src/main/java/jscl/math/numeric/Real.java index eb408992..c9756f71 100644 --- a/jscl/src/main/java/jscl/math/numeric/Real.java +++ b/jscl/src/main/java/jscl/math/numeric/Real.java @@ -2,6 +2,8 @@ package jscl.math.numeric; import jscl.math.NotDivisibleException; +import java.math.BigInteger; + import javax.annotation.Nonnull; public final class Real extends Numeric { @@ -277,4 +279,17 @@ public final class Real extends Numeric { public Complex toComplex() { return Complex.valueOf(this.content, 0.); } + + @Override + public BigInteger toBigInteger() { + if (content == Math.floor(content)) { + return BigInteger.valueOf((long) content); + } + return null; + } + + @Override + public Double toDouble() { + return content; + } }