source: josm/trunk/src/org/openstreetmap/josm/actions/PasteTagsAction.java@ 558

Last change on this file since 558 was 558, checked in by david, 16 years ago

implement Paste Tags

File size: 4.3 KB
Line 
1// License: GPL. Copyright 2007 by Immanuel Scholz and others
2// Author: David Earl
3package org.openstreetmap.josm.actions;
4
5import static org.openstreetmap.josm.tools.I18n.tr;
6
7import java.awt.event.ActionEvent;
8import java.awt.event.KeyEvent;
9import java.util.Collection;
10import java.util.LinkedList;
11import java.util.Iterator;
12import java.util.HashMap;
13import java.util.Map;
14import java.util.Map.Entry;
15
16import org.openstreetmap.josm.Main;
17import org.openstreetmap.josm.command.ChangePropertyCommand;
18import org.openstreetmap.josm.command.Command;
19import org.openstreetmap.josm.command.SequenceCommand;
20import org.openstreetmap.josm.data.SelectionChangedListener;
21import org.openstreetmap.josm.data.SelectionChangedListener;
22import org.openstreetmap.josm.data.osm.DataSet;
23import org.openstreetmap.josm.data.osm.Node;
24import org.openstreetmap.josm.data.osm.Way;
25import org.openstreetmap.josm.data.osm.Relation;
26import org.openstreetmap.josm.data.osm.OsmPrimitive;
27
28public final class PasteTagsAction extends JosmAction implements SelectionChangedListener {
29
30 public PasteTagsAction(JosmAction copyAction) {
31 super(tr("Paste Tags"), "pastetags",
32 tr("Apply tags of contents of paste buffer to all selected items."),
33 KeyEvent.VK_V, KeyEvent.CTRL_MASK | KeyEvent.SHIFT_MASK, true);
34 DataSet.selListeners.add(this);
35 copyAction.addListener(this);
36 setEnabled(false);
37 }
38
39 private void pasteKeys(Collection<Command> clist, Collection<? extends OsmPrimitive> pasteBufferSubset, Collection<OsmPrimitive> selectionSubset) {
40 /* scan the paste buffer, and add tags to each of the selected objects.
41 * If a tag already exists, it is overwritten */
42 if (! selectionSubset.isEmpty()) {
43 for (Iterator<? extends OsmPrimitive> it = pasteBufferSubset.iterator(); it.hasNext();) {
44 OsmPrimitive osm = it.next();
45 for (String key : osm.keys.keySet()) {
46 if (! key.equals("created_by"))
47 clist.add(new ChangePropertyCommand(selectionSubset, key, osm.keys.get(key)));
48 }
49 }
50 }
51 }
52
53 public void actionPerformed(ActionEvent e) {
54 Collection<Command> clist = new LinkedList<Command>();
55 pasteKeys(clist, Main.pasteBuffer.nodes, Main.ds.getSelectedNodes());
56 pasteKeys(clist, Main.pasteBuffer.ways, Main.ds.getSelectedWays());
57 pasteKeys(clist, Main.pasteBuffer.relations, Main.ds.getSelectedRelations());
58 Main.main.undoRedo.add(new SequenceCommand(tr("Paste Tags"), clist));
59 Main.ds.setSelected(Main.ds.getSelected()); // to force selection listeners, in particular the tag panel, to update
60 Main.map.mapView.repaint();
61 }
62
63 private boolean containsSameKeysWithDifferentValues(Collection<? extends OsmPrimitive> osms) {
64 Map<String,String> kvSeen = new HashMap<String,String>();
65 for (Iterator<? extends OsmPrimitive> it = osms.iterator(); it.hasNext();) {
66 OsmPrimitive osm = it.next();
67 if (osm.keys.isEmpty())
68 continue;
69 for (String key : osm.keys.keySet()) {
70 if (key.equals("created_by")) // we ignore created_by
71 continue;
72 String value = osm.keys.get(key);
73 if (! kvSeen.containsKey(key))
74 kvSeen.put(key, value);
75 else if (! kvSeen.get(key).equals(value))
76 return true;
77 }
78 }
79 return false;
80 }
81
82 /**
83 * determines whether to enable the widget depending on the contents of the paste
84 * buffer and current selection
85 * @param pasteBuffer
86 */
87 private void possiblyEnable(Collection<? extends OsmPrimitive> selection, DataSet pasteBuffer) {
88 /* only enable if there is something selected to paste into and
89 if we don't have conflicting keys in the pastebuffer */
90 setEnabled(! selection.isEmpty() &&
91 ! pasteBuffer.allPrimitives().isEmpty() &&
92 (Main.ds.getSelectedNodes().isEmpty() ||
93 ! containsSameKeysWithDifferentValues(pasteBuffer.nodes)) &&
94 (Main.ds.getSelectedWays().isEmpty() ||
95 ! containsSameKeysWithDifferentValues(pasteBuffer.ways)) &&
96 (Main.ds.getSelectedRelations().isEmpty() ||
97 ! containsSameKeysWithDifferentValues(pasteBuffer.relations)));
98 }
99
100 @Override public void pasteBufferChanged(DataSet newPasteBuffer) {
101 possiblyEnable(Main.ds.getSelected(), newPasteBuffer);
102 }
103
104 public void selectionChanged(Collection<? extends OsmPrimitive> newSelection) {
105 possiblyEnable(newSelection, Main.pasteBuffer);
106 }
107}
Note: See TracBrowser for help on using the repository browser.