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

Last change on this file since 6340 was 6340, checked in by Don-vip, 5 years ago

refactor of some GUI/widgets classes (impacts some plugins):

  • gui.BookmarkList moves to gui.download as it is only meant to be used by gui.download.BookmarkSelection
  • tools.UrlLabel moves to gui.widgets
  • gui.JMultilineLabel, gui.MultiplitLayout, gui.MultiSplitPane move to gui.widgets
  • Property svn:eol-style set to native
File size: 8.1 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.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.Set;
15import java.util.Map.Entry;
16
17import javax.swing.JLabel;
18import javax.swing.JOptionPane;
19import javax.swing.JPanel;
20import javax.swing.JScrollPane;
21
22import org.openstreetmap.josm.Main;
23import org.openstreetmap.josm.command.ChangeCommand;
24import org.openstreetmap.josm.command.ChangeRelationMemberRoleCommand;
25import org.openstreetmap.josm.command.Command;
26import org.openstreetmap.josm.data.osm.Node;
27import org.openstreetmap.josm.data.osm.OsmPrimitive;
28import org.openstreetmap.josm.data.osm.Relation;
29import org.openstreetmap.josm.data.osm.Way;
30import org.openstreetmap.josm.gui.DefaultNameFormatter;
31import org.openstreetmap.josm.gui.widgets.JMultilineLabel;
32import org.openstreetmap.josm.tools.GBC;
33import org.openstreetmap.josm.tools.ImageProvider;
34
35/**
36 * Abstract base class for automatic tag corrections.
37 *
38 * Subclasses call applyCorrections() with maps of the requested
39 * corrections and a dialog is pesented to the user to
40 * confirm these changes.
41 */
42
43public abstract class TagCorrector<P extends OsmPrimitive> {
44
45    public abstract Collection<Command> execute(P primitive, P oldprimitive)
46    throws UserCancelException;
47
48    private String[] applicationOptions = new String[] {
49            tr("Apply selected changes"),
50            tr("Do not apply changes"),
51            tr("Cancel")
52    };
53
54    protected Collection<Command> applyCorrections(
55            Map<OsmPrimitive, List<TagCorrection>> tagCorrectionsMap,
56            Map<OsmPrimitive, List<RoleCorrection>> roleCorrectionMap,
57            String description) throws UserCancelException {
58
59        if (!tagCorrectionsMap.isEmpty() || !roleCorrectionMap.isEmpty()) {
60            Collection<Command> commands = new ArrayList<Command>();
61            Map<OsmPrimitive, TagCorrectionTable> tagTableMap =
62                new HashMap<OsmPrimitive, TagCorrectionTable>();
63            Map<OsmPrimitive, RoleCorrectionTable> roleTableMap =
64                new HashMap<OsmPrimitive, RoleCorrectionTable>();
65
66            final JPanel p = new JPanel(new GridBagLayout());
67
68            final JMultilineLabel label1 = new JMultilineLabel(description);
69            label1.setMaxWidth(600);
70            p.add(label1, GBC.eop().anchor(GBC.CENTER));
71
72            final JMultilineLabel label2 = new JMultilineLabel(
73                    tr("Please select which changes you want to apply."));
74            label2.setMaxWidth(600);
75            p.add(label2, GBC.eop().anchor(GBC.CENTER));
76
77            for (Entry<OsmPrimitive, List<TagCorrection>> entry : tagCorrectionsMap.entrySet()) {
78                final OsmPrimitive primitive = entry.getKey();
79                final List<TagCorrection> tagCorrections = entry.getValue();
80
81                if (tagCorrections.isEmpty()) {
82                    continue;
83                }
84
85                final JLabel propertiesLabel = new JLabel(tr("Tags of "));
86                p.add(propertiesLabel, GBC.std());
87
88                final JLabel primitiveLabel = new JLabel(
89                        primitive.getDisplayName(DefaultNameFormatter.getInstance()) + ":",
90                        ImageProvider.get(primitive.getDisplayType()),
91                        JLabel.LEFT
92                );
93                p.add(primitiveLabel, GBC.eol());
94
95                final TagCorrectionTable table = new TagCorrectionTable(
96                        tagCorrections);
97                final JScrollPane scrollPane = new JScrollPane(table);
98                p.add(scrollPane, GBC.eop().fill(GBC.HORIZONTAL));
99
100                tagTableMap.put(primitive, table);
101            }
102
103            for (Entry<OsmPrimitive, List<RoleCorrection>> entry : roleCorrectionMap.entrySet()) {
104                final OsmPrimitive primitive = entry.getKey();
105                final List<RoleCorrection> roleCorrections = entry.getValue();
106
107                if (roleCorrections.isEmpty()) {
108                    continue;
109                }
110
111                final JLabel rolesLabel = new JLabel(
112                        tr("Roles in relations referring to"));
113                p.add(rolesLabel, GBC.std());
114
115                final JLabel primitiveLabel = new JLabel(
116                        primitive.getDisplayName(DefaultNameFormatter.getInstance()),
117                        ImageProvider.get(primitive.getDisplayType()),
118                        JLabel.LEFT
119                );
120                p.add(primitiveLabel, GBC.eol());
121
122                final RoleCorrectionTable table = new RoleCorrectionTable(
123                        roleCorrections);
124                final JScrollPane scrollPane = new JScrollPane(table);
125                p.add(scrollPane, GBC.eop().fill(GBC.HORIZONTAL));
126
127                roleTableMap.put(primitive, table);
128            }
129
130            int answer = JOptionPane.showOptionDialog(
131                    Main.parent,
132                    p,
133                    tr("Automatic tag correction"),
134                    JOptionPane.YES_NO_CANCEL_OPTION,
135                    JOptionPane.PLAIN_MESSAGE,
136                    null,
137                    applicationOptions,
138                    applicationOptions[0]
139            );
140
141            if (answer == JOptionPane.YES_OPTION) {
142                for (Entry<OsmPrimitive, List<TagCorrection>> entry : tagCorrectionsMap.entrySet()) {
143                    List<TagCorrection> tagCorrections = entry.getValue();
144                    OsmPrimitive primitive = entry.getKey();
145
146                    // create the clone
147                    OsmPrimitive clone = null;
148                    if (primitive instanceof Way) {
149                        clone = new Way((Way)primitive);
150                    } else if (primitive instanceof Node) {
151                        clone = new Node((Node)primitive);
152                    } else if (primitive instanceof Relation) {
153                        clone = new Relation((Relation)primitive);
154                    } else
155                        throw new AssertionError();
156
157                    // use this structure to remember keys that have been set already so that
158                    // they're not dropped by a later step
159                    Set<String> keysChanged = new HashSet<String>();
160
161                    // apply all changes to this clone
162                    for (int i = 0; i < tagCorrections.size(); i++) {
163                        if (tagTableMap.get(primitive).getCorrectionTableModel().getApply(i)) {
164                            TagCorrection tagCorrection = tagCorrections.get(i);
165                            if (tagCorrection.isKeyChanged() && !keysChanged.contains(tagCorrection.oldKey)) {
166                                clone.remove(tagCorrection.oldKey);
167                            }
168                            clone.put(tagCorrection.newKey, tagCorrection.newValue);
169                            keysChanged.add(tagCorrection.newKey);
170                        }
171                    }
172
173                    // save the clone
174                    if (!keysChanged.isEmpty()) {
175                        commands.add(new ChangeCommand(primitive, clone));
176                    }
177                }
178                for (Entry<OsmPrimitive, List<RoleCorrection>> entry : roleCorrectionMap.entrySet()) {
179                    OsmPrimitive primitive = entry.getKey();
180                    List<RoleCorrection> roleCorrections = entry.getValue();
181
182                    for (int i = 0; i < roleCorrections.size(); i++) {
183                        RoleCorrection roleCorrection = roleCorrections.get(i);
184                        if (roleTableMap.get(primitive).getCorrectionTableModel().getApply(i)) {
185                            commands.add(new ChangeRelationMemberRoleCommand(roleCorrection.relation, roleCorrection.position, roleCorrection.newRole));
186                        }
187                    }
188                }
189            } else if (answer != JOptionPane.NO_OPTION)
190                throw new UserCancelException();
191            return commands;
192        }
193
194        return Collections.emptyList();
195    }
196}
Note: See TracBrowser for help on using the repository browser.