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

Last change on this file since 1820 was 1820, checked in by Gubaer, 15 years ago

JosmAction is now a LayerChangeListener and a SelectionChangeListener
updated all JosmActions
fixed #3018: Make sure tools menu entries (and actions) are deactivated when no layer

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