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

Last change on this file since 27852 was 27852, checked in by stoecker, 13 years ago

fix shortcut deprecation

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