Ticket #1633: Add Unglue Node.patch
File Add Unglue Node.patch, 6.7 KB (added by , 16 years ago) |
---|
-
src/org/openstreetmap/josm/actions/UnGlueAction.java
7 7 import java.awt.event.KeyEvent; 8 8 import java.util.ArrayList; 9 9 import java.util.Collection; 10 import java.util.Collections; 10 11 import java.util.HashSet; 11 12 import java.util.LinkedList; 12 13 import java.util.List; 13 14 14 15 import javax.swing.JOptionPane; 16 import javax.swing.JPanel; 15 17 16 18 import org.openstreetmap.josm.Main; 17 19 import org.openstreetmap.josm.command.AddCommand; 18 20 import org.openstreetmap.josm.command.ChangeCommand; 19 21 import org.openstreetmap.josm.command.Command; 20 22 import org.openstreetmap.josm.command.SequenceCommand; 23 import org.openstreetmap.josm.data.coor.EastNorth; 21 24 import org.openstreetmap.josm.data.osm.Node; 22 25 import org.openstreetmap.josm.data.osm.OsmPrimitive; 23 26 import org.openstreetmap.josm.data.osm.Relation; 24 27 import org.openstreetmap.josm.data.osm.RelationMember; 25 28 import org.openstreetmap.josm.data.osm.Way; 29 import org.openstreetmap.josm.gui.MapView; 26 30 import org.openstreetmap.josm.tools.Shortcut; 27 31 28 32 /** … … 31 35 * Resulting nodes are identical, up to their position. 32 36 * 33 37 * This is the opposite of the MergeNodesAction. 38 * 39 * If a single node is selected, it will copy that node and remove all tags from the old one 34 40 */ 35 41 36 42 public class UnGlueAction extends JosmAction { //implements SelectionChangedListener { … … 56 62 public void actionPerformed(ActionEvent e) { 57 63 58 64 Collection<OsmPrimitive> selection = Main.ds.getSelected(); 59 65 66 String errMsg = null; 60 67 if (checkSelection(selection)) { 61 68 int count = 0; 62 69 for (Way w : Main.ds.ways) { … … 65 72 count++; 66 73 } 67 74 if (count < 2) { 68 JOptionPane.showMessageDialog(Main.parent, tr("This node is not glued to anything else.")); 75 // If there aren't enough ways, maybe the user wanted to unglue the nodes 76 // (= copy tags to a new node) 77 if(checkForUnglueNode(selection)) 78 unglueNode(e); 79 else 80 errMsg = tr("This node is not glued to anything else."); 69 81 } else { 70 82 // and then do the work. 71 83 unglueWays(); … … 85 97 } 86 98 if (tmpNodes.size() < 1) { 87 99 if (selection.size() > 1) { 88 JOptionPane.showMessageDialog(Main.parent, tr("None of these nodes are glued to anything else."));100 errMsg = tr("None of these nodes are glued to anything else."); 89 101 } else { 90 JOptionPane.showMessageDialog(Main.parent, tr("None of this way's nodes are glued to anything else."));102 errMsg = tr("None of this way's nodes are glued to anything else."); 91 103 } 92 104 } else { 93 105 // and then do the work. … … 95 107 unglueWays2(); 96 108 } 97 109 } else { 98 JOptionPane.showMessageDialog(Main.parent,110 errMsg = 99 111 tr("The current selection cannot be used for unglueing.")+"\n"+ 100 112 "\n"+ 101 113 tr("Select either:")+"\n"+ 114 tr("* One tagged node, or")+"\n"+ 102 115 tr("* One node that is used by more than one way, or")+"\n"+ 103 116 tr("* One node that is used by more than one way and one of those ways, or")+"\n"+ 104 117 tr("* One way that has one or more nodes that are used by more than one way, or")+"\n"+ … … 106 119 "\n"+ 107 120 tr("Note: If a way is selected, this way will get fresh copies of the unglued\n"+ 108 121 "nodes and the new nodes will be selected. Otherwise, all ways will get their\n"+ 109 "own copy and all nodes will be selected.") 110 ); 122 "own copy and all nodes will be selected."); 111 123 } 124 125 if(errMsg != null) 126 JOptionPane.showMessageDialog(Main.parent, errMsg); 127 112 128 selectedNode = null; 113 129 selectedWay = null; 114 130 selectedNodes = null; 115 131 } 132 133 /** 134 * Assumes there is one tagged Node stored in selectedNode that it will try to unglue 135 * (= copy node and remove all tags from the old one. Relations will not be removed) 136 */ 137 private void unglueNode(ActionEvent e) { 138 LinkedList<Command> cmds = new LinkedList<Command>(); 116 139 140 Node c = new Node(selectedNode); 141 c.keys = null; 142 c.tagged = false; 143 c.selected = false; 144 cmds.add(new ChangeCommand(selectedNode, c)); 145 146 Node n = new Node(selectedNode); 147 n.id = 0; 148 149 // If this wasn't called from menu, place it where the cursor is/was 150 if(e.getSource() instanceof JPanel) { 151 MapView mv = Main.map.mapView; 152 n.eastNorth = mv.getEastNorth(mv.lastMEvent.getX(), mv.lastMEvent.getY()); 153 n.coor = Main.proj.eastNorth2latlon(n.eastNorth); 154 } 155 156 cmds.add(new AddCommand(n)); 157 158 fixRelations(selectedNode, cmds, Collections.singletonList(n)); 159 160 Main.main.undoRedo.add(new SequenceCommand(tr("Unglued Node"), cmds)); 161 Main.ds.setSelected(n); 162 Main.map.mapView.repaint(); 163 } 164 117 165 /** 166 * Checks if selection is suitable for ungluing. This is the case when there's a single, 167 * tagged node selected that's part of at least one way (ungluing an unconnected node does 168 * not make sense. Due to the call order in actionPerformed, this is only called when the 169 * node is only part of one or less ways. 170 * 171 * @param The selection to check against 172 * @return Selection is suitable 173 */ 174 private boolean checkForUnglueNode(Collection<? extends OsmPrimitive> selection) { 175 if(selection.size() != 1) 176 return false; 177 OsmPrimitive n = (OsmPrimitive) selection.toArray()[0]; 178 if(!(n instanceof Node)) 179 return false; 180 boolean isPartOfWay = false; 181 for(Way w : Main.ds.ways) { 182 if(w.nodes.contains(n)) { 183 isPartOfWay = true; 184 break; 185 } 186 } 187 if(!isPartOfWay) 188 return false; 189 190 selectedNode = (Node)n; 191 return selectedNode.tagged; 192 } 193 194 /** 118 195 * Checks if the selection consists of something we can work with. 119 196 * Checks only if the number and type of items selected looks good; 120 197 * does not check whether the selected items are really a valid