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

Last change on this file since 729 was 655, checked in by ramack, 16 years ago

patch by bruce89, closes #812; thanks bruce

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