diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/Calculator.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/Calculator.java index ee0e756b..433c2163 100644 --- a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/Calculator.java +++ b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/Calculator.java @@ -1,5 +1,7 @@ package org.solovyev.android.calculator; +import jscl.NumeralBase; +import jscl.math.Generic; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.solovyev.android.calculator.jscl.JsclOperation; @@ -22,4 +24,7 @@ public interface Calculator extends CalculatorEventContainer { CalculatorEventDataId evaluate(@NotNull JsclOperation operation, @NotNull String expression, @Nullable MessageRegistry mr); + + @NotNull + CalculatorEventDataId convert(@NotNull Generic generic, @NotNull NumeralBase to); } diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEvaluationEventDataImpl.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEvaluationEventDataImpl.java index 677d6eca..9df965a0 100644 --- a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEvaluationEventDataImpl.java +++ b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEvaluationEventDataImpl.java @@ -47,8 +47,8 @@ public class CalculatorEvaluationEventDataImpl implements CalculatorEvaluationEv @Override @Nullable - public Long getCalculationId() { - return calculatorEventData.getCalculationId(); + public Long getSequenceId() { + return calculatorEventData.getSequenceId(); } @Override diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEventDataId.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEventDataId.java index 61684be3..783d82d6 100644 --- a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEventDataId.java +++ b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEventDataId.java @@ -13,8 +13,9 @@ public interface CalculatorEventDataId { // the higher id => the later event long getEventId(); + // the higher id => the later event @Nullable - Long getCalculationId(); + Long getSequenceId(); boolean isAfter(@NotNull CalculatorEventDataId calculatorEventDataId); } diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEventDataIdImpl.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEventDataIdImpl.java index 6992bef6..ad2e2ca9 100644 --- a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEventDataIdImpl.java +++ b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEventDataIdImpl.java @@ -13,18 +13,16 @@ class CalculatorEventDataIdImpl implements CalculatorEventDataId { private final long eventId; @Nullable - private final Long calculationId; + private final Long sequenceId; - private CalculatorEventDataIdImpl(long id, - @Nullable Long calculationId) { + private CalculatorEventDataIdImpl(long id, @Nullable Long sequenceId) { this.eventId = id; - this.calculationId = calculationId; + this.sequenceId = sequenceId; } @NotNull - static CalculatorEventDataId newInstance(long id, - @Nullable Long calculationId) { - return new CalculatorEventDataIdImpl(id, calculationId); + static CalculatorEventDataId newInstance(long id, @Nullable Long sequenceId) { + return new CalculatorEventDataIdImpl(id, sequenceId); } @Override @@ -34,8 +32,8 @@ class CalculatorEventDataIdImpl implements CalculatorEventDataId { @Nullable @Override - public Long getCalculationId() { - return this.calculationId; + public Long getSequenceId() { + return this.sequenceId; } @Override @@ -51,7 +49,7 @@ class CalculatorEventDataIdImpl implements CalculatorEventDataId { CalculatorEventDataIdImpl that = (CalculatorEventDataIdImpl) o; if (eventId != that.eventId) return false; - if (calculationId != null ? !calculationId.equals(that.calculationId) : that.calculationId != null) + if (sequenceId != null ? !sequenceId.equals(that.sequenceId) : that.sequenceId != null) return false; return true; @@ -60,7 +58,7 @@ class CalculatorEventDataIdImpl implements CalculatorEventDataId { @Override public int hashCode() { int result = (int) (eventId ^ (eventId >>> 32)); - result = 31 * result + (calculationId != null ? calculationId.hashCode() : 0); + result = 31 * result + (sequenceId != null ? sequenceId.hashCode() : 0); return result; } } diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEventDataImpl.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEventDataImpl.java index ad9d19b8..34b37d2b 100644 --- a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEventDataImpl.java +++ b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEventDataImpl.java @@ -29,8 +29,8 @@ class CalculatorEventDataImpl implements CalculatorEventData { @Override @Nullable - public Long getCalculationId() { - return calculatorEventDataId.getCalculationId(); + public Long getSequenceId() { + return calculatorEventDataId.getSequenceId(); } @Override diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEventType.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEventType.java index c06da282..1fd179b6 100644 --- a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEventType.java +++ b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEventType.java @@ -28,7 +28,19 @@ public enum CalculatorEventType { calculation_finished, // @NotNull org.solovyev.android.calculator.CalculatorFailure - calculation_failed; + calculation_failed, + + /* + ********************************************************************** + * + * CONVERSION + * + ********************************************************************** + */ + conversion_started, + + // @NotNull String conversion result + conversion_finished; public boolean isOfType(@NotNull CalculatorEventType... types) { for (CalculatorEventType type : types) { diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorImpl.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorImpl.java index fab2b16a..3db62bfb 100644 --- a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorImpl.java +++ b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorImpl.java @@ -1,6 +1,7 @@ package org.solovyev.android.calculator; import jscl.AbstractJsclArithmeticException; +import jscl.NumeralBase; import jscl.NumeralBaseException; import jscl.math.Generic; import jscl.text.ParseInterruptedException; @@ -10,6 +11,10 @@ import org.solovyev.android.calculator.jscl.JsclOperation; import org.solovyev.android.calculator.text.TextProcessor; import org.solovyev.common.msg.MessageRegistry; import org.solovyev.common.msg.MessageType; +import org.solovyev.common.text.StringUtils; +import org.solovyev.math.units.UnitConverter; +import org.solovyev.math.units.UnitImpl; +import org.solovyev.math.units.UnitType; import java.util.List; import java.util.concurrent.Executor; @@ -43,6 +48,32 @@ public class CalculatorImpl implements Calculator { public CalculatorImpl() { } + @NotNull + public static String doConversion(@NotNull UnitConverter converter, + @Nullable String from, + @NotNull UnitType fromUnitType, + @NotNull UnitType toUnitType) throws ConversionException{ + final String result; + + if (StringUtils.isEmpty(from)) { + result = ""; + } else { + + String to = null; + try { + if (converter.isSupported(fromUnitType, toUnitType)) { + to = converter.convert(UnitImpl.newInstance(from, fromUnitType), toUnitType).getValue(); + } + } catch (RuntimeException e) { + throw new ConversionException(e); + } + + result = to; + } + + return result; + } + @NotNull private CalculatorEventDataId nextCalculatorEventDataId() { long eventId = counter.incrementAndGet(); @@ -50,9 +81,9 @@ public class CalculatorImpl implements Calculator { } @NotNull - private CalculatorEventDataId nextEventDataId(@NotNull Long calculationId) { + private CalculatorEventDataId nextEventDataId(@NotNull Long sequenceId) { long eventId = counter.incrementAndGet(); - return CalculatorEventDataIdImpl.newInstance(eventId, calculationId); + return CalculatorEventDataIdImpl.newInstance(eventId, sequenceId); } /* @@ -86,14 +117,56 @@ public class CalculatorImpl implements Calculator { threadPoolExecutor.execute(new Runnable() { @Override public void run() { - CalculatorImpl.this.evaluate(eventDataId.getCalculationId(), operation, expression, mr); + CalculatorImpl.this.evaluate(eventDataId.getSequenceId(), operation, expression, mr); } }); return eventDataId; } - private void evaluate(@NotNull Long calculationId, + @NotNull + @Override + public CalculatorEventDataId convert(@NotNull final Generic generic, + @NotNull final NumeralBase to) { + final CalculatorEventDataId eventDataId = nextCalculatorEventDataId(); + + threadPoolExecutor.execute(new Runnable() { + @Override + public void run() { + final Long sequenceId = eventDataId.getSequenceId(); + assert sequenceId != null; + + fireCalculatorEvent(newConversionEventData(sequenceId), CalculatorEventType.conversion_started, null); + + final NumeralBase from = CalculatorLocatorImpl.getInstance().getCalculatorEngine().getEngine().getNumeralBase(); + + if (from != to) { + String fromString = generic.toString(); + if (!StringUtils.isEmpty(fromString)) { + try { + fromString = ToJsclTextProcessor.getInstance().process(fromString).getExpression(); + } catch (CalculatorParseException e) { + // ok, problems while processing occurred + } + } + + // todo serso: continue + //doConversion(AndroidNumeralBase.getConverter(), fromString, AndroidNumeralBase.valueOf(fromString), AndroidNumeralBase.valueOf(to)); + } else { + fireCalculatorEvent(newConversionEventData(sequenceId), CalculatorEventType.conversion_finished, generic.toString()); + } + } + }); + + return eventDataId; + } + + @NotNull + private CalculatorEventData newConversionEventData(@NotNull Long sequenceId) { + return CalculatorEventDataImpl.newInstance(nextEventDataId(sequenceId)); + } + + private void evaluate(@NotNull Long sequenceId, @NotNull JsclOperation operation, @NotNull String expression, @Nullable MessageRegistry mr) { @@ -101,7 +174,7 @@ public class CalculatorImpl implements Calculator { PreparedExpression preparedExpression = null; - fireCalculatorEvent(newCalculationEventData(operation, expression, calculationId), CalculatorEventType.calculation_started, new CalculatorInputImpl(expression, operation)); + fireCalculatorEvent(newCalculationEventData(operation, expression, sequenceId), CalculatorEventType.calculation_started, new CalculatorInputImpl(expression, operation)); try { preparedExpression = preprocessor.process(expression); @@ -116,27 +189,27 @@ public class CalculatorImpl implements Calculator { result.toString(); final CalculatorOutputImpl data = new CalculatorOutputImpl(operation.getFromProcessor().process(result), operation, result); - fireCalculatorEvent(newCalculationEventData(operation, expression, calculationId), CalculatorEventType.calculation_result, data); + fireCalculatorEvent(newCalculationEventData(operation, expression, sequenceId), CalculatorEventType.calculation_result, data); } catch (AbstractJsclArithmeticException e) { - handleException(calculationId, operation, expression, mr, new CalculatorEvalException(e, e, jsclExpression)); + handleException(sequenceId, operation, expression, mr, new CalculatorEvalException(e, e, jsclExpression)); } } catch (ArithmeticException e) { - handleException(calculationId, operation, expression, mr, preparedExpression, new CalculatorParseException(expression, new CalculatorMessage(CalculatorMessages.msg_001, MessageType.error, e.getMessage()))); + handleException(sequenceId, operation, expression, mr, preparedExpression, new CalculatorParseException(expression, new CalculatorMessage(CalculatorMessages.msg_001, MessageType.error, e.getMessage()))); } catch (StackOverflowError e) { - handleException(calculationId, operation, expression, mr, preparedExpression, new CalculatorParseException(expression, new CalculatorMessage(CalculatorMessages.msg_002, MessageType.error))); + handleException(sequenceId, operation, expression, mr, preparedExpression, new CalculatorParseException(expression, new CalculatorMessage(CalculatorMessages.msg_002, MessageType.error))); } catch (jscl.text.ParseException e) { - handleException(calculationId, operation, expression, mr, preparedExpression, new CalculatorParseException(e)); + handleException(sequenceId, operation, expression, mr, preparedExpression, new CalculatorParseException(e)); } catch (ParseInterruptedException e) { // do nothing - we ourselves interrupt the calculations - fireCalculatorEvent(newCalculationEventData(operation, expression, calculationId), CalculatorEventType.calculation_cancelled, null); + fireCalculatorEvent(newCalculationEventData(operation, expression, sequenceId), CalculatorEventType.calculation_cancelled, null); } catch (CalculatorParseException e) { - handleException(calculationId, operation, expression, mr, preparedExpression, e); + handleException(sequenceId, operation, expression, mr, preparedExpression, e); } finally { - fireCalculatorEvent(newCalculationEventData(operation, expression, calculationId), CalculatorEventType.calculation_finished, null); + fireCalculatorEvent(newCalculationEventData(operation, expression, sequenceId), CalculatorEventType.calculation_finished, null); } } } @@ -206,4 +279,13 @@ public class CalculatorImpl implements Calculator { public void fireCalculatorEvents(@NotNull List calculatorEvents) { calculatorEventContainer.fireCalculatorEvents(calculatorEvents); } + + public static final class ConversionException extends Exception { + private ConversionException() { + } + + private ConversionException(Throwable throwable) { + super(throwable); + } + } } diff --git a/calculatorpp/project.properties b/calculatorpp/project.properties index 0b0ebc4d..1b733b09 100644 --- a/calculatorpp/project.properties +++ b/calculatorpp/project.properties @@ -1,20 +1,19 @@ -# This file is automatically generated by Android Tools. -# Do not modify this file -- YOUR CHANGES WILL BE ERASED! -# -# This file must be checked in Version Control Systems. -# -# To customize properties used by the Ant build system use, -# "ant.properties", and override values to adapt the script to your -# project structure. - -# Project target. -target=android-15 -android.library.reference.1=../calculatorpp-service -android.library.reference.2=gen-external-apklibs/org.solovyev.android_android-common-core_1.0.0 -android.library.reference.3=gen-external-apklibs/org.solovyev.android_android-common-ads_1.0.0 -android.library.reference.4=gen-external-apklibs/org.solovyev.android_android-common-view_1.0.0 -android.library.reference.5=gen-external-apklibs/org.solovyev.android_android-common-preferences_1.0.0 -android.library.reference.6=gen-external-apklibs/org.solovyev.android_android-common-other_1.0.0 -android.library.reference.7=gen-external-apklibs/org.solovyev.android_android-common-menu_1.0.0 - - +# This file is automatically generated by Android Tools. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file must be checked in Version Control Systems. +# +# To customize properties used by the Ant build system use, +# "ant.properties", and override values to adapt the script to your +# project structure. + +# Project target. +target=android-15 +android.library.reference.1=gen-external-apklibs/org.solovyev.android_android-common-core_1.0.0 +android.library.reference.2=gen-external-apklibs/org.solovyev.android_android-common-ads_1.0.0 +android.library.reference.3=gen-external-apklibs/org.solovyev.android_android-common-view_1.0.0 +android.library.reference.4=gen-external-apklibs/org.solovyev.android_android-common-preferences_1.0.0 +android.library.reference.5=gen-external-apklibs/org.solovyev.android_android-common-other_1.0.0 +android.library.reference.6=gen-external-apklibs/org.solovyev.android_android-common-menu_1.0.0 + + diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/AndroidCalculatorDisplayView.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/AndroidCalculatorDisplayView.java index e1420698..d8db12c7 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/AndroidCalculatorDisplayView.java +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/AndroidCalculatorDisplayView.java @@ -10,7 +10,6 @@ import android.graphics.Color; import android.text.Html; import android.util.AttributeSet; import android.util.Log; -import jscl.NumeralBase; import jscl.math.Generic; import jscl.math.function.Constant; import jscl.math.function.IConstant; @@ -20,12 +19,9 @@ import org.solovyev.android.calculator.model.CalculatorEngine; import org.solovyev.android.calculator.text.TextProcessor; import org.solovyev.android.calculator.view.NumeralBaseConverterDialog; import org.solovyev.android.calculator.view.TextHighlighter; -import org.solovyev.android.calculator.view.UnitConverterViewBuilder; -import org.solovyev.android.menu.AMenuItem; import org.solovyev.android.menu.LabeledMenuItem; import org.solovyev.android.view.AutoResizeTextView; import org.solovyev.common.collections.CollectionsUtils; -import org.solovyev.common.text.StringUtils; import java.util.HashSet; import java.util.Set; @@ -37,95 +33,18 @@ import java.util.Set; */ public class AndroidCalculatorDisplayView extends AutoResizeTextView implements CalculatorDisplayView { - private static enum ConversionMenuItem implements AMenuItem { - convert_to_bin(NumeralBase.bin), - convert_to_dec(NumeralBase.dec), - convert_to_hex(NumeralBase.hex); - - @NotNull - private final NumeralBase toNumeralBase; - - private ConversionMenuItem(@NotNull NumeralBase toNumeralBase) { - this.toNumeralBase = toNumeralBase; - } - - protected boolean isItemVisibleFor(@NotNull Generic generic, @NotNull JsclOperation operation) { - boolean result = false; - - if (operation == JsclOperation.numeric) { - if (generic.getConstants().isEmpty()) { - try { - convert(generic); - - // conversion possible => return true - result = true; - - } catch (UnitConverterViewBuilder.ConversionException e) { - // conversion is not possible => return false - } - } - } - - return result; - } - - @Override - public void onClick(@NotNull CalculatorDisplayView data, @NotNull Context context) { - final NumeralBase fromNumeralBase = CalculatorEngine.instance.getEngine().getNumeralBase(); - - final Generic lastResult = CalculatorLocatorImpl.getInstance().getCalculatorDisplay().getViewState().getResult(); - - if (lastResult != null) { - String to; - try { - to = convert(lastResult); - - // add prefix - if (fromNumeralBase != toNumeralBase) { - to = toNumeralBase.getJsclPrefix() + to; - } - } catch (UnitConverterViewBuilder.ConversionException e) { - to = context.getString(R.string.c_error); - } - - data.setText(to); - //data.redraw(); - } - } - - @NotNull - private String convert(@NotNull Generic generic) throws UnitConverterViewBuilder.ConversionException { - final NumeralBase fromNumeralBase = CalculatorEngine.instance.getEngine().getNumeralBase(); - - if (fromNumeralBase != toNumeralBase) { - String from = generic.toString(); - if (!StringUtils.isEmpty(from)) { - try { - from = ToJsclTextProcessor.getInstance().process(from).getExpression(); - } catch (CalculatorParseException e) { - // ok, problems while processing occurred - } - } - - return UnitConverterViewBuilder.doConversion(AndroidNumeralBase.getConverter(), from, AndroidNumeralBase.valueOf(fromNumeralBase), AndroidNumeralBase.valueOf(toNumeralBase)); - } else { - return generic.toString(); - } - } - } - - public static enum MenuItem implements LabeledMenuItem { + public static enum MenuItem implements LabeledMenuItem { copy(R.string.c_copy) { @Override - public void onClick(@NotNull CalculatorDisplayView data, @NotNull Context context) { + public void onClick(@NotNull CalculatorDisplayViewState data, @NotNull Context context) { CalculatorModel.copyResult(context, data); } }, convert_to_bin(R.string.convert_to_bin) { @Override - public void onClick(@NotNull CalculatorDisplayView data, @NotNull Context context) { + public void onClick(@NotNull CalculatorDisplayViewState data, @NotNull Context context) { ConversionMenuItem.convert_to_bin.onClick(data, context); } @@ -137,7 +56,7 @@ public class AndroidCalculatorDisplayView extends AutoResizeTextView implements convert_to_dec(R.string.convert_to_dec) { @Override - public void onClick(@NotNull CalculatorDisplayView data, @NotNull Context context) { + public void onClick(@NotNull CalculatorDisplayViewState data, @NotNull Context context) { ConversionMenuItem.convert_to_dec.onClick(data, context); } @@ -149,7 +68,7 @@ public class AndroidCalculatorDisplayView extends AutoResizeTextView implements convert_to_hex(R.string.convert_to_hex) { @Override - public void onClick(@NotNull CalculatorDisplayView data, @NotNull Context context) { + public void onClick(@NotNull CalculatorDisplayViewState data, @NotNull Context context) { ConversionMenuItem.convert_to_hex.onClick(data, context); } @@ -161,8 +80,8 @@ public class AndroidCalculatorDisplayView extends AutoResizeTextView implements convert(R.string.c_convert) { @Override - public void onClick(@NotNull CalculatorDisplayView data, @NotNull Context context) { - final Generic result = data.getState().getResult(); + public void onClick(@NotNull CalculatorDisplayViewState data, @NotNull Context context) { + final Generic result = data.getResult(); if (result != null) { new NumeralBaseConverterDialog(result.toString()).show(context); } @@ -176,8 +95,8 @@ public class AndroidCalculatorDisplayView extends AutoResizeTextView implements plot(R.string.c_plot) { @Override - public void onClick(@NotNull CalculatorDisplayView data, @NotNull Context context) { - final Generic generic = data.getState().getResult(); + public void onClick(@NotNull CalculatorDisplayViewState data, @NotNull Context context) { + final Generic generic = data.getResult(); assert generic != null; final Constant constant = CollectionsUtils.getFirstCollectionElement(getNotSystemConstants(generic)); diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/CalculatorModel.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/CalculatorModel.java index d3268689..e43e9131 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/CalculatorModel.java +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/CalculatorModel.java @@ -97,10 +97,9 @@ public enum CalculatorModel implements CursorControl, HistoryControl { + + convert_to_bin(NumeralBase.bin), + convert_to_dec(NumeralBase.dec), + convert_to_hex(NumeralBase.hex); + + @NotNull + private final NumeralBase toNumeralBase; + + ConversionMenuItem(@NotNull NumeralBase toNumeralBase) { + this.toNumeralBase = toNumeralBase; + } + + protected boolean isItemVisibleFor(@NotNull Generic generic, @NotNull JsclOperation operation) { + boolean result = false; + + if (operation == JsclOperation.numeric) { + if (generic.getConstants().isEmpty()) { + try { + convert(generic); + + // conversion possible => return true + result = true; + + } catch (CalculatorImpl.ConversionException e) { + // conversion is not possible => return false + } + } + } + + return result; + } + + @Override + public void onClick(@NotNull CalculatorDisplayViewState data, @NotNull Context context) { + final NumeralBase fromNumeralBase = CalculatorEngine.instance.getEngine().getNumeralBase(); + + final Generic lastResult = data.getResult(); + + if (lastResult != null) { + convert(lastResult); + } + } + + private void convert(@NotNull Generic generic) { + CalculatorLocatorImpl.getInstance().getCalculator().convert(generic, this.toNumeralBase); + } +} diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/view/UnitConverterViewBuilder.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/view/UnitConverterViewBuilder.java index d75c7240..41603705 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/view/UnitConverterViewBuilder.java +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/view/UnitConverterViewBuilder.java @@ -1,259 +1,224 @@ -package org.solovyev.android.calculator.view; - -import android.app.Activity; -import android.content.Context; -import android.text.ClipboardManager; -import android.text.Editable; -import android.text.TextWatcher; -import android.view.View; -import android.view.ViewGroup; -import android.widget.*; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.solovyev.math.units.Unit; -import org.solovyev.math.units.UnitConverter; -import org.solovyev.math.units.UnitImpl; -import org.solovyev.math.units.UnitType; -import org.solovyev.android.calculator.R; -import org.solovyev.android.view.ViewBuilder; -import org.solovyev.android.view.ViewFromLayoutBuilder; -import org.solovyev.common.text.StringUtils; - -import java.util.Collections; -import java.util.List; - -/** - * User: serso - * Date: 4/20/12 - * Time: 4:50 PM - */ -public class UnitConverterViewBuilder implements ViewBuilder { - - @NotNull - private List> fromUnitTypes = Collections.emptyList(); - - @NotNull - private List> toUnitTypes = Collections.emptyList(); - - @Nullable - private Unit fromValue; - - @NotNull - private UnitConverter converter = UnitConverter.Dummy.getInstance(); - - @Nullable - private View.OnClickListener okButtonOnClickListener; - - @Nullable - private CustomButtonData customButtonData; - - public void setFromUnitTypes(@NotNull List> fromUnitTypes) { - this.fromUnitTypes = fromUnitTypes; - } - - public void setToUnitTypes(@NotNull List> toUnitTypes) { - this.toUnitTypes = toUnitTypes; - } - - public void setFromValue(@Nullable Unit fromValue) { - this.fromValue = fromValue; - } - - public void setConverter(@NotNull UnitConverter converter) { - this.converter = converter; - } - - public void setOkButtonOnClickListener(@Nullable View.OnClickListener okButtonOnClickListener) { - this.okButtonOnClickListener = okButtonOnClickListener; - } - - public void setCustomButtonData(@Nullable CustomButtonData customButtonData) { - this.customButtonData = customButtonData; - } - - @NotNull - @Override - public View build(@NotNull final Context context) { - final View main = ViewFromLayoutBuilder.newInstance(R.layout.unit_converter).build(context); - - final Spinner fromSpinner = (Spinner) main.findViewById(R.id.unit_types_from); - final EditText fromEditText = (EditText) main.findViewById(R.id.units_from); - fromEditText.addTextChangedListener(new TextWatcher() { - @Override - public void beforeTextChanged(CharSequence s, int start, int count, int after) { - } - - @Override - public void onTextChanged(CharSequence s, int start, int before, int count) { - } - - @Override - public void afterTextChanged(Editable s) { - doConversion(main, context, UnitConverterViewBuilder.this.converter); - } - }); - - fillSpinner(main, context, R.id.unit_types_from, fromUnitTypes); - fillSpinner(main, context, R.id.unit_types_to, toUnitTypes); - - if (fromValue != null) { - fromEditText.setText(fromValue.getValue()); - - int i = fromUnitTypes.indexOf(fromValue.getUnitType()); - if ( i >= 0 ) { - fromSpinner.setSelection(i); - } - } - - final Button copyButton = (Button) main.findViewById(R.id.unit_converter_copy_button); - copyButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - final EditText toEditText = (EditText) main.findViewById(R.id.units_to); - - final ClipboardManager clipboard = (ClipboardManager) context.getSystemService(Activity.CLIPBOARD_SERVICE); - clipboard.setText(toEditText.getText().toString()); - Toast.makeText(context, context.getText(R.string.c_result_copied), Toast.LENGTH_SHORT).show(); - } - }); - - final Button okButton = (Button) main.findViewById(R.id.unit_converter_ok_button); - if ( okButtonOnClickListener == null ) { - ((ViewGroup) okButton.getParent()).removeView(okButton); - } else { - okButton.setOnClickListener(this.okButtonOnClickListener); - } - - final Button customButton = (Button) main.findViewById(R.id.unit_converter_custom_button); - if ( customButtonData == null ) { - ((ViewGroup) customButton.getParent()).removeView(customButton); - } else { - customButton.setText(customButtonData.text); - customButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - customButtonData.clickListener.onClick(getFromUnit(main), getToUnit(main)); - } - }); - } - - - - return main; - } - - private void fillSpinner(@NotNull final View main, - @NotNull final Context context, - final int spinnerId, - @NotNull List> unitTypes) { - final Spinner spinner = (Spinner) main.findViewById(spinnerId); - - final ArrayAdapter> adapter = new ArrayAdapter>(context, android.R.layout.simple_spinner_item); - adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); - for (UnitType fromUnitType : unitTypes) { - adapter.add(fromUnitType); - } - spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { - @Override - public void onItemSelected(AdapterView parent, View view, int position, long id) { - doConversion(main, context, UnitConverterViewBuilder.this.converter); - } - - @Override - public void onNothingSelected(AdapterView parent) { - } - }); - spinner.setAdapter(adapter); - } - - private static void doConversion(@NotNull View main, @NotNull Context context, @NotNull UnitConverter converter) { - final EditText fromEditText = (EditText) main.findViewById(R.id.units_from); - - final EditText toEditText = (EditText) main.findViewById(R.id.units_to); - - final String from = fromEditText.getText().toString(); - try { - toEditText.setText(doConversion(converter, from, getFromUnitType(main), getToUnitType(main))); - } catch (ConversionException e) { - toEditText.setText(context.getString(R.string.c_error)); - } - } - - public static final class ConversionException extends Exception { - private ConversionException() { - } - - private ConversionException(Throwable throwable) { - super(throwable); - } - } - - @NotNull - public static String doConversion(@NotNull UnitConverter converter, - @Nullable String from, - @NotNull UnitType fromUnitType, - @NotNull UnitType toUnitType) throws ConversionException{ - final String result; - - if (StringUtils.isEmpty(from)) { - result = ""; - } else { - - String to = null; - try { - if (converter.isSupported(fromUnitType, toUnitType)) { - to = converter.convert(UnitImpl.newInstance(from, fromUnitType), toUnitType).getValue(); - } - } catch (RuntimeException e) { - throw new ConversionException(e); - } - - result = to; - } - - return result; - } - - @NotNull - private static Unit getToUnit(@NotNull View main) { - final EditText toUnits = (EditText) main.findViewById(R.id.units_to); - return UnitImpl.newInstance(toUnits.getText().toString(), getToUnitType(main)); - } - - @NotNull - private static UnitType getToUnitType(@NotNull View main) { - final Spinner toSpinner = (Spinner) main.findViewById(R.id.unit_types_to); - return (UnitType) toSpinner.getSelectedItem(); - } - - @NotNull - private static Unit getFromUnit(@NotNull View main) { - final EditText fromUnits = (EditText) main.findViewById(R.id.units_from); - return UnitImpl.newInstance(fromUnits.getText().toString(), getFromUnitType(main)); - } - - @NotNull - private static UnitType getFromUnitType(@NotNull View main) { - final Spinner fromSpinner = (Spinner) main.findViewById(R.id.unit_types_from); - return (UnitType) fromSpinner.getSelectedItem(); - } - - public static class CustomButtonData { - - @NotNull - private String text; - - @NotNull - private CustomButtonOnClickListener clickListener; - - - public CustomButtonData(@NotNull String text, @NotNull CustomButtonOnClickListener clickListener) { - this.text = text; - this.clickListener = clickListener; - } - } - - public static interface CustomButtonOnClickListener { - void onClick(@NotNull Unit fromUnits, @NotNull Unit toUnits); - } -} +package org.solovyev.android.calculator.view; + +import android.app.Activity; +import android.content.Context; +import android.text.ClipboardManager; +import android.text.Editable; +import android.text.TextWatcher; +import android.view.View; +import android.view.ViewGroup; +import android.widget.*; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.solovyev.android.calculator.CalculatorImpl; +import org.solovyev.math.units.Unit; +import org.solovyev.math.units.UnitConverter; +import org.solovyev.math.units.UnitImpl; +import org.solovyev.math.units.UnitType; +import org.solovyev.android.calculator.R; +import org.solovyev.android.view.ViewBuilder; +import org.solovyev.android.view.ViewFromLayoutBuilder; + +import java.util.Collections; +import java.util.List; + +/** + * User: serso + * Date: 4/20/12 + * Time: 4:50 PM + */ +public class UnitConverterViewBuilder implements ViewBuilder { + + @NotNull + private List> fromUnitTypes = Collections.emptyList(); + + @NotNull + private List> toUnitTypes = Collections.emptyList(); + + @Nullable + private Unit fromValue; + + @NotNull + private UnitConverter converter = UnitConverter.Dummy.getInstance(); + + @Nullable + private View.OnClickListener okButtonOnClickListener; + + @Nullable + private CustomButtonData customButtonData; + + public void setFromUnitTypes(@NotNull List> fromUnitTypes) { + this.fromUnitTypes = fromUnitTypes; + } + + public void setToUnitTypes(@NotNull List> toUnitTypes) { + this.toUnitTypes = toUnitTypes; + } + + public void setFromValue(@Nullable Unit fromValue) { + this.fromValue = fromValue; + } + + public void setConverter(@NotNull UnitConverter converter) { + this.converter = converter; + } + + public void setOkButtonOnClickListener(@Nullable View.OnClickListener okButtonOnClickListener) { + this.okButtonOnClickListener = okButtonOnClickListener; + } + + public void setCustomButtonData(@Nullable CustomButtonData customButtonData) { + this.customButtonData = customButtonData; + } + + @NotNull + @Override + public View build(@NotNull final Context context) { + final View main = ViewFromLayoutBuilder.newInstance(R.layout.unit_converter).build(context); + + final Spinner fromSpinner = (Spinner) main.findViewById(R.id.unit_types_from); + final EditText fromEditText = (EditText) main.findViewById(R.id.units_from); + fromEditText.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + } + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + } + + @Override + public void afterTextChanged(Editable s) { + doConversion(main, context, UnitConverterViewBuilder.this.converter); + } + }); + + fillSpinner(main, context, R.id.unit_types_from, fromUnitTypes); + fillSpinner(main, context, R.id.unit_types_to, toUnitTypes); + + if (fromValue != null) { + fromEditText.setText(fromValue.getValue()); + + int i = fromUnitTypes.indexOf(fromValue.getUnitType()); + if ( i >= 0 ) { + fromSpinner.setSelection(i); + } + } + + final Button copyButton = (Button) main.findViewById(R.id.unit_converter_copy_button); + copyButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + final EditText toEditText = (EditText) main.findViewById(R.id.units_to); + + final ClipboardManager clipboard = (ClipboardManager) context.getSystemService(Activity.CLIPBOARD_SERVICE); + clipboard.setText(toEditText.getText().toString()); + Toast.makeText(context, context.getText(R.string.c_result_copied), Toast.LENGTH_SHORT).show(); + } + }); + + final Button okButton = (Button) main.findViewById(R.id.unit_converter_ok_button); + if ( okButtonOnClickListener == null ) { + ((ViewGroup) okButton.getParent()).removeView(okButton); + } else { + okButton.setOnClickListener(this.okButtonOnClickListener); + } + + final Button customButton = (Button) main.findViewById(R.id.unit_converter_custom_button); + if ( customButtonData == null ) { + ((ViewGroup) customButton.getParent()).removeView(customButton); + } else { + customButton.setText(customButtonData.text); + customButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + customButtonData.clickListener.onClick(getFromUnit(main), getToUnit(main)); + } + }); + } + + + + return main; + } + + private void fillSpinner(@NotNull final View main, + @NotNull final Context context, + final int spinnerId, + @NotNull List> unitTypes) { + final Spinner spinner = (Spinner) main.findViewById(spinnerId); + + final ArrayAdapter> adapter = new ArrayAdapter>(context, android.R.layout.simple_spinner_item); + adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + for (UnitType fromUnitType : unitTypes) { + adapter.add(fromUnitType); + } + spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { + @Override + public void onItemSelected(AdapterView parent, View view, int position, long id) { + doConversion(main, context, UnitConverterViewBuilder.this.converter); + } + + @Override + public void onNothingSelected(AdapterView parent) { + } + }); + spinner.setAdapter(adapter); + } + + private static void doConversion(@NotNull View main, @NotNull Context context, @NotNull UnitConverter converter) { + final EditText fromEditText = (EditText) main.findViewById(R.id.units_from); + + final EditText toEditText = (EditText) main.findViewById(R.id.units_to); + + final String from = fromEditText.getText().toString(); + try { + toEditText.setText(CalculatorImpl.doConversion(converter, from, getFromUnitType(main), getToUnitType(main))); + } catch (CalculatorImpl.ConversionException e) { + toEditText.setText(context.getString(R.string.c_error)); + } + } + + @NotNull + private static Unit getToUnit(@NotNull View main) { + final EditText toUnits = (EditText) main.findViewById(R.id.units_to); + return UnitImpl.newInstance(toUnits.getText().toString(), getToUnitType(main)); + } + + @NotNull + private static UnitType getToUnitType(@NotNull View main) { + final Spinner toSpinner = (Spinner) main.findViewById(R.id.unit_types_to); + return (UnitType) toSpinner.getSelectedItem(); + } + + @NotNull + private static Unit getFromUnit(@NotNull View main) { + final EditText fromUnits = (EditText) main.findViewById(R.id.units_from); + return UnitImpl.newInstance(fromUnits.getText().toString(), getFromUnitType(main)); + } + + @NotNull + private static UnitType getFromUnitType(@NotNull View main) { + final Spinner fromSpinner = (Spinner) main.findViewById(R.id.unit_types_from); + return (UnitType) fromSpinner.getSelectedItem(); + } + + public static class CustomButtonData { + + @NotNull + private String text; + + @NotNull + private CustomButtonOnClickListener clickListener; + + + public CustomButtonData(@NotNull String text, @NotNull CustomButtonOnClickListener clickListener) { + this.text = text; + this.clickListener = clickListener; + } + } + + public static interface CustomButtonOnClickListener { + void onClick(@NotNull Unit fromUnits, @NotNull Unit toUnits); + } +}