[gpsprune] 01/04: Imported Upstream version 18.5

Bas Couwenberg sebastic at debian.org
Tue Jul 26 11:15:19 UTC 2016


This is an automated email from the git hooks/post-receive script.

sebastic pushed a commit to branch master
in repository gpsprune.

commit 7734d058cfb75afe8aad4d9c844143b6f5f78f9d
Author: Bas Couwenberg <sebastic at xs4all.nl>
Date:   Tue Jul 26 12:44:12 2016 +0200

    Imported Upstream version 18.5
---
 build.sh                                           |   2 +-
 tim/prune/GpsPrune.java                            |   4 +-
 tim/prune/function/AboutScreen.java                |   3 +-
 .../function/gpsies/UploadGpsiesFunction.java      |   5 +-
 tim/prune/gui/map/DiskTileCacher.java              |  35 +++----
 tim/prune/gui/map/MapCanvas.java                   |   4 +-
 tim/prune/gui/map/MapTile.java                     |  32 ++++++
 tim/prune/gui/map/MapTileManager.java              |  41 ++++----
 tim/prune/gui/profile/ProfileChart.java            |   5 +-
 tim/prune/lang/prune-texts_cz.properties           |   8 ++
 tim/prune/lang/prune-texts_es.properties           |   5 +
 tim/prune/lang/prune-texts_ru.properties           |  29 ++++--
 tim/prune/lang/prune-texts_uk.properties           |  10 ++
 tim/prune/readme.txt                               |  15 ++-
 tim/prune/save/GpsSaver.java                       |   5 +-
 tim/prune/save/GpxExporter.java                    | 108 +++++++++++----------
 tim/prune/save/SettingsForExport.java              |  66 +++++++++++++
 17 files changed, 263 insertions(+), 114 deletions(-)

diff --git a/build.sh b/build.sh
index e4f7081..3c157d7 100644
--- a/build.sh
+++ b/build.sh
@@ -1,6 +1,6 @@
 # Build script using external exif library
 # Version number
-PRUNENAME=gpsprune_18.4
+PRUNENAME=gpsprune_18.5
 # remove compile directory
 rm -rf compile
 # remove dist directory
