// License: GPL. For details, see LICENSE file. package org.openstreetmap.josm.plugins.utilsplugin2.replacegeometry; import static org.openstreetmap.josm.tools.I18n.tr; import static org.openstreetmap.josm.tools.I18n.trn; import java.awt.event.ActionEvent; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import javax.swing.JOptionPane; import org.openstreetmap.josm.Main; import org.openstreetmap.josm.actions.JosmAction; import org.openstreetmap.josm.command.ChangeCommand; import org.openstreetmap.josm.command.Command; import org.openstreetmap.josm.data.osm.OsmPrimitive; import org.openstreetmap.josm.data.osm.Relation; import org.openstreetmap.josm.data.osm.RelationMember; import org.openstreetmap.josm.data.osm.RelationToChildReference; import org.openstreetmap.josm.gui.DefaultNameFormatter; import org.openstreetmap.josm.gui.Notification; import org.openstreetmap.josm.tools.MultiMap; public class ReplaceMembershipAction extends JosmAction { public ReplaceMembershipAction() { super( tr("Replace Membership"), (String) null, tr("In relations where the selected object is member of, replace it with a new one"), null, false, ReplaceMembershipAction.class.getName(), true); } @Override public void actionPerformed(ActionEvent e) { final Iterator<OsmPrimitive> selection = getLayerManager().getEditDataSet().getSelected().iterator(); final OsmPrimitive firstObject = selection.next(); final OsmPrimitive secondObject = selection.next(); final ReplaceGeometryCommand command = getReplaceGeometryCommand(firstObject, secondObject); final int affectedRelations = command.getChildren().size(); if (affectedRelations > 0) { Main.main.undoRedo.add(command); new Notification(trn("Replaced ''{0}'' by ''{1}'' in {2} relation", "Replaced ''{0}'' by ''{1}'' in {2} relations", affectedRelations, firstObject.getDisplayName(DefaultNameFormatter.getInstance()), secondObject.getDisplayName(DefaultNameFormatter.getInstance()), affectedRelations )).setIcon(JOptionPane.INFORMATION_MESSAGE).show(); } else { new Notification(tr("The first selected object ''{0}'' is not part of any relation", firstObject.getDisplayName(DefaultNameFormatter.getInstance()) )).setIcon(JOptionPane.WARNING_MESSAGE).show(); } } static ReplaceGeometryCommand getReplaceGeometryCommand(OsmPrimitive firstObject, OsmPrimitive secondObject) { final MultiMap<Relation, RelationToChildReference> byRelation = new MultiMap<>(); for (final RelationToChildReference i : RelationToChildReference.getRelationToChildReferences(firstObject)) { byRelation.put(i.getParent(), i); } final List<Command> commands = new ArrayList<>(); for (final Map.Entry<Relation, Set<RelationToChildReference>> i : byRelation.entrySet()) { final Relation oldRelation = i.getKey(); final Relation newRelation = new Relation(oldRelation); for (final RelationToChildReference reference : i.getValue()) { newRelation.setMember(reference.getPosition(), new RelationMember(reference.getRole(), secondObject)); } commands.add(new ChangeCommand(oldRelation, newRelation)); } return new ReplaceGeometryCommand(tr("Replace Membership"), commands); } @Override protected void updateEnabledState() { updateEnabledStateOnCurrentSelection(); } @Override protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) { setEnabled(selection != null && selection.size() == 2); } }