source: josm/trunk/src/org/openstreetmap/josm/actions/CombineWayAction.java@ 321

Last change on this file since 321 was 301, checked in by imi, 17 years ago
  • fixed undo/redo to be global
  • fixed adding of objects work with undo/redo (#212)
File size: 3.8 KB
Line 
1// License: GPL. Copyright 2007 by Immanuel Scholz and others
2package org.openstreetmap.josm.actions;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.awt.GridBagLayout;
7import java.awt.event.ActionEvent;
8import java.awt.event.KeyEvent;
9import java.util.Collection;
10import java.util.HashMap;
11import java.util.LinkedList;
12import java.util.Map;
13import java.util.Set;
14import java.util.TreeMap;
15import java.util.TreeSet;
16import java.util.Map.Entry;
17
18import javax.swing.Box;
19import javax.swing.JComboBox;
20import javax.swing.JLabel;
21import javax.swing.JOptionPane;
22import javax.swing.JPanel;
23
24import org.openstreetmap.josm.Main;
25import org.openstreetmap.josm.command.ChangeCommand;
26import org.openstreetmap.josm.command.Command;
27import org.openstreetmap.josm.command.DeleteCommand;
28import org.openstreetmap.josm.command.SequenceCommand;
29import org.openstreetmap.josm.data.SelectionChangedListener;
30import org.openstreetmap.josm.data.osm.DataSet;
31import org.openstreetmap.josm.data.osm.OsmPrimitive;
32import org.openstreetmap.josm.data.osm.Way;
33import org.openstreetmap.josm.tools.GBC;
34
35/**
36 * Combines multiple ways into one.
37 *
38 * @author Imi
39 */
40public class CombineWayAction extends JosmAction implements SelectionChangedListener {
41
42 public CombineWayAction() {
43 super(tr("Combine Way"), "combineway", tr("Combine several ways into one."), KeyEvent.VK_C, KeyEvent.CTRL_MASK | KeyEvent.SHIFT_MASK, true);
44 DataSet.listeners.add(this);
45 }
46
47 public void actionPerformed(ActionEvent event) {
48 Collection<OsmPrimitive> selection = Main.ds.getSelected();
49 LinkedList<Way> selectedWays = new LinkedList<Way>();
50
51 for (OsmPrimitive osm : selection)
52 if (osm instanceof Way)
53 selectedWays.add((Way)osm);
54
55 if (selectedWays.size() < 2) {
56 JOptionPane.showMessageDialog(Main.parent, tr("Please select at least two ways to combine."));
57 return;
58 }
59
60 // collect properties for later conflict resolving
61 Map<String, Set<String>> props = new TreeMap<String, Set<String>>();
62 for (Way w : selectedWays) {
63 for (Entry<String,String> e : w.entrySet()) {
64 if (!props.containsKey(e.getKey()))
65 props.put(e.getKey(), new TreeSet<String>());
66 props.get(e.getKey()).add(e.getValue());
67 }
68 }
69
70 Way oldWay = selectedWays.poll();
71 Way newWay = new Way(oldWay);
72 LinkedList<Command> cmds = new LinkedList<Command>();
73
74 for (Way w : selectedWays)
75 newWay.segments.addAll(w.segments);
76
77 // display conflict dialog
78 Map<String, JComboBox> components = new HashMap<String, JComboBox>();
79 JPanel p = new JPanel(new GridBagLayout());
80 for (Entry<String, Set<String>> e : props.entrySet()) {
81 if (e.getValue().size() > 1) {
82 JComboBox c = new JComboBox(e.getValue().toArray());
83 c.setEditable(true);
84 p.add(new JLabel(e.getKey()), GBC.std());
85 p.add(Box.createHorizontalStrut(10), GBC.std());
86 p.add(c, GBC.eol());
87 components.put(e.getKey(), c);
88 } else
89 newWay.put(e.getKey(), e.getValue().iterator().next());
90 }
91 if (!components.isEmpty()) {
92 int answer = JOptionPane.showConfirmDialog(Main.parent, p, tr("Enter values for all conflicts."), JOptionPane.OK_CANCEL_OPTION);
93 if (answer != JOptionPane.OK_OPTION)
94 return;
95 for (Entry<String, JComboBox> e : components.entrySet())
96 newWay.put(e.getKey(), e.getValue().getEditor().getItem().toString());
97 }
98
99 cmds.add(new DeleteCommand(selectedWays));
100 cmds.add(new ChangeCommand(oldWay, newWay));
101 Main.main.undoRedo.add(new SequenceCommand(tr("Combine {0} ways", selectedWays.size()), cmds));
102 Main.ds.setSelected(oldWay);
103 }
104
105 /**
106 * Enable the "Combine way" menu option if more then one way is selected
107 */
108 public void selectionChanged(Collection<? extends OsmPrimitive> newSelection) {
109 boolean first = false;
110 for (OsmPrimitive osm : newSelection) {
111 if (osm instanceof Way) {
112 if (first) {
113 setEnabled(true);
114 return;
115 }
116 first = true;
117 }
118 }
119 setEnabled(false);
120 }
121}
Note: See TracBrowser for help on using the repository browser.