source: josm/trunk/src/org/openstreetmap/josm/actions/corrector/TagCorrector.java@ 17597

Last change on this file since 17597 was 17597, checked in by simon04, 3 years ago

fix #20048 - Make dialog "Automatic tag correction" resizeable

  • Property svn:eol-style set to native
File size: 9.0 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.actions.corrector;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.awt.GridBagLayout;
7import java.util.ArrayList;
8import java.util.Collection;
9import java.util.Collections;
10import java.util.HashMap;
11import java.util.HashSet;
12import java.util.List;
13import java.util.Map;
14import java.util.Map.Entry;
15import java.util.Set;
16
17import javax.swing.JLabel;
18import javax.swing.JOptionPane;
19import javax.swing.JPanel;
20import javax.swing.JScrollPane;
21
22import org.openstreetmap.josm.command.ChangePropertyCommand;
23import org.openstreetmap.josm.command.ChangeRelationMemberRoleCommand;
24import org.openstreetmap.josm.command.Command;
25import org.openstreetmap.josm.data.correction.RoleCorrection;
26import org.openstreetmap.josm.data.correction.TagCorrection;
27import org.openstreetmap.josm.data.osm.DataSet;
28import org.openstreetmap.josm.data.osm.DefaultNameFormatter;
29import org.openstreetmap.josm.data.osm.OsmPrimitive;
30import org.openstreetmap.josm.gui.ExtendedDialog;
31import org.openstreetmap.josm.gui.MainApplication;
32import org.openstreetmap.josm.gui.correction.RoleCorrectionTable;
33import org.openstreetmap.josm.gui.correction.TagCorrectionTable;
34import org.openstreetmap.josm.gui.widgets.JMultilineLabel;
35import org.openstreetmap.josm.tools.GBC;
36import org.openstreetmap.josm.tools.ImageProvider;
37import org.openstreetmap.josm.tools.UserCancelException;
38import org.openstreetmap.josm.tools.Utils;
39
40/**
41 * Abstract base class for automatic tag corrections.
42 *
43 * Subclasses call applyCorrections() with maps of the requested
44 * corrections and a dialog is presented to the user to
45 * confirm these changes.
46 * @param <P> The type of OSM primitive to correct
47 */
48public abstract class TagCorrector<P extends OsmPrimitive> {
49
50 /**
51 * Executes the tag correction.
52 * @param oldprimitive old primitive
53 * @param primitive new primitive
54 * @return A list of commands
55 * @throws UserCancelException If the user canceled
56 * @see #applyCorrections(DataSet, Map, Map, String)
57 */
58 public abstract Collection<Command> execute(P oldprimitive, P primitive) throws UserCancelException;
59
60 private static final String[] APPLICATION_OPTIONS = {
61 tr("Apply selected changes"),
62 tr("Do not apply changes"),
63 tr("Cancel")
64 };
65
66 /**
67 * Creates the commands to correct the tags. Asks the users about it.
68 * @param dataSet The data set the primitives will be in once the commands are executed
69 * @param tagCorrectionsMap The possible tag corrections
70 * @param roleCorrectionMap The possible role corrections
71 * @param description A description to add to the dialog.
72 * @return A list of commands
73 * @throws UserCancelException If the user canceled
74 */
75 protected Collection<Command> applyCorrections(
76 DataSet dataSet,
77 Map<OsmPrimitive, List<TagCorrection>> tagCorrectionsMap,
78 Map<OsmPrimitive, List<RoleCorrection>> roleCorrectionMap,
79 String description) throws UserCancelException {
80
81 if (!tagCorrectionsMap.isEmpty() || !roleCorrectionMap.isEmpty()) {
82 Collection<Command> commands = new ArrayList<>();
83 Map<OsmPrimitive, TagCorrectionTable> tagTableMap = new HashMap<>();
84 Map<OsmPrimitive, RoleCorrectionTable> roleTableMap = new HashMap<>();
85
86 final JPanel p = new JPanel(new GridBagLayout());
87
88 final JMultilineLabel label1 = new JMultilineLabel(description);
89 label1.setMaxWidth(600);
90 p.add(label1, GBC.eop().anchor(GBC.CENTER).fill(GBC.HORIZONTAL));
91
92 final JMultilineLabel label2 = new JMultilineLabel(
93 tr("Please select which changes you want to apply."));
94 label2.setMaxWidth(600);
95 p.add(label2, GBC.eop().anchor(GBC.CENTER).fill(GBC.HORIZONTAL));
96
97 for (Entry<OsmPrimitive, List<TagCorrection>> entry : tagCorrectionsMap.entrySet()) {
98 final OsmPrimitive primitive = entry.getKey();
99 final List<TagCorrection> tagCorrections = entry.getValue();
100
101 if (tagCorrections.isEmpty()) {
102 continue;
103 }
104
105 final JLabel propertiesLabel = new JLabel(tr("Tags of "));
106 p.add(propertiesLabel, GBC.std());
107
108 final JLabel primitiveLabel = new JLabel(
109 primitive.getDisplayName(DefaultNameFormatter.getInstance()) + ':',
110 ImageProvider.get(primitive.getDisplayType()),
111 JLabel.LEFT
112 );
113 p.add(primitiveLabel, GBC.eol());
114
115 final TagCorrectionTable table = new TagCorrectionTable(
116 tagCorrections);
117 final JScrollPane scrollPane = new JScrollPane(table);
118 p.add(scrollPane, GBC.eop().fill(GBC.BOTH));
119
120 tagTableMap.put(primitive, table);
121 }
122
123 for (Entry<OsmPrimitive, List<RoleCorrection>> entry : roleCorrectionMap.entrySet()) {
124 final OsmPrimitive primitive = entry.getKey();
125 final List<RoleCorrection> roleCorrections = entry.getValue();
126
127 if (roleCorrections.isEmpty()) {
128 continue;
129 }
130
131 final JLabel rolesLabel = new JLabel(tr("Roles in relations referring to"));
132 p.add(rolesLabel, GBC.std());
133
134 final JLabel primitiveLabel = new JLabel(
135 primitive.getDisplayName(DefaultNameFormatter.getInstance()),
136 ImageProvider.get(primitive.getDisplayType()),
137 JLabel.LEFT
138 );
139 p.add(primitiveLabel, GBC.eol());
140 rolesLabel.setLabelFor(primitiveLabel);
141
142 final RoleCorrectionTable table = new RoleCorrectionTable(roleCorrections);
143 final JScrollPane scrollPane = new JScrollPane(table);
144 p.add(scrollPane, GBC.eop().fill(GBC.BOTH));
145 primitiveLabel.setLabelFor(table);
146
147 roleTableMap.put(primitive, table);
148 }
149
150 ExtendedDialog dialog = new ExtendedDialog(
151 MainApplication.getMainFrame(),
152 tr("Automatic tag correction"),
153 APPLICATION_OPTIONS
154 );
155 dialog.setContent(p, false);
156 dialog.setButtonIcons("dialogs/edit", "dialogs/next", "cancel");
157 dialog.showDialog();
158 int answer = dialog.getValue();
159
160 if (answer == JOptionPane.YES_OPTION) {
161 for (Entry<OsmPrimitive, List<TagCorrection>> entry : tagCorrectionsMap.entrySet()) {
162 OsmPrimitive primitive = entry.getKey();
163
164 // use this structure to remember keys that have been set already so that
165 // they're not dropped by a later step
166 Set<String> keysChanged = new HashSet<>();
167
168 // the map for the change command
169 Map<String, String> tagMap = new HashMap<>();
170
171 List<TagCorrection> tagCorrections = entry.getValue();
172 for (int i = 0; i < tagCorrections.size(); i++) {
173 if (tagTableMap.get(primitive).getCorrectionTableModel().getApply(i)) {
174 TagCorrection tagCorrection = tagCorrections.get(i);
175 if (tagCorrection.isKeyChanged() && !keysChanged.contains(tagCorrection.oldKey)) {
176 tagMap.put(tagCorrection.oldKey, null);
177 }
178 tagMap.put(tagCorrection.newKey, tagCorrection.newValue);
179 keysChanged.add(tagCorrection.newKey);
180 }
181 }
182
183 if (!keysChanged.isEmpty()) {
184 // change the properties of this object
185 commands.add(new ChangePropertyCommand(dataSet, Collections.singleton(primitive),
186 Utils.toUnmodifiableMap(tagMap)));
187 }
188 }
189 for (Entry<OsmPrimitive, List<RoleCorrection>> entry : roleCorrectionMap.entrySet()) {
190 OsmPrimitive primitive = entry.getKey();
191 List<RoleCorrection> roleCorrections = entry.getValue();
192
193 for (int i = 0; i < roleCorrections.size(); i++) {
194 RoleCorrection roleCorrection = roleCorrections.get(i);
195 if (roleTableMap.get(primitive).getCorrectionTableModel().getApply(i)) {
196 commands.add(new ChangeRelationMemberRoleCommand(dataSet,
197 roleCorrection.relation, roleCorrection.position, roleCorrection.newRole));
198 }
199 }
200 }
201 } else if (answer != JOptionPane.NO_OPTION)
202 throw new UserCancelException();
203 return Collections.unmodifiableCollection(commands);
204 }
205
206 return Collections.emptyList();
207 }
208}
Note: See TracBrowser for help on using the repository browser.