Ignore:
Timestamp:
2017-08-28T18:48:58+02:00 (2 years ago)
Author:
Don-vip
Message:

see #15182 - refactor PurgeAction/PurgeCommand to avoid unneeded dependence on action

File:
1 edited

Legend:

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

    r12641 r12688  
    1313import java.util.ArrayList;
    1414import java.util.Collection;
    15 import java.util.HashSet;
    1615import java.util.List;
    17 import java.util.Set;
    1816
    1917import javax.swing.AbstractAction;
     
    3230import org.openstreetmap.josm.command.PurgeCommand;
    3331import org.openstreetmap.josm.data.osm.DataSet;
    34 import org.openstreetmap.josm.data.osm.Node;
    3532import org.openstreetmap.josm.data.osm.OsmPrimitive;
    36 import org.openstreetmap.josm.data.osm.Relation;
    37 import org.openstreetmap.josm.data.osm.RelationMember;
    38 import org.openstreetmap.josm.data.osm.Way;
    3933import org.openstreetmap.josm.gui.ConditionalOptionPaneUtil;
    4034import org.openstreetmap.josm.gui.MainApplication;
     
    6458    protected boolean modified;
    6559
    66     protected transient Set<OsmPrimitive> toPurge;
    67     /**
    68      * finally, contains all objects that are purged
    69      */
    70     protected transient Set<OsmPrimitive> toPurgeChecked;
    71     /**
    72      * Subset of toPurgeChecked. Marks primitives that remain in the dataset, but incomplete.
    73      */
    74     protected transient Set<OsmPrimitive> makeIncomplete;
    7560    /**
    7661     * Subset of toPurgeChecked. Those that have not been in the selection.
     
    8267     */
    8368    public PurgeAction() {
    84         this(true);
    85     }
    86 
    87     /**
    88      * Constructs a new {@code PurgeAction} with optional shortcut.
    89      * @param addShortcut controls whether the shortcut should be registered or not, as for toolbar registration
    90      * @since 11611
    91      */
    92     public PurgeAction(boolean addShortcut) {
    9369        /* translator note: other expressions for "purge" might be "forget", "clean", "obliterate", "prune" */
    94         super(tr("Purge..."), "purge", tr("Forget objects but do not delete them on server when uploading."), addShortcut ?
    95                 Shortcut.registerShortcut("system:purge", tr("Edit: {0}", tr("Purge")), KeyEvent.VK_P, Shortcut.CTRL_SHIFT)
    96                 : null, addShortcut);
     70        super(tr("Purge..."), "purge", tr("Forget objects but do not delete them on server when uploading."),
     71                Shortcut.registerShortcut("system:purge", tr("Edit: {0}", tr("Purge")), KeyEvent.VK_P, Shortcut.CTRL_SHIFT),
     72                true);
    9773        putValue("help", HelpUtil.ht("/Action/Purge"));
    9874    }
     
    141117    public PurgeCommand getPurgeCommand(Collection<OsmPrimitive> sel) {
    142118        layer = getLayerManager().getEditLayer();
    143 
    144         toPurge = new HashSet<>(sel);
    145119        toPurgeAdditionally = new ArrayList<>();
    146         toPurgeChecked = new HashSet<>();
    147 
    148         // Add referrer, unless the object to purge is not new and the parent is a relation
    149         Set<OsmPrimitive> toPurgeRecursive = new HashSet<>();
    150         while (!toPurge.isEmpty()) {
    151 
    152             for (OsmPrimitive osm: toPurge) {
    153                 for (OsmPrimitive parent: osm.getReferrers()) {
    154                     if (toPurge.contains(parent) || toPurgeChecked.contains(parent) || toPurgeRecursive.contains(parent)) {
    155                         continue;
    156                     }
    157                     if (parent instanceof Way || (parent instanceof Relation && osm.isNew())) {
    158                         toPurgeAdditionally.add(parent);
    159                         toPurgeRecursive.add(parent);
    160                     }
    161                 }
    162                 toPurgeChecked.add(osm);
    163             }
    164             toPurge = toPurgeRecursive;
    165             toPurgeRecursive = new HashSet<>();
    166         }
    167 
    168         makeIncomplete = new HashSet<>();
    169 
    170         // Find the objects that will be incomplete after purging.
    171         // At this point, all parents of new to-be-purged primitives are
    172         // also to-be-purged and
    173         // all parents of not-new to-be-purged primitives are either
    174         // to-be-purged or of type relation.
    175         TOP:
    176             for (OsmPrimitive child : toPurgeChecked) {
    177                 if (child.isNew()) {
    178                     continue;
    179                 }
    180                 for (OsmPrimitive parent : child.getReferrers()) {
    181                     if (parent instanceof Relation && !toPurgeChecked.contains(parent)) {
    182                         makeIncomplete.add(child);
    183                         continue TOP;
    184                     }
    185                 }
    186             }
    187 
    188         // Add untagged way nodes. Do not add nodes that have other referrers not yet to-be-purged.
    189         if (Main.pref.getBoolean("purge.add_untagged_waynodes", true)) {
    190             Set<OsmPrimitive> wayNodes = new HashSet<>();
    191             for (OsmPrimitive osm : toPurgeChecked) {
    192                 if (osm instanceof Way) {
    193                     Way w = (Way) osm;
    194                     NODE:
    195                         for (Node n : w.getNodes()) {
    196                             if (n.isTagged() || toPurgeChecked.contains(n)) {
    197                                 continue;
    198                             }
    199                             for (OsmPrimitive ref : n.getReferrers()) {
    200                                 if (ref != w && !toPurgeChecked.contains(ref)) {
    201                                     continue NODE;
    202                                 }
    203                             }
    204                             wayNodes.add(n);
    205                         }
    206                 }
    207             }
    208             toPurgeChecked.addAll(wayNodes);
    209             toPurgeAdditionally.addAll(wayNodes);
    210         }
    211 
    212         if (Main.pref.getBoolean("purge.add_relations_with_only_incomplete_members", true)) {
    213             Set<Relation> relSet = new HashSet<>();
    214             for (OsmPrimitive osm : toPurgeChecked) {
    215                 for (OsmPrimitive parent : osm.getReferrers()) {
    216                     if (parent instanceof Relation
    217                             && !(toPurgeChecked.contains(parent))
    218                             && hasOnlyIncompleteMembers((Relation) parent, toPurgeChecked, relSet)) {
    219                         relSet.add((Relation) parent);
    220                     }
    221                 }
    222             }
    223 
    224             // Add higher level relations (list gets extended while looping over it)
    225             List<Relation> relLst = new ArrayList<>(relSet);
    226             for (int i = 0; i < relLst.size(); ++i) { // foreach loop not applicable since list gets extended while looping over it
    227                 for (OsmPrimitive parent : relLst.get(i).getReferrers()) {
    228                     if (!(toPurgeChecked.contains(parent))
    229                             && hasOnlyIncompleteMembers((Relation) parent, toPurgeChecked, relLst)) {
    230                         relLst.add((Relation) parent);
    231                     }
    232                 }
    233             }
    234             relSet = new HashSet<>(relLst);
    235             toPurgeChecked.addAll(relSet);
    236             toPurgeAdditionally.addAll(relSet);
    237         }
    238 
    239         modified = false;
    240         for (OsmPrimitive osm : toPurgeChecked) {
    241             if (osm.isModified()) {
    242                 modified = true;
    243                 break;
    244             }
    245         }
    246 
    247         return layer != null ? new PurgeCommand(layer, toPurgeChecked, makeIncomplete) :
    248             new PurgeCommand(toPurgeChecked.iterator().next().getDataSet(), toPurgeChecked, makeIncomplete);
     120        PurgeCommand cmd = PurgeCommand.build(layer, sel, toPurgeAdditionally);
     121        modified = cmd.getParticipatingPrimitives().stream().anyMatch(OsmPrimitive::isModified);
     122        return cmd;
    249123    }
    250124
     
    323197        setEnabled(selection != null && !selection.isEmpty());
    324198    }
    325 
    326     private static boolean hasOnlyIncompleteMembers(
    327             Relation r, Collection<OsmPrimitive> toPurge, Collection<? extends OsmPrimitive> moreToPurge) {
    328         for (RelationMember m : r.getMembers()) {
    329             if (!m.getMember().isIncomplete() && !toPurge.contains(m.getMember()) && !moreToPurge.contains(m.getMember()))
    330                 return false;
    331         }
    332         return true;
    333     }
    334199}
Note: See TracChangeset for help on using the changeset viewer.