X-Git-Url: http://gitweb.fperrin.net/?a=blobdiff_plain;f=tim%2Fprune%2FApp.java;h=7be82425ddc3e1628cf0d2c62343d3d50e7c3e47;hb=1ea5817da5381ceebee75ea7294ea78dffff5671;hp=8189ffb6b4aafff66d62d60906961ebaf1ea3e67;hpb=649c5da6ee1bbc590699e11a92316ece2ea8512d;p=GpsPrune.git diff --git a/tim/prune/App.java b/tim/prune/App.java index 8189ffb..7be8242 100644 --- a/tim/prune/App.java +++ b/tim/prune/App.java @@ -10,7 +10,6 @@ import javax.swing.JFrame; import javax.swing.JOptionPane; import tim.prune.config.Config; -import tim.prune.data.Altitude; import tim.prune.data.Checker; import tim.prune.data.DataPoint; import tim.prune.data.Field; @@ -18,11 +17,13 @@ import tim.prune.data.LatLonRectangle; import tim.prune.data.NumberUtils; import tim.prune.data.Photo; import tim.prune.data.PhotoList; +import tim.prune.data.PointCreateOptions; import tim.prune.data.RecentFile; import tim.prune.data.SourceInfo; import tim.prune.data.Track; import tim.prune.data.TrackInfo; import tim.prune.data.SourceInfo.FILE_TYPE; +import tim.prune.data.Unit; import tim.prune.function.AsyncMediaLoader; import tim.prune.function.SaveConfig; import tim.prune.function.SelectTracksFunction; @@ -34,12 +35,15 @@ import tim.prune.gui.MenuManager; import tim.prune.gui.SidebarController; import tim.prune.gui.UndoManager; import tim.prune.gui.Viewport; +import tim.prune.gui.colour.ColourerCaretaker; +import tim.prune.gui.colour.PointColourer; import tim.prune.load.FileLoader; import tim.prune.load.JpegLoader; import tim.prune.load.MediaLinkInfo; import tim.prune.load.TrackNameList; import tim.prune.save.ExifSaver; import tim.prune.save.FileSaver; +import tim.prune.tips.TipManager; import tim.prune.undo.*; @@ -58,12 +62,17 @@ public class App private FileLoader _fileLoader = null; private JpegLoader _jpegLoader = null; private FileSaver _fileSaver = null; - private Stack _undoStack = null; + private UndoStack _undoStack = null; + private ColourerCaretaker _colCaretaker = null; private boolean _mangleTimestampsConfirmed = false; private Viewport _viewport = null; private ArrayList _dataFiles = null; - private boolean _firstDataFile = true; + private boolean _autoAppendNextFile = false; private boolean _busyLoading = false; + private AppMode _appMode = AppMode.NORMAL; + + /** Enum for the app mode - currently only two options but may expand later */ + public enum AppMode {NORMAL, DRAWRECT}; /** @@ -73,10 +82,13 @@ public class App public App(JFrame inFrame) { _frame = inFrame; - _undoStack = new Stack(); + _undoStack = new UndoStack(); _track = new Track(); _trackInfo = new TrackInfo(_track); FunctionLibrary.initialise(this); + _colCaretaker = new ColourerCaretaker(this); + UpdateMessageBroker.addSubscriber(_colCaretaker); + _colCaretaker.setColourer(Config.getPointColourer()); } @@ -103,7 +115,7 @@ public class App public boolean hasDataUnsaved() { return (_undoStack.size() > _lastSavePosition - && (_track.getNumPoints() > 0 || _trackInfo.getPhotoList().getNumPhotos() > 0)); + && (_track.getNumPoints() > 0 || _trackInfo.getPhotoList().hasModifiedMedia())); } /** @@ -114,6 +126,40 @@ public class App return _undoStack; } + /** + * Update the system's point colourer using the one in the Config + */ + public void updatePointColourer() + { + if (_colCaretaker != null) { + _colCaretaker.setColourer(Config.getPointColourer()); + } + } + + /** + * @return colourer object, or null + */ + public PointColourer getPointColourer() + { + if (_colCaretaker == null) {return null;} + return _colCaretaker.getColourer(); + } + + /** + * Show the specified tip if appropriate + * @param inTipNumber tip number from TipManager + */ + public void showTip(int inTipNumber) + { + String key = TipManager.fireTipTrigger(inTipNumber); + if (key != null && !key.equals("")) + { + JOptionPane.showMessageDialog(_frame, I18nManager.getText(key), + I18nManager.getText("tip.title"), JOptionPane.INFORMATION_MESSAGE); + } + } + + /** * Load the specified data files one by one * @param inDataFiles arraylist containing File objects to load @@ -123,14 +169,15 @@ public class App if (inDataFiles == null || inDataFiles.size() == 0) { _dataFiles = null; } - else { + else + { _dataFiles = inDataFiles; File f = _dataFiles.get(0); _dataFiles.remove(0); // Start load of specified file if (_fileLoader == null) _fileLoader = new FileLoader(this, _frame); - _firstDataFile = true; + _autoAppendNextFile = false; // prompt for append _fileLoader.openFile(f); } } @@ -144,6 +191,7 @@ public class App { _undoStack.add(inUndo); UpdateMessageBroker.informSubscribers(inConfirmText); + setCurrentMode(AppMode.NORMAL); } /** @@ -272,6 +320,7 @@ public class App DataPoint currentPoint = _trackInfo.getCurrentPoint(); if (currentPoint != null) { + // Check for photo boolean deletePhoto = false; Photo currentPhoto = currentPoint.getPhoto(); if (currentPhoto != null) @@ -291,10 +340,13 @@ public class App // store necessary information to undo it later int pointIndex = _trackInfo.getSelection().getCurrentPointIndex(); int photoIndex = _trackInfo.getPhotoList().getPhotoIndex(currentPhoto); + int audioIndex = _trackInfo.getAudioList().getAudioIndex(currentPoint.getAudio()); DataPoint nextTrackPoint = _trackInfo.getTrack().getNextTrackPoint(pointIndex + 1); // Construct Undo object - UndoOperation undo = new UndoDeletePoint(pointIndex, currentPoint, photoIndex, - nextTrackPoint != null && nextTrackPoint.getSegmentStart()); + UndoDeletePoint undo = new UndoDeletePoint(pointIndex, currentPoint, photoIndex, + audioIndex, nextTrackPoint != null && nextTrackPoint.getSegmentStart()); + undo.setAtBoundaryOfSelectedRange(pointIndex == _trackInfo.getSelection().getStart() || + pointIndex == _trackInfo.getSelection().getEnd()); // call track to delete point if (_trackInfo.deletePoint()) { @@ -312,94 +364,15 @@ public class App // decouple photo from point currentPhoto.setDataPoint(null); } - UpdateMessageBroker.informSubscribers(); + UpdateMessageBroker.informSubscribers(DataSubscriber.PHOTOS_MODIFIED); } - // Confirm - UpdateMessageBroker.informSubscribers(I18nManager.getText("confirm.deletepoint.single")); - } - } - } - - - /** - * Delete the currently selected range - */ - public void deleteSelectedRange() - { - if (_track == null) return; - // Find out if photos should be deleted or not - int selStart = _trackInfo.getSelection().getStart(); - int selEnd = _trackInfo.getSelection().getEnd(); - if (selStart >= 0 && selEnd >= selStart) - { - int numToDelete = selEnd - selStart + 1; - boolean[] deletePhotos = new boolean[numToDelete]; - Photo[] photosToDelete = new Photo[numToDelete]; - boolean deleteAll = false; - boolean deleteNone = false; - String[] questionOptions = {I18nManager.getText("button.yes"), I18nManager.getText("button.no"), - I18nManager.getText("button.yestoall"), I18nManager.getText("button.notoall"), - I18nManager.getText("button.cancel")}; - DataPoint point = null; - for (int i=0; i -1) { + _trackInfo.getAudioList().deleteAudio(audioIndex); } - } - // add information to undo stack - UndoDeleteRange undo = new UndoDeleteRange(_trackInfo); - // delete requested photos - for (int i=0; i= inIndex) + { + // Extend end of selection by 1 + _trackInfo.getSelection().selectRange(selStart, selEnd+1); + } + // update listeners + UpdateMessageBroker.informSubscribers(I18nManager.getText("confirm.createpoint")); + } + + /** * Cut the current selection and move it to before the currently selected point */ @@ -639,31 +626,33 @@ public class App } /** - * Receive loaded data and start load + * Receive loaded data and determine whether to filter on tracks or not * @param inFieldArray array of fields * @param inDataArray array of data - * @param inAltFormat altitude format * @param inSourceInfo information about the source of the data + * @param inTrackNameList information about the track names */ public void informDataLoaded(Field[] inFieldArray, Object[][] inDataArray, - Altitude.Format inAltFormat, SourceInfo inSourceInfo) + SourceInfo inSourceInfo, TrackNameList inTrackNameList) { - informDataLoaded(inFieldArray, inDataArray, inAltFormat, inSourceInfo, null, null); + // no link array given + informDataLoaded(inFieldArray, inDataArray, null, inSourceInfo, + inTrackNameList, null); } /** * Receive loaded data and determine whether to filter on tracks or not * @param inFieldArray array of fields * @param inDataArray array of data - * @param inAltFormat altitude format + * @param inOptions creation options such as units * @param inSourceInfo information about the source of the data * @param inTrackNameList information about the track names */ public void informDataLoaded(Field[] inFieldArray, Object[][] inDataArray, - Altitude.Format inAltFormat, SourceInfo inSourceInfo, TrackNameList inTrackNameList) + PointCreateOptions inOptions, SourceInfo inSourceInfo, TrackNameList inTrackNameList) { // no link array given - informDataLoaded(inFieldArray, inDataArray, inAltFormat, inSourceInfo, + informDataLoaded(inFieldArray, inDataArray, inOptions, inSourceInfo, inTrackNameList, null); } @@ -671,18 +660,17 @@ public class App * Receive loaded data and determine whether to filter on tracks or not * @param inFieldArray array of fields * @param inDataArray array of data - * @param inAltFormat altitude format + * @param inOptions creation options such as units * @param inSourceInfo information about the source of the data * @param inTrackNameList information about the track names * @param inLinkInfo links to photo/audio clips */ - public void informDataLoaded(Field[] inFieldArray, Object[][] inDataArray, - Altitude.Format inAltFormat, SourceInfo inSourceInfo, - TrackNameList inTrackNameList, MediaLinkInfo inLinkInfo) + public void informDataLoaded(Field[] inFieldArray, Object[][] inDataArray, PointCreateOptions inOptions, + SourceInfo inSourceInfo, TrackNameList inTrackNameList, MediaLinkInfo inLinkInfo) { // Check whether loaded array can be properly parsed into a Track Track loadedTrack = new Track(); - loadedTrack.load(inFieldArray, inDataArray, inAltFormat); + loadedTrack.load(inFieldArray, inDataArray, inOptions); if (loadedTrack.getNumPoints() <= 0) { showErrorMessage("error.load.dialogtitle", "error.load.nopoints"); @@ -702,7 +690,7 @@ public class App { String[] linkArray = inLinkInfo.getLinkArray(); if (linkArray != null) { - new AsyncMediaLoader(this, inLinkInfo.getZipFile(), linkArray, loadedTrack).begin(); + new AsyncMediaLoader(this, inLinkInfo.getZipFile(), linkArray, loadedTrack, inSourceInfo.getFile()).begin(); } } // Look at TrackNameList, decide whether to filter or not @@ -715,6 +703,7 @@ public class App // go directly to load informDataLoaded(loadedTrack, inSourceInfo); } + setCurrentMode(AppMode.NORMAL); } @@ -730,16 +719,19 @@ public class App { // ask whether to replace or append int answer = 0; - if (_dataFiles == null || _firstDataFile) { + if (_autoAppendNextFile) { + // Automatically append the next file + answer = JOptionPane.YES_OPTION; + } + else { + // Ask whether to append or not answer = JOptionPane.showConfirmDialog(_frame, I18nManager.getText("dialog.openappend.text"), I18nManager.getText("dialog.openappend.title"), JOptionPane.YES_NO_CANCEL_OPTION); } - else { - // Automatically append if there's a file load queue - answer = JOptionPane.YES_OPTION; - } + _autoAppendNextFile = false; // reset flag to cancel autoappend + if (answer == JOptionPane.YES_OPTION) { // append data to current Track @@ -807,12 +799,20 @@ public class App loadNextFile(); } + /** + * External trigger to automatically append the next loaded file + * instead of prompting to replace or append + */ + public void autoAppendNextFile() + { + _autoAppendNextFile = true; + } + /** * Load the next file in the waiting list, if any */ private void loadNextFile() { - _firstDataFile = false; if (_dataFiles == null || _dataFiles.size() == 0) { _dataFiles = null; } @@ -821,6 +821,7 @@ public class App public void run() { File f = _dataFiles.get(0); _dataFiles.remove(0); + _autoAppendNextFile = true; _fileLoader.openFile(f); } }).start(); @@ -941,30 +942,16 @@ public class App showErrorMessageNoLookup("error.undofailed.title", I18nManager.getText("error.undofailed.text") + " : " + ue.getMessage()); _undoStack.clear(); - UpdateMessageBroker.informSubscribers(); } catch (EmptyStackException empty) {} + UpdateMessageBroker.informSubscribers(); } - /** - * Helper method to parse an Object into an integer - * @param inObject object, eg from dialog - * @return int value given + * @return the current data status, used for later comparison */ - private static int parseNumber(Object inObject) - { - int num = 0; - if (inObject != null) - { - try - { - num = Integer.parseInt(inObject.toString()); - } - catch (NumberFormatException nfe) - {} - } - return num; + public DataStatus getCurrentDataStatus() { + return new DataStatus(_undoStack.size(), _undoStack.getNumTimesDeleted()); } /** @@ -1035,4 +1022,14 @@ public class App public boolean isBusyLoading() { return _busyLoading; } + + /** @return current app mode */ + public AppMode getCurrentMode() { + return _appMode; + } + + /** @param inMode the current app mode */ + public void setCurrentMode(AppMode inMode) { + _appMode = inMode; + } }