Ticket #17050: refactor_geoimagelayer_plugin.patch

File refactor_geoimagelayer_plugin.patch, 21.0 KB (added by francois2, 2 months ago)

The patch on the photo adjust plugin

  • plugins/photoadjust/src/org/openstreetmap/josm/plugins/photoadjust/PhotoAdjustWorker.java

    diff --git a/plugins/photoadjust/src/org/openstreetmap/josm/plugins/photoadjust/PhotoAdjustWorker.java b/plugins/photoadjust/src/org/openstreetmap/josm/plugins/photoadjust/PhotoAdjustWorker.java
    index 931b749b7..9fba87e2e 100644
    a b import java.awt.event.MouseEvent; 
    66import java.awt.geom.Point2D;
    77import java.util.List;
    88
     9import org.openstreetmap.josm.data.ImageData;
    910import org.openstreetmap.josm.data.coor.LatLon;
    1011import org.openstreetmap.josm.gui.MainApplication;
    1112import org.openstreetmap.josm.gui.layer.geoimage.GeoImageLayer;
    import org.openstreetmap.josm.gui.layer.geoimage.ImageViewerDialog; 
    1819public class PhotoAdjustWorker {
    1920
    2021    private ImageEntry dragPhoto;
    21     private GeoImageLayer dragLayer;
     22    private ImageData dragData;
    2223    // Offset between center of the photo and point where it is
    2324    // clicked.  This must be in pixels to maintain the same offset if
    2425    // the photo is moved very far.
    public class PhotoAdjustWorker { 
    3132     */
    3233    public void reset() {
    3334        dragPhoto = null;
    34         dragLayer = null;
     35        dragData = null;
    3536        dragOffset = null;
    3637    }
    3738
    public class PhotoAdjustWorker { 
    7273     * @param imageLayers List of GeoImageLayers to be considered.
    7374     */
    7475    public void doMousePressed(MouseEvent evt,
    75                                List<GeoImageLayer> imageLayers) {
     76            List<GeoImageLayer> imageLayers) {
    7677        reset();
    7778
    7879        if (evt.getButton() == MouseEvent.BUTTON1
    79             && imageLayers != null && !imageLayers.isEmpty()) {
     80                && imageLayers != null && !imageLayers.isEmpty()) {
    8081            // Check if modifier key is pressed and change to
    8182            // image viewer photo if it is.
    8283            final boolean isShift = (evt.getModifiers() & InputEvent.SHIFT_MASK) != 0;
    8384            final boolean isCtrl = (evt.getModifiers() & InputEvent.CTRL_MASK) != 0;
    8485            if (isShift || isCtrl) {
    85                 final GeoImageLayer viewerLayer = ImageViewerDialog.getCurrentLayer();
    86                 final ImageEntry img = ImageViewerDialog.getCurrentImage();
    87                 if (img != null && viewerLayer != null
    88                     && viewerLayer.isVisible()
    89                     && imageLayers.contains(viewerLayer)) {
    90                     // Change direction if control is pressed, position
    91                     // otherwise.  Shift+control changes direction, similar to
    92                     // rotate in select mode.
    93                     //
    94                     // Combinations:
    95                     // S ... shift pressed
    96                     // C ... control pressed
    97                     // pos ... photo has a position set == is displayed on the map
    98                     // nopos ... photo has no position set
    99                     //
    100                     // S + pos: position at mouse
    101                     // S + nopos: position at mouse
    102                     // C + pos: change orientation
    103                     // C + nopos: ignored
    104                     // S + C + pos: change orientation
    105                     // S + C + nopos: ignore
    106                     if (isCtrl) {
    107                         if (img.getPos() != null) {
    108                             changeDirection(img, viewerLayer, evt);
     86                for (GeoImageLayer layer: imageLayers) {
     87                    if (layer.isVisible()) {
     88                        final ImageEntry img = layer.getImageData().getSelectedImage();
     89                        if (img != null) {
     90                            // Change direction if control is pressed, position
     91                            // otherwise.  Shift+control changes direction, similar to
     92                            // rotate in select mode.
     93                            //
     94                            // Combinations:
     95                            // S ... shift pressed
     96                            // C ... control pressed
     97                            // pos ... photo has a position set == is displayed on the map
     98                            // nopos ... photo has no position set
     99                            //
     100                            // S + pos: position at mouse
     101                            // S + nopos: position at mouse
     102                            // C + pos: change orientation
     103                            // C + nopos: ignored
     104                            // S + C + pos: change orientation
     105                            // S + C + nopos: ignore
     106                            if (isCtrl) {
     107                                if (img.getPos() != null) {
     108                                    changeDirection(img, layer.getImageData(), evt);
     109                                }
     110                            } else { // shift pressed
     111                                movePhoto(img, layer.getImageData(), evt);
     112                            }
     113                            dragPhoto = img;
     114                            dragData = layer.getImageData();
     115                            break;
    109116                        }
    110                     } else { // shift pressed
    111                         movePhoto(img, viewerLayer, evt);
    112117                    }
    113                     dragPhoto = img;
    114                     dragLayer = viewerLayer;
    115118                }
    116119            } else {
    117120                // Start with the top layer.
    public class PhotoAdjustWorker { 
    119122                    if (layer.isVisible()) {
    120123                        dragPhoto = layer.getPhotoUnderMouse(evt);
    121124                        if (dragPhoto != null) {
    122                             dragLayer = layer;
     125                            dragData = layer.getImageData();
    123126                            setDragOffset(dragPhoto, evt);
    124127                            disableCenterView();
    125128                            break;
    public class PhotoAdjustWorker { 
    149152     * @param evt Mouse event from MouseMotionAdapter mouseDragged().
    150153     */
    151154    public void doMouseDragged(MouseEvent evt) {
    152         if (dragLayer != null && dragLayer.isVisible()
    153             && dragPhoto != null) {
     155        if (dragData != null && dragPhoto != null) {
    154156            if ((evt.getModifiers() & InputEvent.CTRL_MASK) != 0) {
    155                 changeDirection(dragPhoto, dragLayer, evt);
     157                changeDirection(dragPhoto, dragData, evt);
    156158            } else {
    157159                disableCenterView();
    158                 movePhoto(dragPhoto, dragLayer, evt);
     160                movePhoto(dragPhoto, dragData, evt);
    159161            }
    160162        }
    161163    }
    public class PhotoAdjustWorker { 
    176178     * Move the photo to the mouse position.
    177179     *
    178180     * @param photo The photo to move.
    179      * @param layer GeoImageLayer of the photo.
     181     * @param data ImageData of the photo.
    180182     * @param evt Mouse event from one of the mouse adapters.
    181183     */
    182     private void movePhoto(ImageEntry photo, GeoImageLayer layer,
    183                            MouseEvent evt) {
     184    private void movePhoto(ImageEntry photo, ImageData data,
     185            MouseEvent evt) {
    184186        LatLon newPos;
    185187        if (dragOffset != null) {
    186188            newPos = MainApplication.getMap().mapView.getLatLon(
    public class PhotoAdjustWorker { 
    189191        } else {
    190192            newPos = MainApplication.getMap().mapView.getLatLon(evt.getX(), evt.getY());
    191193        }
    192         photo.setPos(newPos);
    193         photo.flagNewGpsData();
    194         layer.updateBufferAndRepaint();
     194        data.updateImagePosition(photo, newPos);
    195195        // Re-display the photo because the OSD data might change (new
    196196        // coordinates).  Or do that in doMouseReleased().
    197197        //ImageViewerDialog.showImage(layer, photo);
    public class PhotoAdjustWorker { 
    201201     * Set the image direction, i.e. let it point to where the mouse is.
    202202     *
    203203     * @param photo The photo to move.
    204      * @param layer GeoImageLayer of the photo.
     204     * @param data ImageData of the photo.
    205205     * @param evt Mouse event from one of the mouse adapters.
    206206     */
    207     private void changeDirection(ImageEntry photo, GeoImageLayer layer,
    208                                 MouseEvent evt) {
     207    private void changeDirection(ImageEntry photo, ImageData data,
     208            MouseEvent evt) {
    209209        final LatLon photoLL = photo.getPos();
    210210        if (photoLL == null) {
    211211            // Direction cannot be set if image doesn't have a position.
    public class PhotoAdjustWorker { 
    219219        } else if (direction >= 360.0) {
    220220            direction -= 360.0;
    221221        }
    222         photo.setExifImgDir(direction);
    223         photo.flagNewGpsData();
    224         layer.updateBufferAndRepaint();
    225         ImageViewerDialog.showImage(layer, photo);
     222        data.updateImageDirection(photo, direction);
    226223        setDragOffset(photo, evt);
    227224    }
    228225}
  • plugins/photoadjust/src/org/openstreetmap/josm/plugins/photoadjust/PhotoPropertyEditor.java

    diff --git a/plugins/photoadjust/src/org/openstreetmap/josm/plugins/photoadjust/PhotoPropertyEditor.java b/plugins/photoadjust/src/org/openstreetmap/josm/plugins/photoadjust/PhotoPropertyEditor.java
    index 508c41c86..61837be1e 100644
    a b import static org.openstreetmap.josm.tools.I18n.tr; 
    66import java.awt.Color;
    77import java.awt.GridBagLayout;
    88import java.awt.event.ActionEvent;
     9import java.util.List;
     10import java.util.Optional;
    911
    1012import javax.swing.AbstractAction;
    11 import javax.swing.Action;
    1213import javax.swing.BorderFactory;
    1314import javax.swing.ImageIcon;
    1415import javax.swing.JButton;
    1516import javax.swing.JLabel;
    16 import javax.swing.JOptionPane;
    1717import javax.swing.JPanel;
    1818import javax.swing.JSeparator;
    1919import javax.swing.UIManager;
    import javax.swing.event.DocumentEvent; 
    2121import javax.swing.event.DocumentListener;
    2222
    2323import org.openstreetmap.josm.actions.JosmAction;
     24import org.openstreetmap.josm.data.ImageData;
     25import org.openstreetmap.josm.data.ImageData.ImageDataUpdateListener;
    2426import org.openstreetmap.josm.data.coor.LatLon;
    2527import org.openstreetmap.josm.data.coor.conversion.CoordinateFormatManager;
    2628import org.openstreetmap.josm.data.coor.conversion.LatLonParser;
    import org.openstreetmap.josm.gui.ExtendedDialog; 
    2931import org.openstreetmap.josm.gui.MainApplication;
    3032import org.openstreetmap.josm.gui.MainMenu;
    3133import org.openstreetmap.josm.gui.dialogs.LatLonDialog;
     34import org.openstreetmap.josm.gui.layer.Layer;
     35import org.openstreetmap.josm.gui.layer.LayerManager.LayerAddEvent;
     36import org.openstreetmap.josm.gui.layer.LayerManager.LayerChangeListener;
     37import org.openstreetmap.josm.gui.layer.LayerManager.LayerOrderChangeEvent;
     38import org.openstreetmap.josm.gui.layer.LayerManager.LayerRemoveEvent;
    3239import org.openstreetmap.josm.gui.layer.geoimage.GeoImageLayer;
    3340import org.openstreetmap.josm.gui.layer.geoimage.ImageEntry;
    34 import org.openstreetmap.josm.gui.layer.geoimage.ImageViewerDialog;
    3541import org.openstreetmap.josm.gui.widgets.JosmTextField;
    3642import org.openstreetmap.josm.tools.GBC;
    3743import org.openstreetmap.josm.tools.ImageProvider;
    public class PhotoPropertyEditor { 
    5662        MainMenu.add(MainApplication.getMenu().editMenu, new PropertyEditorAction());
    5763    }
    5864
    59     /**
    60      * Update the geo image layer and the image viewer.
    61      *
    62      * @param layer GeoImageLayer of the photo.
    63      * @param photo The photo that is updated.
    64      */
    65     private static void updateLayer(GeoImageLayer layer, ImageEntry photo) {
    66         layer.updateBufferAndRepaint();
    67         ImageViewerDialog.showImage(layer, photo);
    68     }
    69 
    7065    /**
    7166     * Action if the menu entry is selected.
    7267     */
    73     private static class PropertyEditorAction extends JosmAction {
     68    private static class PropertyEditorAction extends JosmAction implements LayerChangeListener, ImageDataUpdateListener {
    7469        public PropertyEditorAction() {
    7570            super(tr("Edit photo GPS data"),    // String name
    76                   (String)null,                         // String iconName
    77                   tr("Edit GPS data of selected photo."), // String tooltip
    78                   null,                                 // Shortcut shortcut
    79                   true,                                 // boolean registerInToolbar
    80                   "photoadjust/propertyeditor", // String toolbarId
    81                   true                          // boolean installAdapters
    82                   );
     71                    (String)null,                         // String iconName
     72                    tr("Edit GPS data of selected photo."), // String tooltip
     73                    null,                                 // Shortcut shortcut
     74                    true,                                 // boolean registerInToolbar
     75                    "photoadjust/propertyeditor", // String toolbarId
     76                    false                          // boolean installAdapters
     77                    );
     78            this.installAdapters();
     79        }
     80
     81        @Override
     82        protected void installAdapters() {
     83            MainApplication.getLayerManager().addLayerChangeListener(this);
     84            initEnabledState();
    8385        }
    8486
    8587        @Override
    8688        public void actionPerformed(ActionEvent evt) {
    87             try {
    88                 final ImageEntry photo = ImageViewerDialog.getCurrentImage();
    89                 final GeoImageLayer layer = ImageViewerDialog.getCurrentLayer();
    90                 if (photo == null) {
    91                     throw new AssertionError("No image selected.");
    92                 }
    93                 StringBuilder title =
     89            final ImageData data = getLayerWithSelectedImage().get().getImageData();
     90            final ImageEntry photo = data.getSelectedImage();
     91
     92            StringBuilder title =
    9493                    new StringBuilder(tr("Edit Photo GPS Data"));
    95                 if (photo.getFile() != null) {
    96                     title.append(" - ");
    97                     title.append(photo.getFile().getName());
    98                 }
    99                 PropertyEditorDialog dialog =
    100                     new PropertyEditorDialog(title.toString(), photo, layer);
    101                 if (dialog.getValue() == 1) {
    102                     dialog.updateImageTmp();
    103                     // There are cases where isNewGpsData is not set but there
    104                     // is still new data, e.g. if the EXIF data was re-read
    105                     // from the image file.
    106                     photo.applyTmp();
    107                 } else {
    108                     photo.discardTmp();
    109                 }
    110                 updateLayer(layer, photo);
    111             } catch (AssertionError err) {
    112                 JOptionPane.showMessageDialog(MainApplication.getMainFrame(),
    113                                               tr("Please select an image first."),
    114                                               tr("No image selected"),
    115                                               JOptionPane.INFORMATION_MESSAGE);
    116                 return;
     94            if (photo.getFile() != null) {
     95                title.append(" - ");
     96                title.append(photo.getFile().getName());
     97            }
     98            PropertyEditorDialog dialog =
     99                    new PropertyEditorDialog(title.toString(), photo, data);
     100            if (dialog.getValue() == 1) {
     101                dialog.updateImageTmp();
     102                // There are cases where isNewGpsData is not set but there
     103                // is still new data, e.g. if the EXIF data was re-read
     104                // from the image file.
     105                photo.applyTmp();
     106            } else {
     107                photo.discardTmp();
    117108            }
    118        }
     109            data.notifyImageUpdate();
     110        }
    119111
    120112        /**
    121113         * Check if there is a selected image.
    public class PhotoPropertyEditor { 
    124116         *         image shown, {@code false} otherwise.
    125117         */
    126118        private static boolean enabled() {
    127             try {
    128                 //return ImageViewerDialog.getInstance().hasImage();
    129                 ImageViewerDialog.getInstance().hasImage();
    130                 return true;
    131             } catch (AssertionError err) {
    132                 return false;
    133             }
     119            return getLayerWithSelectedImage().isPresent();
     120        }
     121
     122        private static Optional<GeoImageLayer> getLayerWithSelectedImage() {
     123            List<GeoImageLayer> list = MainApplication.getLayerManager().getLayersOfType(GeoImageLayer.class);
     124            return list.stream().filter(l -> l.getImageData().getSelectedImage() != null).findFirst();
    134125        }
    135126
    136127        @Override
    137128        protected void updateEnabledState() {
    138129            setEnabled(enabled());
    139130        }
     131
     132        @Override
     133        public void layerAdded(LayerAddEvent e) {
     134            Layer layer = e.getAddedLayer();
     135            if (layer instanceof GeoImageLayer) {
     136                ((GeoImageLayer) layer).getImageData().addImageDataUpdateListener(this);
     137            }
     138        }
     139
     140        @Override
     141        public void layerRemoving(LayerRemoveEvent e) {
     142            Layer layer = e.getRemovedLayer();
     143
     144            if (layer instanceof GeoImageLayer) {
     145                ((GeoImageLayer) layer).getImageData().removeImageDataUpdateListener(this);
     146            }
     147            this.updateEnabledState();
     148        }
     149
     150        @Override
     151        public void layerOrderChanged(LayerOrderChangeEvent e) {
     152            // ignored
     153        }
     154
     155        @Override
     156        public void imageDataUpdated(ImageData data) {
     157            // ignored
     158        }
     159
     160        @Override
     161        public void selectedImageChanged(ImageData data) {
     162            this.updateEnabledState();
     163        }
    140164    }
    141165
    142166    /**
    public class PhotoPropertyEditor { 
    149173        private final JosmTextField direction = new JosmTextField();
    150174        // Image that is to be updated.
    151175        private final ImageEntry image;
    152         private final GeoImageLayer layer;
     176        private final ImageData data;
    153177        // Image as it was when the dialog was opened.
    154178        private final GpxImageEntry imgOrig;
    155179        private static final Color BG_COLOR_ERROR = new Color(255, 224, 224);
    156180
    157181        public PropertyEditorDialog(String title, final ImageEntry image,
    158                                     final GeoImageLayer layer) {
     182                final ImageData data) {
    159183            super(MainApplication.getMainFrame(), title, tr("Ok"), tr("Cancel"));
    160184            this.image = image;
    161             this.layer = layer;
     185            this.data = data;
    162186            imgOrig = image.clone();
    163187            setButtonIcons("ok", "cancel");
    164188            final JPanel content = new JPanel(new GridBagLayout());
    public class PhotoPropertyEditor { 
    199223            DoubleInputVerifier altVerif = new DoubleInputVerifier(altitude) {
    200224                @Override public void updateValue(Double value) {
    201225                    image.getTmp().setElevation(value);
    202                     updateLayer(layer, image);
     226                    data.notifyImageUpdate();
    203227                }
    204228            };
    205229            altitude.getDocument().addDocumentListener(altVerif);
    public class PhotoPropertyEditor { 
    213237            DoubleInputVerifier speedVerif = new DoubleInputVerifier(speed) {
    214238                @Override public void updateValue(Double value) {
    215239                    image.getTmp().setSpeed(value);
    216                     updateLayer(layer, image);
     240                    data.notifyImageUpdate();
    217241                }
    218242            };
    219243            speedVerif.setMinMax(0.0, null);
    public class PhotoPropertyEditor { 
    229253            DoubleInputVerifier dirVerif = new DoubleInputVerifier(direction) {
    230254                @Override public void updateValue(Double value) {
    231255                    image.getTmp().setExifImgDir(value);
    232                     updateLayer(layer, image);
     256                    data.notifyImageUpdate();
    233257                }
    234258            };
    235259            dirVerif.setMinMax(-360.0, 360.0);
    public class PhotoPropertyEditor { 
    572596            @Override
    573597            public void updateLatLon(LatLon latLon) {
    574598                image.getTmp().setPos(latLon);
    575                 updateLayer(layer, image);
     599                data.notifyImageUpdate();
    576600            }
    577601
    578602            @Override
  • plugins/photoadjust/src/org/openstreetmap/josm/plugins/photoadjust/UntaggedGeoImageLayerAction.java

    diff --git a/plugins/photoadjust/src/org/openstreetmap/josm/plugins/photoadjust/UntaggedGeoImageLayerAction.java b/plugins/photoadjust/src/org/openstreetmap/josm/plugins/photoadjust/UntaggedGeoImageLayerAction.java
    index 69c056680..d8cbd40b4 100644
    a b public class UntaggedGeoImageLayerAction 
    5353                    // Move this image to the new layer and delete it
    5454                    // from the original layer.
    5555                    untagged.add(img);
    56                     layer.removePhotoByIdx(idx);
     56                    layer.getImageData().removeImage(img);
    5757                }
    5858            }
    5959            MainApplication.getLayerManager()