diff options
Diffstat (limited to 'src/main/java/sevenUnitsGUI/Presenter.java')
-rw-r--r-- | src/main/java/sevenUnitsGUI/Presenter.java | 153 |
1 files changed, 96 insertions, 57 deletions
diff --git a/src/main/java/sevenUnitsGUI/Presenter.java b/src/main/java/sevenUnitsGUI/Presenter.java index 57d353d..9f8fe69 100644 --- a/src/main/java/sevenUnitsGUI/Presenter.java +++ b/src/main/java/sevenUnitsGUI/Presenter.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2021 Adrien Hopkins + * Copyright (C) 2021-2022 Adrien Hopkins * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by @@ -19,13 +19,11 @@ package sevenUnitsGUI; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; -import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.NoSuchElementException; import java.util.Optional; -import java.util.OptionalDouble; import java.util.Scanner; import java.util.Set; import java.util.function.Function; @@ -135,25 +133,6 @@ public final class Presenter { } /** - * Accepts a collection and returns a set with the unique elements in that - * collection - * - * @param <E> type of element in collection - * @param collection collection to uniquify - * @return unique collection - * @since 2022-02-26 - */ - private static <E> Set<E> unique(Collection<E> collection) { - final Set<E> uniqueSet = new HashSet<>(); - for (final E e : collection) { - if (!uniqueSet.contains(e)) { - uniqueSet.add(e); - } - } - return uniqueSet; - } - - /** * @return {@code line} with any comments removed. * @since 2021-03-13 */ @@ -206,7 +185,7 @@ public final class Presenter { * removed from the From unit list and imperial/USC units removed from the To * unit list. */ - private boolean oneWayConversion; + private boolean oneWayConversionEnabled; /** * If this is false, duplicate units will be removed from the unit view in @@ -260,13 +239,6 @@ public final class Presenter { } /** - * Gets settings from the view and applies them to both view and presenter. - * - * @since 2021-12-15 - */ - public void applySettings() {} - - /** * Converts from the view's input expression to its output expression. * Displays an error message if any of the required fields are invalid. * @@ -316,8 +288,9 @@ public final class Presenter { // convert and show output if (from.getUnit().canConvertTo(to)) { final double value = from.asUnitValue().convertTo(to).getValue(); - xcview.showExpressionConversionOutput(fromExpression, toExpression, - value); + final UnitConversionRecord uc = UnitConversionRecord.valueOf( + fromExpression, toExpression, "", String.valueOf(value)); + xcview.showExpressionConversionOutput(uc); } else { this.view.showErrorMessage("Conversion Error", "Cannot convert between \"" + fromExpression + "\" and \"" @@ -343,49 +316,82 @@ public final class Presenter { if (this.view instanceof UnitConversionView) { final UnitConversionView ucview = (UnitConversionView) this.view; - final Optional<Unit> fromUnitOptional = ucview.getFromSelection(); - final Optional<Unit> toUnitOptional = ucview.getToSelection(); - final OptionalDouble valueOptional = ucview.getInputValue(); + final Optional<String> fromUnitOptional = ucview.getFromSelection(); + final Optional<String> toUnitOptional = ucview.getToSelection(); + final String valueString = ucview.getInputValue(); - // ensure everything is obtained - final Unit fromUnit, toUnit; - final double value; + // extract values from optionals + final String fromUnitString, toUnitString; if (fromUnitOptional.isPresent()) { - fromUnit = fromUnitOptional.orElseThrow(); + fromUnitString = fromUnitOptional.orElseThrow(); } else { - this.view.showErrorMessage("Unit Conversion Error", + this.view.showErrorMessage("Unit Selection Error", "Please specify a From unit"); return; } if (toUnitOptional.isPresent()) { - toUnit = toUnitOptional.orElseThrow(); + toUnitString = toUnitOptional.orElseThrow(); } else { - this.view.showErrorMessage("Unit Conversion Error", + this.view.showErrorMessage("Unit Selection Error", "Please specify a To unit"); return; } - if (valueOptional.isPresent()) { - value = valueOptional.orElseThrow(); - } else { - this.view.showErrorMessage("Unit Conversion Error", - "Please specify a valid value"); + + // convert strings to data, checking if anything is invalid + final Unit fromUnit, toUnit; + final double value; + + 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 { + value = Double.parseDouble(valueString); + } catch (final NumberFormatException e) { + this.view.showErrorMessage("Value Error", + "Invalid value " + valueString); return; } if (!fromUnit.canConvertTo(toUnit)) - throw new AssertionError( - "From and To units incompatible (should be impossible)"); + throw this.viewError("Could not convert between %s and %s", + fromUnit, toUnit); // convert! final UnitValue initialValue = UnitValue.of(fromUnit, value); final UnitValue converted = initialValue.convertTo(toUnit); - ucview.showUnitConversionOutput(initialValue, converted); + + ucview.showUnitConversionOutput( + UnitConversionRecord.fromValues(initialValue, converted)); } else throw new UnsupportedOperationException( "This function can only be called when the view is a UnitConversionView."); } /** + * @return true iff duplicate units are shown in unit lists + * @since 2022-03-30 + */ + public boolean duplicateUnitsShown() { + return this.showDuplicateUnits; + } + + /** + * @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 isOneWayConversionEnabled() { + return this.oneWayConversionEnabled; + } + + /** * Loads settings from the user's settings file and applies them to the view. * * @since 2021-12-15 @@ -403,7 +409,7 @@ public final class Presenter { // unit conversion specific stuff if (this.view instanceof UnitConversionView) { final UnitConversionView ucview = (UnitConversionView) this.view; - ucview.setDimensions(unique(this.database.dimensionMap().values())); + ucview.setDimensionNames(this.database.dimensionMap().keySet()); } } @@ -417,6 +423,26 @@ public final class Presenter { */ public void saveSettings() {} + /** + * @param oneWayConversionEnabled whether not one-way conversion should be + * enabled + * @since 2022-03-30 + * @see {@link #isOneWayConversionEnabled} + */ + public void setOneWayConversionEnabled(boolean oneWayConversionEnabled) { + this.oneWayConversionEnabled = oneWayConversionEnabled; + this.updateView(); + } + + /** + * @param showDuplicateUnits whether or not duplicate units should be shown + * @since 2022-03-30 + */ + public void setShowDuplicateUnits(boolean showDuplicateUnits) { + this.showDuplicateUnits = showDuplicateUnits; + this.updateView(); + } + void unitNameSelected() {} /** @@ -427,17 +453,30 @@ public final class Presenter { public void updateView() { if (this.view instanceof UnitConversionView) { final UnitConversionView ucview = (UnitConversionView) this.view; - final ObjectProduct<BaseDimension> viewDimension = ucview - .getSelectedDimension().orElseThrow(); + final ObjectProduct<BaseDimension> viewDimension = this.database + .getDimension(((UnitConversionView) this.view) + .getSelectedDimensionName().orElseThrow()); - final Set<Unit> units = this.database + final Set<String> units = this.database .unitMapPrefixless(this.showDuplicateUnits).entrySet().stream() .map(Map.Entry::getValue) .filter(u -> viewDimension.equals(u.getDimension())) - .collect(Collectors.toSet()); + .map(Unit::getName).collect(Collectors.toSet()); - ucview.setFromUnits(units); - ucview.setToUnits(units); + ucview.setFromUnitNames(units); + ucview.setToUnitNames(units); } } + + /** + * @param message message to add + * @param args string formatting arguments for message + * @return AssertionError stating that an error has happened in the view's + * code + * @since 2022-04-09 + */ + private AssertionError viewError(String message, Object... args) { + return new AssertionError("View Programming Error (from " + this.view + + "): " + String.format(message, args)); + } } |