Ticket #5457: SelectAction.java.monster.patch
| File SelectAction.java.monster.patch, 12.8 KB (added by , 16 years ago) |
|---|
-
src/org/openstreetmap/josm/actions/mapmode/SelectAction.java
15 15 import java.util.Collection; 16 16 import java.util.Collections; 17 17 import java.util.HashSet; 18 import java.util.Iterator; 18 19 import java.util.LinkedList; 19 import java.util.List;20 20 import java.util.Set; 21 21 import java.util.TreeSet; 22 22 … … 202 202 "Add and move a virtual new node to {0} ways", virtualWays.size(), 203 203 virtualWays.size()); 204 204 Main.main.undoRedo.add(new SequenceCommand(text, virtualCmds)); 205 selectPrims(Collections.singleton((OsmPrimitive)virtualNode), false, false, false, false);205 getCurrentDataSet().setSelected(Collections.singleton((OsmPrimitive)virtualNode)); 206 206 virtualWays.clear(); 207 207 virtualNode = null; 208 208 } else { … … 268 268 } 269 269 } 270 270 271 private Collection<OsmPrimitive> getNearestCollectionVirtual(Point p, boolean allSegements) { 272 MapView c = Main.map.mapView; 271 private Collection<OsmPrimitive> getNearestCollectionVirtual(Point p) { 273 272 int snapDistance = Main.pref.getInteger("mappaint.node.virtual-snap-distance", 8); 273 int virtualSpace = Main.pref.getInteger("mappaint.node.virtual-space", 70); 274 274 snapDistance *= snapDistance; 275 276 MapView c = Main.map.mapView; 277 278 Collection<OsmPrimitive> sel = getCurrentDataSet().getSelected(); 275 279 OsmPrimitive osm = c.getNearestNode(p, OsmPrimitive.isSelectablePredicate); 276 virtualWays.clear();277 virtualNode = null;278 Node virtualWayNode = null;279 280 280 if (osm == null) 281 { 282 Collection<WaySegment> nearestWaySegs = allSegements 283 ? c.getNearestWaySegments(p, OsmPrimitive.isSelectablePredicate) 284 : Collections.singleton(c.getNearestWaySegment(p, OsmPrimitive.isSelectablePredicate)); 281 if (osm != null) { 282 for (Node n : c.getNearestNodes(p, OsmPrimitive.isSelectablePredicate)) { 283 if (sel.contains(n)) { 284 osm = n; 285 } 286 } 287 } else { 288 Node virtualWayNode = null; 289 Way w = null; 285 290 286 for(WaySegment nearestWS : nearestWaySegs) { 291 Collection<WaySegment> virtualWaysInSel = new ArrayList<WaySegment>(); 292 osm = c.getNearestWay(p, OsmPrimitive.isSelectablePredicate); 293 294 for(WaySegment nearestWS : c.getNearestWaySegments(p, OsmPrimitive.isSelectablePredicate)) { 287 295 if (nearestWS == null) { 288 296 continue; 289 297 } 298 if (sel.contains(w = nearestWS.way)) { 299 osm = w; 300 } 290 301 291 osm = nearestWS.way; 292 if(Main.pref.getInteger("mappaint.node.virtual-size", 8) > 0) 293 { 294 Way w = (Way)osm; 302 if (Main.pref.getInteger("mappaint.node.virtual-size", 8) > 0) { 295 303 Point p1 = c.getPoint(w.getNode(nearestWS.lowerIndex)); 296 304 Point p2 = c.getPoint(w.getNode(nearestWS.lowerIndex+1)); 297 if(SimplePaintVisitor.isLargeSegment(p1, p2, Main.pref.getInteger("mappaint.node.virtual-space", 70)))305 if(SimplePaintVisitor.isLargeSegment(p1, p2, virtualSpace)) 298 306 { 299 307 Point pc = new Point((p1.x+p2.x)/2, (p1.y+p2.y)/2); 300 308 if (p.distanceSq(pc) < snapDistance) … … 303 311 // virtual ways list. Otherwise ways that coincidentally have their 304 312 // virtual node at the same spot will be joined which is likely unwanted 305 313 if(virtualWayNode != null) { 306 if( !w.getNode(nearestWS.lowerIndex+1).equals(virtualWayNode)314 if(!w.getNode(nearestWS.lowerIndex+1).equals(virtualWayNode) 307 315 && !w.getNode(nearestWS.lowerIndex).equals(virtualWayNode)) { 308 316 continue; 309 317 } … … 311 319 virtualWayNode = w.getNode(nearestWS.lowerIndex+1); 312 320 } 313 321 314 virtualWays.add(nearestWS);322 (!sel.contains(w) ? virtualWays : virtualWaysInSel).add(nearestWS); 315 323 if(virtualNode == null) { 316 324 virtualNode = new Node(Main.map.mapView.getLatLon(pc.x, pc.y)); 317 325 } … … 319 327 } 320 328 } 321 329 } 330 331 if (virtualNode != null) { 332 virtualWays = virtualWaysInSel.isEmpty() ? virtualWays : virtualWaysInSel; 333 osm = virtualWays.iterator().next().way; 334 } 322 335 } 336 323 337 if (osm == null) 324 338 return Collections.emptySet(); 325 339 return Collections.singleton(osm); … … 337 351 @Override public void mousePressed(MouseEvent e) { 338 352 if(!Main.map.mapView.isActiveLayerVisible()) 339 353 return; 354 340 355 // request focus in order to enable the expected keyboard shortcuts 341 //342 356 Main.map.mapView.requestFocus(); 343 357 344 358 cancelDrawMode = false; … … 346 360 if (e.getButton() != MouseEvent.BUTTON1) 347 361 return; 348 362 boolean ctrl = (e.getModifiers() & ActionEvent.CTRL_MASK) != 0; 349 boolean alt = (e.getModifiers() & (ActionEvent.ALT_MASK|InputEvent.ALT_GRAPH_MASK)) != 0;350 363 boolean shift = (e.getModifiers() & ActionEvent.SHIFT_MASK) != 0; 351 364 352 365 // We don't want to change to draw tool if the user tries to (de)select … … 359 372 didMove = false; 360 373 initialMoveThresholdExceeded = false; 361 374 362 Collection<OsmPrimitive> osmColl = getNearestCollectionVirtual(e.getPoint() , alt);375 Collection<OsmPrimitive> osmColl = getNearestCollectionVirtual(e.getPoint()); 363 376 364 377 if (ctrl && shift) { 365 378 if (getCurrentDataSet().getSelected().isEmpty()) { … … 382 395 selectionManager.register(Main.map.mapView); 383 396 selectionManager.mousePressed(e); 384 397 } 385 if(mode != Mode.move || shift || ctrl) 386 {398 399 if(mode != Mode.move || shift || ctrl) { 387 400 virtualNode = null; 388 401 virtualWays.clear(); 389 402 } … … 420 433 if (mode == Mode.move) { 421 434 boolean ctrl = (e.getModifiers() & ActionEvent.CTRL_MASK) != 0; 422 435 boolean shift = (e.getModifiers() & ActionEvent.SHIFT_MASK) != 0; 436 boolean alt = (e.getModifiers() & (ActionEvent.ALT_MASK|InputEvent.ALT_GRAPH_MASK)) != 0 437 || Main.pref.getBoolean("selectaction.rotates", false); 438 439 virtualWays.clear(); 440 virtualNode = null; 441 423 442 if (!didMove) { 424 selectPrims( 425 Main.map.mapView.getNearestCollection(e.getPoint(), OsmPrimitive.isSelectablePredicate), 426 shift, ctrl, true, false); 443 Collection<OsmPrimitive> c = Main.map.mapView.getNearestCollection(e.getPoint(), OsmPrimitive.isSelectablePredicate); 444 if (!c.isEmpty() && alt) { 445 if (c.iterator().next() instanceof Node) { 446 // there is at least one node under the cursor: 447 // - make sure (first element of new list) equals (result of getNearestCollection) 448 // - do not consider ways at all, but all nearest nodes 449 c = new ArrayList<OsmPrimitive>(Main.map.mapView.getNearestNodes(e.getPoint(), OsmPrimitive.isSelectablePredicate)); 450 } else { 451 // consider all ways.. 452 c = Main.map.mapView.getAllNearest(e.getPoint(), OsmPrimitive.isSelectablePredicate); 453 } 454 } 455 selectPrims(c, shift, ctrl, true, false); 427 456 428 457 // If the user double-clicked a node, change to draw mode 429 List<OsmPrimitive> sel = new ArrayList<OsmPrimitive>(getCurrentDataSet().getSelected());430 if(e.getClickCount() >=2 && sel.size() == 1 && sel.get(0) instanceof Node) {458 c = getCurrentDataSet().getSelected(); 459 if(e.getClickCount() >=2 && c.size() == 1 && c.iterator().next() instanceof Node) { 431 460 // We need to do it like this as otherwise drawAction will see a double 432 461 // click and switch back to SelectMode 433 462 Main.worker.execute(new Runnable(){ … … 500 529 selectPrims(selectionManager.getObjectsInRectangle(r, alt), shift, ctrl, true, true); 501 530 } 502 531 532 private boolean selMorePrims = false; 533 private OsmPrimitive selCycleStart = null; 534 503 535 public void selectPrims(Collection<OsmPrimitive> selectionList, boolean shift, 504 536 boolean ctrl, boolean released, boolean area) { 505 537 DataSet ds = getCurrentDataSet(); 506 if ((shift && ctrl) || (ctrl && !released) )538 if ((shift && ctrl) || (ctrl && !released) || (!virtualWays.isEmpty())) 507 539 return; // not allowed together 508 540 541 for (OsmPrimitive p : selectionList) { 542 System.out.println("SelectAction:selectPrims(): " + p.getId()); 543 } 544 545 // toggle through possible objects on mouse release 546 if (released && !area) { 547 if (selectionList.size() > 1) { 548 Collection<OsmPrimitive> coll = ds.getSelected(); 549 550 OsmPrimitive first, foundInDS, node, nxt; 551 first = nxt = selectionList.iterator().next(); 552 foundInDS = node = null; 553 554 for (Iterator<OsmPrimitive> i = selectionList.iterator(); i.hasNext(); ) { 555 if (selMorePrims && shift) { 556 if (!coll.contains(nxt = i.next())) { 557 System.out.println("SelectAction:selectPrims(): taking " + nxt.getId()); 558 break; // take first primitive not in dsSel or last if all contained 559 } 560 } else { 561 if (coll.contains(nxt = i.next())) { 562 foundInDS = nxt; 563 if (selMorePrims || ctrl) { 564 ds.clearSelection(nxt); 565 nxt = i.hasNext() ? i.next() : first; 566 } 567 System.out.println("SelectAction:selectPrims(): taking " + nxt.getId()); 568 break; // take next primitive of selList 569 } else if (nxt instanceof Node && node == null) { 570 node = nxt; 571 } 572 } 573 } 574 575 if (ctrl) { 576 if (foundInDS != null) { 577 // a member of selList was foundInDS 578 if (!selectionList.contains(selCycleStart)) { 579 selCycleStart = foundInDS; 580 System.out.println("SelectAction:selectPrims(): cycleStart " + selCycleStart.getId()); 581 } 582 // check if selCycleStart == prim (equals next(foundInDS)) 583 if (selCycleStart.equals(nxt)) { 584 ds.addSelected(nxt); // cycle complete, prim toggled below 585 selCycleStart = null; // check: might do w/out ?? 586 } 587 } else { 588 // no member of selList was foundInDS (sets were disjunct), setup for new cycle 589 selCycleStart = nxt = (node != null) ? node : first; 590 System.out.println("SelectAction:selectPrims(): cycleStart " + selCycleStart.getId()); 591 } 592 } 593 594 selectionList = new ArrayList<OsmPrimitive>(1); // do not modify the passed object.. 595 selectionList.add(nxt); 596 System.out.println("SelectAction:selectPrims(): truncated selList to id=" + nxt.getId()); 597 } 598 } 599 600 // hard-wiring to false due to performance reasons, should do w/out 601 selMorePrims = (released || area) ? false : ds.getSelected().containsAll(selectionList); 602 509 603 if (ctrl) { 510 604 // Ctrl on an item toggles its selection status, 511 605 // but Ctrl on an *area* just clears those items
