Ticket #21605: 21605.patch

File 21605.patch, 9.2 KB (added by taylor.smock, 4 years ago)

Initial patch, needs work on UI

  • src/org/openstreetmap/josm/data/ImageData.java

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
    diff --git a/src/org/openstreetmap/josm/data/ImageData.java b/src/org/openstreetmap/josm/data/ImageData.java
    a b  
    1010import org.openstreetmap.josm.data.coor.LatLon;
    1111import org.openstreetmap.josm.data.gpx.GpxImageEntry;
    1212import org.openstreetmap.josm.data.osm.QuadBuckets;
     13import org.openstreetmap.josm.gui.layer.Layer;
    1314import org.openstreetmap.josm.gui.layer.geoimage.ImageEntry;
    1415import org.openstreetmap.josm.tools.ListenerList;
    1516
     
    4142
    4243    private final ListenerList<ImageDataUpdateListener> listeners = ListenerList.create();
    4344    private final QuadBuckets<ImageEntry> geoImages = new QuadBuckets<>();
     45    private Layer layer;
     46
    4447
    4548    /**
    4649     * Construct a new image container without images
     
    375378        notifyImageUpdate();
    376379    }
    377380
     381    /**
     382     * Set the layer for use with {@link org.openstreetmap.josm.gui.layer.geoimage.ImageViewerDialog#displayImages(Layer, List)}
     383     * @param layer The layer to use for organization
     384     * @since xxx
     385     */
     386    public void setLayer(Layer layer) {
     387        this.layer = layer;
     388    }
     389
     390    /**
     391     * Get the layer that this data is associated with. May be {@code null}.
     392     * @return The layer this data is associated with.
     393     * @since xxx
     394     */
     395    public Layer getLayer() {
     396        return this.layer;
     397    }
     398
     399
    378400    /**
    379401     * Add a listener that listens to image data changes
    380402     * @param listener the {@link ImageDataUpdateListener}
  • src/org/openstreetmap/josm/gui/layer/geoimage/GeoImageLayer.java

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
    diff --git a/src/org/openstreetmap/josm/gui/layer/geoimage/GeoImageLayer.java b/src/org/openstreetmap/josm/gui/layer/geoimage/GeoImageLayer.java
    a b  
    171171        this.gpxData = gpxData;
    172172        this.useThumbs = useThumbs;
    173173        this.data.addImageDataUpdateListener(this);
     174        this.data.setLayer(this);
    174175    }
    175176
    176177    private final class ImageMouseListener extends MouseAdapter {
     
    231232                    }
    232233                } else {
    233234                    data.setSelectedImage(img);
     235                    ImageViewerDialog.getInstance().displayImages(GeoImageLayer.this, Collections.singletonList(img));
    234236                }
    235237            }
    236238        }
     
    521523     * Show current photo on map and in image viewer.
    522524     */
    523525    public void showCurrentPhoto() {
    524         if (data.getSelectedImage() != null) {
    525             clearOtherCurrentPhotos();
    526         }
    527526        updateBufferAndRepaint();
    528527    }
    529528
     
    628627        }
    629628    }
    630629
    631     /**
    632      * Clears the currentPhoto of the other GeoImageLayer's. Otherwise there could be multiple selected photos.
    633      */
    634     private void clearOtherCurrentPhotos() {
    635         for (GeoImageLayer layer:
    636                  MainApplication.getLayerManager().getLayersOfType(GeoImageLayer.class)) {
    637             if (layer != this) {
    638                 layer.getImageData().clearSelectedImage();
    639             }
    640         }
    641     }
    642 
    643630    /**
    644631     * Registers a map mode for which the functionality of this layer should be available.
    645632     * @param mapMode Map mode to be registered
  • src/org/openstreetmap/josm/gui/layer/geoimage/ImageViewerDialog.java

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
    diff --git a/src/org/openstreetmap/josm/gui/layer/geoimage/ImageViewerDialog.java b/src/org/openstreetmap/josm/gui/layer/geoimage/ImageViewerDialog.java
    a b  
    88import java.awt.BorderLayout;
    99import java.awt.Component;
    1010import java.awt.Dimension;
     11import java.awt.FlowLayout;
    1112import java.awt.GridBagConstraints;
    1213import java.awt.GridBagLayout;
    1314import java.awt.event.ActionEvent;
     
    2122import java.util.ArrayList;
    2223import java.util.Arrays;
    2324import java.util.Collections;
     25import java.util.HashMap;
    2426import java.util.List;
     27import java.util.Map;
    2528import java.util.Objects;
    2629import java.util.Optional;
    2730import java.util.concurrent.Future;
     
    5255import org.openstreetmap.josm.gui.layer.LayerManager.LayerChangeListener;
    5356import org.openstreetmap.josm.gui.layer.LayerManager.LayerOrderChangeEvent;
    5457import org.openstreetmap.josm.gui.layer.LayerManager.LayerRemoveEvent;
     58import org.openstreetmap.josm.gui.layer.MainLayerManager;
    5559import org.openstreetmap.josm.gui.layer.MainLayerManager.ActiveLayerChangeEvent;
    5660import org.openstreetmap.josm.gui.layer.MainLayerManager.ActiveLayerChangeListener;
    5761import org.openstreetmap.josm.gui.layer.imagery.ImageryFilterSettings;
     
    120124    private JButton btnOpenExternal;
    121125    private JButton btnDeleteFromDisk;
    122126    private JToggleButton tbCentre;
     127    /** The layer tab (used to select images when multiple layers provide images, makes for easy switching) */
     128    private JPanel layers;
    123129
    124130    private ImageViewerDialog() {
    125131        super(tr("Geotagged Images"), "geoimage", tr("Display geotagged images"), Shortcut.registerShortcut("tools:geotagged",
     
    152158
    153159    private void build() {
    154160        JPanel content = new JPanel(new BorderLayout());
     161        this.layers = new JPanel(new FlowLayout(FlowLayout.LEADING));
     162        content.add(layers, BorderLayout.NORTH);
    155163
    156164        content.add(imgDisplay, BorderLayout.CENTER);
    157165
     
    213221        createLayout(content, false, null);
    214222    }
    215223
     224    private void updateLayers() {
     225        if (this.tabbedEntries.size() <= 1) {
     226            this.layers.setVisible(false);
     227        } else {
     228            final IImageEntry<?> current;
     229            synchronized (this) {
     230                current = this.currentEntry;
     231            }
     232            this.layers.setVisible(true);
     233            // Remove all old components
     234            this.layers.removeAll();
     235            MainLayerManager layerManager = MainApplication.getLayerManager();
     236            List<Layer> invalidLayers = this.tabbedEntries.keySet().stream().filter(layer -> !layerManager.containsLayer(layer))
     237                    .collect(Collectors.toList());
     238            // We need to do multiple calls to avoid ConcurrentModificationExceptions
     239            invalidLayers.forEach(this.tabbedEntries::remove);
     240            for (Map.Entry<Layer, List<IImageEntry<?>>> entry : this.tabbedEntries.entrySet()) {
     241                JButton layerButton = new JButton(tr(entry.getKey().getLabel()));
     242                layerButton.addActionListener(l -> this.displayImages(entry.getKey(), entry.getValue()));
     243                if (entry.getValue().contains(current)) {
     244                    layerButton.setSelected(true);
     245                }
     246                this.layers.add(layerButton);
     247            }
     248            this.layers.invalidate();
     249        }
     250    }
     251
    216252    @Override
    217253    public void destroy() {
    218254        MainApplication.getLayerManager().removeActiveLayerChangeListener(this);
     
    551587        return wasEnabled;
    552588    }
    553589
     590    /** Used for tabbed panes */
     591    private final transient Map<Layer, List<IImageEntry<?>>> tabbedEntries = new HashMap<>();
    554592    private transient IImageEntry<? extends IImageEntry<?>> currentEntry;
    555593
    556594    /**
     
    578616     * @since 18246
    579617     */
    580618    public void displayImages(List<IImageEntry<?>> entries) {
     619        this.displayImages((Layer) null, entries);
     620    }
     621
     622    /**
     623     * Displays images for the given layer.
     624     * @param layer The layer to use for the tab ui
     625     * @param entries image entries
     626     * @since xxx
     627     */
     628    public void displayImages(Layer layer, List<IImageEntry<?>> entries) {
    581629        boolean imageChanged;
    582630        IImageEntry<?> entry = entries != null && entries.size() == 1 ? entries.get(0) : null;
    583631
     
    598646            }
    599647        }
    600648
     649        if (entries == null || entries.isEmpty()) {
     650            this.tabbedEntries.remove(layer);
     651        } else {
     652            this.tabbedEntries.put(layer, entries);
     653        }
     654        this.updateLayers();
    601655        if (entry != null) {
    602656            this.updateButtonsNonNullEntry(entry, imageChanged);
    603657        } else {
     
    819873
    820874    @Override
    821875    public void selectedImageChanged(ImageData data) {
    822         displayImages(new ArrayList<>(data.getSelectedImages()));
     876        displayImages(data.getLayer(), new ArrayList<>(data.getSelectedImages()));
    823877    }
    824878
    825879    @Override
    826880    public void imageDataUpdated(ImageData data) {
    827         displayImages(new ArrayList<>(data.getSelectedImages()));
     881        displayImages(data.getLayer(), new ArrayList<>(data.getSelectedImages()));
    828882    }
    829883}