Ticket #18728: 18728.3.patch

File 18728.3.patch, 6.5 KB (added by GerdP, 3 months ago)
  • src/org/openstreetmap/josm/actions/JoinAreasAction.java

     
    4848import org.openstreetmap.josm.tools.Logging;
    4949import org.openstreetmap.josm.tools.Pair;
    5050import org.openstreetmap.josm.tools.Shortcut;
     51import org.openstreetmap.josm.tools.Stopwatch;
    5152import org.openstreetmap.josm.tools.UserCancelException;
    5253import org.openstreetmap.josm.tools.Utils;
    5354
     
    5758 */
    5859public class JoinAreasAction extends JosmAction {
    5960    // This will be used to commit commands and unite them into one large command sequence at the end
     61    private final transient LinkedList<Command> executedCmds = new LinkedList<>();
    6062    private final transient LinkedList<Command> cmds = new LinkedList<>();
    61     private int cmdsCount;
    6263    private DataSet ds;
    6364    private final transient List<Relation> addedRelations = new LinkedList<>();
    6465    private final boolean addUndoRedo;
     
    478479     */
    479480    @Override
    480481    public void actionPerformed(ActionEvent e) {
     482        Stopwatch stopwatch = Stopwatch.createStarted();
    481483        join(getLayerManager().getEditDataSet().getSelectedWays());
     484        Logging.debug("join areas took {0}", stopwatch.toString());
    482485        clearFields();
    483486    }
    484487
    485488    private void clearFields() {
    486489        ds = null;
    487         cmdsCount = 0;
    488490        cmds.clear();
    489491        addedRelations.clear();
    490492    }
     
    561563                }
    562564                commitCommands(tr("Move tags from ways to relations"));
    563565
    564                 makeCommitsOneAction(marktr("Joined overlapping areas"));
     566                commitExecuted();
    565567
    566568                if (result.polygons != null && ds != null) {
    567569                    List<Way> allWays = new ArrayList<>();
     
    579581            }
    580582        } catch (UserCancelException exception) {
    581583            Logging.trace(exception);
    582             //revert changes
    583             //FIXME: this is dirty hack
    584             makeCommitsOneAction(tr("Reverting changes"));
    585             if (addUndoRedo) {
    586                 UndoRedoHandler.getInstance().undo();
    587                 // add no-change commands to the stack to remove the half-done commands
    588                 Way w = ways.iterator().next();
    589                 cmds.add(new ChangeCommand(w, w));
    590                 cmds.add(new ChangeCommand(w, w));
    591                 commitCommands(tr("Reverting changes"));
    592                 UndoRedoHandler.getInstance().undo();
     584            cmds.clear();
     585            if (!executedCmds.isEmpty()) {
     586                // revert all executed commands
     587                ds = executedCmds.getFirst().getAffectedDataSet();
     588                ds.beginUpdate();
     589                while (!executedCmds.isEmpty()) {
     590                    executedCmds.removeLast().undoCommand();
     591                }
     592                ds.endUpdate();
    593593            }
    594594        }
    595595    }
     
    895895        }
    896896
    897897        cmds.clear();
    898         cmdsCount++;
    899898    }
    900899
    901900    private void commitCommand(Command c) {
    902         if (addUndoRedo) {
    903             UndoRedoHandler.getInstance().add(c);
    904         } else {
    905             c.executeCommand();
     901        c.executeCommand();
     902        executedCmds.add(c);
     903    }
     904
     905    /**
     906     * Add all executed commands as one command to the undo stack without executing them again.
     907     */
     908    private void commitExecuted() {
     909        cmds.clear();
     910        if (addUndoRedo && !executedCmds.isEmpty()) {
     911            UndoRedoHandler ur = UndoRedoHandler.getInstance();
     912            if (executedCmds.size() == 1) {
     913                ur.add(executedCmds.getFirst(), false);
     914            } else {
     915                ur.add(new JoinAreaCommand(executedCmds), false);
     916            }
    906917        }
     918        executedCmds.clear();
    907919    }
    908920
    909921    /**
     
    14351447        // This will turn ways so all of them point in the same direction and CombineAction won't bug
    14361448        // the user about this.
    14371449
    1438         //TODO: ReverseWay and Combine way are really slow and we use them a lot here. This slows down large joins.
    14391450        List<Way> actionWays = new ArrayList<>(ways.size());
    14401451        int oldestPos = 0;
    14411452        Way oldest = ways.get(0).way;
     
    14491460            if (!way.insideToTheRight) {
    14501461                ReverseWayResult res = ReverseWayAction.reverseWay(way.way);
    14511462                commitCommand(res.getReverseCommand());
    1452                 cmdsCount++;
    14531463            }
    14541464        }
    14551465
     
    14611471            throw new JosmRuntimeException("Join areas internal error.");
    14621472        }
    14631473        commitCommand(result.b);
    1464         cmdsCount++;
    14651474
    14661475        return result.a;
    14671476    }
     
    17071716        commitCommands(marktr("Remove tags from inner ways"));
    17081717    }
    17091718
    1710     /**
    1711      * Takes the last cmdsCount actions back and combines them into a single action
    1712      * (for when the user wants to undo the join action)
    1713      * @param message The commit message to display
    1714      */
    1715     private void makeCommitsOneAction(String message) {
    1716         cmds.clear();
    1717         if (addUndoRedo) {
    1718             UndoRedoHandler ur = UndoRedoHandler.getInstance();
    1719             List<Command> commands = ur.getUndoCommands();
    1720             int i = Math.max(commands.size() - cmdsCount, 0);
    1721             for (; i < commands.size(); i++) {
    1722                 cmds.add(commands.get(i));
    1723             }
    1724             ur.undo(cmds.size());
    1725         }
    1726 
    1727         commitCommands(message == null ? marktr("Join Areas Function") : message);
    1728         cmdsCount = 0;
    1729     }
    1730 
    17311719    @Override
    17321720    protected void updateEnabledState() {
    17331721        updateEnabledStateOnCurrentSelection();
     
    17371725    protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) {
    17381726        updateEnabledStateOnModifiableSelection(selection);
    17391727    }
     1728
     1729    private static class JoinAreaCommand extends SequenceCommand {
     1730        JoinAreaCommand(Collection<Command> sequenz) {
     1731            super(tr("Joined overlapping areas"), sequenz, true);
     1732            setSequenceComplete(true);
     1733        }
     1734
     1735        @Override
     1736        public void undoCommand() {
     1737            getAffectedDataSet().beginUpdate();
     1738            super.undoCommand();
     1739            getAffectedDataSet().endUpdate();
     1740        }
     1741
     1742        @Override
     1743        public boolean executeCommand() {
     1744            getAffectedDataSet().beginUpdate();
     1745            boolean rc = super.executeCommand();
     1746            getAffectedDataSet().endUpdate();
     1747            return rc;
     1748        }
     1749    }
     1750
    17401751}