Ticket #10730: 10730-alpha.patch

File 10730-alpha.patch, 9.9 KB (added by simon04, 9 years ago)
  • src/org/openstreetmap/josm/actions/SplitWayAction.java

    diff --git a/src/org/openstreetmap/josm/actions/SplitWayAction.java b/src/org/openstreetmap/josm/actions/SplitWayAction.java
    index 2fd7f2f..9c81a2f 100644
    a b  
    55import static org.openstreetmap.josm.tools.I18n.tr;
    66import static org.openstreetmap.josm.tools.I18n.trn;
    77
     8import java.awt.Component;
     9import java.awt.GridLayout;
    810import java.awt.event.ActionEvent;
    911import java.awt.event.KeyEvent;
    1012import java.util.ArrayList;
     
    1719import java.util.List;
    1820import java.util.Set;
    1921
     22import javax.swing.DefaultListCellRenderer;
     23import javax.swing.JLabel;
     24import javax.swing.JList;
    2025import javax.swing.JOptionPane;
     26import javax.swing.JPanel;
     27import javax.swing.ListSelectionModel;
     28import javax.swing.event.ListSelectionEvent;
     29import javax.swing.event.ListSelectionListener;
    2130
    2231import org.openstreetmap.josm.Main;
    2332import org.openstreetmap.josm.command.AddCommand;
    2433import org.openstreetmap.josm.command.ChangeCommand;
    2534import org.openstreetmap.josm.command.Command;
    2635import org.openstreetmap.josm.command.SequenceCommand;
     36import org.openstreetmap.josm.data.osm.NameFormatter;
    2737import org.openstreetmap.josm.data.osm.Node;
    2838import org.openstreetmap.josm.data.osm.OsmPrimitive;
    2939import org.openstreetmap.josm.data.osm.PrimitiveId;
     
    3141import org.openstreetmap.josm.data.osm.RelationMember;
    3242import org.openstreetmap.josm.data.osm.Way;
    3343import org.openstreetmap.josm.gui.DefaultNameFormatter;
     44import org.openstreetmap.josm.gui.ExtendedDialog;
    3445import org.openstreetmap.josm.gui.Notification;
    3546import org.openstreetmap.josm.gui.layer.OsmDataLayer;
    3647import org.openstreetmap.josm.tools.CheckParameterUtil;
    3748import org.openstreetmap.josm.tools.Shortcut;
     49import org.openstreetmap.josm.tools.Utils;
    3850
    3951/**
    4052 * Splits a way into multiple ways (all identical except for their node list).
    public void actionPerformed(ActionEvent e) {  
    175187        }
    176188
    177189        // Finally, applicableWays contains only one perfect way
    178         Way selectedWay = applicableWays.get(0);
     190        final Way selectedWay = applicableWays.get(0);
    179191
    180192        List<List<Node>> wayChunks = buildSplitChunks(selectedWay, selectedNodes);
    181193        if (wayChunks != null) {
    182             List<OsmPrimitive> sel = new ArrayList<>(selectedWays.size() + selectedRelations.size());
     194            final List<OsmPrimitive> sel = new ArrayList<>(selectedWays.size() + selectedRelations.size());
    183195            sel.addAll(selectedWays);
    184196            sel.addAll(selectedRelations);
    185             SplitWayResult result = splitWay(getEditLayer(), selectedWay, wayChunks, sel);
    186             Main.main.undoRedo.add(result.getCommand());
    187             getCurrentDataSet().setSelected(result.getNewSelection());
     197
     198            final List<Way> newWays = createNewWaysFromChunks(selectedWay, wayChunks);
     199            Way wayToKeep = newWays.get(0);
     200
     201            if (ExpertToggleAction.isExpert() && !selectedWay.isNew()) {
     202                final JList<Way> list = new JList<>(newWays.toArray(new Way[newWays.size()]));
     203                list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
     204                list.addListSelectionListener(new ListSelectionListener() {
     205                    @Override
     206                    public void valueChanged(ListSelectionEvent e) {
     207                        final Way selected = list.getSelectedValue();
     208                        if (Main.isDisplayingMapView() && selected != null) {
     209                            // todo somehow select/highlight this way although it is not yet part of the dataset
     210                        }
     211                    }
     212                });
     213                list.setCellRenderer(new DefaultListCellRenderer() {
     214                    @Override
     215                    public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
     216                        final Component c = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
     217                        ((JLabel) c).setText(tr("Segment {0}: {1}", index + 1, DefaultNameFormatter.getInstance().format((Way) value)));
     218                        return c;
     219                    }
     220                });
     221                list.setSelectedValue(wayToKeep, true);
     222                final String question = tr("Which way segment should reuse id {0}?", selectedWay.getId());
     223                final ExtendedDialog dialog = new ExtendedDialog(Main.parent, question, new String[]{tr("Ok"), tr("Cancel")}, true) {
     224                    @Override
     225                    protected void buttonAction(int buttonIndex, ActionEvent evt) {
     226                        super.buttonAction(buttonIndex, evt);
     227                        if (getValue() == 1) {
     228                            final Way wayToKeep = list.getSelectedValue();
     229                            final SplitWayResult result = doSplitWay(getEditLayer(), selectedWay, wayToKeep, newWays, sel);
     230                            Main.main.undoRedo.add(result.getCommand());
     231                            getCurrentDataSet().setSelected(result.getNewSelection());
     232                        }
     233                    }
     234
     235                    {
     236                        setButtonIcons(new String[]{"ok", "cancel"});
     237                        final JPanel pane = new JPanel(new GridLayout(2, 1));
     238                        pane.add(new JLabel(question));
     239                        pane.add(list);
     240                        setContent(pane);
     241                    }
     242                };
     243                dialog.setModal(false);
     244                dialog.showDialog();
     245            } else {
     246                final SplitWayResult result = doSplitWay(getEditLayer(), selectedWay, wayToKeep, newWays, sel);
     247                Main.main.undoRedo.add(result.getCommand());
     248                getCurrentDataSet().setSelected(result.getNewSelection());
     249            }
    188250        }
    189251    }
    190252
    public void actionPerformed(ActionEvent e) {  
    327389        return wayChunks;
    328390    }
    329391
     392    protected static List<Way> createNewWaysFromChunks(Way way, List<List<Node>> wayChunks) {
     393        final List<Way> newWays = new ArrayList<>();
     394        for (List<Node> wayChunk : wayChunks) {
     395            Way wayToAdd = new Way();
     396            wayToAdd.setKeys(way.getKeys());
     397            wayToAdd.setNodes(wayChunk);
     398            newWays.add(wayToAdd);
     399        }
     400        return newWays;
     401    }
     402
    330403    /**
    331404     * Splits the way {@code way} into chunks of {@code wayChunks} and replies
    332405     * the result of this process in an instance of {@link SplitWayResult}.
    public void actionPerformed(ActionEvent e) {  
    341414     * @param selection The list of currently selected primitives
    342415     * @return the result from the split operation
    343416     */
    344     public static SplitWayResult splitWay(OsmDataLayer layer, Way way, List<List<Node>> wayChunks,
     417    public static SplitWayResult splitWay(final OsmDataLayer layer, final Way way, List<List<Node>> wayChunks,
    345418            Collection<? extends OsmPrimitive> selection) {
    346419        // 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());
     420        final List<OsmPrimitive> newSelection = new ArrayList<>(selection.size() + wayChunks.size());
    349421        newSelection.addAll(selection);
    350422
    351         Iterator<List<Node>> chunkIt = wayChunks.iterator();
     423        // Create all potential new ways
     424        final List<Way> newWays = createNewWaysFromChunks(way, wayChunks);
     425
     426        // Determine which part reuses the existing way
     427        final Way wayToKeep = newWays.get(0);
     428
     429        return doSplitWay(layer, way, wayToKeep, newWays, newSelection);
     430    }
     431
     432    static SplitWayResult doSplitWay(OsmDataLayer layer, Way way, Way wayToKeep, List<Way> newWays,
     433                                   List<OsmPrimitive> newSelection) {
     434
     435        Collection<Command> commandList = new ArrayList<>(newWays.size());
    352436        Collection<String> nowarnroles = Main.pref.getCollection("way.split.roles.nowarn",
    353437                Arrays.asList("outer", "inner", "forward", "backward", "north", "south", "east", "west"));
    354438
    355         // First, change the original way
    356         Way changedWay = new Way(way);
    357         changedWay.setNodes(chunkIt.next());
     439        // Change the original way
     440        final Way changedWay = new Way(way);
     441        changedWay.setNodes(wayToKeep.getNodes());
    358442        commandList.add(new ChangeCommand(way, changedWay));
    359443        if (!newSelection.contains(way)) {
    360444            newSelection.add(way);
    361445        }
     446        newWays.remove(wayToKeep);
    362447
    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());
     448        for (Way wayToAdd : newWays) {
    370449            commandList.add(new AddCommand(layer, wayToAdd));
    371450            newSelection.add(wayToAdd);
    372451        }
     452
    373453        boolean warnmerole = false;
    374454        boolean warnme = false;
    375455        // now copy all relations to new way also
    public static SplitWayResult splitWay(OsmDataLayer layer, Way way, List<List<Nod  
    508588        return new SplitWayResult(
    509589                new SequenceCommand(
    510590                        /* 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()),
     591                        trn("Split way {0} into {1} part", "Split way {0} into {1} parts", newWays.size(),
     592                                way.getDisplayName(DefaultNameFormatter.getInstance()), newWays.size()),
    513593                        commandList
    514594                        ),
    515595                        newSelection,