Ticket #9634: ticket9634_2014-04-12_00:53:36_+0200.patch

File ticket9634_2014-04-12_00:53:36_+0200.patch, 23.5 KB (added by Balaitous, 9 years ago)

I think this time it is OK

  • src/org/openstreetmap/josm/actions/DownloadPrimitiveAction.java

    diff --git src/org/openstreetmap/josm/actions/DownloadPrimitiveAction.java src/org/openstreetmap/josm/actions/DownloadPrimitiveAction.java
    index 5bae4eb..b966d04 100644
    package org.openstreetmap.josm.actions; 
    33
    44import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
    55import static org.openstreetmap.josm.tools.I18n.tr;
    6 import static org.openstreetmap.josm.tools.I18n.trn;
    76
    8 import java.awt.Font;
    9 import java.awt.GridBagLayout;
    107import java.awt.event.ActionEvent;
    118import java.awt.event.KeyEvent;
    12 import java.lang.reflect.InvocationTargetException;
    139import java.util.List;
    14 import java.util.Set;
    15 import java.util.TreeSet;
    16 
    17 import javax.swing.JLabel;
    18 import javax.swing.JOptionPane;
    19 import javax.swing.JPanel;
    20 import javax.swing.JScrollPane;
    21 import javax.swing.SwingUtilities;
    2210
    2311import org.openstreetmap.josm.Main;
    24 import org.openstreetmap.josm.actions.downloadtasks.DownloadReferrersTask;
    25 import org.openstreetmap.josm.data.osm.DataSet;
    26 import org.openstreetmap.josm.data.osm.OsmPrimitive;
    2712import org.openstreetmap.josm.data.osm.PrimitiveId;
    28 import org.openstreetmap.josm.gui.ExtendedDialog;
    2913import org.openstreetmap.josm.gui.download.DownloadObjectDialog;
    30 import org.openstreetmap.josm.gui.io.DownloadPrimitivesTask;
    31 import org.openstreetmap.josm.gui.layer.OsmDataLayer;
    32 import org.openstreetmap.josm.gui.widgets.HtmlPanel;
    33 import org.openstreetmap.josm.gui.widgets.JosmTextArea;
    34 import org.openstreetmap.josm.tools.GBC;
     14import org.openstreetmap.josm.gui.io.DownloadPrimitivesWithReferrersTask;
    3515import org.openstreetmap.josm.tools.Shortcut;
    36 import org.openstreetmap.josm.tools.Utils;
    3716
    3817/**
    3918 * Download an OsmPrimitive by specifying type and ID
    public class DownloadPrimitiveAction extends JosmAction { 
    6241
    6342    /**
    6443     * @param newLayer if the data should be downloaded into a new layer
    65      * @param ids
     44     * @param ids List of primitive id to download
    6645     * @param downloadReferrers if the referrers of the object should be downloaded as well, i.e., parent relations, and for nodes, additionally, parent ways
    6746     * @param full if the members of a relation should be downloaded as well
    6847     */
    6948    public static void processItems(boolean newLayer, final List<PrimitiveId> ids, boolean downloadReferrers, boolean full) {
    70         OsmDataLayer layer = getEditLayer();
    71         if ((layer == null) || newLayer) {
    72             layer = new OsmDataLayer(new DataSet(), OsmDataLayer.createNewName(), null);
    73             Main.main.addLayer(layer);
    74         }
    75         final DownloadPrimitivesTask task = new DownloadPrimitivesTask(layer, ids, full);
     49        final DownloadPrimitivesWithReferrersTask task =
     50                new DownloadPrimitivesWithReferrersTask(newLayer, ids, downloadReferrers, full, null);
    7651        Main.worker.submit(task);
    77 
    78         if (downloadReferrers) {
    79             for (PrimitiveId id : ids) {
    80                 Main.worker.submit(new DownloadReferrersTask(layer, id));
    81             }
    82         }
    83 
    84         Runnable showErrorsAndWarnings = new Runnable() {
     52        Main.worker.submit(new Runnable() {
    8553            @Override
    8654            public void run() {
    87                 final Set<PrimitiveId> errs = task.getMissingPrimitives();
    88                 if (errs != null && !errs.isEmpty()) {
    89                     try {
    90                         SwingUtilities.invokeAndWait(new Runnable() {
    91                             @Override
    92                             public void run() {
    93                                 reportProblemDialog(errs,
    94                                         trn("Object could not be downloaded", "Some objects could not be downloaded", errs.size()),
    95                                         trn("One object could not be downloaded.<br>",
    96                                             "{0} objects could not be downloaded.<br>",
    97                                             errs.size(),
    98                                             errs.size())
    99                                         + tr("The server replied with response code 404.<br>"
    100                                             + "This usually means, the server does not know an object with the requested id."),
    101                                         tr("missing objects:"),
    102                                         JOptionPane.ERROR_MESSAGE
    103                                 ).showDialog();
    104                             }
    105                         });
    106                     } catch (InterruptedException ex) {
    107                         Main.warn("InterruptedException while displaying error dialog");
    108                     } catch (InvocationTargetException ex) {
    109                         Main.warn(ex);
    110                     }
    111                 }
    112 
    113                 final Set<PrimitiveId> del = new TreeSet<PrimitiveId>();
    114                 DataSet ds = getCurrentDataSet();
    115                 for (PrimitiveId id : ids) {
    116                     OsmPrimitive osm = ds.getPrimitiveById(id);
    117                     if (osm != null && osm.isDeleted()) {
    118                         del.add(id);
    119                     }
    120                 }
    121                 if (!del.isEmpty()) {
    122                     SwingUtilities.invokeLater(new Runnable() {
    123                         @Override
    124                         public void run() {
    125                             reportProblemDialog(del,
    126                                     trn("Object deleted", "Objects deleted", del.size()),
    127                                     trn(
    128                                         "One downloaded object is deleted.",
    129                                         "{0} downloaded objects are deleted.",
    130                                         del.size(),
    131                                         del.size()),
    132                                     null,
    133                                     JOptionPane.WARNING_MESSAGE
    134                             ).showDialog();
    135                         }
    136                     });
    137                 }
     55                List<PrimitiveId> downloaded = task.getDownloadedId();
     56                if(downloaded != null)
     57                    Main.main.getCurrentDataSet().setSelected(downloaded);
    13858            }
    139         };
    140         Main.worker.submit(showErrorsAndWarnings);
    141     }
    142 
    143     private static ExtendedDialog reportProblemDialog(Set<PrimitiveId> errs,
    144             String TITLE, String TEXT, String LIST_LABEL, int msgType) {
    145         JPanel p = new JPanel(new GridBagLayout());
    146         p.add(new HtmlPanel(TEXT), GBC.eop());
    147         if (LIST_LABEL != null) {
    148             JLabel missing = new JLabel(LIST_LABEL);
    149             missing.setFont(missing.getFont().deriveFont(Font.PLAIN));
    150             p.add(missing, GBC.eol());
    151         }
    152         JosmTextArea txt = new JosmTextArea();
    153         txt.setFont(new Font("Monospaced", txt.getFont().getStyle(), txt.getFont().getSize()));
    154         txt.setEditable(false);
    155         txt.setBackground(p.getBackground());
    156         txt.setColumns(40);
    157         txt.setRows(1);
    158         txt.setText(Utils.join(", ", errs));
    159         JScrollPane scroll = new JScrollPane(txt);
    160         p.add(scroll, GBC.eop().weight(1.0, 0.0).fill(GBC.HORIZONTAL));
    161 
    162         return new ExtendedDialog(
    163                 Main.parent,
    164                 TITLE,
    165                 new String[] { tr("Ok") })
    166             .setButtonIcons(new String[] { "ok" })
    167             .setIcon(msgType)
    168             .setContent(p, false);
     59        });
    16960    }
    17061}
  • src/org/openstreetmap/josm/actions/downloadtasks/DownloadReferrersTask.java

    diff --git src/org/openstreetmap/josm/actions/downloadtasks/DownloadReferrersTask.java src/org/openstreetmap/josm/actions/downloadtasks/DownloadReferrersTask.java
    index ce7c850..15d7a57 100644
    public class DownloadReferrersTask extends PleaseWaitRunnable { 
    130130     *
    131131     */
    132132    public DownloadReferrersTask(OsmDataLayer targetLayer, PrimitiveId primitiveId) throws IllegalArgumentException {
    133         super("Download referrers", false /* don't ignore exception*/);
     133        this(targetLayer,  primitiveId, null);
     134    }
     135
     136    /**
     137     * constructor
     138     *
     139     * @param targetLayer the target layer. Must not be null.
     140     * @param primitiveId a PrimitiveId object.
     141     * @param progressMonitor ProgressMonitor to use or null to create a new one.
     142     * @exception IllegalArgumentException thrown if id &lt;= 0
     143     * @exception IllegalArgumentException thrown if targetLayer == null
     144     *
     145     */
     146    public DownloadReferrersTask(OsmDataLayer targetLayer, PrimitiveId primitiveId,
     147            ProgressMonitor progressMonitor) throws IllegalArgumentException {
     148        super("Download referrers", progressMonitor, false /* don't ignore exception*/);
    134149        CheckParameterUtil.ensureParameterNotNull(targetLayer, "targetLayer");
    135150        if (primitiveId.isNew())
    136151            throw new IllegalArgumentException(MessageFormat.format("Cannot download referrers for new primitives (ID {0})", primitiveId.getUniqueId()));
    public class DownloadReferrersTask extends PleaseWaitRunnable { 
    167182                    @Override
    168183                    public void run() {
    169184                        targetLayer.onPostDownloadFromServer();
    170                         Main.map.mapView.repaint();
     185                        if(Main.map != null)
     186                            Main.map.mapView.repaint();
    171187                    }
    172188                }
    173189        );
  • src/org/openstreetmap/josm/gui/io/DownloadPrimitivesTask.java

    diff --git src/org/openstreetmap/josm/gui/io/DownloadPrimitivesTask.java src/org/openstreetmap/josm/gui/io/DownloadPrimitivesTask.java
    index 519a151..ef2934d 100644
    import java.io.IOException; 
    88import java.util.List;
    99import java.util.Set;
    1010
     11import org.openstreetmap.josm.Main;
    1112import org.openstreetmap.josm.actions.AutoScaleAction;
    1213import org.openstreetmap.josm.data.osm.DataSet;
    1314import org.openstreetmap.josm.data.osm.DataSetMerger;
    public class DownloadPrimitivesTask extends PleaseWaitRunnable { 
    5152     * @throws IllegalArgumentException thrown if layer is null.
    5253     */
    5354    public DownloadPrimitivesTask(OsmDataLayer layer, List<PrimitiveId> ids, boolean fullRelation) throws IllegalArgumentException {
    54         super(tr("Download objects"), false /* don't ignore exception */);
     55        this(layer, ids, fullRelation, null);
     56    }
     57
     58    /**
     59     * Creates the  task
     60     *
     61     * @param layer the layer in which primitives are updated. Must not be null.
     62     * @param ids a collection of primitives to update from the server. Set to
     63     *     the empty collection if null.
     64     * @param fullRelation true if a full download is required, i.e.,
     65     *     a download including the immediate children of a relation.
     66     * @param progressMonitor ProgressMonitor to use or null to create a new one.
     67     * @throws IllegalArgumentException thrown if layer is null.
     68     */
     69    public DownloadPrimitivesTask(OsmDataLayer layer, List<PrimitiveId> ids, boolean fullRelation,
     70            ProgressMonitor progessMonitor) throws IllegalArgumentException {
     71        super(tr("Download objects"), progessMonitor, false /* don't ignore exception */);
    5572        ensureParameterNotNull(layer, "layer");
    5673        this.ids = ids;
    5774        this.layer = layer;
    public class DownloadPrimitivesTask extends PleaseWaitRunnable { 
    83100            @Override
    84101            public void run() {
    85102                layer.mergeFrom(ds);
    86                 AutoScaleAction.zoomTo(ds.allPrimitives());
     103                if(Main.map != null)
     104                    AutoScaleAction.zoomTo(ds.allPrimitives());
    87105                layer.onPostDownloadFromServer();
    88106            }
    89107        });
  • new file src/org/openstreetmap/josm/gui/io/DownloadPrimitivesWithReferrersTask.java

    diff --git src/org/openstreetmap/josm/gui/io/DownloadPrimitivesWithReferrersTask.java src/org/openstreetmap/josm/gui/io/DownloadPrimitivesWithReferrersTask.java
    new file mode 100644
    index 0000000..67d2904
    - +  
     1package org.openstreetmap.josm.gui.io;
     2
     3import static org.openstreetmap.josm.tools.I18n.tr;
     4import static org.openstreetmap.josm.tools.I18n.trn;
     5
     6import java.awt.Font;
     7import java.awt.GridBagLayout;
     8import java.io.IOException;
     9import java.util.ArrayList;
     10import java.util.HashSet;
     11import java.util.List;
     12import java.util.Set;
     13
     14import javax.swing.JLabel;
     15import javax.swing.JOptionPane;
     16import javax.swing.JPanel;
     17import javax.swing.JScrollPane;
     18
     19import org.openstreetmap.josm.Main;
     20import org.openstreetmap.josm.actions.downloadtasks.DownloadReferrersTask;
     21import org.openstreetmap.josm.data.osm.DataSet;
     22import org.openstreetmap.josm.data.osm.OsmPrimitive;
     23import org.openstreetmap.josm.data.osm.PrimitiveId;
     24import org.openstreetmap.josm.gui.ExtendedDialog;
     25import org.openstreetmap.josm.gui.PleaseWaitRunnable;
     26import org.openstreetmap.josm.gui.layer.OsmDataLayer;
     27import org.openstreetmap.josm.gui.progress.ProgressMonitor;
     28import org.openstreetmap.josm.gui.util.GuiHelper;
     29import org.openstreetmap.josm.gui.widgets.HtmlPanel;
     30import org.openstreetmap.josm.gui.widgets.JosmTextArea;
     31import org.openstreetmap.josm.io.OsmTransferException;
     32import org.openstreetmap.josm.tools.GBC;
     33import org.openstreetmap.josm.tools.Utils;
     34import org.xml.sax.SAXException;
     35
     36/**
     37 * Task for downloading a set of primitives with all referrers.
     38 */
     39public class DownloadPrimitivesWithReferrersTask extends PleaseWaitRunnable {
     40    /** If true download into a new layer */
     41    private final boolean newLayer;
     42    /** List of primitives id to download */
     43    private final List<PrimitiveId> ids;
     44    /** If true, download members for relation */
     45    private final boolean full;
     46    /** If true, download also referrers */
     47    private final boolean downloadReferrers;
     48
     49    /** Temporary layer where downloaded primitives are put */
     50    private OsmDataLayer tmpLayer;
     51    /** Reference to the task that download requested primitives */
     52    private DownloadPrimitivesTask mainTask;
     53    /** Flag indicated that user ask for cancel this task */
     54    private boolean canceled = false;
     55    /** Reference to the task currently running */
     56    private PleaseWaitRunnable currentTask = null;
     57
     58    /**
     59     * Constructor
     60     *
     61     * @param newLayer if the data should be downloaded into a new layer
     62     * @param ids List of primitive id to download
     63     * @param downloadReferrers if the referrers of the object should be downloaded as well,
     64     *     i.e., parent relations, and for nodes, additionally, parent ways
     65     * @param full if the members of a relation should be downloaded as well
     66     * @param monitor ProgressMonitor to use, or null to create a new one
     67     */
     68    public DownloadPrimitivesWithReferrersTask(boolean newLayer, List<PrimitiveId> ids, boolean downloadReferrers,
     69            boolean full, ProgressMonitor monitor) {
     70        super(tr("Download objects"), monitor, false);
     71        this.ids = ids;
     72        this.downloadReferrers = downloadReferrers;
     73        this.full = full;
     74        this.newLayer = newLayer;
     75        // All downloaded primitives are put in a tmpLayer
     76        tmpLayer = new OsmDataLayer(new DataSet(), OsmDataLayer.createNewName(), null);
     77        //Main.main.addLayer(tmpLayer);
     78    }
     79
     80    /**
     81     * Cancel recursively the task. Do not call directly
     82     * @see DownloadPrimitivesWithReferrersTask#operationCancel
     83     */
     84    @Override
     85    protected void cancel() {
     86        synchronized(this) {
     87            canceled = true;
     88            if(currentTask != null)
     89                currentTask.operationCanceled();
     90        }
     91    }
     92
     93    @Override
     94    protected void realRun() throws SAXException, IOException, OsmTransferException {
     95        getProgressMonitor().setTicksCount(ids.size()+1);
     96        // First, download primitives
     97        mainTask = new DownloadPrimitivesTask(tmpLayer, ids, full, getProgressMonitor().createSubTaskMonitor(1, false));
     98        currentTask = mainTask;
     99        synchronized(this) {
     100            if(canceled) {
     101                currentTask = null;
     102                return;
     103            }
     104        }
     105        currentTask.run();
     106        // Then, download referrers for each primitive
     107        if(downloadReferrers)
     108            for(PrimitiveId id : ids) {
     109                synchronized(this) {
     110                    if(canceled) {
     111                        currentTask = null;
     112                        return;
     113                    }
     114                }
     115                currentTask = new DownloadReferrersTask(
     116                        tmpLayer, id, getProgressMonitor().createSubTaskMonitor(1, false));
     117                currentTask.run();
     118            }
     119        currentTask = null;
     120    }
     121
     122    @Override
     123    protected void finish() {
     124        if(canceled)
     125            return;
     126
     127        // Append downloaded data to JOSM
     128        OsmDataLayer layer = Main.main.getEditLayer();
     129        if(layer == null || this.newLayer)
     130            Main.main.addLayer(tmpLayer);
     131        else
     132            layer.mergeFrom(tmpLayer);
     133
     134        // Warm about missing primitives
     135        final Set<PrimitiveId> errs = mainTask.getMissingPrimitives();
     136        if (errs != null && !errs.isEmpty())
     137            GuiHelper.runInEDTAndWait(new Runnable() {
     138                @Override
     139                public void run() {
     140                    reportProblemDialog(errs,
     141                            trn("Object could not be downloaded", "Some objects could not be downloaded", errs.size()),
     142                            trn("One object could not be downloaded.<br>",
     143                                    "{0} objects could not be downloaded.<br>",
     144                                    errs.size(),
     145                                    errs.size())
     146                                    + tr("The server replied with response code 404.<br>"
     147                                         + "This usually means, the server does not know an object with the requested id."),
     148                            tr("missing objects:"),
     149                            JOptionPane.ERROR_MESSAGE
     150                            ).showDialog();
     151                }
     152            });
     153
     154        // Warm about deleted primitives
     155        final Set<PrimitiveId> del = new HashSet<PrimitiveId>();
     156        DataSet ds = Main.main.getCurrentDataSet();
     157        for (PrimitiveId id : ids) {
     158            OsmPrimitive osm = ds.getPrimitiveById(id);
     159            if (osm != null && osm.isDeleted()) {
     160                del.add(id);
     161            }
     162        }
     163        if (!del.isEmpty())
     164            GuiHelper.runInEDTAndWait(new Runnable() {
     165                @Override
     166                public void run() {
     167                    reportProblemDialog(del,
     168                            trn("Object deleted", "Objects deleted", del.size()),
     169                            trn(
     170                                "One downloaded object is deleted.",
     171                                "{0} downloaded objects are deleted.",
     172                                del.size(),
     173                                del.size()),
     174                            null,
     175                            JOptionPane.WARNING_MESSAGE
     176                    ).showDialog();
     177                }
     178            });
     179    }
     180
     181    /**
     182     * Return id of really downloaded primitives.
     183     * @return List of primitives id or null if no primitives was downloaded
     184     */
     185    public List<PrimitiveId> getDownloadedId() {
     186        if(canceled)
     187            return null;
     188        ArrayList<PrimitiveId> downloaded = new ArrayList<PrimitiveId>(ids);
     189        downloaded.removeAll(mainTask.getMissingPrimitives());
     190        return downloaded;
     191    }
     192
     193    /**
     194     * Dialog for report a problem during download.
     195     * @param errs Primitives involved
     196     * @param TITLE Title of dialog
     197     * @param TEXT Detail message
     198     * @param LIST_LABEL List of primitives description
     199     * @param msgType Type of message {@see JOptionPane}
     200     * @return The Dialog object
     201     */
     202    private static ExtendedDialog reportProblemDialog(Set<PrimitiveId> errs,
     203            String TITLE, String TEXT, String LIST_LABEL, int msgType) {
     204        JPanel p = new JPanel(new GridBagLayout());
     205        p.add(new HtmlPanel(TEXT), GBC.eop());
     206        if (LIST_LABEL != null) {
     207            JLabel missing = new JLabel(LIST_LABEL);
     208            missing.setFont(missing.getFont().deriveFont(Font.PLAIN));
     209            p.add(missing, GBC.eol());
     210        }
     211        JosmTextArea txt = new JosmTextArea();
     212        txt.setFont(new Font("Monospaced", txt.getFont().getStyle(), txt.getFont().getSize()));
     213        txt.setEditable(false);
     214        txt.setBackground(p.getBackground());
     215        txt.setColumns(40);
     216        txt.setRows(1);
     217        txt.setText(Utils.join(", ", errs));
     218        JScrollPane scroll = new JScrollPane(txt);
     219        p.add(scroll, GBC.eop().weight(1.0, 0.0).fill(GBC.HORIZONTAL));
     220
     221        return new ExtendedDialog(
     222                Main.parent,
     223                TITLE,
     224                new String[] { tr("Ok") })
     225        .setButtonIcons(new String[] { "ok" })
     226        .setIcon(msgType)
     227        .setContent(p, false);
     228    }
     229}
     230 No newline at end of file
  • src/org/openstreetmap/josm/io/remotecontrol/handler/LoadObjectHandler.java

    diff --git src/org/openstreetmap/josm/io/remotecontrol/handler/LoadObjectHandler.java src/org/openstreetmap/josm/io/remotecontrol/handler/LoadObjectHandler.java
    index 9f4e0cc..cdf0a9a 100644
    import java.util.LinkedList; 
    77import java.util.List;
    88
    99import org.openstreetmap.josm.Main;
    10 import org.openstreetmap.josm.actions.DownloadPrimitiveAction;
    1110import org.openstreetmap.josm.data.osm.PrimitiveId;
    1211import org.openstreetmap.josm.data.osm.SimplePrimitiveId;
    13 import org.openstreetmap.josm.gui.util.GuiHelper;
     12import org.openstreetmap.josm.gui.io.DownloadPrimitivesWithReferrersTask;
    1413import org.openstreetmap.josm.io.remotecontrol.AddTagsDialog;
    1514import org.openstreetmap.josm.io.remotecontrol.PermissionPrefWithDefault;
    1615
    public class LoadObjectHandler extends RequestHandler { 
    3231    public String[] getMandatoryParams() {
    3332        return new String[]{"objects"};
    3433    }
    35    
     34
    3635    @Override
    3736    public String[] getOptionalParams() {
    3837        return new String[] {"new_layer", "addtags", "relation_members", "referrers"};
    public class LoadObjectHandler extends RequestHandler { 
    6059            final boolean newLayer = isLoadInNewLayer();
    6160            final boolean relationMembers = Boolean.parseBoolean(args.get("relation_members"));
    6261            final boolean referrers = args.containsKey("referrers") ? Boolean.parseBoolean(args.get("referrers")) : true;
    63             GuiHelper.runInEDTAndWait(new Runnable() {
    64                 @Override public void run() {
    65                     DownloadPrimitiveAction.processItems(newLayer, ps, referrers, relationMembers);
    66                 }
    67             });
    68             GuiHelper.executeByMainWorkerInEDT(new Runnable() {
     62            final DownloadPrimitivesWithReferrersTask task = new DownloadPrimitivesWithReferrersTask(
     63                    newLayer, ps, referrers, relationMembers, null);
     64            Main.worker.submit(task);
     65            Main.worker.submit(new Runnable() {
    6966                @Override
    7067                public void run() {
    71                     Main.main.getCurrentDataSet().setSelected(ps);
     68                    List<PrimitiveId> downloaded = task.getDownloadedId();
     69                    if(downloaded != null)
     70                        Main.main.getCurrentDataSet().setSelected(downloaded);
    7271                    AddTagsDialog.addTags(args, sender);
    7372                    ps.clear();
    7473                }