// License: GPL. For details, see LICENSE file. package org.openstreetmap.josm.plugins.utilsplugin2.actions; import static org.openstreetmap.josm.tools.I18n.tr; import java.awt.datatransfer.UnsupportedFlavorException; import java.awt.event.ActionEvent; import java.awt.event.KeyEvent; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; 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.command.SequenceCommand; import org.openstreetmap.josm.data.osm.OsmPrimitive; import org.openstreetmap.josm.data.osm.PrimitiveData; import org.openstreetmap.josm.data.osm.Relation; import org.openstreetmap.josm.data.osm.RelationMember; import org.openstreetmap.josm.gui.datatransfer.ClipboardUtils; import org.openstreetmap.josm.gui.datatransfer.data.PrimitiveTransferData; import org.openstreetmap.josm.tools.Shortcut; /** * Pastes relation membership from objects in the paste buffer onto selected object(s). * * @author Zverik */ public class PasteRelationsAction extends JosmAction { private static final String TITLE = tr("Paste Relations"); public PasteRelationsAction() { super(TITLE, "dumbutils/pasterelations", tr("Paste relation membership from objects in the buffer onto selected object(s)"), Shortcut.registerShortcut("tools:pasterelations", tr("Tool: {0}", tr("Paste Relations")), KeyEvent.CHAR_UNDEFINED, Shortcut.NONE), true); } @Override public void actionPerformed(ActionEvent e) { Collection<OsmPrimitive> selection = getLayerManager().getEditDataSet().getSelected(); if (selection.isEmpty()) return; Map<Relation, String> relations = new HashMap<>(); Collection<PrimitiveData> data = Collections.emptySet(); try { data = ((PrimitiveTransferData) ClipboardUtils.getClipboard().getData(PrimitiveTransferData.DATA_FLAVOR)).getDirectlyAdded(); } catch (UnsupportedFlavorException | IOException ex) { Main.warn(ex); } for (PrimitiveData pdata : data) { OsmPrimitive p = getLayerManager().getEditDataSet().getPrimitiveById(pdata.getUniqueId(), pdata.getType()); if (p != null) { for (Relation r : OsmPrimitive.getFilteredList(p.getReferrers(), Relation.class)) { String role = relations.get(r); for (RelationMember m : r.getMembers()) { if (m.getMember().equals(p)) { String newRole = m.getRole(); if (newRole != null && role == null) role = newRole; else if (newRole != null ? !newRole.equals(role) : role != null) { role = ""; break; } } } relations.put(r, role); } } } List<Command> commands = new ArrayList<>(); for (Relation rel : relations.keySet()) { Relation r = new Relation(rel); boolean changed = false; for (OsmPrimitive p : selection) { if (!r.getMemberPrimitives().contains(p) && !r.equals(p)) { String role = relations.get(rel); if ("associatedStreet".equals(r.get("type"))) { if (p.get("highway") != null) { role = "street"; } else if (p.get("addr:housenumber") != null) { role = "house"; } } r.addMember(new RelationMember(role, p)); changed = true; } } if (changed) commands.add(new ChangeCommand(rel, r)); } if (!commands.isEmpty()) Main.main.undoRedo.add(new SequenceCommand(TITLE, commands)); } @Override protected void updateEnabledState() { updateEnabledStateOnCurrentSelection(); } @Override protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) { try { setEnabled(selection != null && !selection.isEmpty() && ClipboardUtils.getClipboard().isDataFlavorAvailable(PrimitiveTransferData.DATA_FLAVOR)); } catch (IllegalStateException e) { Main.warn(e); } catch (NullPointerException e) { // JDK-6322854: On Linux/X11, NPE can happen for unknown reasons, on all versions of Java Main.error(e); } } }