Ticket #18340: 18340.1.patch

File 18340.1.patch, 21.4 KB (added by taylor.smock, 6 years ago)

Update patch from r15528 to r16500. This is just so the patch applies cleanly. No other changes have been made. Renaming/translations/etc. will be in the next patch.

  • src/org/openstreetmap/josm/gui/download/OSMDownloadSource.java

     
    88import java.awt.Dimension;
    99import java.awt.Font;
    1010import java.awt.GridBagLayout;
     11import java.lang.reflect.InvocationTargetException;
    1112import java.util.ArrayList;
     13import java.util.Collections;
    1214import java.util.List;
    1315import java.util.concurrent.ExecutionException;
    1416import java.util.concurrent.Future;
     
    2426import org.openstreetmap.josm.actions.downloadtasks.DownloadNotesTask;
    2527import org.openstreetmap.josm.actions.downloadtasks.DownloadOsmTask;
    2628import org.openstreetmap.josm.actions.downloadtasks.DownloadParams;
     29import org.openstreetmap.josm.actions.downloadtasks.DownloadTask;
    2730import org.openstreetmap.josm.actions.downloadtasks.PostDownloadHandler;
    2831import org.openstreetmap.josm.data.Bounds;
    2932import org.openstreetmap.josm.data.ProjectionBounds;
    3033import org.openstreetmap.josm.data.ViewportData;
     34import org.openstreetmap.josm.data.gpx.GpxData;
     35import org.openstreetmap.josm.data.osm.DataSet;
     36import org.openstreetmap.josm.data.osm.NoteData;
    3137import org.openstreetmap.josm.data.preferences.BooleanProperty;
    3238import org.openstreetmap.josm.gui.MainApplication;
    3339import org.openstreetmap.josm.gui.MapFrame;
     
    4955     */
    5056    public static final String SIMPLE_NAME = "osmdownloadpanel";
    5157
     58    /** The possible methods to get data */
     59    static final List<DataDownloadType> DOWNLOAD_POSSIBILITIES = new ArrayList<>();
     60    static {
     61        // Order is important (determines button order, and what gets zoomed to)
     62        DOWNLOAD_POSSIBILITIES.add(new OsmDataDownloadType());
     63        DOWNLOAD_POSSIBILITIES.add(new GpsDataDownloadType());
     64        DOWNLOAD_POSSIBILITIES.add(new NotesDataDownloadType());
     65    }
     66
    5267    @Override
    5368    public AbstractDownloadSourcePanel<OSMDownloadData> createPanel(DownloadDialog dialog) {
    5469        return new OSMDownloadSourcePanel(this, dialog);
     
    6075                .orElseThrow(() -> new IllegalArgumentException("OSM downloads requires bounds"));
    6176        boolean zoom = settings.zoomToData();
    6277        boolean newLayer = settings.asNewLayer();
    63         List<Pair<AbstractDownloadTask<?>, Future<?>>> tasks = new ArrayList<>();
    64 
    65         if (data.isDownloadOSMData()) {
    66             DownloadOsmTask task = new DownloadOsmTask();
    67             task.setZoomAfterDownload(zoom && !data.isDownloadGPX() && !data.isDownloadNotes());
    68             Future<?> future = task.download(new DownloadParams().withNewLayer(newLayer), bbox, null);
    69             MainApplication.worker.submit(new PostDownloadHandler(task, future));
    70             if (zoom) {
    71                 tasks.add(new Pair<>(task, future));
     78        final List<Pair<AbstractDownloadTask<?>, Future<?>>> tasks = new ArrayList<>();
     79        DataDownloadType zoomTask = zoom ? data.getDownloadPossibilities().stream().findFirst().orElse(null) : null;
     80        data.getDownloadPossibilities().parallelStream().filter(DataDownloadType::isEnabled).forEach(type -> {
     81            try {
     82                AbstractDownloadTask<?> task = type.getDownloadClass().getDeclaredConstructor().newInstance();
     83                task.setZoomAfterDownload(type.equals(zoomTask));
     84                Future<?> future = task.download(new DownloadParams().withNewLayer(newLayer), bbox, null);
     85                MainApplication.worker.submit(new PostDownloadHandler(task, future));
     86                if (zoom) {
     87                    tasks.add(new Pair<AbstractDownloadTask<?>, Future<?>>(task, future));
     88                }
     89            } catch (InstantiationException | IllegalAccessException | IllegalArgumentException
     90                    | InvocationTargetException | NoSuchMethodException | SecurityException e) {
     91                Logging.error(e);
    7292            }
    73         }
     93        });
    7494
    75         if (data.isDownloadGPX()) {
    76             DownloadGpsTask task = new DownloadGpsTask();
    77             task.setZoomAfterDownload(zoom && !data.isDownloadOSMData() && !data.isDownloadNotes());
    78             Future<?> future = task.download(new DownloadParams().withNewLayer(newLayer), bbox, null);
    79             MainApplication.worker.submit(new PostDownloadHandler(task, future));
    80             if (zoom) {
    81                 tasks.add(new Pair<>(task, future));
    82             }
    83         }
    84 
    85         if (data.isDownloadNotes()) {
    86             DownloadNotesTask task = new DownloadNotesTask();
    87             task.setZoomAfterDownload(zoom && !data.isDownloadOSMData() && !data.isDownloadGPX());
    88             Future<?> future = task.download(new DownloadParams(), bbox, null);
    89             MainApplication.worker.submit(new PostDownloadHandler(task, future));
    90             if (zoom) {
    91                 tasks.add(new Pair<>(task, future));
    92             }
    93         }
    94 
    9595        if (zoom && tasks.size() > 1) {
    9696            MainApplication.worker.submit(() -> {
    9797                ProjectionBounds bounds = null;
     
    130130    }
    131131
    132132    /**
     133     * @return The possible downloads that JOSM can make in the default Download
     134     *         screen
     135     * @since xxx
     136     */
     137    public List<DataDownloadType> getDownloadTypes() {
     138        return Collections.unmodifiableList(DOWNLOAD_POSSIBILITIES);
     139    }
     140
     141    /**
     142     * @param type The DataDownloadType object to remove
     143     * @return true if the list was modified
     144     * @since xxx
     145     */
     146    public boolean removeDownloadType(DataDownloadType type) {
     147        boolean modified = false;
     148        if (!(type instanceof OsmDataDownloadType) && !(type instanceof GpsDataDownloadType)
     149                && !(type instanceof NotesDataDownloadType)) {
     150            modified = DOWNLOAD_POSSIBILITIES.remove(type);
     151        }
     152        return modified;
     153    }
     154
     155    /**
     156     * Add a download type to the default JOSM download window
     157     *
     158     * @param type The initialized type to download
     159     * @return true if the list was modified
     160     * @since xxx
     161     */
     162    public boolean addDownloadType(DataDownloadType type) {
     163        boolean modified = false;
     164        if (!(type instanceof OsmDataDownloadType) && !(type instanceof GpsDataDownloadType)
     165                && !(type instanceof NotesDataDownloadType)
     166                || DOWNLOAD_POSSIBILITIES.parallelStream()
     167                        .noneMatch(possibility -> type.getClass().isInstance(possibility))) {
     168            modified = DOWNLOAD_POSSIBILITIES.add(type);
     169        }
     170        return modified;
     171    }
     172
     173    /**
    133174     * The GUI representation of the OSM download source.
    134175     * @since 12652
    135176     */
    136177    public static class OSMDownloadSourcePanel extends AbstractDownloadSourcePanel<OSMDownloadData> {
    137 
    138         private final JCheckBox cbDownloadOsmData;
    139         private final JCheckBox cbDownloadGpxData;
    140         private final JCheckBox cbDownloadNotes;
    141178        private final JLabel sizeCheck = new JLabel();
    142179
    143         private static final BooleanProperty DOWNLOAD_OSM = new BooleanProperty("download.osm.data", true);
    144         private static final BooleanProperty DOWNLOAD_GPS = new BooleanProperty("download.osm.gps", false);
    145         private static final BooleanProperty DOWNLOAD_NOTES = new BooleanProperty("download.osm.notes", false);
    146 
    147180        /**
    148181         * Label used in front of data types available for download. Made public for reuse in other download dialogs.
    149182         * @since 16155
     
    166199
    167200            // adding the download tasks
    168201            add(new JLabel(tr(DATA_SOURCES_AND_TYPES)), GBC.std().insets(5, 5, 1, 5).anchor(GBC.CENTER));
    169             cbDownloadOsmData = new JCheckBox(tr("OpenStreetMap data"), true);
    170             cbDownloadOsmData.setToolTipText(tr("Select to download OSM data in the selected download area."));
    171             cbDownloadOsmData.getModel().addChangeListener(checkboxChangeListener);
    172 
    173             cbDownloadGpxData = new JCheckBox(tr("Raw GPS data"));
    174             cbDownloadGpxData.setToolTipText(tr("Select to download GPS traces in the selected download area."));
    175             cbDownloadGpxData.getModel().addChangeListener(checkboxChangeListener);
    176 
    177             cbDownloadNotes = new JCheckBox(tr("Notes"));
    178             cbDownloadNotes.setToolTipText(tr("Select to download notes in the selected download area."));
    179             cbDownloadNotes.getModel().addChangeListener(checkboxChangeListener);
    180 
    181202            Font labelFont = sizeCheck.getFont();
    182203            sizeCheck.setFont(labelFont.deriveFont(Font.PLAIN, labelFont.getSize()));
    183204
    184             add(cbDownloadOsmData, GBC.std().insets(1, 5, 1, 5));
    185             add(cbDownloadGpxData, GBC.std().insets(1, 5, 1, 5));
    186             add(cbDownloadNotes, GBC.eol().insets(1, 5, 1, 5));
     205            DOWNLOAD_POSSIBILITIES
     206                    .forEach(obj -> add(obj.getCheckBox(checkboxChangeListener), GBC.std().insets(1, 5, 1, 5)));
    187207            add(sizeCheck, GBC.eol().anchor(GBC.EAST).insets(5, 5, 5, 2));
    188208
    189209            setMinimumSize(new Dimension(450, 115));
     
    191211
    192212        @Override
    193213        public OSMDownloadData getData() {
    194             return new OSMDownloadData(
    195                     isDownloadOsmData(),
    196                     isDownloadNotes(),
    197                     isDownloadGpxData());
     214            return new OSMDownloadData(DOWNLOAD_POSSIBILITIES);
    198215        }
    199216
    200217        @Override
    201218        public void rememberSettings() {
    202             DOWNLOAD_OSM.put(isDownloadOsmData());
    203             DOWNLOAD_GPS.put(isDownloadGpxData());
    204             DOWNLOAD_NOTES.put(isDownloadNotes());
     219            DOWNLOAD_POSSIBILITIES.forEach(type -> type.getBooleanProperty().put(type.getCheckBox().isSelected()));
    205220        }
    206221
    207222        @Override
    208223        public void restoreSettings() {
    209             cbDownloadOsmData.setSelected(DOWNLOAD_OSM.get());
    210             cbDownloadGpxData.setSelected(DOWNLOAD_GPS.get());
    211             cbDownloadNotes.setSelected(DOWNLOAD_NOTES.get());
     224            DOWNLOAD_POSSIBILITIES.forEach(type -> type.getCheckBox().setSelected(type.isEnabled()));
    212225        }
    213226
    214227        @Override
     
    232245             * must be chosen : raw osm data, gpx data, notes.
    233246             * If none of those are selected, then the corresponding dialog is shown to inform the user.
    234247             */
    235             if (!isDownloadOsmData() && !isDownloadGpxData() && !isDownloadNotes()) {
     248            if (DOWNLOAD_POSSIBILITIES.parallelStream().noneMatch(type -> type.isEnabled())) {
     249                StringBuilder line1 = new StringBuilder("<html>");
     250                StringBuilder line2 = new StringBuilder(tr("Please choose to either download"));
     251                DOWNLOAD_POSSIBILITIES.forEach(type -> {
     252                    if (line1.length() == 6) {
     253                        line1.append(tr("Neither"));
     254                    } else {
     255                        line1.append(tr("nor"));
     256                    }
     257                    line1.append(" <strong>").append(type.getCheckBox().getText()).append("</strong> ");
     258                    line2.append(' ').append(type.getCheckBox().getText()).append(tr(", or"));
     259                });
     260                line1.append(tr("is enabled.")).append("<br>");
     261                line2.append(tr(" all.")).append("</html>");
    236262                JOptionPane.showMessageDialog(
    237263                        this.getParent(),
    238                         tr("<html>Neither <strong>{0}</strong> nor <strong>{1}</strong> nor <strong>{2}</strong> is enabled.<br>"
    239                                         + "Please choose to either download OSM data, or GPX data, or Notes, or all.</html>",
    240                                 cbDownloadOsmData.getText(),
    241                                 cbDownloadGpxData.getText(),
    242                                 cbDownloadNotes.getText()
    243                         ),
     264                        line1.append(line2).toString(),
    244265                        tr("Error"),
    245266                        JOptionPane.ERROR_MESSAGE
    246267                );
     
    257278         * Replies true if the user selected to download OSM data
    258279         *
    259280         * @return true if the user selected to download OSM data
     281         * @deprecated since xxx -- use {@link OSMDownloadSource#getDownloadTypes} with
     282         *             {@code get(0).getCheckBox().isSelected()}
    260283         */
     284        @Deprecated
    261285        public boolean isDownloadOsmData() {
    262             return cbDownloadOsmData.isSelected();
     286            return DOWNLOAD_POSSIBILITIES.get(0).getCheckBox().isSelected();
    263287        }
    264288
    265289        /**
     
    266290         * Replies true if the user selected to download GPX data
    267291         *
    268292         * @return true if the user selected to download GPX data
     293         * @deprecated since xxx -- use {@link OSMDownloadSource#getDownloadTypes} with
     294         *             {@code get(1).getCheckBox().isSelected()}
    269295         */
     296        @Deprecated
    270297        public boolean isDownloadGpxData() {
    271             return cbDownloadGpxData.isSelected();
     298            return DOWNLOAD_POSSIBILITIES.get(1).getCheckBox().isSelected();
    272299        }
    273300
    274301        /**
     
    275302         * Replies true if user selected to download notes
    276303         *
    277304         * @return true if user selected to download notes
     305         * @deprecated since xxx -- use {@link OSMDownloadSource#getDownloadTypes} with
     306         *             {@code get(2).getCheckBox().isSelected()}
    278307         */
     308        @Deprecated
    279309        public boolean isDownloadNotes() {
    280             return cbDownloadNotes.isSelected();
     310            return DOWNLOAD_POSSIBILITIES.get(2).getCheckBox().isSelected();
    281311        }
    282312
    283313        @Override
     
    302332                return;
    303333            }
    304334
    305             boolean isAreaTooLarge = false;
    306             if (!isDownloadNotes() && !isDownloadOsmData() && !isDownloadGpxData()) {
    307                 isAreaTooLarge = false;
    308             } else if (isDownloadNotes() && !isDownloadOsmData() && !isDownloadGpxData()) {
    309                 // see max_note_request_area in https://github.com/openstreetmap/openstreetmap-website/blob/master/config/settings.yml
    310                 isAreaTooLarge = bbox.getArea() > Config.getPref().getDouble("osm-server.max-request-area-notes", 25);
    311             } else {
    312                 // see max_request_area in https://github.com/openstreetmap/openstreetmap-website/blob/master/config/settings.yml
    313                 isAreaTooLarge = bbox.getArea() > Config.getPref().getDouble("osm-server.max-request-area", 0.25);
    314             }
    315 
    316             displaySizeCheckResult(isAreaTooLarge);
     335            displaySizeCheckResult(DOWNLOAD_POSSIBILITIES.parallelStream()
     336                    .anyMatch(type -> type.isDownloadAreaTooLarge(bbox)));
    317337        }
    318338
    319339        private void displaySizeCheckResult(boolean isAreaTooLarge) {
     
    332352     * Encapsulates data that is required to download from the OSM server.
    333353     */
    334354    static class OSMDownloadData {
    335         private final boolean downloadOSMData;
    336         private final boolean downloadNotes;
    337         private final boolean downloadGPX;
    338355
    339         OSMDownloadData(boolean downloadOSMData, boolean downloadNotes, boolean downloadGPX) {
    340             this.downloadOSMData = downloadOSMData;
    341             this.downloadNotes = downloadNotes;
    342             this.downloadGPX = downloadGPX;
     356        private List<DataDownloadType> downloadPossibilities;
     357
     358        /**
     359         * @param downloadPossibilities A list of DataDownloadTypes (instantiated, with
     360         *                              options set)
     361         */
     362        OSMDownloadData(List<DataDownloadType> downloadPossibilities) {
     363            this.downloadPossibilities = downloadPossibilities;
    343364        }
    344365
    345         boolean isDownloadOSMData() {
    346             return downloadOSMData;
     366        /**
     367         * @return A list of DataDownloadTypes (instantiated, with options set)
     368         */
     369        public List<DataDownloadType> getDownloadPossibilities() {
     370            return downloadPossibilities;
    347371        }
     372    }
    348373
    349         boolean isDownloadNotes() {
    350             return downloadNotes;
     374    /**
     375     * An interface to allow arbitrary download sources and types in the primary
     376     * download window of JOSM
     377     *
     378     * @since xxx
     379     */
     380    interface DataDownloadType {
     381        /**
     382         * @return The checkbox to be added to the UI
     383         */
     384        default JCheckBox getCheckBox() {
     385            return getCheckBox(null);
    351386        }
    352387
    353         boolean isDownloadGPX() {
    354             return downloadGPX;
     388        /**
     389         * @param checkboxChangeListener The listener for checkboxes (may be
     390         *                               {@code null})
     391         * @return The checkbox to be added to the UI
     392         */
     393        JCheckBox getCheckBox(ChangeListener checkboxChangeListener);
     394
     395        /**
     396         * @return The {@link DownloadTask} class which will be getting the data
     397         */
     398        Class<? extends AbstractDownloadTask<?>> getDownloadClass();
     399
     400        /**
     401         * @return The boolean indicating the last state of the download type
     402         */
     403        default boolean isEnabled() {
     404            return getBooleanProperty().get();
    355405        }
     406
     407        /**
     408         * @return The boolean property for this particular download type
     409         */
     410        BooleanProperty getBooleanProperty();
     411
     412        /**
     413         * Check if the area is too large for the current DataDownloadType
     414         *
     415         * @param bound The bound that will be downloaded
     416         * @return {@code true} if we definitely cannot download the area;
     417         */
     418        boolean isDownloadAreaTooLarge(Bounds bound);
    356419    }
     420
     421    private static class OsmDataDownloadType implements DataDownloadType {
     422        static final BooleanProperty IS_ENABLED = new BooleanProperty("download.osm.data", true);
     423        JCheckBox cbDownloadOsmData;
     424
     425        @Override
     426        public JCheckBox getCheckBox(ChangeListener checkboxChangeListener) {
     427            if (cbDownloadOsmData == null) {
     428                cbDownloadOsmData = new JCheckBox(tr("OpenStreetMap data"), true);
     429                cbDownloadOsmData.setToolTipText(tr("Select to download OSM data in the selected download area."));
     430                cbDownloadOsmData.getModel().addChangeListener(checkboxChangeListener);
     431            }
     432            if (checkboxChangeListener != null) {
     433                cbDownloadOsmData.getModel().addChangeListener(checkboxChangeListener);
     434            }
     435            return cbDownloadOsmData;
     436        }
     437
     438        @Override
     439        public Class<? extends AbstractDownloadTask<DataSet>> getDownloadClass() {
     440            return DownloadOsmTask.class;
     441        }
     442
     443        @Override
     444        public BooleanProperty getBooleanProperty() {
     445            return IS_ENABLED;
     446        }
     447
     448        @Override
     449        public boolean isDownloadAreaTooLarge(Bounds bound) {
     450            // see max_request_area in
     451            // https://github.com/openstreetmap/openstreetmap-website/blob/master/config/example.application.yml
     452            return bound.getArea() > Config.getPref().getDouble("osm-server.max-request-area", 0.25);
     453        }
     454    }
     455
     456    private static class GpsDataDownloadType implements DataDownloadType {
     457        static final BooleanProperty IS_ENABLED = new BooleanProperty("download.osm.gps", false);
     458        private JCheckBox cbDownloadGpxData;
     459
     460        @Override
     461        public JCheckBox getCheckBox(ChangeListener checkboxChangeListener) {
     462            if (cbDownloadGpxData == null) {
     463                cbDownloadGpxData = new JCheckBox(tr("Raw GPS data"));
     464                cbDownloadGpxData.setToolTipText(tr("Select to download GPS traces in the selected download area."));
     465            }
     466            if (checkboxChangeListener != null) {
     467                cbDownloadGpxData.getModel().addChangeListener(checkboxChangeListener);
     468            }
     469
     470            return cbDownloadGpxData;
     471        }
     472
     473        @Override
     474        public Class<? extends AbstractDownloadTask<GpxData>> getDownloadClass() {
     475            return DownloadGpsTask.class;
     476        }
     477
     478        @Override
     479        public BooleanProperty getBooleanProperty() {
     480            return IS_ENABLED;
     481        }
     482
     483        @Override
     484        public boolean isDownloadAreaTooLarge(Bounds bound) {
     485            return false;
     486        }
     487    }
     488
     489    private static class NotesDataDownloadType implements DataDownloadType {
     490        static final BooleanProperty IS_ENABLED = new BooleanProperty("download.osm.notes", false);
     491        private JCheckBox cbDownloadNotes;
     492
     493        @Override
     494        public JCheckBox getCheckBox(ChangeListener checkboxChangeListener) {
     495            if (cbDownloadNotes == null) {
     496                cbDownloadNotes = new JCheckBox(tr("Notes"));
     497                cbDownloadNotes.setToolTipText(tr("Select to download notes in the selected download area."));
     498            }
     499            if (checkboxChangeListener != null) {
     500                cbDownloadNotes.getModel().addChangeListener(checkboxChangeListener);
     501            }
     502
     503            return cbDownloadNotes;
     504        }
     505
     506        @Override
     507        public Class<? extends AbstractDownloadTask<NoteData>> getDownloadClass() {
     508            return DownloadNotesTask.class;
     509        }
     510
     511        @Override
     512        public BooleanProperty getBooleanProperty() {
     513            return IS_ENABLED;
     514        }
     515
     516        @Override
     517        public boolean isDownloadAreaTooLarge(Bounds bound) {
     518            // see max_note_request_area in
     519            // https://github.com/openstreetmap/openstreetmap-website/blob/master/config/example.application.yml
     520            return bound.getArea() > Config.getPref().getDouble("osm-server.max-request-area-notes", 25);
     521        }
     522    }
     523
    357524}