summaryrefslogtreecommitdiff
path: root/src/main/java/sevenUnitsGUI/Presenter.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/sevenUnitsGUI/Presenter.java')
-rw-r--r--src/main/java/sevenUnitsGUI/Presenter.java122
1 files changed, 86 insertions, 36 deletions
diff --git a/src/main/java/sevenUnitsGUI/Presenter.java b/src/main/java/sevenUnitsGUI/Presenter.java
index 8f99649..4512e01 100644
--- a/src/main/java/sevenUnitsGUI/Presenter.java
+++ b/src/main/java/sevenUnitsGUI/Presenter.java
@@ -46,6 +46,7 @@ import sevenUnits.unit.UnitDatabase;
import sevenUnits.unit.UnitPrefix;
import sevenUnits.unit.UnitType;
import sevenUnits.unit.UnitValue;
+import sevenUnits.utils.NameSymbol;
import sevenUnits.utils.Nameable;
import sevenUnits.utils.ObjectProduct;
import sevenUnits.utils.UncertainDouble;
@@ -558,17 +559,13 @@ public final class Presenter {
}
// convert strings to data, checking if anything is invalid
- final Unit fromUnit, toUnit;
+ final Unit fromUnit;
final UncertainDouble uncertainValue;
if (this.database.containsUnitName(fromUnitString)) {
fromUnit = this.database.getUnit(fromUnitString);
} else
throw this.viewError("Nonexistent From unit: %s", fromUnitString);
- if (this.database.containsUnitName(toUnitString)) {
- toUnit = this.database.getUnit(toUnitString);
- } else
- throw this.viewError("Nonexistent To unit: %s", toUnitString);
try {
uncertainValue = UncertainDouble
.fromRoundedString(inputValueString);
@@ -577,38 +574,81 @@ public final class Presenter {
"Invalid value " + inputValueString);
return;
}
-
+ if (this.database.containsUnitName(toUnitString)) {
+ final Unit toUnit = this.database.getUnit(toUnitString);
+ ucview.showUnitConversionOutput(
+ this.convertUnitToUnit(fromUnitString, toUnitString,
+ inputValueString, fromUnit, toUnit, uncertainValue));
+ } else if (this.database.containsUnitSetName(toUnitString)) {
+ final List<LinearUnit> toMulti = this.database
+ .getUnitSet(toUnitString);
+ ucview.showUnitConversionOutput(
+ this.convertUnitToMulti(fromUnitString, inputValueString,
+ fromUnit, toMulti, uncertainValue));
+ } else
+ throw this.viewError("Nonexistent To unit: %s", toUnitString);
+ } else
+ throw new UnsupportedOperationException(
+ "This function can only be called when the view is a UnitConversionView.");
+ }
+
+ private UnitConversionRecord convertUnitToMulti(String fromUnitString,
+ String inputValueString, Unit fromUnit, List<LinearUnit> toMulti,
+ UncertainDouble uncertainValue) {
+ for (final LinearUnit toUnit : toMulti) {
if (!fromUnit.canConvertTo(toUnit))
throw this.viewError("Could not convert between %s and %s",
fromUnit, toUnit);
-
- // convert - we will need to erase uncertainty for non-linear units, so
- // we need to treat linear and non-linear units differently
- final String outputValueString;
- if (fromUnit instanceof LinearUnit && toUnit instanceof LinearUnit) {
- final LinearUnit fromLinear = (LinearUnit) fromUnit;
- final LinearUnit toLinear = (LinearUnit) toUnit;
- final LinearUnitValue initialValue = LinearUnitValue.of(fromLinear,
- uncertainValue);
- final LinearUnitValue converted = initialValue.convertTo(toLinear);
-
- outputValueString = this.numberDisplayRule
- .apply(converted.getValue());
- } else {
- final UnitValue initialValue = UnitValue.of(fromUnit,
- uncertainValue.value());
- final UnitValue converted = initialValue.convertTo(toUnit);
-
- outputValueString = this.numberDisplayRule
- .apply(UncertainDouble.of(converted.getValue(), 0));
- }
+ }
+
+ final LinearUnitValue initValue;
+ if (fromUnit instanceof LinearUnit) {
+ final var fromLinear = (LinearUnit) fromUnit;
+ initValue = LinearUnitValue.of(fromLinear, uncertainValue);
+ } else {
+ initValue = UnitValue.of(fromUnit, uncertainValue.value())
+ .convertToBase(NameSymbol.EMPTY);
+ }
+
+ final List<LinearUnitValue> converted = initValue
+ .convertToMultiple(toMulti);
+ final String toExpression = converted.stream().map(
+ v -> this.numberDisplayRule.apply(v.getValue()) + " " + v.getUnit())
+ .collect(Collectors.joining(" + "));
+ return UnitConversionRecord.valueOf(fromUnitString, toExpression,
+ inputValueString, "");
+
+ }
+
+ private UnitConversionRecord convertUnitToUnit(String fromUnitString,
+ String toUnitString, String inputValueString, Unit fromUnit,
+ Unit toUnit, UncertainDouble uncertainValue) {
+ if (!fromUnit.canConvertTo(toUnit))
+ throw this.viewError("Could not convert between %s and %s", fromUnit,
+ toUnit);
- ucview.showUnitConversionOutput(
- UnitConversionRecord.valueOf(fromUnitString, toUnitString,
- inputValueString, outputValueString));
- } else
- throw new UnsupportedOperationException(
- "This function can only be called when the view is a UnitConversionView.");
+ // convert - we will need to erase uncertainty for non-linear units, so
+ // we need to treat linear and non-linear units differently
+ final String outputValueString;
+ if (fromUnit instanceof LinearUnit && toUnit instanceof LinearUnit) {
+ final LinearUnit fromLinear = (LinearUnit) fromUnit;
+ final LinearUnit toLinear = (LinearUnit) toUnit;
+ final LinearUnitValue initialValue = LinearUnitValue.of(fromLinear,
+ uncertainValue);
+ final LinearUnitValue converted = initialValue.convertTo(toLinear);
+
+ outputValueString = this.numberDisplayRule.apply(converted.getValue());
+ } else {
+ final UnitValue initialValue = UnitValue.of(fromUnit,
+ uncertainValue.value());
+ final UnitValue converted = initialValue.convertTo(toUnit);
+
+ outputValueString = this.numberDisplayRule
+ .apply(UncertainDouble.of(converted.getValue(), 0));
+ }
+
+ return UnitConversionRecord.valueOf(fromUnitString, toUnitString,
+ inputValueString, outputValueString);
}
/**
@@ -770,7 +810,7 @@ public final class Presenter {
* @return true iff the One-Way Conversion feature is available (views that
* show units as a list will have metric units removed from the From
* unit list and imperial/USC units removed from the To unit list)
- *
+ *
* @since 2022-03-30
*/
public boolean oneWayConversionEnabled() {
@@ -994,6 +1034,7 @@ public final class Presenter {
.entrySet().stream();
var toUnits = this.database.unitMapPrefixless(this.showDuplicates)
.entrySet().stream();
+ var unitSets = this.database.unitSetMap().entrySet().stream();
// filter by dimension, if one is selected
if (selectedDimensionName.isPresent()) {
@@ -1003,6 +1044,8 @@ public final class Presenter {
u -> viewDimension.equals(u.getValue().getDimension()));
toUnits = toUnits.filter(
u -> viewDimension.equals(u.getValue().getDimension()));
+ unitSets = unitSets.filter(us -> viewDimension
+ .equals(us.getValue().get(0).getDimension()));
}
// filter by unit type, if desired
@@ -1011,13 +1054,20 @@ public final class Presenter {
this::isSemiMetric) != UnitType.METRIC);
toUnits = toUnits.filter(u -> UnitType.getType(u.getValue(),
this::isSemiMetric) != UnitType.NON_METRIC);
+ // unit sets are never considered metric
+ unitSets = unitSets
+ .filter(us -> this.metricExceptions.contains(us.getKey()));
}
// set unit names
ucview.setFromUnitNames(fromUnits.flatMap(this::applySearchRule)
.map(Map.Entry::getKey).collect(Collectors.toSet()));
- ucview.setToUnitNames(toUnits.flatMap(this::applySearchRule)
- .map(Map.Entry::getKey).collect(Collectors.toSet()));
+ final var toUnitNames = toUnits.flatMap(this::applySearchRule)
+ .map(Map.Entry::getKey);
+ final var unitSetNames = unitSets.map(Map.Entry::getKey);
+ final var toNames = Stream.concat(toUnitNames, unitSetNames)
+ .collect(Collectors.toSet());
+ ucview.setToUnitNames(toNames);
}
}