1 package tim.prune.function;
6 import tim.prune.DataSubscriber;
7 import tim.prune.GenericFunction;
8 import tim.prune.I18nManager;
9 import tim.prune.UpdateMessageBroker;
10 import tim.prune.data.AudioClip;
11 import tim.prune.data.DataPoint;
12 import tim.prune.data.Distance;
13 import tim.prune.data.MediaObject;
14 import tim.prune.data.Photo;
15 import tim.prune.data.Track;
16 import tim.prune.data.UnitSetLibrary;
17 import tim.prune.load.MediaHelper;
18 import tim.prune.load.MediaLoadProgressDialog;
19 import tim.prune.undo.UndoLoadAudios;
20 import tim.prune.undo.UndoLoadPhotos;
23 * Function to load media asynchronously,
24 * either from inside a zip/kmz file or remotely
26 public class AsyncMediaLoader extends GenericFunction
27 implements Runnable, Cancellable
29 /** Archive from which points were loaded */
30 private File _zipFile = null;
32 private String[] _linkArray = null;
33 /** Track to use for connecting */
34 private Track _track = null;
36 private File _sourceFile = null;
38 private boolean _cancelled = false;
43 * @param inApp App object
44 * @param inLinkArray array of links
45 * @param inTrack Track object for connecting points
46 * @param inSourceFile file from which data was loaded, if any
48 public AsyncMediaLoader(App inApp, File inZipFile, String[] inLinkArray, Track inTrack, File inSourceFile)
52 _linkArray = inLinkArray;
54 _sourceFile = inSourceFile;
63 if (_linkArray != null)
64 new Thread(this).start();
68 public void cancel() {
73 * @return the name key
75 public String getNameKey() {
76 return "function.asyncmediaload";
80 * Execute the load in a separate thread
84 // Count links first so that progress bar can be shown
86 for (int i=0; i<_linkArray.length; i++) {
87 if (_linkArray[i] != null) {
91 if (numLinks <= 0) return;
92 // Make progress dialog
93 MediaLoadProgressDialog progressDialog = new MediaLoadProgressDialog(_app.getFrame(), this);
95 // Make array to store results
96 MediaObject[] media = new MediaObject[numLinks];
98 for (int i=0; i<_linkArray.length && !_cancelled; i++)
100 if (_linkArray[i] != null)
102 MediaObject mf = MediaHelper.createMediaObject(_zipFile, _linkArray[i], _sourceFile);
105 // Check if the media object has a point now (from exif)
106 DataPoint exifPoint = mf.getDataPoint();
107 // attach media to point and set status
108 _track.getPoint(i).attachMedia(mf);
109 // Check exif to see whether media was already tagged
110 final MediaObject.Status originalMediaStatus =
111 (exifPoint == null ? MediaObject.Status.NOT_CONNECTED : MediaObject.Status.TAGGED);
112 mf.setOriginalStatus(originalMediaStatus);
113 MediaObject.Status currMediaStatus = MediaObject.Status.TAGGED;
114 if (exifPoint != null)
116 final double distinMetres = Distance.convertRadiansToDistance(
117 DataPoint.calculateRadiansBetween(exifPoint, _track.getPoint(i)),
118 UnitSetLibrary.UNITS_METRES);
119 if (distinMetres > 10.0) {
120 currMediaStatus = MediaObject.Status.CONNECTED; // still connected but changed
123 mf.setCurrentStatus(currMediaStatus);
124 media[currLink] = mf;
126 if (!_app.isBusyLoading()) {
127 progressDialog.showProgress(currLink, numLinks);
131 try {Thread.sleep(100);} catch (InterruptedException ie) {}
134 progressDialog.close();
136 // Wait until App is ready to receive media (may have to ask about append/replace etc)
139 // Go through the loaded media and check if the points are still in the track
140 int numPhotos = 0, numAudios = 0;
141 for (currLink=0; currLink<numLinks; currLink++)
143 MediaObject mo = media[currLink];
144 if (mo != null && _track.containsPoint(mo.getDataPoint()))
146 if (mo instanceof Photo)
148 _app.getTrackInfo().getPhotoList().addPhoto((Photo) mo);
151 else if (mo instanceof AudioClip)
153 _app.getTrackInfo().getAudioList().addAudio((AudioClip) mo);
158 // Confirm and update
160 _app.completeFunction(new UndoLoadPhotos(numPhotos, 0), "" + numPhotos + " " +
161 I18nManager.getText(numPhotos == 1?"confirm.jpegload.single":"confirm.jpegload.multi"));
164 _app.completeFunction(new UndoLoadAudios(numAudios), I18nManager.getText("confirm.audioload"));
166 UpdateMessageBroker.informSubscribers(DataSubscriber.DATA_ADDED_OR_REMOVED);
171 * Wait until the App is ready
173 private void waitUntilAppReady()
175 long waitInterval = 500; // milliseconds
176 while (_app.isBusyLoading())
178 try {Thread.sleep(waitInterval);} catch (InterruptedException ie) {}