X-Git-Url: https://gitweb.fperrin.net/?p=GpsPrune.git;a=blobdiff_plain;f=tim%2Fprune%2Fdata%2FTrackInfo.java;h=7bcbc641e75fcae730f07178d5ad93637486145c;hp=b987ea9449d6dff66fd52f2af60031752f415413;hb=4d5796d02a15808311c09448d79e6e7d1de9d636;hpb=5625a1abadb5f2ca5f017fe7dbda1d5141cb637b diff --git a/tim/prune/data/TrackInfo.java b/tim/prune/data/TrackInfo.java index b987ea9..7bcbc64 100644 --- a/tim/prune/data/TrackInfo.java +++ b/tim/prune/data/TrackInfo.java @@ -1,7 +1,6 @@ package tim.prune.data; -import java.util.List; - +import java.util.Set; import tim.prune.UpdateMessageBroker; /** @@ -10,33 +9,31 @@ import tim.prune.UpdateMessageBroker; */ public class TrackInfo { - private UpdateMessageBroker _broker = null; private Track _track = null; private Selection _selection = null; private FileInfo _fileInfo = null; private PhotoList _photoList = null; + private AudioList _audioList = null; /** * Constructor * @param inTrack Track object - * @param inBroker broker object */ - public TrackInfo(Track inTrack, UpdateMessageBroker inBroker) + public TrackInfo(Track inTrack) { - _broker = inBroker; _track = inTrack; - _selection = new Selection(_track, inBroker); + _selection = new Selection(_track); _fileInfo = new FileInfo(); _photoList = new PhotoList(); + _audioList = new AudioList(); } /** * @return the Track object */ - public Track getTrack() - { + public Track getTrack() { return _track; } @@ -44,8 +41,7 @@ public class TrackInfo /** * @return the Selection object */ - public Selection getSelection() - { + public Selection getSelection() { return _selection; } @@ -53,25 +49,37 @@ public class TrackInfo /** * @return the FileInfo object */ - public FileInfo getFileInfo() - { + public FileInfo getFileInfo() { return _fileInfo; } + /** + * Replace the file info with a previously made clone + * @param inInfo cloned file info + */ + public void setFileInfo(FileInfo inInfo) { + _fileInfo = inInfo; + } + /** * @return the PhotoList object */ - public PhotoList getPhotoList() - { + public PhotoList getPhotoList() { return _photoList; } + /** + * @return the AudioList object + */ + public AudioList getAudioList() { + return _audioList; + } + /** * Get the currently selected point, if any * @return DataPoint if single point selected, otherwise null */ - public DataPoint getCurrentPoint() - { + public DataPoint getCurrentPoint() { return _track.getPoint(_selection.getCurrentPointIndex()); } @@ -79,54 +87,40 @@ public class TrackInfo * Get the currently selected photo, if any * @return Photo if selected, otherwise null */ - public Photo getCurrentPhoto() - { + public Photo getCurrentPhoto() { return _photoList.getPhoto(_selection.getCurrentPhotoIndex()); } - /** - * Load the specified data into the Track - * @param inFieldArray array of Field objects describing fields - * @param inPointArray 2d object array containing data - * @param inAltFormat altitude format + * Get the currently selected audio clip, if any + * @return AudioClip if selected, otherwise null */ - public void loadTrack(Field[] inFieldArray, Object[][] inPointArray, int inAltFormat) - { - _track.cropTo(0); - _track.load(inFieldArray, inPointArray, inAltFormat); - _selection.clearAll(); + public AudioClip getCurrentAudio() { + return _audioList.getAudio(_selection.getCurrentAudioIndex()); } /** - * Add a List of Photos - * @param inList List containing Photo objects + * Add a Set of Photos + * @param inSet Set containing Photo objects * @return array containing number of photos and number of points added */ - public int[] addPhotos(List inList) + public int[] addPhotos(Set inSet) { - // TODO: Should photos be sorted at load-time, either by filename or date? // Firstly count number of points and photos to add int numPhotosToAdd = 0; int numPointsToAdd = 0; - if (inList != null && !inList.isEmpty()) + if (inSet != null && !inSet.isEmpty()) { - for (int i=0; i 0) { @@ -171,22 +160,30 @@ public class TrackInfo return result; } - /** - * Delete the currently selected range of points - * @return true if successful + * Add a Set of Audio objects + * @param inSet Set containing Audio objects + * @return number of audio objects added */ - public boolean deleteRange() + public int addAudios(Set inSet) { - int startSel = _selection.getStart(); - int endSel = _selection.getEnd(); - boolean answer = _track.deleteRange(startSel, endSel); - // clear range selection - _selection.modifyRangeDeleted(); - return answer; + int numAudiosAdded = 0; + if (inSet != null && !inSet.isEmpty()) + { + for (AudioClip audio : inSet) + { + if (audio != null && !_audioList.contains(audio)) + { + // Add audio object + _audioList.addAudio(audio); + numAudiosAdded++; + // audio objects never have points when they're loaded + } + } + } + return numAudiosAdded; } - /** * Delete the currently selected point * @return true if point deleted @@ -196,7 +193,6 @@ public class TrackInfo if (_track.deletePoint(_selection.getCurrentPointIndex())) { _selection.modifyPointDeleted(); - _broker.informSubscribers(); return true; } return false; @@ -210,7 +206,6 @@ public class TrackInfo */ public boolean deleteCurrentPhoto(boolean inPointToo) { - // delete currently selected photo int photoIndex = _selection.getCurrentPhotoIndex(); if (photoIndex >= 0) { @@ -234,35 +229,58 @@ public class TrackInfo } // update subscribers _selection.modifyPointDeleted(); - _broker.informSubscribers(); + UpdateMessageBroker.informSubscribers(); } return true; } - /** - * Compress the track to the given resolution - * @param inResolution resolution - * @return number of points deleted + * Delete the currently selected audio item and optionally its point too + * @param inPointToo true to also delete associated point + * @return true if delete successful */ - public int compress(int inResolution) + public boolean deleteCurrentAudio(boolean inPointToo) { - int numDeleted = _track.compress(inResolution); - if (numDeleted > 0) - _selection.clearAll(); - return numDeleted; + int audioIndex = _selection.getCurrentAudioIndex(); + if (audioIndex >= 0) + { + AudioClip audio = _audioList.getAudio(audioIndex); + _audioList.deleteAudio(audioIndex); + // has it got a point? + if (audio.getDataPoint() != null) + { + if (inPointToo) + { + // delete point + int pointIndex = _track.getPointIndex(audio.getDataPoint()); + _track.deletePoint(pointIndex); + } + else + { + // disconnect point from audio + audio.getDataPoint().setAudio(null); + audio.setDataPoint(null); + } + } + // update subscribers + _selection.modifyPointDeleted(); + UpdateMessageBroker.informSubscribers(); + } + return true; } /** - * Delete all the duplicate points in the track + * Delete all the points which have been marked for deletion * @return number of points deleted */ - public int deleteDuplicates() + public int deleteMarkedPoints() { - int numDeleted = _track.deleteDuplicates(); - if (numDeleted > 0) + int numDeleted = _track.deleteMarkedPoints(); + if (numDeleted > 0) { _selection.clearAll(); + UpdateMessageBroker.informSubscribers(); + } return numDeleted; } @@ -276,18 +294,43 @@ public class TrackInfo return _track.cloneRange(_selection.getStart(), _selection.getEnd()); } + /** + * Merge the track segments within the given range + * @param inStart start index + * @param inEnd end index + * @return true if successful + */ + public boolean mergeTrackSegments(int inStart, int inEnd) + { + boolean firstTrackPoint = true; + // Loop between start and end + for (int i=inStart; i<=inEnd; i++) { + DataPoint point = _track.getPoint(i); + // Set all segments to false apart from first track point + if (point != null && !point.isWaypoint()) { + point.setSegmentStart(firstTrackPoint); + firstTrackPoint = false; + } + } + // Find following track point, if any + DataPoint nextPoint = _track.getNextTrackPoint(inEnd+1); + if (nextPoint != null) {nextPoint.setSegmentStart(true);} + _selection.markInvalid(); + UpdateMessageBroker.informSubscribers(); + return true; + } + /** - * Interpolate extra points between two selected ones - * @param inStartIndex start index of interpolation - * @param inNumPoints num points to insert + * Average selected points to create a new one * @return true if successful */ - public boolean interpolate(int inNumPoints) + public boolean average() { - boolean success = _track.interpolate(_selection.getStart(), inNumPoints); - if (success) - _selection.selectRangeEnd(_selection.getEnd() + inNumPoints); + boolean success = _track.average(_selection.getStart(), _selection.getEnd()); + if (success) { + selectPoint(_selection.getEnd()+1); + } return success; } @@ -298,10 +341,52 @@ public class TrackInfo */ public void selectPoint(DataPoint inPoint) { - // get the index of the given Point - int index = _track.getPointIndex(inPoint); + selectPoint(_track.getPointIndex(inPoint)); + } + + /** + * Increment the selected point index by the given increment + * @param inPointIncrement +1 for next point, -1 for previous etc + */ + public void incrementPointIndex(int inPointIncrement) + { + int index = _selection.getCurrentPointIndex() + inPointIncrement; + if (index < 0) index = 0; + else if (index >= _track.getNumPoints()) index = _track.getNumPoints()-1; + selectPoint(index); + } + + /** + * Select the data point with the given index + * @param inPointIndex index of DataPoint to select, or -1 for none + */ + public void selectPoint(int inPointIndex) + { + if (_selection.getCurrentPointIndex() == inPointIndex || inPointIndex >= _track.getNumPoints()) {return;} + DataPoint selectedPoint = _track.getPoint(inPointIndex); + // get the index of the current photo + int photoIndex = _selection.getCurrentPhotoIndex(); + // Check if point has photo or not + boolean pointHasPhoto = inPointIndex >= 0 && selectedPoint.getPhoto() != null; + if (pointHasPhoto) { + photoIndex = _photoList.getPhotoIndex(selectedPoint.getPhoto()); + } + else if (photoIndex < 0 || _photoList.getPhoto(photoIndex).isConnected()) { + // selected point hasn't got a photo - deselect photo if necessary + photoIndex = -1; + } + // Check if point has an audio item or not + int audioIndex = _selection.getCurrentAudioIndex(); + boolean pointHasAudio = inPointIndex >= 0 && selectedPoint.getAudio() != null; + if (pointHasAudio) { + audioIndex = _audioList.getAudioIndex(selectedPoint.getAudio()); + } + else if (audioIndex < 0 || _audioList.getAudio(audioIndex).isConnected()) { + // deselect current audio clip + audioIndex = -1; + } // give to selection - _selection.selectPoint(index); + _selection.selectPointPhotoAudio(inPointIndex, photoIndex, audioIndex); } /** @@ -310,28 +395,107 @@ public class TrackInfo */ public void selectPhoto(int inPhotoIndex) { + if (_selection.getCurrentPhotoIndex() == inPhotoIndex) {return;} + // Photo is primary selection here, not as a result of a point selection + // Therefore the photo selection takes priority, deselecting point if necessary // Find Photo object Photo photo = _photoList.getPhoto(inPhotoIndex); + int pointIndex = _selection.getCurrentPointIndex(); + DataPoint currPoint = getCurrentPoint(); if (photo != null) { - // Find point object and its index - int pointIndex = _track.getPointIndex(photo.getDataPoint()); - // give to selection object - _selection.selectPhotoAndPoint(inPhotoIndex, pointIndex); + // Has the photo got a point? + if (photo.isConnected()) { + pointIndex = _track.getPointIndex(photo.getDataPoint()); + } + else { + // Check whether to deselect current point or not if photo not correlated + if (pointIndex >= 0 && _track.getPoint(pointIndex).getPhoto() != null) { + pointIndex = -1; + } + } + } + else { + // no photo, but maybe need to deselect point + if (currPoint != null && currPoint.getPhoto() != null) { + pointIndex = -1; + } } - else + // Has the new point got an audio clip? + DataPoint selectedPoint = _track.getPoint(pointIndex); + int audioIndex = _selection.getCurrentAudioIndex(); + if (selectedPoint != null && selectedPoint.getAudio() != null) { + // New point has an audio, so select it + audioIndex = _audioList.getAudioIndex(selectedPoint.getAudio()); + } + else if (currPoint != null && selectedPoint != currPoint && currPoint.getAudio() != null) { + // Old point had an audio, so deselect it + audioIndex = -1; + } + // give to selection object + _selection.selectPointPhotoAudio(pointIndex, inPhotoIndex, audioIndex); + } + + /** + * Select the given audio object and its point if any + * @param inAudioIndex index of audio item to select + */ + public void selectAudio(int inAudioIndex) + { + if (_selection.getCurrentAudioIndex() == inAudioIndex) {return;} + // Audio selection takes priority, deselecting point if necessary + AudioClip audio = _audioList.getAudio(inAudioIndex); + int pointIndex = _selection.getCurrentPointIndex(); + DataPoint currPoint = getCurrentPoint(); + if (audio != null) { - // no photo, just reset selection - _selection.selectPhotoAndPoint(-1, -1); + // Find point object and its index + if (audio.isConnected()) { + pointIndex = _track.getPointIndex(audio.getDataPoint()); + } + else { + // Check whether to deselect current point or not if audio not correlated + if (pointIndex >= 0 && _track.getPoint(pointIndex).getAudio() != null) { + pointIndex = -1; + } + } + } + else { + // check if current point has audio or not + if (currPoint != null && currPoint.getAudio() != null) { + pointIndex = -1; + } + } + // Has the new point got a photo? + DataPoint selectedPoint = _track.getPoint(pointIndex); + int photoIndex = _selection.getCurrentPhotoIndex(); + if (selectedPoint != null && selectedPoint.getPhoto() != null) { + // New point has a photo, so select it + photoIndex = _photoList.getPhotoIndex(selectedPoint.getPhoto()); } + else if (currPoint != null && selectedPoint != currPoint && currPoint.getPhoto() != null) { + // Old point had a photo, so deselect it + photoIndex = -1; + } + // give to selection object + _selection.selectPointPhotoAudio(pointIndex, photoIndex, inAudioIndex); } /** - * Fire a trigger to all data subscribers + * Extend the current selection to end at the given point, eg by shift-clicking + * @param inPointNum index of end point */ - public void triggerUpdate() + public void extendSelection(int inPointNum) { - _broker.informSubscribers(); + // See whether to start selection from current range start or current point + int rangeStart = _selection.getStart(); + if (rangeStart < 0 || _selection.getCurrentPointIndex() != _selection.getEnd()) { + rangeStart = _selection.getCurrentPointIndex(); + } + selectPoint(inPointNum); + if (rangeStart < inPointNum) { + _selection.selectRange(rangeStart, inPointNum); + } } }