import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
-import java.util.Calendar;
import java.util.Iterator;
+import java.util.TimeZone;
import java.util.TreeSet;
import javax.swing.BorderFactory;
import tim.prune.App;
import tim.prune.GenericFunction;
import tim.prune.I18nManager;
+import tim.prune.config.TimezoneHelper;
import tim.prune.data.DataPoint;
import tim.prune.data.Distance;
import tim.prune.data.Field;
-import tim.prune.data.MediaFile;
+import tim.prune.data.MediaObject;
import tim.prune.data.MediaList;
import tim.prune.data.TimeDifference;
import tim.prune.data.Timestamp;
import tim.prune.data.Track;
+import tim.prune.data.Unit;
+import tim.prune.data.UnitSetLibrary;
+import tim.prune.tips.TipManager;
/**
* Abstract superclass of the two correlator functions
{
protected JDialog _dialog;
private CardStack _cards = null;
- private JLabel _tipLabel = null;
private JTable _selectionTable = null;
protected JTable _previewTable = null;
private boolean _previewEnabled = false; // flag required to enable preview function on final panel
private boolean[] _cardEnabled = null; // flag for each card
+ private TimeZone _timezone = null;
private JTextField _offsetHourBox = null, _offsetMinBox = null, _offsetSecBox = null;
private JRadioButton _mediaLaterOption = null, _pointLaterOption = null;
private JRadioButton _timeLimitRadio = null, _distLimitRadio = null;
private JTextField _limitMinBox = null, _limitSecBox = null;
private JTextField _limitDistBox = null;
- private JComboBox _distUnitsDropdown = null;
+ private JComboBox<String> _distUnitsDropdown = null;
private JButton _nextButton = null, _backButton = null;
protected JButton _okButton = null;
+
/**
* Constructor
* @param inApp App object to report actions to
_dialog.getContentPane().add(makeDialogContents());
_dialog.pack();
}
+ _okButton.setEnabled(false);
+ // Init timezone to the currently selected one
+ _timezone = TimezoneHelper.getSelectedTimezone();
// Go to first available card
int card = 0;
_cardEnabled = null;
- while (!isCardEnabled(card)) {card++;}
+ while (!isCardEnabled(card)) {
+ card++;
+ }
_cards.showCard(card);
showCard(0); // does set up and next/prev enabling
- _okButton.setEnabled(false);
+ if (!isCardEnabled(1)) {
+ _app.showTip(TipManager.Tip_ManuallyCorrelateOne);
+ }
_dialog.setVisible(true);
}
int numMedia = mediaList.getNumMedia();
for (int i=0; i<numMedia; i++)
{
- MediaFile media = mediaList.getMedia(i);
+ MediaObject media = mediaList.getMedia(i);
// For working out time differences, can't use media which already had point information
if (media.getDataPoint() != null && media.getDataPoint().hasTimestamp()
- && media.getOriginalStatus() == MediaFile.Status.NOT_CONNECTED)
+ && media.getOriginalStatus() == MediaObject.Status.NOT_CONNECTED)
{
// Calculate time difference, add to table model
- long timeDiff = getMediaTimestamp(media).getSecondsSince(media.getDataPoint().getTimestamp());
+ long timeDiff = getMediaTimestamp(media).getSecondsSince(media.getDataPoint().getTimestamp(), _timezone);
model.addMedia(media, timeDiff);
}
}
}
- /**
- * @param inFirstTimestamp timestamp of first photo / audio object, or null if not available
- * @return time difference of local time zone from UTC when the first photo was taken
- */
- private static TimeDifference getTimezoneOffset(Timestamp inFirstTimestamp)
- {
- Calendar cal = null;
- // Use first timestamp if available
- if (inFirstTimestamp != null) {
- cal = inFirstTimestamp.getCalendar();
- }
- else {
- // No photo or no timestamp, just use current time
- cal = Calendar.getInstance();
- }
- // Both time zone offset and dst offset are based on milliseconds, so convert to seconds
- TimeDifference timeDiff = new TimeDifference((cal.get(Calendar.ZONE_OFFSET) + cal.get(Calendar.DST_OFFSET)) / 1000);
- return timeDiff;
- }
-
-
/**
* Calculate the median index to select from the table
* @param inModel table model
{
JPanel card = new JPanel();
card.setLayout(new BorderLayout(10, 10));
- card.add(new JLabel(I18nManager.getText(
- "dialog.correlate." + getMediaTypeKey() + "select.intro")), BorderLayout.NORTH);
+ JLabel introLabel = new JLabel(I18nManager.getText(
+ "dialog.correlate." + getMediaTypeKey() + "select.intro"));
+ introLabel.setBorder(BorderFactory.createEmptyBorder(6, 6, 6, 6));
+ card.add(introLabel, BorderLayout.NORTH);
// table doesn't have model yet - that will be attached later
_selectionTable = new JTable();
JScrollPane photoScrollPane = new JScrollPane(_selectionTable);
card2.setLayout(new BorderLayout());
JPanel card2Top = new JPanel();
card2Top.setLayout(new BoxLayout(card2Top, BoxLayout.Y_AXIS));
- _tipLabel = new JLabel(I18nManager.getText("dialog.correlate.options.tip"));
- _tipLabel.setBorder(BorderFactory.createEmptyBorder(8, 6, 5, 6));
- card2Top.add(_tipLabel);
JLabel introLabel = new JLabel(I18nManager.getText("dialog.correlate.options.intro"));
introLabel.setBorder(BorderFactory.createEmptyBorder(8, 6, 5, 6));
card2Top.add(introLabel);
offsetPanelBot.setLayout(new FlowLayout());
offsetPanelBot.setBorder(null);
_mediaLaterOption = new JRadioButton(I18nManager.getText("dialog.correlate.options." + getMediaTypeKey() + "later"));
- _pointLaterOption = new JRadioButton(I18nManager.getText("dialog.correlate.options.pointlaterphoto"));
+ _pointLaterOption = new JRadioButton(I18nManager.getText("dialog.correlate.options.pointlater" + getMediaTypeKey()));
_mediaLaterOption.addItemListener(optionsChangedListener);
_pointLaterOption.addItemListener(optionsChangedListener);
ButtonGroup laterGroup = new ButtonGroup();
offsetPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
card2Top.add(offsetPanel);
+ // listener for radio buttons
+ ActionListener radioListener = new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ enableEditBoxes();
+ }
+ };
// time limits section
JPanel limitsPanel = new JPanel();
limitsPanel.setBorder(BorderFactory.createTitledBorder(I18nManager.getText("dialog.correlate.options.limitspanel")));
timeLimitPanel.setLayout(new FlowLayout());
JRadioButton noTimeLimitRadio = new JRadioButton(I18nManager.getText("dialog.correlate.options.notimelimit"));
noTimeLimitRadio.addItemListener(optionsChangedListener);
+ noTimeLimitRadio.addActionListener(radioListener);
timeLimitPanel.add(noTimeLimitRadio);
- _timeLimitRadio = new JRadioButton(I18nManager.getText("dialog.correlate.options.timelimit") + " : ");
+ _timeLimitRadio = new JRadioButton(I18nManager.getText("dialog.correlate.options.timelimit") + ": ");
_timeLimitRadio.addItemListener(optionsChangedListener);
+ _timeLimitRadio.addActionListener(radioListener);
timeLimitPanel.add(_timeLimitRadio);
groupRadioButtons(noTimeLimitRadio, _timeLimitRadio);
_limitMinBox = new JTextField(3);
distLimitPanel.setLayout(new FlowLayout());
JRadioButton noDistLimitRadio = new JRadioButton(I18nManager.getText("dialog.correlate.options.nodistancelimit"));
noDistLimitRadio.addItemListener(optionsChangedListener);
+ noDistLimitRadio.addActionListener(radioListener);
distLimitPanel.add(noDistLimitRadio);
- _distLimitRadio = new JRadioButton(I18nManager.getText("dialog.correlate.options.distancelimit"));
+ _distLimitRadio = new JRadioButton(I18nManager.getText("dialog.correlate.options.distancelimit") + ": ");
_distLimitRadio.addItemListener(optionsChangedListener);
+ _distLimitRadio.addActionListener(radioListener);
distLimitPanel.add(_distLimitRadio);
groupRadioButtons(noDistLimitRadio, _distLimitRadio);
_limitDistBox = new JTextField(4);
distLimitPanel.add(_limitDistBox);
String[] distUnitsOptions = {I18nManager.getText("units.kilometres"), I18nManager.getText("units.metres"),
I18nManager.getText("units.miles")};
- _distUnitsDropdown = new JComboBox(distUnitsOptions);
+ _distUnitsDropdown = new JComboBox<String>(distUnitsOptions);
_distUnitsDropdown.addItemListener(optionsChangedListener);
distLimitPanel.add(_distUnitsDropdown);
limitsPanel.add(distLimitPanel);
*/
private boolean isCardEnabled(int inCardNum)
{
- if (_cardEnabled == null) {_cardEnabled = getCardEnabledFlags();}
+ if (_cardEnabled == null) {
+ _cardEnabled = getCardEnabledFlags();
+ }
return (inCardNum >= 0 && inCardNum < _cardEnabled.length && _cardEnabled[inCardNum]);
}
_okButton.setEnabled(inCardNum == 2 && ((MediaPreviewTableModel) _previewTable.getModel()).hasAnySelected());
}
+ /**
+ * Enable or disable the edit boxes according to the radio button selections
+ */
+ private void enableEditBoxes()
+ {
+ // enable/disable text field for distance input
+ _limitDistBox.setEnabled(_distLimitRadio.isSelected());
+ // and for time limits
+ _limitMinBox.setEnabled(_timeLimitRadio.isSelected());
+ _limitSecBox.setEnabled(_timeLimitRadio.isSelected());
+ }
+
/**
* Parse the time limit values entered and validate them
* @return TimeDifference object describing limit
/**
* @return the selected distance units from the dropdown
*/
- protected Distance.Units getSelectedDistanceUnits()
+ protected Unit getSelectedDistanceUnits()
{
- final Distance.Units[] distUnits = {Distance.Units.KILOMETRES, Distance.Units.METRES, Distance.Units.MILES};
+ final Unit[] distUnits = {UnitSetLibrary.UNITS_KILOMETRES, UnitSetLibrary.UNITS_METRES, UnitSetLibrary.UNITS_MILES};
return distUnits[_distUnitsDropdown.getSelectedIndex()];
}
public void createPreview(boolean inFromButton)
{
// Exit if still on first panel
- if (!_previewEnabled) {return;}
+ if (!_previewEnabled) {
+ return;
+ }
// Create a TimeDifference based on the edit boxes
int numHours = getValue(_offsetHourBox.getText());
int numMins = getValue(_offsetMinBox.getText());
* @param inTimeDiff time difference to use for time offsets
* @param inFirstMedia first media object to use for calculating timezone
*/
- protected void setupPreviewCard(TimeDifference inTimeDiff, MediaFile inFirstMedia)
+ protected void setupPreviewCard(TimeDifference inTimeDiff, MediaObject inFirstMedia)
{
_previewEnabled = false;
TimeDifference timeDiff = inTimeDiff;
if (timeDiff == null)
{
- // No time difference available, so calculate based on computer's time zone
- Timestamp tstamp = null;
- if (inFirstMedia != null) {
- tstamp = inFirstMedia.getTimestamp();
- }
- timeDiff = getTimezoneOffset(tstamp);
+ // No time difference available, so try with zero
+ timeDiff = new TimeDifference(0L);
}
// Use time difference to set edit boxes
_offsetHourBox.setText("" + timeDiff.getNumHours());
_mediaLaterOption.setSelected(timeDiff.getIsPositive());
_pointLaterOption.setSelected(!timeDiff.getIsPositive());
_previewEnabled = true;
+ enableEditBoxes();
createPreview(timeDiff, true);
}
* @param inMedia media object
* @return normally just returns the media timestamp, overridden by audio correlator
*/
- protected Timestamp getMediaTimestamp(MediaFile inMedia)
+ protected Timestamp getMediaTimestamp(MediaObject inMedia)
{
return inMedia.getTimestamp();
}
* @param inOffset time offset to apply
* @return point pair resulting from correlation
*/
- protected PointMediaPair getPointPairForMedia(Track inTrack, MediaFile inMedia, TimeDifference inOffset)
+ protected PointMediaPair getPointPairForMedia(Track inTrack, MediaObject inMedia, TimeDifference inOffset)
{
PointMediaPair pair = new PointMediaPair(inMedia);
- // Add/subtract offset to media timestamp
- Timestamp mediaStamp = getMediaTimestamp(inMedia).createMinusOffset(inOffset);
- int numPoints = inTrack.getNumPoints();
- for (int i=0; i<numPoints; i++)
+ if (inMedia.hasTimestamp())
{
- DataPoint point = inTrack.getPoint(i);
- if (point.getPhoto() == null && point.getAudio() == null)
+ // Add/subtract offset to media timestamp
+ Timestamp mediaStamp = getMediaTimestamp(inMedia);
+ int numPoints = inTrack.getNumPoints();
+ for (int i=0; i<numPoints; i++)
{
- Timestamp pointStamp = point.getTimestamp();
- if (pointStamp != null && pointStamp.isValid())
+ DataPoint point = inTrack.getPoint(i);
+ if (point.getPhoto() == null && point.getAudio() == null)
{
- long numSeconds = pointStamp.getSecondsSince(mediaStamp);
- pair.addPoint(point, numSeconds);
+ Timestamp pointStamp = point.getTimestamp();
+ if (pointStamp != null && pointStamp.isValid())
+ {
+ long numSeconds = pointStamp.getSecondsSince(mediaStamp, _timezone)
+ + inOffset.getTotalSeconds();
+ pair.addPoint(point, numSeconds);
+ }
}
}
}