// License: GPL. For details, see LICENSE file.
package mergeoverlap.hack;
import java.awt.Component;
import java.beans.PropertyChangeEvent;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import javax.swing.JPanel;
import org.openstreetmap.josm.Main;
import org.openstreetmap.josm.command.ChangePropertyCommand;
import org.openstreetmap.josm.command.Command;
import org.openstreetmap.josm.data.osm.OsmPrimitive;
import org.openstreetmap.josm.data.osm.Relation;
import org.openstreetmap.josm.data.osm.TagCollection;
import org.openstreetmap.josm.data.osm.Way;
import org.openstreetmap.josm.gui.conflict.tags.CombinePrimitiveResolverDialog;
import org.openstreetmap.josm.gui.conflict.tags.RelationMemberConflictResolver;
import org.openstreetmap.josm.gui.util.GuiHelper;
/**
* This dialog helps to resolve conflicts occurring when ways are combined or
* nodes are merged.
*
* There is a singleton instance of this dialog which can be retrieved using
* {@link #getInstance()}.
*
* The dialog uses two models: one for resolving tag conflicts, the other
* for resolving conflicts in relation memberships. For both models there are accessors,
* i.e {@link #getTagConflictResolverModel()} and {@link #getRelationMemberConflictResolverModel()}.
*
* Models have to be <strong>populated</strong> before the dialog is launched. Example:
* <pre>
* CombinePrimitiveResolverDialog dialog = CombinePrimitiveResolverDialog.getInstance();
* dialog.getTagConflictResolverModel().populate(aTagCollection);
* dialog.getRelationMemberConflictResolverModel().populate(aRelationLinkCollection);
* dialog.prepareDefaultDecisions();
* </pre>
*
* You should also set the target primitive which other primitives (ways or nodes) are
* merged to, see {@link #setTargetPrimitive(OsmPrimitive)}.
*
* After the dialog is closed use {@link #isCanceled()} to check whether the user canceled
* the dialog. If it wasn't canceled you may build a collection of {@link Command} objects
* which reflect the conflict resolution decisions the user made in the dialog:
* see {@link #buildResolutionCommands()}
*/
public class MyCombinePrimitiveResolverDialog extends CombinePrimitiveResolverDialog {
/** the unique instance of the dialog */
private static MyCombinePrimitiveResolverDialog instance;
/**
* Constructs a new {@code MyCombinePrimitiveResolverDialog}.
* @param parent The parent component in which this dialog will be displayed.
*/
public MyCombinePrimitiveResolverDialog(Component parent) {
super(parent);
}
/**
* Replies the unique instance of the dialog
*
* @return the unique instance of the dialog
*/
public static MyCombinePrimitiveResolverDialog getInstance() {
if (instance == null) {
GuiHelper.runInEDTAndWait(() -> instance = new MyCombinePrimitiveResolverDialog(Main.parent));
}
return instance;
}
@Override
protected JPanel buildRelationMemberConflictResolverPanel() {
pnlRelationMemberConflictResolver = new RelationMemberConflictResolver(new MyRelationMemberConflictResolverModel());
return pnlRelationMemberConflictResolver;
}
@Override
protected ApplyAction buildApplyAction() {
return new ApplyAction() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
super.propertyChange(evt);
if (evt.getPropertyName().equals(MyRelationMemberConflictResolverModel.NUM_CONFLICTS_PROP)) {
updateEnabledState();
}
}
};
}
/**
* Replies the relation membership conflict resolver model.
* @return The relation membership conflict resolver model.
*/
@Override
public MyRelationMemberConflictResolverModel getRelationMemberConflictResolverModel() {
return (MyRelationMemberConflictResolverModel) pnlRelationMemberConflictResolver.getModel();
}
/**
* Replies the list of {@link Command commands} needed to apply resolution choices.
* @return The list of {@link Command commands} needed to apply resolution choices.
*/
public List<Command> buildWayResolutionCommands() {
List<Command> cmds = new LinkedList<>();
TagCollection allResolutions = getTagConflictResolverModel().getAllResolutions();
if (!allResolutions.isEmpty()) {
cmds.addAll(buildTagChangeCommand(targetPrimitive, allResolutions));
}
if (targetPrimitive.get("created_by") != null) {
cmds.add(new ChangePropertyCommand(targetPrimitive, "created_by", null));
}
Command cmd = pnlRelationMemberConflictResolver.buildTagApplyCommands(getRelationMemberConflictResolverModel()
.getModifiedRelations(targetPrimitive));
if (cmd != null) {
cmds.add(cmd);
}
return cmds;
}
public void buildRelationCorrespondance(Map<Relation, Relation> newRelations, Map<Way, Way> oldWays) {
getRelationMemberConflictResolverModel().buildRelationCorrespondance(targetPrimitive, newRelations, oldWays);
}
}