// License: GPL. For details, see LICENSE file. package org.openstreetmap.josm.plugins.graphview.plugin.dialogs; import static org.openstreetmap.josm.plugins.graphview.core.property.VehiclePropertyTypes.MAX_INCLINE_DOWN; import static org.openstreetmap.josm.plugins.graphview.core.property.VehiclePropertyTypes.MAX_INCLINE_UP; import static org.openstreetmap.josm.plugins.graphview.core.property.VehiclePropertyTypes.MAX_TRACKTYPE; import static org.openstreetmap.josm.plugins.graphview.core.property.VehiclePropertyTypes.SURFACE_BLACKLIST; import static org.openstreetmap.josm.tools.I18n.tr; import java.awt.Frame; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.Arrays; import java.util.Collection; import java.util.EnumMap; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.Map; import javax.swing.BorderFactory; import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JDialog; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JTextField; import org.openstreetmap.josm.plugins.graphview.core.access.AccessType; import org.openstreetmap.josm.plugins.graphview.core.property.VehiclePropertyType; import org.openstreetmap.josm.plugins.graphview.core.property.VehiclePropertyTypes; import org.openstreetmap.josm.plugins.graphview.plugin.preferences.PreferenceAccessParameters; import org.openstreetmap.josm.plugins.graphview.plugin.preferences.VehiclePropertyStringParser.PropertyValueSyntaxException; public class AccessParameterDialog extends JDialog { public interface BookmarkAction { void execute(String name, PreferenceAccessParameters parameters); } /** * map that contains all float value vehicle properties (as those can be treated uniformly) * and their labels */ private static final Map<VehiclePropertyType<Float>, String> FLOAT_PROPERTIES; static { FLOAT_PROPERTIES = new LinkedHashMap<>(); FLOAT_PROPERTIES.put(VehiclePropertyTypes.HEIGHT, tr("height (m)")); FLOAT_PROPERTIES.put(VehiclePropertyTypes.WIDTH, tr("width (m)")); FLOAT_PROPERTIES.put(VehiclePropertyTypes.LENGTH, tr("length (m)")); FLOAT_PROPERTIES.put(VehiclePropertyTypes.SPEED, tr("speed (km/h)")); FLOAT_PROPERTIES.put(VehiclePropertyTypes.WEIGHT, tr("weight (t)")); FLOAT_PROPERTIES.put(VehiclePropertyTypes.AXLELOAD, tr("axleload (t)")); } private static final Collection<Character> FORBIDDEN_CHARS = Arrays.asList(',', ';', '{', '}', '=', '|'); private class BookmarkNamePanel extends JPanel { private final JTextField bookmarkNameTextField; BookmarkNamePanel(String initialName) { super(); this.setBorder(BorderFactory.createTitledBorder(tr("Bookmark name"))); this.setLayout(new BoxLayout(this, BoxLayout.X_AXIS)); bookmarkNameTextField = new JTextField(initialName); this.add(bookmarkNameTextField); } public String getBookmarkName() { String name = bookmarkNameTextField.getText(); if (existingBookmarkNames.contains(name)) { JOptionPane.showMessageDialog(this, tr("Bookmark name already exists!")); return null; } for (char nameChar : name.toCharArray()) { if (FORBIDDEN_CHARS.contains(nameChar)) { JOptionPane.showMessageDialog(this, tr("Bookmark name must not contain ''{0}''!", nameChar)); return null; } } return name; } } private static class AccessClassPanel extends JPanel { private final JTextField accessClassTextField; AccessClassPanel(PreferenceAccessParameters initialParameters) { super(); this.setBorder(BorderFactory.createTitledBorder(tr("Access class"))); this.setLayout(new BoxLayout(this, BoxLayout.X_AXIS)); accessClassTextField = new JTextField(initialParameters.getAccessClass()); this.add(accessClassTextField); } public String getAccessClass() { String name = accessClassTextField.getText(); for (char nameChar : name.toCharArray()) { if (FORBIDDEN_CHARS.contains(nameChar)) { JOptionPane.showMessageDialog(this, tr("Access class must not contain ''{0}''!", nameChar)); return null; } } return name; } } private static class AccessTypesPanel extends JPanel { private static final int COLS = 4; private final Map<AccessType, JCheckBox> accessTypeCheckBoxes = new EnumMap<>(AccessType.class); AccessTypesPanel(PreferenceAccessParameters initialParameters) { super(); this.setBorder(BorderFactory.createTitledBorder(tr("Access types"))); this.setLayout( new GridLayout(((COLS-1 + AccessType.values().length) / COLS), COLS)); for (AccessType accessType : AccessType.values()) { JCheckBox checkBox = new JCheckBox(accessType.toString()); checkBox.setSelected(initialParameters.getAccessTypeUsable(accessType)); accessTypeCheckBoxes.put(accessType, checkBox); this.add(checkBox); } } public Collection<AccessType> getUsableAccessTypes() { Collection<AccessType> usableAccessTypes = new LinkedList<>(); for (AccessType accessType : AccessType.values()) { if (accessTypeCheckBoxes.get(accessType).isSelected()) { usableAccessTypes.add(accessType); } } return usableAccessTypes; } } private static class VehiclePropertiesPanel extends JPanel { private static final int COLS = 2; private final Map<VehiclePropertyType<Float>, JTextField> floatPropertyTextFields = new HashMap<>(); VehiclePropertiesPanel(PreferenceAccessParameters initialParameters) { super(); this.setBorder(BorderFactory.createTitledBorder(tr("Vehicle properties"))); this.setLayout(new GridLayout(((COLS-1 + FLOAT_PROPERTIES.size()) / COLS), 2*COLS)); for (VehiclePropertyType<Float> vehicleProperty : FLOAT_PROPERTIES.keySet()) { JLabel label = new JLabel(FLOAT_PROPERTIES.get(vehicleProperty)); this.add(label); JTextField textField = new JTextField(); String vehiclePropertyString = initialParameters.getVehiclePropertyString(vehicleProperty); if (vehiclePropertyString != null) { textField.setText(vehiclePropertyString); } floatPropertyTextFields.put(vehicleProperty, textField); this.add(textField); } } public Map<VehiclePropertyType<?>, String> getVehiclePropertyStrings() { Map<VehiclePropertyType<?>, String> vehiclePropertyStrings = new HashMap<>(); for (VehiclePropertyType<Float> vehicleProperty : floatPropertyTextFields.keySet()) { String textFieldContent = floatPropertyTextFields.get(vehicleProperty).getText(); if (textFieldContent.trim().length() > 0) { vehiclePropertyStrings.put(vehicleProperty, textFieldContent); } } return vehiclePropertyStrings; } } private static class RoadQualityPanel extends JPanel { private JTextField inclineUpTextField; private JTextField inclineDownTextField; private JTextField surfaceTextField; private JTextField tracktypeTextField; RoadQualityPanel(PreferenceAccessParameters initialParameters) { this.setBorder(BorderFactory.createTitledBorder(tr("Road requirements"))); this.setLayout(new GridLayout(4, 2)); /* incline up */ { JLabel inclineUpLabel = new JLabel(tr("Max. incline up (%, pos.)")); inclineUpLabel.setToolTipText(tr("Maximum incline the vehicle can go up")); this.add(inclineUpLabel); inclineUpTextField = new JTextField(); String vehiclePropertyString = initialParameters.getVehiclePropertyString(MAX_INCLINE_UP); if (vehiclePropertyString != null) { inclineUpTextField.setText(vehiclePropertyString); } inclineUpTextField.setToolTipText(tr("Maximum incline the vehicle can go up")); this.add(inclineUpTextField); } /* incline down */ { JLabel inclineDownLabel = new JLabel(tr("Max. incline down (%, pos.)")); inclineDownLabel.setToolTipText(tr("Maximum incline the vehicle can go down")); this.add(inclineDownLabel); inclineDownTextField = new JTextField(); String vehiclePropertyString = initialParameters.getVehiclePropertyString(MAX_INCLINE_DOWN); if (vehiclePropertyString != null) { inclineDownTextField.setText(vehiclePropertyString); } inclineDownTextField.setToolTipText(tr("Maximum incline the vehicle can go down")); this.add(inclineDownTextField); } /* surface */ { JLabel surfaceLabel = new JLabel(tr("Surface blacklist")); surfaceLabel.setToolTipText(tr("List of surfaces the vehicle cannot use, " + "values are separated by semicolons (;)")); this.add(surfaceLabel); surfaceTextField = new JTextField(); String vehiclePropertyString = initialParameters.getVehiclePropertyString(SURFACE_BLACKLIST); if (vehiclePropertyString != null) { surfaceTextField.setText(vehiclePropertyString); } surfaceTextField.setToolTipText(tr("List of surfaces the vehicle cannot use, " + "values are separated by semicolons (;)")); this.add(surfaceTextField); } /* tracktype */ { JLabel tracktypeLabel = new JLabel(tr("max. tracktype grade")); tracktypeLabel.setToolTipText(tr("Worst tracktype (1-5) the vehicle can still use," + " 0 for none")); this.add(tracktypeLabel); tracktypeTextField = new JTextField(); String vehiclePropertyString = initialParameters.getVehiclePropertyString(MAX_TRACKTYPE); if (vehiclePropertyString != null) { tracktypeTextField.setText(vehiclePropertyString); } tracktypeTextField.setToolTipText(tr("Worst tracktype (1-5) the vehicle can still use," + " 0 for none")); this.add(tracktypeTextField); } } public Map<VehiclePropertyType<?>, String> getVehiclePropertyStrings() { Map<VehiclePropertyType<?>, String> vehiclePropertyStrings = new HashMap<>(); String incUpString = inclineUpTextField.getText(); if (incUpString.trim().length() > 0) { vehiclePropertyStrings.put(MAX_INCLINE_UP, incUpString); } String incDownString = inclineDownTextField.getText(); if (incDownString.trim().length() > 0) { vehiclePropertyStrings.put(MAX_INCLINE_DOWN, incDownString); } String surfaceString = surfaceTextField.getText(); if (surfaceString.trim().length() > 0) { vehiclePropertyStrings.put(SURFACE_BLACKLIST, surfaceString); } String tracktypeString = tracktypeTextField.getText(); if (tracktypeString.trim().length() > 0) { vehiclePropertyStrings.put(MAX_TRACKTYPE, tracktypeString); } return vehiclePropertyStrings; } } private class OkCancelPanel extends JPanel { OkCancelPanel() { new BoxLayout(this, BoxLayout.X_AXIS); JButton okButton = new JButton(existingBookmark ? tr("Change bookmark") : tr("Create bookmark")); okButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { String bookmarkName = bookmarkNamePanel.getBookmarkName(); if (bookmarkName != null) { PreferenceAccessParameters parameters = getAccessParameters(); if (parameters != null) { okAction.execute(bookmarkName, parameters); AccessParameterDialog.this.dispose(); } } } }); this.add(okButton); JButton cancelButton = new JButton(tr("Cancel")); cancelButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { AccessParameterDialog.this.dispose(); } }); this.add(cancelButton); } } private boolean existingBookmark = false; private final Collection<String> existingBookmarkNames; private final BookmarkAction okAction; private final BookmarkNamePanel bookmarkNamePanel; private final AccessClassPanel accessClassPanel; private final AccessTypesPanel accessTypesPanel; private final VehiclePropertiesPanel vehiclePropertiesPanel; private final RoadQualityPanel roadQualityPanel; public AccessParameterDialog(final Frame owner, boolean existingBookmark, String initialName, Collection<String> existingBookmarkNames, PreferenceAccessParameters initialAccessParameters, BookmarkAction okAction) { super(owner, tr("Edit access parameters"), true); this.existingBookmark = existingBookmark; this.existingBookmarkNames = existingBookmarkNames; this.okAction = okAction; GridBagLayout layout = new GridBagLayout(); this.setLayout(layout); GridBagConstraints gbc = new GridBagConstraints(); gbc.gridx = 0; gbc.weighty = 1; gbc.fill = GridBagConstraints.BOTH; bookmarkNamePanel = new BookmarkNamePanel(initialName); gbc.gridy = 0; layout.setConstraints(bookmarkNamePanel, gbc); this.add(bookmarkNamePanel); accessClassPanel = new AccessClassPanel(initialAccessParameters); gbc.gridy = 1; layout.setConstraints(accessClassPanel, gbc); this.add(accessClassPanel); accessTypesPanel = new AccessTypesPanel(initialAccessParameters); gbc.gridy = 2; layout.setConstraints(accessTypesPanel, gbc); this.add(accessTypesPanel); vehiclePropertiesPanel = new VehiclePropertiesPanel(initialAccessParameters); gbc.gridy = 3; layout.setConstraints(vehiclePropertiesPanel, gbc); this.add(vehiclePropertiesPanel); roadQualityPanel = new RoadQualityPanel(initialAccessParameters); gbc.gridy = 4; layout.setConstraints(roadQualityPanel, gbc); this.add(roadQualityPanel); JPanel okCancelPanel = new OkCancelPanel(); gbc.gridy = 5; gbc.weighty = 0; gbc.fill = GridBagConstraints.HORIZONTAL; layout.setConstraints(okCancelPanel, gbc); this.add(okCancelPanel); this.pack(); } private PreferenceAccessParameters getAccessParameters() { String accessClass = accessClassPanel.getAccessClass(); Collection<AccessType> usableAccessTypes = accessTypesPanel.getUsableAccessTypes(); Map<VehiclePropertyType<?>, String> vehiclePropertyStrings = vehiclePropertiesPanel.getVehiclePropertyStrings(); Map<VehiclePropertyType<?>, String> additionalVehiclePropertyStrings = roadQualityPanel.getVehiclePropertyStrings(); if (accessClass != null && usableAccessTypes != null && vehiclePropertyStrings != null && additionalVehiclePropertyStrings != null) { vehiclePropertyStrings.putAll(additionalVehiclePropertyStrings); try { return new PreferenceAccessParameters(accessClass, usableAccessTypes, vehiclePropertyStrings); } catch (PropertyValueSyntaxException e) { JOptionPane.showMessageDialog(this, e.getMessage()); return null; } } else { return null; } } }