Ticket #5843: remotecontrol_addtags.patch

File remotecontrol_addtags.patch, 19.5 KB (added by freemaps.osm@…, 11 years ago)

new patch witch bugs fixed and some mor features

  • src/org/openstreetmap/josm/io/remotecontrol/gui/AddTagsDialog.java

     
     1package org.openstreetmap.josm.io.remotecontrol.gui;
     2
     3import static org.openstreetmap.josm.tools.I18n.tr;
     4
     5import java.awt.Color;
     6import java.awt.Component;
     7import java.awt.Dimension;
     8import java.awt.Font;
     9import java.awt.GridBagLayout;
     10import java.awt.event.ActionEvent;
     11import java.util.Collection;
     12
     13import javax.swing.JPanel;
     14import javax.swing.JTable;
     15import javax.swing.table.DefaultTableModel;
     16import javax.swing.table.TableCellRenderer;
     17import javax.swing.table.TableModel;
     18
     19import org.openstreetmap.josm.Main;
     20import org.openstreetmap.josm.command.ChangePropertyCommand;
     21import org.openstreetmap.josm.data.SelectionChangedListener;
     22import org.openstreetmap.josm.data.osm.DataSet;
     23import org.openstreetmap.josm.data.osm.OsmPrimitive;
     24import org.openstreetmap.josm.gui.ExtendedDialog;
     25import 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
     37public 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

     
    55
    66import java.awt.geom.Area;
    77import java.awt.geom.Rectangle2D;
     8import java.io.UnsupportedEncodingException;
     9import java.net.URLDecoder;
    810import java.util.HashSet;
    911import java.util.concurrent.Future;
    1012
     
    2123import org.openstreetmap.josm.data.osm.Relation;
    2224import org.openstreetmap.josm.data.osm.Way;
    2325import org.openstreetmap.josm.data.osm.visitor.BoundingXYVisitor;
     26import org.openstreetmap.josm.io.remotecontrol.gui.AddTagsDialog;
    2427
    2528/**
    2629 * Handler for load_and_zoom request.
    2730 */
    2831public class LoadAndZoomHandler extends RequestHandler
    2932{
    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";
    3235
    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;
    3942
    40     @Override
    41     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        }
    4649
    47     @Override
    48     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        }
    5255
    53     @Override
    54     protected void handleRequest() throws RequestHandlerErrorException
    55     {
    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"));
    6669
    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                 else
    74                 {
     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                                {
    7578
    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                }
    161114
    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                }
    165128
    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}