source: osm/applications/editors/josm/plugins/reltoolbox/src/relcontext/actions/AddRemoveMemberAction.java

Last change on this file was 36483, checked in by stoecker, 2 months ago

set eol-style, fix checkstyle issues, add ignores

  • Property svn:eol-style set to native
File size: 6.3 KB
RevLine 
[32395]1// License: GPL. For details, see LICENSE file.
[25649]2package relcontext.actions;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
[28693]5
[25649]6import java.awt.event.ActionEvent;
[25717]7import java.awt.event.KeyEvent;
[28693]8import java.util.ArrayList;
9import java.util.Collection;
10
[25649]11import org.openstreetmap.josm.actions.JosmAction;
[36217]12import org.openstreetmap.josm.command.ChangeMembersCommand;
[25751]13import org.openstreetmap.josm.command.Command;
[34551]14import org.openstreetmap.josm.data.UndoRedoHandler;
[32398]15import org.openstreetmap.josm.data.osm.DataSet;
[25688]16import org.openstreetmap.josm.data.osm.Node;
[28693]17import org.openstreetmap.josm.data.osm.OsmPrimitive;
[25688]18import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
[25649]19import org.openstreetmap.josm.data.osm.Relation;
[25669]20import org.openstreetmap.josm.data.osm.RelationMember;
[25688]21import org.openstreetmap.josm.data.osm.Way;
[29344]22import org.openstreetmap.josm.gui.util.GuiHelper;
[25682]23import org.openstreetmap.josm.tools.ImageProvider;
[25717]24import org.openstreetmap.josm.tools.Shortcut;
[28693]25
[25649]26import relcontext.ChosenRelation;
27import relcontext.ChosenRelationListener;
28
29/**
30 * An action to add or remove (or both) member(s) from the chosen relation.
31 * In time should be able to determine correct position for new members.
32 * Also, there should be some support for entering a role for new members.
33 *
34 * @author Zverik
35 */
36public class AddRemoveMemberAction extends JosmAction implements ChosenRelationListener {
[36102]37 private final ChosenRelation rel;
38 private final SortAndFixAction sortAndFix;
[25649]39
[32395]40 public AddRemoveMemberAction(ChosenRelation rel, SortAndFixAction sortAndFix) {
[25717]41 super(null, "relcontext/addremove", tr("Add/remove members from the chosen relation"),
42 Shortcut.registerShortcut("reltoolbox:addremove", tr("Relation Toolbox: {0}", tr("Add/remove members from the chosen relation")),
[32395]43 KeyEvent.VK_EQUALS, Shortcut.DIRECT), false);
[25649]44 this.rel = rel;
[28693]45 this.sortAndFix = sortAndFix;
[25667]46 rel.addChosenRelationListener(this);
47 updateEnabledState();
[25649]48 }
49
[32395]50 @Override
51 public void actionPerformed(ActionEvent e) {
[32398]52 if (rel.get() == null)
[25669]53 return;
54
55 Relation r = new Relation(rel.get());
56
[32398]57 Collection<OsmPrimitive> toAdd = new ArrayList<>(getLayerManager().getEditDataSet().getSelected());
[25669]58 toAdd.remove(rel.get());
59 toAdd.removeAll(r.getMemberPrimitives());
60
[25751]61 // 0. check if relation is broken (temporary)
[28693]62 boolean isBroken = !toAdd.isEmpty() && sortAndFix.needsFixing(r);
[25751]63
[25669]64 // 1. remove all present members
[32398]65 r.removeMembersFor(getLayerManager().getEditDataSet().getSelected());
[25669]66
67 // 2. add all new members
[32395]68 for (OsmPrimitive p : toAdd) {
[25688]69 int pos = -1; //p instanceof Way ? findAdjacentMember(p, r) : -1;
[32398]70 if (pos < 0) {
[25688]71 r.addMember(new RelationMember("", p));
[32395]72 } else {
[25688]73 r.addMember(pos, new RelationMember("", p));
[32395]74 }
[25669]75 }
76
[25751]77 // 3. check for roles again (temporary)
[28693]78 Command roleFix = !isBroken && sortAndFix.needsFixing(r) ? sortAndFix.fixRelation(r) : null;
[32398]79 if (roleFix != null) {
[25751]80 roleFix.executeCommand();
[32395]81 }
[25751]82
[32398]83 if (!r.getMemberPrimitives().equals(rel.get().getMemberPrimitives())) {
[36217]84 UndoRedoHandler.getInstance().add(new ChangeMembersCommand(rel.get(), r.getMembers()));
[32395]85 }
[36217]86 r.setMembers(null); // See #19885
[25649]87 }
88
[25688]89 /**
90 * Finds two relation members between which to place given way. Incomplete.
91 * @see org.openstreetmap.josm.gui.dialogs.relation.MemberTableModel#determineDirection
92 */
[32395]93 protected int findAdjacentMember(Way w, Relation r) {
[25688]94 Node firstNode = w.firstNode();
95 Node lastNode = w.lastNode();
96
[32395]97 if (firstNode != null && !firstNode.equals(lastNode)) {
98 for (int i = 0; i < r.getMembersCount(); i++) {
[36217]99 if (r.getMember(i).getType() == OsmPrimitiveType.WAY) {
[32398]100 Way rw = (Way) r.getMember(i).getMember();
[25688]101 Node firstNodeR = rw.firstNode();
102 Node lastNodeR = rw.lastNode();
[32398]103 if (firstNode.equals(firstNodeR) || firstNode.equals(lastNodeR) || lastNode.equals(firstNodeR) || lastNode.equals(lastNodeR))
[25688]104 return i + 1;
105 }
106 }
107 }
108 return -1;
109 }
110
[32395]111 @Override
112 public void chosenRelationChanged(Relation oldRelation, Relation newRelation) {
[25669]113 updateEnabledState();
[25649]114 }
115
116 @Override
117 protected void updateEnabledState() {
[32398]118 updateEnabledState(getLayerManager().getEditDataSet() == null ? null : getLayerManager().getEditDataSet().getSelected());
[25649]119 }
120
121 @Override
[32395]122 protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) {
[25669]123 updateIcon();
[32395]124 if (rel == null || rel.get() == null || selection == null || selection.isEmpty()) {
[25649]125 setEnabled(false);
126 return;
127 }
[32395]128 if (selection.size() == 1 && selection.contains(rel.get())) {
[25669]129 setEnabled(false);
130 return;
131 }
[25649]132 setEnabled(true);
[25669]133 }
134
135 protected void updateIcon() {
[29344]136 final int state; // 0=unknown, 1=add, 2=remove, 3=both
[32398]137 DataSet ds = getLayerManager().getEditDataSet();
[36217]138 if (ds == null || ds.getSelected().isEmpty() || rel == null || rel.get() == null) {
[25682]139 state = 0;
[32395]140 } else {
[32398]141 Collection<OsmPrimitive> toAdd = new ArrayList<>(ds.getSelected());
[25669]142 toAdd.remove(rel.get());
143 int selectedSize = toAdd.size();
[32398]144 if (selectedSize == 0) {
[25682]145 state = 0;
[32395]146 } else {
[25669]147 toAdd.removeAll(rel.get().getMemberPrimitives());
[32398]148 if (toAdd.isEmpty()) {
[25682]149 state = 2;
[32398]150 } else if (toAdd.size() < selectedSize) {
[25682]151 state = 3;
[32395]152 } else {
[25682]153 state = 1;
[32395]154 }
[25669]155 }
156 }
[36217]157 GuiHelper.runInEDT(() -> {
158 if (state == 0) {
159 putValue(LARGE_ICON_KEY, ImageProvider.get("relcontext", "addremove"));
160 } else {
161 String iconName = state == 1 ? "add" : state == 2 ? "remove" : "addremove";
162 putValue(NAME, null);
163 putValue(LARGE_ICON_KEY, ImageProvider.get("relcontext", iconName));
[29344]164 }
165 });
[25649]166 }
167}
Note: See TracBrowser for help on using the repository browser.