From 112bb0c9b46894adca9a33ed8c99ea712b253185 Mon Sep 17 00:00:00 2001
From: activityworkshop
Date: Sat, 14 Feb 2015 15:22:56 +0100
Subject: [PATCH] Version 8, September 2009
---
tim/prune/App.java | 183 ++++--
tim/prune/Config.java | 211 ++++---
tim/prune/ExternalTools.java | 66 ++-
tim/prune/FunctionLibrary.java | 24 +
tim/prune/GpsPruner.java | 60 +-
tim/prune/I18nManager.java | 25 +-
tim/prune/configuration.txt | 74 ---
tim/prune/correlate/PhotoCorrelator.java | 14 +-
.../correlate/PhotoSelectionTableModel.java | 2 +-
tim/prune/data/Altitude.java | 48 +-
tim/prune/data/Coordinate.java | 42 +-
tim/prune/data/DataPoint.java | 2 +-
tim/prune/data/Distance.java | 10 +
tim/prune/data/Field.java | 2 +
tim/prune/data/FieldList.java | 4 +-
tim/prune/data/LatLonRectangle.java | 2 +-
tim/prune/data/NumberUtils.java | 55 ++
tim/prune/data/Photo.java | 8 +
tim/prune/data/Selection.java | 114 ++--
tim/prune/data/Track.java | 121 ++--
tim/prune/data/TrackInfo.java | 84 ++-
tim/prune/function/AboutScreen.java | 28 +-
tim/prune/function/AddAltitudeOffset.java | 181 ++++++
tim/prune/function/AddTimeOffset.java | 4 +-
tim/prune/function/FindWaypoint.java | 156 ++++++
tim/prune/function/SaveConfig.java | 150 +++++
tim/prune/function/SetKmzImageSize.java | 159 ++++++
tim/prune/function/SetMapBgFunction.java | 8 +-
tim/prune/function/SetPathsFunction.java | 167 ++++++
tim/prune/function/ShowKeysScreen.java | 106 ++++
.../function/browser/BrowserLauncher.java | 4 +-
tim/prune/function/charts/Charter.java | 60 +-
.../compress/CompressTrackFunction.java | 2 +-
.../compress/DuplicatePointAlgorithm.java | 4 +-
.../function/distance/DistanceTableModel.java | 2 +-
tim/prune/function/edit/PointNameEditor.java | 27 +-
tim/prune/function/gpsies/FormPoster.java | 326 +++++++++++
.../function/gpsies/GetGpsiesFunction.java | 308 +++++++++++
tim/prune/function/gpsies/GpsiesTrack.java | 99 ++++
.../function/gpsies/GpsiesXmlHandler.java | 104 ++++
tim/prune/function/gpsies/TrackListModel.java | 108 ++++
tim/prune/gui/DetailsDisplay.java | 42 +-
tim/prune/gui/FunctionLauncher.java | 33 ++
tim/prune/gui/IconManager.java | 4 +
tim/prune/gui/MenuManager.java | 224 ++++----
tim/prune/gui/ProfileChart.java | 24 +-
tim/prune/gui/SelectorDisplay.java | 37 +-
tim/prune/gui/Viewport.java | 43 ++
tim/prune/gui/WaypointNameMatcher.java | 98 ++++
tim/prune/gui/WholeNumberField.java | 8 +
tim/prune/gui/images/scalebar.gif | Bin 0 -> 92 bytes
tim/prune/gui/images/scalebar_on.gif | Bin 0 -> 107 bytes
tim/prune/gui/map/MapCanvas.java | 50 +-
tim/prune/gui/map/MapTileCacher.java | 7 +-
tim/prune/gui/map/MapTileConfig.java | 4 +-
tim/prune/gui/map/ScaleBar.java | 111 ++++
tim/prune/lang/prune-texts_af.properties | 154 ++++++
tim/prune/lang/prune-texts_de.properties | 242 +++++---
tim/prune/lang/prune-texts_de_CH.properties | 79 ++-
tim/prune/lang/prune-texts_en.properties | 76 ++-
tim/prune/lang/prune-texts_es.properties | 258 +++++----
tim/prune/lang/prune-texts_fr.properties | 438 ++++++++-------
tim/prune/lang/prune-texts_in.properties | 424 ++------------
tim/prune/lang/prune-texts_it.properties | 138 +++--
tim/prune/lang/prune-texts_pl.properties | 370 ++++++++-----
tim/prune/lang/prune-texts_pt.properties | 403 +-------------
tim/prune/lang/prune-texts_ro.properties | 459 ++-------------
tim/prune/lang/prune-texts_zh.properties | 523 ++++++++++++++++++
tim/prune/load/FileCacher.java | 2 +
tim/prune/load/FileLoader.java | 85 ++-
tim/prune/load/FileSplitter.java | 23 +-
tim/prune/load/GpsLoader.java | 31 +-
tim/prune/load/JpegLoader.java | 8 +-
tim/prune/load/NmeaFileLoader.java | 132 +++++
tim/prune/load/NmeaMessage.java | 96 ++++
tim/prune/load/TextFileLoader.java | 2 +
tim/prune/load/xml/GpxHandler.java | 7 +
tim/prune/load/xml/KmlHandler.java | 4 +-
tim/prune/load/xml/ZipFileLoader.java | 50 +-
tim/prune/readme.txt | 19 +-
tim/prune/save/ExifSaver.java | 7 +-
tim/prune/save/FileSaver.java | 39 +-
tim/prune/save/GpsSaver.java | 23 +-
tim/prune/save/GpxExporter.java | 55 +-
tim/prune/save/KmlExporter.java | 148 +++--
tim/prune/save/PointTypeSelector.java | 114 ++++
tim/prune/save/PovExporter.java | 17 +-
tim/prune/threedee/Java3DWindow.java | 4 +-
tim/prune/threedee/ThreeDModel.java | 2 +-
tim/prune/undo/UndoAddAltitudeOffset.java | 62 +++
tim/prune/undo/UndoInsert.java | 2 +-
91 files changed, 5759 insertions(+), 2576 deletions(-)
delete mode 100644 tim/prune/configuration.txt
create mode 100644 tim/prune/data/NumberUtils.java
create mode 100644 tim/prune/function/AddAltitudeOffset.java
create mode 100644 tim/prune/function/FindWaypoint.java
create mode 100644 tim/prune/function/SaveConfig.java
create mode 100644 tim/prune/function/SetKmzImageSize.java
create mode 100644 tim/prune/function/SetPathsFunction.java
create mode 100644 tim/prune/function/ShowKeysScreen.java
create mode 100644 tim/prune/function/gpsies/FormPoster.java
create mode 100644 tim/prune/function/gpsies/GetGpsiesFunction.java
create mode 100644 tim/prune/function/gpsies/GpsiesTrack.java
create mode 100644 tim/prune/function/gpsies/GpsiesXmlHandler.java
create mode 100644 tim/prune/function/gpsies/TrackListModel.java
create mode 100644 tim/prune/gui/FunctionLauncher.java
create mode 100644 tim/prune/gui/Viewport.java
create mode 100644 tim/prune/gui/WaypointNameMatcher.java
create mode 100644 tim/prune/gui/images/scalebar.gif
create mode 100644 tim/prune/gui/images/scalebar_on.gif
create mode 100644 tim/prune/gui/map/ScaleBar.java
create mode 100644 tim/prune/lang/prune-texts_af.properties
create mode 100644 tim/prune/lang/prune-texts_zh.properties
create mode 100644 tim/prune/load/NmeaFileLoader.java
create mode 100644 tim/prune/load/NmeaMessage.java
create mode 100644 tim/prune/save/PointTypeSelector.java
create mode 100644 tim/prune/undo/UndoAddAltitudeOffset.java
diff --git a/tim/prune/App.java b/tim/prune/App.java
index ced255a..091a37c 100644
--- a/tim/prune/App.java
+++ b/tim/prune/App.java
@@ -1,8 +1,10 @@
package tim.prune;
+import java.util.ArrayList;
import java.util.EmptyStackException;
import java.util.Set;
import java.util.Stack;
+import java.io.File;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
@@ -14,6 +16,7 @@ import tim.prune.data.Field;
import tim.prune.data.LatLonRectangle;
import tim.prune.data.Latitude;
import tim.prune.data.Longitude;
+import tim.prune.data.NumberUtils;
import tim.prune.data.Photo;
import tim.prune.data.PhotoList;
import tim.prune.data.Track;
@@ -22,31 +25,14 @@ 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.UndoManager;
+import tim.prune.gui.Viewport;
import tim.prune.load.FileLoader;
import tim.prune.load.JpegLoader;
import tim.prune.save.ExifSaver;
import tim.prune.save.FileSaver;
-import tim.prune.undo.UndoAddTimeOffset;
-import tim.prune.undo.UndoCompress;
-import tim.prune.undo.UndoConnectPhoto;
-import tim.prune.undo.UndoConnectPhotoWithClone;
-import tim.prune.undo.UndoCreatePoint;
-import tim.prune.undo.UndoCutAndMove;
-import tim.prune.undo.UndoDeletePhoto;
-import tim.prune.undo.UndoDeletePoint;
-import tim.prune.undo.UndoDeleteRange;
-import tim.prune.undo.UndoDisconnectPhoto;
-import tim.prune.undo.UndoEditPoint;
-import tim.prune.undo.UndoException;
-import tim.prune.undo.UndoInsert;
-import tim.prune.undo.UndoLoad;
-import tim.prune.undo.UndoLoadPhotos;
-import tim.prune.undo.UndoMergeTrackSegments;
-import tim.prune.undo.UndoOperation;
-import tim.prune.undo.UndoReverseSection;
+import tim.prune.undo.*;
/**
@@ -65,6 +51,10 @@ public class App
private FileSaver _fileSaver = null;
private Stack _undoStack = null;
private boolean _mangleTimestampsConfirmed = false;
+ private Viewport _viewport = null;
+ private ArrayList _dataFiles = null;
+ private boolean _firstDataFile = true;
+
/**
* Constructor
@@ -114,6 +104,27 @@ public class App
return _undoStack;
}
+ /**
+ * Load the specified data files one by one
+ * @param inDataFiles arraylist containing File objects to load
+ */
+ public void loadDataFiles(ArrayList inDataFiles)
+ {
+ if (inDataFiles == null || inDataFiles.size() == 0) {
+ _dataFiles = null;
+ }
+ else {
+ _dataFiles = inDataFiles;
+ File f = _dataFiles.get(0);
+ _dataFiles.remove(0);
+ // Start load of specified file
+ if (_fileLoader == null)
+ _fileLoader = new FileLoader(this, _frame);
+ _firstDataFile = true;
+ _fileLoader.openFile(f);
+ }
+ }
+
/**
* Complete a function execution
* @param inUndo undo object to be added to stack
@@ -238,24 +249,6 @@ public class App
}
- /**
- * Edit the name of the currently selected (way)point
- */
- public void editCurrentPointName()
- {
- if (_track != null)
- {
- DataPoint currentPoint = _trackInfo.getCurrentPoint();
- if (currentPoint != null)
- {
- // Open point dialog to display details
- PointNameEditor editor = new PointNameEditor(this, _frame);
- editor.showDialog(currentPoint);
- }
- }
- }
-
-
/**
* Delete the currently selected point
*/
@@ -465,6 +458,39 @@ public class App
}
+ /**
+ * Complete the add altitude offset function with the specified offset
+ * @param inOffset altitude offset to add as String
+ * @param inFormat altitude format of offset (eg Feet, Metres)
+ */
+ public void finishAddAltitudeOffset(String inOffset, Altitude.Format inFormat)
+ {
+ // Sanity check
+ if (inOffset == null || inOffset.equals("") || inFormat==Altitude.Format.NO_FORMAT) {
+ return;
+ }
+ // Construct undo information
+ UndoAddAltitudeOffset undo = new UndoAddAltitudeOffset(_trackInfo);
+ int selStart = _trackInfo.getSelection().getStart();
+ int selEnd = _trackInfo.getSelection().getEnd();
+ // How many decimal places are given in the offset?
+ int numDecimals = NumberUtils.getDecimalPlaces(inOffset);
+ boolean success = false;
+ // Decimal offset given
+ try {
+ double offsetd = Double.parseDouble(inOffset);
+ success = _trackInfo.getTrack().addAltitudeOffset(selStart, selEnd, offsetd, inFormat, numDecimals);
+ }
+ catch (NumberFormatException nfe) {}
+ if (success)
+ {
+ _undoStack.add(undo);
+ UpdateMessageBroker.informSubscribers(DataSubscriber.DATA_EDITED);
+ UpdateMessageBroker.informSubscribers(I18nManager.getText("confirm.addaltitudeoffset"));
+ }
+ }
+
+
/**
* Merge the track segments within the current selection
*/
@@ -480,7 +506,7 @@ public class App
// Make undo object
UndoMergeTrackSegments undo = new UndoMergeTrackSegments(_track, selStart, selEnd);
// Call track to merge segments
- if (_track.mergeTrackSegments(selStart, selEnd)) {
+ if (_trackInfo.mergeTrackSegments(selStart, selEnd)) {
_undoStack.add(undo);
UpdateMessageBroker.informSubscribers(I18nManager.getText("confirm.mergetracksegments"));
}
@@ -542,7 +568,7 @@ public class App
DataPoint point = new DataPoint(new Latitude(inLat, Coordinate.FORMAT_NONE), new Longitude(inLong, Coordinate.FORMAT_NONE), null);
point.setSegmentStart(true);
_track.appendPoints(new DataPoint[] {point});
- _trackInfo.getSelection().selectPoint(_trackInfo.getTrack().getNumPoints()-1);
+ _trackInfo.selectPoint(_trackInfo.getTrack().getNumPoints()-1);
// add undo object to stack
_undoStack.add(undo);
// update listeners
@@ -582,22 +608,13 @@ public class App
// Add undo object to stack, set confirm message
_undoStack.add(undo);
- _trackInfo.getSelection().deselectRange();
+ _trackInfo.getSelection().selectRange(-1, -1);
UpdateMessageBroker.informSubscribers();
UpdateMessageBroker.informSubscribers(I18nManager.getText("confirm.cutandmove"));
}
}
}
-
- /**
- * Select all points
- */
- public void selectAll()
- {
- _trackInfo.getSelection().select(0, 0, _track.getNumPoints()-1);
- }
-
/**
* Select nothing
*/
@@ -608,7 +625,6 @@ public class App
_track.clearDeletionMarkers();
}
-
/**
* Receive loaded data and optionally merge with current Track
* @param inFieldArray array of fields
@@ -625,16 +641,25 @@ public class App
if (loadedTrack.getNumPoints() <= 0)
{
showErrorMessage("error.load.dialogtitle", "error.load.nopoints");
+ // load next file if there's a queue
+ loadNextFile();
return;
}
// Decide whether to load or append
if (_track.getNumPoints() > 0)
{
// ask whether to replace or append
- int answer = JOptionPane.showConfirmDialog(_frame,
- I18nManager.getText("dialog.openappend.text"),
- I18nManager.getText("dialog.openappend.title"),
- JOptionPane.YES_NO_CANCEL_OPTION);
+ int answer = 0;
+ if (_dataFiles == null || _firstDataFile) {
+ answer = JOptionPane.showConfirmDialog(_frame,
+ I18nManager.getText("dialog.openappend.text"),
+ I18nManager.getText("dialog.openappend.title"),
+ JOptionPane.YES_NO_CANCEL_OPTION);
+ }
+ else {
+ // Automatically append if there's a file load queue
+ answer = JOptionPane.YES_OPTION;
+ }
if (answer == JOptionPane.YES_OPTION)
{
// append data to current Track
@@ -683,6 +708,38 @@ public class App
UpdateMessageBroker.informSubscribers(I18nManager.getText("confirm.loadfile") + " '" + inFilename + "'");
// update menu
_menuManager.informFileLoaded();
+ // load next file if there's a queue
+ loadNextFile();
+ }
+
+ /**
+ * Inform the app that NO data was loaded, eg cancel pressed
+ * Only needed if there's another file waiting in the queue
+ */
+ public void informNoDataLoaded()
+ {
+ // Load next file if there's a queue
+ loadNextFile();
+ }
+
+ /**
+ * Load the next file in the waiting list, if any
+ */
+ private void loadNextFile()
+ {
+ _firstDataFile = false;
+ if (_dataFiles == null || _dataFiles.size() == 0) {
+ _dataFiles = null;
+ }
+ else {
+ new Thread(new Runnable() {
+ public void run() {
+ File f = _dataFiles.get(0);
+ _dataFiles.remove(0);
+ _fileLoader.openFile(f);
+ }
+ }).start();
+ }
}
@@ -710,7 +767,7 @@ public class App
{
UpdateMessageBroker.informSubscribers("" + numPhotosAdded + " " + I18nManager.getText("confirm.jpegload.multi"));
}
- // TODO: Improve message when photo(s) fail to load (eg already added)
+ // MAYBE: Improve message when photo(s) fail to load (eg already added)
UpdateMessageBroker.informSubscribers();
// update menu
_menuManager.informFileLoaded();
@@ -964,4 +1021,20 @@ public class App
JOptionPane.showMessageDialog(_frame, inMessage,
I18nManager.getText(inTitleKey), JOptionPane.ERROR_MESSAGE);
}
+
+ /**
+ * @param inViewport viewport object
+ */
+ public void setViewport(Viewport inViewport)
+ {
+ _viewport = inViewport;
+ }
+
+ /**
+ * @return current viewport object
+ */
+ public Viewport getViewport()
+ {
+ return _viewport;
+ }
}
diff --git a/tim/prune/Config.java b/tim/prune/Config.java
index aa36c15..befbacc 100644
--- a/tim/prune/Config.java
+++ b/tim/prune/Config.java
@@ -9,67 +9,46 @@ import java.util.Properties;
*/
public abstract class Config
{
- /** Working directory for loading and saving */
- private static File _workingDir = null;
- /** Default language */
- private static String _langCode = null;
- /** GPS device name */
- private static String _gpsDevice = null;
- /** GPS format name */
- private static String _gpsFormat = null;
- /** Font to use for povray */
- private static String _povrayFont = null;
- /** True to use metric units */
- private static boolean _metricUnits = true;
- /** Path to gnuplot executable */
- private static String _gnuplotPath = null;
- /** Index of selected map tile server */
- private static int _mapTileServerIndex = -1;
- /** URL for freeform map tile server */
- private static String _mapTileServerUrl = null;
/** File from which Config was loaded */
private static File _configFile = null;
- // TODO: Need setters for all these parameters if want to make the config saveable
+ /** Hashtable containing all config values */
+ private static Properties _configValues = new Properties();
/** Default config file */
private static final File DEFAULT_CONFIG_FILE = new File(".pruneconfig");
- /** Key for working directory */
- private static final String KEY_WORKING_DIR = "prune.directory";
+ /** Key for track directory */
+ public static final String KEY_TRACK_DIR = "prune.trackdirectory";
+ /** Key for photo directory */
+ public static final String KEY_PHOTO_DIR = "prune.photodirectory";
/** Key for language code */
- private static final String KEY_LANGUAGE_CODE = "prune.languagecode";
+ public static final String KEY_LANGUAGE_CODE = "prune.languagecode";
/** Key for GPS device */
- private static final String KEY_GPS_DEVICE = "prune.gpsdevice";
+ public static final String KEY_GPS_DEVICE = "prune.gpsdevice";
/** Key for GPS format */
- private static final String KEY_GPS_FORMAT = "prune.gpsformat";
+ public static final String KEY_GPS_FORMAT = "prune.gpsformat";
/** Key for Povray font */
- private static final String KEY_POVRAY_FONT = "prune.povrayfont";
+ public static final String KEY_POVRAY_FONT = "prune.povrayfont";
/** Key for metric/imperial */
- private static final String KEY_METRIC_UNITS = "prune.metricunits";
- /** Key for gpsbabel path */
- private static final String KEY_GNUPLOTPATH = "prune.gnuplotpath";
+ public static final String KEY_METRIC_UNITS = "prune.metricunits";
/** Key for map server index */
- private static final String KEY_MAPSERVERINDEX = "prune.mapserverindex";
+ public static final String KEY_MAPSERVERINDEX = "prune.mapserverindex";
/** Key for map server url */
- private static final String KEY_MAPSERVERURL = "prune.mapserverurl";
-
-
- /**
- * @return working directory for loading and saving
- */
- public static File getWorkingDirectory()
- {
- return _workingDir;
- }
+ public static final String KEY_MAPSERVERURL = "prune.mapserverurl";
+ /** Key for show pace flag */
+ public static final String KEY_SHOW_PACE = "prune.showpace";
+ /** Key for width of thumbnails in kmz */
+ public static final String KEY_KMZ_IMAGE_WIDTH = "prune.kmzimagewidth";
+ /** Key for height of thumbnails in kmz */
+ public static final String KEY_KMZ_IMAGE_HEIGHT = "prune.kmzimageheight";
+ /** Key for gpsbabel path */
+ public static final String KEY_GPSBABEL_PATH = "prune.gpsbabelpath";
+ /** Key for gnuplot path */
+ public static final String KEY_GNUPLOT_PATH = "prune.gnuplotpath";
+ /** Key for exiftool path */
+ public static final String KEY_EXIFTOOL_PATH = "prune.exiftoolpath";
- /**
- * @param inDirectory working directory to use
- */
- public static void setWorkingDirectory(File inDirectory)
- {
- _workingDir = inDirectory;
- }
/**
* Load the default configuration file
@@ -110,19 +89,8 @@ public abstract class Config
}
catch (Exception e) {}
}
- // Save the properties we know about, ignore the rest
- _langCode = props.getProperty(KEY_LANGUAGE_CODE);
- String dir = props.getProperty(KEY_WORKING_DIR);
- if (dir != null) {setWorkingDirectory(new File(dir));}
- _gpsDevice = props.getProperty(KEY_GPS_DEVICE);
- _gpsFormat = props.getProperty(KEY_GPS_FORMAT);
- _povrayFont = props.getProperty(KEY_POVRAY_FONT);
- String useMetric = props.getProperty(KEY_METRIC_UNITS);
- _metricUnits = (useMetric == null || useMetric.equals("") || useMetric.toLowerCase().equals("y"));
- _gnuplotPath = props.getProperty(KEY_GNUPLOTPATH);
- if (_gnuplotPath == null || _gnuplotPath.equals("")) {_gnuplotPath = "gnuplot";}
- _mapTileServerIndex = parseInt(props.getProperty(KEY_MAPSERVERINDEX));
- _mapTileServerUrl = props.getProperty(KEY_MAPSERVERURL);
+ // Save all properties from file
+ _configValues.putAll(props);
if (loadFailed) {
throw new ConfigException();
}
@@ -140,6 +108,12 @@ public abstract class Config
props.put(KEY_GPS_DEVICE, "usb:");
props.put(KEY_GPS_FORMAT, "garmin");
props.put(KEY_POVRAY_FONT, "crystal.ttf"); // alternative: DejaVuSans-Bold.ttf
+ props.put(KEY_SHOW_PACE, "0"); // hide by default
+ props.put(KEY_EXIFTOOL_PATH, "exiftool");
+ props.put(KEY_GNUPLOT_PATH, "gnuplot");
+ props.put(KEY_GPSBABEL_PATH, "gpsbabel");
+ props.put(KEY_KMZ_IMAGE_WIDTH, "240");
+ props.put(KEY_KMZ_IMAGE_HEIGHT, "180");
return props;
}
@@ -157,81 +131,98 @@ public abstract class Config
return val;
}
- /** @return language code */
- public static String getLanguageCode()
- {
- return _langCode;
- }
-
- /** @return gps device */
- public static String getGpsDevice()
- {
- return _gpsDevice;
- }
-
- /** @return gps format */
- public static String getGpsFormat()
- {
- return _gpsFormat;
- }
-
- /** @return povray font */
- public static String getPovrayFont()
- {
- return _povrayFont;
- }
-
- /** @return true to use metric units */
- public static boolean getUseMetricUnits()
+ /** @return File from which config was loaded (or null) */
+ public static File getConfigFile()
{
- return _metricUnits;
+ return _configFile;
}
- /** @param inMetric true to use metric units */
- public static void setUseMetricUnits(boolean inMetric)
+ /**
+ * @return config Properties object to allow all config values to be saved
+ */
+ public static Properties getAllConfig()
{
- _metricUnits = inMetric;
+ return _configValues;
}
- /** @return path to gnuplot */
- public static String getGnuplotPath()
+ /**
+ * Store the given configuration setting
+ * @param inKey key (from constants)
+ * @param inValue value as string
+ */
+ public static void setConfigString(String inKey, String inValue)
{
- return _gnuplotPath;
+ if (inKey != null && !inKey.equals(""))
+ {
+ _configValues.put(inKey, inValue);
+ }
}
- /** @param inPath path to Gnuplot */
- public static void setGnuplotPath(String inPath)
+ /**
+ * Store the given configuration setting
+ * @param inKey key (from constants)
+ * @param inValue value as boolean
+ */
+ public static void setConfigBoolean(String inKey, boolean inValue)
{
- _gnuplotPath = inPath;
+ if (inKey != null && !inKey.equals(""))
+ {
+ _configValues.put(inKey, (inValue?"1":"0"));
+ }
}
- /** @return index of map server */
- public static int getMapServerIndex()
+ /**
+ * Store the given configuration setting
+ * @param inKey key (from constants)
+ * @param inValue value as int
+ */
+ public static void setConfigInt(String inKey, int inValue)
{
- return _mapTileServerIndex;
+ if (inKey != null && !inKey.equals(""))
+ {
+ _configValues.put(inKey, "" + inValue);
+ }
}
- /** @param inIndex selected index */
- public static void setMapServerIndex(int inIndex)
+ /**
+ * Get the given configuration setting as a String
+ * @param inKey key
+ * @return configuration setting as a String
+ */
+ public static String getConfigString(String inKey)
{
- _mapTileServerIndex = inIndex;
+ return _configValues.getProperty(inKey);
}
- /** @return url of map server */
- public static String getMapServerUrl()
+ /**
+ * Get the given configuration setting as a boolean
+ * @param inKey key
+ * @return configuration setting as a boolean
+ */
+ public static boolean getConfigBoolean(String inKey)
{
- return _mapTileServerUrl;
+ String val = _configValues.getProperty(inKey);
+ return (val == null || val.equals("1"));
}
- /** @param inUrl url of map server */
- public static void setMapServerUrl(String inUrl)
+ /**
+ * Get the given configuration setting as an int
+ * @param inKey key
+ * @return configuration setting as an int
+ */
+ public static int getConfigInt(String inKey)
{
- _mapTileServerUrl = inUrl;
+ return parseInt(_configValues.getProperty(inKey));
}
- /** @return File from which config was loaded (or null) */
- public static File getConfigFile()
+ /**
+ * Check whether the given key corresponds to a boolean property
+ * @param inKey key to check
+ * @return true if corresponding property is boolean
+ */
+ public static boolean isKeyBoolean(String inKey)
{
- return _configFile;
+ // Only two boolean keys so far
+ return inKey != null && (inKey.equals(KEY_METRIC_UNITS) || inKey.equals(KEY_SHOW_PACE));
}
}
diff --git a/tim/prune/ExternalTools.java b/tim/prune/ExternalTools.java
index 22291fb..a2d3e56 100644
--- a/tim/prune/ExternalTools.java
+++ b/tim/prune/ExternalTools.java
@@ -8,42 +8,55 @@ import java.io.IOException;
*/
public abstract class ExternalTools
{
+ /** Constant for Exiftool */
+ public static final int TOOL_EXIFTOOL = 0;
+ /** Constant for Gpsbabel */
+ public static final int TOOL_GPSBABEL = 1;
+ /** Constant for Gnuplot */
+ public static final int TOOL_GNUPLOT = 2;
+ /** Config keys in order that the tools are defined above */
+ private static final String[] CONFIG_KEYS = {Config.KEY_EXIFTOOL_PATH, Config.KEY_GPSBABEL_PATH, Config.KEY_GNUPLOT_PATH};
+ /** Verification flags for the tools in the order defined above */
+ private static final String[] VERIFY_FLAGS = {"-v", "-V", "-V"};
- /**
- * Attempt to call Povray to see if it's installed / available in path
- * @return true if found, false otherwise
- */
- public static boolean isPovrayInstalled()
- {
- return check("povray");
- }
-
-
- /**
- * Attempt to call Exiftool to see if it's installed / available in path
- * @return true if found, false otherwise
- */
- public static boolean isExiftoolInstalled()
- {
- return check("exiftool -v");
- }
/**
- * Attempt to call gpsbabel to see if it's installed / available in path
- * @return true if found, false otherwise
+ * Check if the selected tool is installed
+ * @param inToolNum number of tool, from constants
+ * @return true if selected tool is installed
*/
- public static boolean isGpsbabelInstalled()
+ public static boolean isToolInstalled(int inToolNum)
{
- return check("gpsbabel -V");
+ switch (inToolNum) {
+ case TOOL_EXIFTOOL:
+ case TOOL_GPSBABEL:
+ case TOOL_GNUPLOT:
+ String toolPath = Config.getConfigString(CONFIG_KEYS[inToolNum]);
+ if (toolPath != null && toolPath.length() > 0) {
+ return check(toolPath + " " + VERIFY_FLAGS[inToolNum]);
+ }
+ }
+ // Not found
+ return false;
}
/**
- * Attempt to call gnuplot to see if it's installed / available in path
- * @return true if found, false otherwise
+ * Check if the selected tool is installed using the given path
+ * @param inToolNum number of tool, from constants
+ * @param inPath selected path to use instead of configured one
+ * @return true if selected tool is installed
*/
- public static boolean isGnuplotInstalled()
+ public static boolean isToolInstalled(int inToolNum, String inPath)
{
- return check(Config.getGnuplotPath() + " -V");
+ if (inPath == null || inPath.equals("")) {return false;}
+ switch (inToolNum) {
+ case TOOL_EXIFTOOL:
+ case TOOL_GPSBABEL:
+ case TOOL_GNUPLOT:
+ return check(inPath + " " + VERIFY_FLAGS[inToolNum]);
+ }
+ // Not found
+ return false;
}
/**
@@ -52,6 +65,7 @@ public abstract class ExternalTools
*/
private static boolean check(String inCommand)
{
+ // System.out.println("Checking tool '" + inCommand + "'");
try
{
Runtime.getRuntime().exec(inCommand);
diff --git a/tim/prune/FunctionLibrary.java b/tim/prune/FunctionLibrary.java
index 3227c31..1a2518c 100644
--- a/tim/prune/FunctionLibrary.java
+++ b/tim/prune/FunctionLibrary.java
@@ -2,15 +2,23 @@ package tim.prune;
import tim.prune.correlate.PhotoCorrelator;
import tim.prune.function.AboutScreen;
+import tim.prune.function.AddAltitudeOffset;
import tim.prune.function.AddTimeOffset;
import tim.prune.function.CheckVersionScreen;
+import tim.prune.function.FindWaypoint;
import tim.prune.function.HelpScreen;
import tim.prune.function.RearrangeWaypointsFunction;
+import tim.prune.function.SaveConfig;
+import tim.prune.function.SetKmzImageSize;
import tim.prune.function.SetMapBgFunction;
+import tim.prune.function.ShowKeysScreen;
import tim.prune.function.ShowThreeDFunction;
import tim.prune.function.charts.Charter;
import tim.prune.function.compress.CompressTrackFunction;
import tim.prune.function.distance.DistanceFunction;
+import tim.prune.function.edit.PointNameEditor;
+import tim.prune.function.gpsies.GetGpsiesFunction;
+import tim.prune.function.SetPathsFunction;
import tim.prune.load.GpsLoader;
import tim.prune.save.GpsSaver;
import tim.prune.save.GpxExporter;
@@ -27,15 +35,23 @@ public abstract class FunctionLibrary
public static PovExporter FUNCTION_POVEXPORT = null;
public static GenericFunction FUNCTION_GPSLOAD = null;
public static GenericFunction FUNCTION_GPSSAVE = null;
+ public static GenericFunction FUNCTION_SAVECONFIG = null;
+ public static GenericFunction FUNCTION_EDIT_WAYPOINT_NAME = null;
public static RearrangeWaypointsFunction FUNCTION_REARRANGE_WAYPOINTS = null;
public static GenericFunction FUNCTION_COMPRESS = null;
public static GenericFunction FUNCTION_ADD_TIME_OFFSET = null;
+ public static GenericFunction FUNCTION_ADD_ALTITUDE_OFFSET = null;
+ public static GenericFunction FUNCTION_FIND_WAYPOINT = null;
public static GenericFunction FUNCTION_CORRELATE_PHOTOS = null;
public static GenericFunction FUNCTION_CHARTS = null;
public static GenericFunction FUNCTION_3D = null;
public static GenericFunction FUNCTION_DISTANCES = null;
+ public static GenericFunction FUNCTION_GET_GPSIES = null;
public static GenericFunction FUNCTION_SET_MAP_BG = null;
+ public static GenericFunction FUNCTION_SET_PATHS = null;
+ public static GenericFunction FUNCTION_SET_KMZ_IMAGE_SIZE = null;
public static GenericFunction FUNCTION_HELP = null;
+ public static GenericFunction FUNCTION_SHOW_KEYS = null;
public static GenericFunction FUNCTION_ABOUT = null;
public static GenericFunction FUNCTION_CHECK_VERSION = null;
@@ -51,15 +67,23 @@ public abstract class FunctionLibrary
FUNCTION_POVEXPORT = new PovExporter(inApp);
FUNCTION_GPSLOAD = new GpsLoader(inApp);
FUNCTION_GPSSAVE = new GpsSaver(inApp);
+ FUNCTION_SAVECONFIG = new SaveConfig(inApp);
+ FUNCTION_EDIT_WAYPOINT_NAME = new PointNameEditor(inApp);
FUNCTION_REARRANGE_WAYPOINTS = new RearrangeWaypointsFunction(inApp);
FUNCTION_COMPRESS = new CompressTrackFunction(inApp);
FUNCTION_ADD_TIME_OFFSET = new AddTimeOffset(inApp);
+ FUNCTION_ADD_ALTITUDE_OFFSET = new AddAltitudeOffset(inApp);
+ FUNCTION_FIND_WAYPOINT = new FindWaypoint(inApp);
FUNCTION_CORRELATE_PHOTOS = new PhotoCorrelator(inApp);
FUNCTION_CHARTS = new Charter(inApp);
FUNCTION_3D = new ShowThreeDFunction(inApp);
FUNCTION_DISTANCES = new DistanceFunction(inApp);
+ FUNCTION_GET_GPSIES = new GetGpsiesFunction(inApp);
FUNCTION_SET_MAP_BG = new SetMapBgFunction(inApp);
+ FUNCTION_SET_PATHS = new SetPathsFunction(inApp);
+ FUNCTION_SET_KMZ_IMAGE_SIZE = new SetKmzImageSize(inApp);
FUNCTION_HELP = new HelpScreen(inApp);
+ FUNCTION_SHOW_KEYS = new ShowKeysScreen(inApp);
FUNCTION_ABOUT = new AboutScreen(inApp);
FUNCTION_CHECK_VERSION= new CheckVersionScreen(inApp);
}
diff --git a/tim/prune/GpsPruner.java b/tim/prune/GpsPruner.java
index f8e36ad..29f7eb5 100644
--- a/tim/prune/GpsPruner.java
+++ b/tim/prune/GpsPruner.java
@@ -4,7 +4,9 @@ import java.awt.event.WindowAdapter;
import java.awt.BorderLayout;
import java.awt.event.WindowEvent;
import java.io.File;
+import java.io.FileNotFoundException;
import java.util.Locale;
+import java.util.ArrayList;
import javax.swing.JFrame;
import javax.swing.JSplitPane;
import javax.swing.JToolBar;
@@ -16,6 +18,7 @@ import tim.prune.gui.MenuManager;
import tim.prune.gui.ProfileChart;
import tim.prune.gui.SelectorDisplay;
import tim.prune.gui.StatusBar;
+import tim.prune.gui.Viewport;
import tim.prune.gui.map.MapCanvas;
/**
@@ -26,9 +29,9 @@ import tim.prune.gui.map.MapCanvas;
public class GpsPruner
{
/** Version number of application, used in about screen and for version check */
- public static final String VERSION_NUMBER = "7";
+ public static final String VERSION_NUMBER = "8";
/** Build number, just used for about screen */
- public static final String BUILD_NUMBER = "136";
+ public static final String BUILD_NUMBER = "155";
/** Static reference to App object */
private static App APP = null;
@@ -40,19 +43,23 @@ public class GpsPruner
public static void main(String[] args)
{
Locale locale = null;
+ String localeCode = null;
String langFilename = null;
String configFilename = null;
+ ArrayList dataFiles = new ArrayList();
boolean showUsage = false;
for (int i=0; i inDataFiles)
{
JFrame frame = new JFrame("Prune");
APP = new App(frame);
@@ -148,6 +175,8 @@ public class GpsPruner
UpdateMessageBroker.addSubscriber(rightPanel);
MapCanvas mapDisp = new MapCanvas(APP, APP.getTrackInfo());
UpdateMessageBroker.addSubscriber(mapDisp);
+ Viewport viewport = new Viewport(mapDisp);
+ APP.setViewport(viewport);
ProfileChart profileDisp = new ProfileChart(APP.getTrackInfo());
UpdateMessageBroker.addSubscriber(profileDisp);
StatusBar statusBar = new StatusBar();
@@ -187,5 +216,8 @@ public class GpsPruner
frame.setVisible(true);
// Set position of map/profile splitter
midPane.setDividerLocation(0.75);
+
+ // Finally, give the files to load to the App
+ APP.loadDataFiles(inDataFiles);
}
}
diff --git a/tim/prune/I18nManager.java b/tim/prune/I18nManager.java
index 80be52b..b9ce3cc 100644
--- a/tim/prune/I18nManager.java
+++ b/tim/prune/I18nManager.java
@@ -2,6 +2,7 @@ package tim.prune;
import java.io.File;
import java.io.FileInputStream;
+import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Locale;
import java.util.MissingResourceException;
@@ -35,14 +36,19 @@ public abstract class I18nManager
EnglishTexts = ResourceBundle.getBundle(BUNDLE_NAME, BACKUP_LOCALE);
// Get bundle for selected locale, if any
- if (inLocale != null)
+ try
{
- LocalTexts = ResourceBundle.getBundle(BUNDLE_NAME, inLocale);
+ if (inLocale != null)
+ {
+ LocalTexts = ResourceBundle.getBundle(BUNDLE_NAME, inLocale);
+ }
+ else
+ {
+ // locale is null so just use the system default
+ LocalTexts = ResourceBundle.getBundle(BUNDLE_NAME, Locale.getDefault());
+ }
}
- else
- {
- // locale is null so just use the system default
- LocalTexts = ResourceBundle.getBundle(BUNDLE_NAME, Locale.getDefault());
+ catch (MissingResourceException mre) { // ignore error, default to english
}
}
@@ -50,21 +56,26 @@ public abstract class I18nManager
/**
* Add a language file
* @param inFilename filename of file
+ * @throws FileNotFoundException if load failed
*/
- public static void addLanguageFile(String inFilename)
+ public static void addLanguageFile(String inFilename) throws FileNotFoundException
{
FileInputStream fis = null;
+ boolean fileLoaded = false;
try
{
File file = new File(inFilename);
ExternalPropsFile = new Properties();
fis = new FileInputStream(file);
ExternalPropsFile.load(fis);
+ fileLoaded = true; // everything worked
}
catch (IOException ioe) {}
finally { try { fis.close();
} catch (Exception e) {}
}
+ // complain if file wasn't loaded, by throwing a filenotfound exception
+ if (!fileLoaded) throw new FileNotFoundException();
}
diff --git a/tim/prune/configuration.txt b/tim/prune/configuration.txt
deleted file mode 100644
index 2955efc..0000000
--- a/tim/prune/configuration.txt
+++ /dev/null
@@ -1,74 +0,0 @@
-
-== Prune configuration ==
-=========================
-
-Starting with version 6 of Prune, it's possible to create a configuration file which controls a few basic configuration options. Currently there isn't a nice gui to let you select these options, although this may be added in the future. Instead, you can just create a text file with the configuration, and save it with any regular text editor. Then Prune will load these options when it starts up.
-
-== File location ==
-By default, Prune will try to load a file called .pruneconfig from the current directory (note the dot at the start of the filename). If this file isn't there, it doesn't matter, it'll just be ignored and Prune will use default settings as before. The file won't be created for you if it doesn't exist.
-If you create this file in your home directory and you also launch Prune from the same directory, Prune will find the file and use whatever configuration is specified inside.
-
-If you want to use another location for this file, or another name, you'll have to tell Prune where it is. You can do this with an extra commandline parameter, like this:
- java -jar prune.jar --configfile=h:/gps/pruneconfig.txt
-You can obviously set this in any shortcuts or aliases that you're currently using so you don't have to type it in every time. If you specify a file like this and Prune can't find it or can't read it, you'll get a warning message in the console.
-
-== File structure ==
-The configuration file is a simple text file, so you can edit it with any editor like Notepad, Kate or gedit. Each line in the file represents a configuration setting, with the format:
- key=value
-The key should match one of the recognised keys given below. Any unrecognised keys will just be ignored.
-The file can contain any number of settings, in any order. You can have just one in there or all possible settings.
-
-== Possible configuration settings ==
-The following settings can be defined in the file, in any order:
-
-== Working directory ==
-This setting defines the default directory when you start Prune. If your track files are always in a certain directory, you can set this here so that Prune starts from that directory. Example:
- prune.directory=/home/user/gps/
-
-== Language code ==
-This setting defines the language to use for Prune's interface. By default, Prune will try to use the language set in your system. If you use the --lang= command line parameter, you can override this to use a different one. Or you can put a line in your configuration file to define it there instead. Possible codes are currently EN, DE, DE_ch, ES, FR, IT and PL. Example:
- prune.languagecode=ES
-If you use the --lang= command line parameter, this takes priority over what's in the configuration file.
-
-== Metric/imperial units ==
-By default Prune uses metric units, displaying altitudes in metres and distances in kilometres. This setting allows you to specify whether you want metric or imperial units by default. Example:
- prune.metricunits=n
-By using a value of "n" (for "no"), Prune then displays values in imperial units of feet and miles.
-
-== Povray font ==
-When Prune exports to Pov format, it specifies a font to use for the cardinals N, S, E, W. Usually this is "crystal.ttf" because this comes as standard with povray. This setting allows you to change that default if you always want to use a specific font installed on your system. Example:
- prune.povrayfont=DejaVuSans-Bold.ttf
-The available fonts will depend on what you have installed. See the povray documentation for more on this.
-
-== GPS device ==
-When Prune invokes Gpsbabel to load data, it needs to specify the GPS device to load from. The name of this will depend on your GPS receiver and your connection (eg serial/usb). If you call gpsbabel from the command line, it's the -f parameter. This setting allows you to specify the default value used by Prune when you select the load from gps function. Example:
- prune.gpsdevice=usb:
-A GPS connected to the serial port may appear as /dev/ttyS0.
-
-== GPS format ==
-This setting controls the default value of the format parameter to gpsbabel. If you call gpsbabel from the command line, it's the -i parameter. Example:
- prune.gpsformat=garmin
-
-== Gnuplot path ==
-On linux systems this setting is unnecessary as the gnuplot executable will be found in /usr/bin but on Windows the executable must be called pgnuplot (with an extra p) and may not be in the system path. This setting controls the default location searched to call gnuplot.
- prune.gnuplotpath=gnuplot
-
-== Map server ==
-The default map tile server is called Mapnik and shows the maps just like they are in openstreetmap.org. The following two settings allow other tile servers to be used by default. The settings are the same as in the dialog View -> 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=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 6c47d00..d60e905 100644
--- a/tim/prune/correlate/PhotoCorrelator.java
+++ b/tim/prune/correlate/PhotoCorrelator.java
@@ -69,10 +69,6 @@ public class PhotoCorrelator extends GenericFunction
public PhotoCorrelator(App inApp)
{
super(inApp);
- _dialog = new JDialog(inApp.getFrame(), I18nManager.getText(getNameKey()), true);
- _dialog.setLocationRelativeTo(inApp.getFrame());
- _dialog.getContentPane().add(makeDialogContents());
- _dialog.pack();
}
@@ -86,6 +82,14 @@ public class PhotoCorrelator extends GenericFunction
*/
public void begin()
{
+ // First create dialog if necessary
+ if (_dialog == null)
+ {
+ _dialog = new JDialog(_parentFrame, I18nManager.getText(getNameKey()), true);
+ _dialog.setLocationRelativeTo(_parentFrame);
+ _dialog.getContentPane().add(makeDialogContents());
+ _dialog.pack();
+ }
// Check whether track has timestamps, exit if not
if (!_app.getTrackInfo().getTrack().hasData(Field.TIMESTAMP))
{
@@ -378,7 +382,7 @@ public class PhotoCorrelator extends GenericFunction
_pointLaterOption.setSelected(!inTimeDiff.getIsPositive());
createPreview(inTimeDiff, true);
CardLayout cl = (CardLayout) _cards.getLayout();
- cl.next(_cards);
+ cl.last(_cards);
_backButton.setEnabled(hasTimeDiff);
_nextButton.setEnabled(false);
// enable ok button if any photos have been selected
diff --git a/tim/prune/correlate/PhotoSelectionTableModel.java b/tim/prune/correlate/PhotoSelectionTableModel.java
index dbd9d8e..4472e6b 100644
--- a/tim/prune/correlate/PhotoSelectionTableModel.java
+++ b/tim/prune/correlate/PhotoSelectionTableModel.java
@@ -65,7 +65,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
+ // MAYBE: only show time of photos (not date) if dates all identical
PhotoSelectionTableRow row = _list.get(inRowIndex);
if (inColumnIndex == 0) return row.getPhoto().getFile().getName();
else if (inColumnIndex == 1) return row.getPhoto().getTimestamp().getText();
diff --git a/tim/prune/data/Altitude.java b/tim/prune/data/Altitude.java
index 495e844..3328817 100644
--- a/tim/prune/data/Altitude.java
+++ b/tim/prune/data/Altitude.java
@@ -61,6 +61,24 @@ public class Altitude
_valid = true;
}
+ /**
+ * @return an exact copy of this Altitude object
+ */
+ public Altitude clone()
+ {
+ return new Altitude(_stringValue, _format);
+ }
+
+ /**
+ * Reset the altitude parameters to the same as the given object
+ * @param inClone clone object to copy
+ */
+ public void reset(Altitude inClone)
+ {
+ _value = inClone._value;
+ _format = inClone._format;
+ _valid = inClone._valid;
+ }
/**
* @return true if the value could be parsed
@@ -114,7 +132,9 @@ public class Altitude
public String getStringValue(Format inFormat)
{
if (!_valid) {return "";}
- if (inFormat == _format && _stringValue != null && !_stringValue.equals("")) {
+ // Return string value if the same format or "no format" was requested
+ if ((inFormat == _format || inFormat == Format.NO_FORMAT)
+ && _stringValue != null && !_stringValue.equals("")) {
return _stringValue;
}
return "" + getValue(inFormat);
@@ -155,4 +175,30 @@ public class Altitude
int newValue = startValue + (int) ((endValue - startValue) * inFrac);
return new Altitude(newValue, altFormat);
}
+
+ /**
+ * Add the given offset to the current altitude
+ * @param inOffset offset as double
+ * @param inFormat format of offset, feet or metres
+ * @param inDecimals number of decimal places
+ */
+ public void addOffset(double inOffset, Format inFormat, int inDecimals)
+ {
+ // Use the maximum number of decimal places from current value and offset
+ int numDecimals = NumberUtils.getDecimalPlaces(_stringValue);
+ if (numDecimals < inDecimals) {numDecimals = inDecimals;}
+ // Convert offset to correct units
+ double offset = inOffset;
+ if (inFormat != _format)
+ {
+ if (inFormat == Format.FEET)
+ offset = inOffset * CONVERT_FEET_TO_METRES;
+ else
+ offset = inOffset * CONVERT_METRES_TO_FEET;
+ }
+ // Add the offset
+ double newValue = Double.parseDouble(_stringValue.trim()) + offset;
+ _value = (int) newValue;
+ _stringValue = NumberUtils.formatNumber(newValue, numDecimals);
+ }
}
diff --git a/tim/prune/data/Coordinate.java b/tim/prune/data/Coordinate.java
index 19a1688..8b79049 100644
--- a/tim/prune/data/Coordinate.java
+++ b/tim/prune/data/Coordinate.java
@@ -76,7 +76,7 @@ public abstract class Coordinate
char currChar;
long[] fields = new long[4]; // needs to be long for lengthy decimals
long[] denoms = new long[4];
- String secondDelim = "";
+ boolean[] otherDelims = new boolean[5]; // remember whether delimiters have non-decimal chars
try
{
// Loop over characters in input string, populating fields array
@@ -97,10 +97,8 @@ public abstract class Coordinate
else
{
inNumeric = false;
- // Remember second delimiter
- if (numFields == 2) {
- secondDelim += currChar;
- }
+ // Remember delimiters
+ if (currChar != ',' && currChar != '.') {otherDelims[numFields] = true;}
}
}
_valid = (numFields > 0);
@@ -116,16 +114,28 @@ public abstract class Coordinate
_fracDenom = 10;
if (numFields == 2)
{
- // String is just decimal degrees
- double numMins = fields[1] * 60.0 / denoms[1];
- _minutes = (int) numMins;
- double numSecs = (numMins - _minutes) * 60.0;
- _seconds = (int) numSecs;
- _fracs = (int) ((numSecs - _seconds) * 10);
- _asDouble = _degrees + 1.0 * fields[1] / denoms[1];
+ if (!otherDelims[1])
+ {
+ // String is just decimal degrees
+ double numMins = fields[1] * 60.0 / denoms[1];
+ _minutes = (int) numMins;
+ double numSecs = (numMins - _minutes) * 60.0;
+ _seconds = (int) numSecs;
+ _fracs = (int) ((numSecs - _seconds) * 10);
+ _asDouble = _degrees + 1.0 * fields[1] / denoms[1];
+ }
+ else
+ {
+ // String is degrees and minutes (due to non-decimal separator)
+ _originalFormat = FORMAT_DEG_MIN;
+ _minutes = (int) fields[1];
+ _seconds = 0;
+ _fracs = 0;
+ _asDouble = 1.0 * _degrees + (_minutes / 60.0);
+ }
}
// Differentiate between d-m.f and d-m-s using . or ,
- else if (numFields == 3 && (secondDelim.equals(".") || secondDelim.equals(",")))
+ else if (numFields == 3 && !otherDelims[2])
{
// String is degrees-minutes.fractions
_originalFormat = FORMAT_DEG_MIN;
@@ -265,7 +275,7 @@ public abstract class Coordinate
{
StringBuffer buffer = new StringBuffer();
buffer.append(PRINTABLE_CARDINALS[_cardinal])
- .append(threeDigitString(_degrees)).append('°')
+ .append(threeDigitString(_degrees)).append('\u00B0')
.append(twoDigitString(_minutes)).append('\'')
.append(twoDigitString(_seconds)).append('.')
.append(formatFraction(_fracs, _fracDenom));
@@ -274,13 +284,13 @@ public abstract class Coordinate
}
case FORMAT_DEG_MIN:
{
- answer = "" + PRINTABLE_CARDINALS[_cardinal] + threeDigitString(_degrees) + "°"
+ answer = "" + PRINTABLE_CARDINALS[_cardinal] + threeDigitString(_degrees) + "\u00B0"
+ (_minutes + _seconds / 60.0 + _fracs / 60.0 / _fracDenom) + "'";
break;
}
case FORMAT_DEG_WHOLE_MIN:
{
- answer = "" + PRINTABLE_CARDINALS[_cardinal] + threeDigitString(_degrees) + "°"
+ answer = "" + PRINTABLE_CARDINALS[_cardinal] + threeDigitString(_degrees) + "\u00B0"
+ (int) Math.floor(_minutes + _seconds / 60.0 + _fracs / 60.0 / _fracDenom + 0.5) + "'";
break;
}
diff --git a/tim/prune/data/DataPoint.java b/tim/prune/data/DataPoint.java
index 2d60ce7..966b560 100644
--- a/tim/prune/data/DataPoint.java
+++ b/tim/prune/data/DataPoint.java
@@ -155,7 +155,7 @@ public class DataPoint
}
else {
// use default altitude format from config
- parseFields(inField, Config.getUseMetricUnits()?Altitude.Format.METRES:Altitude.Format.FEET);
+ parseFields(inField, Config.getConfigBoolean(Config.KEY_METRIC_UNITS)?Altitude.Format.METRES:Altitude.Format.FEET);
}
}
diff --git a/tim/prune/data/Distance.java b/tim/prune/data/Distance.java
index 9909df7..d12d988 100644
--- a/tim/prune/data/Distance.java
+++ b/tim/prune/data/Distance.java
@@ -57,4 +57,14 @@ public abstract class Distance
// default kilometres
return inDist / EARTH_RADIUS_KM;
}
+
+ /**
+ * Convert the given distance from metres to miles
+ * @param inMetres number of metres
+ * @return number of miles
+ */
+ public static double convertMetresToMiles(double inMetres)
+ {
+ return inMetres / 1000.0 * CONVERT_KM_TO_MILES;
+ }
}
diff --git a/tim/prune/data/Field.java b/tim/prune/data/Field.java
index 089d8cd..5d0adc4 100644
--- a/tim/prune/data/Field.java
+++ b/tim/prune/data/Field.java
@@ -21,6 +21,8 @@ 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);
+ // TODO: Field for photo filename, ability to load (from text) and save (to text)
+
private static final Field[] ALL_AVAILABLE_FIELDS = {
LATITUDE, LONGITUDE, ALTITUDE, TIMESTAMP, WAYPT_NAME, WAYPT_TYPE, NEW_SEGMENT,
new Field("fieldname.custom", FieldType.NONE)
diff --git a/tim/prune/data/FieldList.java b/tim/prune/data/FieldList.java
index e4baecc..1542f09 100644
--- a/tim/prune/data/FieldList.java
+++ b/tim/prune/data/FieldList.java
@@ -6,6 +6,7 @@ package tim.prune.data;
*/
public class FieldList
{
+ /** Array of Field objects making the list */
private Field[] _fieldArray;
@@ -62,8 +63,7 @@ public class FieldList
/**
- * Check whether the FieldList contains the given
- * Field object
+ * Check whether the FieldList contains the given Field object
* @param inField Field to check
* @return true if the FieldList contains the given field
*/
diff --git a/tim/prune/data/LatLonRectangle.java b/tim/prune/data/LatLonRectangle.java
index 74c9855..0aeb1c8 100644
--- a/tim/prune/data/LatLonRectangle.java
+++ b/tim/prune/data/LatLonRectangle.java
@@ -19,7 +19,7 @@ public class LatLonRectangle
{
_latRange = inLatRange;
_lonRange = inLonRange;
- // TODO: Expand range by certain percentage
+ // MAYBE: Expand range by certain percentage
}
/**
diff --git a/tim/prune/data/NumberUtils.java b/tim/prune/data/NumberUtils.java
new file mode 100644
index 0000000..0c76981
--- /dev/null
+++ b/tim/prune/data/NumberUtils.java
@@ -0,0 +1,55 @@
+package tim.prune.data;
+
+import java.text.DecimalFormat;
+import java.text.NumberFormat;
+import java.util.Locale;
+
+/**
+ * Abstract class to offer general number manipulation functions
+ */
+public abstract class NumberUtils
+{
+ /** Number formatter object to avoid lots of instantiations */
+ private static final NumberFormat NUM_FORMATTER = NumberFormat.getNumberInstance(Locale.UK);
+ // Select the UK locale for this formatter so that decimal point is always used (not comma)
+ static {
+ if (NUM_FORMATTER instanceof DecimalFormat) ((DecimalFormat) NUM_FORMATTER).applyPattern("0.000");
+ }
+
+ /**
+ * Find the number of decimal places represented in the String
+ * @param inString String to check
+ * @return number of decimal places, or 0 for integer value
+ */
+ public static int getDecimalPlaces(String inString)
+ {
+ if (inString == null || inString.equals("")) {return 0;}
+ int places = 0;
+ final int sLen = inString.length();
+ for (int i=sLen-1; i>=0; i--) {
+ char c = inString.charAt(i);
+ if (c >= '0' && c <= '9') {
+ // Numeric character found
+ places++;
+ }
+ else {
+ // Non-numeric character found, return places
+ return places;
+ }
+ }
+ // No non-numeric characters found, so must be integer
+ return 0;
+ }
+
+ /**
+ * Format the given number to the given number of decimal places
+ * @param inNumber double number to format
+ * @param inDecimalPlaces number of decimal places
+ */
+ public static String formatNumber(double inNumber, int inDecimalPlaces)
+ {
+ NUM_FORMATTER.setMaximumFractionDigits(inDecimalPlaces);
+ NUM_FORMATTER.setMinimumFractionDigits(inDecimalPlaces);
+ return NUM_FORMATTER.format(inNumber);
+ }
+}
\ No newline at end of file
diff --git a/tim/prune/data/Photo.java b/tim/prune/data/Photo.java
index 805e22e..4fdb612 100644
--- a/tim/prune/data/Photo.java
+++ b/tim/prune/data/Photo.java
@@ -182,6 +182,14 @@ public class Photo
_currentStatus = inStatus;
}
+ /**
+ * @return true if photo is connected to a point
+ */
+ public boolean isConnected()
+ {
+ return _currentStatus != Status.NOT_CONNECTED;
+ }
+
/**
* @return byte array of thumbnail data
*/
diff --git a/tim/prune/data/Selection.java b/tim/prune/data/Selection.java
index c07c1a9..6924d13 100644
--- a/tim/prune/data/Selection.java
+++ b/tim/prune/data/Selection.java
@@ -19,6 +19,7 @@ public class Selection
private Altitude.Format _altitudeFormat = Altitude.Format.NO_FORMAT;
private long _totalSeconds = 0L, _movingSeconds = 0L;
private double _angDistance = -1.0, _angMovingDistance = -1.0;
+ private boolean _multipleSegments = false;
/**
@@ -32,60 +33,14 @@ public class Selection
/**
- * Reset selection to be recalculated
+ * Mark selection invalid so it will be recalculated
*/
- private void reset()
+ public void markInvalid()
{
_valid = false;
}
- /**
- * Select the point at the given index
- * @param inIndex index number of selected point
- */
- public void selectPoint(int inIndex)
- {
- if (inIndex >= -1)
- {
- _currentPoint = inIndex;
- check();
- }
- }
-
- /**
- * Select the specified point and range in one go
- * @param inPointIndex point selection
- * @param inStart range start
- * @param inEnd range end
- */
- public void select(int inPointIndex, int inStart, int inEnd)
- {
- _currentPoint = inPointIndex;
- _startIndex = inStart;
- _endIndex = inEnd;
- reset();
- check();
- }
-
-
- /**
- * Select the previous point
- */
- public void selectPreviousPoint()
- {
- if (_currentPoint > 0)
- selectPoint(_currentPoint - 1);
- }
-
- /**
- * Select the next point
- */
- public void selectNextPoint()
- {
- selectPoint(_currentPoint + 1);
- }
-
/**
* @return the current point index
*/
@@ -110,6 +65,7 @@ public class Selection
private void recalculate()
{
_altitudeFormat = Altitude.Format.NO_FORMAT;
+ _multipleSegments = false;
if (_track.getNumPoints() > 0 && hasRangeSelected())
{
_altitudeRange = new IntegerRange();
@@ -164,7 +120,10 @@ public class Selection
{
double radians = DataPoint.calculateRadiansBetween(lastPoint, currPoint);
_angDistance += radians;
- if (!currPoint.getSegmentStart()) {
+ if (currPoint.getSegmentStart()) {
+ _multipleSegments = true;
+ }
+ else {
_angMovingDistance += radians;
}
}
@@ -273,23 +232,35 @@ public class Selection
}
/**
- * Clear selected point and range
+ * @return true if track has multiple segments
+ */
+ public boolean getHasMultipleSegments()
+ {
+ return _multipleSegments;
+ }
+
+ /**
+ * Clear selected point, range and photo
*/
public void clearAll()
{
_currentPoint = -1;
- deselectRange();
- deselectPhoto();
+ selectRange(-1, -1);
+ _currentPhotoIndex = -1;
+ check();
}
/**
* Deselect range
+ * @param inStartIndex index of start of range
+ * @param inEndIndex index of end of range
*/
- public void deselectRange()
+ public void selectRange(int inStartIndex, int inEndIndex)
{
- _startIndex = _endIndex = -1;
- reset();
+ _startIndex = inStartIndex;
+ _endIndex = inEndIndex;
+ markInvalid();
check();
}
@@ -307,7 +278,7 @@ public class Selection
* Set the index for the start of the range selection
* @param inStartIndex start index
*/
- public void selectRangeStart(int inStartIndex)
+ private void selectRangeStart(int inStartIndex)
{
if (inStartIndex < 0)
{
@@ -322,7 +293,7 @@ public class Selection
_endIndex = _track.getNumPoints() - 1;
}
}
- reset();
+ markInvalid();
UpdateMessageBroker.informSubscribers();
}
@@ -350,12 +321,11 @@ public class Selection
{
_endIndex = inEndIndex;
// Move start of selection to min if necessary
- if (_startIndex > _endIndex || _startIndex < 0)
- {
+ if (_startIndex > _endIndex || _startIndex < 0) {
_startIndex = 0;
}
}
- reset();
+ markInvalid();
UpdateMessageBroker.informSubscribers();
}
@@ -393,22 +363,12 @@ public class Selection
_endIndex--;
if (_currentPoint < _startIndex)
_startIndex--;
- reset();
+ markInvalid();
}
check();
}
- /**
- * Deselect photo
- */
- public void deselectPhoto()
- {
- _currentPhotoIndex = -1;
- check();
- }
-
-
/**
* Select the specified photo and point
* @param inPhotoIndex index of selected photo in PhotoList
@@ -417,16 +377,8 @@ public class Selection
public void selectPhotoAndPoint(int inPhotoIndex, int inPointIndex)
{
_currentPhotoIndex = inPhotoIndex;
- if (inPointIndex > -1)
- {
- // select associated point, if any
- selectPoint(inPointIndex);
- }
- else
- {
- // Check if not already done
- check();
- }
+ _currentPoint = inPointIndex;
+ check();
}
diff --git a/tim/prune/data/Track.java b/tim/prune/data/Track.java
index df51e8f..08168d1 100644
--- a/tim/prune/data/Track.java
+++ b/tim/prune/data/Track.java
@@ -22,7 +22,8 @@ public class Track
private double[] _yValues = null;
private boolean _scaled = false;
private int _numPoints = 0;
- private boolean _mixedData = false;
+ private boolean _hasTrackpoint = false;
+ private boolean _hasWaypoint = false;
// Master field list
private FieldList _masterFieldList = null;
// variable ranges
@@ -154,8 +155,8 @@ public class Track
for (int i=0; i<_numPoints; i++)
{
DataPoint point = _dataPoints[i];
- // Don't delete waypoints or photo points
- if (point.isWaypoint() || point.getPhoto() != null || !point.getDeleteFlag())
+ // Don't delete photo points
+ if (point.getPhoto() != null || !point.getDeleteFlag())
{
newPointArray[numCopied] = point;
numCopied++;
@@ -297,32 +298,42 @@ public class Track
return foundTimestamp;
}
-
/**
- * Merge the track segments within the given range
- * @param inStart start index
- * @param inEnd end index
- * @return true if successful
+ * Add the given altitude offset to the specified range
+ * @param inStart start of range
+ * @param inEnd end of range
+ * @param inOffset offset to add (-ve to subtract)
+ * @param inFormat altitude format of offset
+ * @param inDecimals number of decimal places in offset
+ * @return true on success
*/
- public boolean mergeTrackSegments(int inStart, int inEnd)
+ public boolean addAltitudeOffset(int inStart, int inEnd, double inOffset,
+ Altitude.Format inFormat, int inDecimals)
{
- boolean firstTrackPoint = true;
- // Loop between start and end
- for (int i=inStart; i<=inEnd; i++) {
- DataPoint point = getPoint(i);
- // Set all segments to false apart from first track point
- if (point != null && !point.isWaypoint()) {
- point.setSegmentStart(firstTrackPoint);
- firstTrackPoint = false;
+ // sanity check
+ if (inStart < 0 || inEnd < 0 || inStart >= inEnd || inEnd >= _numPoints) {
+ return false;
+ }
+ boolean foundAlt = false;
+ // Loop over all points within range
+ for (int i=inStart; i<=inEnd; i++)
+ {
+ Altitude alt = _dataPoints[i].getAltitude();
+ if (alt != null && alt.isValid())
+ {
+ // This point has an altitude so add the offset to it
+ foundAlt = true;
+ alt.addOffset(inOffset, inFormat, inDecimals);
}
}
- // Find following track point, if any
- DataPoint nextPoint = getNextTrackPoint(inEnd+1);
- if (nextPoint != null) {nextPoint.setSegmentStart(true);}
- UpdateMessageBroker.informSubscribers();
- return true;
+ // needs to be scaled again
+ _scaled = false;
+ return foundAlt;
}
+ // TODO: Function to collect and sort photo points by time or photo filename
+ // TODO: Function to convert waypoint names into timestamps
+
/**
* Collect all waypoints to the start or end of the track
* @param inAtStart true to collect at start, false for end
@@ -445,8 +456,9 @@ public class Track
*/
public boolean cutAndMoveSection(int inSectionStart, int inSectionEnd, int inMoveTo)
{
+ // TODO: Move cut/move into separate function?
// Check that indices make sense
- if (inSectionStart > 0 && inSectionEnd > inSectionStart && inMoveTo > 0
+ if (inSectionStart > 0 && inSectionEnd > inSectionStart && inMoveTo >= 0
&& (inMoveTo < inSectionStart || inMoveTo > (inSectionEnd+1)))
{
// do the cut and move
@@ -457,30 +469,34 @@ public class Track
{
int sectionLength = inSectionEnd - inSectionStart + 1;
// move section to earlier point
- if (inMoveTo > 0)
+ if (inMoveTo > 0) {
System.arraycopy(_dataPoints, 0, newPointArray, 0, inMoveTo); // unchanged points before
+ }
System.arraycopy(_dataPoints, inSectionStart, newPointArray, inMoveTo, sectionLength); // moved bit
// after insertion point, before moved bit
- if (inSectionStart > (inMoveTo + 1))
- System.arraycopy(_dataPoints, inMoveTo, newPointArray, inMoveTo + sectionLength, inSectionStart - inMoveTo);
+ System.arraycopy(_dataPoints, inMoveTo, newPointArray, inMoveTo + sectionLength, inSectionStart - inMoveTo);
// after moved bit
- if (inSectionEnd < (_numPoints - 1))
+ if (inSectionEnd < (_numPoints - 1)) {
System.arraycopy(_dataPoints, inSectionEnd+1, newPointArray, inSectionEnd+1, _numPoints - inSectionEnd - 1);
+ }
}
else
{
// Move section to later point
- if (inSectionStart > 0)
+ if (inSectionStart > 0) {
System.arraycopy(_dataPoints, 0, newPointArray, 0, inSectionStart); // unchanged points before
+ }
// from end of section to move to point
- if (inMoveTo > (inSectionEnd + 1))
+ if (inMoveTo > (inSectionEnd + 1)) {
System.arraycopy(_dataPoints, inSectionEnd+1, newPointArray, inSectionStart, inMoveTo - inSectionEnd - 1);
+ }
// moved bit
System.arraycopy(_dataPoints, inSectionStart, newPointArray, inSectionStart + inMoveTo - inSectionEnd - 1,
inSectionEnd - inSectionStart + 1);
// unchanged bit after
- if (inSectionEnd < (_numPoints - 1))
+ if (inSectionEnd < (_numPoints - 1)) {
System.arraycopy(_dataPoints, inMoveTo, newPointArray, inMoveTo, _numPoints - inMoveTo);
+ }
}
// Copy array references
_dataPoints = newPointArray;
@@ -533,7 +549,7 @@ public class Track
double latitudeDiff = 0.0, longitudeDiff = 0.0;
double totalAltitude = 0;
int numAltitudes = 0;
- Altitude.Format altFormat = Config.getUseMetricUnits()?Altitude.Format.METRES:Altitude.Format.FEET;
+ Altitude.Format altFormat = Config.getConfigBoolean(Config.KEY_METRIC_UNITS)?Altitude.Format.METRES:Altitude.Format.FEET;
// loop between start and end points
for (int i=inStartIndex; i<= inEndIndex; i++)
{
@@ -605,6 +621,7 @@ public class Track
if (!_scaled) scalePoints();
return _altitudeRange;
}
+
/**
* @return the number of (valid) points in the track
*/
@@ -684,6 +701,8 @@ public class Track
*/
public boolean hasData(Field inField)
{
+ // Don't use this method for altitudes
+ if (inField.equals(Field.ALTITUDE)) {return hasAltitudeData();}
return hasData(inField, 0, _numPoints-1);
}
@@ -713,14 +732,30 @@ public class Track
return false;
}
+ /**
+ * @return true if track has altitude data (which are not all zero)
+ */
+ public boolean hasAltitudeData()
+ {
+ return getAltitudeRange().getMaximum() > 0;
+ }
+
+ /**
+ * @return true if track contains at least one trackpoint
+ */
+ public boolean hasTrackPoints()
+ {
+ if (!_scaled) scalePoints();
+ return _hasTrackpoint;
+ }
/**
- * @return true if track contains waypoints and trackpoints
+ * @return true if track contains waypoints
*/
- public boolean hasMixedData()
+ public boolean hasWaypoints()
{
if (!_scaled) scalePoints();
- return _mixedData;
+ return _hasWaypoint;
}
/**
@@ -809,7 +844,7 @@ public class Track
_latRange = new DoubleRange();
_altitudeRange = new AltitudeRange();
int p;
- boolean hasWaypoint = false, hasTrackpoint = false;
+ _hasWaypoint = false; _hasTrackpoint = false;
for (p=0; p < getNumPoints(); p++)
{
DataPoint point = getPoint(p);
@@ -822,12 +857,11 @@ public class Track
_altitudeRange.addValue(point.getAltitude());
}
if (point.isWaypoint())
- hasWaypoint = true;
+ _hasWaypoint = true;
else
- hasTrackpoint = true;
+ _hasTrackpoint = true;
}
}
- _mixedData = hasWaypoint && hasTrackpoint;
// Loop over points and calculate scales
_xValues = new double[getNumPoints()];
@@ -1099,10 +1133,15 @@ public class Track
for (int i=0; i= _track.getNumPoints()) {return;}
+ // get the index of the current photo
+ int photoIndex = _selection.getCurrentPhotoIndex();
+ // Check if point has photo or not
+ boolean pointHasPhoto = false;
+ if (inPointIndex >= 0)
+ {
+ Photo pointPhoto = _track.getPoint(inPointIndex).getPhoto();
+ pointHasPhoto = (pointPhoto != null);
+ if (pointHasPhoto) {
+ photoIndex = _photoList.getPhotoIndex(pointPhoto);
+ }
+ }
+ // Might need to deselect photo
+ if (!pointHasPhoto)
+ {
+ // selected point hasn't got a photo - deselect photo if necessary
+ if (photoIndex < 0 || _photoList.getPhoto(photoIndex).isConnected()) {
+ photoIndex = -1;
+ }
+ }
// give to selection
- _selection.selectPoint(index);
+ _selection.selectPhotoAndPoint(photoIndex, inPointIndex);
}
/**
@@ -297,19 +350,36 @@ public class TrackInfo
*/
public void selectPhoto(int inPhotoIndex)
{
+ if (_selection.getCurrentPhotoIndex() == inPhotoIndex) {return;}
+ // Photo is primary selection here, not as a result of a point selection
+ // Therefore the photo selection takes priority, deselecting point if necessary
// Find Photo object
Photo photo = _photoList.getPhoto(inPhotoIndex);
if (photo != null)
{
// Find point object and its index
int pointIndex = _track.getPointIndex(photo.getDataPoint());
+ // Check whether to deselect current point or not if photo not correlated
+ if (pointIndex < 0)
+ {
+ int currPointIndex = _selection.getCurrentPointIndex();
+ if (currPointIndex >= 0 && _track.getPoint(currPointIndex).getPhoto() == null)
+ {
+ pointIndex = currPointIndex; // Keep currently selected point
+ }
+ }
// give to selection object
_selection.selectPhotoAndPoint(inPhotoIndex, pointIndex);
}
- else
- {
+ else {
// no photo, just reset selection
- _selection.selectPhotoAndPoint(-1, -1);
+ DataPoint currPoint = getCurrentPoint();
+ if (currPoint != null && currPoint.getPhoto() == null) {
+ _selection.selectPhotoAndPoint(-1, _selection.getCurrentPointIndex()); // keep point
+ }
+ else {
+ _selection.selectPhotoAndPoint(-1, -1); // deselect point too
+ }
}
}
}
diff --git a/tim/prune/function/AboutScreen.java b/tim/prune/function/AboutScreen.java
index 0f20ba0..2835d41 100644
--- a/tim/prune/function/AboutScreen.java
+++ b/tim/prune/function/AboutScreen.java
@@ -90,8 +90,8 @@ public class AboutScreen extends GenericFunction
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, português, bahasa indonesia, românÄ").append("
");
+ .append("deutsch, english, espa\u00F1ol, fran\u00E7ais, italiano, polski, \u4e2d\u6587; (chinese) " +
+ "schwiizerd\u00FC\u00FCtsch, portugu\u00EAs, bahasa indonesia, rom\u00E2n\u0103").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));
@@ -122,7 +122,7 @@ public class AboutScreen extends GenericFunction
new JLabel(System.getProperty("java.runtime.version")),
1, 1);
// Create install labels to be populated later
- final int NUM_INSTALL_CHECKS = 5;
+ final int NUM_INSTALL_CHECKS = 4;
_installedLabels = new JLabel[NUM_INSTALL_CHECKS];
for (int i=0; i 0.001);
+ }
+ };
+ MouseAdapter mouseListener = new MouseAdapter() {
+ public void mouseReleased(java.awt.event.MouseEvent arg0) {
+ _okButton.setEnabled(Math.abs(getOffset()) > 0.001);
+ };
+ };
+ _editField.addKeyListener(keyListener);
+ _editField.addMouseListener(mouseListener);
+ mainPanel.add(_editField);
+ dialogPanel.add(mainPanel, BorderLayout.CENTER);
+ // button panel at bottom
+ JPanel buttonPanel = new JPanel();
+ buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
+ _okButton = new JButton(I18nManager.getText("button.ok"));
+ ActionListener okListener = new ActionListener() {
+ public void actionPerformed(ActionEvent e)
+ {
+ finish();
+ }
+ };
+ _okButton.addActionListener(okListener);
+ _okButton.setEnabled(false);
+ _editField.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;
+ }
+
+ /**
+ * Get the value of the altitude to add
+ * @return entered altitude offset as numeric value
+ */
+ private double getOffset()
+ {
+ double ans = 0.0;
+ try {
+ ans = Double.parseDouble(_editField.getText());
+ }
+ catch (Exception e) {}
+ return ans;
+ }
+
+ /**
+ * Set the label text according to the current units
+ * @param inStart start index of selection
+ * @param inEnd end index of selection
+ */
+ private void setLabelText(int inStart, int inEnd)
+ {
+ _altFormat = Altitude.Format.NO_FORMAT;
+ for (int i=inStart; i<=inEnd && _altFormat==Altitude.Format.NO_FORMAT; i++)
+ {
+ Altitude alt = _app.getTrackInfo().getTrack().getPoint(i).getAltitude();
+ if (alt != null) {
+ _altFormat = alt.getFormat();
+ }
+ }
+ if (_altFormat==Altitude.Format.NO_FORMAT) {
+ _altFormat = Altitude.Format.METRES;
+ }
+ final String unitKey = (_altFormat==Altitude.Format.METRES?"units.metres.short":"units.feet.short");
+ _descLabel.setText(I18nManager.getText("dialog.addaltitude.desc") + " (" + I18nManager.getText(unitKey) + ")");
+ }
+
+ /**
+ * Finish the dialog when OK pressed
+ */
+ private void finish()
+ {
+ // Pass information back to App to complete function
+ _app.finishAddAltitudeOffset(_editField.getText(), _altFormat);
+ _dialog.dispose();
+ }
+}
diff --git a/tim/prune/function/AddTimeOffset.java b/tim/prune/function/AddTimeOffset.java
index 8b5d4a8..bbfda5e 100644
--- a/tim/prune/function/AddTimeOffset.java
+++ b/tim/prune/function/AddTimeOffset.java
@@ -178,8 +178,8 @@ public class AddTimeOffset extends GenericFunction
private long getOffsetSecs()
{
long offsetSecs = _minuteField.getValue() * 60L
- + _hourField.getValue() * 60L * 60L
- + _dayField.getValue() * 60L * 60L * 24L;
+ + _hourField.getValue() * 60L * 60L
+ + _dayField.getValue() * 60L * 60L * 24L;
if (_subtractRadio.isSelected()) {offsetSecs = -offsetSecs;}
return offsetSecs;
}
diff --git a/tim/prune/function/FindWaypoint.java b/tim/prune/function/FindWaypoint.java
new file mode 100644
index 0000000..8b6beea
--- /dev/null
+++ b/tim/prune/function/FindWaypoint.java
@@ -0,0 +1,156 @@
+package tim.prune.function;
+
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.FlowLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.KeyAdapter;
+import java.awt.event.KeyEvent;
+
+import javax.swing.BorderFactory;
+import javax.swing.BoxLayout;
+import javax.swing.JButton;
+import javax.swing.JDialog;
+import javax.swing.JLabel;
+import javax.swing.JList;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTextField;
+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.gui.WaypointNameMatcher;
+
+/**
+ * Class to provide the function to find a waypoint by name
+ */
+public class FindWaypoint extends GenericFunction
+{
+ private WaypointNameMatcher _nameMatcher = null;
+ private JDialog _dialog = null;
+ private JTextField _searchField = null;
+ private JList _pointList = null;
+ private JButton _okButton = null;
+
+
+ /**
+ * Constructor
+ * @param inApp application object for callback
+ */
+ public FindWaypoint(App inApp)
+ {
+ super(inApp);
+ }
+
+ /** Get the name key */
+ public String getNameKey() {
+ return "function.findwaypoint";
+ }
+
+ /**
+ * Begin the function
+ */
+ 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();
+ }
+ // Initialise waypoint list from track
+ _nameMatcher.init(_app.getTrackInfo().getTrack());
+ // Show dialog
+ _searchField.setText("");
+ _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());
+ JPanel topPanel = new JPanel();
+ topPanel.setLayout(new BoxLayout(topPanel, BoxLayout.Y_AXIS));
+ topPanel.add(new JLabel(I18nManager.getText("dialog.findwaypoint.intro")));
+ JPanel subPanel = new JPanel();
+ subPanel.add(new JLabel(I18nManager.getText("dialog.findwaypoint.search")));
+ _searchField = new JTextField(12);
+ _searchField.addKeyListener(new KeyAdapter() {
+ public void keyReleased(KeyEvent e)
+ {
+ _nameMatcher.findMatches(_searchField.getText());
+ if (_nameMatcher.getSize() == 0 || _nameMatcher.getSize() < _pointList.getSelectedIndex())
+ _okButton.setEnabled(false);
+ else if (_pointList.getSelectedIndex() >= 0)
+ _okButton.setEnabled(true);
+ // close dialog if escape pressed
+ if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
+ _dialog.dispose();
+ }
+ }
+ });
+ subPanel.add(_searchField);
+ topPanel.add(subPanel);
+ dialogPanel.add(topPanel, BorderLayout.NORTH);
+
+ // middle panel with list
+ _nameMatcher = new WaypointNameMatcher();
+ _pointList = new JList(_nameMatcher);
+ _pointList.addListSelectionListener(new ListSelectionListener() {
+ public void valueChanged(ListSelectionEvent e)
+ {
+ if (!e.getValueIsAdjusting()) _okButton.setEnabled(true);
+ }});
+ JScrollPane listPane = new JScrollPane(_pointList);
+ dialogPanel.add(listPane, BorderLayout.CENTER);
+
+ // button panel at bottom
+ JPanel buttonPanel = new JPanel();
+ buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
+ _okButton = new JButton(I18nManager.getText("button.ok"));
+ ActionListener okListener = new ActionListener() {
+ public void actionPerformed(ActionEvent e)
+ {
+ finish();
+ }
+ };
+ _okButton.addActionListener(okListener);
+ _okButton.setEnabled(false);
+ 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;
+ }
+
+ /**
+ * Finish the dialog when OK pressed
+ * Select the point and close the dialog
+ */
+ private void finish()
+ {
+ DataPoint selectedPoint = _nameMatcher.getWaypoint(_pointList.getSelectedIndex());
+ _app.getTrackInfo().selectPoint(selectedPoint);
+ _dialog.dispose();
+ }
+}
diff --git a/tim/prune/function/SaveConfig.java b/tim/prune/function/SaveConfig.java
new file mode 100644
index 0000000..0f2339f
--- /dev/null
+++ b/tim/prune/function/SaveConfig.java
@@ -0,0 +1,150 @@
+package tim.prune.function;
+
+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.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.Properties;
+
+import javax.swing.BorderFactory;
+import javax.swing.JButton;
+import javax.swing.JDialog;
+import javax.swing.JFileChooser;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+
+import tim.prune.App;
+import tim.prune.Config;
+import tim.prune.GenericFunction;
+import tim.prune.I18nManager;
+
+/**
+ * Class to provide the function to save the config settings
+ */
+public class SaveConfig extends GenericFunction
+{
+ private JDialog _dialog = null;
+
+ /**
+ * Constructor
+ * @param inApp application object for callback
+ */
+ public SaveConfig(App inApp)
+ {
+ super(inApp);
+ }
+
+ /** Get the name key */
+ public String getNameKey() {
+ return "function.saveconfig";
+ }
+
+ /**
+ * Begin the function
+ */
+ public void begin()
+ {
+ // Make new dialog window (don't reuse it)
+ _dialog = new JDialog(_parentFrame, I18nManager.getText(getNameKey()), true);
+ _dialog.setLocationRelativeTo(_parentFrame);
+ _dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
+ _dialog.getContentPane().add(makeDialogComponents());
+ _dialog.pack();
+ _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());
+ dialogPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 15));
+ JLabel descLabel = new JLabel(I18nManager.getText("dialog.saveconfig.desc"));
+ dialogPanel.add(descLabel, BorderLayout.NORTH);
+
+ // Grid panel in centre
+ JPanel mainPanel = new JPanel();
+ mainPanel.setLayout(new GridLayout(0, 2, 15, 2));
+ mainPanel.setBorder(BorderFactory.createEmptyBorder(5, 15, 5, 15));
+ Properties conf = Config.getAllConfig();
+ Enumeration keys = conf.keys();
+ while (keys.hasMoreElements())
+ {
+ String key = keys.nextElement().toString();
+ String keyLabel = I18nManager.getText("dialog.saveconfig." + key);
+ if (!keyLabel.equals("dialog.saveconfig." + key))
+ {
+ mainPanel.add(new JLabel(keyLabel));
+ String val = conf.getProperty(key);
+ if (Config.isKeyBoolean(key)) {
+ val = Config.getConfigBoolean(key)?I18nManager.getText("dialog.about.yes"):I18nManager.getText("dialog.about.no");
+ }
+ else if (val != null && val.length() > 30) {
+ val = val.substring(0, 30) + " ...";
+ }
+ mainPanel.add(new JLabel(val));
+ }
+ }
+ dialogPanel.add(mainPanel, BorderLayout.CENTER);
+
+ // button panel at bottom
+ JPanel buttonPanel = new JPanel();
+ buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
+ JButton okButton = new JButton(I18nManager.getText("button.ok"));
+ okButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e)
+ {
+ finish();
+ }
+ });
+ buttonPanel.add(okButton);
+ JButton cancelButton = new JButton(I18nManager.getText("button.cancel"));
+ cancelButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e)
+ {
+ _dialog.dispose();
+ _dialog = null;
+ }
+ });
+ buttonPanel.add(cancelButton);
+ dialogPanel.add(buttonPanel, BorderLayout.SOUTH);
+ return dialogPanel;
+ }
+
+
+ /**
+ * Finish the dialog when OK pressed
+ */
+ private void finish()
+ {
+ File configFile = Config.getConfigFile();
+ if (configFile == null) {configFile = new File(".pruneconfig");}
+ JFileChooser chooser = new JFileChooser(configFile.getAbsoluteFile().getParent());
+ chooser.setSelectedFile(configFile);
+ int response = chooser.showSaveDialog(_parentFrame);
+ if (response == JFileChooser.APPROVE_OPTION)
+ {
+ File saveFile = chooser.getSelectedFile();
+ try
+ {
+ Config.getAllConfig().store(new FileOutputStream(saveFile), "Prune config file");
+ }
+ catch (IOException ioe) {
+ _app.showErrorMessageNoLookup(getNameKey(),
+ I18nManager.getText("error.save.failed") + " : " + ioe.getMessage());
+ }
+ }
+ _dialog.dispose();
+ _dialog = null;
+ }
+}
diff --git a/tim/prune/function/SetKmzImageSize.java b/tim/prune/function/SetKmzImageSize.java
new file mode 100644
index 0000000..1677e54
--- /dev/null
+++ b/tim/prune/function/SetKmzImageSize.java
@@ -0,0 +1,159 @@
+package tim.prune.function;
+
+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.awt.event.KeyAdapter;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseAdapter;
+
+import javax.swing.BorderFactory;
+import javax.swing.JButton;
+import javax.swing.JDialog;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.SwingConstants;
+
+import tim.prune.App;
+import tim.prune.Config;
+import tim.prune.GenericFunction;
+import tim.prune.I18nManager;
+import tim.prune.gui.WholeNumberField;
+
+/**
+ * Class to provide the function to set the image size for kmz output
+ */
+public class SetKmzImageSize extends GenericFunction
+{
+ private JDialog _dialog = null;
+ private JButton _okButton = null;
+ private WholeNumberField _widthField = null, _heightField = null;
+
+
+ /**
+ * Constructor
+ * @param inApp application object for callback
+ */
+ public SetKmzImageSize(App inApp)
+ {
+ super(inApp);
+ }
+
+ /** Get the name key */
+ public String getNameKey() {
+ return "function.setkmzimagesize";
+ }
+
+ /**
+ * Begin the function
+ */
+ 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();
+ }
+ // Initialise values from config
+ _widthField.setValue(Config.getConfigInt(Config.KEY_KMZ_IMAGE_WIDTH));
+ _heightField.setValue(Config.getConfigInt(Config.KEY_KMZ_IMAGE_HEIGHT));
+ _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());
+
+ // Make a central panel with the text boxes
+ JPanel mainPanel = new JPanel();
+ mainPanel.setLayout(new GridLayout(0, 2));
+ mainPanel.add(makeRightLabel("dialog.saveconfig.prune.kmzimagewidth"));
+ _widthField = new WholeNumberField(4);
+ mainPanel.add(_widthField);
+ mainPanel.add(makeRightLabel("dialog.saveconfig.prune.kmzimageheight"));
+ _heightField = new WholeNumberField(4);
+ mainPanel.add(_heightField);
+ dialogPanel.add(mainPanel, BorderLayout.CENTER);
+
+ // Listeners to enable/disable ok button
+ KeyAdapter keyListener = new KeyAdapter() {
+ /** Key released */
+ public void keyReleased(KeyEvent arg0) {
+ _okButton.setEnabled(_widthField.getValue()>0 && _heightField.getValue()>0);
+ }
+ };
+ MouseAdapter mouseListener = new MouseAdapter() {
+ public void mouseReleased(java.awt.event.MouseEvent arg0) {
+ _okButton.setEnabled(_widthField.getValue()>0 && _heightField.getValue()>0);
+ };
+ };
+ _widthField.addKeyListener(keyListener);
+ _heightField.addKeyListener(keyListener);
+ _widthField.addMouseListener(mouseListener);
+ _heightField.addMouseListener(mouseListener);
+
+ // button panel at bottom
+ JPanel buttonPanel = new JPanel();
+ buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
+ _okButton = new JButton(I18nManager.getText("button.ok"));
+ ActionListener okListener = new ActionListener() {
+ public void actionPerformed(ActionEvent e)
+ {
+ finish();
+ }
+ };
+ _okButton.addActionListener(okListener);
+ _okButton.setEnabled(false);
+ 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;
+ }
+
+ /**
+ * @param inKey text key
+ * @return right-aligned label
+ */
+ private static final JLabel makeRightLabel(String inKey)
+ {
+ JLabel label = new JLabel(I18nManager.getText(inKey) + " : ");
+ label.setHorizontalAlignment(SwingConstants.RIGHT);
+ return label;
+ }
+
+
+ /**
+ * Finish the dialog when OK pressed
+ */
+ private void finish()
+ {
+ if (_widthField.getValue() > 0 && _heightField.getValue() > 0)
+ {
+ // Set entered values in Config
+ Config.setConfigInt(Config.KEY_KMZ_IMAGE_WIDTH, _widthField.getValue());
+ Config.setConfigInt(Config.KEY_KMZ_IMAGE_HEIGHT, _heightField.getValue());
+ _dialog.dispose();
+ }
+ }
+}
diff --git a/tim/prune/function/SetMapBgFunction.java b/tim/prune/function/SetMapBgFunction.java
index 7c5df3a..a683634 100644
--- a/tim/prune/function/SetMapBgFunction.java
+++ b/tim/prune/function/SetMapBgFunction.java
@@ -144,10 +144,10 @@ public class SetMapBgFunction extends GenericFunction
{
// Get values from config
try {
- _serverRadios[Config.getMapServerIndex()].setSelected(true);
+ _serverRadios[Config.getConfigInt(Config.KEY_MAPSERVERINDEX)].setSelected(true);
}
catch (ArrayIndexOutOfBoundsException e) {} // ignore
- String url = Config.getMapServerUrl();
+ String url = Config.getConfigString(Config.KEY_MAPSERVERURL);
if (url != null) {_serverUrl.setText(url);}
// Choose default if none selected
if (getSelectedServer() < 0) {
@@ -194,8 +194,8 @@ public class SetMapBgFunction extends GenericFunction
{
int serverNum = getSelectedServer();
if (!inputOK()) {serverNum = 0;}
- Config.setMapServerIndex(serverNum);
- Config.setMapServerUrl(_serverUrl.getText());
+ Config.setConfigInt(Config.KEY_MAPSERVERINDEX, serverNum);
+ Config.setConfigString(Config.KEY_MAPSERVERURL, _serverUrl.getText());
UpdateMessageBroker.informSubscribers(DataSubscriber.MAPSERVER_CHANGED);
_dialog.dispose();
}
diff --git a/tim/prune/function/SetPathsFunction.java b/tim/prune/function/SetPathsFunction.java
new file mode 100644
index 0000000..65c3c41
--- /dev/null
+++ b/tim/prune/function/SetPathsFunction.java
@@ -0,0 +1,167 @@
+package tim.prune.function;
+
+import java.awt.BorderLayout;
+import java.awt.FlowLayout;
+import java.awt.GridLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import javax.swing.BorderFactory;
+import javax.swing.JButton;
+import javax.swing.JDialog;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+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;
+
+/**
+ * Function to set the paths for the external programs (eg gnuplot)
+ */
+public class SetPathsFunction extends GenericFunction
+{
+ /** dialog object, cached */
+ private JDialog _dialog = null;
+ /** edit boxes */
+ private JTextField[] _editFields = null;
+ /** yes/no labels */
+ private JLabel[] _installedLabels = null;
+ /** Config keys */
+ private static final String[] CONFIG_KEYS = {Config.KEY_GPSBABEL_PATH, Config.KEY_GNUPLOT_PATH, Config.KEY_EXIFTOOL_PATH};
+ /** Label keys */
+ private static final String[] LABEL_KEYS = {"gpsbabel", "gnuplot", "exiftool"};
+ /** Number of entries */
+ private static final int NUM_KEYS = CONFIG_KEYS.length;
+
+ /**
+ * Constructor from superclass
+ * @param inApp app object
+ */
+ public SetPathsFunction(App inApp)
+ {
+ super(inApp);
+ }
+
+ /**
+ * @return key for function name
+ */
+ public String getNameKey()
+ {
+ return "function.setpaths";
+ }
+
+ /**
+ * 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();
+ }
+ checkPaths();
+ // Show dialog
+ _dialog.setVisible(true);
+ }
+
+
+ /**
+ * Make the dialog components
+ * @return panel containing gui elements
+ */
+ private JPanel makeDialogComponents()
+ {
+ JPanel dialogPanel = new JPanel();
+ dialogPanel.setLayout(new BorderLayout());
+ dialogPanel.add(new JLabel(I18nManager.getText("dialog.setpaths.intro")), BorderLayout.NORTH);
+
+ // Main panel with edit boxes for paths
+ JPanel mainPanel = new JPanel();
+ mainPanel.setLayout(new GridLayout(3, 3, 10, 1));
+ _editFields = new JTextField[NUM_KEYS];
+ _installedLabels = new JLabel[NUM_KEYS];
+ for (int i=0; i= 0;
+ String osName = System.getProperty("os.name").toLowerCase();
+ boolean isMacOsx = osName.indexOf("mac os") >= 0
+ || osName.indexOf("darwin") >= 0;
if (isMacOsx) {
// for Mac Osx just use "open" command
_browserCommand = new String[] {"open", null};
diff --git a/tim/prune/function/charts/Charter.java b/tim/prune/function/charts/Charter.java
index a3348c8..01bf16c 100644
--- a/tim/prune/function/charts/Charter.java
+++ b/tim/prune/function/charts/Charter.java
@@ -87,6 +87,12 @@ public class Charter extends GenericFunction
*/
public void begin()
{
+ // First check if gnuplot is available
+ if (!ExternalTools.isToolInstalled(ExternalTools.TOOL_GNUPLOT))
+ {
+ _app.showErrorMessage(getNameKey(), "dialog.charts.gnuplotnotfound");
+ return;
+ }
// Make dialog window
if (_dialog == null)
{
@@ -183,14 +189,6 @@ public class Charter extends GenericFunction
// 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() {
@@ -277,7 +275,8 @@ public class Charter extends GenericFunction
OutputStreamWriter writer = null;
try
{
- Process process = Runtime.getRuntime().exec(Config.getGnuplotPath() + " -persist");
+ final String gnuplotPath = Config.getConfigString(Config.KEY_GNUPLOT_PATH);
+ Process process = Runtime.getRuntime().exec(gnuplotPath + " -persist");
writer = new OutputStreamWriter(process.getOutputStream());
if (showSvg)
{
@@ -439,7 +438,7 @@ public class Charter extends GenericFunction
*/
private static String getUnitsLabel(String inMetric, String inImperial)
{
- String key = Config.getUseMetricUnits()?inMetric:inImperial;
+ String key = Config.getConfigBoolean(Config.KEY_METRIC_UNITS)?inMetric:inImperial;
return I18nManager.getText(key);
}
@@ -462,7 +461,7 @@ public class Charter extends GenericFunction
{
totalRads += DataPoint.calculateRadiansBetween(prevPoint, currPoint);
}
- if (Config.getUseMetricUnits()) {
+ if (Config.getConfigBoolean(Config.KEY_METRIC_UNITS)) {
values.setData(i, Distance.convertRadiansToDistance(totalRads, Units.KILOMETRES));
} else {
values.setData(i, Distance.convertRadiansToDistance(totalRads, Units.MILES));
@@ -507,7 +506,7 @@ public class Charter extends GenericFunction
private static ChartSeries getAltitudeValues(Track inTrack)
{
ChartSeries values = new ChartSeries(inTrack.getNumPoints());
- Altitude.Format altFormat = Config.getUseMetricUnits()?Altitude.Format.METRES:Altitude.Format.FEET;
+ Altitude.Format altFormat = Config.getConfigBoolean(Config.KEY_METRIC_UNITS)?Altitude.Format.METRES:Altitude.Format.FEET;
for (int i=0; i= 0) {
+ out.write(buf, 0, nread);
+ total += nread;
+ }
+ }
+ out.flush();
+ buf = null;
+ }
+
+ /**
+ * adds a file parameter to the request
+ * @param name parameter name
+ * @param filename the name of the file
+ * @param is input stream to read the contents of the file from
+ * @throws IOException
+ */
+ public void setParameter(String name, String filename, InputStream is) throws IOException
+ {
+ boundary();
+ writeName(name);
+ write("; filename=\"");
+ write(filename);
+ write('"');
+ newline();
+ write("Content-Type: ");
+ String type = URLConnection.guessContentTypeFromName(filename);
+ if (type == null) type = "application/octet-stream";
+ writeln(type);
+ newline();
+ pipe(is, _os);
+ newline();
+ }
+
+ /**
+ * adds a file parameter to the request
+ * @param name parameter name
+ * @param file the file to upload
+ * @throws IOException
+ */
+ public void setParameter(String name, File file) throws IOException {
+ setParameter(name, file.getPath(), new FileInputStream(file));
+ }
+
+ /**
+ * adds a parameter to the request; if the parameter is a File, the file is uploaded,
+ * otherwise the string value of the parameter is passed in the request
+ * @param name parameter name
+ * @param object parameter value, a File or anything else that can be stringified
+ * @throws IOException
+ */
+ public void setParameter(String name, Object object) throws IOException
+ {
+ if (object instanceof File) {
+ setParameter(name, (File) object);
+ } else {
+ setParameter(name, object.toString());
+ }
+ }
+
+ /**
+ * posts the requests to the server
+ * @return input stream with the server response
+ * @throws IOException
+ */
+ public InputStream post() throws IOException {
+ boundary();
+ writeln("--");
+ _os.close();
+ return _connection.getInputStream();
+ }
+
+ /**
+ * post the POST request to the server, with the specified parameter
+ * @param name parameter name
+ * @param value parameter value
+ * @return input stream with the server response
+ * @throws IOException
+ * @see setParameter
+ */
+ public InputStream post(String name, Object value) throws IOException {
+ setParameter(name, value);
+ return post();
+ }
+
+ /**
+ * post the POST request to the server, with the specified parameters
+ * @param name1 first parameter name
+ * @param value1 first parameter value
+ * @param name2 second parameter name
+ * @param value2 second parameter value
+ * @return input stream with the server response
+ * @throws IOException
+ * @see setParameter
+ */
+ public InputStream post(String name1, Object value1, String name2, Object value2) throws IOException {
+ setParameter(name1, value1);
+ return post(name2, value2);
+ }
+
+ /**
+ * post the POST request to the server, with the specified parameters
+ * @param name1 first parameter name
+ * @param value1 first parameter value
+ * @param name2 second parameter name
+ * @param value2 second parameter value
+ * @param name3 third parameter name
+ * @param value3 third parameter value
+ * @return input stream with the server response
+ * @throws IOException
+ * @see setParameter
+ */
+ public InputStream post(String name1, Object value1, String name2, Object value2,
+ String name3, Object value3) throws IOException
+ {
+ setParameter(name1, value1);
+ return post(name2, value2, name3, value3);
+ }
+
+ /**
+ * post the POST request to the server, with the specified parameters
+ * @param name1 first parameter name
+ * @param value1 first parameter value
+ * @param name2 second parameter name
+ * @param value2 second parameter value
+ * @param name3 third parameter name
+ * @param value3 third parameter value
+ * @param name4 fourth parameter name
+ * @param value4 fourth parameter value
+ * @return input stream with the server response
+ * @throws IOException
+ * @see setParameter
+ */
+ public InputStream post(String name1, Object value1, String name2, Object value2,
+ String name3, Object value3, String name4, Object value4) throws IOException
+ {
+ setParameter(name1, value1);
+ return post(name2, value2, name3, value3, name4, value4);
+ }
+
+ /**
+ * post the POST request specified URL, with the specified parameter
+ * @param name parameter name
+ * @param value parameter value
+ * @return input stream with the server response
+ * @throws IOException
+ * @see setParameter
+ */
+ public static InputStream post(URL url, String name1, Object value1) throws IOException {
+ return new FormPoster(url).post(name1, value1);
+ }
+
+ /**
+ * post the POST request to specified URL, with the specified parameters
+ * @param name1 first parameter name
+ * @param value1 first parameter value
+ * @param name2 second parameter name
+ * @param value2 second parameter value
+ * @return input stream with the server response
+ * @throws IOException
+ * @see setParameter
+ */
+ public static InputStream post(URL url, String name1, Object value1,
+ String name2, Object value2) throws IOException
+ {
+ return new FormPoster(url).post(name1, value1, name2, value2);
+ }
+
+ /**
+ * post the POST request to specified URL, with the specified parameters
+ * @param name1 first parameter name
+ * @param value1 first parameter value
+ * @param name2 second parameter name
+ * @param value2 second parameter value
+ * @param name3 third parameter name
+ * @param value3 third parameter value
+ * @return input stream with the server response
+ * @throws IOException
+ * @see setParameter
+ */
+ public static InputStream post(URL url, String name1, Object value1, String name2, Object value2,
+ String name3, Object value3) throws IOException
+ {
+ return new FormPoster(url).post(name1, value1, name2, value2, name3, value3);
+ }
+
+ /**
+ * post the POST request to specified URL, with the specified parameters
+ * @param name1 first parameter name
+ * @param value1 first parameter value
+ * @param name2 second parameter name
+ * @param value2 second parameter value
+ * @param name3 third parameter name
+ * @param value3 third parameter value
+ * @param name4 fourth parameter name
+ * @param value4 fourth parameter value
+ * @return input stream with the server response
+ * @throws IOException
+ * @see setParameter
+ */
+ public static InputStream post(URL url, String name1, Object value1, String name2, Object value2,
+ String name3, Object value3, String name4, Object value4) throws IOException
+ {
+ return new FormPoster(url).post(name1, value1, name2, value2, name3, value3, name4, value4);
+ }
+}
diff --git a/tim/prune/function/gpsies/GetGpsiesFunction.java b/tim/prune/function/gpsies/GetGpsiesFunction.java
new file mode 100644
index 0000000..493aedf
--- /dev/null
+++ b/tim/prune/function/gpsies/GetGpsiesFunction.java
@@ -0,0 +1,308 @@
+package tim.prune.function.gpsies;
+
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.FlowLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.io.IOException;
+import java.net.URL;
+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.JSplitPane;
+import javax.swing.JTable;
+import javax.swing.JTextArea;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import tim.prune.App;
+import tim.prune.GenericFunction;
+import tim.prune.I18nManager;
+import tim.prune.function.browser.BrowserLauncher;
+import tim.prune.load.xml.XmlFileLoader;
+import tim.prune.load.xml.ZipFileLoader;
+
+/**
+ * Function to load track information from Gpsies.com
+ * according to the currently viewed area
+ */
+public class GetGpsiesFunction extends GenericFunction implements Runnable
+{
+ /** Dialog object */
+ private JDialog _dialog = null;
+ /** list model */
+ private TrackListModel _trackListModel = null;
+ /** track table */
+ private JTable _trackTable = null;
+ /** Cancelled flag */
+ private boolean _cancelled = false;
+ /** Status label */
+ private JLabel _statusLabel = null;
+ /** Description box */
+ private JTextArea _descriptionBox = null;
+ /** Load button */
+ private JButton _loadButton = null;
+ /** Show button */
+ private JButton _showButton = null;
+ /** Number of results per page */
+ private static final int RESULTS_PER_PAGE = 20;
+ /** Maximum number of results to get */
+ private static final int MAX_RESULTS = 60;
+
+
+ /**
+ * Constructor
+ * @param inApp App object
+ */
+ public GetGpsiesFunction(App inApp)
+ {
+ super(inApp);
+ }
+
+ /**
+ * @return name key
+ */
+ public String getNameKey() {
+ return "function.getgpsies";
+ }
+
+ /**
+ * Begin the function
+ */
+ public void begin()
+ {
+ // Initialise dialog, show empty list
+ if (_dialog == null)
+ {
+ _dialog = new JDialog(_parentFrame, I18nManager.getText(getNameKey()), true);
+ _dialog.setLocationRelativeTo(_parentFrame);
+ _dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
+ // add closing listener
+ _dialog.addWindowListener(new WindowAdapter() {
+ public void windowClosing(WindowEvent e) {
+ _cancelled = true;
+ }
+ });
+ _dialog.getContentPane().add(makeDialogComponents());
+ _dialog.pack();
+ }
+ // Clear list
+ _trackListModel.clear();
+ _loadButton.setEnabled(false);
+ _showButton.setEnabled(false);
+ _cancelled = false;
+ _descriptionBox.setText("");
+ // Start new thread to load list asynchronously
+ new Thread(this).start();
+
+ // Show dialog
+ _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());
+
+ // Status label
+ _statusLabel = new JLabel(I18nManager.getText("confirm.running"));
+ dialogPanel.add(_statusLabel, BorderLayout.NORTH);
+ // Main panel with track list
+ _trackListModel = new TrackListModel();
+ _trackTable = new JTable(_trackListModel);
+ _trackTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
+ public void valueChanged(ListSelectionEvent e) {
+ if (!e.getValueIsAdjusting())
+ {
+ if (_trackTable.getSelectedRow() >= 0
+ && _trackTable.getSelectedRow() < _trackListModel.getRowCount())
+ {
+ _loadButton.setEnabled(true);
+ _showButton.setEnabled(true);
+ setDescription(_trackListModel.getTrack(_trackTable.getSelectedRow()).getDescription());
+ _descriptionBox.setCaretPosition(0);
+ }
+ else {
+ _descriptionBox.setText("");
+ }
+ }
+ }
+ });
+ _trackTable.getColumnModel().getColumn(0).setPreferredWidth(300);
+ _trackTable.getColumnModel().getColumn(1).setPreferredWidth(70);
+ JScrollPane tablePane = new JScrollPane(_trackTable);
+ tablePane.setPreferredSize(new Dimension(450, 200));
+ // Panel to hold description label and box
+ JPanel descPanel = new JPanel();
+ descPanel.setLayout(new BorderLayout());
+ JLabel descLabel = new JLabel(I18nManager.getText("dialog.gpsies.description") + " :");
+ descPanel.add(descLabel, BorderLayout.NORTH);
+ _descriptionBox = new JTextArea(5, 20);
+ _descriptionBox.setEditable(false);
+ _descriptionBox.setLineWrap(true);
+ _descriptionBox.setWrapStyleWord(true);
+ JScrollPane descPane = new JScrollPane(_descriptionBox);
+ descPane.setPreferredSize(new Dimension(400, 80));
+ descPanel.add(descPane, BorderLayout.CENTER);
+ // Use split pane to split table from description
+ JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, tablePane, descPanel);
+ splitPane.setResizeWeight(1.0);
+ dialogPanel.add(splitPane, BorderLayout.CENTER);
+
+ // button panel at bottom
+ JPanel buttonPanel = new JPanel();
+ buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
+ _loadButton = new JButton(I18nManager.getText("button.load"));
+ _loadButton.setEnabled(false);
+ _loadButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e)
+ {
+ loadSelectedTrack();
+ }
+ });
+ buttonPanel.add(_loadButton);
+ _showButton = new JButton(I18nManager.getText("button.showwebpage"));
+ _showButton.setEnabled(false);
+ _showButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e)
+ {
+ showSelectedTrack();
+ }
+ });
+ buttonPanel.add(_showButton);
+ JButton cancelButton = new JButton(I18nManager.getText("button.cancel"));
+ cancelButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e)
+ {
+ _cancelled = true;
+ _dialog.dispose();
+ }
+ });
+ buttonPanel.add(cancelButton);
+ dialogPanel.add(buttonPanel, BorderLayout.SOUTH);
+ dialogPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 15));
+ return dialogPanel;
+ }
+
+ /**
+ * Set the description in the box
+ * @param inDesc description to set, or null for no description
+ */
+ private void setDescription(String inDesc)
+ {
+ String text = inDesc;
+ if (inDesc == null || inDesc.length() < 2) {
+ text = I18nManager.getText("dialog.gpsies.nodescription");
+ }
+ _descriptionBox.setText(text);
+ }
+
+ /**
+ * Run method to call gpsies.com in separate thread
+ */
+ public void run()
+ {
+ _statusLabel.setText(I18nManager.getText("confirm.running"));
+ // Act on callback to update list and send another request if necessary
+ double[] coords = _app.getViewport().getBounds();
+ // Example http://www.gpsies.com/api.do?BBOX=10,51,12,53&limit=20&trackTypes=jogging&filetype=kml&device=Run.GPS
+ int currPage = 1;
+
+ ArrayList trackList = null;
+ URL url = null;
+ String descMessage = "";
+ // Loop for each page of the results
+ do
+ {
+ String urlString = "http://www.gpsies.com/api.do?BBOX=" +
+ coords[1] + "," + coords[0] + "," + coords[3] + "," + coords[2] +
+ "&limit=" + RESULTS_PER_PAGE + "&resultPage=" + currPage;
+ // System.out.println(urlString);
+ // Parse the returned XML with a special handler
+ GpsiesXmlHandler xmlHandler = new GpsiesXmlHandler();
+ try
+ {
+ url = new URL(urlString);
+ SAXParser saxParser = SAXParserFactory.newInstance().newSAXParser();
+ saxParser.parse(url.openStream(), xmlHandler);
+ }
+ catch (Exception e) {
+ descMessage = e.getClass().getName() + " - " + e.getMessage();
+ }
+ // TODO: Close streams somehow? Haven't got a reference to the input stream to close it!
+ // Add track list to model
+ trackList = xmlHandler.getTrackList();
+ _trackListModel.addTracks(trackList);
+
+ // Compare number of results with results per page and call again if necessary
+ currPage++;
+ }
+ while (trackList != null && trackList.size() == RESULTS_PER_PAGE
+ && _trackListModel.getRowCount() < MAX_RESULTS && !_cancelled);
+ // Set status label according to error or "none found", leave blank if ok
+ if (descMessage.equals("") && (trackList == null || trackList.size() == 0)) {
+ descMessage = I18nManager.getText("dialog.gpsies.nonefound");
+ }
+ _statusLabel.setText(descMessage);
+ }
+
+
+ /**
+ * Load the selected track
+ */
+ private void loadSelectedTrack()
+ {
+ // Find the row selected in the table and get the corresponding track
+ int rowNum = _trackTable.getSelectedRow();
+ if (rowNum >= 0 && rowNum < _trackListModel.getRowCount())
+ {
+ String url = _trackListModel.getTrack(rowNum).getDownloadLink();
+ XmlFileLoader xmlLoader = new XmlFileLoader(_app);
+ ZipFileLoader loader = new ZipFileLoader(_app, xmlLoader);
+ try
+ {
+ loader.openStream(new URL(url).openStream());
+ }
+ catch (IOException ioe) {
+ System.err.println("IO Exception : " + ioe.getMessage());
+ }
+ }
+ // Close the dialog
+ _cancelled = true;
+ _dialog.dispose();
+ }
+
+
+ /**
+ * Show the webpage for the selected track
+ */
+ private void showSelectedTrack()
+ {
+ // Find the row selected in the table and show the corresponding url
+ int rowNum = _trackTable.getSelectedRow();
+ if (rowNum >= 0 && rowNum < _trackListModel.getRowCount())
+ {
+ String id = _trackListModel.getTrack(rowNum).getFileId();
+ BrowserLauncher.launchBrowser("http://gpsies.com/map.do?fileId=" + id);
+ }
+ // Close the dialog
+ _cancelled = true;
+ _dialog.dispose();
+ }
+}
diff --git a/tim/prune/function/gpsies/GpsiesTrack.java b/tim/prune/function/gpsies/GpsiesTrack.java
new file mode 100644
index 0000000..7441195
--- /dev/null
+++ b/tim/prune/function/gpsies/GpsiesTrack.java
@@ -0,0 +1,99 @@
+package tim.prune.function.gpsies;
+
+/**
+ * Class to hold a single track from Gpsies.com
+ */
+public class GpsiesTrack
+{
+ /** Track name or title */
+ private String _trackName = null;
+ /** Description */
+ private String _description = null;
+ /** File id for more details */
+ private String _fileId = null;
+ /** Track length in metres */
+ private double _trackLength = 0.0;
+ /** Download link */
+ private String _downloadLink = null;
+
+
+ /**
+ * @param inName name of track
+ */
+ public void setTrackName(String inName)
+ {
+ _trackName = inName;
+ }
+
+ /**
+ * @return track name
+ */
+ public String getTrackName()
+ {
+ return _trackName;
+ }
+
+ /**
+ * @param inDesc description
+ */
+ public void setDescription(String inDesc)
+ {
+ _description = inDesc;
+ }
+
+ /**
+ * @return track description
+ */
+ public String getDescription()
+ {
+ return _description;
+ }
+
+ /**
+ * @param inId id of track
+ */
+ public void setFileId(String inId)
+ {
+ _fileId = inId;
+ }
+
+ /**
+ * @return file id
+ */
+ public String getFileId()
+ {
+ return _fileId;
+ }
+
+ /**
+ * @param inLength length of track
+ */
+ public void setLength(double inLength)
+ {
+ _trackLength = inLength;
+ }
+
+ /**
+ * @return track length
+ */
+ public double getLength()
+ {
+ return _trackLength;
+ }
+
+ /**
+ * @param inLink link to download track
+ */
+ public void setDownloadLink(String inLink)
+ {
+ _downloadLink = inLink;
+ }
+
+ /**
+ * @return download link
+ */
+ public String getDownloadLink()
+ {
+ return _downloadLink;
+ }
+}
diff --git a/tim/prune/function/gpsies/GpsiesXmlHandler.java b/tim/prune/function/gpsies/GpsiesXmlHandler.java
new file mode 100644
index 0000000..e639160
--- /dev/null
+++ b/tim/prune/function/gpsies/GpsiesXmlHandler.java
@@ -0,0 +1,104 @@
+package tim.prune.function.gpsies;
+
+import java.util.ArrayList;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+/**
+ * XML handler for dealing with XML returned from gpsies.com
+ */
+public class GpsiesXmlHandler extends DefaultHandler
+{
+ private boolean _inTracks = false;
+ private boolean _inTrack = false;
+ private boolean _inTrackName = false;
+ private boolean _inDescription = false;
+ private boolean _inFileId = false;
+ private boolean _inTrackLength = false;
+ private boolean _inLink = false;
+ private String _value = null;
+ private ArrayList _trackList = null;
+ private GpsiesTrack _track = null;
+
+
+ /**
+ * React to the start of an XML tag
+ */
+ public void startElement(String inUri, String inLocalName, String inTagName,
+ Attributes inAttributes) throws SAXException
+ {
+ if (inTagName.equals("tracks")) {
+ _inTracks = true;
+ _trackList = new ArrayList();
+ }
+ else if (_inTracks && inTagName.equals("track")) {
+ _inTrack = true;
+ _track = new GpsiesTrack();
+ }
+ else if (_inTrack && inTagName.equals("title")) {_inTrackName = true;}
+ else if (_inTrack && inTagName.equals("description")) {_inDescription = true;}
+ else if (_inTrack && inTagName.equals("fileId")) {_inFileId = true;}
+ else if (_inTrack && inTagName.equals("trackLengthM")) {_inTrackLength = true;}
+ else if (_inTrack && inTagName.equals("downloadLink")) {_inLink = true;}
+ super.startElement(inUri, inLocalName, inTagName, inAttributes);
+ }
+
+ /**
+ * React to the end of an XML tag
+ */
+ public void endElement(String inUri, String inLocalName, String inTagName)
+ throws SAXException
+ {
+ if (inTagName.equals("tracks")) {_inTracks = false;}
+ else if (_inTrack && inTagName.equals("track")) {
+ _trackList.add(_track);
+ _inTrack = false;
+ }
+ else if (_inTrackName && inTagName.equals("title")) {
+ _track.setTrackName(_value);
+ _inTrackName = false;
+ }
+ else if (_inDescription && inTagName.equals("description")) {
+ _track.setDescription(_value);
+ _inDescription = false;
+ }
+ else if (_inFileId && inTagName.equals("fileId")) {
+ _track.setFileId(_value);
+ _inFileId = false;
+ }
+ else if (_inTrackLength && inTagName.equals("trackLengthM")) {
+ try {
+ _track.setLength(Double.parseDouble(_value));
+ }
+ catch (NumberFormatException nfe) {}
+ _inTrackLength = false;
+ }
+ else if (_inLink && inTagName.equals("downloadLink")) {
+ _track.setDownloadLink(_value);
+ _inLink = false;
+ }
+ super.endElement(inUri, inLocalName, inTagName);
+ }
+
+ /**
+ * React to characters received inside tags
+ */
+ public void characters(char[] inCh, int inStart, int inLength)
+ throws SAXException
+ {
+ _value = new String(inCh, inStart, inLength);
+ // System.out.println("Value: '" + value + "'");
+ // TODO: Note, this doesn't cope well with split characters for really long descriptions etc
+ super.characters(inCh, inStart, inLength);
+ }
+
+ /**
+ * @return the list of tracks
+ */
+ public ArrayList getTrackList()
+ {
+ return _trackList;
+ }
+}
diff --git a/tim/prune/function/gpsies/TrackListModel.java b/tim/prune/function/gpsies/TrackListModel.java
new file mode 100644
index 0000000..275ae83
--- /dev/null
+++ b/tim/prune/function/gpsies/TrackListModel.java
@@ -0,0 +1,108 @@
+package tim.prune.function.gpsies;
+
+import java.text.NumberFormat;
+import java.util.ArrayList;
+
+import javax.swing.table.AbstractTableModel;
+
+import tim.prune.Config;
+import tim.prune.I18nManager;
+import tim.prune.data.Distance;
+
+/**
+ * Model for list of tracks from gpsies.com
+ */
+public class TrackListModel extends AbstractTableModel
+{
+ /** List of tracks */
+ private ArrayList _trackList = null;
+ /** Column heading for track name */
+ private static final String _nameColLabel = I18nManager.getText("dialog.gpsies.column.name");
+ /** Column heading for length */
+ private static final String _lengthColLabel = I18nManager.getText("dialog.gpsies.column.length");
+ /** Formatter for distances */
+ private NumberFormat _distanceFormatter = NumberFormat.getInstance();
+
+ /**
+ * Constructor
+ */
+ public TrackListModel()
+ {
+ _distanceFormatter.setMaximumFractionDigits(1);
+ }
+
+ /**
+ * @return column count
+ */
+ public int getColumnCount()
+ {
+ return 2;
+ }
+
+ /**
+ * @return number of rows
+ */
+ public int getRowCount()
+ {
+ if (_trackList == null) return 0;
+ return _trackList.size();
+ }
+
+ /**
+ * @param inColNum column number
+ * @return column label for given column
+ */
+ public String getColumnName(int inColNum)
+ {
+ if (inColNum == 0) {return _nameColLabel;}
+ return _lengthColLabel;
+ }
+
+ /**
+ * @param inRowNum row number
+ * @param inColNum column number
+ * @return cell entry at given row and column
+ */
+ public Object getValueAt(int inRowNum, int inColNum)
+ {
+ GpsiesTrack track = _trackList.get(inRowNum);
+ if (inColNum == 0) {return track.getTrackName();}
+ double lengthM = track.getLength();
+ if (Config.getConfigBoolean(Config.KEY_METRIC_UNITS)) {
+ return _distanceFormatter.format(lengthM / 1000.0) + " " + I18nManager.getText("units.kilometres.short");
+ }
+ // must be imperial
+ return _distanceFormatter.format(Distance.convertMetresToMiles(lengthM))
+ + " " + I18nManager.getText("units.miles.short");
+ }
+
+ /**
+ * Add a list of tracks to this model
+ * @param inList list of tracks to add
+ */
+ public void addTracks(ArrayList inList)
+ {
+ if (_trackList == null) {_trackList = new ArrayList();}
+ if (inList != null && inList.size() > 0) {
+ _trackList.addAll(inList);
+ }
+ fireTableDataChanged();
+ }
+
+ /**
+ * @param inRowNum row number from 0
+ * @return track object for this row
+ */
+ public GpsiesTrack getTrack(int inRowNum)
+ {
+ return _trackList.get(inRowNum);
+ }
+
+ /**
+ * Clear the list of tracks
+ */
+ public void clear()
+ {
+ _trackList = null;
+ }
+}
diff --git a/tim/prune/gui/DetailsDisplay.java b/tim/prune/gui/DetailsDisplay.java
index 2703c1b..c40f8c2 100644
--- a/tim/prune/gui/DetailsDisplay.java
+++ b/tim/prune/gui/DetailsDisplay.java
@@ -46,6 +46,7 @@ public class DetailsDisplay extends GenericDisplay
private JLabel _durationLabel = null;
private JLabel _altRangeLabel = null, _updownLabel = null;
private JLabel _aveSpeedLabel = null, _aveMovingSpeedLabel = null;
+ private JLabel _paceLabel = null;
// Photo details
private JLabel _photoLabel = null;
@@ -138,6 +139,8 @@ public class DetailsDisplay extends GenericDisplay
rangeDetailsPanel.add(_aveSpeedLabel);
_aveMovingSpeedLabel = new JLabel("");
rangeDetailsPanel.add(_aveMovingSpeedLabel);
+ _paceLabel = new JLabel("");
+ rangeDetailsPanel.add(_paceLabel);
_altRangeLabel = new JLabel("");
rangeDetailsPanel.add(_altRangeLabel);
_updownLabel = new JLabel("");
@@ -196,12 +199,12 @@ public class DetailsDisplay extends GenericDisplay
lowerPanel.add(unitsLabel);
String[] distUnits = {I18nManager.getText("units.kilometres"), I18nManager.getText("units.miles")};
_distUnitsDropdown = new JComboBox(distUnits);
- if (!Config.getUseMetricUnits()) {_distUnitsDropdown.setSelectedIndex(1);}
+ if (!Config.getConfigBoolean(Config.KEY_METRIC_UNITS)) {_distUnitsDropdown.setSelectedIndex(1);}
_distUnitsDropdown.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
dataUpdated(DataSubscriber.UNITS_CHANGED);
- Config.setUseMetricUnits(_distUnitsDropdown.getSelectedIndex() == 0);
+ Config.setConfigBoolean(Config.KEY_METRIC_UNITS, _distUnitsDropdown.getSelectedIndex() == 0);
}
});
lowerPanel.add(_distUnitsDropdown);
@@ -245,7 +248,8 @@ public class DetailsDisplay extends GenericDisplay
:"");
if (currentPoint.getTimestamp().isValid())
{
- if (currentPointIndex > 0 && currentPointIndex < (_trackInfo.getTrack().getNumPoints()-1)) {
+ if (currentPointIndex > 0 && currentPointIndex < (_trackInfo.getTrack().getNumPoints()-1))
+ {
DataPoint prevPoint = _trackInfo.getTrack().getPoint(currentPointIndex - 1);
DataPoint nextPoint = _trackInfo.getTrack().getPoint(currentPointIndex + 1);
if (prevPoint.getTimestamp().isValid() && nextPoint.getTimestamp().isValid())
@@ -286,6 +290,7 @@ public class DetailsDisplay extends GenericDisplay
_updownLabel.setText("");
_aveSpeedLabel.setText("");
_aveMovingSpeedLabel.setText("");
+ _paceLabel.setText("");
}
else
{
@@ -293,19 +298,38 @@ public class DetailsDisplay extends GenericDisplay
+ (selection.getStart()+1) + " " + I18nManager.getText("details.range.to")
+ " " + (selection.getEnd()+1));
_distanceLabel.setText(LABEL_RANGE_DISTANCE + roundedNumber(selection.getDistance(distUnits)) + " " + distUnitsStr);
- _movingDistanceLabel.setText(LABEL_RANGE_MOVINGDISTANCE + roundedNumber(selection.getMovingDistance(distUnits)) + " " + distUnitsStr);
+ if (selection.getHasMultipleSegments()) {
+ _movingDistanceLabel.setText(LABEL_RANGE_MOVINGDISTANCE + roundedNumber(selection.getMovingDistance(distUnits)) + " " + distUnitsStr);
+ }
+ else {
+ _movingDistanceLabel.setText(null);
+ }
if (selection.getNumSeconds() > 0)
{
_durationLabel.setText(LABEL_RANGE_DURATION + buildDurationString(selection.getNumSeconds()));
_aveSpeedLabel.setText(I18nManager.getText("details.range.avespeed") + ": "
+ roundedNumber(selection.getDistance(distUnits)/selection.getNumSeconds()*3600.0) + " " + speedUnitsStr);
- _aveMovingSpeedLabel.setText(I18nManager.getText("details.range.avemovingspeed") + ": "
- + roundedNumber(selection.getMovingDistance(distUnits)/selection.getMovingSeconds()*3600.0) + " " + speedUnitsStr);
+ if (selection.getHasMultipleSegments()) {
+ _aveMovingSpeedLabel.setText(I18nManager.getText("details.range.avemovingspeed") + ": "
+ + roundedNumber(selection.getMovingDistance(distUnits)/selection.getMovingSeconds()*3600.0) + " " + speedUnitsStr);
+ }
+ else {
+ _aveMovingSpeedLabel.setText(null);
+ }
+ if (Config.getConfigBoolean(Config.KEY_SHOW_PACE)) {
+ _paceLabel.setText(I18nManager.getText("details.range.pace") + ": "
+ + buildDurationString((long) (selection.getNumSeconds()/selection.getDistance(distUnits)))
+ + " / " + distUnitsStr);
+ }
+ else {
+ _paceLabel.setText("");
+ }
}
else {
_durationLabel.setText("");
_aveSpeedLabel.setText("");
_aveMovingSpeedLabel.setText("");
+ _paceLabel.setText("");
}
String altUnitsLabel = getAltitudeUnitsLabel(selection.getAltitudeFormat());
IntegerRange altRange = selection.getAltitudeRange();
@@ -326,7 +350,7 @@ public class DetailsDisplay extends GenericDisplay
}
// show photo details and thumbnail
Photo currentPhoto = _trackInfo.getPhotoList().getPhoto(_trackInfo.getSelection().getCurrentPhotoIndex());
- if (_track == null || ( (currentPoint == null || currentPoint.getPhoto() == null) && currentPhoto == null))
+ if ((currentPoint == null || currentPoint.getPhoto() == null) && currentPhoto == null)
{
// no photo, hide details
_photoLabel.setText(I18nManager.getText("details.nophoto"));
@@ -338,7 +362,7 @@ public class DetailsDisplay extends GenericDisplay
{
if (currentPhoto == null) {currentPhoto = currentPoint.getPhoto();}
_photoLabel.setText(I18nManager.getText("details.photofile") + ": " + currentPhoto.getFile().getName());
- _photoLabel.setText(LABEL_POINT_TIMESTAMP + currentPhoto.getTimestamp().getText());
+ _photoTimestampLabel.setText(LABEL_POINT_TIMESTAMP + currentPhoto.getTimestamp().getText());
_photoConnectedLabel.setText(I18nManager.getText("details.photo.connected") + ": "
+ (currentPhoto.getCurrentStatus() == Photo.Status.NOT_CONNECTED ?
I18nManager.getText("dialog.about.no"):I18nManager.getText("dialog.about.yes")));
@@ -403,7 +427,7 @@ public class DetailsDisplay extends GenericDisplay
if (inNumSecs < 86400L) return "" + (inNumSecs / 60 / 60) + I18nManager.getText("display.range.time.hours")
+ " " + ((inNumSecs / 60) % 60) + I18nManager.getText("display.range.time.mins");
if (inNumSecs < 432000L) return "" + (inNumSecs / 86400L) + I18nManager.getText("display.range.time.days")
- + " " + (inNumSecs / 60 / 60) + I18nManager.getText("display.range.time.hours");
+ + " " + (inNumSecs / 60 / 60) % 24 + I18nManager.getText("display.range.time.hours");
if (inNumSecs < 8640000L) return "" + (inNumSecs / 86400L) + I18nManager.getText("display.range.time.days");
return "big";
}
diff --git a/tim/prune/gui/FunctionLauncher.java b/tim/prune/gui/FunctionLauncher.java
new file mode 100644
index 0000000..e846412
--- /dev/null
+++ b/tim/prune/gui/FunctionLauncher.java
@@ -0,0 +1,33 @@
+package tim.prune.gui;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import tim.prune.GenericFunction;
+
+/**
+ * Class to launch a function triggered by an action
+ */
+public class FunctionLauncher implements ActionListener
+{
+ /** Function to launch */
+ private GenericFunction _function = null;
+
+ /**
+ * Constructor
+ * @param inFunction function to launch
+ */
+ public FunctionLauncher(GenericFunction inFunction)
+ {
+ _function = inFunction;
+ }
+
+ /**
+ * React to action
+ * @param e event
+ */
+ public void actionPerformed(ActionEvent e)
+ {
+ _function.begin();
+ }
+
+}
\ No newline at end of file
diff --git a/tim/prune/gui/IconManager.java b/tim/prune/gui/IconManager.java
index 8930d68..85a182a 100644
--- a/tim/prune/gui/IconManager.java
+++ b/tim/prune/gui/IconManager.java
@@ -12,6 +12,10 @@ public abstract class IconManager
/** Icon for window */
public static final String WINDOW_ICON = "window_icon.png";
+ /** Icon for scalebar button on main map display */
+ public static final String SCALEBAR_BUTTON = "scalebar.gif";
+ /** Icon for map button on main map display when selected */
+ public static final String SCALEBAR_BUTTON_ON = "scalebar_on.gif";
/** Icon for map button on main map display */
public static final String MAP_BUTTON = "map_icon.gif";
/** Icon for map button on main map display when selected */
diff --git a/tim/prune/gui/MenuManager.java b/tim/prune/gui/MenuManager.java
index 7b256ba..cbf25af 100644
--- a/tim/prune/gui/MenuManager.java
+++ b/tim/prune/gui/MenuManager.java
@@ -4,7 +4,9 @@ import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
+
import javax.swing.JButton;
+import javax.swing.JCheckBoxMenuItem;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
@@ -12,10 +14,12 @@ import javax.swing.JToolBar;
import javax.swing.KeyStroke;
import tim.prune.App;
+import tim.prune.Config;
import tim.prune.DataSubscriber;
import tim.prune.FunctionLibrary;
import tim.prune.GenericFunction;
import tim.prune.I18nManager;
+import tim.prune.UpdateMessageBroker;
import tim.prune.data.PhotoList;
import tim.prune.data.Selection;
import tim.prune.data.Track;
@@ -54,14 +58,18 @@ public class MenuManager implements DataSubscriber
private JMenuItem _selectNoneItem = null;
private JMenuItem _selectStartItem = null;
private JMenuItem _selectEndItem = null;
+ private JMenuItem _findWaypointItem = null;
private JMenuItem _reverseItem = null;
private JMenuItem _addTimeOffsetItem = null;
+ private JMenuItem _addAltitudeOffsetItem = null;
private JMenuItem _mergeSegmentsItem = null;
private JMenu _rearrangeMenu = null;
private JMenuItem _cutAndMoveItem = null;
private JMenuItem _show3dItem = null;
private JMenu _browserMapMenu = null;
private JMenuItem _chartItem = null;
+ private JCheckBoxMenuItem _paceCheckbox = null;
+ private JMenuItem _getGpsiesItem = null;
private JMenuItem _distanceItem = null;
private JMenuItem _saveExifItem = null;
private JMenuItem _connectPhotoItem = null;
@@ -91,6 +99,14 @@ public class MenuManager implements DataSubscriber
private JButton _selectEndButton = null;
private JButton _connectPhotoButton = null;
+ /** Array of key events */
+ private static final int[] KEY_EVENTS = {
+ KeyEvent.VK_A, KeyEvent.VK_B, KeyEvent.VK_C, KeyEvent.VK_D, KeyEvent.VK_E,
+ KeyEvent.VK_F, KeyEvent.VK_G, KeyEvent.VK_H, KeyEvent.VK_I, KeyEvent.VK_J,
+ KeyEvent.VK_K, KeyEvent.VK_L, KeyEvent.VK_M, KeyEvent.VK_N, KeyEvent.VK_O,
+ KeyEvent.VK_P, KeyEvent.VK_Q, KeyEvent.VK_R, KeyEvent.VK_S, KeyEvent.VK_T,
+ KeyEvent.VK_U, KeyEvent.VK_V, KeyEvent.VK_W, KeyEvent.VK_X, KeyEvent.VK_Y, KeyEvent.VK_Z};
+
/**
* Constructor
@@ -114,9 +130,10 @@ public class MenuManager implements DataSubscriber
{
JMenuBar menubar = new JMenuBar();
JMenu fileMenu = new JMenu(I18nManager.getText("menu.file"));
+ setAltKey(fileMenu, "altkey.menu.file");
// Open file
JMenuItem openMenuItem = new JMenuItem(I18nManager.getText("menu.file.open"));
- openMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, InputEvent.CTRL_DOWN_MASK));
+ setShortcut(openMenuItem, "shortcut.menu.file.open");
_openFileAction = new ActionListener() {
public void actionPerformed(ActionEvent e)
{
@@ -138,26 +155,16 @@ public class MenuManager implements DataSubscriber
fileMenu.addSeparator();
// Load from GPS
JMenuItem loadFromGpsMenuItem = makeMenuItem(FunctionLibrary.FUNCTION_GPSLOAD);
- loadFromGpsMenuItem.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e)
- {
- FunctionLibrary.FUNCTION_GPSLOAD.begin();
- }
- });
+ setShortcut(loadFromGpsMenuItem, "shortcut.menu.file.load");
fileMenu.add(loadFromGpsMenuItem);
- // Save to GPS
+ // Send 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);
+ setShortcut(_saveItem, "shortcut.menu.file.save");
_saveAction = new ActionListener() {
public void actionPerformed(ActionEvent e)
{
@@ -169,32 +176,14 @@ public class MenuManager implements DataSubscriber
fileMenu.add(_saveItem);
// Export - Kml
_exportKmlItem = makeMenuItem(FunctionLibrary.FUNCTION_KMLEXPORT);
- _exportKmlItem.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e)
- {
- FunctionLibrary.FUNCTION_KMLEXPORT.begin();
- }
- });
_exportKmlItem.setEnabled(false);
fileMenu.add(_exportKmlItem);
// Gpx
_exportGpxItem = makeMenuItem(FunctionLibrary.FUNCTION_GPXEXPORT);
- _exportGpxItem.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e)
- {
- FunctionLibrary.FUNCTION_GPXEXPORT.begin();
- }
- });
_exportGpxItem.setEnabled(false);
fileMenu.add(_exportGpxItem);
// Pov
_exportPovItem = makeMenuItem(FunctionLibrary.FUNCTION_POVEXPORT);
- _exportPovItem.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e)
- {
- FunctionLibrary.FUNCTION_POVEXPORT.begin();
- }
- });
_exportPovItem.setEnabled(false);
fileMenu.add(_exportPovItem);
fileMenu.addSeparator();
@@ -209,8 +198,9 @@ public class MenuManager implements DataSubscriber
menubar.add(fileMenu);
// Edit menu
JMenu editMenu = new JMenu(I18nManager.getText("menu.edit"));
- editMenu.setMnemonic(KeyEvent.VK_E);
+ setAltKey(editMenu, "altkey.menu.edit");
_undoItem = new JMenuItem(I18nManager.getText("menu.edit.undo"));
+ setShortcut(_undoItem, "shortcut.menu.edit.undo");
_undoAction = new ActionListener() {
public void actionPerformed(ActionEvent e)
{
@@ -240,13 +230,7 @@ public class MenuManager implements DataSubscriber
_editPointItem.addActionListener(_editPointAction);
_editPointItem.setEnabled(false);
editMenu.add(_editPointItem);
- _editWaypointNameItem = new JMenuItem(I18nManager.getText("menu.edit.editwaypointname"));
- _editWaypointNameItem.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e)
- {
- _app.editCurrentPointName();
- }
- });
+ _editWaypointNameItem = makeMenuItem(FunctionLibrary.FUNCTION_EDIT_WAYPOINT_NAME);
_editWaypointNameItem.setEnabled(false);
editMenu.add(_editWaypointNameItem);
_deletePointItem = new JMenuItem(I18nManager.getText("menu.edit.deletepoint"));
@@ -271,12 +255,7 @@ public class MenuManager implements DataSubscriber
editMenu.add(_deleteRangeItem);
editMenu.addSeparator();
_compressItem = makeMenuItem(FunctionLibrary.FUNCTION_COMPRESS);
- _compressItem.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e)
- {
- FunctionLibrary.FUNCTION_COMPRESS.begin();
- }
- });
+ setShortcut(_compressItem, "shortcut.menu.edit.compress");
_compressItem.setEnabled(false);
editMenu.add(_compressItem);
_deleteMarkedPointsItem = new JMenuItem(I18nManager.getText("menu.edit.deletemarked"));
@@ -317,14 +296,11 @@ public class MenuManager implements DataSubscriber
_reverseItem.setEnabled(false);
editMenu.add(_reverseItem);
_addTimeOffsetItem = makeMenuItem(FunctionLibrary.FUNCTION_ADD_TIME_OFFSET);
- _addTimeOffsetItem.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e)
- {
- FunctionLibrary.FUNCTION_ADD_TIME_OFFSET.begin();
- }
- });
_addTimeOffsetItem.setEnabled(false);
editMenu.add(_addTimeOffsetItem);
+ _addAltitudeOffsetItem = makeMenuItem(FunctionLibrary.FUNCTION_ADD_ALTITUDE_OFFSET);
+ _addAltitudeOffsetItem.setEnabled(false);
+ editMenu.add(_addAltitudeOffsetItem);
_mergeSegmentsItem = new JMenuItem(I18nManager.getText("menu.edit.mergetracksegments"));
_mergeSegmentsItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
@@ -378,12 +354,14 @@ public class MenuManager implements DataSubscriber
// Select menu
JMenu selectMenu = new JMenu(I18nManager.getText("menu.select"));
+ setAltKey(selectMenu, "altkey.menu.select");
_selectAllItem = new JMenuItem(I18nManager.getText("menu.select.all"));
+ setShortcut(_selectAllItem, "shortcut.menu.select.all");
_selectAllItem.setEnabled(false);
_selectAllItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
- _app.selectAll();
+ _selection.selectRange(0, _track.getNumPoints()-1);
}
});
selectMenu.add(_selectAllItem);
@@ -417,17 +395,16 @@ public class MenuManager implements DataSubscriber
};
_selectEndItem.addActionListener(_selectEndAction);
selectMenu.add(_selectEndItem);
+ selectMenu.addSeparator();
+ _findWaypointItem = makeMenuItem(FunctionLibrary.FUNCTION_FIND_WAYPOINT);
+ _findWaypointItem.setEnabled(false);
+ selectMenu.add(_findWaypointItem);
menubar.add(selectMenu);
// Add view menu
JMenu viewMenu = new JMenu(I18nManager.getText("menu.view"));
+ setAltKey(viewMenu, "altkey.menu.view");
_show3dItem = makeMenuItem(FunctionLibrary.FUNCTION_3D);
- _show3dItem.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e)
- {
- FunctionLibrary.FUNCTION_3D.begin();
- }
- });
_show3dItem.setEnabled(false);
viewMenu.add(_show3dItem);
// browser submenu
@@ -468,35 +445,21 @@ public class MenuManager implements DataSubscriber
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);
+ // Get gpsies tracks
+ _getGpsiesItem = makeMenuItem(FunctionLibrary.FUNCTION_GET_GPSIES);
+ _getGpsiesItem.setEnabled(false);
+ viewMenu.add(_getGpsiesItem);
menubar.add(viewMenu);
// Add photo menu
JMenu photoMenu = new JMenu(I18nManager.getText("menu.photo"));
+ setAltKey(photoMenu, "altkey.menu.photo");
addPhotosMenuItem = new JMenuItem(I18nManager.getText("menu.file.addphotos"));
addPhotosMenuItem.addActionListener(_addPhotoAction);
photoMenu.add(addPhotosMenuItem);
@@ -542,41 +505,49 @@ public class MenuManager implements DataSubscriber
photoMenu.addSeparator();
// correlate all photos
_correlatePhotosItem = makeMenuItem(FunctionLibrary.FUNCTION_CORRELATE_PHOTOS);
- _correlatePhotosItem.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e)
- {
- FunctionLibrary.FUNCTION_CORRELATE_PHOTOS.begin();
- }
- });
_correlatePhotosItem.setEnabled(false);
photoMenu.add(_correlatePhotosItem);
menubar.add(photoMenu);
+ // Settings menu
+ JMenu settingsMenu = new JMenu(I18nManager.getText("menu.settings"));
+ setAltKey(settingsMenu, "altkey.menu.settings");
+ // Set the map background
+ JMenuItem mapBgItem = makeMenuItem(FunctionLibrary.FUNCTION_SET_MAP_BG);
+ settingsMenu.add(mapBgItem);
+ // Turn pace display on/off
+ _paceCheckbox = new JCheckBoxMenuItem(
+ I18nManager.getText("menu.settings.showpace"), false);
+ _paceCheckbox.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ Config.setConfigBoolean(Config.KEY_SHOW_PACE, _paceCheckbox.isSelected());
+ UpdateMessageBroker.informSubscribers();
+ }
+ });
+ settingsMenu.add(_paceCheckbox);
+ // Set kmz image size
+ JMenuItem setKmzImageSizeItem = makeMenuItem(FunctionLibrary.FUNCTION_SET_KMZ_IMAGE_SIZE);
+ settingsMenu.add(setKmzImageSizeItem);
+ // Set program paths
+ JMenuItem setPathsItem = makeMenuItem(FunctionLibrary.FUNCTION_SET_PATHS);
+ settingsMenu.add(setPathsItem);
+ settingsMenu.addSeparator();
+ // Save configuration
+ JMenuItem saveConfigMenuItem = makeMenuItem(FunctionLibrary.FUNCTION_SAVECONFIG);
+ settingsMenu.add(saveConfigMenuItem);
+ menubar.add(settingsMenu);
+
// Help menu
JMenu helpMenu = new JMenu(I18nManager.getText("menu.help"));
+ setAltKey(helpMenu, "altkey.menu.help");
JMenuItem helpItem = makeMenuItem(FunctionLibrary.FUNCTION_HELP);
- helpItem.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e)
- {
- FunctionLibrary.FUNCTION_HELP.begin();
- }
- });
+ setShortcut(helpItem, "shortcut.menu.help.help");
helpMenu.add(helpItem);
+ JMenuItem showKeysItem = makeMenuItem(FunctionLibrary.FUNCTION_SHOW_KEYS);
+ helpMenu.add(showKeysItem);
JMenuItem aboutItem = makeMenuItem(FunctionLibrary.FUNCTION_ABOUT);
- aboutItem.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e)
- {
- FunctionLibrary.FUNCTION_ABOUT.begin();
- }
- });
helpMenu.add(aboutItem);
JMenuItem checkVersionItem = makeMenuItem(FunctionLibrary.FUNCTION_CHECK_VERSION);
- checkVersionItem.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e)
- {
- FunctionLibrary.FUNCTION_CHECK_VERSION.begin();
- }
- });
helpMenu.add(checkVersionItem);
menubar.add(helpMenu);
@@ -590,7 +561,49 @@ public class MenuManager implements DataSubscriber
*/
private static JMenuItem makeMenuItem(GenericFunction inFunction)
{
- return new JMenuItem(I18nManager.getText(inFunction.getNameKey()));
+ JMenuItem item = new JMenuItem(I18nManager.getText(inFunction.getNameKey()));
+ item.addActionListener(new FunctionLauncher(inFunction));
+ return item;
+ }
+
+ /**
+ * Set the alt key for the given menu
+ * @param inMenu menu to set
+ * @param inKey key to lookup to get language-sensitive altkey
+ */
+ private static void setAltKey(JMenu inMenu, String inKey)
+ {
+ // Lookup the key in the properties
+ String altKey = I18nManager.getText(inKey);
+ if (altKey != null && altKey.length() == 1)
+ {
+ int code = altKey.charAt(0) - 'A';
+ if (code >= 0 && code < 26)
+ {
+ // Found a valid code between A and Z
+ inMenu.setMnemonic(KEY_EVENTS[code]);
+ }
+ }
+ }
+
+ /**
+ * Set the shortcut key for the given menu item
+ * @param inMenuItem menu item to set
+ * @param inKey key to lookup to get language-sensitive shortcut
+ */
+ private static void setShortcut(JMenuItem inMenuItem, String inKey)
+ {
+ // Lookup the key in the properties
+ String altKey = I18nManager.getText(inKey);
+ if (altKey != null && altKey.length() == 1)
+ {
+ int code = altKey.charAt(0) - 'A';
+ if (code >= 0 && code < 26)
+ {
+ // Found a valid code between A and Z
+ inMenuItem.setAccelerator(KeyStroke.getKeyStroke(KEY_EVENTS[code], InputEvent.CTRL_DOWN_MASK));
+ }
+ }
}
/**
@@ -691,13 +704,15 @@ public class MenuManager implements DataSubscriber
_exportPovItem.setEnabled(hasData);
_compressItem.setEnabled(hasData);
_deleteMarkedPointsItem.setEnabled(hasData && _track.hasMarkedPoints());
- _rearrangeMenu.setEnabled(hasData && _track.hasMixedData());
+ _rearrangeMenu.setEnabled(hasData && _track.hasTrackPoints() && _track.hasWaypoints());
_selectAllItem.setEnabled(hasData);
_selectNoneItem.setEnabled(hasData);
_show3dItem.setEnabled(hasData);
_chartItem.setEnabled(hasData);
_browserMapMenu.setEnabled(hasData);
_distanceItem.setEnabled(hasData);
+ _getGpsiesItem.setEnabled(hasData);
+ _findWaypointItem.setEnabled(hasData && _track.hasWaypoints());
// is undo available?
boolean hasUndo = !_app.getUndoStack().isEmpty();
_undoItem.setEnabled(hasUndo);
@@ -738,6 +753,7 @@ public class MenuManager implements DataSubscriber
_mergeSegmentsItem.setEnabled(hasRange);
_reverseItem.setEnabled(hasRange);
_addTimeOffsetItem.setEnabled(hasRange);
+ _addAltitudeOffsetItem.setEnabled(hasRange);
// Is the currently selected point outside the current range?
_cutAndMoveItem.setEnabled(hasRange && hasPoint &&
(_selection.getCurrentPointIndex() < _selection.getStart()
diff --git a/tim/prune/gui/ProfileChart.java b/tim/prune/gui/ProfileChart.java
index a0adfdb..f7ae105 100644
--- a/tim/prune/gui/ProfileChart.java
+++ b/tim/prune/gui/ProfileChart.java
@@ -20,6 +20,7 @@ public class ProfileChart extends GenericChart
private static final int[] ALTITUDE_SCALES = {10000, 5000, 2000, 1000, 500, 200, 100, 50};
private static final Color COLOR_LINES = Color.GRAY;
private static final Color COLOR_ALT_BARS = Color.BLUE;
+ private static final Color COLOR_CURR_RANGE = Color.GREEN;
private static final Color COLOR_SELECTED = Color.RED;
private static final Color COLOR_SELECTED_BG = Color.ORANGE;
private static final Color COLOR_ALT_SCALE = Color.RED;
@@ -48,13 +49,9 @@ public class ProfileChart extends GenericChart
{
int width = getWidth();
int height = getHeight();
- AltitudeRange altitudeRange = _track.getAltitudeRange();
- int minAltitude = altitudeRange.getMinimum();
- int maxAltitude = altitudeRange.getMaximum();
// message if no altitudes in track
- if (minAltitude < 0 || maxAltitude < 0
- || minAltitude == maxAltitude)
+ if (!_track.hasAltitudeData())
{
g.setColor(COLOR_LINES);
g.drawString(I18nManager.getText("display.noaltitudes"), 50, height/2);
@@ -62,12 +59,20 @@ public class ProfileChart extends GenericChart
}
// altitude profile
+ AltitudeRange altitudeRange = _track.getAltitudeRange();
+ int minAltitude = altitudeRange.getMinimum();
+ int maxAltitude = altitudeRange.getMaximum();
int numPoints = _track.getNumPoints();
_xScaleFactor = 1.0 * (width - 2 * BORDER_WIDTH) / numPoints;
- double yScaleFactor = 1.0 * (height - 2 * BORDER_WIDTH) /
- (altitudeRange.getMaximum() - minAltitude);
+ double yScaleFactor = 1.0 * (height - 2 * BORDER_WIDTH) / (maxAltitude - minAltitude);
int barWidth = (int) (_xScaleFactor + 1.0);
int selectedPoint = _trackInfo.getSelection().getCurrentPointIndex();
+ // selection start, end
+ int selectionStart = -1, selectionEnd = -1;
+ if (_trackInfo.getSelection().hasRangeSelected()) {
+ selectionStart = _trackInfo.getSelection().getStart();
+ selectionEnd = _trackInfo.getSelection().getEnd();
+ }
// horizontal lines for scale - set to round numbers eg 500m
int lineScale = getLineScale(minAltitude, maxAltitude);
@@ -103,6 +108,9 @@ public class ProfileChart extends GenericChart
else
{
g.setColor(COLOR_ALT_BARS);
+ if (p >= selectionStart && p <= selectionEnd) {
+ g.setColor(COLOR_CURR_RANGE);
+ }
}
if (_track.getPoint(p).getAltitude().isValid())
{
@@ -209,7 +217,7 @@ public class ProfileChart extends GenericChart
{
// work out which data point is nearest and select it
int pointNum = (int) ((e.getX() - BORDER_WIDTH) / _xScaleFactor);
- _trackInfo.getSelection().selectPoint(pointNum);
+ _trackInfo.selectPoint(pointNum);
}
}
}
diff --git a/tim/prune/gui/SelectorDisplay.java b/tim/prune/gui/SelectorDisplay.java
index 28e0a95..48a5ac4 100644
--- a/tim/prune/gui/SelectorDisplay.java
+++ b/tim/prune/gui/SelectorDisplay.java
@@ -22,8 +22,6 @@ import javax.swing.event.ListSelectionListener;
import tim.prune.DataSubscriber;
import tim.prune.I18nManager;
-import tim.prune.data.DataPoint;
-import tim.prune.data.Photo;
import tim.prune.data.TrackInfo;
/**
@@ -117,7 +115,9 @@ public class SelectorDisplay extends GenericDisplay
_photoList.addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e)
{
- if (!e.getValueIsAdjusting()) selectPhoto(_photoList.getSelectedIndex());
+ if (!e.getValueIsAdjusting()) {
+ selectPhoto(_photoList.getSelectedIndex());
+ }
}});
JPanel photoListPanel = new JPanel();
photoListPanel.setLayout(new BorderLayout());
@@ -149,7 +149,7 @@ public class SelectorDisplay extends GenericDisplay
{
if (_track != null && !_ignoreScrollEvents)
{
- _trackInfo.getSelection().selectPoint(inValue);
+ _trackInfo.selectPoint(inValue);
}
}
@@ -217,7 +217,7 @@ public class SelectorDisplay extends GenericDisplay
}
else
{
- _scroller.setMaximum(_track.getNumPoints() + SCROLLBAR_INTERVAL);
+ _scroller.setMaximum(_track.getNumPoints() -1 + SCROLLBAR_INTERVAL);
if (currentPointIndex >= 0)
_scroller.setValue(currentPointIndex);
_scroller.setEnabled(true);
@@ -246,23 +246,20 @@ public class SelectorDisplay extends GenericDisplay
_waypointList.clearSelection();
}
}
- // Do the same for the photos
- if (_photoList.getSelectedIndex() >= 0)
+ // Make sure correct photo is selected
+ if (_photoListModel.getSize() > 0)
{
- DataPoint trackPoint = _trackInfo.getCurrentPoint();
- Photo selectedPhoto = _photoListModel.getPhoto(_photoList.getSelectedIndex());
- // Get selected Photo, if it's still there
- DataPoint photoPoint = null;
- if (selectedPhoto != null) {
- photoPoint = _photoListModel.getPhoto(_photoList.getSelectedIndex()).getDataPoint();
- }
- // Compare selected photo with selected point
- if ( (photoPoint != null && (trackPoint == null || !photoPoint.equals(trackPoint)))
- || (_trackInfo.getSelection().getCurrentPhotoIndex() < 0) )
+ int photoIndex = _trackInfo.getSelection().getCurrentPhotoIndex();
+ int listSelection = _photoList.getSelectedIndex();
+ // Change listbox selection if indexes not equal
+ if (listSelection != photoIndex)
{
- // photo is selected in list but different from current point - deselect
- _photoList.clearSelection();
- _trackInfo.getSelection().deselectPhoto();
+ if (photoIndex < 0) {
+ _photoList.clearSelection();
+ }
+ else {
+ _photoList.setSelectedIndex(photoIndex);
+ }
}
}
}
diff --git a/tim/prune/gui/Viewport.java b/tim/prune/gui/Viewport.java
new file mode 100644
index 0000000..25eba2f
--- /dev/null
+++ b/tim/prune/gui/Viewport.java
@@ -0,0 +1,43 @@
+package tim.prune.gui;
+
+import tim.prune.gui.map.MapCanvas;
+import tim.prune.gui.map.MapPosition;
+import tim.prune.gui.map.MapUtils;
+
+/**
+ * Class to provide access to current viewport
+ * The point of this class is to decouple the view from the MapCanvas object
+ * so that when the GetGpsies function needs to know the area currently viewed, it doesn't
+ * need to have a direct connection to the MapCanvas. Instead it asks the App for the viewport,
+ * which is then able to get the map position from the MapCanvas.
+ * I'm still not sure whether this is ugly or not, but it's more efficient than constantly listening.
+ */
+public class Viewport
+{
+ /** Map canvas object */
+ private MapCanvas _mapCanvas = null;
+
+ /**
+ * Constructor
+ * @param inCanvas map canvas object
+ */
+ public Viewport(MapCanvas inCanvas)
+ {
+ _mapCanvas = inCanvas;
+ }
+
+ /**
+ * @return coordinate bounds of current viewport
+ */
+ public double[] getBounds()
+ {
+ int width = _mapCanvas.getWidth();
+ int height = _mapCanvas.getHeight();
+ MapPosition mapPosition = _mapCanvas.getMapPosition();
+ double minLat = MapUtils.getLatitudeFromY(mapPosition.getYFromPixels(height, height));
+ double maxLat = MapUtils.getLatitudeFromY(mapPosition.getYFromPixels(0, height));
+ double minLon = MapUtils.getLongitudeFromX(mapPosition.getXFromPixels(0, width));
+ double maxLon = MapUtils.getLongitudeFromX(mapPosition.getXFromPixels(width, width));
+ return new double[] {minLat, minLon, maxLat, maxLon};
+ }
+}
diff --git a/tim/prune/gui/WaypointNameMatcher.java b/tim/prune/gui/WaypointNameMatcher.java
new file mode 100644
index 0000000..db0f827
--- /dev/null
+++ b/tim/prune/gui/WaypointNameMatcher.java
@@ -0,0 +1,98 @@
+package tim.prune.gui;
+
+import java.util.ArrayList;
+import javax.swing.AbstractListModel;
+
+import tim.prune.data.DataPoint;
+import tim.prune.data.Track;
+
+/**
+ * Class to deal with the matching of waypoint names
+ * and the representation in a list
+ */
+public class WaypointNameMatcher extends AbstractListModel
+{
+ private ArrayList _waypoints = null;
+ private int _numPoints = 0;
+ private String[] _waypointNames = null;
+ private ArrayList _matches = null;
+
+
+ /**
+ * Initialisation giving Track object
+ * @param inTrack Track object
+ */
+ public void init(Track inTrack)
+ {
+ // Get list of waypoints from track
+ _waypoints = new ArrayList();
+ inTrack.getWaypoints(_waypoints);
+ // Initialise match flags and waypoint names
+ _numPoints = _waypoints.size();
+ _waypointNames = new String[_numPoints];
+ for (int i=0; i<_numPoints; i++) {
+ _waypointNames[i] = _waypoints.get(i).getWaypointName().toLowerCase();
+ }
+ _matches = new ArrayList();
+ findMatches(null);
+ }
+
+ /**
+ * Search for the given term and collect the matches
+ * @param inSearch string to search for
+ */
+ public void findMatches(String inSearch)
+ {
+ // Reset array
+ _matches.clear();
+ // Convert search to lower case to match name array
+ String search = null;
+ if (inSearch != null && !inSearch.equals("")) {
+ search = inSearch.toLowerCase();
+ }
+ // Loop through waypoint names
+ for (int i=0; i<_numPoints; i++)
+ {
+ if (search == null || _waypointNames[i].indexOf(search) >= 0)
+ {
+ _matches.add(_waypoints.get(i));
+ }
+ }
+ fireChanged();
+ }
+
+ /**
+ * @see javax.swing.ListModel#getSize()
+ */
+ public int getSize()
+ {
+ if (_numPoints == 0) return 0;
+ return _matches.size();
+ }
+
+ /**
+ * @see javax.swing.ListModel#getElementAt(int)
+ */
+ public Object getElementAt(int inIndex)
+ {
+ return _matches.get(inIndex).getWaypointName();
+ }
+
+ /**
+ * Get the waypoint at the given index
+ * @param inIndex index number, starting at 0
+ * @return DataPoint object
+ */
+ public DataPoint getWaypoint(int inIndex)
+ {
+ return _matches.get(inIndex);
+ }
+
+ /**
+ * Fire event to notify that contents have changed
+ */
+ public void fireChanged()
+ {
+ this.fireContentsChanged(this, 0, getSize()-1);
+ }
+}
diff --git a/tim/prune/gui/WholeNumberField.java b/tim/prune/gui/WholeNumberField.java
index 9a35280..09f676d 100644
--- a/tim/prune/gui/WholeNumberField.java
+++ b/tim/prune/gui/WholeNumberField.java
@@ -69,6 +69,14 @@ public class WholeNumberField extends JTextField
return parseValue(getText());
}
+ /**
+ * @param inValue value to set
+ */
+ public void setValue(int inValue)
+ {
+ setText("" + inValue);
+ }
+
/**
* @param inText text to parse
* @return value as integer
diff --git a/tim/prune/gui/images/scalebar.gif b/tim/prune/gui/images/scalebar.gif
new file mode 100644
index 0000000000000000000000000000000000000000..99b74f4e2643e2600b5423acb6310c9da630fea0
GIT binary patch
literal 92
zcmZ?wbhEHb6krfwSjYeZ|Ns97(+r9~Ss1w(m>6_GT#!5ilkSxMm8ajnZzvIJVF+Or
nkI4)PXXr^TWn8v%ZCa{C!_K2-0wLe>JpS?@4fUw(l7KsEE1Him<_H>_EbJmxLBDe+}dh#Mn=
FH2@@HAzlCg
literal 0
HcmV?d00001
diff --git a/tim/prune/gui/map/MapCanvas.java b/tim/prune/gui/map/MapCanvas.java
index a8df86e..2af4ae8 100644
--- a/tim/prune/gui/map/MapCanvas.java
+++ b/tim/prune/gui/map/MapCanvas.java
@@ -53,6 +53,8 @@ public class MapCanvas extends JPanel implements MouseListener, MouseMotionListe
private App _app = null;
/** Track object */
private Track _track = null;
+ /** TrackInfo object */
+ private TrackInfo _trackInfo = null;
/** Selection object */
private Selection _selection = null;
/** Previously selected point */
@@ -63,6 +65,8 @@ public class MapCanvas extends JPanel implements MouseListener, MouseMotionListe
private BufferedImage _mapImage = null;
/** Slider for transparency */
private JSlider _transparencySlider = null;
+ /** Checkbox for scale bar */
+ private JCheckBox _scaleCheckBox = null;
/** Checkbox for maps */
private JCheckBox _mapCheckBox = null;
/** Checkbox for autopan */
@@ -75,6 +79,8 @@ public class MapCanvas extends JPanel implements MouseListener, MouseMotionListe
private JPanel _topPanel = null;
/** Side component panel */
private JPanel _sidePanel = null;
+ /** Scale bar */
+ private ScaleBar _scaleBar = null;
/* Data */
private DoubleRange _latRange = null, _lonRange = null;
private DoubleRange _xRange = null, _yRange = null;
@@ -126,6 +132,7 @@ public class MapCanvas extends JPanel implements MouseListener, MouseMotionListe
public MapCanvas(App inApp, TrackInfo inTrackInfo)
{
_app = inApp;
+ _trackInfo = inTrackInfo;
_track = inTrackInfo.getTrack();
_selection = inTrackInfo.getSelection();
_mapPosition = new MapPosition();
@@ -169,6 +176,18 @@ public class MapCanvas extends JPanel implements MouseListener, MouseMotionListe
});
_transparencySlider.setFocusable(false); // stop slider from stealing keyboard focus
_topPanel.add(_transparencySlider);
+ // Add checkbox button for enabling scale bar
+ _scaleCheckBox = new JCheckBox(IconManager.getImageIcon(IconManager.SCALEBAR_BUTTON), true);
+ _scaleCheckBox.setSelectedIcon(IconManager.getImageIcon(IconManager.SCALEBAR_BUTTON_ON));
+ _scaleCheckBox.setOpaque(false);
+ _scaleCheckBox.setToolTipText(I18nManager.getText("menu.map.showscalebar"));
+ _scaleCheckBox.addItemListener(new ItemListener() {
+ public void itemStateChanged(ItemEvent e) {
+ _scaleBar.setVisible(_scaleCheckBox.isSelected());
+ }
+ });
+ _scaleCheckBox.setFocusable(false); // stop button from stealing keyboard focus
+ _topPanel.add(_scaleCheckBox);
// Add checkbox button for enabling maps or not
_mapCheckBox = new JCheckBox(IconManager.getImageIcon(IconManager.MAP_BUTTON), false);
_mapCheckBox.setSelectedIcon(IconManager.getImageIcon(IconManager.MAP_BUTTON_ON));
@@ -223,12 +242,16 @@ public class MapCanvas extends JPanel implements MouseListener, MouseMotionListe
zoomOutButton.setFocusable(false); // stop button from stealing keyboard focus
_sidePanel.add(zoomOutButton);
+ // Bottom panel for scale bar
+ _scaleBar = new ScaleBar();
+
// add control panels to this one
setLayout(new BorderLayout());
_topPanel.setVisible(false);
_sidePanel.setVisible(false);
add(_topPanel, BorderLayout.NORTH);
add(_sidePanel, BorderLayout.WEST);
+ add(_scaleBar, BorderLayout.SOUTH);
// Make popup menu
makePopup();
}
@@ -347,8 +370,10 @@ public class MapCanvas extends JPanel implements MouseListener, MouseMotionListe
}
// Draw the mapImage if necessary
- if ((_mapImage == null || _recalculate)) {
+ if ((_mapImage == null || _recalculate))
+ {
getMapTiles();
+ _scaleBar.updateScale(_mapPosition.getZoom(), _mapPosition.getCentreTileY());
}
// Draw the prepared image onto the panel
if (_mapImage != null) {
@@ -370,6 +395,7 @@ public class MapCanvas extends JPanel implements MouseListener, MouseMotionListe
inG.fillRect(0, 0, getWidth(), getHeight());
inG.setColor(COLOR_MESSAGES);
inG.drawString(I18nManager.getText("display.nodata"), 50, getHeight()/2);
+ _scaleBar.updateScale(-1, 0);
}
// Draw slider etc on top
paintChildren(inG);
@@ -430,7 +456,8 @@ public class MapCanvas extends JPanel implements MouseListener, MouseMotionListe
// 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) {
+ 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);
@@ -740,7 +767,7 @@ public class MapCanvas extends JPanel implements MouseListener, MouseMotionListe
_mapPosition.getXFromPixels(inE.getX(), getWidth()),
_mapPosition.getYFromPixels(inE.getY(), getHeight()),
_mapPosition.getBoundsFromPixels(CLICK_SENSITIVITY), false);
- _selection.selectPoint(pointIndex);
+ _trackInfo.selectPoint(pointIndex);
}
else
{
@@ -876,6 +903,7 @@ public class MapCanvas extends JPanel implements MouseListener, MouseMotionListe
public void keyPressed(KeyEvent inE)
{
int code = inE.getKeyCode();
+ int currPointIndex = _selection.getCurrentPointIndex();
// Check for meta key
if (inE.isControlDown())
{
@@ -885,10 +913,10 @@ public class MapCanvas extends JPanel implements MouseListener, MouseMotionListe
else if (code == KeyEvent.VK_DOWN)
zoomOut();
// Key nav for next/prev point
- else if (code == KeyEvent.VK_LEFT)
- _selection.selectPreviousPoint();
+ else if (code == KeyEvent.VK_LEFT && currPointIndex > 0)
+ _trackInfo.selectPoint(currPointIndex-1);
else if (code == KeyEvent.VK_RIGHT)
- _selection.selectNextPoint();
+ _trackInfo.selectPoint(currPointIndex+1);
}
else
{
@@ -905,7 +933,7 @@ public class MapCanvas extends JPanel implements MouseListener, MouseMotionListe
rightwardsPan = -PAN_DISTANCE;
panMap(rightwardsPan, upwardsPan);
// Check for delete key to delete current point
- if (code == KeyEvent.VK_DELETE && _selection.getCurrentPointIndex() >= 0)
+ if (code == KeyEvent.VK_DELETE && currPointIndex >= 0)
{
_app.deleteCurrentPoint();
}
@@ -939,4 +967,12 @@ public class MapCanvas extends JPanel implements MouseListener, MouseMotionListe
else if (clicks > 0)
zoomOut();
}
+
+ /**
+ * @return current map position
+ */
+ public MapPosition getMapPosition()
+ {
+ return _mapPosition;
+ }
}
diff --git a/tim/prune/gui/map/MapTileCacher.java b/tim/prune/gui/map/MapTileCacher.java
index ea5b6fb..366e1ad 100644
--- a/tim/prune/gui/map/MapTileCacher.java
+++ b/tim/prune/gui/map/MapTileCacher.java
@@ -30,7 +30,7 @@ public class MapTileCacher implements ImageObserver
private MapTileConfig _tileConfig = null;
/** Grid size */
- private static final int GRID_SIZE = 11;
+ private static final int GRID_SIZE = 15;
/** max zoom level of map tiles */
private static final int MAX_TILE_ZOOM = 18;
@@ -52,7 +52,10 @@ public class MapTileCacher implements ImageObserver
*/
public void centreMap(int inZoom, int inTileX, int inTileY)
{
- if (inZoom != _zoom)
+ int shift = Math.max(Math.abs(inTileX-_tileX), Math.abs(inTileY - _tileY));
+ if (shift == 0) {return;}
+ // Clear cache if either zoom has changed or map has jumped too far
+ if (inZoom != _zoom || shift > GRID_SIZE/2)
{
_zoom = inZoom;
clearAll();
diff --git a/tim/prune/gui/map/MapTileConfig.java b/tim/prune/gui/map/MapTileConfig.java
index 762baf4..1f9c387 100644
--- a/tim/prune/gui/map/MapTileConfig.java
+++ b/tim/prune/gui/map/MapTileConfig.java
@@ -31,8 +31,8 @@ public class MapTileConfig
*/
public MapTileConfig()
{
- _index = Config.getMapServerIndex();
- _url = fixUrl(Config.getMapServerUrl());
+ _index = Config.getConfigInt(Config.KEY_MAPSERVERINDEX);
+ _url = fixUrl(Config.getConfigString(Config.KEY_MAPSERVERURL));
// 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)))
diff --git a/tim/prune/gui/map/ScaleBar.java b/tim/prune/gui/map/ScaleBar.java
new file mode 100644
index 0000000..0f65db9
--- /dev/null
+++ b/tim/prune/gui/map/ScaleBar.java
@@ -0,0 +1,111 @@
+package tim.prune.gui.map;
+
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Graphics;
+import javax.swing.JPanel;
+
+import tim.prune.Config;
+import tim.prune.I18nManager;
+
+/**
+ * Class to show a scale bar on the main map of Prune
+ */
+public class ScaleBar extends JPanel
+{
+ /** zoom level */
+ private int _zoomLevel = -1;
+ /** y tile number */
+ private int _yTile = -1;
+
+ // Dimensions
+ /** Offset from left side in pixels */
+ private static final int LEFT_OFFSET = 20;
+ /** Offset from top in pixels */
+ private static final int Y_OFFSET = 10;
+ /** Tick height in pixels */
+ private static final int TICK_HEIGHT = 5;
+ /** Margin between bar and end text in pixels */
+ private static final int MARGIN_WIDTH = 8;
+
+ /** metric scales for each zoom level */
+ private static final int[] _metricScales = {10000, 5000, 2000, 2000, 1000, 500, 200, 100,
+ 50, 20, 10, 5, 2, 2, 1, -2, -5, -10, -20, -50, -100, -200};
+ /** pixel counts for each zoom level (metric) */
+ private static final int[] _metricPixels = {64, 64, 51, 102, 102, 102, 81, 81,
+ 81, 65, 65, 65, 52, 105, 105, 105, 83, 83, 83, 67, 67, 67};
+ /** imperial scales for each zoom level (num miles) */
+ private static final int[] _mileScales = {10000, 10000, 5000, 2000, 2000, 1000, 500, 200,
+ 100, 50, 20, 10, 5, 2, 1, -2, -2, -5, -10, -20, -50, -100};
+ /** pixel counts for each zoom level (miles) */
+ private static final int[] _milePixels = {79, 79, 79, 64, 127, 127, 127, 102,
+ 102, 102, 81, 81, 81, 65, 65, 65, 130, 104, 104, 104, 104, 83, 83};
+
+
+ /**
+ * Constructor
+ */
+ public ScaleBar()
+ {
+ super();
+ setOpaque(false);
+ setPreferredSize(new Dimension(100, 20));
+ }
+
+ /**
+ * Paint method to override display
+ * @param inG graphics object
+ */
+ public void paint(Graphics inG)
+ {
+ super.paint(inG);
+ if (_zoomLevel > -1)
+ {
+ try {
+ boolean useMetric = Config.getConfigBoolean(Config.KEY_METRIC_UNITS);
+ int rightSide = LEFT_OFFSET + (useMetric?_metricPixels[_zoomLevel]:_milePixels[_zoomLevel]);
+ int scale = (useMetric?_metricScales[_zoomLevel]:_mileScales[_zoomLevel]);
+
+ // work out cos(latitude) from y tile and zoom, and apply to scale
+ final double n = Math.pow(2, _zoomLevel);
+ final double angle = Math.PI * (1 - 2.0*_yTile/n);
+ final double lat = Math.atan(Math.sinh(angle));
+ final double cosLat = Math.cos(lat);
+ rightSide = (int) (rightSide / cosLat);
+ // Adjust if scale is too large
+ while (rightSide > 300)
+ {
+ rightSide /= 2;
+ scale /= 2;
+ // Abort if scale is now less than 1 unit (shouldn't ever be)
+ if (scale < 1) {return;}
+ }
+
+ // horizontal
+ inG.setColor(Color.BLACK);
+ inG.drawLine(LEFT_OFFSET, Y_OFFSET, rightSide, Y_OFFSET);
+ inG.drawLine(LEFT_OFFSET, Y_OFFSET+1, rightSide, Y_OFFSET+1);
+ // 0 tick
+ inG.drawLine(LEFT_OFFSET, Y_OFFSET, LEFT_OFFSET, Y_OFFSET-TICK_HEIGHT);
+ inG.drawLine(LEFT_OFFSET+1, Y_OFFSET, LEFT_OFFSET+1, Y_OFFSET-TICK_HEIGHT);
+ // end tick
+ inG.drawLine(rightSide, Y_OFFSET, rightSide, Y_OFFSET-TICK_HEIGHT);
+ inG.drawLine(rightSide+1, Y_OFFSET, rightSide+1, Y_OFFSET-TICK_HEIGHT);
+ // text
+ String text = (scale>0?(""+scale):("1/"+(-scale))) + " " + I18nManager.getText(useMetric?"units.kilometres.short":"units.miles.short");
+ inG.drawString(text, rightSide+MARGIN_WIDTH, Y_OFFSET);
+ }
+ catch (ArrayIndexOutOfBoundsException ai) {}
+ }
+ }
+
+ /**
+ * Update the scale level
+ * @param inZoom new zoom level
+ */
+ public void updateScale(int inZoom, int inYtile)
+ {
+ _zoomLevel = inZoom;
+ _yTile = inYtile;
+ }
+}
diff --git a/tim/prune/lang/prune-texts_af.properties b/tim/prune/lang/prune-texts_af.properties
new file mode 100644
index 0000000..42875f6
--- /dev/null
+++ b/tim/prune/lang/prune-texts_af.properties
@@ -0,0 +1,154 @@
+# Text entries for the Prune application
+# Afrikaans entries as extra
+
+# Menu entries
+menu.file=L\u00eaer
+menu.file.open=Open L\u00eaer
+menu.file.addphotos=Voeg Fotos By
+menu.file.save=Stoor
+menu.file.exit=Gaan Uit
+menu.edit=Redigeer
+menu.edit.undo=Herroep
+menu.edit.clearundo=Herroep Lys Skoonmaak
+menu.edit.editpoint=Redigeer Punt
+menu.edit.deletepoint=Punt Uitvee
+menu.edit.deleterange=Reeks Uitvee
+menu.edit.deletemarked=Gemerkde Punt Uitvee
+menu.edit.interpolate=Interpoleer
+menu.edit.average=Gemiddelde Seleksie
+menu.edit.reverse=Reeks Omkeer
+menu.edit.mergetracksegments=Saamvoeg van spoor segmente
+menu.edit.rearrange=Herrangskik bakens
+menu.edit.rearrange.start=Bakens na begin van l\u00eaer
+menu.edit.rearrange.end=Bakens na einde van l\u00eaer
+menu.edit.rearrange.nearest=Beweeg elk na naaste spoor punt
+menu.edit.cutandmove=Sny en skuif seleksie
+menu.select=Selekteer
+menu.select.all=Selekteer Alles
+menu.select.none=Selekteer Niks
+menu.select.start=Stel Reeks Begin
+menu.select.end=Stel Reeks Einde
+menu.photo=Foto
+menu.photo.saveexif=Stoor na EXIF
+menu.photo.connect=Las foto by huidige punt
+menu.photo.disconnect=Ontkoppel foto vanaf huidige punt
+menu.photo.delete=Verwyder foto
+menu.view=Kyk
+menu.view.browser=Kaart in werf blaaier
+menu.view.browser.google=Google Kaarte
+menu.view.browser.openstreetmap=Openstreetmap
+menu.view.browser.mapquest=Mapquest
+menu.view.browser.yahoo=Yahoo Kaarte
+menu.help=Hulp
+# Popup menu for map
+menu.map.zoomin=Zoom in
+menu.map.zoomout=Zoom uit
+menu.map.zoomfull=Zoom na vol skaal
+menu.map.newpoint=Skep nuwe punt
+menu.map.connect=Connekteer baan punte
+menu.map.autopan=Automatiese Skuif van Kyk Venster
+menu.map.showmap=Wys Kaart
+
+# Functions
+function.loadfromgps=Laai van GPS data
+function.sendtogps=Stuur van GPS data
+function.exportkml=KML Uitvoer
+function.exportgpx=GPS Uitvoer
+function.exportpov=POV Uitvoer
+function.editwaypointname=Redigeer Baken Naam
+function.compress=Kompakteer spoor
+function.addtimeoffset=Voeg tyd spruit by
+function.findwaypoint=Vind Baken
+function.charts=Grafieke
+function.show3d=3D Kyk
+function.distances=Afstande
+function.setmapbg=Stel Kaart agtergrond
+function.getgpsies=Kry GPS spore
+function.correlatephotos=Korreleer Fotos
+function.help=Hulp
+function.showkeys=Wys Kortpad sleutels
+function.about=Omtrent Prune
+function.checkversion=Kyk vir nuwe weergawe
+function.saveconfig=Stoor Stellings
+
+# Dialogs
+dialog.exit.confirm.title=Uitgaan uit Prune
+dialog.exit.confirm.text=Jou data is nie gestoor nie. Is jy seker jy wil uitgaan?
+dialog.openappend.title=Voegby tot bestaande data
+dialog.openappend.text=Voeg hierdie data by die data wat alreeds gelaai is?
+dialog.deletepoint.title=Vee punt uit
+dialog.deletepoint.deletephoto=Vee aangehegde foto van die punt uit?
+dialog.deletephoto.title=Vee foto uit
+dialog.deletephoto.deletepoint=Vee punt uit wat aan hierdie foto geheg is?
+dialog.openoptions.title=Oopmaak Opsies
+dialog.openoptions.filesnippet=Ekstrak vanuit L\u00eaer
+dialog.load.table.field=Veld
+dialog.load.table.datatype=Data Tipe
+dialog.load.table.description=Beskrywing
+dialog.delimiter.label=Veld Skeinding Karakter
+dialog.delimiter.comma=Komma ,
+dialog.delimiter.tab=Tab
+dialog.delimiter.space=Spasie
+dialog.delimiter.semicolon=Komma Punt ;
+dialog.delimiter.other=Ander
+dialog.openoptions.deliminfo.records=Rekords, met
+dialog.openoptions.deliminfo.fields=velde
+dialog.openoptions.deliminfo.norecords=Geen rekords
+dialog.openoptions.altitudeunits=Hoogte Eenhede
+dialog.jpegload.subdirectories=Sluit sub-gidse in
+dialog.jpegload.loadjpegswithoutcoords=Sluit fotos sonder koordinate in
+dialog.jpegload.loadjpegsoutsidearea=Sluit foto buitekant huidige area in
+dialog.jpegload.progress.title=Fotos Laai
+dialog.jpegload.progress=Wag asseblief terwyl fotos gesoek word
+dialog.gpsload.nogpsbabel=Geen gpsbabel program kon gevind word. Gaanvoort?
+dialog.gpsload.device=Apparaat naam
+dialog.gpsload.format=Formaat
+dialog.gpsload.getwaypoints=Laai Bakens
+dialog.gpsload.gettracks=Laai spore
+dialog.gpssend.sendwaypoints=Stuur Bakens
+dialog.gpssend.sendtracks=Stuur Spore
+dialog.gpssend.trackname=Spoor name
+dialog.saveoptions.title=Stoor L\u00eaer
+dialog.save.fieldstosave=Velde om te stoor
+dialog.save.table.field=Veld
+dialog.save.table.hasdata=Het Data
+dialog.save.table.save=Stoor
+dialog.save.headerrow=Hoof Afvoer Ry
+dialog.save.coordinateunits=Koordinaat eenhede
+dialog.save.altitudeunits=Hoogte Eenhede
+dialog.save.timestampformat=Tyd Stempel Formaat
+dialog.save.overwrite.title=L\u00eaer bestaan reeds
+dialog.save.overwrite.text=Hierdie L\u00eaer bestaan reeds. Is jy seker jy wil die l\u00eaer oorskryf?
+dialog.exportkml.text=Titel vir die data
+dialog.exportkml.altitude=Absolute hoogte (vir aviasie)
+dialog.exportkml.kmz=Kompakteer om kmz l\u00eaer te maak
+dialog.exportkml.exportimages=Voer beeld duimnaelsketse uit na kmz
+dialog.exportgpx.name=Naam
+dialog.exportgpx.desc=Beskrywing
+dialog.exportgpx.includetimestamps=Tydstempel Insluit
+dialog.exportpov.text=Steutel asseblief parameters in vir POV uitvoer
+dialog.exportpov.font=Font
+dialog.exportpov.camerax=Kamera X
+dialog.exportpov.cameray=Kamera Y
+dialog.exportpov.cameraz=Kamera Z
+dialog.exportpov.modelstyle=Model styl
+dialog.exportpov.ballsandsticks=Balle en stokkies
+dialog.exportpov.tubesandwalls=Buise en mure
+dialog.exportpov.warningtracksize=Hierdie spoor het 'n groot aantal punte, wat Java3D miskien nie kan vertoon.\nIs jy seker jy wil voortgaan?
+dialog.pointtype.desc=Stoor die volgende punt tipes
+dialog.pointtype.track=Spoor punte
+dialog.pointtype.waypoint=Bakens
+dialog.pointtype.photo=Foto punte
+dialog.confirmreversetrack.title=Bevestig omkering
+dialog.confirmreversetrack.text=Hierdie spoor bevat tydstempel informasie, wat uit sekwensie/order sal wees na omkering.\nIs jy seker jy wil die spoor omruil vir die seksie?
+dialog.confirmcutandmove.title=Bevestig sny en skuif
+dialog.confirmcutandmove.text=Hierdie spoor het tydstempel informasie, wat uit sekwensie/orde sal wees na skuif.\nIs jy seker jy wil die seksie skuif?
+dialog.interpolate.title=Interpoleer punte
+dialog.interpolate.parameter.text=Aantal punte om bytevoeg tussen geselekteerde punte.
+dialog.undo.title=Herroep aksie(s)
+dialog.undo.pretext=Selekteer asb die aksie(s) om te herroep
+dialog.undo.none.title=Kan nie herroep
+dialog.undo.none.text=Geen operasies om te herroep!
+dialog.clearundo.title=Maak Herroep lys uit skoon
+dialog.clearundo.text=Is jy seker jy wil die herroep lys skoon maak?\nAlle herroep informasie sal verlore gaan!
+dialog.pointedit.title=Redigeer punt
diff --git a/tim/prune/lang/prune-texts_de.properties b/tim/prune/lang/prune-texts_de.properties
index 81b2b78..daf49fe 100644
--- a/tim/prune/lang/prune-texts_de.properties
+++ b/tim/prune/lang/prune-texts_de.properties
@@ -11,18 +11,17 @@ menu.edit=Bearbeiten
menu.edit.undo=Rückgängig
menu.edit.clearundo=Liste der letzten Änderungen löschen
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.deletemarked=Komprimierten Punkte löschen
+menu.edit.deletemarked=Komprimierte Punkte löschen
menu.edit.interpolate=Interpolieren
menu.edit.average=Durchschnitt berechnen
menu.edit.reverse=Bereich umkehren
-menu.edit.mergetracksegments=Trackteile verbinden
-menu.edit.rearrange=Waypoints reorganisieren
-menu.edit.rearrange.start=Alle Waypoints zum Anfang
-menu.edit.rearrange.end=Alle Waypoints zum Ende
-menu.edit.rearrange.nearest=Jeden Waypoint zum nächsten Trackpunkt verschieben
+menu.edit.mergetracksegments=Trackabschnitte verbinden
+menu.edit.rearrange=Wegpunkte reorganisieren
+menu.edit.rearrange.start=Alle Wegpunkte zum Anfang
+menu.edit.rearrange.end=Alle Wegpunkte ans Ende
+menu.edit.rearrange.nearest=Jeden Wegpunkt zum nächsten Trackpunkt verschieben
menu.edit.cutandmove=Schneiden und verschieben
menu.select=Markieren
menu.select.all=Alles markieren
@@ -40,15 +39,36 @@ menu.view.browser.google=Google Maps
menu.view.browser.openstreetmap=Openstreetmap
menu.view.browser.mapquest=
menu.view.browser.yahoo=
+menu.settings=Einstellungen
+menu.settings.showpace=Tempo anzeigen
menu.help=Hilfe
# Popup menu for map
menu.map.zoomin=Hineinzoomen
menu.map.zoomout=Herauszoomen
-menu.map.zoomfull=Auf Bildschirmgröße anpassen
-menu.map.newpoint=Neuen Punkt kreieren
+menu.map.zoomfull=Auf Bildschirmgröße zoomen
+menu.map.newpoint=Neuen Punkt erzeugen
menu.map.connect=Trackpunkte mit Linie anzeigen
menu.map.autopan=Autozentrierung
menu.map.showmap=Karte zeigen
+menu.map.showscalebar=Maßstab anzeigen
+
+# Alt keys for menus
+altkey.menu.file=D
+altkey.menu.edit=B
+altkey.menu.select=M
+altkey.menu.view=A
+altkey.menu.photo=F
+altkey.menu.settings=E
+altkey.menu.help=H
+
+# Ctrl shortcuts for menu items
+shortcut.menu.file.open=O
+shortcut.menu.file.load=L
+shortcut.menu.file.save=S
+shortcut.menu.edit.undo=Z
+shortcut.menu.edit.compress=K
+shortcut.menu.select.all=A
+shortcut.menu.help.help=H
# Functions
function.loadfromgps=Vom GPS laden
@@ -56,28 +76,36 @@ function.sendtogps=zum GPS schicken
function.exportkml=KML exportieren
function.exportgpx=GPX exportieren
function.exportpov=POV exportieren
+function.editwaypointname=Wegpunkt Name bearbeiten
function.compress=Track komprimieren
-function.addtimeoffset=Zeitdifferenz addieren
-function.charts=Diagrammen
+function.addtimeoffset=Zeitverschiebung aufrechnen
+function.addaltitudeoffset=Höhenverschiebung aufrechnen
+function.findwaypoint=Wegpunkt finden
+function.charts=Diagramme
function.show3d=3D Ansicht
function.distances=Distanzen
function.setmapbg=Karte Hintergrund setzen
+function.setkmzimagesize=Bildgröße im KMZ setzen
+function.setpaths=Programmenpfade setzen
+function.getgpsies=Gpsies Tracks holen
function.correlatephotos=Fotos korrelieren
function.help=Hilfe
+function.showkeys=Tastenkombinationen anzeigen
function.about=Über Prune
function.checkversion=Nach neuen Versionen suchen
+function.saveconfig=Einstellungen speichern
# Dialogs
dialog.exit.confirm.title=Prune beenden
dialog.exit.confirm.text=Ihre Daten wurden nicht gespeichert. Wollen Sie das Programm trotzdem beenden?
-dialog.openappend.title=an existierende Daten anhängen oder ersetzen
+dialog.openappend.title=Daten anhängen oder ersetzen
dialog.openappend.text=Diese Daten an die aktuellen Daten anhängen?
dialog.deletepoint.title=Punkt löschen
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.openoptions.title=Öffnen
-dialog.openoptions.filesnippet=Extrakt von der Datei
+dialog.openoptions.filesnippet=Dateiausschnitt
dialog.load.table.field=Feld
dialog.load.table.datatype=Daten Typ
dialog.load.table.description=Beschreibung
@@ -96,13 +124,13 @@ 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.nogpsbabel=Kein gpsbabel Programm wurde gefunden. Weiter?
-dialog.gpsload.device=Device Name
+dialog.gpsload.nogpsbabel=Programm gpsbabel wurde nicht gefunden. Weiter?
+dialog.gpsload.device=Gerätename
dialog.gpsload.format=Format
-dialog.gpsload.getwaypoints=Waypoints laden
+dialog.gpsload.getwaypoints=Wegpunkte laden
dialog.gpsload.gettracks=Tracks laden
-dialog.gpssend.sendwaypoints=Waypoints schicken
-dialog.gpssend.sendtracks=Tracks schicken
+dialog.gpssend.sendwaypoints=Wegpunkte senden
+dialog.gpssend.sendtracks=Tracks senden
dialog.gpssend.trackname=Track Name
dialog.saveoptions.title=Datei speichern
dialog.save.fieldstosave=Zu speichernde Felder
@@ -114,14 +142,14 @@ dialog.save.coordinateunits=Koordinaten Ma
dialog.save.altitudeunits=Höhe Maßeinheiten
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.save.overwrite.text=Diese Datei gibt es schon. Wollen Sie die vorhandene Datei überschreiben?
dialog.exportkml.text=Titel für die Daten
-dialog.exportkml.altitude=Auch Höheninformation (für Luftfahrt)
+dialog.exportkml.altitude=Absolute Höheninformation (für Luftfahrt)
dialog.exportkml.kmz=Daten in kmz Datei komprimieren
-dialog.exportkml.exportimages=Bilder in kmz exportieren
+dialog.exportkml.exportimages=Vorschaubilder mit in kmz exportieren
dialog.exportgpx.name=Name
dialog.exportgpx.desc=Beschreibung
-dialog.exportgpx.includetimestamps=Zeitstempel exportieren
+dialog.exportgpx.includetimestamps=Zeitstempel mit exportieren
dialog.exportpov.text=Geben Sie die Parameter für den POV Export ein
dialog.exportpov.font=Font
dialog.exportpov.camerax=Kamera X
@@ -130,28 +158,31 @@ dialog.exportpov.cameraz=Kamera Z
dialog.exportpov.modelstyle=Modellstil
dialog.exportpov.ballsandsticks=Bälle und Stangen
dialog.exportpov.tubesandwalls=Röhren und Wände
-dialog.exportpov.warningtracksize=Dieser Track hat sehr viele Punkte, die Java3D vielleicht nicht bearbeiten kann.\nMöchten Sie den Vorgang trotzdem fortführen?
+dialog.exportpov.warningtracksize=Dieser Track hat sehr viele Punkte, die Java3D vielleicht nicht bearbeiten kann.\nMöchten Sie den Vorgang trotzdem fortsetzen?
+dialog.pointtype.desc=Folgende Punkttypen speichern:
+dialog.pointtype.track=Trackpunkte
+dialog.pointtype.waypoint=Wegpunkte
+dialog.pointtype.photo=Fotopunkte
dialog.confirmreversetrack.title=Umkehrung bestätigen
-dialog.confirmreversetrack.text=Diese Daten enthalten Zeitstempel Informationen, die bei einer Umkehrung in falscher Reihenfolge erscheinen würden.\nSind Sie sicher, dass Sie diesen Bereich umkehren wollen?
+dialog.confirmreversetrack.text=Diese Daten enthalten Zeitangaben, die bei einer Umkehrung in falscher Reihenfolge erscheinen würden.\nSind Sie sicher, dass Sie diesen Bereich umkehren wollen?
dialog.confirmcutandmove.title=Verschieben bestätigen
-dialog.confirmcutandmove.text=Diese Daten enthalten Zeitstempel Informationen, die nach dem Verschieben in falscher Reihenfolge erscheinen würden.\nSind Sie sicher, dass Sie diesen Bereich verschieben wollen?
+dialog.confirmcutandmove.text=Diese Daten enthalten Zeitangaben, die nach dem Verschieben in falscher Reihenfolge erscheinen würden.\nSind Sie sicher, dass Sie diesen Bereich verschieben wollen?
dialog.interpolate.title=Punkte interpolieren
-dialog.interpolate.parameter.text=Anzahl Punkte die zwischen den gewählten Punkten eingefügt werden sollen
+dialog.interpolate.parameter.text=Anzahl Punkte, die zwischen den gewählten Punkten eingefügt werden sollen
dialog.undo.title=Aktionen Rückgängig
-dialog.undo.pretext=Auswahl der Operationen die rückgängig gemacht werden sollen.
+dialog.undo.pretext=Bitte die Operationen, die rückgängig gemacht werden sollen, auswählen.
dialog.undo.none.title=Undo nicht möglich
dialog.undo.none.text=Keine Operationen können rückgängig gemacht werden.
dialog.clearundo.title=Undo-Liste löschen
dialog.clearundo.text=Sind Sie sicher, Sie wollen die Undo-Liste löschen?\nAlle Undo Information wird veloren gehen!
dialog.pointedit.title=Punkt bearbeiten
-dialog.pointedit.text=Wählen Sie jeden Feld aus zu bearbeiten, und mit dem 'Bearbeiten' Knopf den Wert ändern
+dialog.pointedit.text=Wählen Sie die Felder aus, die Sie bearbeiten möchten, und verwenden Sie den 'Bearbeiten' Knopf, um den Wert zu ändern
dialog.pointedit.table.field=Feld
dialog.pointedit.table.value=Wert
dialog.pointedit.table.changed=Geändert
dialog.pointedit.changevalue.text=Geben Sie den neuen Wert für dieses Feld ein
dialog.pointedit.changevalue.title=Feld bearbeiten
-dialog.pointnameedit.title=Waypoint Name bearbeiten
-dialog.pointnameedit.name=Waypoint Name
+dialog.pointnameedit.name=Wegpunkt Name
dialog.pointnameedit.uppercase=GROß geschrieben
dialog.pointnameedit.lowercase=klein geschrieben
dialog.pointnameedit.sentencecase=Gemischt geschrieben
@@ -161,11 +192,13 @@ dialog.addtimeoffset.days=Tage
dialog.addtimeoffset.hours=Stunde
dialog.addtimeoffset.minutes=Minute
dialog.addtimeoffset.notimestamps=Zeitdifferenz kann nicht addiert werden weil dieser Bereich keine Zeitinformation hat
+dialog.findwaypoint.intro=Geben Sie einen Teil von dem Namen ein
+dialog.findwaypoint.search=Suche
dialog.connect.title=Foto mit Punkt verbinden
-dialog.connectphoto.clonepoint=Dieser Punkt hat schon ein Foto.\nWollen Sie eine Kopie von dem Punkt machen?
+dialog.connectphoto.clonepoint=Diesem Punkt ist schon ein Foto zugeordnet.\nWollen Sie eine Kopie dieses Punktes machen?
dialog.saveexif.title=Exif speichern
-dialog.saveexif.intro=Selektieren Sie die Fotos zu speichern
-dialog.saveexif.nothingtosave=Koordinaten sind nicht modifiziert, nichts zu speichern
+dialog.saveexif.intro=Wählen Sie die Fotos zum Speichern aus
+dialog.saveexif.nothingtosave=Koordinaten sind unverändert. Es gibt nichts zu speichern.
dialog.saveexif.noexiftool=Kein exiftool Programm gefunden. Trotzdem fortfahren?
dialog.saveexif.table.photoname=Foto Name
dialog.saveexif.table.status=Status
@@ -181,27 +214,32 @@ 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.needaltitudeortimes=Ohne Daten über Höhe und Zeit kann kein Diagramm 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.charts.gnuplotnotfound=Gnuplot konnte im angegebenen Pfad nicht gefunden werden
+dialog.distances.intro=Luftlinienentfernung 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.distances.currentpoint=Aktueller Punkt
+dialog.distances.toofewpoints=Diese Funktion braucht Wegpunkte 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
-dialog.correlate.photoselect.photoname=Foto Name
+dialog.gpsies.column.name=Track Name
+dialog.gpsies.column.length=Länge
+dialog.gpsies.description=Beschreibung
+dialog.gpsies.nodescription=Keine Beschreibung
+dialog.gpsies.nonefound=Keine Tracks gefunden
+dialog.correlate.notimestamps=Die Punkte enthalten keine Zeitangaben, deshalb können die Fotos nicht zugeordnet werden.
+dialog.correlate.nouncorrelatedphotos=Alle Fotos sind schon zugeordnet.\nWollen Sie trotzdem fortfahren?
+dialog.correlate.photoselect.intro=Wählen Sie eines dieser Fotos aus, um die Zeitdifferenz zu berechnen
+dialog.correlate.photoselect.photoname=Bezeichnung des Fotos
dialog.correlate.photoselect.timediff=Zeitdifferenz
dialog.correlate.photoselect.photolater=Foto später
-dialog.correlate.options.tip=Tipp: Mit mindestens einem korrelierten Foto, die Zeitdifferenz kann automatisch berechnet werden.
-dialog.correlate.options.intro=Wählen Sie die Optionen aus für die Korrelation
+dialog.correlate.options.tip=Tipp: Mit mindestens einem korrelierten Foto kann die Zeitdifferenz automatisch berechnet werden.
+dialog.correlate.options.intro=Wählen Sie die Optionen für die Korrelation aus
dialog.correlate.options.offsetpanel=Zeitunterschied
dialog.correlate.options.offset=Unterschied
dialog.correlate.options.offset.hours=Stunden,
@@ -215,22 +253,22 @@ dialog.correlate.options.timelimit=Zeitgrenzen
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.correlate.alloutsiderange=Alle Fotos sind außerhalb vom Track Zeitraum. Sie können nicht korreliert werden.\nVersuchen Sie es mit einem anderen Offset oder binden Sie manuell mindestens ein Foto ein.
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.wackypoints.title=Ungewöhnliche Punkte entfernen
+dialog.compress.wackypoints.paramdesc=Distanzfaktor
+dialog.compress.singletons.title=Singletons (isolierte Punkte) entfernen
+dialog.compress.singletons.paramdesc=Distanzfaktor
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.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.
-dialog.about.summarytext2=Es ist unter den Gnu GPL zur Verfügung gestellt, für frei, gratis und offen Gebrauch und Weiterentwicklung. Kopieren, Weiterverbreitung und Veränderungen sind erlaubt und willkommen unter die Bedingungen in der enthaltenen license.txt
Datei.
-dialog.about.summarytext3=Bitte sehen Sie http://activityworkshop.net/
für weitere Information und Benutzeranleitungen.
+dialog.about.summarytext1=Prune ist ein Programm zum Laden, Darstellen und Editieren von Daten von GPS Geräten.
+dialog.about.summarytext2=Es wird unter der Gnu GPL zur Verfügung gestellt, zum freien, kostenlosen und offenen Gebrauch und zur Weiterentwicklung. Kopieren, Weiterverbreitung und Veränderungen sind erlaubt und willkommen unter den in der license.txt
Datei enthaltenen Bedingungen.
+dialog.about.summarytext3=Auf der Seite http://activityworkshop.net/
finden Sie weitere Information und Benutzeranleitungen.
dialog.about.languages=Verfügbare Sprachen
dialog.about.translatedby=Deutsche Übersetzung von activityworkshop.
dialog.about.systeminfo=System Information
@@ -249,23 +287,44 @@ dialog.about.credits.exifcode=Exif Code von
dialog.about.credits.icons=Einige Bilder von
dialog.about.credits.translators=Dolmetscher
dialog.about.credits.translations=Übersetzungen mit Hilfe von
-dialog.about.credits.devtools=Entwicklungsprogrammen
-dialog.about.credits.othertools=Andere Programmen
+dialog.about.credits.devtools=Entwicklungsprogramme
+dialog.about.credits.othertools=Andere Programme
dialog.about.credits.thanks=Danke an
dialog.about.readme=Liesmich
-dialog.checkversion.error=Die Versionnummer konnte nicht geprüft werden.\nBitte prüfen Sie die Internet Verbindung.
+dialog.checkversion.error=Die Versionnummer konnte nicht ermittelt 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
dialog.checkversion.newversion2=.
dialog.checkversion.releasedate1=Diese neue Version ist am
dialog.checkversion.releasedate2=veröffentlicht worden.
-dialog.checkversion.download=Um die neue Version herunterzuladen, schauen Sie nach http://activityworkshop.net/software/prune/download.html.
+dialog.checkversion.download=Um die neue Version herunterzuladen, gehen Sie zu http://activityworkshop.net/software/prune/download.html.
+dialog.keys.intro=Anstatt die Maus können Sie diesen Taste-Kombinationen nutzen
+dialog.keys.keylist=Pfeil Tasten Karte verschieben Strg + links, rechts Pfeil Vorherigen oder nächsten Punkt markieren Strg + auf, abwärts Pfeil Ein- oder Auszoomen Entf Aktuellen Punkt entfernen
+dialog.saveconfig.desc=Die folgende Einstellungen können gespeichert werden :
+dialog.saveconfig.prune.trackdirectory=Datenverzeichnis
+dialog.saveconfig.prune.photodirectory=Fotoverzeichnis
+dialog.saveconfig.prune.languagecode=Sprachecode (DE)
+dialog.saveconfig.prune.gpsdevice=GPS Gerätename
+dialog.saveconfig.prune.gpsformat=GPS Format
+dialog.saveconfig.prune.povrayfont=Povray Font
+dialog.saveconfig.prune.metricunits=Metrische Einheiten verwenden?
+dialog.saveconfig.prune.gnuplotpath=Gnuplot Pfad
+dialog.saveconfig.prune.gpsbabelpath=Gpsbabel Pfad
+dialog.saveconfig.prune.exiftoolpath=Exiftool Pfad
+dialog.saveconfig.prune.mapserverindex=Kartenserver Index
+dialog.saveconfig.prune.mapserverurl=Kartenserver URL
+dialog.saveconfig.prune.showpace=Tempo anzeigen
+dialog.saveconfig.prune.kmzimagewidth=Bildbreite in KMZ
+dialog.saveconfig.prune.kmzimageheight=Bildhöhe in KMZ
+dialog.setpaths.intro=Sie können hier die Pfade für externe Applikationen setzen:
+dialog.addaltitude.noaltitudes=Der markierten Bereich enthält keine Höhenangaben
+dialog.addaltitude.desc=Höhenverschiebung aufzurechnen
# 3d window
dialog.3d.title=Prune 3D Ansicht
dialog.3d.altitudecap=Minimum Höhenskala
dialog.3dlines.title=Prune Gitterlinien
-dialog.3dlines.empty=Keine Linien zum anzeigen!
+dialog.3dlines.empty=Keine Linien zum Anzeigen!
dialog.3dlines.intro=Hier sind die Linien für die 3D Ansicht
# Confirm messages || These are displayed as confirmation in the status bar
@@ -275,13 +334,14 @@ confirm.save.ok2=Punkte gespeichert nach
confirm.deletepoint.single=Punkt wurde entfernt
confirm.deletepoint.multi=Punkte wurden entfernt
confirm.point.edit=Punkt editiert
-confirm.mergetracksegments=Trackteilen verbunden
+confirm.mergetracksegments=Trackabschnitte verbunden
confirm.reverserange=Bereich umgekehrt
-confirm.addtimeoffset=Zeitdifferenz addiert
-confirm.rearrangewaypoints=Waypoints reorganisiert
+confirm.addtimeoffset=Zeitverschiebung aufgerechnet
+confirm.addaltitudeoffset=Höhenverschiebung aufgerechnet
+confirm.rearrangewaypoints=Wegpunkte reorganisiert
confirm.cutandmove=Bereich verschoben
confirm.saveexif.ok1=Es wurden
-confirm.saveexif.ok2=Foto Dateien geschrieben
+confirm.saveexif.ok2=Fotodateien geschrieben
confirm.undo.single=Operation rückgängig gemacht
confirm.undo.multi=Operationen rückgängig gemacht
confirm.jpegload.single=Foto wurde geladen
@@ -291,6 +351,7 @@ confirm.photo.disconnect=Foto getrennt
confirm.correlate.single=Foto wurde korreliert
confirm.correlate.multi=Fotos wurden korreliert
confirm.createpoint=Punkt kreiert
+confirm.running=In Bearbeitung ...
# Buttons
button.ok=OK
@@ -299,8 +360,8 @@ button.next=Vorw
button.finish=Fertig
button.cancel=Abbrechen
button.overwrite=Überschreiben
-button.moveup=Aufwärts moven
-button.movedown=Abwärts moven
+button.moveup=Nach oben verschieben
+button.movedown=Nach unten verschieben
button.showlines=Linien anzeigen
button.edit=Bearbeiten
button.exit=Beenden
@@ -312,10 +373,11 @@ button.yestoall=Ja f
button.notoall=Nein für alle
button.selectall=Alle selektieren
button.selectnone=Nichts selektieren
-button.preview=Vorschauen
+button.preview=Vorschau
+button.load=Laden
button.guessfields=Felder erraten
button.showwebpage=Webseite anzeigen
-button.gnuplotpath=Gnuplot Pfad setzen
+button.check=Prüfen
# File types
filetype.txt=TXT Dateien
@@ -329,7 +391,7 @@ filetype.svg=SVG Dateien
# Display components
display.nodata=Keine Daten geladen
-display.noaltitudes=Track enthält keine Höhe Daten
+display.noaltitudes=Track enthält keine Höhenangaben
details.trackdetails=Details vom Track
details.notrack=Kein Track geladen
details.track.points=Punkte
@@ -339,9 +401,9 @@ details.pointdetails=Details vom Punkt
details.index.selected=Index
details.index.of=von
details.nopointselection=Nichts selektiert
-details.photofile=Foto Datei
-details.norangeselection=Nichts selektiert
-details.rangedetails=Details vom Bereich
+details.photofile=Fotodatei
+details.norangeselection=Kein Bereich ausgewählt
+details.rangedetails=Details der Auswahl
details.range.selected=Markiert
details.range.to=bis
details.altitude.to=bis
@@ -355,13 +417,14 @@ display.range.time.hours=h
display.range.time.days=T
details.range.avespeed=Geschwindigkeit
details.range.avemovingspeed=Geschwindigkeit unterwegs
-details.waypointsphotos.waypoints=Waypoints
+details.range.pace=Tempo
+details.waypointsphotos.waypoints=Wegpunkte
details.waypointsphotos.photos=Fotos
-details.photodetails=Details vom Foto
-details.nophoto=Kein Foto selektiert
+details.photodetails=Fotodetails
+details.nophoto=Kein Foto ausgewählt
details.photo.loading=Laden
details.photo.connected=Verbunden
-map.overzoom=Keine Karten mit diesem Zoom verfügbar
+map.overzoom=Keine Karten für diesen Zoomfaktor verfügbar
# Field names
fieldname.latitude=Breitengrad
@@ -375,14 +438,14 @@ fieldname.newsegment=Segment
fieldname.custom=Custom
fieldname.prefix=Feld
fieldname.distance=Länge
-fieldname.movingdistance=Weglänge
-fieldname.duration=Zeitlänge
+fieldname.movingdistance=Wegstrecke
+fieldname.duration=Zeitdauer
fieldname.speed=Geschwindigkeit
fieldname.verticalspeed=Vertikale Geschwindigkeit
# Measurement units
units.original=Original
-units.default=Default
+units.default=Standard
units.metres=Meter
units.metres.short=
units.feet=
@@ -415,14 +478,15 @@ undo.load=Daten laden
undo.loadphotos=Fotos laden
undo.editpoint=Punkt bearbeiten
undo.deletepoint=Punkt löschen
-undo.deletephoto=Photo entfernen
+undo.deletephoto=Foto entfernen
undo.deleterange=Bereich löschen
undo.compress=Track komprimieren
undo.insert=Punkte hinzufügen
undo.reverse=Bereich umdrehen
-undo.mergetracksegments=Trackteile verbinden
-undo.addtimeoffset=zeitdifferenz addieren
-undo.rearrangewaypoints=Waypoints reorganisieren
+undo.mergetracksegments=Trackabschnitte verbinden
+undo.addtimeoffset=Zeitverschiebung aufrechnen
+undo.addaltitudeoffset=Höhenverschiebung aufrechnen
+undo.rearrangewaypoints=Wegpunkte reorganisieren
undo.cutandmove=Bereich verschieben
undo.connectphoto=Foto verbinden
undo.disconnectphoto=Foto trennen
@@ -431,11 +495,11 @@ undo.createpoint=Punkt kreieren
# Error messages
error.save.dialogtitle=Fehler beim Speichern
-error.save.nodata=Keine Daten wurden geladen
-error.save.failed=Speichern von der Datei fehlgeschlagen:
+error.save.nodata=Keine Daten zum Sichern vorhanden
+error.save.failed=Speichern von der Datei fehlgeschlagen
error.saveexif.filenotfound=Foto Datei nicht gefunden
error.saveexif.cannotoverwrite1=Foto Datei
-error.saveexif.cannotoverwrite2=ist schreib-geschützt. Speichern zu einer Kopie?
+error.saveexif.cannotoverwrite2=ist schreib-geschützt. Als Kopie speichern?
error.load.dialogtitle=Fehler beim Laden
error.load.noread=Datei konnte nicht gelesen werden
error.load.nopoints=Keine gültigen Daten in Datei gefunden
@@ -449,11 +513,11 @@ error.jpegload.noexiffound=Keine EXIF Information gefunden
error.jpegload.nogpsfound=Keine GPS Information gefunden
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.noop.title=Funktion hat nichts bewirkt
+error.rearrange.noop=Die Wegpunkte zu reorganisieren hatte keinen Effekt
error.function.notavailable.title=Funktion nicht verfügbar
-error.function.nojava3d=Diese Funktion braucht den Java3d Library,\nvon Sun.com erhältlich.
-error.3d=Ein Fehler ist mit der 3d Darstellung aufgetreten
+error.function.nojava3d=Diese Funktion benötigt die Java3d Library,\nvon Sun.com erhältlich.
+error.3d=Ein Fehler ist bei der 3D Darstellung aufgetreten
error.readme.notfound=Liesmich Datei nicht gefunden
-error.osmimage.dialogtitle=Laden von Karten-Bilder fehlgeschlagen
-error.osmimage.failed=Laden von Karten-Bilder fehlgeschlagen. Bitte prüfen Sie die Internet-Verbindung.
+error.osmimage.dialogtitle=Laden von Karten-Bildern fehlgeschlagen
+error.osmimage.failed=Laden von Karten-Bildern fehlgeschlagen. Bitte prüfen Sie die Internetverbindung.
diff --git a/tim/prune/lang/prune-texts_de_CH.properties b/tim/prune/lang/prune-texts_de_CH.properties
index 5cbeed6..b00f39d 100644
--- a/tim/prune/lang/prune-texts_de_CH.properties
+++ b/tim/prune/lang/prune-texts_de_CH.properties
@@ -2,7 +2,7 @@
# Swiss-German entries as extra
# Menu entries
-menu.file=Datei
+menu.file=File
menu.file.open=File öffne
menu.file.addphotos=Fötelis innätue
menu.file.save=Speichere
@@ -11,7 +11,6 @@ menu.edit=Editiere
menu.edit.undo=Undo
menu.edit.clearundo=Undo-Liste lösche
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.deletemarked=Komprimierte Punkte lösche
@@ -40,6 +39,8 @@ menu.view.browser.google=
menu.view.browser.openstreetmap=
menu.view.browser.mapquest=
menu.view.browser.yahoo=
+menu.settings=Iistellige
+menu.settings.showpace=Tempo aazeige
menu.help=Hilfe
# Popup menu for map
menu.map.zoomin=Innezoome
@@ -49,6 +50,25 @@ menu.map.newpoint=Noii Punkt
menu.map.connect=Trackpünktli verbindä
menu.map.autopan=Autopan
menu.map.showmap=Kate zeigä
+menu.map.showscalebar=Massstab aazeige
+
+# Alt keys for menus
+altkey.menu.file=F
+altkey.menu.edit=E
+altkey.menu.select=S
+altkey.menu.view=A
+altkey.menu.photo=F
+altkey.menu.settings=I
+altkey.menu.help=H
+
+# Ctrl shortcuts for menu items
+shortcut.menu.file.open=O
+shortcut.menu.file.load=L
+shortcut.menu.file.save=S
+shortcut.menu.edit.undo=Z
+shortcut.menu.edit.compress=K
+shortcut.menu.select.all=A
+shortcut.menu.help.help=H
# Functions
function.loadfromgps=uusem GPS lade
@@ -56,16 +76,24 @@ function.sendtogps=zum GPS schicke
function.exportkml=KML exportierä
function.exportgpx=GPX exportierä
function.exportpov=POV exportierä
+function.editwaypointname=Waypoint Name editiere
function.compress=Track komprimierä
function.addtimeoffset=Ziitverschiebig zutue
+function.addaltitudeoffset=Höchiverschiebig zutue
+function.findwaypoint=Waypoint findä
function.charts=Diagramme
function.show3d=Drüü-D Aasicht
function.distances=Distanze
function.setmapbg=Karte Hintegrund setzä
+function.getgpsies=Gpsies Tracks holä
function.correlatephotos=Fötelis korrelierä
+function.setkmzimagesize=Bildligrösse inem KMZ setze
+function.setpaths=Programmepfade setze
function.help=Hilfe
+function.showkeys=Tastekombinatione aazeige
function.about=Über Prune
function.checkversion=Pruef nach ne noie Version
+function.saveconfig=Iistellige speichere
# Dialogs
dialog.exit.confirm.title=Prune beände
@@ -116,7 +144,7 @@ dialog.save.timestampformat=Ziitst
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.text=Titel für die Date
-dialog.exportkml.altitude=Au Höchiinformation (fürs Fliege)
+dialog.exportkml.altitude=Absolut Höchiinformation (fürs Fliege)
dialog.exportkml.kmz=Date ins kmz File komprimierä
dialog.exportkml.exportimages=Bildli ins Kmz exportierä
dialog.exportgpx.name=Name
@@ -131,6 +159,10 @@ dialog.exportpov.modelstyle=Modellstil
dialog.exportpov.ballsandsticks=Bälle und Schtange
dialog.exportpov.tubesandwalls=Röhre und Wände
dialog.exportpov.warningtracksize=Dieser Track hät mega viele Punkte, die Java3D villiicht nöd chann bearbeite.\nSind Sie sicher, Sie wend trotzdem fortsetze?
+dialog.pointtype.desc=Folgende Punkttype speichere:
+dialog.pointtype.track=Trackpunkte
+dialog.pointtype.waypoint=Waypoints
+dialog.pointtype.photo=Fötelipunkte
dialog.confirmreversetrack.title=Umdrehig bestätige
dialog.confirmreversetrack.text=Diese Daten enthalte Ziitstämpel Informatione, die bei dr Umkehrig usser Reihefolge erschiene würdi.\nSind Sie sicher, Sie wend dn Beriich umkehre?
dialog.confirmcutandmove.title=Move bestätige
@@ -150,7 +182,6 @@ dialog.pointedit.table.value=Wert
dialog.pointedit.table.changed=Geändert
dialog.pointedit.changevalue.text=Gebet Sie den neuen Wert für diesen Fäld ina
dialog.pointedit.changevalue.title=Fäld editiere
-dialog.pointnameedit.title=Waypoint Name editiere
dialog.pointnameedit.name=Waypoint Name
dialog.pointnameedit.uppercase=GROSS gschriebe
dialog.pointnameedit.lowercase=chli gschriebe
@@ -161,6 +192,8 @@ dialog.addtimeoffset.days=Tage
dialog.addtimeoffset.hours=Schtunde
dialog.addtimeoffset.minutes=Minute
dialog.addtimeoffset.notimestamps=Ziitverschiebig nöd möglech wil dr Beriich kei Ziitinfo hät
+dialog.findwaypoint.intro=Gebet Sie en Teil vonem Namen ina
+dialog.findwaypoint.search=Sueche
dialog.connect.title=Föteli verknüpfe
dialog.connectphoto.clonepoint=Derer Punkt hät scho s Föteli.\nWend sie ne Kopie vonem Punkt machä?
dialog.saveexif.title=Exif go speicherä
@@ -194,9 +227,14 @@ dialog.setmapbg.osma=
dialog.setmapbg.cyclemap=Velokarte
dialog.setmapbg.other=Anderi
dialog.setmapbg.server=Server URL
+dialog.gpsies.column.name=Track Name
+dialog.gpsies.column.length=Länge
+dialog.gpsies.description=Beschriebig
+dialog.gpsies.nodescription=Kei Beschriebig
+dialog.gpsies.nonefound=Kei Tracks gfunde
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ä
+dialog.correlate.photoselect.intro=Wählet Sie eini vo deren Föteli uus, um die Ziitdifferänz zu berächnä
dialog.correlate.photoselect.photoname=Föteli Name
dialog.correlate.photoselect.timediff=Ziitdifferänz
dialog.correlate.photoselect.photolater=Föteli spöter
@@ -260,6 +298,27 @@ dialog.checkversion.newversion2=.
dialog.checkversion.releasedate1=Die noii Version isch am
dialog.checkversion.releasedate2=ussecho.
dialog.checkversion.download=Um die noii Version runterzlade, schauet Sie na http://activityworkshop.net/software/prune/download.html.
+dialog.keys.intro=Aastatt d'Muus könnet Sie diese Tastekombinationen nutze
+dialog.keys.keylist=Pfiil Taste Karte verschiebe Strg + links, rächts Pfiil Vorherigi oder nöchsti Punkt markiere Strg + uuf, aba Pfiil Ii- oder Uusezoome Entf Aktuelli Punkt lösche
+dialog.saveconfig.desc=Die folgendi Iinstellige könne gspeicheret werde :
+dialog.saveconfig.prune.trackdirectory=Trackverzeichnis
+dialog.saveconfig.prune.photodirectory=Föteliverzeichnis
+dialog.saveconfig.prune.languagecode=Sprochecode (DE_ch)
+dialog.saveconfig.prune.gpsdevice=GPS Gerätename
+dialog.saveconfig.prune.gpsformat=GPS Format
+dialog.saveconfig.prune.povrayfont=Povray Font
+dialog.saveconfig.prune.metricunits=Metrischi Einheite verwende?
+dialog.saveconfig.prune.gnuplotpath=Gnuplot Pfad
+dialog.saveconfig.prune.gpsbabelpath=Gpsbabel Pfad
+dialog.saveconfig.prune.exiftoolpath=Exiftool Pfad
+dialog.saveconfig.prune.mapserverindex=Kartenserver Index
+dialog.saveconfig.prune.mapserverurl=Kartenserver URL
+dialog.saveconfig.prune.showpace=Tempo aazeige
+dialog.saveconfig.prune.kmzimagewidth=Bildbreiti im KMZ
+dialog.saveconfig.prune.kmzimageheight=Bildhöchi im KMZ
+dialog.setpaths.intro=Sie könnet dann die Pfade für dia Applikatione setzä:
+dialog.addaltitude.noaltitudes=Dr seläktierte Beriich hät keini Höchiinformation
+dialog.addaltitude.desc=Höchiverschiebig zuzutue
# 3d window
dialog.3d.title=Prune Drüü-d Aasicht
@@ -278,6 +337,7 @@ confirm.point.edit=Punkt editiert
confirm.mergetracksegments=Segmänte gmerged
confirm.reverserange=Beriich umgdrähet
confirm.addtimeoffset=Ziitverschiebig zutue
+confirm.addaltitudeoffset=Höchiverschiebig zutue
confirm.rearrangewaypoints=Waypoints umorganisiert
confirm.cutandmove=Beriich gmoved
confirm.saveexif.ok1=Es sin
@@ -291,6 +351,7 @@ confirm.photo.disconnect=F
confirm.correlate.single=Föteli isch korreliert worde
confirm.correlate.multi=Fötelis sin korreliert worde
confirm.createpoint=Punkt kreiert worde
+confirm.running=Am Laufe ...
# Buttons
button.ok=OK
@@ -313,9 +374,11 @@ button.notoall=Nei f
button.selectall=Alli selektierä
button.selectnone=Nüüt selektierä
button.preview=Vorschauä
+button.load=Ladä
button.guessfields=Fälde erratä
button.showwebpage=Websiite aazeigä
-button.gnuplotpath=Gnuplot Pfad setzä
+button.check=Prüefa
+
# File types
filetype.txt=TXT Dateie
@@ -355,6 +418,7 @@ display.range.time.hours=Std
display.range.time.days=T
details.range.avespeed=Gschwindikeit
details.range.avemovingspeed=Gschwindikeit ufem Wäg
+details.range.pace=Tempo
details.waypointsphotos.waypoints=Waypoints
details.waypointsphotos.photos=Fötelis
details.photodetails=Details vonem Föteli
@@ -422,6 +486,7 @@ undo.insert=Punkte inn
undo.reverse=Beriich umdrähie
undo.mergetracksegments=track segmänte merge
undo.addtimeoffset=ziitverschiebig zutue
+undo.addaltitudeoffset=höchiverschiebig zutue
undo.rearrangewaypoints=Waypoints reorganisierä
undo.cutandmove=Selektion movä
undo.connectphoto=Föteli verbindä
@@ -432,7 +497,7 @@ undo.createpoint=Punkt kreier
# Error messages
error.save.dialogtitle=Fähle bim Speichere
error.save.nodata=Kei Date zum speichere
-error.save.failed=Speichere vom File fehlgschlage :
+error.save.failed=Speichere vom File fehlgschlage
error.saveexif.filenotfound=Föteli File nöd gfunde
error.saveexif.cannotoverwrite1=Föteli File
error.saveexif.cannotoverwrite2=isch nöd schriibbar. Speichere na einer Kopie?
diff --git a/tim/prune/lang/prune-texts_en.properties b/tim/prune/lang/prune-texts_en.properties
index f76bd36..85f4024 100644
--- a/tim/prune/lang/prune-texts_en.properties
+++ b/tim/prune/lang/prune-texts_en.properties
@@ -11,7 +11,6 @@ menu.edit=Edit
menu.edit.undo=Undo
menu.edit.clearundo=Clear undo list
menu.edit.editpoint=Edit point
-menu.edit.editwaypointname=Edit waypoint name
menu.edit.deletepoint=Delete point
menu.edit.deleterange=Delete range
menu.edit.deletemarked=Delete marked points
@@ -40,6 +39,8 @@ menu.view.browser.google=Google maps
menu.view.browser.openstreetmap=Openstreetmap
menu.view.browser.mapquest=Mapquest
menu.view.browser.yahoo=Yahoo maps
+menu.settings=Settings
+menu.settings.showpace=Show pace in range display
menu.help=Help
# Popup menu for map
menu.map.zoomin=Zoom in
@@ -49,6 +50,25 @@ menu.map.newpoint=Create new point
menu.map.connect=Connect track points
menu.map.autopan=Autopan
menu.map.showmap=Show map
+menu.map.showscalebar=Show scalebar
+
+# Alt keys for menus
+altkey.menu.file=F
+altkey.menu.edit=E
+altkey.menu.select=S
+altkey.menu.view=V
+altkey.menu.photo=P
+altkey.menu.settings=T
+altkey.menu.help=H
+
+# Ctrl shortcuts for menu items
+shortcut.menu.file.open=O
+shortcut.menu.file.load=L
+shortcut.menu.file.save=S
+shortcut.menu.edit.undo=Z
+shortcut.menu.edit.compress=C
+shortcut.menu.select.all=A
+shortcut.menu.help.help=H
# Functions
function.loadfromgps=Load data from GPS
@@ -56,16 +76,24 @@ function.sendtogps=Send data to GPS
function.exportkml=Export KML
function.exportgpx=Export GPX
function.exportpov=Export POV
+function.editwaypointname=Edit waypoint name
function.compress=Compress track
function.addtimeoffset=Add time offset
+function.addaltitudeoffset=Add altitude offset
+function.findwaypoint=Find waypoint
function.charts=Charts
function.show3d=Three-D view
function.distances=Distances
-function.setmapbg=Set map background
+function.getgpsies=Get Gpsies tracks
function.correlatephotos=Correlate photos
+function.setmapbg=Set map background
+function.setkmzimagesize=Set KMZ image size
+function.setpaths=Set program paths
function.help=Help
+function.showkeys=Show shortcut keys
function.about=About Prune
function.checkversion=Check for new version
+function.saveconfig=Save settings
# Dialogs
dialog.exit.confirm.title=Exit Prune
@@ -116,7 +144,7 @@ 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.text=Title for the data
-dialog.exportkml.altitude=Include altitudes (for aviation)
+dialog.exportkml.altitude=Absolute altitudes (for aviation)
dialog.exportkml.kmz=Compress to make kmz file
dialog.exportkml.exportimages=Export image thumbnails to kmz
dialog.exportgpx.name=Name
@@ -131,6 +159,10 @@ dialog.exportpov.modelstyle=Model style
dialog.exportpov.ballsandsticks=Balls and sticks
dialog.exportpov.tubesandwalls=Tubes and walls
dialog.exportpov.warningtracksize=This track has a large number of points, which Java3D might not be able to display.\nAre you sure you want to continue?
+dialog.pointtype.desc=Save the following point types:
+dialog.pointtype.track=Track points
+dialog.pointtype.waypoint=Waypoints
+dialog.pointtype.photo=Photo points
dialog.confirmreversetrack.title=Confirm reversal
dialog.confirmreversetrack.text=This track contains timestamp information, which will be out of sequence after a reversal.\nAre you sure you want to reverse this section?
dialog.confirmcutandmove.title=Confirm cut and move
@@ -150,7 +182,6 @@ dialog.pointedit.table.value=Value
dialog.pointedit.table.changed=Changed
dialog.pointedit.changevalue.text=Enter the new value for this field
dialog.pointedit.changevalue.title=Edit field
-dialog.pointnameedit.title=Edit waypoint name
dialog.pointnameedit.name=Waypoint name
dialog.pointnameedit.uppercase=UPPER case
dialog.pointnameedit.lowercase=lower case
@@ -161,6 +192,8 @@ dialog.addtimeoffset.days=Days
dialog.addtimeoffset.hours=Hours
dialog.addtimeoffset.minutes=Minutes
dialog.addtimeoffset.notimestamps=Cannot add a time offset as this selection doesn't contain any timestamp information
+dialog.findwaypoint.intro=Enter part of the waypoint name
+dialog.findwaypoint.search=Search
dialog.connect.title=Connect photo to point
dialog.connectphoto.clonepoint=This point already has a photo.\nDo you want to make a copy of the point?
dialog.saveexif.title=Save Exif
@@ -194,6 +227,11 @@ dialog.setmapbg.osma=Osma
dialog.setmapbg.cyclemap=Cyclemap
dialog.setmapbg.other=Other
dialog.setmapbg.server=Server URL
+dialog.gpsies.column.name=Track name
+dialog.gpsies.column.length=Length
+dialog.gpsies.description=Description
+dialog.gpsies.nodescription=No description
+dialog.gpsies.nonefound=No tracks found
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
@@ -260,6 +298,27 @@ dialog.checkversion.newversion2=.
dialog.checkversion.releasedate1=This new version was released on
dialog.checkversion.releasedate2=.
dialog.checkversion.download=To download the new version, go to http://activityworkshop.net/software/prune/download.html.
+dialog.keys.intro=You can use the following shortcut keys instead of using the mouse
+dialog.keys.keylist=Arrow keys Pan map left right, up, down Ctrl + left, right arrow Select previous or next point Ctrl + up, down arrow Zoom in or out Del Delete current point
+dialog.saveconfig.desc=The following settings can be saved to a configuration file :
+dialog.saveconfig.prune.trackdirectory=Track directory
+dialog.saveconfig.prune.photodirectory=Photo directory
+dialog.saveconfig.prune.languagecode=Language code (EN)
+dialog.saveconfig.prune.gpsdevice=GPS device
+dialog.saveconfig.prune.gpsformat=GPS format
+dialog.saveconfig.prune.povrayfont=Povray font
+dialog.saveconfig.prune.metricunits=Use metric units?
+dialog.saveconfig.prune.gnuplotpath=Path to gnuplot
+dialog.saveconfig.prune.gpsbabelpath=Path to gpsbabel
+dialog.saveconfig.prune.exiftoolpath=Path to exiftool
+dialog.saveconfig.prune.mapserverindex=Index of map server
+dialog.saveconfig.prune.mapserverurl=URL of map server
+dialog.saveconfig.prune.showpace=Show pace
+dialog.saveconfig.prune.kmzimagewidth=KMZ image width
+dialog.saveconfig.prune.kmzimageheight=KMZ image height
+dialog.setpaths.intro=If you need to, you can choose the paths to the external applications:
+dialog.addaltitude.noaltitudes=The selected range does not contain altitudes
+dialog.addaltitude.desc=Altitude offset to add
# 3d window
dialog.3d.title=Prune Three-d view
@@ -278,6 +337,7 @@ confirm.point.edit=point edited
confirm.mergetracksegments=Track segments merged
confirm.reverserange=Range reversed
confirm.addtimeoffset=Time offset added
+confirm.addaltitudeoffset=Altitude offset added
confirm.rearrangewaypoints=Waypoints rearranged
confirm.cutandmove=Selection moved
confirm.saveexif.ok1=Saved
@@ -291,6 +351,7 @@ confirm.photo.disconnect=photo disconnected
confirm.correlate.single=photo was correlated
confirm.correlate.multi=photos were correlated
confirm.createpoint=point created
+confirm.running=Running ...
# Buttons
button.ok=OK
@@ -313,9 +374,10 @@ button.notoall=No to all
button.selectall=Select all
button.selectnone=Select none
button.preview=Preview
+button.load=Load
button.guessfields=Guess fields
button.showwebpage=Show webpage
-button.gnuplotpath=Set gnuplot path
+button.check=Check
# File types
filetype.txt=TXT files
@@ -355,6 +417,7 @@ display.range.time.hours=h
display.range.time.days=d
details.range.avespeed=Ave speed
details.range.avemovingspeed=Moving ave
+details.range.pace=Pace
details.waypointsphotos.waypoints=Waypoints
details.waypointsphotos.photos=Photos
details.photodetails=Photo details
@@ -422,6 +485,7 @@ undo.insert=insert points
undo.reverse=reverse range
undo.mergetracksegments=merge track segments
undo.addtimeoffset=add time offset
+undo.addaltitudeoffset=add altitude offset
undo.rearrangewaypoints=rearrange waypoints
undo.cutandmove=move section
undo.connectphoto=connect photo
@@ -432,7 +496,7 @@ undo.createpoint=create point
# Error messages
error.save.dialogtitle=Error saving data
error.save.nodata=No data to save
-error.save.failed=Failed to save the data to file:
+error.save.failed=Failed to save the data to file
error.saveexif.filenotfound=Failed to find photo file
error.saveexif.cannotoverwrite1=Photo file
error.saveexif.cannotoverwrite2=is read-only and can't be overwritten. Write to copy?
diff --git a/tim/prune/lang/prune-texts_es.properties b/tim/prune/lang/prune-texts_es.properties
index 6dbaddb..b8baa47 100644
--- a/tim/prune/lang/prune-texts_es.properties
+++ b/tim/prune/lang/prune-texts_es.properties
@@ -11,10 +11,9 @@ menu.edit=Editar
menu.edit.undo=Deshacer
menu.edit.clearundo=Despejar la lista de deshacer
menu.edit.editpoint=Editar punto
-menu.edit.editwaypointname=Editar nombre de waypoint
menu.edit.deletepoint=Eliminar punto
menu.edit.deleterange=Eliminar rango
-menu.edit.deletemarked=
+menu.edit.deletemarked=Eliminar puntos marcados
menu.edit.interpolate=Interpolar
menu.edit.average=Crear punto a la media del rango
menu.edit.reverse=Invertir rango
@@ -22,8 +21,8 @@ menu.edit.mergetracksegments=Unir los segmentos de track
menu.edit.rearrange=Reorganizar waypoints
menu.edit.rearrange.start=Volver al comienzo
menu.edit.rearrange.end=Ir al final
-menu.edit.rearrange.nearest=Ir al más próximo
-menu.edit.cutandmove=
+menu.edit.rearrange.nearest=Ir al m\u00e1s pr\u00f3ximo
+menu.edit.cutandmove=Cortar y mover selecci\u00f3n
menu.select=Seleccionar
menu.select.all=Seleccionar todo
menu.select.none=No seleccionar nada
@@ -38,8 +37,10 @@ menu.view=Ver
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.view.browser.mapquest=Mapquest
+menu.view.browser.yahoo=mapas Yahoo
+menu.settings=Preferencias
+menu.settings.showpace=
menu.help=Ayuda
# Popup menu for map
menu.map.zoomin=Ampliar zoom
@@ -47,8 +48,27 @@ menu.map.zoomout=Reducir zoom
menu.map.zoomfull=Mostrar todo
menu.map.newpoint=Crear uno punto nuevo
menu.map.connect=Conectar puntos de track
-menu.map.autopan=Posicionar automáticamente
+menu.map.autopan=Posicionar autom\u00e1ticamente
menu.map.showmap=Mostrar el mapa
+menu.map.showscalebar=
+
+# Alt keys for menus
+altkey.menu.file=A
+altkey.menu.edit=E
+altkey.menu.select=S
+altkey.menu.view=V
+altkey.menu.photo=F
+altkey.menu.settings=P
+altkey.menu.help=Y
+
+# Ctrl shortcuts for menu items
+shortcut.menu.file.open=A
+shortcut.menu.file.load=C
+shortcut.menu.file.save=G
+shortcut.menu.edit.undo=Z
+shortcut.menu.edit.compress=C
+shortcut.menu.select.all=T
+shortcut.menu.help.help=H
# Functions
function.loadfromgps=Cargar datos del GPS
@@ -56,16 +76,24 @@ 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.editwaypointname=Editar nombre de waypoint
+function.compress=Comprimir track
+function.addtimeoffset=A\u00f1adir compensar tiempo
+function.addaltitudeoffset=A\u00f1adir compensar altitud
+function.findwaypoint=Buscar waypoint
function.charts=Diagramas
function.show3d=Mostrar en 3-D
function.distances=Distancias
-function.setmapbg=Configurar fondo de mapa
+function.getgpsies=Bajar ruta de Gpsies
function.correlatephotos=Correlacionar fotos
+function.setmapbg=Configurar fondo de mapa
+function.setkmzimagesize=Configurar tama\u00f1os de las im\u00e1genes KMZ
+function.setpaths=Configurar rutas del programas
function.help=Ayuda
+function.showkeys=
function.about=Acerca de Prune
-function.checkversion=Buscar una nueva versión
+function.checkversion=Buscar una nueva versi\u00f3n
+function.saveconfig=Guardar preferencias
# Dialogs
dialog.exit.confirm.title=Salir de Prune
@@ -80,7 +108,7 @@ dialog.openoptions.title=Opciones de abrir
dialog.openoptions.filesnippet=Extraer archivo
dialog.load.table.field=Campo
dialog.load.table.datatype=Tipo de datos
-dialog.load.table.description=Descripción
+dialog.load.table.description=Descripci\u00f3n
dialog.delimiter.label=Separador de campo
dialog.delimiter.comma=Coma ,
dialog.delimiter.tab=Tabulador
@@ -93,14 +121,14 @@ dialog.openoptions.deliminfo.norecords=Ningun dato
dialog.openoptions.altitudeunits=Unidades altitud
dialog.jpegload.subdirectories=Incluir subdirectorios
dialog.jpegload.loadjpegswithoutcoords=Fotos sin coordenadas tambien
-dialog.jpegload.loadjpegsoutsidearea=
+dialog.jpegload.loadjpegsoutsidearea=Incluir fotos fuera del \u00e1rea
dialog.jpegload.progress.title=Cargando fotos
dialog.jpegload.progress=Por favor espere mientras se buscan las fotos
dialog.gpsload.nogpsbabel=gpsbabel program no encontrado. Desea continuar?
dialog.gpsload.device=
-dialog.gpsload.format=
-dialog.gpsload.getwaypoints=
-dialog.gpsload.gettracks=
+dialog.gpsload.format=Formato
+dialog.gpsload.getwaypoints=Cargar waypoints
+dialog.gpsload.gettracks=Cargar tracks
dialog.gpssend.sendwaypoints=
dialog.gpssend.sendtracks=
dialog.gpssend.trackname=Nombre del track
@@ -109,51 +137,54 @@ dialog.save.fieldstosave=Campos a guardar
dialog.save.table.field=Campo
dialog.save.table.hasdata=Contiene datos
dialog.save.table.save=Guardar
-dialog.save.headerrow=Título fila
+dialog.save.headerrow=T\u00edtulo fila
dialog.save.coordinateunits=Unidades de las coordenadas
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.text=Descripción para los datos
-dialog.exportkml.altitude=Incluir altitudes (para aviación)
+dialog.exportkml.text=Descripci\u00f3n para los datos
+dialog.exportkml.altitude=Absoluta altitudes (para aviaci\u00f3n)
dialog.exportkml.kmz=Comprimir al archivo kmz
dialog.exportkml.exportimages=Exportar fotos al kmz
dialog.exportgpx.name=Nombre
-dialog.exportgpx.desc=Descripción
+dialog.exportgpx.desc=Descripci\u00f3n
dialog.exportgpx.includetimestamps=Tiempo tambien
dialog.exportpov.text=Introdzca los Parametros para exportar
dialog.exportpov.font=Fuente
-dialog.exportpov.camerax=Cámara X
-dialog.exportpov.cameray=Cámara Y
-dialog.exportpov.cameraz=Cámara Z
-dialog.exportpov.modelstyle=
-dialog.exportpov.ballsandsticks=
-dialog.exportpov.tubesandwalls=
-dialog.exportpov.warningtracksize=Este track contiene un gran numero de puntos. Puede ser que Java3D no los pueda visualizar. Está seguro de que desea continuar?
-dialog.confirmreversetrack.title=Confirmar inversión
-dialog.confirmreversetrack.text=Este track contiene información sobre la fecha, que estará fuera de secuencia después de la inversión. Esta seguro que desea invertir esta sección?
+dialog.exportpov.camerax=C\u00e1mara X
+dialog.exportpov.cameray=C\u00e1mara Y
+dialog.exportpov.cameraz=C\u00e1mara Z
+dialog.exportpov.modelstyle=Estilo
+dialog.exportpov.ballsandsticks=Balas en palos
+dialog.exportpov.tubesandwalls=Tubos y paredes
+dialog.exportpov.warningtracksize=Este track contiene un gran numero de puntos. Puede ser que Java3D no los pueda visualizar. Est\u00e1 seguro de que desea continuar?
+dialog.pointtype.desc=
+dialog.pointtype.track=
+dialog.pointtype.waypoint=
+dialog.pointtype.photo=
+dialog.confirmreversetrack.title=Confirmar inversi\u00f3n
+dialog.confirmreversetrack.text=Este track contiene informaci\u00f3n sobre la fecha, que estar\u00e1 fuera de secuencia despu\u00e9s de la inversi\u00f3n. Esta seguro que desea invertir esta secci\u00f3n?
dialog.confirmcutandmove.title=Confirmar ...
-dialog.confirmcutandmove.text=Este track contiene información sobre la fecha, que estará fuera de secuencia después de la .... Esta seguro que desea ... esta sección?
+dialog.confirmcutandmove.text=Este track contiene informaci\u00f3n sobre la fecha, que estar\u00e1 fuera de secuencia despu\u00e9s de la .... Esta seguro que desea ... esta secci\u00f3n?
dialog.interpolate.title=Interpolar puntos
-dialog.interpolate.parameter.text=Número de los puntos a insertar entre los puntos elegidos
+dialog.interpolate.parameter.text=N\u00famero de los puntos a insertar entre los puntos elegidos
dialog.undo.title=Deshacer
-dialog.undo.pretext=Por favor, seleccione la operación(es) a deshacer
+dialog.undo.pretext=Por favor, seleccione la operaci\u00f3n(es) a deshacer
dialog.undo.none.title=No se puede deshacer
-dialog.undo.none.text=Ninguna operación a deshacer
+dialog.undo.none.text=Ninguna operaci\u00f3n a deshacer
dialog.clearundo.title=Despejar la lista de deshacer
-dialog.clearundo.text=Esta seguro que desea despejar la lista de deshacer?, se perderá toda la información!
+dialog.clearundo.text=Esta seguro que desea despejar la lista de deshacer?, se perder\u00e1 toda la informaci\u00f3n!
dialog.pointedit.title=Editar punto
-dialog.pointedit.text=Seleccione cada campo a editar y use el botón 'Editar' para modificar el valor
+dialog.pointedit.text=Seleccione cada campo a editar y use el bot\u00f3n 'Editar' para modificar el valor
dialog.pointedit.table.field=Campo
dialog.pointedit.table.value=Valor
dialog.pointedit.table.changed=Modificado
dialog.pointedit.changevalue.text=Introduzca el nuevo valor de campo
dialog.pointedit.changevalue.title=Editar campo
-dialog.pointnameedit.title=Editar nombre de waypoint
dialog.pointnameedit.name=Nombre de waypoint
-dialog.pointnameedit.uppercase=Mayúsculas
-dialog.pointnameedit.lowercase=minúsculas
+dialog.pointnameedit.uppercase=May\u00fasculas
+dialog.pointnameedit.lowercase=min\u00fasculas
dialog.pointnameedit.sentencecase=Mezcla
dialog.addtimeoffset.add=
dialog.addtimeoffset.subtract=
@@ -161,6 +192,8 @@ dialog.addtimeoffset.days=Dias
dialog.addtimeoffset.hours=Horas
dialog.addtimeoffset.minutes=Minutos
dialog.addtimeoffset.notimestamps=
+dialog.findwaypoint.intro=
+dialog.findwaypoint.search=
dialog.connect.title=Conectar foto
dialog.connectphoto.clonepoint=
dialog.saveexif.title=Guardar Exif
@@ -176,7 +209,7 @@ dialog.saveexif.photostatus.modified=Modificada
dialog.saveexif.overwrite=Sobreescribirlar archivos?
dialog.charts.xaxis=Eje de abscisas
dialog.charts.yaxis=Eje vertical
-dialog.charts.output=
+dialog.charts.output=Resultado
dialog.charts.screen=
dialog.charts.svg=
dialog.charts.svgwidth=
@@ -194,29 +227,34 @@ 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.gpsies.column.name=Nombre
+dialog.gpsies.column.length=
+dialog.gpsies.description=Descripci\u00f3n
+dialog.gpsies.nodescription=Ning\u00fan descripci\u00f3n
+dialog.gpsies.nonefound=
+dialog.correlate.notimestamps=No hay informaci\u00f3n de tiempo para los puntos, as\u00ed que no hay nada que correlacionar con las fotos.
+dialog.correlate.nouncorrelatedphotos=No hay fotos no correlacionadas.\nEst\u00e1 seguro de que desea continuar?
dialog.correlate.photoselect.intro=Seleccione una de estas fotos correlacionadas para usar como margen de tiempo
dialog.correlate.photoselect.photoname=Nombre de la foto
dialog.correlate.photoselect.timediff=Diferencia de tiempo
-dialog.correlate.photoselect.photolater=Foto más adelante
-dialog.correlate.options.tip=Sugerencia: Correlacionando al menos una foto manualmente, el margen de tiempo se calcula automáticamente.
-dialog.correlate.options.intro=Seleccionar las opciones para correlación automática
+dialog.correlate.photoselect.photolater=Foto m\u00e1s adelante
+dialog.correlate.options.tip=Sugerencia: Correlacionando al menos una foto manualmente, el margen de tiempo se calcula autom\u00e1ticamente.
+dialog.correlate.options.intro=Seleccionar las opciones para correlaci\u00f3n autom\u00e1tica
dialog.correlate.options.offsetpanel=Margen de tiempo
dialog.correlate.options.offset=Margen
dialog.correlate.options.offset.hours=horas,
dialog.correlate.options.offset.minutes=minutos y
dialog.correlate.options.offset.seconds=segundos
-dialog.correlate.options.photolater=Foto después de punto
-dialog.correlate.options.pointlater=Punto después de foto
-dialog.correlate.options.limitspanel=Límites de correlación
-dialog.correlate.options.notimelimit=Sin límite de tiempo
-dialog.correlate.options.timelimit=Límite de tiempo
-dialog.correlate.options.nodistancelimit=Sin límite de distancia
-dialog.correlate.options.distancelimit=Límite de distancia
+dialog.correlate.options.photolater=Foto despu\u00e9s de punto
+dialog.correlate.options.pointlater=Punto despu\u00e9s de foto
+dialog.correlate.options.limitspanel=L\u00edmites de correlaci\u00f3n
+dialog.correlate.options.notimelimit=Sin l\u00edmite de tiempo
+dialog.correlate.options.timelimit=L\u00edmite de tiempo
+dialog.correlate.options.nodistancelimit=Sin l\u00edmite de distancia
+dialog.correlate.options.distancelimit=L\u00edmite 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.correlate.alloutsiderange=Todas las fotos est\u00e1n 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\u00fan punto eliminado
dialog.compress.duplicates.title=Eliminar duplicados
dialog.compress.closepoints.title=
dialog.compress.closepoints.paramdesc=
@@ -225,14 +263,14 @@ 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.version=Versión
+dialog.help.help=Por favor, ver\n http://activityworkshop.net/software/prune/\npara m\u00e1s informaci\u00f3n y gu\u00edas del usuario.
+dialog.about.version=Versi\u00f3n
dialog.about.build=Construir
dialog.about.summarytext1=Prune es un programa para cargar, mostrar y editar datos de receptores GPS.
-dialog.about.summarytext2=Distribuido bajo el GNU GPL para uso libre y gratuito. Se permite (y se anima) la copia, redistribución y modificación de acuerdo a las condiciones incluidas en el archivo licence.txt
.
-dialog.about.summarytext3=Por favor, ver http://activityworkshop.net/
para más información y guías del usuario.
-dialog.about.languages=
-dialog.about.translatedby=Traducción al español realizada por activityworkshop y amigos muy amables!
+dialog.about.summarytext2=Distribuido bajo el GNU GPL para uso libre y gratuito. Se permite (y se anima) la copia, redistribuci\u00f3n y modificaci\u00f3n de acuerdo a las condiciones incluidas en el archivo licence.txt
.
+dialog.about.summarytext3=Por favor, ver http://activityworkshop.net/
para m\u00e1s informaci\u00f3n y gu\u00edas del usuario.
+dialog.about.languages=Idiomas disponibles
+dialog.about.translatedby=Traducci\u00f3n al espa\u00f1ol realizada por activityworkshop y amigos muy amables!
dialog.about.systeminfo=Informacion del sistema
dialog.about.systeminfo.os=Sistema operativo
dialog.about.systeminfo.java=Java Runtime
@@ -244,11 +282,11 @@ dialog.about.systeminfo.gnuplot=Gnuplot instalado
dialog.about.yes=Si
dialog.about.no=No
dialog.about.credits=Credits
-dialog.about.credits.code=El código de Prune fue escrito por
-dialog.about.credits.exifcode=El código Exif por
+dialog.about.credits.code=El c\u00f3digo de Prune fue escrito por
+dialog.about.credits.exifcode=El c\u00f3digo Exif por
dialog.about.credits.icons=Algunos iconos se tomaron de
dialog.about.credits.translators=Traductores
-dialog.about.credits.translations=Ayuda en la traducción
+dialog.about.credits.translations=Ayuda en la traducci\u00f3n
dialog.about.credits.devtools=Herramientas de desarrollo
dialog.about.credits.othertools=Otras herramientas
dialog.about.credits.thanks=Gracias a
@@ -260,13 +298,34 @@ 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.keys.intro=
+dialog.keys.keylist=
+dialog.saveconfig.desc=
+dialog.saveconfig.prune.trackdirectory=
+dialog.saveconfig.prune.photodirectory=
+dialog.saveconfig.prune.languagecode=
+dialog.saveconfig.prune.gpsdevice=
+dialog.saveconfig.prune.gpsformat=
+dialog.saveconfig.prune.povrayfont=Fuente povray
+dialog.saveconfig.prune.metricunits=
+dialog.saveconfig.prune.gnuplotpath=
+dialog.saveconfig.prune.gpsbabelpath=
+dialog.saveconfig.prune.exiftoolpath=
+dialog.saveconfig.prune.mapserverindex=
+dialog.saveconfig.prune.mapserverurl=
+dialog.saveconfig.prune.showpace=
+dialog.saveconfig.prune.kmzimagewidth=
+dialog.saveconfig.prune.kmzimageheight=
+dialog.setpaths.intro=
+dialog.addaltitude.noaltitudes=
+dialog.addaltitude.desc=
# 3d window
dialog.3d.title=Prune vista 3-D
dialog.3d.altitudecap=Escala de las altitudes
-dialog.3dlines.title=Cuadrícula Prune
-dialog.3dlines.empty=No hay ninguna cuadrícula!
-dialog.3dlines.intro=Información de la cuadrícula
+dialog.3dlines.title=Cuadr\u00edcula Prune
+dialog.3dlines.empty=No hay ninguna cuadr\u00edcula!
+dialog.3dlines.intro=Informaci\u00f3n de la cuadr\u00edcula
# Confirm messages || These are displayed as confirmation in the status bar
confirm.loadfile=Dato cargado de
@@ -278,19 +337,21 @@ confirm.point.edit=Punto editado
confirm.mergetracksegments=Segmentos unidos
confirm.reverserange=Rango invertido
confirm.addtimeoffset=
+confirm.addaltitudeoffset=
confirm.rearrangewaypoints=Waypoints reorganizados
confirm.cutandmove=
confirm.saveexif.ok1=Guardando
confirm.saveexif.ok2=fotos
-confirm.undo.single=operación no realizada
-confirm.undo.multi=operación(es) no realizada(s)
+confirm.undo.single=operaci\u00f3n no realizada
+confirm.undo.multi=operaci\u00f3n(es) no realizada(s)
confirm.jpegload.single=Foto incluida
confirm.jpegload.multi=Fotos incluidas
confirm.photo.connect=Foto conectado
confirm.photo.disconnect=Foto desconectado
confirm.correlate.single=foto fue correlada
confirm.correlate.multi=fotos fueron correladas
-confirm.createpoint=
+confirm.createpoint=punto creado
+confirm.running=Trabajando ...
# Buttons
button.ok=Aceptar
@@ -301,21 +362,22 @@ button.cancel=Cancelar
button.overwrite=Sobreescribir
button.moveup=Mover hacia arriba
button.movedown=Mover hacia abajo
-button.showlines=Mostrar cuadrícula
+button.showlines=Mostrar cuadr\u00edcula
button.edit=Editar
button.exit=Salir
button.close=Cerrar
-button.continue=Continúe
+button.continue=Contin\u00fae
button.yes=Si
button.no=No
button.yestoall=Si por todo
button.notoall=No por todo
button.selectall=Seleccionar todo
button.selectnone=Seleccionar nada
-button.preview=Previsualización
+button.preview=Previsualizaci\u00f3n
+button.load=Cargar
button.guessfields=Adivinar campos
-button.showwebpage=
-button.gnuplotpath=
+button.showwebpage=Mostrar p\u00e1gina web
+button.check=Verificar
# File types
filetype.txt=Archivos TXT
@@ -328,19 +390,19 @@ filetype.pov=Archivos POV
filetype.svg=Archivos SVG
# Display components
-display.nodata=Ningún dato cargado
+display.nodata=Ning\u00fan dato cargado
display.noaltitudes=Los datos del track no incluyen altitudes
details.trackdetails=Detalles del track
-details.notrack=Ningún track cargado
+details.notrack=Ning\u00fan track cargado
details.track.points=Puntos
details.track.file=Archivo
-details.track.numfiles=Número de archivos
+details.track.numfiles=N\u00famero de archivos
details.pointdetails=Detalles del punto
details.index.selected=Indice seleccionado
details.index.of=de
-details.nopointselection=Ningún punto seleccionado
+details.nopointselection=Ning\u00fan punto seleccionado
details.photofile=Archivo de fotos
-details.norangeselection=Ningún rango seleccionado
+details.norangeselection=Ning\u00fan rango seleccionado
details.rangedetails=Detalles del rango
details.range.selected=Rango seleccionado
details.range.to=hacia
@@ -355,6 +417,7 @@ display.range.time.hours=h
display.range.time.days=d
details.range.avespeed=Velocidad media
details.range.avemovingspeed=
+details.range.pace=
details.waypointsphotos.waypoints=Waypoints
details.waypointsphotos.photos=Fotos
details.photodetails=Detalles del Foto
@@ -367,7 +430,7 @@ map.overzoom=
fieldname.latitude=Latitud
fieldname.longitude=Longitud
fieldname.altitude=Altitud
-fieldname.timestamp=Información de tiempo
+fieldname.timestamp=Informaci\u00f3n de tiempo
fieldname.time=Tiempo
fieldname.waypointname=Nombre
fieldname.waypointtype=Tipo
@@ -376,9 +439,9 @@ fieldname.custom=Personalizado
fieldname.prefix=Campo
fieldname.distance=Distancia
fieldname.movingdistance=
-fieldname.duration=Duración
+fieldname.duration=Duraci\u00f3n
fieldname.speed=Velocidad
-fieldname.verticalspeed=
+fieldname.verticalspeed=Velocidad vertical
# Measurement units
units.original=Original
@@ -387,7 +450,7 @@ units.metres=Metros
units.metres.short=m
units.feet=Pies
units.feet.short=ft
-units.kilometres=Kilómetros
+units.kilometres=Kil\u00f3metros
units.kilometres.short=km
units.kmh=km/h
units.miles=Millas
@@ -422,6 +485,7 @@ undo.insert=insertar puntos
undo.reverse=invertir rango
undo.mergetracksegments=unir los segmentos de track
undo.addtimeoffset=
+undo.addaltitudeoffset=
undo.rearrangewaypoints=reordenar waypoints
undo.cutandmove=
undo.connectphoto=conectar foto
@@ -431,29 +495,29 @@ undo.createpoint=crear punto
# Error messages
error.save.dialogtitle=Fallo al guardar datos
-error.save.nodata=Ningún dato salvado
-error.save.failed=Fallo al guardar datos al archivo:
+error.save.nodata=Ning\u00fan dato salvado
+error.save.failed=Fallo al guardar datos al archivo
error.saveexif.filenotfound=Archivo no encontrado
error.saveexif.cannotoverwrite1=No se puede guardar
error.saveexif.cannotoverwrite2=. Guardar a una copia?
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.nopoints=Ninguna informaci\u00f3n coordenadas encontrada
error.load.unknownxml=Formato xml no reconocido:
-error.load.noxmlinzip=
+error.load.noxmlinzip=Ning\u00fan xml archivo encontrado
error.load.othererror=Fallo al cargar datos:
error.jpegload.dialogtitle=Error cargando fotos
-error.jpegload.nofilesfound=Ningún archivo encontrado
-error.jpegload.nojpegsfound=Ningún archivo jpeg encontrado
-error.jpegload.noexiffound=Ninguna información EXIF encontrada
-error.jpegload.nogpsfound=Ninguna información GPS encontrada
+error.jpegload.nofilesfound=Ning\u00fan archivo encontrado
+error.jpegload.nojpegsfound=Ning\u00fan archivo jpeg encontrado
+error.jpegload.noexiffound=Ninguna informaci\u00f3n EXIF encontrada
+error.jpegload.nogpsfound=Ninguna informaci\u00f3n GPS encontrada
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.notavailable.title=Función no disponible
-error.function.nojava3d=Esta función requiere la librería Java3d, disponible en Sun.com.
-error.3d=Ha ocurrido un error con la función 3-D
+error.undofailed.text=No ha sido posible deshacer la operaci\u00f3n
+error.function.noop.title=La funci\u00f3n no se ha efectuado
+error.rearrange.noop=Reordenaci\u00f3n de waypoints no se ha efectuado
+error.function.notavailable.title=Funci\u00f3n no disponible
+error.function.nojava3d=Esta funci\u00f3n requiere la librer\u00eda Java3d, disponible en Sun.com.
+error.3d=Ha ocurrido un error con la funci\u00f3n 3-D
error.readme.notfound=Archivo readme no encontrado
error.osmimage.dialogtitle=Error al cargar el mapa
-error.osmimage.failed=Imposible cargar el mapa. Por favor, compruebe la conexión a internet.
+error.osmimage.failed=Imposible cargar el mapa. Por favor, compruebe la conexi\u00f3n a internet.
diff --git a/tim/prune/lang/prune-texts_fr.properties b/tim/prune/lang/prune-texts_fr.properties
index c76eb66..a3e16ec 100644
--- a/tim/prune/lang/prune-texts_fr.properties
+++ b/tim/prune/lang/prune-texts_fr.properties
@@ -7,32 +7,31 @@ menu.file.open=Ouvrir fichier
menu.file.addphotos=Ajouter photos
menu.file.save=Enregistrer
menu.file.exit=Quitter
-menu.edit=Édition
+menu.edit=\u00c9dition
menu.edit.undo=Annuler
menu.edit.clearundo=Purger la liste d'annulation
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.deletemarked=Supprimer les points marqués
+menu.edit.deleterange=Supprimer l'\u00e9tendue
+menu.edit.deletemarked=Supprimer les points marqu\u00e9s
menu.edit.interpolate=Interpoler
-menu.edit.average=Créer un point pour la sélection
-menu.edit.reverse=Inverser l'étendue
+menu.edit.average=Cr\u00e9er un point pour la s\u00e9lection
+menu.edit.reverse=Inverser l'\u00e9tendue
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=R\u00e9arranger les waypoints
+menu.edit.rearrange.start=Tous au d\u00e9but du fichier
+menu.edit.rearrange.end=Tous \u00e0 la fin du fichier
menu.edit.rearrange.nearest=Chacun au point de trace le plus proche
-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
-menu.select.start=Définir le début de l'étendue
-menu.select.end=Définir la fin de l'étendue
+menu.edit.cutandmove=Couper et bouger la s\u00e9lection
+menu.select=S\u00e9lectionner
+menu.select.all=Tout s\u00e9lectionner
+menu.select.none=Rien s\u00e9lectionner
+menu.select.start=D\u00e9finir le d\u00e9but de l'\u00e9tendue
+menu.select.end=D\u00e9finir la fin de l'\u00e9tendue
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.disconnect=D\u00e9tacher du point
menu.photo.delete=Retirer la photo
menu.view=Affichage
menu.view.browser=Ouvrir la carte dans le navigateur
@@ -40,48 +39,77 @@ menu.view.browser.google=Google maps
menu.view.browser.openstreetmap=Openstreetmap
menu.view.browser.mapquest=Mapquest
menu.view.browser.yahoo=Yahoo maps
+menu.settings=Pr\u00e9f\u00e9rences
+menu.settings.showpace=Montrer allure dans les d\u00e9tails
menu.help=Aide
# Popup menu for map
menu.map.zoomin=Zoom avant
-menu.map.zoomout=Zoom arrière
-menu.map.zoomfull=Adapter à la vue
+menu.map.zoomout=Zoom arri\u00e8re
+menu.map.zoomfull=Adapter \u00e0 la vue
menu.map.newpoint=Ajouter un point
menu.map.connect=Relier les points de trace
-menu.map.autopan=Déplacement automatique
+menu.map.autopan=D\u00e9placement automatique
menu.map.showmap=Montrer la carte
+menu.map.showscalebar=Montrer l'echelle
+
+# Alt keys for menus
+altkey.menu.file=F
+altkey.menu.edit=E
+altkey.menu.select=S
+altkey.menu.view=A
+altkey.menu.photo=P
+altkey.menu.settings=R
+altkey.menu.help=I
+
+# Ctrl shortcuts for menu items
+shortcut.menu.file.open=O
+shortcut.menu.file.load=T
+shortcut.menu.file.save=E
+shortcut.menu.edit.undo=Z
+shortcut.menu.edit.compress=C
+shortcut.menu.select.all=S
+shortcut.menu.help.help=A
# Functions
-function.loadfromgps=Télécharger du GPS
+function.loadfromgps=T\u00e9l\u00e9charger du GPS
function.sendtogps=Envoyer au GPS
function.exportkml=Exporter en KML
function.exportgpx=Exporter en GPX
function.exportpov=Exporter en POV
+function.editwaypointname=Editer le nom du waypoint
function.compress=Compresser la trace
-function.addtimeoffset=Ajouter un décalage d'horaire
+function.addtimeoffset=Ajouter un d\u00e9calage d'horaire
+function.addaltitudeoffset=Ajouter un d\u00e9calage d'altitude
+function.findwaypoint=Trouver un waypoint
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.getgpsies=R\u00e9cup\u00e9rer les traces Gpsies
+function.correlatephotos=Corr\u00e9ler les photos
+function.setmapbg=D\u00e9finir le fond de carte
+function.setkmzimagesize=D\u00e9finir la taille de l'image KMZ
+function.setpaths=D\u00e9finir les chemins des programmes
function.help=Aide
+function.showkeys=Montrer les raccourcis clavier
function.about=À propos de Prune
-function.checkversion=Chercher une mise à jour
+function.checkversion=Chercher une mise \u00e0 jour
+function.saveconfig=Enregistrer les pr\u00e9f\u00e9rences
# Dialogs
dialog.exit.confirm.title=Quitter Prune
-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.exit.confirm.text=Les donn\u00e9es ont \u00e9t\u00e9 modifi\u00e9es. Souhaitez-vous quitter Prune sans les enregistrer ?
+dialog.openappend.title=Ajouter aux donn\u00e9es existantes
+dialog.openappend.text=Ajouter aux donn\u00e9es d\u00e9j\u00e0 charg\u00e9es ?
dialog.deletepoint.title=Effacer le point
-dialog.deletepoint.deletephoto=Effacer la photo attachée à ce point ?
+dialog.deletepoint.deletephoto=Effacer la photo attach\u00e9e \u00e0 ce point ?
dialog.deletephoto.title=Effacer la photo
-dialog.deletephoto.deletepoint=Effacer le point attaché à cette photo ?
+dialog.deletephoto.deletepoint=Effacer le point attach\u00e9 \u00e0 cette photo ?
dialog.openoptions.title=Ouvrir options
dialog.openoptions.filesnippet=Extrait de fichier
dialog.load.table.field=Champ
-dialog.load.table.datatype=Type de donnée
+dialog.load.table.datatype=Type de donn\u00e9e
dialog.load.table.description=Description
-dialog.delimiter.label=Séparateur de texte
+dialog.delimiter.label=S\u00e9parateur de texte
dialog.delimiter.comma=Virgule ,
dialog.delimiter.tab=Tabulation
dialog.delimiter.space=Espace
@@ -90,67 +118,70 @@ dialog.delimiter.other=Autres
dialog.openoptions.deliminfo.records=enregistrements, avec
dialog.openoptions.deliminfo.fields=champs
dialog.openoptions.deliminfo.norecords=Pas d'enregistrements
-dialog.openoptions.altitudeunits=Unités d'altitude
+dialog.openoptions.altitudeunits=Unit\u00e9s d'altitude
dialog.jpegload.subdirectories=Inclure les sous-dossiers
-dialog.jpegload.loadjpegswithoutcoords=Inclure les photos sans coordonnées
+dialog.jpegload.loadjpegswithoutcoords=Inclure les photos sans coordonn\u00e9es
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.nogpsbabel=Gpsbabel introuvable. Continuer ?
-dialog.gpsload.device=Chemin du périphérique
+dialog.gpsload.device=Chemin du p\u00e9riph\u00e9rique
dialog.gpsload.format=Format
-dialog.gpsload.getwaypoints=Télécharger les waypoints
-dialog.gpsload.gettracks=Télécharger les traces
+dialog.gpsload.getwaypoints=T\u00e9l\u00e9charger les waypoints
+dialog.gpsload.gettracks=T\u00e9l\u00e9charger 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.fieldstosave=Champs \u00e0 enregistrer
dialog.save.table.field=Champ
-dialog.save.table.hasdata=Possède une information
+dialog.save.table.hasdata=Poss\u00e8de une information
dialog.save.table.save=Enregistrer
-dialog.save.headerrow=Entêtes
-dialog.save.coordinateunits=Unités des coordonnées
-dialog.save.altitudeunits=Unités d'altitude
+dialog.save.headerrow=Ent\u00eates
+dialog.save.coordinateunits=Unit\u00e9s des coordonn\u00e9es
+dialog.save.altitudeunits=Unit\u00e9s d'altitude
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.text=Titre pour les données
-dialog.exportkml.altitude=Inclure les altitudes (pour aviation)
+dialog.save.overwrite.title=Le fichier existe d\u00e9j\u00e0
+dialog.save.overwrite.text=Ce fichier existe d\u00e9j\u00e0. \u00cates-vous s\u00fbr de vouloir \u00e9craser ce fichier ?
+dialog.exportkml.text=Titre pour les donn\u00e9es
+dialog.exportkml.altitude=Absolues altitudes (pour aviation)
dialog.exportkml.kmz=Compresser au format kmz
dialog.exportkml.exportimages=Exporter les vignettes au format kmz
dialog.exportgpx.name=Nom
-dialog.exportgpx.desc=Légende
+dialog.exportgpx.desc=L\u00e9gende
dialog.exportgpx.includetimestamps=Inclure l'heure pour chaque point
-dialog.exportpov.text=Entrez les paramètres pour l'export POV
+dialog.exportpov.text=Entrez les param\u00e8tres pour l'export POV
dialog.exportpov.font=Police
-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.camerax=Cam\u00e9ra X
+dialog.exportpov.cameray=Cam\u00e9ra Y
+dialog.exportpov.cameraz=Cam\u00e9ra Z
+dialog.exportpov.modelstyle=Style du mod\u00e8le
+dialog.exportpov.ballsandsticks=Points et b\u00e2tons
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.exportpov.warningtracksize=Cette trace poss\u00e8de un grand nombre de points, Java3D peut ne pas pouvoir l'afficher.\n\u00cates-vous s\u00fbr de vouloir continuer ?
+dialog.pointtype.desc=Sauvegarder ces types de points:
+dialog.pointtype.track=Points de la trace
+dialog.pointtype.waypoint=Waypoints
+dialog.pointtype.photo=Points de photos
dialog.confirmreversetrack.title=Confirmer l'inversion
-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.confirmreversetrack.text=Cette trace contient des informations temporelles qui seront d\u00e9sordonn\u00e9es apr\u00e8s une inversion.\n\u00cates-vous s\u00fbr de vouloir inverser cette section ?
+dialog.confirmcutandmove.title=Confirmer le d\u00e9placement
+dialog.confirmcutandmove.text=Cette trace contient des informations temporelles qui seront d\u00e9sordonn\u00e9es apr\u00e8s un d\u00e9placement.\n\u00cates-vous s\u00fbr de vouloir d\u00e9placer cette section ?
dialog.interpolate.title=Interpoler les points
-dialog.interpolate.parameter.text=Nombre de points à insérer entre les points sélectionnés
+dialog.interpolate.parameter.text=Nombre de points \u00e0 ins\u00e9rer entre les points s\u00e9lectionn\u00e9s
dialog.undo.title=Annuler les actions
-dialog.undo.pretext=Sélectionnez les actions à annuler
+dialog.undo.pretext=S\u00e9lectionnez les actions \u00e0 annuler
dialog.undo.none.title=Annulation impossible
-dialog.undo.none.text=Pas d'opération à annuler !
+dialog.undo.none.text=Pas d'op\u00e9ration \u00e0 annuler !
dialog.clearundo.title=Purger la liste d'annulation
-dialog.clearundo.text=Etes-vous sûr de vouloir effacer la liste d'annulation ?\nToutes les informations d'annulation seront perdues !
+dialog.clearundo.text=Etes-vous s\u00fbr de vouloir effacer la liste d'annulation ?\nToutes les informations d'annulation seront perdues !
dialog.pointedit.title=Editer le point
-dialog.pointedit.text=Sélectionner chaque champ à éditer et utiliser le bouton 'Editer' pour changer la valeur
+dialog.pointedit.text=S\u00e9lectionner chaque champ \u00e0 \u00e9diter et utiliser le bouton 'Editer' pour changer la valeur
dialog.pointedit.table.field=Champ
dialog.pointedit.table.value=Valeur
-dialog.pointedit.table.changed=Changé
+dialog.pointedit.table.changed=Chang\u00e9
dialog.pointedit.changevalue.text=Entrer la nouvelle valeur pour ce champ
dialog.pointedit.changevalue.title=Editer le champ
-dialog.pointnameedit.title=Editer le nom de waypoint
dialog.pointnameedit.name=Nom de waypoint
dialog.pointnameedit.uppercase=CASSE MAJUSCULES
dialog.pointnameedit.lowercase=casse minuscules
@@ -160,137 +191,167 @@ dialog.addtimeoffset.subtract=Avancer l'heure
dialog.addtimeoffset.days=Jours
dialog.addtimeoffset.hours=Heures
dialog.addtimeoffset.minutes=Minutes
-dialog.addtimeoffset.notimestamps=Ne peut pas décaler l'heure; cette sélection ne contient pas de données d'heure
+dialog.addtimeoffset.notimestamps=Ne peut pas d\u00e9caler l'heure; cette s\u00e9lection ne contient pas de donn\u00e9es d'heure
+dialog.findwaypoint.intro=Entrez une partie du nom de waypoint
+dialog.findwaypoint.search=Chercher
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.connectphoto.clonepoint=Ce point est d\u00e9j\u00e0 li\u00e9 \u00e0 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
+dialog.saveexif.intro=S\u00e9lectionner les photos \u00e0 sauver \u00e0 l'aide des cases \u00e0 cocher
+dialog.saveexif.nothingtosave=Coordonn\u00e9es inchang\u00e9es, rien \u00e0 enregistrer
dialog.saveexif.noexiftool=Exiftool introuvable. Continuer ?
dialog.saveexif.table.photoname=Nom de la photo
dialog.saveexif.table.status=Statut
dialog.saveexif.table.save=Enregistrer
-dialog.saveexif.photostatus.connected=Connecté
-dialog.saveexif.photostatus.disconnected=Déconnecté
-dialog.saveexif.photostatus.modified=Modifié
+dialog.saveexif.photostatus.connected=Connect\u00e9
+dialog.saveexif.photostatus.disconnected=D\u00e9connect\u00e9
+dialog.saveexif.photostatus.modified=Modifi\u00e9
dialog.saveexif.overwrite=Ecraser les fichiers
dialog.charts.xaxis=Axe des x
dialog.charts.yaxis=Axe des y
dialog.charts.output=Sortie
-dialog.charts.screen=Sortie sur écran
+dialog.charts.screen=Sortie sur \u00e9cran
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.needaltitudeortimes=La trace ne peut g\u00e9n\u00e9rer 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.charts.gnuplotnotfound=Gnuplot est introuvable dans le chemin indiqu\u00e9
+dialog.distances.intro=Distances \u00e0 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.mapnik=Mapnik (d\u00e9faut)
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
+dialog.gpsies.column.name=Nom de trace
+dialog.gpsies.column.length=Distance
+dialog.gpsies.description=Description
+dialog.gpsies.nodescription=Aucune description
+dialog.gpsies.nonefound=Aucun trace trouv\u00e9
+dialog.correlate.notimestamps=Les points n'ont pas d'indication de temps, il n'est pas possible de les corr\u00e9ler.
+dialog.correlate.nouncorrelatedphotos=Il n'y a pas de photos non-corr\u00e9l\u00e9es.\nVoulez-vous continuer ?
+dialog.correlate.photoselect.intro=S\u00e9lectionner une de ces photos corr\u00e9l\u00e9es pour d\u00e9finir le d\u00e9calage de temps
dialog.correlate.photoselect.photoname=Nom de la photo
-dialog.correlate.photoselect.timediff=Différence de temps
+dialog.correlate.photoselect.timediff=Diff\u00e9rence de temps
dialog.correlate.photoselect.photolater=Photo prise plus tard
-dialog.correlate.options.tip=Astuce : En corrélant manuellement au moins une photo, le décalage de temps peut être calculé pour vous.
-dialog.correlate.options.intro=Sélectionner les options pour la corrélation automatique
-dialog.correlate.options.offsetpanel=Décalage de temps
-dialog.correlate.options.offset=Décalage
+dialog.correlate.options.tip=Astuce : En corr\u00e9lant manuellement au moins une photo, le d\u00e9calage de temps peut \u00eatre calcul\u00e9 pour vous.
+dialog.correlate.options.intro=S\u00e9lectionner les options pour la corr\u00e9lation automatique
+dialog.correlate.options.offsetpanel=D\u00e9calage de temps
+dialog.correlate.options.offset=D\u00e9calage
dialog.correlate.options.offset.hours=heures,
dialog.correlate.options.offset.minutes=minutes et
dialog.correlate.options.offset.seconds=secondes
-dialog.correlate.options.photolater=Photo postérieure au point
-dialog.correlate.options.pointlater=Point postérieur à la photo
-dialog.correlate.options.limitspanel=Limites de corrélation
+dialog.correlate.options.photolater=Photo post\u00e9rieure au point
+dialog.correlate.options.pointlater=Point post\u00e9rieur \u00e0 la photo
+dialog.correlate.options.limitspanel=Limites de corr\u00e9lation
dialog.correlate.options.notimelimit=Pas de limite de temps
dialog.correlate.options.timelimit=Limite de temps
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.correlate.options.correlate=Corr\u00e9ler
+dialog.correlate.alloutsiderange=Les photos ne correspondent pas \u00e0 la plage de temps de la trace, aucune ne peut \u00eatre corr\u00e9l\u00e9e.\nEssayez de modifier le d\u00e9calage ou de corr\u00e9ler manuellement au moins une photo.
+dialog.compress.nonefound=Pas de donn\u00e9es \u00e0 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.title=Suppression des points isol\u00e9s
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.compress.summarylabel=Points \u00e0 supprimer
+dialog.help.help=Consultez la page\n http://activityworkshop.net/software/prune/\npour plus de d\u00e9tails et des manuels utilisateur.
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.summarytext1=Prune est un programme pour charger, afficher et \u00e9diter des donn\u00e9es de r\u00e9cepteurs GPS.
+dialog.about.summarytext2=Distribu\u00e9 sous license Gnu GPL pour un usage et une am\u00e9lioration libres, ouverts et mondiaux. La copie, la redistribution et la modification sont autoris\u00e9es et encourag\u00e9es selon les conditions d\u00e9taill\u00e9es dans le fichier license.txt
inclus.
+dialog.about.summarytext3=Consultez la page http://activityworkshop.net/
pour plus de d\u00e9tails et des manuels utilisateur.
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.translatedby=Texte en fran\u00e7ais par Petrovsk et theYinYeti.
+dialog.about.systeminfo=Info Syst\u00e8me
+dialog.about.systeminfo.os=Syst\u00e8me d'exploitation
dialog.about.systeminfo.java=Java Runtime
-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.systeminfo.java3d=Java3d install\u00e9
+dialog.about.systeminfo.povray=Povray install\u00e9
+dialog.about.systeminfo.exiftool=Exiftool install\u00e9
+dialog.about.systeminfo.gpsbabel=Gpsbabel install\u00e9
+dialog.about.systeminfo.gnuplot=Gnuplot install\u00e9
dialog.about.yes=Oui
dialog.about.no=Non
-dialog.about.credits=Crédits
-dialog.about.credits.code=Code de Prune écrit par
+dialog.about.credits=Cr\u00e9dits
+dialog.about.credits.code=Code de Prune \u00e9crit par
dialog.about.credits.exifcode=Code Exif par
-dialog.about.credits.icons=Quelques icônes provenant de
-dialog.about.credits.translators=Interprètes
+dialog.about.credits.icons=Quelques ic\u00f4nes provenant de
+dialog.about.credits.translators=Interpr\u00e8tes
dialog.about.credits.translations=Traduction avec l'aide de
-dialog.about.credits.devtools=Outils de développement
+dialog.about.credits.devtools=Outils de d\u00e9veloppement
dialog.about.credits.othertools=Autre outils
-dialog.about.credits.thanks=Merci à
+dialog.about.credits.thanks=Merci \u00e0
dialog.about.readme=Lisez-moi
-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.error=Ne peut pas v\u00e9rifier la version.\nVeuillez v\u00e9rifier votre connexion Internet.
+dialog.checkversion.uptodate=Vous utilisez d\u00e9j\u00e0 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.
+dialog.checkversion.download=Pour t\u00e9l\u00e9charger la nouvelle version, aller \u00e0 http://activityworkshop.net/software/prune/download.html.
+dialog.keys.intro=Vous pouvez utiliser ces raccourcis clavier \u00e0 la place de la souris
+dialog.keys.keylist=Touches-fl\u00e8ches Faire d\u00e9filer la carte horizontallement et verticallement Ctrl + gauche, Ctrl + droite Choisir le point pr\u00e9c\u00e9dent ou suivant Ctrl + haut, Ctrl + bas Zoomer, s'\u00e9loigner Suppr Effacer le point courant
+dialog.saveconfig.desc=Les param\u00e8tres suivants peuvent \u00eatre sauvegard\u00e9s dans un fichier de configuration:
+dialog.saveconfig.prune.trackdirectory=Dossier des traces
+dialog.saveconfig.prune.photodirectory=Dossier des Photos
+dialog.saveconfig.prune.languagecode=Code langue (FR)
+dialog.saveconfig.prune.gpsdevice=Chemin du p\u00e9riph\u00e9rique GPS
+dialog.saveconfig.prune.gpsformat=Format GPS
+dialog.saveconfig.prune.povrayfont=Police povray
+dialog.saveconfig.prune.metricunits=Utiliser le syst\u00e8me m\u00e9trique?
+dialog.saveconfig.prune.gnuplotpath=Chemin gnuplot
+dialog.saveconfig.prune.gpsbabelpath=Chemin gpsbabel
+dialog.saveconfig.prune.exiftoolpath=Chemin exiftool
+dialog.saveconfig.prune.mapserverindex=Index du serveur de carte
+dialog.saveconfig.prune.mapserverurl=URL du serveur de carte
+dialog.saveconfig.prune.showpace=Montrer l'allure
+dialog.saveconfig.prune.kmzimagewidth=Largeur de l'image KMZ
+dialog.saveconfig.prune.kmzimageheight=Hauteur de l'image KMZ
+dialog.setpaths.intro=Si vous le souhaitez, vous pouvez d\u00e9finir les chemins des applications externes:
+dialog.addaltitude.noaltitudes=L'\u00e9tendue s\u00e9lectionn\u00e9e de contient pas d'altitudes
+dialog.addaltitude.desc=D\u00e9callage d'altitude \u00e0 ajouter
# 3d window
dialog.3d.title=Vue 3D de Prune
dialog.3d.altitudecap=Etendue d'altitude minimale
dialog.3dlines.title=Grille de Prune
-dialog.3dlines.empty=Pas de grille à afficher !
+dialog.3dlines.empty=Pas de grille \u00e0 afficher !
dialog.3dlines.intro=Ceci est la grille pour la vue 3D
-# Confirm messages - these are displayed as confirmation in the status bar
-confirm.loadfile=Données chargées depuis le fichier
-confirm.save.ok1=Enregistrement réussi de
+# Confirm messages || These are displayed as confirmation in the status bar
+confirm.loadfile=Donn\u00e9es charg\u00e9es depuis le fichier
+confirm.save.ok1=Enregistrement r\u00e9ussi de
confirm.save.ok2=points dans le fichier
-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=Décalage ajouté
-confirm.rearrangewaypoints=Waypoints réarrangés
-confirm.cutandmove=Sélection déplacée
+confirm.deletepoint.single=point a \u00e9t\u00e9 effac\u00e9
+confirm.deletepoint.multi=points ont \u00e9t\u00e9 effac\u00e9s
+confirm.point.edit=point \u00e9dit\u00e9
+confirm.mergetracksegments=Segments de trace ont \u00e9t\u00e9 fusionn\u00e9
+confirm.reverserange=Etendue invers\u00e9e
+confirm.addtimeoffset=D\u00e9calage ajout\u00e9
+confirm.addaltitudeoffset=D\u00e9calage d'altitude ajout\u00e9
+confirm.rearrangewaypoints=Waypoints r\u00e9arrang\u00e9s
+confirm.cutandmove=S\u00e9lection d\u00e9plac\u00e9e
confirm.saveexif.ok1=Enregistrement de
confirm.saveexif.ok2=fichiers photo
-confirm.undo.single=opération annulée
-confirm.undo.multi=opérations annulées
-confirm.jpegload.single=la photo a été ajoutée
-confirm.jpegload.multi=les photos ont été ajoutées
-confirm.photo.connect=photo reliée
-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=Point créé
+confirm.undo.single=op\u00e9ration annul\u00e9e
+confirm.undo.multi=op\u00e9rations annul\u00e9es
+confirm.jpegload.single=la photo a \u00e9t\u00e9 ajout\u00e9e
+confirm.jpegload.multi=les photos ont \u00e9t\u00e9 ajout\u00e9es
+confirm.photo.connect=photo reli\u00e9e
+confirm.photo.disconnect=photo d\u00e9tach\u00e9e
+confirm.correlate.single=photo a \u00e9t\u00e9 corr\u00e9l\u00e9e
+confirm.correlate.multi=photos ont \u00e9t\u00e9 corr\u00e9l\u00e9es
+confirm.createpoint=Point cr\u00e9\u00e9
+confirm.running=En cours...
# Buttons
button.ok=OK
@@ -298,11 +359,11 @@ button.back=Retour
button.next=Prochain
button.finish=Fin
button.cancel=Annuler
-button.overwrite=Écraser
+button.overwrite=\u00c9craser
button.moveup=Monter
button.movedown=Descendre
button.showlines=Montrer les lignes
-button.edit=Éditer
+button.edit=\u00c9diter
button.exit=Terminer
button.close=Fermer
button.continue=Continuer
@@ -310,12 +371,13 @@ button.yes=Oui
button.no=Non
button.yestoall=Oui pour tous
button.notoall=Non pour tous
-button.selectall=Tout sélectionner
-button.selectnone=Ne rien sélectionner
-button.preview=Aperçu
+button.selectall=Tout s\u00e9lectionner
+button.selectnone=Ne rien s\u00e9lectionner
+button.preview=Aper\u00e7u
+button.load=T\u00e9l\u00e9charger
button.guessfields=Deviner les champs
button.showwebpage=Montrer page web
-button.gnuplotpath=Localiser gnuplot
+button.check=V\u00e9rifier
# File types
filetype.txt=Fichiers TXT
@@ -328,40 +390,41 @@ filetype.pov=Fichiers POV
filetype.svg=Fichiers SVG
# Display components
-display.nodata=Pas de données chargées
+display.nodata=Pas de donn\u00e9es charg\u00e9es
display.noaltitudes=La trace ne comporte pas d'information d'altitude
-details.trackdetails=Détails de la trace
-details.notrack=Pas de trace chargée
+details.trackdetails=D\u00e9tails de la trace
+details.notrack=Pas de trace charg\u00e9e
details.track.points=Points
details.track.file=Fichier
details.track.numfiles=Nombre de fichiers
-details.pointdetails=Détails du point
+details.pointdetails=D\u00e9tails du point
details.index.selected=Index
details.index.of=sur
details.nopointselection=Aucun point choisi
details.photofile=Fichier photo
-details.norangeselection=Aucune étendue sélectionnée
-details.rangedetails=Détails sur l'étendue
-details.range.selected=Sélection des points
-details.range.to=à
-details.altitude.to=à
-details.range.climb=Montée
+details.norangeselection=Aucune \u00e9tendue s\u00e9lectionn\u00e9e
+details.rangedetails=D\u00e9tails sur l'\u00e9tendue
+details.range.selected=S\u00e9lection des points
+details.range.to=\u00e0
+details.altitude.to=\u00e0
+details.range.climb=Mont\u00e9e
details.range.descent=Descente
-details.coordformat=Format de coordonnées
-details.distanceunits=Unités de distance
+details.coordformat=Format de coordonn\u00e9es
+details.distanceunits=Unit\u00e9s de distance
display.range.time.secs=s
display.range.time.mins=m
display.range.time.hours=h
display.range.time.days=j
details.range.avespeed=Vitesse moyenne
details.range.avemovingspeed=Moyenne continue
+details.range.pace=Allure
details.waypointsphotos.waypoints=Waypoints
details.waypointsphotos.photos=Photos
-details.photodetails=Détails de la photo
+details.photodetails=D\u00e9tails 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
+details.photo.connected=Reli\u00e9e
+map.overzoom=Aucune carte disponible \u00e0 ce niveau de zoom
# Field names
fieldname.latitude=Latitude
@@ -372,22 +435,22 @@ fieldname.time=Temps
fieldname.waypointname=Nom
fieldname.waypointtype=Type
fieldname.newsegment=Segment
-fieldname.custom=Personnalisé
+fieldname.custom=Personnalis\u00e9
fieldname.prefix=Champ
fieldname.distance=Distance
fieldname.movingdistance=Distance continue
-fieldname.duration=Durée
+fieldname.duration=Dur\u00e9e
fieldname.speed=Vitesse
fieldname.verticalspeed=Vitesse verticale
# Measurement units
units.original=Original
-units.default=Défaut
-units.metres=mètres
+units.default=D\u00e9faut
+units.metres=m\u00e8tres
units.metres.short=m
units.feet=pieds
units.feet.short=p
-units.kilometres=Kilomètres
+units.kilometres=Kilom\u00e8tres
units.kilometres.short=km
units.kmh=km/h
units.miles=Miles
@@ -398,7 +461,7 @@ units.feetpersec=ft/s
units.hours=heures
units.degminsec=Deg-min-sec
units.degmin=Deg-min
-units.deg=Degrés
+units.deg=Degr\u00e9s
units.iso8601=ISO 8601
# External urls
@@ -411,49 +474,50 @@ cardinal.e=E
cardinal.w=O
# Undo operations
-undo.load=charger les données
+undo.load=charger les donn\u00e9es
undo.loadphotos=charger les photos
-undo.editpoint=éditer le point
+undo.editpoint=\u00e9diter le point
undo.deletepoint=effacer le point
undo.deletephoto=retirer la photo
-undo.deleterange=effacer l'étendue
+undo.deleterange=effacer l'\u00e9tendue
undo.compress=compresser la trace
-undo.insert=insérer les points
-undo.reverse=inverser l'étendue
+undo.insert=ins\u00e9rer les points
+undo.reverse=inverser l'\u00e9tendue
undo.mergetracksegments=fusionner les segments de trace
-undo.addtimeoffset=ajouter décalage d'heure
-undo.rearrangewaypoints=réarranger les waypoints
-undo.cutandmove=déplacer la sélection
+undo.addtimeoffset=ajouter d\u00e9calage d'heure
+undo.addaltitudeoffset=ajouter d\u00e9calage d'altitude
+undo.rearrangewaypoints=r\u00e9arranger les waypoints
+undo.cutandmove=d\u00e9placer la s\u00e9lection
undo.connectphoto=relier la photo
-undo.disconnectphoto=détacher la photo
-undo.correlate=corréler les photos
+undo.disconnectphoto=d\u00e9tacher la photo
+undo.correlate=corr\u00e9ler les photos
undo.createpoint=ajouter un point
# Error messages
-error.save.dialogtitle=Erreur à l'enregistrement des données
-error.save.nodata=Pas de données à enregistrer
-error.save.failed=Echec de l'enregistrement des données dans le fichier:
+error.save.dialogtitle=Erreur \u00e0 l'enregistrement des donn\u00e9es
+error.save.nodata=Pas de donn\u00e9es \u00e0 enregistrer
+error.save.failed=Echec de l'enregistrement des donn\u00e9es dans le fichier
error.saveexif.filenotfound=Fichier photo introuvable
error.saveexif.cannotoverwrite1=Le fichier photo
-error.saveexif.cannotoverwrite2=est en lecture seule et ne peut pas être écraser. Enregistrer sur une copie ?
-error.load.dialogtitle=Erreur au chargement des données
+error.saveexif.cannotoverwrite2=est en lecture seule et ne peut pas \u00eatre \u00e9craser. Enregistrer sur une copie ?
+error.load.dialogtitle=Erreur au chargement des donn\u00e9es
error.load.noread=Fichier illisible
-error.load.nopoints=Aucune coordonnée trouvée dans le fichier
+error.load.nopoints=Aucune coordonn\u00e9e trouv\u00e9e dans le fichier
error.load.unknownxml=Format xml non-reconnu :
-error.load.noxmlinzip=
-error.load.othererror=Erreur à la lecture du fichier :
+error.load.noxmlinzip=Aucune xml fichier trouv\u00e9e dans le fichier
+error.load.othererror=Erreur \u00e0 la lecture du fichier :
error.jpegload.dialogtitle=Erreur au chargement des photos
-error.jpegload.nofilesfound=Aucun fichier trouvé
-error.jpegload.nojpegsfound=Aucun fichier jpeg trouvé
-error.jpegload.noexiffound=Aucune information EXIF trouvée
-error.jpegload.nogpsfound=Aucune information GPS trouvée
+error.jpegload.nofilesfound=Aucun fichier trouv\u00e9
+error.jpegload.nojpegsfound=Aucun fichier jpeg trouv\u00e9
+error.jpegload.noexiffound=Aucune information EXIF trouv\u00e9e
+error.jpegload.nogpsfound=Aucune information GPS trouv\u00e9e
error.undofailed.title=Echec de l'annulation
-error.undofailed.text=Echec de l'opération d'annulation
+error.undofailed.text=Echec de l'op\u00e9ration d'annulation
error.function.noop.title=Fonction sans effet
-error.rearrange.noop=Réarrangement des waypoints sans effet
+error.rearrange.noop=R\u00e9arrangement des waypoints sans effet
error.function.notavailable.title=Function non-disponible
-error.function.nojava3d=Cette fonction nécessite la librairie Java3d,\ndisponible sur Sun.com.
-error.3d=Un problème est survenu avec l'affichage 3D
+error.function.nojava3d=Cette fonction n\u00e9cessite la librairie Java3d,\ndisponible sur Sun.com.
+error.3d=Un probl\u00e8me est survenu avec l'affichage 3D
error.readme.notfound=Fichier Lisez-moi introuvable
error.osmimage.dialogtitle=Erreur au chargement des portions de cartes
-error.osmimage.failed=Erreur du chargement des portions de cartes. Vérifiez votre connexion internet.
+error.osmimage.failed=Erreur du chargement des portions de cartes. V\u00e9rifiez votre connexion internet.
diff --git a/tim/prune/lang/prune-texts_in.properties b/tim/prune/lang/prune-texts_in.properties
index e1daaf6..d31df3f 100644
--- a/tim/prune/lang/prune-texts_in.properties
+++ b/tim/prune/lang/prune-texts_in.properties
@@ -9,313 +9,83 @@ 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.photo.delete=Menghapus foto
menu.view=Lihat
-menu.view.browser=
-menu.view.browser.google=
-menu.view.browser.openstreetmap=
-menu.view.browser.mapquest=
-menu.view.browser.yahoo=
+menu.settings=Pengaturan
+menu.view.browser=Peta di browser
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
+# Alt keys for menus
+altkey.menu.file=B
+altkey.menu.edit=U
+altkey.menu.select=P
+altkey.menu.view=L
+altkey.menu.photo=F
+altkey.menu.settings=G
+altkey.menu.help=N
+
+# Ctrl shortcuts for menu items
+shortcut.menu.file.open=B
+shortcut.menu.file.load=M
+shortcut.menu.file.save=S
+shortcut.menu.edit.undo=Z
+shortcut.menu.edit.compress=P
+shortcut.menu.select.all=-
+shortcut.menu.help.help=-
+
# 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.editwaypointname=Perbaiki Nama waypoint
function.compress=Padatkan jalur
-function.addtimeoffset=
+
+function.findwaypoint=Menemukan waypoint
function.charts=Grafik
function.show3d=Lihat tiga-D
-function.distances=
-function.setmapbg=
+function.distances=Jarak
+
function.correlatephotos=Korelasikan foto
function.help=Bantuan
function.about=Tentang Prune
-function.checkversion=
+function.saveconfig=Simpan pengaturan
# 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
@@ -328,132 +98,14 @@ 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=
+display.nodata=Tidak ada data
+details.trackdetails=Rincian track
+details.notrack=Tidak ada track
+details.pointdetails=Rincian titik
+details.nopointselection=Tidak ada titik
+details.norangeselection=Tidak ada jangkauan
+details.rangedetails=Rincian jangkauan
+details.waypointsphotos.photos=Foto
+details.photodetails=Rincian foto
+details.nophoto=Tidak ada foto
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 628f09d..a219fab 100644
--- a/tim/prune/lang/prune-texts_it.properties
+++ b/tim/prune/lang/prune-texts_it.properties
@@ -11,7 +11,6 @@ menu.edit=Edita
menu.edit.undo=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.deletemarked=Cancella punti marcati
@@ -22,7 +21,7 @@ menu.edit.mergetracksegments=Unisci segmenti traccia
menu.edit.rearrange=Riorganizza waypoint
menu.edit.rearrange.start=Tutti all'inizio del file
menu.edit.rearrange.end=Tutti alla fine del file
-menu.edit.rearrange.nearest=Sul punto più vicino
+menu.edit.rearrange.nearest=Sul punto pi\u00f9 vicino
menu.edit.cutandmove=Taglia e muovi la selezione
menu.select=Seleziona
menu.select.all=Seleziona tutto
@@ -40,6 +39,8 @@ menu.view.browser.google=Google maps
menu.view.browser.openstreetmap=Openstreetmap
menu.view.browser.mapquest=Mapquest
menu.view.browser.yahoo=mappe Yahoo
+menu.settings=Preferenze
+menu.settings.showpace=
menu.help=Aiuto
# Popup menu for map
menu.map.zoomin=Zoom +
@@ -49,6 +50,25 @@ menu.map.newpoint=Crea punto nuovo
menu.map.connect=Aggancia ai punti
menu.map.autopan=Autopan
menu.map.showmap=Mostra sulla mappa
+menu.map.showscalebar=
+
+# Alt keys for menus
+altkey.menu.file=F
+altkey.menu.edit=E
+altkey.menu.select=S
+altkey.menu.view=V
+altkey.menu.photo=O
+altkey.menu.settings=P
+altkey.menu.help=A
+
+# Ctrl shortcuts for menu items
+shortcut.menu.file.open=A
+shortcut.menu.file.load=C
+shortcut.menu.file.save=S
+shortcut.menu.edit.undo=Z
+shortcut.menu.edit.compress=C
+shortcut.menu.select.all=T
+shortcut.menu.help.help=H
# Functions
function.loadfromgps=Carica dati da GPS
@@ -56,22 +76,30 @@ function.sendtogps=Invia dati al GPS
function.exportkml=Esporta in KML
function.exportgpx=Esporta in GPX
function.exportpov=Esporta in POV
+function.editwaypointname=Edita nome waypoint
function.compress=Comprimi la traccia
function.addtimeoffset=Aggiungi uno scarto temporale
+function.addaltitudeoffset=
+function.findwaypoint=
function.charts=Diagrammi
function.show3d=Mostra in 3D
function.distances=Mostra distanze
-function.setmapbg=Configura sfondo mappa
+function.getgpsies=
function.correlatephotos=Correla le foto
+function.setmapbg=Configura sfondo mappa
+function.setkmzimagesize=
+function.setpaths=
function.help=Aiuto
+function.showkeys=
function.about=Informazioni su Prune
function.checkversion=Controlla gli aggiornamenti
+function.saveconfig=
# Dialogs
dialog.exit.confirm.title=Esci da Prune
dialog.exit.confirm.text=Le modifiche non sono state salvate. Sei sicuro di voler uscire?
dialog.openappend.title=Aggiungi ai dati esistenti
-dialog.openappend.text=Aggiungi questi dati a quelli già caricati?
+dialog.openappend.text=Aggiungi questi dati a quelli gi\u00e0 caricati?
dialog.deletepoint.title=Cancella Punto
dialog.deletepoint.deletephoto=Cancella la foto collegata a questo punto?
dialog.deletephoto.title=Cancella Foto
@@ -90,7 +118,7 @@ dialog.delimiter.other=Altro
dialog.openoptions.deliminfo.records=registra, con
dialog.openoptions.deliminfo.fields=campi
dialog.openoptions.deliminfo.norecords=Nessun record
-dialog.openoptions.altitudeunits=Unità di misura altitudine
+dialog.openoptions.altitudeunits=Unit\u00e0 di misura altitudine
dialog.jpegload.subdirectories=Includi sottocartelle
dialog.jpegload.loadjpegswithoutcoords=Includi foto senza coordinate
dialog.jpegload.loadjpegsoutsidearea=Includi foto fuori dall'area corrente
@@ -110,11 +138,11 @@ dialog.save.table.field=Campo
dialog.save.table.hasdata=Ha dati
dialog.save.table.save=Salva
dialog.save.headerrow=Regista l'intestazione delle righe
-dialog.save.coordinateunits=Unità di misura coordinate
-dialog.save.altitudeunits=Unità di misura altitudine
+dialog.save.coordinateunits=Unit\u00e0 di misura coordinate
+dialog.save.altitudeunits=Unit\u00e0 di misura altitudine
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.save.overwrite.title=File gi\u00e0 esistente
+dialog.save.overwrite.text=Questo file esiste gi\u00e0. Sei sicuro di volerlo sovrascrivere?
dialog.exportkml.text=Titolo dei dati
dialog.exportkml.altitude=Includi altitudine (per aviazione)
dialog.exportkml.kmz=Comprimi per file kmz
@@ -130,7 +158,11 @@ dialog.exportpov.cameraz=Camera Z
dialog.exportpov.modelstyle=Stile del modello
dialog.exportpov.ballsandsticks=Palle e bacchette
dialog.exportpov.tubesandwalls=Tubi e pareti
-dialog.exportpov.warningtracksize=Questa traccia ha un elevato numero di punti, e Java3D può non essere in grado di visualizzarli.\nSei sicuro di voler continuare?
+dialog.exportpov.warningtracksize=Questa traccia ha un elevato numero di punti, e Java3D pu\u00f2 non essere in grado di visualizzarli.\nSei sicuro di voler continuare?
+dialog.pointtype.desc=
+dialog.pointtype.track=
+dialog.pointtype.waypoint=
+dialog.pointtype.photo=
dialog.confirmreversetrack.title=Conferma l'inversione
dialog.confirmreversetrack.text=Questa traccia contiene informazioni sull'orario di scatto che possono essere messe fuori sequenza dopo l'inversione.\nSei sicuro di voler invertire questa sezione?
dialog.confirmcutandmove.title=Conferma il taglio e lo spostamento
@@ -139,7 +171,7 @@ dialog.interpolate.title=Interpola i punti
dialog.interpolate.parameter.text=Numero di punti da inserire tra i punti selezionati
dialog.undo.title=Annulla l'azione(i)
dialog.undo.pretext=Per favore seleziona l'azione(i) da annullare
-dialog.undo.none.title=Non è possibile annullare
+dialog.undo.none.title=Non \u00e8 possibile annullare
dialog.undo.none.text=Nessuna operazione da annullare!
dialog.clearundo.title=Cancella la lista annulla
dialog.clearundo.text=Sei sicuro di voler cancellare la lista annulla?\nTutte le informazioni saranno perse!
@@ -150,7 +182,6 @@ dialog.pointedit.table.value=Valore
dialog.pointedit.table.changed=Cambiato
dialog.pointedit.changevalue.text=Inserisci il nuovo valore di questo campo
dialog.pointedit.changevalue.title=Edita il campo
-dialog.pointnameedit.title=Edita il nome del waypoint
dialog.pointnameedit.name=Nome del waypoint
dialog.pointnameedit.uppercase=MAIUSCOLE
dialog.pointnameedit.lowercase=minuscole
@@ -160,9 +191,11 @@ dialog.addtimeoffset.subtract=Scarto in sottrazione
dialog.addtimeoffset.days=Giorni
dialog.addtimeoffset.hours=Ore
dialog.addtimeoffset.minutes=Minuti
-dialog.addtimeoffset.notimestamps=Non posso aggiungere uno scarto temporale a questa selezione perché non contiene informazioni temporali
+dialog.addtimeoffset.notimestamps=Non posso aggiungere uno scarto temporale a questa selezione perch\u00e9 non contiene informazioni temporali
+dialog.findwaypoint.intro=
+dialog.findwaypoint.search=
dialog.connect.title=Collega la foto al punto
-dialog.connectphoto.clonepoint=Questo punto ha già una foto collegata.\nVuoi fare una copia del punto?
+dialog.connectphoto.clonepoint=Questo punto ha gi\u00e0 una foto collegata.\nVuoi fare una copia del punto?
dialog.saveexif.title=Salva Exif
dialog.saveexif.intro=Seleziona le foto da salvare usando le caselle di spunta
dialog.saveexif.nothingtosave=Le coordinate non sono cambiate, niente da registrare
@@ -194,7 +227,12 @@ 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.gpsies.column.name=
+dialog.gpsies.column.length=
+dialog.gpsies.description=
+dialog.gpsies.nodescription=
+dialog.gpsies.nonefound=
+dialog.correlate.notimestamps=Non ci sono informazioni temporali tra i dati dei punti, non c'\u00e8 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
dialog.correlate.photoselect.photoname=Nome della foto
@@ -215,7 +253,7 @@ dialog.correlate.options.timelimit=Limite di tempo
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.correlate.alloutsiderange=Tutte le foto sono fuori dall'orario della traccia, e nessuna pu\u00f2 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
@@ -225,11 +263,11 @@ 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.help.help=Per favore vedi\n http://activityworkshop.net/software/prune/\nper maggiori informazioni e per la guida utente.
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.summarytext1=Prune \u00e8 un programma per il caricamento, la visione e l'edit di dati provenienti da un GPS.
+dialog.about.summarytext2=\u00c8 rilasciato sotto la licenza Gnu GPL per l'uso gratuito e aperto ed il suo miglioramento, con validit\u00e0 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 + altro
@@ -241,11 +279,11 @@ 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.yes=S\u00ec
dialog.about.no=No
dialog.about.credits=Crediti
-dialog.about.credits.code=Il codice Prune code è scritto da
-dialog.about.credits.exifcode=Il codice Exif è scritto da
+dialog.about.credits.code=Il codice Prune code \u00e8 scritto da
+dialog.about.credits.exifcode=Il codice Exif \u00e8 scritto da
dialog.about.credits.icons=Alcune icone prese da
dialog.about.credits.translators=Traduttori
dialog.about.credits.translations=Aiuto nella traduzione da
@@ -255,11 +293,32 @@ dialog.about.credits.thanks=Grazie a
dialog.about.readme=Leggimi
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
+dialog.checkversion.newversion1=Una nuova versione di Prune \u00e8 disponibile! L'ultima versione \u00e8 ora la versione
dialog.checkversion.newversion2=.
-dialog.checkversion.releasedate1=Questa nuova versione è stata rilasciata il
+dialog.checkversion.releasedate1=Questa nuova versione \u00e8 stata rilasciata il
dialog.checkversion.releasedate2=.
dialog.checkversion.download=Per scaricare la nuova versione vai a http://activityworkshop.net/software/prune/download.html.
+dialog.keys.intro=
+dialog.keys.keylist=
+dialog.saveconfig.desc=
+dialog.saveconfig.prune.trackdirectory=
+dialog.saveconfig.prune.photodirectory=
+dialog.saveconfig.prune.languagecode=
+dialog.saveconfig.prune.gpsdevice=Nome del Dispositivo GPS
+dialog.saveconfig.prune.gpsformat=Formato GPS
+dialog.saveconfig.prune.povrayfont=Font povray
+dialog.saveconfig.prune.metricunits=
+dialog.saveconfig.prune.gnuplotpath=Path gnuplot
+dialog.saveconfig.prune.gpsbabelpath=Path gpsbabel
+dialog.saveconfig.prune.exiftoolpath=Path exiftool
+dialog.saveconfig.prune.mapserverindex=
+dialog.saveconfig.prune.mapserverurl=
+dialog.saveconfig.prune.showpace=
+dialog.saveconfig.prune.kmzimagewidth=
+dialog.saveconfig.prune.kmzimageheight=
+dialog.setpaths.intro=
+dialog.addaltitude.noaltitudes=
+dialog.addaltitude.desc=
# 3d window
dialog.3d.title=Visione Prune in 3D
@@ -272,25 +331,27 @@ 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.deletepoint.single=punto è stato rimosso
+confirm.deletepoint.single=punto \u00e8 stato rimosso
confirm.deletepoint.multi=punti sono stati rimossi
confirm.point.edit=punto editato
confirm.mergetracksegments=segmeni di traccia uniti
confirm.reverserange=Intervallo invertito
confirm.addtimeoffset=Scarto temporale aggiunto
+confirm.addaltitudeoffset=
confirm.rearrangewaypoints=Waypoint riorganizzati
confirm.cutandmove=Selezione spostata
confirm.saveexif.ok1=Salvato
confirm.saveexif.ok2=foto
confirm.undo.single=operazione annullate
confirm.undo.multi=operazioni annullate
-confirm.jpegload.single=foto è stata aggiunta
+confirm.jpegload.single=foto \u00e8 stata aggiunta
confirm.jpegload.multi=foto sono state aggiunte
confirm.photo.connect=foto collegata
confirm.photo.disconnect=foto scollegata
confirm.correlate.single=foto era correlata
confirm.correlate.multi=foto erano correlate
confirm.createpoint=punto creato
+confirm.running=
# Buttons
button.ok=OK
@@ -306,16 +367,17 @@ button.edit=Modifica
button.exit=Esci
button.close=Chiudi
button.continue=Continuare
-button.yes=Sì
+button.yes=S\u00ec
button.no=No
button.yestoall=Si a tutto
button.notoall=No a tutto
button.selectall=Seleziona tutto
button.selectnone=Deseleziona tutto
button.preview=Anteprima
+button.load=Carica
button.guessfields=Campi soluzione
button.showwebpage=Mostra pagina
-button.gnuplotpath=Fissa path gnuplot
+button.check=
# File types
filetype.txt=File TXT
@@ -348,13 +410,14 @@ details.altitude.to=a
details.range.climb=Salita
details.range.descent=Discesa
details.coordformat=Formato coordinate
-details.distanceunits=Unità di misura distanze
+details.distanceunits=Unit\u00e0 di misura distanze
display.range.time.secs=s
display.range.time.mins=m
display.range.time.hours=h
display.range.time.days=g
-details.range.avespeed=Velocità media
-details.range.avemovingspeed=Velocità media in movimento
+details.range.avespeed=Velocit\u00e0 media
+details.range.avemovingspeed=Velocit\u00e0 media in movimento
+details.range.pace=
details.waypointsphotos.waypoints=Waypoint
details.waypointsphotos.photos=Foto
details.photodetails=Dettagli foto
@@ -377,8 +440,8 @@ fieldname.prefix=Campo
fieldname.distance=Distanza
fieldname.movingdistance=Distanza in movimento
fieldname.duration=Durata
-fieldname.speed=Velocità
-fieldname.verticalspeed=Velocità verticale
+fieldname.speed=Velocit\u00e0
+fieldname.verticalspeed=Velocit\u00e0 verticale
# Measurement units
units.original=Originale
@@ -422,6 +485,7 @@ undo.insert=inserisci punti
undo.reverse=inverti l'intervallo
undo.mergetracksegments=unisci segmenti traccia
undo.addtimeoffset=aggiungi scarto temporale
+undo.addaltitudeoffset=
undo.rearrangewaypoints=riorganizza waypoint
undo.cutandmove=muovi selezione
undo.connectphoto=collega foto
@@ -432,10 +496,10 @@ undo.createpoint=crea punto
# Error messages
error.save.dialogtitle=Errore nel salvataggio dati
error.save.nodata=Nessun dato da salvare
-error.save.failed=Fallito il tentativo di salvare i dati nel file:
+error.save.failed=Fallito il tentativo di salvare i dati nel file
error.saveexif.filenotfound=Non trovato un file di foto
error.saveexif.cannotoverwrite1=File di foto
-error.saveexif.cannotoverwrite2=è in sola lettura e non può essere sovrascritto. Creo una copia?
+error.saveexif.cannotoverwrite2=\u00e8 in sola lettura e non pu\u00f2 essere sovrascritto. Creo una copia?
error.load.dialogtitle=Errore nel caricamento dati
error.load.noread=Non posso leggere il file
error.load.nopoints=Non ci sono coordinate nel file
@@ -453,7 +517,7 @@ error.function.noop.title=La funzione non ha avuto effetto
error.rearrange.noop=La riorganizzazione dei waypoint non ha avuto effetto
error.function.notavailable.title=Funzione non disponibile
error.function.nojava3d=Questa funzione richiede la libreria Java3d,\ndisponibile all'indirizzo Sun.com.
-error.3d=È avvenuto un errore nella visualizzazione 3D
+error.3d=\u00c8 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
-error.osmimage.failed=Impossibile caricare le immagini della mappa. Per favore verifica la connessione a internet.
+error.osmimage.failed=Impossibile caricare le immagini della mappa. Per favore verifica la connessione a internet.
\ No newline at end of file
diff --git a/tim/prune/lang/prune-texts_pl.properties b/tim/prune/lang/prune-texts_pl.properties
index 5478bd1..8e05b67 100644
--- a/tim/prune/lang/prune-texts_pl.properties
+++ b/tim/prune/lang/prune-texts_pl.properties
@@ -3,26 +3,25 @@
# Menu entries
menu.file=Plik
-menu.file.open=Otw\u00F3rz
+menu.file.open=Otw\u00f3rz
menu.file.addphotos=Dodaj zdj\u0119cia
menu.file.save=Zapisz
menu.file.exit=Zako\u0144cz
menu.edit=Edycja
menu.edit.undo=Cofnij
-menu.edit.clearundo=Wyczy\u015B\u0107 list\u0119 zmian
+menu.edit.clearundo=Wyczy\u015b\u0107 list\u0119 zmian
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.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.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.interpolate=Wstaw pomi\u0119dzy
+menu.edit.average=U\u015brednij zaznaczenie
+menu.edit.reverse=Odwr\u00f3\u0107 zakres
+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=Wytnij i przesu\u0144 zaznaczenie
menu.select=Zaznacz
menu.select.all=Zaznacz wszystko
@@ -40,43 +39,72 @@ menu.view.browser.google=Mapy Google
menu.view.browser.openstreetmap=Openstreetmap
menu.view.browser.mapquest=Mapquest
menu.view.browser.yahoo=Mapy Yahoo
+menu.settings=Ustawienia
+menu.settings.showpace=Poka\u017c tempo przy wy\u015bwietlaniu zakresu
menu.help=Pomoc
# Popup menu for map
menu.map.zoomin=Powi\u0119ksz
-menu.map.zoomout=Zmniejsz
+menu.map.zoomout=Pomniejsz
menu.map.zoomfull=Dostosuj powi\u0119kszenie
-menu.map.newpoint=Stw\u00F3rz nowy punkt
-menu.map.connect=Po\u0142\u0105cz punkty \u015Bcie\u017Cki
+menu.map.newpoint=Stw\u00f3rz nowy punkt
+menu.map.connect=Po\u0142\u0105cz punkty \u015bcie\u017cki
menu.map.autopan=Przesuwanie mapy
-menu.map.showmap=Poka\u017C map\u0119
+menu.map.showmap=Poka\u017c map\u0119
+menu.map.showscalebar=Poka\u017c skal\u0119
+
+# Alt keys for menus
+altkey.menu.file=P
+altkey.menu.edit=E
+altkey.menu.select=A
+altkey.menu.view=W
+altkey.menu.photo=Z
+altkey.menu.settings=T
+altkey.menu.help=M
+
+# Ctrl shortcuts for menu items
+shortcut.menu.file.open=O
+shortcut.menu.file.load=L
+shortcut.menu.file.save=S
+shortcut.menu.edit.undo=Z
+shortcut.menu.edit.compress=C
+shortcut.menu.select.all=A
+shortcut.menu.help.help=H
# Functions
function.loadfromgps=\u0141aduj z GPS
-function.sendtogps=Wy\u015Blij dane do urz\u0105dzenia 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.editwaypointname=Zmie\u0144 nazw\u0119 punktu po\u015bredniego
+function.compress=Kompresuj \u015bcie\u017ck\u0119
function.addtimeoffset=Dodaj przesuni\u0119cie czasu
+function.addaltitudeoffset=Dodaj przesuni\u0119cie wysoko\u015bci
+function.findwaypoint=Znajd\u017a punkt po\u015bredni
function.charts=Wykres
-function.show3d=Poka\u017C model 3D
-function.distances=Odleg\u0142o\u015Bci
+function.show3d=Poka\u017c model 3D
+function.distances=Odleg\u0142o\u015bci
+function.getgpsies=Pobierz \u015bcie\u017cki z Gpsies
+function.correlatephotos=Powi\u0105\u017c zdj\u0119cia
function.setmapbg=Wybierz map\u0119
-function.correlatephotos=Powi\u0105\u017C zdj\u0119cia
+function.setkmzimagesize=Ustaw rozmiar zdj\u0119\u0107 w KMZ
+function.setpaths=Ustaw \u015bcie\u017cki do program\u00f3w
function.help=Pomoc
+function.showkeys=Poka\u017c klawisze skr\u00f3tu
function.about=O Prune
-function.checkversion=Sprawd\u017A czy jest nowa wersja
+function.checkversion=Sprawd\u017a czy jest nowa wersja
+function.saveconfig=Zapisz ustawienia
# Dialogs
dialog.exit.confirm.title=Zako\u0144cz Prune
-dialog.exit.confirm.text=Dane nie s\u0105 zapisane. Czy na pewno chcesz wyj\u015B\u0107?
+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.openappend.text=Doda\u0107 dane do ju\u017c za\u0142adowanych?
dialog.deletepoint.title=Usu\u0144 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=Usun\u0105\u0107 punkt do\u0142\u0105czony do tego zdj\u0119cia?
-dialog.openoptions.title=Otw\u00F3rz opcje
+dialog.openoptions.title=Otw\u00f3rz opcje
dialog.openoptions.filesnippet=Fragment z pliku
dialog.load.table.field=Pole
dialog.load.table.datatype=Typ danych
@@ -85,73 +113,76 @@ dialog.delimiter.label=Pole separatora
dialog.delimiter.comma=Przecinek ,
dialog.delimiter.tab=Tabulator
dialog.delimiter.space=Spacja
-dialog.delimiter.semicolon=\u015Arednik ;
+dialog.delimiter.semicolon=\u015arednik ;
dialog.delimiter.other=Inne
dialog.openoptions.deliminfo.records=rekordy, z
dialog.openoptions.deliminfo.fields=pola
-dialog.openoptions.deliminfo.norecords=Brak rekord\u00F3w
-dialog.openoptions.altitudeunits=Jednostki wysoko\u015Bci
+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.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.nogpsbabel=Nie znaleziono 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.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 do zapisu
dialog.save.table.field=Pole
-dialog.save.table.hasdata=je\u015Bli s\u0105 dane
+dialog.save.table.hasdata=je\u015bli s\u0105 dane
dialog.save.table.save=Zapisz
-dialog.save.headerrow=Dodaj wiersz nag\u0142\u00F3wka
-dialog.save.coordinateunits=Jednostki wsp\u00F3\u0142rz\u0119dnych
-dialog.save.altitudeunits=Jednostki wysoko\u015Bci
+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=Ten plik ju\u017C istnieje. Czy na pewno chcesz go nadpisa\u0107?
+dialog.save.overwrite.title=Plik ju\u017c istnieje
+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.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=Do\u0142\u0105cz znaczniki czasu
-dialog.exportpov.text=Wprowad\u017A dodatkowe parametry eksportu do formatu POV
+dialog.exportpov.text=Wprowad\u017a dodatkowe parametry eksportu do formatu POV
dialog.exportpov.font=Czcionka
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.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.pointtype.desc=Zapisz punkty nast\u0119puj\u0105cych typ\u00f3w:
+dialog.pointtype.track=punkty \u015bcie\u017cki
+dialog.pointtype.waypoint=punkty po\u015brednie
+dialog.pointtype.photo=punkty zdj\u0119\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=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.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=Czy na pewno chcesz wyczy\u015Bci\u0107 list\u0119 zmian?\nWszystkie informacje o zmianach b\u0119d\u0105 utracone!
+dialog.clearundo.title=Wyczy\u015b\u0107 list\u0119 zmian
+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=Zaznacz wszystkie pola do edycji i u\u017Cyj przycisku 'Edytuj' by zmieni\u0107 warto\u015Bci
+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=Warto\u015B\u0107
+dialog.pointedit.table.value=Warto\u015b\u0107
dialog.pointedit.table.changed=Zmieniony
-dialog.pointedit.changevalue.text=Wprowad\u017A now\u0105 warto\u015B\u0107 tego pola
+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=Nazwa punktu po\u015Bredniego
+dialog.pointnameedit.name=Nazwa punktu po\u015bredniego
dialog.pointnameedit.uppercase=WIELKIE litery
dialog.pointnameedit.lowercase=ma\u0142e litery
dialog.pointnameedit.sentencecase=Jak W Zdaniu
@@ -160,12 +191,14 @@ dialog.addtimeoffset.subtract=Odejmij czas
dialog.addtimeoffset.days=Dni
dialog.addtimeoffset.hours=Godziny
dialog.addtimeoffset.minutes=Minuty
-dialog.addtimeoffset.notimestamps=Nie mo\u017Cna przesun\u0105\u0107 czasu, poniewa\u017C zaznaczenie nie zawiera znacznik\u00F3w czasu
+dialog.addtimeoffset.notimestamps=Nie mo\u017cna przesun\u0105\u0107 czasu, poniewa\u017c zaznaczenie nie zawiera znacznik\u00f3w czasu
+dialog.findwaypoint.intro=
+dialog.findwaypoint.search=
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.connectphoto.clonepoint=Ten punkt po\u0142\u0105czono ju\u017c ze zdj\u0119ciem.\nCzy chcesz zrobi\u0107 kopi\u0119 tego punktu?
dialog.saveexif.title=Zapisz Exif
-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.intro=Zaznacz zdj\u0119cia do zapisu u\u017cywaj\u0105c znacznik\u00f3w
+dialog.saveexif.nothingtosave=Wsp\u00f3\u0142rz\u0119dne nie zosta\u0142y 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
@@ -174,63 +207,68 @@ dialog.saveexif.photostatus.connected=Po\u0142\u0105czony
dialog.saveexif.photostatus.disconnected=Roz\u0142\u0105czony
dialog.saveexif.photostatus.modified=Zmodyfikowany
dialog.saveexif.overwrite=Nadpisz pliki
-dialog.charts.xaxis=O\u015B X
-dialog.charts.yaxis=O\u015B Y
+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.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.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.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.distances.toofewpoints=Ta funkcja wymaga przynajmniej dw\u00f3ch punkt\u00f3w po\u015brednich, aby mo\u017cna by\u0142o 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.gpsies.column.name=Nazwa \u015bcie\u017cki
+dialog.gpsies.column.length=D\u0142ugo\u015b\u0107
+dialog.gpsies.description=Opis
+dialog.gpsies.nodescription=Brak opisu
+dialog.gpsies.nonefound=
+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.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.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.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.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 punkt\u00f3w bliskich sobie
+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.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=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.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
@@ -246,39 +284,61 @@ dialog.about.no=Nie
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.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.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.
+dialog.checkversion.download=Aby \u015bci\u0105gn\u0105\u0107 now\u0105 wersj\u0119 przejd\u017a na http://activityworkshop.net/software/prune/download.html.
+dialog.keys.intro=U\u017cuwaj nast\u0119puj\u0105cych klawiszy skr\u00f3t\u00f3w zamiast myszki
+dialog.keys.keylist=klawisze strza\u0142ek Przesuwa map\u0119 w lewo, w prawo, w g\u00f3r\u0119, w d\u00f3\u0142 Ctrl + lewa, prawa strza\u0142ka Wybierz punkt poprzedni lub nast\u0119pny Ctrl + strza\u0142ka w g\u00f3r\u0119, w d\u00f3\u0142 Powi\u0119ksz, pomniejsz Del Usun bie\u017c\u0105cy punkt
+dialog.saveconfig.desc=Nast\u0119puj\u0105ce ustawienia mog\u0105 zosta\u0107 zapisane w pliku konfiguracyjnym:
+dialog.saveconfig.prune.trackdirectory=Katalog ze \u015bcie\u017ckami
+dialog.saveconfig.prune.photodirectory=Katalog ze zdj\u0119ciami
+dialog.saveconfig.prune.languagecode=Kod j\u0119zyka (PL)
+dialog.saveconfig.prune.gpsdevice=Urz\u0105dzenie GPS
+dialog.saveconfig.prune.gpsformat=Format pliku GPS
+dialog.saveconfig.prune.povrayfont=czcionka dla Povray-a
+dialog.saveconfig.prune.metricunits=U\u017cywaj jednostek metrycznych?
+dialog.saveconfig.prune.gnuplotpath=\u015bcie\u017cka do gnuplot
+dialog.saveconfig.prune.gpsbabelpath=\u015bcie\u017cka do gpsbabel
+dialog.saveconfig.prune.exiftoolpath=\u015bcie\u017cka do exiftool
+dialog.saveconfig.prune.mapserverindex=kolejny numer serwera map
+dialog.saveconfig.prune.mapserverurl=URL serwera map
+dialog.saveconfig.prune.showpace=Pokazuj tempo
+dialog.saveconfig.prune.kmzimagewidth=szeroko\u015b\u0107 obrazka w KMZ
+dialog.saveconfig.prune.kmzimageheight=wysoko\u015b\u0107 obrazka w KMZ
+dialog.setpaths.intro=Je\u015bli zachodzi tak potrzeba, mo\u017cesz wybra\u0107 \u015bcie\u017cki do aplikacji zewn\u0119trznych
+dialog.addaltitude.noaltitudes=Wybrany zakres nie zawiera danych o wysoko\u015bciach
+dialog.addaltitude.desc=Warto\u015b\u0107 przesuni\u0119cia wysoko\u015bci
# 3d window
-dialog.3d.title=Prune widok tr\u00F3jwymiarowy
-dialog.3d.altitudecap=Minimalny zakres wysoko\u015Bci
+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.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=Za\u0142adowano dane z pliku
-confirm.save.ok1=Zapisano pomy\u015Blnie
-confirm.save.ok2=punkt\u00F3w do 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.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.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.addaltitudeoffset=Dodano przesuni\u0119cie wysoko\u015bci
+confirm.rearrangewaypoints=Przestawiono punkty po\u015brednie
confirm.cutandmove=Przesuni\u0119to zaznaczenie
confirm.saveexif.ok1=Zapisano
confirm.saveexif.ok2=pliki zdj\u0119\u0107
@@ -291,6 +351,7 @@ 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
+confirm.running=Przetwarzam dane ...
# Buttons
button.ok=OK
@@ -299,9 +360,9 @@ button.next=Nast\u0119pny
button.finish=Koniec
button.cancel=Anuluj
button.overwrite=Nadpisz
-button.moveup=Do g\u00F3ry
-button.movedown=Do d\u00F3\u0142
-button.showlines=Poka\u017C linie
+button.moveup=Do g\u00f3ry
+button.movedown=Na d\u00f3\u0142
+button.showlines=Poka\u017c linie
button.edit=Edycja
button.exit=Zako\u0144cz
button.close=Zamknij
@@ -313,9 +374,10 @@ button.notoall=Nie na wszystko
button.selectall=Zaznacz wszystko
button.selectnone=Odznacz
button.preview=Podgl\u0105d
+button.load=\u0141aduj
button.guessfields=Zgadnij pola
-button.showwebpage=Poka\u017C stron\u0119 web
-button.gnuplotpath=Podaj \u015Bcie\u017Ck\u0119 do gnuplot
+button.showwebpage=Poka\u017c stron\u0119 web
+button.check=Sprawd\u017a
# File types
filetype.txt=Pliki TXT
@@ -329,60 +391,61 @@ filetype.svg=Pliki SVG
# Display components
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
+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=Ilo\u015B\u0107 plik\u00F3w
-details.pointdetails=Szczeg\u00F3\u0142y punktu
+details.track.numfiles=Ilo\u015b\u0107 plik\u00f3w
+details.pointdetails=Szczeg\u00f3\u0142y punktu
details.index.selected=Indeks
details.index.of=z
-details.nopointselection=\u017Baden punkt nie jest zaznaczony
+details.nopointselection=\u017baden punkt nie jest zaznaczony
details.photofile=Plik zdj\u0119cia
details.norangeselection=Brak zakresu zaznaczenia
-details.rangedetails=Szczeg\u00F3\u0142y zakresu
+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
+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=\u015Arednia pr\u0119dko\u015B\u0107
-details.range.avemovingspeed=\u015Arednie przesuni\u0119cie
-details.waypointsphotos.waypoints=Punkty po\u015Brednie
+details.range.avespeed=\u015arednia pr\u0119dko\u015b\u0107
+details.range.avemovingspeed=\u015arednie przesuni\u0119cie
+details.range.pace=Tempo
+details.waypointsphotos.waypoints=Punkty po\u015brednie
details.waypointsphotos.photos=Zdj\u0119cia
-details.photodetails=Szczeg\u00F3\u0142y zdj\u0119cia
+details.photodetails=Szczeg\u00f3\u0142y zdj\u0119cia
details.nophoto=Brak zaznaczonego zdj\u0119cia
details.photo.loading=Wczytywanie
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.latitude=Szeroko\u015b\u0107
+fieldname.longitude=D\u0142ugo\u015b\u0107
+fieldname.altitude=Wysoko\u015b\u0107
fieldname.timestamp=Czas
fieldname.time=Czas
fieldname.waypointname=Nazwa
fieldname.waypointtype=Typ
fieldname.newsegment=Odcinek
-fieldname.custom=U\u017Cytkownika
+fieldname.custom=U\u017cytkownika
fieldname.prefix=Pole
-fieldname.distance=Odleg\u0142o\u015B\u0107
-fieldname.movingdistance=Odleg\u0142o\u015B\u0107 przesuni\u0119cia
+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
+fieldname.speed=Pr\u0119dko\u015b\u0107
+fieldname.verticalspeed=Pr\u0119dko\u015b\u0107 pionowa
# Measurement units
units.original=Oryginalny
-units.default=Domy\u015Blny
+units.default=Domy\u015blny
units.metres=Metry
units.metres.short=m
units.feet=Stopy
@@ -417,43 +480,44 @@ undo.editpoint=edycja punktu
undo.deletepoint=usu\u0144 punkt
undo.deletephoto=usu\u0144 zdj\u0119cie (nie z dysku)
undo.deleterange=usu\u0144 zakres
-undo.compress=skompresuj \u015Bcie\u017Ck\u0119
+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.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.addaltitudeoffset=dodaj przeuni\u0119cie wysoko\u015bci
+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
+undo.createpoint=stw\u00f3rz punkt
# Error messages
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.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.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.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.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.undofailed.text=Nie mo\u017cna cofn\u0105\u0107
error.function.noop.title=Funkcja nie ma skutku
-error.rearrange.noop=Przestawienie punkt\u00F3w po\u015Brednich nie przyniesie 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.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.
+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.
\ No newline at end of file
diff --git a/tim/prune/lang/prune-texts_pt.properties b/tim/prune/lang/prune-texts_pt.properties
index 3944ed2..53e0142 100644
--- a/tim/prune/lang/prune-texts_pt.properties
+++ b/tim/prune/lang/prune-texts_pt.properties
@@ -4,456 +4,85 @@
# 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
+# Alt keys for menus
+altkey.menu.file=A
+altkey.menu.edit=E
+altkey.menu.select=S
+altkey.menu.view=X
+altkey.menu.photo=F
+altkey.menu.help=A
+
+# Ctrl shortcuts for menu items
+shortcut.menu.file.open=A
+shortcut.menu.file.save=S
+shortcut.menu.edit.undo=Z
+shortcut.menu.select.all=T
+shortcut.menu.help.help=H
+
# Functions
-function.loadfromgps=
-function.sendtogps=
function.exportkml=Exportar KML
function.exportgpx=Exportar GPX
function.exportpov=Exportar POV
-function.compress=
-function.addtimeoffset=
+function.editwaypointname=Editar nome do waypoint
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
index 95c1df0..9e9b22e 100644
--- a/tim/prune/lang/prune-texts_ro.properties
+++ b/tim/prune/lang/prune-texts_ro.properties
@@ -2,19 +2,18 @@
# Romanian entries as extra
# Menu entries
-menu.file=Fisier
-menu.file.open=Deschidere fisier
+menu.file=Fi\u015Fier
+menu.file.open=Deschidere fi\u015Fier
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.clearundo=\u015Etergere 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.deletepoint=\u015Etergere punct
+menu.edit.deleterange=\u015Etergere gama
+menu.edit.deletemarked=\u015Etergere puncte marcate
menu.edit.interpolate=Interpolare
menu.edit.average=Mediere selectie
menu.edit.reverse=Inversare selectie
@@ -42,418 +41,62 @@ 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=
+menu.map.zoomin=Apropie in
+menu.map.zoomout=Apropie out
+menu.map.newpoint=Adaug\u0103 punct
+menu.map.connect=Traseaz\u0103 linii între puncte
-# 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=
+# Alt keys for menus
+altkey.menu.file=F
+altkey.menu.edit=E
+altkey.menu.select=S
+altkey.menu.view=V
+altkey.menu.photo=O
+altkey.menu.help=A
-# 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=
+# Ctrl shortcuts for menu items
+shortcut.menu.file.open=D
+shortcut.menu.file.save=S
+shortcut.menu.edit.undo=Z
+shortcut.menu.select.all=T
-# 3d window
-dialog.3d.title=
-dialog.3d.altitudecap=
-dialog.3dlines.title=
-dialog.3dlines.empty=
-dialog.3dlines.intro=
+# Functions
+function.exportkml=Export\u0103 într-un fi\u015Fier KML
+function.exportgpx=Export\u0103 într-un fi\u015Fier GPX
+function.exportpov=Export\u0103 într-un fi\u015Fier POV
+function.editwaypointname=Editare nume waypoint
+function.help=Ajutor
+function.about=Despre Prune
-# 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=
+# Dialogs
+dialog.save.overwrite.text=Fi\u015Fierul exist\u0103. Îl suprascriu?
+dialog.pointedit.text=V\u0103 rog selecta\u0163i rândul care va fi editat
+dialog.pointedit.table.value=Valoare
+dialog.findwaypoint.search=C\u0103utare
+dialog.setmapbg.mapnik=Mapnik (implicit)
+dialog.setmapbg.server=Adres\u0103 server
+dialog.correlate.options.tip=Indiciu: By manually correlating at least one photo, the time offset can be calculated for you.
+dialog.about.version=Versiunea
+dialog.about.readme=Cite\u015Fte-m\u0103
# 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=
+button.ok=OK
+button.cancel=Renun\u0163\u0103
+button.edit=Editare
+button.exit=Iesire
# File types
-filetype.txt=
-filetype.jpeg=
-filetype.kmlkmz=
-filetype.kml=
-filetype.kmz=
-filetype.gpx=
-filetype.pov=
-filetype.svg=
+filetype.jpeg=Imagine JPEG (*.jpg)
# 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=
+details.track.points=Puncte
+details.pointdetails=Punct
+details.range.selected=Selectat
+details.range.to=la
+details.altitude.to=la
# 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=
+fieldname.waypointname=Nume
# 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=
+units.default=Implicit
diff --git a/tim/prune/lang/prune-texts_zh.properties b/tim/prune/lang/prune-texts_zh.properties
new file mode 100644
index 0000000..d91fea7
--- /dev/null
+++ b/tim/prune/lang/prune-texts_zh.properties
@@ -0,0 +1,523 @@
+# Text entries for the Prune application
+# Chinese entries as extra
+
+# Menu entries
+menu.file=\u6587\u4ef6
+menu.file.open=\u6253\u5f00
+menu.file.addphotos=\u6dfb\u52a0\u76f8\u7247
+menu.file.save=\u4fdd\u5b58
+menu.file.exit=\u9000\u51fa
+menu.edit=\u7f16\u8f91
+menu.edit.undo=\u64a4\u9500
+menu.edit.clearundo=\u6e05\u9664\u64a4\u9500\u6e05\u5355
+menu.edit.editpoint=\u7f16\u8f91\u8f68\u8ff9\u70b9
+menu.edit.deletepoint=\u5220\u9664\u8f68\u8ff9\u70b9
+menu.edit.deleterange=\u5220\u9664\u8f68\u8ff9\u70b9\u6bb5
+menu.edit.deletemarked=\u5220\u9664\u5df2\u6807\u793a\u8f68\u8ff9\u70b9
+menu.edit.interpolate=\u63d2\u5165\u8f68\u8ff9\u70b9
+menu.edit.average=\u8bbe\u7f6e\u5e73\u5747\u8f68\u8ff9\u70b9
+menu.edit.reverse=\u8f68\u8ff9\u70b9\u53cd\u5411
+menu.edit.mergetracksegments=\u5408\u5e76\u8f68\u8ff9\u6bb5
+menu.edit.rearrange=\u822a\u70b9\u91cd\u7f6e
+menu.edit.rearrange.start=\u81f3\u8d77\u59cb\u4f4d\u7f6e
+menu.edit.rearrange.end=\u81f3\u672b\u4f4d\u7f6e
+menu.edit.rearrange.nearest=\u81f3\u6700\u8fd1\u8f68\u8ff9\u70b9
+menu.edit.cutandmove=\u79fb\u52a8
+menu.select=\u9009\u62e9
+menu.select.all=\u5168\u9009
+menu.select.none=\u64a4\u9500\u9009\u62e9
+menu.select.start=\u8bbe\u7f6e\u8d77\u70b9
+menu.select.end=\u8bbe\u7f6e\u672b\u70b9
+menu.photo=\u76f8\u7247
+menu.photo.saveexif=\u5750\u6807\u4fdd\u5b58\u81f3Exif
+menu.photo.connect=\u94fe\u63a5\u76f8\u7247
+menu.photo.disconnect=\u64a4\u9500\u94fe\u63a5
+menu.photo.delete=\u5220\u9664\u7167\u7247
+menu.view=\u67e5\u770b
+menu.view.browser=\u5728\u6d4f\u89c8\u5668\u4e2d\u6253\u5f00\u5730\u56fe
+menu.view.browser.google=Google\u5730\u56fe
+menu.view.browser.openstreetmap=Openstreet\u5730\u56fe
+menu.view.browser.mapquest=Mapquest\u5730\u56fe
+menu.view.browser.yahoo=Yahoo\u5730\u56fe
+menu.settings=\u8bbe\u7f6e
+menu.settings.showpace=\u663e\u793a\u6b65\u901f
+menu.help=\u5e2e\u52a9
+# Popup menu for map
+menu.map.zoomin=\u653e\u5927
+menu.map.zoomout=\u7f29\u5c0f
+menu.map.zoomfull=\u539f\u5c3a\u5bf8
+menu.map.newpoint=\u65b0\u5efa\u8f68\u8ff9\u70b9
+menu.map.connect=\u8fde\u63a5\u8f68\u8ff9\u70b9
+menu.map.autopan=\u81ea\u52a8\u7f29\u653e
+menu.map.showmap=\u663e\u793a\u5730\u56fe
+menu.map.showscalebar=\u663e\u793a\u6bd4\u4f8b\u5c3a
+
+# Alt keys for menus
+altkey.menu.file=
+altkey.menu.edit=
+altkey.menu.select=
+altkey.menu.view=
+altkey.menu.photo=
+altkey.menu.settings=
+altkey.menu.help=
+
+# Ctrl shortcuts for menu items
+shortcut.menu.file.open=
+shortcut.menu.file.load=
+shortcut.menu.file.save=
+shortcut.menu.edit.undo=
+shortcut.menu.edit.compress=
+shortcut.menu.select.all=
+shortcut.menu.help.help=
+
+# Functions
+function.loadfromgps=\u4eceGPS\u5bfc\u5165
+function.sendtogps=\u53d1\u9001\u81f3GPS
+function.exportkml=\u8f93\u51faKML\u6587\u4ef6
+function.exportgpx=\u8f93\u51faGPX\u6587\u4ef6
+function.exportpov=\u8f93\u51faPOV\u6587\u4ef6
+function.editwaypointname=\u7f16\u8f91\u822a\u70b9\u540d
+function.compress=\u538b\u7f29\u8f68\u8ff9(\u6807\u793a\u8981\u5220\u9664\u822a\u70b9\uff09
+function.addtimeoffset=\u52a0\u5165\u65f6\u95f4\u5dee
+function.addaltitudeoffset=\u52a0\u5165\u9ad8\u5ea6\u504f\u79fb
+function.findwaypoint=\u67e5\u627e\u822a\u70b9
+function.charts=\u9ad8\u5ea6\u901f\u5ea6\u56fe\u8868
+function.show3d=3-D\u89c6\u56fe
+function.distances=\u8ddd\u79bb
+function.getgpsies=Gpsies\u8f68\u8ff9
+function.correlatephotos=\u94fe\u63a5\u76f8\u7247
+function.setmapbg=\u80cc\u666f\u5730\u56fe
+function.setkmzimagesize=
+function.setpaths=\u8bbe\u7f6e\u7a0b\u5e8f\u8def\u5f84
+function.help=\u5e2e\u52a9
+function.showkeys=\u663e\u793a\u5feb\u6377\u952e
+function.about=\u5173\u4e8ePrune
+function.checkversion=\u68c0\u67e5\u66f4\u65b0
+function.saveconfig=\u4fdd\u5b58\u8bbe\u7f6e
+
+# Dialogs
+dialog.exit.confirm.title=\u9000\u51fa
+dialog.exit.confirm.text=\u6570\u636e\u672a\u4fdd\u5b58\uff0c\u662f\u5426\u9000\u51fa\uff1f
+dialog.openappend.title=\u9644\u52a0\u81f3\u5df2\u5bfc\u5165\u6570\u636e
+dialog.openappend.text=\u9644\u52a0\u73b0\u6709\u6570\u636e\u81f3\u5df2\u5bfc\u5165\u6570\u636e
+dialog.deletepoint.title=\u5220\u9664\u8f68\u8ff9\u70b9
+dialog.deletepoint.deletephoto=\u5220\u9664\u8f68\u8ff9\u70b9\u94fe\u63a5\u7684\u76f8\u7247\uff1f
+dialog.deletephoto.title=\u5220\u9664\u76f8\u7247
+dialog.deletephoto.deletepoint=\u5220\u9664\u76f8\u7247\u94fe\u63a5\u7684\u8f68\u8ff9\u70b9\uff1f
+dialog.openoptions.title=\u6253\u5f00\u9009\u9879
+dialog.openoptions.filesnippet=\u6587\u4ef6\u683c\u5f0f
+dialog.load.table.field=\u6570\u636e\u6bb5
+dialog.load.table.datatype=\u6570\u636e\u7c7b\u578b
+dialog.load.table.description=\u63cf\u8ff0
+dialog.delimiter.label=\u6570\u636e\u6bb5\u5206\u9694\u7b26
+dialog.delimiter.comma=\u9017\u53f7
+dialog.delimiter.tab=Tab
+dialog.delimiter.space=\u7a7a\u683c
+dialog.delimiter.semicolon=\u5206\u53f7
+dialog.delimiter.other=\u5176\u4ed6
+dialog.openoptions.deliminfo.records=\u6761\u8bb0\u5f55\uff0c
+dialog.openoptions.deliminfo.fields=\u6570\u636e\u6bb5
+dialog.openoptions.deliminfo.norecords=\u65e0\u7eaa\u5f55
+dialog.openoptions.altitudeunits=\u9ad8\u5ea6\u5355\u4f4d
+dialog.jpegload.subdirectories=\u542b\u6b21\u7ea7\u65b9\u4f4d
+dialog.jpegload.loadjpegswithoutcoords=\u542b\u65e0\u5750\u6807\u70b9\u76f8\u7247
+dialog.jpegload.loadjpegsoutsidearea=\u542b\u533a\u57df\u5916\u76f8\u7247
+dialog.jpegload.progress.title=\u5bfc\u5165\u76f8\u7247
+dialog.jpegload.progress=\u8bf7\u7b49\u5f85\uff0c\u6b63\u641c\u7d22\u76f8\u7247
+dialog.gpsload.nogpsbabel=\u627e\u4e0d\u5230Gpsbabel,\u7ee7\u7eed\uff1f
+dialog.gpsload.device=GPS\u7aef\u53e3\u540d\u79f0
+dialog.gpsload.format=GPS\u6587\u4ef6\u683c\u5f0f
+dialog.gpsload.getwaypoints=\u5bfc\u5165\u822a\u70b9
+dialog.gpsload.gettracks=\u5bfc\u5165\u8f68\u8ff9
+dialog.gpssend.sendwaypoints=\u53d1\u9001\u822a\u70b9
+dialog.gpssend.sendtracks=\u53d1\u9001\u8f68\u8ff9
+dialog.gpssend.trackname=\u8f68\u8ff9\u540d
+dialog.saveoptions.title=\u4fdd\u5b58
+dialog.save.fieldstosave=\u4fdd\u5b58\u6570\u636e\u6bb5
+dialog.save.table.field=\u6570\u636e\u6bb5
+dialog.save.table.hasdata=\u6709\u6570\u636e
+dialog.save.table.save=\u4fdd\u5b58
+dialog.save.headerrow=\u8f93\u51fa\u5934\u884c
+dialog.save.coordinateunits=\u5750\u6807\u5355\u4f4d
+dialog.save.altitudeunits=\u9ad8\u5ea6\u5355\u4f4d
+dialog.save.timestampformat=\u65f6\u95f4\u683c\u5f0f
+dialog.save.overwrite.title=\u6587\u4ef6\u5df2\u5b58\u5728
+dialog.save.overwrite.text=\u6587\u4ef6\u5df2\u5b58\u5728\uff0c\u662f\u5426\u8986\u76d6\uff1f
+dialog.exportkml.text=\u6570\u636e\u540d\u79f0
+dialog.exportkml.altitude=\u7edd\u5bf9\u9ad8\u5ea6\uff08\u822a\u7a7a\u7528\uff09
+dialog.exportkml.kmz=\u538b\u7f29\u6210KMZ\u6587\u4ef6
+dialog.exportkml.exportimages=\u8f93\u51fa\u76f8\u7247\u7d22\u5f15\u56fe\u81f3KMZ
+dialog.exportgpx.name=\u540d\u79f0
+dialog.exportgpx.desc=\u63cf\u8ff0
+dialog.exportgpx.includetimestamps=\u5305\u542b\u65f6\u95f4
+dialog.exportpov.text=\u8bf7\u8f93\u5165POV\u53c2\u6570
+dialog.exportpov.font=\u5b57\u4f53
+dialog.exportpov.camerax=X\u76f8\u673a
+dialog.exportpov.cameray=Y\u76f8\u673a
+dialog.exportpov.cameraz=Z\u76f8\u673a
+dialog.exportpov.modelstyle=\u6a21\u578b\u7c7b\u578b
+dialog.exportpov.ballsandsticks=\u7403\u548c\u6746
+dialog.exportpov.tubesandwalls=\u7ba1\u548c\u5899
+dialog.exportpov.warningtracksize=\u8f68\u8ff9\u542b\u6709\u592a\u591a\u822a\u70b9\uff0cJAVA3D\u53ef\u80fd\u65e0\u6cd5\u663e\u793a\n\u662f\u5426\u7ee7\u7eed\uff1f
+dialog.pointtype.desc=\u4fdd\u5b58\u4e0b\u5217\u70b9\uff1a
+dialog.pointtype.track=\u8f68\u8ff9\u70b9
+dialog.pointtype.waypoint=\u822a\u70b9
+dialog.pointtype.photo=\u76f8\u7247\u70b9
+dialog.confirmreversetrack.title=\u786e\u8ba4\u53cd\u5411
+dialog.confirmreversetrack.text=\u8f68\u8ff9\u5305\u542b\u65f6\u95f4\u4fe1\u606f\uff0c\u53cd\u5411\u540e\u53ef\u80fd\u4e22\u5931\n\u662f\u5426\u7ee7\u7eed\uff1f
+dialog.confirmcutandmove.title=\u786e\u8ba4\u526a\u5207\u548c\u79fb\u52a8
+dialog.confirmcutandmove.text=\u8f68\u8ff9\u5305\u542b\u65f6\u95f4\u4fe1\u606f\uff0c\u79fb\u52a8\u540e\u53ef\u80fd\u4e22\u5931\n\u662f\u5426\u7ee7\u7eed\uff1f
+dialog.interpolate.title=\u91cd\u53e0\u8f68\u8ff9\u70b9
+dialog.interpolate.parameter.text=\u6240\u9009\u4e24\u70b9\u4e2d\u63d2\u5165\u70b9\u7684\u4e2a\u6570
+dialog.undo.title=\u64a4\u9500\u52a8\u4f5c
+dialog.undo.pretext=\u8bf7\u9009\u62e9\u8981\u64a4\u9500\u7684\u52a8\u4f5c
+dialog.undo.none.title=\u4e0d\u80fd\u64a4\u9500
+dialog.undo.none.text=\u65e0\u52a8\u4f5c\u53ef\u64a4\u9500
+dialog.clearundo.title=\u6e05\u9664\u64a4\u9500\u6e05\u5355
+dialog.clearundo.text=\u662f\u5426\u786e\u5b9e\u8981\u6e05\u9664\u64a4\u9500\u6e05\u5355\uff1f\n\u64a4\u9500\u4fe1\u606f\u4f1a\u4e22\u5931
+dialog.pointedit.title=\u7f16\u8f91\u8f68\u8ff9\u70b9
+dialog.pointedit.text=\u9009\u62e9\u8981\u7f16\u8f91\u7684\u533a\u57df\u5e76\u7528\u201c\u7f16\u8f91\u201d\u952e\u6539\u53d8\u6570\u503c
+dialog.pointedit.table.field=\u6570\u636e\u6bb5
+dialog.pointedit.table.value=\u6570\u503c
+dialog.pointedit.table.changed=\u6539\u53d8
+dialog.pointedit.changevalue.text=\u8f93\u5165\u65b0\u6570\u503c
+dialog.pointedit.changevalue.title=\u7f16\u8f91\u6570\u636e\u6bb5
+dialog.pointnameedit.name=\u822a\u70b9\u540d\u79f0
+dialog.pointnameedit.uppercase=\u4e0a\u6863\u952e
+dialog.pointnameedit.lowercase=\u4e0b\u6863\u952e
+dialog.pointnameedit.sentencecase=\u6807\u9898\u952e
+dialog.addtimeoffset.add=\u5ef6\u540e\u65f6\u95f4
+dialog.addtimeoffset.subtract=\u63d0\u524d\u65f6\u95f4
+dialog.addtimeoffset.days=\u5929\u6570
+dialog.addtimeoffset.hours=\u5c0f\u65f6
+dialog.addtimeoffset.minutes=\u5206\u949f
+dialog.addtimeoffset.notimestamps=\u4e0d\u80fd\u6dfb\u52a0\u65f6\u95f4\u56e0\u4e3a\u6b64\u6bb5\u4e0d\u542b\u65f6\u95f4\u4fe1\u606f
+dialog.findwaypoint.intro=\u8f93\u5165\u90e8\u5206\u822a\u70b9\u540d
+dialog.findwaypoint.search=\u641c\u7d22
+dialog.connect.title=\u94fe\u63a5\u7167\u7247\u548c\u822a\u70b9
+dialog.connectphoto.clonepoint=\u6b64\u8f68\u8ff9\u70b9\u5df2\u6709\u50cf\u7247\n\u662f\u5426\u590d\u5236\u822a\u70b9\uff1f
+dialog.saveexif.title=\u4fdd\u5b58Exif
+dialog.saveexif.intro=\u9009\u62e9\u8981\u4fdd\u5b58\u7684\u76f8\u7247
+dialog.saveexif.nothingtosave=\u5750\u6807\u672a\u6539\u53d8\uff0c\u65e0\u4fdd\u5b58\u5185\u5bb9
+dialog.saveexif.noexiftool=\u672a\u627e\u5230Exif \u5de5\u5177\uff0c\u7ee7\u7eed\uff1f
+dialog.saveexif.table.photoname=\u76f8\u7247\u540d
+dialog.saveexif.table.status=\u72b6\u6001
+dialog.saveexif.table.save=\u4fdd\u5b58
+dialog.saveexif.photostatus.connected=\u5df2\u94fe\u63a5
+dialog.saveexif.photostatus.disconnected=\u672a\u94fe\u63a5
+dialog.saveexif.photostatus.modified=\u5df2\u6539\u53d8
+dialog.saveexif.overwrite=\u8986\u76d6\u6587\u4ef6
+dialog.charts.xaxis=X\u8f74
+dialog.charts.yaxis=Y\u8f74
+dialog.charts.output=\u8f93\u51fa
+dialog.charts.screen=\u8f93\u51fa\u81f3\u5c4f\u5e55
+dialog.charts.svg=\u8f93\u51fa\u81f3SVG\u6587\u4ef6
+dialog.charts.svgwidth=SVG\u5bbd\u5ea6
+dialog.charts.svgheight=SVG\u9ad8\u5ea6
+dialog.charts.needaltitudeortimes=\u8f68\u8ff9\u5fc5\u987b\u542b\u6709\u9ad8\u5ea6\u6216\u65f6\u95f4\u4fe1\u606f
+dialog.charts.gnuplotpath=gnuplot\u8def\u5f84
+dialog.charts.gnuplotnotfound=\u8def\u5f84\u9519\u8bef\uff0c\u65e0\u6cd5\u627e\u5230gnuplot
+dialog.distances.intro=\u822a\u70b9\u4e4b\u95f4\u76f4\u7ebf\u8ddd\u79bb
+dialog.distances.column.from=\u4ece\u6b64\u70b9
+dialog.distances.column.to=\u5230\u6b64\u70b9
+dialog.distances.currentpoint=\u5f53\u524d\u70b9
+dialog.distances.toofewpoints=\u9700\u8981\u822a\u70b9\u6765\u8ba1\u7b97\u8ddd\u79bb
+dialog.setmapbg.mapnik=Mapnik(\u7f3a\u7701)
+dialog.setmapbg.osma=Osma
+dialog.setmapbg.cyclemap=Cyclemap
+dialog.setmapbg.other=\u5176\u4ed6(\u5728\u4e0b\u9762\u8f93\u5165URL)
+dialog.setmapbg.server=\u5730\u56fe\u670d\u52a1\u5668URL
+dialog.gpsies.column.name=\u8f68\u8ff9\u540d\u79f0
+dialog.gpsies.column.length=\u957f\u5ea6
+dialog.gpsies.description=\u63cf\u8ff0
+dialog.gpsies.nodescription=\u65e0\u63cf\u8ff0
+dialog.gpsies.nonefound=
+dialog.correlate.notimestamps=\u6570\u636e\u70b9\u4e2d\u65e0\u65f6\u95f4\u4fe1\u606f\uff0c\u76f8\u7247\u65e0\u6cd5\u94fe\u63a5
+dialog.correlate.nouncorrelatedphotos=\u6240\u6709\u76f8\u7247\u5df2\u94fe\u63a5\n\u7ee7\u7eed\uff1f
+dialog.correlate.photoselect.intro=\u9009\u62e9\u5df2\u94fe\u63a5\u76f8\u7247\u4f5c\u4e3a\u65f6\u95f4\u504f\u79fb
+dialog.correlate.photoselect.photoname=\u76f8\u7247\u540d
+dialog.correlate.photoselect.timediff=\u65f6\u95f4\u5dee
+dialog.correlate.photoselect.photolater=\u76f8\u7247\u5ef6\u540e
+dialog.correlate.options.tip=\u63d0\u793a\uff1a\u624b\u52a8\u94fe\u63a5\u81f3\u5c11\u4e00\u5f20\u76f8\u7247\uff0c\u53ef\u81ea\u52a8\u8ba1\u7b97\u65f6\u95f4\u504f\u79fb
+dialog.correlate.options.intro=\u9009\u62e9\u81ea\u52a8\u94fe\u63a5\u8bbe\u7f6e
+dialog.correlate.options.offsetpanel=\u65f6\u95f4\u504f\u79fb
+dialog.correlate.options.offset=\u504f\u79fb
+dialog.correlate.options.offset.hours=\u5c0f\u65f6
+dialog.correlate.options.offset.minutes=\u5206\u949f
+dialog.correlate.options.offset.seconds=\u79d2
+dialog.correlate.options.photolater=\u76f8\u7247\u6ede\u540e\u4e8e\u8f68\u8ff9\u70b9
+dialog.correlate.options.pointlater=\u8f68\u8ff9\u70b9\u6ede\u540e\u4e8e\u76f8\u7247
+dialog.correlate.options.limitspanel=\u94fe\u63a5\u9650\u5236
+dialog.correlate.options.notimelimit=\u65e0\u65f6\u95f4\u9650\u5236
+dialog.correlate.options.timelimit=\u65f6\u95f4\u9650\u5236
+dialog.correlate.options.nodistancelimit=\u65e0\u8ddd\u79bb\u9650\u5236
+dialog.correlate.options.distancelimit=\u8ddd\u79bb\u9650\u5236
+dialog.correlate.options.correlate=\u94fe\u63a5
+dialog.correlate.alloutsiderange=\u65e0\u6cd5\u94fe\u63a5\uff0c\u6240\u6709\u76f8\u7247\u8d85\u51fa\u8f68\u8ff9\u65f6\u95f4\u8303\u56f4\n\u8bf7\u6539\u53d8\u65f6\u95f4\u504f\u79fb\u6216\u624b\u52a8\u94fe\u63a5\u81f3\u5c11\u4e00\u5f20\u76f8\u7247
+dialog.compress.nonefound=\u65e0\u6cd5\u5220\u9664\u6570\u636e\u70b9
+dialog.compress.duplicates.title=\u91cd\u590d\u70b9\u5220\u9664
+dialog.compress.closepoints.title=\u90bb\u8fd1\u70b9\u5220\u9664
+dialog.compress.closepoints.paramdesc=\u8303\u56f4\u7cfb\u6570
+dialog.compress.wackypoints.title=\u5f02\u5e38\u70b9\u5220\u9664
+dialog.compress.wackypoints.paramdesc=\u8ddd\u79bb\u7cfb\u6570
+dialog.compress.singletons.title=\u79bb\u6563\u70b9\u5220\u9664
+dialog.compress.singletons.paramdesc=\u8ddd\u79bb\u7cfb\u6570
+dialog.compress.summarylabel=\u8981\u5220\u9664\u7684\u70b9
+dialog.help.help=\u66f4\u591a\u4fe1\u606f\u548c\u7528\u6cd5\uff0c\u8bf7\u53c2\u8003\u7f51\u7ad9\nhttp://activityworkshop.net/software/prune///
+dialog.about.version=\u7248\u672c
+dialog.about.build=Build
+dialog.about.summarytext1=Prune\u662f\u4e00\u4e2a\u4eceGPS\u4e2d\u5bfc\u5165\u6570\u636e\uff0c\u663e\u793a\u6570\u636e\u548c\u7f16\u8f91\u6570\u636e\u7684\u8f6f\u4ef6
+dialog.about.summarytext2=\u5b83\u7684\u53d1\u884c\u662f\u57fa\u4e8eGnu GPL\u89c4\u5219\uff0c\u662f\u514d\u8d39\u7684\uff0c\u5f00\u653e\u5f0f\u7684\uff0c\u5168\u4e16\u754c\u5171\u7528\u5e76\u6539\u5584\u589e\u5f3a\u5176\u529f\u80fd\n\u5728\u7b26\u5408"license.txt"\u6761\u4ef6\u4e0b\uff0c\u5bb9\u8bb8\u5e76\u9f13\u52b1\u590d\u5236\uff0c\u5206\u53d1\u53ca\u4fee\u6539\u3002
+dialog.about.summarytext3=\u66f4\u591a\u4fe1\u606f\u53ca\u7528\u6cd5\u6307\u5357\uff0c\u8bf7\u53c2\u8003\u7f51\u7ad9\uff1a\nhttp:activityworkshop.net/
+dialog.about.languages=\u652f\u6301\u8bed\u8a00
+dialog.about.translatedby=\u4e2d\u6587\u7ffb\u8bd1\uff1a\u9ed1\u8001\u9648 (Sam Chen)
+dialog.about.systeminfo=\u7cfb\u7edf\u4fe1\u606f
+dialog.about.systeminfo.os=\u64cd\u4f5c\u7cfb\u7edf
+dialog.about.systeminfo.java=Java Runtime
+dialog.about.systeminfo.java3d=Java 3D \u662f\u5426\u5b89\u88c5
+dialog.about.systeminfo.povray=Povray \u662f\u5426\u5b89\u88c5
+dialog.about.systeminfo.exiftool=Exiftool \u662f\u5426\u5b89\u88c5
+dialog.about.systeminfo.gpsbabel=Gpsbabel \u662f\u5426\u5b89\u88c5
+dialog.about.systeminfo.gnuplot=Gnuplot \u662f\u5426\u5b89\u88c5
+dialog.about.yes=\u662f
+dialog.about.no=\u5426
+dialog.about.credits=\u81f4\u8c22
+dialog.about.credits.code=Prune \u539f\u7801\u7f16\u5199
+dialog.about.credits.exifcode=Exif \u539f\u7801\u7f16\u5199
+dialog.about.credits.icons=\u56fe\u6807\u6765\u81ea\u4e8e
+dialog.about.credits.translators=\u8bd1\u8005
+dialog.about.credits.translations=\u7ffb\u8bd1\u52a9\u7406
+dialog.about.credits.devtools=\u5f00\u53d1\u5de5\u5177
+dialog.about.credits.othertools=\u5176\u4ed6\u5de5\u5177
+dialog.about.credits.thanks=\u81f3\u8c22
+dialog.about.readme=\u7248\u672c\u4fe1\u606f
+dialog.checkversion.error=\u65e0\u6cd5\u68c0\u6d4b\u7248\u672c\u66f4\u65b0\n\u8bf7\u68c0\u67e5\u7f51\u7edc\u8fde\u63a5
+dialog.checkversion.uptodate=\u4f60\u4f7f\u7528\u7684\u5df2\u662f\u6700\u65b0\u7248\u672c
+dialog.checkversion.newversion1=\u65b0\u7248\u672c\u5b58\u5728\uff0c \u6700\u65b0\u7248\u672c\u53f7\u662f\uff1a
+dialog.checkversion.newversion2=
+dialog.checkversion.releasedate1=\u65b0\u7248\u672c\u53d1\u884c\u4e8e
+dialog.checkversion.releasedate2=
+dialog.checkversion.download=\u4e0b\u8f7d\u6700\u65b0\u7248\u672c\uff0c\u8bf7\u767b\u9646\u7f51\u7ad9\uff1a\nhttp://activityworkshop.net/software/prune/download.html
+dialog.keys.intro=\u53ef\u7528\u4e0b\u5217\u5feb\u6377\u952e\u66ff\u4ee3\u9f20\u6807
+dialog.keys.keylist=
+dialog.saveconfig.desc=\u4e0b\u5217\u8bbe\u7f6e\u5c06\u4fdd\u5b58\u5230\u8bbe\u7f6e\u6587\u4ef6
+dialog.saveconfig.prune.trackdirectory=\u8f68\u8ff9\u6587\u4ef6\u5939
+dialog.saveconfig.prune.photodirectory=\u76f8\u7247\u6587\u4ef6\u5939
+dialog.saveconfig.prune.languagecode=\u8bed\u8a00\u9009\u62e9(ZH)
+dialog.saveconfig.prune.gpsdevice=GPS\u7aef\u53e3\u540d\u79f0
+dialog.saveconfig.prune.gpsformat=GPS\u6587\u4ef6\u683c\u5f0f
+dialog.saveconfig.prune.povrayfont=Povray \u5b57\u4f53
+dialog.saveconfig.prune.metricunits=\u4f7f\u7528\u516c\u5236\uff1f
+dialog.saveconfig.prune.gnuplotpath=gnuplot\u8def\u5f84
+dialog.saveconfig.prune.gpsbabelpath=gpsbabel\u8def\u5f84
+dialog.saveconfig.prune.exiftoolpath=exiftool\u8def\u5f84
+dialog.saveconfig.prune.mapserverindex=\u80cc\u666f\u5730\u56fe\u7801(1-4)
+dialog.saveconfig.prune.mapserverurl=\u90094\u65f6\u5730\u56fe\u670d\u52a1\u5668URL
+dialog.saveconfig.prune.showpace=\u663e\u793a\u6b65\u901f
+dialog.saveconfig.prune.kmzimagewidth=
+dialog.saveconfig.prune.kmzimageheight=
+dialog.setpaths.intro=\u82e5\u9700\u8981\uff0c\u53ef\u8bbe\u5b9a\u5916\u6302\u7a0b\u5e8f\u8def\u5f84
+dialog.addaltitude.noaltitudes=\u8f68\u8ff9\u4e0d\u542b\u9ad8\u5ea6\u4fe1\u606f
+dialog.addaltitude.desc=\u9ad8\u5ea6\u504f\u79fb
+
+# 3d window
+dialog.3d.title=Prune 3D \u663e\u793a
+dialog.3d.altitudecap=\u9ad8\u5ea6\u6bd4\u4f8b
+dialog.3dlines.title=Prune \u7f51\u683c\u7ebf
+dialog.3dlines.empty=\u65e0\u6cd5\u663e\u793a\u7f51\u683c\u7ebf
+dialog.3dlines.intro=3D \u7f51\u683c\u7ebf
+
+# Confirm messages || These are displayed as confirmation in the status bar
+confirm.loadfile=\u6570\u636e\u5df2\u4ece\u6587\u4ef6\u5bfc\u5165
+confirm.save.ok1=\u4fdd\u5b58\u6210\u529f
+confirm.save.ok2=\u5df2\u4fdd\u5b58\u7684\u8f68\u8ff9\u70b9
+confirm.deletepoint.single=\u5df1\u5220\u9664\u7684\u8f68\u8ff9\u70b9
+confirm.deletepoint.multi=\u5df2\u5220\u9664\u7684\u8f68\u8ff9\u70b9
+confirm.point.edit=\u5df2\u7f16\u8f91\u7684\u8f68\u8ff9\u70b9
+confirm.mergetracksegments=\u5df2\u5408\u5e76\u7684\u8f68\u8ff9\u6bb5
+confirm.reverserange=\u53cd\u5411\u7684\u8303\u56f4
+confirm.addtimeoffset=\u5df2\u52a0\u4e0a\u65f6\u95f4\u504f\u5dee
+confirm.addaltitudeoffset=
+confirm.rearrangewaypoints=\u91cd\u65b0\u914d\u7f6e\u7684\u822a\u70b9
+confirm.cutandmove=\u5df2\u79fb\u52a8\u7684\u8f68\u8ff9\u6bb5
+confirm.saveexif.ok1=\u5df2\u4fdd\u5b58
+confirm.saveexif.ok2=\u76f8\u7247\u6587\u4ef6
+confirm.undo.single=\u5df2\u64a4\u9500\u7684\u64cd\u4f5c
+confirm.undo.multi=\u5df2\u64a4\u9500\u7684\u64cd\u4f5c
+confirm.jpegload.single=\u5df2\u52a0\u5165\u76f8\u7247
+confirm.jpegload.multi=\u5df2\u52a0\u5165\u76f8\u7247
+confirm.photo.connect=\u76f8\u7247\u5df2\u94fe\u63a5
+confirm.photo.disconnect=\u76f8\u7247\u672a\u94fe\u63a5
+confirm.correlate.single=\u76f8\u7247\u5df2\u94fe\u63a5
+confirm.correlate.multi=\u76f8\u7247\u5df2\u94fe\u63a5
+confirm.createpoint=\u5df2\u521b\u5efa\u70b9
+confirm.running=\u8bf7\u7a0d\u7b49...
+
+# Buttons
+button.ok=\u786e\u5b9a
+button.back=\u8fd4\u56de
+button.next=\u4e0b\u4e00\u6b65
+button.finish=\u5b8c\u6210
+button.cancel=\u53d6\u6d88
+button.overwrite=\u8986\u76d6
+button.moveup=\u4e0a\u79fb
+button.movedown=\u4e0b\u79fb
+button.showlines=\u663e\u793a\u7ebf\u6761
+button.edit=\u7f16\u8f91
+button.exit=\u9000\u51fa
+button.close=\u5173\u95ed
+button.continue=\u7ee7\u7eed
+button.yes=\u662f
+button.no=\u5426
+button.yestoall=\u5168\u90e8\u662f
+button.notoall=\u5168\u90e8\u5426
+button.selectall=\u5168\u9009
+button.selectnone=\u5168\u4e0d\u9009
+button.preview=\u9884\u89c8
+button.load=\u5bfc\u5165
+button.guessfields=\u731c\u4f30\u533a\u57df\u5185\u5bb9
+button.showwebpage=\u663e\u793a\u7f51\u9875
+button.check=\u68c0\u67e5
+
+# File types
+filetype.txt=TXT\u6587\u4ef6
+filetype.jpeg=JPG\u6587\u4ef6
+filetype.kmlkmz=KML,KMZ\u6587\u4ef6
+filetype.kml=KML\u6587\u4ef6
+filetype.kmz=KMZ\u6587\u4ef6
+filetype.gpx=GPX\u6587\u4ef6
+filetype.pov=POV\u6587\u4ef6
+filetype.svg=SVG\u6587\u4ef6
+
+# Display components
+display.nodata=\u65e0\u6570\u636e
+display.noaltitudes=\u8f68\u8ff9\u6570\u636e\u4e0d\u542b\u9ad8\u5ea6\u4fe1\u606f
+details.trackdetails=\u8f68\u8ff9\u4fe1\u606f
+details.notrack=\u65e0\u8f68\u8ff9
+details.track.points=\u8f68\u8ff9\u70b9
+details.track.file=\u6587\u4ef6
+details.track.numfiles=\u6587\u4ef6\u6570
+details.pointdetails=\u8f68\u8ff9\u70b9\u4fe1\u606f
+details.index.selected=\u7b2c
+details.index.of=\u70b9\u53d6\u81ea
+details.nopointselection=\u6ca1\u6709\u9009\u62e9\u70b9
+details.photofile=\u76f8\u7247\u6587\u4ef6
+details.norangeselection=\u6ca1\u6709\u9009\u62e9\u8f68\u8ff9/\u822a\u70b9\u6bb5
+details.rangedetails=\u8f68\u8ff9/\u822a\u70b9\u6bb5\u4fe1\u606f
+details.range.selected=\u9009\u4e2d
+details.range.to=\u81f3
+details.altitude.to=\u81f3
+details.range.climb=\u7d2f\u8ba1\u722c\u5347
+details.range.descent=\u7d2f\u8ba1\u4e0b\u964d
+details.coordformat=\u5750\u6807\u683c\u5f0f
+details.distanceunits=\u8ddd\u79bb\u5355\u4f4d
+display.range.time.secs=\u79d2
+display.range.time.mins=\u5206
+display.range.time.hours=\u5c0f\u65f6
+display.range.time.days=\u5929
+details.range.avespeed=\u5e73\u5747\u901f\u5ea6
+details.range.avemovingspeed=\u5e73\u5747\u79fb\u52a8
+details.range.pace=\u6b65\u901f
+details.waypointsphotos.waypoints=\u822a\u70b9
+details.waypointsphotos.photos=\u76f8\u7247
+details.photodetails=\u76f8\u7247\u4fe1\u606f
+details.nophoto=\u65e0\u76f8\u7247\u88ab\u9009\u4e2d
+details.photo.loading=\u6b63\u5bfc\u5165
+details.photo.connected=\u5df2\u94fe\u63a5
+map.overzoom=\u5728\u6b64\u653e\u5927\u5c3a\u5bf8\u4e0b\u65e0\u5730\u56fe\u8d44\u6599
+
+# Field names
+fieldname.latitude=\u7eac\u5ea6
+fieldname.longitude=\u7ecf\u5ea6
+fieldname.altitude=\u9ad8\u5ea6
+fieldname.timestamp=\u65f6\u95f4
+fieldname.time=\u65f6\u95f4
+fieldname.waypointname=\u540d\u79f0
+fieldname.waypointtype=\u7c7b\u578b
+fieldname.newsegment=\u6bb5
+fieldname.custom=\u7528\u6237
+fieldname.prefix=\u6570\u636e\u6bb5
+fieldname.distance=\u8ddd\u79bb
+fieldname.movingdistance=\u79fb\u52a8\u8ddd\u79bb
+fieldname.duration=\u65f6\u957f
+fieldname.speed=\u901f\u5ea6
+fieldname.verticalspeed=\u5782\u76f4\u901f\u5ea6
+
+# Measurement units
+units.original=\u539f\u59cb
+units.default=\u7f3a\u7701
+units.metres=\u7c73
+units.metres.short=\u7c73
+units.feet=\u82f1\u5c3a
+units.feet.short=\u82f1\u5c3a
+units.kilometres=\u5343\u7c73
+units.kilometres.short=\u5343\u7c73
+units.kmh=\u5343\u7c73/\u65f6
+units.miles=\u82f1\u91cc
+units.miles.short=\u82f1\u91cc
+units.mph=\u82f1\u91cc/\u65f6
+units.metrespersec=\u7c73/\u79d2
+units.feetpersec=\u82f1\u5c3a/\u79d2
+units.hours=\u5c0f\u65f6
+units.degminsec=\u5ea6-\u5206-\u79d2
+units.degmin=\u5ea6-\u5206
+units.deg=\u5ea6
+units.iso8601=ISO 8601
+
+# External urls
+url.googlemaps=ditu.google.cn
+
+# Cardinals for 3d plots
+cardinal.n=N
+cardinal.s=S
+cardinal.e=E
+cardinal.w=W
+
+# Undo operations
+undo.load=\u5bfc\u5165\u6570\u636e
+undo.loadphotos=\u5bfc\u5165\u76f8\u7247
+undo.editpoint=\u7f16\u8f91\u8f68\u8ff9\u70b9
+undo.deletepoint=\u5220\u9664\u8f68\u8ff9\u70b9
+undo.deletephoto=\u5220\u9664\u76f8\u7247
+undo.deleterange=\u5220\u9664\u6bb5
+undo.compress=\u538b\u7f29\u8f68\u8ff9
+undo.insert=\u63d2\u5165\u822a\u70b9
+undo.reverse=\u53cd\u5411\u6bb5
+undo.mergetracksegments=\u5408\u5e76\u6bb5
+undo.addtimeoffset=\u6dfb\u52a0\u65f6\u95f4\u504f\u79fb
+undo.addaltitudeoffset=\u52a0\u5165\u9ad8\u5ea6\u504f\u79fb
+undo.rearrangewaypoints=\u91cd\u65b0\u914d\u7f6e\u822a\u70b9
+undo.cutandmove=\u79fb\u52a8\u6bb5
+undo.connectphoto=\u94fe\u63a5\u76f8\u7247
+undo.disconnectphoto=\u65ad\u5f00\u94fe\u63a5
+undo.correlate=\u94fe\u63a5\u76f8\u7247
+undo.createpoint=\u521b\u5efa\u8f68\u8ff9\u70b9
+
+# Error messages
+error.save.dialogtitle=\u4fdd\u5b58\u6570\u636e\u9519\u8bef
+error.save.nodata=\u65e0\u6570\u636e\u4fdd\u5b58
+error.save.failed=\u5411\u6587\u4ef6\u4fdd\u5b58\u6570\u636e\u5931\u8d25
+error.saveexif.filenotfound=\u627e\u4e0d\u5230\u76f8\u7247\u6587\u4ef6
+error.saveexif.cannotoverwrite1=\u76f8\u7247\u6587\u4ef6
+error.saveexif.cannotoverwrite2=\u53ea\u8bfb\u6587\u4ef6\uff0c\u4fdd\u5b58\u526f\u672c\uff1f
+error.load.dialogtitle=\u5bfc\u5165\u6570\u636e\u9519\u8bef
+error.load.noread=\u65e0\u6cd5\u8bfb\u6587\u4ef6
+error.load.nopoints=\u6587\u4ef6\u4e2d\u65e0\u5750\u6807\u4fe1\u606f
+error.load.unknownxml=XML\u683c\u5f0f\u9519\u8bef
+error.load.noxmlinzip=Zip\u6587\u4ef6\u4e2d\u65e0\u6cd5\u627e\u5230XML
+error.load.othererror=\u8bfb\u6587\u4ef6\u9519\u8bef
+error.jpegload.dialogtitle=\u5bfc\u5165\u76f8\u7247\u9519\u8bef
+error.jpegload.nofilesfound=\u627e\u4e0d\u5230\u6587\u4ef6
+error.jpegload.nojpegsfound=\u627e\u4e0d\u5230Jpeg\u6587\u4ef6
+error.jpegload.noexiffound=\u627e\u4e0d\u5230EXIF\u4fe1\u606f
+error.jpegload.nogpsfound=\u627e\u4e0d\u5230GPS\u4fe1\u606f
+error.undofailed.title=\u64a4\u9500\u5931\u8d25
+error.undofailed.text=\u64a4\u9500\u64cd\u4f5c\u5931\u8d25
+error.function.noop.title=\u529f\u80fd\u65e0\u6548
+error.rearrange.noop=\u91cd\u65b0\u914d\u7f6e\u822a\u70b9\u65e0\u6548
+error.function.notavailable.title=\u65e0\u6b64\u529f\u80fd
+error.function.nojava3d=\u6b64\u529f\u80fd\u9700\u8981 Java 3D\n\u53ef\u4eceSun.com\u83b7\u5f97
+error.3d=3D \u663e\u793a\u65f6\u51fa\u73b0\u4e00\u4e2a\u9519\u8bef
+error.readme.notfound=\u627e\u4e0d\u5230\u7248\u672c\u4fe1\u606f\u6587\u4ef6
+error.osmimage.dialogtitle=\u5bfc\u5165\u5730\u56fe\u65f6\u9519\u8bef
+error.osmimage.failed=\u5bfc\u5165\u5730\u56fe\u9519\u8bef\uff0c\u68c0\u67e5\u7f51\u7edc\u8fde\u63a5
diff --git a/tim/prune/load/FileCacher.java b/tim/prune/load/FileCacher.java
index de1e7ca..1d12397 100644
--- a/tim/prune/load/FileCacher.java
+++ b/tim/prune/load/FileCacher.java
@@ -12,7 +12,9 @@ import java.util.ArrayList;
*/
public class FileCacher
{
+ /** File to cache */
private File _file = null;
+ /** Array to hold lines of file */
private String[] _contentArray = null;
diff --git a/tim/prune/load/FileLoader.java b/tim/prune/load/FileLoader.java
index b3c03b4..889f1d7 100644
--- a/tim/prune/load/FileLoader.java
+++ b/tim/prune/load/FileLoader.java
@@ -1,7 +1,7 @@
package tim.prune.load;
import java.io.File;
-
+import java.util.ArrayList;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
@@ -21,6 +21,7 @@ public class FileLoader
private JFileChooser _fileChooser = null;
private JFrame _parentFrame;
private TextFileLoader _textFileLoader = null;
+ private NmeaFileLoader _nmeaFileLoader = null;
private XmlFileLoader _xmlFileLoader = null;
private ZipFileLoader _zipFileLoader = null;
@@ -35,6 +36,7 @@ public class FileLoader
_app = inApp;
_parentFrame = inParentFrame;
_textFileLoader = new TextFileLoader(inApp, inParentFrame);
+ _nmeaFileLoader = new NmeaFileLoader(inApp);
_xmlFileLoader = new XmlFileLoader(inApp);
_zipFileLoader = new ZipFileLoader(inApp, _xmlFileLoader);
}
@@ -56,47 +58,76 @@ public class FileLoader
_fileChooser.addChoosableFileFilter(new GenericFileFilter("filetype.kmz", new String[] {"kmz"}));
_fileChooser.setAcceptAllFileFilterUsed(true);
// start from directory in config if already set (by load jpegs)
- File configDir = Config.getWorkingDirectory();
- if (configDir != null) {_fileChooser.setCurrentDirectory(configDir);}
+ String configDir = Config.getConfigString(Config.KEY_TRACK_DIR);
+ if (configDir == null) {configDir = Config.getConfigString(Config.KEY_PHOTO_DIR);}
+ if (configDir != null) {_fileChooser.setCurrentDirectory(new File(configDir));}
+ _fileChooser.setMultiSelectionEnabled(true); // Allow multiple selections
}
// Show the open dialog
if (_fileChooser.showOpenDialog(_parentFrame) == JFileChooser.APPROVE_OPTION)
{
- File file = _fileChooser.getSelectedFile();
- // Check file exists and is readable
- if (file != null && file.exists() && file.canRead())
+ File[] files = _fileChooser.getSelectedFiles();
+ // Loop through files looking for files which exist and are readable
+ ArrayList dataFiles = new ArrayList();
+ if (files != null)
{
- // Store directory in config for later
- Config.setWorkingDirectory(file.getParentFile());
- // Check file type to see if it's xml or just normal text
- String fileExtension = file.getName().toLowerCase();
- if (fileExtension.length() > 4)
- {fileExtension = fileExtension.substring(fileExtension.length() - 4);}
- if (fileExtension.equals(".kml") || fileExtension.equals(".gpx")
- || fileExtension.equals(".xml"))
- {
- // Use xml loader for kml, gpx and xml filenames
- _xmlFileLoader.openFile(file);
- }
- else if (fileExtension.equals(".kmz") || fileExtension.equals(".zip"))
- {
- // Use zip loader for zipped kml (or zipped gpx)
- _zipFileLoader.openFile(file);
- }
- else
+ for (int i=0; i 0) {
+ _app.loadDataFiles(dataFiles);
+ }
else
{
- // couldn't read file - show error message
+ // couldn't find any files to load - show error message
_app.showErrorMessage("error.load.dialogtitle", "error.load.noread");
}
}
}
+ /**
+ * Open the selected input file
+ * @param inFile file to open
+ */
+ public void openFile(File inFile)
+ {
+ // Store directory in config for later
+ File parent = inFile.getParentFile();
+ if (parent != null) {
+ Config.setConfigString(Config.KEY_TRACK_DIR, parent.getAbsolutePath());
+ }
+ // Check file type to see if it's xml or just normal text
+ String fileExtension = inFile.getName().toLowerCase();
+ if (fileExtension.length() > 4)
+ {fileExtension = fileExtension.substring(fileExtension.length() - 4);}
+ if (fileExtension.equals(".kml") || fileExtension.equals(".gpx")
+ || fileExtension.equals(".xml"))
+ {
+ // Use xml loader for kml, gpx and xml filenames
+ _xmlFileLoader.openFile(inFile);
+ }
+ else if (fileExtension.equals(".kmz") || fileExtension.equals(".zip"))
+ {
+ // Use zip loader for zipped kml (or zipped gpx)
+ _zipFileLoader.openFile(inFile);
+ }
+ else if (fileExtension.equals("nmea"))
+ {
+ _nmeaFileLoader.openFile(inFile);
+ }
+ else
+ {
+ // Use text loader for everything else
+ _textFileLoader.openFile(inFile);
+ }
+ }
+
/**
* @return the last delimiter character used for a text file load
*/
diff --git a/tim/prune/load/FileSplitter.java b/tim/prune/load/FileSplitter.java
index 99464f7..60c2c5d 100644
--- a/tim/prune/load/FileSplitter.java
+++ b/tim/prune/load/FileSplitter.java
@@ -33,7 +33,7 @@ public class FileSplitter
if (_cacher == null) return null;
String[] contents = _cacher.getContents();
if (contents == null || contents.length == 0) return null;
- String delimStr = "" + inDelim;
+ String delimStr = checkDelimiter(inDelim);
// Count non-blank rows and max field count
_numRows = 0;
int maxFields = 0;
@@ -61,9 +61,11 @@ public class FileSplitter
result[i] = new String[maxFields];
if (contents[i] != null)
{
- String wholeLine = contents[i].trim();
- if (!wholeLine.equals(""))
+ String wholeLine = contents[i];
+ if (!wholeLine.trim().equals(""))
{
+ // Don't use trimmed string here because you'll lose empty fields at beginning
+ // if separated by spaces or tabs
String[] splitLine = wholeLine.split(delimStr);
if (splitLine != null)
{
@@ -120,4 +122,19 @@ public class FileSplitter
// Should probably trap out of range values
return !_columnStates[inColumnNum];
}
+
+ /**
+ * Check the delimiter for proper regular expression matching
+ * @param inDelim character selected as delimiter
+ * @return regular expression for splitting
+ */
+ private static String checkDelimiter(char inDelim)
+ {
+ String result = "" + inDelim;
+ // Don't pass asterisks or dots without escaping them for RE
+ if (inDelim == '*' || inDelim == '.') {
+ result = "\\" + result;
+ }
+ return result;
+ }
}
diff --git a/tim/prune/load/GpsLoader.java b/tim/prune/load/GpsLoader.java
index 0d3d8f4..3ec3c6b 100644
--- a/tim/prune/load/GpsLoader.java
+++ b/tim/prune/load/GpsLoader.java
@@ -6,6 +6,8 @@ import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
+import java.awt.event.KeyAdapter;
+import java.awt.event.KeyEvent;
import java.io.BufferedReader;
import java.io.InputStreamReader;
@@ -68,7 +70,7 @@ public class GpsLoader extends GenericFunction implements Runnable
public void begin()
{
// Check if gpsbabel looks like it's installed
- if (_gpsBabelChecked || ExternalTools.isGpsbabelInstalled()
+ if (_gpsBabelChecked || ExternalTools.isToolInstalled(ExternalTools.TOOL_GPSBABEL)
|| JOptionPane.showConfirmDialog(_dialog,
I18nManager.getText("dialog.gpsload.nogpsbabel"),
I18nManager.getText(getNameKey()),
@@ -109,12 +111,21 @@ public class GpsLoader extends GenericFunction implements Runnable
JLabel deviceLabel = new JLabel(I18nManager.getText("dialog.gpsload.device"));
deviceLabel.setHorizontalAlignment(SwingConstants.RIGHT);
gridPanel.add(deviceLabel);
- _deviceField = new JTextField(Config.getGpsDevice(), 12);
+ _deviceField = new JTextField(Config.getConfigString(Config.KEY_GPS_DEVICE), 12);
+ _deviceField.addKeyListener(new KeyAdapter() {
+ public void keyReleased(KeyEvent e)
+ {
+ // close dialog if escape pressed
+ if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
+ _dialog.dispose();
+ }
+ }
+ });
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);
+ _formatField = new JTextField(Config.getConfigString(Config.KEY_GPS_FORMAT), 12);
gridPanel.add(_formatField);
gridPanel.setAlignmentX(Component.CENTER_ALIGNMENT);
gridPanel.setBorder(BorderFactory.createEmptyBorder(10, 5, 5, 20));
@@ -230,20 +241,26 @@ public class GpsLoader extends GenericFunction implements Runnable
{
// Set up command to call gpsbabel
String[] commands = null;
+ final String device = _deviceField.getText().trim();
+ final String format = _formatField.getText().trim();
+ final String command = Config.getConfigString(Config.KEY_GPSBABEL_PATH);
if (inWaypoints && inTracks) {
// Both waypoints and track points selected
- commands = new String[] {"gpsbabel", "-w", "-t", "-i", _formatField.getText(),
- "-f", _deviceField.getText(), "-o", "gpx", "-F", "-"};
+ commands = new String[] {command, "-w", "-t", "-i", format,
+ "-f", device, "-o", "gpx", "-F", "-"};
}
else
{
// Only waypoints OR track points selected
- commands = new String[] {"gpsbabel", "-w", "-i", _formatField.getText(),
- "-f", _deviceField.getText(), "-o", "gpx", "-F", "-"};
+ commands = new String[] {command, "-w", "-i", format,
+ "-f", device, "-o", "gpx", "-F", "-"};
if (inTracks) {
commands[1] = "-t";
}
}
+ // Save GPS settings in config
+ Config.setConfigString(Config.KEY_GPS_DEVICE, device);
+ Config.setConfigString(Config.KEY_GPS_FORMAT, format);
String errorMessage = "";
XmlHandler handler = null;
diff --git a/tim/prune/load/JpegLoader.java b/tim/prune/load/JpegLoader.java
index 7939f1b..194f2b7 100644
--- a/tim/prune/load/JpegLoader.java
+++ b/tim/prune/load/JpegLoader.java
@@ -92,8 +92,9 @@ public class JpegLoader implements Runnable
panel.add(_outsideAreaCheckbox);
_fileChooser.setAccessory(panel);
// start from directory in config if already set by other operations
- File configDir = Config.getWorkingDirectory();
- if (configDir != null) {_fileChooser.setCurrentDirectory(configDir);}
+ String configDir = Config.getConfigString(Config.KEY_PHOTO_DIR);
+ if (configDir == null) {configDir = Config.getConfigString(Config.KEY_TRACK_DIR);}
+ if (configDir != null) {_fileChooser.setCurrentDirectory(new File(configDir));}
}
// enable/disable track checkbox
_trackRectangle = inRectangle;
@@ -311,7 +312,8 @@ public class JpegLoader implements Runnable
{
// Store first directory in config for later
if (i == 0 && inFirstDir) {
- Config.setWorkingDirectory(file.isDirectory()?file:file.getParentFile());
+ File workingDir = file.isDirectory()?file:file.getParentFile();
+ Config.setConfigString(Config.KEY_PHOTO_DIR, workingDir.getAbsolutePath());
}
// Check whether it's a file or a directory
if (file.isFile())
diff --git a/tim/prune/load/NmeaFileLoader.java b/tim/prune/load/NmeaFileLoader.java
new file mode 100644
index 0000000..ad01789
--- /dev/null
+++ b/tim/prune/load/NmeaFileLoader.java
@@ -0,0 +1,132 @@
+package tim.prune.load;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.ArrayList;
+
+import tim.prune.App;
+import tim.prune.data.Altitude;
+import tim.prune.data.Field;
+
+/**
+ * Class to handle the loading of Nmea files
+ */
+public class NmeaFileLoader
+{
+ /** App for callback of file loading */
+ private App _app = null;
+
+ /**
+ * Constructor
+ * @param inApp App object
+ */
+ public NmeaFileLoader(App inApp)
+ {
+ _app = inApp;
+ }
+
+ /**
+ * Open the selected file
+ * @param inFile File to open
+ */
+ public void openFile(File inFile)
+ {
+ BufferedReader reader = null;
+ ArrayList messages = new ArrayList();
+ try
+ {
+ reader = new BufferedReader(new FileReader(inFile));
+ String currLine = reader.readLine();
+ boolean newSegment = true;
+ while (currLine != null)
+ {
+ // Try to make an NmeaMessage object for each line of file
+ if (currLine.trim().length() > 0)
+ {
+ NmeaMessage message = processLine(currLine);
+ if (message != null)
+ {
+ if (message.hasFix()) {
+ message.setSegment(newSegment);
+ // add message to list
+ messages.add(message);
+ }
+ // Start a new segment if fix lost
+ newSegment = !message.hasFix();
+ }
+ }
+ // Read next line, if any
+ currLine = reader.readLine();
+ }
+ }
+ catch (IOException ioe) {
+ _app.showErrorMessage("error.load.dialogtitle", "error.load.noread");
+ }
+ finally
+ {
+ // close file ignoring errors
+ try
+ {
+ if (reader != null) reader.close();
+ }
+ catch (Exception e) {}
+ }
+ if (messages.size() > 0)
+ {
+ _app.informDataLoaded(getFieldArray(), makeDataArray(messages),
+ Altitude.Format.METRES, inFile.getName());
+ }
+ }
+
+ /**
+ * Process the given NMEA line and return the message
+ * @param inLine line to process
+ * @return message object
+ */
+ private static NmeaMessage processLine(String inLine)
+ {
+ // Only consider lines which are long enough and begin with the GPS position sentence
+ if (inLine == null || inLine.length() < 20 || !inLine.startsWith("$GPGGA")) {
+ return null;
+ }
+ // TODO: May be possible to pull date out of GPRMC messages, but then need to back-populate
+ // Assume comma delimiter, split into array
+ String[] splitLine = inLine.split(",");
+ if (splitLine != null && splitLine.length >= 10)
+ {
+ return new NmeaMessage(splitLine[2] + splitLine[3], // latitude
+ splitLine[4] + splitLine[5], // longitude
+ splitLine[9], // altitude
+ splitLine[1], // timestamp
+ splitLine[6]); // fix
+ }
+ // Couldn't parse it, return null
+ return null;
+ }
+
+ /**
+ * Make an object array from the data list
+ * @param inList list of messages
+ * @return object array for loading
+ */
+ private static Object[][] makeDataArray(ArrayList inList)
+ {
+ Object[][] result = new Object[inList.size()][];
+ for (int i=0; i 6)
+ {
+ int dotPos = inCoordinate.indexOf('.');
+ if (dotPos > 0) {
+ return inCoordinate.substring(0, dotPos-2) + "d" + inCoordinate.substring(dotPos-2);
+ }
+ }
+ return inCoordinate;
+ }
+
+ /**
+ * Use time from NMEA message, and today's date (as date isn't given in GPGGA messages)
+ * @return Timestamp in parseable format
+ */
+ private String getTimestamp()
+ {
+ try
+ {
+ Calendar cal = Calendar.getInstance();
+ cal.set(Calendar.HOUR_OF_DAY, Integer.parseInt(_timestamp.substring(0, 2)));
+ cal.set(Calendar.MINUTE, Integer.parseInt(_timestamp.substring(2, 4)));
+ cal.set(Calendar.SECOND, Integer.parseInt(_timestamp.substring(4, 6)));
+ cal.set(Calendar.MILLISECOND, 0);
+ // Return time as number of milliseconds
+ return "" + cal.getTimeInMillis();
+ }
+ catch (Exception e) {} // ignore parsing errors, just have no timestamp
+ return null;
+ }
+}
diff --git a/tim/prune/load/TextFileLoader.java b/tim/prune/load/TextFileLoader.java
index d4a9aa6..64c9eba 100644
--- a/tim/prune/load/TextFileLoader.java
+++ b/tim/prune/load/TextFileLoader.java
@@ -127,6 +127,7 @@ public class TextFileLoader
else {
// Didn't pass pre-check
_app.showErrorMessage("error.load.dialogtitle", "error.load.noread");
+ _app.informNoDataLoaded();
}
}
@@ -255,6 +256,7 @@ public class TextFileLoader
public void actionPerformed(ActionEvent e)
{
_dialog.dispose();
+ _app.informNoDataLoaded();
}
});
buttonPanel.add(cancelButton);
diff --git a/tim/prune/load/xml/GpxHandler.java b/tim/prune/load/xml/GpxHandler.java
index 3bdfb3e..8ab3e17 100644
--- a/tim/prune/load/xml/GpxHandler.java
+++ b/tim/prune/load/xml/GpxHandler.java
@@ -17,12 +17,15 @@ public class GpxHandler extends XmlHandler
private boolean _insideName = false;
private boolean _insideElevation = false;
private boolean _insideTime = false;
+// private boolean _insideType = false;
private boolean _startSegment = true;
private String _name = null, _latitude = null, _longitude = null;
private String _elevation = null;
private String _time = null;
+// private String _type = null;
private ArrayList _pointList = new ArrayList();
+ // FIXME: Read waypoint type too
/**
* Receive the start of a tag
@@ -58,6 +61,10 @@ public class GpxHandler extends XmlHandler
{
_insideTime = true;
}
+// else if (qName.equalsIgnoreCase("type"))
+// {
+// _insideType = true;
+// }
else if (qName.equalsIgnoreCase("trkseg"))
{
_startSegment = true;
diff --git a/tim/prune/load/xml/KmlHandler.java b/tim/prune/load/xml/KmlHandler.java
index bed8774..787dd0b 100644
--- a/tim/prune/load/xml/KmlHandler.java
+++ b/tim/prune/load/xml/KmlHandler.java
@@ -86,7 +86,7 @@ public class KmlHandler extends XmlHandler
private void processPlacemark()
{
if (_coordinates == null) return;
- String allCoords = _coordinates.toString();
+ String allCoords = _coordinates.toString().trim();
String[] coordArray = allCoords.split("[ \n]");
int numPoints = coordArray.length;
if (numPoints == 1)
@@ -103,7 +103,7 @@ public class KmlHandler extends XmlHandler
if (coordArray[p] != null && coordArray[p].trim().length()>3)
{
String[] pointArray = makeStringArray(coordArray[p], null);
- if (firstPoint) {pointArray[4] = "1";}
+ if (firstPoint) {pointArray[4] = "1";} // start of segment flag
firstPoint = false;
_pointList.add(pointArray);
}
diff --git a/tim/prune/load/xml/ZipFileLoader.java b/tim/prune/load/xml/ZipFileLoader.java
index cf3801c..ba9407c 100644
--- a/tim/prune/load/xml/ZipFileLoader.java
+++ b/tim/prune/load/xml/ZipFileLoader.java
@@ -1,9 +1,11 @@
package tim.prune.load.xml;
import java.io.File;
+import java.io.InputStream;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
+import java.util.zip.ZipInputStream;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
@@ -33,7 +35,7 @@ public class ZipFileLoader
}
/**
- * Open the selected file and show the GUI dialog to select load options
+ * Open the selected file and select appropriate xml loader
* @param inFile File to open
*/
public void openFile(File inFile)
@@ -75,8 +77,52 @@ public class ZipFileLoader
}
}
catch (Exception e) {
- System.err.println("Error: " + e.getMessage());
+ System.err.println("Error: " + e.getClass().getName() + " -message= " + e.getMessage());
}
}
+ /**
+ * Use the given stream to access a remote zip file
+ * @param inStream stream to use to access file
+ */
+ public void openStream(InputStream inStream)
+ {
+ try
+ {
+ ZipInputStream zis = new ZipInputStream(inStream);
+ boolean xmlFound = false;
+ while (!xmlFound && zis.available() > 0)
+ {
+ ZipEntry entry = zis.getNextEntry();
+ 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(zis, _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, "gpsies");
+ xmlFound = true;
+ }
+ }
+ }
+ }
+ // 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.getClass().getName() + " -message= " + e.getMessage());
+ }
+ }
}
diff --git a/tim/prune/readme.txt b/tim/prune/readme.txt
index 660750a..51d9cc7 100644
--- a/tim/prune/readme.txt
+++ b/tim/prune/readme.txt
@@ -1,4 +1,4 @@
-Prune version 7
+Prune version 8
===============
Prune is an application for viewing, editing and managing coordinate data from GPS systems,
@@ -17,7 +17,7 @@ Running
=======
To run Prune from the jar file, simply call it from a command prompt or shell:
- java -jar prune_07.jar
+ java -jar prune_08.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
@@ -25,8 +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_07.jar --lang=DE
+ java -jar prune_08.jar --lang=DE
+New with version 8
+==================
+
+The following features were added since version 7:
+ - Loading of NMEA files (with suffix .nmea)
+ - Loading of nearby tracks from gpsies.com
+ - Function for finding waypoints by name
+ - Language-sensitive keyboard shortcuts
+ - Scale bar
+ - Display of pace (time per km or time per mile)
+ - Ability to display and save configuration settings
+ - Configurable program paths and KMZ image sizes
+ - Chinese language thanks to generous user input
New with version 7
==================
diff --git a/tim/prune/save/ExifSaver.java b/tim/prune/save/ExifSaver.java
index 6533fcb..f8e04de 100644
--- a/tim/prune/save/ExifSaver.java
+++ b/tim/prune/save/ExifSaver.java
@@ -19,6 +19,7 @@ import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.JTable;
+import tim.prune.Config;
import tim.prune.ExternalTools;
import tim.prune.I18nManager;
import tim.prune.UpdateMessageBroker;
@@ -79,7 +80,7 @@ public class ExifSaver implements Runnable
public boolean saveExifInformation(PhotoList inPhotoList)
{
// Check if external exif tool can be called
- boolean exifToolInstalled = ExternalTools.isExiftoolInstalled();
+ boolean exifToolInstalled = ExternalTools.isToolInstalled(ExternalTools.TOOL_EXIFTOOL);
if (!exifToolInstalled)
{
// show warning
@@ -331,7 +332,7 @@ public class ExifSaver implements Runnable
{
// Make a string array to construct the command and its parameters
String[] result = new String[inOverwrite?5:4];
- result[0] = "exiftool";
+ result[0] = Config.getConfigString(Config.KEY_EXIFTOOL_PATH);
result[1] = "-P";
if (inOverwrite) {result[2] = " -overwrite_original_in_place";}
// remove all gps tags
@@ -353,7 +354,7 @@ public class ExifSaver implements Runnable
{
// Make a string array to construct the command and its parameters
String[] result = new String[inOverwrite?10:9];
- result[0] = "exiftool";
+ result[0] = Config.getConfigString(Config.KEY_EXIFTOOL_PATH);
result[1] = "-P";
if (inOverwrite) {result[2] = "-overwrite_original_in_place";}
int paramOffset = inOverwrite?3:2;
diff --git a/tim/prune/save/FileSaver.java b/tim/prune/save/FileSaver.java
index ea4efb8..3ea60db 100644
--- a/tim/prune/save/FileSaver.java
+++ b/tim/prune/save/FileSaver.java
@@ -65,9 +65,11 @@ public class FileSaver
private JRadioButton[] _delimiterRadios = null;
private JTextField _otherDelimiterText = null;
private JCheckBox _headerRowCheckbox = null;
+ private PointTypeSelector _pointTypeSelector = null;
private JRadioButton[] _coordUnitsRadios = null;
private JRadioButton[] _altitudeUnitsRadios = null;
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 Altitude.Format[] FORMAT_ALTS = {Altitude.Format.NO_FORMAT, Altitude.Format.METRES, Altitude.Format.FEET};
@@ -224,13 +226,18 @@ public class FileSaver
firstCard.add(Box.createRigidArea(new Dimension(0,10)));
_headerRowCheckbox = new JCheckBox(I18nManager.getText("dialog.save.headerrow"), true);
firstCard.add(_headerRowCheckbox);
-
_cards.add(firstCard, "card1");
+ // Second card
JPanel secondCard = new JPanel();
secondCard.setLayout(new BorderLayout());
JPanel secondCardHolder = new JPanel();
secondCardHolder.setLayout(new BoxLayout(secondCardHolder, BoxLayout.Y_AXIS));
+ // point type selector
+ secondCardHolder.add(Box.createRigidArea(new Dimension(0,10)));
+ _pointTypeSelector = new PointTypeSelector();
+ _pointTypeSelector.setAlignmentX(JLabel.LEFT_ALIGNMENT);
+ secondCardHolder.add(_pointTypeSelector);
JLabel coordLabel = new JLabel(I18nManager.getText("dialog.save.coordinateunits"));
coordLabel.setAlignmentX(JLabel.LEFT_ALIGNMENT);
secondCardHolder.add(coordLabel);
@@ -251,7 +258,7 @@ public class FileSaver
}
coordsUnitsPanel.setAlignmentX(JPanel.LEFT_ALIGNMENT);
secondCardHolder.add(coordsUnitsPanel);
- secondCardHolder.add(Box.createRigidArea(new Dimension(0,10)));
+ secondCardHolder.add(Box.createRigidArea(new Dimension(0,7)));
// altitude units
JLabel altUnitsLabel = new JLabel(I18nManager.getText("dialog.save.altitudeunits"));
altUnitsLabel.setAlignmentX(JLabel.LEFT_ALIGNMENT);
@@ -272,7 +279,7 @@ public class FileSaver
}
altUnitsPanel.setAlignmentX(JPanel.LEFT_ALIGNMENT);
secondCardHolder.add(altUnitsPanel);
- secondCardHolder.add(Box.createRigidArea(new Dimension(0,10)));
+ secondCardHolder.add(Box.createRigidArea(new Dimension(0,7)));
// Selection of format of timestamps
JLabel timestampLabel = new JLabel(I18nManager.getText("dialog.save.timestampformat"));
timestampLabel.setAlignmentX(JLabel.LEFT_ALIGNMENT);
@@ -367,6 +374,7 @@ public class FileSaver
default : _delimiterRadios[4].setSelected(true);
_otherDelimiterText.setText("" + inDefaultDelimiter);
}
+ _pointTypeSelector.init(_app.getTrackInfo());
// set card and enable buttons
CardLayout cl = (CardLayout) _cards.getLayout();
cl.first(_cards);
@@ -381,6 +389,8 @@ public class FileSaver
*/
private boolean saveToFile()
{
+ // TODO: Shorten method
+ if (!_pointTypeSelector.getAnythingSelected()) {return false;}
boolean saveOK = true;
FileWriter writer = null;
if (_fileChooser == null)
@@ -392,8 +402,9 @@ public class FileSaver
_fileChooser.addChoosableFileFilter(new GenericFileFilter("filetype.kml", new String[] {"kml"}));
_fileChooser.setAcceptAllFileFilterUsed(true);
// start from directory in config which should be set
- File configDir = Config.getWorkingDirectory();
- if (configDir != null) {_fileChooser.setCurrentDirectory(configDir);}
+ String configDir = Config.getConfigString(Config.KEY_TRACK_DIR);
+ if (configDir == null) {configDir = Config.getConfigString(Config.KEY_PHOTO_DIR);}
+ if (configDir != null) {_fileChooser.setCurrentDirectory(new File(configDir));}
}
if (_fileChooser.showSaveDialog(_parentFrame) == JFileChooser.APPROVE_OPTION)
{
@@ -466,10 +477,16 @@ public class FileSaver
}
// Loop over points outputting each in turn to buffer
- int numPoints = _track.getNumPoints();
+ final int numPoints = _track.getNumPoints();
+ int numSaved = 0;
for (int p=0; p\n\n\t\n");
}
- if (!point.isWaypoint()) {
- // export the track point
- exportTrackpoint(point, inWriter, inTimestamps);
- firstPoint = false;
+ if (!point.isWaypoint())
+ {
+ if ((point.getPhoto()==null && exportTrackpoints) || (point.getPhoto()!=null && exportPhotos))
+ {
+ // export the point
+ exportTrackpoint(point, inWriter, exportTimestamps);
+ numSaved++;
+ firstPoint = false;
+ }
}
}
inWriter.write("\t \n");
}
inWriter.write(" \n");
- return numPoints;
+ return numSaved;
}
-
/**
* Export the specified waypoint into the file
* @param inPoint waypoint to export
diff --git a/tim/prune/save/KmlExporter.java b/tim/prune/save/KmlExporter.java
index 67ad261..42ba748 100644
--- a/tim/prune/save/KmlExporter.java
+++ b/tim/prune/save/KmlExporter.java
@@ -56,18 +56,25 @@ public class KmlExporter extends GenericFunction implements Runnable
private Track _track = null;
private JDialog _dialog = null;
private JTextField _descriptionField = null;
+ private PointTypeSelector _pointTypeSelector = null;
private JCheckBox _altitudesCheckbox = null;
private JCheckBox _kmzCheckbox = null;
private JCheckBox _exportImagesCheckbox = null;
+ private JLabel _progressLabel = null;
private JProgressBar _progressBar = null;
private JFileChooser _fileChooser = null;
private File _exportFile = null;
+ private JButton _okButton = null;
+ private boolean _cancelPressed = false;
// Filename of Kml file within zip archive
private static final String KML_FILENAME_IN_KMZ = "doc.kml";
- // Width and height of thumbnail images in Kmz
- private static final int THUMBNAIL_WIDTH = 240;
- private static final int THUMBNAIL_HEIGHT = 180;
+ // Default width and height of thumbnail images in Kmz
+ private static final int DEFAULT_THUMBNAIL_WIDTH = 240;
+ private static final int DEFAULT_THUMBNAIL_HEIGHT = 180;
+ // Actual selected width and height of thumbnail images in Kmz
+ private static int THUMBNAIL_WIDTH = 0;
+ private static int THUMBNAIL_HEIGHT = 0;
/**
@@ -101,6 +108,9 @@ public class KmlExporter extends GenericFunction implements Runnable
_dialog.pack();
}
enableCheckboxes();
+ _descriptionField.setEnabled(true);
+ _okButton.setEnabled(true);
+ _progressLabel.setText("");
_progressBar.setVisible(false);
_dialog.setVisible(true);
}
@@ -113,7 +123,7 @@ public class KmlExporter extends GenericFunction implements Runnable
private Component makeDialogComponents()
{
JPanel dialogPanel = new JPanel();
- dialogPanel.setLayout(new BorderLayout());
+ dialogPanel.setLayout(new BorderLayout(0, 5));
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
// Make a central panel with the text box and checkboxes
@@ -122,15 +132,22 @@ public class KmlExporter extends GenericFunction implements Runnable
descPanel.add(new JLabel(I18nManager.getText("dialog.exportkml.text")));
_descriptionField = new JTextField(20);
descPanel.add(_descriptionField);
+ descPanel.setAlignmentX(Component.CENTER_ALIGNMENT);
mainPanel.add(descPanel);
dialogPanel.add(mainPanel, BorderLayout.CENTER);
+ // point type selection
+ _pointTypeSelector = new PointTypeSelector();
+ _pointTypeSelector.setAlignmentX(Component.CENTER_ALIGNMENT);
+ mainPanel.add(_pointTypeSelector);
// Checkbox for altitude export
_altitudesCheckbox = new JCheckBox(I18nManager.getText("dialog.exportkml.altitude"));
_altitudesCheckbox.setHorizontalTextPosition(SwingConstants.LEFT);
+ _altitudesCheckbox.setAlignmentX(Component.CENTER_ALIGNMENT);
mainPanel.add(_altitudesCheckbox);
// Checkboxes for kmz export and image export
_kmzCheckbox = new JCheckBox(I18nManager.getText("dialog.exportkml.kmz"));
_kmzCheckbox.setHorizontalTextPosition(SwingConstants.LEFT);
+ _kmzCheckbox.setAlignmentX(Component.CENTER_ALIGNMENT);
_kmzCheckbox.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
@@ -141,29 +158,35 @@ public class KmlExporter extends GenericFunction implements Runnable
mainPanel.add(_kmzCheckbox);
_exportImagesCheckbox = new JCheckBox(I18nManager.getText("dialog.exportkml.exportimages"));
_exportImagesCheckbox.setHorizontalTextPosition(SwingConstants.LEFT);
+ _exportImagesCheckbox.setAlignmentX(Component.CENTER_ALIGNMENT);
mainPanel.add(_exportImagesCheckbox);
mainPanel.add(Box.createVerticalStrut(10));
+ _progressLabel = new JLabel("...");
+ _progressLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
+ mainPanel.add(_progressLabel);
_progressBar = new JProgressBar(0, 100);
_progressBar.setVisible(false);
+ _progressBar.setAlignmentX(Component.CENTER_ALIGNMENT);
mainPanel.add(_progressBar);
mainPanel.add(Box.createVerticalStrut(10));
// button panel at bottom
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
- JButton okButton = new JButton(I18nManager.getText("button.ok"));
+ _okButton = new JButton(I18nManager.getText("button.ok"));
ActionListener okListener = new ActionListener() {
public void actionPerformed(ActionEvent e)
{
startExport();
}
};
- okButton.addActionListener(okListener);
+ _okButton.addActionListener(okListener);
_descriptionField.addActionListener(okListener);
- buttonPanel.add(okButton);
+ buttonPanel.add(_okButton);
JButton cancelButton = new JButton(I18nManager.getText("button.cancel"));
cancelButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
+ _cancelPressed = true;
_dialog.dispose();
}
});
@@ -178,6 +201,7 @@ public class KmlExporter extends GenericFunction implements Runnable
*/
private void enableCheckboxes()
{
+ _pointTypeSelector.init(_trackInfo);
boolean hasAltitudes = _track.hasData(Field.ALTITUDE);
if (!hasAltitudes) {_altitudesCheckbox.setSelected(false);}
boolean hasPhotos = _trackInfo.getPhotoList() != null && _trackInfo.getPhotoList().getNumPhotos() > 0;
@@ -191,15 +215,19 @@ public class KmlExporter extends GenericFunction implements Runnable
*/
private void startExport()
{
- // OK pressed, so choose output file
+ // OK pressed, now validate selection checkboxes
+ if (!_pointTypeSelector.getAnythingSelected()) {
+ return;
+ }
+ // Choose output file
if (_fileChooser == null)
{
_fileChooser = new JFileChooser();
_fileChooser.setDialogType(JFileChooser.SAVE_DIALOG);
_fileChooser.setFileFilter(new GenericFileFilter("filetype.kmlkmz", new String[] {"kml", "kmz"}));
// start from directory in config which should be set
- File configDir = Config.getWorkingDirectory();
- if (configDir != null) {_fileChooser.setCurrentDirectory(configDir);}
+ String configDir = Config.getConfigString(Config.KEY_TRACK_DIR);
+ if (configDir != null) {_fileChooser.setCurrentDirectory(new File(configDir));}
}
String requiredExtension = null, otherExtension = null;
if (_kmzCheckbox.isSelected())
@@ -239,6 +267,7 @@ public class KmlExporter extends GenericFunction implements Runnable
{
// New file or overwrite confirmed, so initiate export in separate thread
_exportFile = file;
+ _cancelPressed = false;
new Thread(this).start();
}
else
@@ -255,12 +284,23 @@ public class KmlExporter extends GenericFunction implements Runnable
*/
public void run()
{
- // Initialise progress bar
+ // Disable ok button to stop second go
+ _okButton.setEnabled(false);
+ _descriptionField.setEnabled(false);
+ // Initialise progress indicators
+ _progressLabel.setText(I18nManager.getText("confirm.running"));
_progressBar.setVisible(true);
_progressBar.setValue(0);
boolean exportToKmz = _kmzCheckbox.isSelected();
boolean exportImages = exportToKmz && _exportImagesCheckbox.isSelected();
_progressBar.setMaximum(exportImages?getNumPhotosToExport():1);
+
+ // Determine photo thumbnail size from config
+ THUMBNAIL_WIDTH = Config.getConfigInt(Config.KEY_KMZ_IMAGE_WIDTH);
+ if (THUMBNAIL_WIDTH < DEFAULT_THUMBNAIL_WIDTH) {THUMBNAIL_WIDTH = DEFAULT_THUMBNAIL_WIDTH;}
+ THUMBNAIL_HEIGHT = Config.getConfigInt(Config.KEY_KMZ_IMAGE_HEIGHT);
+ if (THUMBNAIL_HEIGHT < DEFAULT_THUMBNAIL_HEIGHT) {THUMBNAIL_HEIGHT = DEFAULT_THUMBNAIL_HEIGHT;}
+
OutputStreamWriter writer = null;
ZipOutputStream zipOutputStream = null;
try
@@ -275,13 +315,20 @@ public class KmlExporter extends GenericFunction implements Runnable
{
// kmz requested - need zip output stream
zipOutputStream = new ZipOutputStream(new FileOutputStream(_exportFile));
+ // Export images into zip file too if requested
+ if (exportImages)
+ {
+ // Create thumbnails of each photo in turn and add to zip as images/image.jpg
+ // This is done first so that photo sizes are known for later
+ exportThumbnails(zipOutputStream);
+ }
writer = new OutputStreamWriter(zipOutputStream);
// Make an entry in the zip file for the kml file
ZipEntry kmlEntry = new ZipEntry(KML_FILENAME_IN_KMZ);
zipOutputStream.putNextEntry(kmlEntry);
}
// write file
- int numPoints = exportData(writer, exportImages);
+ final int numPoints = exportData(writer, exportImages);
// update progress bar
_progressBar.setValue(1);
@@ -292,18 +339,12 @@ public class KmlExporter extends GenericFunction implements Runnable
writer.flush();
// Close off this entry in the zip file
zipOutputStream.closeEntry();
- // Export images into zip file too if requested
- if (exportImages)
- {
- // Create thumbnails of each photo in turn and add to zip as images/image.jpg
- exportThumbnails(zipOutputStream);
- }
}
// close file
writer.close();
// Store directory in config for later
- Config.setWorkingDirectory(_exportFile.getParentFile());
+ Config.setConfigString(Config.KEY_TRACK_DIR, _exportFile.getParentFile().getAbsolutePath());
// show confirmation
UpdateMessageBroker.informSubscribers(I18nManager.getText("confirm.save.ok1")
+ " " + numPoints + " " + I18nManager.getText("confirm.save.ok2")
@@ -337,6 +378,9 @@ public class KmlExporter extends GenericFunction implements Runnable
private int exportData(OutputStreamWriter inWriter, boolean inExportImages)
throws IOException
{
+ boolean writeTrack = _pointTypeSelector.getTrackpointsSelected();
+ boolean writeWaypoints = _pointTypeSelector.getWaypointsSelected();
+ boolean writePhotos = _pointTypeSelector.getPhotopointsSelected();
inWriter.write("\n\n\n");
inWriter.write("\t");
if (_descriptionField != null && _descriptionField.getText() != null && !_descriptionField.getText().equals(""))
@@ -349,28 +393,34 @@ public class KmlExporter extends GenericFunction implements Runnable
}
inWriter.write(" \n");
- boolean exportAltitudes = _altitudesCheckbox.isSelected();
+ boolean absoluteAltitudes = _altitudesCheckbox.isSelected();
int i = 0;
DataPoint point = null;
boolean hasTrackpoints = false;
- // Loop over waypoints
+ // Loop over waypoints (if any)
boolean writtenPhotoHeader = false;
- int numPoints = _track.getNumPoints();
+ final int numPoints = _track.getNumPoints();
+ int numSaved = 0;
int photoNum = 0;
+ // Loop over waypoints
for (i=0; icc0000cc\n\t\t\t\t4 \n\t\t\t\n"
+ "\t\t\t33cc0000 \n"
+ "\t\t\n\t\t\n";
- if (exportAltitudes) {
+ if (absoluteAltitudes) {
trackStart += "\t\t\t1 \n\t\t\tabsolute \n";
}
+ else {
+ trackStart += "\t\t\tclampToGround \n";
+ }
trackStart += "\t\t\t";
String trackEnd = "\t\t\t \n\t\t \n\t";
@@ -409,7 +463,8 @@ public class KmlExporter extends GenericFunction implements Runnable
}
if (!point.isWaypoint() && point.getPhoto() == null)
{
- exportTrackpoint(point, inWriter, exportAltitudes);
+ exportTrackpoint(point, inWriter);
+ numSaved++;
firstTrackpoint = false;
}
}
@@ -417,7 +472,7 @@ public class KmlExporter extends GenericFunction implements Runnable
inWriter.write(trackEnd);
}
inWriter.write(" \n ");
- return numPoints;
+ return numSaved;
}
@@ -425,24 +480,27 @@ public class KmlExporter extends GenericFunction implements Runnable
* Export the specified waypoint into the file
* @param inPoint waypoint to export
* @param inWriter writer object
- * @param inExportAltitude true to include altitude
+ * @param inAbsoluteAltitude true for absolute altitude
* @throws IOException on write failure
*/
- private void exportWaypoint(DataPoint inPoint, Writer inWriter, boolean inExportAltitude) throws IOException
+ private void exportWaypoint(DataPoint inPoint, Writer inWriter, boolean inAbsoluteAltitude) throws IOException
{
inWriter.write("\t\n\t\t");
inWriter.write(inPoint.getWaypointName().trim());
inWriter.write(" \n");
inWriter.write("\t\t\n");
- if (inExportAltitude && inPoint.hasAltitude()) {
+ if (inAbsoluteAltitude && inPoint.hasAltitude()) {
inWriter.write("\t\t\tabsolute \n");
}
+ else {
+ inWriter.write("\t\t\tclampToGround \n");
+ }
inWriter.write("\t\t\t");
inWriter.write(inPoint.getLongitude().output(Coordinate.FORMAT_DECIMAL_FORCE_POINT));
inWriter.write(',');
inWriter.write(inPoint.getLatitude().output(Coordinate.FORMAT_DECIMAL_FORCE_POINT));
inWriter.write(",");
- if (inExportAltitude && inPoint.hasAltitude()) {
+ if (inPoint.hasAltitude()) {
inWriter.write("" + inPoint.getAltitude().getStringValue(Altitude.Format.METRES));
}
else {
@@ -458,11 +516,11 @@ public class KmlExporter extends GenericFunction implements Runnable
* @param inWriter writer object
* @param inImageLink flag to set whether to export image links or not
* @param inImageNumber number of image for filename
- * @param inExportAltitude true to include altitude
+ * @param inAbsoluteAltitude true for absolute altitudes
* @throws IOException on write failure
*/
private void exportPhotoPoint(DataPoint inPoint, Writer inWriter, boolean inImageLink,
- int inImageNumber, boolean inExportAltitude)
+ int inImageNumber, boolean inAbsoluteAltitude)
throws IOException
{
inWriter.write("\t\n\t\t");
@@ -480,15 +538,19 @@ public class KmlExporter extends GenericFunction implements Runnable
}
inWriter.write("#camera_icon \n");
inWriter.write("\t\t\n");
- if (inExportAltitude && inPoint.hasAltitude()) {
+ if (inAbsoluteAltitude && inPoint.hasAltitude()) {
inWriter.write("\t\t\tabsolute \n");
}
+ else {
+ inWriter.write("\t\t\tclampToGround \n");
+ }
inWriter.write("\t\t\t");
inWriter.write(inPoint.getLongitude().output(Coordinate.FORMAT_DECIMAL_FORCE_POINT));
inWriter.write(',');
inWriter.write(inPoint.getLatitude().output(Coordinate.FORMAT_DECIMAL_FORCE_POINT));
inWriter.write(",");
- if (inExportAltitude && inPoint.hasAltitude()) {
+ // Altitude if point has one
+ if (inPoint.hasAltitude()) {
inWriter.write("" + inPoint.getAltitude().getStringValue(Altitude.Format.METRES));
}
else {
@@ -502,16 +564,15 @@ public class KmlExporter extends GenericFunction implements Runnable
* Export the specified trackpoint into the file
* @param inPoint trackpoint to export
* @param inWriter writer object
- * @param inExportAltitude true to include altitude
*/
- private void exportTrackpoint(DataPoint inPoint, Writer inWriter, boolean inExportAltitude) throws IOException
+ private void exportTrackpoint(DataPoint inPoint, Writer inWriter) throws IOException
{
inWriter.write(inPoint.getLongitude().output(Coordinate.FORMAT_DECIMAL_FORCE_POINT));
inWriter.write(',');
inWriter.write(inPoint.getLatitude().output(Coordinate.FORMAT_DECIMAL_FORCE_POINT));
- // Altitude either absolute or locked to ground by Google Earth
+ // Altitude if point has one
inWriter.write(",");
- if (inExportAltitude && inPoint.hasAltitude()) {
+ if (inPoint.hasAltitude()) {
inWriter.write("" + inPoint.getAltitude().getStringValue(Altitude.Format.METRES));
}
else {
@@ -539,7 +600,7 @@ public class KmlExporter extends GenericFunction implements Runnable
DataPoint point = null;
int photoNum = 0;
// Loop over all points in track
- for (int i=0; i 0
+ };
+ // Enable or disable checkboxes according to data present
+ for (int i=0; i<3; i++)
+ {
+ if (flags[i]) {
+ _checkboxes[i].setEnabled(true);
+ }
+ else {
+ _checkboxes[i].setSelected(false);
+ _checkboxes[i].setEnabled(false);
+ }
+ }
+ }
+
+ /**
+ * @return true if trackpoints selected
+ */
+ public boolean getTrackpointsSelected()
+ {
+ return _checkboxes[0].isSelected();
+ }
+
+ /**
+ * @return true if waypoints selected
+ */
+ public boolean getWaypointsSelected()
+ {
+ return _checkboxes[1].isSelected();
+ }
+
+ /**
+ * @return true if photo points selected
+ */
+ public boolean getPhotopointsSelected()
+ {
+ return _checkboxes[2].isSelected();
+ }
+
+ /**
+ * @return true if at least one type selected
+ */
+ public boolean getAnythingSelected()
+ {
+ return getTrackpointsSelected() || getWaypointsSelected()
+ || getPhotopointsSelected();
+ }
+}
diff --git a/tim/prune/save/PovExporter.java b/tim/prune/save/PovExporter.java
index c96d744..654aac6 100644
--- a/tim/prune/save/PovExporter.java
+++ b/tim/prune/save/PovExporter.java
@@ -167,7 +167,7 @@ public class PovExporter extends GenericFunction
JLabel fontLabel = new JLabel(I18nManager.getText("dialog.exportpov.font"));
fontLabel.setHorizontalAlignment(SwingConstants.TRAILING);
centralPanel.add(fontLabel);
- String defaultFont = Config.getPovrayFont();
+ String defaultFont = Config.getConfigString(Config.KEY_POVRAY_FONT);
if (defaultFont == null || defaultFont.equals("")) {
defaultFont = DEFAULT_FONT_FILE;
}
@@ -265,8 +265,8 @@ public class PovExporter extends GenericFunction
_fileChooser.setFileFilter(new GenericFileFilter("filetype.pov", new String[] {"pov"}));
_fileChooser.setAcceptAllFileFilterUsed(false);
// start from directory in config which should be set
- File configDir = Config.getWorkingDirectory();
- if (configDir != null) {_fileChooser.setCurrentDirectory(configDir);}
+ final String configDir = Config.getConfigString(Config.KEY_TRACK_DIR);
+ if (configDir != null) {_fileChooser.setCurrentDirectory(new File(configDir));}
}
// Allow choose again if an existing file is selected
@@ -295,7 +295,7 @@ public class PovExporter extends GenericFunction
{
// file saved
// Store directory in config for later
- Config.setWorkingDirectory(file.getParentFile());
+ Config.setConfigString(Config.KEY_TRACK_DIR, file.getParentFile().getAbsolutePath());
}
else
{
@@ -359,7 +359,7 @@ public class PovExporter extends GenericFunction
}
catch (IOException ioe)
{
- JOptionPane.showMessageDialog(_parentFrame, I18nManager.getText("error.save.failed") + ioe.getMessage(),
+ JOptionPane.showMessageDialog(_parentFrame, I18nManager.getText("error.save.failed") + " : " + ioe.getMessage(),
I18nManager.getText("error.save.dialogtitle"), JOptionPane.ERROR_MESSAGE);
}
finally
@@ -394,6 +394,9 @@ public class PovExporter extends GenericFunction
{
fontPath = DEFAULT_FONT_FILE;
}
+ else {
+ Config.setConfigString(Config.KEY_POVRAY_FONT, fontPath);
+ }
// Set up output
String[] outputLines = {
"global_settings { ambient_light rgb <4, 4, 4> }", "",
@@ -428,7 +431,7 @@ public class PovExporter extends GenericFunction
" open",
" pigment { color rgb <0.5 0.5 0.5> }",
" }", "",
- // TODO: Export rods to POV? How to store in data?
+ // MAYBE: Export rods to POV? How to store in data?
"#declare waypoint_sphere =",
" sphere {",
" <0, 0, 0>, 0.4",
@@ -514,7 +517,7 @@ public class PovExporter extends GenericFunction
" pigment { color rgb <1 1 1> }",
" translate <-" + (inModelSize * 1.03) + ", 0.2, 0>",
"}", "",
- // TODO: Light positions should relate to model size
+ // MAYBE: Light positions should relate to model size
"// lights",
"light_source { <-1, 9, -4> color rgb <0.5 0.5 0.5>}",
"light_source { <1, 6, -14> color rgb <0.6 0.6 0.6>}",
diff --git a/tim/prune/threedee/Java3DWindow.java b/tim/prune/threedee/Java3DWindow.java
index e3531f0..0bde564 100644
--- a/tim/prune/threedee/Java3DWindow.java
+++ b/tim/prune/threedee/Java3DWindow.java
@@ -465,7 +465,7 @@ public class Java3DWindow implements ThreeDWindow
private static Group createWaypoint(Point3d inPointPos)
{
Material mat = getWaypointMaterial();
- // TODO: sort symbol scaling
+ // MAYBE: sort symbol scaling
Sphere dot = new Sphere(0.35f); // * symbolScaling / 100f);
return createBall(inPointPos, dot, mat);
}
@@ -485,7 +485,7 @@ public class Java3DWindow implements ThreeDWindow
private static Group createTrackpoint(Point3d inPointPos, byte inHeightCode)
{
Material mat = getTrackpointMaterial(inHeightCode);
- // TODO: sort symbol scaling
+ // MAYBE: sort symbol scaling
Sphere dot = new Sphere(0.2f); // * symbolScaling / 100f);
return createBall(inPointPos, dot, mat);
}
diff --git a/tim/prune/threedee/ThreeDModel.java b/tim/prune/threedee/ThreeDModel.java
index 929659b..65f1152 100644
--- a/tim/prune/threedee/ThreeDModel.java
+++ b/tim/prune/threedee/ThreeDModel.java
@@ -18,7 +18,7 @@ public class ThreeDModel
private int _altitudeCap = -1;
private double _scaleFactor = 1.0;
private double _altFactor = 1.0;
- // TODO: How to store rods (lifts) in data?
+ // MAYBE: How to store rods (lifts) in data?
private byte[] _pointTypes = null;
private byte[] _pointHeights = null;
diff --git a/tim/prune/undo/UndoAddAltitudeOffset.java b/tim/prune/undo/UndoAddAltitudeOffset.java
new file mode 100644
index 0000000..4dbdd08
--- /dev/null
+++ b/tim/prune/undo/UndoAddAltitudeOffset.java
@@ -0,0 +1,62 @@
+package tim.prune.undo;
+
+import tim.prune.I18nManager;
+import tim.prune.UpdateMessageBroker;
+import tim.prune.data.Altitude;
+import tim.prune.data.TrackInfo;
+
+/**
+ * Undo addition/subtraction of an altitude offset
+ */
+public class UndoAddAltitudeOffset implements UndoOperation
+{
+ /** Start index of section */
+ private int _startIndex;
+ /** altitude values before operation */
+ private Altitude[] _altitudes;
+
+
+ /**
+ * Constructor
+ * @param inTrackInfo track info object
+ */
+ public UndoAddAltitudeOffset(TrackInfo inTrackInfo)
+ {
+ _startIndex = inTrackInfo.getSelection().getStart();
+ final int endIndex = inTrackInfo.getSelection().getEnd();
+ final int numPoints = endIndex - _startIndex + 1;
+ // Make array of cloned altitude objects
+ _altitudes = new Altitude[numPoints];
+ for (int i=0; i