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

Last change on this file since 33265 was 32398, checked in by donvip, 8 years ago

checkstyle

File size: 6.3 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package relcontext.actions;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.awt.event.ActionEvent;
7import java.awt.event.KeyEvent;
8import java.util.ArrayList;
9import java.util.Collection;
10
11import org.openstreetmap.josm.Main;
12import org.openstreetmap.josm.actions.JosmAction;
13import org.openstreetmap.josm.command.ChangeCommand;
14import org.openstreetmap.josm.command.Command;
15import org.openstreetmap.josm.data.osm.DataSet;
16import org.openstreetmap.josm.data.osm.Node;
17import org.openstreetmap.josm.data.osm.OsmPrimitive;
18import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
19import org.openstreetmap.josm.data.osm.Relation;
20import org.openstreetmap.josm.data.osm.RelationMember;
21import org.openstreetmap.josm.data.osm.Way;
22import org.openstreetmap.josm.gui.util.GuiHelper;
23import org.openstreetmap.josm.tools.ImageProvider;
24import org.openstreetmap.josm.tools.Shortcut;
25
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 {
37 private ChosenRelation rel;
38 private SortAndFixAction sortAndFix;
39
40 public AddRemoveMemberAction(ChosenRelation rel, SortAndFixAction sortAndFix) {
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")),
43 KeyEvent.VK_EQUALS, Shortcut.DIRECT), false);
44 this.rel = rel;
45 this.sortAndFix = sortAndFix;
46 rel.addChosenRelationListener(this);
47 updateEnabledState();
48 }
49
50 @Override
51 public void actionPerformed(ActionEvent e) {
52 if (rel.get() == null)
53 return;
54
55 Relation r = new Relation(rel.get());
56
57 Collection<OsmPrimitive> toAdd = new ArrayList<>(getLayerManager().getEditDataSet().getSelected());
58 toAdd.remove(rel.get());
59 toAdd.removeAll(r.getMemberPrimitives());
60
61 // 0. check if relation is broken (temporary)
62 boolean isBroken = !toAdd.isEmpty() && sortAndFix.needsFixing(r);
63
64 // 1. remove all present members
65 r.removeMembersFor(getLayerManager().getEditDataSet().getSelected());
66
67 // 2. add all new members
68 for (OsmPrimitive p : toAdd) {
69 int pos = -1; //p instanceof Way ? findAdjacentMember(p, r) : -1;
70 if (pos < 0) {
71 r.addMember(new RelationMember("", p));
72 } else {
73 r.addMember(pos, new RelationMember("", p));
74 }
75 }
76
77 // 3. check for roles again (temporary)
78 Command roleFix = !isBroken && sortAndFix.needsFixing(r) ? sortAndFix.fixRelation(r) : null;
79 if (roleFix != null) {
80 roleFix.executeCommand();
81 }
82
83 if (!r.getMemberPrimitives().equals(rel.get().getMemberPrimitives())) {
84 Main.main.undoRedo.add(new ChangeCommand(rel.get(), r));
85 }
86 }
87
88 /**
89 * Finds two relation members between which to place given way. Incomplete.
90 * @see org.openstreetmap.josm.gui.dialogs.relation.MemberTableModel#determineDirection
91 */
92 protected int findAdjacentMember(Way w, Relation r) {
93 Node firstNode = w.firstNode();
94 Node lastNode = w.lastNode();
95
96 if (firstNode != null && !firstNode.equals(lastNode)) {
97 for (int i = 0; i < r.getMembersCount(); i++) {
98 if (r.getMember(i).getType().equals(OsmPrimitiveType.WAY)) {
99 Way rw = (Way) r.getMember(i).getMember();
100 Node firstNodeR = rw.firstNode();
101 Node lastNodeR = rw.lastNode();
102 if (firstNode.equals(firstNodeR) || firstNode.equals(lastNodeR) || lastNode.equals(firstNodeR) || lastNode.equals(lastNodeR))
103 return i + 1;
104 }
105 }
106 }
107 return -1;
108 }
109
110 @Override
111 public void chosenRelationChanged(Relation oldRelation, Relation newRelation) {
112 updateEnabledState();
113 }
114
115 @Override
116 protected void updateEnabledState() {
117 updateEnabledState(getLayerManager().getEditDataSet() == null ? null : getLayerManager().getEditDataSet().getSelected());
118 }
119
120 @Override
121 protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) {
122 updateIcon();
123 if (rel == null || rel.get() == null || selection == null || selection.isEmpty()) {
124 setEnabled(false);
125 return;
126 }
127 if (selection.size() == 1 && selection.contains(rel.get())) {
128 setEnabled(false);
129 return;
130 }
131 setEnabled(true);
132 }
133
134 protected void updateIcon() {
135 // todo: change icon based on selection
136 final int state; // 0=unknown, 1=add, 2=remove, 3=both
137 DataSet ds = getLayerManager().getEditDataSet();
138 if (ds == null || ds.getSelected() == null
139 || ds.getSelected().isEmpty() || rel == null || rel.get() == null) {
140 state = 0;
141 } else {
142 Collection<OsmPrimitive> toAdd = new ArrayList<>(ds.getSelected());
143 toAdd.remove(rel.get());
144 int selectedSize = toAdd.size();
145 if (selectedSize == 0) {
146 state = 0;
147 } else {
148 toAdd.removeAll(rel.get().getMemberPrimitives());
149 if (toAdd.isEmpty()) {
150 state = 2;
151 } else if (toAdd.size() < selectedSize) {
152 state = 3;
153 } else {
154 state = 1;
155 }
156 }
157 }
158 GuiHelper.runInEDT(new Runnable() {
159 @Override
160 public void run() {
161 if (state == 0) {
162 putValue(LARGE_ICON_KEY, ImageProvider.get("relcontext", "addremove"));
163 } else {
164 String iconName = state == 1 ? "add" : state == 2 ? "remove" : "addremove";
165 putValue(NAME, null);
166 putValue(LARGE_ICON_KEY, ImageProvider.get("relcontext", iconName));
167 }
168 }
169 });
170 }
171}
Note: See TracBrowser for help on using the repository browser.