Changeset 17999 in josm for trunk/src/org/openstreetmap


Ignore:
Timestamp:
2021-07-11T04:39:26+02:00 (3 years ago)
Author:
Don-vip
Message:

fix #20935 - fix IAE: "Node pair not part of way" when splitting way (patch by Bjoeni)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/actions/SplitWayAction.java

    r17362 r17999  
    3636import org.openstreetmap.josm.data.osm.Way;
    3737import org.openstreetmap.josm.data.osm.WaySegment;
     38import org.openstreetmap.josm.data.osm.event.AbstractDatasetChangedEvent;
     39import org.openstreetmap.josm.data.osm.event.DataChangedEvent;
     40import org.openstreetmap.josm.data.osm.event.DataSetListener;
     41import org.openstreetmap.josm.data.osm.event.NodeMovedEvent;
     42import org.openstreetmap.josm.data.osm.event.PrimitivesAddedEvent;
     43import org.openstreetmap.josm.data.osm.event.PrimitivesRemovedEvent;
     44import org.openstreetmap.josm.data.osm.event.RelationMembersChangedEvent;
     45import org.openstreetmap.josm.data.osm.event.TagsChangedEvent;
     46import org.openstreetmap.josm.data.osm.event.WayNodesChangedEvent;
    3847import org.openstreetmap.josm.gui.ExtendedDialog;
    3948import org.openstreetmap.josm.gui.MainApplication;
     
    146155
    147156            if (ExpertToggleAction.isExpert() && !selectedWay.isNew()) {
    148                 final ExtendedDialog dialog = new SegmentToKeepSelectionDialog(selectedWay, newWays, wayToKeep, sel);
     157                final ExtendedDialog dialog = new SegmentToKeepSelectionDialog(selectedWay, newWays, wayToKeep, selectedNodes, sel);
    149158                dialog.toggleEnable("way.split.segment-selection-dialog");
    150159                if (!dialog.toggleCheckState()) {
     
    165174    static class SegmentToKeepSelectionDialog extends ExtendedDialog {
    166175        static final AtomicInteger DISPLAY_COUNT = new AtomicInteger();
    167         final transient Way selectedWay;
    168         final transient List<Way> newWays;
    169176        final JList<Way> list;
     177        transient Way selectedWay;
     178        transient List<Way> newWays;
     179        transient Way wayToKeep;
    170180        final transient List<OsmPrimitive> selection;
    171         final transient Way wayToKeep;
    172 
    173         SegmentToKeepSelectionDialog(Way selectedWay, List<Way> newWays, Way wayToKeep, List<OsmPrimitive> selection) {
     181        final transient List<Node> selectedNodes;
     182        private final SplitWayDataSetListener dataSetListener;
     183
     184        SegmentToKeepSelectionDialog(Way selectedWay, List<Way> newWays, Way wayToKeep, List<Node> selectedNodes, List<OsmPrimitive> selection) {
    174185            super(MainApplication.getMainFrame(), tr("Which way segment should reuse the history of {0}?", selectedWay.getId()),
    175186                    new String[]{tr("Ok"), tr("Cancel")}, true);
     
    177188            this.selectedWay = selectedWay;
    178189            this.newWays = newWays;
     190            this.selectedNodes = selectedNodes;
    179191            this.selection = selection;
    180192            this.wayToKeep = wayToKeep;
    181193            this.list = new JList<>(newWays.toArray(new Way[0]));
     194            this.dataSetListener = new SplitWayDataSetListener();
     195            selectedWay.getDataSet().addDataSetListener(dataSetListener);
     196
    182197            configureList();
    183198
     
    210225
    211226        protected void setHighlightedWaySegments(Collection<WaySegment> segments) {
    212             selectedWay.getDataSet().setHighlightedWaySegments(segments);
    213             MainApplication.getMap().mapView.repaint();
     227            DataSet ds = selectedWay.getDataSet();
     228            if (ds != null) {
     229                ds.setHighlightedWaySegments(segments);
     230                MainApplication.getMap().mapView.repaint();
     231            }
    214232        }
    215233
     
    221239                list.setSelectedValue(wayToKeep, true);
    222240            } else {
     241                DataSet ds = selectedWay.getDataSet();
     242                if (ds != null) {
     243                    ds.removeDataSetListener(dataSetListener);
     244                }
    223245                setHighlightedWaySegments(Collections.emptyList());
    224246                DISPLAY_COUNT.decrementAndGet();
     
    233255            super.buttonAction(buttonIndex, evt);
    234256            toggleSaveState(); // necessary since #showDialog() does not handle it due to the non-modal dialog
    235             if (getValue() == 1) {
     257            if (getValue() == 1 && selectedWay.getDataSet() != null) {
    236258                doSplitWay(selectedWay, list.getSelectedValue(), newWays, selection);
    237259            }
     260        }
     261
     262        private class SplitWayDataSetListener implements DataSetListener {
     263
     264            @Override
     265            public void primitivesAdded(PrimitivesAddedEvent event) {
     266            }
     267
     268            @Override
     269            public void primitivesRemoved(PrimitivesRemovedEvent event) {
     270                if (event.getPrimitives().stream().anyMatch(p -> p instanceof Way)) {
     271                    updateWaySegments();
     272                }
     273            }
     274
     275            @Override
     276            public void tagsChanged(TagsChangedEvent event) {}
     277
     278            @Override
     279            public void nodeMoved(NodeMovedEvent event) {}
     280
     281            @Override
     282            public void wayNodesChanged(WayNodesChangedEvent event) {
     283                updateWaySegments();
     284            }
     285
     286            @Override
     287            public void relationMembersChanged(RelationMembersChangedEvent event) {}
     288
     289            @Override
     290            public void otherDatasetChange(AbstractDatasetChangedEvent event) {}
     291
     292            @Override
     293            public void dataChanged(DataChangedEvent event) {}
     294
     295            private void updateWaySegments() {
     296                if (!selectedWay.isUsable()) {
     297                    setVisible(false);
     298                    return;
     299                }
     300                newWays = SplitWayCommand.createNewWaysFromChunks(selectedWay,
     301                        SplitWayCommand.buildSplitChunks(selectedWay, selectedNodes));
     302                if (list.getSelectedIndex() < newWays.size()) {
     303                    wayToKeep = newWays.get(list.getSelectedIndex());
     304                } else {
     305                    wayToKeep = SplitWayCommand.Strategy.keepLongestChunk().determineWayToKeep(newWays);
     306                }
     307                list.setListData(newWays.toArray(new Way[0]));
     308                list.setSelectedValue(wayToKeep, true);
     309            }
     310
    238311        }
    239312    }
Note: See TracChangeset for help on using the changeset viewer.