Ticket #21605: 21605.1.patch
| File 21605.1.patch, 10.9 KB (added by , 3 years ago) |
|---|
-
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 10 10 import org.openstreetmap.josm.data.coor.LatLon; 11 11 import org.openstreetmap.josm.data.gpx.GpxImageEntry; 12 12 import org.openstreetmap.josm.data.osm.QuadBuckets; 13 import org.openstreetmap.josm.gui.layer.Layer; 13 14 import org.openstreetmap.josm.gui.layer.geoimage.ImageEntry; 14 15 import org.openstreetmap.josm.tools.ListenerList; 15 16 … … 41 42 42 43 private final ListenerList<ImageDataUpdateListener> listeners = ListenerList.create(); 43 44 private final QuadBuckets<ImageEntry> geoImages = new QuadBuckets<>(); 45 private Layer layer; 46 44 47 45 48 /** 46 49 * Construct a new image container without images … … 375 378 notifyImageUpdate(); 376 379 } 377 380 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 378 400 /** 379 401 * Add a listener that listens to image data changes 380 402 * @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 171 171 this.gpxData = gpxData; 172 172 this.useThumbs = useThumbs; 173 173 this.data.addImageDataUpdateListener(this); 174 this.data.setLayer(this); 174 175 } 175 176 176 177 private final class ImageMouseListener extends MouseAdapter { … … 231 232 } 232 233 } else { 233 234 data.setSelectedImage(img); 235 ImageViewerDialog.getInstance().displayImages(GeoImageLayer.this, Collections.singletonList(img)); 234 236 } 235 237 } 236 238 } … … 521 523 * Show current photo on map and in image viewer. 522 524 */ 523 525 public void showCurrentPhoto() { 524 if (data.getSelectedImage() != null) {525 clearOtherCurrentPhotos();526 }527 526 updateBufferAndRepaint(); 528 527 } 529 528 … … 628 627 } 629 628 } 630 629 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 643 630 /** 644 631 * Registers a map mode for which the functionality of this layer should be available. 645 632 * @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 8 8 import java.awt.BorderLayout; 9 9 import java.awt.Component; 10 10 import java.awt.Dimension; 11 import java.awt.FlowLayout; 11 12 import java.awt.GridBagConstraints; 12 13 import java.awt.GridBagLayout; 13 14 import java.awt.event.ActionEvent; 14 15 import java.awt.event.KeyEvent; 15 16 import java.awt.event.WindowEvent; 17 import java.awt.image.BufferedImage; 16 18 import java.io.IOException; 17 19 import java.io.Serializable; 18 20 import java.time.ZoneOffset; … … 21 23 import java.util.ArrayList; 22 24 import java.util.Arrays; 23 25 import java.util.Collections; 26 import java.util.HashMap; 24 27 import java.util.List; 28 import java.util.Map; 25 29 import java.util.Objects; 26 30 import java.util.Optional; 27 31 import java.util.concurrent.Future; … … 30 34 31 35 import javax.swing.AbstractAction; 32 36 import javax.swing.Box; 37 import javax.swing.ImageIcon; 33 38 import javax.swing.JButton; 39 import javax.swing.JComponent; 34 40 import javax.swing.JLabel; 35 41 import javax.swing.JOptionPane; 36 42 import javax.swing.JPanel; … … 52 58 import org.openstreetmap.josm.gui.layer.LayerManager.LayerChangeListener; 53 59 import org.openstreetmap.josm.gui.layer.LayerManager.LayerOrderChangeEvent; 54 60 import org.openstreetmap.josm.gui.layer.LayerManager.LayerRemoveEvent; 61 import org.openstreetmap.josm.gui.layer.MainLayerManager; 55 62 import org.openstreetmap.josm.gui.layer.MainLayerManager.ActiveLayerChangeEvent; 56 63 import org.openstreetmap.josm.gui.layer.MainLayerManager.ActiveLayerChangeListener; 57 64 import org.openstreetmap.josm.gui.layer.imagery.ImageryFilterSettings; … … 120 127 private JButton btnOpenExternal; 121 128 private JButton btnDeleteFromDisk; 122 129 private JToggleButton tbCentre; 130 /** The layer tab (used to select images when multiple layers provide images, makes for easy switching) */ 131 private JPanel layers; 123 132 124 133 private ImageViewerDialog() { 125 134 super(tr("Geotagged Images"), "geoimage", tr("Display geotagged images"), Shortcut.registerShortcut("tools:geotagged", … … 152 161 153 162 private void build() { 154 163 JPanel content = new JPanel(new BorderLayout()); 164 this.layers = new JPanel(new FlowLayout(FlowLayout.LEADING)); 165 content.add(layers, BorderLayout.NORTH); 155 166 156 167 content.add(imgDisplay, BorderLayout.CENTER); 157 168 … … 213 224 createLayout(content, false, null); 214 225 } 215 226 227 private void updateLayers() { 228 if (this.tabbedEntries.size() <= 1) { 229 this.layers.setVisible(false); 230 } else { 231 final IImageEntry<?> current; 232 synchronized (this) { 233 current = this.currentEntry; 234 } 235 this.layers.setVisible(true); 236 // Remove all old components 237 this.layers.removeAll(); 238 MainLayerManager layerManager = MainApplication.getLayerManager(); 239 List<Layer> invalidLayers = this.tabbedEntries.keySet().stream().filter(layer -> !layerManager.containsLayer(layer)) 240 .collect(Collectors.toList()); 241 // We need to do multiple calls to avoid ConcurrentModificationExceptions 242 invalidLayers.forEach(this.tabbedEntries::remove); 243 List<JButton> layerButtons = new ArrayList<>(this.tabbedEntries.size()); 244 for (Map.Entry<Layer, List<IImageEntry<?>>> entry : this.tabbedEntries.entrySet()) { 245 JButton layerButton = new JButton(tr(entry.getKey().getLabel())); 246 layerButton.addActionListener(l -> this.displayImages(entry.getKey(), entry.getValue())); 247 if (!this.isDocked && entry.getValue().size() == 1) { 248 try { 249 BufferedImage image = entry.getValue().get(0).read(ImageProvider.ImageSizes.SETTINGS_TAB.getImageDimension()); 250 ImageIcon imageIcon = new ImageIcon(image); 251 layerButton.setIcon(imageIcon); 252 } catch (IOException e) { 253 Logging.trace(e); 254 } 255 } 256 layerButtons.add(layerButton); 257 if (entry.getValue().contains(current)) { 258 // Disable button since it is currently selected. Also fixes an issue where clicking on the layer with the current image 259 // would prevent updates 260 layerButton.setEnabled(false); 261 } 262 } 263 layerButtons.forEach(this.layers::add); 264 int maxPreferredHeight = layerButtons.stream().mapToInt(JComponent::getHeight).max().orElse(Integer.MIN_VALUE); 265 if (maxPreferredHeight > 0) { 266 layerButtons.forEach(button -> button.setPreferredSize(new Dimension(button.getPreferredSize().width, maxPreferredHeight))); 267 } 268 this.layers.invalidate(); 269 } 270 } 271 272 216 273 @Override 217 274 public void destroy() { 218 275 MainApplication.getLayerManager().removeActiveLayerChangeListener(this); … … 551 608 return wasEnabled; 552 609 } 553 610 611 /** Used for tabbed panes */ 612 private final transient Map<Layer, List<IImageEntry<?>>> tabbedEntries = new HashMap<>(); 554 613 private transient IImageEntry<? extends IImageEntry<?>> currentEntry; 555 614 556 615 /** … … 578 637 * @since 18246 579 638 */ 580 639 public void displayImages(List<IImageEntry<?>> entries) { 640 this.displayImages((Layer) null, entries); 641 } 642 643 /** 644 * Displays images for the given layer. 645 * @param layer The layer to use for the tab ui 646 * @param entries image entries 647 * @since xxx 648 */ 649 public void displayImages(Layer layer, List<IImageEntry<?>> entries) { 581 650 boolean imageChanged; 582 651 IImageEntry<?> entry = entries != null && entries.size() == 1 ? entries.get(0) : null; 583 652 … … 598 667 } 599 668 } 600 669 670 if (entries == null || entries.isEmpty()) { 671 this.tabbedEntries.remove(layer); 672 } else { 673 this.tabbedEntries.put(layer, entries); 674 } 675 this.updateLayers(); 601 676 if (entry != null) { 602 677 this.updateButtonsNonNullEntry(entry, imageChanged); 603 678 } else { … … 730 805 if (btnCollapse != null) { 731 806 btnCollapse.setVisible(!isDocked); 732 807 } 808 this.updateLayers(); 733 809 } 734 810 735 811 /** … … 819 895 820 896 @Override 821 897 public void selectedImageChanged(ImageData data) { 822 displayImages( new ArrayList<>(data.getSelectedImages()));898 displayImages(data.getLayer(), new ArrayList<>(data.getSelectedImages())); 823 899 } 824 900 825 901 @Override 826 902 public void imageDataUpdated(ImageData data) { 827 displayImages( new ArrayList<>(data.getSelectedImages()));903 displayImages(data.getLayer(), new ArrayList<>(data.getSelectedImages())); 828 904 } 829 905 }
