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}