Ticket #5843: remotecontrol_addtags.patch
| File remotecontrol_addtags.patch, 19.5 KB (added by , 15 years ago) |
|---|
-
src/org/openstreetmap/josm/io/remotecontrol/gui/AddTagsDialog.java
1 package org.openstreetmap.josm.io.remotecontrol.gui; 2 3 import static org.openstreetmap.josm.tools.I18n.tr; 4 5 import java.awt.Color; 6 import java.awt.Component; 7 import java.awt.Dimension; 8 import java.awt.Font; 9 import java.awt.GridBagLayout; 10 import java.awt.event.ActionEvent; 11 import java.util.Collection; 12 13 import javax.swing.JPanel; 14 import javax.swing.JTable; 15 import javax.swing.table.DefaultTableModel; 16 import javax.swing.table.TableCellRenderer; 17 import javax.swing.table.TableModel; 18 19 import org.openstreetmap.josm.Main; 20 import org.openstreetmap.josm.command.ChangePropertyCommand; 21 import org.openstreetmap.josm.data.SelectionChangedListener; 22 import org.openstreetmap.josm.data.osm.DataSet; 23 import org.openstreetmap.josm.data.osm.OsmPrimitive; 24 import org.openstreetmap.josm.gui.ExtendedDialog; 25 import org.openstreetmap.josm.tools.GBC; 26 27 /** 28 * 29 * @author master 30 * 31 * Dialog to add tags as part of the remotecontrol 32 * Existing Keys get grey color and unchecked selectboxes so they will not overwrite the old Key-Value-Pairs by default. 33 * You can choose the tags you want to add by selectboxes. You can edit the tags before you apply them. 34 * 35 */ 36 37 public class AddTagsDialog extends ExtendedDialog implements SelectionChangedListener { 38 39 40 private final JTable propertyTable; 41 private Collection<? extends OsmPrimitive> sel; 42 boolean[] existing; 43 44 public AddTagsDialog(String[][] tags) { 45 super(Main.parent, tr("Add tags to selected objects"), new String[] { tr("Add tags"), tr("Cancel")}, 46 false, 47 true); 48 49 DataSet.addSelectionListener(this); 50 51 52 DefaultTableModel tm = new DefaultTableModel(new String[] {tr("Assume"), tr("Key"), tr("Value")}, tags.length) { 53 @Override 54 public Class getColumnClass(int c) { 55 return getValueAt(0, c).getClass(); 56 } 57 58 }; 59 60 sel = Main.main.getCurrentDataSet().getSelected(); 61 existing = new boolean[tags.length]; 62 63 for (int i = 0; i<tags.length; i++) { 64 existing[i] = false; 65 String key = tags[i][0]; 66 Boolean b = Boolean.TRUE; 67 for (OsmPrimitive osm : sel) { 68 if (osm.keySet().contains(key)) { 69 b = Boolean.FALSE; 70 existing[i]=true; 71 break; 72 } 73 } 74 tm.setValueAt(b, i, 0); 75 tm.setValueAt(tags[i][0], i, 1); 76 tm.setValueAt(tags[i][1], i, 2); 77 } 78 79 propertyTable = new JTable(tm) { 80 81 private static final long serialVersionUID = 1L; 82 83 @Override 84 public Component prepareRenderer(TableCellRenderer renderer, int row, int column) { 85 Component c = super.prepareRenderer(renderer, row, column); 86 if (existing[row]) { 87 c.setFont(c.getFont().deriveFont(Font.ITALIC)); 88 c.setForeground(new Color(100, 100, 100)); 89 } else { 90 c.setFont(c.getFont().deriveFont(Font.PLAIN)); 91 c.setForeground(new Color(0, 0, 0)); 92 } 93 return c; 94 } 95 }; 96 97 // a checkbox has a size of 15 px 98 propertyTable.getColumnModel().getColumn(0).setMaxWidth(15); 99 // get edit results if the table looses the focus, for example if a user clicks "add tags" 100 propertyTable.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE); 101 102 // set the content of this AddTagsDialog consisting of the tableHeader and the table itself. 103 JPanel tablePanel = new JPanel(); 104 tablePanel.setLayout(new GridBagLayout()); 105 tablePanel.add(propertyTable.getTableHeader(), GBC.eol().fill(GBC.HORIZONTAL)); 106 tablePanel.add(propertyTable, GBC.eol().fill(GBC.BOTH)); 107 setContent(tablePanel); 108 109 // set the default Dimensions and show the dialog 110 setPreferredSize(new Dimension(400,tablePanel.getPreferredSize().height+100)); 111 showDialog(); 112 } 113 /** 114 * This method looks for existing tags in the current selection and sets the corresponding boolean in the boolean array existing[] 115 */ 116 private void findExistingTags() { 117 TableModel tm = propertyTable.getModel(); 118 for (int i=0; i<tm.getRowCount(); i++) { 119 String key = (String)tm.getValueAt(i, 1); 120 existing[i] = false; 121 for (OsmPrimitive osm : sel) { 122 if (osm.keySet().contains(key)) { 123 existing[i] = true; 124 break; 125 } 126 } 127 } 128 propertyTable.repaint(); 129 } 130 131 /** 132 * If you click the "Add tags" button build a ChangePropertyCommand for every key that has a checked checkbox to apply the key value pair to all selected osm objects. 133 * You get a entry for every key in the command queue. 134 */ 135 @Override 136 protected void buttonAction(int buttonIndex, ActionEvent evt) { 137 if (buttonIndex == 0) { 138 TableModel tm = propertyTable.getModel(); 139 for (int i=0; i<tm.getRowCount(); i++) { 140 if ((Boolean)tm.getValueAt(i, 0)) { 141 Main.main.undoRedo.add(new ChangePropertyCommand(sel, (String)tm.getValueAt(i, 1), (String)tm.getValueAt(i, 2))); 142 } 143 } 144 } 145 setVisible(false); 146 } 147 148 @Override 149 public void selectionChanged(Collection<? extends OsmPrimitive> newSelection) { 150 sel = newSelection; 151 findExistingTags(); 152 } 153 154 } -
src/org/openstreetmap/josm/io/remotecontrol/handler/LoadAndZoomHandler.java
5 5 6 6 import java.awt.geom.Area; 7 7 import java.awt.geom.Rectangle2D; 8 import java.io.UnsupportedEncodingException; 9 import java.net.URLDecoder; 8 10 import java.util.HashSet; 9 11 import java.util.concurrent.Future; 10 12 … … 21 23 import org.openstreetmap.josm.data.osm.Relation; 22 24 import org.openstreetmap.josm.data.osm.Way; 23 25 import org.openstreetmap.josm.data.osm.visitor.BoundingXYVisitor; 26 import org.openstreetmap.josm.io.remotecontrol.gui.AddTagsDialog; 24 27 25 28 /** 26 29 * Handler for load_and_zoom request. 27 30 */ 28 31 public class LoadAndZoomHandler extends RequestHandler 29 32 { 30 public static final String command = "load_and_zoom";31 public static final String command2 = "zoom";33 public static final String command = "load_and_zoom"; 34 public static final String command2 = "zoom"; 32 35 33 public static final String loadDataPermissionKey = "remotecontrol.permission.load-data";34 public static final boolean loadDataPermissionDefault = true;35 public static final String changeSelectionPermissionKey = "remotecontrol.permission.change-selection";36 public static final boolean changeSelectionPermissionDefault = true;37 public static final String changeViewportPermissionKey = "remotecontrol.permission.change-viewport";38 public static final boolean changeViewportPermissionDefault = true;36 public static final String loadDataPermissionKey = "remotecontrol.permission.load-data"; 37 public static final boolean loadDataPermissionDefault = true; 38 public static final String changeSelectionPermissionKey = "remotecontrol.permission.change-selection"; 39 public static final boolean changeSelectionPermissionDefault = true; 40 public static final String changeViewportPermissionKey = "remotecontrol.permission.change-viewport"; 41 public static final boolean changeViewportPermissionDefault = true; 39 42 40 @Override41 public String getPermissionMessage()42 {43 return tr("Remote Control has been asked to load data from the API.") +44 "<br>" + tr("Request details: {0}", request);45 }43 @Override 44 public String getPermissionMessage() 45 { 46 return tr("Remote Control has been asked to load data from the API.") + 47 "<br>" + tr("Request details: {0}", request); 48 } 46 49 47 @Override48 protected String[] getMandatoryParams()49 {50 return new String[] { "bottom", "top", "left", "right" };51 }50 @Override 51 protected String[] getMandatoryParams() 52 { 53 return new String[] { "bottom", "top", "left", "right" }; 54 } 52 55 53 @Override54 protected void handleRequest() throws RequestHandlerErrorException55 {56 DownloadTask osmTask = new DownloadOsmTask();57 double minlat = 0;58 double maxlat = 0;59 double minlon = 0;60 double maxlon = 0;61 try {62 minlat = Double.parseDouble(args.get("bottom"));63 maxlat = Double.parseDouble(args.get("top"));64 minlon = Double.parseDouble(args.get("left"));65 maxlon = Double.parseDouble(args.get("right"));56 @Override 57 protected void handleRequest() throws RequestHandlerErrorException 58 { 59 DownloadTask osmTask = new DownloadOsmTask(); 60 double minlat = 0; 61 double maxlat = 0; 62 double minlon = 0; 63 double maxlon = 0; 64 try { 65 minlat = Double.parseDouble(args.get("bottom")); 66 maxlat = Double.parseDouble(args.get("top")); 67 minlon = Double.parseDouble(args.get("left")); 68 maxlon = Double.parseDouble(args.get("right")); 66 69 67 if(command.equals(myCommand))68 {69 if (!Main.pref.getBoolean(loadDataPermissionKey, loadDataPermissionDefault))70 {71 System.out.println("RemoteControl: download forbidden by preferences");72 }73 else74 {70 if(command.equals(myCommand)) 71 { 72 if (!Main.pref.getBoolean(loadDataPermissionKey, loadDataPermissionDefault)) 73 { 74 System.out.println("RemoteControl: download forbidden by preferences"); 75 } 76 else 77 { 75 78 76 // find out whether some data has already been downloaded 77 Area present = null; 78 Area toDownload = null; 79 DataSet ds = Main.main.getCurrentDataSet(); 80 if (ds != null) 81 present = ds.getDataSourceArea(); 82 if (present != null && !present.isEmpty()) { 83 toDownload = new Area(new Rectangle2D.Double(minlon,minlat,maxlon-minlon,maxlat-minlat)); 84 toDownload.subtract(present); 85 if (!toDownload.isEmpty()) 86 { 87 // the result might not be a rectangle (L shaped etc) 88 Rectangle2D downloadBounds = toDownload.getBounds2D(); 89 minlat = downloadBounds.getMinY(); 90 minlon = downloadBounds.getMinX(); 91 maxlat = downloadBounds.getMaxY(); 92 maxlon = downloadBounds.getMaxX(); 93 } 94 } 95 if((toDownload != null) && toDownload.isEmpty()) 96 { 97 System.out.println("RemoteControl: no download necessary"); 98 } 99 else 100 { 101 Future<?> future = osmTask.download(false /*no new layer*/, new Bounds(minlat,minlon,maxlat,maxlon), null /* let the task manage the progress monitor */); 102 Main.worker.submit(new PostDownloadHandler(osmTask, future)); 103 } 104 } 105 } 106 } catch (Exception ex) { 107 System.out.println("RemoteControl: Error parsing load_and_zoom remote control request:"); 108 ex.printStackTrace(); 109 throw new RequestHandlerErrorException(); 110 } 111 if (args.containsKey("select") && Main.pref.getBoolean(changeSelectionPermissionKey, changeSelectionPermissionDefault)) { 112 // select objects after downloading, zoom to selection. 113 final String selection = args.get("select"); 114 Main.worker.execute(new Runnable() { 115 public void run() { 116 HashSet<Long> ways = new HashSet<Long>(); 117 HashSet<Long> nodes = new HashSet<Long>(); 118 HashSet<Long> relations = new HashSet<Long>(); 119 HashSet<OsmPrimitive> newSel = new HashSet<OsmPrimitive>(); 120 for (String item : selection.split(",")) { 121 if (item.startsWith("way")) { 122 ways.add(Long.parseLong(item.substring(3))); 123 } else if (item.startsWith("node")) { 124 nodes.add(Long.parseLong(item.substring(4))); 125 } else if (item.startsWith("relation")) { 126 relations.add(Long.parseLong(item.substring(8))); 127 } else if (item.startsWith("rel")) { 128 relations.add(Long.parseLong(item.substring(3))); 129 } else { 130 System.out.println("RemoteControl: invalid selection '"+item+"' ignored"); 131 } 132 } 133 DataSet ds = Main.main.getCurrentDataSet(); 134 if(ds == null) // e.g. download failed 135 return; 136 for (Way w : ds.getWays()) { 137 if (ways.contains(w.getId())) { 138 newSel.add(w); 139 } 140 } 141 for (Node n : ds.getNodes()) { 142 if (nodes.contains(n.getId())) { 143 newSel.add(n); 144 } 145 } 146 for (Relation r : ds.getRelations()) { 147 if (relations.contains(r.getId())) { 148 newSel.add(r); 149 } 150 } 151 ds.setSelected(newSel); 152 if (Main.pref.getBoolean(changeViewportPermissionKey, changeViewportPermissionDefault)) 153 new AutoScaleAction("selection").actionPerformed(null); 154 } 155 }); 156 } else if (Main.pref.getBoolean(changeViewportPermissionKey, changeViewportPermissionDefault)) { 157 // after downloading, zoom to downloaded area. 158 zoom(minlat, maxlat, minlon, maxlon); 159 } 160 } 79 // find out whether some data has already been downloaded 80 Area present = null; 81 Area toDownload = null; 82 DataSet ds = Main.main.getCurrentDataSet(); 83 if (ds != null) 84 present = ds.getDataSourceArea(); 85 if (present != null && !present.isEmpty()) { 86 toDownload = new Area(new Rectangle2D.Double(minlon,minlat,maxlon-minlon,maxlat-minlat)); 87 toDownload.subtract(present); 88 if (!toDownload.isEmpty()) 89 { 90 // the result might not be a rectangle (L shaped etc) 91 Rectangle2D downloadBounds = toDownload.getBounds2D(); 92 minlat = downloadBounds.getMinY(); 93 minlon = downloadBounds.getMinX(); 94 maxlat = downloadBounds.getMaxY(); 95 maxlon = downloadBounds.getMaxX(); 96 } 97 } 98 if((toDownload != null) && toDownload.isEmpty()) 99 { 100 System.out.println("RemoteControl: no download necessary"); 101 } 102 else 103 { 104 Future<?> future = osmTask.download(false /*no new layer*/, new Bounds(minlat,minlon,maxlat,maxlon), null /* let the task manage the progress monitor */); 105 Main.worker.submit(new PostDownloadHandler(osmTask, future)); 106 } 107 } 108 } 109 } catch (Exception ex) { 110 System.out.println("RemoteControl: Error parsing load_and_zoom remote control request:"); 111 ex.printStackTrace(); 112 throw new RequestHandlerErrorException(); 113 } 161 114 162 protected void zoom(double minlat, double maxlat, double minlon, double maxlon) { 163 final Bounds bounds = new Bounds(new LatLon(minlat, minlon), 164 new LatLon(maxlat, maxlon)); 115 /** 116 * deselect objects if parameter addtags given 117 */ 118 if (args.containsKey("addtags")) { 119 Main.worker.execute(new Runnable() { 120 public void run() { 121 DataSet ds = Main.main.getCurrentDataSet(); 122 if(ds == null) // e.g. download failed 123 return; 124 ds.clearSelection(); 125 } 126 }); 127 } 165 128 166 // make sure this isn't called unless there *is* a MapView 167 // 168 if (Main.map != null && Main.map.mapView != null) { 169 Main.worker.execute(new Runnable() { 170 public void run() { 171 BoundingXYVisitor bbox = new BoundingXYVisitor(); 172 bbox.visit(bounds); 173 Main.map.mapView.recalculateCenterScale(bbox); 174 } 175 }); 176 } 177 } 178 } 179 No newline at end of file 129 if (args.containsKey("select") && Main.pref.getBoolean(changeSelectionPermissionKey, changeSelectionPermissionDefault)) { 130 // select objects after downloading, zoom to selection. 131 final String selection = args.get("select"); 132 Main.worker.execute(new Runnable() { 133 public void run() { 134 HashSet<Long> ways = new HashSet<Long>(); 135 HashSet<Long> nodes = new HashSet<Long>(); 136 HashSet<Long> relations = new HashSet<Long>(); 137 HashSet<OsmPrimitive> newSel = new HashSet<OsmPrimitive>(); 138 for (String item : selection.split(",")) { 139 if (item.startsWith("way")) { 140 ways.add(Long.parseLong(item.substring(3))); 141 } else if (item.startsWith("node")) { 142 nodes.add(Long.parseLong(item.substring(4))); 143 } else if (item.startsWith("relation")) { 144 relations.add(Long.parseLong(item.substring(8))); 145 } else if (item.startsWith("rel")) { 146 relations.add(Long.parseLong(item.substring(3))); 147 } else { 148 System.out.println("RemoteControl: invalid selection '"+item+"' ignored"); 149 } 150 } 151 DataSet ds = Main.main.getCurrentDataSet(); 152 if(ds == null) // e.g. download failed 153 return; 154 for (Way w : ds.getWays()) { 155 if (ways.contains(w.getId())) { 156 newSel.add(w); 157 } 158 } 159 for (Node n : ds.getNodes()) { 160 if (nodes.contains(n.getId())) { 161 newSel.add(n); 162 } 163 } 164 for (Relation r : ds.getRelations()) { 165 if (relations.contains(r.getId())) { 166 newSel.add(r); 167 } 168 } 169 ds.setSelected(newSel); 170 if (Main.pref.getBoolean(changeViewportPermissionKey, changeViewportPermissionDefault)) 171 new AutoScaleAction("selection").actionPerformed(null); 172 } 173 }); 174 } else if (Main.pref.getBoolean(changeViewportPermissionKey, changeViewportPermissionDefault)) { 175 // after downloading, zoom to downloaded area. 176 zoom(minlat, maxlat, minlon, maxlon); 177 } 178 179 /* 180 * parse addtags parameters 181 * Example URL (part): 182 * addtags=wikipedia:de%3DResidenzschloss Dresden|name:en%3DDresden Castle 183 */ 184 if (args.containsKey("addtags")) { 185 Main.worker.execute(new Runnable() { 186 public void run() { 187 String[] tags = null; 188 try { 189 tags = URLDecoder.decode(args.get("addtags"), "UTF-8").split("\\|"); 190 } catch (UnsupportedEncodingException e) { 191 System.err.println("Your System has no support for UTF8.\nDamn Windows!"); 192 } 193 String[][] keyValue = new String[tags.length][2]; 194 for (int i = 0; i<tags.length; i++) { 195 keyValue[i] = tags[i].split("="); 196 197 keyValue[i][0] = keyValue[i][0]; 198 keyValue[i][1] = keyValue[i][1]; 199 200 } 201 202 new AddTagsDialog(keyValue); 203 } 204 }); 205 } 206 207 } 208 209 protected void zoom(double minlat, double maxlat, double minlon, double maxlon) { 210 final Bounds bounds = new Bounds(new LatLon(minlat, minlon), 211 new LatLon(maxlat, maxlon)); 212 213 // make sure this isn't called unless there *is* a MapView 214 // 215 if (Main.map != null && Main.map.mapView != null) { 216 Main.worker.execute(new Runnable() { 217 public void run() { 218 BoundingXYVisitor bbox = new BoundingXYVisitor(); 219 bbox.visit(bounds); 220 Main.map.mapView.recalculateCenterScale(bbox); 221 } 222 }); 223 } 224 } 225 }