diff --git a/tim/prune/GpsPrune.java b/tim/prune/GpsPrune.java
index 606e61c..ad71987 100644
--- a/tim/prune/GpsPrune.java
+++ b/tim/prune/GpsPrune.java
@@ -36,9 +36,9 @@ import tim.prune.gui.profile.ProfileChart;
 public class GpsPrune
 {
 	/** Version number of application, used in about screen and for version check */
-	public static final String VERSION_NUMBER = "18.4";
+	public static final String VERSION_NUMBER = "18.5";
 	/** Build number, just used for about screen */
-	public static final String BUILD_NUMBER = "340";
+	public static final String BUILD_NUMBER = "342";
 	/** Static reference to App object */
 	private static App APP = null;
 
diff --git a/tim/prune/function/AboutScreen.java b/tim/prune/function/AboutScreen.java
index c6bd759..d2f5712 100644
--- a/tim/prune/function/AboutScreen.java
+++ b/tim/prune/function/AboutScreen.java
@@ -168,6 +168,7 @@ public class AboutScreen extends GenericFunction
 		creditsPanel.setLayout(gridBag);
 		constraints = new GridBagConstraints();
 		constraints.weightx = 0.0; constraints.weighty = 0.0;
+		constraints.ipady = 3;
 
 		addToGridBagPanel(creditsPanel, gridBag, constraints,
 			new JLabel(I18nManager.getText("dialog.about.credits.code") + " : "),
@@ -200,7 +201,7 @@ public class AboutScreen extends GenericFunction
 			new JLabel(" katpatuka, R\u00E9mi, Marcus, Ali, Javier, Jeroen, prot_d, Gy\u00F6rgy,"),
 			1, 5);
 		addToGridBagPanel(creditsPanel, gridBag, constraints,
-			new JLabel(" HooAU, Sergey, P\u00E9ter, serhijdubyk, Peter, Cristian"),
+			new JLabel(" HooAU, Sergey, P\u00E9ter, serhijdubyk, Peter, Cristian, Roman"),
 			1, 6);
 		addToGridBagPanel(creditsPanel, gridBag, constraints,
 			new JLabel(I18nManager.getText("dialog.about.credits.translations") + " : "),
diff --git a/tim/prune/function/gpsies/UploadGpsiesFunction.java b/tim/prune/function/gpsies/UploadGpsiesFunction.java
index 9a4ae30..3cef9db 100644
--- a/tim/prune/function/gpsies/UploadGpsiesFunction.java
+++ b/tim/prune/function/gpsies/UploadGpsiesFunction.java
@@ -39,6 +39,7 @@ import tim.prune.I18nManager;
 import tim.prune.function.browser.BrowserLauncher;
 import tim.prune.gui.GuiGridLayout;
 import tim.prune.save.GpxExporter;
+import tim.prune.save.SettingsForExport;
 
 /**
  * Function to upload track information up to Gpsies.com
@@ -279,9 +280,9 @@ public class UploadGpsiesFunction extends GenericFunction
 			_writer = new OutputStreamWriter(oStream);
 			new Thread(new Runnable() {
 				public void run() {
-					boolean[] saveFlags = {true, true, true, true, false, true}; // export everything
 					try {
-						GpxExporter.exportData(_writer, _app.getTrackInfo(), _nameField.getText(), null, saveFlags, null);
+						GpxExporter.exportData(_writer, _app.getTrackInfo(), _nameField.getText(),
+							null, new SettingsForExport(), null);
 					} catch (IOException e) {}
 					finally {
 						try {_writer.close();} catch (IOException e) {}
diff --git a/tim/prune/gui/map/DiskTileCacher.java b/tim/prune/gui/map/DiskTileCacher.java
index 63dc684..fd2042a 100644
--- a/tim/prune/gui/map/DiskTileCacher.java
+++ b/tim/prune/gui/map/DiskTileCacher.java
@@ -46,10 +46,9 @@ public class DiskTileCacher implements Runnable
 	 * Get the specified tile from the disk cache
 	 * @param inBasePath base path to whole disk cache
 	 * @param inTilePath relative path to requested tile
-	 * @param inCheckAge true to check age of file, false to ignore
 	 * @return tile image if available, or null if not there
 	 */
-	public static Image getTile(String inBasePath, String inTilePath, boolean inCheckAge)
+	public static MapTile getTile(String inBasePath, String inTilePath)
 	{
 		if (inBasePath == null) {return null;}
 		File tileFile = new File(inBasePath, inTilePath);
@@ -57,17 +56,17 @@ public class DiskTileCacher implements Runnable
 		if (tileFile.exists() && tileFile.canRead() && tileFile.length() > 0)
 		{
 			long fileStamp = tileFile.lastModified();
-			if (!inCheckAge || ((System.currentTimeMillis()-fileStamp) < CACHE_TIME_LIMIT))
+			boolean isExpired = ((System.currentTimeMillis()-fileStamp) > CACHE_TIME_LIMIT);
+			try
 			{
-				try {
-					image = Toolkit.getDefaultToolkit().createImage(tileFile.getAbsolutePath());
-				}
-				catch (Exception e) {
-					System.err.println("createImage: " + e.getClass().getName() + " _ " + e.getMessage());
-				}
+				image = Toolkit.getDefaultToolkit().createImage(tileFile.getAbsolutePath());
+				return new MapTile(image, isExpired);
+			}
+			catch (Exception e) {
+				System.err.println("createImage: " + e.getClass().getName() + " _ " + e.getMessage());
 			}
 		}
-		return image;
+		return null;
 	}
 
 	/**
@@ -76,31 +75,28 @@ public class DiskTileCacher implements Runnable
 	 * @param inBasePath base path to disk cache
 	 * @param inTilePath relative path to this tile
 	 * @param inObserver observer to inform when load complete
-	 * @return true if successful, false for failure
 	 */
-	public static boolean saveTile(URL inUrl, String inBasePath, String inTilePath, ImageObserver inObserver)
+	public static void saveTile(URL inUrl, String inBasePath, String inTilePath, ImageObserver inObserver)
 	{
-		if (inBasePath == null || inTilePath == null) {return false;}
+		if (inBasePath == null || inTilePath == null) {return;}
 		// save file if possible
 		File basePath = new File(inBasePath);
 		if (!basePath.exists() || !basePath.isDirectory() || !basePath.canWrite()) {
 			// Can't write to base path
-			return false;
+			return;
 		}
 		File tileFile = new File(basePath, inTilePath);
 		// Check if this file is already being loaded
-		if (isBeingLoaded(tileFile)) {return true;}
+		if (isBeingLoaded(tileFile)) {return;}
 		// Check if it has already failed
-		if (BLOCKED_URLS.contains(inUrl.toString())) {return true;}
+		if (BLOCKED_URLS.contains(inUrl.toString())) {return;}
 
 		File dir = tileFile.getParentFile();
 		// Start a new thread to load the image if necessary
 		if ((dir.exists() || dir.mkdirs()) && dir.canWrite())
 		{
 			new Thread(new DiskTileCacher(inUrl, tileFile, inObserver)).start();
-			return true;
 		}
-		return false; // couldn't write the file
 	}
 
 	/**
@@ -141,6 +137,7 @@ public class DiskTileCacher implements Runnable
 		{
 			// Open streams from URL and to file
 			out = new FileOutputStream(tempFile);
+			//System.out.println("Opening URL: " + _url.toString());
 			// Set http user agent on connection
 			URLConnection conn = _url.openConnection();
 			conn.setRequestProperty("User-Agent", "GpsPrune v" + GpsPrune.VERSION_NUMBER);
@@ -165,7 +162,7 @@ public class DiskTileCacher implements Runnable
 			}
 		}
 		// Move temp file to desired file location
-		if (!tempFile.renameTo(_file))
+		if (tempFile.exists() && !tempFile.renameTo(_file))
 		{
 			// File couldn't be moved - delete both to be sure
 			tempFile.delete();
diff --git a/tim/prune/gui/map/MapCanvas.java b/tim/prune/gui/map/MapCanvas.java
index 4221520..5711951 100644
--- a/tim/prune/gui/map/MapCanvas.java
+++ b/tim/prune/gui/map/MapCanvas.java
@@ -705,7 +705,7 @@ public class MapCanvas extends JPanel implements MouseListener, MouseMotionListe
 			anyWaypoints = anyWaypoints || isWaypoint;
 			if (!isWaypoint)
 			{
-				if ((currPointVisible || prevPointVisible) && drawPoints)
+				if (currPointVisible || (drawLines && prevPointVisible))
 				{
 					// For track points, work out which colour to use
 					if (_track.getPoint(i).getDeleteFlag()) {
@@ -722,7 +722,7 @@ public class MapCanvas extends JPanel implements MouseListener, MouseMotionListe
 					}
 
 					// Draw rectangle for track point if it's visible
-					if (currPointVisible)
+					if (currPointVisible && drawPoints)
 					{
 						inG.drawRect(px-2, py-2, 3, 3);
 						pointsPainted++;
diff --git a/tim/prune/gui/map/MapTile.java b/tim/prune/gui/map/MapTile.java
new file mode 100644
index 0000000..36a494d
--- /dev/null
+++ b/tim/prune/gui/map/MapTile.java
@@ -0,0 +1,32 @@
+package tim.prune.gui.map;
+
+import java.awt.Image;
+
+/**
+ * Simple wrapper to hold an image for a map tile
+ * and a boolean flag to show whether it's expired or not
+ */
+public class MapTile
+{
+	/** Image or null if no image available */
+	private Image _image = null;
+	/** True if image expired, false if still fresh */
+	private boolean _expired = false;
+
+	/** Constructor */
+	public MapTile(Image inImage, boolean inExpired)
+	{
+		_image = inImage;
+		_expired = inExpired;
+	}
+
+	/** Get the image */
+	public Image getImage() {
+		return _image;
+	}
+
+	/** Return true if image is too old */
+	public boolean isExpired() {
+		return _expired;
+	}
+}
diff --git a/tim/prune/gui/map/MapTileManager.java b/tim/prune/gui/map/MapTileManager.java
index ed8849b..f7370c5 100644
--- a/tim/prune/gui/map/MapTileManager.java
+++ b/tim/prune/gui/map/MapTileManager.java
@@ -155,14 +155,14 @@ public class MapTileManager implements ImageObserver
 		inX = ((inX % _numTileIndices) + _numTileIndices) % _numTileIndices;
 
 		// Check first in memory cache for tile
-		Image tile = null;
+		Image tileImage = null;
 		MemTileCacher tempCache = null;
 		if (_tempCaches != null)
 		{
 			tempCache = _tempCaches[inLayer]; // Should probably guard array indexes here
-			tile = tempCache.getTile(inX, inY);
-			if (tile != null) {
-				return tile;
+			tileImage = tempCache.getTile(inX, inY);
+			if (tileImage != null) {
+				return tileImage;
 			}
 		}
 
@@ -170,32 +170,37 @@ public class MapTileManager implements ImageObserver
 		String diskCachePath = Config.getConfigString(Config.KEY_DISK_CACHE);
 		boolean useDisk = (diskCachePath != null);
 		boolean onlineMode = Config.getConfigBoolean(Config.KEY_ONLINE_MODE);
+		MapTile mapTile = null;
 		if (useDisk)
 		{
-			tile = DiskTileCacher.getTile(diskCachePath, _mapSource.makeFilePath(inLayer, _zoom, inX, inY), onlineMode);
-			if (tile != null)
+			// Get the map tile from cache
+			mapTile = DiskTileCacher.getTile(diskCachePath, _mapSource.makeFilePath(inLayer, _zoom, inX, inY));
+			if (mapTile != null && mapTile.getImage() != null)
 			{
-				if (_returnIncompleteImages) {return tile;}
+				tileImage = mapTile.getImage();
+				if (_returnIncompleteImages) {return tileImage;}
 				// Pass tile to memory cache
 				if (tempCache != null) {
-					tempCache.setTile(tile, inX, inY, _zoom);
+					tempCache.setTile(tileImage, inX, inY, _zoom);
 				}
-				if (tile.getWidth(this) > 0) {return tile;}
-				return null;
+				tileImage.getWidth(this); // trigger the load from file
 			}
-			// else System.out.println("DTC gave null tile for " + _zoom + ", " + inX + ", " + inY);
 		}
-		// Tile wasn't in memory or on disk, so if online let's get it
-		if (onlineMode && _downloadTiles && inDownloadIfNecessary)
+		// Maybe we've got an image now, maybe it's expired
+		final boolean shouldDownload = (tileImage == null || mapTile == null || mapTile.isExpired());
+
+		// If we're online then try to download the tile
+		if (onlineMode && _downloadTiles && inDownloadIfNecessary && shouldDownload)
 		{
 			try
 			{
 				URL tileUrl = new URL(_mapSource.makeURL(inLayer, _zoom, inX, inY));
-				// System.out.println("Going to fetch: " + tileUrl);
-				if (useDisk && DiskTileCacher.saveTile(tileUrl, diskCachePath,
-					_mapSource.makeFilePath(inLayer, _zoom, inX, inY), this))
+				//System.out.println("Trying to fetch: " + tileUrl);
+				if (useDisk)
 				{
-					// Image now copied directly from URL stream to disk cache
+					DiskTileCacher.saveTile(tileUrl, diskCachePath,
+						_mapSource.makeFilePath(inLayer, _zoom, inX, inY), this);
+					// Image will now be copied directly from URL stream to disk cache
 				}
 				else
 				{
@@ -206,7 +211,7 @@ public class MapTileManager implements ImageObserver
 			}
 			catch (MalformedURLException urle) {} // ignore
 		}
-		return null;
+		return tileImage;
 	}
 
 	/**
diff --git a/tim/prune/gui/profile/ProfileChart.java b/tim/prune/gui/profile/ProfileChart.java
index b2d0d0d..6e21996 100644
--- a/tim/prune/gui/profile/ProfileChart.java
+++ b/tim/prune/gui/profile/ProfileChart.java
@@ -136,8 +136,7 @@ public class ProfileChart extends GenericDisplay implements MouseListener
 
 			// horizontal lines for scale - set to round numbers eg 500
 			int lineScale = getLineScale(minValue, maxValue);
-			int scaleValue = (int) (minValue/lineScale + 1) * lineScale;
-			if (minValue < 0.0) {scaleValue -= lineScale;}
+			double scaleValue = Math.ceil(minValue/lineScale) * lineScale;
 			int x = 0, y = 0;
 			final int zeroY = height - BORDER_WIDTH - (int) (yScaleFactor * (0.0 - minValue));
 
@@ -223,7 +222,7 @@ public class ProfileChart extends GenericDisplay implements MouseListener
 					if (y < (BORDER_WIDTH + textHeight)) {
 						y = BORDER_WIDTH + textHeight;
 					}
-					g.drawString(""+scaleValue, BORDER_WIDTH + 5, y);
+					g.drawString(""+(int)scaleValue, BORDER_WIDTH + 5, y);
 					scaleValue += lineScale;
 				}
 			}
diff --git a/tim/prune/lang/prune-texts_cz.properties b/tim/prune/lang/prune-texts_cz.properties
index 0d8c177..c060e88 100644
--- a/tim/prune/lang/prune-texts_cz.properties
+++ b/tim/prune/lang/prune-texts_cz.properties
@@ -39,6 +39,7 @@ menu.view.browser.yahoo=Mapy Yahoo
 menu.view.browser.bing=Mapy Bing
 menu.settings=Nastaven\u00ed
 menu.settings.onlinemode=Na\u010d\u00edtat mapy z internetu
+menu.settings.antialias=Pou\u017e\u00edt antialiasing
 menu.settings.autosave=P\u0159i ukon\u010den\u00ed automaticky ukl\u00e1dat
 menu.help=Pomoc
 # Popup menu for map
@@ -111,6 +112,8 @@ function.lookupsrtm=Na\u010d\u00edst nadm. v\u00fd\u0161ku ze SRTM
 function.downloadsrtm=St\u00e1hnout dla\u017edice ze SRTM
 function.getwikipedia=Hledat na Wikipedii podle vzd\u00e1lenosti
 function.searchwikipedianames=Hledat na Wikipedii podle jm\u00e9na
+function.searchopencachingde=Hledat na OpenCaching.de
+function.mapillary=Hledat fotografie v Mapillary
 function.downloadosm=St\u00e1hnout data OSM pro oblast
 function.duplicatepoint=Zdvojit bod
 function.setcolours=Nastavit barvy
@@ -376,6 +379,7 @@ dialog.gpsies.activity.sailing=Lo\u010f
 dialog.gpsies.activity.skating=Bruslen\u00ed
 dialog.wikipedia.column.name=N\u00e1zev \u010dl\u00e1nku
 dialog.wikipedia.column.distance=Vzd\u00e1lenost
+dialog.wikipedia.gallery=Galerie
 dialog.correlate.notimestamps=U bod\u016f nejsou \u010dasov\u00e9 zna\u010dky, tak\u017ee nen\u00ed s \u010d\u00edm fotografie sladit.
 dialog.correlate.nouncorrelatedphotos=V\u0161echny fotografie jsou slad\u011bn\u00e9.\nOpravdu chcete pokra\u010dovat?
 dialog.correlate.nouncorrelatedaudios=V\u0161echny audionahr\u00e1vky jsou slad\u011bn\u00e9.\nOpravdu chcete pokra\u010dovat?
@@ -562,6 +566,7 @@ dialog.weather.day.sunday=Ned\u011ble
 dialog.weather.temp=Teplota
 dialog.weather.humidity=Vlhkost
 dialog.weather.creditnotice=Data poskytuje slu\u017eba openweathermap.org, v\u00edce informac\u00ed na t\u00e9to adrese.
+dialog.deletebydate.column.delete=Smazat
 
 # 3d window
 dialog.3d.title=Trojrozm\u011brn\u00e9 zobrazen\u00ed GpsPrune
@@ -769,6 +774,9 @@ logic.or=nebo
 url.googlemaps=maps.google.cz
 wikipedia.lang=cs
 openweathermap.lang=en
+webservice.peakfinder=Otev\u0159\u00edt Peakfinder.org
+webservice.geohack=Otev\u0159\u00edt Geohack
+webservice.panoramio=Otev\u0159\u00edt Panoramio
 
 # Cardinals for 3d plots
 cardinal.n=N
diff --git a/tim/prune/lang/prune-texts_es.properties b/tim/prune/lang/prune-texts_es.properties
index f5d6214..d8c19aa 100644
--- a/tim/prune/lang/prune-texts_es.properties
+++ b/tim/prune/lang/prune-texts_es.properties
@@ -591,6 +591,8 @@ dialog.weather.humidity=Humedad
 dialog.deletebydate.nodate=Sin marcas de tiempo
 dialog.deletebydate.column.keep=Mantener
 dialog.deletebydate.column.delete=Eliminar
+dialog.setaltitudetolerance.text.metres=Limite (en metros) por debajo de cual pequeñas subidas o bajadas serán ignoradas
+dialog.setaltitudetolerance.text.feet=Limite (en pies) por debajo de cual pequeñas subidas o bajadas serán ignoradas
 dialog.autoplay.duration=Duraci\u00f3n (seg)
 dialog.autoplay.usetimestamps=Usar informaci\u00f3n de tiempo
 dialog.autoplay.rewind=Rebobinar
@@ -641,6 +643,9 @@ confirm.correlateaudios.multi=Los audios fueron correlacionados
 
 ## Tips, shown just once when appropriate
 tip.title=Sugerencia
+tip.useamapcache=By setting up a disk cache (Preferencias -> Guardar mapas en disco)\nyou can speed up the display and reduce network traffic.
+tip.learntimeparams=The results will be more accurate if you use\nTrack -> Apprender parametros por la estimaci\u00f3n del tiempo\non your recorded tracks.
+tip.downloadsrtm=You can speed this up by calling\nOnline -> Descargar datos de SRTM\nto save the data in your map cache.
 tip.manuallycorrelateone=Correlacionando al menos una foto manualmente, el margen de tiempo se calcula autom\u00e1ticamente.
 
 ## Buttons
diff --git a/tim/prune/lang/prune-texts_ru.properties b/tim/prune/lang/prune-texts_ru.properties
index 87a20b1..6e6e8d7 100644
--- a/tim/prune/lang/prune-texts_ru.properties
+++ b/tim/prune/lang/prune-texts_ru.properties
@@ -1,5 +1,5 @@
 # Text entries for the GpsPrune application
-# Russian entries thanks to Sergey
+# Russian entries thanks to Sergey, Roman
 
 # Menu entries
 menu.file=\u0424\u0430\u0439\u043b
@@ -13,7 +13,6 @@ menu.track.undo=\u041e\u0442\u043c\u0435\u043d\u0438\u0442\u044c
 menu.track.clearundo=\u041e\u0447\u0438\u0441\u0442\u0438\u0442\u044c \u0441\u043f\u0438\u0441\u043e\u043a \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439
 menu.track.markrectangle=\u041e\u0442\u043c\u0435\u0442\u0438\u0442\u044c \u0442\u043e\u0447\u043a\u0438 \u0432 \u043a\u0432\u0430\u0434\u0440\u0430\u0442\u0435
 function.deletemarked=\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u043e\u0442\u043c\u0435\u0447\u0435\u043d\u043d\u044b\u0435 \u0442\u043e\u0447\u043a\u0438
-function.rearrangewaypoints=\u041f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b\u044b
 menu.range=\u0418\u043d\u0442\u0435\u0440\u0432\u0430\u043b
 menu.range.all=\u0412\u044b\u0431\u0440\u0430\u0442\u044c \u0432\u0441\u0435
 menu.range.none=\u041e\u0442\u043c\u0435\u043d\u0438\u0442\u044c \u0432\u044b\u0431\u043e\u0440\u043a\u0443
@@ -38,19 +37,20 @@ menu.view.browser.mapquest=Mapquest
 menu.view.browser.yahoo=Yahoo maps
 menu.view.browser.bing=Bing maps
 menu.settings=\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438
-menu.settings.onlinemode=\u0417\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u043a\u0430\u0440\u0442\u0443 \u0438\u0437 \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442
+menu.settings.onlinemode=\u0417\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u043a\u0430\u0440\u0442\u0443 \u0438\u0437 \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442\u0430
+menu.settings.antialias=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0433\u043b\u0430\u0436\u0438\u0432\u0430\u043d\u0438\u0435
 menu.settings.autosave=\u0410\u0432\u0442\u043e\u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u043f\u0440\u0438 \u0432\u044b\u0445\u043e\u0434\u0435
 menu.help=\u041f\u043e\u043c\u043e\u0449\u044c
 # Popup menu for map
 menu.map.zoomin=\u0423\u0432\u0435\u043b\u0438\u0447\u0438\u0442\u044c
 menu.map.zoomout=\u0423\u043c\u0435\u043d\u044c\u0448\u0438\u0442\u044c
-menu.map.zoomfull=\u0423\u0432\u0435\u043b\u0447\u0438\u0442\u044c \u0434\u043e \u043f\u043e\u043b\u043d\u043e\u0439 \u0448\u043a\u0430\u043b\u044b
+menu.map.zoomfull=\u0423\u0432\u0435\u043b\u0447\u0438\u0442\u044c \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e
 menu.map.newpoint=\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u043e\u0434\u043d\u0443 \u0442\u043e\u0447\u043a\u0443
 menu.map.drawpoints=\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0442\u043e\u0447\u0435\u043a
 menu.map.connect=\u0421\u043e\u0435\u0434\u0438\u043d\u0438\u0442\u044c \u0442\u043e\u0447\u043a\u0438 \u0442\u0440\u0435\u043a\u0430 \u0441 \u043b\u0438\u043d\u0438\u0435\u0439
 menu.map.autopan=\u041e\u0442\u043e\u0431\u0440\u0430\u0437\u0438\u0442\u044c \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u043e\u0435
 menu.map.showmap=\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u041e\u0421\u041c-\u043a\u0430\u0440\u0442\u0443
-menu.map.showscalebar=\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u043b\u0438\u043d\u0435\u0439\u043a\u0443 \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0430
+menu.map.showscalebar=\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u0448\u043a\u0430\u043b\u0443 \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0430
 menu.map.editmode=\u0420\u0435\u0436\u0438\u043c \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f
 
 # Alt keys for menus
@@ -86,11 +86,14 @@ function.exportsvg=\u042d\u043a\u0441\u043f\u043e\u0440\u0442 \u0432 SVG
 function.exportimage=\u042d\u043a\u0441\u043f\u043e\u0440\u0442 \u0432 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u0301\u043d\u0438\u0435
 function.editwaypointname=\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438\u043c\u044f \u043f\u0443\u0442\u0435\u0432\u043e\u0439 \u0442\u043e\u0447\u043a\u0438
 function.compress=\u0421\u0436\u0430\u0442\u044c \u0442\u0440\u0435\u043a
+function.marklifts=\u041e\u0442\u043c\u0435\u0442\u0438\u0442\u044c \u043f\u043e\u0434\u044a\u0451\u043c\u0438\u043d\u0438\u043a \u0432 \u0433\u043e\u0440\u0443
 function.deleterange=\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b
 function.croptrack=\u041e\u0431\u0440\u0435\u0437\u0430\u0442\u044c \u0442\u0440\u0435\u043a
-function.interpolate=\u0418\u043d\u0442\u0435\u0440\u043f\u043e\u043b\u044f\u0446\u0438\u044f \u0442\u043e\u0447\u0435\u043a
+function.interpolate=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0442\u043e\u0447\u0435\u043a\u0438 \u0432 \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b
+function.deletebydate=\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0442\u043e\u0447\u043a\u0438 \u043f\u043e \u0434\u0430\u0442\u0435
 function.addtimeoffset=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043e\u0442\u043c\u0435\u0442\u043a\u0443 \u0432\u0440\u0435\u043c\u0435\u043d\u0438
 function.addaltitudeoffset=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043e\u0442\u043c\u0435\u0442\u043a\u0443 \u0432\u044b\u0441\u043e\u0442\u044b
+function.rearrangewaypoints=\u041f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b\u044b
 function.convertnamestotimes=\u041f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u044c \u0438\u043c\u044f \u043f\u0443\u0442\u0435\u0432\u043e\u0439 \u0442\u043e\u0447\u043a\u0438 \u0432\u043e \u0432\u0440\u0435\u043c\u044f
 function.deletefieldvalues=\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u044f
 function.findwaypoint=\u041d\u0430\u0439\u0442\u0438 \u043f\u0443\u0442\u0435\u0432\u0443\u044e \u0442\u043e\u0447\u043a\u0443
@@ -104,6 +107,7 @@ function.learnestimationparams=\u0417\u0430\u043f\u043e\u043c\u043d\u0438\u0442\
 function.autoplay=\u0412\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u0435
 function.setmapbg=\u0412\u044b\u0431\u0440\u0430\u0442\u044c \u043a\u0430\u0440\u0442\u0443-\u043f\u043e\u0434\u043b\u043e\u0436\u043a\u0443
 function.setpaths=\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043f\u0443\u0442\u0438 \u043a \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430\u043c
+function.selectsegment=\u0412\u044b\u0431\u0440\u0430\u0442\u044c \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u0441\u0435\u0433\u043c\u0435\u043d\u0442
 function.splitsegments=\u0420\u0430\u0437\u0434\u0435\u043b\u0438\u0442\u044c \u0442\u0440\u0435\u043a \u043d\u0430 \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u044b
 function.sewsegments=\u0421\u043a\u043b\u0435\u0438\u0442\u044c \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u044b \u0442\u0440\u0435\u043a\u0430 \u0432\u043e\u0435\u0434\u0438\u043d\u043e
 function.getgpsies=\u0417\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0442\u0440\u0435\u043a\u0438
@@ -112,6 +116,8 @@ function.lookupsrtm=\u0412\u044b\u0441\u043e\u0442\u044b \u0432 SRTM
 function.downloadsrtm=\u0417\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c STRM
 function.getwikipedia=\u0421\u0442\u0430\u0442\u044c\u044f \u043e \u0431\u043b\u0438\u0436\u0430\u0439\u0448\u0435\u0439 \u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u0432 \u0412\u0438\u043a\u0438
 function.searchwikipedianames=\u041f\u043e\u0438\u0441\u043a \u0441\u0442\u0430\u0442\u0435\u0439 \u0432 \u0412\u0438\u043a\u0438 \u043f\u043e \u0438\u043c\u0435\u043d\u0438
+function.searchopencachingde=\u041f\u043e\u0438\u0441\u043a OpenCaching.de
+function.mapillary=\u041f\u043e\u0438\u0441\u043a \u0431\u043b\u0438\u0436\u0430\u0439\u0448\u0438\u0445 \u0444\u043e\u0442\u043e
 function.downloadosm=\u0417\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c OSM \u0434\u0430\u043d\u043d\u044b\u0435 \u043d\u0430 \u0442\u0435\u0440\u0440\u0438\u0442\u043e\u0440\u0438\u044e
 function.duplicatepoint=\u041a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u043e\u0447\u043a\u0443 \u0432 \u043a\u043e\u043d\u0435\u0446 \u0442\u0440\u0435\u043a\u0430
 function.setcolours=\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0446\u0432\u0435\u0442\u0430
@@ -139,6 +145,7 @@ function.saveconfig=\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u044
 function.diskcache=\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u043a\u0430\u0440\u0442\u044b \u043d\u0430 \u0434\u0438\u0441\u043a
 function.managetilecache=\u0423\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043a\u0435\u0448\u0435\u043c
 function.getweatherforecast=\u0417\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u043f\u0440\u043e\u0433\u043d\u043e\u0437 \u043f\u043e\u0433\u043e\u0434\u044b
+function.setaltitudetolerance=\u0417\u0430\u0434\u0430\u0442\u044c \u043e\u0433\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 \u0432\u044b\u0441\u043e\u0442\u044b
 
 # Dialogs
 dialog.exit.confirm.title=\u0412\u044b\u0445\u043e\u0434
@@ -186,6 +193,7 @@ dialog.gpssend.sendtracks=\u041f\u043e\u0441\u043b\u0430\u0442\u044c \u0442\u044
 dialog.gpssend.trackname=\u0418\u043c\u044f \u0442\u0440\u0435\u043a\u0430
 dialog.gpsbabel.filters=\u0424\u0438\u043b\u044c\u0442\u0440\u044b
 dialog.addfilter.title=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0444\u0438\u043b\u044c\u0442\u0440
+dialog.gpsbabel.filter.simplify=\u0421\u043e\u043a\u0440\u0430\u0442\u0438\u0442\u044c
 dialog.gpsbabel.filter.distance=\u0420\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u0435
 dialog.gpsbabel.filter.interpolate=\u0418\u043d\u0442\u0435\u0440\u043f\u043e\u043b\u044f\u0446\u0438\u044f
 dialog.gpsbabel.filter.discard.numsats=\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0441\u043f\u0443\u0442\u043d\u0438\u043a\u043e\u0432 <
@@ -388,6 +396,7 @@ dialog.rearrange.toend=\u041f\u0435\u0440\u0435\u043c\u0435\u0441\u0442\u0438\u0
 dialog.rearrange.tonearest=\u041f\u0435\u0440\u0435\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u043a \u0431\u043b\u0438\u0436\u0430\u0439\u0448\u0435\u0439
 dialog.rearrange.nosort=\u041d\u0435 \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c
 dialog.rearrange.sortbyfilename=\u0421\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u043e \u0438\u043c\u0435\u043d\u0438 \u0444\u0430\u0439\u043b\u0430
+dialog.rearrange.sortbyname=\u0421\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u043e \u0438\u043c\u0435\u043d\u0438
 dialog.rearrange.sortbytime=\u0421\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438
 dialog.compress.closepoints.title=\u0423\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u0441\u0431\u043b\u0438\u0436\u0435\u043d\u043d\u044b\u0445 \u0442\u043e\u0447\u0435\u043a
 dialog.compress.closepoints.paramdesc=\u0420\u0430\u0437\u043c\u0430\u0445
@@ -534,7 +543,7 @@ dialog.weather.day.sunday=\u0412\u043e\u0441\u043a\u0440\u0435\u0441\u0435\u043d
 dialog.weather.wind=\u0412\u0435\u0442\u0435\u0440
 dialog.weather.temp=\u0422\u00b0
 dialog.weather.humidity=\u0412\u043b\u0430\u0436\u043d\u043e\u0441\u0442\u044c
-dialog.weather.creditnotice=\u0414\u043B\u044F \u043F\u043E\u043B\u0443\u0447\u0435\u043D\u0438\u044F \u0434\u043E\u043F\u043E\u043B\u043D\u0438\u0442\u0435\u043B\u044C\u043D\u043E\u0439 \u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u0438 \u043E\u0431\u0440\u0430\u0442\u0438\u0442\u0435\u0441\u044C \u043F\u043E openweathermap.org.
+dialog.weather.creditnotice=\u0414\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u0435\u0441\u044c \u043f\u043e openweathermap.org.
 dialog.autoplay.rewind=\u041d\u0430\u0437\u0430\u0434
 dialog.autoplay.pause=\u0414\u0435\u0301\u043b\u0430\u0442\u044c \u043f\u0430\u0301\u0443\u0437\u0443
 dialog.autoplay.play=\u0412\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0441\u0442\u0438
@@ -688,6 +697,7 @@ fieldname.longitude=\u0414\u043e\u043b\u0433\u043e\u0442\u0430
 fieldname.altitude=\u0412\u044b\u0441\u043e\u0442\u0430
 fieldname.timestamp=\u0412\u0440\u0435\u043c\u044f
 fieldname.time=\u0412\u0440\u0435\u043c\u044f
+fieldname.date=\u0414\u0430\u0442\u0430
 fieldname.waypointname=\u0418\u043c\u044f
 fieldname.waypointtype=\u0422\u0438\u043f
 fieldname.newsegment=\u0421\u0435\u0433\u043c\u0435\u043d\u0442
@@ -738,10 +748,13 @@ units.degreesfahrenheit.short=\u00b0F
 logic.and=\u0438
 logic.or=\u0438\u043b\u0438
 
-# External urls
+# External urls and services
 url.googlemaps=maps.google.ru
 wikipedia.lang=ru
 openweathermap.lang=ru
+webservice.peakfinder=\u041e\u0442\u043a\u0440\u044b\u0442\u044c Peakfinder.org
+webservice.geohack=\u041e\u0442\u043a\u0440\u044b\u0442\u044c \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 Geohack
+webservice.panoramio=\u041e\u0442\u043a\u0440\u044b\u0442\u044c \u043a\u0430\u0440\u0442\u0443 Panoramio
 
 # Cardinals for 3d plots
 cardinal.n=\u0421\u0435\u0432\u0435\u0440
diff --git a/tim/prune/lang/prune-texts_uk.properties b/tim/prune/lang/prune-texts_uk.properties
index 9624351..ddfb0ac 100644
--- a/tim/prune/lang/prune-texts_uk.properties
+++ b/tim/prune/lang/prune-texts_uk.properties
@@ -54,6 +54,7 @@ menu.map.editmode=\u0420\u0435\u0436\u0438\u043c \u0440\u0435\u0434\u0430\u0433\
 
 # Alt keys for menus
 altkey.menu.file=F
+altkey.menu.online=N
 altkey.menu.track=T
 altkey.menu.range=R
 altkey.menu.point=P
@@ -87,6 +88,7 @@ function.compress=\u0421\u0442\u0438\u0441\u043d\u0443\u0442\u0438 \u0442\u0440\
 function.deleterange=\u0412\u0438\u043b\u0443\u0447\u0438\u0442\u0438 \u0456\u043d\u0442\u0435\u0440\u0432\u0430\u043b
 function.croptrack=\u041e\u0431\u0440\u0456\u0437\u0430\u0442\u0438 \u0442\u0440\u0435\u043a
 function.interpolate=\u0406\u043d\u0442\u0435\u0440\u043f\u043e\u043b\u044f\u0446\u0456\u044f \u0442\u043e\u0447\u043e\u043a
+function.deletebydate=\u0412\u0438\u043b\u0443\u0447\u0438\u0442\u0438 \u0442\u043e\u0447\u043a\u0438 \u0437\u0430 \u0434\u0430\u0442\u043e\u044e
 function.addtimeoffset=\u0414\u043e\u0434\u0430\u0442\u0438 \u043f\u043e\u0437\u043d\u0430\u0447\u043a\u0443 \u0447\u0430\u0441\u0443
 function.addaltitudeoffset=\u0414\u043e\u0434\u0430\u0442\u0438 \u043f\u043e\u0437\u043d\u0430\u0447\u043a\u0443 \u0432\u0438\u0441\u043e\u0442\u0438
 function.rearrangewaypoints=\u041f\u0435\u0440\u0435\u0432\u0438\u0437\u043d\u0430\u0447\u0438\u0442\u0438 \u0456\u043d\u0442\u0435\u0440\u0432\u0430\u043b\u0438
@@ -102,9 +104,13 @@ function.estimatetime=\u041f\u0440\u0438\u0431\u043b\u0438\u0437\u043d\u0438\u04
 function.learnestimationparams=\u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0438 \u0432\u0433\u0430\u0434\u0443\u0432\u0430\u043d\u043d\u044f \u043f\u0440\u0438\u0431\u043b\u0438\u0437\u043d\u043e\u0433\u043e \u0447\u0430\u0441\u0443
 function.setmapbg=\u0412\u0438\u0431\u0440\u0430\u0442\u0438 \u043c\u0430\u043f\u0443-\u043f\u0456\u0434\u043a\u043b\u0430\u0434\u043a\u0443
 function.setpaths=\u0412\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0438 \u0448\u043b\u044f\u0445\u0438 \u0434\u043e \u043f\u0440\u043e\u0433\u0440\u0430\u043c
+function.selectsegment=\u0412\u0438\u0431\u0440\u0430\u0442\u0438 \u043f\u043e\u0442\u043e\u0447\u043d\u0438\u0439 \u0441\u0435\u0433\u043c\u0435\u043d\u0442
+function.splitsegments=\u0420\u043e\u0437\u0431\u0438\u0442\u0438 \u0442\u0440\u0435\u043a \u043d\u0430 \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u0438
+function.sewsegments=\u0417\u0448\u0438\u0442\u0438 \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u0438 \u0442\u0440\u0435\u043a\u0456\u0432 \u0440\u0430\u0437\u043e\u043c
 function.getgpsies=\u0417\u0432\u0430\u043d\u0442\u0430\u0436\u0438\u0442\u0438 \u0442\u0440\u0435\u043a\u0438 \u0437 Gpsies
 function.uploadgpsies=\u0412\u0438\u0432\u0430\u043d\u0442\u0430\u0436\u0438\u0442\u0438 \u0442\u0440\u0435\u043a\u0438 \u043d\u0430 Gpsies
 function.lookupsrtm=\u041e\u0442\u0440\u0438\u043c\u0430\u0442\u0438 \u0432\u0438\u0441\u043e\u0442\u0438 \u0437 SRTM
+function.downloadsrtm=\u0417\u0432\u0430\u043d\u0442\u0430\u0436\u0438\u0442\u0438 SRTM-\u0442\u0430\u0439\u043b\u0438
 function.getwikipedia=\u041e\u0442\u0440\u0438\u043c\u0430\u0442\u0438 \u043d\u0430\u0439\u0431\u043b\u0438\u0436\u0447\u0443 \u0441\u0442\u0430\u0442\u0442\u044e \u0437 \u0412\u0456\u043a\u0456\u043f\u0435\u0434\u0456\u0457
 function.searchwikipedianames=\u041f\u043e\u0448\u0443\u043a \u0441\u0442\u0430\u0442\u0435\u0439 \u0437 \u0412\u0456\u043a\u0456\u043f\u0435\u0434\u0456\u0457 \u0437\u0430 \u043d\u0430\u0437\u0432\u043e\u044e
 function.downloadosm=\u0417\u0432\u0430\u043d\u0442\u0430\u0436\u0438\u0442\u0438 OSM-\u0434\u0430\u043d\u0456 \u043d\u0430 \u0442\u0435\u0440\u0438\u0442\u043e\u0440\u0456\u044e
@@ -236,12 +242,16 @@ button.no=\u041d\u0456
 # Display components
 display.nodata=\u0416\u043e\u0434\u043d\u0438\u0445 \u0434\u0430\u043d\u0438\u0445 \u043d\u0435 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043e
 details.trackdetails=\u041f\u043e\u0434\u0440\u043e\u0431\u0438\u0446\u0456 \u0442\u0440\u0435\u043a\u0443
+details.notrack=\u0416\u043e\u0434\u043d\u043e\u0433\u043e \u0442\u0440\u0435\u043a\u0443 \u043d\u0435 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043e
 details.track.points=\u0422\u043e\u0447\u043a\u0438
 details.track.file=\u0424\u0430\u0439\u043b
 details.pointdetails=\u041f\u043e\u0434\u0440\u043e\u0431\u0438\u0446\u0456 \u0442\u043e\u0447\u043a\u0438
 details.nopointselection=\u0422\u043e\u0447\u043a\u0443 \u043d\u0435 \u0432\u0438\u0431\u0440\u0430\u043d\u043e
 details.norangeselection=\u0414\u0456\u0430\u043f\u0430\u0437\u043e\u043d \u043d\u0435 \u0432\u0438\u0431\u0440\u0430\u043d\u043e
 details.rangedetails=\u041f\u043e\u0434\u0440\u043e\u0431\u0438\u0446\u0456 \u0434\u0456\u0430\u043f\u0430\u0437\u043e\u043d\u0443
+details.coordformat=\u0424\u043e\u0440\u043c\u0430\u0442 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442
+details.distanceunits=\u041e\u0434\u0438\u043d\u0438\u0446\u0456 \u0432\u0456\u0434\u0441\u0442\u0430\u043d\u0456
+details.lists.waypoints=\u0428\u043b\u044f\u0445\u043e\u0432\u0456 \u0442\u043e\u0447\u043a\u0438
 details.lists.photos=\u0421\u0432\u0456\u0442\u043b\u0438\u043d\u0438
 details.photodetails=\u041f\u043e\u0434\u0440\u043e\u0431\u0438\u0446\u0456 \u0441\u0432\u0456\u0442\u043b\u0438\u043d\u0438
 details.nophoto=\u0421\u0432\u0456\u0442\u043b\u0438\u043d\u0443 \u043d\u0435 \u0432\u0438\u0431\u0440\u0430\u043d\u043e
diff --git a/tim/prune/readme.txt b/tim/prune/readme.txt
index d4996f7..afde04b 100644
--- a/tim/prune/readme.txt
+++ b/tim/prune/readme.txt
@@ -1,4 +1,4 @@
-GpsPrune version 18.4
+GpsPrune version 18.5
 =====================
 
 GpsPrune is an application for viewing, editing and managing coordinate data from GPS systems,
@@ -17,7 +17,7 @@ Running
 =======
 
 To run GpsPrune from the jar file, simply call it from a command prompt or shell:
-   java -jar gpsprune_18.4.jar
+   java -jar gpsprune_18.5.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,9 +25,18 @@ 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 gpsprune_18.4.jar --lang=DE
+   java -jar gpsprune_18.5.jar --lang=DE
 
 
+New with version 18.5
+=====================
+The following fixes and additions were made since version 18.4:
+  - When points have no altitudes, send them to a GPS with altitude 0 (prevents weird values when reading back)
+  - When points are not displayed on map, still colour the lines according to the selected scheme
+  - When points all have crazy values, don't hang the profile chart
+  - When images can't be fetched from the internet, don't delete expired cache images
+  - Translation updates to es, uk, ru, cz
+
 New with version 18.4
 =====================
 The following fixes and additions were made since version 18.3:
diff --git a/tim/prune/save/GpsSaver.java b/tim/prune/save/GpsSaver.java
index 3fa66c3..6179a5c 100644
--- a/tim/prune/save/GpsSaver.java
+++ b/tim/prune/save/GpsSaver.java
@@ -311,8 +311,9 @@ public class GpsSaver extends GenericFunction implements Runnable
 		if (trackName == null || trackName.equals("")) {trackName = "gpsprune";}
 		// Generate the GPX file and send to the GPS
 		OutputStreamWriter writer = new OutputStreamWriter(process.getOutputStream());
-		boolean[] saveFlags = {true, true, true, true, false, true}; // export everything
-		GpxExporter.exportData(writer, _app.getTrackInfo(), trackName, null, saveFlags, null);
+		SettingsForExport settings = new SettingsForExport();
+		settings.setExportMissingAltitudesAsZero(true);
+		GpxExporter.exportData(writer, _app.getTrackInfo(), trackName, null, settings, null);
 		writer.close();
 
 		// Read the error stream to see if there's a better error message there
diff --git a/tim/prune/save/GpxExporter.java b/tim/prune/save/GpxExporter.java
index 9363616..7cac01c 100644
--- a/tim/prune/save/GpxExporter.java
+++ b/tim/prune/save/GpxExporter.java
@@ -290,12 +290,17 @@ public class GpxExporter extends GenericFunction implements Runnable
 				writer = new OutputStreamWriter(new FileOutputStream(_exportFile), "UTF-8");
 			else
 				writer = new OutputStreamWriter(new FileOutputStream(_exportFile));
-			final boolean[] saveFlags = {_pointTypeSelector.getTrackpointsSelected(), _pointTypeSelector.getWaypointsSelected(),
-				_pointTypeSelector.getPhotopointsSelected(), _pointTypeSelector.getAudiopointsSelected(),
-				_pointTypeSelector.getJustSelection(), _timestampsCheckbox.isSelected()};
+			// TODO: Move to new method
+			SettingsForExport settings = new SettingsForExport();
+			settings.setExportTrackPoints(_pointTypeSelector.getTrackpointsSelected());
+			settings.setExportWaypoints(_pointTypeSelector.getWaypointsSelected());
+			settings.setExportPhotoPoints(_pointTypeSelector.getPhotopointsSelected());
+			settings.setExportAudiopoints(_pointTypeSelector.getAudiopointsSelected());
+			settings.setExportJustSelection(_pointTypeSelector.getJustSelection());
+			settings.setExportTimestamps(_timestampsCheckbox.isSelected());
 			// write file
 			final int numPoints = exportData(writer, _trackInfo, _nameField.getText(),
-				_descriptionField.getText(), saveFlags, gpxCachers);
+				_descriptionField.getText(), settings, gpxCachers);
 
 			// close file
 			writer.close();
@@ -334,13 +339,13 @@ public class GpxExporter extends GenericFunction implements Runnable
 	 * @param inInfo track info object
 	 * @param inName name of track (optional)
 	 * @param inDesc description of track (optional)
-	 * @param inSaveFlags array of booleans to export tracks, waypoints, photos, audios, selection, timestamps
+	 * @param inExportSettings flags for what to export and how
 	 * @param inGpxCachers list of Gpx cachers containing input data
 	 * @return number of points written
 	 * @throws IOException if io errors occur on write
 	 */
 	public static int exportData(OutputStreamWriter inWriter, TrackInfo inInfo, String inName,
-		String inDesc, boolean[] inSaveFlags, GpxCacherList inGpxCachers) throws IOException
+		String inDesc, SettingsForExport inSettings, GpxCacherList inGpxCachers) throws IOException
 	{
 		// Write or copy headers
 		inWriter.write(getXmlHeaderString(inWriter));
@@ -353,12 +358,9 @@ public class GpxExporter extends GenericFunction implements Runnable
 		writeNameAndDescription(inWriter, trackName, desc, isVersion1_1);
 
 		DataPoint point = null;
-		final boolean exportTrackpoints = inSaveFlags[0];
-		final boolean exportWaypoints = inSaveFlags[1];
-		final boolean exportPhotos = inSaveFlags[2];
-		final boolean exportAudios = inSaveFlags[3];
-		final boolean exportSelection = inSaveFlags[4];
-		final boolean exportTimestamps = inSaveFlags[5];
+		final boolean exportWaypoints = inSettings.getExportWaypoints();
+		final boolean exportSelection = inSettings.getExportJustSelection();
+		final boolean exportTimestamps = inSettings.getExportTimestamps();
 		// Examine selection
 		int selStart = -1, selEnd = -1;
 		if (exportSelection) {
@@ -388,23 +390,23 @@ public class GpxExporter extends GenericFunction implements Runnable
 						inWriter.write('\n');
 					}
 					else {
-						exportWaypoint(point, inWriter, exportTimestamps, exportPhotos, exportAudios);
+						exportWaypoint(point, inWriter, inSettings);
 					}
 					numSaved++;
 				}
 			}
 		}
 		// Export both route points and then track points
