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

Last change on this file since 30145 was 29344, checked in by donvip, 12 years ago

[josm_plugins] fix EDT violations in measurement and reltoolbox plugins

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