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

Last change on this file since 1728 was 1613, checked in by stoecker, 15 years ago

fixed #2172 - Teemu Koskinen - ReverseWayTagCorrector's role correction broken

  • Property svn:eol-style set to native
File size: 5.6 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.DataSource;
22import org.openstreetmap.josm.data.osm.OsmPrimitive;
23import org.openstreetmap.josm.tools.Shortcut;
24
25public final class PasteTagsAction extends JosmAction implements SelectionChangedListener {
26
27 public PasteTagsAction(JosmAction copyAction) {
28 super(tr("Paste Tags"), "pastetags",
29 tr("Apply tags of contents of paste buffer to all selected items."),
30 Shortcut.registerShortcut("system:pastestyle", tr("Edit: {0}", tr("Paste Tags")), KeyEvent.VK_V, Shortcut.GROUP_MENU, Shortcut.SHIFT_DEFAULT), true);
31 DataSet.selListeners.add(this);
32 copyAction.addListener(this);
33 setEnabled(false);
34 }
35
36 private void pasteKeys(Collection<Command> clist, Collection<? extends OsmPrimitive> pasteBufferSubset, Collection<OsmPrimitive> selectionSubset) {
37 /* scan the paste buffer, and add tags to each of the selected objects.
38 * If a tag already exists, it is overwritten */
39 if (selectionSubset == null || selectionSubset.isEmpty())
40 return;
41
42 for (Iterator<? extends OsmPrimitive> it = pasteBufferSubset.iterator(); it.hasNext();) {
43 OsmPrimitive osm = it.next();
44 Map<String, String> m = osm.keys;
45 if(m == null)
46 continue;
47
48 for (String key : m.keySet()) {
49 clist.add(new ChangePropertyCommand(selectionSubset, key, osm.keys.get(key)));
50 }
51 }
52 }
53
54 public void actionPerformed(ActionEvent e) {
55 Collection<Command> clist = new LinkedList<Command>();
56 String pbSource = "Multiple Sources";
57 if(Main.pasteBuffer.dataSources.size() == 1)
58 pbSource = ((DataSource) Main.pasteBuffer.dataSources.toArray()[0]).origin;
59
60 boolean pbNodes = Main.pasteBuffer.nodes.size() > 0;
61 boolean pbWays = Main.pasteBuffer.ways.size() > 0;
62
63 boolean seNodes = Main.ds.getSelectedNodes().size() > 0;
64 boolean seWays = Main.ds.getSelectedWays().size() > 0;
65 boolean seRels = Main.ds.getSelectedRelations().size() > 0;
66
67 if(!seNodes && seWays && !seRels && pbNodes && pbSource.equals("Copied Nodes")) {
68 // Copy from nodes to ways
69 pasteKeys(clist, Main.pasteBuffer.nodes, Main.ds.getSelectedWays());
70 } else if(seNodes && !seWays && !seRels && pbWays && pbSource.equals("Copied Ways")) {
71 // Copy from ways to nodes
72 pasteKeys(clist, Main.pasteBuffer.ways, Main.ds.getSelectedNodes());
73 } else {
74 // Copy from equal to equal
75 pasteKeys(clist, Main.pasteBuffer.nodes, Main.ds.getSelectedNodes());
76 pasteKeys(clist, Main.pasteBuffer.ways, Main.ds.getSelectedWays());
77 pasteKeys(clist, Main.pasteBuffer.relations, Main.ds.getSelectedRelations());
78 }
79 Main.main.undoRedo.add(new SequenceCommand(tr("Paste Tags"), clist));
80 Main.ds.setSelected(Main.ds.getSelected()); // to force selection listeners, in particular the tag panel, to update
81 Main.map.mapView.repaint();
82 }
83
84 private boolean containsSameKeysWithDifferentValues(Collection<? extends OsmPrimitive> osms) {
85 Map<String,String> kvSeen = new HashMap<String,String>();
86 for (Iterator<? extends OsmPrimitive> it = osms.iterator(); it.hasNext();) {
87 OsmPrimitive osm = it.next();
88 if (osm.keys == null || osm.keys.isEmpty())
89 continue;
90 for (String key : osm.keys.keySet()) {
91 String value = osm.keys.get(key);
92 if (! kvSeen.containsKey(key))
93 kvSeen.put(key, value);
94 else if (! kvSeen.get(key).equals(value))
95 return true;
96 }
97 }
98 return false;
99 }
100
101 /**
102 * Determines whether to enable the widget depending on the contents of the paste
103 * buffer and current selection
104 * @param pasteBuffer
105 */
106 private void possiblyEnable(Collection<? extends OsmPrimitive> selection, DataSet pasteBuffer) {
107 /* only enable if there is something selected to paste into and
108 if we don't have conflicting keys in the pastebuffer */
109 setEnabled(selection != null &&
110 ! selection.isEmpty() &&
111 ! pasteBuffer.allPrimitives().isEmpty() &&
112 (Main.ds.getSelectedNodes().isEmpty() ||
113 ! containsSameKeysWithDifferentValues(pasteBuffer.nodes)) &&
114 (Main.ds.getSelectedWays().isEmpty() ||
115 ! containsSameKeysWithDifferentValues(pasteBuffer.ways)) &&
116 (Main.ds.getSelectedRelations().isEmpty() ||
117 ! containsSameKeysWithDifferentValues(pasteBuffer.relations)));
118 }
119
120 @Override public void pasteBufferChanged(DataSet newPasteBuffer) {
121 possiblyEnable(Main.ds.getSelected(), newPasteBuffer);
122 }
123
124 public void selectionChanged(Collection<? extends OsmPrimitive> newSelection) {
125 possiblyEnable(newSelection, Main.pasteBuffer);
126 }
127}
Note: See TracBrowser for help on using the repository browser.