-		if (exportTrackpoints || exportPhotos || exportAudios)
+		if (inSettings.getExportTrackPoints() || inSettings.getExportPhotoPoints() || inSettings.getExportAudioPoints())
 		{
 			// Output all route points (if any)
-			numSaved += writeTrackPoints(inWriter, inInfo, exportSelection, exportTrackpoints, exportPhotos,
-				exportAudios, exportTimestamps, true, inGpxCachers, "<rtept", "\t<rte><number>1</number>\n",
+			numSaved += writeTrackPoints(inWriter, inInfo, inSettings,
+				true, inGpxCachers, "<rtept", "\t<rte><number>1</number>\n",
 				null, "\t</rte>\n");
 			// Output all track points, if any
 			String trackStart = "\t<trk>\n\t\t<name>" + trackName + "</name>\n\t\t<number>1</number>\n\t\t<trkseg>\n";
-			numSaved += writeTrackPoints(inWriter, inInfo, exportSelection, exportTrackpoints, exportPhotos,
-				exportAudios, exportTimestamps, false, inGpxCachers, "<trkpt", trackStart,
+			numSaved += writeTrackPoints(inWriter, inInfo, inSettings,
+				false, inGpxCachers, "<trkpt", trackStart,
 				"\t</trkseg>\n\t<trkseg>\n", "\t\t</trkseg>\n\t</trk>\n");
 		}
 
@@ -450,11 +452,7 @@ public class GpxExporter extends GenericFunction implements Runnable
 	 * Loop through the track outputting the relevant track points
 	 * @param inWriter writer object for output
 	 * @param inInfo track info object containing track
-	 * @param inExportSelection true to just output current selection
-	 * @param inExportTrackpoints true to output track points
-	 * @param inExportPhotos true to output photo points
-	 * @param inExportAudios true to output audio points
-	 * @param inExportTimestamps true to include timestamps in export
+	 * @param inSettings export settings defining what should be exported
 	 * @param inOnlyCopies true to only export if source can be copied
 	 * @param inCachers list of GpxCachers
 	 * @param inPointTag tag to match for each point
@@ -463,26 +461,30 @@ public class GpxExporter extends GenericFunction implements Runnable
 	 * @param inEndTag end tag to output
 	 */
 	private static int writeTrackPoints(OutputStreamWriter inWriter,
-		TrackInfo inInfo, boolean inExportSelection, boolean inExportTrackpoints,
-		boolean inExportPhotos, boolean inExportAudios, boolean exportTimestamps,
+		TrackInfo inInfo, SettingsForExport inSettings,
 		boolean inOnlyCopies, GpxCacherList inCachers, String inPointTag,
 		String inStartTag, String inSegmentTag, String inEndTag)
 	throws IOException
 	{
-		// Note: far too many input parameters to this method but avoids duplication
+		// Note: Too many input parameters to this method but avoids duplication
 		// of output functionality for writing track points and route points
 		int numPoints = inInfo.getTrack().getNumPoints();
 		int selStart = inInfo.getSelection().getStart();
 		int selEnd = inInfo.getSelection().getEnd();
 		int numSaved = 0;
+		final boolean exportSelection = inSettings.getExportJustSelection();
+		final boolean exportTrackPoints = inSettings.getExportTrackPoints();
+		final boolean exportPhotos = inSettings.getExportPhotoPoints();
+		final boolean exportAudios = inSettings.getExportAudioPoints();
+		final boolean exportTimestamps = inSettings.getExportTimestamps();
 		// Loop over track points
 		for (int i=0; i<numPoints; i++)
 		{
 			DataPoint point = inInfo.getTrack().getPoint(i);
-			if ((!inExportSelection || (i>=selStart && i<=selEnd)) && !point.isWaypoint())
+			if ((!exportSelection || (i>=selStart && i<=selEnd)) && !point.isWaypoint())
 			{
-				if ((point.getPhoto()==null && inExportTrackpoints) || (point.getPhoto()!=null && inExportPhotos)
-					|| (point.getAudio()!=null && inExportAudios))
+				if ((point.getPhoto()==null && exportTrackPoints) || (point.getPhoto()!=null && exportPhotos)
+					|| (point.getAudio()!=null && exportAudios))
 				{
 					// get the source from the point (if any)
 					String pointSource = getPointSource(inCachers, point);
@@ -506,15 +508,20 @@ public class GpxExporter extends GenericFunction implements Runnable
 							inWriter.write(pointSource);
 							inWriter.write('\n');
 						}
-						else {
-							if (!inOnlyCopies) {exportTrackpoint(point, inWriter, exportTimestamps, inExportPhotos, inExportAudios);}
+						else
+						{
+							if (!inOnlyCopies) {
+								exportTrackpoint(point, inWriter, inSettings);
+							}
 						}
 						numSaved++;
 					}
 				}
 			}
 		}
-		if (numSaved > 0) {inWriter.write(inEndTag);}
+		if (numSaved > 0) {
+			inWriter.write(inEndTag);
+		}
 		return numSaved;
 	}
 
@@ -663,13 +670,11 @@ public class GpxExporter extends GenericFunction implements Runnable
 	 * Export the specified waypoint into the file
 	 * @param inPoint waypoint to export
 	 * @param inWriter writer object
-	 * @param inTimestamps true to export timestamps too
-	 * @param inPhoto true to export link to photo
-	 * @param inAudio true to export link to audio
+	 * @param inSettings export settings
 	 * @throws IOException on write failure
 	 */
-	private static void exportWaypoint(DataPoint inPoint, Writer inWriter, boolean inTimestamps,
-		boolean inPhoto, boolean inAudio)
+	private static void exportWaypoint(DataPoint inPoint, Writer inWriter,
+		SettingsForExport inSettings)
 		throws IOException
 	{
 		inWriter.write("\t<wpt lat=\"");
@@ -678,14 +683,14 @@ public class GpxExporter extends GenericFunction implements Runnable
 		inWriter.write(inPoint.getLongitude().output(Coordinate.FORMAT_DECIMAL_FORCE_POINT));
 		inWriter.write("\">\n");
 		// altitude if available
-		if (inPoint.hasAltitude())
+		if (inPoint.hasAltitude() || inSettings.getExportMissingAltitudesAsZero())
 		{
 			inWriter.write("\t\t<ele>");
-			inWriter.write("" + inPoint.getAltitude().getStringValue(UnitSetLibrary.UNITS_METRES));
+			inWriter.write(inPoint.hasAltitude() ? inPoint.getAltitude().getStringValue(UnitSetLibrary.UNITS_METRES) : "0");
 			inWriter.write("</ele>\n");
 		}
-		// timestamp if available (point might have timestamp and then be turned into a waypoint)
-		if (inPoint.hasTimestamp() && inTimestamps)
+		// timestamp if available (some waypoints have timestamps, some not)
+		if (inPoint.hasTimestamp() && inSettings.getExportTimestamps())
 		{
 			inWriter.write("\t\t<time>");
 			inWriter.write(inPoint.getTimestamp().getText(Timestamp.Format.ISO8601));
@@ -704,13 +709,13 @@ public class GpxExporter extends GenericFunction implements Runnable
 			inWriter.write("</desc>\n");
 		}
 		// Media links, if any
-		if (inPhoto && inPoint.getPhoto() != null)
+		if (inSettings.getExportPhotoPoints() && inPoint.getPhoto() != null)
 		{
 			inWriter.write("\t\t");
 			inWriter.write(makeMediaLink(inPoint.getPhoto()));
 			inWriter.write('\n');
 		}
-		if (inAudio && inPoint.getAudio() != null)
+		if (inSettings.getExportAudioPoints() && inPoint.getAudio() != null)
 		{
 			inWriter.write("\t\t");
 			inWriter.write(makeMediaLink(inPoint.getAudio()));
@@ -736,12 +741,9 @@ public class GpxExporter extends GenericFunction implements Runnable
 	 * Export the specified trackpoint into the file
 	 * @param inPoint trackpoint to export
 	 * @param inWriter writer object
-	 * @param inTimestamps true to export timestamps too
-	 * @param inExportPhoto true to export photo link
-	 * @param inExportAudio true to export audio link
+	 * @param inSettings export settings
 	 */
-	private static void exportTrackpoint(DataPoint inPoint, Writer inWriter, boolean inTimestamps,
-		boolean inExportPhoto, boolean inExportAudio)
+	private static void exportTrackpoint(DataPoint inPoint, Writer inWriter, SettingsForExport inSettings)
 		throws IOException
 	{
 		inWriter.write("\t\t\t<trkpt lat=\"");
@@ -750,24 +752,24 @@ public class GpxExporter extends GenericFunction implements Runnable
 		inWriter.write(inPoint.getLongitude().output(Coordinate.FORMAT_DECIMAL_FORCE_POINT));
 		inWriter.write("\">\n");
 		// altitude
-		if (inPoint.hasAltitude())
+		if (inPoint.hasAltitude() || inSettings.getExportMissingAltitudesAsZero())
 		{
 			inWriter.write("\t\t\t\t<ele>");
-			inWriter.write("" + inPoint.getAltitude().getStringValue(UnitSetLibrary.UNITS_METRES));
+			inWriter.write(inPoint.hasAltitude() ? inPoint.getAltitude().getStringValue(UnitSetLibrary.UNITS_METRES) : "0");
 			inWriter.write("</ele>\n");
 		}
 		// timestamp if available (and selected)
-		if (inPoint.hasTimestamp() && inTimestamps)
+		if (inPoint.hasTimestamp() && inSettings.getExportTimestamps())
 		{
 			inWriter.write("\t\t\t\t<time>");
 			inWriter.write(inPoint.getTimestamp().getText(Timestamp.Format.ISO8601));
 			inWriter.write("</time>\n");
 		}
 		// photo, audio
-		if (inPoint.getPhoto() != null && inExportPhoto) {
+		if (inPoint.getPhoto() != null && inSettings.getExportPhotoPoints()) {
 			inWriter.write(makeMediaLink(inPoint.getPhoto()));
 		}
-		if (inPoint.getAudio() != null && inExportAudio) {
+		if (inPoint.getAudio() != null && inSettings.getExportAudioPoints()) {
 			inWriter.write(makeMediaLink(inPoint.getAudio()));
 		}
 		inWriter.write("\t\t\t</trkpt>\n");
diff --git a/tim/prune/save/SettingsForExport.java b/tim/prune/save/SettingsForExport.java
new file mode 100644
index 0000000..b7e3c69
--- /dev/null
+++ b/tim/prune/save/SettingsForExport.java
@@ -0,0 +1,66 @@
+package tim.prune.save;
+
+/**
+ * Settings for controlling what gets exported,
+ * for example by the Gpx export functions
+ */
+public class SettingsForExport
+{
+	private boolean _exportTrackPoints = true;
+	private boolean _exportWaypoints   = true;
+	private boolean _exportJustSelection = false;
+	private boolean _exportTimestamps  = true;
+	private boolean _exportMissingAltitudes = false;
+	private boolean _exportPhotoPoints = true;
+	private boolean _exportAudioPoints = true;
+
+	/** Set to export track points or not */
+	public void setExportTrackPoints(boolean inExport) {
+		_exportTrackPoints = inExport;
+	}
+
+	/** Set to export waypoints or not */
+	public void setExportWaypoints(boolean inExport) {
+		_exportWaypoints = inExport;
+	}
+
+	/** Set to export just the selection or everything */
+	public void setExportJustSelection(boolean inExport) {
+		_exportJustSelection = inExport;
+	}
+
+	/** Set to export timestamps or not */
+	public void setExportTimestamps(boolean inExport) {
+		_exportTimestamps = inExport;
+	}
+
+	/** Set to export missing altitudes as zero or not */
+	public void setExportMissingAltitudesAsZero(boolean inExport) {
+		_exportMissingAltitudes = inExport;
+	}
+
+	/** Set to export photo points or not */
+	public void setExportPhotoPoints(boolean inExport) {
+		_exportPhotoPoints = inExport;
+	}
+
+	/** Set to export audio points or not */
+	public void setExportAudiopoints(boolean inExport) {
+		_exportAudioPoints = inExport;
+	}
+
+	/** @return true to export track points */
+	public boolean getExportTrackPoints() {return _exportTrackPoints;}
+	/** @return true to export waypoints */
+	public boolean getExportWaypoints() {return _exportWaypoints;}
+	/** @return true to export just the selection */
+	public boolean getExportJustSelection() {return _exportJustSelection;}
+	/** @return true to export timestamps */
+	public boolean getExportTimestamps() {return _exportTimestamps;}
+	/** @return true to export zeroes for missing altitudes */
+	public boolean getExportMissingAltitudesAsZero() {return _exportMissingAltitudes;}
+	/** @return true to export photo points */
+	public boolean getExportPhotoPoints() {return _exportPhotoPoints;}
+	/** @return true to export audio points */
+	public boolean getExportAudioPoints() {return _exportAudioPoints;}
+}

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-grass/gpsprune.git



More information about the Pkg-grass-devel mailing list