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

Last change on this file since 32395 was 32395, checked in by donvip, 10 years ago

checkstyle, update to JOSM 10279

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