From 54b9d8bc8f0025ccf97a67d9dd217ef1f9cf082f Mon Sep 17 00:00:00 2001
From: activityworkshop
Date: Sat, 14 Feb 2015 15:13:41 +0100
Subject: [PATCH] Version 7, February 2009
---
tim/prune/App.java | 533 +++-----------
tim/prune/Config.java | 98 ++-
tim/prune/DataSubscriber.java | 2 +
tim/prune/ExternalTools.java | 9 +
tim/prune/FunctionLibrary.java | 66 ++
tim/prune/GenericFunction.java | 35 +
tim/prune/GpsPruner.java | 35 +-
tim/prune/I18nManager.java | 7 +-
tim/prune/configuration.txt | 16 +-
tim/prune/correlate/PhotoCorrelator.java | 139 +++-
.../correlate/PhotoPreviewTableModel.java | 13 +-
tim/prune/correlate/PhotoPreviewTableRow.java | 2 +-
.../correlate/PhotoSelectionTableModel.java | 7 +-
tim/prune/correlate/TimeIndexPair.java | 19 +-
tim/prune/data/Altitude.java | 34 +-
tim/prune/data/AltitudeRange.java | 14 +-
tim/prune/data/Coordinate.java | 24 +-
tim/prune/data/DataPoint.java | 93 +--
tim/prune/data/Distance.java | 28 +-
tim/prune/data/DoubleRange.java | 8 +
tim/prune/data/Field.java | 35 +-
tim/prune/data/FieldType.java | 8 +
tim/prune/data/IntegerRange.java | 9 -
tim/prune/data/Photo.java | 26 +-
tim/prune/data/PhotoList.java | 18 +-
tim/prune/data/PhotoStatus.java | 11 -
tim/prune/data/Selection.java | 12 +-
tim/prune/data/Timestamp.java | 9 +-
tim/prune/data/Track.java | 294 +++-----
tim/prune/data/TrackInfo.java | 58 +-
tim/prune/drew/jpeg/ExifReader.java | 36 +-
tim/prune/drew/jpeg/JpegData.java | 6 +-
tim/prune/drew/jpeg/JpegSegmentData.java | 32 +-
tim/prune/{gui => function}/AboutScreen.java | 124 ++--
.../AddTimeOffset.java} | 85 ++-
.../{gui => function}/CheckVersionScreen.java | 42 +-
tim/prune/function/HelpScreen.java | 47 ++
.../function/RearrangeWaypointsFunction.java | 76 ++
tim/prune/function/SetMapBgFunction.java | 202 +++++
tim/prune/function/ShowThreeDFunction.java | 58 ++
.../browser/BrowserLauncher.java | 20 +-
.../{ => function}/browser/UrlGenerator.java | 57 +-
tim/prune/function/charts/ChartSeries.java | 51 ++
tim/prune/function/charts/Charter.java | 697 ++++++++++++++++++
.../compress/ClosePointsAlgorithm.java | 107 +++
.../compress/CompressTrackFunction.java | 182 +++++
.../compress/CompressionAlgorithm.java | 108 +++
.../compress/DuplicatePointAlgorithm.java | 82 +++
.../compress/SingleParameterAlgorithm.java | 86 +++
.../function/compress/SingletonAlgorithm.java | 86 +++
tim/prune/function/compress/SummaryLabel.java | 62 ++
tim/prune/function/compress/TrackDetails.java | 120 +++
.../compress/WackyPointAlgorithm.java | 86 +++
.../function/distance/DistanceFunction.java | 153 ++++
.../function/distance/DistanceTableModel.java | 108 +++
.../function/distance/FromTableModel.java | 36 +
.../function/distance/GenericTableModel.java | 50 ++
.../edit/EditFieldsTableModel.java | 4 +-
tim/prune/{ => function}/edit/FieldEdit.java | 2 +-
.../{ => function}/edit/FieldEditList.java | 6 +-
.../{ => function}/edit/PointEditor.java | 4 +-
.../{ => function}/edit/PointNameEditor.java | 74 +-
tim/prune/gui/DetailsDisplay.java | 17 +-
tim/prune/gui/GenericChart.java | 23 +-
tim/prune/gui/MenuManager.java | 170 +++--
tim/prune/gui/PhotoThumbnail.java | 4 +-
tim/prune/gui/ProfileChart.java | 42 +-
tim/prune/gui/UndoManager.java | 6 +-
tim/prune/gui/WaypointListModel.java | 8 +-
tim/prune/gui/WholeNumberField.java | 2 +-
tim/prune/gui/map/MapCanvas.java | 214 ++++--
tim/prune/gui/map/MapPosition.java | 10 +-
tim/prune/gui/map/MapTileCacher.java | 33 +-
tim/prune/gui/map/MapTileConfig.java | 92 +++
tim/prune/lang/prune-texts_de.properties | 108 ++-
tim/prune/lang/prune-texts_de_CH.properties | 120 +--
...s.properties => prune-texts_en.properties} | 96 ++-
tim/prune/lang/prune-texts_es.properties | 96 ++-
tim/prune/lang/prune-texts_fr.properties | 184 +++--
tim/prune/lang/prune-texts_in.properties | 459 ++++++++++++
tim/prune/lang/prune-texts_it.properties | 110 ++-
tim/prune/lang/prune-texts_pl.properties | 586 ++++++++-------
tim/prune/lang/prune-texts_pt.properties | 459 ++++++++++++
tim/prune/lang/prune-texts_ro.properties | 459 ++++++++++++
tim/prune/load/FieldSelectionTableModel.java | 4 +-
tim/prune/load/FileCacher.java | 4 +-
tim/prune/load/FileLoader.java | 18 +-
tim/prune/load/GpsLoader.java | 117 ++-
tim/prune/load/JpegLoader.java | 26 +-
tim/prune/load/PhotoSorter.java | 8 +-
tim/prune/load/TextFileLoader.java | 26 +-
tim/prune/load/xml/GpxHandler.java | 4 +-
tim/prune/load/xml/KmlHandler.java | 15 +-
tim/prune/load/xml/XmlFileLoader.java | 34 +-
tim/prune/load/xml/ZipFileLoader.java | 82 +++
tim/prune/readme.txt | 21 +-
tim/prune/save/ExifSaver.java | 7 +-
tim/prune/save/FieldSelectionTableModel.java | 2 +-
tim/prune/save/FileSaver.java | 12 +-
tim/prune/save/GpsSaver.java | 271 +++++++
tim/prune/save/GpxExporter.java | 97 +--
tim/prune/save/KmlExporter.java | 51 +-
tim/prune/save/PhotoTableEntry.java | 7 +-
tim/prune/save/PhotoTableModel.java | 2 +-
tim/prune/save/PovExporter.java | 35 +-
tim/prune/threedee/Java3DWindow.java | 24 +-
tim/prune/threedee/LineDialog.java | 2 +-
tim/prune/threedee/ThreeDModel.java | 3 +-
tim/prune/threedee/WindowFactory.java | 9 +-
tim/prune/undo/UndoDeleteDuplicates.java | 32 -
tim/prune/undo/UndoEditPoint.java | 7 +-
tim/prune/undo/UndoInsert.java | 38 +-
112 files changed, 6794 insertions(+), 2013 deletions(-)
create mode 100644 tim/prune/FunctionLibrary.java
create mode 100644 tim/prune/GenericFunction.java
delete mode 100644 tim/prune/data/PhotoStatus.java
rename tim/prune/{gui => function}/AboutScreen.java (74%)
rename tim/prune/{gui/TimeOffsetDialog.java => function/AddTimeOffset.java} (65%)
rename tim/prune/{gui => function}/CheckVersionScreen.java (74%)
create mode 100644 tim/prune/function/HelpScreen.java
create mode 100644 tim/prune/function/RearrangeWaypointsFunction.java
create mode 100644 tim/prune/function/SetMapBgFunction.java
create mode 100644 tim/prune/function/ShowThreeDFunction.java
rename tim/prune/{ => function}/browser/BrowserLauncher.java (85%)
rename tim/prune/{ => function}/browser/UrlGenerator.java (67%)
create mode 100644 tim/prune/function/charts/ChartSeries.java
create mode 100644 tim/prune/function/charts/Charter.java
create mode 100644 tim/prune/function/compress/ClosePointsAlgorithm.java
create mode 100644 tim/prune/function/compress/CompressTrackFunction.java
create mode 100644 tim/prune/function/compress/CompressionAlgorithm.java
create mode 100644 tim/prune/function/compress/DuplicatePointAlgorithm.java
create mode 100644 tim/prune/function/compress/SingleParameterAlgorithm.java
create mode 100644 tim/prune/function/compress/SingletonAlgorithm.java
create mode 100644 tim/prune/function/compress/SummaryLabel.java
create mode 100644 tim/prune/function/compress/TrackDetails.java
create mode 100644 tim/prune/function/compress/WackyPointAlgorithm.java
create mode 100644 tim/prune/function/distance/DistanceFunction.java
create mode 100644 tim/prune/function/distance/DistanceTableModel.java
create mode 100644 tim/prune/function/distance/FromTableModel.java
create mode 100644 tim/prune/function/distance/GenericTableModel.java
rename tim/prune/{ => function}/edit/EditFieldsTableModel.java (97%)
rename tim/prune/{ => function}/edit/FieldEdit.java (94%)
rename tim/prune/{ => function}/edit/FieldEditList.java (79%)
rename tim/prune/{ => function}/edit/PointEditor.java (98%)
rename tim/prune/{ => function}/edit/PointNameEditor.java (81%)
create mode 100644 tim/prune/gui/map/MapTileConfig.java
rename tim/prune/lang/{prune-texts.properties => prune-texts_en.properties} (86%)
create mode 100644 tim/prune/lang/prune-texts_in.properties
create mode 100644 tim/prune/lang/prune-texts_pt.properties
create mode 100644 tim/prune/lang/prune-texts_ro.properties
create mode 100644 tim/prune/load/xml/ZipFileLoader.java
create mode 100644 tim/prune/save/GpsSaver.java
delete mode 100644 tim/prune/undo/UndoDeleteDuplicates.java
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