001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.gui.layer.geoimage;
003
004import static org.openstreetmap.josm.tools.I18n.tr;
005
006import java.awt.event.ActionEvent;
007import java.awt.event.ItemEvent;
008import java.awt.event.ItemListener;
009import java.awt.event.KeyEvent;
010import java.util.List;
011import java.util.Objects;
012
013import javax.swing.event.ChangeEvent;
014import javax.swing.event.ChangeListener;
015
016import org.openstreetmap.josm.actions.JosmAction;
017import org.openstreetmap.josm.data.gpx.GpxImageCorrelation;
018import org.openstreetmap.josm.data.gpx.GpxImageCorrelationSettings;
019import org.openstreetmap.josm.gui.ExtendedDialog;
020import org.openstreetmap.josm.gui.MainApplication;
021import org.openstreetmap.josm.gui.layer.geoimage.CorrelateGpxWithImages.RepaintTheMapListener;
022import org.openstreetmap.josm.tools.Shortcut;
023
024/**
025 * Edit a sequence of geo-located images.
026 * @since 18065
027 */
028public class EditImagesSequenceAction extends JosmAction {
029
030    private final transient GeoImageLayer yLayer;
031    private final ImageDirectionPositionPanel pDirectionPosition;
032
033    /**
034     * Constructs a new {@code EditImagesSequenceAction}.
035     * @param layer The image layer
036     */
037    public EditImagesSequenceAction(GeoImageLayer layer) {
038        super(tr("Edit images sequence"), "dialogs/geoimage/gpx2img", "geoimage_editsequence",
039            Shortcut.registerShortcut("geoimage:editsequence", tr("Edit images sequence"), KeyEvent.CHAR_UNDEFINED, Shortcut.NONE),
040            false);
041        this.yLayer = Objects.requireNonNull(layer);
042        this.pDirectionPosition = ImageDirectionPositionPanel.forImageSequence();
043
044        Updater updater = new Updater();
045        pDirectionPosition.addFocusListenerOnComponent(new RepaintTheMapListener(yLayer));
046        pDirectionPosition.addChangeListenerOnComponents(updater);
047        pDirectionPosition.addItemListenerOnComponents(updater);
048    }
049
050    @Override
051    public void actionPerformed(ActionEvent e) {
052        ExtendedDialog ed = new ExtendedDialog(
053                MainApplication.getMainFrame(), tr("Edit images sequence"), tr("Apply"), tr("Cancel"))
054            .setContent(pDirectionPosition).setButtonIcons("ok", "cancel");
055        ed.setResizable(false);
056        if (ed.showDialog().getValue() == 1) {
057            yLayer.applyTmp();
058        } else {
059            yLayer.discardTmp();
060        }
061        yLayer.updateBufferAndRepaint();
062    }
063
064    class Updater implements ChangeListener, ItemListener {
065
066        @Override
067        public void stateChanged(ChangeEvent e) {
068            matchAndUpdate();
069        }
070
071        @Override
072        public void itemStateChanged(ItemEvent e) {
073            matchAndUpdate();
074        }
075
076        void matchAndUpdate() {
077            // The selection of images we are about to correlate may have changed.
078            // So reset all images.
079            yLayer.discardTmp();
080            // Construct a list of images that have a date, and sort them on the date.
081            List<ImageEntry> dateImgLst = yLayer.getSortedImgList(true, true);
082            // Create a temporary copy for each image
083            dateImgLst.forEach(ie -> ie.createTmp().unflagNewGpsData());
084            GpxImageCorrelation.matchGpxTrack(dateImgLst, yLayer.getFauxGpxData(),
085                            new GpxImageCorrelationSettings(0, false, pDirectionPosition.getSettings()));
086            yLayer.updateBufferAndRepaint();
087        }
088    }
089}