Changeset 4081 in josm


Ignore:
Timestamp:
2011-05-15T16:12:43+02:00 (10 years ago)
Author:
bastiK
Message:

applied #6251 (patch by akks) - Download multiple objects on Ctrl-Shift-O

Location:
trunk/src/org/openstreetmap/josm
Files:
1 added
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/actions/DownloadPrimitiveAction.java

    r4045 r4081  
    44import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
    55import static org.openstreetmap.josm.tools.I18n.tr;
    6 
    7 import java.awt.GridBagConstraints;
     6import static org.openstreetmap.josm.tools.I18n.trn;
     7
     8import java.awt.Font;
    89import java.awt.GridBagLayout;
    910import java.awt.event.ActionEvent;
    1011import java.awt.event.KeyEvent;
     12import java.lang.reflect.InvocationTargetException;
     13import java.util.List;
     14import java.util.Set;
     15import java.util.TreeSet;
     16import javax.swing.BorderFactory;
     17import javax.swing.GroupLayout;
    1118
    1219import javax.swing.JCheckBox;
     
    1421import javax.swing.JOptionPane;
    1522import javax.swing.JPanel;
     23import javax.swing.JScrollPane;
     24import javax.swing.JTextArea;
    1625import javax.swing.KeyStroke;
     26import javax.swing.SwingUtilities;
     27import javax.swing.border.EtchedBorder;
    1728
    1829import org.openstreetmap.josm.Main;
    19 import org.openstreetmap.josm.actions.downloadtasks.DownloadPrimitiveTask;
    2030import org.openstreetmap.josm.actions.downloadtasks.DownloadReferrersTask;
    2131import org.openstreetmap.josm.data.osm.DataSet;
     32import org.openstreetmap.josm.data.osm.OsmPrimitive;
    2233import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
    23 import org.openstreetmap.josm.data.osm.SimplePrimitiveId;
     34import org.openstreetmap.josm.data.osm.PrimitiveId;
    2435import org.openstreetmap.josm.gui.ExtendedDialog;
     36import org.openstreetmap.josm.gui.io.DownloadPrimitivesTask;
    2537import org.openstreetmap.josm.gui.layer.OsmDataLayer;
     38import org.openstreetmap.josm.gui.widgets.HtmlPanel;
    2639import org.openstreetmap.josm.gui.widgets.OsmIdTextField;
    2740import org.openstreetmap.josm.gui.widgets.OsmPrimitiveTypesComboBox;
     41import org.openstreetmap.josm.tools.GBC;
    2842import org.openstreetmap.josm.tools.Shortcut;
     43import org.openstreetmap.josm.tools.Utils;
    2944
    3045/**
     
    4257
    4358    public void actionPerformed(ActionEvent e) {
     59       
     60        JPanel all = new JPanel();
     61        GroupLayout layout = new GroupLayout(all);
     62        all.setLayout(layout);
     63        layout.setAutoCreateGaps(true);
     64        layout.setAutoCreateContainerGaps(true);
     65       
     66        JLabel lbl1 = new JLabel(tr("Object type:"));
     67        OsmPrimitiveTypesComboBox cbType = new OsmPrimitiveTypesComboBox();
     68        cbType.addItem(new SimpleListItem("mixed", tr("mixed")));
     69        cbType.setToolTipText(tr("Choose the OSM object type"));
     70        JLabel lbl2 = new JLabel(tr("Object ID:"));
     71        OsmIdTextField tfId = new OsmIdTextField();
     72        tfId.setToolTipText(tr("Enter the ID of the object that should be downloaded"));
     73        // forward the enter key stroke to the download button
     74        tfId.getKeymap().removeKeyStrokeBinding(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0, false));
    4475        JCheckBox layer = new JCheckBox(tr("Separate Layer"));
    4576        layer.setToolTipText(tr("Select if the data should be downloaded into a new layer"));
     
    4879        referrers.setToolTipText(tr("Select if the referrers of the object should be downloaded as well"));
    4980        referrers.setSelected(Main.pref.getBoolean("downloadprimitive.referrers"));
    50         JPanel all = new JPanel(new GridBagLayout());
    51         GridBagConstraints gc = new GridBagConstraints();
    52         gc.fill = GridBagConstraints.HORIZONTAL;
    53         gc.anchor = GridBagConstraints.FIRST_LINE_START;
    54         gc.gridy = 0;
    55         gc.weightx = 0;
    56         all.add(new JLabel(tr("Object type:")), gc);
    57         OsmPrimitiveTypesComboBox cbType = new OsmPrimitiveTypesComboBox();
    58         cbType.setToolTipText(tr("Choose the OSM object type"));
    59         gc.weightx = 1;
    60         all.add(cbType, gc);
    61         gc.gridy = 1;
    62         gc.weightx = 0;
    63         all.add(new JLabel(tr("Object ID:")), gc);
    64         OsmIdTextField tfId = new OsmIdTextField();
    65         tfId.setToolTipText(tr("Enter the ID of the object that should be downloaded"));
    66         // forward the enter key stroke to the download button
    67         tfId.getKeymap().removeKeyStrokeBinding(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0, false));
    68         gc.weightx = 1;
    69         all.add(tfId, gc);
    70         gc.gridy = 2;
    71         gc.fill = GridBagConstraints.BOTH;
    72         gc.weighty = 1.0;
    73         gc.weightx = 0;
    74         all.add(referrers, gc);
    75         gc.gridy = 3;
    76         all.add(layer, gc);
     81        HtmlPanel help = new HtmlPanel(tr("Object IDs can be separated by comma or space.<br/>"
     82                + " Examples: <b><ul><li>1 2 5</li><li>1,2,5</li></ul><br/></b>"
     83                + " In mixed mode, specify objects like this: <b>w123, n110, w12, r15</b><br/>"));
     84        help.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED));
     85       
     86        layout.setVerticalGroup(layout.createSequentialGroup()
     87            .addGroup(layout.createParallelGroup()
     88                .addComponent(lbl1)
     89                .addComponent(cbType, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE))
     90            .addGroup(layout.createParallelGroup()
     91                .addComponent(lbl2)
     92                .addComponent(tfId, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE))
     93            .addComponent(referrers)
     94            .addComponent(layer)
     95            .addComponent(help)
     96        );
     97       
     98        layout.setHorizontalGroup(layout.createParallelGroup()
     99            .addGroup(layout.createSequentialGroup()
     100                .addGroup(layout.createParallelGroup()
     101                    .addComponent(lbl1)
     102                    .addComponent(lbl2)
     103                )
     104                .addGroup(layout.createParallelGroup()
     105                    .addComponent(cbType)
     106                    .addComponent(tfId))
     107                )
     108            .addComponent(referrers)
     109            .addComponent(layer)
     110            .addComponent(help)
     111        );
     112       
    77113        ExtendedDialog dialog = new ExtendedDialog(Main.parent,
    78114                tr("Download object"),
     
    93129        Main.pref.put("downloadprimitive.referrers", referrers.isSelected());
    94130        Main.pref.put("download.newlayer", layer.isSelected());
    95         int id = tfId.getOsmId();
    96         if(id <= 0)
     131
     132        tfId.setType(cbType.getType());
     133        if(tfId.readOsmIds()==false) {
    97134            JOptionPane.showMessageDialog(
    98135                    Main.parent,
    99                     tr("Invalid ID specified. Cannot download object."),
     136                    tr("Invalid ID list specified\n"
     137                    + " Cannot download object."),
    100138                    tr("Information"),
    101139                    JOptionPane.INFORMATION_MESSAGE
    102140            );
    103         else
    104             download(layer.isSelected(), cbType.getType(), id, referrers.isSelected());
    105     }
    106 
    107     /**
    108      * Download the given primitive.
    109      */
    110     public void download(boolean newLayer, OsmPrimitiveType type, int id, boolean downloadReferrers) {
     141            return;
     142        }
     143
     144        processItems(layer.isSelected(), cbType.getType(), tfId.getIds(), referrers.isSelected());
     145    }
     146   
     147    void processItems(boolean newLayer, OsmPrimitiveType type,
     148            final List<PrimitiveId> ids,
     149            boolean downloadReferrers) {
    111150        OsmDataLayer layer = getEditLayer();
    112151        if ((layer == null) || newLayer) {
     
    114153            Main.main.addLayer(layer);
    115154        }
    116         Main.worker.submit(new DownloadPrimitiveTask(new SimplePrimitiveId(id, type), layer));
     155        final DownloadPrimitivesTask task = new DownloadPrimitivesTask(layer, ids);
     156        Main.worker.submit(task);
     157       
    117158        if (downloadReferrers) {
    118             Main.worker.submit(new DownloadReferrersTask(layer, id, type));
     159            for (PrimitiveId id : ids) {
     160                Main.worker.submit(new DownloadReferrersTask(layer, id));
     161            }
     162        }
     163       
     164        Runnable showErrorsAndWarnings = new Runnable() {
     165            @Override
     166            public void run() {
     167                Set<PrimitiveId> errs = task.getMissingPrimitives();
     168                if (errs != null && !errs.isEmpty()) {
     169                    final ExtendedDialog dlg = reportProblemDialog(errs,
     170                            trn("Object could not be downloaded", "Some objects could not be downloaded", errs.size()),
     171                            trn("One object could not be downloaded.<br>",
     172                                "{0} objects could not be downloaded.<br>",
     173                                errs.size(),
     174                                errs.size())
     175                            + tr("The server replied with response code 404.<br>"
     176                                + "This usually means, the server does not know an object with the requested id."),
     177                            tr("missing objects:"),
     178                            JOptionPane.ERROR_MESSAGE
     179                    );
     180                    try {
     181                        SwingUtilities.invokeAndWait(new Runnable() {
     182                            @Override
     183                            public void run() {
     184                                dlg.showDialog();
     185                            }
     186                        });
     187                    } catch (InterruptedException ex) {
     188                    } catch (InvocationTargetException ex) {
     189                    }
     190                }
     191               
     192                Set<PrimitiveId> del = new TreeSet<PrimitiveId>();
     193                DataSet ds = getCurrentDataSet();
     194                for (PrimitiveId id : ids) {
     195                    OsmPrimitive osm = ds.getPrimitiveById(id);
     196                    if (osm != null && osm.isDeleted()) {
     197                        del.add(id);
     198                    }
     199                }
     200                if (del != null && !del.isEmpty()) {
     201                    final ExtendedDialog dlg = reportProblemDialog(del,
     202                            trn("Object deleted", "Objects deleted", del.size()),
     203                            trn(
     204                                "One downloaded object is deleted.",
     205                                "{0} downloaded objects are deleted.",
     206                                del.size(),
     207                                del.size()),
     208                            null,
     209                            JOptionPane.WARNING_MESSAGE
     210                    );
     211                    SwingUtilities.invokeLater(new Runnable() {
     212                        @Override
     213                        public void run() {
     214                            dlg.showDialog();
     215                        }
     216                    });
     217                }
     218            }
     219        };
     220        Main.worker.submit(showErrorsAndWarnings);
     221    }
     222   
     223    private ExtendedDialog reportProblemDialog(Set<PrimitiveId> errs,
     224            String TITLE, String TEXT, String LIST_LABEL, int msgType) {
     225        JPanel p = new JPanel(new GridBagLayout());
     226        p.add(new HtmlPanel(TEXT), GBC.eop());
     227        if (LIST_LABEL != null) {
     228            JLabel missing = new JLabel(LIST_LABEL);
     229            missing.setFont(missing.getFont().deriveFont(Font.PLAIN));
     230            p.add(missing, GBC.eol());
     231        }
     232        JTextArea txt = new JTextArea();
     233        txt.setFont(new Font("Monospaced", txt.getFont().getStyle(), txt.getFont().getSize()));
     234        txt.setEditable(false);
     235        txt.setBackground(p.getBackground());
     236        txt.setColumns(40);
     237        txt.setRows(1);
     238        txt.setText(Utils.join(", ", errs));
     239        JScrollPane scroll = new JScrollPane(txt);
     240        p.add(scroll, GBC.eop().weight(1.0, 0.0).fill(GBC.HORIZONTAL));
     241
     242        return new ExtendedDialog(
     243                Main.parent,
     244                TITLE,
     245                new String[] { tr("Ok") })
     246            .setButtonIcons(new String[] { "ok" })
     247            .setIcon(msgType)
     248            .setContent(p, false);
     249    }
     250
     251    private static class SimpleListItem  {
     252        final String data;
     253        final String text;
     254       
     255        public SimpleListItem(String data, String text) { 
     256            this.data = data;   
     257            this.text = text;
     258        }
     259       
     260        @Override public String toString() {
     261            return text;
    119262        }
    120263    }
  • trunk/src/org/openstreetmap/josm/gui/widgets/OsmIdTextField.java

    r3083 r4081  
    44import static org.openstreetmap.josm.tools.I18n.tr;
    55
     6import java.util.ArrayList;
     7import java.util.List;
     8import java.util.StringTokenizer;
     9
    610import javax.swing.JTextField;
    711import javax.swing.text.JTextComponent;
     12
     13import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
     14import org.openstreetmap.josm.data.osm.PrimitiveId;
     15import org.openstreetmap.josm.data.osm.SimplePrimitiveId;
    816
    917/**
     
    1826    }
    1927
    20     public int getOsmId() {
     28    public void setType(OsmPrimitiveType type) {
     29        validator.type = type;
     30    }
     31
     32    public long getOsmId() {
    2133        return validator.getOsmId();
    2234    }
     35
     36    /**
     37     * Get entered ID list - supports "1,2,3" "1 2   ,3" or even "1 2 3 v2 6 v8"
     38     * @return list of id's
     39     */
     40    public List<PrimitiveId> getIds() {
     41        return validator.ids;
     42    }
     43
     44    public boolean readOsmIds() {
     45        return validator.readOsmIds();
     46    }
     47
    2348
    2449    /**
     
    3257        }
    3358
     59        private List<PrimitiveId> ids = new ArrayList<PrimitiveId>();
     60        private OsmPrimitiveType type;
     61
    3462        public OsmIdValidator(JTextComponent tc) {
    3563            super(tc, false);
     
    3866        @Override
    3967        public boolean isValid() {
    40             return getOsmId() > 0;
     68            return getOsmId() > 0 || readOsmIds() != false;
    4169        }
    4270
     
    5078        }
    5179
    52         public int getOsmId() {
     80        public long getOsmId() {
    5381            String value  = getComponent().getText();
    5482            if (value == null || value.trim().length() == 0) return 0;
    5583            try {
    56                 int osmId = Integer.parseInt(value.trim());
    57                 if (osmId > 0) return osmId;
     84                long osmId = Long.parseLong(value.trim());
     85                if (osmId > 0)
     86                    return osmId;
    5887                return 0;
    5988            } catch(NumberFormatException e) {
     
    6190            }
    6291        }
     92       
     93        public boolean readOsmIds() {
     94            String value  = getComponent().getText();
     95            char c;
     96            if (value == null || value.trim().length() == 0) return false;
     97            try {
     98                ids.clear();
     99                StringTokenizer st = new StringTokenizer(value,",.+/ \t\n");
     100                String s;
     101                while (st.hasMoreTokens()) {
     102                    s = st.nextToken();
     103                    // convert tokens to int skipping v-words (version v2 etc)
     104                    c = s.charAt(0);
     105                    if (c=='v') {
     106                        continue;
     107                    }
     108                    else if (c=='n') {
     109                        ids.add(new SimplePrimitiveId(Long.parseLong(s.substring(1)), OsmPrimitiveType.NODE));
     110                    } else if (c=='w') {
     111                        ids.add(new SimplePrimitiveId(Long.parseLong(s.substring(1)), OsmPrimitiveType.WAY));
     112                    } else if (c=='r') {
     113                        ids.add(new SimplePrimitiveId(Long.parseLong(s.substring(1)), OsmPrimitiveType.RELATION));
     114                    } else if (type==OsmPrimitiveType.NODE) {
     115                        ids.add(new SimplePrimitiveId(Long.parseLong(s), OsmPrimitiveType.NODE));
     116                    } else if (type==OsmPrimitiveType.WAY) {
     117                        ids.add(new SimplePrimitiveId(Long.parseLong(s), OsmPrimitiveType.WAY));
     118                    } else if (type==OsmPrimitiveType.RELATION) {
     119                        ids.add(new SimplePrimitiveId(Long.parseLong(s), OsmPrimitiveType.RELATION));
     120                    }
     121                }
     122                return true;
     123            } catch(NumberFormatException e) {
     124                return false;
     125            }
     126        }
    63127    }
    64128}
  • trunk/src/org/openstreetmap/josm/gui/widgets/OsmPrimitiveTypesComboBox.java

    r3905 r4081  
    1919
    2020    public OsmPrimitiveType getType() {
    21         return (OsmPrimitiveType)this.getSelectedItem();
     21        try {
     22            return (OsmPrimitiveType)this.getSelectedItem();
     23        } catch (Exception e) {
     24            return null;
     25        }
    2226    }
    2327}
  • trunk/src/org/openstreetmap/josm/io/MultiFetchServerObjectReader.java

    r3995 r4081  
    1010import java.util.HashSet;
    1111import java.util.Iterator;
     12import java.util.LinkedHashSet;
    1213import java.util.NoSuchElementException;
    1314import java.util.Set;
     
    2223import org.openstreetmap.josm.data.osm.Relation;
    2324import org.openstreetmap.josm.data.osm.RelationMember;
     25import org.openstreetmap.josm.data.osm.SimplePrimitiveId;
    2426import org.openstreetmap.josm.data.osm.Way;
    2527import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
     
    4951public class MultiFetchServerObjectReader extends OsmServerReader{
    5052
    51     static private Logger logger = Logger.getLogger(MultiFetchServerObjectReader.class.getName());
     53    static final private Logger logger = Logger.getLogger(MultiFetchServerObjectReader.class.getName());
    5254    /**
    5355     * the max. number of primitives retrieved in one step. Assuming IDs with 7 digits,
     
    5961    static private int MAX_IDS_PER_REQUEST = 200;
    6062
    61     private HashSet<Long> nodes;
    62     private HashSet<Long> ways;
    63     private HashSet<Long> relations;
    64     private HashSet<Long> missingPrimitives;
     63    private Set<Long> nodes;
     64    private Set<Long> ways;
     65    private Set<Long> relations;
     66    private Set<PrimitiveId> missingPrimitives;
    6567    private DataSet outputDataSet;
    6668
     
    7072     */
    7173    public MultiFetchServerObjectReader() {
    72         nodes = new HashSet<Long>();
    73         ways = new HashSet<Long>();
    74         relations = new HashSet<Long>();
     74        nodes = new LinkedHashSet<Long>();
     75        ways = new LinkedHashSet<Long>();
     76        relations = new LinkedHashSet<Long>();
    7577        this.outputDataSet = new DataSet();
    76         this.missingPrimitives = new HashSet<Long>();
     78        this.missingPrimitives = new LinkedHashSet<PrimitiveId>();
    7779    }
    7880
     
    117119    }
    118120
    119     /**
    120      * appends a {@see Node}s id to the list of ids which will be fetched from the server.
    121      *
    122      * @param node  the node (ignored, if null)
    123      * @return this
    124      *
    125      */
    126121    public MultiFetchServerObjectReader append(DataSet ds, long id, OsmPrimitiveType type) {
    127122        switch(type) {
    128123        case NODE:
    129124            Node n = (Node)ds.getPrimitiveById(id,type);
    130             append(n);
     125            appendNode(n);
    131126            break;
    132127        case WAY:
    133128            Way w= (Way)ds.getPrimitiveById(id,type);
    134             append(w);
     129            appendWay(w);
    135130            break;
    136131        case RELATION:
    137132            Relation r = (Relation)ds.getPrimitiveById(id,type);
    138             append(r);
     133            appendRelation(r);
    139134            break;
    140135        }
     
    149144     *
    150145     */
    151     public MultiFetchServerObjectReader append(Node node) {
     146    public MultiFetchServerObjectReader appendNode(Node node) {
    152147        if (node == null) return this;
    153148        remember(node.getPrimitiveId());
     
    162157     *
    163158     */
    164     public MultiFetchServerObjectReader append(Way way) {
     159    public MultiFetchServerObjectReader appendWay(Way way) {
    165160        if (way == null) return this;
    166161        if (way.isNew()) return this;
     
    181176     *
    182177     */
    183     public MultiFetchServerObjectReader append(Relation relation) {
     178    protected MultiFetchServerObjectReader appendRelation(Relation relation) {
    184179        if (relation == null) return this;
    185180        if (relation.isNew()) return this;
     
    194189            }
    195190            if (!member.getMember().isIncomplete()) {
    196                 appendGeneric(member.getMember());
    197             }
    198         }
    199         return this;
    200     }
    201 
    202     protected MultiFetchServerObjectReader appendGeneric(OsmPrimitive primitive) {
     191                append(member.getMember());
     192            }
     193        }
     194        return this;
     195    }
     196
     197    public MultiFetchServerObjectReader append(OsmPrimitive primitive) {
    203198        if (OsmPrimitiveType.from(primitive).equals(OsmPrimitiveType.NODE))
    204             return append((Node)primitive);
     199            return appendNode((Node)primitive);
    205200        else if (OsmPrimitiveType.from(primitive).equals(OsmPrimitiveType.WAY))
    206             return append((Way)primitive);
     201            return appendWay((Way)primitive);
    207202        else if (OsmPrimitiveType.from(primitive).equals(OsmPrimitiveType.RELATION))
    208             return append((Relation)primitive);
     203            return appendRelation((Relation)primitive);
    209204
    210205        return this;
     
    225220        if (primitives == null) return this;
    226221        for (OsmPrimitive primitive : primitives) {
    227             appendGeneric(primitive);
     222            append(primitive);
    228223        }
    229224        return this;
     
    367362                if (e.getResponseCode() == HttpURLConnection.HTTP_NOT_FOUND) {
    368363                    logger.warning(tr("Server replied with response code 404 for id {0}. Skipping.", Long.toString(id)));
    369                     missingPrimitives.add(id);
     364                    missingPrimitives.add(new SimplePrimitiveId(id, type));
    370365                    continue;
    371366                }
     
    449444        progressMonitor.beginTask(trn("Downloading {0} object from ''{1}''", "Downloading {0} objects from ''{1}''", n, n, OsmApi.getOsmApi().getBaseUrl()));
    450445        try {
    451             missingPrimitives = new HashSet<Long>();
     446            missingPrimitives = new HashSet<PrimitiveId>();
    452447            if (isCanceled())return null;
    453448            fetchPrimitives(ways,OsmPrimitiveType.WAY, progressMonitor);
     
    472467     * @return the set of ids of missing primitives
    473468     */
    474     public Set<Long> getMissingPrimitives() {
     469    public Set<PrimitiveId> getMissingPrimitives() {
    475470        return missingPrimitives;
    476471    }
  • trunk/src/org/openstreetmap/josm/tools/I18n.java

    r3957 r4081  
    177177
    178178    /**
    179      * Example: trn("Found {0} error!", "Found {0} errors!", i, Integer.toString(i));
     179     * Example: trn("Found {0} error in {1}!", "Found {0} errors in {1}!", i, Integer.toString(i), url);
    180180     */
    181181    public static final String trn(String text, String pluralText, long n, Object... objects) {
Note: See TracChangeset for help on using the changeset viewer.