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

Last change on this file since 12663 was 12620, checked in by Don-vip, 7 years ago

see #15182 - deprecate all Main logging methods and introduce suitable replacements in Logging for most of them

  • Property svn:eol-style set to native
File size: 7.3 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.beans.PropertyChangeListener;
7import java.beans.PropertyChangeSupport;
8import java.lang.reflect.Method;
9import java.util.ArrayList;
10import java.util.Collection;
11import java.util.List;
12
13import org.openstreetmap.josm.Main;
14import org.openstreetmap.josm.data.osm.Relation;
15import org.openstreetmap.josm.data.osm.RelationMember;
16import org.openstreetmap.josm.gui.ExtendedDialog;
17import org.openstreetmap.josm.gui.layer.OsmDataLayer;
18import org.openstreetmap.josm.tools.CheckParameterUtil;
19import org.openstreetmap.josm.tools.Logging;
20
21/**
22 * Abstract relation editor.
23 * @since 1599
24 */
25public abstract class RelationEditor extends ExtendedDialog implements IRelationEditor {
26
27 /** the property name for the current relation.
28 * @see #setRelation(Relation)
29 * @see #getRelation()
30 */
31 public static final String RELATION_PROP = RelationEditor.class.getName() + ".relation";
32
33 /** the property name for the current relation snapshot
34 * @see #getRelationSnapshot()
35 */
36 public static final String RELATION_SNAPSHOT_PROP = RelationEditor.class.getName() + ".relationSnapshot";
37
38 /** the list of registered relation editor classes */
39 private static List<Class<RelationEditor>> editors = new ArrayList<>();
40
41 /** The relation that this editor is working on. */
42 private transient Relation relation;
43
44 /** The version of the relation when editing is started. This is null if a new relation is created. */
45 private transient Relation relationSnapshot;
46
47 /** The data layer the relation belongs to */
48 private final transient OsmDataLayer layer;
49
50 private final PropertyChangeSupport support = new PropertyChangeSupport(this);
51
52 /**
53 * Creates a new relation editor
54 *
55 * @param layer the {@link OsmDataLayer} in whose context a relation is edited. Must not be null.
56 * @param relation the relation. Can be null if a new relation is to be edited.
57 * @throws IllegalArgumentException if layer is null
58 */
59 protected RelationEditor(OsmDataLayer layer, Relation relation) {
60 super(Main.parent,
61 "",
62 new String[] {tr("Apply Changes"), tr("Cancel")},
63 false,
64 false
65 );
66 CheckParameterUtil.ensureParameterNotNull(layer, "layer");
67 this.layer = layer;
68 setRelation(relation);
69 layer.removeRecentRelation(relation);
70 }
71
72 /**
73 * Registers a relation editor class. Depending on the type of relation to be edited
74 * {@link #getEditor(OsmDataLayer, Relation, Collection)} will create an instance of
75 * this class.
76 *
77 * @param clazz the class
78 */
79 public void registerRelationEditor(Class<RelationEditor> clazz) {
80 if (clazz != null && !editors.contains(clazz)) {
81 editors.add(clazz);
82 }
83 }
84
85 /**
86 * This is a factory method that creates an appropriate RelationEditor instance suitable for editing the relation
87 * that was passed in as an argument.
88 *
89 * This method is guaranteed to return a working RelationEditor. If no specific editor has been registered for the
90 * type of relation, then a generic editor will be returned.
91 *
92 * Editors can be registered by adding their class to the static list "editors" in the RelationEditor class.
93 * When it comes to editing a relation, all registered editors are queried via their static "canEdit" method whether
94 * they feel responsible for that kind of relation, and if they return true then an instance of that class will be used.
95 *
96 * @param layer the data layer the relation is a member of
97 * @param r the relation to be edited
98 * @param selectedMembers a collection of relation members which shall be selected when the editor is first launched
99 * @return an instance of RelationEditor suitable for editing that kind of relation
100 */
101 public static RelationEditor getEditor(OsmDataLayer layer, Relation r, Collection<RelationMember> selectedMembers) {
102 for (Class<RelationEditor> e : editors) {
103 try {
104 Method m = e.getMethod("canEdit", Relation.class);
105 Boolean canEdit = (Boolean) m.invoke(null, r);
106 if (canEdit) {
107 return e.getConstructor(Relation.class, Collection.class).newInstance(layer, r, selectedMembers);
108 }
109 } catch (ReflectiveOperationException ex) {
110 Logging.warn(ex);
111 }
112 }
113 if (RelationDialogManager.getRelationDialogManager().isOpenInEditor(layer, r))
114 return RelationDialogManager.getRelationDialogManager().getEditorForRelation(layer, r);
115 else {
116 RelationEditor editor = new GenericRelationEditor(layer, r, selectedMembers);
117 RelationDialogManager.getRelationDialogManager().positionOnScreen(editor);
118 RelationDialogManager.getRelationDialogManager().register(layer, r, editor);
119 return editor;
120 }
121 }
122
123 /**
124 * updates the title of the relation editor
125 */
126 protected void updateTitle() {
127 if (getRelation() == null) {
128 setTitle(tr("Create new relation in layer ''{0}''", layer.getName()));
129 } else if (getRelation().isNew()) {
130 setTitle(tr("Edit new relation in layer ''{0}''", layer.getName()));
131 } else {
132 setTitle(tr("Edit relation #{0} in layer ''{1}''", relation.getId(), layer.getName()));
133 }
134 }
135
136 @Override
137 public final Relation getRelation() {
138 return relation;
139 }
140
141 @Override
142 public final void setRelation(Relation relation) {
143 setRelationSnapshot((relation == null) ? null : new Relation(relation));
144 Relation oldValue = this.relation;
145 this.relation = relation;
146 if (this.relation != oldValue) {
147 support.firePropertyChange(RELATION_PROP, oldValue, this.relation);
148 }
149 updateTitle();
150 }
151
152 @Override
153 public final OsmDataLayer getLayer() {
154 return layer;
155 }
156
157 @Override
158 public final Relation getRelationSnapshot() {
159 return relationSnapshot;
160 }
161
162 protected final void setRelationSnapshot(Relation snapshot) {
163 Relation oldValue = relationSnapshot;
164 relationSnapshot = snapshot;
165 if (relationSnapshot != oldValue) {
166 support.firePropertyChange(RELATION_SNAPSHOT_PROP, oldValue, relationSnapshot);
167 }
168 }
169
170 @Override
171 public final boolean isDirtyRelation() {
172 return !relation.hasEqualSemanticAttributes(relationSnapshot);
173 }
174
175 /* ----------------------------------------------------------------------- */
176 /* property change support */
177 /* ----------------------------------------------------------------------- */
178
179 @Override
180 public final void addPropertyChangeListener(PropertyChangeListener listener) {
181 this.support.addPropertyChangeListener(listener);
182 }
183
184 @Override
185 public final void removePropertyChangeListener(PropertyChangeListener listener) {
186 this.support.removePropertyChangeListener(listener);
187 }
188
189 @Override
190 public void dispose() {
191 layer.setRecentRelation(relation);
192 super.dispose();
193 }
194}
Note: See TracBrowser for help on using the repository browser.