X-Git-Url: https://gitweb.fperrin.net/?p=GpsPrune.git;a=blobdiff_plain;f=src%2Ftim%2Fprune%2Ffunction%2FAsyncMediaLoader.java;fp=src%2Ftim%2Fprune%2Ffunction%2FAsyncMediaLoader.java;h=78ffc838197450079cf935f6da59cdd1186b35e4;hp=0000000000000000000000000000000000000000;hb=ce6f2161b8596f7018d6a76bff79bc9e571f35fd;hpb=2d8cb72e84d5cc1089ce77baf1e34ea3ea2f8465 diff --git a/src/tim/prune/function/AsyncMediaLoader.java b/src/tim/prune/function/AsyncMediaLoader.java new file mode 100644 index 0000000..78ffc83 --- /dev/null +++ b/src/tim/prune/function/AsyncMediaLoader.java @@ -0,0 +1,182 @@ +package tim.prune.function; + +import java.io.File; + +import tim.prune.App; +import tim.prune.DataSubscriber; +import tim.prune.GenericFunction; +import tim.prune.I18nManager; +import tim.prune.UpdateMessageBroker; +import tim.prune.data.AudioClip; +import tim.prune.data.DataPoint; +import tim.prune.data.Distance; +import tim.prune.data.MediaObject; +import tim.prune.data.Photo; +import tim.prune.data.Track; +import tim.prune.data.UnitSetLibrary; +import tim.prune.load.MediaHelper; +import tim.prune.load.MediaLoadProgressDialog; +import tim.prune.undo.UndoLoadAudios; +import tim.prune.undo.UndoLoadPhotos; + +/** + * Function to load media asynchronously, + * either from inside a zip/kmz file or remotely + */ +public class AsyncMediaLoader extends GenericFunction +implements Runnable, Cancellable +{ + /** Archive from which points were loaded */ + private File _zipFile = null; + /** Array of links */ + private String[] _linkArray = null; + /** Track to use for connecting */ + private Track _track = null; + /** Source file */ + private File _sourceFile = null; + /** Cancelled flag */ + private boolean _cancelled = false; + + + /** + * Constructor + * @param inApp App object + * @param inLinkArray array of links + * @param inTrack Track object for connecting points + * @param inSourceFile file from which data was loaded, if any + */ + public AsyncMediaLoader(App inApp, File inZipFile, String[] inLinkArray, Track inTrack, File inSourceFile) + { + super(inApp); + _zipFile = inZipFile; + _linkArray = inLinkArray; + _track = inTrack; + _sourceFile = inSourceFile; + } + + /** + * Begin the load + */ + public void begin() + { + _cancelled = false; + if (_linkArray != null) + new Thread(this).start(); + } + + /** Cancel */ + public void cancel() { + _cancelled = true; + } + + /** + * @return the name key + */ + public String getNameKey() { + return "function.asyncmediaload"; + } + + /** + * Execute the load in a separate thread + */ + public void run() + { + // Count links first so that progress bar can be shown + int numLinks = 0; + for (int i=0; i<_linkArray.length; i++) { + if (_linkArray[i] != null) { + numLinks++; + } + } + if (numLinks <= 0) return; + // Make progress dialog + MediaLoadProgressDialog progressDialog = new MediaLoadProgressDialog(_app.getFrame(), this); + + // Make array to store results + MediaObject[] media = new MediaObject[numLinks]; + int currLink = 0; + for (int i=0; i<_linkArray.length && !_cancelled; i++) + { + if (_linkArray[i] != null) + { + MediaObject mf = MediaHelper.createMediaObject(_zipFile, _linkArray[i], _sourceFile); + if (mf != null) + { + // Check if the media object has a point now (from exif) + DataPoint exifPoint = mf.getDataPoint(); + // attach media to point and set status + _track.getPoint(i).attachMedia(mf); + // Check exif to see whether media was already tagged + final MediaObject.Status originalMediaStatus = + (exifPoint == null ? MediaObject.Status.NOT_CONNECTED : MediaObject.Status.TAGGED); + mf.setOriginalStatus(originalMediaStatus); + MediaObject.Status currMediaStatus = MediaObject.Status.TAGGED; + if (exifPoint != null) + { + final double distinMetres = Distance.convertRadiansToDistance( + DataPoint.calculateRadiansBetween(exifPoint, _track.getPoint(i)), + UnitSetLibrary.UNITS_METRES); + if (distinMetres > 10.0) { + currMediaStatus = MediaObject.Status.CONNECTED; // still connected but changed + } + } + mf.setCurrentStatus(currMediaStatus); + media[currLink] = mf; + // update progress + if (!_app.isBusyLoading()) { + progressDialog.showProgress(currLink, numLinks); + } + currLink++; + } + try {Thread.sleep(100);} catch (InterruptedException ie) {} + } + } + progressDialog.close(); + + // Wait until App is ready to receive media (may have to ask about append/replace etc) + waitUntilAppReady(); + + // Go through the loaded media and check if the points are still in the track + int numPhotos = 0, numAudios = 0; + for (currLink=0; currLink 0) { + _app.completeFunction(new UndoLoadPhotos(numPhotos, 0), "" + numPhotos + " " + + I18nManager.getText(numPhotos == 1?"confirm.jpegload.single":"confirm.jpegload.multi")); + } + if (numAudios > 0) { + _app.completeFunction(new UndoLoadAudios(numAudios), I18nManager.getText("confirm.audioload")); + } + UpdateMessageBroker.informSubscribers(DataSubscriber.DATA_ADDED_OR_REMOVED); + } + + + /** + * Wait until the App is ready + */ + private void waitUntilAppReady() + { + long waitInterval = 500; // milliseconds + while (_app.isBusyLoading()) + { + try {Thread.sleep(waitInterval);} catch (InterruptedException ie) {} + waitInterval *= 1.2; + } + } +}