diff --git a/src/controller/IndoorHelperController.java b/src/controller/IndoorHelperController.java index 637e8c7..48e08e5 100644 --- a/src/controller/IndoorHelperController.java +++ b/src/controller/IndoorHelperController.java @@ -1,30 +1,12 @@ // License: AGPL. For details, see LICENSE file. package controller; -import static org.openstreetmap.josm.tools.I18n.tr; - -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.ItemEvent; -import java.awt.event.ItemListener; -import java.awt.event.KeyEvent; -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import javax.swing.AbstractAction; -import javax.swing.JOptionPane; - +import model.IndoorHelperModel; +import model.IndoorLevel; +import model.TagCatalog.IndoorObject; import org.openstreetmap.josm.actions.ValidateAction; import org.openstreetmap.josm.data.Preferences; -import org.openstreetmap.josm.data.osm.DataSet; -import org.openstreetmap.josm.data.osm.OsmDataManager; -import org.openstreetmap.josm.data.osm.OsmPrimitive; -import org.openstreetmap.josm.data.osm.Tag; +import org.openstreetmap.josm.data.osm.*; import org.openstreetmap.josm.gui.MainApplication; import org.openstreetmap.josm.gui.help.HelpBrowser; import org.openstreetmap.josm.gui.mappaint.MapPaintStyles; @@ -32,15 +14,16 @@ import org.openstreetmap.josm.spi.preferences.MapListSetting; import org.openstreetmap.josm.spi.preferences.Setting; import org.openstreetmap.josm.tools.Shortcut; - -import model.IndoorHelperModel; -import model.IndoorLevel; -import model.TagCatalog.IndoorObject; import views.LevelSelectorView; import views.ToolBoxView; +import javax.swing.*; +import java.awt.event.*; +import java.util.*; + +import static org.openstreetmap.josm.tools.I18n.tr; + /** - * * IndoorHelper controller class which provides the communication between the * IndoorHelperModel and the different views. * @@ -51,7 +34,7 @@ public class IndoorHelperController { private final IndoorHelperModel model = new IndoorHelperModel(); private ToolBoxView toolboxView; - private String levelValue, levelNum; + private String workingLevel, levelNum; private final SpaceAction spaceAction = new SpaceAction(); private Shortcut spaceShortcut; private final EnterAction enterAction = new EnterAction(); @@ -74,8 +57,8 @@ public class IndoorHelperController { // collecting all tags List tags = new ArrayList<>(); - if (!toolboxView.getLevelCheckBoxStatus() && !levelValue.equals("")) { - tags.add(new Tag("level", levelValue)); + if (!toolboxView.getLevelCheckBoxStatus() && !workingLevel.equals("")) { + tags.add(new Tag("level", workingLevel)); } if (!toolboxView.getLevelNameText().isEmpty() && !toolboxView.getLevelCheckBoxStatus()) { tags.add(new Tag("level_name", toolboxView.getLevelNameText())); @@ -107,9 +90,6 @@ public class IndoorHelperController { /** * The listener which is called when a new item in the object list is selected. - * - * @author egru - * @author rebsc */ private final ItemListener toolObjectItemListener = e -> { if (toolboxView.getSelectedObject().equals(IndoorObject.ROOM)) { @@ -126,23 +106,17 @@ public class IndoorHelperController { /** * The listener which is called when the LevelCheckBox is selected. - * - * @author rebsc */ private final ItemListener toolLevelCheckBoxListener = e -> toolboxView .setLVLUiElementsEnabled(e.getStateChange() != ItemEvent.SELECTED); /** * The listener which is called when the helpButton got pushed. - * - * @author rebsc */ private final ActionListener toolHelpButtonListener = e -> HelpBrowser.setUrlForHelpTopic("Plugin/IndoorHelper"); /** * The listener which is called when the addLevelButton got pushed. - * - * @author rebsc */ private final ActionListener toolAddLevelButtonListener = e -> { if (selectorView == null) { @@ -159,16 +133,12 @@ public class IndoorHelperController { /** * The listener which is called when the MultiCheckBox is selected. - * - * @author rebsc */ private final ItemListener toolMultiCheckBoxListener = e -> toolboxView .setMultiUiElementsEnabled(e.getStateChange() != ItemEvent.SELECTED); /** * The listener which is called when the OUTER Button got pushed. - * - * @author rebsc */ private final ActionListener toolOuterButtonListener = e -> { // Select drawing action @@ -181,8 +151,6 @@ public class IndoorHelperController { /** * The listener which is called when the INNER Button got pushed. - * - * @author rebsc */ private final ActionListener toolInnerButtonListener = e -> { // Select drawing action @@ -195,29 +163,21 @@ public class IndoorHelperController { /** * Listener for preset button 1. - * - * @author egru */ private final ActionListener preset1Listener = e -> model.addTagsToOSM(toolboxView.getPreset1()); /** * Listener for preset button 2. - * - * @author egru */ private final ActionListener preset2Listener = e -> model.addTagsToOSM(toolboxView.getPreset2()); /** * Listener for preset button 3. - * - * @author egru */ private final ActionListener preset3Listener = e -> model.addTagsToOSM(toolboxView.getPreset3()); /** * Listener for preset button 4. - * - * @author egru */ private final ActionListener preset4Listener = e -> model.addTagsToOSM(toolboxView.getPreset4()); @@ -230,8 +190,6 @@ private void refreshPresets() { /** * Specific listener for the applyButton - * - * @author rebsc */ private final ActionListener toolLevelOkButtonListener = e -> { levelHelp = true; @@ -254,8 +212,6 @@ private void refreshPresets() { /** * Specific listener for the cancelButton - * - * @author rebsc */ private final ActionListener toolLevelCancelButtonListener = e -> { selectorView.dispose(); @@ -264,8 +220,6 @@ private void refreshPresets() { /** * General listener for LevelSelectorView window - * - * @author rebsc */ class ToolSelectorWindowSListener extends WindowAdapter { @@ -309,7 +263,7 @@ public IndoorHelperController() { innerHelp = false; levelHelp = false; innerRelation = null; - levelValue = ""; + workingLevel = ""; levelNum = ""; } @@ -346,8 +300,6 @@ private void addLevelSelectorListeners() { /** * Shortcut for spacebar - * - * @author rebsc */ private class SpaceAction extends AbstractAction { @@ -389,8 +341,6 @@ public void actionPerformed(ActionEvent e) { /** * Shortcut for enter - * - * @author rebsc */ private class EnterAction extends AbstractAction { @@ -417,28 +367,27 @@ public void actionPerformed(ActionEvent e) { * specific tag (key). Just unsets the disabled state if object has a tag-value which is part of the * current working level. * - * @author rebsc * @param key specific key to unset hidden objects which contains it */ public void unsetSpecificKeyFilter(String key) { - DataSet editDataSet = OsmDataManager.getInstance().getEditDataSet(); if (editDataSet != null) { - Collection p = editDataSet.allPrimitives(); - int level = Integer.parseInt(levelValue); - - // Find all primitives with the specific tag and check if value is part of the current - // workinglevel. After that unset the disabled status. - for (OsmPrimitive osm : p) { - if ((osm.isDisabledAndHidden() || osm.isDisabled()) && osm.hasKey(key)) { - for (Map.Entry e : osm.getInterestingTags().entrySet()) { - if (e.getKey().equals(key)) { + ArrayList primitiveCollection = new ArrayList<>(editDataSet.allPrimitives()); + int level = Integer.parseInt(workingLevel); + // Find all primitives with the specific tag and check if value is part of the current working level. + // After that unset the disabled status. + for (OsmPrimitive primitive : primitiveCollection) { + if ((primitive.isDisabledAndHidden() || primitive.isDisabled()) && primitive.hasKey(key)) { + for (Map.Entry entry : primitive.getInterestingTags().entrySet()) { + if (entry.getKey().equals(key)) { // Compare values to current working level - if (IndoorLevel.isPartOfWorkingLevel(e.getValue(), level)) { - osm.unsetDisabledState(); - } else { - osm.setDisabledState(true); - } + new Thread(() -> { + if (IndoorLevel.isPartOfWorkingLevel(entry.getValue(), level)) { + primitive.unsetDisabledState(); + } else { + primitive.setDisabledType(true); + } + }).start(); } } } @@ -447,21 +396,13 @@ public void unsetSpecificKeyFilter(String key) { } /** - * Function which updates the current working level tag - * - * @param indoorLevel current working level - */ - public void setIndoorLevel(String indoorLevel) { - this.toolboxView.setLevelLabel(indoorLevel); - } - - /** - * Function which gets the current working level tag + * Function sets the current working level and updates the toolbox level label * - * @param indoorLevel current working level + * @param indoorLevel current working level as string */ - public void getIndoorLevel(String indoorLevel) { - levelValue = indoorLevel; + public void setWorkingLevel(String indoorLevel) { + workingLevel = indoorLevel; + toolboxView.setLevelLabel(workingLevel); } /** @@ -497,7 +438,7 @@ private static void setPluginPreferences(boolean enabled) { for (Map map : styleMapsNew) { if (map.containsValue(tr("Indoor"))) { // find saved preference value - enabled = map.containsValue(tr("true")); + enabled = map.containsValue(tr("true")); styleMapsNew.remove(map); break; } diff --git a/src/model/IndoorLevel.java b/src/model/IndoorLevel.java index 8785da1..5f4a0ca 100644 --- a/src/model/IndoorLevel.java +++ b/src/model/IndoorLevel.java @@ -1,23 +1,16 @@ // License: AGPL. For details, see LICENSE file. package model; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - import org.openstreetmap.josm.data.osm.Tag; /** - * * The class to save a level of the building. * * @author egru - * */ public class IndoorLevel { - private static final Pattern RANGE = Pattern.compile("(-?[0-9]+)-(-?[0-9]+)"); - private Tag levelNumberTag; private Tag nameTag; @@ -34,7 +27,7 @@ public IndoorLevel(int levelNumber) { * Constructor which adds level number and name tag. * * @param levelNumber number of the level - * @param nameTag optional name tag for the level + * @param nameTag optional name tag for the level */ public IndoorLevel(int levelNumber, String nameTag) { this.setLevelNumber(levelNumber); @@ -99,26 +92,61 @@ public boolean hasEmptyName() { return this.nameTag == null; } - public static boolean isPartOfWorkingLevel(String vals, int level) { - for (String val : vals.split(";")) { - int firstVal, secVal; - Matcher m = RANGE.matcher(val); - - //Extract values - if (m.matches()) { - firstVal = Integer.parseInt(m.group(1)); - secVal = Integer.parseInt(m.group(2)); - } else { - firstVal = Integer.parseInt(val); - secVal = firstVal; + /** + * Checks if repeat_on tag value includes current working level value + * @param repeatOnValue tag as string + * @param workingLevel current working level as value + * @return true if repeat_on tag includes current working level, else false + */ + public static boolean isPartOfWorkingLevel(String repeatOnValue, int workingLevel) { + // check if repeat_on value includes amount of levels + if (repeatOnValue.contains(";")) { + try { + String[] levels = repeatOnValue.split(";"); + for (String levelIndex : levels) { + if (workingLevel == Integer.parseInt(levelIndex)) return true; + } + } catch (Exception ignored) { + return false; } - - // Compare values to current working level - if (level >= firstVal && level <= secVal) { - return true; + } + // check if repeat_on value includes a range + else if (repeatOnValue.contains("-")) { + try { + char[] elements = repeatOnValue.toCharArray(); + int minLimit = 0; + int maxLimit = 0; + + if (repeatOnValue.lastIndexOf("-") == 1) { // case 2-1 + minLimit = Integer.parseInt(Character.toString(elements[0])); + maxLimit = Integer.parseInt(Character.toString(elements[2])); + } else if (repeatOnValue.lastIndexOf("-") == 2) { // case -2-1 + minLimit = Integer.parseInt(Character.toString(elements[1])) * -1; + maxLimit = Integer.parseInt(Character.toString(elements[3])); + } else if (repeatOnValue.lastIndexOf("-") == 3) { // case -2--1 + minLimit = Integer.parseInt(Character.toString(elements[1])) * -1; + maxLimit = Integer.parseInt(Character.toString(elements[4])) * -1; + } + + if (minLimit == maxLimit) { + return false; + } + + if (minLimit <= workingLevel && maxLimit >= workingLevel) { + return true; + } + } catch (Exception ignored) { + return false; + } + } + // repeat_on value is single value + else { + try { + return workingLevel == Integer.parseInt(repeatOnValue); + } catch (Exception ignored) { + return false; } } - return false; } } diff --git a/src/org/openstreetmap/josm/plugins/indoorhelper/IndoorHelperPlugin.java b/src/org/openstreetmap/josm/plugins/indoorhelper/IndoorHelperPlugin.java index 47d76cf..f3b668b 100644 --- a/src/org/openstreetmap/josm/plugins/indoorhelper/IndoorHelperPlugin.java +++ b/src/org/openstreetmap/josm/plugins/indoorhelper/IndoorHelperPlugin.java @@ -1,12 +1,8 @@ // License: AGPL. For details, see LICENSE file. package org.openstreetmap.josm.plugins.indoorhelper; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - +import controller.IndoorHelperController; +import io.controller.ImportDataController; import org.openstreetmap.josm.gui.MainApplication; import org.openstreetmap.josm.gui.MapFrame; import org.openstreetmap.josm.gui.autofilter.AutoFilter; @@ -20,8 +16,7 @@ import org.openstreetmap.josm.plugins.PluginInformation; import org.openstreetmap.josm.spi.preferences.Config; -import controller.IndoorHelperController; -import io.controller.ImportDataController; +import java.io.*; /** * This is the main class for the indoorhelper plug-in. @@ -105,18 +100,13 @@ public void activeOrEditLayerChanged(ActiveLayerChangeEvent e) { @Override public void paintableInvalidated(PaintableInvalidationEvent event) { AutoFilter currentAutoFilter = AutoFilterManager.getInstance().getCurrentAutoFilter(); - if (currentAutoFilter != null) { if (indoorController != null) { - String currentFilterValue = currentAutoFilter.getLabel(); - - indoorController.setIndoorLevel(currentFilterValue); - indoorController.getIndoorLevel(currentFilterValue); + indoorController.setWorkingLevel(currentAutoFilter.getLabel()); indoorController.unsetSpecificKeyFilter("repeat_on"); } } else if (indoorController != null) { - indoorController.setIndoorLevel(""); - indoorController.getIndoorLevel(""); + indoorController.setWorkingLevel(""); } } diff --git a/test/unit/model/IndoorLevelTest.java b/test/unit/model/IndoorLevelTest.java index 365e4ed..8cf6a0d 100644 --- a/test/unit/model/IndoorLevelTest.java +++ b/test/unit/model/IndoorLevelTest.java @@ -1,12 +1,10 @@ // License: AGPL. For details, see LICENSE file. -package unit.model; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; +package model; import org.junit.Test; -import model.IndoorLevel; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; /** * Unit tests of {@link IndoorLevel} class. @@ -14,7 +12,7 @@ public class IndoorLevelTest { /** - * Test case for {@link IndoorLevel#isisPartOfWorkingLevel} method. + * Test case for {@link IndoorLevel#isPartOfWorkingLevel} method. */ @Test public void testIsPartOfWorkingLevel() { @@ -22,6 +20,7 @@ public void testIsPartOfWorkingLevel() { assertTrue(IndoorLevel.isPartOfWorkingLevel("-3--1", -2)); assertTrue(IndoorLevel.isPartOfWorkingLevel("-3--1", -1)); assertFalse(IndoorLevel.isPartOfWorkingLevel("-3--1", 0)); + assertFalse(IndoorLevel.isPartOfWorkingLevel("-3--1", -4)); assertTrue(IndoorLevel.isPartOfWorkingLevel("-1;0;1", -1)); assertTrue(IndoorLevel.isPartOfWorkingLevel("-1;0;1", 0)); @@ -38,10 +37,14 @@ public void testIsPartOfWorkingLevel() { assertTrue(IndoorLevel.isPartOfWorkingLevel("0-3", 0)); assertTrue(IndoorLevel.isPartOfWorkingLevel("0-3", 1)); assertTrue(IndoorLevel.isPartOfWorkingLevel("0-3", 3)); + assertFalse(IndoorLevel.isPartOfWorkingLevel("0-3", 4)); assertFalse(IndoorLevel.isPartOfWorkingLevel("2;3;4", 1)); assertTrue(IndoorLevel.isPartOfWorkingLevel("2;3;4", 2)); assertTrue(IndoorLevel.isPartOfWorkingLevel("2;3;4", 3)); assertTrue(IndoorLevel.isPartOfWorkingLevel("2;3;4", 4)); + + assertFalse(IndoorLevel.isPartOfWorkingLevel(".", 4)); + assertFalse(IndoorLevel.isPartOfWorkingLevel(";t-3", 4)); } } diff --git a/test/unit/model/PresetCounterTest.java b/test/unit/model/PresetCounterTest.java index 6fc3bae..bb8a48b 100644 --- a/test/unit/model/PresetCounterTest.java +++ b/test/unit/model/PresetCounterTest.java @@ -1,15 +1,13 @@ // License: AGPL. For details, see LICENSE file. -package unit.model; +package model; -import static org.junit.Assert.assertEquals; +import model.TagCatalog.IndoorObject; +import org.junit.Test; import java.util.ArrayList; import java.util.List; -import org.junit.Test; - -import model.PresetCounter; -import model.TagCatalog.IndoorObject; +import static org.junit.Assert.assertEquals; /** * Unit tests of {@link PresetCounter} class. diff --git a/test/unit/parser/BIMtoOSMParserTest.java b/test/unit/parser/BIMtoOSMParserTest.java index 1e2f350..12df1c5 100644 --- a/test/unit/parser/BIMtoOSMParserTest.java +++ b/test/unit/parser/BIMtoOSMParserTest.java @@ -1,11 +1,10 @@ // License: AGPL. For details, see LICENSE file. -package unit.parser; - -import java.io.File; +package parser; +import io.parser.BIMtoOSMParser; import org.junit.Test; -import io.parser.BIMtoOSMParser; +import java.io.File; /** * Unit tests of {@link BIMtoOSMParser} class. * @author rebsc