Ticket #1469: Virtual For All.patch

File Virtual For All.patch, 7.8 KB (added by xeen, 17 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    }