source: josm/trunk/src/org/openstreetmap/josm/gui/dialogs/relation/RelationEditor.java@ 2070

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

new: rewrite of CombineWay action
new: conflict resolution dialog for CombineWay, including conflicts for different relation memberships
cleanup: cleanup in OsmReader, reduces memory footprint and reduces parsing time
cleanup: made most of the public fields in OsmPrimitive @deprecated, added accessors and changed the code
cleanup: replaced usages of @deprecated constructors for ExtendedDialog
fixed #3208: Combine ways brokes relation order

WARNING: this changeset touches a lot of code all over the code base. "latest" might become slightly unstable in the next days. Also experience incompatibility issues with plugins in the next few days.

File size: 6.7 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.dialogs.relation;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.lang.reflect.Constructor;
7import java.lang.reflect.Method;
8import java.util.ArrayList;
9import java.util.Collection;
10
11import org.openstreetmap.josm.Main;
12import org.openstreetmap.josm.data.osm.Relation;
13import org.openstreetmap.josm.data.osm.RelationMember;
14import org.openstreetmap.josm.gui.ExtendedDialog;
15import org.openstreetmap.josm.gui.layer.OsmDataLayer;
16
17public abstract class RelationEditor extends ExtendedDialog {
18
19 /** the list of registered relation editor classes */
20 private static ArrayList<Class<RelationEditor>> editors = new ArrayList<Class<RelationEditor>>();
21
22 /**
23 * Registers a relation editor class. Depending on the type of relation to be edited
24 * {@see #getEditor(OsmDataLayer, Relation, Collection)} will create an instance of
25 * this class.
26 *
27 * @param clazz the class
28 */
29 public void registerRelationEditor(Class<RelationEditor> clazz) {
30 if (clazz == null) return;
31 if (!editors.contains(clazz)) {
32 editors.add(clazz);
33 }
34 }
35
36 /**
37 * The relation that this editor is working on.
38 */
39 private Relation relation;
40
41 /**
42 * The version of the relation when editing is started. This is
43 * null if a new relation is created. */
44 private Relation relationSnapshot;
45
46 /** the data layer the relation belongs to */
47 private OsmDataLayer layer;
48
49 /**
50 * This is a factory method that creates an appropriate RelationEditor
51 * instance suitable for editing the relation that was passed in as an
52 * argument.
53 *
54 * This method is guaranteed to return a working RelationEditor. If no
55 * specific editor has been registered for the type of relation, then
56 * a generic editor will be returned.
57 *
58 * Editors can be registered by adding their class to the static list "editors"
59 * in the RelationEditor class. When it comes to editing a relation, all
60 * registered editors are queried via their static "canEdit" method whether they
61 * feel responsible for that kind of relation, and if they return true
62 * then an instance of that class will be used.
63 *
64 * @param r the relation to be edited
65 * @return an instance of RelationEditor suitable for editing that kind of relation
66 */
67 public static RelationEditor getEditor(OsmDataLayer layer, Relation r, Collection<RelationMember> selectedMembers) {
68 for (Class<RelationEditor> e : editors) {
69 try {
70 Method m = e.getMethod("canEdit", Relation.class);
71 Boolean canEdit = (Boolean) m.invoke(null, r);
72 if (canEdit) {
73 Constructor<RelationEditor> con = e.getConstructor(Relation.class, Collection.class);
74 RelationEditor editor = con.newInstance(layer, r, selectedMembers);
75 return editor;
76 }
77 } catch (Exception ex) {
78 // plod on
79 }
80 }
81 if (RelationDialogManager.getRelationDialogManager().isOpenInEditor(layer, r))
82 return RelationDialogManager.getRelationDialogManager().getEditorForRelation(layer, r);
83 else {
84 RelationEditor editor = new GenericRelationEditor(layer, r, selectedMembers);
85 RelationDialogManager.getRelationDialogManager().positionOnScreen(editor);
86 RelationDialogManager.getRelationDialogManager().register(layer, r, editor);
87 return editor;
88 }
89 }
90
91 /**
92 * Creates a new relation editor
93 *
94 * @param layer the {@see OsmDataLayer} in whose context a relation is edited. Must not be null.
95 * @param relation the relation. Can be null if a new relation is to be edited.
96 * @param selectedMembers a collection of members in <code>relation</code> which the editor
97 * should display selected when the editor is first displayed on screen
98 * @throws IllegalArgumentException thrown if layer is null
99 */
100 protected RelationEditor(OsmDataLayer layer, Relation relation, Collection<RelationMember> selectedMembers) throws IllegalArgumentException{
101 // Initalizes ExtendedDialog
102 super(Main.parent,
103 "",
104 new String[] { tr("Apply Changes"), tr("Cancel")},
105 false
106 );
107 if (layer == null)
108 throw new IllegalArgumentException(tr("parameter ''{0}'' must not be null", "layer"));
109 this.layer = layer;
110 setRelation(relation);
111 }
112
113 /**
114 * updates the title of the relation editor
115 */
116 protected void updateTitle() {
117 if (getRelation() == null) {
118 setTitle(tr("Create new relation in layer ''{0}''", layer.getName()));
119 } else if (getRelation().getId() == 0) {
120 setTitle(tr("Edit new relation in layer ''{0}''", layer.getName()));
121 } else {
122 setTitle(tr("Edit relation #{0} in layer ''{1}''", relation.getId(), layer.getName()));
123 }
124 }
125 /**
126 * Replies the currently edited relation
127 *
128 * @return the currently edited relation
129 */
130 protected Relation getRelation() {
131 return relation;
132 }
133
134 /**
135 * Sets the currently edited relation. Creates a snapshot of the current
136 * state of the relation. See {@see #getRelationSnapshot()}
137 *
138 * @param relation the relation
139 */
140 protected void setRelation(Relation relation) {
141 this.relationSnapshot = (relation == null) ? null : new Relation(relation);
142 this.relation = relation;
143 updateTitle();
144 }
145
146 /**
147 * Replies the {@see OsmDataLayer} in whose context this relation editor is
148 * open
149 *
150 * @return the {@see OsmDataLayer} in whose context this relation editor is
151 * open
152 */
153 protected OsmDataLayer getLayer() {
154 return layer;
155 }
156
157 /**
158 * Replies the state of the edited relation when the editor has been launched
159 *
160 * @return the state of the edited relation when the editor has been launched
161 */
162 protected Relation getRelationSnapshot() {
163 return relationSnapshot;
164 }
165
166 /**
167 * Replies true if the currently edited relation has been changed elsewhere.
168 *
169 * In this case a relation editor can't apply updates to the relation directly. Rather,
170 * it has to create a conflict.
171 *
172 * @return true if the currently edited relation has been changed elsewhere.
173 */
174 protected boolean isDirtyRelation() {
175 return ! relation.hasEqualSemanticAttributes(relationSnapshot);
176 }
177}
Note: See TracBrowser for help on using the repository browser.