source: josm/trunk/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTableModel.java@ 1804

Last change on this file since 1804 was 1804, checked in by Gubaer, 15 years ago

improved window management for relation editor windows
added duplicate action to relation editor

File size: 12.2 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.dialogs.relation;
3
4import java.util.ArrayList;
5import java.util.Arrays;
6import java.util.Collection;
7import java.util.Collections;
8import java.util.Iterator;
9import java.util.List;
10import java.util.concurrent.CopyOnWriteArrayList;
11
12import javax.swing.DefaultListSelectionModel;
13import javax.swing.ListSelectionModel;
14import javax.swing.table.AbstractTableModel;
15
16import org.openstreetmap.josm.data.osm.DataSet;
17import org.openstreetmap.josm.data.osm.OsmPrimitive;
18import org.openstreetmap.josm.data.osm.Relation;
19import org.openstreetmap.josm.data.osm.RelationMember;
20
21public class MemberTableModel extends AbstractTableModel{
22
23 private Relation relation;
24 private ArrayList<RelationMember> members;
25 private ArrayList<String> memberLinkingInfo;
26 private DefaultListSelectionModel listSelectionModel;
27 private CopyOnWriteArrayList<IMemberModelListener> listeners;
28
29 /**
30 * constructor
31 */
32 public MemberTableModel(){
33 members = new ArrayList<RelationMember>();
34 memberLinkingInfo = new ArrayList<String>();
35 listeners = new CopyOnWriteArrayList<IMemberModelListener>();
36 }
37
38 public void addMemberModelListener(IMemberModelListener listener) {
39 synchronized(listeners) {
40 if (listener != null && ! listeners.contains(listener)) {
41 listeners.add(listener);
42 }
43 }
44 }
45
46 public void removeMemberModelListener(IMemberModelListener listener) {
47 synchronized(listeners) {
48 if (listener != null && listeners.contains(listener)) {
49 listeners.remove(listener);
50 }
51 }
52 }
53
54 protected void fireMakeMemberVisible(int index) {
55 synchronized(listeners) {
56 for (IMemberModelListener listener: listeners) {
57 listener.makeMemberVisible(index);
58 }
59 }
60 }
61
62 public void populate(Relation relation) {
63 members.clear();
64 if (relation != null && relation.members != null) {
65 members.addAll(relation.members);
66 }
67 this.relation = relation;
68 fireTableDataChanged();
69 }
70
71 public int getColumnCount() {
72 return 3;
73 }
74
75 public int getRowCount() {
76 return members.size();
77 }
78
79 public Object getValueAt(int rowIndex, int columnIndex) {
80 switch(columnIndex) {
81 case 0: return members.get(rowIndex).role;
82 case 1: return members.get(rowIndex).member;
83 case 2: return "";
84 }
85 // should not happen
86 return null;
87 }
88
89 @Override
90 public boolean isCellEditable(int rowIndex, int columnIndex) {
91 return columnIndex == 0;
92 }
93
94 @Override
95 public void setValueAt(Object value, int rowIndex, int columnIndex) {
96 RelationMember member = members.get(rowIndex);
97 member.role = value.toString();
98 }
99
100
101 public OsmPrimitive getReferredPrimitive(int idx) {
102 return members.get(idx).member;
103 }
104
105 public void moveUp(int[] selectedRows) {
106 if (! canMoveUp(selectedRows))
107 return;
108
109 for (int row : selectedRows) {
110 RelationMember member1 = members.get(row);
111 RelationMember member2 = members.get(row-1);
112 members.set(row, member2);
113 members.set(row-1, member1);
114 }
115 fireTableDataChanged();
116 getSelectionModel();
117 listSelectionModel.clearSelection();
118 for (int row : selectedRows) {
119 row--;
120 listSelectionModel.addSelectionInterval(row, row);
121 }
122 fireMakeMemberVisible(selectedRows[0] -1);
123 }
124
125 public void moveDown(int[] selectedRows) {
126 if (! canMoveDown(selectedRows))
127 return;
128
129 for (int i=selectedRows.length-1; i >=0; i--) {
130 int row = selectedRows[i];
131 RelationMember member1 = members.get(row);
132 RelationMember member2 = members.get(row+1);
133 members.set(row, member2);
134 members.set(row+1, member1);
135 }
136 fireTableDataChanged();
137 getSelectionModel();
138 listSelectionModel.clearSelection();
139 for (int row : selectedRows) {
140 row++;
141 listSelectionModel.addSelectionInterval(row, row);
142 }
143 fireMakeMemberVisible(selectedRows[0] + 1);
144 }
145
146 public void remove(int[] selectedRows) {
147 if (! canRemove(selectedRows))
148 return;
149 int offset = 0;
150 for (int row : selectedRows) {
151 row -= offset;
152 members.remove(row);
153 offset++;
154 }
155 fireTableDataChanged();
156 }
157
158 public boolean canMoveUp(int [] rows) {
159 if (rows == null || rows.length == 0) return false;
160 Arrays.sort(rows);
161 return rows[0] > 0 && members.size() > 0;
162 }
163
164 public boolean canMoveDown(int [] rows) {
165 if (rows == null || rows.length == 0) return false;
166 Arrays.sort(rows);
167 return members.size() >0 && rows[rows.length-1] < members.size() - 1;
168 }
169
170 public boolean canRemove(int [] rows) {
171 if (rows == null || rows.length == 0) return false;
172 return true;
173 }
174
175 public DefaultListSelectionModel getSelectionModel() {
176 if (listSelectionModel == null) {
177 listSelectionModel = new DefaultListSelectionModel();
178 listSelectionModel.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
179 }
180 return listSelectionModel;
181 }
182
183 public void updateMemberReferences(DataSet ds) {
184 for (RelationMember member : members) {
185 if (member.member.id == 0) {
186 continue;
187 }
188 OsmPrimitive primitive = ds.getPrimitiveById(member.member.id);
189 if (primitive != null) {
190 member.member = primitive;
191 }
192 }
193 fireTableDataChanged();
194 }
195
196 public void removeMembersReferringTo(List<? extends OsmPrimitive> primitives) {
197 if (primitives == null) return;
198 Iterator<RelationMember> it = members.iterator();
199 while(it.hasNext()) {
200 RelationMember member = it.next();
201 if (primitives.contains(member.member)) {
202 it.remove();
203 }
204 }
205 fireTableDataChanged();
206 }
207
208 public void applyToRelation(Relation relation) {
209 relation.members.clear();
210 relation.members.addAll(members);
211 }
212
213 public boolean hasSameMembersAs(Relation relation) {
214 if (relation == null) return false;
215 if (relation.members.size() != members.size()) return false;
216 for (int i=0; i<relation.members.size();i++) {
217 if (! relation.members.get(i).equals(members.get(i)))
218 return false;
219 }
220 return true;
221 }
222
223 public boolean hasIncompleteMembers() {
224 for (RelationMember member: members) {
225 if (member.member.incomplete)
226 return true;
227 }
228 return false;
229 }
230
231 protected List<Integer> getSelectedIndices() {
232 ArrayList<Integer> selectedIndices = new ArrayList<Integer>();
233 for (int i=0; i< members.size();i++) {
234 if (getSelectionModel().isSelectedIndex(i)) {
235 selectedIndices.add(i);
236 }
237 }
238 return selectedIndices;
239 }
240
241 public void addMembersAtBeginning(List<? extends OsmPrimitive> primitives) {
242 if (primitives == null) return;
243 for (OsmPrimitive primitive: primitives) {
244 RelationMember member = new RelationMember(null,primitive);
245 members.add(0,member);
246 }
247 fireTableDataChanged();
248 getSelectionModel().clearSelection();
249 for (int i=0; i<primitives.size();i++) {
250 getSelectionModel().addSelectionInterval(i,i);
251 }
252 fireMakeMemberVisible(0);
253 }
254
255 public void addMembersAtEnd(List<? extends OsmPrimitive> primitives) {
256 if (primitives == null) return;
257
258 for (OsmPrimitive primitive: primitives) {
259 RelationMember member = new RelationMember(null,primitive);
260 members.add(member);
261 }
262 fireTableDataChanged();
263 getSelectionModel().clearSelection();
264 for (int i=0; i<primitives.size();i++) {
265 getSelectionModel().addSelectionInterval(members.size()-1-i,members.size()-1-i);
266 }
267 fireMakeMemberVisible(members.size() -1);
268 }
269
270 public void addMembersBeforeIdx(List<? extends OsmPrimitive> primitives, int idx) {
271 if (primitives == null) return;
272
273 for (OsmPrimitive primitive: primitives) {
274 RelationMember member = new RelationMember(null,primitive);
275 members.add(idx,member);
276 }
277 fireTableDataChanged();
278 getSelectionModel().clearSelection();
279 for (int i=0; i<primitives.size();i++) {
280 getSelectionModel().addSelectionInterval(idx+i,idx+i);
281 }
282 fireMakeMemberVisible(idx);
283 }
284
285 public void addMembersAfterIdx(List<? extends OsmPrimitive> primitives, int idx) {
286 if (primitives == null) return;
287 int j =1;
288 for (OsmPrimitive primitive: primitives) {
289 RelationMember member = new RelationMember(null,primitive);
290 members.add(idx+j,member);
291 j++;
292 }
293 fireTableDataChanged();
294 getSelectionModel().clearSelection();
295 for (int i=0; i<primitives.size();i++) {
296 getSelectionModel().addSelectionInterval(idx+1 + i,idx+1 +i);
297 }
298 fireMakeMemberVisible(idx+1);
299 }
300
301 /**
302 * Replies the number of members which refer to a particular primitive
303 *
304 * @param primitive the primitive
305 * @return the number of members which refer to a particular primitive
306 */
307 public int getNumMembersWithPrimitive(OsmPrimitive primitive) {
308 int count = 0;
309 for (RelationMember member : members) {
310 if (member.member.equals(primitive)) {
311 count++;
312 }
313 }
314 return count;
315 }
316
317 /**
318 * updates the role of the members given by the indices in <code>idx</code>
319 *
320 * @param idx the array of indices
321 * @param role the new role
322 */
323 public void updateRole(int [] idx, String role) {
324 if (idx == null || idx.length == 0) return;
325 for (int row: idx) {
326 members.get(row).role = role;
327 }
328 fireTableDataChanged();
329 for (int row: idx) {
330 getSelectionModel().addSelectionInterval(row, row);
331 }
332 }
333
334 /**
335 * Replies a collection with the currently selected relation members
336 *
337 * @return a collection with the currently selected relation members
338 */
339 public Collection<RelationMember> getSelectedMembers() {
340 ArrayList<RelationMember> selectedMembers = new ArrayList<RelationMember>();
341 for (int i: getSelectedIndices()) {
342 selectedMembers.add(members.get(i));
343 }
344 return selectedMembers;
345 }
346
347
348 /**
349 * Selectes the members in the collection selectedMembers
350 *
351 * @param selectedMembers the collection of selected members
352 */
353 public void setSelectedMembers(Collection<RelationMember> selectedMembers) {
354 if (selectedMembers == null || selectedMembers.isEmpty())
355 return;
356
357 // lookup the indices for the respective members
358 //
359 ArrayList<Integer> selectedIndices = new ArrayList<Integer>();
360 for (RelationMember member: selectedMembers) {
361 int idx = members.indexOf(member);
362 if (idx >= 0 && !selectedIndices.contains(idx)) {
363 selectedIndices.add(idx);
364 }
365 }
366
367 // select the members
368 //
369 Collections.sort(selectedIndices);
370 getSelectionModel().clearSelection();
371 for (int row : selectedIndices) {
372 getSelectionModel().addSelectionInterval(row, row);
373 }
374
375 // make the first selected member visible
376 //
377 if (selectedIndices.size() > 0) {
378 fireMakeMemberVisible(selectedIndices.get(0));
379 }
380 }
381}
Note: See TracBrowser for help on using the repository browser.