Changeset 18043 in josm for trunk/src/org/openstreetmap
- Timestamp:
- 2021-07-16T21:56:38+02:00 (3 years ago)
- Location:
- trunk/src/org/openstreetmap/josm/gui/layer/geoimage
- Files:
-
- 1 added
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/gui/layer/geoimage/CorrelateGpxWithImages.java
r18042 r18043 33 33 import java.util.Comparator; 34 34 import java.util.Date; 35 import java.util.Dictionary;36 import java.util.Hashtable;37 35 import java.util.List; 38 36 import java.util.Objects; … … 56 54 import javax.swing.JScrollPane; 57 55 import javax.swing.JSeparator; 58 import javax.swing.JSlider;59 56 import javax.swing.JSpinner; 60 57 import javax.swing.ListSelectionModel; … … 63 60 import javax.swing.SwingConstants; 64 61 import javax.swing.border.Border; 65 import javax.swing.event.ChangeEvent;66 import javax.swing.event.ChangeListener;67 62 import javax.swing.event.DocumentEvent; 68 63 import javax.swing.event.DocumentListener; … … 85 80 import org.openstreetmap.josm.gui.layer.LayerManager.LayerOrderChangeEvent; 86 81 import org.openstreetmap.josm.gui.layer.LayerManager.LayerRemoveEvent; 82 import org.openstreetmap.josm.gui.layer.geoimage.AdjustTimezoneAndOffsetDialog.AdjustListener; 87 83 import org.openstreetmap.josm.gui.layer.gpx.GpxDataHelper; 88 84 import org.openstreetmap.josm.gui.widgets.AbstractFileChooser; … … 94 90 import org.openstreetmap.josm.tools.GBC; 95 91 import org.openstreetmap.josm.tools.ImageProvider; 96 import org.openstreetmap.josm.tools.JosmRuntimeException;97 92 import org.openstreetmap.josm.tools.Logging; 98 93 import org.openstreetmap.josm.tools.Pair; … … 778 773 779 774 private static class GpxLayerRenamedListener implements PropertyChangeListener { 780 private GpxDataWrapper gdw;775 private final GpxDataWrapper gdw; 781 776 GpxLayerRenamedListener(GpxDataWrapper gdw) { 782 777 this.gdw = gdw; … … 972 967 statusBar.add(statusBarText); 973 968 969 RepaintTheMapListener repaintTheMap = new RepaintTheMapListener(); 974 970 tfTimezone.addFocusListener(repaintTheMap); 975 971 tfOffset.addFocusListener(repaintTheMap); … … 1030 1026 1031 1027 @Override 1032 public void insertUpdate(DocumentEvent e v) {1028 public void insertUpdate(DocumentEvent e) { 1033 1029 matchAndUpdateStatusBar(); 1034 1030 } 1035 1031 1036 1032 @Override 1037 public void removeUpdate(DocumentEvent e v) {1033 public void removeUpdate(DocumentEvent e) { 1038 1034 matchAndUpdateStatusBar(); 1039 1035 } 1040 1036 1041 1037 @Override 1042 public void changedUpdate(DocumentEvent e v) {1038 public void changedUpdate(DocumentEvent e) { 1043 1039 // Do nothing 1044 1040 } … … 1098 1094 } 1099 1095 1100 private final transient RepaintTheMapListener repaintTheMap = new RepaintTheMapListener();1101 1102 1096 private class RepaintTheMapListener implements FocusListener { 1103 1097 @Override … … 1117 1111 1118 1112 @Override 1119 public void actionPerformed(ActionEvent arg0) {1113 public void actionPerformed(ActionEvent e) { 1120 1114 1121 1115 final GpxTimeOffset offset = GpxTimeOffset.milliseconds( … … 1124 1118 final Pair<GpxTimezone, GpxTimeOffset> timezoneOffsetPair = offset.withoutDayOffset().splitOutTimezone(); 1125 1119 1126 // Info Labels1127 final JLabel lblMatches = new JLabel();1128 1129 // Timezone Slider1130 // The slider allows to switch timezon from -12:00 to 12:00 in 30 minutes steps. Therefore the range is -24 to 24.1131 final JLabel lblTimezone = new JLabel();1132 final JSlider sldTimezone = new JSlider(-24, 24, 0);1133 sldTimezone.setPaintLabels(true);1134 Dictionary<Integer, JLabel> labelTable = new Hashtable<>();1135 // CHECKSTYLE.OFF: ParenPad1136 for (int i = -12; i <= 12; i += 6) {1137 labelTable.put(i * 2, new JLabel(new GpxTimezone(i).formatTimezone()));1138 }1139 // CHECKSTYLE.ON: ParenPad1140 sldTimezone.setLabelTable(labelTable);1141 1142 // Minutes Slider1143 final JLabel lblMinutes = new JLabel();1144 final JSlider sldMinutes = new JSlider(-15, 15, 0);1145 sldMinutes.setPaintLabels(true);1146 sldMinutes.setMajorTickSpacing(5);1147 1148 // Seconds slider1149 final JLabel lblSeconds = new JLabel();1150 final JSlider sldSeconds = new JSlider(-600, 600, 0);1151 sldSeconds.setPaintLabels(true);1152 labelTable = new Hashtable<>();1153 // CHECKSTYLE.OFF: ParenPad1154 for (int i = -60; i <= 60; i += 30) {1155 labelTable.put(i * 10, new JLabel(GpxTimeOffset.seconds(i).formatOffset()));1156 }1157 // CHECKSTYLE.ON: ParenPad1158 sldSeconds.setLabelTable(labelTable);1159 sldSeconds.setMajorTickSpacing(300);1160 1161 1120 // This is called whenever one of the sliders is moved. 1162 // It updates the labels and also calls the "match photos" code 1163 class SliderListener implements ChangeListener { 1164 @Override 1165 public void stateChanged(ChangeEvent e) { 1166 timezone = new GpxTimezone(sldTimezone.getValue() / 2.); 1167 1168 lblTimezone.setText(tr("Timezone: {0}", timezone.formatTimezone())); 1169 lblMinutes.setText(tr("Minutes: {0}", sldMinutes.getValue())); 1170 lblSeconds.setText(tr("Seconds: {0}", GpxTimeOffset.milliseconds(100L * sldSeconds.getValue()).formatOffset())); 1171 1172 delta = GpxTimeOffset.milliseconds(100L * sldSeconds.getValue() 1173 + TimeUnit.MINUTES.toMillis(sldMinutes.getValue()) 1174 + TimeUnit.DAYS.toMillis(dayOffset)); 1175 1176 tfTimezone.getDocument().removeDocumentListener(statusBarUpdater); 1177 tfOffset.getDocument().removeDocumentListener(statusBarUpdater); 1178 1179 tfTimezone.setText(timezone.formatTimezone()); 1180 tfOffset.setText(delta.formatOffset()); 1181 1182 tfTimezone.getDocument().addDocumentListener(statusBarUpdater); 1183 tfOffset.getDocument().addDocumentListener(statusBarUpdater); 1184 1185 lblMatches.setText(statusBarText.getText() + "<br>" + trn("(Time difference of {0} day)", 1186 "Time difference of {0} days", Math.abs(dayOffset), Math.abs(dayOffset))); 1187 1188 statusBarUpdater.matchAndUpdateStatusBar(); 1189 yLayer.updateBufferAndRepaint(); 1190 } 1191 } 1192 1193 // Put everything together 1194 JPanel p = new JPanel(new GridBagLayout()); 1195 p.setPreferredSize(new Dimension(400, 230)); 1196 p.add(lblMatches, GBC.eol().fill()); 1197 p.add(lblTimezone, GBC.eol().fill()); 1198 p.add(sldTimezone, GBC.eol().fill().insets(0, 0, 0, 10)); 1199 p.add(lblMinutes, GBC.eol().fill()); 1200 p.add(sldMinutes, GBC.eol().fill().insets(0, 0, 0, 10)); 1201 p.add(lblSeconds, GBC.eol().fill()); 1202 p.add(sldSeconds, GBC.eol().fill()); 1203 1204 // If there's an error in the calculation the found values 1205 // will be off range for the sliders. Catch this error 1206 // and inform the user about it. 1207 try { 1208 sldTimezone.setValue((int) (timezoneOffsetPair.a.getHours() * 2)); 1209 sldMinutes.setValue((int) (timezoneOffsetPair.b.getSeconds() / 60)); 1210 final long deciSeconds = timezoneOffsetPair.b.getMilliseconds() / 100; 1211 sldSeconds.setValue((int) (deciSeconds % 600)); 1212 } catch (JosmRuntimeException | IllegalArgumentException | IllegalStateException e) { 1213 Logging.warn(e); 1214 JOptionPane.showMessageDialog(MainApplication.getMainFrame(), 1215 tr("An error occurred while trying to match the photos to the GPX track." 1216 +" You can adjust the sliders to manually match the photos."), 1217 tr("Matching photos to track failed"), 1218 JOptionPane.WARNING_MESSAGE); 1219 } 1220 1221 // Call the sliderListener once manually so labels get adjusted 1222 new SliderListener().stateChanged(null); 1223 // Listeners added here, otherwise it tries to match three times 1224 // (when setting the default values) 1225 sldTimezone.addChangeListener(new SliderListener()); 1226 sldMinutes.addChangeListener(new SliderListener()); 1227 sldSeconds.addChangeListener(new SliderListener()); 1121 // It calls the "match photos" code 1122 AdjustListener listener = (tz, min, sec) -> { 1123 timezone = tz; 1124 1125 delta = GpxTimeOffset.milliseconds(100L * sec 1126 + TimeUnit.MINUTES.toMillis(min) 1127 + TimeUnit.DAYS.toMillis(dayOffset)); 1128 1129 tfTimezone.getDocument().removeDocumentListener(statusBarUpdater); 1130 tfOffset.getDocument().removeDocumentListener(statusBarUpdater); 1131 1132 tfTimezone.setText(timezone.formatTimezone()); 1133 tfOffset.setText(delta.formatOffset()); 1134 1135 tfTimezone.getDocument().addDocumentListener(statusBarUpdater); 1136 tfOffset.getDocument().addDocumentListener(statusBarUpdater); 1137 1138 statusBarUpdater.matchAndUpdateStatusBar(); 1139 yLayer.updateBufferAndRepaint(); 1140 1141 return statusBarText.getText(); 1142 }; 1228 1143 1229 1144 // There is no way to cancel this dialog, all changes get applied 1230 1145 // immediately. Therefore "Close" is marked with an "OK" icon. 1231 1146 // Settings are only saved temporarily to the layer. 1232 new ExtendedDialog(MainApplication.getMainFrame(), 1233 tr("Adjust timezone and offset"), 1234 tr("Close")). 1235 setContent(p).setButtonIcons("ok").showDialog(); 1147 new AdjustTimezoneAndOffsetDialog(MainApplication.getMainFrame(), 1148 timezoneOffsetPair.a, timezoneOffsetPair.b, dayOffset) 1149 .adjustListener(listener).showDialog(); 1236 1150 } 1237 1151 } … … 1284 1198 1285 1199 @Override 1286 public void actionPerformed(ActionEvent arg0) {1200 public void actionPerformed(ActionEvent e) { 1287 1201 GpxDataWrapper gpxW = selectedGPX(true); 1288 1202 if (gpxW == null)
Note:
See TracChangeset
for help on using the changeset viewer.