Ticket #1469: Virtual For All.patch

File Virtual For All.patch, 7.8 KB (added by xeen, 4 years ago)
  • src/org/openstreetmap/josm/actions/mapmode/SelectAction.java

     
    6060    private boolean didMove = false; 
    6161    private boolean cancelDrawMode = false; 
    6262    Node virtualNode = null; 
    63     WaySegment virtualWay = null; 
     63    Collection<WaySegment> virtualWays = new ArrayList<WaySegment>(); 
    6464    SequenceCommand virtualCmds = null; 
    6565 
    6666    /** 
     
    146146    @Override public void mouseDragged(MouseEvent e) { 
    147147        if(!Main.map.mapView.isVisibleDrawableLayer()) 
    148148            return; 
    149          
     149 
    150150        cancelDrawMode = true; 
    151151        if (mode == Mode.select) return; 
    152152 
     
    180180        if (dx == 0 && dy == 0) 
    181181            return; 
    182182 
    183         if (virtualWay != null)    { 
     183        if (virtualWays.size() > 0) { 
    184184            Collection<Command> virtualCmds = new LinkedList<Command>(); 
    185185            virtualCmds.add(new AddCommand(virtualNode)); 
    186             Way w = virtualWay.way; 
    187             Way wnew = new Way(w); 
    188             wnew.addNode(virtualWay.lowerIndex+1, virtualNode); 
    189             virtualCmds.add(new ChangeCommand(w, wnew)); 
     186            for(WaySegment virtualWay : virtualWays) { 
     187                Way w = virtualWay.way; 
     188                Way wnew = new Way(w); 
     189                wnew.addNode(virtualWay.lowerIndex+1, virtualNode); 
     190                virtualCmds.add(new ChangeCommand(w, wnew)); 
     191            } 
    190192            virtualCmds.add(new MoveCommand(virtualNode, dx, dy)); 
    191             Main.main.undoRedo.add(new SequenceCommand(tr("Add and move a virtual new node to way"), virtualCmds)); 
     193            String text = virtualWays.size() == 1 
     194                ? tr("Add and move a virtual new node to way") 
     195                : tr("Add and move a virtual new node to {0} ways", virtualWays.size()); 
     196 
     197            Main.main.undoRedo.add(new SequenceCommand(text, virtualCmds)); 
    192198            selectPrims(Collections.singleton((OsmPrimitive)virtualNode), false, false); 
    193             virtualWay = null; 
     199            virtualWays.clear(); 
    194200            virtualNode = null; 
    195201        } else { 
    196202            // Currently we support moving and rotating, which do not affect relations. 
     
    221227 
    222228                        JOptionPane.showMessageDialog(Main.parent, 
    223229                            tr("Cannot move objects outside of the world.")); 
     230                        restoreCursor(); 
    224231                        return; 
    225232                    } 
    226233                } 
     
    238245        didMove = true; 
    239246    } 
    240247 
    241     private Collection<OsmPrimitive> getNearestCollectionVirtual(Point p) { 
     248    private Collection<OsmPrimitive> getNearestCollectionVirtual(Point p, boolean allSegements) { 
    242249        MapView c = Main.map.mapView; 
    243250        int snapDistance = Main.pref.getInteger("mappaint.node.virtual-snap-distance", 8); 
    244251        snapDistance *= snapDistance; 
    245252        OsmPrimitive osm = c.getNearestNode(p); 
    246         virtualWay = null; 
     253        virtualWays.clear(); 
    247254        virtualNode = null; 
     255        Node virtualWayNode = null; 
    248256 
    249257        if (osm == null) 
    250258        { 
    251             WaySegment nearestWaySeg = c.getNearestWaySegment(p); 
    252             if (nearestWaySeg != null) 
    253             { 
    254                 osm = nearestWaySeg.way; 
     259            Collection<WaySegment> nearestWaySegs = allSegements 
     260                 ? c.getNearestWaySegments(p) 
     261                 : Collections.singleton(c.getNearestWaySegment(p)); 
     262 
     263            for(WaySegment nearestWS : nearestWaySegs) { 
     264                if (nearestWS == null) 
     265                    continue; 
     266 
     267                osm = nearestWS.way; 
    255268                if(Main.pref.getInteger("mappaint.node.virtual-size", 8) > 0) 
    256269                { 
    257270                    Way w = (Way)osm; 
    258                     Point p1 = c.getPoint(w.nodes.get(nearestWaySeg.lowerIndex).eastNorth); 
    259                     Point p2 = c.getPoint(w.nodes.get(nearestWaySeg.lowerIndex+1).eastNorth); 
     271                    Point p1 = c.getPoint(w.nodes.get(nearestWS.lowerIndex).eastNorth); 
     272                    Point p2 = c.getPoint(w.nodes.get(nearestWS.lowerIndex+1).eastNorth); 
    260273                    if(SimplePaintVisitor.isLargeSegment(p1, p2, Main.pref.getInteger("mappaint.node.virtual-space", 70))) 
    261274                    { 
    262275                        Point pc = new Point((p1.x+p2.x)/2, (p1.y+p2.y)/2); 
    263276                        if (p.distanceSq(pc) < snapDistance) 
    264277                        { 
    265                             virtualWay = nearestWaySeg; 
    266                             virtualNode = new Node(Main.map.mapView.getLatLon(pc.x, pc.y)); 
    267                             osm = w; 
     278                            // Check that only segments on top of each other get added to the 
     279                            // virtual ways list. Otherwise ways that coincidentally have their 
     280                            // virtual node at the same spot will be joined which is likely unwanted 
     281                            if(virtualWayNode != null) { 
     282                                if(  !w.nodes.get(nearestWS.lowerIndex+1).equals(virtualWayNode) 
     283                                  && !w.nodes.get(nearestWS.lowerIndex  ).equals(virtualWayNode)) 
     284                                    continue; 
     285                            } else 
     286                                virtualWayNode = w.nodes.get(nearestWS.lowerIndex+1); 
     287 
     288                            virtualWays.add(nearestWS); 
     289                            if(virtualNode == null) 
     290                                virtualNode = new Node(Main.map.mapView.getLatLon(pc.x, pc.y)); 
    268291                        } 
    269292                    } 
    270293                } 
     
    287310    @Override public void mousePressed(MouseEvent e) { 
    288311        if(!Main.map.mapView.isVisibleDrawableLayer()) 
    289312            return; 
    290          
     313 
    291314        cancelDrawMode = false; 
    292315        if (! (Boolean)this.getValue("active")) return; 
    293316        if (e.getButton() != MouseEvent.BUTTON1) 
    294317            return; 
    295318        boolean ctrl = (e.getModifiers() & ActionEvent.CTRL_MASK) != 0; 
    296         // boolean alt = (e.getModifiers() & ActionEvent.ALT_MASK) != 0; 
     319        boolean alt = (e.getModifiers() & ActionEvent.ALT_MASK) != 0; 
    297320        boolean shift = (e.getModifiers() & ActionEvent.SHIFT_MASK) != 0; 
    298          
     321 
    299322        // We don't want to change to draw tool if the user tries to (de)select 
    300323        // stuff but accidentally clicks in an empty area when selection is empty 
    301324        if(shift || ctrl) 
     
    305328        didMove = false; 
    306329        initialMoveThresholdExceeded = false; 
    307330 
    308         Collection<OsmPrimitive> osmColl = getNearestCollectionVirtual(e.getPoint()); 
     331        Collection<OsmPrimitive> osmColl = getNearestCollectionVirtual(e.getPoint(), alt); 
    309332 
    310333        if (ctrl && shift) { 
    311334            if (Main.ds.getSelected().isEmpty()) selectPrims(osmColl, true, false); 
     
    329352        if(mode != Mode.move || shift || ctrl) 
    330353        { 
    331354            virtualNode = null; 
    332             virtualWay = null; 
     355            virtualWays.clear(); 
    333356        } 
    334357 
    335358        updateStatusLine(); 
    336         Main.map.mapView.repaint(); 
     359        // Mode.select redraws when selectPrims is called 
     360        // Mode.move   redraws when mouseDragged is called 
     361        // Mode.rotate redraws here 
     362        if(mode == Mode.rotate) 
     363            Main.map.mapView.repaint(); 
    337364 
    338365        mousePos = e.getPoint(); 
    339366    } 
     
    344371    @Override public void mouseReleased(MouseEvent e) { 
    345372        if(!Main.map.mapView.isVisibleDrawableLayer()) 
    346373            return; 
    347          
     374 
    348375        if (mode == Mode.select) { 
    349376            selectionManager.unregister(Main.map.mapView); 
    350377 
     
    397424            } 
    398425        } 
    399426 
    400         updateStatusLine(); 
     427        // I don't see why we need this. 
     428        //updateStatusLine(); 
    401429        mode = null; 
    402430        updateStatusLine(); 
    403431    }