// License: GPL. For details, see LICENSE file. package org.openstreetmap.josm.plugins.turnlanes.gui; import static org.openstreetmap.josm.tools.I18n.tr; import java.awt.BorderLayout; import java.awt.CardLayout; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; import javax.swing.ButtonGroup; import javax.swing.JPanel; import javax.swing.JToggleButton; import org.openstreetmap.josm.Main; import org.openstreetmap.josm.actions.JosmAction; import org.openstreetmap.josm.data.SelectionChangedListener; import org.openstreetmap.josm.data.osm.DataSet; import org.openstreetmap.josm.data.osm.Node; import org.openstreetmap.josm.data.osm.OsmPrimitive; import org.openstreetmap.josm.data.osm.Way; import org.openstreetmap.josm.data.osm.event.AbstractDatasetChangedEvent; import org.openstreetmap.josm.data.osm.event.DataChangedEvent; import org.openstreetmap.josm.data.osm.event.DataSetListener; import org.openstreetmap.josm.data.osm.event.NodeMovedEvent; import org.openstreetmap.josm.data.osm.event.PrimitivesAddedEvent; import org.openstreetmap.josm.data.osm.event.PrimitivesRemovedEvent; import org.openstreetmap.josm.data.osm.event.RelationMembersChangedEvent; import org.openstreetmap.josm.data.osm.event.TagsChangedEvent; import org.openstreetmap.josm.data.osm.event.WayNodesChangedEvent; import org.openstreetmap.josm.gui.dialogs.ToggleDialog; import org.openstreetmap.josm.gui.layer.MainLayerManager.ActiveLayerChangeEvent; import org.openstreetmap.josm.gui.layer.MainLayerManager.ActiveLayerChangeListener; import org.openstreetmap.josm.gui.layer.OsmDataLayer; import org.openstreetmap.josm.plugins.turnlanes.model.ModelContainer; public class TurnLanesDialog extends ToggleDialog implements ActiveLayerChangeListener, SelectionChangedListener { private class EditAction extends JosmAction { private static final long serialVersionUID = 4114119073563457706L; EditAction() { super(tr("Edit"), "dialogs/edit", tr("Edit turn relations and lane lengths for selected node."), null, false); } @Override public void actionPerformed(ActionEvent e) { final CardLayout cl = (CardLayout) body.getLayout(); cl.show(body, CARD_EDIT); editing = true; editButton.setSelected(true); refresh(); } } private class ValidateAction extends JosmAction { private static final long serialVersionUID = 7510740945725851427L; ValidateAction() { super(tr("Validate"), "dialogs/validator", tr("Validate turn- and lane-length-relations for consistency."), null, false); } @Override public void actionPerformed(ActionEvent e) { final CardLayout cl = (CardLayout) body.getLayout(); cl.show(body, CARD_VALIDATE); editing = false; validateButton.setSelected(true); } } private final DataSetListener dataSetListener = new DataSetListener() { @Override public void wayNodesChanged(WayNodesChangedEvent event) { refresh(); } @Override public void tagsChanged(TagsChangedEvent event) { refresh(); } @Override public void relationMembersChanged(RelationMembersChangedEvent event) { refresh(); } @Override public void primitivesRemoved(PrimitivesRemovedEvent event) { refresh(); } @Override public void primitivesAdded(PrimitivesAddedEvent event) { refresh(); } @Override public void otherDatasetChange(AbstractDatasetChangedEvent event) { refresh(); } @Override public void nodeMoved(NodeMovedEvent event) { refresh(); } @Override public void dataChanged(DataChangedEvent event) { refresh(); } private void refresh() { if (editing) { junctionPane.refresh(); } } }; private final JosmAction editAction = new EditAction(); private final JosmAction validateAction = new ValidateAction(); private static final long serialVersionUID = -1998375221636611358L; private static final String CARD_EDIT = "EDIT"; private static final String CARD_VALIDATE = "VALIDATE"; private final JPanel body = new JPanel(); private final JunctionPane junctionPane = new JunctionPane(GuiContainer.empty()); private final JToggleButton editButton = new JToggleButton(editAction); private final JToggleButton validateButton = new JToggleButton(validateAction); private final Set<OsmPrimitive> selected = new HashSet<>(); private boolean editing = true; private boolean wasShowing = false; public TurnLanesDialog() { super(tr("Turn Lanes"), "turnlanes.png", tr("Edit turn lanes"), null, 200); Main.getLayerManager().addActiveLayerChangeListener(this); DataSet.addSelectionListener(this); final JPanel buttonPanel = new JPanel(new GridLayout(1, 2, 4, 4)); final ButtonGroup group = new ButtonGroup(); group.add(editButton); group.add(validateButton); buttonPanel.add(editButton); buttonPanel.add(validateButton); body.setLayout(new CardLayout(4, 4)); add(buttonPanel, BorderLayout.SOUTH); add(body, BorderLayout.CENTER); body.add(junctionPane, CARD_EDIT); body.add(new ValidationPanel(), CARD_VALIDATE); editButton.doClick(); } @Override protected void stateChanged() { if (isShowing && !wasShowing) { refresh(); } wasShowing = isShowing; } void refresh() { if (isShowing && editing) { final Collection<OsmPrimitive> s = Collections.unmodifiableCollection(selected); final List<Node> nodes = OsmPrimitive.getFilteredList(s, Node.class); final List<Way> ways = OsmPrimitive.getFilteredList(s, Way.class); final ModelContainer mc = nodes.isEmpty() ? ModelContainer.empty() : ModelContainer .createEmpty(nodes, ways); junctionPane.setJunction(new GuiContainer(mc)); } } @Override public void activeOrEditLayerChanged(ActiveLayerChangeEvent e) { OsmDataLayer oldLayer = e.getPreviousEditLayer(); if (oldLayer != null) { oldLayer.data.removeDataSetListener(dataSetListener); } OsmDataLayer newLayer = Main.getLayerManager().getEditLayer(); if (newLayer != null) { newLayer.data.addDataSetListener(dataSetListener); } } @Override public void selectionChanged(Collection<? extends OsmPrimitive> newSelection) { if (selected.equals(new HashSet<>(newSelection))) { return; } selected.clear(); selected.addAll(newSelection); refresh(); } @Override public void destroy() { super.destroy(); Main.getLayerManager().removeActiveLayerChangeListener(this); DataSet.removeSelectionListener(this); editAction.destroy(); validateAction.destroy(); } }