- Timestamp:
- 2015-10-17T13:14:12+02:00 (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/actions/SplitWayAction.java
r8846 r8886 6 6 import static org.openstreetmap.josm.tools.I18n.trn; 7 7 8 import java.awt.Component; 9 import java.awt.GridLayout; 8 10 import java.awt.event.ActionEvent; 9 11 import java.awt.event.KeyEvent; … … 18 20 import java.util.Set; 19 21 22 import javax.swing.DefaultListCellRenderer; 23 import javax.swing.JLabel; 24 import javax.swing.JList; 20 25 import javax.swing.JOptionPane; 26 import javax.swing.JPanel; 27 import javax.swing.ListSelectionModel; 28 import javax.swing.event.ListSelectionEvent; 29 import javax.swing.event.ListSelectionListener; 21 30 22 31 import org.openstreetmap.josm.Main; … … 31 40 import org.openstreetmap.josm.data.osm.RelationMember; 32 41 import org.openstreetmap.josm.data.osm.Way; 42 import org.openstreetmap.josm.data.osm.WaySegment; 33 43 import org.openstreetmap.josm.gui.DefaultNameFormatter; 44 import org.openstreetmap.josm.gui.ExtendedDialog; 34 45 import org.openstreetmap.josm.gui.Notification; 35 46 import org.openstreetmap.josm.gui.layer.OsmDataLayer; 36 47 import org.openstreetmap.josm.tools.CheckParameterUtil; 37 48 import org.openstreetmap.josm.tools.Shortcut; 49 import org.openstreetmap.josm.tools.Utils; 38 50 39 51 /** … … 176 188 177 189 // Finally, applicableWays contains only one perfect way 178 Way selectedWay = applicableWays.get(0); 179 180 List<List<Node>> wayChunks = buildSplitChunks(selectedWay, selectedNodes); 190 final Way selectedWay = applicableWays.get(0); 191 final List<List<Node>> wayChunks = buildSplitChunks(selectedWay, selectedNodes); 181 192 if (wayChunks != null) { 182 List<OsmPrimitive> sel = new ArrayList<>(selectedWays.size() + selectedRelations.size());193 final List<OsmPrimitive> sel = new ArrayList<>(selectedWays.size() + selectedRelations.size()); 183 194 sel.addAll(selectedWays); 184 195 sel.addAll(selectedRelations); 185 SplitWayResult result = splitWay(getEditLayer(), selectedWay, wayChunks, sel); 186 Main.main.undoRedo.add(result.getCommand()); 187 getCurrentDataSet().setSelected(result.getNewSelection()); 188 } 189 } 190 191 /** 192 * Determine witch ways to split. 196 197 final List<Way> newWays = createNewWaysFromChunks(selectedWay, wayChunks); 198 final Way wayToKeep = determineWayToKeep(newWays); 199 200 if (ExpertToggleAction.isExpert() && !selectedWay.isNew()) { 201 final ExtendedDialog dialog = new SegmentToKeepSelectionDialog(selectedWay, newWays, wayToKeep, sel); 202 dialog.setModal(false); 203 dialog.showDialog(); 204 } else { 205 final SplitWayResult result = doSplitWay(getEditLayer(), selectedWay, wayToKeep, newWays, sel); 206 Main.main.undoRedo.add(result.getCommand()); 207 getCurrentDataSet().setSelected(result.getNewSelection()); 208 } 209 } 210 } 211 212 /** 213 * A dialog to query which way segment should reuse the history of the way to split. 214 */ 215 static class SegmentToKeepSelectionDialog extends ExtendedDialog { 216 final Way selectedWay; 217 final List<Way> newWays; 218 final JList<Way> list; 219 final List<OsmPrimitive> selection; 220 221 SegmentToKeepSelectionDialog(Way selectedWay, List<Way> newWays, Way wayToKeep, List<OsmPrimitive> selection) { 222 super(Main.parent, tr("Which way segment should reuse the history of {0}?", selectedWay.getId()), 223 new String[]{tr("Ok"), tr("Cancel")}, true); 224 225 this.selectedWay = selectedWay; 226 this.newWays = newWays; 227 this.selection = selection; 228 this.list = new JList<>(newWays.toArray(new Way[newWays.size()])); 229 buildList(); 230 this.list.setSelectedValue(wayToKeep, true); 231 232 setButtonIcons(new String[]{"ok", "cancel"}); 233 final JPanel pane = new JPanel(new GridLayout(2, 1)); 234 pane.add(new JLabel(getTitle())); 235 pane.add(list); 236 setContent(pane); 237 } 238 239 private void buildList() { 240 list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 241 list.addListSelectionListener(new ListSelectionListener() { 242 @Override 243 public void valueChanged(ListSelectionEvent e) { 244 final Way selected = list.getSelectedValue(); 245 if (Main.isDisplayingMapView() && selected != null) { 246 final List<WaySegment> segments = Utils.transform(selected.getNodes().subList(0, selected.getNodesCount() - 1), new Utils.Function<Node, WaySegment>() { 247 @Override 248 public WaySegment apply(Node x) { 249 return new WaySegment(selectedWay, selectedWay.getNodes().indexOf(x)); 250 } 251 }); 252 setHighlightedWaySegments(segments); 253 } 254 } 255 }); 256 list.setCellRenderer(new DefaultListCellRenderer() { 257 @Override 258 public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected, boolean cellHasFocus) { 259 final Component c = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); 260 ((JLabel) c).setText(tr("Segment {0}: {1}", index + 1, DefaultNameFormatter.getInstance().format((Way) value))); 261 return c; 262 } 263 }); 264 } 265 266 protected void setHighlightedWaySegments(Collection<WaySegment> segments) { 267 selectedWay.getDataSet().setHighlightedWaySegments(segments); 268 Main.map.mapView.repaint(); 269 } 270 271 @Override 272 public void setVisible(boolean visible) { 273 super.setVisible(visible); 274 if (visible) { 275 list.setSelectedIndex(list.getSelectedIndex()); // highlight way segments 276 } else { 277 setHighlightedWaySegments(Collections.<WaySegment>emptyList()); 278 } 279 } 280 281 @Override 282 protected void buttonAction(int buttonIndex, ActionEvent evt) { 283 super.buttonAction(buttonIndex, evt); 284 if (getValue() == 1) { 285 final Way wayToKeep = list.getSelectedValue(); 286 final SplitWayResult result = doSplitWay(getEditLayer(), selectedWay, wayToKeep, newWays, selection); 287 Main.main.undoRedo.add(result.getCommand()); 288 getCurrentDataSet().setSelected(result.getNewSelection()); 289 } 290 } 291 } 292 293 /** 294 * Determines which way chunk should reuse the old id and its history. Selects the one with the highest node count. 295 * @param wayChunks the way chunks 296 * @return the way to keep 297 */ 298 protected static Way determineWayToKeep(Iterable<Way> wayChunks) { 299 Way wayToKeep = null; 300 for (Way i : wayChunks) { 301 if (wayToKeep == null || i.getNodesCount() > wayToKeep.getNodesCount()) { 302 wayToKeep = i; 303 } 304 } 305 return wayToKeep; 306 } 307 308 /** 309 * Determine which ways to split. 193 310 * @param selectedWays List of user selected ways. 194 311 * @param selectedNodes List of user selected nodes. … … 329 446 330 447 /** 448 * Creates new way objects for the way chunks and transfers the keys from the original way. 449 * @param way the original way whose keys are transferred 450 * @param wayChunks the way chunks 451 * @return the new way objects 452 */ 453 protected static List<Way> createNewWaysFromChunks(Way way, Iterable<List<Node>> wayChunks) { 454 final List<Way> newWays = new ArrayList<>(); 455 for (List<Node> wayChunk : wayChunks) { 456 Way wayToAdd = new Way(); 457 wayToAdd.setKeys(way.getKeys()); 458 wayToAdd.setNodes(wayChunk); 459 newWays.add(wayToAdd); 460 } 461 return newWays; 462 } 463 464 /** 331 465 * Splits the way {@code way} into chunks of {@code wayChunks} and replies 332 466 * the result of this process in an instance of {@link SplitWayResult}. … … 345 479 Collection<? extends OsmPrimitive> selection) { 346 480 // build a list of commands, and also a new selection list 347 Collection<Command> commandList = new ArrayList<>(wayChunks.size()); 348 List<OsmPrimitive> newSelection = new ArrayList<>(selection.size() + wayChunks.size()); 481 final List<OsmPrimitive> newSelection = new ArrayList<>(selection.size() + wayChunks.size()); 349 482 newSelection.addAll(selection); 350 483 351 Iterator<List<Node>> chunkIt = wayChunks.iterator(); 484 // Create all potential new ways 485 final List<Way> newWays = createNewWaysFromChunks(way, wayChunks); 486 487 // Determine which part reuses the existing way 488 final Way wayToKeep = determineWayToKeep(newWays); 489 490 return doSplitWay(layer, way, wayToKeep, newWays, newSelection); 491 } 492 493 static SplitWayResult doSplitWay(OsmDataLayer layer, Way way, Way wayToKeep, List<Way> newWays, 494 List<OsmPrimitive> newSelection) { 495 496 Collection<Command> commandList = new ArrayList<>(newWays.size()); 352 497 Collection<String> nowarnroles = Main.pref.getCollection("way.split.roles.nowarn", 353 498 Arrays.asList("outer", "inner", "forward", "backward", "north", "south", "east", "west")); 354 499 355 // First, change the original way356 Way changedWay = new Way(way);357 changedWay.setNodes( chunkIt.next());500 // Change the original way 501 final Way changedWay = new Way(way); 502 changedWay.setNodes(wayToKeep.getNodes()); 358 503 commandList.add(new ChangeCommand(way, changedWay)); 359 504 if (!newSelection.contains(way)) { 360 505 newSelection.add(way); 361 506 } 362 363 List<Way> newWays = new ArrayList<>(); 364 // Second, create new ways 365 while (chunkIt.hasNext()) { 366 Way wayToAdd = new Way(); 367 wayToAdd.setKeys(way.getKeys()); 368 newWays.add(wayToAdd); 369 wayToAdd.setNodes(chunkIt.next()); 507 newWays.remove(wayToKeep); 508 509 for (Way wayToAdd : newWays) { 370 510 commandList.add(new AddCommand(layer, wayToAdd)); 371 511 newSelection.add(wayToAdd); 372 512 } 513 373 514 boolean warnmerole = false; 374 515 boolean warnme = false; … … 509 650 new SequenceCommand( 510 651 /* for correct i18n of plural forms - see #9110 */ 511 trn("Split way {0} into {1} part", "Split way {0} into {1} parts", wayChunks.size(),512 way.getDisplayName(DefaultNameFormatter.getInstance()), wayChunks.size()),652 trn("Split way {0} into {1} part", "Split way {0} into {1} parts", newWays.size(), 653 way.getDisplayName(DefaultNameFormatter.getInstance()), newWays.size()), 513 654 commandList 514 655 ),
Note:
See TracChangeset
for help on using the changeset viewer.