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

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

replaced JOptionDialog.show... by OptionPaneUtil.show....
improved relation editor

File size: 6.1 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 protected RelationEditor(OsmDataLayer layer, Relation relation, Collection<RelationMember> selectedMembers) {
92 // Initalizes ExtendedDialog
93 super(Main.parent,
94 "",
95 new String[] { tr("Apply Changes"), tr("Cancel")},
96 false
97 );
98 this.layer = layer;
99 setRelation(relation);
100 }
101
102 /**
103 * updates the title of the relation editor
104 */
105 protected void updateTitle() {
106 if (getRelation() == null) {
107 setTitle(tr("Create new relation in layer ''{0}''", layer.getName()));
108 } else if (getRelation().id == 0) {
109 setTitle(tr("Edit new relation in layer ''{0}''", layer.getName()));
110 } else {
111 setTitle(tr("Edit relation #{0} in layer ''{1}''", relation.id, layer.getName()));
112 }
113 }
114 /**
115 * Replies the currently edited relation
116 *
117 * @return the currently edited relation
118 */
119 protected Relation getRelation() {
120 return relation;
121 }
122
123 /**
124 * Sets the currently edited relation. Creates a snapshot of the current
125 * state of the relation. See {@see #getRelationSnapshot()}
126 *
127 * @param relation the relation
128 */
129 protected void setRelation(Relation relation) {
130 this.relationSnapshot = (relation == null) ? null : new Relation(relation);
131 this.relation = relation;
132 updateTitle();
133 }
134
135 /**
136 * Replies the {@see OsmDataLayer} in whose context this relation editor is
137 * open
138 *
139 * @return the {@see OsmDataLayer} in whose context this relation editor is
140 * open
141 */
142 protected OsmDataLayer getLayer() {
143 return layer;
144 }
145
146 /**
147 * Replies the state of the edited relation when the editor has been launched
148 *
149 * @return the state of the edited relation when the editor has been launched
150 */
151 protected Relation getRelationSnapshot() {
152 return relationSnapshot;
153 }
154
155 /**
156 * Replies true if the currently edited relation has been changed elsewhere.
157 *
158 * In this case a relation editor can't apply updates to the relation directly. Rather,
159 * it has to create a conflict.
160 *
161 * @return true if the currently edited relation has been changed elsewhere.
162 */
163 protected boolean isDirtyRelation() {
164 return ! relation.hasEqualSemanticAttributes(relationSnapshot);
165 }
166}
Note: See TracBrowser for help on using the repository browser.