From: activityworkshop Date: Sat, 14 Feb 2015 14:13:41 +0000 (+0100) Subject: Version 7, February 2009 X-Git-Tag: v19.2~31 X-Git-Url: http://gitweb.fperrin.net/?p=GpsPrune.git;a=commitdiff_plain;h=54b9d8bc8f0025ccf97a67d9dd217ef1f9cf082f Version 7, February 2009 --- diff --git a/tim/prune/App.java b/tim/prune/App.java index ecde548..ced255a 100644 --- a/tim/prune/App.java +++ b/tim/prune/App.java @@ -7,10 +7,7 @@ import java.util.Stack; import javax.swing.JFrame; import javax.swing.JOptionPane; -import tim.prune.browser.BrowserLauncher; -import tim.prune.browser.UrlGenerator; -import tim.prune.correlate.PhotoCorrelator; -import tim.prune.correlate.PointPair; +import tim.prune.data.Altitude; import tim.prune.data.Coordinate; import tim.prune.data.DataPoint; import tim.prune.data.Field; @@ -21,31 +18,23 @@ import tim.prune.data.Photo; import tim.prune.data.PhotoList; import tim.prune.data.Track; import tim.prune.data.TrackInfo; -import tim.prune.edit.FieldEditList; -import tim.prune.edit.PointEditor; -import tim.prune.edit.PointNameEditor; +import tim.prune.function.browser.BrowserLauncher; +import tim.prune.function.browser.UrlGenerator; +import tim.prune.function.edit.FieldEditList; +import tim.prune.function.edit.PointEditor; +import tim.prune.function.edit.PointNameEditor; import tim.prune.gui.MenuManager; -import tim.prune.gui.TimeOffsetDialog; import tim.prune.gui.UndoManager; import tim.prune.load.FileLoader; -import tim.prune.load.GpsLoader; import tim.prune.load.JpegLoader; import tim.prune.save.ExifSaver; import tim.prune.save.FileSaver; -import tim.prune.save.GpxExporter; -import tim.prune.save.KmlExporter; -import tim.prune.save.PovExporter; -import tim.prune.threedee.ThreeDException; -import tim.prune.threedee.ThreeDWindow; -import tim.prune.threedee.WindowFactory; import tim.prune.undo.UndoAddTimeOffset; import tim.prune.undo.UndoCompress; import tim.prune.undo.UndoConnectPhoto; import tim.prune.undo.UndoConnectPhotoWithClone; -import tim.prune.undo.UndoCorrelatePhotos; import tim.prune.undo.UndoCreatePoint; import tim.prune.undo.UndoCutAndMove; -import tim.prune.undo.UndoDeleteDuplicates; import tim.prune.undo.UndoDeletePhoto; import tim.prune.undo.UndoDeletePoint; import tim.prune.undo.UndoDeleteRange; @@ -57,7 +46,6 @@ import tim.prune.undo.UndoLoad; import tim.prune.undo.UndoLoadPhotos; import tim.prune.undo.UndoMergeTrackSegments; import tim.prune.undo.UndoOperation; -import tim.prune.undo.UndoRearrangeWaypoints; import tim.prune.undo.UndoReverseSection; @@ -74,21 +62,10 @@ public class App private MenuManager _menuManager = null; private FileLoader _fileLoader = null; private JpegLoader _jpegLoader = null; - private GpsLoader _gpsLoader = null; private FileSaver _fileSaver = null; - private KmlExporter _kmlExporter = null; - private GpxExporter _gpxExporter = null; - private PovExporter _povExporter = null; - private BrowserLauncher _browserLauncher = null; - private Stack _undoStack = null; + private Stack _undoStack = null; private boolean _mangleTimestampsConfirmed = false; - // Constants - public static final int REARRANGE_TO_START = 0; - public static final int REARRANGE_TO_END = 1; - public static final int REARRANGE_TO_NEAREST = 2; - - /** * Constructor * @param inFrame frame object for application @@ -96,9 +73,10 @@ public class App public App(JFrame inFrame) { _frame = inFrame; - _undoStack = new Stack(); + _undoStack = new Stack(); _track = new Track(); _trackInfo = new TrackInfo(_track); + FunctionLibrary.initialise(this); } @@ -110,6 +88,14 @@ public class App return _trackInfo; } + /** + * @return the dialog frame + */ + public JFrame getFrame() + { + return _frame; + } + /** * Check if the application has unsaved data * @return true if data is unsaved, false otherwise @@ -123,11 +109,22 @@ public class App /** * @return the undo stack */ - public Stack getUndoStack() + public Stack getUndoStack() { return _undoStack; } + /** + * Complete a function execution + * @param inUndo undo object to be added to stack + * @param inConfirmText confirmation text + */ + public void completeFunction(UndoOperation inUndo, String inConfirmText) + { + _undoStack.add(inUndo); + UpdateMessageBroker.informSubscribers(inConfirmText); + } + /** * Set the MenuManager object to be informed about changes * @param inManager MenuManager object @@ -159,25 +156,13 @@ public class App _jpegLoader.openDialog(new LatLonRectangle(_track.getLatRange(), _track.getLonRange())); } - /** - * Start a load from Gps - */ - public void beginLoadFromGps() - { - if (_gpsLoader == null) - _gpsLoader = new GpsLoader(this, _frame); - _gpsLoader.openDialog(); - } - /** * Save the file in the selected format */ public void saveFile() { - if (_track == null) - { - JOptionPane.showMessageDialog(_frame, I18nManager.getText("error.save.nodata"), - I18nManager.getText("error.save.dialogtitle"), JOptionPane.ERROR_MESSAGE); + if (_track == null) { + showErrorMessage("error.save.dialogtitle", "error.save.nodata"); } else { @@ -191,105 +176,6 @@ public class App } - /** - * Export track data as Kml - */ - public void exportKml() - { - if (_track == null) - { - JOptionPane.showMessageDialog(_frame, I18nManager.getText("error.save.nodata"), - I18nManager.getText("error.save.dialogtitle"), JOptionPane.ERROR_MESSAGE); - } - else - { - // Invoke the export - if (_kmlExporter == null) - { - _kmlExporter = new KmlExporter(_frame, _trackInfo); - } - _kmlExporter.showDialog(); - } - } - - - /** - * Export track data as Gpx - */ - public void exportGpx() - { - if (_track == null) - { - JOptionPane.showMessageDialog(_frame, I18nManager.getText("error.save.nodata"), - I18nManager.getText("error.save.dialogtitle"), JOptionPane.ERROR_MESSAGE); - } - else - { - // Invoke the export - if (_gpxExporter == null) - { - _gpxExporter = new GpxExporter(_frame, _trackInfo); - } - _gpxExporter.showDialog(); - } - } - - - /** - * Export track data as Pov without specifying settings - */ - public void exportPov() - { - exportPov(false, 0.0, 0.0, 0.0, 0); - } - - /** - * Export track data as Pov and also specify settings - * @param inX X component of unit vector - * @param inY Y component of unit vector - * @param inZ Z component of unit vector - * @param inAltitudeCap altitude cap - */ - public void exportPov(double inX, double inY, double inZ, int inAltitudeCap) - { - exportPov(true, inX, inY, inZ, inAltitudeCap); - } - - /** - * Export track data as Pov with optional angle specification - * @param inDefineAngles true to define angles, false to ignore - * @param inX X component of unit vector - * @param inY Y component of unit vector - * @param inZ Z component of unit vector - * @param inAltitudeCap altitude cap - */ - private void exportPov(boolean inDefineSettings, double inX, double inY, double inZ, int inAltitudeCap) - { - // Check track has data to export - if (_track == null || _track.getNumPoints() <= 0) - { - JOptionPane.showMessageDialog(_frame, I18nManager.getText("error.save.nodata"), - I18nManager.getText("error.save.dialogtitle"), JOptionPane.ERROR_MESSAGE); - } - else - { - // Make new exporter if necessary - if (_povExporter == null) - { - _povExporter = new PovExporter(_frame, _track); - } - // Specify angles if necessary - if (inDefineSettings) - { - _povExporter.setCameraCoordinates(inX, inY, inZ); - _povExporter.setAltitudeCap(inAltitudeCap); - } - // Initiate export - _povExporter.showDialog(); - } - } - - /** * Exit the application if confirmed */ @@ -514,57 +400,13 @@ public class App /** - * Delete all the duplicate points in the track + * Finish the compression by deleting the marked points */ - public void deleteDuplicates() - { - if (_track != null) - { - // Save undo information - UndoOperation undo = new UndoDeleteDuplicates(_track); - // tell track to do it - int numDeleted = _trackInfo.deleteDuplicates(); - if (numDeleted > 0) - { - _undoStack.add(undo); - String message = null; - if (numDeleted == 1) - { - message = "1 " + I18nManager.getText("confirm.deleteduplicates.single"); - } - else - { - message = "" + numDeleted + " " + I18nManager.getText("confirm.deleteduplicates.multi"); - } - // Pass message to broker - UpdateMessageBroker.informSubscribers(message); - } - else - { - // No duplicates found to delete - JOptionPane.showMessageDialog(_frame, - I18nManager.getText("dialog.deleteduplicates.nonefound"), - I18nManager.getText("dialog.deleteduplicates.title"), JOptionPane.INFORMATION_MESSAGE); - } - } - } - - - /** - * Compress the track - */ - public void compressTrack() + public void finishCompressTrack() { UndoCompress undo = new UndoCompress(_track); - // Get compression parameter - Object compParam = JOptionPane.showInputDialog(_frame, - I18nManager.getText("dialog.compresstrack.parameter.text"), - I18nManager.getText("dialog.compresstrack.title"), - JOptionPane.QUESTION_MESSAGE, null, null, "100"); - int compNumber = parseNumber(compParam); - if (compNumber <= 0) return; // call track to do compress - int numPointsDeleted = _trackInfo.compress(compNumber); + int numPointsDeleted = _trackInfo.deleteMarkedPoints(); // add to undo stack if successful if (numPointsDeleted > 0) { @@ -573,14 +415,11 @@ public class App UpdateMessageBroker.informSubscribers("" + numPointsDeleted + " " + (numPointsDeleted==1?I18nManager.getText("confirm.deletepoint.single"):I18nManager.getText("confirm.deletepoint.multi"))); } - else - { - JOptionPane.showMessageDialog(_frame, I18nManager.getText("dialog.compresstrack.nonefound"), - I18nManager.getText("dialog.compresstrack.title"), JOptionPane.WARNING_MESSAGE); + else { + showErrorMessage("function.compress", "dialog.compress.nonefound"); } } - /** * Reverse the currently selected section of the track */ @@ -607,24 +446,6 @@ public class App } } - /** - * Trigger the dialog to add a time offset to the current selection - */ - public void beginAddTimeOffset() - { - int selStart = _trackInfo.getSelection().getStart(); - int selEnd = _trackInfo.getSelection().getEnd(); - if (!_track.hasData(Field.TIMESTAMP, selStart, selEnd)) { - JOptionPane.showMessageDialog(_frame, - I18nManager.getText("dialog.addtimeoffset.notimestamps"), - I18nManager.getText("dialog.addtimeoffset.title"), JOptionPane.ERROR_MESSAGE); - } - else { - TimeOffsetDialog timeDialog = new TimeOffsetDialog(this, _frame); - timeDialog.showDialog(); - } - } - /** * Complete the add time offset function with the specified offset * @param inTimeOffset time offset to add (+ve for add, -ve for subtract) @@ -690,6 +511,24 @@ public class App } + /** + * Average the selected points + */ + public void averageSelection() + { + // Find following track point + DataPoint nextPoint = _track.getNextTrackPoint(_trackInfo.getSelection().getEnd() + 1); + boolean segFlag = false; + if (nextPoint != null) {segFlag = nextPoint.getSegmentStart();} + UndoInsert undo = new UndoInsert(_trackInfo.getSelection().getEnd() + 1, 1, nextPoint != null, segFlag); + // call track info object to do the averaging + if (_trackInfo.average()) + { + _undoStack.add(undo); + } + } + + /** * Create a new point at the given lat/long coordinates * @param inLat latitude @@ -711,37 +550,6 @@ public class App } - /** - * Rearrange the waypoints into track order - * @param inFunction nearest point, all to end or all to start - */ - public void rearrangeWaypoints(int inFunction) - { - UndoRearrangeWaypoints undo = new UndoRearrangeWaypoints(_track); - boolean success = false; - if (inFunction == REARRANGE_TO_START || inFunction == REARRANGE_TO_END) - { - // Collect the waypoints to the start or end of the track - success = _track.collectWaypoints(inFunction == REARRANGE_TO_START); - } - else - { - // Interleave the waypoints into track order - success = _track.interleaveWaypoints(); - } - if (success) - { - _undoStack.add(undo); - UpdateMessageBroker.informSubscribers(I18nManager.getText("confirm.rearrangewaypoints")); - } - else - { - JOptionPane.showMessageDialog(_frame, I18nManager.getText("error.rearrange.noop"), - I18nManager.getText("error.function.noop.title"), JOptionPane.WARNING_MESSAGE); - } - } - - /** * Cut the current selection and move it to before the currently selected point */ @@ -782,34 +590,6 @@ public class App } - /** - * Open a new window with the 3d view - */ - public void show3dWindow() - { - ThreeDWindow window = WindowFactory.getWindow(this, _frame); - if (window == null) - { - JOptionPane.showMessageDialog(_frame, I18nManager.getText("error.function.nojava3d"), - I18nManager.getText("error.function.notavailable.title"), JOptionPane.WARNING_MESSAGE); - } - else - { - try - { - // Pass the track object and show the window - window.setTrack(_track); - window.show(); - } - catch (ThreeDException e) - { - JOptionPane.showMessageDialog(_frame, I18nManager.getText("error.3d") + ": " + e.getMessage(), - I18nManager.getText("error.3d.title"), JOptionPane.ERROR_MESSAGE); - } - } - } - - /** * Select all points */ @@ -825,6 +605,7 @@ public class App { // deselect point, range and photo _trackInfo.getSelection().clearAll(); + _track.clearDeletionMarkers(); } @@ -835,44 +616,25 @@ public class App * @param inAltFormat altitude format * @param inFilename filename used */ - public void informDataLoaded(Field[] inFieldArray, Object[][] inDataArray, int inAltFormat, String inFilename) - { - informDataLoaded(inFieldArray, inDataArray, inAltFormat, inFilename, false); - } - - /** - * Receive loaded data and optionally merge with current Track - * @param inFieldArray array of fields - * @param inDataArray array of data - * @param inAltFormat altitude format - * @param inFilename filename used - * @param inOverrideAppend true to override append question and always append - */ - public void informDataLoaded(Field[] inFieldArray, Object[][] inDataArray, int inAltFormat, - String inFilename, boolean inOverrideAppend) + public void informDataLoaded(Field[] inFieldArray, Object[][] inDataArray, Altitude.Format inAltFormat, + String inFilename) { // Check whether loaded array can be properly parsed into a Track Track loadedTrack = new Track(); loadedTrack.load(inFieldArray, inDataArray, inAltFormat); if (loadedTrack.getNumPoints() <= 0) { - JOptionPane.showMessageDialog(_frame, - I18nManager.getText("error.load.nopoints"), - I18nManager.getText("error.load.dialogtitle"), - JOptionPane.ERROR_MESSAGE); + showErrorMessage("error.load.dialogtitle", "error.load.nopoints"); return; } // Decide whether to load or append - if (_track != null && _track.getNumPoints() > 0) + if (_track.getNumPoints() > 0) { // ask whether to replace or append - int answer = JOptionPane.YES_OPTION; - if (!inOverrideAppend) { - answer = JOptionPane.showConfirmDialog(_frame, - I18nManager.getText("dialog.openappend.text"), - I18nManager.getText("dialog.openappend.title"), - JOptionPane.YES_NO_CANCEL_OPTION); - } + int answer = JOptionPane.showConfirmDialog(_frame, + I18nManager.getText("dialog.openappend.text"), + I18nManager.getText("dialog.openappend.title"), + JOptionPane.YES_NO_CANCEL_OPTION); if (answer == JOptionPane.YES_OPTION) { // append data to current Track @@ -898,9 +660,8 @@ public class App } _undoStack.add(new UndoLoad(_trackInfo, inDataArray.length, photos)); _lastSavePosition = _undoStack.size(); - // TODO: Should be possible to reuse the Track object already loaded? - _trackInfo.selectPoint(null); - _trackInfo.loadTrack(inFieldArray, inDataArray, inAltFormat); + _trackInfo.getSelection().clearAll(); + _track.load(loadedTrack); _trackInfo.getFileInfo().setFile(inFilename); if (photos != null) { @@ -910,10 +671,11 @@ public class App } else { - // currently no data held, so use received data + // Currently no data held, so transfer received data _undoStack.add(new UndoLoad(_trackInfo, inDataArray.length, null)); _lastSavePosition = _undoStack.size(); - _trackInfo.loadTrack(inFieldArray, inDataArray, inAltFormat); + _trackInfo.getSelection().clearAll(); + _track.load(loadedTrack); _trackInfo.getFileInfo().setFile(inFilename); } UpdateMessageBroker.informSubscribers(); @@ -928,7 +690,7 @@ public class App * Accept a list of loaded photos * @param inPhotoSet Set of Photo objects */ - public void informPhotosLoaded(Set inPhotoSet) + public void informPhotosLoaded(Set inPhotoSet) { if (inPhotoSet != null && !inPhotoSet.isEmpty()) { @@ -1063,117 +825,6 @@ public class App } - /** - * Begin the photo correlation process by invoking dialog - */ - public void beginCorrelatePhotos() - { - PhotoCorrelator correlator = new PhotoCorrelator(this, _frame); - // TODO: Do we need to keep a reference to this Photo Correlator object to reuse it later? - correlator.begin(); - } - - - /** - * Finish the photo correlation process - * @param inPointPairs array of PointPair objects describing operation - */ - public void finishCorrelatePhotos(PointPair[] inPointPairs) - { - // TODO: This method is too big for App, but where should it go? - if (inPointPairs != null && inPointPairs.length > 0) - { - // begin to construct undo information - UndoCorrelatePhotos undo = new UndoCorrelatePhotos(_trackInfo); - // loop over Photos - int arraySize = inPointPairs.length; - int i = 0, numPhotos = 0; - int numPointsToCreate = 0; - PointPair pair = null; - for (i=0; i 0) - { - // make new array for added points - DataPoint[] addedPoints = new DataPoint[numPointsToCreate]; - int pointNum = 0; - DataPoint pointToAdd = null; - for (i=0; i 0L) - { - // interpolate point - pointToAdd = DataPoint.interpolate(pair.getPointBefore(), pair.getPointAfter(), pair.getFraction()); - } - if (pointToAdd != null) - { - // link photo to point - pointToAdd.setPhoto(pair.getPhoto()); - pair.getPhoto().setDataPoint(pointToAdd); - // set to start of segment so not joined in track - pointToAdd.setSegmentStart(true); - // add to point array - addedPoints[pointNum] = pointToAdd; - pointNum++; - } - } - } - // expand track - _track.appendPoints(addedPoints); - } - // add undo information to stack - undo.setNumPhotosCorrelated(numPhotos); - _undoStack.add(undo); - // confirm correlation - UpdateMessageBroker.informSubscribers("" + numPhotos + " " - + (numPhotos==1?I18nManager.getText("confirm.correlate.single"):I18nManager.getText("confirm.correlate.multi"))); - // observers already informed by track update - } - } - - /** * Save the coordinates of photos in their exif data */ @@ -1246,7 +897,7 @@ public class App { for (int i=0; i Set map background. +The "mapserverindex" parameter is a number from 0 to 3, where 0=Mapnik, 1=Osma, 2=Opencyclemap and 3=Other. If the mapserverindex is set to 3, Prune will use the URL given by the "mapserverurl" parameter. + prune.mapserverindex=3 + prune.mapserverurl=http://openpistemap.org/tiles/contours/ + == Example file == The following can be used as a template to make your own file. # Prune configuration file prune.directory=/home/user/gps/ -prune.languagecode=ES +prune.languagecode=EN prune.metricunits=y prune.povrayfont=crystal.ttf prune.gpsdevice=usb: prune.gpsformat=garmin - +prune.gnuplotpath=gnuplot +prune.mapserverindex=3 +prune.mapserverurl=http://openpistemap.org/tiles/contours/ diff --git a/tim/prune/correlate/PhotoCorrelator.java b/tim/prune/correlate/PhotoCorrelator.java index ccf5345..6c47d00 100644 --- a/tim/prune/correlate/PhotoCorrelator.java +++ b/tim/prune/correlate/PhotoCorrelator.java @@ -17,7 +17,6 @@ import javax.swing.ButtonGroup; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JDialog; -import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; @@ -27,6 +26,7 @@ import javax.swing.JTable; import javax.swing.JTextField; import tim.prune.App; +import tim.prune.GenericFunction; import tim.prune.I18nManager; import tim.prune.data.DataPoint; import tim.prune.data.Distance; @@ -37,15 +37,14 @@ import tim.prune.data.TimeDifference; import tim.prune.data.Timestamp; import tim.prune.data.Track; import tim.prune.data.TrackInfo; +import tim.prune.undo.UndoCorrelatePhotos; /** * Class to manage the automatic correlation of photos to points * including the GUI stuff to control the correlation options */ -public class PhotoCorrelator +public class PhotoCorrelator extends GenericFunction { - private App _app; - private JFrame _parentFrame; private JDialog _dialog; private JButton _nextButton = null, _backButton = null; private JButton _okButton = null; @@ -66,19 +65,22 @@ public class PhotoCorrelator /** * Constructor * @param inApp App object to report actions to - * @param inFrame parent frame for dialogs */ - public PhotoCorrelator(App inApp, JFrame inFrame) + public PhotoCorrelator(App inApp) { - _app = inApp; - _parentFrame = inFrame; - _dialog = new JDialog(inFrame, I18nManager.getText("dialog.correlate.title"), true); - _dialog.setLocationRelativeTo(inFrame); + super(inApp); + _dialog = new JDialog(inApp.getFrame(), I18nManager.getText(getNameKey()), true); + _dialog.setLocationRelativeTo(inApp.getFrame()); _dialog.getContentPane().add(makeDialogContents()); _dialog.pack(); } + /** Get the name key */ + public String getNameKey() { + return "function.correlatephotos"; + } + /** * Reset dialog and show it */ @@ -88,7 +90,7 @@ public class PhotoCorrelator if (!_app.getTrackInfo().getTrack().hasData(Field.TIMESTAMP)) { JOptionPane.showMessageDialog(_parentFrame, I18nManager.getText("dialog.correlate.notimestamps"), - I18nManager.getText("dialog.correlate.title"), JOptionPane.INFORMATION_MESSAGE); + I18nManager.getText(getNameKey()), JOptionPane.INFORMATION_MESSAGE); return; } // Check for any non-correlated photos, show warning continue/cancel @@ -96,7 +98,7 @@ public class PhotoCorrelator { Object[] buttonTexts = {I18nManager.getText("button.continue"), I18nManager.getText("button.cancel")}; if (JOptionPane.showOptionDialog(_parentFrame, I18nManager.getText("dialog.correlate.nouncorrelatedphotos"), - I18nManager.getText("dialog.correlate.title"), JOptionPane.YES_NO_OPTION, + I18nManager.getText(getNameKey()), JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE, null, buttonTexts, buttonTexts[1]) == JOptionPane.NO_OPTION) { @@ -127,7 +129,7 @@ public class PhotoCorrelator _tipLabel.setVisible(true); setupSecondCard(null); } - _dialog.show(); + _dialog.setVisible(true); } @@ -298,7 +300,7 @@ public class PhotoCorrelator { public void actionPerformed(ActionEvent e) { - _app.finishCorrelatePhotos(getPointPairs()); + finishCorrelation(); _dialog.dispose(); } }); @@ -457,7 +459,7 @@ public class PhotoCorrelator if (inShowWarning && !model.hasPhotosSelected()) { JOptionPane.showMessageDialog(_dialog, I18nManager.getText("dialog.correlate.alloutsiderange"), - I18nManager.getText("dialog.correlate.title"), JOptionPane.ERROR_MESSAGE); + I18nManager.getText(getNameKey()), JOptionPane.ERROR_MESSAGE); } } @@ -503,9 +505,9 @@ public class PhotoCorrelator /** * @return the selected distance units from the dropdown */ - private int getSelectedDistanceUnits() + private Distance.Units getSelectedDistanceUnits() { - final int[] distUnits = {Distance.UNITS_KILOMETRES, Distance.UNITS_METRES, Distance.UNITS_MILES}; + final Distance.Units[] distUnits = {Distance.Units.KILOMETRES, Distance.Units.METRES, Distance.Units.MILES}; return distUnits[_distUnitsDropdown.getSelectedIndex()]; } @@ -604,7 +606,7 @@ public class PhotoCorrelator private static int getMedianIndex(PhotoSelectionTableModel inModel) { // make sortable list - TreeSet set = new TreeSet(); + TreeSet set = new TreeSet(); // loop through rows of table adding to list int numRows = inModel.getRowCount(); int i; @@ -615,10 +617,10 @@ public class PhotoCorrelator } // pull out middle entry and return index TimeIndexPair pair = null; - Iterator iterator = set.iterator(); + Iterator iterator = set.iterator(); for (i=0; i<(numRows+1)/2; i++) { - pair = (TimeIndexPair) iterator.next(); + pair = iterator.next(); } return pair.getIndex(); } @@ -654,4 +656,101 @@ public class PhotoCorrelator // no uncorrelated photos found return false; } + + /** + * Finish the correlation by modifying the track + * and passing the Undo information back to the App + */ + private void finishCorrelation() + { + PointPair[] pointPairs = getPointPairs(); + if (pointPairs == null || pointPairs.length <= 0) {return;} + + // begin to construct undo information + UndoCorrelatePhotos undo = new UndoCorrelatePhotos(_app.getTrackInfo()); + // loop over Photos + int arraySize = pointPairs.length; + int i = 0, numPhotos = 0; + int numPointsToCreate = 0; + PointPair pair = null; + for (i=0; i 0) + { + // make new array for added points + DataPoint[] addedPoints = new DataPoint[numPointsToCreate]; + int pointNum = 0; + DataPoint pointToAdd = null; + for (i=0; i 0L) + { + // interpolate point + pointToAdd = DataPoint.interpolate(pair.getPointBefore(), pair.getPointAfter(), pair.getFraction()); + } + if (pointToAdd != null) + { + // link photo to point + pointToAdd.setPhoto(pair.getPhoto()); + pair.getPhoto().setDataPoint(pointToAdd); + // set to start of segment so not joined in track + pointToAdd.setSegmentStart(true); + // add to point array + addedPoints[pointNum] = pointToAdd; + pointNum++; + } + } + } + // expand track + _app.getTrackInfo().getTrack().appendPoints(addedPoints); + } + + // send undo information back to controlling app + undo.setNumPhotosCorrelated(numPhotos); + _app.completeFunction(undo, ("" + numPhotos + " " + + (numPhotos==1?I18nManager.getText("confirm.correlate.single"):I18nManager.getText("confirm.correlate.multi")))); + // observers already informed by track update + } } diff --git a/tim/prune/correlate/PhotoPreviewTableModel.java b/tim/prune/correlate/PhotoPreviewTableModel.java index aed044d..47d48b7 100644 --- a/tim/prune/correlate/PhotoPreviewTableModel.java +++ b/tim/prune/correlate/PhotoPreviewTableModel.java @@ -12,9 +12,9 @@ import tim.prune.data.Distance; public class PhotoPreviewTableModel extends AbstractTableModel { /** ArrayList containing TableRow objects */ - private ArrayList _list = new ArrayList(); + private ArrayList _list = new ArrayList(); /** Distance units */ - private int _distanceUnits = Distance.UNITS_KILOMETRES; + private Distance.Units _distanceUnits = Distance.Units.KILOMETRES; /** Number formatter */ private static final NumberFormat FORMAT_ONE_DP = NumberFormat.getNumberInstance(); @@ -67,8 +67,7 @@ public class PhotoPreviewTableModel extends AbstractTableModel */ public PhotoPreviewTableRow getRow(int inRowIndex) { - PhotoPreviewTableRow row = (PhotoPreviewTableRow) _list.get(inRowIndex); - return row; + return _list.get(inRowIndex); } @@ -80,7 +79,7 @@ public class PhotoPreviewTableModel extends AbstractTableModel */ public Object getValueAt(int inRowIndex, int inColumnIndex) { - PhotoPreviewTableRow row = (PhotoPreviewTableRow) _list.get(inRowIndex); + PhotoPreviewTableRow row = _list.get(inRowIndex); if (inColumnIndex == 0) return row.getPhoto().getFile().getName(); else if (inColumnIndex == 1) { return row.getPhoto().getTimestamp().getText(); @@ -104,7 +103,7 @@ public class PhotoPreviewTableModel extends AbstractTableModel /** * @param inUnits the distance units to use */ - public void setDistanceUnits(int inUnits) + public void setDistanceUnits(Distance.Units inUnits) { _distanceUnits = inUnits; } @@ -133,7 +132,7 @@ public class PhotoPreviewTableModel extends AbstractTableModel * Get the class of objects in the given column * @see javax.swing.table.AbstractTableModel#getColumnClass(int) */ - public Class getColumnClass(int inColumnIndex) + public Class getColumnClass(int inColumnIndex) { if (inColumnIndex == 4) {return Boolean.class;} return super.getColumnClass(inColumnIndex); diff --git a/tim/prune/correlate/PhotoPreviewTableRow.java b/tim/prune/correlate/PhotoPreviewTableRow.java index 9df0b52..7095537 100644 --- a/tim/prune/correlate/PhotoPreviewTableRow.java +++ b/tim/prune/correlate/PhotoPreviewTableRow.java @@ -31,7 +31,7 @@ public class PhotoPreviewTableRow extends PhotoSelectionTableRow * @param inUnits units to use * @return distance in selected format */ - public double getDistance(int inUnits) + public double getDistance(Distance.Units inUnits) { return Distance.convertRadiansToDistance(_distance, inUnits); } diff --git a/tim/prune/correlate/PhotoSelectionTableModel.java b/tim/prune/correlate/PhotoSelectionTableModel.java index 2e9d315..dbd9d8e 100644 --- a/tim/prune/correlate/PhotoSelectionTableModel.java +++ b/tim/prune/correlate/PhotoSelectionTableModel.java @@ -11,7 +11,7 @@ import tim.prune.data.Photo; */ public class PhotoSelectionTableModel extends AbstractTableModel { - private ArrayList _list = new ArrayList(); + private ArrayList _list = new ArrayList(); /** @@ -53,8 +53,7 @@ public class PhotoSelectionTableModel extends AbstractTableModel */ public PhotoSelectionTableRow getRow(int inRowIndex) { - PhotoSelectionTableRow row = (PhotoSelectionTableRow) _list.get(inRowIndex); - return row; + return _list.get(inRowIndex); } @@ -67,7 +66,7 @@ public class PhotoSelectionTableModel extends AbstractTableModel public Object getValueAt(int inRowIndex, int inColumnIndex) { // TODO: only show time of photos (not date) if dates all identical - PhotoSelectionTableRow row = (PhotoSelectionTableRow) _list.get(inRowIndex); + PhotoSelectionTableRow row = _list.get(inRowIndex); if (inColumnIndex == 0) return row.getPhoto().getFile().getName(); else if (inColumnIndex == 1) return row.getPhoto().getTimestamp().getText(); else if (inColumnIndex == 2) return row.getTimeDiff().getDescription(); diff --git a/tim/prune/correlate/TimeIndexPair.java b/tim/prune/correlate/TimeIndexPair.java index 50305d4..775b151 100644 --- a/tim/prune/correlate/TimeIndexPair.java +++ b/tim/prune/correlate/TimeIndexPair.java @@ -4,7 +4,7 @@ package tim.prune.correlate; * Simple class to hold a time and an index. * Used in a TreeSet for calculating median time difference */ -public class TimeIndexPair implements Comparable +public class TimeIndexPair implements Comparable { /** Time as long */ private long _time = 0L; @@ -37,9 +37,20 @@ public class TimeIndexPair implements Comparable * Compare two TimeIndexPair objects * @see java.lang.Comparable#compareTo(java.lang.Object) */ - public int compareTo(Object inOther) + public int compareTo(TimeIndexPair inOther) { - TimeIndexPair other = (TimeIndexPair) inOther; - return (int) (_time - other._time); + return (int) (_time - inOther._time); + } + + /** + * Override equals method to match compareTo + */ + public boolean equals(Object inOther) + { + if (inOther instanceof TimeIndexPair) { + TimeIndexPair otherPair = (TimeIndexPair) inOther; + return _time == otherPair._time; + } + return false; } } diff --git a/tim/prune/data/Altitude.java b/tim/prune/data/Altitude.java index 78a98e0..495e844 100644 --- a/tim/prune/data/Altitude.java +++ b/tim/prune/data/Altitude.java @@ -7,20 +7,25 @@ public class Altitude { private boolean _valid = false; private int _value = 0; - private int _format = -1; + private Format _format = Format.NO_FORMAT; private String _stringValue = null; /** Altitude formats */ - public static final int FORMAT_NONE = -1; - public static final int FORMAT_METRES = 0; - public static final int FORMAT_FEET = 1; + public enum Format { + /** No format */ + NO_FORMAT, + /** Metres */ + METRES, + /** Feet */ + FEET + } /** Constants for conversion */ private static final double CONVERT_FEET_TO_METRES = 0.3048; private static final double CONVERT_METRES_TO_FEET = 3.28084; /** Constant for no altitude value */ - public static final Altitude NONE = new Altitude(null, FORMAT_NONE); + public static final Altitude NONE = new Altitude(null, Format.NO_FORMAT); /** @@ -28,7 +33,7 @@ public class Altitude * @param inString string to parse * @param inFormat format of altitude, either metres or feet */ - public Altitude(String inString, int inFormat) + public Altitude(String inString, Format inFormat) { if (inString != null && !inString.equals("")) { @@ -49,7 +54,7 @@ public class Altitude * @param inValue int value of altitude * @param inFormat format of altitude, either metres or feet */ - public Altitude(int inValue, int inFormat) + public Altitude(int inValue, Format inFormat) { _value = inValue; _format = inFormat; @@ -78,7 +83,7 @@ public class Altitude /** * @return format of number */ - public int getFormat() + public Format getFormat() { return _format; } @@ -89,14 +94,14 @@ public class Altitude * @param inFormat desired format, either FORMAT_METRES or FORMAT_FEET * @return value as an int */ - public int getValue(int inFormat) + public int getValue(Format inFormat) { // Note possible rounding errors here if converting to/from units if (inFormat == _format) return _value; - if (inFormat == FORMAT_METRES) + if (inFormat == Format.METRES) return (int) (_value * CONVERT_FEET_TO_METRES); - if (inFormat == FORMAT_FEET) + if (inFormat == Format.FEET) return (int) (_value * CONVERT_METRES_TO_FEET); return _value; } @@ -106,8 +111,9 @@ public class Altitude * @param inFormat specified format * @return string value, if possible the original one */ - public String getStringValue(int inFormat) + public String getStringValue(Format inFormat) { + if (!_valid) {return "";} if (inFormat == _format && _stringValue != null && !_stringValue.equals("")) { return _stringValue; } @@ -140,9 +146,9 @@ public class Altitude { // Check if altitudes are valid if (inStart == null || inEnd == null || !inStart.isValid() || !inEnd.isValid()) - return new Altitude(null, FORMAT_NONE); + return Altitude.NONE; // Use altitude format of first point - int altFormat = inStart.getFormat(); + Format altFormat = inStart.getFormat(); int startValue = inStart.getValue(); int endValue = inEnd.getValue(altFormat); // interpolate between start and end diff --git a/tim/prune/data/AltitudeRange.java b/tim/prune/data/AltitudeRange.java index aff974d..98fa20e 100644 --- a/tim/prune/data/AltitudeRange.java +++ b/tim/prune/data/AltitudeRange.java @@ -7,7 +7,7 @@ package tim.prune.data; public class AltitudeRange { private IntegerRange _range = new IntegerRange(); - private int _format = Altitude.FORMAT_NONE; + private Altitude.Format _format = Altitude.Format.NO_FORMAT; /** @@ -16,7 +16,7 @@ public class AltitudeRange public void clear() { _range.clear(); - _format = Altitude.FORMAT_NONE; + _format = Altitude.Format.NO_FORMAT; } @@ -30,7 +30,7 @@ public class AltitudeRange { int altValue = inAltitude.getValue(_format); _range.addValue(altValue); - if (_format == Altitude.FORMAT_NONE) + if (_format == Altitude.Format.NO_FORMAT) { _format = inAltitude.getFormat(); } @@ -39,11 +39,11 @@ public class AltitudeRange /** - * @return true if positive data values were found + * @return true if altitude range found */ - public boolean hasData() + public boolean hasRange() { - return (_range.hasData()); + return _range.getMaximum() > _range.getMinimum(); } @@ -68,7 +68,7 @@ public class AltitudeRange /** * @return the altitude format used */ - public int getFormat() + public Altitude.Format getFormat() { return _format; } diff --git a/tim/prune/data/Coordinate.java b/tim/prune/data/Coordinate.java index 7e52d83..19a1688 100644 --- a/tim/prune/data/Coordinate.java +++ b/tim/prune/data/Coordinate.java @@ -1,5 +1,9 @@ package tim.prune.data; +import java.text.DecimalFormat; +import java.text.NumberFormat; +import java.util.Locale; + /** * Class to represent a lat/long coordinate * and provide conversion functions @@ -11,7 +15,7 @@ public abstract class Coordinate public static final int EAST = 1; public static final int SOUTH = 2; public static final int WEST = 3; - public static final char[] PRINTABLE_CARDINALS = {'N', 'E', 'S', 'W'}; + private static final char[] PRINTABLE_CARDINALS = {'N', 'E', 'S', 'W'}; public static final int FORMAT_DEG_MIN_SEC = 10; public static final int FORMAT_DEG_MIN = 11; public static final int FORMAT_DEG = 12; @@ -19,8 +23,16 @@ public abstract class Coordinate public static final int FORMAT_DEG_WHOLE_MIN = 14; public static final int FORMAT_DEG_MIN_SEC_WITH_SPACES = 15; public static final int FORMAT_CARDINAL = 16; + public static final int FORMAT_DECIMAL_FORCE_POINT = 17; public static final int FORMAT_NONE = 19; + /** Number formatter for fixed decimals with forced decimal point */ + private static final NumberFormat EIGHT_DP = NumberFormat.getNumberInstance(Locale.UK); + // Select the UK locale for this formatter so that decimal point is always used (not comma) + static { + if (EIGHT_DP instanceof DecimalFormat) ((DecimalFormat) EIGHT_DP).applyPattern("0.00000000"); + } + // Instance variables private boolean _valid = false; protected int _cardinal = NORTH; @@ -110,6 +122,7 @@ public abstract class Coordinate double numSecs = (numMins - _minutes) * 60.0; _seconds = (int) numSecs; _fracs = (int) ((numSecs - _seconds) * 10); + _asDouble = _degrees + 1.0 * fields[1] / denoms[1]; } // Differentiate between d-m.f and d-m-s using . or , else if (numFields == 3 && (secondDelim.equals(".") || secondDelim.equals(","))) @@ -120,6 +133,7 @@ public abstract class Coordinate double numSecs = fields[2] * 60.0 / denoms[2]; _seconds = (int) numSecs; _fracs = (int) ((numSecs - _seconds) * 10); + _asDouble = 1.0 * _degrees + (_minutes / 60.0) + (numSecs / 3600.0); } else if (numFields == 4 || numFields == 3) { @@ -130,8 +144,8 @@ public abstract class Coordinate _fracs = (int) fields[3]; _fracDenom = (int) denoms[3]; if (_fracDenom < 1) {_fracDenom = 1;} + _asDouble = 1.0 * _degrees + (_minutes / 60.0) + (_seconds / 3600.0) + (_fracs / 3600.0 / _fracDenom); } - _asDouble = 1.0 * _degrees + (_minutes / 60.0) + (_seconds / 3600.0) + (_fracs / 3600.0 / _fracDenom); if (_cardinal == WEST || _cardinal == SOUTH || inString.charAt(0) == '-') _asDouble = -_asDouble; // validate fields @@ -277,6 +291,12 @@ public abstract class Coordinate + (_degrees + _minutes / 60.0 + _seconds / 3600.0 + _fracs / 3600.0 / _fracDenom); break; } + case FORMAT_DECIMAL_FORCE_POINT: + { + // Forcing a decimal point instead of system-dependent commas etc + answer = EIGHT_DP.format(_asDouble); + break; + } case FORMAT_DEG_MIN_SEC_WITH_SPACES: { // Note: cardinal not needed as this format is only for exif, which has cardinal separately diff --git a/tim/prune/data/DataPoint.java b/tim/prune/data/DataPoint.java index 4cf7c82..2d60ce7 100644 --- a/tim/prune/data/DataPoint.java +++ b/tim/prune/data/DataPoint.java @@ -1,5 +1,7 @@ package tim.prune.data; +import tim.prune.Config; + /** * Class to represent a single data point in the series * including all its fields @@ -18,6 +20,7 @@ public class DataPoint private Photo _photo = null; private String _waypointName = null; private boolean _startOfSegment = false; + private boolean _markedForDeletion = false; /** @@ -26,31 +29,44 @@ public class DataPoint * @param inFieldList list of fields * @param inAltFormat altitude format */ - public DataPoint(String[] inValueArray, FieldList inFieldList, int inAltFormat) + public DataPoint(String[] inValueArray, FieldList inFieldList, Altitude.Format inAltFormat) { // save data _fieldValues = inValueArray; // save list of fields _fieldList = inFieldList; // parse fields into objects - parseFields(inAltFormat); + parseFields(null, inAltFormat); } /** * Parse the string values into objects eg Coordinates + * @param inField field which has changed, or null for all * @param inAltFormat altitude format */ - private void parseFields(int inAltFormat) + private void parseFields(Field inField, Altitude.Format inAltFormat) { - _latitude = new Latitude(getFieldValue(Field.LATITUDE)); - _longitude = new Longitude(getFieldValue(Field.LONGITUDE)); - _altitude = new Altitude(getFieldValue(Field.ALTITUDE), inAltFormat); - _timestamp = new Timestamp(getFieldValue(Field.TIMESTAMP)); - _waypointName = getFieldValue(Field.WAYPT_NAME); - String segmentStr = getFieldValue(Field.NEW_SEGMENT); - if (segmentStr != null) {segmentStr = segmentStr.trim();} - _startOfSegment = (segmentStr != null && (segmentStr.equals("1") || segmentStr.toUpperCase().equals("Y"))); + if (inField == null || inField == Field.LATITUDE) { + _latitude = new Latitude(getFieldValue(Field.LATITUDE)); + } + if (inField == null || inField == Field.LONGITUDE) { + _longitude = new Longitude(getFieldValue(Field.LONGITUDE)); + } + if (inField == null || inField == Field.ALTITUDE) { + _altitude = new Altitude(getFieldValue(Field.ALTITUDE), inAltFormat); + } + if (inField == null || inField == Field.TIMESTAMP) { + _timestamp = new Timestamp(getFieldValue(Field.TIMESTAMP)); + } + if (inField == null || inField == Field.WAYPT_NAME) { + _waypointName = getFieldValue(Field.WAYPT_NAME); + } + if (inField == null || inField == Field.NEW_SEGMENT) { + String segmentStr = getFieldValue(Field.NEW_SEGMENT); + if (segmentStr != null) {segmentStr = segmentStr.trim();} + _startOfSegment = (segmentStr != null && (segmentStr.equals("1") || segmentStr.toUpperCase().equals("Y"))); + } } @@ -75,7 +91,7 @@ public class DataPoint } else { _altitude = inAltitude; - _fieldValues[2] = "" + inAltitude.getValue(Altitude.FORMAT_METRES); // units are ignored + _fieldValues[2] = "" + inAltitude.getValue(Altitude.Format.METRES); // units are ignored } _timestamp = new Timestamp(null); } @@ -133,14 +149,13 @@ public class DataPoint // Set field value in array _fieldValues[fieldIndex] = inValue; // Change Coordinate, Altitude, Name or Timestamp fields after edit - if (_altitude != null) - { - parseFields(_altitude.getFormat()); + if (_altitude != null && _altitude.getFormat() != Altitude.Format.NO_FORMAT) { + // Altitude already present so reuse format + parseFields(inField, _altitude.getFormat()); } - else - { - // use default altitude format of metres - parseFields(Altitude.FORMAT_METRES); + else { + // use default altitude format from config + parseFields(inField, Config.getUseMetricUnits()?Altitude.Format.METRES:Altitude.Format.FEET); } } @@ -150,6 +165,14 @@ public class DataPoint setFieldValue(Field.NEW_SEGMENT, inFlag?"1":null); } + /** + * Mark the point for deletion + * @param inFlag true to delete, false to keep + */ + public void setMarkedForDeletion(boolean inFlag) { + _markedForDeletion = inFlag; + } + /** @return latitude */ public Coordinate getLatitude() { @@ -192,6 +215,12 @@ public class DataPoint return _startOfSegment; } + /** @return true if point marked for deletion */ + public boolean getDeleteFlag() + { + return _markedForDeletion; + } + /** * @return true if point has a waypoint name */ @@ -353,32 +382,6 @@ public class DataPoint } - /** - * Restore the contents from another point - * @param inOther point containing contents to copy - * @return true if successful - */ - public boolean restoreContents(DataPoint inOther) - { - if (inOther != null) - { - // Copy string values across - _fieldValues = inOther._fieldValues; - if (_altitude != null) - { - parseFields(_altitude.getFormat()); - } - else - { - // use default altitude format of metres - parseFields(Altitude.FORMAT_METRES); - } - return true; - } - return false; - } - - /** * Get string for debug * @see java.lang.Object#toString() diff --git a/tim/prune/data/Distance.java b/tim/prune/data/Distance.java index 311cd88..9909df7 100644 --- a/tim/prune/data/Distance.java +++ b/tim/prune/data/Distance.java @@ -5,10 +5,18 @@ package tim.prune.data; */ public abstract class Distance { - // distance formats - public static final int UNITS_KILOMETRES = 1; - public static final int UNITS_MILES = 2; - public static final int UNITS_METRES = 3; + /** distance units */ + public enum Units + { + /** Kilometres */ + KILOMETRES, + /** Miles */ + MILES, + /** Metres */ + METRES, + /** Feet */ + FEET + } // Geographical constants private static final double EARTH_RADIUS_KM = 6372.795; @@ -22,12 +30,12 @@ public abstract class Distance * @param inUnits desired units, eg miles or km * @return distance in specified format */ - public static double convertRadiansToDistance(double inAngDist, int inUnits) + public static double convertRadiansToDistance(double inAngDist, Units inUnits) { // Multiply by appropriate factor - if (inUnits == UNITS_MILES) + if (inUnits == Units.MILES) return inAngDist * EARTH_RADIUS_KM * CONVERT_KM_TO_MILES; - else if (inUnits == UNITS_METRES) + else if (inUnits == Units.METRES) return inAngDist * EARTH_RADIUS_KM * 1000; // default kilometres return inAngDist * EARTH_RADIUS_KM; @@ -39,12 +47,12 @@ public abstract class Distance * @param inUnits units, eg miles or km * @return angular distance in radians */ - public static double convertDistanceToRadians(double inDist, int inUnits) + public static double convertDistanceToRadians(double inDist, Units inUnits) { // Divide by appropriate factor - if (inUnits == UNITS_MILES) + if (inUnits == Units.MILES) return inDist / EARTH_RADIUS_KM / CONVERT_KM_TO_MILES; - else if (inUnits == UNITS_METRES) + else if (inUnits == Units.METRES) return inDist / EARTH_RADIUS_KM / 1000; // default kilometres return inDist / EARTH_RADIUS_KM; diff --git a/tim/prune/data/DoubleRange.java b/tim/prune/data/DoubleRange.java index e103759..b6b8a8f 100644 --- a/tim/prune/data/DoubleRange.java +++ b/tim/prune/data/DoubleRange.java @@ -71,4 +71,12 @@ public class DoubleRange { return _max; } + + /** + * @return range, as maximum - minimum + */ + public double getRange() + { + return _max - _min; + } } diff --git a/tim/prune/data/Field.java b/tim/prune/data/Field.java index 5f28fc5..089d8cd 100644 --- a/tim/prune/data/Field.java +++ b/tim/prune/data/Field.java @@ -21,9 +21,9 @@ public class Field public static final Field WAYPT_TYPE = new Field("fieldname.waypointtype", FieldType.NONE); public static final Field NEW_SEGMENT = new Field("fieldname.newsegment", FieldType.BOOL); - public static final Field[] ALL_AVAILABLE_FIELDS = { - LATITUDE, LONGITUDE, ALTITUDE, TIMESTAMP, WAYPT_NAME, WAYPT_TYPE, NEW_SEGMENT, - new Field("fieldname.custom", FieldType.NONE) + private static final Field[] ALL_AVAILABLE_FIELDS = { + LATITUDE, LONGITUDE, ALTITUDE, TIMESTAMP, WAYPT_NAME, WAYPT_TYPE, NEW_SEGMENT, + new Field("fieldname.custom", FieldType.NONE) }; /** @@ -95,4 +95,33 @@ public class Field { return (isBuiltIn() == inOther.isBuiltIn() && getName().equals(inOther.getName())); } + + /** + * Get the field for the given field name + * @param inFieldName name of field to look for + * @return Field if found, or null otherwise + */ + public static Field getField(String inFieldName) + { + for (int i=0; i= 0); - } - - /** * @return minimum value, or -1 if none found */ diff --git a/tim/prune/data/Photo.java b/tim/prune/data/Photo.java index 2f230cc..805e22e 100644 --- a/tim/prune/data/Photo.java +++ b/tim/prune/data/Photo.java @@ -19,13 +19,23 @@ public class Photo /** Size of original image */ private Dimension _size = null; /** Status of photo when loaded */ - private byte _originalStatus = PhotoStatus.NOT_CONNECTED; + private Status _originalStatus = Status.NOT_CONNECTED; /** Current photo status */ - private byte _currentStatus = PhotoStatus.NOT_CONNECTED; + private Status _currentStatus = Status.NOT_CONNECTED; // TODO: Need to store caption for image? // thumbnail for image (from exif) private byte[] _exifThumbnail = null; + /** Photo status */ + public enum Status { + /** Photo is not connected to any point */ + NOT_CONNECTED, + /** Photo has been connected to a point since it was loaded */ + TAGGED, + /** Photo is connected to a point */ + CONNECTED + }; + /** * Constructor @@ -56,11 +66,11 @@ public class Photo // set status according to point if (inPoint == null) { - setCurrentStatus(PhotoStatus.NOT_CONNECTED); + setCurrentStatus(Status.NOT_CONNECTED); } else { - setCurrentStatus(PhotoStatus.CONNECTED); + setCurrentStatus(Status.CONNECTED); } } @@ -143,7 +153,7 @@ public class Photo /** * @param inStatus status of photo when loaded */ - public void setOriginalStatus(byte inStatus) + public void setOriginalStatus(Status inStatus) { _originalStatus = inStatus; _currentStatus = inStatus; @@ -152,7 +162,7 @@ public class Photo /** * @return status of photo when it was loaded */ - public byte getOriginalStatus() + public Status getOriginalStatus() { return _originalStatus; } @@ -160,14 +170,14 @@ public class Photo /** * @return current status of photo */ - public byte getCurrentStatus() + public Status getCurrentStatus() { return _currentStatus; } /** * @param inStatus current status of photo */ - public void setCurrentStatus(byte inStatus) + public void setCurrentStatus(Status inStatus) { _currentStatus = inStatus; } diff --git a/tim/prune/data/PhotoList.java b/tim/prune/data/PhotoList.java index b7c044d..18ebe15 100644 --- a/tim/prune/data/PhotoList.java +++ b/tim/prune/data/PhotoList.java @@ -7,7 +7,7 @@ import java.util.ArrayList; */ public class PhotoList { - private ArrayList _photos = null; + private ArrayList _photos = null; /** * Empty constructor @@ -21,7 +21,7 @@ public class PhotoList * Constructor * @param inList ArrayList containing Photo objects */ - private PhotoList(ArrayList inList) + private PhotoList(ArrayList inList) { _photos = inList; } @@ -48,7 +48,7 @@ public class PhotoList // Make sure array is initialised if (_photos == null) { - _photos = new ArrayList(); + _photos = new ArrayList(); } // Add the photo _photos.add(inPhoto); @@ -68,7 +68,7 @@ public class PhotoList // Make sure array is initialised if (_photos == null) { - _photos = new ArrayList(); + _photos = new ArrayList(); } // Add the photo _photos.add(inIndex, inPhoto); @@ -135,7 +135,7 @@ public class PhotoList public Photo getPhoto(int inIndex) { if (inIndex < 0 || inIndex >= getNumPhotos()) return null; - return (Photo) _photos.get(inIndex); + return _photos.get(inIndex); } @@ -201,7 +201,7 @@ public class PhotoList if (numPhotos > 0) { // Construct new list to copy into - ArrayList listCopy = new ArrayList(); + ArrayList listCopy = new ArrayList(); // Loop over photos in list for (int i=0; i listCopy = new ArrayList(); + for (int i=0; i<_photos.size(); i++) { + listCopy.add(_photos.get(i)); + } + return new PhotoList(listCopy); } diff --git a/tim/prune/data/PhotoStatus.java b/tim/prune/data/PhotoStatus.java deleted file mode 100644 index 831f36f..0000000 --- a/tim/prune/data/PhotoStatus.java +++ /dev/null @@ -1,11 +0,0 @@ -package tim.prune.data; - -/** - * Interface to hold constants for photo status - */ -public interface PhotoStatus -{ - public static final byte NOT_CONNECTED = 0; - public static final byte TAGGED = 1; - public static final byte CONNECTED = 2; -} diff --git a/tim/prune/data/Selection.java b/tim/prune/data/Selection.java index 95e0cfb..c07c1a9 100644 --- a/tim/prune/data/Selection.java +++ b/tim/prune/data/Selection.java @@ -16,7 +16,7 @@ public class Selection private int _currentPhotoIndex = -1; private IntegerRange _altitudeRange = null; private int _climb = -1, _descent = -1; - private int _altitudeFormat = Altitude.FORMAT_NONE; + private Altitude.Format _altitudeFormat = Altitude.Format.NO_FORMAT; private long _totalSeconds = 0L, _movingSeconds = 0L; private double _angDistance = -1.0, _angMovingDistance = -1.0; @@ -109,7 +109,7 @@ public class Selection */ private void recalculate() { - _altitudeFormat = Altitude.FORMAT_NONE; + _altitudeFormat = Altitude.Format.NO_FORMAT; if (_track.getNumPoints() > 0 && hasRangeSelected()) { _altitudeRange = new IntegerRange(); @@ -132,7 +132,7 @@ public class Selection if (!currPoint.isWaypoint() && altitude.isValid()) { altValue = altitude.getValue(_altitudeFormat); - if (_altitudeFormat == Altitude.FORMAT_NONE) + if (_altitudeFormat == Altitude.Format.NO_FORMAT) _altitudeFormat = altitude.getFormat(); _altitudeRange.addValue(altValue); if (foundAlt) @@ -202,7 +202,7 @@ public class Selection /** * @return the altitude format, ie feet or metres */ - public int getAltitudeFormat() + public Altitude.Format getAltitudeFormat() { return _altitudeFormat; } @@ -258,7 +258,7 @@ public class Selection * @param inUnits distance units to use, from class Distance * @return distance of Selection in specified units */ - public double getDistance(int inUnits) + public double getDistance(Distance.Units inUnits) { return Distance.convertRadiansToDistance(_angDistance, inUnits); } @@ -267,7 +267,7 @@ public class Selection * @param inUnits distance units to use, from class Distance * @return moving distance of Selection in specified units */ - public double getMovingDistance(int inUnits) + public double getMovingDistance(Distance.Units inUnits) { return Distance.convertRadiansToDistance(_angMovingDistance, inUnits); } diff --git a/tim/prune/data/Timestamp.java b/tim/prune/data/Timestamp.java index 6b7f77b..f1d0569 100644 --- a/tim/prune/data/Timestamp.java +++ b/tim/prune/data/Timestamp.java @@ -17,9 +17,10 @@ public class Timestamp private String _text = null; private String _timeText = null; - private static DateFormat DEFAULT_DATE_FORMAT = DateFormat.getDateTimeInstance(); - private static DateFormat DEFAULT_TIME_FORMAT = DateFormat.getTimeInstance(); - private static DateFormat ISO_8601_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); + private static final DateFormat DEFAULT_DATE_FORMAT = DateFormat.getDateTimeInstance(); + private static final DateFormat DEFAULT_TIME_FORMAT = DateFormat.getTimeInstance(); + private static final DateFormat ISO_8601_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); + private static final DateFormat ISO_8601_FORMAT_NOZ = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); private static DateFormat[] ALL_DATE_FORMATS = null; private static Calendar CALENDAR = null; private static long SECS_SINCE_1970 = 0L; @@ -53,7 +54,7 @@ public class Timestamp new SimpleDateFormat("HH:mm:ss dd MMM yyyy"), new SimpleDateFormat("dd MMM yyyy HH:mm:ss"), new SimpleDateFormat("yyyy MMM dd HH:mm:ss"), - ISO_8601_FORMAT + ISO_8601_FORMAT, ISO_8601_FORMAT_NOZ }; } diff --git a/tim/prune/data/Track.java b/tim/prune/data/Track.java index eeb5b62..df51e8f 100644 --- a/tim/prune/data/Track.java +++ b/tim/prune/data/Track.java @@ -2,9 +2,10 @@ package tim.prune.data; import java.util.List; +import tim.prune.Config; import tim.prune.UpdateMessageBroker; -import tim.prune.edit.FieldEdit; -import tim.prune.edit.FieldEditList; +import tim.prune.function.edit.FieldEdit; +import tim.prune.function.edit.FieldEditList; import tim.prune.gui.map.MapUtils; @@ -19,8 +20,6 @@ public class Track // Scaled x, y values private double[] _xValues = null; private double[] _yValues = null; - private double[] _xValuesNew = null; - private double[] _yValuesNew = null; private boolean _scaled = false; private int _numPoints = 0; private boolean _mixedData = false; @@ -53,7 +52,7 @@ public class Track * @param inPointArray 2d object array containing data * @param inAltFormat altitude format */ - public void load(Field[] inFieldArray, Object[][] inPointArray, int inAltFormat) + public void load(Field[] inFieldArray, Object[][] inPointArray, Altitude.Format inAltFormat) { if (inFieldArray == null || inPointArray == null) { @@ -88,6 +87,19 @@ public class Track } + /** + * Load the track by transferring the contents from a loaded Track object + * @param inOther Track object containing loaded data + */ + public void load(Track inOther) + { + _numPoints = inOther._numPoints; + _masterFieldList = inOther._masterFieldList; + _dataPoints = inOther._dataPoints; + // needs to be scaled + _scaled = false; + } + ////////////////// Modification methods ////////////////////// @@ -131,64 +143,22 @@ public class Track /** - * Compress the track to the given resolution - * @param inResolution resolution + * Delete the points marked for deletion * @return number of points deleted */ - public int compress(int inResolution) + public int deleteMarkedPoints() { - // (maybe should be separate thread?) - // (maybe should be in separate class?) - // (maybe should be based on subtended angles instead of distances?) - // Suggestion: Find last track point, don't delete it (or maybe preserve first and last of each segment?) - - if (inResolution <= 0) return 0; int numCopied = 0; - // Establish range of track and minimum range between points - scalePoints(); - double wholeScale = _xRange.getMaximum() - _xRange.getMinimum(); - double yscale = _yRange.getMaximum() - _yRange.getMinimum(); - if (yscale > wholeScale) wholeScale = yscale; - double minDist = wholeScale / inResolution; - - // Keep track of segment start flags of the deleted points - boolean setSegment = false; // Copy selected points DataPoint[] newPointArray = new DataPoint[_numPoints]; - int[] pointIndices = new int[_numPoints]; for (int i=0; i<_numPoints; i++) { DataPoint point = _dataPoints[i]; - boolean keepPoint = true; // Don't delete waypoints or photo points - if (!point.isWaypoint() && point.getPhoto() == null) - { - // go through newPointArray to check for range - for (int j=0; j 0) - { - // Make new resized array and copy DataPoints over - DataPoint[] newPointArray = new DataPoint[_numPoints - numDupes]; - j = 0; - for (i=0; i<_numPoints; i++) - { - if (!dupes[i]) - { - newPointArray[j] = _dataPoints[i]; - j++; - } - } - // Copy array references - _dataPoints = newPointArray; - _numPoints = _dataPoints.length; - _scaled = false; - } - return numDupes; - } - - /** * Reverse the specified range of points * @param inStart start index @@ -613,6 +515,53 @@ public class Track } + /** + * Average selected points + * @param inStartIndex start index of selection + * @param inEndIndex end index of selection + * @return true if successful + */ + public boolean average(int inStartIndex, int inEndIndex) + { + // check parameters + if (inStartIndex < 0 || inStartIndex >= _numPoints || inEndIndex <= inStartIndex) + return false; + + DataPoint startPoint = getPoint(inStartIndex); + double firstLatitude = startPoint.getLatitude().getDouble(); + double firstLongitude = startPoint.getLongitude().getDouble(); + double latitudeDiff = 0.0, longitudeDiff = 0.0; + double totalAltitude = 0; + int numAltitudes = 0; + Altitude.Format altFormat = Config.getUseMetricUnits()?Altitude.Format.METRES:Altitude.Format.FEET; + // loop between start and end points + for (int i=inStartIndex; i<= inEndIndex; i++) + { + DataPoint currPoint = getPoint(i); + latitudeDiff += (currPoint.getLatitude().getDouble() - firstLatitude); + longitudeDiff += (currPoint.getLongitude().getDouble() - firstLongitude); + if (currPoint.hasAltitude()) { + totalAltitude += currPoint.getAltitude().getValue(altFormat); + numAltitudes++; + } + } + int numPoints = inEndIndex - inStartIndex + 1; + double meanLatitude = firstLatitude + (latitudeDiff / numPoints); + double meanLongitude = firstLongitude + (longitudeDiff / numPoints); + Altitude meanAltitude = null; + if (numAltitudes > 0) {meanAltitude = new Altitude((int) (totalAltitude / numAltitudes), altFormat);} + + DataPoint insertedPoint = new DataPoint(new Latitude(meanLatitude, Coordinate.FORMAT_NONE), + new Longitude(meanLongitude, Coordinate.FORMAT_NONE), meanAltitude); + // Make into singleton + insertedPoint.setSegmentStart(true); + DataPoint nextPoint = getNextTrackPoint(inEndIndex+1); + if (nextPoint != null) {nextPoint.setSegmentStart(true);} + // Insert points into track + return insertRange(new DataPoint[] {insertedPoint}, inEndIndex + 1); + } + + /** * Append the specified points to the end of the track * @param inPoints DataPoint objects to add @@ -719,26 +668,6 @@ public class Track return _yValues[inPointNum]; } - /** - * @param inPointNum point index, starting at 0 - * @return scaled x value of specified point - */ - public double getXNew(int inPointNum) - { - if (!_scaled) scalePoints(); - return _xValuesNew[inPointNum]; - } - - /** - * @param inPointNum point index, starting at 0 - * @return scaled y value of specified point - */ - public double getYNew(int inPointNum) - { - if (!_scaled) scalePoints(); - return _yValuesNew[inPointNum]; - } - /** * @return the master field list */ @@ -768,11 +697,17 @@ public class Track */ public boolean hasData(Field inField, int inStart, int inEnd) { + // Loop over selected point range for (int i=inStart; i<=inEnd; i++) { if (_dataPoints[i].getFieldValue(inField) != null) { - return true; + // Check altitudes and timestamps + if ((inField != Field.ALTITUDE || _dataPoints[i].getAltitude().isValid()) + && (inField != Field.TIMESTAMP || _dataPoints[i].getTimestamp().isValid())) + { + return true; + } } } return false; @@ -788,12 +723,41 @@ public class Track return _mixedData; } + /** + * @return true if track contains any points marked for deletion + */ + public boolean hasMarkedPoints() + { + if (_numPoints < 1) { + return false; + } + // Loop over points looking for any marked for deletion + for (int i=0; i<=_numPoints-1; i++) + { + if (_dataPoints[i] != null && _dataPoints[i].getDeleteFlag()) { + return true; + } + } + // None found + return false; + } + + /** + * Clear all the deletion markers + */ + public void clearDeletionMarkers() + { + for (int i=0; i<_numPoints; i++) + { + _dataPoints[i].setMarkedForDeletion(false); + } + } /** * Collect all the waypoints into the given List * @param inList List to fill with waypoints */ - public void getWaypoints(List inList) + public void getWaypoints(List inList) { // clear list inList.clear(); @@ -865,16 +829,9 @@ public class Track } _mixedData = hasWaypoint && hasTrackpoint; - // Use medians to centre at 0 - double longMedian = (_longRange.getMaximum() + _longRange.getMinimum()) / 2.0; - double latMedian = (_latRange.getMaximum() + _latRange.getMinimum()) / 2.0; - double longFactor = Math.cos(latMedian / 180.0 * Math.PI); // Function of median latitude - // Loop over points and calculate scales _xValues = new double[getNumPoints()]; _yValues = new double[getNumPoints()]; - _xValuesNew = new double[getNumPoints()]; - _yValuesNew = new double[getNumPoints()]; _xRange = new DoubleRange(); _yRange = new DoubleRange(); for (p=0; p < getNumPoints(); p++) @@ -882,12 +839,10 @@ public class Track DataPoint point = getPoint(p); if (point != null) { - _xValues[p] = (point.getLongitude().getDouble() - longMedian) * longFactor; + _xValues[p] = MapUtils.getXFromLongitude(point.getLongitude().getDouble()); _xRange.addValue(_xValues[p]); - _xValuesNew[p] = MapUtils.getXFromLongitude(point.getLongitude().getDouble()); - _yValues[p] = (point.getLatitude().getDouble() - latMedian); + _yValues[p] = MapUtils.getYFromLatitude(point.getLatitude().getDouble()); _yRange.addValue(_yValues[p]); - _yValuesNew[p] = MapUtils.getYFromLatitude(point.getLatitude().getDouble()); } } _scaled = true; @@ -928,41 +883,6 @@ public class Track return nearestPoint; } - - /** - * Find the nearest point to the specified x and y coordinates - * or -1 if no point is within the specified max distance - * @param inX x coordinate - * @param inY y coordinate - * @param inMaxDist maximum distance from selected coordinates - * @param inJustTrackPoints true if waypoints should be ignored - * @return index of nearest point or -1 if not found - */ - public int getNearestPointIndexNew(double inX, double inY, double inMaxDist, boolean inJustTrackPoints) - { - int nearestPoint = 0; - double nearestDist = -1.0; - double currDist; - for (int i=0; i < getNumPoints(); i++) - { - if (!inJustTrackPoints || !_dataPoints[i].isWaypoint()) - { - currDist = Math.abs(_xValuesNew[i] - inX) + Math.abs(_yValuesNew[i] - inY); - if (currDist < nearestDist || nearestDist < 0.0) - { - nearestPoint = i; - nearestDist = currDist; - } - } - } - // Check whether it's within required distance - if (nearestDist > inMaxDist && inMaxDist > 0.0) - { - return -1; - } - return nearestPoint; - } - /** * Get the next track point starting from the given index * @param inStartIndex index to start looking from @@ -1187,7 +1107,7 @@ public class Track // set photo status if coordinates have changed if (inPoint.getPhoto() != null && coordsChanged) { - inPoint.getPhoto().setCurrentStatus(PhotoStatus.CONNECTED); + inPoint.getPhoto().setCurrentStatus(Photo.Status.CONNECTED); } // point possibly needs to be scaled again _scaled = false; diff --git a/tim/prune/data/TrackInfo.java b/tim/prune/data/TrackInfo.java index 4f3ce27..d58cc16 100644 --- a/tim/prune/data/TrackInfo.java +++ b/tim/prune/data/TrackInfo.java @@ -82,31 +82,17 @@ public class TrackInfo } - /** - * 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 - */ - public void loadTrack(Field[] inFieldArray, Object[][] inPointArray, int inAltFormat) - { - _track.cropTo(0); - _track.load(inFieldArray, inPointArray, inAltFormat); - _selection.clearAll(); - } - - /** * 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(Set inSet) + public int[] addPhotos(Set inSet) { // Firstly count number of points and photos to add int numPhotosToAdd = 0; int numPointsToAdd = 0; - Iterator iterator = null; + Iterator iterator = null; if (inSet != null && !inSet.isEmpty()) { iterator = inSet.iterator(); @@ -114,7 +100,7 @@ public class TrackInfo { try { - Photo photo = (Photo) iterator.next(); + Photo photo = iterator.next(); if (photo != null && !_photoList.contains(photo)) { numPhotosToAdd++; @@ -139,7 +125,7 @@ public class TrackInfo { try { - Photo photo = (Photo) iterator.next(); + Photo photo = iterator.next(); if (photo != null && !_photoList.contains(photo)) { // Add photo @@ -240,28 +226,12 @@ public class TrackInfo /** - * Compress the track to the given resolution - * @param inResolution resolution - * @return number of points deleted - */ - public int compress(int inResolution) - { - int numDeleted = _track.compress(inResolution); - if (numDeleted > 0) { - _selection.clearAll(); - UpdateMessageBroker.informSubscribers(); - } - return numDeleted; - } - - - /** - * 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(); + int numDeleted = _track.deleteMarkedPoints(); if (numDeleted > 0) { _selection.clearAll(); UpdateMessageBroker.informSubscribers(); @@ -295,6 +265,20 @@ public class TrackInfo } + /** + * Average selected points to create a new one + * @return true if successful + */ + public boolean average() + { + boolean success = _track.average(_selection.getStart(), _selection.getEnd()); + if (success) { + _selection.selectPoint(_selection.getEnd()+1); + } + return success; + } + + /** * Select the given DataPoint * @param inPoint DataPoint object to select diff --git a/tim/prune/drew/jpeg/ExifReader.java b/tim/prune/drew/jpeg/ExifReader.java index 1637a9d..9e0fd59 100644 --- a/tim/prune/drew/jpeg/ExifReader.java +++ b/tim/prune/drew/jpeg/ExifReader.java @@ -25,31 +25,27 @@ public class ExifReader /** Thumbnail length */ private int _thumbnailLength = -1; - /** - * The number of bytes used per format descriptor. - */ + /** The number of bytes used per format descriptor */ private static final int[] BYTES_PER_FORMAT = {0, 1, 1, 2, 4, 8, 1, 1, 2, 4, 8, 4, 8}; - /** - * The number of formats known. - */ + /** The number of formats known */ private static final int MAX_FORMAT_CODE = 12; // Format types // Note: Cannot use the DataFormat enumeration in the case statement that uses these tags. // Is there a better way? - private static final int FMT_BYTE = 1; + //private static final int FMT_BYTE = 1; private static final int FMT_STRING = 2; - private static final int FMT_USHORT = 3; - private static final int FMT_ULONG = 4; + //private static final int FMT_USHORT = 3; + //private static final int FMT_ULONG = 4; private static final int FMT_URATIONAL = 5; - private static final int FMT_SBYTE = 6; - private static final int FMT_UNDEFINED = 7; - private static final int FMT_SSHORT = 8; - private static final int FMT_SLONG = 9; + //private static final int FMT_SBYTE = 6; + //private static final int FMT_UNDEFINED = 7; + //private static final int FMT_SSHORT = 8; + //private static final int FMT_SLONG = 9; private static final int FMT_SRATIONAL = 10; - private static final int FMT_SINGLE = 11; - private static final int FMT_DOUBLE = 12; + //private static final int FMT_SINGLE = 11; + //private static final int FMT_DOUBLE = 12; public static final int TAG_EXIF_OFFSET = 0x8769; public static final int TAG_INTEROP_OFFSET = 0xA005; @@ -85,7 +81,7 @@ public class ExifReader /** - * Creates an ExifReader for a Jpeg file. + * Creates an ExifReader for a Jpeg file * @param inFile File object to attempt to read from * @throws JpegException on failure */ @@ -144,7 +140,7 @@ public class ExifReader firstDirectoryOffset = 14; } - HashMap processedDirectoryOffsets = new HashMap(); + HashMap processedDirectoryOffsets = new HashMap(); // 0th IFD (we merge with Exif IFD) processDirectory(metadata, false, processedDirectoryOffsets, firstDirectoryOffset, TIFF_HEADER_START_OFFSET); @@ -179,15 +175,15 @@ public class ExifReader * 2 bytes: format code * 4 bytes: component count */ - private void processDirectory(JpegData inMetadata, boolean inIsGPS, HashMap inDirectoryOffsets, + private void processDirectory(JpegData inMetadata, boolean inIsGPS, HashMap inDirectoryOffsets, int inDirOffset, int inTiffHeaderOffset) { // check for directories we've already visited to avoid stack overflows when recursive/cyclic directory structures exist - if (inDirectoryOffsets.containsKey(new Integer(inDirOffset))) + if (inDirectoryOffsets.containsKey(Integer.valueOf(inDirOffset))) return; // remember that we've visited this directory so that we don't visit it again later - inDirectoryOffsets.put(new Integer(inDirOffset), "processed"); + inDirectoryOffsets.put(Integer.valueOf(inDirOffset), "processed"); if (inDirOffset >= _data.length || inDirOffset < 0) { diff --git a/tim/prune/drew/jpeg/JpegData.java b/tim/prune/drew/jpeg/JpegData.java index 3d16733..f8be61a 100644 --- a/tim/prune/drew/jpeg/JpegData.java +++ b/tim/prune/drew/jpeg/JpegData.java @@ -20,7 +20,7 @@ public class JpegData private Rational[] _gpsDatestamp = null; private String _originalTimestamp = null; private byte[] _thumbnail = null; - private ArrayList _errors = null; + private ArrayList _errors = null; /** @@ -190,7 +190,7 @@ public class JpegData */ public void addError(String inError) { - if (_errors == null) _errors = new ArrayList(); + if (_errors == null) _errors = new ArrayList(); _errors.add(inError); } @@ -214,7 +214,7 @@ public class JpegData /** * @return all errors as a list */ - public List getErrors() + public List getErrors() { return _errors; } diff --git a/tim/prune/drew/jpeg/JpegSegmentData.java b/tim/prune/drew/jpeg/JpegSegmentData.java index 23197f8..8541a08 100644 --- a/tim/prune/drew/jpeg/JpegSegmentData.java +++ b/tim/prune/drew/jpeg/JpegSegmentData.java @@ -12,17 +12,9 @@ import java.util.List; public class JpegSegmentData { /** A map of byte[], keyed by the segment marker */ - private final HashMap _segmentDataMap; + private final HashMap> _segmentDataMap = new HashMap>(10); - /** - * Constructor for an empty collection - */ - public JpegSegmentData() - { - _segmentDataMap = new HashMap(10); - } - /** * Add a segment to the collection * @param inSegmentMarker marker byte @@ -30,7 +22,7 @@ public class JpegSegmentData */ public void addSegment(byte inSegmentMarker, byte[] inSegmentBytes) { - List segmentList = getOrCreateSegmentList(inSegmentMarker); + List segmentList = getOrCreateSegmentList(inSegmentMarker); segmentList.add(inSegmentBytes); } @@ -54,12 +46,12 @@ public class JpegSegmentData */ public byte[] getSegment(byte inSegmentMarker, int inOccurrence) { - final List segmentList = getSegmentList(inSegmentMarker); + final List segmentList = getSegmentList(inSegmentMarker); if (segmentList==null || segmentList.size()<=inOccurrence) return null; else - return (byte[]) segmentList.get(inOccurrence); + return segmentList.get(inOccurrence); } @@ -70,7 +62,7 @@ public class JpegSegmentData */ public int getSegmentCount(byte inSegmentMarker) { - final List segmentList = getSegmentList(inSegmentMarker); + final List segmentList = getSegmentList(inSegmentMarker); if (segmentList == null) return 0; else @@ -83,9 +75,9 @@ public class JpegSegmentData * @param inSegmentMarker marker byte * @return list of segments */ - private List getSegmentList(byte inSegmentMarker) + private List getSegmentList(byte inSegmentMarker) { - return (List)_segmentDataMap.get(new Byte(inSegmentMarker)); + return _segmentDataMap.get(Byte.valueOf(inSegmentMarker)); } @@ -94,19 +86,19 @@ public class JpegSegmentData * @param inSegmentMarker marker byte * @return list of segments */ - private List getOrCreateSegmentList(byte inSegmentMarker) + private List getOrCreateSegmentList(byte inSegmentMarker) { - List segmentList = null; - Byte key = new Byte(inSegmentMarker); + List segmentList = null; + Byte key = Byte.valueOf(inSegmentMarker); if (_segmentDataMap.containsKey(key)) { // list already exists - segmentList = (List)_segmentDataMap.get(key); + segmentList = _segmentDataMap.get(key); } else { // create new list and add it - segmentList = new ArrayList(); + segmentList = new ArrayList(); _segmentDataMap.put(key, segmentList); } return segmentList; diff --git a/tim/prune/gui/AboutScreen.java b/tim/prune/function/AboutScreen.java similarity index 74% rename from tim/prune/gui/AboutScreen.java rename to tim/prune/function/AboutScreen.java index 0d1ef5b..0f20ba0 100644 --- a/tim/prune/gui/AboutScreen.java +++ b/tim/prune/function/AboutScreen.java @@ -1,4 +1,4 @@ -package tim.prune.gui; +package tim.prune.function; import java.awt.BorderLayout; import java.awt.Component; @@ -18,14 +18,15 @@ import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JDialog; import javax.swing.JEditorPane; -import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTabbedPane; import javax.swing.JTextArea; +import tim.prune.App; import tim.prune.ExternalTools; +import tim.prune.GenericFunction; import tim.prune.GpsPruner; import tim.prune.I18nManager; import tim.prune.threedee.WindowFactory; @@ -33,20 +34,31 @@ import tim.prune.threedee.WindowFactory; /** * Class to represent the "About" popup window */ -public class AboutScreen extends JDialog +public class AboutScreen extends GenericFunction { - JButton _okButton = null; + private JDialog _dialog = null; + private JTabbedPane _tabs = null; + private JButton _okButton = null; + /** Labels for whether tools installed or not */ + private JLabel[] _installedLabels = null; + /** * Constructor - * @param inParent parent frame + * @param inApp app object */ - public AboutScreen(JFrame inParent) + public AboutScreen(App inApp) { - super(inParent, I18nManager.getText("dialog.about.title")); - getContentPane().add(makeContents()); + super(inApp); } + /** + * Return the name key for this function + */ + public String getNameKey() + { + return "function.about"; + } /** * @return the contents of the window as a Component @@ -56,8 +68,8 @@ public class AboutScreen extends JDialog JPanel mainPanel = new JPanel(); mainPanel.setLayout(new BorderLayout()); - JTabbedPane tabPane = new JTabbedPane(); - mainPanel.add(tabPane, BorderLayout.CENTER); + _tabs = new JTabbedPane(); + mainPanel.add(_tabs, BorderLayout.CENTER); JPanel aboutPanel = new JPanel(); aboutPanel.setLayout(new BoxLayout(aboutPanel, BoxLayout.Y_AXIS)); @@ -78,7 +90,8 @@ public class AboutScreen extends JDialog descBuffer.append("

").append(I18nManager.getText("dialog.about.summarytext2")).append("

"); descBuffer.append("

").append(I18nManager.getText("dialog.about.summarytext3")).append("

"); descBuffer.append("

").append(I18nManager.getText("dialog.about.languages")).append(" : ") - .append("deutsch, english, español, français, italiano, polski, schwiizerdüütsch").append("

"); + .append("deutsch, english, español, français, italiano, polski,
" + + "schwiizerdüütsch, português, bahasa indonesia, română").append("

"); descBuffer.append("

").append(I18nManager.getText("dialog.about.translatedby")).append("

"); JEditorPane descPane = new JEditorPane("text/html", descBuffer.toString()); descPane.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3)); @@ -88,7 +101,7 @@ public class AboutScreen extends JDialog aboutPanel.add(descPane); aboutPanel.add(new JLabel(" ")); - tabPane.add(I18nManager.getText("dialog.about.title"), aboutPanel); + _tabs.add(I18nManager.getText("function.about"), aboutPanel); // Second pane for system info JPanel sysInfoPanel = new JPanel(); @@ -108,31 +121,33 @@ public class AboutScreen extends JDialog addToGridBagPanel(sysInfoPanel, gridBag, constraints, new JLabel(System.getProperty("java.runtime.version")), 1, 1); + // Create install labels to be populated later + final int NUM_INSTALL_CHECKS = 5; + _installedLabels = new JLabel[NUM_INSTALL_CHECKS]; + for (int i=0; i= 0 && (serverNum != OTHER_SERVER_NUM || _serverUrl.getText().length() > 4); + } + + /** + * Finish the dialog when OK pressed + */ + private void finish() + { + int serverNum = getSelectedServer(); + if (!inputOK()) {serverNum = 0;} + Config.setMapServerIndex(serverNum); + Config.setMapServerUrl(_serverUrl.getText()); + UpdateMessageBroker.informSubscribers(DataSubscriber.MAPSERVER_CHANGED); + _dialog.dispose(); + } +} diff --git a/tim/prune/function/ShowThreeDFunction.java b/tim/prune/function/ShowThreeDFunction.java new file mode 100644 index 0000000..8ba0f41 --- /dev/null +++ b/tim/prune/function/ShowThreeDFunction.java @@ -0,0 +1,58 @@ +package tim.prune.function; + +import javax.swing.JOptionPane; + +import tim.prune.App; +import tim.prune.GenericFunction; +import tim.prune.I18nManager; +import tim.prune.threedee.ThreeDException; +import tim.prune.threedee.ThreeDWindow; +import tim.prune.threedee.WindowFactory; + +/** + * Class to show the 3d window + */ +public class ShowThreeDFunction extends GenericFunction +{ + /** + * Constructor + * @param inApp app object + */ + public ShowThreeDFunction(App inApp) + { + super(inApp); + } + + /** + * Get the name key + */ + public String getNameKey() { + return "function.show3d"; + } + + /** + * Show the help screen + */ + public void begin() + { + ThreeDWindow window = WindowFactory.getWindow(_parentFrame); + if (window == null) + { + JOptionPane.showMessageDialog(_parentFrame, I18nManager.getText("error.function.nojava3d"), + I18nManager.getText("error.function.notavailable.title"), JOptionPane.WARNING_MESSAGE); + } + else + { + try + { + // Pass the track object and show the window + window.setTrack(_app.getTrackInfo().getTrack()); + window.show(); + } + catch (ThreeDException e) + { + _app.showErrorMessageNoLookup(getNameKey(), I18nManager.getText("error.3d") + ": " + e.getMessage()); + } + } + } +} diff --git a/tim/prune/browser/BrowserLauncher.java b/tim/prune/function/browser/BrowserLauncher.java similarity index 85% rename from tim/prune/browser/BrowserLauncher.java rename to tim/prune/function/browser/BrowserLauncher.java index fe4c79a..1decbc3 100644 --- a/tim/prune/browser/BrowserLauncher.java +++ b/tim/prune/function/browser/BrowserLauncher.java @@ -1,4 +1,4 @@ -package tim.prune.browser; +package tim.prune.function.browser; import javax.swing.JOptionPane; @@ -6,15 +6,17 @@ import javax.swing.JOptionPane; /** * Class to launch a browser window to show an external map */ -public class BrowserLauncher +public abstract class BrowserLauncher { - private String[] _browserCommand = null; - private boolean _urlNeedsQuotes = false; + private static boolean _initialised = false; + private static String[] _browserCommand = null; + private static boolean _urlNeedsQuotes = false; + /** - * Constructor to set up browser + * Init method to set up browser */ - public BrowserLauncher() + private static void init() { // First check if "which" command is available if (commandExists("which")) @@ -45,8 +47,10 @@ public class BrowserLauncher _urlNeedsQuotes = true; } } + _initialised = true; } + /** * Check if the specified command exists on the system * @param inCommand command to check @@ -66,12 +70,14 @@ public class BrowserLauncher return false; } + /** * Launch a browser window to show the given url * @param inUrl url to show */ - public void launchBrowser(String inUrl) + public static void launchBrowser(String inUrl) { + if (!_initialised) {init();} if (_browserCommand == null) { JOptionPane.showMessageDialog(null, "Cannot show url: " + inUrl); } diff --git a/tim/prune/browser/UrlGenerator.java b/tim/prune/function/browser/UrlGenerator.java similarity index 67% rename from tim/prune/browser/UrlGenerator.java rename to tim/prune/function/browser/UrlGenerator.java index aa78a22..14d1577 100644 --- a/tim/prune/browser/UrlGenerator.java +++ b/tim/prune/function/browser/UrlGenerator.java @@ -1,4 +1,4 @@ -package tim.prune.browser; +package tim.prune.function.browser; import java.text.DecimalFormat; import java.text.NumberFormat; @@ -16,7 +16,7 @@ import tim.prune.data.TrackInfo; public abstract class UrlGenerator { /** Number formatter for five dp */ - public static final NumberFormat FIVE_DP = NumberFormat.getNumberInstance(Locale.UK); + private static final NumberFormat FIVE_DP = NumberFormat.getNumberInstance(Locale.UK); // Select the UK locale for this formatter so that decimal point is always used (not comma) static { if (FIVE_DP instanceof DecimalFormat) ((DecimalFormat) FIVE_DP).applyPattern("0.00000"); @@ -26,8 +26,12 @@ public abstract class UrlGenerator public static final int MAP_SOURCE_GOOGLE = 0; /** Constant for Open Street Maps */ public static final int MAP_SOURCE_OSM = 1; + /** Constant for Mapquest */ + public static final int MAP_SOURCE_MAPQUEST = 2; + /** Constant for Yahoo */ + public static final int MAP_SOURCE_YAHOO = 3; - // TODO: Add other map sources, eg Yahoo, MSN, search.ch ? + // TODO: Add other map sources, eg MSN, search.ch ? /** * Generate a URL for the given source and track info @@ -40,6 +44,12 @@ public abstract class UrlGenerator if (inSource == MAP_SOURCE_GOOGLE) { return generateGoogleUrl(inTrackInfo); } + else if (inSource == MAP_SOURCE_MAPQUEST) { + return generateMapquestUrl(inTrackInfo); + } + else if (inSource == MAP_SOURCE_YAHOO) { + return generateYahooUrl(inTrackInfo); + } return generateOpenStreetMapUrl(inTrackInfo); } @@ -104,6 +114,47 @@ public abstract class UrlGenerator } /** + * Generate a url for Mapquest maps + * @param inTrackInfo track information + * @return URL + */ + private static String generateMapquestUrl(TrackInfo inTrackInfo) + { + // Check if any data to display + if (inTrackInfo == null || inTrackInfo.getTrack() == null || inTrackInfo.getTrack().getNumPoints() < 1) + { + return null; + } + double medianLat = getMedianValue(inTrackInfo.getTrack().getLatRange()); + double medianLon = getMedianValue(inTrackInfo.getTrack().getLonRange()); + // Build basic url with centre position + String url = "http://atlas.mapquest.com/maps/map.adp?latlongtype=decimal&latitude=" + + FIVE_DP.format(medianLat) + "&longitude=" + FIVE_DP.format(medianLon); + return url; + } + + + /** + * Generate a url for Yahoo maps + * @param inTrackInfo track information + * @return URL + */ + private static String generateYahooUrl(TrackInfo inTrackInfo) + { + // Check if any data to display + if (inTrackInfo == null || inTrackInfo.getTrack() == null || inTrackInfo.getTrack().getNumPoints() < 1) + { + return null; + } + double medianLat = getMedianValue(inTrackInfo.getTrack().getLatRange()); + double medianLon = getMedianValue(inTrackInfo.getTrack().getLonRange()); + // Build basic url with centre position + String url = "http://maps.yahoo.com/#lat=" + FIVE_DP.format(medianLat) + + "&lon=" + FIVE_DP.format(medianLon) + "&zoom=13"; + return url; + } + +/** * Get the median value from the given lat/long range * @param inRange range of values * @return median value diff --git a/tim/prune/function/charts/ChartSeries.java b/tim/prune/function/charts/ChartSeries.java new file mode 100644 index 0000000..ea6128f --- /dev/null +++ b/tim/prune/function/charts/ChartSeries.java @@ -0,0 +1,51 @@ +package tim.prune.function.charts; + +/** + * Class to hold a data series for the charts + */ +public class ChartSeries +{ + /** Array of booleans, true for data existing, false otherwise */ + private boolean[] _hasData = null; + /** Array of data */ + private double[] _data = null; + + /** + * Constructor + * @param inNumPoints number of points + */ + public ChartSeries(int inNumPoints) + { + _hasData = new boolean[inNumPoints]; + _data = new double[inNumPoints]; + } + + /** + * @param inIndex index of point + * @return true if series has data for this point + */ + public boolean hasData(int inIndex) + { + return _hasData[inIndex]; + } + + /** + * @param inIndex index of point + * @return data value for this point + */ + public double getData(int inIndex) + { + return _data[inIndex]; + } + + /** + * Set the data at the given index + * @param inIndex index of point + * @param inData data value + */ + public void setData(int inIndex, double inData) + { + _hasData[inIndex] = true; + _data[inIndex] = inData; + } +} diff --git a/tim/prune/function/charts/Charter.java b/tim/prune/function/charts/Charter.java new file mode 100644 index 0000000..a3348c8 --- /dev/null +++ b/tim/prune/function/charts/Charter.java @@ -0,0 +1,697 @@ +package tim.prune.function.charts; + +import java.awt.BorderLayout; +import java.awt.FlowLayout; +import java.awt.GridLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.OutputStreamWriter; + +import javax.swing.BorderFactory; +import javax.swing.BoxLayout; +import javax.swing.ButtonGroup; +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JDialog; +import javax.swing.JFileChooser; +import javax.swing.JLabel; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JRadioButton; +import javax.swing.JTextField; +import javax.swing.SwingConstants; + +import tim.prune.App; +import tim.prune.Config; +import tim.prune.ExternalTools; +import tim.prune.GenericFunction; +import tim.prune.I18nManager; +import tim.prune.data.Altitude; +import tim.prune.data.DataPoint; +import tim.prune.data.Distance; +import tim.prune.data.Field; +import tim.prune.data.Timestamp; +import tim.prune.data.Track; +import tim.prune.data.Distance.Units; +import tim.prune.load.GenericFileFilter; + +/** + * Class to manage the generation of charts using gnuplot + */ +public class Charter extends GenericFunction +{ + /** dialog object, cached */ + private JDialog _dialog = null; + /** radio button for distance axis */ + private JRadioButton _distanceRadio = null; + /** radio button for time axis */ + private JRadioButton _timeRadio = null; + /** array of checkboxes for specifying y axes */ + private JCheckBox[] _yAxesBoxes = null; + /** radio button for svg output */ + private JRadioButton _svgRadio = null; + /** file chooser for saving svg file */ + private JFileChooser _fileChooser = null; + /** text field for svg width */ + private JTextField _svgWidthField = null; + /** text field for svg height */ + private JTextField _svgHeightField = null; + + /** Default dimensions of Svg file */ + private static final String DEFAULT_SVG_WIDTH = "800"; + private static final String DEFAULT_SVG_HEIGHT = "400"; + + + /** + * Constructor from superclass + * @param inApp app object + */ + public Charter(App inApp) + { + super(inApp); + } + + /** + * @return key for function name + */ + public String getNameKey() + { + return "function.charts"; + } + + /** + * Show the dialog + */ + public void begin() + { + // Make dialog window + if (_dialog == null) + { + _dialog = new JDialog(_parentFrame, I18nManager.getText(getNameKey()), true); + _dialog.setLocationRelativeTo(_parentFrame); + _dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); + _dialog.getContentPane().add(makeDialogComponents()); + _dialog.pack(); + } + if (setupDialog(_app.getTrackInfo().getTrack())) { + _dialog.setVisible(true); + } + else { + _app.showErrorMessage(getNameKey(), "dialog.charts.needaltitudeortimes"); + } + } + + + /** + * Make the dialog components + * @return panel containing gui elements + */ + private JPanel makeDialogComponents() + { + JPanel dialogPanel = new JPanel(); + dialogPanel.setLayout(new BorderLayout()); + + JPanel mainPanel = new JPanel(); + mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS)); + // x axis choice + JPanel axisPanel = new JPanel(); + axisPanel.setBorder(BorderFactory.createTitledBorder(I18nManager.getText("dialog.charts.xaxis"))); + _distanceRadio = new JRadioButton(I18nManager.getText("fieldname.distance")); + _distanceRadio.setSelected(true); + _timeRadio = new JRadioButton(I18nManager.getText("fieldname.time")); + ButtonGroup axisGroup = new ButtonGroup(); + axisGroup.add(_distanceRadio); axisGroup.add(_timeRadio); + axisPanel.add(_distanceRadio); axisPanel.add(_timeRadio); + mainPanel.add(axisPanel); + + // y axis choices + JPanel yPanel = new JPanel(); + yPanel.setBorder(BorderFactory.createTitledBorder(I18nManager.getText("dialog.charts.yaxis"))); + _yAxesBoxes = new JCheckBox[4]; // dist altitude speed vertspeed (time not available on y axis) + _yAxesBoxes[0] = new JCheckBox(I18nManager.getText("fieldname.distance")); + _yAxesBoxes[1] = new JCheckBox(I18nManager.getText("fieldname.altitude")); + _yAxesBoxes[1].setSelected(true); + _yAxesBoxes[2] = new JCheckBox(I18nManager.getText("fieldname.speed")); + _yAxesBoxes[3] = new JCheckBox(I18nManager.getText("fieldname.verticalspeed")); + for (int i=0; i<4; i++) { + yPanel.add(_yAxesBoxes[i]); + } + mainPanel.add(yPanel); + + // Add validation to prevent choosing invalid (ie dist/dist) combinations + ActionListener xAxisListener = new ActionListener() { + public void actionPerformed(ActionEvent e) { + enableYbox(0, _timeRadio.isSelected()); + } + }; + _timeRadio.addActionListener(xAxisListener); + _distanceRadio.addActionListener(xAxisListener); + + // output buttons + JPanel outputPanel = new JPanel(); + outputPanel.setBorder(BorderFactory.createTitledBorder(I18nManager.getText("dialog.charts.output"))); + outputPanel.setLayout(new BorderLayout()); + JPanel radiosPanel = new JPanel(); + JRadioButton screenRadio = new JRadioButton(I18nManager.getText("dialog.charts.screen")); + screenRadio.setSelected(true); + _svgRadio = new JRadioButton(I18nManager.getText("dialog.charts.svg")); + ButtonGroup outputGroup = new ButtonGroup(); + outputGroup.add(screenRadio); outputGroup.add(_svgRadio); + radiosPanel.add(screenRadio); radiosPanel.add(_svgRadio); + outputPanel.add(radiosPanel, BorderLayout.NORTH); + // panel for svg width, height + JPanel sizePanel = new JPanel(); + sizePanel.setLayout(new GridLayout(2, 2, 10, 1)); + JLabel widthLabel = new JLabel(I18nManager.getText("dialog.charts.svgwidth")); + widthLabel.setHorizontalAlignment(SwingConstants.RIGHT); + sizePanel.add(widthLabel); + _svgWidthField = new JTextField(DEFAULT_SVG_WIDTH, 5); + sizePanel.add(_svgWidthField); + JLabel heightLabel = new JLabel(I18nManager.getText("dialog.charts.svgheight")); + heightLabel.setHorizontalAlignment(SwingConstants.RIGHT); + sizePanel.add(heightLabel); + _svgHeightField = new JTextField(DEFAULT_SVG_HEIGHT, 5); + sizePanel.add(_svgHeightField); + + outputPanel.add(sizePanel, BorderLayout.EAST); + mainPanel.add(outputPanel); + dialogPanel.add(mainPanel, BorderLayout.CENTER); + + // button panel on bottom + JPanel buttonPanel = new JPanel(); + buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT)); + // Gnuplot button + JButton gnuplotButton = new JButton(I18nManager.getText("button.gnuplotpath")); + gnuplotButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + setGnuplotPath(); + } + }); + buttonPanel.add(gnuplotButton); + // Cancel button + JButton cancelButton = new JButton(I18nManager.getText("button.cancel")); + cancelButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + _dialog.setVisible(false); + } + }); + buttonPanel.add(cancelButton); + // ok button + JButton okButton = new JButton(I18nManager.getText("button.ok")); + okButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + showChart(_app.getTrackInfo().getTrack()); + _dialog.setVisible(false); + } + }); + buttonPanel.add(okButton); + dialogPanel.add(buttonPanel, BorderLayout.SOUTH); + return dialogPanel; + } + + + /** + * Set up the dialog according to the track contents + * @param inTrack track object + * @return true if it's all ok + */ + private boolean setupDialog(Track inTrack) + { + boolean hasTimes = inTrack.hasData(Field.TIMESTAMP); + boolean hasAltitudes = inTrack.getAltitudeRange().hasRange(); + _timeRadio.setEnabled(hasTimes); + + // Add checks to prevent choosing unavailable combinations + if (!hasTimes) { + _distanceRadio.setSelected(true); + } + enableYbox(0, !_distanceRadio.isSelected()); + enableYbox(1, hasAltitudes); + enableYbox(2, hasTimes); + enableYbox(3, hasTimes && hasAltitudes); + return (hasTimes || hasAltitudes); + } + + + /** + * Enable or disable the given y axis checkbox + * @param inIndex index of checkbox + * @param inFlag true to enable + */ + private void enableYbox(int inIndex, boolean inFlag) + { + _yAxesBoxes[inIndex].setEnabled(inFlag); + if (!inFlag) { + _yAxesBoxes[inIndex].setSelected(inFlag); + } + } + + /** + * Show the chart for the specified track + * @param inTrack track object containing data + */ + private void showChart(Track inTrack) + { + int numCharts = 0; + for (int i=0; i<_yAxesBoxes.length; i++) { + if (_yAxesBoxes[i].isSelected()) { + numCharts++; + } + } + // Select default chart if none selected + if (numCharts == 0) { + _yAxesBoxes[1].setSelected(true); + numCharts = 1; + } + int[] heights = getHeights(numCharts); + + boolean showSvg = _svgRadio.isSelected(); + File svgFile = null; + if (showSvg) { + svgFile = selectSvgFile(); + if (svgFile == null) {showSvg = false;} + } + OutputStreamWriter writer = null; + try + { + Process process = Runtime.getRuntime().exec(Config.getGnuplotPath() + " -persist"); + writer = new OutputStreamWriter(process.getOutputStream()); + if (showSvg) + { + writer.write("set terminal svg size " + getSvgValue(_svgWidthField, DEFAULT_SVG_WIDTH) + " " + + getSvgValue(_svgHeightField, DEFAULT_SVG_HEIGHT) + "\n"); + writer.write("set out '" + svgFile.getAbsolutePath() + "'\n"); + } + if (numCharts > 1) { + writer.write("set multiplot layout " + numCharts + ",1\n"); + } + // Loop over possible charts + int chartNum = 0; + for (int c=0; c<_yAxesBoxes.length; c++) + { + if (_yAxesBoxes[c].isSelected()) + { + writer.write("set size 1," + (0.01*heights[chartNum*2+1]) + "\n"); + writer.write("set origin 0," + (0.01*heights[chartNum*2]) + "\n"); + writeChart(writer, inTrack, _distanceRadio.isSelected(), c); + chartNum++; + } + } + // Close multiplot if open + if (numCharts > 1) { + writer.write("unset multiplot\n"); + } + } + catch (Exception e) { + _app.showErrorMessageNoLookup(getNameKey(), e.getMessage()); + } + finally { + try { + // Close writer + if (writer != null) writer.close(); + } + catch (Exception e) {} // ignore + } + } + + + /** + * Parse the given text field's value and return as string + * @param inField text field to read from + * @param inDefault default value if not valid + * @return value of svg dimension as string + */ + private static String getSvgValue(JTextField inField, String inDefault) + { + int value = 0; + try { + value = Integer.parseInt(inField.getText()); + } + catch (Exception e) {} // ignore, value stays zero + if (value > 0) { + return "" + value; + } + return inDefault; + } + + + /** + * Write out the selected chart to the given Writer object + * @param inWriter writer object + * @param inTrack Track containing data + * @param inDistance true if x axis is distance + * @param inYaxis index of y axis + * @throws IOException if writing error occurred + */ + private static void writeChart(OutputStreamWriter inWriter, Track inTrack, boolean inDistance, int inYaxis) + throws IOException + { + ChartSeries xValues = null, yValues = null; + ChartSeries distValues = getDistanceValues(inTrack); + // Choose x values according to axis + if (inDistance) { + xValues = distValues; + } + else { + xValues = getTimeValues(inTrack); + } + // Choose y values according to axis + switch (inYaxis) + { + case 0: // y axis is distance + yValues = distValues; + break; + case 1: // y axis is altitude + yValues = getAltitudeValues(inTrack); + break; + case 2: // y axis is speed + yValues = getSpeedValues(inTrack); + break; + case 3: // y axis is vertical speed + yValues = getVertSpeedValues(inTrack); + break; + } + // Make a temporary data file for the output (one per subchart) + File tempFile = File.createTempFile("prunedata", null); + tempFile.deleteOnExit(); + // write out values for x and y to temporary file + FileWriter tempFileWriter = null; + try { + tempFileWriter = new FileWriter(tempFile); + tempFileWriter.write("# Temporary data file for Prune charts\n\n"); + for (int i=0; i 1.0) param = 1.0 / param; + if (param <= 0.0 || param >= 1.0) { + // Parameter isn't valid, don't delete any + return 0; + } + double threshold = _trackDetails.getTrackSpan() * param; + + // Loop over all points checking distances to previous point + // TODO: Maybe this should also check distance to _next_ point as well! + int numPoints = _track.getNumPoints(); + int prevPointIndex = 0; + int prevTrackPointIndex = 0; + double pointDist = 0.0; + int numDeleted = 0; + for (int i=1; i 0); + return deleteFlags; + } + + + /** + * Create dialog components + * @return Panel containing all gui elements in dialog + */ + private JPanel makeDialogComponents() + { + JPanel dialogPanel = new JPanel(); + dialogPanel.setLayout(new BorderLayout()); + + // Make a central panel + JPanel mainPanel = new JPanel(); + mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS)); + + // Add each of the algorithm components to the panel + for (int i=0; i<_algorithms.length; i++) + { + mainPanel.add(_algorithms[i].getGuiComponents()); + mainPanel.add(Box.createRigidArea(new Dimension(0, 2))); + } + // Summary label below algorithms + JPanel summaryPanel = new JPanel(); + _summaryLabel = new SummaryLabel(_track); + summaryPanel.add(_summaryLabel); + mainPanel.add(summaryPanel); + dialogPanel.add(mainPanel, BorderLayout.NORTH); + + // button panel at bottom + JPanel buttonPanel = new JPanel(); + buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT)); + _okButton = new JButton(I18nManager.getText("button.ok")); + _okButton.setEnabled(false); + ActionListener okListener = new ActionListener() { + public void actionPerformed(ActionEvent e) + { + finish(); + } + }; + _okButton.addActionListener(okListener); + buttonPanel.add(_okButton); + JButton cancelButton = new JButton(I18nManager.getText("button.cancel")); + cancelButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) + { + _dialog.dispose(); + } + }); + buttonPanel.add(cancelButton); + dialogPanel.add(buttonPanel, BorderLayout.SOUTH); + dialogPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 15)); + return dialogPanel; + } + + + /** + * Initialise all the algorithms to use + */ + private void makeAlgorithms() + { + // make listener to be informed of algorithm activation + ActionListener changeListener = new ActionListener() { + public void actionPerformed(ActionEvent arg0) + { + preview(); + }; + }; + // construct track details to be used by all algorithms + TrackDetails details = new TrackDetails(_track); + // make array of algorithm objects + _algorithms = new CompressionAlgorithm[] { + new DuplicatePointAlgorithm(_track, details, changeListener), + new ClosePointsAlgorithm(_track, details, changeListener), + new WackyPointAlgorithm(_track, details, changeListener), + new SingletonAlgorithm(_track, details, changeListener) + }; + } + + + /** + * Finish the dialog when OK pressed + */ + private void finish() + { + boolean[] deleteFlags = preview(); + // All flags are now combined in deleteFlags array + for (int i=0; i threshold) + { + // Now need to find next track point, and measure distances + DataPoint nextPoint = _track.getNextTrackPoint(i+1); + if (nextPoint != null && DataPoint.calculateRadiansBetween(currPoint, nextPoint) > threshold) + { + // Found a point to delete (hope that next point hasn't been deleted already) + inFlags[i] = true; + numDeleted++; + } + } + } + // Remember last (not-deleted) track point + if (!currPoint.isWaypoint()) {prevPoint = currPoint;} + } + } + return numDeleted; + } + + /** + * @return specific gui components for dialog + */ + protected Component getSpecificGuiComponents() + { + return getSpecificGuiComponents("dialog.compress.singletons.paramdesc", "2"); + } + + /** + * @return title key for box + */ + protected String getTitleTextKey() + { + return "dialog.compress.singletons.title"; + } +} diff --git a/tim/prune/function/compress/SummaryLabel.java b/tim/prune/function/compress/SummaryLabel.java new file mode 100644 index 0000000..57f8ad1 --- /dev/null +++ b/tim/prune/function/compress/SummaryLabel.java @@ -0,0 +1,62 @@ +package tim.prune.function.compress; + +import javax.swing.JLabel; + +import tim.prune.I18nManager; +import tim.prune.data.Track; + +/** + * Summary label for compression + */ +public class SummaryLabel extends JLabel +{ + /** Track object */ + private Track _track = null; + + + /** + * Constructor + * @param inTrack track object to work out percentages + */ + public SummaryLabel(Track inTrack) + { + super("..........................."); + setEnabled(false); + _track = inTrack; + } + + /** + * Set value + * @param inNumToDelete number of points to delete + */ + public void setValue(int inNumToDelete) + { + setText(makeString(inNumToDelete)); + setEnabled(true); + } + + /** + * Clear value + */ + public void clearValue() + { + setText(makeString(0)); + setEnabled(false); + } + + /** + * Make a string describing the deletion + * @param inNumToDelete number of points to delete + * @return String describing number and %age + */ + private String makeString(int inNumToDelete) + { + String desc = I18nManager.getText("dialog.compress.summarylabel") + ": " + inNumToDelete; + if (inNumToDelete > 0) + { + long percent = Math.round(100.0 * inNumToDelete / _track.getNumPoints()); + desc += " (" + percent + "%)"; + } + return desc; + } +} diff --git a/tim/prune/function/compress/TrackDetails.java b/tim/prune/function/compress/TrackDetails.java new file mode 100644 index 0000000..b218861 --- /dev/null +++ b/tim/prune/function/compress/TrackDetails.java @@ -0,0 +1,120 @@ +package tim.prune.function.compress; + +import tim.prune.data.DataPoint; +import tim.prune.data.Track; + +/** + * Class to hold details about a track + * which might be useful for compression + */ +public class TrackDetails +{ + /** Track object */ + private Track _track = null; + /** Range span */ + private double _trackSpan = -1.0; + /** Markers for start of segment */ + private boolean[] _segmentStarts = null; + /** Markers for end of segment */ + private boolean[] _segmentEnds = null; + /** Mean distance between track points in radians */ + private double _meanRadians = 0.0; + + + /** + * Constructor + * @param inTrack track object + */ + public TrackDetails(Track inTrack) + { + _track = inTrack; + } + + /** + * Recalculate all details + */ + public void initialise() + { + // calculate track span + double xRange = _track.getXRange().getRange(); + double yRange = _track.getYRange().getRange(); + _trackSpan = (xRange > yRange ? xRange : yRange); + + // Calculate segment starts / ends + int numPoints = _track.getNumPoints(); + _segmentStarts = new boolean[numPoints]; + _segmentEnds = new boolean[numPoints]; + int prevTrackPointIndex = -1; + int numDistances = 0; double totalRadians = 0.0; + // Loop over points + for (int i=0; i= 0) { + _segmentEnds[prevTrackPointIndex] = true; + } + } + else { + // Add up distances between points within the same track segment + if (prevTrackPointIndex >= 0) { + numDistances++; + totalRadians += DataPoint.calculateRadiansBetween(_track.getPoint(prevTrackPointIndex), point); + } + } + prevTrackPointIndex = i; + } + } + // last segment + _segmentEnds[prevTrackPointIndex] = true; + // Mean radians between points + _meanRadians = totalRadians / numDistances; + } + + + /** + * @return the track span + */ + public double getTrackSpan() + { + if (_trackSpan < 0.0) {initialise();} + return _trackSpan; + } + + /** + * @param inPointIndex index of point to check + * @return true if specified point is start of segment + */ + public boolean isSegmentStart(int inPointIndex) + { + if (_segmentStarts == null || + _segmentStarts.length != _track.getNumPoints()) {initialise();} + return _segmentStarts[inPointIndex]; + } + + /** + * @param inPointIndex index of point to check + * @return true if specified point is end of segment + */ + public boolean isSegmentEnd(int inPointIndex) + { + if (_segmentEnds == null || + _segmentEnds.length != _track.getNumPoints()) {initialise();} + return _segmentEnds[inPointIndex]; + } + + /** + * @return mean radians between adjacent track points + */ + public double getMeanRadians() + { + if (_meanRadians == 0.0) {initialise();} + return _meanRadians; + } +} diff --git a/tim/prune/function/compress/WackyPointAlgorithm.java b/tim/prune/function/compress/WackyPointAlgorithm.java new file mode 100644 index 0000000..d7b5b9f --- /dev/null +++ b/tim/prune/function/compress/WackyPointAlgorithm.java @@ -0,0 +1,86 @@ +package tim.prune.function.compress; + +import java.awt.Component; +import java.awt.event.ActionListener; + +import tim.prune.data.DataPoint; +import tim.prune.data.Track; + +/** + * Algorithm for detecting wacky points to compress + */ +public class WackyPointAlgorithm extends SingleParameterAlgorithm +{ + /** + * Constructor + * @param inTrack track object + * @param inDetails track details object + * @param inListener listener to attach to activation control + */ + public WackyPointAlgorithm(Track inTrack, TrackDetails inDetails, ActionListener inListener) + { + super(inTrack, inDetails, inListener); + } + + /** + * Perform the compression and work out which points should be deleted + * @param inFlags deletion flags from previous algorithms + * @return number of points deleted + */ + protected int compress(boolean[] inFlags) + { + double param = getParameter(); + if (param <= 0.0) return 0; + int numPoints = _track.getNumPoints(); + int numDeleted = 0; + double threshold = param * _trackDetails.getMeanRadians(); + DataPoint currPoint = null, prevPoint = null; + // Loop over all points looking for points far away from neighbours + for (int i=0; i threshold) + { + // Now need to find next track point, and measure distances + DataPoint nextPoint = _track.getNextTrackPoint(i+1); + if (nextPoint != null && DataPoint.calculateRadiansBetween(currPoint, nextPoint) > threshold + && DataPoint.calculateRadiansBetween(prevPoint, nextPoint) < threshold) + { + // Found a point to delete (hope that next point hasn't been deleted already) + inFlags[i] = true; + numDeleted++; + } + } + } + // Remember last (not-deleted) track point + if (!currPoint.isWaypoint()) {prevPoint = currPoint;} + } + } + return numDeleted; + } + + /** + * @return specific gui components for dialog + */ + protected Component getSpecificGuiComponents() + { + return getSpecificGuiComponents("dialog.compress.wackypoints.paramdesc", "2"); + } + + /** + * @return title key for box + */ + protected String getTitleTextKey() + { + return "dialog.compress.wackypoints.title"; + } + +} diff --git a/tim/prune/function/distance/DistanceFunction.java b/tim/prune/function/distance/DistanceFunction.java new file mode 100644 index 0000000..b41ab8b --- /dev/null +++ b/tim/prune/function/distance/DistanceFunction.java @@ -0,0 +1,153 @@ +package tim.prune.function.distance; + +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.GridLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.ArrayList; + +import javax.swing.BorderFactory; +import javax.swing.JButton; +import javax.swing.JDialog; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTable; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; + +import tim.prune.App; +import tim.prune.GenericFunction; +import tim.prune.I18nManager; +import tim.prune.data.DataPoint; +import tim.prune.data.TrackInfo; + +/** + * Class to provide the distance measuring function between waypoints + */ +public class DistanceFunction extends GenericFunction +{ + /** Dialog */ + private JDialog _dialog = null; + /** Table for 'from' point selection */ + private JTable _pointTable = null; + /** Model for 'from' table */ + private FromTableModel _fromModel = null; + /** Model for distance table */ + private DistanceTableModel _distModel = null; + + + /** + * Constructor + * @param inApp App object + */ + public DistanceFunction(App inApp) + { + super(inApp); + } + + /** Get the name key */ + public String getNameKey() { + return "function.distances"; + } + + /** + * Begin the function + */ + public void begin() + { + if (_dialog == null) + { + _dialog = new JDialog(_parentFrame, I18nManager.getText(getNameKey()), true); + _dialog.setLocationRelativeTo(_parentFrame); + _dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); + _dialog.getContentPane().add(makeDialogComponents()); + _dialog.pack(); + } + ArrayList pointList = getPointList(_app.getTrackInfo()); + // Check if point list has size at least 2 + if (pointList.size() < 2) { + _app.showErrorMessage(getNameKey(), "dialog.distances.toofewpoints"); + return; + } + _fromModel.init(pointList); + _distModel.init(pointList); + _pointTable.getSelectionModel().setSelectionInterval(0, 0); + _distModel.recalculate(0); + _dialog.setVisible(true); + } + + /** + * Create dialog components + * @return Panel containing all gui elements in dialog + */ + private Component makeDialogComponents() + { + JPanel dialogPanel = new JPanel(); + dialogPanel.setLayout(new BorderLayout(5, 5)); + // Label at top + JLabel topLabel = new JLabel(I18nManager.getText("dialog.distances.intro")); + topLabel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); + dialogPanel.add(topLabel, BorderLayout.NORTH); + + JPanel mainPanel = new JPanel(); + mainPanel.setLayout(new GridLayout(1, 2)); + // First table for 'from point' + _fromModel = new FromTableModel(); + _pointTable = new JTable(_fromModel); + _pointTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() { + /** selection changed */ + public void valueChanged(ListSelectionEvent e) { + if (!e.getValueIsAdjusting()) { + _distModel.recalculate(_pointTable.getSelectedRow()); + } + } + }); + JScrollPane scrollPane = new JScrollPane(_pointTable); + scrollPane.setPreferredSize(new Dimension(100, 250)); + mainPanel.add(scrollPane); + // second table for distances + _distModel = new DistanceTableModel(); + JTable distTable = new JTable(_distModel); + distTable.setAutoCreateRowSorter(true); + scrollPane = new JScrollPane(distTable); + scrollPane.setPreferredSize(new Dimension(200, 250)); + mainPanel.add(scrollPane); + dialogPanel.add(mainPanel, BorderLayout.CENTER); + + // button panel at bottom + JPanel buttonPanel = new JPanel(); + buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT)); + JButton closeButton = new JButton(I18nManager.getText("button.close")); + closeButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) + { + _dialog.dispose(); + } + }); + buttonPanel.add(closeButton); + dialogPanel.add(buttonPanel, BorderLayout.SOUTH); + return dialogPanel; + } + + /** + * Get the point list for the tables + * @param inTrackInfo TrackInfo object + */ + private static ArrayList getPointList(TrackInfo inTrackInfo) + { + // Get the list of waypoints (if any) + ArrayList pointList = new ArrayList(); + inTrackInfo.getTrack().getWaypoints(pointList); + // Get the current point (if any) + DataPoint currPoint = inTrackInfo.getCurrentPoint(); + if (currPoint != null && !currPoint.isWaypoint()) { + // Add current point to start of list + pointList.add(0, currPoint); + } + return pointList; + } +} diff --git a/tim/prune/function/distance/DistanceTableModel.java b/tim/prune/function/distance/DistanceTableModel.java new file mode 100644 index 0000000..8adbf69 --- /dev/null +++ b/tim/prune/function/distance/DistanceTableModel.java @@ -0,0 +1,108 @@ +package tim.prune.function.distance; + +import tim.prune.Config; +import tim.prune.I18nManager; +import tim.prune.data.DataPoint; +import tim.prune.data.Distance; + +/** + * Class to hold the table model for the distances table + */ +public class DistanceTableModel extends GenericTableModel +{ + /** Distances */ + private double[] _distances = null; + /** Metric distances? */ + private boolean _useMetric = true; + /** Previous value of metric flag (to spot changes) */ + private boolean _prevUseMetric = false; + /** Column heading */ + private static final String _toColLabel = I18nManager.getText("dialog.distances.column.to"); + /** Column heading (depends on metric/imperial settings) */ + private String _distanceLabel = null; + + /** + * @return column count + */ + public int getColumnCount() + { + return 2; + } + + /** + * @param inRowIndex row index + * @param inColumnIndex column index + * @return cell value + */ + public Object getValueAt(int inRowIndex, int inColumnIndex) + { + if (inColumnIndex == 0) {return getPointName(inRowIndex);} + if (_distances == null) {return 0.0;} + return new Double(_distances[inRowIndex]); + } + + /** + * @param inColumnIndex column index + * @return column name + */ + public String getColumnName(int inColumnIndex) + { + if (inColumnIndex == 0) {return _toColLabel;} + return _distanceLabel; + } + + /** + * Get the column class (required for sorting) + * @param inColumnIndex column index + * @return Class of specified column + */ + public Class getColumnClass(int inColumnIndex) + { + if (inColumnIndex == 0) return String.class; + return Double.class; + } + + /** + * Recalculate the distances + * @param inIndex index of selected 'from' point + */ + public void recalculate(int inIndex) + { + // Use metric or not? + _useMetric = Config.getUseMetricUnits(); + _distanceLabel = getDistanceLabel(_useMetric); + // Initialize array of distances + int numRows = getRowCount(); + if (_distances == null || _distances.length != numRows) { + _distances = new double[numRows]; + } + DataPoint fromPoint = _pointList.get(inIndex); + for (int i=0; i _pointList = null; + /** Column heading */ + private static String _currPointLabel = I18nManager.getText("dialog.distances.currentpoint"); + + /** + * Initialize the table model with the point list + * @param inPointList list of points + */ + public void init(ArrayList inPointList) + { + _pointList = inPointList; + } + + /** + * @return row count + */ + public int getRowCount() + { + if (_pointList == null) {return 0;} + return _pointList.size(); + } + + /** + * Get the name of the specified point from the list + * @param inIndex index of point + * @return waypoint name if waypoint, otherwise "current point" + */ + protected String getPointName(int inIndex) + { + if (_pointList == null) {return "null";} + DataPoint point = _pointList.get(inIndex); + if (point.isWaypoint()) {return point.getWaypointName();} + return _currPointLabel; + } +} diff --git a/tim/prune/edit/EditFieldsTableModel.java b/tim/prune/function/edit/EditFieldsTableModel.java similarity index 97% rename from tim/prune/edit/EditFieldsTableModel.java rename to tim/prune/function/edit/EditFieldsTableModel.java index fb4a86b..f4ee561 100644 --- a/tim/prune/edit/EditFieldsTableModel.java +++ b/tim/prune/function/edit/EditFieldsTableModel.java @@ -1,4 +1,4 @@ -package tim.prune.edit; +package tim.prune.function.edit; import javax.swing.table.AbstractTableModel; @@ -98,7 +98,7 @@ public class EditFieldsTableModel extends AbstractTableModel /** * @return Class of cell data */ - public Class getColumnClass(int inColumnIndex) + public Class getColumnClass(int inColumnIndex) { if (inColumnIndex <= 1) return String.class; return Boolean.class; diff --git a/tim/prune/edit/FieldEdit.java b/tim/prune/function/edit/FieldEdit.java similarity index 94% rename from tim/prune/edit/FieldEdit.java rename to tim/prune/function/edit/FieldEdit.java index 5877ab1..41f38b3 100644 --- a/tim/prune/edit/FieldEdit.java +++ b/tim/prune/function/edit/FieldEdit.java @@ -1,4 +1,4 @@ -package tim.prune.edit; +package tim.prune.function.edit; import tim.prune.data.Field; diff --git a/tim/prune/edit/FieldEditList.java b/tim/prune/function/edit/FieldEditList.java similarity index 79% rename from tim/prune/edit/FieldEditList.java rename to tim/prune/function/edit/FieldEditList.java index 70bd263..8612e8a 100644 --- a/tim/prune/edit/FieldEditList.java +++ b/tim/prune/function/edit/FieldEditList.java @@ -1,4 +1,4 @@ -package tim.prune.edit; +package tim.prune.function.edit; import java.util.ArrayList; @@ -7,7 +7,7 @@ import java.util.ArrayList; */ public class FieldEditList { - private ArrayList _editList = new ArrayList(); + private ArrayList _editList = new ArrayList(); /** @@ -35,6 +35,6 @@ public class FieldEditList */ public FieldEdit getEdit(int inIndex) { - return (FieldEdit) _editList.get(inIndex); + return _editList.get(inIndex); } } diff --git a/tim/prune/edit/PointEditor.java b/tim/prune/function/edit/PointEditor.java similarity index 98% rename from tim/prune/edit/PointEditor.java rename to tim/prune/function/edit/PointEditor.java index ea67a0a..6808e6a 100644 --- a/tim/prune/edit/PointEditor.java +++ b/tim/prune/function/edit/PointEditor.java @@ -1,4 +1,4 @@ -package tim.prune.edit; +package tim.prune.function.edit; import java.awt.BorderLayout; import java.awt.Component; @@ -78,7 +78,7 @@ public class PointEditor // Create Gui and show it _dialog.getContentPane().add(makeDialogComponents()); _dialog.pack(); - _dialog.show(); + _dialog.setVisible(true); } diff --git a/tim/prune/edit/PointNameEditor.java b/tim/prune/function/edit/PointNameEditor.java similarity index 81% rename from tim/prune/edit/PointNameEditor.java rename to tim/prune/function/edit/PointNameEditor.java index 3229bc2..19edfbb 100644 --- a/tim/prune/edit/PointNameEditor.java +++ b/tim/prune/function/edit/PointNameEditor.java @@ -1,4 +1,4 @@ -package tim.prune.edit; +package tim.prune.function.edit; import java.awt.Component; import java.awt.BorderLayout; @@ -53,23 +53,26 @@ public class PointNameEditor public void showDialog(DataPoint inPoint) { _point = inPoint; - _dialog = new JDialog(_parentFrame, I18nManager.getText("dialog.pointnameedit.title"), true); - _dialog.setLocationRelativeTo(_parentFrame); + if (_dialog == null) + { + _dialog = new JDialog(_parentFrame, I18nManager.getText("dialog.pointnameedit.title"), true); + _dialog.setLocationRelativeTo(_parentFrame); + // Create Gui and show it + _dialog.getContentPane().add(makeDialogComponents()); + _dialog.pack(); + } // Check current waypoint name, if any String name = _point.getWaypointName(); - // Create Gui and show it - _dialog.getContentPane().add(makeDialogComponents(name)); - _dialog.pack(); - _dialog.show(); + resetDialog(name); + _dialog.setVisible(true); } /** * Make the dialog components - * @param inName initial name of point * @return the GUI components for the dialog */ - private Component makeDialogComponents(String inName) + private Component makeDialogComponents() { JPanel panel = new JPanel(); panel.setLayout(new BorderLayout()); @@ -80,16 +83,12 @@ public class PointNameEditor ActionListener okActionListener = new ActionListener() { public void actionPerformed(ActionEvent e) { - // Check for empty name - if (_nameField.getText().length() > 0) - { - // update App with edit - confirmEdit(); - _dialog.dispose(); - } + // update App with edit + confirmEdit(); + _dialog.dispose(); } }; - _nameField = new JTextField(inName, 12); + _nameField = new JTextField("", 12); _nameField.addKeyListener(new KeyAdapter() { public void keyReleased(KeyEvent e) { @@ -98,8 +97,8 @@ public class PointNameEditor { _dialog.dispose(); } - // Enable ok button if name not empty - _okButton.setEnabled(_nameField.getText().length() > 0); + // Enable ok button if name changed + _okButton.setEnabled(hasNameChanged()); } }); _nameField.addActionListener(okActionListener); @@ -158,6 +157,16 @@ public class PointNameEditor } + /** + * Reset the dialog with the given name + * @param inName waypoint name + */ + private void resetDialog(String inName) + { + _nameField.setText(inName); + _okButton.setEnabled(false); + } + /** * Turn a String into sentence case by capitalizing each word * @param inString String to convert @@ -189,22 +198,31 @@ public class PointNameEditor private void confirmEdit() { // Check whether name has really changed - String prevName = _point.getWaypointName(); - String newName = _nameField.getText().trim(); - boolean prevNull = (prevName == null || prevName.equals("")); - boolean newNull = (newName == null || newName.equals("")); - if ( (prevNull && !newNull) - || (!prevNull && newNull) - || (!prevNull && !newNull && !prevName.equals(newName)) ) + if (hasNameChanged()) { // Make lists for edit and undo, and add the changed field FieldEditList editList = new FieldEditList(); FieldEditList undoList = new FieldEditList(); - editList.addEdit(new FieldEdit(Field.WAYPT_NAME, newName)); - undoList.addEdit(new FieldEdit(Field.WAYPT_NAME, prevName)); + editList.addEdit(new FieldEdit(Field.WAYPT_NAME, _nameField.getText().trim())); + undoList.addEdit(new FieldEdit(Field.WAYPT_NAME, _point.getWaypointName())); // Pass back to App to perform edit _app.completePointEdit(editList, undoList); } } + + /** + * Check whether the name has been changed or not + * @return true if the new name is different + */ + private boolean hasNameChanged() + { + String prevName = _point.getWaypointName(); + String newName = _nameField.getText().trim(); + boolean prevNull = (prevName == null || prevName.equals("")); + boolean newNull = (newName == null || newName.equals("")); + return (prevNull && !newNull) + || (!prevNull && newNull) + || (!prevNull && !newNull && !prevName.equals(newName)); + } } diff --git a/tim/prune/gui/DetailsDisplay.java b/tim/prune/gui/DetailsDisplay.java index e153a6c..2703c1b 100644 --- a/tim/prune/gui/DetailsDisplay.java +++ b/tim/prune/gui/DetailsDisplay.java @@ -25,7 +25,6 @@ import tim.prune.data.DataPoint; import tim.prune.data.Distance; import tim.prune.data.IntegerRange; import tim.prune.data.Photo; -import tim.prune.data.PhotoStatus; import tim.prune.data.Selection; import tim.prune.data.TrackInfo; @@ -75,7 +74,7 @@ public class DetailsDisplay extends GenericDisplay private static final String LABEL_RANGE_CLIMB = I18nManager.getText("details.range.climb") + ": "; private static final String LABEL_RANGE_DESCENT = ", " + I18nManager.getText("details.range.descent") + ": "; private static String LABEL_POINT_ALTITUDE_UNITS = null; - private static int LABEL_POINT_ALTITUDE_FORMAT = Altitude.FORMAT_NONE; + private static Altitude.Format LABEL_POINT_ALTITUDE_FORMAT = Altitude.Format.NO_FORMAT; /** @@ -202,6 +201,7 @@ public class DetailsDisplay extends GenericDisplay public void actionPerformed(ActionEvent e) { dataUpdated(DataSubscriber.UNITS_CHANGED); + Config.setUseMetricUnits(_distUnitsDropdown.getSelectedIndex() == 0); } }); lowerPanel.add(_distUnitsDropdown); @@ -221,7 +221,7 @@ public class DetailsDisplay extends GenericDisplay Selection selection = _trackInfo.getSelection(); int currentPointIndex = selection.getCurrentPointIndex(); _speedLabel.setText(""); - int distUnits = _distUnitsDropdown.getSelectedIndex()==0?Distance.UNITS_KILOMETRES:Distance.UNITS_MILES; + Distance.Units distUnits = _distUnitsDropdown.getSelectedIndex()==0?Distance.Units.KILOMETRES:Distance.Units.MILES; String distUnitsStr = I18nManager.getText(_distUnitsDropdown.getSelectedIndex()==0?"units.kilometres.short":"units.miles.short"); String speedUnitsStr = I18nManager.getText(_distUnitsDropdown.getSelectedIndex()==0?"units.kmh":"units.mph"); if (_track == null || currentPoint == null) @@ -252,12 +252,13 @@ public class DetailsDisplay extends GenericDisplay { // use total distance and total time between neighbouring points long diff = nextPoint.getTimestamp().getSecondsSince(prevPoint.getTimestamp()); - if (diff < 1000) { + if (diff < 1000 && diff > 0) + { double rads = DataPoint.calculateRadiansBetween(prevPoint, currentPoint) + DataPoint.calculateRadiansBetween(currentPoint, nextPoint); double dist = Distance.convertRadiansToDistance(rads, distUnits); String speed = roundedNumber(3600 * dist / diff) + " " + speedUnitsStr; - _speedLabel.setText(I18nManager.getText("details.speed") + ": " + speed); + _speedLabel.setText(I18nManager.getText("fieldname.speed") + ": " + speed); } } } @@ -339,7 +340,7 @@ public class DetailsDisplay extends GenericDisplay _photoLabel.setText(I18nManager.getText("details.photofile") + ": " + currentPhoto.getFile().getName()); _photoLabel.setText(LABEL_POINT_TIMESTAMP + currentPhoto.getTimestamp().getText()); _photoConnectedLabel.setText(I18nManager.getText("details.photo.connected") + ": " - + (currentPhoto.getCurrentStatus() == PhotoStatus.NOT_CONNECTED ? + + (currentPhoto.getCurrentStatus() == Photo.Status.NOT_CONNECTED ? I18nManager.getText("dialog.about.no"):I18nManager.getText("dialog.about.yes"))); _photoThumbnail.setVisible(true); _photoThumbnail.setPhoto(currentPhoto); @@ -353,12 +354,12 @@ public class DetailsDisplay extends GenericDisplay * @param inFormat altitude format * @return language-sensitive string */ - private static String getAltitudeUnitsLabel(int inFormat) + private static String getAltitudeUnitsLabel(Altitude.Format inFormat) { if (inFormat == LABEL_POINT_ALTITUDE_FORMAT && LABEL_POINT_ALTITUDE_UNITS != null) return LABEL_POINT_ALTITUDE_UNITS; LABEL_POINT_ALTITUDE_FORMAT = inFormat; - if (inFormat == Altitude.FORMAT_METRES) + if (inFormat == Altitude.Format.METRES) return " " + I18nManager.getText("units.metres.short"); return " " + I18nManager.getText("units.feet.short"); } diff --git a/tim/prune/gui/GenericChart.java b/tim/prune/gui/GenericChart.java index 71455eb..731b91c 100644 --- a/tim/prune/gui/GenericChart.java +++ b/tim/prune/gui/GenericChart.java @@ -44,26 +44,29 @@ public abstract class GenericChart extends GenericDisplay implements MouseListen /** * Override paint method to draw map + * @param inG graphics object */ - public void paint(Graphics g) + public void paint(Graphics inG) { - super.paint(g); + super.paint(inG); int width = getWidth(); int height = getHeight(); // border background - g.setColor(COLOR_BORDER_BG); - g.fillRect(0, 0, width, height); + inG.setColor(COLOR_BORDER_BG); + inG.fillRect(0, 0, width, height); if (width < 2*BORDER_WIDTH || height < 2*BORDER_WIDTH) return; // blank graph area, with line border - g.setColor(COLOR_CHART_BG); - g.fillRect(BORDER_WIDTH, BORDER_WIDTH, width - 2*BORDER_WIDTH, height-2*BORDER_WIDTH); - g.setColor(COLOR_CHART_LINE); - g.drawRect(BORDER_WIDTH, BORDER_WIDTH, width - 2*BORDER_WIDTH, height-2*BORDER_WIDTH); + inG.setColor(COLOR_CHART_BG); + inG.fillRect(BORDER_WIDTH, BORDER_WIDTH, width - 2*BORDER_WIDTH, height-2*BORDER_WIDTH); // Display message if no data to be displayed if (_track == null || _track.getNumPoints() <= 0) { - g.setColor(COLOR_NODATA_TEXT); - g.drawString(I18nManager.getText("display.nodata"), 50, height/2); + inG.setColor(COLOR_NODATA_TEXT); + inG.drawString(I18nManager.getText("display.nodata"), 50, height/2); + } + else { + inG.setColor(COLOR_CHART_LINE); + inG.drawRect(BORDER_WIDTH, BORDER_WIDTH, width - 2*BORDER_WIDTH, height-2*BORDER_WIDTH); } } diff --git a/tim/prune/gui/MenuManager.java b/tim/prune/gui/MenuManager.java index e1c8cf0..7b256ba 100644 --- a/tim/prune/gui/MenuManager.java +++ b/tim/prune/gui/MenuManager.java @@ -5,7 +5,6 @@ import java.awt.event.ActionListener; import java.awt.event.InputEvent; import java.awt.event.KeyEvent; import javax.swing.JButton; -import javax.swing.JFrame; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; @@ -14,12 +13,15 @@ import javax.swing.KeyStroke; import tim.prune.App; import tim.prune.DataSubscriber; +import tim.prune.FunctionLibrary; +import tim.prune.GenericFunction; import tim.prune.I18nManager; -import tim.prune.browser.UrlGenerator; import tim.prune.data.PhotoList; import tim.prune.data.Selection; import tim.prune.data.Track; import tim.prune.data.TrackInfo; +import tim.prune.function.RearrangeWaypointsFunction.Rearrange; +import tim.prune.function.browser.UrlGenerator; /** * Class to manage the menu bar and tool bar, @@ -27,13 +29,13 @@ import tim.prune.data.TrackInfo; */ public class MenuManager implements DataSubscriber { - private JFrame _parent = null; private App _app = null; private Track _track = null; private Selection _selection = null; private PhotoList _photos = null; // Menu items which need enabling/disabling + private JMenuItem _sendGpsItem = null; private JMenuItem _saveItem = null; private JMenuItem _exportKmlItem = null; private JMenuItem _exportGpxItem = null; @@ -44,9 +46,10 @@ public class MenuManager implements DataSubscriber private JMenuItem _editWaypointNameItem = null; private JMenuItem _deletePointItem = null; private JMenuItem _deleteRangeItem = null; - private JMenuItem _deleteDuplicatesItem = null; private JMenuItem _compressItem = null; + private JMenuItem _deleteMarkedPointsItem = null; private JMenuItem _interpolateItem = null; + private JMenuItem _averageItem = null; private JMenuItem _selectAllItem = null; private JMenuItem _selectNoneItem = null; private JMenuItem _selectStartItem = null; @@ -58,6 +61,8 @@ public class MenuManager implements DataSubscriber private JMenuItem _cutAndMoveItem = null; private JMenuItem _show3dItem = null; private JMenu _browserMapMenu = null; + private JMenuItem _chartItem = null; + private JMenuItem _distanceItem = null; private JMenuItem _saveExifItem = null; private JMenuItem _connectPhotoItem = null; private JMenuItem _deletePhotoItem = null; @@ -89,13 +94,11 @@ public class MenuManager implements DataSubscriber /** * Constructor - * @param inParent parent object for dialogs * @param inApp application to call on menu actions * @param inTrackInfo track info object */ - public MenuManager(JFrame inParent, App inApp, TrackInfo inTrackInfo) + public MenuManager(App inApp, TrackInfo inTrackInfo) { - _parent = inParent; _app = inApp; _track = inTrackInfo.getTrack(); _selection = inTrackInfo.getSelection(); @@ -132,15 +135,26 @@ public class MenuManager implements DataSubscriber }; addPhotosMenuItem.addActionListener(_addPhotoAction); fileMenu.add(addPhotosMenuItem); - // Add photos - JMenuItem loadFromGpsMenuItem = new JMenuItem(I18nManager.getText("menu.file.loadfromgps")); + fileMenu.addSeparator(); + // Load from GPS + JMenuItem loadFromGpsMenuItem = makeMenuItem(FunctionLibrary.FUNCTION_GPSLOAD); loadFromGpsMenuItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { - _app.beginLoadFromGps(); + FunctionLibrary.FUNCTION_GPSLOAD.begin(); } }); fileMenu.add(loadFromGpsMenuItem); + // Save to GPS + _sendGpsItem = makeMenuItem(FunctionLibrary.FUNCTION_GPSSAVE); + _sendGpsItem.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) + { + FunctionLibrary.FUNCTION_GPSSAVE.begin(); + } + }); + _sendGpsItem.setEnabled(false); + fileMenu.add(_sendGpsItem); fileMenu.addSeparator(); // Save _saveItem = new JMenuItem(I18nManager.getText("menu.file.save"), KeyEvent.VK_S); @@ -154,31 +168,31 @@ public class MenuManager implements DataSubscriber _saveItem.setEnabled(false); fileMenu.add(_saveItem); // Export - Kml - _exportKmlItem = new JMenuItem(I18nManager.getText("menu.file.exportkml")); + _exportKmlItem = makeMenuItem(FunctionLibrary.FUNCTION_KMLEXPORT); _exportKmlItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { - _app.exportKml(); + FunctionLibrary.FUNCTION_KMLEXPORT.begin(); } }); _exportKmlItem.setEnabled(false); fileMenu.add(_exportKmlItem); // Gpx - _exportGpxItem = new JMenuItem(I18nManager.getText("menu.file.exportgpx")); + _exportGpxItem = makeMenuItem(FunctionLibrary.FUNCTION_GPXEXPORT); _exportGpxItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { - _app.exportGpx(); + FunctionLibrary.FUNCTION_GPXEXPORT.begin(); } }); _exportGpxItem.setEnabled(false); fileMenu.add(_exportGpxItem); // Pov - _exportPovItem = new JMenuItem(I18nManager.getText("menu.file.exportpov")); + _exportPovItem = makeMenuItem(FunctionLibrary.FUNCTION_POVEXPORT); _exportPovItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { - _app.exportPov(); + FunctionLibrary.FUNCTION_POVEXPORT.begin(); } }); _exportPovItem.setEnabled(false); @@ -255,24 +269,25 @@ public class MenuManager implements DataSubscriber _deleteRangeItem.addActionListener(_deleteRangeAction); _deleteRangeItem.setEnabled(false); editMenu.add(_deleteRangeItem); - _deleteDuplicatesItem = new JMenuItem(I18nManager.getText("menu.edit.deleteduplicates")); - _deleteDuplicatesItem.addActionListener(new ActionListener() { + editMenu.addSeparator(); + _compressItem = makeMenuItem(FunctionLibrary.FUNCTION_COMPRESS); + _compressItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { - _app.deleteDuplicates(); + FunctionLibrary.FUNCTION_COMPRESS.begin(); } }); - _deleteDuplicatesItem.setEnabled(false); - editMenu.add(_deleteDuplicatesItem); - _compressItem = new JMenuItem(I18nManager.getText("menu.edit.compress")); - _compressItem.addActionListener(new ActionListener() { + _compressItem.setEnabled(false); + editMenu.add(_compressItem); + _deleteMarkedPointsItem = new JMenuItem(I18nManager.getText("menu.edit.deletemarked")); + _deleteMarkedPointsItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { - _app.compressTrack(); + _app.finishCompressTrack(); } }); - _compressItem.setEnabled(false); - editMenu.add(_compressItem); + _deleteMarkedPointsItem.setEnabled(false); + editMenu.add(_deleteMarkedPointsItem); editMenu.addSeparator(); _interpolateItem = new JMenuItem(I18nManager.getText("menu.edit.interpolate")); _interpolateItem.addActionListener(new ActionListener() { @@ -283,6 +298,15 @@ public class MenuManager implements DataSubscriber }); _interpolateItem.setEnabled(false); editMenu.add(_interpolateItem); + _averageItem = new JMenuItem(I18nManager.getText("menu.edit.average")); + _averageItem.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) + { + _app.averageSelection(); + } + }); + _averageItem.setEnabled(false); + editMenu.add(_averageItem); _reverseItem = new JMenuItem(I18nManager.getText("menu.edit.reverse")); _reverseItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) @@ -292,11 +316,11 @@ public class MenuManager implements DataSubscriber }); _reverseItem.setEnabled(false); editMenu.add(_reverseItem); - _addTimeOffsetItem = new JMenuItem(I18nManager.getText("menu.edit.addtimeoffset")); + _addTimeOffsetItem = makeMenuItem(FunctionLibrary.FUNCTION_ADD_TIME_OFFSET); _addTimeOffsetItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { - _app.beginAddTimeOffset(); + FunctionLibrary.FUNCTION_ADD_TIME_OFFSET.begin(); } }); _addTimeOffsetItem.setEnabled(false); @@ -317,7 +341,7 @@ public class MenuManager implements DataSubscriber rearrangeStartItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { - _app.rearrangeWaypoints(App.REARRANGE_TO_START); + FunctionLibrary.FUNCTION_REARRANGE_WAYPOINTS.rearrangeWaypoints(Rearrange.TO_START); } }); rearrangeStartItem.setEnabled(true); @@ -326,7 +350,7 @@ public class MenuManager implements DataSubscriber rearrangeEndItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { - _app.rearrangeWaypoints(App.REARRANGE_TO_END); + FunctionLibrary.FUNCTION_REARRANGE_WAYPOINTS.rearrangeWaypoints(Rearrange.TO_END); } }); rearrangeEndItem.setEnabled(true); @@ -335,7 +359,7 @@ public class MenuManager implements DataSubscriber rearrangeNearestItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { - _app.rearrangeWaypoints(App.REARRANGE_TO_NEAREST); + FunctionLibrary.FUNCTION_REARRANGE_WAYPOINTS.rearrangeWaypoints(Rearrange.TO_NEAREST); } }); rearrangeNearestItem.setEnabled(true); @@ -397,11 +421,11 @@ public class MenuManager implements DataSubscriber // Add view menu JMenu viewMenu = new JMenu(I18nManager.getText("menu.view")); - _show3dItem = new JMenuItem(I18nManager.getText("menu.view.show3d")); + _show3dItem = makeMenuItem(FunctionLibrary.FUNCTION_3D); _show3dItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { - _app.show3dWindow(); + FunctionLibrary.FUNCTION_3D.begin(); } }); _show3dItem.setEnabled(false); @@ -425,7 +449,50 @@ public class MenuManager implements DataSubscriber } }); _browserMapMenu.add(openMapsItem); + JMenuItem mapquestMapsItem = new JMenuItem(I18nManager.getText("menu.view.browser.mapquest")); + mapquestMapsItem.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) + { + _app.showExternalMap(UrlGenerator.MAP_SOURCE_MAPQUEST); + } + }); + _browserMapMenu.add(mapquestMapsItem); + JMenuItem yahooMapsItem = new JMenuItem(I18nManager.getText("menu.view.browser.yahoo")); + yahooMapsItem.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) + { + _app.showExternalMap(UrlGenerator.MAP_SOURCE_YAHOO); + } + }); + _browserMapMenu.add(yahooMapsItem); viewMenu.add(_browserMapMenu); + // Charts + _chartItem = makeMenuItem(FunctionLibrary.FUNCTION_CHARTS); + _chartItem.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) + { + FunctionLibrary.FUNCTION_CHARTS.begin(); + } + }); + _chartItem.setEnabled(false); + viewMenu.add(_chartItem); + // Distances + _distanceItem = makeMenuItem(FunctionLibrary.FUNCTION_DISTANCES); + _distanceItem.setEnabled(false); + _distanceItem.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + FunctionLibrary.FUNCTION_DISTANCES.begin(); + } + }); + viewMenu.add(_distanceItem); + // Set the map background + JMenuItem mapBgItem = makeMenuItem(FunctionLibrary.FUNCTION_SET_MAP_BG); + mapBgItem.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent arg0) { + FunctionLibrary.FUNCTION_SET_MAP_BG.begin(); + } + }); + viewMenu.add(mapBgItem); menubar.add(viewMenu); // Add photo menu @@ -474,11 +541,11 @@ public class MenuManager implements DataSubscriber photoMenu.add(_deletePhotoItem); photoMenu.addSeparator(); // correlate all photos - _correlatePhotosItem = new JMenuItem(I18nManager.getText("menu.photo.correlate")); + _correlatePhotosItem = makeMenuItem(FunctionLibrary.FUNCTION_CORRELATE_PHOTOS); _correlatePhotosItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { - _app.beginCorrelatePhotos(); + FunctionLibrary.FUNCTION_CORRELATE_PHOTOS.begin(); } }); _correlatePhotosItem.setEnabled(false); @@ -487,27 +554,27 @@ public class MenuManager implements DataSubscriber // Help menu JMenu helpMenu = new JMenu(I18nManager.getText("menu.help")); - JMenuItem helpItem = new JMenuItem(I18nManager.getText("menu.help")); + JMenuItem helpItem = makeMenuItem(FunctionLibrary.FUNCTION_HELP); helpItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { - _app.showHelp(); + FunctionLibrary.FUNCTION_HELP.begin(); } }); helpMenu.add(helpItem); - JMenuItem aboutItem = new JMenuItem(I18nManager.getText("menu.help.about")); + JMenuItem aboutItem = makeMenuItem(FunctionLibrary.FUNCTION_ABOUT); aboutItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { - new AboutScreen(_parent).show(); + FunctionLibrary.FUNCTION_ABOUT.begin(); } }); helpMenu.add(aboutItem); - JMenuItem checkVersionItem = new JMenuItem(I18nManager.getText("menu.help.checkversion")); + JMenuItem checkVersionItem = makeMenuItem(FunctionLibrary.FUNCTION_CHECK_VERSION); checkVersionItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { - CheckVersionScreen.show(_parent); + FunctionLibrary.FUNCTION_CHECK_VERSION.begin(); } }); helpMenu.add(checkVersionItem); @@ -516,6 +583,15 @@ public class MenuManager implements DataSubscriber return menubar; } + /** + * Convenience method for making a menu item using a function + * @param inFunction function + * @return menu item using localized name of function + */ + private static JMenuItem makeMenuItem(GenericFunction inFunction) + { + return new JMenuItem(I18nManager.getText(inFunction.getNameKey())); + } /** * Create a JToolBar containing all toolbar buttons @@ -592,10 +668,11 @@ public class MenuManager implements DataSubscriber public void informFileLoaded() { // save, undo, delete enabled + _sendGpsItem.setEnabled(true); _saveItem.setEnabled(true); _undoItem.setEnabled(true); - _deleteDuplicatesItem.setEnabled(true); _compressItem.setEnabled(true); + _deleteMarkedPointsItem.setEnabled(false); } @@ -606,19 +683,21 @@ public class MenuManager implements DataSubscriber { boolean hasData = (_track != null && _track.getNumPoints() > 0); // set functions which require data + _sendGpsItem.setEnabled(hasData); _saveItem.setEnabled(hasData); _saveButton.setEnabled(hasData); _exportKmlItem.setEnabled(hasData); _exportGpxItem.setEnabled(hasData); _exportPovItem.setEnabled(hasData); - _deleteDuplicatesItem.setEnabled(hasData); _compressItem.setEnabled(hasData); + _deleteMarkedPointsItem.setEnabled(hasData && _track.hasMarkedPoints()); _rearrangeMenu.setEnabled(hasData && _track.hasMixedData()); _selectAllItem.setEnabled(hasData); _selectNoneItem.setEnabled(hasData); - if (_show3dItem != null) - _show3dItem.setEnabled(hasData); + _show3dItem.setEnabled(hasData); + _chartItem.setEnabled(hasData); _browserMapMenu.setEnabled(hasData); + _distanceItem.setEnabled(hasData); // is undo available? boolean hasUndo = !_app.getUndoStack().isEmpty(); _undoItem.setEnabled(hasUndo); @@ -655,6 +734,7 @@ public class MenuManager implements DataSubscriber _deleteRangeButton.setEnabled(hasRange); _interpolateItem.setEnabled(hasRange && (_selection.getEnd() - _selection.getStart()) == 1); + _averageItem.setEnabled(hasRange); _mergeSegmentsItem.setEnabled(hasRange); _reverseItem.setEnabled(hasRange); _addTimeOffsetItem.setEnabled(hasRange); diff --git a/tim/prune/gui/PhotoThumbnail.java b/tim/prune/gui/PhotoThumbnail.java index 6293891..2ad22fa 100644 --- a/tim/prune/gui/PhotoThumbnail.java +++ b/tim/prune/gui/PhotoThumbnail.java @@ -21,7 +21,8 @@ public class PhotoThumbnail extends JPanel implements Runnable private int _lastWidth = -1; private int _lastHeight = -1; private boolean _loadingImage = false; - private static String _loadingString = null; + /** String to show before photo is loaded */ + private static final String _loadingString = I18nManager.getText("details.photo.loading") + " ..."; /** @@ -31,7 +32,6 @@ public class PhotoThumbnail extends JPanel implements Runnable { // TODO: Make size of thumbnail dynamic, as big as it can be setOpaque(true); - _loadingString = I18nManager.getText("details.photo.loading") + " ..."; } diff --git a/tim/prune/gui/ProfileChart.java b/tim/prune/gui/ProfileChart.java index 22724b5..a0adfdb 100644 --- a/tim/prune/gui/ProfileChart.java +++ b/tim/prune/gui/ProfileChart.java @@ -6,6 +6,7 @@ import java.awt.Graphics; import java.awt.event.MouseEvent; import tim.prune.I18nManager; +import tim.prune.data.Altitude; import tim.prune.data.AltitudeRange; import tim.prune.data.Track; import tim.prune.data.TrackInfo; @@ -86,28 +87,33 @@ public class ProfileChart extends GenericChart } } - // loop through points - int chartFormat = altitudeRange.getFormat(); - for (int p = 0; p < numPoints; p++) + try { - int x = (int) (_xScaleFactor * p); - if (p == selectedPoint) + // loop through points + Altitude.Format chartFormat = altitudeRange.getFormat(); + for (int p = 0; p < numPoints; p++) { - g.setColor(COLOR_SELECTED_BG); - g.fillRect(BORDER_WIDTH + x, BORDER_WIDTH+1, barWidth, height-2*BORDER_WIDTH-2); - g.setColor(COLOR_SELECTED); - } - else - { - g.setColor(COLOR_ALT_BARS); - } - if (_track.getPoint(p).getAltitude().isValid()) - { - altitude = _track.getPoint(p).getAltitude().getValue(chartFormat); - y = (int) (yScaleFactor * (altitude - minAltitude)); - g.fillRect(BORDER_WIDTH+x, height-BORDER_WIDTH - y, barWidth, y); + int x = (int) (_xScaleFactor * p); + if (p == selectedPoint) + { + g.setColor(COLOR_SELECTED_BG); + g.fillRect(BORDER_WIDTH + x, BORDER_WIDTH+1, barWidth, height-2*BORDER_WIDTH-2); + g.setColor(COLOR_SELECTED); + } + else + { + g.setColor(COLOR_ALT_BARS); + } + if (_track.getPoint(p).getAltitude().isValid()) + { + altitude = _track.getPoint(p).getAltitude().getValue(chartFormat); + y = (int) (yScaleFactor * (altitude - minAltitude)); + g.fillRect(BORDER_WIDTH+x, height-BORDER_WIDTH - y, barWidth, y); + } } } + catch (NullPointerException npe) { // ignore, probably due to data being changed + } // Draw numbers on top of the graph to mark scale if (lineScale > 1) { diff --git a/tim/prune/gui/UndoManager.java b/tim/prune/gui/UndoManager.java index 46a1c8d..1b77fe1 100644 --- a/tim/prune/gui/UndoManager.java +++ b/tim/prune/gui/UndoManager.java @@ -44,13 +44,13 @@ public class UndoManager JPanel mainPanel = new JPanel(); mainPanel.setLayout(new BorderLayout(3, 3)); mainPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - Stack undoStack = inApp.getUndoStack(); + Stack undoStack = inApp.getUndoStack(); mainPanel.add(new JLabel(I18nManager.getText("dialog.undo.pretext")), BorderLayout.NORTH); String[] undoActions = new String[undoStack.size()]; for (int i=0; i _waypoints = null; /** * Constructor giving Track object @@ -21,7 +21,7 @@ public class WaypointListModel extends AbstractListModel public WaypointListModel(Track inTrack) { _track = inTrack; - _waypoints = new ArrayList(); + _waypoints = new ArrayList(); _track.getWaypoints(_waypoints); } @@ -38,7 +38,7 @@ public class WaypointListModel extends AbstractListModel */ public Object getElementAt(int inIndex) { - return ((DataPoint)_waypoints.get(inIndex)).getWaypointName(); + return _waypoints.get(inIndex).getWaypointName(); } /** @@ -48,7 +48,7 @@ public class WaypointListModel extends AbstractListModel */ public DataPoint getWaypoint(int inIndex) { - return (DataPoint) _waypoints.get(inIndex); + return _waypoints.get(inIndex); } /** diff --git a/tim/prune/gui/WholeNumberField.java b/tim/prune/gui/WholeNumberField.java index dcf6740..9a35280 100644 --- a/tim/prune/gui/WholeNumberField.java +++ b/tim/prune/gui/WholeNumberField.java @@ -13,7 +13,7 @@ public class WholeNumberField extends JTextField /** * Inner class to act as document for validation */ - protected class WholeNumberDocument extends PlainDocument + protected static class WholeNumberDocument extends PlainDocument { /** Num digits to allow */ private int _maxDigits = 0; diff --git a/tim/prune/gui/map/MapCanvas.java b/tim/prune/gui/map/MapCanvas.java index e6236cd..a8df86e 100644 --- a/tim/prune/gui/map/MapCanvas.java +++ b/tim/prune/gui/map/MapCanvas.java @@ -27,7 +27,6 @@ import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JMenuItem; -import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JPopupMenu; import javax.swing.JSlider; @@ -36,6 +35,7 @@ import javax.swing.event.ChangeListener; import tim.prune.App; import tim.prune.DataSubscriber; +import tim.prune.FunctionLibrary; import tim.prune.I18nManager; import tim.prune.data.DoubleRange; import tim.prune.data.Selection; @@ -109,7 +109,9 @@ public class MapCanvas extends JPanel implements MouseListener, MouseMotionListe // Colours private static final Color COLOR_BG = Color.WHITE; + private static final Color COLOR_MESSAGES = Color.GRAY; private static final Color COLOR_POINT = Color.BLUE; + private static final Color COLOR_POINT_DELETED = Color.RED; private static final Color COLOR_CURR_RANGE = Color.GREEN; private static final Color COLOR_CROSSHAIRS = Color.RED; private static final Color COLOR_WAYPT_NAME = Color.BLACK; @@ -264,6 +266,16 @@ public class MapCanvas extends JPanel implements MouseListener, MouseMotionListe }}); zoomFullItem.setEnabled(true); _popup.add(zoomFullItem); + _popup.addSeparator(); + // Set background + JMenuItem setMapBgItem = new JMenuItem( + I18nManager.getText(FunctionLibrary.FUNCTION_SET_MAP_BG.getNameKey())); + setMapBgItem.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) + { + FunctionLibrary.FUNCTION_SET_MAP_BG.begin(); + }}); + _popup.add(setMapBgItem); // new point option JMenuItem newPointItem = new JMenuItem(I18nManager.getText("menu.map.newpoint")); newPointItem.addActionListener(new ActionListener() { @@ -309,10 +321,10 @@ public class MapCanvas extends JPanel implements MouseListener, MouseMotionListe if (_autopanCheckBox.isSelected()) { int selectedPoint = _selection.getCurrentPointIndex(); - if (selectedPoint > 0 && _dragFromX == -1 && selectedPoint != _prevSelectedPoint) + if (selectedPoint >= 0 && _dragFromX == -1 && selectedPoint != _prevSelectedPoint) { - int px = getWidth() / 2 + _mapPosition.getXFromCentre(_track.getXNew(selectedPoint)); - int py = getHeight() / 2 + _mapPosition.getYFromCentre(_track.getYNew(selectedPoint)); + int px = getWidth() / 2 + _mapPosition.getXFromCentre(_track.getX(selectedPoint)); + int py = getHeight() / 2 + _mapPosition.getYFromCentre(_track.getY(selectedPoint)); int panX = 0; int panY = 0; if (px < PAN_DISTANCE) { @@ -356,7 +368,7 @@ public class MapCanvas extends JPanel implements MouseListener, MouseMotionListe { inG.setColor(COLOR_BG); inG.fillRect(0, 0, getWidth(), getHeight()); - inG.setColor(Color.GRAY); + inG.setColor(COLOR_MESSAGES); inG.drawString(I18nManager.getText("display.nodata"), 50, getHeight()/2); } // Draw slider etc on top @@ -391,63 +403,117 @@ public class MapCanvas extends JPanel implements MouseListener, MouseMotionListe boolean loadingFailed = false; if (_mapImage == null) return; - // Loop over tiles drawing each one - int[] tileIndices = _mapPosition.getTileIndices(getWidth(), getHeight()); - int[] pixelOffsets = _mapPosition.getDisplayOffsets(getWidth(), getHeight()); - for (int tileX = tileIndices[0]; tileX <= tileIndices[1] && !loadingFailed; tileX++) + if (_tileCacher.isOverzoomed()) { - int x = (tileX - tileIndices[0]) * 256 - pixelOffsets[0]; - for (int tileY = tileIndices[2]; tileY <= tileIndices[3]; tileY++) + // display overzoom message + g.setColor(COLOR_MESSAGES); + g.drawString(I18nManager.getText("map.overzoom"), 50, getHeight()/2); + } + else + { + // Loop over tiles drawing each one + int[] tileIndices = _mapPosition.getTileIndices(getWidth(), getHeight()); + int[] pixelOffsets = _mapPosition.getDisplayOffsets(getWidth(), getHeight()); + for (int tileX = tileIndices[0]; tileX <= tileIndices[1] && !loadingFailed; tileX++) { - int y = (tileY - tileIndices[2]) * 256 - pixelOffsets[1]; - Image image = _tileCacher.getTile(tileX, tileY); - if (image != null) { - g.drawImage(image, x, y, 256, 256, null); + int x = (tileX - tileIndices[0]) * 256 - pixelOffsets[0]; + for (int tileY = tileIndices[2]; tileY <= tileIndices[3]; tileY++) + { + int y = (tileY - tileIndices[2]) * 256 - pixelOffsets[1]; + Image image = _tileCacher.getTile(tileX, tileY); + if (image != null) { + g.drawImage(image, x, y, 256, 256, null); + } } } - } - // Make maps brighter / fainter - float[] scaleFactors = {1.0f, 1.05f, 1.1f, 1.2f, 1.6f, 2.0f}; - float scaleFactor = scaleFactors[_transparencySlider.getValue()]; - if (scaleFactor > 1.0f) { - RenderingHints hints = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF); - hints.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); - RescaleOp op = new RescaleOp(scaleFactor, 0, hints); - op.filter(_mapImage, _mapImage); + // Make maps brighter / fainter + float[] scaleFactors = {1.0f, 1.05f, 1.1f, 1.2f, 1.6f, 2.0f}; + float scaleFactor = scaleFactors[_transparencySlider.getValue()]; + if (scaleFactor > 1.0f) { + RenderingHints hints = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF); + hints.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); + RescaleOp op = new RescaleOp(scaleFactor, 0, hints); + op.filter(_mapImage, _mapImage); + } } } + // Paint the track points on top + int pointsPainted = 1; + try + { + pointsPainted = paintPoints(g); + } + catch (NullPointerException npe) { // ignore, probably due to data being changed during drawing + } + + // free g + g.dispose(); + + _recalculate = false; + // Zoom to fit if no points found + if (pointsPainted <= 0 && _checkBounds) { + zoomToFit(); + _recalculate = true; + repaint(); + } + _checkBounds = false; + // enable / disable transparency slider + _transparencySlider.setEnabled(_mapCheckBox.isSelected()); + } + + + /** + * Paint the points using the given graphics object + * @param inG Graphics object to use for painting + * @return number of points painted, if any + */ + private int paintPoints(Graphics inG) + { int pointsPainted = 0; // draw track points - g.setColor(COLOR_POINT); + inG.setColor(COLOR_POINT); int prevX = -1, prevY = -1; boolean connectPoints = _connectCheckBox.isSelected(); + boolean prevPointVisible = false, currPointVisible = false; for (int i=0; i<_track.getNumPoints(); i++) { - int px = getWidth() / 2 + _mapPosition.getXFromCentre(_track.getXNew(i)); - int py = getHeight() / 2 + _mapPosition.getYFromCentre(_track.getYNew(i)); - if (px >= 0 && px < getWidth() && py >= 0 && py < getHeight()) + int px = getWidth() / 2 + _mapPosition.getXFromCentre(_track.getX(i)); + int py = getHeight() / 2 + _mapPosition.getYFromCentre(_track.getY(i)); + currPointVisible = px >= 0 && px < getWidth() && py >= 0 && py < getHeight(); + if (currPointVisible) { if (!_track.getPoint(i).isWaypoint()) { - g.drawRect(px-2, py-2, 3, 3); - // Connect track points - if (connectPoints && prevX != -1 && prevY != -1 && !_track.getPoint(i).getSegmentStart()) { - g.drawLine(prevX, prevY, px, py); + // Draw rectangle for track point + if (_track.getPoint(i).getDeleteFlag()) { + inG.setColor(COLOR_POINT_DELETED); } + else { + inG.setColor(COLOR_POINT); + } + inG.drawRect(px-2, py-2, 3, 3); pointsPainted++; - prevX = px; prevY = py; } } - else { - prevX = -1; prevY = -1; + if (!_track.getPoint(i).isWaypoint()) + { + // Connect track points if either of them are visible + if (connectPoints && (currPointVisible || prevPointVisible) + && !(prevX == -1 && prevY == -1) + && !_track.getPoint(i).getSegmentStart()) + { + inG.drawLine(prevX, prevY, px, py); + } + prevX = px; prevY = py; } + prevPointVisible = currPointVisible; } // Loop over points, just drawing blobs for waypoints - g.setColor(COLOR_WAYPT_NAME); - FontMetrics fm = g.getFontMetrics(); + inG.setColor(COLOR_WAYPT_NAME); + FontMetrics fm = inG.getFontMetrics(); int nameHeight = fm.getHeight(); int width = getWidth(); int height = getHeight(); @@ -455,11 +521,11 @@ public class MapCanvas extends JPanel implements MouseListener, MouseMotionListe { if (_track.getPoint(i).isWaypoint()) { - int px = getWidth() / 2 + _mapPosition.getXFromCentre(_track.getXNew(i)); - int py = getHeight() / 2 + _mapPosition.getYFromCentre(_track.getYNew(i)); + int px = getWidth() / 2 + _mapPosition.getXFromCentre(_track.getX(i)); + int py = getHeight() / 2 + _mapPosition.getYFromCentre(_track.getY(i)); if (px >= 0 && px < getWidth() && py >= 0 && py < getHeight()) { - g.fillRect(px-3, py-3, 6, 6); + inG.fillRect(px-3, py-3, 6, 6); pointsPainted++; } } @@ -469,8 +535,8 @@ public class MapCanvas extends JPanel implements MouseListener, MouseMotionListe { if (_track.getPoint(i).isWaypoint()) { - int px = getWidth() / 2 + _mapPosition.getXFromCentre(_track.getXNew(i)); - int py = getHeight() / 2 + _mapPosition.getYFromCentre(_track.getYNew(i)); + int px = getWidth() / 2 + _mapPosition.getXFromCentre(_track.getX(i)); + int py = getHeight() / 2 + _mapPosition.getYFromCentre(_track.getY(i)); if (px >= 0 && px < getWidth() && py >= 0 && py < getHeight()) { // Figure out where to draw waypoint name so it doesn't obscure track @@ -493,7 +559,7 @@ public class MapCanvas extends JPanel implements MouseListener, MouseMotionListe && !overlapsPoints(nameXs[a], nameYs[a], nameWidth, nameHeight)) { // Found a rectangle to fit - draw name here and quit - g.drawString(waypointName, nameXs[a], nameYs[a]); + inG.drawString(waypointName, nameXs[a], nameYs[a]); drawnName = true; break; } @@ -503,17 +569,17 @@ public class MapCanvas extends JPanel implements MouseListener, MouseMotionListe } } // Loop over points, drawing blobs for photo points - g.setColor(COLOR_PHOTO_PT); + inG.setColor(COLOR_PHOTO_PT); for (int i=0; i<_track.getNumPoints(); i++) { if (_track.getPoint(i).getPhoto() != null) { - int px = getWidth() / 2 + _mapPosition.getXFromCentre(_track.getXNew(i)); - int py = getHeight() / 2 + _mapPosition.getYFromCentre(_track.getYNew(i)); + int px = getWidth() / 2 + _mapPosition.getXFromCentre(_track.getX(i)); + int py = getHeight() / 2 + _mapPosition.getYFromCentre(_track.getY(i)); if (px >= 0 && px < getWidth() && py >= 0 && py < getHeight()) { - g.drawRect(px-1, py-1, 2, 2); - g.drawRect(px-2, py-2, 4, 4); + inG.drawRect(px-1, py-1, 2, 2); + inG.drawRect(px-2, py-2, 4, 4); pointsPainted++; } } @@ -522,12 +588,12 @@ public class MapCanvas extends JPanel implements MouseListener, MouseMotionListe // Draw selected range if (_selection.hasRangeSelected()) { - g.setColor(COLOR_CURR_RANGE); + inG.setColor(COLOR_CURR_RANGE); for (int i=_selection.getStart(); i<=_selection.getEnd(); i++) { - int px = getWidth() / 2 + _mapPosition.getXFromCentre(_track.getXNew(i)); - int py = getHeight() / 2 + _mapPosition.getYFromCentre(_track.getYNew(i)); - g.drawRect(px-1, py-1, 2, 2); + int px = getWidth() / 2 + _mapPosition.getXFromCentre(_track.getX(i)); + int py = getHeight() / 2 + _mapPosition.getYFromCentre(_track.getY(i)); + inG.drawRect(px-1, py-1, 2, 2); } } @@ -535,30 +601,18 @@ public class MapCanvas extends JPanel implements MouseListener, MouseMotionListe int selectedPoint = _selection.getCurrentPointIndex(); if (selectedPoint >= 0) { - int px = getWidth() / 2 + _mapPosition.getXFromCentre(_track.getXNew(selectedPoint)); - int py = getHeight() / 2 + _mapPosition.getYFromCentre(_track.getYNew(selectedPoint)); - g.setColor(COLOR_CROSSHAIRS); + int px = getWidth() / 2 + _mapPosition.getXFromCentre(_track.getX(selectedPoint)); + int py = getHeight() / 2 + _mapPosition.getYFromCentre(_track.getY(selectedPoint)); + inG.setColor(COLOR_CROSSHAIRS); // crosshairs - g.drawLine(px, 0, px, getHeight()); - g.drawLine(0, py, getWidth(), py); + inG.drawLine(px, 0, px, getHeight()); + inG.drawLine(0, py, getWidth(), py); // oval - g.drawOval(px - 2, py - 2, 4, 4); - g.drawOval(px - 3, py - 3, 6, 6); - } - - // free g - g.dispose(); - - _recalculate = false; - // Zoom to fit if no points found - if (pointsPainted <= 0 && _checkBounds) { - zoomToFit(); - _recalculate = true; - repaint(); + inG.drawOval(px - 2, py - 2, 4, 4); + inG.drawOval(px - 3, py - 3, 6, 6); } - _checkBounds = false; - // enable / disable transparency slider - _transparencySlider.setEnabled(_mapCheckBox.isSelected()); + // Return the number of points painted + return pointsPainted; } @@ -601,22 +655,19 @@ public class MapCanvas extends JPanel implements MouseListener, MouseMotionListe /** * Inform that tiles have been updated and the map can be repainted - * @param isOK true if data loaded ok, false for error + * @param inIsOk true if data loaded ok, false for error */ public synchronized void tilesUpdated(boolean inIsOk) { // Show message if loading failed (but not too many times) - if (!inIsOk && !_shownOsmErrorAlready) + if (!inIsOk && !_shownOsmErrorAlready && _mapCheckBox.isSelected()) { _shownOsmErrorAlready = true; // use separate thread to show message about failing to load osm images new Thread(new Runnable() { public void run() { try {Thread.sleep(500);} catch (InterruptedException ie) {} - JOptionPane.showMessageDialog(MapCanvas.this, - I18nManager.getText("error.osmimage.failed"), - I18nManager.getText("error.osmimage.dialogtitle"), - JOptionPane.ERROR_MESSAGE); + _app.showErrorMessage("error.osmimage.dialogtitle", "error.osmimage.failed"); } }).start(); } @@ -685,7 +736,7 @@ public class MapCanvas extends JPanel implements MouseListener, MouseMotionListe // select point if it's a left-click if (!inE.isMetaDown()) { - int pointIndex = _track.getNearestPointIndexNew( + int pointIndex = _track.getNearestPointIndex( _mapPosition.getXFromPixels(inE.getX(), getWidth()), _mapPosition.getYFromPixels(inE.getY(), getHeight()), _mapPosition.getBoundsFromPixels(CLICK_SENSITIVITY), false); @@ -806,6 +857,9 @@ public class MapCanvas extends JPanel implements MouseListener, MouseMotionListe if ((inUpdateType & DataSubscriber.DATA_ADDED_OR_REMOVED) > 0) { _checkBounds = true; } + if ((inUpdateType & DataSubscriber.MAPSERVER_CHANGED) > 0) { + _tileCacher.setTileConfig(new MapTileConfig()); + } repaint(); // enable or disable components boolean hasData = _track.getNumPoints() > 0; diff --git a/tim/prune/gui/map/MapPosition.java b/tim/prune/gui/map/MapPosition.java index 73c7ed9..d035f10 100644 --- a/tim/prune/gui/map/MapPosition.java +++ b/tim/prune/gui/map/MapPosition.java @@ -13,10 +13,12 @@ public class MapPosition /** y position (scale depends on zoom) */ private long _yPosition = 0L; - /** Zoom level, from 2 to 15 */ + /** Zoom level, from 2 to max */ private int _zoom = 12; /** Factor to zoom by, 2 to the power of zoom */ private int _zoomFactor = 1 << _zoom; + /** Maximum zoom level */ + private static final int MAX_ZOOM = 21; /** @@ -35,7 +37,7 @@ public class MapPosition double diffY = Math.abs(inMaxY - inMinY); // Find out what zoom level to go to int requiredZoom = -1; - for (int currZoom = 15; currZoom >= 2; currZoom--) + for (int currZoom = MAX_ZOOM; currZoom >= 2; currZoom--) { if (transformToPixels(diffX, currZoom) < inWidth && transformToPixels(diffY, currZoom) < inHeight) @@ -69,7 +71,7 @@ public class MapPosition // Find out what zoom level to go to int requiredZoom = -1; int multFactor = 0; - for (int currZoom = 16; currZoom >= _zoom; currZoom--) + for (int currZoom = MAX_ZOOM; currZoom >= _zoom; currZoom--) { multFactor = 1 << (currZoom - _zoom); if ((diffX * multFactor) < inWidth && (diffY * multFactor) < inHeight) @@ -227,7 +229,7 @@ public class MapPosition */ public void zoomIn() { - if (_zoom < 16) + if (_zoom < MAX_ZOOM) { _zoom++; _zoomFactor = 1 << _zoom; diff --git a/tim/prune/gui/map/MapTileCacher.java b/tim/prune/gui/map/MapTileCacher.java index 50387dd..ea5b6fb 100644 --- a/tim/prune/gui/map/MapTileCacher.java +++ b/tim/prune/gui/map/MapTileCacher.java @@ -14,8 +14,6 @@ public class MapTileCacher implements ImageObserver { /** Parent to be informed of updates */ private MapCanvas _parent = null; - /** Default grid size */ - private static final int GRID_SIZE = 11; /** Array of images to hold tiles */ private Image[] _tiles = new Image[GRID_SIZE * GRID_SIZE]; /** Current zoom level */ @@ -28,6 +26,13 @@ public class MapTileCacher implements ImageObserver private int _gridCentreX = 0; /** Y coord of grid centre */ private int _gridCentreY = 0; + /** Tile configuration */ + private MapTileConfig _tileConfig = null; + + /** Grid size */ + private static final int GRID_SIZE = 11; + /** max zoom level of map tiles */ + private static final int MAX_TILE_ZOOM = 18; /** @@ -82,6 +87,7 @@ public class MapTileCacher implements ImageObserver */ public Image getTile(int inX, int inY) { + if (_tileConfig == null) {_tileConfig = new MapTileConfig();} int arrayIndex = getArrayIndex(inX, inY); Image image = _tiles[arrayIndex]; if (image != null) @@ -90,13 +96,17 @@ public class MapTileCacher implements ImageObserver return image; } + // Protect against zoom > max + if (isOverzoomed()) return null; + // Trigger load if not already triggered // Work out tile coords for URL int urlX = getUrlCoordinate(inX, _zoom); int urlY = getUrlCoordinate(inY, _zoom); try { - String url = "http://tile.openstreetmap.org/" + _zoom + "/" + urlX + "/" + urlY + ".png"; + // Use configured tile server + String url = _tileConfig.getUrl() + _zoom + "/" + urlX + "/" + urlY + ".png"; // Load image asynchronously, using observer image = Toolkit.getDefaultToolkit().createImage(new URL(url)); _tiles[arrayIndex] = image; @@ -106,6 +116,13 @@ public class MapTileCacher implements ImageObserver return null; } + /** + * @return true if zoom is too high for tiles + */ + public boolean isOverzoomed() + { + return (_zoom > MAX_TILE_ZOOM); + } /** * Get the array index for the given coordinates @@ -193,4 +210,14 @@ public class MapTileCacher implements ImageObserver } return !loaded; } + + /** + * Set or reset the tile config + * @param inConfig object containing tile config + */ + public void setTileConfig(MapTileConfig inConfig) + { + _tileConfig = inConfig; + clearAll(); + } } diff --git a/tim/prune/gui/map/MapTileConfig.java b/tim/prune/gui/map/MapTileConfig.java new file mode 100644 index 0000000..762baf4 --- /dev/null +++ b/tim/prune/gui/map/MapTileConfig.java @@ -0,0 +1,92 @@ +package tim.prune.gui.map; + +import java.net.MalformedURLException; +import java.net.URL; + +import tim.prune.Config; + +/** + * Class to hold the config for the map tiles + * and retrieve the correct URL prefix + */ +public class MapTileConfig +{ + /** Index of map server */ + private int _index = 0; + /** Url for other */ + private String _url = null; + + /** server urls for known maps */ + private static final String[] SERVER_URLS = { + "http://tile.openstreetmap.org/", // mapnik + "http://tah.openstreetmap.org/Tiles/tile/", // osma + "http://andy.sandbox.cloudmade.com/tiles/cycle/" // cyclemap + }; + /** Index of 'other' server with freeform url */ + private static final int OTHER_SERVER_NUM = 3; + + + /** + * Default constructor using Config + */ + public MapTileConfig() + { + _index = Config.getMapServerIndex(); + _url = fixUrl(Config.getMapServerUrl()); + // reset index wrong or if other url too short + if (_index < 0 || _index > OTHER_SERVER_NUM || + (_index == OTHER_SERVER_NUM && (_url == null || _url.length() < 5))) + { + _index = 0; + } + } + + /** + * @return url + */ + public String getUrl() + { + if (_index == OTHER_SERVER_NUM) {return _url;} + return SERVER_URLS[_index]; + } + + /** + * Checks the given url for having the right prefix and trailing slash + * @param inUrl url to check + * @return validated url with correct prefix and trailing slash, or null + */ + private static String fixUrl(String inUrl) + { + if (inUrl == null || inUrl.equals("")) {return null;} + String url = inUrl; + // check prefix + try { + new URL(url); + } + catch (MalformedURLException e) { + // add the http protocol + url = "http://" + url; + } + // check trailing / + if (!url.endsWith("/")) { + url = url + "/"; + } + return url; + } + + /** + * @param inOther other config object + * @return true if the objects are exactly the same + */ + public boolean equals(MapTileConfig inOther) + { + // Other object must be non-null and must have same index + if (inOther == null || inOther._index != _index) {return false;} + // Check url if other selected + if (_index == OTHER_SERVER_NUM) { + return inOther._url.equals(_url); + } + // Not other so must match + return true; + } +} diff --git a/tim/prune/lang/prune-texts_de.properties b/tim/prune/lang/prune-texts_de.properties index d01a872..81b2b78 100644 --- a/tim/prune/lang/prune-texts_de.properties +++ b/tim/prune/lang/prune-texts_de.properties @@ -5,11 +5,7 @@ menu.file=Datei menu.file.open=Datei öffnen menu.file.addphotos=Fotos laden -menu.file.loadfromgps=Vom GPS laden menu.file.save=Speichern -menu.file.exportkml=KML exportieren -menu.file.exportgpx=GPX exportieren -menu.file.exportpov=POV exportieren menu.file.exit=Beenden menu.edit=Bearbeiten menu.edit.undo=Rückgängig @@ -18,11 +14,10 @@ menu.edit.editpoint=Punkt bearbeiten menu.edit.editwaypointname=Waypoint Name bearbeiten menu.edit.deletepoint=Punkt löschen menu.edit.deleterange=Bereich löschen -menu.edit.deleteduplicates=Duplikate löschen -menu.edit.compress=Track komprimieren +menu.edit.deletemarked=Komprimierten Punkte löschen menu.edit.interpolate=Interpolieren +menu.edit.average=Durchschnitt berechnen menu.edit.reverse=Bereich umkehren -menu.edit.addtimeoffset=Zeitdifferenz addieren menu.edit.mergetracksegments=Trackteile verbinden menu.edit.rearrange=Waypoints reorganisieren menu.edit.rearrange.start=Alle Waypoints zum Anfang @@ -38,16 +33,14 @@ menu.photo=Foto menu.photo.saveexif=Exif Daten speichern menu.photo.connect=Mit Punkt verbinden menu.photo.disconnect=Vom Punkt trennen -menu.photo.correlate=Alle Fotos korrelieren menu.photo.delete=Foto entfernen menu.view=Ansicht -menu.view.show3d=In 3D zeigen menu.view.browser=Karte in Browser menu.view.browser.google=Google Maps menu.view.browser.openstreetmap=Openstreetmap +menu.view.browser.mapquest= +menu.view.browser.yahoo= menu.help=Hilfe -menu.help.about=Über Prune -menu.help.checkversion=Nach neuen Versionen suchen # Popup menu for map menu.map.zoomin=Hineinzoomen menu.map.zoomout=Herauszoomen @@ -57,6 +50,23 @@ menu.map.connect=Trackpunkte mit Linie anzeigen menu.map.autopan=Autozentrierung menu.map.showmap=Karte zeigen +# Functions +function.loadfromgps=Vom GPS laden +function.sendtogps=zum GPS schicken +function.exportkml=KML exportieren +function.exportgpx=GPX exportieren +function.exportpov=POV exportieren +function.compress=Track komprimieren +function.addtimeoffset=Zeitdifferenz addieren +function.charts=Diagrammen +function.show3d=3D Ansicht +function.distances=Distanzen +function.setmapbg=Karte Hintergrund setzen +function.correlatephotos=Fotos korrelieren +function.help=Hilfe +function.about=Über Prune +function.checkversion=Nach neuen Versionen suchen + # Dialogs dialog.exit.confirm.title=Prune beenden dialog.exit.confirm.text=Ihre Daten wurden nicht gespeichert. Wollen Sie das Programm trotzdem beenden? @@ -66,11 +76,6 @@ dialog.deletepoint.title=Punkt l dialog.deletepoint.deletephoto=Das zu diesem Punkt gehörende Foto ebenfalls löschen? dialog.deletephoto.title=Foto entfernen dialog.deletephoto.deletepoint=Den zu diesem Foto gehörenden Punkt auch löschen? -dialog.deleteduplicates.title=Duplikate löschen -dialog.deleteduplicates.nonefound=Keine Duplikate gefunden -dialog.compresstrack.title=Track komprimieren -dialog.compresstrack.parameter.text=Parameter für Komprimierung (niedrige Nummer = höhere Komprimierung) -dialog.compresstrack.nonefound=Es konnten keine Punkte entfernt werden dialog.openoptions.title=Öffnen dialog.openoptions.filesnippet=Extrakt von der Datei dialog.load.table.field=Feld @@ -85,19 +90,20 @@ dialog.delimiter.other=Andere dialog.openoptions.deliminfo.records=Aufnahmen, mit dialog.openoptions.deliminfo.fields=Feldern dialog.openoptions.deliminfo.norecords=Keine Rekords -dialog.openoptions.tabledesc=Extrakt von der Datei dialog.openoptions.altitudeunits=Höhe Maßeinheiten dialog.jpegload.subdirectories=Unterordner auch durchsuchen dialog.jpegload.loadjpegswithoutcoords=Auch Fotos ohne Koordinaten laden dialog.jpegload.loadjpegsoutsidearea=Auch Fotos ausserhalb vom Track laden dialog.jpegload.progress.title=Fotos werden geladen dialog.jpegload.progress=Bitte warten während die Fotos durchgesucht werden -dialog.gpsload.title=Vom GPS laden dialog.gpsload.nogpsbabel=Kein gpsbabel Programm wurde gefunden. Weiter? dialog.gpsload.device=Device Name dialog.gpsload.format=Format dialog.gpsload.getwaypoints=Waypoints laden dialog.gpsload.gettracks=Tracks laden +dialog.gpssend.sendwaypoints=Waypoints schicken +dialog.gpssend.sendtracks=Tracks schicken +dialog.gpssend.trackname=Track Name dialog.saveoptions.title=Datei speichern dialog.save.fieldstosave=Zu speichernde Felder dialog.save.table.field=Feld @@ -109,16 +115,13 @@ dialog.save.altitudeunits=H dialog.save.timestampformat=Zeitstempelformat dialog.save.overwrite.title=Datei schon vorhanden dialog.save.overwrite.text=Diese Datei existiert schon. Wollen Sie die vorhandene Datei überschreiben? -dialog.exportkml.title=KML exportieren dialog.exportkml.text=Titel für die Daten dialog.exportkml.altitude=Auch Höheninformation (für Luftfahrt) dialog.exportkml.kmz=Daten in kmz Datei komprimieren dialog.exportkml.exportimages=Bilder in kmz exportieren -dialog.exportgpx.title=GPX exportieren dialog.exportgpx.name=Name dialog.exportgpx.desc=Beschreibung dialog.exportgpx.includetimestamps=Zeitstempel exportieren -dialog.exportpov.title=POV exportieren dialog.exportpov.text=Geben Sie die Parameter für den POV Export ein dialog.exportpov.font=Font dialog.exportpov.camerax=Kamera X @@ -152,7 +155,6 @@ dialog.pointnameedit.name=Waypoint Name dialog.pointnameedit.uppercase=GROß geschrieben dialog.pointnameedit.lowercase=klein geschrieben dialog.pointnameedit.sentencecase=Gemischt geschrieben -dialog.addtimeoffset.title=Zeitdifferenz addieren dialog.addtimeoffset.add=Zeit addieren dialog.addtimeoffset.subtract=Zeit subtrahieren dialog.addtimeoffset.days=Tage @@ -172,7 +174,26 @@ dialog.saveexif.photostatus.connected=Verbunden dialog.saveexif.photostatus.disconnected=Getrennt dialog.saveexif.photostatus.modified=Modifiziert dialog.saveexif.overwrite=Dateien überschreiben -dialog.correlate.title=Fotos korrelieren +dialog.charts.xaxis=X Achse +dialog.charts.yaxis=Y Achse +dialog.charts.output=Ausgabe +dialog.charts.screen=zum Bildschirm +dialog.charts.svg=zur SVG Datei +dialog.charts.svgwidth=SVG Breite +dialog.charts.svgheight=SVG Höhe +dialog.charts.needaltitudeortimes=Ohne Daten über Höhe und Zeit, kann keine Diagrammen erzeugt werden. +dialog.charts.gnuplotpath=Gnuplot Pfad +dialog.charts.gnuplotnotfound=Gnuplot konnte mit diesem Pfad nicht gefunden werden +dialog.distances.intro=Distanzen per Luftlinie zwischen Punkte +dialog.distances.column.from=Vom Punkt +dialog.distances.column.to=Zum Punkt +dialog.distances.currentpoint=Aktuelle Punkt +dialog.distances.toofewpoints=Diese Funktion braucht Waypoints um die Distanzen zu berechnen +dialog.setmapbg.mapnik= +dialog.setmapbg.osma= +dialog.setmapbg.cyclemap=Fahrradkarte +dialog.setmapbg.other=Andere +dialog.setmapbg.server=Server URL dialog.correlate.notimestamps=Die Punkte haben keine Zeitinformation, deswegen ist es nicht möglich die Fotos zu korrelieren. dialog.correlate.nouncorrelatedphotos=Alle Photos sind schon korreliert.\nWollen Sie trotzdem fortsetzen? dialog.correlate.photoselect.intro=Selektieren Sie einen von diesen Fotos um die Differenz zu berechnen @@ -195,8 +216,16 @@ dialog.correlate.options.nodistancelimit=Keine Distanzgrenzen dialog.correlate.options.distancelimit=Distanzgrenzen dialog.correlate.options.correlate=Korrelieren dialog.correlate.alloutsiderange=Alle Fotos sind ausserhalb vom Track Zeitraum, so können nicht korreliert werden.\nVersuchen Sie mit einem anderen Offset oder verbinden Sie manuell mindestens ein Foto. +dialog.compress.nonefound=Es konnten keine Punkte entfernt werden +dialog.compress.duplicates.title=Duplikate entfernen +dialog.compress.closepoints.title=Nahegelegene Punkte entfernen +dialog.compress.closepoints.paramdesc=Span Faktor +dialog.compress.wackypoints.title=Komische Punkte entfernen +dialog.compress.wackypoints.paramdesc=Distanz Faktor +dialog.compress.singletons.title=Singletons entfernen +dialog.compress.singletons.paramdesc=Distanz Faktor +dialog.compress.summarylabel=Punkte zu entfernen dialog.help.help=Bitte sehen Sie\n http://activityworkshop.net/software/prune/\nfür weitere Information und Benutzeranleitungen. -dialog.about.title=Über Prune dialog.about.version=Version dialog.about.build=Build dialog.about.summarytext1=Prune ist ein Programm für das Laden, Darstellen und Editieren von Daten von GPS Geräten. @@ -211,6 +240,7 @@ dialog.about.systeminfo.java3d=Java3d installiert dialog.about.systeminfo.povray=Povray installiert dialog.about.systeminfo.exiftool=Exiftool installiert dialog.about.systeminfo.gpsbabel=Gpsbabel installiert +dialog.about.systeminfo.gnuplot=Gnuplot installiert dialog.about.yes=Ja dialog.about.no=Nein dialog.about.credits=Credits @@ -223,7 +253,6 @@ dialog.about.credits.devtools=Entwicklungsprogrammen dialog.about.credits.othertools=Andere Programmen dialog.about.credits.thanks=Danke an dialog.about.readme=Liesmich -dialog.checkversion.title=Versionnummer prüfen dialog.checkversion.error=Die Versionnummer konnte nicht geprüft werden.\nBitte prüfen Sie die Internet Verbindung. dialog.checkversion.uptodate=Sie haben schon die letzte Version vom Prune. dialog.checkversion.newversion1=Eine neue Version vom Prune ist jetzt verfügbar! Die neue Version heißt Version @@ -243,8 +272,6 @@ dialog.3dlines.intro=Hier sind die Linien f confirm.loadfile=Daten geladen vom confirm.save.ok1=Es wurden confirm.save.ok2=Punkte gespeichert nach -confirm.deleteduplicates.single=Duplikat wurde gelöscht -confirm.deleteduplicates.multi=Duplikate wurden gelöscht confirm.deletepoint.single=Punkt wurde entfernt confirm.deletepoint.multi=Punkte wurden entfernt confirm.point.edit=Punkt editiert @@ -288,14 +315,17 @@ button.selectnone=Nichts selektieren button.preview=Vorschauen button.guessfields=Felder erraten button.showwebpage=Webseite anzeigen +button.gnuplotpath=Gnuplot Pfad setzen # File types filetype.txt=TXT Dateien filetype.jpeg=JPG Dateien filetype.kmlkmz=KML, KMZ Dateien filetype.kml=KML Dateien +filetype.kmz=KMZ Dateien filetype.gpx=GPX Dateien filetype.pov=POV Dateien +filetype.svg=SVG Dateien # Display components display.nodata=Keine Daten geladen @@ -309,7 +339,6 @@ details.pointdetails=Details vom Punkt details.index.selected=Index details.index.of=von details.nopointselection=Nichts selektiert -details.speed=Geschwindigkeit details.photofile=Foto Datei details.norangeselection=Nichts selektiert details.rangedetails=Details vom Bereich @@ -332,12 +361,14 @@ details.photodetails=Details vom Foto details.nophoto=Kein Foto selektiert details.photo.loading=Laden details.photo.connected=Verbunden +map.overzoom=Keine Karten mit diesem Zoom verfügbar # Field names fieldname.latitude=Breitengrad fieldname.longitude=Längengrad fieldname.altitude=Höhe fieldname.timestamp=Zeitstempel +fieldname.time=Zeit fieldname.waypointname=Name fieldname.waypointtype=Typ fieldname.newsegment=Segment @@ -346,20 +377,25 @@ fieldname.prefix=Feld fieldname.distance=Länge fieldname.movingdistance=Weglänge fieldname.duration=Zeitlänge +fieldname.speed=Geschwindigkeit +fieldname.verticalspeed=Vertikale Geschwindigkeit # Measurement units units.original=Original units.default=Default units.metres=Meter -units.metres.short=m -units.feet=Füße -units.feet.short=ft +units.metres.short= +units.feet= +units.feet.short= units.kilometres=Kilometer units.kilometres.short=km units.kmh=km/h -units.miles=Meilen -units.miles.short=mi -units.mph=mi/h +units.miles= +units.miles.short= +units.mph= +units.metrespersec=m/s +units.feetpersec=ft/s +units.hours=Std units.degminsec=Grad-Min-Sek units.degmin=Grad-Min units.deg=Grad @@ -383,7 +419,6 @@ undo.deletephoto=Photo entfernen undo.deleterange=Bereich löschen undo.compress=Track komprimieren undo.insert=Punkte hinzufügen -undo.deleteduplicates=Duplikaten löschen undo.reverse=Bereich umdrehen undo.mergetracksegments=Trackteile verbinden undo.addtimeoffset=zeitdifferenz addieren @@ -405,6 +440,7 @@ error.load.dialogtitle=Fehler beim Laden error.load.noread=Datei konnte nicht gelesen werden error.load.nopoints=Keine gültigen Daten in Datei gefunden error.load.unknownxml=Unbekanntes xml Format: +error.load.noxmlinzip=Keine xml Datei in Zip Datei gefunden error.load.othererror=Fehler beim Lesen von der Datei: error.jpegload.dialogtitle=Fehler beim Laden von Fotos error.jpegload.nofilesfound=Keine Dateien gefunden @@ -415,10 +451,8 @@ error.undofailed.title=Undo fehlgeschlagen error.undofailed.text=Operation konnte nicht rückgängig gemacht werden error.function.noop.title=Funktion hat nichts gemacht error.rearrange.noop=Waypoints Reorganisieren hatte keinen Effekt -error.function.notimplemented=Sorry, diese Funktion wurde noch nicht implementiert. error.function.notavailable.title=Funktion nicht verfügbar error.function.nojava3d=Diese Funktion braucht den Java3d Library,\nvon Sun.com erhältlich. -error.3d.title=Fehler mit 3d Darstellung error.3d=Ein Fehler ist mit der 3d Darstellung aufgetreten error.readme.notfound=Liesmich Datei nicht gefunden error.osmimage.dialogtitle=Laden von Karten-Bilder fehlgeschlagen diff --git a/tim/prune/lang/prune-texts_de_CH.properties b/tim/prune/lang/prune-texts_de_CH.properties index acd3c22..5cbeed6 100644 --- a/tim/prune/lang/prune-texts_de_CH.properties +++ b/tim/prune/lang/prune-texts_de_CH.properties @@ -4,12 +4,8 @@ # Menu entries menu.file=Datei menu.file.open=File öffne -menu.file.loadfromgps=uusem GPS lade menu.file.addphotos=Fötelis innätue menu.file.save=Speichere -menu.file.exportkml=KML exportiere -menu.file.exportgpx=GPX exportiere -menu.file.exportpov=POV exportiere menu.file.exit=Beände menu.edit=Editiere menu.edit.undo=Undo @@ -18,11 +14,10 @@ menu.edit.editpoint=Punkt editiere menu.edit.editwaypointname=Waypoint Name editiere menu.edit.deletepoint=Punkt lösche menu.edit.deleterange=Beriich lösche -menu.edit.deleteduplicates=Doppeldate lösche -menu.edit.compress=Date komprimiere +menu.edit.deletemarked=Komprimierte Punkte lösche menu.edit.interpolate=Interpoliere +menu.edit.average=Durchschnitt uusrächne menu.edit.reverse=Beriich umdrähie -menu.edit.addtimeoffset=Ziitverschiebig zutue menu.edit.mergetracksegments=Track Segmänte merge menu.edit.rearrange=Waypoints reorganisiere menu.edit.rearrange.start=Alli zum Aafang @@ -38,25 +33,40 @@ menu.photo=F menu.photo.saveexif=Exif Date speicherä menu.photo.connect=Mitem Punkt verbindä menu.photo.disconnect=Vonem Punkt trännä -menu.photo.correlate=Alli Fötelis korrelierä menu.photo.delete=Föteli entfernä menu.view=Aasicht -menu.view.show3d=In drüü-D zeigä menu.view.browser=Karte inem Browser -menu.view.browser.google=Google maps -menu.view.browser.openstreetmap=Openstreetmap +menu.view.browser.google= +menu.view.browser.openstreetmap= +menu.view.browser.mapquest= +menu.view.browser.yahoo= menu.help=Hilfe -menu.help.about=Über Prune -menu.help.checkversion=Pruef nach ne noie Version # Popup menu for map -menu.map.zoomin=Einzoome -menu.map.zoomout=Uuszoome +menu.map.zoomin=Innezoome +menu.map.zoomout=Uusezoome menu.map.zoomfull=Zoome zum ganzes Bild menu.map.newpoint=Noii Punkt menu.map.connect=Trackpünktli verbindä menu.map.autopan=Autopan menu.map.showmap=Kate zeigä +# Functions +function.loadfromgps=uusem GPS lade +function.sendtogps=zum GPS schicke +function.exportkml=KML exportierä +function.exportgpx=GPX exportierä +function.exportpov=POV exportierä +function.compress=Track komprimierä +function.addtimeoffset=Ziitverschiebig zutue +function.charts=Diagramme +function.show3d=Drüü-D Aasicht +function.distances=Distanze +function.setmapbg=Karte Hintegrund setzä +function.correlatephotos=Fötelis korrelierä +function.help=Hilfe +function.about=Über Prune +function.checkversion=Pruef nach ne noie Version + # Dialogs dialog.exit.confirm.title=Prune beände dialog.exit.confirm.text=Ihri Date sind nonig gspeicheret worde. Wend Sie trotzdem s Programm beände? @@ -66,11 +76,6 @@ dialog.deletepoint.title=Punkt l dialog.deletepoint.deletephoto=s Föteli vonem Punkt au löschä? dialog.deletephoto.title=Föteli entfernä dialog.deletephoto.deletepoint=Punkt vonem Föteli au löschä? -dialog.deleteduplicates.title=Duplikaten lösche -dialog.deleteduplicates.nonefound=Keine Duplikaten gefunden -dialog.compresstrack.title=Track komprimiere -dialog.compresstrack.parameter.text=Parameter für Komprimierig (niedriger Nummer = höher Komprimierig) -dialog.compresstrack.nonefound=Kei Punkte hätte gelöscht werde könne dialog.openoptions.title=Öffne Optionen dialog.openoptions.filesnippet=Extrakt vom File dialog.load.table.field=Fäld @@ -85,19 +90,20 @@ dialog.delimiter.other=Andere dialog.openoptions.deliminfo.records=Rekords, mit dialog.openoptions.deliminfo.fields=Fäldere dialog.openoptions.deliminfo.norecords=Kei Rekords -dialog.openoptions.tabledesc=Extrakt vom File dialog.openoptions.altitudeunits=Höchi Masseiheite dialog.jpegload.subdirectories=Subordnern au dialog.jpegload.loadjpegswithoutcoords=Au Fötelis ohni Koordinate dialog.jpegload.loadjpegsoutsidearea=Au Fötelis uuserhalb vonem Track dialog.jpegload.progress.title=Fötelis lade dialog.jpegload.progress=Bitte warte während die Fötelis durägsucht werde -dialog.gpsload.title=Lade uusem GPS dialog.gpsload.nogpsbabel=Kei gpsbabel Programm gfunde. Wiiter? dialog.gpsload.device=Device Name dialog.gpsload.format=Format dialog.gpsload.getwaypoints=Waypoints lade dialog.gpsload.gettracks=Tracks lade +dialog.gpssend.sendwaypoints=Waypoints schicke +dialog.gpssend.sendtracks=Tracks schicke +dialog.gpssend.trackname=Track Name dialog.saveoptions.title=File speicherä dialog.save.fieldstosave=Fälder zu speicherä dialog.save.table.field=Fäld @@ -109,16 +115,13 @@ dialog.save.altitudeunits=H dialog.save.timestampformat=Ziitstämpelformat dialog.save.overwrite.title=s'File existiert scho dialog.save.overwrite.text=s'File existiert scho. Sind Sie sicher, Sie wend s'File überschriibe? -dialog.exportkml.title=KML exportierä dialog.exportkml.text=Titel für die Date dialog.exportkml.altitude=Au Höchiinformation (fürs Fliege) dialog.exportkml.kmz=Date ins kmz File komprimierä dialog.exportkml.exportimages=Bildli ins Kmz exportierä -dialog.exportgpx.title=GPX exportierä dialog.exportgpx.name=Name dialog.exportgpx.desc=Beschriibig dialog.exportgpx.includetimestamps=Au Ziitstämpel -dialog.exportpov.title=POV exportierä dialog.exportpov.text=Gäbet Sie die Parameter ii fürs POV Export dialog.exportpov.font=Font dialog.exportpov.camerax=Kamera X @@ -152,7 +155,6 @@ dialog.pointnameedit.name=Waypoint Name dialog.pointnameedit.uppercase=GROSS gschriebe dialog.pointnameedit.lowercase=chli gschriebe dialog.pointnameedit.sentencecase=Gmischt Gschriebe -dialog.addtimeoffset.title=Ziitverschiebig zutue dialog.addtimeoffset.add=Ziit zutue dialog.addtimeoffset.subtract=Ziit davo neh dialog.addtimeoffset.days=Tage @@ -172,7 +174,26 @@ dialog.saveexif.photostatus.connected=Verbund dialog.saveexif.photostatus.disconnected=Gtrännt dialog.saveexif.photostatus.modified=Gänderet dialog.saveexif.overwrite=Files überschriebä -dialog.correlate.title=Fötelis korrelierä +dialog.charts.xaxis=X Achse +dialog.charts.yaxis=Y Achse +dialog.charts.output=Uusgabe +dialog.charts.screen=Bildschirm +dialog.charts.svg=SVG File +dialog.charts.svgwidth=SVG Breiti +dialog.charts.svgheight=SVG Höhi +dialog.charts.needaltitudeortimes=Ohni Höhi Date und au ohne Ziit, isch es nöd möglech, Diagramme z zeigä. +dialog.charts.gnuplotpath=Gnuplot Pfad +dialog.charts.gnuplotnotfound=Gnuplot isch mit dem Pfad nöd gfunde worde +dialog.distances.intro=Dischtanze per Luftlinie zwüschet Punkte +dialog.distances.column.from=Vom Punkt +dialog.distances.column.to=Zum Punkt +dialog.distances.currentpoint=Aktuelli Punkt +dialog.distances.toofewpoints=d'Funktion bruucht Waypoints um die Dischtanze z berächne +dialog.setmapbg.mapnik= +dialog.setmapbg.osma= +dialog.setmapbg.cyclemap=Velokarte +dialog.setmapbg.other=Anderi +dialog.setmapbg.server=Server URL dialog.correlate.notimestamps=Es hät kei Ziitstämpel inem Track innä, so s'isch nöd möglech die Fötelis zu korrelierä. dialog.correlate.nouncorrelatedphotos=Alle Fötelis sin scho korreliert.\nWend Sie trotzdem fortsetzä? dialog.correlate.photoselect.intro=Wählet Sie eini vo deren Föteli uus um die Ziitdifferänz zu berächnä @@ -195,8 +216,16 @@ dialog.correlate.options.nodistancelimit=Kei Distanzgr dialog.correlate.options.distancelimit=Distanzgränzä dialog.correlate.options.correlate=Korrelierä dialog.correlate.alloutsiderange=Alli Fötelis sin uusserhalb vonem Track Ziitruum, so chönne nöd korreliert werdä.\nVersuechet Sie mitenem anderen Offset oder verbindet Sie manuell mindeschtens eis Föteli. +dialog.compress.nonefound=Kei Punkte hätte gelöscht werde könne +dialog.compress.duplicates.title=Duplikate entfärnä +dialog.compress.closepoints.title=Nöchiglägeni Punkte entfärnä +dialog.compress.closepoints.paramdesc=Span Faktor +dialog.compress.wackypoints.title=Komischi Punkte entfärnä +dialog.compress.wackypoints.paramdesc=Distanz Faktor +dialog.compress.singletons.title=Singletons entfärnä +dialog.compress.singletons.paramdesc=Distanz faktor +dialog.compress.summarylabel=Punkte zu entfärnä dialog.help.help=Bitte lueg na\n http://activityworkshop.net/software/prune/\nfür wiitere Information und Benutzeraaleitige. -dialog.about.title=Über Prune dialog.about.version=Version dialog.about.build=Build dialog.about.summarytext1=Prune isch s Programm fürs Lade, Darstelle und Editiere vo Date von GPS Geräte. @@ -211,6 +240,7 @@ dialog.about.systeminfo.java3d=Java3d inschtalliert dialog.about.systeminfo.povray=Povray inschtalliert dialog.about.systeminfo.exiftool=Exiftool inschtalliert dialog.about.systeminfo.gpsbabel=Gpsbabel inschtalliert +dialog.about.systeminfo.gnuplot=Gnuplot inschtalliert dialog.about.yes=Ja dialog.about.no=Nei dialog.about.credits=Credits @@ -223,7 +253,6 @@ dialog.about.credits.devtools=Entwicklungsw dialog.about.credits.othertools=Anderi Wärkzüüge dialog.about.credits.thanks=Danke an dialog.about.readme=Läsmi -dialog.checkversion.title=Pruef d'Version dialog.checkversion.error=Die Versionnummer könne nöd gefprüft werdä.\nGits ne internet Verbindig? dialog.checkversion.uptodate=Sie han die noischti Version vonem Prune scho. dialog.checkversion.newversion1=Ne noii Version vonem Prune isch jetzt usse! Die heisst jetzt Version @@ -243,8 +272,6 @@ dialog.3dlines.intro=Hier sin die Linie f confirm.loadfile=Date glade vom confirm.save.ok1=Es sin confirm.save.ok2=Punkte gspeicheret worde na -confirm.deleteduplicates.single=Duplikat isch glöscht worde -confirm.deleteduplicates.multi=Duplikaten sin glöscht worde confirm.deletepoint.single=Punkt isch entfernt worde confirm.deletepoint.multi=Punkte sin entfernt worde confirm.point.edit=Punkt editiert @@ -288,14 +315,17 @@ button.selectnone=N button.preview=Vorschauä button.guessfields=Fälde erratä button.showwebpage=Websiite aazeigä +button.gnuplotpath=Gnuplot Pfad setzä # File types filetype.txt=TXT Dateie filetype.jpeg=JPG Dateie filetype.kmlkmz=KML, KMZ Dateie filetype.kml=KML Dateie +filetype.kmz=KMZ Dateie filetype.gpx=GPX Dateie filetype.pov=POV Dateie +filetype.svg=SVG Dateie # Display components display.nodata=Kei Date glade worde @@ -305,11 +335,10 @@ details.notrack=Kei Track glade worde details.track.points=Punkte details.track.file=Datei details.track.numfiles=Anzahl Dateie -details.pointdetails=Details vom Punkt +details.pointdetails=Details vonem Punkt details.index.selected=Index details.index.of=vo details.nopointselection=Nüüt selektiert -details.speed=Gschwindikeit details.photofile=Föteli Datei details.norangeselection=Nüüt selektiert details.rangedetails=Details vonem Beriich @@ -328,16 +357,18 @@ details.range.avespeed=Gschwindikeit details.range.avemovingspeed=Gschwindikeit ufem Wäg details.waypointsphotos.waypoints=Waypoints details.waypointsphotos.photos=Fötelis -details.photodetails=Details vom Föteli +details.photodetails=Details vonem Föteli details.nophoto=Kei föteli selektiert details.photo.loading=Ladä details.photo.connected=Verbundä +map.overzoom=Kei Karte mit diesem Zoom # Field names fieldname.latitude=Breitegrad fieldname.longitude=Längegrad fieldname.altitude=Höchi fieldname.timestamp=Ziitstämpel +fieldname.time=Ziit fieldname.waypointname=Name fieldname.waypointtype=Typ fieldname.newsegment=Segmänt @@ -346,20 +377,25 @@ fieldname.prefix=F fieldname.distance=Längi fieldname.movingdistance=Weglängi fieldname.duration=Ziitlängi +fieldname.speed=Gschwindikeit +fieldname.verticalspeed=Uf/Ab Gschwindikeit # Measurement units units.original=Original units.default=Default units.metres=Meter -units.metres.short=m -units.feet=Fuess -units.feet.short=ft +units.metres.short= +units.feet= +units.feet.short= units.kilometres=Kilometer units.kilometres.short=km units.kmh=km/h -units.miles=Meile -units.miles.short=mi -units.mph=mi/Std +units.miles= +units.miles.short= +units.mph= +units.metrespersec=m/s +units.feetpersec=ft/s +units.hours=Std units.degminsec=Grad-Min-Sek units.degmin=Grad-Min units.deg=Grad @@ -383,7 +419,6 @@ undo.deletephoto=F undo.deleterange=Beriich löschä undo.compress=Track komprimierä undo.insert=Punkte innätuä -undo.deleteduplicates=Duplikaten löschä undo.reverse=Beriich umdrähie undo.mergetracksegments=track segmänte merge undo.addtimeoffset=ziitverschiebig zutue @@ -405,6 +440,7 @@ error.load.dialogtitle=F error.load.noread=File cha nöd glase werde error.load.nopoints=Kei gültigi Information inem File gfunde error.load.unknownxml=Unbekanntes xml Format: +error.load.noxmlinzip=Kei xml im Zip File gfunde error.load.othererror=Fähle bim Läse: error.jpegload.dialogtitle=Fähle bim Lade von Fötelis error.jpegload.nofilesfound=Kei Dateie gfunde @@ -415,10 +451,8 @@ error.undofailed.title=Undo isch fehlgschlage worde error.undofailed.text=Operation kann nöd rückgängig gmacht werde error.function.noop.title=Funktion hät gar nüüt gmacht error.rearrange.noop=Waypoints Reorganisierig hät kei Effäkt gha -error.function.notimplemented=Sorry, d'Funktion isch nonig implementiert worde. error.function.notavailable.title=Funktion nöd verfüegbar error.function.nojava3d=Sorry, d'Funktion brucht d Java3d Library,\nvo Sun.com erhältlech. -error.3d.title=Fähler mitere 3d Darstellig error.3d=N Fähler isch mitere 3d Darstellig ufgtrete error.readme.notfound=Läs mi File nöd gfunde error.osmimage.dialogtitle=Fähle bim Bildli-Lade diff --git a/tim/prune/lang/prune-texts.properties b/tim/prune/lang/prune-texts_en.properties similarity index 86% rename from tim/prune/lang/prune-texts.properties rename to tim/prune/lang/prune-texts_en.properties index 53a65b0..f76bd36 100644 --- a/tim/prune/lang/prune-texts.properties +++ b/tim/prune/lang/prune-texts_en.properties @@ -5,11 +5,7 @@ menu.file=File menu.file.open=Open file menu.file.addphotos=Add photos -menu.file.loadfromgps=Load from GPS menu.file.save=Save -menu.file.exportkml=Export KML -menu.file.exportgpx=Export GPX -menu.file.exportpov=Export POV menu.file.exit=Exit menu.edit=Edit menu.edit.undo=Undo @@ -18,11 +14,10 @@ menu.edit.editpoint=Edit point menu.edit.editwaypointname=Edit waypoint name menu.edit.deletepoint=Delete point menu.edit.deleterange=Delete range -menu.edit.deleteduplicates=Delete duplicates -menu.edit.compress=Compress track +menu.edit.deletemarked=Delete marked points menu.edit.interpolate=Interpolate +menu.edit.average=Average selection menu.edit.reverse=Reverse range -menu.edit.addtimeoffset=Add time offset menu.edit.mergetracksegments=Merge track segments menu.edit.rearrange=Rearrange waypoints menu.edit.rearrange.start=All to start of file @@ -38,16 +33,14 @@ menu.photo=Photo menu.photo.saveexif=Save to Exif menu.photo.connect=Connect to point menu.photo.disconnect=Disconnect from point -menu.photo.correlate=Correlate all photos menu.photo.delete=Remove photo menu.view=View -menu.view.show3d=Show in three-D menu.view.browser=Map in browser menu.view.browser.google=Google maps menu.view.browser.openstreetmap=Openstreetmap +menu.view.browser.mapquest=Mapquest +menu.view.browser.yahoo=Yahoo maps menu.help=Help -menu.help.about=About Prune -menu.help.checkversion=Check for new version # Popup menu for map menu.map.zoomin=Zoom in menu.map.zoomout=Zoom out @@ -57,6 +50,23 @@ menu.map.connect=Connect track points menu.map.autopan=Autopan menu.map.showmap=Show map +# Functions +function.loadfromgps=Load data from GPS +function.sendtogps=Send data to GPS +function.exportkml=Export KML +function.exportgpx=Export GPX +function.exportpov=Export POV +function.compress=Compress track +function.addtimeoffset=Add time offset +function.charts=Charts +function.show3d=Three-D view +function.distances=Distances +function.setmapbg=Set map background +function.correlatephotos=Correlate photos +function.help=Help +function.about=About Prune +function.checkversion=Check for new version + # Dialogs dialog.exit.confirm.title=Exit Prune dialog.exit.confirm.text=Your data is not saved. Are you sure you want to exit? @@ -66,11 +76,6 @@ dialog.deletepoint.title=Delete Point dialog.deletepoint.deletephoto=Delete photo attached to this point? dialog.deletephoto.title=Delete Photo dialog.deletephoto.deletepoint=Delete point attached to this photo? -dialog.deleteduplicates.title=Delete Duplicates -dialog.deleteduplicates.nonefound=No duplicates found -dialog.compresstrack.title=Compress Track -dialog.compresstrack.parameter.text=Parameter for compression (lower number = more compression) -dialog.compresstrack.nonefound=No data points could be removed dialog.openoptions.title=Open options dialog.openoptions.filesnippet=Extract of file dialog.load.table.field=Field @@ -85,19 +90,20 @@ dialog.delimiter.other=Other dialog.openoptions.deliminfo.records=records, with dialog.openoptions.deliminfo.fields=fields dialog.openoptions.deliminfo.norecords=No records -dialog.openoptions.tabledesc=Extract of file dialog.openoptions.altitudeunits=Altitude units dialog.jpegload.subdirectories=Include subdirectories dialog.jpegload.loadjpegswithoutcoords=Include photos without coordinates dialog.jpegload.loadjpegsoutsidearea=Include photos outside current area dialog.jpegload.progress.title=Loading photos dialog.jpegload.progress=Please wait while the photos are searched -dialog.gpsload.title=Load from GPS dialog.gpsload.nogpsbabel=No gpsbabel program could be found. Continue? dialog.gpsload.device=Device name dialog.gpsload.format=Format dialog.gpsload.getwaypoints=Load waypoints dialog.gpsload.gettracks=Load tracks +dialog.gpssend.sendwaypoints=Send waypoints +dialog.gpssend.sendtracks=Send tracks +dialog.gpssend.trackname=Track name dialog.saveoptions.title=Save file dialog.save.fieldstosave=Fields to save dialog.save.table.field=Field @@ -109,16 +115,13 @@ dialog.save.altitudeunits=Altitude units dialog.save.timestampformat=Timestamp format dialog.save.overwrite.title=File already exists dialog.save.overwrite.text=This file already exists. Are you sure you want to overwrite the file? -dialog.exportkml.title=Export KML dialog.exportkml.text=Title for the data dialog.exportkml.altitude=Include altitudes (for aviation) dialog.exportkml.kmz=Compress to make kmz file dialog.exportkml.exportimages=Export image thumbnails to kmz -dialog.exportgpx.title=Export GPX dialog.exportgpx.name=Name dialog.exportgpx.desc=Description dialog.exportgpx.includetimestamps=Include timestamps -dialog.exportpov.title=Export POV dialog.exportpov.text=Please enter the parameters for the POV export dialog.exportpov.font=Font dialog.exportpov.camerax=Camera X @@ -152,7 +155,6 @@ dialog.pointnameedit.name=Waypoint name dialog.pointnameedit.uppercase=UPPER case dialog.pointnameedit.lowercase=lower case dialog.pointnameedit.sentencecase=Sentence Case -dialog.addtimeoffset.title=Add time offset dialog.addtimeoffset.add=Add time dialog.addtimeoffset.subtract=Subtract time dialog.addtimeoffset.days=Days @@ -172,7 +174,26 @@ dialog.saveexif.photostatus.connected=Connected dialog.saveexif.photostatus.disconnected=Disconnected dialog.saveexif.photostatus.modified=Modified dialog.saveexif.overwrite=Overwrite files -dialog.correlate.title=Correlate photos +dialog.charts.xaxis=X axis +dialog.charts.yaxis=Y axes +dialog.charts.output=Output +dialog.charts.screen=Output to screen +dialog.charts.svg=Output to SVG file +dialog.charts.svgwidth=SVG width +dialog.charts.svgheight=SVG height +dialog.charts.needaltitudeortimes=The track must have either altitudes or time information in order to create charts +dialog.charts.gnuplotpath=Path to gnuplot +dialog.charts.gnuplotnotfound=Could not find gnuplot with the given path +dialog.distances.intro=Straight line distances between points +dialog.distances.column.from=From point +dialog.distances.column.to=To point +dialog.distances.currentpoint=Current point +dialog.distances.toofewpoints=This function needs waypoints in order to calculate the distances between them +dialog.setmapbg.mapnik=Mapnik (default) +dialog.setmapbg.osma=Osma +dialog.setmapbg.cyclemap=Cyclemap +dialog.setmapbg.other=Other +dialog.setmapbg.server=Server URL dialog.correlate.notimestamps=There are no timestamps in the data points, so there is nothing to correlate with the photos. dialog.correlate.nouncorrelatedphotos=There are no uncorrelated photos.\nAre you sure you want to continue? dialog.correlate.photoselect.intro=Select one of these correlated photos to use as the time offset @@ -195,8 +216,16 @@ dialog.correlate.options.nodistancelimit=No distance limit dialog.correlate.options.distancelimit=Distance limit dialog.correlate.options.correlate=Correlate dialog.correlate.alloutsiderange=All photos are outside the time range of the track, so none can be correlated.\nTry changing the offset or manually correlating at least one photo. +dialog.compress.nonefound=No data points could be removed +dialog.compress.duplicates.title=Duplicate removal +dialog.compress.closepoints.title=Nearby point removal +dialog.compress.closepoints.paramdesc=Span factor +dialog.compress.wackypoints.title=Wacky point removal +dialog.compress.wackypoints.paramdesc=Distance factor +dialog.compress.singletons.title=Singleton removal +dialog.compress.singletons.paramdesc=Distance factor +dialog.compress.summarylabel=Points to delete dialog.help.help=Please see\n http://activityworkshop.net/software/prune/\nfor more information and user guides. -dialog.about.title=About Prune dialog.about.version=Version dialog.about.build=Build dialog.about.summarytext1=Prune is a program for loading, displaying and editing data from GPS receivers. @@ -211,6 +240,7 @@ dialog.about.systeminfo.java3d=Java3d installed dialog.about.systeminfo.povray=Povray installed dialog.about.systeminfo.exiftool=Exiftool installed dialog.about.systeminfo.gpsbabel=Gpsbabel installed +dialog.about.systeminfo.gnuplot=Gnuplot installed dialog.about.yes=Yes dialog.about.no=No dialog.about.credits=Credits @@ -223,7 +253,6 @@ dialog.about.credits.devtools=Development tools dialog.about.credits.othertools=Other tools dialog.about.credits.thanks=Thanks to dialog.about.readme=Readme -dialog.checkversion.title=Check version dialog.checkversion.error=The version number couldn't be checked.\nPlease check the internet connection. dialog.checkversion.uptodate=You are using the latest version of Prune. dialog.checkversion.newversion1=A new version of Prune is now available! The latest version is now version @@ -243,8 +272,6 @@ dialog.3dlines.intro=These are the gridlines for the three-d view confirm.loadfile=Data loaded from file confirm.save.ok1=Successfully saved confirm.save.ok2=points to file -confirm.deleteduplicates.single=duplicate was deleted -confirm.deleteduplicates.multi=duplicates were deleted confirm.deletepoint.single=data point was removed confirm.deletepoint.multi=data points were removed confirm.point.edit=point edited @@ -288,14 +315,17 @@ button.selectnone=Select none button.preview=Preview button.guessfields=Guess fields button.showwebpage=Show webpage +button.gnuplotpath=Set gnuplot path # File types filetype.txt=TXT files filetype.jpeg=JPG files filetype.kmlkmz=KML, KMZ files filetype.kml=KML files +filetype.kmz=KMZ files filetype.gpx=GPX files filetype.pov=POV files +filetype.svg=SVG files # Display components display.nodata=No data loaded @@ -309,7 +339,6 @@ details.pointdetails=Point details details.index.selected=Index details.index.of=of details.nopointselection=No point selected -details.speed=Speed details.photofile=Photo file details.norangeselection=No range selected details.rangedetails=Range details @@ -332,12 +361,14 @@ details.photodetails=Photo details details.nophoto=No photo selected details.photo.loading=Loading details.photo.connected=Connected +map.overzoom=No maps available at this zoom level # Field names fieldname.latitude=Latitude fieldname.longitude=Longitude fieldname.altitude=Altitude fieldname.timestamp=Time +fieldname.time=Time fieldname.waypointname=Name fieldname.waypointtype=Type fieldname.newsegment=Segment @@ -346,6 +377,8 @@ fieldname.prefix=Field fieldname.distance=Distance fieldname.movingdistance=Moving distance fieldname.duration=Duration +fieldname.speed=Speed +fieldname.verticalspeed=Vertical speed # Measurement units units.original=Original @@ -360,6 +393,9 @@ units.kmh=km/h units.miles=Miles units.miles.short=mi units.mph=mph +units.metrespersec=m/s +units.feetpersec=ft/s +units.hours=hours units.degminsec=Deg-min-sec units.degmin=Deg-min units.deg=Degrees @@ -383,7 +419,6 @@ undo.deletephoto=remove photo undo.deleterange=delete range undo.compress=compress track undo.insert=insert points -undo.deleteduplicates=delete duplicates undo.reverse=reverse range undo.mergetracksegments=merge track segments undo.addtimeoffset=add time offset @@ -405,6 +440,7 @@ error.load.dialogtitle=Error loading data error.load.noread=Cannot read file error.load.nopoints=No coordinate information found in the file error.load.unknownxml=Unrecognised xml format: +error.load.noxmlinzip=No xml file found inside zip file error.load.othererror=Error reading file: error.jpegload.dialogtitle=Error loading photos error.jpegload.nofilesfound=No files found @@ -415,10 +451,8 @@ error.undofailed.title=Undo failed error.undofailed.text=Failed to undo operation error.function.noop.title=Function had no effect error.rearrange.noop=Rearranging waypoints had no effect -error.function.notimplemented=Sorry, this function has not yet been implemented. error.function.notavailable.title=Function not available error.function.nojava3d=This function requires the Java3d library,\navailable from Sun.com. -error.3d.title=Error in 3d display error.3d=An error occurred with the 3d display error.readme.notfound=Readme file not found error.osmimage.dialogtitle=Error loading map images diff --git a/tim/prune/lang/prune-texts_es.properties b/tim/prune/lang/prune-texts_es.properties index cfa1a09..6dbaddb 100644 --- a/tim/prune/lang/prune-texts_es.properties +++ b/tim/prune/lang/prune-texts_es.properties @@ -5,11 +5,7 @@ menu.file=Archivo menu.file.open=Abrir archivo menu.file.addphotos=Cargar fotos -menu.file.loadfromgps=Cargar datos del GPS menu.file.save=Guardar -menu.file.exportkml=Exportar KML -menu.file.exportgpx=Exportar GPX -menu.file.exportpov=Exportar POV menu.file.exit=Salir menu.edit=Editar menu.edit.undo=Deshacer @@ -18,11 +14,10 @@ menu.edit.editpoint=Editar punto menu.edit.editwaypointname=Editar nombre de waypoint menu.edit.deletepoint=Eliminar punto menu.edit.deleterange=Eliminar rango -menu.edit.deleteduplicates=Eliminar duplicados -menu.edit.compress=Comprimir track +menu.edit.deletemarked= menu.edit.interpolate=Interpolar +menu.edit.average=Crear punto a la media del rango menu.edit.reverse=Invertir rango -menu.edit.addtimeoffset= menu.edit.mergetracksegments=Unir los segmentos de track menu.edit.rearrange=Reorganizar waypoints menu.edit.rearrange.start=Volver al comienzo @@ -38,16 +33,14 @@ menu.photo=Foto menu.photo.saveexif=Guardar Exif menu.photo.connect=Conectar con punto menu.photo.disconnect=Desconectar de punto -menu.photo.correlate=Correlacionar todas las fotos menu.photo.delete=Eliminar foto menu.view=Ver -menu.view.show3d=Mostrar en 3-D menu.view.browser=Mapa en un navegador menu.view.browser.google=Google maps menu.view.browser.openstreetmap=Openstreetmap +menu.view.browser.mapquest= +menu.view.browser.yahoo= menu.help=Ayuda -menu.help.about=Acerca de Prune -menu.help.checkversion=Buscar una nueva versión # Popup menu for map menu.map.zoomin=Ampliar zoom menu.map.zoomout=Reducir zoom @@ -57,6 +50,23 @@ menu.map.connect=Conectar puntos de track menu.map.autopan=Posicionar automáticamente menu.map.showmap=Mostrar el mapa +# Functions +function.loadfromgps=Cargar datos del GPS +function.sendtogps=Enviar datos al GPS +function.exportkml=Exportar KML +function.exportgpx=Exportar GPX +function.exportpov=Exportar POV +function.compress=Comprimir Track +function.addtimeoffset= +function.charts=Diagramas +function.show3d=Mostrar en 3-D +function.distances=Distancias +function.setmapbg=Configurar fondo de mapa +function.correlatephotos=Correlacionar fotos +function.help=Ayuda +function.about=Acerca de Prune +function.checkversion=Buscar una nueva versión + # Dialogs dialog.exit.confirm.title=Salir de Prune dialog.exit.confirm.text=Los datos han sido modificados. Desea salir de Prune? @@ -66,11 +76,6 @@ dialog.deletepoint.title=Borrar punto dialog.deletepoint.deletephoto=Borrar la foto tambien? dialog.deletephoto.title=Borrar foto dialog.deletephoto.deletepoint=Borrar el punto tambien? -dialog.deleteduplicates.title=Borrar duplicados -dialog.deleteduplicates.nonefound=Ningún duplicado encontrado -dialog.compresstrack.title=Comprimir Track -dialog.compresstrack.parameter.text=Parámetro para comprimir (menor valor => mayor compresión) -dialog.compresstrack.nonefound=Ningún punto eliminado dialog.openoptions.title=Opciones de abrir dialog.openoptions.filesnippet=Extraer archivo dialog.load.table.field=Campo @@ -85,19 +90,20 @@ dialog.delimiter.other=Otro dialog.openoptions.deliminfo.records=datos, con dialog.openoptions.deliminfo.fields=campos dialog.openoptions.deliminfo.norecords=Ningun dato -dialog.openoptions.tabledesc=Extraer archivo dialog.openoptions.altitudeunits=Unidades altitud dialog.jpegload.subdirectories=Incluir subdirectorios dialog.jpegload.loadjpegswithoutcoords=Fotos sin coordenadas tambien dialog.jpegload.loadjpegsoutsidearea= dialog.jpegload.progress.title=Cargando fotos dialog.jpegload.progress=Por favor espere mientras se buscan las fotos -dialog.gpsload.title= dialog.gpsload.nogpsbabel=gpsbabel program no encontrado. Desea continuar? dialog.gpsload.device= dialog.gpsload.format= dialog.gpsload.getwaypoints= dialog.gpsload.gettracks= +dialog.gpssend.sendwaypoints= +dialog.gpssend.sendtracks= +dialog.gpssend.trackname=Nombre del track dialog.saveoptions.title=Guardar archivo dialog.save.fieldstosave=Campos a guardar dialog.save.table.field=Campo @@ -109,16 +115,13 @@ dialog.save.altitudeunits=Unidades de las altitudes dialog.save.timestampformat=Format del tiempo dialog.save.overwrite.title=El archivo ya existe dialog.save.overwrite.text=El archivo ya existe, desea sobreescribirlo? -dialog.exportkml.title=Exportar KML dialog.exportkml.text=Descripción para los datos dialog.exportkml.altitude=Incluir altitudes (para aviación) dialog.exportkml.kmz=Comprimir al archivo kmz dialog.exportkml.exportimages=Exportar fotos al kmz -dialog.exportgpx.title=Exportar GPX dialog.exportgpx.name=Nombre dialog.exportgpx.desc=Descripción dialog.exportgpx.includetimestamps=Tiempo tambien -dialog.exportpov.title=Exportar POV dialog.exportpov.text=Introdzca los Parametros para exportar dialog.exportpov.font=Fuente dialog.exportpov.camerax=Cámara X @@ -152,7 +155,6 @@ dialog.pointnameedit.name=Nombre de waypoint dialog.pointnameedit.uppercase=Mayúsculas dialog.pointnameedit.lowercase=minúsculas dialog.pointnameedit.sentencecase=Mezcla -dialog.addtimeoffset.title= dialog.addtimeoffset.add= dialog.addtimeoffset.subtract= dialog.addtimeoffset.days=Dias @@ -172,7 +174,26 @@ dialog.saveexif.photostatus.connected=Conectada dialog.saveexif.photostatus.disconnected=Desconectada dialog.saveexif.photostatus.modified=Modificada dialog.saveexif.overwrite=Sobreescribirlar archivos? -dialog.correlate.title=Correlacionar fotos +dialog.charts.xaxis=Eje de abscisas +dialog.charts.yaxis=Eje vertical +dialog.charts.output= +dialog.charts.screen= +dialog.charts.svg= +dialog.charts.svgwidth= +dialog.charts.svgheight= +dialog.charts.needaltitudeortimes= +dialog.charts.gnuplotpath= +dialog.charts.gnuplotnotfound= +dialog.distances.intro= +dialog.distances.column.from=De punto +dialog.distances.column.to=Al punto +dialog.distances.currentpoint=Punto actual +dialog.distances.toofewpoints= +dialog.setmapbg.mapnik=Mapnik (por defecto) +dialog.setmapbg.osma= +dialog.setmapbg.cyclemap= +dialog.setmapbg.other=Otro +dialog.setmapbg.server= dialog.correlate.notimestamps=No hay información de tiempo para los puntos, así que no hay nada que correlacionar con las fotos. dialog.correlate.nouncorrelatedphotos=No hay fotos no correlacionadas.\nEstá seguro de que desea continuar? dialog.correlate.photoselect.intro=Seleccione una de estas fotos correlacionadas para usar como margen de tiempo @@ -195,8 +216,16 @@ dialog.correlate.options.nodistancelimit=Sin l dialog.correlate.options.distancelimit=Límite de distancia dialog.correlate.options.correlate=Correlacionar dialog.correlate.alloutsiderange=Todas las fotos están fuera del margen horario del track, por lo que ninguna puede ser correlada.\nIntente cambiar el margen o correle manualmente al menos una foto. +dialog.compress.nonefound=Ningún punto eliminado +dialog.compress.duplicates.title=Eliminar duplicados +dialog.compress.closepoints.title= +dialog.compress.closepoints.paramdesc= +dialog.compress.wackypoints.title= +dialog.compress.wackypoints.paramdesc= +dialog.compress.singletons.title= +dialog.compress.singletons.paramdesc= +dialog.compress.summarylabel= dialog.help.help=Por favor, ver\n http://activityworkshop.net/software/prune/\npara más información y guías del usuario. -dialog.about.title=Acerca de Prune dialog.about.version=Versión dialog.about.build=Construir dialog.about.summarytext1=Prune es un programa para cargar, mostrar y editar datos de receptores GPS. @@ -211,6 +240,7 @@ dialog.about.systeminfo.java3d=Java3d instalado dialog.about.systeminfo.povray=Povray instalado dialog.about.systeminfo.exiftool=Exiftool instalado dialog.about.systeminfo.gpsbabel=Gpsbabel instalado +dialog.about.systeminfo.gnuplot=Gnuplot instalado dialog.about.yes=Si dialog.about.no=No dialog.about.credits=Credits @@ -223,7 +253,6 @@ dialog.about.credits.devtools=Herramientas de desarrollo dialog.about.credits.othertools=Otras herramientas dialog.about.credits.thanks=Gracias a dialog.about.readme=Readme -dialog.checkversion.title= dialog.checkversion.error= dialog.checkversion.uptodate= dialog.checkversion.newversion1= @@ -243,8 +272,6 @@ dialog.3dlines.intro=Informaci confirm.loadfile=Dato cargado de confirm.save.ok1=Guardando confirm.save.ok2=puntos al archivo -confirm.deleteduplicates.single=duplicado eliminado -confirm.deleteduplicates.multi=duplicados eliminados confirm.deletepoint.single=punto eliminado confirm.deletepoint.multi=puntos eliminados confirm.point.edit=Punto editado @@ -288,14 +315,17 @@ button.selectnone=Seleccionar nada button.preview=Previsualización button.guessfields=Adivinar campos button.showwebpage= +button.gnuplotpath= # File types filetype.txt=Archivos TXT filetype.jpeg=Archivos JPG filetype.kmlkmz=Archivos KML, KMZ filetype.kml=Archivos KML +filetype.kmz=Archivos KMZ filetype.gpx=Archivos GPX filetype.pov=Archivos POV +filetype.svg=Archivos SVG # Display components display.nodata=Ningún dato cargado @@ -309,7 +339,6 @@ details.pointdetails=Detalles del punto details.index.selected=Indice seleccionado details.index.of=de details.nopointselection=Ningún punto seleccionado -details.speed=Velocidad details.photofile=Archivo de fotos details.norangeselection=Ningún rango seleccionado details.rangedetails=Detalles del rango @@ -332,12 +361,14 @@ details.photodetails=Detalles del Foto details.nophoto=Ninguna foto seleccionada details.photo.loading=Cargando details.photo.connected=Conectada +map.overzoom= # Field names fieldname.latitude=Latitud fieldname.longitude=Longitud fieldname.altitude=Altitud fieldname.timestamp=Información de tiempo +fieldname.time=Tiempo fieldname.waypointname=Nombre fieldname.waypointtype=Tipo fieldname.newsegment=Segmento @@ -346,6 +377,8 @@ fieldname.prefix=Campo fieldname.distance=Distancia fieldname.movingdistance= fieldname.duration=Duración +fieldname.speed=Velocidad +fieldname.verticalspeed= # Measurement units units.original=Original @@ -360,6 +393,9 @@ units.kmh=km/h units.miles=Millas units.miles.short=mi units.mph=mi/h +units.metrespersec=m/s +units.feetpersec=ft/s +units.hours=horas units.degminsec=Gra-min-seg units.degmin=Gra-min units.deg=Grados @@ -383,7 +419,6 @@ undo.deletephoto=eliminar foto undo.deleterange=eliminar rango undo.compress=comprimir track undo.insert=insertar puntos -undo.deleteduplicates=eliminar duplicados undo.reverse=invertir rango undo.mergetracksegments=unir los segmentos de track undo.addtimeoffset= @@ -405,6 +440,7 @@ error.load.dialogtitle=Fallo al cargar datos error.load.noread=No se puede leer el fichero error.load.nopoints=Ninguna información coordenadas encontrada error.load.unknownxml=Formato xml no reconocido: +error.load.noxmlinzip= error.load.othererror=Fallo al cargar datos: error.jpegload.dialogtitle=Error cargando fotos error.jpegload.nofilesfound=Ningún archivo encontrado @@ -415,10 +451,8 @@ error.undofailed.title=Fallo al deshacer error.undofailed.text=No ha sido posible deshacer la operación error.function.noop.title=La función no se ha efectuado error.rearrange.noop=Reordenación de waypoints no se ha efectuado -error.function.notimplemented=Esta función aún no ha sido implementada error.function.notavailable.title=Función no disponible error.function.nojava3d=Esta función requiere la librería Java3d, disponible en Sun.com. -error.3d.title=Fallo al mostrar 3-D error.3d=Ha ocurrido un error con la función 3-D error.readme.notfound=Archivo readme no encontrado error.osmimage.dialogtitle=Error al cargar el mapa diff --git a/tim/prune/lang/prune-texts_fr.properties b/tim/prune/lang/prune-texts_fr.properties index 0926a55..c76eb66 100644 --- a/tim/prune/lang/prune-texts_fr.properties +++ b/tim/prune/lang/prune-texts_fr.properties @@ -4,12 +4,8 @@ # Menu entries menu.file=Fichier menu.file.open=Ouvrir fichier -menu.file.addphotos=Ouvrir photos -menu.file.loadfromgps=Charger à partir du GPS +menu.file.addphotos=Ajouter photos menu.file.save=Enregistrer -menu.file.exportkml=Exporter en KML -menu.file.exportgpx=Exporter en GPX -menu.file.exportpov=Exporter en POV menu.file.exit=Quitter menu.edit=Édition menu.edit.undo=Annuler @@ -18,17 +14,16 @@ menu.edit.editpoint=Editer le point menu.edit.editwaypointname=Editer le nom du waypoint menu.edit.deletepoint=Supprimer le point menu.edit.deleterange=Supprimer l'étendue -menu.edit.deleteduplicates=Supprimer les doublons -menu.edit.compress=Compacter la trace +menu.edit.deletemarked=Supprimer les points marqués menu.edit.interpolate=Interpoler +menu.edit.average=Créer un point pour la sélection menu.edit.reverse=Inverser l'étendue -menu.edit.addtimeoffset= menu.edit.mergetracksegments=Fusionner les segments de trace menu.edit.rearrange=Réarranger les waypoints menu.edit.rearrange.start=Tous au début du fichier menu.edit.rearrange.end=Tous à la fin du fichier menu.edit.rearrange.nearest=Chacun au point de trace le plus proche -menu.edit.cutandmove= +menu.edit.cutandmove=Couper et bouger la sélection menu.select=Sélectionner menu.select.all=Tout sélectionner menu.select.none=Rien sélectionner @@ -38,39 +33,49 @@ menu.photo=Photo menu.photo.saveexif=Enregistrer dans les Exif menu.photo.connect=Relier au point menu.photo.disconnect=Détacher du point -menu.photo.correlate=Corréler toutes les photos menu.photo.delete=Retirer la photo menu.view=Affichage -menu.view.show3d=Montrer en 3D menu.view.browser=Ouvrir la carte dans le navigateur menu.view.browser.google=Google maps menu.view.browser.openstreetmap=Openstreetmap +menu.view.browser.mapquest=Mapquest +menu.view.browser.yahoo=Yahoo maps menu.help=Aide -menu.help.about=À propos de Prune -menu.help.checkversion= # Popup menu for map menu.map.zoomin=Zoom avant menu.map.zoomout=Zoom arrière menu.map.zoomfull=Adapter à la vue -menu.map.newpoint= +menu.map.newpoint=Ajouter un point menu.map.connect=Relier les points de trace menu.map.autopan=Déplacement automatique menu.map.showmap=Montrer la carte +# Functions +function.loadfromgps=Télécharger du GPS +function.sendtogps=Envoyer au GPS +function.exportkml=Exporter en KML +function.exportgpx=Exporter en GPX +function.exportpov=Exporter en POV +function.compress=Compresser la trace +function.addtimeoffset=Ajouter un décalage d'horaire +function.charts=Graphiques +function.show3d=Montrer en 3D +function.distances=Distances +function.setmapbg=Définir le fond de carte +function.correlatephotos=Corréler les photos +function.help=Aide +function.about=À propos de Prune +function.checkversion=Chercher une mise à jour + # Dialogs dialog.exit.confirm.title=Quitter Prune -dialog.exit.confirm.text=Les données ont été modifiées. Souhaitez-vous quitter Prune sans enregistrer ? +dialog.exit.confirm.text=Les données ont été modifiées. Souhaitez-vous quitter Prune sans les enregistrer ? dialog.openappend.title=Ajouter aux données existantes dialog.openappend.text=Ajouter aux données déjà chargées ? dialog.deletepoint.title=Effacer le point dialog.deletepoint.deletephoto=Effacer la photo attachée à ce point ? dialog.deletephoto.title=Effacer la photo dialog.deletephoto.deletepoint=Effacer le point attaché à cette photo ? -dialog.deleteduplicates.title=Effacer les doublons -dialog.deleteduplicates.nonefound=Aucun doublon trouvé -dialog.compresstrack.title=Compresser la trace -dialog.compresstrack.parameter.text=Paramètre pour la compression (faible chiffre = forte compression) -dialog.compresstrack.nonefound=Pas de données à effacer dialog.openoptions.title=Ouvrir options dialog.openoptions.filesnippet=Extrait de fichier dialog.load.table.field=Champ @@ -85,19 +90,20 @@ dialog.delimiter.other=Autres dialog.openoptions.deliminfo.records=enregistrements, avec dialog.openoptions.deliminfo.fields=champs dialog.openoptions.deliminfo.norecords=Pas d'enregistrements -dialog.openoptions.tabledesc=Extrait de fichier dialog.openoptions.altitudeunits=Unités d'altitude dialog.jpegload.subdirectories=Inclure les sous-dossiers dialog.jpegload.loadjpegswithoutcoords=Inclure les photos sans coordonnées -dialog.jpegload.loadjpegsoutsidearea= +dialog.jpegload.loadjpegsoutsidearea=Inclure des photos en dehors de l'endroit actuel dialog.jpegload.progress.title=Chargement des photos dialog.jpegload.progress=Veuillez patienter pendant la recherche des photos -dialog.gpsload.title= dialog.gpsload.nogpsbabel=Gpsbabel introuvable. Continuer ? -dialog.gpsload.device= -dialog.gpsload.format= -dialog.gpsload.getwaypoints= -dialog.gpsload.gettracks= +dialog.gpsload.device=Chemin du périphérique +dialog.gpsload.format=Format +dialog.gpsload.getwaypoints=Télécharger les waypoints +dialog.gpsload.gettracks=Télécharger les traces +dialog.gpssend.sendwaypoints=Envoyer les waypoints +dialog.gpssend.sendtracks=Envoyer les traces +dialog.gpssend.trackname=Nom de trace dialog.saveoptions.title=Enregistrer le fichier dialog.save.fieldstosave=Champs à enregistrer dialog.save.table.field=Champ @@ -109,29 +115,26 @@ dialog.save.altitudeunits=Unit dialog.save.timestampformat=Format de l'heure dialog.save.overwrite.title=Le fichier existe déjà dialog.save.overwrite.text=Ce fichier existe déjà. Êtes-vous sûr de vouloir écraser ce fichier ? -dialog.exportkml.title=Exporter en KML dialog.exportkml.text=Titre pour les données dialog.exportkml.altitude=Inclure les altitudes (pour aviation) dialog.exportkml.kmz=Compresser au format kmz dialog.exportkml.exportimages=Exporter les vignettes au format kmz -dialog.exportgpx.title=Exporter en GPX dialog.exportgpx.name=Nom dialog.exportgpx.desc=Légende -dialog.exportgpx.includetimestamps= -dialog.exportpov.title=Exporter en POV +dialog.exportgpx.includetimestamps=Inclure l'heure pour chaque point dialog.exportpov.text=Entrez les paramètres pour l'export POV dialog.exportpov.font=Police -dialog.exportpov.camerax=Camera X -dialog.exportpov.cameray=Camera Y -dialog.exportpov.cameraz=Camera Z -dialog.exportpov.modelstyle= -dialog.exportpov.ballsandsticks= -dialog.exportpov.tubesandwalls= -dialog.exportpov.warningtracksize=Cette trace possède un grand nombre de points, Java3D peut ne pas pouvoir l'afficher.\nEtes-vous sûr de vouloir continuer ? +dialog.exportpov.camerax=Caméra X +dialog.exportpov.cameray=Caméra Y +dialog.exportpov.cameraz=Caméra Z +dialog.exportpov.modelstyle=Style du modèle +dialog.exportpov.ballsandsticks=Points et bâtons +dialog.exportpov.tubesandwalls=Tubes et murs +dialog.exportpov.warningtracksize=Cette trace possède un grand nombre de points, Java3D peut ne pas pouvoir l'afficher.\nÊtes-vous sûr de vouloir continuer ? dialog.confirmreversetrack.title=Confirmer l'inversion -dialog.confirmreversetrack.text=Cette trace contient des informations temporelles qui seront désordonnées après une inversion.\nEtes-vous sûr de vouloir inverser cette section ? -dialog.confirmcutandmove.title=Confirmer ... -dialog.confirmcutandmove.text=Cette trace contient des informations temporelles qui seront désordonnées après une ....\nEtes-vous sûr de vouloir ... cette section ? +dialog.confirmreversetrack.text=Cette trace contient des informations temporelles qui seront désordonnées après une inversion.\nÊtes-vous sûr de vouloir inverser cette section ? +dialog.confirmcutandmove.title=Confirmer le déplacement +dialog.confirmcutandmove.text=Cette trace contient des informations temporelles qui seront désordonnées après un déplacement.\nÊtes-vous sûr de vouloir déplacer cette section ? dialog.interpolate.title=Interpoler les points dialog.interpolate.parameter.text=Nombre de points à insérer entre les points sélectionnés dialog.undo.title=Annuler les actions @@ -152,15 +155,14 @@ dialog.pointnameedit.name=Nom de waypoint dialog.pointnameedit.uppercase=CASSE MAJUSCULES dialog.pointnameedit.lowercase=casse minuscules dialog.pointnameedit.sentencecase=Casse Phrase -dialog.addtimeoffset.title= -dialog.addtimeoffset.add= -dialog.addtimeoffset.subtract= +dialog.addtimeoffset.add=Retarder l'heure +dialog.addtimeoffset.subtract=Avancer l'heure dialog.addtimeoffset.days=Jours dialog.addtimeoffset.hours=Heures dialog.addtimeoffset.minutes=Minutes -dialog.addtimeoffset.notimestamps= -dialog.connect.title= -dialog.connectphoto.clonepoint= +dialog.addtimeoffset.notimestamps=Ne peut pas décaler l'heure; cette sélection ne contient pas de données d'heure +dialog.connect.title=Lier la photo au point +dialog.connectphoto.clonepoint=Ce point est déjà lié à une photo.\nVoulez-vous faire une copie de ce point ? dialog.saveexif.title=Enregistrer Exif dialog.saveexif.intro=Sélectionner les photos à sauver à l'aide des cases à cocher dialog.saveexif.nothingtosave=Coordonnées inchangées, rien à enregistrer @@ -172,7 +174,26 @@ dialog.saveexif.photostatus.connected=Connect dialog.saveexif.photostatus.disconnected=Déconnecté dialog.saveexif.photostatus.modified=Modifié dialog.saveexif.overwrite=Ecraser les fichiers -dialog.correlate.title=Corréler les photos +dialog.charts.xaxis=Axe des x +dialog.charts.yaxis=Axe des y +dialog.charts.output=Sortie +dialog.charts.screen=Sortie sur écran +dialog.charts.svg=Sortie dans un fichier SVG +dialog.charts.svgwidth=Largeur de l'image SVG +dialog.charts.svgheight=Hauteur de l'image SVG +dialog.charts.needaltitudeortimes=La trace ne peut générer des graphiques sans disposer d'altitudes ou d'indications temporelles +dialog.charts.gnuplotpath=Chemin gnuplot +dialog.charts.gnuplotnotfound=Gnuplot est introuvable dans le chemin indiqué +dialog.distances.intro=Distances à vol d'oiseau entre des points +dialog.distances.column.from=Du point +dialog.distances.column.to=Vers le point +dialog.distances.currentpoint=Point courant +dialog.distances.toofewpoints=Cette fonction a besoin de waypoints pour calculer les distances entre eux +dialog.setmapbg.mapnik=Mapnik (défaut) +dialog.setmapbg.osma=Osma +dialog.setmapbg.cyclemap=Cyclemap +dialog.setmapbg.other=Autres +dialog.setmapbg.server=URL du serveur dialog.correlate.notimestamps=Les points n'ont pas d'indication de temps, il n'est pas possible de les corréler. dialog.correlate.nouncorrelatedphotos=Il n'y a pas de photos non-corrélées.\nVoulez-vous continuer ? dialog.correlate.photoselect.intro=Sélectionner une de ces photos corrélées pour définir le décalage de temps @@ -195,15 +216,23 @@ dialog.correlate.options.nodistancelimit=Pas de limite de distance dialog.correlate.options.distancelimit=Limite de distance dialog.correlate.options.correlate=Corréler dialog.correlate.alloutsiderange=Les photos ne correspondent pas à la plage de temps de la trace, aucune ne peut être corrélée.\nEssayez de modifier le décalage ou de corréler manuellement au moins une photo. +dialog.compress.nonefound=Pas de données à effacer +dialog.compress.duplicates.title=Suppression des doublons +dialog.compress.closepoints.title=Suppression des points voisins +dialog.compress.closepoints.paramdesc=Taille du voisinage +dialog.compress.wackypoints.title=Suppression des points anormaux +dialog.compress.wackypoints.paramdesc=Distance +dialog.compress.singletons.title=Suppression des points isolés +dialog.compress.singletons.paramdesc=Distance +dialog.compress.summarylabel=Points à supprimer dialog.help.help=Consultez la page\n http://activityworkshop.net/software/prune/\npour plus de détails et des manuels utilisateur. -dialog.about.title=À propos de Prune dialog.about.version=Version dialog.about.build=Build dialog.about.summarytext1=Prune est un programme pour charger, afficher et éditer des données de récepteurs GPS. dialog.about.summarytext2=Distribué sous license Gnu GPL pour un usage et une amélioration libres, ouverts et mondiaux.
La copie, la redistribution et la modification sont autorisées et encouragées
selon les conditions détaillées dans le fichier license.txt inclus. dialog.about.summarytext3=Consultez la page http://activityworkshop.net/ pour plus de détails et des manuels utilisateur. -dialog.about.languages= -dialog.about.translatedby=Texte en français par Petrovsk. +dialog.about.languages=Langues disponibles +dialog.about.translatedby=Texte en français par Petrovsk et theYinYeti. dialog.about.systeminfo=Info Système dialog.about.systeminfo.os=Système d'exploitation dialog.about.systeminfo.java=Java Runtime @@ -211,6 +240,7 @@ dialog.about.systeminfo.java3d=Java3d install dialog.about.systeminfo.povray=Povray installé dialog.about.systeminfo.exiftool=Exiftool installé dialog.about.systeminfo.gpsbabel=Gpsbabel installé +dialog.about.systeminfo.gnuplot=Gnuplot installé dialog.about.yes=Oui dialog.about.no=Non dialog.about.credits=Crédits @@ -223,14 +253,13 @@ dialog.about.credits.devtools=Outils de d dialog.about.credits.othertools=Autre outils dialog.about.credits.thanks=Merci à dialog.about.readme=Lisez-moi -dialog.checkversion.title= -dialog.checkversion.error= -dialog.checkversion.uptodate= -dialog.checkversion.newversion1= -dialog.checkversion.newversion2= -dialog.checkversion.releasedate1= -dialog.checkversion.releasedate2= -dialog.checkversion.download=To download the new version, go to http://activityworkshop.net/software/prune/download.html. +dialog.checkversion.error=Ne peut pas vérifier la version.\nVeuillez vérifier votre connexion Internet. +dialog.checkversion.uptodate=Vous utilisez déjà la version actuelle de Prune. +dialog.checkversion.newversion1=La version actuelle est maintenant la version +dialog.checkversion.newversion2=. +dialog.checkversion.releasedate1=La nouvelle version est sortie le +dialog.checkversion.releasedate2=. +dialog.checkversion.download=Pour télécharger la nouvelle version, aller à http://activityworkshop.net/software/prune/download.html. # 3d window dialog.3d.title=Vue 3D de Prune @@ -243,16 +272,14 @@ dialog.3dlines.intro=Ceci est la grille pour la vue 3D confirm.loadfile=Données chargées depuis le fichier confirm.save.ok1=Enregistrement réussi de confirm.save.ok2=points dans le fichier -confirm.deleteduplicates.single=doublon a été effacé -confirm.deleteduplicates.multi=doublons ont été effacés confirm.deletepoint.single=point a été effacé confirm.deletepoint.multi=points ont été effacés confirm.point.edit=point édité confirm.mergetracksegments=Segments de trace ont été fusionné confirm.reverserange=Etendue inversée -confirm.addtimeoffset= -confirm.rearrangewaypoints= -confirm.cutandmove= +confirm.addtimeoffset=Décalage ajouté +confirm.rearrangewaypoints=Waypoints réarrangés +confirm.cutandmove=Sélection déplacée confirm.saveexif.ok1=Enregistrement de confirm.saveexif.ok2=fichiers photo confirm.undo.single=opération annulée @@ -263,7 +290,7 @@ confirm.photo.connect=photo reli confirm.photo.disconnect=photo détachée confirm.correlate.single=photo a été corrélée confirm.correlate.multi=photos ont été corrélées -confirm.createpoint= +confirm.createpoint=Point créé # Buttons button.ok=OK @@ -287,15 +314,18 @@ button.selectall=Tout s button.selectnone=Ne rien sélectionner button.preview=Aperçu button.guessfields=Deviner les champs -button.showwebpage= +button.showwebpage=Montrer page web +button.gnuplotpath=Localiser gnuplot # File types filetype.txt=Fichiers TXT filetype.jpeg=Fichiers JPG filetype.kmlkmz=Fichiers KML, KMZ filetype.kml=Fichiers KML +filetype.kmz=Fichiers KMZ filetype.gpx=Fichiers GPX filetype.pov=Fichiers POV +filetype.svg=Fichiers SVG # Display components display.nodata=Pas de données chargées @@ -309,7 +339,6 @@ details.pointdetails=D details.index.selected=Index details.index.of=sur details.nopointselection=Aucun point choisi -details.speed=Vitesse details.photofile=Fichier photo details.norangeselection=Aucune étendue sélectionnée details.rangedetails=Détails sur l'étendue @@ -325,27 +354,31 @@ display.range.time.mins=m display.range.time.hours=h display.range.time.days=j details.range.avespeed=Vitesse moyenne -details.range.avemovingspeed= +details.range.avemovingspeed=Moyenne continue details.waypointsphotos.waypoints=Waypoints details.waypointsphotos.photos=Photos details.photodetails=Détails de la photo details.nophoto=Pas de photo details.photo.loading=Chargement details.photo.connected=Reliée +map.overzoom=Aucune carte disponible à ce niveau de zoom # Field names fieldname.latitude=Latitude fieldname.longitude=Longitude fieldname.altitude=Altitude fieldname.timestamp=Date et heure +fieldname.time=Temps fieldname.waypointname=Nom fieldname.waypointtype=Type fieldname.newsegment=Segment fieldname.custom=Personnalisé fieldname.prefix=Champ fieldname.distance=Distance -fieldname.movingdistance= +fieldname.movingdistance=Distance continue fieldname.duration=Durée +fieldname.speed=Vitesse +fieldname.verticalspeed=Vitesse verticale # Measurement units units.original=Original @@ -360,6 +393,9 @@ units.kmh=km/h units.miles=Miles units.miles.short=mi units.mph=mi/h +units.metrespersec=m/s +units.feetpersec=ft/s +units.hours=heures units.degminsec=Deg-min-sec units.degmin=Deg-min units.deg=Degrés @@ -383,16 +419,15 @@ undo.deletephoto=retirer la photo undo.deleterange=effacer l'étendue undo.compress=compresser la trace undo.insert=insérer les points -undo.deleteduplicates=effacer les doublons undo.reverse=inverser l'étendue undo.mergetracksegments=fusionner les segments de trace -undo.addtimeoffset= +undo.addtimeoffset=ajouter décalage d'heure undo.rearrangewaypoints=réarranger les waypoints -undo.cutandmove= +undo.cutandmove=déplacer la sélection undo.connectphoto=relier la photo undo.disconnectphoto=détacher la photo undo.correlate=corréler les photos -undo.createpoint= +undo.createpoint=ajouter un point # Error messages error.save.dialogtitle=Erreur à l'enregistrement des données @@ -405,6 +440,7 @@ error.load.dialogtitle=Erreur au chargement des donn error.load.noread=Fichier illisible error.load.nopoints=Aucune coordonnée trouvée dans le fichier error.load.unknownxml=Format xml non-reconnu : +error.load.noxmlinzip= error.load.othererror=Erreur à la lecture du fichier : error.jpegload.dialogtitle=Erreur au chargement des photos error.jpegload.nofilesfound=Aucun fichier trouvé @@ -415,10 +451,8 @@ error.undofailed.title=Echec de l'annulation error.undofailed.text=Echec de l'opération d'annulation error.function.noop.title=Fonction sans effet error.rearrange.noop=Réarrangement des waypoints sans effet -error.function.notimplemented=Désolé, cette fonction n'a pas encore été implémentée. error.function.notavailable.title=Function non-disponible error.function.nojava3d=Cette fonction nécessite la librairie Java3d,\ndisponible sur Sun.com. -error.3d.title=Erreur dans l'affichage 3D error.3d=Un problème est survenu avec l'affichage 3D error.readme.notfound=Fichier Lisez-moi introuvable error.osmimage.dialogtitle=Erreur au chargement des portions de cartes diff --git a/tim/prune/lang/prune-texts_in.properties b/tim/prune/lang/prune-texts_in.properties new file mode 100644 index 0000000..e1daaf6 --- /dev/null +++ b/tim/prune/lang/prune-texts_in.properties @@ -0,0 +1,459 @@ +# Text entries for the Prune application +# Indonesian entries as extra + +# Menu entries +menu.file=Berkas +menu.file.open=Buka +menu.file.addphotos=Muat foto +menu.file.save=Simpan +menu.file.exit=Keluar +menu.edit=Ubah +menu.edit.undo=Batal +menu.edit.clearundo= +menu.edit.editpoint=Perbaiki titik +menu.edit.editwaypointname=Perbaiki Nama waypoint +menu.edit.deletepoint=Hapus titik +menu.edit.deleterange=Hapus jarak +menu.edit.deletemarked= +menu.edit.interpolate= +menu.edit.average= +menu.edit.reverse= +menu.edit.mergetracksegments= +menu.edit.rearrange= +menu.edit.rearrange.start= +menu.edit.rearrange.end= +menu.edit.rearrange.nearest= +menu.edit.cutandmove= +menu.select=Pilih +menu.select.all=Pilih semua +menu.select.none=Tidak memilih +menu.select.start= +menu.select.end= +menu.photo=Foto +menu.photo.saveexif=Simpan ke Exif +menu.photo.connect=Hubungkan ke titik +menu.photo.disconnect=Putuskan dari titik +menu.photo.delete= +menu.view=Lihat +menu.view.browser= +menu.view.browser.google= +menu.view.browser.openstreetmap= +menu.view.browser.mapquest= +menu.view.browser.yahoo= +menu.help=Bantuan +# Popup menu for map +menu.map.zoomin=Perbesar +menu.map.zoomout=Perkecil +menu.map.zoomfull= +menu.map.newpoint=Buat titik baru +menu.map.connect=Hubungkan titik jalur +menu.map.autopan= +menu.map.showmap=Tampilkan peta + +# Functions +function.loadfromgps=Muat data dari GPS +function.sendtogps=Kirim data ke GPS +function.exportkml=Ekspor KML +function.exportgpx=Ekspor GPX +function.exportpov=Ekspor POV +function.compress=Padatkan jalur +function.addtimeoffset= +function.charts=Grafik +function.show3d=Lihat tiga-D +function.distances= +function.setmapbg= +function.correlatephotos=Korelasikan foto +function.help=Bantuan +function.about=Tentang Prune +function.checkversion= + +# Dialogs +dialog.exit.confirm.title= +dialog.exit.confirm.text= +dialog.openappend.title= +dialog.openappend.text= +dialog.deletepoint.title= +dialog.deletepoint.deletephoto= +dialog.deletephoto.title= +dialog.deletephoto.deletepoint= +dialog.openoptions.title= +dialog.openoptions.filesnippet= +dialog.load.table.field= +dialog.load.table.datatype=Jenis +dialog.load.table.description=Keterangan +dialog.delimiter.label= +dialog.delimiter.comma= +dialog.delimiter.tab= +dialog.delimiter.space= +dialog.delimiter.semicolon= +dialog.delimiter.other= +dialog.openoptions.deliminfo.records= +dialog.openoptions.deliminfo.fields= +dialog.openoptions.deliminfo.norecords= +dialog.openoptions.altitudeunits= +dialog.jpegload.subdirectories= +dialog.jpegload.loadjpegswithoutcoords= +dialog.jpegload.loadjpegsoutsidearea= +dialog.jpegload.progress.title= +dialog.jpegload.progress= +dialog.gpsload.nogpsbabel= +dialog.gpsload.device= +dialog.gpsload.format= +dialog.gpsload.getwaypoints= +dialog.gpsload.gettracks= +dialog.gpssend.sendwaypoints= +dialog.gpssend.sendtracks= +dialog.gpssend.trackname= +dialog.saveoptions.title= +dialog.save.fieldstosave= +dialog.save.table.field= +dialog.save.table.hasdata= +dialog.save.table.save= +dialog.save.headerrow= +dialog.save.coordinateunits= +dialog.save.altitudeunits= +dialog.save.timestampformat= +dialog.save.overwrite.title= +dialog.save.overwrite.text= +dialog.exportkml.text= +dialog.exportkml.altitude= +dialog.exportkml.kmz= +dialog.exportkml.exportimages= +dialog.exportgpx.name= +dialog.exportgpx.desc= +dialog.exportgpx.includetimestamps= +dialog.exportpov.text= +dialog.exportpov.font= +dialog.exportpov.camerax= +dialog.exportpov.cameray= +dialog.exportpov.cameraz= +dialog.exportpov.modelstyle= +dialog.exportpov.ballsandsticks= +dialog.exportpov.tubesandwalls= +dialog.exportpov.warningtracksize= +dialog.confirmreversetrack.title= +dialog.confirmreversetrack.text= +dialog.confirmcutandmove.title= +dialog.confirmcutandmove.text= +dialog.interpolate.title= +dialog.interpolate.parameter.text= +dialog.undo.title= +dialog.undo.pretext= +dialog.undo.none.title= +dialog.undo.none.text= +dialog.clearundo.title= +dialog.clearundo.text= +dialog.pointedit.title= +dialog.pointedit.text= +dialog.pointedit.table.field= +dialog.pointedit.table.value= +dialog.pointedit.table.changed= +dialog.pointedit.changevalue.text= +dialog.pointedit.changevalue.title= +dialog.pointnameedit.title= +dialog.pointnameedit.name=Nama +dialog.pointnameedit.uppercase= +dialog.pointnameedit.lowercase= +dialog.pointnameedit.sentencecase= +dialog.addtimeoffset.add= +dialog.addtimeoffset.subtract= +dialog.addtimeoffset.days= +dialog.addtimeoffset.hours= +dialog.addtimeoffset.minutes= +dialog.addtimeoffset.notimestamps= +dialog.connect.title= +dialog.connectphoto.clonepoint= +dialog.saveexif.title= +dialog.saveexif.intro= +dialog.saveexif.nothingtosave= +dialog.saveexif.noexiftool= +dialog.saveexif.table.photoname= +dialog.saveexif.table.status= +dialog.saveexif.table.save= +dialog.saveexif.photostatus.connected= +dialog.saveexif.photostatus.disconnected= +dialog.saveexif.photostatus.modified= +dialog.saveexif.overwrite= +dialog.charts.xaxis= +dialog.charts.yaxis= +dialog.charts.output= +dialog.charts.screen= +dialog.charts.svg= +dialog.charts.svgwidth= +dialog.charts.svgheight= +dialog.charts.needaltitudeortimes= +dialog.charts.gnuplotpath= +dialog.charts.gnuplotnotfound= +dialog.distances.intro= +dialog.distances.column.from=Awal +dialog.distances.column.to=Akhir +dialog.distances.currentpoint= +dialog.distances.toofewpoints= +dialog.setmapbg.mapnik= +dialog.setmapbg.osma= +dialog.setmapbg.cyclemap= +dialog.setmapbg.other= +dialog.setmapbg.server= +dialog.correlate.notimestamps= +dialog.correlate.nouncorrelatedphotos= +dialog.correlate.photoselect.intro= +dialog.correlate.photoselect.photoname= +dialog.correlate.photoselect.timediff= +dialog.correlate.photoselect.photolater= +dialog.correlate.options.tip= +dialog.correlate.options.intro= +dialog.correlate.options.offsetpanel= +dialog.correlate.options.offset= +dialog.correlate.options.offset.hours= +dialog.correlate.options.offset.minutes= +dialog.correlate.options.offset.seconds= +dialog.correlate.options.photolater= +dialog.correlate.options.pointlater= +dialog.correlate.options.limitspanel= +dialog.correlate.options.notimelimit= +dialog.correlate.options.timelimit= +dialog.correlate.options.nodistancelimit= +dialog.correlate.options.distancelimit= +dialog.correlate.options.correlate= +dialog.correlate.alloutsiderange= +dialog.compress.nonefound= +dialog.compress.duplicates.title= +dialog.compress.closepoints.title= +dialog.compress.closepoints.paramdesc= +dialog.compress.wackypoints.title= +dialog.compress.wackypoints.paramdesc= +dialog.compress.singletons.title= +dialog.compress.singletons.paramdesc= +dialog.compress.summarylabel= +dialog.help.help= +dialog.about.version= +dialog.about.build= +dialog.about.summarytext1= +dialog.about.summarytext2= +dialog.about.summarytext3= +dialog.about.languages=Bahasa +dialog.about.translatedby= +dialog.about.systeminfo= +dialog.about.systeminfo.os= +dialog.about.systeminfo.java= +dialog.about.systeminfo.java3d= +dialog.about.systeminfo.povray= +dialog.about.systeminfo.exiftool= +dialog.about.systeminfo.gpsbabel= +dialog.about.systeminfo.gnuplot= +dialog.about.yes=Ya +dialog.about.no=Tidak +dialog.about.credits= +dialog.about.credits.code= +dialog.about.credits.exifcode= +dialog.about.credits.icons= +dialog.about.credits.translators= +dialog.about.credits.translations= +dialog.about.credits.devtools= +dialog.about.credits.othertools= +dialog.about.credits.thanks= +dialog.about.readme= +dialog.checkversion.error= +dialog.checkversion.uptodate= +dialog.checkversion.newversion1= +dialog.checkversion.newversion2= +dialog.checkversion.releasedate1= +dialog.checkversion.releasedate2= +dialog.checkversion.download= + +# 3d window +dialog.3d.title= +dialog.3d.altitudecap= +dialog.3dlines.title= +dialog.3dlines.empty= +dialog.3dlines.intro= + +# Confirm messages || These are displayed as confirmation in the status bar +confirm.loadfile= +confirm.save.ok1= +confirm.save.ok2= +confirm.deletepoint.single= +confirm.deletepoint.multi= +confirm.point.edit= +confirm.mergetracksegments= +confirm.reverserange= +confirm.addtimeoffset= +confirm.rearrangewaypoints= +confirm.cutandmove= +confirm.saveexif.ok1= +confirm.saveexif.ok2= +confirm.undo.single= +confirm.undo.multi= +confirm.jpegload.single= +confirm.jpegload.multi= +confirm.photo.connect= +confirm.photo.disconnect= +confirm.correlate.single= +confirm.correlate.multi= +confirm.createpoint= + +# Buttons +button.ok= +button.back=Sebelumnya +button.next=Lanjut +button.finish= +button.cancel= +button.overwrite= +button.moveup= +button.movedown= +button.showlines= +button.edit= +button.exit= +button.close=Tutup +button.continue= +button.yes=Ya +button.no=Tidak +button.yestoall= +button.notoall= +button.selectall= +button.selectnone= +button.preview= +button.guessfields=Deteksi otomatis +button.showwebpage= +button.gnuplotpath= + +# File types +filetype.txt=Berkas teks +filetype.jpeg=Berkas JPG +filetype.kmlkmz=Berkas KML, KMZ +filetype.kml=Berkas KML +filetype.kmz=Berkas KMZ +filetype.gpx=Berkas GPX +filetype.pov=Berkas POV +filetype.svg=Berkas SVG + +# Display components +display.nodata= +display.noaltitudes= +details.trackdetails= +details.notrack= +details.track.points= +details.track.file= +details.track.numfiles= +details.pointdetails= +details.index.selected= +details.index.of= +details.nopointselection= +details.photofile= +details.norangeselection= +details.rangedetails= +details.range.selected= +details.range.to= +details.altitude.to= +details.range.climb= +details.range.descent= +details.coordformat= +details.distanceunits= +display.range.time.secs= +display.range.time.mins= +display.range.time.hours= +display.range.time.days= +details.range.avespeed= +details.range.avemovingspeed= +details.waypointsphotos.waypoints= +details.waypointsphotos.photos= +details.photodetails= +details.nophoto= +details.photo.loading=Membuka +details.photo.connected= +map.overzoom= + +# Field names +fieldname.latitude= +fieldname.longitude= +fieldname.altitude= +fieldname.timestamp= +fieldname.time= +fieldname.waypointname= +fieldname.waypointtype= +fieldname.newsegment= +fieldname.custom= +fieldname.prefix= +fieldname.distance= +fieldname.movingdistance= +fieldname.duration= +fieldname.speed= +fieldname.verticalspeed= + +# Measurement units +units.original= +units.default= +units.metres= +units.metres.short= +units.feet= +units.feet.short= +units.kilometres= +units.kilometres.short= +units.kmh= +units.miles= +units.miles.short= +units.mph= +units.metrespersec= +units.feetpersec= +units.hours= +units.degminsec= +units.degmin= +units.deg= +units.iso8601= + +# External urls +url.googlemaps= + +# Cardinals for 3d plots +cardinal.n= +cardinal.s= +cardinal.e= +cardinal.w= + +# Undo operations +undo.load= +undo.loadphotos= +undo.editpoint= +undo.deletepoint= +undo.deletephoto= +undo.deleterange= +undo.compress= +undo.insert= +undo.reverse= +undo.mergetracksegments= +undo.addtimeoffset= +undo.rearrangewaypoints= +undo.cutandmove= +undo.connectphoto= +undo.disconnectphoto= +undo.correlate= +undo.createpoint= + +# Error messages +error.save.dialogtitle= +error.save.nodata= +error.save.failed= +error.saveexif.filenotfound= +error.saveexif.cannotoverwrite1= +error.saveexif.cannotoverwrite2= +error.load.dialogtitle= +error.load.noread= +error.load.nopoints= +error.load.unknownxml= +error.load.noxmlinzip= +error.load.othererror= +error.jpegload.dialogtitle= +error.jpegload.nofilesfound= +error.jpegload.nojpegsfound= +error.jpegload.noexiffound= +error.jpegload.nogpsfound= +error.undofailed.title= +error.undofailed.text= +error.function.noop.title= +error.rearrange.noop= +error.function.notavailable.title= +error.function.nojava3d= +error.3d= +error.readme.notfound= +error.osmimage.dialogtitle= +error.osmimage.failed= diff --git a/tim/prune/lang/prune-texts_it.properties b/tim/prune/lang/prune-texts_it.properties index 8c4e780..628f09d 100644 --- a/tim/prune/lang/prune-texts_it.properties +++ b/tim/prune/lang/prune-texts_it.properties @@ -5,24 +5,19 @@ menu.file=File menu.file.open=Apri file menu.file.addphotos=Aggiungi foto -menu.file.loadfromgps=Carica dati da GPS menu.file.save=Salva -menu.file.exportkml=Esporta in KML -menu.file.exportgpx=Esporta in GPX -menu.file.exportpov=Esporta in POV menu.file.exit=Esci menu.edit=Edita menu.edit.undo=Annulla -menu.edit.clearundo=Cancella la lista annulla +menu.edit.clearundo=Cancella lista ultime modifiche menu.edit.editpoint=Edita punto menu.edit.editwaypointname=Edita nome waypoint menu.edit.deletepoint=Cancella punto menu.edit.deleterange=Cancella la serie -menu.edit.deleteduplicates=Cancella duplicati -menu.edit.compress=Comprimi traccia +menu.edit.deletemarked=Cancella punti marcati menu.edit.interpolate=Interpola +menu.edit.average=Crea punto medio della selezione menu.edit.reverse=Inverti la serie -menu.edit.addtimeoffset=Imposta lo scarto di orario menu.edit.mergetracksegments=Unisci segmenti traccia menu.edit.rearrange=Riorganizza waypoint menu.edit.rearrange.start=Tutti all'inizio del file @@ -38,25 +33,40 @@ menu.photo=Foto menu.photo.saveexif=Salva su Exif menu.photo.connect=Collega al punto menu.photo.disconnect=Scollega dal punto -menu.photo.correlate=Correla tutte le foto menu.photo.delete=Rimuovi foto menu.view=Visualizza -menu.view.show3d=Mostra in 3D menu.view.browser=Mappa sul browser menu.view.browser.google=Google maps menu.view.browser.openstreetmap=Openstreetmap +menu.view.browser.mapquest=Mapquest +menu.view.browser.yahoo=mappe Yahoo menu.help=Aiuto -menu.help.about=Informazioni su Prune -menu.help.checkversion=Controlla gli aggiornamenti # Popup menu for map menu.map.zoomin=Zoom + menu.map.zoomout=Zoom - menu.map.zoomfull=Zoom tutto -menu.map.newpoint= +menu.map.newpoint=Crea punto nuovo menu.map.connect=Aggancia ai punti menu.map.autopan=Autopan menu.map.showmap=Mostra sulla mappa +# Functions +function.loadfromgps=Carica dati da GPS +function.sendtogps=Invia dati al GPS +function.exportkml=Esporta in KML +function.exportgpx=Esporta in GPX +function.exportpov=Esporta in POV +function.compress=Comprimi la traccia +function.addtimeoffset=Aggiungi uno scarto temporale +function.charts=Diagrammi +function.show3d=Mostra in 3D +function.distances=Mostra distanze +function.setmapbg=Configura sfondo mappa +function.correlatephotos=Correla le foto +function.help=Aiuto +function.about=Informazioni su Prune +function.checkversion=Controlla gli aggiornamenti + # Dialogs dialog.exit.confirm.title=Esci da Prune dialog.exit.confirm.text=Le modifiche non sono state salvate. Sei sicuro di voler uscire? @@ -66,11 +76,6 @@ dialog.deletepoint.title=Cancella Punto dialog.deletepoint.deletephoto=Cancella la foto collegata a questo punto? dialog.deletephoto.title=Cancella Foto dialog.deletephoto.deletepoint=Cancella il punto collegato a questa foto? -dialog.deleteduplicates.title=Cancella Duplicati -dialog.deleteduplicates.nonefound=Nessun punto duplicato trovato -dialog.compresstrack.title=Comprimi la traccia -dialog.compresstrack.parameter.text=Parametro di compressione (più basso il numero = maggiore la compressione) -dialog.compresstrack.nonefound=Nessun punto rimosso dialog.openoptions.title=Apri opzioni dialog.openoptions.filesnippet=Estrai dal file dialog.load.table.field=Campo @@ -85,19 +90,20 @@ dialog.delimiter.other=Altro dialog.openoptions.deliminfo.records=registra, con dialog.openoptions.deliminfo.fields=campi dialog.openoptions.deliminfo.norecords=Nessun record -dialog.openoptions.tabledesc=Estrai dal file dialog.openoptions.altitudeunits=Unità di misura altitudine dialog.jpegload.subdirectories=Includi sottocartelle dialog.jpegload.loadjpegswithoutcoords=Includi foto senza coordinate dialog.jpegload.loadjpegsoutsidearea=Includi foto fuori dall'area corrente dialog.jpegload.progress.title=Caricamento foto dialog.jpegload.progress=Per favore aspetta, sto cercando le foto -dialog.gpsload.title=Carica dati da GPS dialog.gpsload.nogpsbabel=Non ho trovato il programma gpsbabel. Continuo? dialog.gpsload.device=Nome del Dispositivo dialog.gpsload.format=Formato dialog.gpsload.getwaypoints=Carica waypoint dialog.gpsload.gettracks=Carica tracce +dialog.gpssend.sendwaypoints=Invia waypoints +dialog.gpssend.sendtracks=Invia tracce +dialog.gpssend.trackname=Nome del tracce dialog.saveoptions.title=Salva il file dialog.save.fieldstosave=Campi da salvare dialog.save.table.field=Campo @@ -109,16 +115,13 @@ dialog.save.altitudeunits=Unit dialog.save.timestampformat=Formato della data dialog.save.overwrite.title=File già esistente dialog.save.overwrite.text=Questo file esiste già. Sei sicuro di volerlo sovrascrivere? -dialog.exportkml.title=Esporta in KML dialog.exportkml.text=Titolo dei dati dialog.exportkml.altitude=Includi altitudine (per aviazione) dialog.exportkml.kmz=Comprimi per file kmz dialog.exportkml.exportimages=Esporta le anteprime delle immagini per kmz -dialog.exportgpx.title=Esporta in GPX dialog.exportgpx.name=Nome dialog.exportgpx.desc=Descrizione dialog.exportgpx.includetimestamps=Includi dati temporali -dialog.exportpov.title=Esporta in POV dialog.exportpov.text=Per favore inserisci i parametri per l'esportazione in POV dialog.exportpov.font=Font dialog.exportpov.camerax=Camera X @@ -152,7 +155,6 @@ dialog.pointnameedit.name=Nome del waypoint dialog.pointnameedit.uppercase=MAIUSCOLE dialog.pointnameedit.lowercase=minuscole dialog.pointnameedit.sentencecase=Iniziali Maiuscole -dialog.addtimeoffset.title=Aggiungi uno scarto temporale dialog.addtimeoffset.add=Scarto in aggiunta dialog.addtimeoffset.subtract=Scarto in sottrazione dialog.addtimeoffset.days=Giorni @@ -172,7 +174,26 @@ dialog.saveexif.photostatus.connected=Collegata dialog.saveexif.photostatus.disconnected=Scollegata dialog.saveexif.photostatus.modified=Modificata dialog.saveexif.overwrite=Sovrascrivi il file -dialog.correlate.title=Correla le foto +dialog.charts.xaxis=Asse X +dialog.charts.yaxis=Asse Y +dialog.charts.output=Output +dialog.charts.screen=Output su schermo +dialog.charts.svg=Output a file SVG +dialog.charts.svgwidth=larghezza SVG +dialog.charts.svgheight=altezza SVG +dialog.charts.needaltitudeortimes=La traccia necessita di dati altitudine o tempo per creare diagrammi +dialog.charts.gnuplotpath=Path gnuplot +dialog.charts.gnuplotnotfound=Gnuplot non trovato nel path indicato +dialog.distances.intro=Distanze dirette tra punti +dialog.distances.column.from=Dal punto +dialog.distances.column.to=Al punto +dialog.distances.currentpoint=Punto attuale +dialog.distances.toofewpoints=Questa funzione necessita di waypoints per calcolare le distanze tra loro +dialog.setmapbg.mapnik=Mapnik (default) +dialog.setmapbg.osma=Osma +dialog.setmapbg.cyclemap=Mappa ciclistica +dialog.setmapbg.other=Altro +dialog.setmapbg.server=URL server dialog.correlate.notimestamps=Non ci sono informazioni temporali tra i dati dei punti, non c'è niente per collegarli con le foto. dialog.correlate.nouncorrelatedphotos=Non ci sono foto non correlate.\nSei sicuro di voler continuare? dialog.correlate.photoselect.intro=Selezione una delle foto correlate da usare come scarto dell'orario @@ -195,15 +216,23 @@ dialog.correlate.options.nodistancelimit=Nessun limite di distanza dialog.correlate.options.distancelimit=Distanza limite dialog.correlate.options.correlate=Correlate dialog.correlate.alloutsiderange=Tutte le foto sono fuori dall'orario della traccia, e nessuna può essere correlata.\nProva a cambiare lo scarto o correla manualmente almeno una foto. +dialog.compress.nonefound=Nessun punto rimosso +dialog.compress.duplicates.title=Cancella duplicati +dialog.compress.closepoints.title=Cancella punti vicini +dialog.compress.closepoints.paramdesc=Fattore vicinanza +dialog.compress.wackypoints.title=Cancella punti strani +dialog.compress.wackypoints.paramdesc=Fattore distanza +dialog.compress.singletons.title=Cancella solitari +dialog.compress.singletons.paramdesc=Fattore distanza +dialog.compress.summarylabel=Punti da cancellare dialog.help.help=Per favore vedi\n http://activityworkshop.net/software/prune/\nper maggiori informazioni e per la guida utente. -dialog.about.title=Informazioni su Prune dialog.about.version=Versione dialog.about.build=Build dialog.about.summarytext1=Prune è un programma per il caricamento, la visione e l'edit di dati provenienti da un GPS. dialog.about.summarytext2=È rilasciato sotto la licenza Gnu GPL per l'uso gratuito e aperto ed il suo miglioramento, con validità mondiale.
La copia, la ridistribuzione sono permesse e incoraggiate
in accordo con i termini inclusi nel file license.txt. dialog.about.summarytext3=Per favore vedi http://activityworkshop.net/ per maggiori informazioni e per la guida utente. dialog.about.languages=Lingue disponibili -dialog.about.translatedby=Testo italiano di Giovanni Sartor +dialog.about.translatedby=Testo italiano di Giovanni Sartor + altro dialog.about.systeminfo=Info di sistema dialog.about.systeminfo.os=Sistema operativo dialog.about.systeminfo.java=Java Runtime @@ -211,6 +240,7 @@ dialog.about.systeminfo.java3d=Java3d installato dialog.about.systeminfo.povray=Povray installato dialog.about.systeminfo.exiftool=Exiftool installato dialog.about.systeminfo.gpsbabel=Gpsbabel installato +dialog.about.systeminfo.gnuplot=Gnuplot installato dialog.about.yes=Sì dialog.about.no=No dialog.about.credits=Crediti @@ -223,7 +253,6 @@ dialog.about.credits.devtools=Tool di sviluppo dialog.about.credits.othertools=Altri tool dialog.about.credits.thanks=Grazie a dialog.about.readme=Leggimi -dialog.checkversion.title=Controlla aggiornamenti dialog.checkversion.error=Non posso verificare l'aggiornamento.\nPer favore controlla la connessione internet. dialog.checkversion.uptodate=Stai usando l'ultima versione di Prune dialog.checkversion.newversion1=Una nuova versione di Prune è disponibile! L'ultima versione è ora la versione @@ -243,8 +272,6 @@ dialog.3dlines.intro=Queste sono le linee della griglia per la visione 3D confirm.loadfile=Dati caricati da file confirm.save.ok1=Salvati con successo confirm.save.ok2=punti nel file -confirm.deleteduplicates.single=duplicato è stato cancellato -confirm.deleteduplicates.multi=duplicati sono stati cancellati confirm.deletepoint.single=punto è stato rimosso confirm.deletepoint.multi=punti sono stati rimossi confirm.point.edit=punto editato @@ -263,7 +290,7 @@ confirm.photo.connect=foto collegata confirm.photo.disconnect=foto scollegata confirm.correlate.single=foto era correlata confirm.correlate.multi=foto erano correlate -confirm.createpoint= +confirm.createpoint=punto creato # Buttons button.ok=OK @@ -288,14 +315,17 @@ button.selectnone=Deseleziona tutto button.preview=Anteprima button.guessfields=Campi soluzione button.showwebpage=Mostra pagina +button.gnuplotpath=Fissa path gnuplot # File types filetype.txt=File TXT filetype.jpeg=File JPG filetype.kmlkmz=File KML, KMZ filetype.kml=File KML +filetype.kmz=FIle KMZ filetype.gpx=File GPX filetype.pov=File POV +filetype.svg=File SVG # Display components display.nodata=Nessun dato caricato @@ -309,7 +339,6 @@ details.pointdetails=Dettagli punto details.index.selected=Indice details.index.of=di details.nopointselection=Nessun punto selezionato -details.speed=Velocità details.photofile=File della foto details.norangeselection=Nessun intervallo selezionato details.rangedetails=Dettagli dell'intervallo @@ -325,27 +354,31 @@ display.range.time.mins=m display.range.time.hours=h display.range.time.days=g details.range.avespeed=Velocità media -details.range.avemovingspeed= +details.range.avemovingspeed=Velocità media in movimento details.waypointsphotos.waypoints=Waypoint details.waypointsphotos.photos=Foto details.photodetails=Dettagli foto details.nophoto=Nessuna foto selezionata details.photo.loading=Caricamento details.photo.connected=Collegata +map.overzoom=Mappa non disponibile a questo livello di zoom # Field names fieldname.latitude=Latitudine fieldname.longitude=Longitudine fieldname.altitude=Altitudine fieldname.timestamp=Dati temporali +fieldname.time=Tempo fieldname.waypointname=Nome fieldname.waypointtype=Tipo fieldname.newsegment=Segmento fieldname.custom=Custom fieldname.prefix=Campo fieldname.distance=Distanza -fieldname.movingdistance= +fieldname.movingdistance=Distanza in movimento fieldname.duration=Durata +fieldname.speed=Velocità +fieldname.verticalspeed=Velocità verticale # Measurement units units.original=Originale @@ -360,6 +393,9 @@ units.kmh=km/h units.miles=Miglia units.miles.short=mi units.mph=mph +units.metrespersec=m/s +units.feetpersec=ft/s +units.hours=Ore units.degminsec=Deg-min-sec units.degmin=Deg-min units.deg=Degrees @@ -383,7 +419,6 @@ undo.deletephoto=rimuovi foto undo.deleterange=cancella l'intervallo undo.compress=comprimi traccia undo.insert=inserisci punti -undo.deleteduplicates=cancella duplicati undo.reverse=inverti l'intervallo undo.mergetracksegments=unisci segmenti traccia undo.addtimeoffset=aggiungi scarto temporale @@ -392,7 +427,7 @@ undo.cutandmove=muovi selezione undo.connectphoto=collega foto undo.disconnectphoto=scollega foto undo.correlate=correla foto -undo.createpoint= +undo.createpoint=crea punto # Error messages error.save.dialogtitle=Errore nel salvataggio dati @@ -405,6 +440,7 @@ error.load.dialogtitle=Errore nel caricamento dati error.load.noread=Non posso leggere il file error.load.nopoints=Non ci sono coordinate nel file error.load.unknownxml=Formato xml non riconosciuto: +error.load.noxmlinzip=File xml non trovato all'interno del zip file error.load.othererror=Errore nella lettura del file: error.jpegload.dialogtitle=Errore nel caricamento delle foto error.jpegload.nofilesfound=File non trovato @@ -415,10 +451,8 @@ error.undofailed.title=Impossibile annullare error.undofailed.text=Impossibile annullare l'operazione error.function.noop.title=La funzione non ha avuto effetto error.rearrange.noop=La riorganizzazione dei waypoint non ha avuto effetto -error.function.notimplemented=Mi dispiace, questa funzione non è ancora stata implementata. error.function.notavailable.title=Funzione non disponibile error.function.nojava3d=Questa funzione richiede la libreria Java3d,\ndisponibile all'indirizzo Sun.com. -error.3d.title=Errore nella visualizzazione 3D error.3d=È avvenuto un errore nella visualizzazione 3D error.readme.notfound=Non ho trovato il file Leggimi error.osmimage.dialogtitle=Errore nel caricamento nelle immagini della mappa diff --git a/tim/prune/lang/prune-texts_pl.properties b/tim/prune/lang/prune-texts_pl.properties index a16c037..5478bd1 100644 --- a/tim/prune/lang/prune-texts_pl.properties +++ b/tim/prune/lang/prune-texts_pl.properties @@ -5,11 +5,7 @@ menu.file=Plik menu.file.open=Otw\u00F3rz menu.file.addphotos=Dodaj zdj\u0119cia -menu.file.loadfromgps= menu.file.save=Zapisz -menu.file.exportkml=Eksportuj jako KML -menu.file.exportgpx=Eksportuj jako GPX -menu.file.exportpov=Eksportuj jako POV menu.file.exit=Zako\u0144cz menu.edit=Edycja menu.edit.undo=Cofnij @@ -18,252 +14,283 @@ menu.edit.editpoint=Edytuj punkt menu.edit.editwaypointname=Zmie\u0144 nazw\u0119 punktu po\u015Bredniego menu.edit.deletepoint=Usu\u0144 punkt menu.edit.deleterange=Usu\u0144 zakres -menu.edit.deleteduplicates=Usu\u0144 duplikaty -menu.edit.compress=Skompresuj scie\u017Ck\u0119 +menu.edit.deletemarked=Usu\u0144 zaznaczone punkty menu.edit.interpolate=Interpoluj punkty +menu.edit.average=U\u015Brednij zaznaczenie menu.edit.reverse=Odwr\u00F3\u0107 zakres -menu.edit.addtimeoffset= -menu.edit.mergetracksegments= +menu.edit.mergetracksegments=Po\u0142\u0105cz fragmenty \u015Bcie\u017Cek menu.edit.rearrange=Zmie\u0144 kolejno\u015B\u0107 punkt\u00F3w po\u015Brednich menu.edit.rearrange.start=Wszystkie na pocz\u0105tek \u015Bcie\u017Cki menu.edit.rearrange.end=Wszystkie na koniec \u015Bcie\u017Cki menu.edit.rearrange.nearest=Do najbli\u017Cszego punktu -menu.edit.cutandmove= -menu.select=Zakres +menu.edit.cutandmove=Wytnij i przesu\u0144 zaznaczenie +menu.select=Zaznacz menu.select.all=Zaznacz wszystko menu.select.none=Usu\u0144 zaznaczenie -menu.select.start=Zaznacz pocz\u0105tek -menu.select.end=Zaznacz koniec +menu.select.start=Zaznacz pocz\u0105tek zakresu +menu.select.end=Zaznacz koniec zakresu menu.photo=Zdj\u0119cie menu.photo.saveexif=Zapisz Exif menu.photo.connect=Przy\u0142\u0105cz do punktu menu.photo.disconnect=Od\u0142\u0105cz od punktu -menu.photo.correlate=Skoreluj wszystkie zdj\u0119cia menu.photo.delete=Usu\u0144 zdj\u0119cie menu.view=Widok -menu.view.show3d=Poka\u017C 3D model -menu.view.browser= -menu.view.browser.google= -menu.view.browser.openstreetmap= +menu.view.browser=Mapa w przegl\u0105darce +menu.view.browser.google=Mapy Google +menu.view.browser.openstreetmap=Openstreetmap +menu.view.browser.mapquest=Mapquest +menu.view.browser.yahoo=Mapy Yahoo menu.help=Pomoc -menu.help.about=Prune - Informacje -menu.help.checkversion= # Popup menu for map menu.map.zoomin=Powi\u0119ksz menu.map.zoomout=Zmniejsz -menu.map.zoomfull=Dostosuj powi\u0119kszenie -menu.map.newpoint= -menu.map.connect=Po\u0142\u0105czenie track punkty +menu.map.zoomfull=Dostosuj powi\u0119kszenie +menu.map.newpoint=Stw\u00F3rz nowy punkt +menu.map.connect=Po\u0142\u0105cz punkty \u015Bcie\u017Cki menu.map.autopan=Przesuwanie mapy -menu.map.showmap= +menu.map.showmap=Poka\u017C map\u0119 + +# Functions +function.loadfromgps=\u0141aduj z GPS +function.sendtogps=Wy\u015Blij dane do urz\u0105dzenia GPS +function.exportkml=Eksportuj KML +function.exportgpx=Eksportuj jako GPX +function.exportpov=Eksportuj jako POV +function.compress=Skompresuj \u015Bcie\u017Ck\u0119 +function.addtimeoffset=Dodaj przesuni\u0119cie czasu +function.charts=Wykres +function.show3d=Poka\u017C model 3D +function.distances=Odleg\u0142o\u015Bci +function.setmapbg=Wybierz map\u0119 +function.correlatephotos=Powi\u0105\u017C zdj\u0119cia +function.help=Pomoc +function.about=O Prune +function.checkversion=Sprawd\u017A czy jest nowa wersja # Dialogs dialog.exit.confirm.title=Zako\u0144cz Prune -dialog.exit.confirm.text= -dialog.openappend.title= -dialog.openappend.text= +dialog.exit.confirm.text=Dane nie s\u0105 zapisane. Czy na pewno chcesz wyj\u015B\u0107? +dialog.openappend.title=Dodaj do istniej\u0105cych danych +dialog.openappend.text=Doda\u0107 te dane do ju\u017C za\u0142adowanych? dialog.deletepoint.title=Usu\u0144 punkt -dialog.deletepoint.deletephoto=Usu\u0144 zdj\u0119cie attached to this punkt? +dialog.deletepoint.deletephoto=Usun\u0105\u0107 zdj\u0119cie do\u0142\u0105czone do tego punktu? dialog.deletephoto.title=Usu\u0144 zdj\u0119cie -dialog.deletephoto.deletepoint=Usu\u0144 punkt attached to this zdj\u0119cie? -dialog.deleteduplicates.title=Usu\u0144 Duplicates -dialog.deleteduplicates.nonefound=Brak duplikaty found -dialog.compresstrack.title=Skompresuj scie\u017Ck\u0119 -dialog.compresstrack.parameter.text= -dialog.compresstrack.nonefound=No data punkty could be removed +dialog.deletephoto.deletepoint=Usun\u0105\u0107 punkt do\u0142\u0105czony do tego zdj\u0119cia? dialog.openoptions.title=Otw\u00F3rz opcje -dialog.openoptions.filesnippet=Extract of plik +dialog.openoptions.filesnippet=Fragment z pliku dialog.load.table.field=Pole -dialog.load.table.datatype=Data Type +dialog.load.table.datatype=Typ danych dialog.load.table.description=Opis -dialog.delimiter.label=Pole separator +dialog.delimiter.label=Pole separatora dialog.delimiter.comma=Przecinek , dialog.delimiter.tab=Tabulator dialog.delimiter.space=Spacja dialog.delimiter.semicolon=\u015Arednik ; dialog.delimiter.other=Inne -dialog.openoptions.deliminfo.records= +dialog.openoptions.deliminfo.records=rekordy, z dialog.openoptions.deliminfo.fields=pola -dialog.openoptions.deliminfo.norecords= -dialog.openoptions.tabledesc=Extract of plik -dialog.openoptions.altitudeunits=Wysoko\u015B\u0107 jednostki -dialog.jpegload.subdirectories= -dialog.jpegload.loadjpegswithoutcoords=Include zdj\u0119cia without koordinaty -dialog.jpegload.loadjpegsoutsidearea= -dialog.jpegload.progress.title=Loading zdj\u0119cia -dialog.jpegload.progress=Please wait while the zdj\u0119cia are searched -dialog.gpsload.title= -dialog.gpsload.nogpsbabel= -dialog.gpsload.device= -dialog.gpsload.format= -dialog.gpsload.getwaypoints= -dialog.gpsload.gettracks= +dialog.openoptions.deliminfo.norecords=Brak rekord\u00F3w +dialog.openoptions.altitudeunits=Jednostki wysoko\u015Bci +dialog.jpegload.subdirectories=Do\u0142\u0105cz podkatalogi +dialog.jpegload.loadjpegswithoutcoords=Do\u0142\u0105cz zdj\u0119cia bez wsp\u00F3\u0142rz\u0119dnych +dialog.jpegload.loadjpegsoutsidearea=Do\u0142\u0105cz zdj\u0119cia spoza bie\u017C\u0105cego obszaru +dialog.jpegload.progress.title=\u0141aduj\u0119 zdj\u0119cia +dialog.jpegload.progress=Czekaj, szukam zdj\u0119\u0107 +dialog.gpsload.nogpsbabel=Nie znalezionio programu gpsbabel. Kontynuowa\u0107? +dialog.gpsload.device=Nazwa urz\u0105dzenia +dialog.gpsload.format=Format +dialog.gpsload.getwaypoints=\u0141aduj punkty po\u015Brednie +dialog.gpsload.gettracks=\u0141aduj \u015Bcie\u017Cki +dialog.gpssend.sendwaypoints=Wy\u015Blij punkty po\u015Brednie +dialog.gpssend.sendtracks=Wy\u015Blij \u015Bcie\u017Cki +dialog.gpssend.trackname=Nazwa \u015Bcie\u017Cki dialog.saveoptions.title=Zapisz plik -dialog.save.fieldstosave=Pola to save +dialog.save.fieldstosave=Pola do zapisu dialog.save.table.field=Pole -dialog.save.table.hasdata= +dialog.save.table.hasdata=je\u015Bli s\u0105 dane dialog.save.table.save=Zapisz -dialog.save.headerrow= -dialog.save.coordinateunits=Wsp\u00f3\u0142rz\u0119dne jednostki -dialog.save.altitudeunits=Wysoko\u015B\u0107 jednostki -dialog.save.timestampformat= +dialog.save.headerrow=Dodaj wiersz nag\u0142\u00F3wka +dialog.save.coordinateunits=Jednostki wsp\u00F3\u0142rz\u0119dnych +dialog.save.altitudeunits=Jednostki wysoko\u015Bci +dialog.save.timestampformat=Format znacznika czasu dialog.save.overwrite.title=Plik ju\u017C istnieje -dialog.save.overwrite.text=This plik already exists. Are you sure you want to overwrite the plik? -dialog.exportkml.title=Eksportuj KML -dialog.exportkml.text=Tytu\u0142 for the data -dialog.exportkml.altitude= -dialog.exportkml.kmz= -dialog.exportkml.exportimages=Eksportuj image thumbnails to kmz -dialog.exportgpx.title=Eksportuj jako GPX +dialog.save.overwrite.text=Ten plik ju\u017C istnieje. Czy na pewno chcesz go nadpisa\u0107? +dialog.exportkml.text=Tytu\u0142 dla danych +dialog.exportkml.altitude=Do\u0142\u0105cz wysoko\u015Bci (dla cel\u00F3w lotniczych) +dialog.exportkml.kmz=Skompresuj do pliku KMZ +dialog.exportkml.exportimages=Eksportuj miniaturki zdj\u0119\u0107 do KMZ dialog.exportgpx.name=Nazwa dialog.exportgpx.desc=Opis -dialog.exportgpx.includetimestamps= -dialog.exportpov.title=Eksportuj jako POV -dialog.exportpov.text= +dialog.exportgpx.includetimestamps=Do\u0142\u0105cz znaczniki czasu +dialog.exportpov.text=Wprowad\u017A dodatkowe parametry eksportu do formatu POV dialog.exportpov.font=Czcionka -dialog.exportpov.camerax=Camera X -dialog.exportpov.cameray=Camera Y -dialog.exportpov.cameraz=Camera Z -dialog.exportpov.modelstyle= -dialog.exportpov.ballsandsticks= -dialog.exportpov.tubesandwalls= -dialog.exportpov.warningtracksize=This track has a large number of punkty, which Java3D might not be able to display.\nCzy chcesz kontynuowa\u0107? -dialog.confirmreversetrack.title= -dialog.confirmreversetrack.text= -dialog.confirmcutandmove.title= -dialog.confirmcutandmove.text= +dialog.exportpov.camerax=Kamera X +dialog.exportpov.cameray=Kamera Y +dialog.exportpov.cameraz=Kamera Z +dialog.exportpov.modelstyle=Styl modelu +dialog.exportpov.ballsandsticks=Kule i pa\u0142ki +dialog.exportpov.tubesandwalls=Rurki i \u015Bciany +dialog.exportpov.warningtracksize=Ta \u015Bcie\u017Cka ma bardzo wiele punkt\u00F3w, kt\u00F3rych Java3D mo\u017Ce nie wy\u015Bwietli\u0107.\nCzy chcesz kontynuowa\u0107? +dialog.confirmreversetrack.title=Potwierd\u017A odwr\u00F3cenie +dialog.confirmreversetrack.text=Ta \u015Bcie\u017Cka zawiera znaczniki czasu, kt\u00F3re po odwr\u00F3ceniu nie b\u0119d\u0105 ustawione w kolejno\u015Bci.\nCzy na pewno chcesz odwr\u00F3ci\u0107 ten fragment? +dialog.confirmcutandmove.title=Potwierd\u017A wytnij i przesu\u0144 +dialog.confirmcutandmove.text=Ta \u015Bcie\u017Cka zawiera znaczniki czasu, kt\u00F3re po przesuni\u0119ciu nie b\u0119d\u0105 ustawione w kolejno\u015Bci.\nCzy na pewno chcesz przesun\u0105\u0107 ten fragment? dialog.interpolate.title=Interpoluj punkty -dialog.interpolate.parameter.text=Number of punkty to insert between selected punkty -dialog.undo.title=Cofnij action(s) -dialog.undo.pretext= -dialog.undo.none.title= -dialog.undo.none.text= +dialog.interpolate.parameter.text=Ilo\u015B\u0107 punkt\u00F3w do wstawienia pomi\u0119dzy wybrane punkty +dialog.undo.title=Potwierd\u017A akcje +dialog.undo.pretext=Wybierz akcje kt\u00F3re chcesz cofn\u0105\u0107 +dialog.undo.none.title=Nie mo\u017Cna cofn\u0105\u0107 +dialog.undo.none.text=Brak zmian do cofni\u0119cia dialog.clearundo.title=Wyczy\u015B\u0107 list\u0119 zmian -dialog.clearundo.text= +dialog.clearundo.text=Czy na pewno chcesz wyczy\u015Bci\u0107 list\u0119 zmian?\nWszystkie informacje o zmianach b\u0119d\u0105 utracone! dialog.pointedit.title=Edytuj punkt -dialog.pointedit.text= +dialog.pointedit.text=Zaznacz wszystkie pola do edycji i u\u017Cyj przycisku 'Edytuj' by zmieni\u0107 warto\u015Bci dialog.pointedit.table.field=Pole -dialog.pointedit.table.value= +dialog.pointedit.table.value=Warto\u015B\u0107 dialog.pointedit.table.changed=Zmieniony -dialog.pointedit.changevalue.text= -dialog.pointedit.changevalue.title=Edytuj field +dialog.pointedit.changevalue.text=Wprowad\u017A now\u0105 warto\u015B\u0107 tego pola +dialog.pointedit.changevalue.title=Edytuj pole dialog.pointnameedit.title=Zmie\u0144 nazw\u0119 punktu po\u015Bredniego -dialog.pointnameedit.name=Waypoint nazwa -dialog.pointnameedit.uppercase= -dialog.pointnameedit.lowercase= -dialog.pointnameedit.sentencecase= -dialog.addtimeoffset.title= -dialog.addtimeoffset.add= -dialog.addtimeoffset.subtract= -dialog.addtimeoffset.days= -dialog.addtimeoffset.hours= +dialog.pointnameedit.name=Nazwa punktu po\u015Bredniego +dialog.pointnameedit.uppercase=WIELKIE litery +dialog.pointnameedit.lowercase=ma\u0142e litery +dialog.pointnameedit.sentencecase=Jak W Zdaniu +dialog.addtimeoffset.add=Dodaj czas +dialog.addtimeoffset.subtract=Odejmij czas +dialog.addtimeoffset.days=Dni +dialog.addtimeoffset.hours=Godziny dialog.addtimeoffset.minutes=Minuty -dialog.addtimeoffset.notimestamps= -dialog.connect.title= -dialog.connectphoto.clonepoint= +dialog.addtimeoffset.notimestamps=Nie mo\u017Cna przesun\u0105\u0107 czasu, poniewa\u017C zaznaczenie nie zawiera znacznik\u00F3w czasu +dialog.connect.title=Po\u0142\u0105cz zdj\u0119cie do punktu +dialog.connectphoto.clonepoint=Ten punkt ju\u017C ma zdj\u0119cie.\nCzy chcesz zrobi\u0107 kopi\u0119 tego punktu? dialog.saveexif.title=Zapisz Exif -dialog.saveexif.intro=Select the zdj\u0119cia to save using the checkboxes -dialog.saveexif.nothingtosave= -dialog.saveexif.noexiftool= -dialog.saveexif.table.photoname=Nazwa zdj\u0119cie +dialog.saveexif.intro=Zaznacz zdj\u0119cia do zapisu u\u017Cywaj\u0105c p\u00F3l opcji +dialog.saveexif.nothingtosave=Wsp\u00F3\u0142rz\u0119dne s\u0105 nie zmienione, Nie ma nic do zapisu +dialog.saveexif.noexiftool=Nie znaleziono programu exiftool. Kontynuowa\u0107? +dialog.saveexif.table.photoname=Nazwa zdj\u0119cia dialog.saveexif.table.status=Status dialog.saveexif.table.save=Zapisz -dialog.saveexif.photostatus.connected= -dialog.saveexif.photostatus.disconnected= +dialog.saveexif.photostatus.connected=Po\u0142\u0105czony +dialog.saveexif.photostatus.disconnected=Roz\u0142\u0105czony dialog.saveexif.photostatus.modified=Zmodyfikowany -dialog.saveexif.overwrite=Overwrite pliki -dialog.correlate.title=Skoreluj zdj\u0119cie -dialog.correlate.notimestamps=There are no timestamps in the data punkty, so there is nothing to correlate with the zdj\u0119cia. -dialog.correlate.nouncorrelatedphotos=There are no uncorrelated zdj\u0119cia.\nAre you sure you want to continue? -dialog.correlate.photoselect.intro=Select one of these correlated zdj\u0119cia to use as the time offset -dialog.correlate.photoselect.photoname=Nazwa zdj\u0119cie -dialog.correlate.photoselect.timediff= -dialog.correlate.photoselect.photolater=Zdj\u0119cie later -dialog.correlate.options.tip=Tip: By manually correlating at least one zdj\u0119cie, the time offset can be calculated for you. -dialog.correlate.options.intro= -dialog.correlate.options.offsetpanel= -dialog.correlate.options.offset= -dialog.correlate.options.offset.hours=hours, -dialog.correlate.options.offset.minutes=minuty i -dialog.correlate.options.offset.seconds=seconds -dialog.correlate.options.photolater=Zdj\u0119cie po punkt -dialog.correlate.options.pointlater=Punkt po zdj\u0119cie -dialog.correlate.options.limitspanel= -dialog.correlate.options.notimelimit= -dialog.correlate.options.timelimit= -dialog.correlate.options.nodistancelimit= -dialog.correlate.options.distancelimit= -dialog.correlate.options.correlate= -dialog.correlate.alloutsiderange=All zdj\u0119cia are outside the time range of the track, so none can be correlated.\nTry changing the offset or manually correlating at least one zdj\u0119cie. -dialog.help.help=Please see\n http://activityworkshop.net/software/prune/\npo wi\u0119cej informacji and user guides. -dialog.about.title=Prune Informacje +dialog.saveexif.overwrite=Nadpisz pliki +dialog.charts.xaxis=O\u015B X +dialog.charts.yaxis=O\u015B Y +dialog.charts.output=Wykres +dialog.charts.screen=Wy\u015Bwietl na ekranie +dialog.charts.svg=Zapisz do pliku SVG +dialog.charts.svgwidth=szeroko\u015B\u0107 SVG +dialog.charts.svgheight=wysoko\u015B\u0107 SVG +dialog.charts.needaltitudeortimes=\u015Acie\u017Cka musi posiada\u0107 zapisane wysoko\u015Bci lub znaczniki czasu aby mo\u017Cliwe by\u0142o utworzenie wykres\u00F3w +dialog.charts.gnuplotpath=\u015Acie\u017Cka do programu gnuplot +dialog.charts.gnuplotnotfound=Nie znalaz\u0142em programu gnuplot +dialog.distances.intro=Odleg\u0142o\u015B\u0107 mi\u0119dzy punktami w linii prostej +dialog.distances.column.from=Z punktu +dialog.distances.column.to=Do punktu +dialog.distances.currentpoint=Wybrany punkt +dialog.distances.toofewpoints=Ta funkcja wymaga przynajmniej dw\u00F3ch punkt\u00F3w po\u015Brednich aby obliczy\u0107 odleg\u0142o\u015Bci +dialog.setmapbg.mapnik=Mapnik (domy\u015Blny) +dialog.setmapbg.osma=Osma +dialog.setmapbg.cyclemap=Cyclemap +dialog.setmapbg.other=Inne +dialog.setmapbg.server=Adres URL serwera +dialog.correlate.notimestamps=Punkty nie maj\u0105 znacznik\u00F3w czasu, nie mo\u017Cna ich powi\u0105za\u0107 ze zdj\u0119ciami. +dialog.correlate.nouncorrelatedphotos=Nie ma nie powi\u0105zanych zdj\u0119\u0107.\nCzy na pewno chcesz kontynuowa\u0107? +dialog.correlate.photoselect.intro=Wybierz jedno z powi\u0105zanych zdj\u0119\u0107 i u\u017Cyj go jako wzorca do przesuni\u0119cia czasu +dialog.correlate.photoselect.photoname=Nazwa zdj\u0119cia +dialog.correlate.photoselect.timediff=R\u00F3\u017Cnica czasowa +dialog.correlate.photoselect.photolater=P\u00F3\u017Aniejsze zdj\u0119cie +dialog.correlate.options.tip=Porada: Gdy powi\u0105\u017Cesz r\u0119cznie przynajmniej jedno zdj\u0119cie, r\u00F3\u017Cnica czasowa zostanie policzona automatycznie. +dialog.correlate.options.intro=Wybierz opcje dla automatycznej korelacji +dialog.correlate.options.offsetpanel=Przesuni\u0119cie czasowe +dialog.correlate.options.offset=Przesuni\u0119cie +dialog.correlate.options.offset.hours=godzin, +dialog.correlate.options.offset.minutes=minut i +dialog.correlate.options.offset.seconds=sekund +dialog.correlate.options.photolater=Zdj\u0119cie p\u00F3\u017Aniejsze ni\u017C punkt +dialog.correlate.options.pointlater=Punkt p\u00F3\u017Aniejszy ni\u017C zdj\u0119cie +dialog.correlate.options.limitspanel=Ograniczenia korelacji +dialog.correlate.options.notimelimit=Bez limitu czasu +dialog.correlate.options.timelimit=Limit czasu +dialog.correlate.options.nodistancelimit=Bez limitu odleg\u0142o\u015Bci +dialog.correlate.options.distancelimit=Limit odleg\u0142o\u015Bci +dialog.correlate.options.correlate=Powi\u0105\u017C ze sob\u0105 +dialog.correlate.alloutsiderange=Wszystkie zdj\u0119cia s\u0105 poza zakresem czasu \u015Bcie\u017Cki, tak \u017Ce \u017Cadne nie mo\u017Ce zosta\u0107 z ni\u0105 skorelowane.\nSpr\u00F3buj zmieni\u0107 przesuni\u0119cie lub r\u0119cznie skoreluj przynajmniej jedno zdj\u0119cie. +dialog.compress.nonefound=Nie mo\u017Cna usun\u0105\u0107 \u017Cadnych punkt\u00F3w +dialog.compress.duplicates.title=Usuwanie duplikat\u00F3w +dialog.compress.closepoints.title=Usuwanie bliskich sobie punkt\u00F3w +dialog.compress.closepoints.paramdesc=Wsp\u00F3\u0142czynnik rozpi\u0119to\u015Bci +dialog.compress.wackypoints.title=Usuwanie dziwacznych punkt\u00F3w +dialog.compress.wackypoints.paramdesc=Wsp\u00F3\u0142czynnik odleg\u0142o\u015Bci +dialog.compress.singletons.title=Usuwanie odosobnionych punkt\u00F3w +dialog.compress.singletons.paramdesc=Wsp\u00F3\u0142czynnik odleg\u0142o\u015Bci +dialog.compress.summarylabel=Punkty do usuni\u0119cia +dialog.help.help=Na stronie\n http://activityworkshop.net/software/prune/ \nznajdziesz wi\u0119cej informacji oraz podr\u0119cznik u\u017Cytkownika dialog.about.version=Wersja dialog.about.build=Build -dialog.about.summarytext1= -dialog.about.summarytext2= -dialog.about.summarytext3= -dialog.about.languages= -dialog.about.translatedby=Tekst po polsku by Piotr. -dialog.about.systeminfo= -dialog.about.systeminfo.os= -dialog.about.systeminfo.java= +dialog.about.summarytext1=Prune s\u0142u\u017Cy do pobierania, wy\u015Bwietlania i edycji danych z odbiornik\u00F3w GPS. +dialog.about.summarytext2=Ten program zosta\u0142 udost\u0119pniony na podstawie licencji GNU pozwalaj\u0105cej
na jego wolne, nieograniczone i og\u00F3lno\u015Bwiatowe u\u017Cytkowanie i rozszerzanie.
Kopiowanie, rozprowadzanie i modyfikowanie s\u0105 dozwolone i zalecane
zgodnie z warunkami zawartymi w do\u0142\u0105czonym plikulicense.txt +dialog.about.summarytext3=Na stronie http://activityworkshop.net/ znajdziesz wi\u0119cej informacji oraz podr\u0119cznik u\u017Cytkownika. +dialog.about.languages=Dost\u0119pne j\u0119zyki +dialog.about.translatedby=Tekst po polsku: Piotr, Weehal +dialog.about.systeminfo=Informacje o systemie +dialog.about.systeminfo.os=System operacyjny +dialog.about.systeminfo.java=Wersja Java Runtime dialog.about.systeminfo.java3d=Java3d zainstalowana -dialog.about.systeminfo.povray=Povray zainstalowana -dialog.about.systeminfo.exiftool=Exiftool zainstalowana -dialog.about.systeminfo.gpsbabel=Gpsbabel zainstalowana +dialog.about.systeminfo.povray=Povray zainstalowany +dialog.about.systeminfo.exiftool=Exiftool zainstalowany +dialog.about.systeminfo.gpsbabel=Gpsbabel zainstalowany +dialog.about.systeminfo.gnuplot=Gnuplot zainstalowany dialog.about.yes=Tak dialog.about.no=Nie -dialog.about.credits= -dialog.about.credits.code= -dialog.about.credits.exifcode= -dialog.about.credits.icons= -dialog.about.credits.translators= -dialog.about.credits.translations=T\u0142umaczenie helped by -dialog.about.credits.devtools= -dialog.about.credits.othertools= -dialog.about.credits.thanks=Dzi\u0119kuje to -dialog.about.readme=Readme -dialog.checkversion.title= -dialog.checkversion.error= -dialog.checkversion.uptodate= -dialog.checkversion.newversion1= -dialog.checkversion.newversion2= -dialog.checkversion.releasedate1= -dialog.checkversion.releasedate2= -dialog.checkversion.download=To download the new version, go to http://activityworkshop.net/software/prune/download.html. +dialog.about.credits=Podzi\u0119kowania +dialog.about.credits.code=Kod Prune napisany przez +dialog.about.credits.exifcode=Kod Exif przez +dialog.about.credits.icons=Niekt\u00F3re ikony z +dialog.about.credits.translators=T\u0142umacze +dialog.about.credits.translations=Pomoc w t\u0142umaczeniu +dialog.about.credits.devtools=Narz\u0119dzia deweloperskie +dialog.about.credits.othertools=Inne narz\u0119dzia +dialog.about.credits.thanks=Podzi\u0119kowania dla +dialog.about.readme=Czytaj To +dialog.checkversion.error=Nie mo\u017Cna sprawdzi\u0107 numeru wersji.\nSprawd\u017A po\u0142\u0105czenie z internetem. +dialog.checkversion.uptodate=U\u017Cywasz najnowszej wersji Prune. +dialog.checkversion.newversion1=Dost\u0119pna jest nowa wersja Prune! Najnowsz\u0105 wersj\u0105 jest wersja +dialog.checkversion.newversion2=. +dialog.checkversion.releasedate1=Nowa wersja zosta\u0142a opublikowana +dialog.checkversion.releasedate2=. +dialog.checkversion.download=Aby \u015Bci\u0105gn\u0105\u0107 now\u0105 wersj\u0119 przejd\u017A na http://activityworkshop.net/software/prune/download.html. # 3d window -dialog.3d.title=Prune tr\u00f3jwymiarowa model -dialog.3d.altitudecap= -dialog.3dlines.title= -dialog.3dlines.empty= -dialog.3dlines.intro= +dialog.3d.title=Prune widok tr\u00F3jwymiarowy +dialog.3d.altitudecap=Minimalny zakres wysoko\u015Bci +dialog.3dlines.title=Linie siatki +dialog.3dlines.empty=Brak siatki do wy\u015Bwietlenia! +dialog.3dlines.intro=Linie siatki w widoku 3D # Confirm messages || These are displayed as confirmation in the status bar -confirm.loadfile= -confirm.save.ok1= -confirm.save.ok2=punkty to plik -confirm.deleteduplicates.single= -confirm.deleteduplicates.multi= -confirm.deletepoint.single=data punkt was removed -confirm.deletepoint.multi=data punkty were removed -confirm.undo.single= -confirm.undo.multi= -confirm.point.edit=punkt edited -confirm.mergetracksegments= -confirm.reverserange= -confirm.addtimeoffset= -confirm.rearrangewaypoints= -confirm.cutandmove= -confirm.saveexif.ok1= -confirm.saveexif.ok2=zdj\u0119cia pliki -confirm.jpegload.single=zdj\u0119cie was added -confirm.jpegload.multi=zdj\u0119cia were added -confirm.photo.connect=zdj\u0119cie connected -confirm.photo.disconnect=zdj\u0119cie disconnected -confirm.correlate.single=zdj\u0119cie was correlated -confirm.correlate.multi=zdj\u0119cia were correlated -confirm.createpoint= +confirm.loadfile=Za\u0142adowano dane z pliku +confirm.save.ok1=Zapisano pomy\u015Blnie +confirm.save.ok2=punkt\u00F3w do pliku +confirm.deletepoint.single=usuni\u0119to punkt +confirm.deletepoint.multi=punkt\u00F3w usuni\u0119to +confirm.point.edit=zmieniono punkt +confirm.mergetracksegments=Po\u0142\u0105czono fragmenty \u015Bcie\u017Cki +confirm.reverserange=Odwr\u00F3cono zakres +confirm.addtimeoffset=Dodano przesuni\u0119cie czasowe +confirm.rearrangewaypoints=Przestawiono punkty po\u015Brednie +confirm.cutandmove=Przesuni\u0119to zaznaczenie +confirm.saveexif.ok1=Zapisano +confirm.saveexif.ok2=pliki zdj\u0119\u0107 +confirm.undo.single=cofni\u0119to operacj\u0119 +confirm.undo.multi=operacje zosta\u0142y cofni\u0119te +confirm.jpegload.single=dodano zdj\u0119cie +confirm.jpegload.multi=zdj\u0119\u0107 dodano +confirm.photo.connect=przy\u0142\u0105czono zdj\u0119cie +confirm.photo.disconnect=od\u0142\u0105czono zdj\u0119cie +confirm.correlate.single=zdj\u0119cie zosta\u0142o po\u0142\u0105czone +confirm.correlate.multi=zdj\u0119cia zosta\u0142y po\u0142\u0105czone +confirm.createpoint=stworzono punkt # Buttons button.ok=OK @@ -271,7 +298,7 @@ button.back=Poprzedni button.next=Nast\u0119pny button.finish=Koniec button.cancel=Anuluj -button.overwrite=Zapisz Zmiany +button.overwrite=Nadpisz button.moveup=Do g\u00F3ry button.movedown=Do d\u00F3\u0142 button.showlines=Poka\u017C linie @@ -281,88 +308,97 @@ button.close=Zamknij button.continue=Kontynuuj button.yes=Tak button.no=Nie -button.yestoall=To wszystko -button.notoall=Nie wszystko +button.yestoall=Tak na wszystko +button.notoall=Nie na wszystko button.selectall=Zaznacz wszystko button.selectnone=Odznacz button.preview=Podgl\u0105d -button.guessfields= -button.showwebpage= +button.guessfields=Zgadnij pola +button.showwebpage=Poka\u017C stron\u0119 web +button.gnuplotpath=Podaj \u015Bcie\u017Ck\u0119 do gnuplot # File types filetype.txt=Pliki TXT filetype.jpeg=Pliki JPG filetype.kmlkmz=Pliki KML, KMZ filetype.kml=Pliki KML +filetype.kmz=Pliki KMZ filetype.gpx=Pliki GPX filetype.pov=Pliki POV +filetype.svg=Pliki SVG # Display components -display.nodata=Brak za\u0142awadowanych danych -display.noaltitudes=Track data does not include altitudes -details.trackdetails=Track szczeg\u00F3\u0142y -details.notrack=Brak za\u0142awadowanych track +display.nodata=Nie za\u0142adowano danych +display.noaltitudes=\u015Acie\u017Cki nie zawieraj\u0105 informacji o wysoko\u015Bci +details.trackdetails=Szczeg\u00F3\u0142y \u015Bcie\u017Cki +details.notrack=Brak za\u0142adowanych \u015Bcie\u017Cek details.track.points=Punkty details.track.file=Plik -details.track.numfiles=Number ze pliki -details.pointdetails=Punkt szczeg\u00F3\u0142y +details.track.numfiles=Ilo\u015B\u0107 plik\u00F3w +details.pointdetails=Szczeg\u00F3\u0142y punktu details.index.selected=Indeks details.index.of=z -details.nopointselection=Brak punkt zaznaczenia -details.speed= -details.photofile=Plik zdj\u0119cie -details.norangeselection=Brak range zaznaczenia -details.rangedetails=Range szczeg\u00F3\u0142y -details.range.selected= -details.range.to= -details.altitude.to= -details.range.climb= -details.range.descent= -details.coordformat=Format wsp\u00f3\u0142rz\u0119dne -details.distanceunits=Jednostki dystansowy +details.nopointselection=\u017Baden punkt nie jest zaznaczony +details.photofile=Plik zdj\u0119cia +details.norangeselection=Brak zakresu zaznaczenia +details.rangedetails=Szczeg\u00F3\u0142y zakresu +details.range.selected=Wybrany +details.range.to=do +details.altitude.to=do +details.range.climb=Wzniesienie +details.range.descent=Zst\u0105pienie +details.coordformat=Format wsp\u00f3\u0142rz\u0119dnych +details.distanceunits=Jednostki odleg\u0142o\u015Bci display.range.time.secs=s display.range.time.mins=m display.range.time.hours=h display.range.time.days=d -details.range.avespeed= -details.range.avemovingspeed= -details.waypointsphotos.waypoints=Waypoints +details.range.avespeed=\u015Arednia pr\u0119dko\u015B\u0107 +details.range.avemovingspeed=\u015Arednie przesuni\u0119cie +details.waypointsphotos.waypoints=Punkty po\u015Brednie details.waypointsphotos.photos=Zdj\u0119cia -details.photodetails=Zdj\u0119cie szczeg\u00F3\u0142y -details.nophoto=Brak zdj\u0119cie zaznaczenia +details.photodetails=Szczeg\u00F3\u0142y zdj\u0119cia +details.nophoto=Brak zaznaczonego zdj\u0119cia details.photo.loading=Wczytywanie -details.photo.connected= +details.photo.connected=Pod\u0142\u0105czony +map.overzoom=Brak map dla danego powi\u0119kszenia # Field names fieldname.latitude=Szeroko\u015B\u0107 fieldname.longitude=D\u0142ugo\u015B\u0107 fieldname.altitude=Wysoko\u015B\u0107 -fieldname.timestamp= +fieldname.timestamp=Czas +fieldname.time=Czas fieldname.waypointname=Nazwa -fieldname.waypointtype=Type -fieldname.newsegment= +fieldname.waypointtype=Typ +fieldname.newsegment=Odcinek fieldname.custom=U\u017Cytkownika fieldname.prefix=Pole -fieldname.distance=Dystansowy -fieldname.movingdistance= -fieldname.duration= +fieldname.distance=Odleg\u0142o\u015B\u0107 +fieldname.movingdistance=Odleg\u0142o\u015B\u0107 przesuni\u0119cia +fieldname.duration=Czas trwania +fieldname.speed=Pr\u0119dko\u015B\u0107 +fieldname.verticalspeed=Pr\u0119dko\u015B\u0107 pionowa # Measurement units units.original=Oryginalny units.default=Domy\u015Blny -units.metres=Metres +units.metres=Metry units.metres.short=m -units.feet=Feet +units.feet=Stopy units.feet.short=ft -units.kilometres=Kilometres +units.kilometres=Kilometry units.kilometres.short=km units.kmh=km/h -units.miles=Miles +units.miles=Mile units.miles.short=mi units.mph=mi/h -units.degminsec=Deg-min-sek -units.degmin=Deg-min -units.deg=Degrees +units.metrespersec=m/s +units.feetpersec=ft/s +units.hours=Godziny +units.degminsec=Sto-min-sek +units.degmin=Sto-min +units.deg=Stopnie units.iso8601=ISO 8601 # External urls @@ -375,51 +411,49 @@ cardinal.e=E cardinal.w=W # Undo operations -undo.load=load data -undo.loadphotos=load zdj\u0119cia -undo.editpoint=edycja punkt +undo.load=za\u0142aduj dane +undo.loadphotos=za\u0142aduj zdj\u0119cia +undo.editpoint=edycja punktu undo.deletepoint=usu\u0144 punkt -undo.deletephoto=remove zdj\u0119cie -undo.deleterange=usu\u0144 range -undo.compress= -undo.insert=insert punkty -undo.deleteduplicates=usu\u0144 duplicates -undo.reverse= -undo.mergetracksegments= -undo.addtimeoffset= -undo.rearrangewaypoints= -undo.cutandmove= -undo.connectphoto=connect zdj\u0119cie -undo.disconnectphoto=disconnect zdj\u0119cie -undo.correlate=correlate zdj\u0119cia -undo.createpoint= +undo.deletephoto=usu\u0144 zdj\u0119cie (nie z dysku) +undo.deleterange=usu\u0144 zakres +undo.compress=skompresuj \u015Bcie\u017Ck\u0119 +undo.insert=wstaw punkty +undo.reverse=odwr\u00F3\u0107 zakres +undo.mergetracksegments=po\u0142\u0105cz fragmenty \u015Bcie\u017Cki +undo.addtimeoffset=dodaj przesuni\u0119cie czasowe +undo.rearrangewaypoints=przestaw punkty po\u015Brednie +undo.cutandmove=przesu\u0144 fragment +undo.connectphoto=do\u0142\u0105cz zdj\u0119cie +undo.disconnectphoto=od\u0142\u0105cz zdj\u0119cie +undo.correlate=po\u0142\u0105cz ze zdj\u0119ciami +undo.createpoint=stw\u00F3rz punkt # Error messages -error.save.dialogtitle= -error.save.nodata= -error.save.failed=Failed to save the data to plik: -error.saveexif.filenotfound=Failed to find zdj\u0119cie plik -error.saveexif.cannotoverwrite1=Zdj\u0119cie plik -error.saveexif.cannotoverwrite2=is read-only and can't be overwritten. Write to copy? -error.load.dialogtitle=B\u0142\u0105d loading data -error.load.noread=Cannot read plik -error.load.nopoints=No koordinaty information found in the plik -error.load.unknownxml=Nieznany xml format: -error.load.othererror=B\u0142\u0105d reading plik: -error.jpegload.dialogtitle=B\u0142\u0105d loading zdj\u0119cia -error.jpegload.nofilesfound=No pliki found -error.jpegload.nojpegsfound=No jpeg pliki found -error.jpegload.noexiffound=No EXIF information found -error.jpegload.nogpsfound=No GPS information found -error.undofailed.title=Cofnij failed +error.save.dialogtitle=B\u0142\u0105d zapisu danych +error.save.nodata=Brak danych do zapisu +error.save.failed=Nie powi\u00F3d\u0142 si\u0119 zapis danych do pliku: +error.saveexif.filenotfound=Nie znaleziono pliku zdj\u0119cia +error.saveexif.cannotoverwrite1=Plik ze zdj\u0119ciem +error.saveexif.cannotoverwrite2=jest w trybie tylko do odczytu i nie mo\u017Ce zosta\u0107 nadpisany. Zapisa\u0107 do kopii? +error.load.dialogtitle=B\u0142\u0105d \u0142adowania danych +error.load.noread=Nie mo\u017Cna przeczyta\u0107 pliku +error.load.nopoints=Nie znaleziono informacji o wsp\u00F3\u0142rz\u0119dnych w pliku +error.load.unknownxml=Nieznany format xml: +error.load.noxmlinzip=Nie znaleziono pliku xml w pliku zip +error.load.othererror=B\u0142\u0105d czytania pliku: +error.jpegload.dialogtitle=B\u0142\u0105d \u0142adowania zdj\u0119cia +error.jpegload.nofilesfound=Nie znaleziono plik\u00F3w +error.jpegload.nojpegsfound=Nie znaleziono plik\u00F3w jpeg +error.jpegload.noexiffound=Nie znaleziono informacji EXIF +error.jpegload.nogpsfound=Nie znaleziono informacji GPS +error.undofailed.title=Cofnij nie powiod\u0142o si\u0119 error.undofailed.text=Nie mo\u017Cna cofn\u0105\u0107 -error.function.noop.title=Funkcji had no effect -error.rearrange.noop=Rearranging waypoints had no effect -error.function.notimplemented= -error.function.notavailable.title=Funkcji nie jest dost\u0119pny -error.function.nojava3d=This funkcji requires the Java3d library,\navailable from Sun.com. -error.3d.title=B\u0142\u0105d in 3d display -error.3d=A b\u0142\u0105d occurred with the 3d display -error.readme.notfound= -error.osmimage.dialogtitle= -error.osmimage.failed= +error.function.noop.title=Funkcja nie ma skutku +error.rearrange.noop=Przestawienie punkt\u00F3w po\u015Brednich nie przyniesie skutku +error.function.notavailable.title=Funkcja nie dost\u0119pna +error.function.nojava3d=Ta funkcja wymaga biblioteki Java3d,\ndost\u0119pnej na Sun.com. +error.3d=Nast\u0105pi\u0142 b\u0142\u0105d z wy\u015Bwietlaniem 3D +error.readme.notfound=Nie znaleziono pliku Readme +error.osmimage.dialogtitle=B\u0142\u0105d przy \u0142adowaniu obraz\u00F3w map +error.osmimage.failed=B\u0142\u0105d przy \u0142adowaniu obraz\u00F3w map. Sprawd\u017A po\u0142\u0105czenie z internetem. diff --git a/tim/prune/lang/prune-texts_pt.properties b/tim/prune/lang/prune-texts_pt.properties new file mode 100644 index 0000000..3944ed2 --- /dev/null +++ b/tim/prune/lang/prune-texts_pt.properties @@ -0,0 +1,459 @@ +# Text entries for the Prune application +# Portuguese entries as extra + +# Menu entries +menu.file=Arquivo +menu.file.open=Abrir +menu.file.addphotos= +menu.file.save=Salvar +menu.file.exit=Sair +menu.edit=Editar +menu.edit.undo=Desfazer +menu.edit.clearundo= +menu.edit.editpoint=Editar ponto +menu.edit.editwaypointname=Editar nome do waypoint +menu.edit.deletepoint= +menu.edit.deleterange= +menu.edit.deletemarked= +menu.edit.interpolate= +menu.edit.average= +menu.edit.reverse= +menu.edit.mergetracksegments= +menu.edit.rearrange= +menu.edit.rearrange.start= +menu.edit.rearrange.end= +menu.edit.rearrange.nearest= +menu.edit.cutandmove= +menu.select=Selecionar +menu.select.all=Selectionar tudo +menu.select.none=Não selecionar nenhuns +menu.select.start= +menu.select.end= +menu.photo=Foto +menu.photo.saveexif=Salvar exif +menu.photo.connect= +menu.photo.disconnect= +menu.photo.delete=Remover Foto +menu.view=Exibir +menu.view.browser= +menu.view.browser.google= +menu.view.browser.openstreetmap= +menu.view.browser.mapquest= +menu.view.browser.yahoo= +menu.help=Ajuda +# Popup menu for map +menu.map.zoomin=Ampliar zoom +menu.map.zoomout=Reduzir zoom +menu.map.zoomfull= +menu.map.newpoint= +menu.map.connect= +menu.map.autopan= +menu.map.showmap=Mostrar o mapa + +# Functions +function.loadfromgps= +function.sendtogps= +function.exportkml=Exportar KML +function.exportgpx=Exportar GPX +function.exportpov=Exportar POV +function.compress= +function.addtimeoffset= +function.charts=Diagramas +function.show3d=Visualizar 3d +function.distances=Distâncias +function.setmapbg= +function.correlatephotos= +function.help=Ajuda +function.about=Sobre o Prune +function.checkversion= + +# Dialogs +dialog.exit.confirm.title= +dialog.exit.confirm.text= +dialog.openappend.title= +dialog.openappend.text= +dialog.deletepoint.title= +dialog.deletepoint.deletephoto= +dialog.deletephoto.title= +dialog.deletephoto.deletepoint= +dialog.openoptions.title= +dialog.openoptions.filesnippet= +dialog.load.table.field= +dialog.load.table.datatype= +dialog.load.table.description= +dialog.delimiter.label= +dialog.delimiter.comma= +dialog.delimiter.tab= +dialog.delimiter.space= +dialog.delimiter.semicolon= +dialog.delimiter.other= +dialog.openoptions.deliminfo.records= +dialog.openoptions.deliminfo.fields= +dialog.openoptions.deliminfo.norecords= +dialog.openoptions.altitudeunits= +dialog.jpegload.subdirectories= +dialog.jpegload.loadjpegswithoutcoords= +dialog.jpegload.loadjpegsoutsidearea= +dialog.jpegload.progress.title= +dialog.jpegload.progress= +dialog.gpsload.nogpsbabel= +dialog.gpsload.device= +dialog.gpsload.format= +dialog.gpsload.getwaypoints= +dialog.gpsload.gettracks= +dialog.gpssend.sendwaypoints= +dialog.gpssend.sendtracks= +dialog.gpssend.trackname= +dialog.saveoptions.title= +dialog.save.fieldstosave= +dialog.save.table.field= +dialog.save.table.hasdata= +dialog.save.table.save= +dialog.save.headerrow= +dialog.save.coordinateunits= +dialog.save.altitudeunits= +dialog.save.timestampformat= +dialog.save.overwrite.title= +dialog.save.overwrite.text= +dialog.exportkml.text= +dialog.exportkml.altitude= +dialog.exportkml.kmz= +dialog.exportkml.exportimages= +dialog.exportgpx.name= +dialog.exportgpx.desc= +dialog.exportgpx.includetimestamps= +dialog.exportpov.text= +dialog.exportpov.font= +dialog.exportpov.camerax= +dialog.exportpov.cameray= +dialog.exportpov.cameraz= +dialog.exportpov.modelstyle= +dialog.exportpov.ballsandsticks= +dialog.exportpov.tubesandwalls= +dialog.exportpov.warningtracksize= +dialog.confirmreversetrack.title= +dialog.confirmreversetrack.text= +dialog.confirmcutandmove.title= +dialog.confirmcutandmove.text= +dialog.interpolate.title= +dialog.interpolate.parameter.text= +dialog.undo.title= +dialog.undo.pretext= +dialog.undo.none.title= +dialog.undo.none.text= +dialog.clearundo.title= +dialog.clearundo.text= +dialog.pointedit.title= +dialog.pointedit.text= +dialog.pointedit.table.field= +dialog.pointedit.table.value= +dialog.pointedit.table.changed= +dialog.pointedit.changevalue.text= +dialog.pointedit.changevalue.title= +dialog.pointnameedit.title= +dialog.pointnameedit.name= +dialog.pointnameedit.uppercase= +dialog.pointnameedit.lowercase= +dialog.pointnameedit.sentencecase= +dialog.addtimeoffset.add= +dialog.addtimeoffset.subtract= +dialog.addtimeoffset.days= +dialog.addtimeoffset.hours= +dialog.addtimeoffset.minutes= +dialog.addtimeoffset.notimestamps= +dialog.connect.title= +dialog.connectphoto.clonepoint= +dialog.saveexif.title= +dialog.saveexif.intro= +dialog.saveexif.nothingtosave= +dialog.saveexif.noexiftool= +dialog.saveexif.table.photoname= +dialog.saveexif.table.status= +dialog.saveexif.table.save= +dialog.saveexif.photostatus.connected= +dialog.saveexif.photostatus.disconnected= +dialog.saveexif.photostatus.modified= +dialog.saveexif.overwrite= +dialog.charts.xaxis= +dialog.charts.yaxis= +dialog.charts.output= +dialog.charts.screen= +dialog.charts.svg= +dialog.charts.svgwidth= +dialog.charts.svgheight= +dialog.charts.needaltitudeortimes= +dialog.charts.gnuplotpath= +dialog.charts.gnuplotnotfound= +dialog.distances.intro= +dialog.distances.column.from= +dialog.distances.column.to= +dialog.distances.currentpoint= +dialog.distances.toofewpoints= +dialog.setmapbg.mapnik= +dialog.setmapbg.osma= +dialog.setmapbg.cyclemap= +dialog.setmapbg.other= +dialog.setmapbg.server= +dialog.correlate.notimestamps= +dialog.correlate.nouncorrelatedphotos= +dialog.correlate.photoselect.intro= +dialog.correlate.photoselect.photoname= +dialog.correlate.photoselect.timediff= +dialog.correlate.photoselect.photolater= +dialog.correlate.options.tip= +dialog.correlate.options.intro= +dialog.correlate.options.offsetpanel= +dialog.correlate.options.offset= +dialog.correlate.options.offset.hours= +dialog.correlate.options.offset.minutes= +dialog.correlate.options.offset.seconds= +dialog.correlate.options.photolater= +dialog.correlate.options.pointlater= +dialog.correlate.options.limitspanel= +dialog.correlate.options.notimelimit= +dialog.correlate.options.timelimit= +dialog.correlate.options.nodistancelimit= +dialog.correlate.options.distancelimit= +dialog.correlate.options.correlate= +dialog.correlate.alloutsiderange= +dialog.compress.nonefound= +dialog.compress.duplicates.title= +dialog.compress.closepoints.title= +dialog.compress.closepoints.paramdesc= +dialog.compress.wackypoints.title= +dialog.compress.wackypoints.paramdesc= +dialog.compress.singletons.title= +dialog.compress.singletons.paramdesc= +dialog.compress.summarylabel= +dialog.help.help= +dialog.about.version= +dialog.about.build= +dialog.about.summarytext1= +dialog.about.summarytext2= +dialog.about.summarytext3= +dialog.about.languages= +dialog.about.translatedby= +dialog.about.systeminfo= +dialog.about.systeminfo.os= +dialog.about.systeminfo.java= +dialog.about.systeminfo.java3d= +dialog.about.systeminfo.povray= +dialog.about.systeminfo.exiftool= +dialog.about.systeminfo.gpsbabel= +dialog.about.systeminfo.gnuplot= +dialog.about.yes=Sim +dialog.about.no=Não +dialog.about.credits= +dialog.about.credits.code= +dialog.about.credits.exifcode= +dialog.about.credits.icons= +dialog.about.credits.translators= +dialog.about.credits.translations= +dialog.about.credits.devtools= +dialog.about.credits.othertools= +dialog.about.credits.thanks= +dialog.about.readme= +dialog.checkversion.error= +dialog.checkversion.uptodate= +dialog.checkversion.newversion1= +dialog.checkversion.newversion2= +dialog.checkversion.releasedate1= +dialog.checkversion.releasedate2= +dialog.checkversion.download= + +# 3d window +dialog.3d.title= +dialog.3d.altitudecap= +dialog.3dlines.title= +dialog.3dlines.empty= +dialog.3dlines.intro= + +# Confirm messages || These are displayed as confirmation in the status bar +confirm.loadfile= +confirm.save.ok1= +confirm.save.ok2= +confirm.deletepoint.single= +confirm.deletepoint.multi= +confirm.point.edit= +confirm.mergetracksegments= +confirm.reverserange= +confirm.addtimeoffset= +confirm.rearrangewaypoints= +confirm.cutandmove= +confirm.saveexif.ok1= +confirm.saveexif.ok2= +confirm.undo.single= +confirm.undo.multi= +confirm.jpegload.single= +confirm.jpegload.multi= +confirm.photo.connect= +confirm.photo.disconnect= +confirm.correlate.single= +confirm.correlate.multi= +confirm.createpoint= + +# Buttons +button.ok= +button.back= +button.next= +button.finish= +button.cancel=Cancelar +button.overwrite= +button.moveup= +button.movedown= +button.showlines= +button.edit=Editar +button.exit=Sair +button.close=Fechar +button.continue= +button.yes=Sim +button.no=Não +button.yestoall= +button.notoall= +button.selectall= +button.selectnone= +button.preview= +button.guessfields= +button.showwebpage= +button.gnuplotpath= + +# File types +filetype.txt= +filetype.jpeg= +filetype.kmlkmz= +filetype.kml= +filetype.kmz= +filetype.gpx= +filetype.pov= +filetype.svg= + +# Display components +display.nodata=Nenhum dados foi carregado +display.noaltitudes= +details.trackdetails=Detalhes da track +details.notrack= +details.track.points=Pontos +details.track.file=Arquivo +details.track.numfiles=Número de arquivos +details.pointdetails=Detalhes da ponto +details.index.selected= +details.index.of=de +details.nopointselection= +details.photofile= +details.norangeselection= +details.rangedetails=Detalhes da range +details.range.selected=Selecionado +details.range.to=a +details.altitude.to=a +details.range.climb= +details.range.descent= +details.coordformat= +details.distanceunits= +display.range.time.secs= +display.range.time.mins= +display.range.time.hours= +display.range.time.days= +details.range.avespeed= +details.range.avemovingspeed= +details.waypointsphotos.waypoints= +details.waypointsphotos.photos=Fotos +details.photodetails=Detalhes da foto +details.nophoto= +details.photo.loading=Carregando +details.photo.connected= +map.overzoom= + +# Field names +fieldname.latitude=Latitude +fieldname.longitude=Longitude +fieldname.altitude=Altura +fieldname.timestamp= +fieldname.time=Tempo +fieldname.waypointname= +fieldname.waypointtype= +fieldname.newsegment= +fieldname.custom= +fieldname.prefix= +fieldname.distance=Distância +fieldname.movingdistance= +fieldname.duration= +fieldname.speed=Velocidade +fieldname.verticalspeed= + +# Measurement units +units.original= +units.default= +units.metres= +units.metres.short= +units.feet= +units.feet.short= +units.kilometres= +units.kilometres.short= +units.kmh= +units.miles= +units.miles.short= +units.mph= +units.metrespersec= +units.feetpersec= +units.hours= +units.degminsec= +units.degmin= +units.deg= +units.iso8601= + +# External urls +url.googlemaps=maps.google.pt + +# Cardinals for 3d plots +cardinal.n= +cardinal.s= +cardinal.e= +cardinal.w= + +# Undo operations +undo.load= +undo.loadphotos= +undo.editpoint= +undo.deletepoint= +undo.deletephoto= +undo.deleterange= +undo.compress= +undo.insert= +undo.reverse= +undo.mergetracksegments= +undo.addtimeoffset= +undo.rearrangewaypoints= +undo.cutandmove= +undo.connectphoto= +undo.disconnectphoto= +undo.correlate= +undo.createpoint= + +# Error messages +error.save.dialogtitle= +error.save.nodata= +error.save.failed= +error.saveexif.filenotfound= +error.saveexif.cannotoverwrite1= +error.saveexif.cannotoverwrite2= +error.load.dialogtitle= +error.load.noread= +error.load.nopoints= +error.load.unknownxml= +error.load.noxmlinzip= +error.load.othererror= +error.jpegload.dialogtitle= +error.jpegload.nofilesfound= +error.jpegload.nojpegsfound= +error.jpegload.noexiffound= +error.jpegload.nogpsfound= +error.undofailed.title= +error.undofailed.text= +error.function.noop.title= +error.rearrange.noop= +error.function.notavailable.title= +error.function.nojava3d= +error.3d= +error.readme.notfound= +error.osmimage.dialogtitle= +error.osmimage.failed= diff --git a/tim/prune/lang/prune-texts_ro.properties b/tim/prune/lang/prune-texts_ro.properties new file mode 100644 index 0000000..95c1df0 --- /dev/null +++ b/tim/prune/lang/prune-texts_ro.properties @@ -0,0 +1,459 @@ +# Text entries for the Prune application +# Romanian entries as extra + +# Menu entries +menu.file=Fisier +menu.file.open=Deschidere fisier +menu.file.addphotos=Adaugare foto +menu.file.save=Salvare +menu.file.exit=Iesire +menu.edit=Editare +menu.edit.undo=Anulare +menu.edit.clearundo=Stergere lista de anulari +menu.edit.editpoint=Editare punct +menu.edit.editwaypointname=Editare nume waypoint +menu.edit.deletepoint=Stergere punct +menu.edit.deleterange=Stergere gama +menu.edit.deletemarked=Stergere puncte marcate +menu.edit.interpolate=Interpolare +menu.edit.average=Mediere selectie +menu.edit.reverse=Inversare selectie +menu.edit.mergetracksegments=Unire segmente traseu +menu.edit.rearrange=Rearanjare waypoint +menu.edit.rearrange.start=Toate la inceputul fisierului +menu.edit.rearrange.end=Toate la sfarsitul fisierului +menu.edit.rearrange.nearest=Fiecare la punctul cel mai apropiat al traseului +menu.edit.cutandmove=Taiere si mutare selectie +menu.select=Selectare +menu.select.all=Selectare toate +menu.select.none=Nu selecta niciun punct +menu.select.start=Seteaza inceputul selectiei +menu.select.end=Seteaza sfarsitul selectiei +menu.photo=Foto +menu.photo.saveexif=Salveaza la Exif +menu.photo.connect=Conecteaza la punct +menu.photo.disconnect=Deconecteaza de la punct +menu.photo.delete=Elimina foto +menu.view=Vizualizare +menu.view.browser=Harta in browser +menu.view.browser.google=Harti Google +menu.view.browser.openstreetmap=Openstreetmap +menu.view.browser.mapquest=Mapquest +menu.view.browser.yahoo=Harti Yahoo +menu.help=Ajutor +# Popup menu for map +menu.map.zoomin= +menu.map.zoomout= +menu.map.zoomfull= +menu.map.newpoint= +menu.map.connect= +menu.map.autopan= +menu.map.showmap= + +# Functions +function.loadfromgps= +function.sendtogps= +function.exportkml= +function.exportgpx= +function.exportpov= +function.compress= +function.addtimeoffset= +function.charts= +function.show3d= +function.distances= +function.setmapbg= +function.correlatephotos= +function.help= +function.about= +function.checkversion= + +# Dialogs +dialog.exit.confirm.title= +dialog.exit.confirm.text= +dialog.openappend.title= +dialog.openappend.text= +dialog.deletepoint.title= +dialog.deletepoint.deletephoto= +dialog.deletephoto.title= +dialog.deletephoto.deletepoint= +dialog.openoptions.title= +dialog.openoptions.filesnippet= +dialog.load.table.field= +dialog.load.table.datatype= +dialog.load.table.description= +dialog.delimiter.label= +dialog.delimiter.comma= +dialog.delimiter.tab= +dialog.delimiter.space= +dialog.delimiter.semicolon= +dialog.delimiter.other= +dialog.openoptions.deliminfo.records= +dialog.openoptions.deliminfo.fields= +dialog.openoptions.deliminfo.norecords= +dialog.openoptions.altitudeunits= +dialog.jpegload.subdirectories= +dialog.jpegload.loadjpegswithoutcoords= +dialog.jpegload.loadjpegsoutsidearea= +dialog.jpegload.progress.title= +dialog.jpegload.progress= +dialog.gpsload.nogpsbabel= +dialog.gpsload.device= +dialog.gpsload.format= +dialog.gpsload.getwaypoints= +dialog.gpsload.gettracks= +dialog.gpssend.sendwaypoints= +dialog.gpssend.sendtracks= +dialog.gpssend.trackname= +dialog.saveoptions.title= +dialog.save.fieldstosave= +dialog.save.table.field= +dialog.save.table.hasdata= +dialog.save.table.save= +dialog.save.headerrow= +dialog.save.coordinateunits= +dialog.save.altitudeunits= +dialog.save.timestampformat= +dialog.save.overwrite.title= +dialog.save.overwrite.text= +dialog.exportkml.text= +dialog.exportkml.altitude= +dialog.exportkml.kmz= +dialog.exportkml.exportimages= +dialog.exportgpx.name= +dialog.exportgpx.desc= +dialog.exportgpx.includetimestamps= +dialog.exportpov.text= +dialog.exportpov.font= +dialog.exportpov.camerax= +dialog.exportpov.cameray= +dialog.exportpov.cameraz= +dialog.exportpov.modelstyle= +dialog.exportpov.ballsandsticks= +dialog.exportpov.tubesandwalls= +dialog.exportpov.warningtracksize= +dialog.confirmreversetrack.title= +dialog.confirmreversetrack.text= +dialog.confirmcutandmove.title= +dialog.confirmcutandmove.text= +dialog.interpolate.title= +dialog.interpolate.parameter.text= +dialog.undo.title= +dialog.undo.pretext= +dialog.undo.none.title= +dialog.undo.none.text= +dialog.clearundo.title= +dialog.clearundo.text= +dialog.pointedit.title= +dialog.pointedit.text= +dialog.pointedit.table.field= +dialog.pointedit.table.value= +dialog.pointedit.table.changed= +dialog.pointedit.changevalue.text= +dialog.pointedit.changevalue.title= +dialog.pointnameedit.title= +dialog.pointnameedit.name= +dialog.pointnameedit.uppercase= +dialog.pointnameedit.lowercase= +dialog.pointnameedit.sentencecase= +dialog.addtimeoffset.add= +dialog.addtimeoffset.subtract= +dialog.addtimeoffset.days= +dialog.addtimeoffset.hours= +dialog.addtimeoffset.minutes= +dialog.addtimeoffset.notimestamps= +dialog.connect.title= +dialog.connectphoto.clonepoint= +dialog.saveexif.title= +dialog.saveexif.intro= +dialog.saveexif.nothingtosave= +dialog.saveexif.noexiftool= +dialog.saveexif.table.photoname= +dialog.saveexif.table.status= +dialog.saveexif.table.save= +dialog.saveexif.photostatus.connected= +dialog.saveexif.photostatus.disconnected= +dialog.saveexif.photostatus.modified= +dialog.saveexif.overwrite= +dialog.charts.xaxis= +dialog.charts.yaxis= +dialog.charts.output= +dialog.charts.screen= +dialog.charts.svg= +dialog.charts.svgwidth= +dialog.charts.svgheight= +dialog.charts.needaltitudeortimes= +dialog.charts.gnuplotpath= +dialog.charts.gnuplotnotfound= +dialog.distances.intro= +dialog.distances.column.from= +dialog.distances.column.to= +dialog.distances.currentpoint= +dialog.distances.toofewpoints= +dialog.setmapbg.mapnik= +dialog.setmapbg.osma= +dialog.setmapbg.cyclemap= +dialog.setmapbg.other= +dialog.setmapbg.server= +dialog.correlate.notimestamps= +dialog.correlate.nouncorrelatedphotos= +dialog.correlate.photoselect.intro= +dialog.correlate.photoselect.photoname= +dialog.correlate.photoselect.timediff= +dialog.correlate.photoselect.photolater= +dialog.correlate.options.tip= +dialog.correlate.options.intro= +dialog.correlate.options.offsetpanel= +dialog.correlate.options.offset= +dialog.correlate.options.offset.hours= +dialog.correlate.options.offset.minutes= +dialog.correlate.options.offset.seconds= +dialog.correlate.options.photolater= +dialog.correlate.options.pointlater= +dialog.correlate.options.limitspanel= +dialog.correlate.options.notimelimit= +dialog.correlate.options.timelimit= +dialog.correlate.options.nodistancelimit= +dialog.correlate.options.distancelimit= +dialog.correlate.options.correlate= +dialog.correlate.alloutsiderange= +dialog.compress.nonefound= +dialog.compress.duplicates.title= +dialog.compress.closepoints.title= +dialog.compress.closepoints.paramdesc= +dialog.compress.wackypoints.title= +dialog.compress.wackypoints.paramdesc= +dialog.compress.singletons.title= +dialog.compress.singletons.paramdesc= +dialog.compress.summarylabel= +dialog.help.help= +dialog.about.version= +dialog.about.build= +dialog.about.summarytext1= +dialog.about.summarytext2= +dialog.about.summarytext3= +dialog.about.languages= +dialog.about.translatedby= +dialog.about.systeminfo= +dialog.about.systeminfo.os= +dialog.about.systeminfo.java= +dialog.about.systeminfo.java3d= +dialog.about.systeminfo.povray= +dialog.about.systeminfo.exiftool= +dialog.about.systeminfo.gpsbabel= +dialog.about.systeminfo.gnuplot= +dialog.about.yes= +dialog.about.no= +dialog.about.credits= +dialog.about.credits.code= +dialog.about.credits.exifcode= +dialog.about.credits.icons= +dialog.about.credits.translators= +dialog.about.credits.translations= +dialog.about.credits.devtools= +dialog.about.credits.othertools= +dialog.about.credits.thanks= +dialog.about.readme= +dialog.checkversion.error= +dialog.checkversion.uptodate= +dialog.checkversion.newversion1= +dialog.checkversion.newversion2= +dialog.checkversion.releasedate1= +dialog.checkversion.releasedate2= +dialog.checkversion.download= + +# 3d window +dialog.3d.title= +dialog.3d.altitudecap= +dialog.3dlines.title= +dialog.3dlines.empty= +dialog.3dlines.intro= + +# Confirm messages || These are displayed as confirmation in the status bar +confirm.loadfile= +confirm.save.ok1= +confirm.save.ok2= +confirm.deletepoint.single= +confirm.deletepoint.multi= +confirm.point.edit= +confirm.mergetracksegments= +confirm.reverserange= +confirm.addtimeoffset= +confirm.rearrangewaypoints= +confirm.cutandmove= +confirm.saveexif.ok1= +confirm.saveexif.ok2= +confirm.undo.single= +confirm.undo.multi= +confirm.jpegload.single= +confirm.jpegload.multi= +confirm.photo.connect= +confirm.photo.disconnect= +confirm.correlate.single= +confirm.correlate.multi= +confirm.createpoint= + +# Buttons +button.ok= +button.back= +button.next= +button.finish= +button.cancel= +button.overwrite= +button.moveup= +button.movedown= +button.showlines= +button.edit= +button.exit= +button.close= +button.continue= +button.yes= +button.no= +button.yestoall= +button.notoall= +button.selectall= +button.selectnone= +button.preview= +button.guessfields= +button.showwebpage= +button.gnuplotpath= + +# File types +filetype.txt= +filetype.jpeg= +filetype.kmlkmz= +filetype.kml= +filetype.kmz= +filetype.gpx= +filetype.pov= +filetype.svg= + +# Display components +display.nodata= +display.noaltitudes= +details.trackdetails= +details.notrack= +details.track.points= +details.track.file= +details.track.numfiles= +details.pointdetails= +details.index.selected= +details.index.of= +details.nopointselection= +details.photofile= +details.norangeselection= +details.rangedetails= +details.range.selected= +details.range.to= +details.altitude.to= +details.range.climb= +details.range.descent= +details.coordformat= +details.distanceunits= +display.range.time.secs= +display.range.time.mins= +display.range.time.hours= +display.range.time.days= +details.range.avespeed= +details.range.avemovingspeed= +details.waypointsphotos.waypoints= +details.waypointsphotos.photos= +details.photodetails= +details.nophoto= +details.photo.loading= +details.photo.connected= +map.overzoom= + +# Field names +fieldname.latitude= +fieldname.longitude= +fieldname.altitude= +fieldname.timestamp= +fieldname.time= +fieldname.waypointname= +fieldname.waypointtype= +fieldname.newsegment= +fieldname.custom= +fieldname.prefix= +fieldname.distance= +fieldname.movingdistance= +fieldname.duration= +fieldname.speed= +fieldname.verticalspeed= + +# Measurement units +units.original= +units.default= +units.metres= +units.metres.short= +units.feet= +units.feet.short= +units.kilometres= +units.kilometres.short= +units.kmh= +units.miles= +units.miles.short= +units.mph= +units.metrespersec= +units.feetpersec= +units.hours= +units.degminsec= +units.degmin= +units.deg= +units.iso8601= + +# External urls +url.googlemaps= + +# Cardinals for 3d plots +cardinal.n= +cardinal.s= +cardinal.e= +cardinal.w= + +# Undo operations +undo.load= +undo.loadphotos= +undo.editpoint= +undo.deletepoint= +undo.deletephoto= +undo.deleterange= +undo.compress= +undo.insert= +undo.reverse= +undo.mergetracksegments= +undo.addtimeoffset= +undo.rearrangewaypoints= +undo.cutandmove= +undo.connectphoto= +undo.disconnectphoto= +undo.correlate= +undo.createpoint= + +# Error messages +error.save.dialogtitle= +error.save.nodata= +error.save.failed= +error.saveexif.filenotfound= +error.saveexif.cannotoverwrite1= +error.saveexif.cannotoverwrite2= +error.load.dialogtitle= +error.load.noread= +error.load.nopoints= +error.load.unknownxml= +error.load.noxmlinzip= +error.load.othererror= +error.jpegload.dialogtitle= +error.jpegload.nofilesfound= +error.jpegload.nojpegsfound= +error.jpegload.noexiffound= +error.jpegload.nogpsfound= +error.undofailed.title= +error.undofailed.text= +error.function.noop.title= +error.rearrange.noop= +error.function.notavailable.title= +error.function.nojava3d= +error.3d= +error.readme.notfound= +error.osmimage.dialogtitle= +error.osmimage.failed= diff --git a/tim/prune/load/FieldSelectionTableModel.java b/tim/prune/load/FieldSelectionTableModel.java index 6814e2b..d4d92a0 100644 --- a/tim/prune/load/FieldSelectionTableModel.java +++ b/tim/prune/load/FieldSelectionTableModel.java @@ -215,9 +215,7 @@ public class FieldSelectionTableModel extends AbstractTableModel if (!hasField(inValue)) { // Change is ok - find new Field object corresponding to text - for (int i=0; i contentList = new ArrayList(); if (_file != null && _file.exists() && _file.canRead()) { BufferedReader reader = null; @@ -62,7 +62,7 @@ public class FileCacher int numLines = contentList.size(); _contentArray = new String[numLines]; for (int i=0; i 0) {errorMessage = errorMessage2;} if (errorMessage.length() > 0) {throw new Exception(errorMessage);} // Send data back to app - boolean append = _waypointCheckbox.isSelected() && !inWaypoints; _app.informDataLoaded(handler.getFieldArray(), handler.getDataArray(), - Altitude.FORMAT_METRES, _deviceField.getText(), append); + Altitude.Format.METRES, _deviceField.getText()); } } diff --git a/tim/prune/load/JpegLoader.java b/tim/prune/load/JpegLoader.java index c506236..7939f1b 100644 --- a/tim/prune/load/JpegLoader.java +++ b/tim/prune/load/JpegLoader.java @@ -13,7 +13,6 @@ import javax.swing.JDialog; import javax.swing.JFileChooser; import javax.swing.JFrame; import javax.swing.JLabel; -import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JProgressBar; @@ -26,7 +25,6 @@ import tim.prune.data.LatLonRectangle; import tim.prune.data.Latitude; import tim.prune.data.Longitude; import tim.prune.data.Photo; -import tim.prune.data.PhotoStatus; import tim.prune.data.Timestamp; import tim.prune.drew.jpeg.ExifReader; import tim.prune.drew.jpeg.JpegData; @@ -50,7 +48,7 @@ public class JpegLoader implements Runnable private int[] _fileCounts = null; private boolean _cancelled = false; private LatLonRectangle _trackRectangle = null; - private TreeSet _photos = null; + private TreeSet _photos = null; /** @@ -136,7 +134,7 @@ public class JpegLoader implements Runnable panel.add(cancelButton); _progressDialog.getContentPane().add(panel); _progressDialog.pack(); - _progressDialog.show(); + _progressDialog.setVisible(true); } @@ -147,7 +145,7 @@ public class JpegLoader implements Runnable { // Initialise arrays, errors, summaries _fileCounts = new int[4]; // files, jpegs, exifs, gps - _photos = new TreeSet(new PhotoSorter()); + _photos = new TreeSet(new PhotoSorter()); File[] files = _fileChooser.getSelectedFiles(); // Loop recursively over selected files/directories to count files int numFiles = countFileList(files, true, _subdirCheckbox.isSelected()); @@ -158,7 +156,7 @@ public class JpegLoader implements Runnable // Process the files recursively and build lists of photos processFileList(files, true, _subdirCheckbox.isSelected()); - _progressDialog.hide(); + _progressDialog.setVisible(false); if (_cancelled) {return;} //System.out.println("Finished - counts are: " + _fileCounts[0] + ", " + _fileCounts[1] @@ -166,26 +164,22 @@ public class JpegLoader implements Runnable if (_fileCounts[0] == 0) { // No files found at all - JOptionPane.showMessageDialog(_parentFrame, I18nManager.getText("error.jpegload.nofilesfound"), - I18nManager.getText("error.jpegload.dialogtitle"), JOptionPane.ERROR_MESSAGE); + _app.showErrorMessage("error.jpegload.dialogtitle", "error.jpegload.nofilesfound"); } else if (_fileCounts[1] == 0) { // No jpegs found - JOptionPane.showMessageDialog(_parentFrame, I18nManager.getText("error.jpegload.nojpegsfound"), - I18nManager.getText("error.jpegload.dialogtitle"), JOptionPane.ERROR_MESSAGE); + _app.showErrorMessage("error.jpegload.dialogtitle", "error.jpegload.nojpegsfound"); } else if (!_noExifCheckbox.isSelected() && _fileCounts[2] == 0) { // Need coordinates but no exif found - JOptionPane.showMessageDialog(_parentFrame, I18nManager.getText("error.jpegload.noexiffound"), - I18nManager.getText("error.jpegload.dialogtitle"), JOptionPane.ERROR_MESSAGE); + _app.showErrorMessage("error.jpegload.dialogtitle", "error.jpegload.noexiffound"); } else if (!_noExifCheckbox.isSelected() && _fileCounts[3] == 0) { // Need coordinates but no gps information found - JOptionPane.showMessageDialog(_parentFrame, I18nManager.getText("error.jpegload.nogpsfound"), - I18nManager.getText("error.jpegload.dialogtitle"), JOptionPane.ERROR_MESSAGE); + _app.showErrorMessage("error.jpegload.dialogtitle", "error.jpegload.nogpsfound"); } else { @@ -271,7 +265,7 @@ public class JpegLoader implements Runnable point.setPhoto(photo); point.setSegmentStart(true); photo.setDataPoint(point); - photo.setOriginalStatus(PhotoStatus.TAGGED); + photo.setOriginalStatus(Photo.Status.TAGGED); _fileCounts[3]++; } // Use exif timestamp if gps timestamp not available @@ -352,7 +346,7 @@ public class JpegLoader implements Runnable Altitude altitude = null; if (inData.getAltitude() != null) { - altitude = new Altitude(inData.getAltitude().intValue(), Altitude.FORMAT_METRES); + altitude = new Altitude(inData.getAltitude().intValue(), Altitude.Format.METRES); } return new DataPoint(latitude, longitude, altitude); } diff --git a/tim/prune/load/PhotoSorter.java b/tim/prune/load/PhotoSorter.java index 7e65cac..6da6f64 100644 --- a/tim/prune/load/PhotoSorter.java +++ b/tim/prune/load/PhotoSorter.java @@ -8,17 +8,17 @@ import tim.prune.data.Photo; /** * Class to sort photos by name */ -public class PhotoSorter implements Comparator +public class PhotoSorter implements Comparator { /** * Compare two photos * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object) */ - public int compare(Object o1, Object o2) + public int compare(Photo o1, Photo o2) { - File file1 = ((Photo) o1).getFile(); - File file2 = ((Photo) o2).getFile(); + File file1 = o1.getFile(); + File file2 = o2.getFile(); int nameComp = file1.getName().compareTo(file2.getName()); if (nameComp == 0) { diff --git a/tim/prune/load/TextFileLoader.java b/tim/prune/load/TextFileLoader.java index 0d7ef48..d4a9aa6 100644 --- a/tim/prune/load/TextFileLoader.java +++ b/tim/prune/load/TextFileLoader.java @@ -54,7 +54,7 @@ public class TextFileLoader // previously selected values private char _lastUsedDelimiter = ','; private Field[] _lastSelectedFields = null; - private int _lastAltitudeFormat = Altitude.FORMAT_NONE; + private Altitude.Format _lastAltitudeFormat = Altitude.Format.NO_FORMAT; // constants private static final int SNIPPET_SIZE = 6; @@ -122,12 +122,11 @@ public class TextFileLoader _delimiterRadios[_delimiterRadios.length-1].setSelected(true); informDelimiterSelected(); _dialog.pack(); - _dialog.show(); + _dialog.setVisible(true); } - else - { - JOptionPane.showMessageDialog(_parentFrame, I18nManager.getText("error.load.noread"), - I18nManager.getText("error.load.dialogtitle"), JOptionPane.ERROR_MESSAGE); + else { + // Didn't pass pre-check + _app.showErrorMessage("error.load.dialogtitle", "error.load.noread"); } } @@ -318,7 +317,7 @@ public class TextFileLoader JScrollPane tableScrollPane = new JScrollPane(extractTable); extractTable.setPreferredScrollableViewportSize(new Dimension(350, 80)); extractTable.getTableHeader().setReorderingAllowed(false); - secondCard.add(makeLabelledPanel("dialog.openoptions.tabledesc", tableScrollPane), BorderLayout.NORTH); + secondCard.add(makeLabelledPanel("dialog.openoptions.filesnippet", tableScrollPane), BorderLayout.NORTH); JPanel innerPanel2 = new JPanel(); innerPanel2.setLayout(new BorderLayout()); innerPanel2.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); @@ -494,16 +493,17 @@ public class TextFileLoader _fieldTable.setModel(_fieldTableModel); // add dropdowns to second column JComboBox fieldTypesBox = new JComboBox(); - for (int i=0; i _pointList = new ArrayList(); /** @@ -161,7 +161,7 @@ public class GpxHandler extends XmlHandler String[][] result = new String[numPoints][]; for (int i=0; i _pointList = new ArrayList(); /** @@ -97,11 +97,16 @@ public class KmlHandler extends XmlHandler else if (numPoints > 1) { // Add each of the unnamed track points to list + boolean firstPoint = true; for (int p=0; p3) + { + String[] pointArray = makeStringArray(coordArray[p], null); + if (firstPoint) {pointArray[4] = "1";} + firstPoint = false; + _pointList.add(pointArray); + } } } } @@ -144,7 +149,7 @@ public class KmlHandler extends XmlHandler String[][] result = new String[numPoints][]; for (int i=0; i entries = file.entries(); + boolean xmlFound = false; + while (entries.hasMoreElements() && !xmlFound) + { + ZipEntry entry = (ZipEntry) entries.nextElement(); + String entryName = entry.toString(); + if (entryName != null && entryName.length() > 4) + { + String suffix = entryName.substring(entryName.length()-4).toLowerCase(); + if (suffix.equals(".kml") || suffix.equals(".gpx") || suffix.equals(".xml")) + { + _xmlLoader.reset(); + SAXParser saxParser = SAXParserFactory.newInstance().newSAXParser(); + saxParser.parse(file.getInputStream(entry), _xmlLoader); + XmlHandler handler = _xmlLoader.getHandler(); + if (handler == null) { + _app.showErrorMessage("error.load.dialogtitle", "error.load.othererror"); + } + else { + // Send back to app + _app.informDataLoaded(handler.getFieldArray(), handler.getDataArray(), + Altitude.Format.METRES, inFile.getName()); + xmlFound = true; + } + } + } + } + file.close(); + // Check whether there was an xml file inside + if (!xmlFound) { + _app.showErrorMessage("error.load.dialogtitle", "error.load.noxmlinzip"); + } + } + catch (Exception e) { + System.err.println("Error: " + e.getMessage()); + } + } + +} diff --git a/tim/prune/readme.txt b/tim/prune/readme.txt index bdc6cae..660750a 100644 --- a/tim/prune/readme.txt +++ b/tim/prune/readme.txt @@ -1,8 +1,9 @@ -Prune version 6 +Prune version 7 =============== Prune is an application for viewing, editing and managing coordinate data from GPS systems, -including format conversion and photo correlation. +including format conversion, charting and photo correlation. +Full details can be found at http://activityworkshop.net/software/prune/ Prune is copyright activityworkshop.net and distributed under the terms of the Gnu GPL version 2. You may freely use the software, and may help others to freely use it too. For further information @@ -16,7 +17,7 @@ Running ======= To run Prune from the jar file, simply call it from a command prompt or shell: - java -jar prune_06.jar + java -jar prune_07.jar If the jar file is saved in a different directory, you will need to include the path. Depending on your system settings, you may be able to click or double-click on the jar file @@ -24,9 +25,21 @@ in a file manager window to execute it. A shortcut, menu item, alias, desktop i or other link can of course be made should you wish. To specify a language other than the default, use an additional parameter, eg: - java -jar prune_06.jar --lang=DE + java -jar prune_07.jar --lang=DE +New with version 7 +================== + +The following features were added since version 6: + - Loading of KMZ files and zipped GPX + - Improved compression functions with four configurable algorithms + - New function to call gpsbabel to send data directly to GPS receiver + - Charting functions (eg altitude or speed against distance) using gnuplot + - Map view can now use other OpenStreetMap images such as OpenCycleMap or any other tile server + - New function to create an average position from a track section + - Display of straight line distances between waypoints + New with version 6 ================== diff --git a/tim/prune/save/ExifSaver.java b/tim/prune/save/ExifSaver.java index a5ae402..6533fcb 100644 --- a/tim/prune/save/ExifSaver.java +++ b/tim/prune/save/ExifSaver.java @@ -27,7 +27,6 @@ import tim.prune.data.Coordinate; import tim.prune.data.DataPoint; import tim.prune.data.Photo; import tim.prune.data.PhotoList; -import tim.prune.data.PhotoStatus; /** * Class to call Exiftool to save coordinate information in jpg files @@ -115,7 +114,7 @@ public class ExifSaver implements Runnable _dialog.pack(); // set progress bar and show dialog _progressBar.setVisible(false); - _dialog.show(); + _dialog.setVisible(true); return true; } @@ -291,7 +290,7 @@ public class ExifSaver implements Runnable } } String[] command = null; - if (inPhoto.getCurrentStatus() == PhotoStatus.NOT_CONNECTED) + if (inPhoto.getCurrentStatus() == Photo.Status.NOT_CONNECTED) { // Photo is no longer connected, so delete gps tags command = getDeleteGpsExifTagsCommand(inPhoto.getFile(), inOverwriteFlag); @@ -369,7 +368,7 @@ public class ExifSaver implements Runnable result[paramOffset + 3] = "-GPSLongitudeRef=" + inPoint.getLongitude().output(Coordinate.FORMAT_CARDINAL); // add altitude if it has it result[paramOffset + 4] = "-GPSAltitude=" - + (inPoint.hasAltitude()?inPoint.getAltitude().getValue(Altitude.FORMAT_METRES):0); + + (inPoint.hasAltitude()?inPoint.getAltitude().getValue(Altitude.Format.METRES):0); result[paramOffset + 5] = "-GPSAltitudeRef='Above Sea Level'"; // add the filename to modify result[paramOffset + 6] = inFile.getAbsolutePath(); diff --git a/tim/prune/save/FieldSelectionTableModel.java b/tim/prune/save/FieldSelectionTableModel.java index e4a2773..15d568c 100644 --- a/tim/prune/save/FieldSelectionTableModel.java +++ b/tim/prune/save/FieldSelectionTableModel.java @@ -109,7 +109,7 @@ public class FieldSelectionTableModel extends AbstractTableModel /** * @return Class of cell data */ - public Class getColumnClass(int inColumnIndex) + public Class getColumnClass(int inColumnIndex) { if (inColumnIndex==0) return String.class; return Boolean.class; diff --git a/tim/prune/save/FileSaver.java b/tim/prune/save/FileSaver.java index 5991b86..ea4efb8 100644 --- a/tim/prune/save/FileSaver.java +++ b/tim/prune/save/FileSaver.java @@ -70,7 +70,7 @@ public class FileSaver private JRadioButton[] _timestampUnitsRadios = null; private static final int[] FORMAT_COORDS = {Coordinate.FORMAT_NONE, Coordinate.FORMAT_DEG_MIN_SEC, Coordinate.FORMAT_DEG_MIN, Coordinate.FORMAT_DEG}; - private static final int[] FORMAT_ALTS = {Altitude.FORMAT_NONE, Altitude.FORMAT_METRES, Altitude.FORMAT_FEET}; + private static final Altitude.Format[] FORMAT_ALTS = {Altitude.Format.NO_FORMAT, Altitude.Format.METRES, Altitude.Format.FEET}; private static final int[] FORMAT_TIMES = {Timestamp.FORMAT_ORIGINAL, Timestamp.FORMAT_LOCALE, Timestamp.FORMAT_ISO_8601}; @@ -113,7 +113,7 @@ public class FileSaver } // Initialise dialog and show it initDialog(_model, inDefaultDelimiter); - _dialog.show(); + _dialog.setVisible(true); } @@ -404,7 +404,7 @@ public class FileSaver for (int i=0; i<_coordUnitsRadios.length; i++) if (_coordUnitsRadios[i].isSelected()) coordFormat = FORMAT_COORDS[i]; - int altitudeFormat = Altitude.FORMAT_NONE; + Altitude.Format altitudeFormat = Altitude.Format.NO_FORMAT; for (int i=0; i<_altitudeUnitsRadios.length; i++) { if (_altitudeUnitsRadios[i].isSelected()) @@ -540,10 +540,8 @@ public class FileSaver catch (IOException ioe) { saveOK = false; - JOptionPane.showMessageDialog(_parentFrame, - I18nManager.getText("error.save.failed") + ioe.getMessage(), - I18nManager.getText("error.save.dialogtitle"), - JOptionPane.ERROR_MESSAGE); + _app.showErrorMessageNoLookup("error.save.dialogtitle", + I18nManager.getText("error.save.failed") + " : " + ioe.getMessage()); } finally { diff --git a/tim/prune/save/GpsSaver.java b/tim/prune/save/GpsSaver.java new file mode 100644 index 0000000..e3777a2 --- /dev/null +++ b/tim/prune/save/GpsSaver.java @@ -0,0 +1,271 @@ +package tim.prune.save; + +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.FlowLayout; +import java.awt.GridLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; + +import javax.swing.BorderFactory; +import javax.swing.BoxLayout; +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JDialog; +import javax.swing.JLabel; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JProgressBar; +import javax.swing.JTextField; +import javax.swing.SwingConstants; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; + +import tim.prune.App; +import tim.prune.Config; +import tim.prune.ExternalTools; +import tim.prune.GenericFunction; +import tim.prune.I18nManager; + +/** + * Class to manage the loading of GPS data using GpsBabel + */ +public class GpsSaver extends GenericFunction implements Runnable +{ + private boolean _gpsBabelChecked = false; + private JDialog _dialog = null; + private JTextField _deviceField = null, _formatField = null; + private JTextField _trackNameField = null; + private JCheckBox _waypointCheckbox = null, _trackCheckbox = null; + private JButton _okButton = null; + private JProgressBar _progressBar = null; + private boolean _cancelled = false; + + + /** + * Constructor + * @param inApp app object + */ + public GpsSaver(App inApp) + { + super(inApp); + } + + /** get name key */ + public String getNameKey() { + return "function.sendtogps"; + } + + /** + * Open the GUI to select options and start the load + */ + public void begin() + { + // Check if gpsbabel looks like it's installed + if (_gpsBabelChecked || ExternalTools.isGpsbabelInstalled() + || JOptionPane.showConfirmDialog(_dialog, + I18nManager.getText("dialog.gpsload.nogpsbabel"), + I18nManager.getText(getNameKey()), + JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE) == JOptionPane.YES_OPTION) + { + _gpsBabelChecked = true; + // Make dialog window + if (_dialog == null) + { + _dialog = new JDialog(_parentFrame, I18nManager.getText("function.sendtogps"), true); + _dialog.setLocationRelativeTo(_parentFrame); + _dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); + _dialog.getContentPane().add(makeDialogComponents()); + _dialog.pack(); + } + // Initialise progress bars, buttons + enableOkButton(); + setupProgressBar(true); + _dialog.setVisible(true); + } + } + + + /** + * @return a panel containing the main dialog components + */ + private JPanel makeDialogComponents() + { + JPanel outerPanel = new JPanel(); + outerPanel.setLayout(new BorderLayout()); + // Main panel with options etc + JPanel mainPanel = new JPanel(); + mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS)); + + // text fields for options + JPanel gridPanel = new JPanel(); + gridPanel.setLayout(new GridLayout(0, 2, 10, 3)); + JLabel deviceLabel = new JLabel(I18nManager.getText("dialog.gpsload.device")); + deviceLabel.setHorizontalAlignment(SwingConstants.RIGHT); + gridPanel.add(deviceLabel); + _deviceField = new JTextField(Config.getGpsDevice(), 12); + gridPanel.add(_deviceField); + JLabel formatLabel = new JLabel(I18nManager.getText("dialog.gpsload.format")); + formatLabel.setHorizontalAlignment(SwingConstants.RIGHT); + gridPanel.add(formatLabel); + _formatField = new JTextField(Config.getGpsFormat(), 12); + gridPanel.add(_formatField); + JLabel nameLabel = new JLabel(I18nManager.getText("dialog.gpssend.trackname")); + nameLabel.setHorizontalAlignment(SwingConstants.RIGHT); + gridPanel.add(nameLabel); + _trackNameField = new JTextField("", 12); + gridPanel.add(_trackNameField); + gridPanel.setAlignmentX(Component.CENTER_ALIGNMENT); + gridPanel.setBorder(BorderFactory.createEmptyBorder(10, 5, 5, 20)); + mainPanel.add(gridPanel); + + // checkboxes + ChangeListener checkboxListener = new ChangeListener() { + public void stateChanged(ChangeEvent e) + { + enableOkButton(); + } + }; + _waypointCheckbox = new JCheckBox(I18nManager.getText("dialog.gpssend.sendwaypoints"), true); + _waypointCheckbox.addChangeListener(checkboxListener); + _waypointCheckbox.setAlignmentX(Component.CENTER_ALIGNMENT); + mainPanel.add(_waypointCheckbox); + _trackCheckbox = new JCheckBox(I18nManager.getText("dialog.gpssend.sendtracks"), true); + _trackCheckbox.addChangeListener(checkboxListener); + _trackCheckbox.setAlignmentX(Component.CENTER_ALIGNMENT); + mainPanel.add(_trackCheckbox); + + // progress bar (initially invisible) + _progressBar = new JProgressBar(0, 10); + mainPanel.add(_progressBar); + outerPanel.add(mainPanel, BorderLayout.NORTH); + + // Lower panel with ok and cancel buttons + JPanel buttonPanel = new JPanel(); + buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT)); + _okButton = new JButton(I18nManager.getText("button.ok")); + _okButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) + { + // start thread to call gpsbabel + _cancelled = false; + new Thread(GpsSaver.this).start(); + } + }); + buttonPanel.add(_okButton); + JButton cancelButton = new JButton(I18nManager.getText("button.cancel")); + cancelButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) + { + _cancelled = true; + _dialog.dispose(); + } + }); + buttonPanel.add(cancelButton); + outerPanel.add(buttonPanel, BorderLayout.SOUTH); + return outerPanel; + } + + + /** + * @param inStart true if the dialog is restarting + */ + private void setupProgressBar(boolean inStart) + { + // set visibility + _progressBar.setVisible(!inStart); + // set indeterminate flags, initial value + _progressBar.setIndeterminate(false); + _progressBar.setValue(0); + } + + + /** + * Enable or disable the ok button + */ + private void enableOkButton() + { + _okButton.setEnabled(_waypointCheckbox.isSelected() || _trackCheckbox.isSelected()); + } + + + /** + * Run method for performing tasks in separate thread + */ + public void run() + { + _okButton.setEnabled(false); + setupProgressBar(false); + + _progressBar.setIndeterminate(true); + try + { + callGpsBabel(); + } + catch (Exception e) + { + JOptionPane.showMessageDialog(_dialog, e.getMessage(), + I18nManager.getText("function.sendtogps"), JOptionPane.ERROR_MESSAGE); + _cancelled = true; + } + + setupProgressBar(true); + enableOkButton(); + + // Close dialog + if (!_cancelled) { + _dialog.dispose(); + } + } + + + /** + * Execute the call to gpsbabel + */ + private void callGpsBabel() throws Exception + { + // Set up command to call gpsbabel + String[] commands = null; + if (_waypointCheckbox.isSelected() && _trackCheckbox.isSelected()) { + // Both waypoints and track points selected + commands = new String[] {"gpsbabel", "-w", "-t", "-i", "gpx", "-f", "-", "-o", _formatField.getText(), + "-F", _deviceField.getText()}; + } + else + { + // Only waypoints OR trackpoints selected + commands = new String[] {"gpsbabel", "-w", "-i", "gpx", "-f", "-", "-o", _formatField.getText(), + "-F", _deviceField.getText()}; + if (_trackCheckbox.isSelected()) { + commands[1] = "-t"; + } + } + + String errorMessage = ""; + Process process = Runtime.getRuntime().exec(commands); + + String trackName = _trackNameField.getText(); + if (trackName == null || trackName.equals("")) {trackName = "prune";} + // Generate the GPX file and send to the GPS + OutputStreamWriter writer = new OutputStreamWriter(process.getOutputStream()); + GpxExporter.exportData(writer, _app.getTrackInfo().getTrack(), trackName, null, true); + writer.close(); + + // Read the error stream to see if there's a better error message there + BufferedReader r = new BufferedReader(new InputStreamReader(process.getErrorStream())); + String line = null; + String errorMessage2 = ""; + while ((line = r.readLine()) != null) { + errorMessage2 += line + "\n"; + } + // Close error stream + try { + r.close(); + } catch (Exception e) {} + if (errorMessage2.length() > 0) {errorMessage = errorMessage2;} + if (errorMessage.length() > 0) {throw new Exception(errorMessage);} + } +} diff --git a/tim/prune/save/GpxExporter.java b/tim/prune/save/GpxExporter.java index 5afdda3..89d40ef 100644 --- a/tim/prune/save/GpxExporter.java +++ b/tim/prune/save/GpxExporter.java @@ -18,13 +18,14 @@ import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JDialog; import javax.swing.JFileChooser; -import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JTextField; +import tim.prune.App; import tim.prune.Config; +import tim.prune.GenericFunction; import tim.prune.GpsPruner; import tim.prune.I18nManager; import tim.prune.UpdateMessageBroker; @@ -33,16 +34,14 @@ import tim.prune.data.Coordinate; import tim.prune.data.DataPoint; import tim.prune.data.Timestamp; import tim.prune.data.Track; -import tim.prune.data.TrackInfo; import tim.prune.load.GenericFileFilter; /** * Class to export track information * into a specified Gpx file */ -public class GpxExporter implements Runnable +public class GpxExporter extends GenericFunction implements Runnable { - private JFrame _parentFrame = null; private Track _track = null; private JDialog _dialog = null; private JTextField _nameField = null; @@ -52,38 +51,41 @@ public class GpxExporter implements Runnable private File _exportFile = null; /** version number of Gpx */ - private static final String GPX_VERSION_NUMBER = "1.1"; + private static final String GPX_VERSION_NUMBER = "1.0"; /** this program name */ private static final String GPX_CREATOR = "Prune v" + GpsPruner.VERSION_NUMBER + " activityworkshop.net"; /** - * Constructor giving frame and track - * @param inParentFrame parent frame - * @param inTrackInfo track info object to save + * Constructor + * @param inApp app object */ - public GpxExporter(JFrame inParentFrame, TrackInfo inTrackInfo) + public GpxExporter(App inApp) { - _parentFrame = inParentFrame; - _track = inTrackInfo.getTrack(); + super(inApp); + _track = inApp.getTrackInfo().getTrack(); } + /** Get name key */ + public String getNameKey() { + return "function.exportgpx"; + } /** * Show the dialog to select options and export file */ - public void showDialog() + public void begin() { // Make dialog window if (_dialog == null) { - _dialog = new JDialog(_parentFrame, I18nManager.getText("dialog.exportgpx.title"), true); + _dialog = new JDialog(_parentFrame, I18nManager.getText(getNameKey()), true); _dialog.setLocationRelativeTo(_parentFrame); _dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); _dialog.getContentPane().add(makeDialogComponents()); _dialog.pack(); } - _dialog.show(); + _dialog.setVisible(true); } @@ -202,7 +204,8 @@ public class GpxExporter implements Runnable // normal writing to file writer = new OutputStreamWriter(new FileOutputStream(_exportFile)); // write file - int numPoints = exportData(writer); + int numPoints = exportData(writer, _track, _nameField.getText(), + _descriptionField.getText(), _timestampsCheckbox.isSelected()); // close file writer.close(); @@ -235,9 +238,15 @@ public class GpxExporter implements Runnable /** * Export the information to the given writer * @param inWriter writer object + * @param inTrack track object containing data + * @param inName name of track (optional) + * @param inDesc description of track (optional) + * @param inTimestamps true to export timestamps * @return number of points written + * @throws IOException if io errors occur on write */ - private int exportData(OutputStreamWriter inWriter) throws IOException + public static int exportData(OutputStreamWriter inWriter, Track inTrack, String inName, + String inDesc, boolean inTimestamps) throws IOException { inWriter.write("\n\n"); // Name field - if (_nameField != null && _nameField.getText() != null && !_nameField.getText().equals("")) + String trackName = "PruneTrack"; + if (inName != null && !inName.equals("")) { + trackName = inName; inWriter.write("\t"); - inWriter.write(_nameField.getText()); + inWriter.write(trackName); inWriter.write("\n"); } // Description field inWriter.write("\t"); - if (_descriptionField != null && _descriptionField.getText() != null && !_descriptionField.getText().equals("")) - { - inWriter.write(_descriptionField.getText()); + if (inDesc != null && !inDesc.equals("")) { + inWriter.write(inDesc); } else { @@ -269,14 +279,14 @@ public class GpxExporter implements Runnable DataPoint point = null; boolean hasTrackpoints = false; // Loop over waypoints - int numPoints = _track.getNumPoints(); + int numPoints = inTrack.getNumPoints(); for (i=0; i\n"); + inWriter.write("\t" + trackName + "1\n"); // Loop over track points for (i=0; i\n\t\n"); } if (!point.isWaypoint()) { // export the track point - exportTrackpoint(point, inWriter); + exportTrackpoint(point, inWriter, inTimestamps); firstPoint = false; } } @@ -313,27 +323,30 @@ public class GpxExporter implements Runnable * Export the specified waypoint into the file * @param inPoint waypoint to export * @param inWriter writer object + * @param inTimestamps true to export timestamps too * @throws IOException on write failure */ - private void exportWaypoint(DataPoint inPoint, Writer inWriter) throws IOException + private static void exportWaypoint(DataPoint inPoint, Writer inWriter, boolean inTimestamps) + throws IOException { inWriter.write("\t\n"); - inWriter.write("\t\t"); - inWriter.write(inPoint.getWaypointName().trim()); - inWriter.write("\n"); // altitude if available if (inPoint.hasAltitude()) { inWriter.write("\t\t"); - inWriter.write("" + inPoint.getAltitude().getStringValue(Altitude.FORMAT_METRES)); + inWriter.write("" + inPoint.getAltitude().getStringValue(Altitude.Format.METRES)); inWriter.write("\n"); } - // timestamp if available (point might have altitude and then be turned into a waypoint) - if (inPoint.hasTimestamp() && _timestampsCheckbox.isSelected()) + // write waypoint name after elevation + inWriter.write("\t\t"); + inWriter.write(inPoint.getWaypointName().trim()); + inWriter.write("\n"); + // timestamp if available (point might have timestamp and then be turned into a waypoint) + if (inPoint.hasTimestamp() && inTimestamps) { inWriter.write("\t\t