From: activityworkshop Date: Sun, 15 Feb 2015 09:58:28 +0000 (+0100) Subject: Version 13, August 2011 X-Git-Tag: v19.2~22 X-Git-Url: http://gitweb.fperrin.net/?p=GpsPrune.git;a=commitdiff_plain;h=649c5da6ee1bbc590699e11a92316ece2ea8512d Version 13, August 2011 --- diff --git a/tim/prune/App.java b/tim/prune/App.java index 6fab583..8189ffb 100644 --- a/tim/prune/App.java +++ b/tim/prune/App.java @@ -9,31 +9,34 @@ import java.util.Stack; import javax.swing.JFrame; import javax.swing.JOptionPane; +import tim.prune.config.Config; import tim.prune.data.Altitude; -import tim.prune.data.AudioFile; import tim.prune.data.Checker; import tim.prune.data.DataPoint; import tim.prune.data.Field; import tim.prune.data.LatLonRectangle; -import tim.prune.data.MediaFile; import tim.prune.data.NumberUtils; import tim.prune.data.Photo; import tim.prune.data.PhotoList; +import tim.prune.data.RecentFile; import tim.prune.data.SourceInfo; import tim.prune.data.Track; import tim.prune.data.TrackInfo; +import tim.prune.data.SourceInfo.FILE_TYPE; +import tim.prune.function.AsyncMediaLoader; +import tim.prune.function.SaveConfig; import tim.prune.function.SelectTracksFunction; 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.gui.SidebarController; import tim.prune.gui.MenuManager; +import tim.prune.gui.SidebarController; import tim.prune.gui.UndoManager; import tim.prune.gui.Viewport; import tim.prune.load.FileLoader; import tim.prune.load.JpegLoader; -import tim.prune.load.MediaHelper; +import tim.prune.load.MediaLinkInfo; import tim.prune.load.TrackNameList; import tim.prune.save.ExifSaver; import tim.prune.save.FileSaver; @@ -60,6 +63,7 @@ public class App private Viewport _viewport = null; private ArrayList _dataFiles = null; private boolean _firstDataFile = true; + private boolean _busyLoading = false; /** @@ -209,6 +213,10 @@ public class App JOptionPane.WARNING_MESSAGE, null, buttonTexts, buttonTexts[1]) == JOptionPane.YES_OPTION) { + // save settings + if (Config.getConfigBoolean(Config.KEY_AUTOSAVE_SETTINGS)) { + new SaveConfig(this).silentSave(); + } System.exit(0); } } @@ -270,7 +278,7 @@ public class App { // Confirm deletion of photo or decoupling int response = JOptionPane.showConfirmDialog(_frame, - I18nManager.getText("dialog.deletepoint.deletephoto") + " " + currentPhoto.getFile().getName(), + I18nManager.getText("dialog.deletepoint.deletephoto") + " " + currentPhoto.getName(), I18nManager.getText("dialog.deletepoint.title"), JOptionPane.YES_NO_CANCEL_OPTION); if (response == JOptionPane.CANCEL_OPTION || response == JOptionPane.CLOSED_OPTION) @@ -304,6 +312,7 @@ public class App // decouple photo from point currentPhoto.setDataPoint(null); } + UpdateMessageBroker.informSubscribers(); } // Confirm UpdateMessageBroker.informSubscribers(I18nManager.getText("confirm.deletepoint.single")); @@ -317,82 +326,80 @@ public class App */ public void deleteSelectedRange() { - if (_track != null) + if (_track == null) return; + // Find out if photos should be deleted or not + int selStart = _trackInfo.getSelection().getStart(); + int selEnd = _trackInfo.getSelection().getEnd(); + if (selStart >= 0 && selEnd >= selStart) { - // Find out if photos should be deleted or not - int selStart = _trackInfo.getSelection().getStart(); - int selEnd = _trackInfo.getSelection().getEnd(); - if (selStart >= 0 && selEnd >= selStart) + int numToDelete = selEnd - selStart + 1; + boolean[] deletePhotos = new boolean[numToDelete]; + Photo[] photosToDelete = new Photo[numToDelete]; + boolean deleteAll = false; + boolean deleteNone = false; + String[] questionOptions = {I18nManager.getText("button.yes"), I18nManager.getText("button.no"), + I18nManager.getText("button.yestoall"), I18nManager.getText("button.notoall"), + I18nManager.getText("button.cancel")}; + DataPoint point = null; + for (int i=0; i 1) { // Launch a dialog to let the user choose which tracks to load, then continue - new SelectTracksFunction(this, inFieldArray, inDataArray, inAltFormat, inSourceInfo, - inTrackNameList).begin(); + new SelectTracksFunction(this, loadedTrack, inSourceInfo, inTrackNameList).begin(); } else { // go directly to load @@ -747,9 +747,6 @@ public class App undo.setNumPhotosAudios(_trackInfo.getPhotoList().getNumPhotos(), _trackInfo.getAudioList().getNumAudios()); _undoStack.add(undo); _track.combine(inLoadedTrack); - // Add photos and audios (if any in loaded track) to list(s) - MediaHelper.addMediaFromTrack(_track, _trackInfo.getPhotoList(), Photo.class); - MediaHelper.addMediaFromTrack(_track, _trackInfo.getAudioList(), AudioFile.class); // set source information inSourceInfo.populatePointObjects(_track, inLoadedTrack.getNumPoints()); _trackInfo.getFileInfo().addSource(inSourceInfo); @@ -771,9 +768,6 @@ public class App _trackInfo.getFileInfo().replaceSource(inSourceInfo); _trackInfo.getPhotoList().removeCorrelatedPhotos(); _trackInfo.getAudioList().removeCorrelatedAudios(); - // Add photos and audios (if any in loaded track) to list(s) - MediaHelper.addMediaFromTrack(_track, _trackInfo.getPhotoList(), Photo.class); - MediaHelper.addMediaFromTrack(_track, _trackInfo.getAudioList(), AudioFile.class); } } else @@ -787,16 +781,18 @@ public class App _track.load(inLoadedTrack); inSourceInfo.populatePointObjects(_track, _track.getNumPoints()); _trackInfo.getFileInfo().addSource(inSourceInfo); - // Add photos and audios (if any in loaded track) to list(s) - MediaHelper.addMediaFromTrack(_track, _trackInfo.getPhotoList(), Photo.class); - MediaHelper.addMediaFromTrack(_track, _trackInfo.getAudioList(), AudioFile.class); } + // Update config before subscribers are told + boolean isRegularLoad = (inSourceInfo.getFileType() != FILE_TYPE.GPSBABEL); + Config.getRecentFileList().addFile(new RecentFile(inSourceInfo.getFile(), isRegularLoad)); UpdateMessageBroker.informSubscribers(); // Update status bar UpdateMessageBroker.informSubscribers(I18nManager.getText("confirm.loadfile") + " '" + inSourceInfo.getName() + "'"); // update menu _menuManager.informFileLoaded(); + // Remove busy lock + _busyLoading = false; // load next file if there's a queue loadNextFile(); } @@ -1034,4 +1030,9 @@ public class App { _sidebarController.toggle(); } + + /** @return true if App is currently busy with loading data */ + public boolean isBusyLoading() { + return _busyLoading; + } } diff --git a/tim/prune/FunctionLibrary.java b/tim/prune/FunctionLibrary.java index 93532b5..0830049 100644 --- a/tim/prune/FunctionLibrary.java +++ b/tim/prune/FunctionLibrary.java @@ -11,7 +11,8 @@ import tim.prune.function.gpsies.GetGpsiesFunction; import tim.prune.function.gpsies.UploadGpsiesFunction; import tim.prune.function.srtm.LookupSrtmFunction; import tim.prune.load.AudioLoader; -import tim.prune.load.GpsLoader; +import tim.prune.load.BabelLoadFromFile; +import tim.prune.load.BabelLoadFromGps; import tim.prune.save.GpsSaver; import tim.prune.save.GpxExporter; import tim.prune.save.KmlExporter; @@ -29,6 +30,7 @@ public abstract class FunctionLibrary public static SvgExporter FUNCTION_SVGEXPORT = null; public static GenericFunction FUNCTION_GPSLOAD = null; public static GenericFunction FUNCTION_GPSSAVE = null; + public static GenericFunction FUNCTION_IMPORTBABEL = null; public static GenericFunction FUNCTION_SAVECONFIG = null; public static GenericFunction FUNCTION_EDIT_WAYPOINT_NAME = null; public static RearrangeWaypointsFunction FUNCTION_REARRANGE_WAYPOINTS = null; @@ -88,8 +90,9 @@ public abstract class FunctionLibrary FUNCTION_KMLEXPORT = new KmlExporter(inApp); FUNCTION_POVEXPORT = new PovExporter(inApp); FUNCTION_SVGEXPORT = new SvgExporter(inApp); - FUNCTION_GPSLOAD = new GpsLoader(inApp); + FUNCTION_GPSLOAD = new BabelLoadFromGps(inApp); FUNCTION_GPSSAVE = new GpsSaver(inApp); + FUNCTION_IMPORTBABEL = new BabelLoadFromFile(inApp); FUNCTION_SAVECONFIG = new SaveConfig(inApp); FUNCTION_EDIT_WAYPOINT_NAME = new PointNameEditor(inApp); FUNCTION_REARRANGE_WAYPOINTS = new RearrangeWaypointsFunction(inApp); diff --git a/tim/prune/GpsPruner.java b/tim/prune/GpsPrune.java similarity index 93% rename from tim/prune/GpsPruner.java rename to tim/prune/GpsPrune.java index 0028093..41dac2b 100644 --- a/tim/prune/GpsPruner.java +++ b/tim/prune/GpsPrune.java @@ -26,23 +26,23 @@ import tim.prune.gui.map.MapCanvas; import tim.prune.gui.profile.ProfileChart; /** - * Prune is a tool to visualize, edit, convert and prune GPS data + * GpsPrune is a tool to visualize, edit, convert and prune GPS data * Please see the included readme.txt or http://activityworkshop.net - * This software is copyright activityworkshop.net 2006-2010 and made available through the Gnu GPL version 2. + * This software is copyright activityworkshop.net 2006-2011 and made available through the Gnu GPL version 2. * For license details please see the included license.txt. - * GpsPruner is the main entry point to the application, including initialisation and launch + * GpsPrune is the main entry point to the application, including initialisation and launch */ -public class GpsPruner +public class GpsPrune { /** Version number of application, used in about screen and for version check */ - public static final String VERSION_NUMBER = "12.1"; + public static final String VERSION_NUMBER = "13"; /** Build number, just used for about screen */ - public static final String BUILD_NUMBER = "224"; + public static final String BUILD_NUMBER = "240"; /** Static reference to App object */ private static App APP = null; /** Program name, used for Frame title and for Macs also on the system bar */ - private static final String PROGRAM_NAME = "Prune"; + private static final String PROGRAM_NAME = "GpsPrune"; /** @@ -200,7 +200,7 @@ public class GpsPruner UpdateMessageBroker.addSubscriber(profileDisp); StatusBar statusBar = new StatusBar(); UpdateMessageBroker.addSubscriber(statusBar); - UpdateMessageBroker.informSubscribers("Prune v" + VERSION_NUMBER); + UpdateMessageBroker.informSubscribers("GpsPrune v" + VERSION_NUMBER); // Arrange in the frame using split panes JSplitPane midSplit = new JSplitPane(JSplitPane.VERTICAL_SPLIT, mapDisp, profileDisp); @@ -235,6 +235,8 @@ public class GpsPruner frame.setVisible(true); // Set position of map/profile splitter midSplit.setDividerLocation(0.75); + // Update menu (only needed for recent file list) + UpdateMessageBroker.informSubscribers(); // Make a full screen toggler SidebarController fsc = new SidebarController(new Component[] {leftPanel, profileDisp, rightPanel}, diff --git a/tim/prune/config/ColourScheme.java b/tim/prune/config/ColourScheme.java index 5f3e0cd..babe9e1 100644 --- a/tim/prune/config/ColourScheme.java +++ b/tim/prune/config/ColourScheme.java @@ -3,7 +3,7 @@ package tim.prune.config; import java.awt.Color; /** - * Class to hold a colour scheme for Prune, including + * Class to hold a colour scheme for GpsPrune, including * colours for background, points, selections and texts */ public class ColourScheme diff --git a/tim/prune/config/Config.java b/tim/prune/config/Config.java index 0873b0f..412f408 100644 --- a/tim/prune/config/Config.java +++ b/tim/prune/config/Config.java @@ -4,6 +4,8 @@ import java.io.File; import java.io.FileInputStream; import java.util.Properties; +import tim.prune.data.RecentFileList; + /** * Abstract class to hold application-wide configuration @@ -17,9 +19,12 @@ public abstract class Config private static Properties _configValues = new Properties(); /** Colour scheme object is also part of config */ private static ColourScheme _colourScheme = new ColourScheme(); + /** Recently-used file list */ + private static RecentFileList _recentFiles = new RecentFileList(); /** Default config file */ - private static final File DEFAULT_CONFIG_FILE = new File(".pruneconfig"); + public static final File DEFAULT_CONFIG_FILE = new File(".pruneconfig"); + public static final File HOME_CONFIG_FILE = new File(System.getProperty("user.home"), ".pruneconfig"); /** Key for track directory */ public static final String KEY_TRACK_DIR = "prune.trackdirectory"; @@ -63,6 +68,10 @@ public abstract class Config public static final String KEY_LINE_WIDTH = "prune.linewidth"; /** Key for kml track colour */ public static final String KEY_KML_TRACK_COLOUR = "prune.kmltrackcolour"; + /** Key for autosaving settings */ + public static final String KEY_AUTOSAVE_SETTINGS = "prune.autosavesettings"; + /** Key for recently used files */ + public static final String KEY_RECENT_FILES = "prune.recentfiles"; /** @@ -70,11 +79,21 @@ public abstract class Config */ public static void loadDefaultFile() { - try + if (DEFAULT_CONFIG_FILE.exists()) + { + try { + loadFile(DEFAULT_CONFIG_FILE); + return; + } + catch (ConfigException ce) {} // ignore + } + if (HOME_CONFIG_FILE.exists()) { - loadFile(DEFAULT_CONFIG_FILE); + try { + loadFile(HOME_CONFIG_FILE); + } + catch (ConfigException ce) {} // ignore } - catch (ConfigException ce) {} // ignore } @@ -107,6 +126,7 @@ public abstract class Config // Save all properties from file _configValues.putAll(props); _colourScheme.loadFromHex(_configValues.getProperty(KEY_COLOUR_SCHEME)); + _recentFiles = new RecentFileList(_configValues.getProperty(KEY_RECENT_FILES)); if (loadFailed) { throw new ConfigException(); } @@ -130,6 +150,7 @@ public abstract class Config props.put(KEY_GPSBABEL_PATH, "gpsbabel"); props.put(KEY_KMZ_IMAGE_WIDTH, "240"); props.put(KEY_KMZ_IMAGE_HEIGHT, "240"); + props.put(KEY_AUTOSAVE_SETTINGS, "0"); // autosave false by default return props; } @@ -158,6 +179,8 @@ public abstract class Config */ public static Properties getAllConfig() { + // Update recently-used files + _configValues.setProperty(KEY_RECENT_FILES, _recentFiles.getConfigString()); return _configValues; } @@ -169,6 +192,14 @@ public abstract class Config return _colourScheme; } + /** + * @return list of recently used files + */ + public static RecentFileList getRecentFileList() + { + return _recentFiles; + } + /** * Store the given configuration setting * @param inKey key (from constants) diff --git a/tim/prune/copyright.txt b/tim/prune/copyright.txt index c25b77e..d65d1dd 100644 --- a/tim/prune/copyright.txt +++ b/tim/prune/copyright.txt @@ -1,4 +1,4 @@ -The source code of Prune is copyright 2006-2010 activityworkshop.net +The source code of GpsPrune is copyright 2006-2011 activityworkshop.net and is distributed under the terms of the Gnu GPL version 2. Portions of the package jpeg.drew (if included in this package) were taken diff --git a/tim/prune/correlate/AudioCorrelator.java b/tim/prune/correlate/AudioCorrelator.java index 57ecb7f..432674e 100644 --- a/tim/prune/correlate/AudioCorrelator.java +++ b/tim/prune/correlate/AudioCorrelator.java @@ -11,17 +11,17 @@ import tim.prune.App; import tim.prune.DataSubscriber; import tim.prune.I18nManager; import tim.prune.UpdateMessageBroker; -import tim.prune.data.AudioFile; +import tim.prune.data.AudioClip; import tim.prune.data.AudioList; import tim.prune.data.DataPoint; -import tim.prune.data.MediaFile; +import tim.prune.data.MediaObject; import tim.prune.data.MediaList; import tim.prune.data.TimeDifference; import tim.prune.data.Timestamp; import tim.prune.undo.UndoCorrelateAudios; /** - * Class to manage the automatic correlation of audio files to points + * Class to manage the automatic correlation of audio clips to points * which is very similar to the PhotoCorrelator apart from the clip lengths */ public class AudioCorrelator extends Correlator @@ -92,7 +92,7 @@ public class AudioCorrelator extends Correlator { for (int i=0; i 0) {return true;} } return false; @@ -113,13 +113,13 @@ public class AudioCorrelator extends Correlator int numAudios = audios.getNumAudios(); for (int i=0; i inList) { + private AudioList(ArrayList inList) { super(inList); } @@ -28,37 +28,37 @@ public class AudioList extends MediaList public AudioList cloneList() { if (getNumMedia() == 0) return this; - ArrayList listCopy = new ArrayList(); + ArrayList listCopy = new ArrayList(); listCopy.addAll(_media); return new AudioList(listCopy); } /** - * @return the number of audio files in the list + * @return the number of audio clips in the list */ public int getNumAudios() { return getNumMedia(); } /** - * Add an audio file to the list + * Add an audio clip to the list * @param inAudio object to add */ - public void addAudio(AudioFile inAudio) { + public void addAudio(AudioClip inAudio) { addMedia(inAudio); } /** - * Add an audio file to the list + * Add an audio clip to the list * @param inAudio object to add * @param inIndex index at which to add */ - public void addAudio(AudioFile inAudio, int inIndex) { + public void addAudio(AudioClip inAudio, int inIndex) { addMedia(inAudio, inIndex); } /** - * Remove the selected audio file from the list + * Remove the selected audio clip from the list * @param inIndex index number to remove */ public void deleteAudio(int inIndex) { @@ -66,11 +66,11 @@ public class AudioList extends MediaList } /** - * Get the index of the given audio file + * Get the index of the given audio clip * @param inAudio object to check * @return index of this object in the list, or -1 if not found */ - public int getAudioIndex(AudioFile inAudio) { + public int getAudioIndex(AudioClip inAudio) { return getMediaIndex(inAudio); } @@ -79,8 +79,8 @@ public class AudioList extends MediaList * @param inIndex index number, starting at 0 * @return specified object */ - public AudioFile getAudio(int inIndex) { - return (AudioFile) getMedia(inIndex); + public AudioClip getAudio(int inIndex) { + return (AudioClip) getMedia(inIndex); } /** diff --git a/tim/prune/data/Coordinate.java b/tim/prune/data/Coordinate.java index 556bd89..40853eb 100644 --- a/tim/prune/data/Coordinate.java +++ b/tim/prune/data/Coordinate.java @@ -60,7 +60,7 @@ public abstract class Coordinate inString = inString.trim(); strLen = inString.length(); } - if (strLen > 1) + if (strLen > 0) { // Check for cardinal character either at beginning or end boolean hasCardinal = true; @@ -98,8 +98,11 @@ public abstract class Coordinate numFields++; denoms[numFields-1] = 1; } - fields[numFields-1] = fields[numFields-1] * 10 + (currChar - '0'); - denoms[numFields-1] *= 10; + if (denoms[numFields-1] < 1E18) // ignore trailing characters if too big for long + { + fields[numFields-1] = fields[numFields-1] * 10 + (currChar - '0'); + denoms[numFields-1] *= 10; + } } else { diff --git a/tim/prune/data/DataPoint.java b/tim/prune/data/DataPoint.java index e053e1a..3d17cbc 100644 --- a/tim/prune/data/DataPoint.java +++ b/tim/prune/data/DataPoint.java @@ -19,8 +19,8 @@ public class DataPoint private Timestamp _timestamp = null; /** Attached photo */ private Photo _photo = null; - /** Attached audio file */ - private AudioFile _audio = null; + /** Attached audio clip */ + private AudioClip _audio = null; private String _waypointName = null; private boolean _startOfSegment = false; private boolean _markedForDeletion = false; @@ -315,10 +315,10 @@ public class DataPoint } /** - * Set the audio file for this point + * Set the audio clip for this point * @param inAudio audio object */ - public void setAudio(AudioFile inAudio) { + public void setAudio(AudioClip inAudio) { _audio = inAudio; _modifyCount++; } @@ -326,23 +326,23 @@ public class DataPoint /** * @return associated audio object */ - public AudioFile getAudio() { + public AudioClip getAudio() { return _audio; } /** * Attach the given media object according to type - * @param inMedia either a photo or an audio file + * @param inMedia either a photo or an audio clip */ - public void attachMedia(MediaFile inMedia) + public void attachMedia(MediaObject inMedia) { if (inMedia != null) { if (inMedia instanceof Photo) { setPhoto((Photo) inMedia); inMedia.setDataPoint(this); } - else if (inMedia instanceof AudioFile) { - setAudio((AudioFile) inMedia); + else if (inMedia instanceof AudioClip) { + setAudio((AudioClip) inMedia); inMedia.setDataPoint(this); } } diff --git a/tim/prune/data/Field.java b/tim/prune/data/Field.java index fa4600d..6d87704 100644 --- a/tim/prune/data/Field.java +++ b/tim/prune/data/Field.java @@ -17,12 +17,13 @@ public class Field public static final Field TIMESTAMP = new Field("fieldname.timestamp", true); public static final Field WAYPT_NAME = new Field("fieldname.waypointname", true); public static final Field WAYPT_TYPE = new Field("fieldname.waypointtype", true); + public static final Field DESCRIPTION = new Field("fieldname.description", true); public static final Field NEW_SEGMENT = new Field("fieldname.newsegment", true); // 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, + LATITUDE, LONGITUDE, ALTITUDE, TIMESTAMP, WAYPT_NAME, WAYPT_TYPE, DESCRIPTION, NEW_SEGMENT, new Field(I18nManager.getText("fieldname.custom")) }; diff --git a/tim/prune/data/MediaList.java b/tim/prune/data/MediaList.java index 3fc87fe..d7b4780 100644 --- a/tim/prune/data/MediaList.java +++ b/tim/prune/data/MediaList.java @@ -7,8 +7,8 @@ import java.util.ArrayList; */ public abstract class MediaList { - /** list of media file objects */ - protected ArrayList _media = null; + /** list of media objects */ + protected ArrayList _media = null; /** @@ -22,11 +22,11 @@ public abstract class MediaList * Constructor * @param inList ArrayList containing media objects */ - protected MediaList(ArrayList inList) + protected MediaList(ArrayList inList) { _media = inList; if (_media == null) { - _media = new ArrayList(); + _media = new ArrayList(); } } @@ -41,7 +41,7 @@ public abstract class MediaList * Add an object to the list * @param inObject object to add */ - public void addMedia(MediaFile inObject) + public void addMedia(MediaObject inObject) { if (inObject != null) { _media.add(inObject); @@ -53,7 +53,7 @@ public abstract class MediaList * @param inObject object to add * @param inIndex index at which to add */ - public void addMedia(MediaFile inObject, int inIndex) + public void addMedia(MediaObject inObject, int inIndex) { if (inObject != null) { _media.add(inIndex, inObject); @@ -77,7 +77,7 @@ public abstract class MediaList * @param inMedia media object to check * @return true if it's already in the list */ - public boolean contains(MediaFile inMedia) { + public boolean contains(MediaObject inMedia) { return (getMediaIndex(inMedia) > -1); } @@ -87,16 +87,16 @@ public abstract class MediaList * @param inMedia object to check * @return index of this object in the list, or -1 if not found */ - public int getMediaIndex(MediaFile inMedia) + public int getMediaIndex(MediaObject inMedia) { // Check if we need to check final int num = getNumMedia(); - if (num <= 0 || inMedia == null || inMedia.getFile() == null) + if (num <= 0 || inMedia == null) return -1; // Loop over list for (int i=0; i= getNumMedia()) return null; return _media.get(inIndex); @@ -147,7 +147,7 @@ public abstract class MediaList final int num = getNumMedia(); String[] names = new String[num]; for (int i=0; i 0) { // Construct new list to copy into - ArrayList listCopy = new ArrayList(); + ArrayList listCopy = new ArrayList(); // Loop over list - for (MediaFile m : _media) + for (MediaObject m : _media) { // Copy media if it has no point if (m != null) @@ -206,6 +206,19 @@ public abstract class MediaList } } + /** + * @return true if any of the media objects have Files + */ + public boolean hasMediaWithFile() + { + for (MediaObject m: _media) { + if (m.getFile() != null) { + return true; + } + } + return false; + } + /** * @return clone of list contents */ diff --git a/tim/prune/data/MediaFile.java b/tim/prune/data/MediaObject.java similarity index 56% rename from tim/prune/data/MediaFile.java rename to tim/prune/data/MediaObject.java index d860db8..e028f4a 100644 --- a/tim/prune/data/MediaFile.java +++ b/tim/prune/data/MediaObject.java @@ -3,13 +3,19 @@ package tim.prune.data; import java.io.File; /** - * Class to represent a general media file for correlation. - * Subclasses are currently Photo and AudioFile + * Class to represent a general media object for correlation. + * Subclasses are currently Photo and AudioClip */ -public abstract class MediaFile +public abstract class MediaObject { - /** File where media is stored */ + /** File where media is stored (if any) */ protected File _file = null; + /** Name of file */ + protected String _name = null; + /** Cached data if downloaded */ + protected byte[] _data = null; + /** URL if media came from net */ + protected String _url = null; /** Timestamp, if any */ protected Timestamp _timestamp = null; /** Associated DataPoint if correlated */ @@ -20,7 +26,8 @@ public abstract class MediaFile private Status _currentStatus = Status.NOT_CONNECTED; /** Connection status */ - public enum Status { + public enum Status + { /** Media is not connected to any point */ NOT_CONNECTED, /** Media has been connected to a point since it was loaded */ @@ -35,12 +42,29 @@ public abstract class MediaFile * @param inFile file object * @param inStamp timestamp object */ - public MediaFile(File inFile, Timestamp inStamp) + public MediaObject(File inFile, Timestamp inStamp) { _file = inFile; + _name = inFile.getName(); + _data = null; _timestamp = inStamp; } + /** + * Constructor for byte arrays + * @param inData byte array containing data + * @param inName name of object + * @param inUrl source url of object or null + */ + public MediaObject(byte[] inData, String inName, String inUrl) + { + _file = null; + _data = inData; + _name = inName; + _url = inUrl; + _timestamp = null; + } + /** * @return the file object */ @@ -48,6 +72,11 @@ public abstract class MediaFile return _file; } + /** @return media name */ + public String getName() { + return _name; + } + /** * @return the timestamp object */ @@ -62,11 +91,27 @@ public abstract class MediaFile _timestamp = inTimestamp; } + /** + * @return byte data of media + */ + public byte[] getByteData() { + return _data; + } + + /** + * @return source Url (or null) + */ + public String getUrl() { + return _url; + } + /** * @return true if details are valid (might not have timestamp) */ - public boolean isValid() { - return _file != null && _file.exists() && _file.canRead(); + public boolean isValid() + { + return ((_file != null && _file.exists() && _file.canRead()) + || (_data != null && _data.length > 0)); } /** @@ -77,14 +122,21 @@ public abstract class MediaFile } /** - * Check if this object refers to the same File as another - * @param inOther other MediaFile object - * @return true if the Files are the same + * Check if this object refers to the same object as another + * @param inOther other MediaObject + * @return true if the objects are the same */ - public boolean equals(MediaFile inOther) + public boolean equals(MediaObject inOther) { - return (inOther != null && inOther.getFile() != null && getFile() != null - && inOther.getFile().equals(getFile())); + if (_file != null) + { + // compare file objects + return (inOther != null && inOther.getFile() != null && getFile() != null + && inOther.getFile().equals(getFile())); + } + // compare data arrays + return (inOther != null && _name != null && inOther._name != null && _name.equals(inOther._name) + && _data != null && inOther._data != null && _data.length == inOther._data.length); } /** @@ -143,7 +195,7 @@ public abstract class MediaFile } /** - * @return true if file is connected to a point + * @return true if this object is connected to a point */ public boolean isConnected() { @@ -151,7 +203,7 @@ public abstract class MediaFile } /** - * Reset any cached data held by the media file (eg thumbnail) + * Reset any cached data (eg thumbnail) */ public void resetCachedData() {} } diff --git a/tim/prune/data/Photo.java b/tim/prune/data/Photo.java index c904674..0c5d9e5 100644 --- a/tim/prune/data/Photo.java +++ b/tim/prune/data/Photo.java @@ -8,14 +8,16 @@ import javax.swing.ImageIcon; /** * Class to represent a photo and link to DataPoint */ -public class Photo extends MediaFile +public class Photo extends MediaObject { /** Size of original image */ private Dimension _size = null; /** rotation flag (clockwise from 0 to 3) */ private int _rotation = 0; // TODO: Need to store caption for image? - // thumbnail for image (from exif) + /** Bearing, if any */ + private double _bearing = -1.0; + /** thumbnail for image (from exif) */ private byte[] _exifThumbnail = null; /** @@ -27,12 +29,27 @@ public class Photo extends MediaFile super(inFile, null); } + /** + * Constructor using data, eg from zip file or URL + * @param inData data as byte array + * @param inName name of file from which it came + * @param inUrl url from which it came (or null) + */ + public Photo(byte[] inData, String inName, String inUrl) + { + super(inData, inName, inUrl); + } + /** * Calculate the size of the image (slow) */ private void calculateSize() { - ImageIcon icon = new ImageIcon(_file.getAbsolutePath()); + ImageIcon icon = null; + if (_file != null) + icon = new ImageIcon(_file.getAbsolutePath()); + else + icon = new ImageIcon(_data); int width = icon.getIconWidth(); int height = icon.getIconHeight(); if (width > 0 && height > 0) @@ -57,11 +74,7 @@ public class Photo extends MediaFile */ public int getWidth() { - if (_size == null) - { - calculateSize(); - if (_size == null) {return -1;} - } + if (getSize() == null) {return -1;} return _size.width; } @@ -70,11 +83,7 @@ public class Photo extends MediaFile */ public int getHeight() { - if (_size == null) - { - calculateSize(); - if (_size == null) {return -1;} - } + if (getSize() == null) {return -1;} return _size.height; } @@ -130,4 +139,30 @@ public class Photo extends MediaFile { return _rotation * 90; } + + /** + * @return a new image icon for the whole image + */ + public ImageIcon createImageIcon() + { + if (_file != null) { + return new ImageIcon(_file.getAbsolutePath()); + } + if (_data != null) { + return new ImageIcon(_data); + } + return null; + } + + /** + * @param inValue bearing in degrees, 0 to 360 + */ + public void setBearing(double inValue) { + _bearing = inValue; + } + + /** @return bearing in degrees */ + public double getBearing() { + return _bearing; + } } diff --git a/tim/prune/data/PhotoList.java b/tim/prune/data/PhotoList.java index 4540553..3281962 100644 --- a/tim/prune/data/PhotoList.java +++ b/tim/prune/data/PhotoList.java @@ -18,7 +18,7 @@ public class PhotoList extends MediaList * Constructor * @param inList ArrayList containing Photo objects */ - private PhotoList(ArrayList inList) { + private PhotoList(ArrayList inList) { super(inList); } @@ -28,7 +28,7 @@ public class PhotoList extends MediaList public PhotoList cloneList() { if (getNumMedia() == 0) return this; - ArrayList listCopy = new ArrayList(); + ArrayList listCopy = new ArrayList(); listCopy.addAll(_media); return new PhotoList(listCopy); } diff --git a/tim/prune/data/RecentFile.java b/tim/prune/data/RecentFile.java new file mode 100644 index 0000000..d13388d --- /dev/null +++ b/tim/prune/data/RecentFile.java @@ -0,0 +1,77 @@ +package tim.prune.data; + +import java.io.File; + +/** + * Simple class to represent an entry in the recently-used files list + */ +public class RecentFile +{ + private boolean _regularLoad = true; // false for load via gpsbabel + private File _file = null; + + /** + * Constructor + * @param inFile file + * @param inRegular true for regular load, false for gpsbabel load + */ + public RecentFile(File inFile, boolean inRegular) + { + _file = inFile; + _regularLoad = inRegular; + } + + /** + * Constructor + * @param inDesc String from config + */ + public RecentFile(String inDesc) + { + if (inDesc != null && inDesc.length() > 3) + { + _regularLoad = (inDesc.charAt(0) != 'g'); + _file = new File(inDesc.substring(1)); + } + } + + /** + * @return file object + */ + public File getFile() { + return _file; + } + + /** + * @return true for regular load, false for gpsbabel load + */ + public boolean isRegularLoad() { + return _regularLoad; + } + + /** + * @return true if file (still) exists + */ + public boolean isValid() { + return _file != null && _file.exists() && _file.isFile(); + } + + /** + * @return string to save in config + */ + public String getConfigString() + { + if (!isValid()) return ""; + return (_regularLoad?"r":"g") + _file.getAbsolutePath(); + } + + /** + * Check for equality + * @param inOther other RecentFile object + * @return true if they both refer to the same file + */ + public boolean isSameFile(RecentFile inOther) + { + return inOther != null && isValid() && inOther.isValid() + && _file.equals(inOther._file); + } +} diff --git a/tim/prune/data/RecentFileList.java b/tim/prune/data/RecentFileList.java new file mode 100644 index 0000000..ee8b84d --- /dev/null +++ b/tim/prune/data/RecentFileList.java @@ -0,0 +1,164 @@ +package tim.prune.data; + +/** + * Class to hold and manage the list of recently used files + */ +public class RecentFileList +{ + private RecentFile[] _files = null; + private static final int DEFAULT_SIZE = 6; + private static final int MAX_SIZE = 20; + + /** + * Default constructor + */ + public RecentFileList() + { + _files = new RecentFile[DEFAULT_SIZE]; + } + + /** + * Constructor + * @param inString String from config + */ + public RecentFileList(String inString) + { + _files = null; + int pos = 0; + if (inString != null && inString.length() > 0) + { + for (String s : inString.split(";")) + { + if (pos == 0) + { + int listSize = DEFAULT_SIZE; + try + { + listSize = Integer.parseInt(s); + if (listSize < 1 || listSize > MAX_SIZE) { + listSize = DEFAULT_SIZE; + } + } + catch (NumberFormatException nfe) {} + _files = new RecentFile[listSize]; + pos++; + } + else if (pos <= _files.length) + { + RecentFile rf = new RecentFile(s); + if (rf.isValid()) + { + _files[pos-1] = rf; + pos++; + } + } + } + } + if (_files == null) { + _files = new RecentFile[DEFAULT_SIZE]; + } + } + + /** + * @return size of list (may not have this many entries yet) + */ + public int getSize() + { + if (_files == null) return 0; + return _files.length; + } + + /** + * @return the number of valid entries in the list + */ + public int getNumEntries() + { + if (_files == null) return 0; + int numFound = 0; + for (RecentFile rf : _files) { + if (rf != null && rf.isValid()) + numFound++; + } + return numFound; + } + + /** + * @return string to save in config + */ + public String getConfigString() + { + StringBuilder builder = new StringBuilder(100); + int size = getSize(); + builder.append("" + size); + for (RecentFile f : _files) + { + builder.append(';'); + if (f != null) builder.append(f.getConfigString()); + } + return builder.toString(); + } + + /** + * Add the given file to the top of the list + * @param inRF file to add + */ + public void addFile(RecentFile inRF) + { + // Build a new array with the latest file at the top + RecentFile[] files = new RecentFile[_files.length]; + int rfIndex = 0; + if (inRF != null && inRF.isValid()) + { + files[rfIndex] = inRF; + rfIndex++; + } + // Loop, copying the other files + for (RecentFile rf : _files) + { + if (rf != null && rf.isValid() && (inRF==null || !rf.isSameFile(inRF))) + { + files[rfIndex] = rf; + rfIndex++; + if (rfIndex >= files.length) break; + } + } + _files = files; + } + + /** + * Verify all the entries and remove the invalid ones + */ + public void verifyAll() { + addFile(null); + } + + /** + * Get the RecentFile object at the given index + * @param inIndex index, starting at 0 + * @return RecentFile object or null if out of range + */ + public RecentFile getFile(int inIndex) + { + if (inIndex < 0 || inIndex >= _files.length) return null; + return _files[inIndex]; + } + + /** + * Resize the list to the new size + * @param inNewSize new size of list + */ + public void resizeList(int inNewSize) + { + // don't do anything if size doesn't make sense + if (inNewSize > 0 && inNewSize <= MAX_SIZE) + { + RecentFile[] files = new RecentFile[inNewSize]; + int numToCopy = _files.length; + if (inNewSize < numToCopy) { + numToCopy = inNewSize; + } + System.arraycopy(_files, 0, files, 0, numToCopy); + _files = files; + } + } +} diff --git a/tim/prune/data/SourceInfo.java b/tim/prune/data/SourceInfo.java index 341bf02..e78d575 100644 --- a/tim/prune/data/SourceInfo.java +++ b/tim/prune/data/SourceInfo.java @@ -125,6 +125,7 @@ public class SourceInfo for (int i=0; i<_points.length && (idx < 0); i++) { if (_points[i] == inPoint) {idx = i;} } + if (idx == -1) {return idx;} // point not found if (_pointIndices == null) {return idx;} // All points loaded return _pointIndices[idx]; // use point index mapping } diff --git a/tim/prune/data/Track.java b/tim/prune/data/Track.java index fa1be1e..fc65959 100644 --- a/tim/prune/data/Track.java +++ b/tim/prune/data/Track.java @@ -46,6 +46,19 @@ public class Track _scaled = false; } + /** + * Constructor using fields and points from another Track + * @param inFieldList Field list from another Track object + * @param inPoints (edited) point array + */ + public Track(FieldList inFieldList, DataPoint[] inPoints) + { + _masterFieldList = inFieldList; + _dataPoints = inPoints; + if (_dataPoints == null) _dataPoints = new DataPoint[0]; + _numPoints = _dataPoints.length; + _scaled = false; + } /** * Load method, for initialising and reinitialising data @@ -966,6 +979,7 @@ public class Track */ public DataPoint getPreviousTrackPoint(int inStartIndex) { + // end index is given as _numPoints but actually it just counts down to -1 return getNextTrackPoint(inStartIndex, _numPoints, false); } @@ -1178,4 +1192,18 @@ public class Track } return false; } + + /** + * @param inPoint point to check + * @return true if this track contains the given point + */ + public boolean containsPoint(DataPoint inPoint) + { + if (inPoint == null) return false; + for (int i=0; i < getNumPoints(); i++) + { + if (getPoint(i) == inPoint) return true; + } + return false; // not found + } } diff --git a/tim/prune/data/TrackInfo.java b/tim/prune/data/TrackInfo.java index 3df964b..5834414 100644 --- a/tim/prune/data/TrackInfo.java +++ b/tim/prune/data/TrackInfo.java @@ -92,10 +92,10 @@ public class TrackInfo } /** - * Get the currently selected audio file, if any - * @return AudioFile if selected, otherwise null + * Get the currently selected audio clip, if any + * @return AudioClip if selected, otherwise null */ - public AudioFile getCurrentAudio() { + public AudioClip getCurrentAudio() { return _audioList.getAudio(_selection.getCurrentAudioIndex()); } @@ -165,12 +165,12 @@ public class TrackInfo * @param inSet Set containing Audio objects * @return number of audio objects added */ - public int addAudios(Set inSet) + public int addAudios(Set inSet) { int numAudiosAdded = 0; if (inSet != null && !inSet.isEmpty()) { - for (AudioFile audio : inSet) + for (AudioClip audio : inSet) { if (audio != null && !_audioList.contains(audio)) { @@ -208,7 +208,6 @@ public class TrackInfo if (_track.deletePoint(_selection.getCurrentPointIndex())) { _selection.modifyPointDeleted(); - UpdateMessageBroker.informSubscribers(); return true; } return false; @@ -260,7 +259,7 @@ public class TrackInfo int audioIndex = _selection.getCurrentAudioIndex(); if (audioIndex >= 0) { - AudioFile audio = _audioList.getAudio(audioIndex); + AudioClip audio = _audioList.getAudio(audioIndex); _audioList.deleteAudio(audioIndex); // has it got a point? if (audio.getDataPoint() != null) @@ -374,6 +373,18 @@ public class TrackInfo selectPoint(_track.getPointIndex(inPoint)); } + /** + * Increment the selected point index by the given increment + * @param inPointIncrement +1 for next point, -1 for previous etc + */ + public void incrementPointIndex(int inPointIncrement) + { + int index = _selection.getCurrentPointIndex() + inPointIncrement; + if (index < 0) index = 0; + else if (index >= _track.getNumPoints()) index = _track.getNumPoints()-1; + selectPoint(index); + } + /** * Select the data point with the given index * @param inPointIndex index of DataPoint to select, or -1 for none @@ -400,7 +411,7 @@ public class TrackInfo audioIndex = _audioList.getAudioIndex(selectedPoint.getAudio()); } else if (audioIndex < 0 || _audioList.getAudio(audioIndex).isConnected()) { - // deselect current audio file + // deselect current audio clip audioIndex = -1; } // give to selection @@ -439,7 +450,7 @@ public class TrackInfo pointIndex = -1; } } - // Has the new point got an audio file? + // Has the new point got an audio clip? DataPoint selectedPoint = _track.getPoint(pointIndex); int audioIndex = _selection.getCurrentAudioIndex(); if (selectedPoint != null) { @@ -460,7 +471,7 @@ public class TrackInfo { if (_selection.getCurrentAudioIndex() == inAudioIndex) {return;} // Audio selection takes priority, deselecting point if necessary - AudioFile audio = _audioList.getAudio(inAudioIndex); + AudioClip audio = _audioList.getAudio(inAudioIndex); int pointIndex = _selection.getCurrentPointIndex(); DataPoint currPoint = getCurrentPoint(); if (audio != null) diff --git a/tim/prune/function/AboutScreen.java b/tim/prune/function/AboutScreen.java index d0e4d3c..c2dc3fe 100644 --- a/tim/prune/function/AboutScreen.java +++ b/tim/prune/function/AboutScreen.java @@ -32,7 +32,7 @@ import javax.swing.JTextArea; import tim.prune.App; import tim.prune.ExternalTools; import tim.prune.GenericFunction; -import tim.prune.GpsPruner; +import tim.prune.GpsPrune; import tim.prune.I18nManager; import tim.prune.jpeg.ExifGateway; import tim.prune.threedee.WindowFactory; @@ -81,14 +81,14 @@ public class AboutScreen extends GenericFunction JPanel aboutPanel = new JPanel(); aboutPanel.setLayout(new BoxLayout(aboutPanel, BoxLayout.Y_AXIS)); aboutPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - JLabel titleLabel = new JLabel("Prune"); + JLabel titleLabel = new JLabel("GpsPrune"); titleLabel.setFont(new Font("SansSerif", Font.BOLD, 24)); titleLabel.setAlignmentX(JLabel.CENTER_ALIGNMENT); aboutPanel.add(titleLabel); - JLabel versionLabel = new JLabel(I18nManager.getText("dialog.about.version") + ": " + GpsPruner.VERSION_NUMBER); + JLabel versionLabel = new JLabel(I18nManager.getText("dialog.about.version") + ": " + GpsPrune.VERSION_NUMBER); versionLabel.setAlignmentX(JLabel.CENTER_ALIGNMENT); aboutPanel.add(versionLabel); - JLabel buildLabel = new JLabel(I18nManager.getText("dialog.about.build") + ": " + GpsPruner.BUILD_NUMBER); + JLabel buildLabel = new JLabel(I18nManager.getText("dialog.about.build") + ": " + GpsPrune.BUILD_NUMBER); buildLabel.setAlignmentX(JLabel.CENTER_ALIGNMENT); aboutPanel.add(buildLabel); aboutPanel.add(new JLabel(" ")); @@ -99,7 +99,7 @@ public class AboutScreen extends GenericFunction descBuffer.append("

").append(I18nManager.getText("dialog.about.languages")).append(" : ") .append("\u010de\u0161tina, deutsch, english, espa\u00F1ol, fran\u00E7ais, italiano, magyar,
" + " nederlands, polski, portugu\u00EAs, \u4e2d\u6587 (chinese), \u65E5\u672C\u8A9E (japanese), \uD55C\uAD6D\uC5B4/\uC870\uC120\uB9D0 (korean),
" + - " schwiizerd\u00FC\u00FCtsch, t\u00FCrk\u00E7e, rom\u00E2n\u0103, afrikaans, bahasa indonesia, farsi

"); + " schwiizerd\u00FC\u00FCtsch, t\u00FCrk\u00E7e, rom\u00E2n\u0103, afrikaans, bahasa indonesia

"); 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)); diff --git a/tim/prune/function/AsyncMediaLoader.java b/tim/prune/function/AsyncMediaLoader.java new file mode 100644 index 0000000..0365125 --- /dev/null +++ b/tim/prune/function/AsyncMediaLoader.java @@ -0,0 +1,158 @@ +package tim.prune.function; + +import java.io.File; + +import tim.prune.App; +import tim.prune.DataSubscriber; +import tim.prune.GenericFunction; +import tim.prune.I18nManager; +import tim.prune.UpdateMessageBroker; +import tim.prune.data.AudioClip; +import tim.prune.data.MediaObject; +import tim.prune.data.Photo; +import tim.prune.data.Track; +import tim.prune.load.MediaHelper; +import tim.prune.load.MediaLoadProgressDialog; +import tim.prune.undo.UndoLoadAudios; +import tim.prune.undo.UndoLoadPhotos; + +/** + * Function to load media asynchronously, + * either from inside a zip/kmz file or remotely + */ +public class AsyncMediaLoader extends GenericFunction +implements Runnable, Cancellable +{ + /** Archive from which points were loaded */ + private File _zipFile = null; + /** Array of links */ + private String[] _linkArray = null; + /** Track to use for connecting */ + private Track _track = null; + /** Cancelled flag */ + private boolean _cancelled = false; + + + /** + * Constructor + * @param inApp App object + * @param inLinkArray array of links + * @param inTrack Track object for connecting points + */ + public AsyncMediaLoader(App inApp, File inZipFile, String[] inLinkArray, Track inTrack) + { + super(inApp); + _zipFile = inZipFile; + _linkArray = inLinkArray; + _track = inTrack; + } + + /** + * Begin the load + */ + public void begin() + { + _cancelled = false; + if (_linkArray != null) + new Thread(this).start(); + } + + /** Cancel */ + public void cancel() { + _cancelled = true; + } + + /** + * @return the name key + */ + public String getNameKey() { + return "function.asyncmediaload"; + } + + /** + * Execute the load in a separate thread + */ + public void run() + { + // Count links first so that progress bar can be shown + int numLinks = 0; + for (int i=0; i<_linkArray.length; i++) { + if (_linkArray[i] != null) { + numLinks++; + } + } + if (numLinks <= 0) return; + // Make progress dialog + MediaLoadProgressDialog progressDialog = new MediaLoadProgressDialog(_app.getFrame(), this); + // Make array to store results + MediaObject[] media = new MediaObject[numLinks]; + int currLink = 0; + for (int i=0; i<_linkArray.length && !_cancelled; i++) + { + if (_linkArray[i] != null) + { + MediaObject mf = MediaHelper.createMediaObject(_zipFile, _linkArray[i]); + if (mf != null) + { + // attach media to point and set status + _track.getPoint(i).attachMedia(mf); + mf.setOriginalStatus(MediaObject.Status.TAGGED); + mf.setCurrentStatus(MediaObject.Status.TAGGED); + media[currLink] = mf; + // update progress + if (!_app.isBusyLoading()) + progressDialog.showProgress(currLink, numLinks); + currLink++; + } + try {Thread.sleep(100);} catch (InterruptedException ie) {} + } + } + progressDialog.close(); + + // Wait until App is ready to receive media (may have to ask about append/replace etc) + waitUntilAppReady(); + + // Go through the loaded media and check if the points are still in the track + int numPhotos = 0, numAudios = 0; + for (currLink=0; currLink 0) { + _app.completeFunction(new UndoLoadPhotos(numPhotos, 0), "" + numPhotos + " " + + I18nManager.getText(numPhotos == 1?"confirm.jpegload.single":"confirm.jpegload.multi")); + } + if (numAudios > 0) { + _app.completeFunction(new UndoLoadAudios(numAudios), I18nManager.getText("confirm.audioload")); + } + UpdateMessageBroker.informSubscribers(DataSubscriber.DATA_ADDED_OR_REMOVED); + } + + + /** + * Wait until the App is ready + */ + private void waitUntilAppReady() + { + long waitInterval = 500; // milliseconds + while (_app.isBusyLoading()) + { + try {Thread.sleep(waitInterval);} catch (InterruptedException ie) {} + waitInterval *= 1.2; + } + } +} diff --git a/tim/prune/function/Cancellable.java b/tim/prune/function/Cancellable.java new file mode 100644 index 0000000..ad51474 --- /dev/null +++ b/tim/prune/function/Cancellable.java @@ -0,0 +1,12 @@ +package tim.prune.function; + +/** + * Interface implemented by functions which can be cancelled + */ +public interface Cancellable +{ + /** + * Cancel the function + */ + public void cancel(); +} diff --git a/tim/prune/function/CheckVersionScreen.java b/tim/prune/function/CheckVersionScreen.java index a34319f..1d3192a 100644 --- a/tim/prune/function/CheckVersionScreen.java +++ b/tim/prune/function/CheckVersionScreen.java @@ -11,12 +11,12 @@ import javax.swing.JOptionPane; import tim.prune.App; import tim.prune.GenericFunction; -import tim.prune.GpsPruner; +import tim.prune.GpsPrune; import tim.prune.I18nManager; import tim.prune.function.browser.BrowserLauncher; /** - * Class to check the version of Prune + * Class to check the version of GpsPrune * and show an appropriate dialog */ public class CheckVersionScreen extends GenericFunction @@ -42,7 +42,7 @@ public class CheckVersionScreen extends GenericFunction */ public void begin() { - final String filePathStart = "http://activityworkshop.net/software/prune/prune_versioncheck_"; + final String filePathStart = "http://activityworkshop.net/software/gpsprune/gpsprune_versioncheck_"; final String filePathEnd = ".txt"; String latestVer = null; String nextVersion = null; @@ -51,7 +51,7 @@ public class CheckVersionScreen extends GenericFunction try { // Load properties from the url on the server - InputStream inStream = new URL(filePathStart + GpsPruner.VERSION_NUMBER + filePathEnd).openStream(); + InputStream inStream = new URL(filePathStart + GpsPrune.VERSION_NUMBER + filePathEnd).openStream(); props.load(inStream); // Extract the three fields we want, ignore others @@ -68,7 +68,7 @@ public class CheckVersionScreen extends GenericFunction JOptionPane.showMessageDialog(_parentFrame, I18nManager.getText("dialog.checkversion.error"), I18nManager.getText(getNameKey()), JOptionPane.ERROR_MESSAGE); } - else if (latestVer.equals(GpsPruner.VERSION_NUMBER)) + else if (latestVer.equals(GpsPrune.VERSION_NUMBER)) { // Version on the server is the same as this one String displayMessage = I18nManager.getText("dialog.checkversion.uptodate"); @@ -106,7 +106,7 @@ public class CheckVersionScreen extends GenericFunction == JOptionPane.YES_OPTION) { // User selected to launch home page - BrowserLauncher.launchBrowser("http://activityworkshop.net/software/prune/download.html"); + BrowserLauncher.launchBrowser("http://activityworkshop.net/software/gpsprune/download.html"); } } } diff --git a/tim/prune/function/ConnectToPointFunction.java b/tim/prune/function/ConnectToPointFunction.java index fa6f30b..0998020 100644 --- a/tim/prune/function/ConnectToPointFunction.java +++ b/tim/prune/function/ConnectToPointFunction.java @@ -5,14 +5,14 @@ import tim.prune.DataSubscriber; import tim.prune.GenericFunction; import tim.prune.I18nManager; import tim.prune.UpdateMessageBroker; -import tim.prune.data.AudioFile; +import tim.prune.data.AudioClip; import tim.prune.data.DataPoint; import tim.prune.data.Photo; import tim.prune.undo.UndoConnectMedia; import tim.prune.undo.UndoOperation; /** - * Function to connect either a photo or an audio file to the current point + * Function to connect either a photo or an audio clip to the current point */ public class ConnectToPointFunction extends GenericFunction { @@ -38,7 +38,7 @@ public class ConnectToPointFunction extends GenericFunction { Photo photo = _app.getTrackInfo().getCurrentPhoto(); DataPoint point = _app.getTrackInfo().getCurrentPoint(); - AudioFile audio = _app.getTrackInfo().getCurrentAudio(); + AudioClip audio = _app.getTrackInfo().getCurrentAudio(); boolean connectPhoto = (point != null && photo != null && point.getPhoto() == null); boolean connectAudio = (point != null && audio != null && point.getAudio() == null); @@ -46,8 +46,8 @@ public class ConnectToPointFunction extends GenericFunction // TODO: Let user choose whether to connect photo/audio or both } // Make undo object - UndoOperation undo = new UndoConnectMedia(point, connectPhoto?photo.getFile().getName():null, - connectAudio?audio.getFile().getName():null); + UndoOperation undo = new UndoConnectMedia(point, connectPhoto?photo.getName():null, + connectAudio?audio.getName():null); // Connect the media if (connectPhoto) { photo.setDataPoint(point); diff --git a/tim/prune/function/DisconnectAudioFunction.java b/tim/prune/function/DisconnectAudioFunction.java index abcd9c4..962da71 100644 --- a/tim/prune/function/DisconnectAudioFunction.java +++ b/tim/prune/function/DisconnectAudioFunction.java @@ -5,7 +5,7 @@ import tim.prune.DataSubscriber; import tim.prune.GenericFunction; import tim.prune.I18nManager; import tim.prune.UpdateMessageBroker; -import tim.prune.data.AudioFile; +import tim.prune.data.AudioClip; import tim.prune.data.DataPoint; import tim.prune.undo.UndoDisconnectMedia; import tim.prune.undo.UndoOperation; @@ -33,11 +33,11 @@ public class DisconnectAudioFunction extends GenericFunction */ public void begin() { - AudioFile audio = _app.getTrackInfo().getCurrentAudio(); + AudioClip audio = _app.getTrackInfo().getCurrentAudio(); if (audio != null && audio.getDataPoint() != null) { DataPoint point = audio.getDataPoint(); - UndoOperation undo = new UndoDisconnectMedia(point, false, true, audio.getFile().getName()); + UndoOperation undo = new UndoDisconnectMedia(point, false, true, audio.getName()); // disconnect audio.setDataPoint(null); point.setAudio(null); diff --git a/tim/prune/function/DisconnectPhotoFunction.java b/tim/prune/function/DisconnectPhotoFunction.java index 6223433..96e039d 100644 --- a/tim/prune/function/DisconnectPhotoFunction.java +++ b/tim/prune/function/DisconnectPhotoFunction.java @@ -36,7 +36,7 @@ public class DisconnectPhotoFunction extends GenericFunction if (photo != null && photo.getDataPoint() != null) { DataPoint point = photo.getDataPoint(); - UndoDisconnectMedia undo = new UndoDisconnectMedia(point, true, false, photo.getFile().getName()); + UndoDisconnectMedia undo = new UndoDisconnectMedia(point, true, false, photo.getName()); // disconnect photo.setDataPoint(null); point.setPhoto(null); diff --git a/tim/prune/function/DiskCacheConfig.java b/tim/prune/function/DiskCacheConfig.java index 58643d1..98a6405 100644 --- a/tim/prune/function/DiskCacheConfig.java +++ b/tim/prune/function/DiskCacheConfig.java @@ -24,6 +24,7 @@ import tim.prune.GenericFunction; import tim.prune.I18nManager; import tim.prune.UpdateMessageBroker; import tim.prune.config.Config; +import tim.prune.function.cache.ManageCacheFunction; /** * Class to show the popup window for setting the path to disk cache @@ -34,7 +35,7 @@ public class DiskCacheConfig extends GenericFunction private JCheckBox _cacheCheckbox = null; private JTextField _cacheDirBox = null; private JButton _browseButton = null; - private JButton _okButton = null; + private JButton _okButton = null, _manageButton = null; private boolean _initialCheckState = false; private String _initialCacheDir = null; @@ -67,7 +68,7 @@ public class DiskCacheConfig extends GenericFunction _cacheCheckbox = new JCheckBox(I18nManager.getText("dialog.diskcache.save")); _cacheCheckbox.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) { - enableOk(); + enableButtons(); } }); topPanel.add(_cacheCheckbox); @@ -75,12 +76,12 @@ public class DiskCacheConfig extends GenericFunction // dir panel JPanel dirPanel = new JPanel(); dirPanel.setLayout(new BorderLayout()); - dirPanel.add(new JLabel(I18nManager.getText("dialog.diskcache.dir")), BorderLayout.WEST); + dirPanel.add(new JLabel(I18nManager.getText("dialog.diskcache.dir") + " : "), BorderLayout.WEST); _cacheDirBox = new JTextField(24); _cacheDirBox.addKeyListener(new KeyAdapter() { public void keyReleased(KeyEvent arg0) { super.keyReleased(arg0); - enableOk(); + enableButtons(); } }); dirPanel.add(_cacheDirBox, BorderLayout.CENTER); @@ -91,20 +92,23 @@ public class DiskCacheConfig extends GenericFunction } }); dirPanel.add(_browseButton, BorderLayout.EAST); - dialogPanel.add(dirPanel, BorderLayout.CENTER); + // holder panel so it doesn't expand vertically + JPanel dirHolderPanel = new JPanel(); + dirHolderPanel.setLayout(new BorderLayout()); + dirHolderPanel.add(dirPanel, BorderLayout.NORTH); + dialogPanel.add(dirHolderPanel, BorderLayout.CENTER); - // Cancel button at the bottom - JPanel buttonPanel = new JPanel(); - buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT)); + // OK, Cancel buttons at the bottom right + JPanel buttonPanelr = new JPanel(); + buttonPanelr.setLayout(new FlowLayout(FlowLayout.RIGHT)); _okButton = new JButton(I18nManager.getText("button.ok")); - _okButton.addActionListener(new ActionListener() - { + _okButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { finish(); } }); - buttonPanel.add(_okButton); + buttonPanelr.add(_okButton); JButton cancelButton = new JButton(I18nManager.getText("button.cancel")); cancelButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) @@ -112,17 +116,36 @@ public class DiskCacheConfig extends GenericFunction _dialog.dispose(); } }); - buttonPanel.add(cancelButton); + buttonPanelr.add(cancelButton); + + // Manage button at the bottom left + JPanel buttonPanell = new JPanel(); + buttonPanell.setLayout(new FlowLayout(FlowLayout.LEFT)); + _manageButton = new JButton(I18nManager.getText("button.manage")); + _manageButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) + { + finish(); + new ManageCacheFunction(_app).begin(); + } + }); + buttonPanell.add(_manageButton); + // Put them together + JPanel buttonPanel = new JPanel(); + buttonPanel.setLayout(new BorderLayout()); + buttonPanel.add(buttonPanelr, BorderLayout.EAST); + buttonPanel.add(buttonPanell, BorderLayout.WEST); dialogPanel.add(buttonPanel, BorderLayout.SOUTH); return dialogPanel; } /** - * Enable or disable the ok button according to what's changed + * Enable or disable the buttons according to what's changed */ - private void enableOk() + private void enableButtons() { - boolean checkState = _cacheCheckbox.isSelected(); + final boolean checkState = _cacheCheckbox.isSelected(); + final String path = _cacheDirBox.getText(); _cacheDirBox.setEditable(checkState); _browseButton.setEnabled(checkState); boolean ok = false; @@ -131,9 +154,9 @@ public class DiskCacheConfig extends GenericFunction else { // If checkbox has been switched off then enable if (!checkState) {ok = true;} - else { + else + { // checkbox is on, check value - String path = _cacheDirBox.getText(); if (path.equals("") || (_initialCacheDir != null && path.equals(_initialCacheDir))) { // Value blank or same as before ok = false; @@ -144,6 +167,14 @@ public class DiskCacheConfig extends GenericFunction } } _okButton.setEnabled(ok); + // Manage button needs a valid cache + boolean cacheDirGood = false; + if (checkState && !path.equals("")) + { + File dir = new File(path); + cacheDirGood = dir.exists() && dir.canRead() && dir.isDirectory(); + } + _manageButton.setEnabled(cacheDirGood); } /** @@ -162,7 +193,7 @@ public class DiskCacheConfig extends GenericFunction String currPath = Config.getConfigString(Config.KEY_DISK_CACHE); _cacheCheckbox.setSelected(currPath != null); _cacheDirBox.setText(currPath==null?"":currPath); - enableOk(); + enableButtons(); // Remember current state _initialCheckState = _cacheCheckbox.isSelected(); _dialog.setVisible(true); @@ -182,7 +213,7 @@ public class DiskCacheConfig extends GenericFunction { _cacheDirBox.setText(chooser.getSelectedFile().getAbsolutePath()); } - enableOk(); + enableButtons(); } /** diff --git a/tim/prune/function/DownloadOsmFunction.java b/tim/prune/function/DownloadOsmFunction.java index bef09ad..e3d3627 100644 --- a/tim/prune/function/DownloadOsmFunction.java +++ b/tim/prune/function/DownloadOsmFunction.java @@ -243,7 +243,7 @@ public class DownloadOsmFunction extends GenericFunction implements Runnable */ public void run() { - final String url = "http://www.informationfreeway.org/api/0.6/map?bbox=" + + final String url = "http://xapi.openstreetmap.org/api/0.6/map?bbox=" + _latLonLabels[1].getText() + "," + _latLonLabels[3].getText() + "," + _latLonLabels[2].getText() + "," + _latLonLabels[0].getText(); @@ -263,8 +263,7 @@ public class DownloadOsmFunction extends GenericFunction implements Runnable } catch (MalformedURLException mue) {} catch (IOException ioe) { - // TODO: throw exception or show dialog - System.out.println("Exception: " + ioe.getClass().getName()); + _app.showErrorMessageNoLookup(getNameKey(), ioe.getClass().getName() + " - " + ioe.getMessage()); } // clean up streams finally { diff --git a/tim/prune/function/GetWikipediaFunction.java b/tim/prune/function/GetWikipediaFunction.java index acef09c..dc2da5b 100644 --- a/tim/prune/function/GetWikipediaFunction.java +++ b/tim/prune/function/GetWikipediaFunction.java @@ -26,6 +26,8 @@ public class GetWikipediaFunction extends GenericDownloaderFunction private static final int MAX_RESULTS = 20; /** Maximum distance from point in km */ private static final int MAX_DISTANCE = 15; + /** Username to use for geonames queries */ + private static final String GEONAMES_USERNAME = "gpsprune"; /** @@ -77,10 +79,11 @@ public class GetWikipediaFunction extends GenericDownloaderFunction String descMessage = ""; InputStream inStream = null; - // Example http://ws.geonames.org/findNearbyWikipedia?lat=47&lng=9 - String urlString = "http://ws.geonames.org/findNearbyWikipedia?lat=" + + // Example http://api.geonames.org/findNearbyWikipedia?lat=47&lng=9 + String urlString = "http://api.geonames.org/findNearbyWikipedia?lat=" + lat + "&lng=" + lon + "&maxRows=" + MAX_RESULTS - + "&radius=" + MAX_DISTANCE + "&lang=" + I18nManager.getText("wikipedia.lang"); + + "&radius=" + MAX_DISTANCE + "&lang=" + I18nManager.getText("wikipedia.lang") + + "&username=" + GEONAMES_USERNAME; // Parse the returned XML with a special handler GetWikipediaXmlHandler xmlHandler = new GetWikipediaXmlHandler(); try @@ -106,8 +109,16 @@ public class GetWikipediaFunction extends GenericDownloaderFunction descMessage = I18nManager.getText("dialog.gpsies.nonefound"); } _statusLabel.setText(descMessage); + // Show error message if any + if (trackList == null || trackList.size() == 0) { + String error = xmlHandler.getErrorMessage(); + if (error != null && !error.equals("")) { + _app.showErrorMessageNoLookup(getNameKey(), error); + } + } } + /** * Load the selected track or point */ diff --git a/tim/prune/function/GetWikipediaXmlHandler.java b/tim/prune/function/GetWikipediaXmlHandler.java index 3cca682..d9a3b74 100644 --- a/tim/prune/function/GetWikipediaXmlHandler.java +++ b/tim/prune/function/GetWikipediaXmlHandler.java @@ -17,6 +17,7 @@ public class GetWikipediaXmlHandler extends DefaultHandler private ArrayList _trackList = null; private GpsiesTrack _track = null; private String _lat = null, _lon = null; + private String _errorMessage = null; /** @@ -33,6 +34,9 @@ public class GetWikipediaXmlHandler extends DefaultHandler _lat = null; _lon = null; } + else if (inTagName.equals("status")) { + _errorMessage = inAttributes.getValue("message"); + } else _value = null; super.startElement(inUri, inLocalName, inTagName, inAttributes); } @@ -90,4 +94,11 @@ public class GetWikipediaXmlHandler extends DefaultHandler { return _trackList; } + + /** + * @return error message, if any + */ + public String getErrorMessage() { + return _errorMessage; + } } diff --git a/tim/prune/function/HelpScreen.java b/tim/prune/function/HelpScreen.java index 53816dc..25fb8ec 100644 --- a/tim/prune/function/HelpScreen.java +++ b/tim/prune/function/HelpScreen.java @@ -41,7 +41,7 @@ public class HelpScreen extends GenericFunction == JOptionPane.YES_OPTION) { // User selected to launch home page - BrowserLauncher.launchBrowser("http://activityworkshop.net/software/prune/index.html"); + BrowserLauncher.launchBrowser("http://activityworkshop.net/software/gpsprune/index.html"); } } } diff --git a/tim/prune/function/PhotoPopupFunction.java b/tim/prune/function/PhotoPopupFunction.java index 6b8b3e0..1a81be1 100644 --- a/tim/prune/function/PhotoPopupFunction.java +++ b/tim/prune/function/PhotoPopupFunction.java @@ -71,8 +71,8 @@ public class PhotoPopupFunction extends GenericFunction { _frame.setVisible(false); Photo photo = _app.getTrackInfo().getCurrentPhoto(); - _frame.setTitle(photo.getFile().getName()); - _label.setText("'" + photo.getFile().getName() + "' (" + _frame.setTitle(photo.getName()); + _label.setText("'" + photo.getName() + "' (" + photo.getWidth() + " x " + photo.getHeight() + ")"); _photoThumb.setPhoto(photo); } diff --git a/tim/prune/function/PlayAudioFunction.java b/tim/prune/function/PlayAudioFunction.java index 7e7a34a..0e14d7c 100644 --- a/tim/prune/function/PlayAudioFunction.java +++ b/tim/prune/function/PlayAudioFunction.java @@ -1,5 +1,6 @@ package tim.prune.function; +import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; import javax.sound.sampled.AudioInputStream; @@ -8,9 +9,10 @@ import javax.sound.sampled.Clip; import tim.prune.App; import tim.prune.GenericFunction; +import tim.prune.data.AudioClip; /** - * Class to play the current audio file + * Class to play the current audio clip */ public class PlayAudioFunction extends GenericFunction implements Runnable { @@ -49,12 +51,13 @@ public class PlayAudioFunction extends GenericFunction implements Runnable */ public void run() { - File audioFile = _app.getTrackInfo().getCurrentAudio().getFile(); + AudioClip audio = _app.getTrackInfo().getCurrentAudio(); + File audioFile = audio.getFile(); boolean played = false; - if (audioFile.exists() && audioFile.isFile() && audioFile.canRead()) + if (audioFile != null && audioFile.exists() && audioFile.isFile() && audioFile.canRead()) { // First choice is to play using java - played = playClip(audioFile); + played = playClip(audio); // Second choice is to try the Desktop library from java 6, if available if (!played) { try { @@ -84,6 +87,10 @@ public class PlayAudioFunction extends GenericFunction implements Runnable } } } + else if (audioFile == null && audio.getByteData() != null) { + // Try to play audio clip using byte array (can't use Desktop or Runtime) + played = playClip(audio); + } if (!played) { // If still not worked, show error message @@ -93,16 +100,21 @@ public class PlayAudioFunction extends GenericFunction implements Runnable /** * Try to play the sound file using built-in java libraries + * @param inAudio audio clip to play * @return true if play was successful */ - private boolean playClip(File inFile) + private boolean playClip(AudioClip inClip) { boolean success = false; AudioInputStream audioInputStream = null; _clip = null; try { - audioInputStream = AudioSystem.getAudioInputStream(inFile); + if (inClip.getFile() != null) + audioInputStream = AudioSystem.getAudioInputStream(inClip.getFile()); + else if (inClip.getByteData() != null) + audioInputStream = AudioSystem.getAudioInputStream(new ByteArrayInputStream(inClip.getByteData())); + else return false; _clip = AudioSystem.getClip(); _clip.open(audioInputStream); // play the clip @@ -110,6 +122,7 @@ public class PlayAudioFunction extends GenericFunction implements Runnable _clip.drain(); success = true; } catch (Exception e) { + System.err.println(e.getClass().getName() + " - " + e.getMessage()); } finally { // close the stream to clean up try { diff --git a/tim/prune/function/RearrangePhotosFunction.java b/tim/prune/function/RearrangePhotosFunction.java index 7a408c0..b8d9312 100644 --- a/tim/prune/function/RearrangePhotosFunction.java +++ b/tim/prune/function/RearrangePhotosFunction.java @@ -194,17 +194,21 @@ public class RearrangePhotosFunction extends GenericFunction private static void sortPhotos(DataPoint[] inPhotos, boolean inSortByFile) { Comparator comparator = null; - if (inSortByFile) { + if (inSortByFile) + { // sort by filename comparator = new Comparator() { public int compare(DataPoint inP1, DataPoint inP2) { if (inP2 == null) return -1; // all nulls at end if (inP1 == null) return 1; + if (inP1.getPhoto().getFile() == null || inP2.getPhoto().getFile() == null) + return inP1.getPhoto().getName().compareTo(inP2.getPhoto().getName()); return inP1.getPhoto().getFile().compareTo(inP2.getPhoto().getFile()); } }; } - else { + else + { // sort by photo timestamp comparator = new Comparator() { public int compare(DataPoint inP1, DataPoint inP2) { diff --git a/tim/prune/function/RemoveAudioFunction.java b/tim/prune/function/RemoveAudioFunction.java index fa859be..c4aa720 100644 --- a/tim/prune/function/RemoveAudioFunction.java +++ b/tim/prune/function/RemoveAudioFunction.java @@ -5,11 +5,11 @@ import javax.swing.JOptionPane; import tim.prune.App; import tim.prune.GenericFunction; import tim.prune.I18nManager; -import tim.prune.data.AudioFile; +import tim.prune.data.AudioClip; import tim.prune.undo.UndoDeleteAudio; /** - * Function to remove the currently selected audio file + * Function to remove the currently selected audio clip */ public class RemoveAudioFunction extends GenericFunction { @@ -32,7 +32,7 @@ public class RemoveAudioFunction extends GenericFunction public void begin() { // Delete the current audio, and optionally its point too, keeping undo information - AudioFile currentAudio = _app.getTrackInfo().getCurrentAudio(); + AudioClip currentAudio = _app.getTrackInfo().getCurrentAudio(); if (currentAudio != null) { // Audio is selected, see if it has a point or not @@ -61,7 +61,7 @@ public class RemoveAudioFunction extends GenericFunction } // Add undo information to stack if necessary if (deleted) { - _app.completeFunction(undoAction, currentAudio.getFile().getName() + " " + I18nManager.getText("confirm.media.removed")); + _app.completeFunction(undoAction, currentAudio.getName() + " " + I18nManager.getText("confirm.media.removed")); } } } diff --git a/tim/prune/function/RemovePhotoFunction.java b/tim/prune/function/RemovePhotoFunction.java index b09ae10..8cdf7bc 100644 --- a/tim/prune/function/RemovePhotoFunction.java +++ b/tim/prune/function/RemovePhotoFunction.java @@ -62,7 +62,7 @@ public class RemovePhotoFunction extends GenericFunction } // Add undo information to stack if necessary if (photoDeleted) { - _app.completeFunction(undoAction, currentPhoto.getFile().getName() + " " + I18nManager.getText("confirm.media.removed")); + _app.completeFunction(undoAction, currentPhoto.getName() + " " + I18nManager.getText("confirm.media.removed")); } } } diff --git a/tim/prune/function/SaveConfig.java b/tim/prune/function/SaveConfig.java index 6c0e4d0..af7eb83 100644 --- a/tim/prune/function/SaveConfig.java +++ b/tim/prune/function/SaveConfig.java @@ -128,28 +128,46 @@ public class SaveConfig extends GenericFunction private void finish() { File configFile = Config.getConfigFile(); - if (configFile == null) {configFile = new File(".pruneconfig");} + if (configFile == null) {configFile = Config.HOME_CONFIG_FILE;} JFileChooser chooser = new JFileChooser(configFile.getAbsoluteFile().getParent()); chooser.setSelectedFile(configFile); int response = chooser.showSaveDialog(_parentFrame); if (response == JFileChooser.APPROVE_OPTION) { File saveFile = chooser.getSelectedFile(); - FileOutputStream outStream = null; - try - { - outStream = new FileOutputStream(saveFile); - Config.getAllConfig().store(outStream, "Prune config file"); - } - catch (IOException ioe) { - _app.showErrorMessageNoLookup(getNameKey(), - I18nManager.getText("error.save.failed") + " : " + ioe.getMessage()); - } - finally { - try {outStream.close();} catch (Exception e) {} - } + saveConfig(saveFile); } _dialog.dispose(); _dialog = null; } + + /** + * Autosave the settings file without any prompts + */ + public void silentSave() + { + saveConfig(Config.getConfigFile()); + } + + /** + * Actually save the config file + * @param inSaveFile file to save to + */ + private void saveConfig(File inSaveFile) + { + FileOutputStream outStream = null; + try + { + outStream = new FileOutputStream(inSaveFile); + Config.getAllConfig().store(outStream, "GpsPrune config file"); + } + catch (IOException ioe) { + _app.showErrorMessageNoLookup(getNameKey(), + I18nManager.getText("error.save.failed") + " : " + ioe.getMessage()); + } + catch (NullPointerException npe) {} // no config file given + finally { + try {outStream.close();} catch (Exception e) {} + } + } } diff --git a/tim/prune/function/SearchWikipediaNames.java b/tim/prune/function/SearchWikipediaNames.java index 4377df8..ab24522 100644 --- a/tim/prune/function/SearchWikipediaNames.java +++ b/tim/prune/function/SearchWikipediaNames.java @@ -1,7 +1,9 @@ package tim.prune.function; import java.io.InputStream; +import java.io.UnsupportedEncodingException; import java.net.URL; +import java.net.URLEncoder; import java.util.ArrayList; import javax.swing.JOptionPane; @@ -26,6 +28,8 @@ public class SearchWikipediaNames extends GenericDownloaderFunction private String _searchTerm = null; /** Maximum number of results to get */ private static final int MAX_RESULTS = 20; + /** Username to use for geonames queries */ + private static final String GEONAMES_USERNAME = "gpsprune"; /** * Constructor @@ -88,9 +92,16 @@ public class SearchWikipediaNames extends GenericDownloaderFunction else { lang = "en"; } + // Replace awkward characters with character equivalents + String searchTerm; + try { + searchTerm = URLEncoder.encode(_searchTerm, "UTF-8"); + } catch (UnsupportedEncodingException e1) { + searchTerm = _searchTerm; + } // Example http://ws.geonames.org/wikipediaSearch?q=london&maxRows=10 - String urlString = "http://ws.geonames.org/wikipediaSearch?title=" + _searchTerm + "&maxRows=" + MAX_RESULTS - + "&lang=" + lang; + String urlString = "http://api.geonames.org/wikipediaSearch?title=" + searchTerm + + "&maxRows=" + MAX_RESULTS + "&lang=" + lang + "&username=" + GEONAMES_USERNAME; // Parse the returned XML with a special handler GetWikipediaXmlHandler xmlHandler = new GetWikipediaXmlHandler(); try diff --git a/tim/prune/function/SelectTracksFunction.java b/tim/prune/function/SelectTracksFunction.java index b7ff0a4..f2fe23b 100644 --- a/tim/prune/function/SelectTracksFunction.java +++ b/tim/prune/function/SelectTracksFunction.java @@ -18,8 +18,7 @@ import javax.swing.ListSelectionModel; import tim.prune.App; import tim.prune.GenericFunction; import tim.prune.I18nManager; -import tim.prune.data.Altitude; -import tim.prune.data.Field; +import tim.prune.data.DataPoint; import tim.prune.data.SourceInfo; import tim.prune.data.Track; import tim.prune.load.TrackNameList; @@ -29,9 +28,7 @@ import tim.prune.load.TrackNameList; */ public class SelectTracksFunction extends GenericFunction { - private Field[] _fieldArray = null; - private Object[][] _dataArray = null; - private Altitude.Format _altFormat = Altitude.Format.NO_FORMAT; + private Track _track = null; private SourceInfo _sourceInfo = null; private TrackNameList _trackNameList = null; private JDialog _dialog = null; @@ -40,19 +37,15 @@ public class SelectTracksFunction extends GenericFunction /** * Constructor * @param inApp app object to use for load - * @param inFieldArray field array - * @param inDataArray data array - * @param inAltFormat altitude format + * @param inTrack loaded track object * @param inSourceInfo source information * @param inTrackNameList track name list */ - public SelectTracksFunction(App inApp, Field[] inFieldArray, Object[][] inDataArray, - Altitude.Format inAltFormat, SourceInfo inSourceInfo, TrackNameList inTrackNameList) + public SelectTracksFunction(App inApp, Track inTrack, SourceInfo inSourceInfo, + TrackNameList inTrackNameList) { super(inApp); - _fieldArray = inFieldArray; - _dataArray = inDataArray; - _altFormat = inAltFormat; + _track = inTrack; _sourceInfo = inSourceInfo; _trackNameList = inTrackNameList; } @@ -147,13 +140,10 @@ public class SelectTracksFunction extends GenericFunction private void finish() { _dialog.dispose(); - // Load track as it is, which is expensive but makes interrogating waypoints easier - Track loadedTrack = new Track(); - loadedTrack.load(_fieldArray, _dataArray, _altFormat); int[] tracks = _trackList.getSelectedIndices(); // Check if all tracks are selected, then don't have to filter at all if (tracks.length == _trackNameList.getNumTracks()) { - _app.informDataLoaded(loadedTrack, _sourceInfo); + _app.informDataLoaded(_track, _sourceInfo); } else { @@ -165,13 +155,13 @@ public class SelectTracksFunction extends GenericFunction // Loop over all points, counting points which survive filter and making flag array int numPointsSelected = 0; int currentTrack = -1; - final int totalPoints = loadedTrack.getNumPoints(); + final int totalPoints = _track.getNumPoints(); boolean[] selectedPoints = new boolean[totalPoints]; for (int i=0; i 0) { + totalDeleted += numFilesDeleted; + } + } + } + } + if (totalDeleted > 0) + { + // Show confirmation message + JOptionPane.showMessageDialog(_dialog, I18nManager.getText("dialog.diskcache.deleted1") + + " " + totalDeleted + " " + I18nManager.getText("dialog.diskcache.deleted2"), + I18nManager.getText(getNameKey()), JOptionPane.INFORMATION_MESSAGE); + // reload model + _cards.first(_cardPanel); + new Thread(this).start(); + } + else { + _app.showErrorMessage(getNameKey(), "error.cache.cannotdelete"); + } + } + + + /** + * Delete recursively all files which are older than the age limit + * @param inDir directory to delete from + * @param inMaxDays age limit in days + * @return number of files deleted + */ + private static int deleteFilesFrom(File inDir, int inMaxDays) + { + int numDeleted = 0; + long now = System.currentTimeMillis(); + if (inDir.exists() && inDir.isDirectory()) + { + for (File subdir : inDir.listFiles()) + { + if (subdir.isDirectory()) { + numDeleted += deleteFilesFrom(subdir, inMaxDays); + } + else if (subdir.isFile() && subdir.exists() && _TILEFILTER.accept(subdir)) + { + long fileAge = (now - subdir.lastModified()) / 1000 / 60 / 60 / 24; + if (inMaxDays < 0 || fileAge > inMaxDays) + { + if (subdir.delete()) { + numDeleted++; + } + } + } + } + // Try to delete the directory (doesn't work if not empty) + inDir.delete(); + } + return numDeleted; + } +} diff --git a/tim/prune/function/cache/RowInfo.java b/tim/prune/function/cache/RowInfo.java new file mode 100644 index 0000000..dc90abd --- /dev/null +++ b/tim/prune/function/cache/RowInfo.java @@ -0,0 +1,121 @@ +package tim.prune.function.cache; + +/** + * Class to hold the information for a single table row. + * Used to describe a tileset or for a single zoom level of a tileset. + */ +public class RowInfo +{ + private int _zoom = -1; + private int _minZoom = -1, _maxZoom = -1; + private int _numTiles = 0; + private long _totalSize = 0L; + private boolean _unexpected = false; + + + /** + * Set the zoom level + * @param inZoom zoom level + */ + public void setZoom(int inZoom) { + _zoom = inZoom; + } + + /** + * Add a zoom level and adjust max/min + * @param inZoom zoom level + */ + public void addZoom(int inZoom) + { + if (_minZoom < 0 || _minZoom > inZoom) + _minZoom = inZoom; + if (_maxZoom < inZoom) + _maxZoom = inZoom; + } + + /** + * @return the zoom level + */ + public int getZoom() { + return _zoom; + } + + /** + * @return the zoom range as a string + */ + public String getZoomRange() + { + if (_minZoom < 0 && _maxZoom < 0) return ""; + if (_minZoom == _maxZoom || _maxZoom < 0) return "" + _minZoom; + if (_minZoom < 0) return "" + _maxZoom; + return "" + _minZoom + " - " + _maxZoom; + } + + /** + * Add a single tile of the given size + * @param inSize size in bytes + */ + public void addTile(long inSize) { + addTiles(1, inSize); + } + + /** + * Add the given tiles + * @param inNumTiles number of tiles to add + * @param inSize total size of the tiles in bytes + */ + public void addTiles(int inNumTiles, long inSize) + { + _numTiles += inNumTiles; + _totalSize += inSize; + } + + /** + * @return the total number of tiles found + */ + public int getNumTiles() { + return _numTiles; + } + + /** + * @return the total size of the tiles in bytes + */ + public long getTotalSize() { + return _totalSize; + } + + /** + * Mark that an unexpected file or directory was found + */ + public void foundUnexpected() { + _unexpected = true; + } + + /** + * @return true if any unexpected files or directories were found + */ + public boolean wasUnexpected() { + return _unexpected; + } + + /** + * Add the given RowInfo object to this one + * @param inOther other row object + */ + public void addRow(RowInfo inOther) + { + if (inOther == null) + return; + _numTiles += inOther._numTiles; + _totalSize += inOther._totalSize; + // TODO: Max age + // Zoom range + if (inOther._minZoom > 0) + addZoom(inOther._minZoom); + if (inOther._maxZoom > 0) + addZoom(inOther._maxZoom); + if (inOther._zoom > 0) + addZoom(inOther._zoom); + _unexpected = _unexpected || inOther._unexpected; + } +} diff --git a/tim/prune/function/cache/TileCacheModel.java b/tim/prune/function/cache/TileCacheModel.java new file mode 100644 index 0000000..2f45414 --- /dev/null +++ b/tim/prune/function/cache/TileCacheModel.java @@ -0,0 +1,216 @@ +package tim.prune.function.cache; + +import java.io.File; +import java.util.ArrayList; + +import tim.prune.gui.map.MapSource; +import tim.prune.gui.map.MapSourceLibrary; + +/** + * Class to obtain and hold information about the current + * tile cache including its subdirectories + */ +public class TileCacheModel +{ + /** Cache directory */ + private File _cacheDir = null; + /** Array of tilesets */ + private ArrayList _tileSets = null; + /** Summary information */ + private RowInfo _summaryRow = null; + /** Cancelled flag */ + private boolean _cancelled = false; + + + /** + * Constructor + * @param inDir start directory + */ + public TileCacheModel(File inDir) + { + if (inDir != null && inDir.exists() && inDir.isDirectory() && inDir.canRead()) { + _cacheDir = inDir; + } + _cancelled = false; + } + + /** + * Build the tilesets by searching recursively + */ + public void buildTileSets() + { + if (_cacheDir == null) return; + + _tileSets = new ArrayList(); + // go through subdirectories, if any + File[] subdirs = _cacheDir.listFiles(); + for (File subdir : subdirs) + { + if (subdir != null && subdir.isDirectory() && subdir.exists() && subdir.canRead() + && !_cancelled) + { + getTileSets(subdir, null, _tileSets); + } + } + // Loop over found tile sets and create summary rowinfo + _summaryRow = new RowInfo(); + for (TileSet ts : _tileSets) + { + _summaryRow.addRow(ts.getRowInfo()); + } + } + + /** + * Get all the tilesets from the given directory + * @param inDir directory to search + * @return array of TileSet objects + */ + private static void getTileSets(File inDir, String inParentPath, ArrayList inTsList) + { + final String wholePath = (inParentPath == null ? "" : inParentPath) + + inDir.getName() + File.separator; + // See if any configured backgrounds use this directory + // or if the directories match OSM structure + String usedByDesc = matchConfig(wholePath); + boolean tsFound = false; + if (usedByDesc != null || looksLikeCacheDir(inDir)) + { + TileSet ts = new TileSet(inDir, wholePath, usedByDesc); + if (usedByDesc != null || ts.getRowInfo().getNumTiles() > 0) + { + tsFound = true; + inTsList.add(ts); + } + } + // If a tileset wasn't found, look through subdirectories + if (!tsFound) + { + // Go through subdirectories and look at each of them too + File[] subdirs = inDir.listFiles(); + if (subdirs != null) { + for (File subdir : subdirs) + { + if (subdir != null && subdir.exists() && subdir.isDirectory() + && subdir.canRead()) + { + getTileSets(subdir, wholePath, inTsList); + } + } + } + } + } + + /** + * Match the given directory name to find the configs which use it + * @param inName name of directory to match + * @return null if not used, otherwise comma-separated list of background names + */ + private static String matchConfig(String inName) + { + if (inName == null || inName.equals("")) + return null; + String usedBy = null; + for (int i=0; i= 0 && inIndex < getNumTileSets()) { + return _tileSets.get(inIndex); + } + return null; + } + + /** + * Cancel the search + */ + public void cancel() { + _cancelled = true; + } + + /** + * @return true if search was cancelled + */ + public boolean isAborted() { + return _cancelled; + } +} diff --git a/tim/prune/function/cache/TileFilter.java b/tim/prune/function/cache/TileFilter.java new file mode 100644 index 0000000..dd87056 --- /dev/null +++ b/tim/prune/function/cache/TileFilter.java @@ -0,0 +1,15 @@ +package tim.prune.function.cache; + +import tim.prune.load.GenericFileFilter; + +/** + * File filter for map tiles + */ +public class TileFilter extends GenericFileFilter +{ + /** Constructor */ + public TileFilter() + { + super("filetype.jpeg", new String[] {"jpg", "png", "gif", "temp"}); + } +} diff --git a/tim/prune/function/cache/TileSet.java b/tim/prune/function/cache/TileSet.java new file mode 100644 index 0000000..3e308ba --- /dev/null +++ b/tim/prune/function/cache/TileSet.java @@ -0,0 +1,114 @@ +package tim.prune.function.cache; + +import java.io.File; +import java.util.ArrayList; + + +/** + * Class to hold information about a single tile set + * within the overall Tile Cache. + */ +public class TileSet +{ + /** Summary row info for whole tileset */ + private RowInfo _rowInfo = null; + /** Path relative to mapcache root */ + private String _path = null; + /** Comma-separated list of configs using this tileset */ + private String _usedBy = null; + /** List of infos for each zoom level */ + private ArrayList _zoomLevels = null; + + + /** + * Constructor + * @param inDir directory of tileset + * @param inPath String describing relative path from cache root + * @param inUsedBy String describing which configs use this Tileset + */ + public TileSet(File inDir, String inPath, String inUsedBy) + { + _path = inPath; + _usedBy = inUsedBy; + _rowInfo = new RowInfo(); + _zoomLevels = new ArrayList(); + // Go through zoom directories and construct row info objects + if (inDir != null && inDir.exists() && inDir.isDirectory() && inDir.canRead()) + { + for (File subdir : inDir.listFiles()) + { + if (subdir != null && subdir.exists() && subdir.isDirectory() + && subdir.canRead() && isNumeric(subdir.getName())) + { + RowInfo row = makeRowInfo(subdir); + _zoomLevels.add(row); + _rowInfo.addRow(row); + } + } + } + } + + /** + * Check if a directory name is numeric + * @param inName name of directory + * @return true if it only contains characters 0-9 + */ + public static boolean isNumeric(String inName) + { + if (inName == null || inName.equals("")) return false; + for (int i=0; i '9') return false; + } + return true; + } + + /** + * Make a RowInfo object from the given directory + * @param inDir directory for a single zoom level + * @return RowInfo object describing files and size + */ + private static RowInfo makeRowInfo(File inDir) + { + RowInfo row = new RowInfo(); + row.setZoom(Integer.parseInt(inDir.getName())); + for (File subdir : inDir.listFiles()) + { + if (subdir != null && subdir.exists() && subdir.isDirectory() + && subdir.canRead() && isNumeric(subdir.getName())) + { + // Found a directory of images (finally!) + for (File f : subdir.listFiles()) + { + if (f != null && f.exists() && f.isFile() && f.canRead()) + { + final String filename = f.getName(); + int dotpos = filename.lastIndexOf('.'); + if (dotpos > 0 && isNumeric(filename.substring(0, dotpos))) { + row.addTile(f.length()); + } + } + } + } + } + return row; + } + + /** + * @return row info object + */ + public RowInfo getRowInfo() { + return _rowInfo; + } + + /** @return relative path to tileset */ + public String getPath() { + return _path; + } + + /** @return users of tileset */ + public String getUsedBy() { + return _usedBy; + } +} diff --git a/tim/prune/function/cache/TileSetTableModel.java b/tim/prune/function/cache/TileSetTableModel.java new file mode 100644 index 0000000..8803894 --- /dev/null +++ b/tim/prune/function/cache/TileSetTableModel.java @@ -0,0 +1,77 @@ +package tim.prune.function.cache; + +import javax.swing.table.AbstractTableModel; + +import tim.prune.I18nManager; + +/** + * Class to act as a table model for the list of tile sets + */ +public final class TileSetTableModel extends AbstractTableModel +{ + /** Model from which values are drawn */ + private TileCacheModel _model = null; + + + /** + * Constructor + * @param inModel model to use + */ + public TileSetTableModel(TileCacheModel inModel) { + _model = inModel; + } + + /** @return the column count (always constant) */ + public int getColumnCount() { + return 5; + } + + /** @return name of specified column */ + public String getColumnName(int inColumnIndex) + { + switch (inColumnIndex) + { + case 0: return I18nManager.getText("dialog.diskcache.table.path"); + case 1: return I18nManager.getText("dialog.diskcache.table.usedby"); + case 2: return I18nManager.getText("dialog.diskcache.table.zoom"); + case 3: return I18nManager.getText("dialog.diskcache.table.tiles"); + case 4: return I18nManager.getText("dialog.diskcache.table.megabytes"); + } + return ""; + } + + /** + * @return number of rows in the table + */ + public int getRowCount() + { + if (_model == null) + return 0; + return _model.getNumTileSets(); + } + + /** + * @param inRowIndex row index + * @param inColumnIndex column index + * @return the value of the specified cell + */ + public Object getValueAt(int inRowIndex, int inColumnIndex) + { + if (_model != null && inColumnIndex >= 0 && inColumnIndex < getColumnCount()) + { + TileSet set = _model.getTileSet(inRowIndex); + if (set != null) + { + switch (inColumnIndex) + { + case 0: return set.getPath(); + case 1: return set.getUsedBy(); + case 2: return set.getRowInfo().getZoomRange(); + case 3: return "" + set.getRowInfo().getNumTiles(); + case 4: return "" + (set.getRowInfo().getTotalSize() / 1024 / 1024) + " MB"; + } + } + } + return null; + } +} diff --git a/tim/prune/function/charts/Charter.java b/tim/prune/function/charts/Charter.java index 3edb475..502c914 100644 --- a/tim/prune/function/charts/Charter.java +++ b/tim/prune/function/charts/Charter.java @@ -380,7 +380,7 @@ public class Charter extends GenericFunction FileWriter tempFileWriter = null; try { tempFileWriter = new FileWriter(tempFile); - tempFileWriter.write("# Temporary data file for Prune charts\n\n"); + tempFileWriter.write("# Temporary data file for GpsPrune charts\n\n"); for (int i=0; i 1.0) param = 1.0 / param; + if (param <= 0.0 || param >= 1.0) { + // Parameter isn't valid, don't delete any + return 0; + } + double threshold = _trackDetails.getTrackSpan() * param; + + int numPoints = _track.getNumPoints(); + int origNumDeleted = countFlags(inFlags); + // Convert inFlags into keepFlags + int[] keepFlags = new int[numPoints]; + int segStart = -1, segEnd = -1; + // Loop over all points in track + for (int i=0; i -1 && segEnd > segStart) + { + keepFlags[segEnd] = 1; // keep + compressSegment(keepFlags, segStart, segEnd, threshold); + segStart = segEnd = -1; + } + } + if (inFlags[i]) keepFlags[i] = -1; // already deleted + else if (currPoint.isWaypoint() || currPoint.hasMedia() || currPoint.getSegmentStart()) { + keepFlags[i] = 1; // keep + } + // Don't consider points which are already marked as deleted, ignore waypoints + if (!inFlags[i] && !currPoint.isWaypoint()) + { + // remember starts and ends + if (segStart < 0) {segStart = i;} + else {segEnd = i;} + } + } + // Last segment, if any + if (segStart >= 0 && segEnd > segStart) { + keepFlags[segEnd] = 1; // keep + compressSegment(keepFlags, segStart, segEnd, threshold); + } + // Convert keepFlags back into inFlags + for (int i=1; i 1.0) { + dist = endxy.vectorTo(currPoint).len(); // outside on the B side + } + else { + // P lies between A and B so use dot product + dist = Math.abs(perpendicular.dot(ac)); + } + if (dist > maxDist) + { + maxDist = dist; + furthestIndex = i; + } + } + } + // Check furthest point and see if it's further than the threshold + if (maxDist > inThreshold) + { + inFlags[furthestIndex] = 1; + // Make recursive calls for bit before and bit after kept point + compressSegment(inFlags, inSegStart, furthestIndex, inThreshold); + compressSegment(inFlags, furthestIndex, inSegEnd, inThreshold); + } + } + + + /** + * @return specific gui components for dialog + */ + protected Component getSpecificGuiComponents() + { + return getSpecificGuiComponents("dialog.compress.douglaspeucker.paramdesc", "2000"); + } + + /** + * @return title key for box + */ + protected String getTitleTextKey() + { + return "dialog.compress.douglaspeucker.title"; + } +} diff --git a/tim/prune/function/compress/XYpoint.java b/tim/prune/function/compress/XYpoint.java new file mode 100644 index 0000000..b3d93d1 --- /dev/null +++ b/tim/prune/function/compress/XYpoint.java @@ -0,0 +1,49 @@ +package tim.prune.function.compress; + +/** + * Basic class to hold x and y coordinates + * for a point or a vector + */ +public class XYpoint +{ + // x and y coordinates + public double x = 0.0, y = 0.0; + + /** + * Empty constructor + */ + public XYpoint() { + this(0.0, 0.0); + } + + /** + * Constructor + * @param inX x value + * @param inY y value + */ + public XYpoint(double inX, double inY) { + x = inX; y = inY; + } + + /** + * @param inOther other vector + * @return scalar dot product + */ + public double dot(XYpoint inOther) { + return (x * inOther.x + y * inOther.y); + } + + /** @return length of vector */ + public double len() {return Math.sqrt(len2());} + + /** @return squared length of vector */ + public double len2() {return (x*x + y*y);} + + /** + * @param inOther other point object + * @return vector from this one to the other one + */ + public XYpoint vectorTo(XYpoint inOther) { + return new XYpoint(inOther.x - x, inOther.y - y); + } +} diff --git a/tim/prune/function/gpsies/GetGpsiesFunction.java b/tim/prune/function/gpsies/GetGpsiesFunction.java index 804c4ce..51085cf 100644 --- a/tim/prune/function/gpsies/GetGpsiesFunction.java +++ b/tim/prune/function/gpsies/GetGpsiesFunction.java @@ -3,12 +3,14 @@ package tim.prune.function.gpsies; import java.io.IOException; import java.io.InputStream; import java.net.URL; +import java.net.URLConnection; import java.util.ArrayList; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import tim.prune.App; +import tim.prune.GpsPrune; import tim.prune.I18nManager; import tim.prune.load.xml.XmlFileLoader; import tim.prune.load.xml.ZipFileLoader; @@ -23,6 +25,8 @@ public class GetGpsiesFunction extends GenericDownloaderFunction private static final int RESULTS_PER_PAGE = 20; /** Maximum number of results to get */ private static final int MAX_RESULTS = 60; + /** New API key (specific to this program) */ + private static final String GPSIES_API_KEY = "oumgvvbckiwpvsnb"; /** @@ -69,16 +73,19 @@ public class GetGpsiesFunction extends GenericDownloaderFunction // Loop for each page of the results do { - String urlString = "http://www.gpsies.com/api.do?BBOX=" + + String urlString = "http://ws.gpsies.com/api.do?BBOX=" + coords[1] + "," + coords[0] + "," + coords[3] + "," + coords[2] + - "&limit=" + RESULTS_PER_PAGE + "&resultPage=" + currPage; + "&limit=" + RESULTS_PER_PAGE + "&resultPage=" + currPage + + "&key=" + GPSIES_API_KEY; // Parse the returned XML with a special handler GpsiesXmlHandler xmlHandler = new GpsiesXmlHandler(); try { url = new URL(urlString); SAXParser saxParser = SAXParserFactory.newInstance().newSAXParser(); - inStream = url.openStream(); + URLConnection conn = url.openConnection(); + conn.setRequestProperty("User-Agent", "GpsPrune v" + GpsPrune.VERSION_NUMBER); + inStream = conn.getInputStream(); saxParser.parse(inStream, xmlHandler); } catch (Exception e) { diff --git a/tim/prune/function/srtm/LookupSrtmFunction.java b/tim/prune/function/srtm/LookupSrtmFunction.java index 1bf26cd..22ee831 100644 --- a/tim/prune/function/srtm/LookupSrtmFunction.java +++ b/tim/prune/function/srtm/LookupSrtmFunction.java @@ -104,6 +104,7 @@ public class LookupSrtmFunction extends GenericFunction implements Runnable cancelButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { _cancelled = true; + _dialog.dispose(); } }); buttonPanel.add(cancelButton); @@ -178,6 +179,7 @@ public class LookupSrtmFunction extends GenericFunction implements Runnable _progressBar.setMaximum(inTileList.size()); _progressBar.setIndeterminate(inTileList.size() <= 1); _progressBar.setValue(0); + String errorMessage = null; // Get urls for each tile URL[] urls = TileFinder.getUrls(inTileList); for (int t=0; t 0) { // Inform app including undo information @@ -260,6 +263,9 @@ public class LookupSrtmFunction extends GenericFunction implements Runnable _app.completeFunction(undo, I18nManager.getText("confirm.lookupsrtm1") + " " + numAltitudesFound + " " + I18nManager.getText("confirm.lookupsrtm2")); } + else if (errorMessage != null) { + _app.showErrorMessageNoLookup(getNameKey(), errorMessage); + } else if (inTileList.size() > 0) { _app.showErrorMessage(getNameKey(), "error.lookupsrtm.nonefound"); } diff --git a/tim/prune/gui/AudioListener.java b/tim/prune/gui/AudioListener.java index fe1e933..6bf3ffe 100644 --- a/tim/prune/gui/AudioListener.java +++ b/tim/prune/gui/AudioListener.java @@ -10,7 +10,7 @@ import tim.prune.function.PlayAudioFunction; /** * Class to update the supplied progress bar on the basis of - * the currently playing audio file (if any) + * the currently playing audio clip (if any) */ public class AudioListener implements Runnable, ActionListener { diff --git a/tim/prune/gui/DetailsDisplay.java b/tim/prune/gui/DetailsDisplay.java index dee14a9..ec68e16 100644 --- a/tim/prune/gui/DetailsDisplay.java +++ b/tim/prune/gui/DetailsDisplay.java @@ -27,7 +27,7 @@ import tim.prune.I18nManager; import tim.prune.UpdateMessageBroker; import tim.prune.config.Config; import tim.prune.data.Altitude; -import tim.prune.data.AudioFile; +import tim.prune.data.AudioClip; import tim.prune.data.Coordinate; import tim.prune.data.DataPoint; import tim.prune.data.Distance; @@ -63,6 +63,7 @@ public class DetailsDisplay extends GenericDisplay private PhotoThumbnail _photoThumbnail = null; private JLabel _photoTimestampLabel = null; private JLabel _photoConnectedLabel = null; + private JLabel _photoBearingLabel = null; private JPanel _rotationButtons = null; // Audio details @@ -160,6 +161,8 @@ public class DetailsDisplay extends GenericDisplay _photoDetailsPanel.add(_photoTimestampLabel); _photoConnectedLabel = new JLabel(""); _photoDetailsPanel.add(_photoConnectedLabel); + _photoBearingLabel = new JLabel(""); + _photoDetailsPanel.add(_photoBearingLabel); _photoThumbnail = new PhotoThumbnail(); _photoThumbnail.setVisible(false); _photoThumbnail.setPreferredSize(new Dimension(100, 100)); @@ -381,17 +384,24 @@ public class DetailsDisplay extends GenericDisplay _photoLabel.setText(I18nManager.getText("details.nophoto")); _photoTimestampLabel.setText(""); _photoConnectedLabel.setText(""); + _photoBearingLabel.setText(""); _photoThumbnail.setVisible(false); _rotationButtons.setVisible(false); } else { if (currentPhoto == null) {currentPhoto = currentPoint.getPhoto();} - _photoLabel.setText(I18nManager.getText("details.photofile") + ": " + currentPhoto.getFile().getName()); - _photoTimestampLabel.setText(LABEL_POINT_TIMESTAMP + currentPhoto.getTimestamp().getText()); + _photoLabel.setText(I18nManager.getText("details.photofile") + ": " + currentPhoto.getName()); + _photoTimestampLabel.setText(currentPhoto.hasTimestamp()?(LABEL_POINT_TIMESTAMP + currentPhoto.getTimestamp().getText()):""); _photoConnectedLabel.setText(I18nManager.getText("details.media.connected") + ": " + (currentPhoto.getCurrentStatus() == Photo.Status.NOT_CONNECTED ? I18nManager.getText("dialog.about.no"):I18nManager.getText("dialog.about.yes"))); + if (currentPhoto.getBearing() >= 0.0 && currentPhoto.getBearing() <= 360.0) + { + _photoBearingLabel.setText(I18nManager.getText("details.photo.bearing") + ": " + + (int) currentPhoto.getBearing() + " \u00B0"); + } + else _photoBearingLabel.setText(""); _photoThumbnail.setVisible(true); _photoThumbnail.setPhoto(currentPhoto); _rotationButtons.setVisible(true); @@ -401,7 +411,7 @@ public class DetailsDisplay extends GenericDisplay // audio details _audioDetailsPanel.setVisible(_trackInfo.getAudioList().getNumAudios() > 0); - AudioFile currentAudio = _trackInfo.getAudioList().getAudio(_trackInfo.getSelection().getCurrentAudioIndex()); + AudioClip currentAudio = _trackInfo.getAudioList().getAudio(_trackInfo.getSelection().getCurrentAudioIndex()); if (currentAudio == null) { _audioLabel.setText(I18nManager.getText("details.noaudio")); _audioTimestampLabel.setText(""); @@ -410,8 +420,8 @@ public class DetailsDisplay extends GenericDisplay } else { - _audioLabel.setText(LABEL_AUDIO_FILE + currentAudio.getFile().getName()); - _audioTimestampLabel.setText(LABEL_POINT_TIMESTAMP + currentAudio.getTimestamp().getText()); + _audioLabel.setText(LABEL_AUDIO_FILE + currentAudio.getName()); + _audioTimestampLabel.setText(currentAudio.hasTimestamp()?(LABEL_POINT_TIMESTAMP + currentAudio.getTimestamp().getText()):""); int audioLength = currentAudio.getLengthInSeconds(); _audioLengthLabel.setText(audioLength < 0?"":LABEL_RANGE_DURATION + DisplayUtils.buildDurationString(audioLength)); _audioConnectedLabel.setText(I18nManager.getText("details.media.connected") + ": " diff --git a/tim/prune/gui/IconManager.java b/tim/prune/gui/IconManager.java index 858e97a..1c0cc7e 100644 --- a/tim/prune/gui/IconManager.java +++ b/tim/prune/gui/IconManager.java @@ -62,9 +62,9 @@ public abstract class IconManager public static final String ROTATE_RIGHT = "rotate_right_icon.png"; /** Icon for showing photo popup */ public static final String SHOW_DETAILS = "show_details_icon.gif"; - /** Icon for playing audio file */ + /** Icon for playing audio clip */ public static final String PLAY_AUDIO = "play_audio.gif"; - /** Icon for stopping the current audio file */ + /** Icon for stopping the current audio clip */ public static final String STOP_AUDIO = "stop_audio.gif"; /** diff --git a/tim/prune/gui/MediaListModel.java b/tim/prune/gui/MediaListModel.java index 2d8eb6e..e2a7307 100644 --- a/tim/prune/gui/MediaListModel.java +++ b/tim/prune/gui/MediaListModel.java @@ -2,7 +2,7 @@ package tim.prune.gui; import javax.swing.AbstractListModel; -import tim.prune.data.MediaFile; +import tim.prune.data.MediaObject; import tim.prune.data.MediaList; /** @@ -33,9 +33,9 @@ public class MediaListModel extends AbstractListModel */ public Object getElementAt(int inIndex) { - MediaFile m = _media.getMedia(inIndex); + MediaObject m = _media.getMedia(inIndex); // * means modified since loading - return (m.getCurrentStatus() == m.getOriginalStatus()?"":"* ") + m.getFile().getName(); + return (m.getCurrentStatus() == m.getOriginalStatus()?"":"* ") + m.getName(); } /** diff --git a/tim/prune/gui/MenuManager.java b/tim/prune/gui/MenuManager.java index 47044f2..8229aa3 100644 --- a/tim/prune/gui/MenuManager.java +++ b/tim/prune/gui/MenuManager.java @@ -20,8 +20,10 @@ import tim.prune.GenericFunction; import tim.prune.I18nManager; import tim.prune.UpdateMessageBroker; import tim.prune.config.Config; -import tim.prune.data.AudioFile; +import tim.prune.data.AudioClip; import tim.prune.data.Photo; +import tim.prune.data.RecentFile; +import tim.prune.data.RecentFileList; import tim.prune.data.Selection; import tim.prune.data.Track; import tim.prune.data.TrackInfo; @@ -45,6 +47,7 @@ public class MenuManager implements DataSubscriber private JMenuItem _exportGpxItem = null; private JMenuItem _exportPovItem = null; private JMenuItem _exportSvgItem = null; + private JMenu _recentFileMenu = null; private JMenuItem _undoItem = null; private JMenuItem _clearUndoItem = null; private JMenuItem _editPointItem = null; @@ -97,6 +100,7 @@ public class MenuManager implements DataSubscriber private JMenuItem _correlateAudiosItem = null; private JMenuItem _selectNoAudioItem = null; private JCheckBoxMenuItem _onlineCheckbox = null; + private JCheckBoxMenuItem _autosaveSettingsCheckbox = null; // ActionListeners for reuse by menu and toolbar private ActionListener _openFileAction = null; @@ -160,6 +164,9 @@ public class MenuManager implements DataSubscriber }; openMenuItem.addActionListener(_openFileAction); fileMenu.add(openMenuItem); + // import through gpsbabel + JMenuItem importBabelItem = makeMenuItem(FunctionLibrary.FUNCTION_IMPORTBABEL); + fileMenu.add(importBabelItem); // Add photos JMenuItem addPhotosMenuItem = new JMenuItem(I18nManager.getText("menu.file.addphotos")); _addPhotoAction = new ActionListener() { @@ -169,9 +176,13 @@ public class MenuManager implements DataSubscriber }; addPhotosMenuItem.addActionListener(_addPhotoAction); fileMenu.add(addPhotosMenuItem); - // Add audio files + // Add audio clips JMenuItem addAudioMenuItem = makeMenuItem(FunctionLibrary.FUNCTION_LOAD_AUDIO); fileMenu.add(addAudioMenuItem); + // recent files + _recentFileMenu = new JMenu(I18nManager.getText("menu.file.recentfiles")); + _recentFileMenu.setEnabled(false); + fileMenu.add(_recentFileMenu); fileMenu.addSeparator(); // Load from GPS JMenuItem loadFromGpsMenuItem = makeMenuItem(FunctionLibrary.FUNCTION_GPSLOAD); @@ -213,6 +224,7 @@ public class MenuManager implements DataSubscriber }); fileMenu.add(exitMenuItem); menubar.add(fileMenu); + // Track menu JMenu trackMenu = new JMenu(I18nManager.getText("menu.track")); setAltKey(trackMenu, "altkey.menu.track"); @@ -449,6 +461,7 @@ public class MenuManager implements DataSubscriber _app.toggleSidebars(); } }); + sidebarsCheckbox.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F11, 0)); // shortcut F11 viewMenu.add(sidebarsCheckbox); // 3d _show3dItem = makeMenuItem(FunctionLibrary.FUNCTION_3D, false); @@ -570,14 +583,14 @@ public class MenuManager implements DataSubscriber // connect audio _connectAudioItem = makeMenuItem(FunctionLibrary.FUNCTION_CONNECT_TO_POINT, false); audioMenu.add(_connectAudioItem); - // Disconnect current audio file + // Disconnect current audio clip _disconnectAudioItem = makeMenuItem(FunctionLibrary.FUNCTION_DISCONNECT_AUDIO, false); audioMenu.add(_disconnectAudioItem); - // Remove current audio file + // Remove current audio clip _removeAudioItem = makeMenuItem(FunctionLibrary.FUNCTION_REMOVE_AUDIO, false); audioMenu.add(_removeAudioItem); audioMenu.addSeparator(); - // Correlate audio files + // Correlate audio clips _correlateAudiosItem = makeMenuItem(FunctionLibrary.FUNCTION_CORRELATE_AUDIOS, false); audioMenu.add(_correlateAudiosItem); menubar.add(audioMenu); @@ -613,6 +626,15 @@ public class MenuManager implements DataSubscriber settingsMenu.addSeparator(); // Save configuration settingsMenu.add(makeMenuItem(FunctionLibrary.FUNCTION_SAVECONFIG)); + _autosaveSettingsCheckbox = new JCheckBoxMenuItem( + I18nManager.getText("menu.settings.autosave"), false); + _autosaveSettingsCheckbox.setSelected(Config.getConfigBoolean(Config.KEY_AUTOSAVE_SETTINGS)); + _autosaveSettingsCheckbox.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + Config.setConfigBoolean(Config.KEY_AUTOSAVE_SETTINGS, _autosaveSettingsCheckbox.isSelected()); + } + }); + settingsMenu.add(_autosaveSettingsCheckbox); menubar.add(settingsMenu); // Help menu @@ -832,11 +854,11 @@ public class MenuManager implements DataSubscriber _duplicatePointItem.setEnabled(hasPoint); // are there any photos? boolean anyPhotos = _app.getTrackInfo().getPhotoList().getNumPhotos() > 0; - _saveExifItem.setEnabled(anyPhotos); + _saveExifItem.setEnabled(anyPhotos && _app.getTrackInfo().getPhotoList().hasMediaWithFile()); // is there a current photo, audio? Photo currentPhoto = _app.getTrackInfo().getCurrentPhoto(); boolean hasPhoto = currentPhoto != null; - AudioFile currentAudio = _app.getTrackInfo().getCurrentAudio(); + AudioClip currentAudio = _app.getTrackInfo().getCurrentAudio(); boolean hasAudio = currentAudio != null; // connect is available if (photo/audio) and point selected, and media has no point boolean connectAvailable = (hasPhoto && hasPoint && currentPhoto.getDataPoint() == null) @@ -881,6 +903,41 @@ public class MenuManager implements DataSubscriber if (_mapCheckbox.isSelected() != mapsOn) { _mapCheckbox.setSelected(mapsOn); } + // Are there any recently-used files? + RecentFileList rfl = Config.getRecentFileList(); + final int numRecentFiles = rfl.getNumEntries(); + final boolean hasRecentFiles = numRecentFiles > 0; + _recentFileMenu.setEnabled(hasRecentFiles); + if (hasRecentFiles) + { + int numItems = _recentFileMenu.getMenuComponentCount(); + if (numItems == numRecentFiles) + { + // Right number of items, just change texts + for (int i=0; i dataFiles = new ArrayList(); + dataFiles.add(rf.getFile()); + _app.loadDataFiles(dataFiles); + } + else + { + // Trigger a load via gpsbabel + new BabelLoadFromFile(_app).beginWithFile(rf.getFile()); + } + } + else + { + _app.showErrorMessage("function.open", "error.load.noread"); + Config.getRecentFileList().verifyAll(); // Called on a file which no longer exists + UpdateMessageBroker.informSubscribers(); + } + } +} diff --git a/tim/prune/gui/SelectorDisplay.java b/tim/prune/gui/SelectorDisplay.java index f0772bf..73a504a 100644 --- a/tim/prune/gui/SelectorDisplay.java +++ b/tim/prune/gui/SelectorDisplay.java @@ -130,7 +130,7 @@ public class SelectorDisplay extends GenericDisplay _photoListPanel = makeListPanel("details.lists.photos", _photoList); // don't add photo list (because there aren't any photos yet) - // List for audio files + // List for audio clips _audioListModel = new MediaListModel(_trackInfo.getAudioList()); _audioList = new JList(_audioListModel); _audioList.addListSelectionListener(new ListSelectionListener() { @@ -181,8 +181,8 @@ public class SelectorDisplay extends GenericDisplay } /** - * Select the specified audio file - * @param inIndex index of selected audio file + * Select the specified audio clip + * @param inIndex index of selected audio clip */ private void selectAudio(int inIndex) { @@ -289,7 +289,7 @@ public class SelectorDisplay extends GenericDisplay } } } - // Same for audio files + // Same for audio clips if (_audioListModel.getSize() > 0) { int audioIndex = _trackInfo.getSelection().getCurrentAudioIndex(); diff --git a/tim/prune/gui/WaypointListModel.java b/tim/prune/gui/WaypointListModel.java index e5b4186..3508697 100644 --- a/tim/prune/gui/WaypointListModel.java +++ b/tim/prune/gui/WaypointListModel.java @@ -38,8 +38,11 @@ public class WaypointListModel extends AbstractListModel */ public Object getElementAt(int inIndex) { - if (inIndex < 0 || inIndex >= getSize()) return ""; - return _waypoints.get(inIndex).getWaypointName(); + DataPoint p = null; + if (inIndex < 0 || inIndex >= getSize() + || _waypoints == null || (p = _waypoints.get(inIndex)) == null) + return ""; + return p.getWaypointName(); } /** diff --git a/tim/prune/gui/map/CloudmadeMapSource.java b/tim/prune/gui/map/CloudmadeMapSource.java index 0cc9b77..2e627a8 100644 --- a/tim/prune/gui/map/CloudmadeMapSource.java +++ b/tim/prune/gui/map/CloudmadeMapSource.java @@ -7,7 +7,7 @@ public class CloudmadeMapSource extends OsmMapSource { /** Selected style number */ private String _style = null; - /** Server prefix including API-key unique to Prune application */ + /** Server prefix including API-key unique to GpsPrune application */ private static final String SERVER_PREFIX = "tile.cloudmade.com/03d86b66f51f4a3b8c236ac06f2a2e57/"; /** diff --git a/tim/prune/gui/map/DiskTileCacher.java b/tim/prune/gui/map/DiskTileCacher.java index a250e23..84f54de 100644 --- a/tim/prune/gui/map/DiskTileCacher.java +++ b/tim/prune/gui/map/DiskTileCacher.java @@ -68,28 +68,29 @@ 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 void saveTile(URL inUrl, String inBasePath, String inTilePath, ImageObserver inObserver) + public static boolean saveTile(URL inUrl, String inBasePath, String inTilePath, ImageObserver inObserver) { - if (inBasePath == null || inTilePath == null) {return;} + if (inBasePath == null || inTilePath == null) {return false;} // save file if possible File basePath = new File(inBasePath); if (!basePath.exists() || !basePath.isDirectory() || !basePath.canWrite()) { - //System.err.println("Can't write"); // Can't write to base path - return; + return false; } File tileFile = new File(basePath, inTilePath); // Check if this file is already being loaded - if (!isBeingLoaded(tileFile)) + if (isBeingLoaded(tileFile)) {return true;} + + File dir = tileFile.getParentFile(); + // Start a new thread to load the image if necessary + if ((dir.exists() || dir.mkdirs()) && dir.canWrite()) { - File dir = tileFile.getParentFile(); - // Start a new thread to load the image if necessary - if (dir.exists() || dir.mkdirs()) - { - new DiskTileCacher(inUrl, tileFile, inObserver); - } + new DiskTileCacher(inUrl, tileFile, inObserver); + return true; } + return false; // couldn't write the file } /** diff --git a/tim/prune/gui/map/MapCanvas.java b/tim/prune/gui/map/MapCanvas.java index acac7a1..82cf434 100644 --- a/tim/prune/gui/map/MapCanvas.java +++ b/tim/prune/gui/map/MapCanvas.java @@ -9,7 +9,6 @@ import java.awt.FontMetrics; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Image; -import java.awt.RenderingHints; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; @@ -22,7 +21,6 @@ import java.awt.event.MouseMotionListener; import java.awt.event.MouseWheelEvent; import java.awt.event.MouseWheelListener; import java.awt.image.BufferedImage; -import java.awt.image.RescaleOp; import javax.swing.BorderFactory; import javax.swing.BoxLayout; @@ -171,16 +169,22 @@ public class MapCanvas extends JPanel implements MouseListener, MouseMotionListe _topPanel.setLayout(new FlowLayout()); _topPanel.setOpaque(false); // Make slider for transparency - _transparencySlider = new JSlider(0, 5, 0); + _transparencySlider = new JSlider(-6, 6, 0); _transparencySlider.setPreferredSize(new Dimension(100, 20)); _transparencySlider.setMajorTickSpacing(1); _transparencySlider.setSnapToTicks(true); _transparencySlider.setOpaque(false); + _transparencySlider.setValue(0); _transparencySlider.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent e) { - _recalculate = true; - repaint(); + int val = _transparencySlider.getValue(); + if (val == 1 || val == -1) + _transparencySlider.setValue(0); + else { + _recalculate = true; + repaint(); + } } }); _transparencySlider.setFocusable(false); // stop slider from stealing keyboard focus @@ -339,7 +343,7 @@ public class MapCanvas extends JPanel implements MouseListener, MouseMotionListe _yRange = new DoubleRange(MapUtils.getYFromLatitude(_latRange.getMinimum()), MapUtils.getYFromLatitude(_latRange.getMaximum())); _mapPosition.zoomToXY(_xRange.getMinimum(), _xRange.getMaximum(), _yRange.getMinimum(), _yRange.getMaximum(), - getWidth(), getHeight()); + getWidth(), getHeight()); } @@ -487,15 +491,15 @@ public class MapCanvas extends JPanel implements MouseListener, MouseMotionListe } } - // Make maps brighter / fainter - final float[] scaleFactors = {1.0f, 1.05f, 1.1f, 1.2f, 1.6f, 2.2f}; - final float scaleFactor = scaleFactors[_transparencySlider.getValue()]; - if (scaleFactor > 1.0f) + // Make maps brighter / fainter according to slider + final int brightnessIndex = Math.max(1, _transparencySlider.getValue()) - 1; + if (brightnessIndex > 0) { - RenderingHints hints = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF); - hints.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); - RescaleOp op = new RescaleOp(scaleFactor, 0, hints); - op.filter(_mapImage, _mapImage); + final int[] alphas = {0, 40, 80, 120, 160, 210}; + Color bgColor = Config.getColourScheme().getColour(ColourScheme.IDX_BACKGROUND); + bgColor = new Color(bgColor.getRed(), bgColor.getGreen(), bgColor.getBlue(), alphas[brightnessIndex]); + g.setColor(bgColor); + g.fillRect(0, 0, getWidth(), getHeight()); } } } @@ -532,11 +536,16 @@ public class MapCanvas extends JPanel implements MouseListener, MouseMotionListe private int paintPoints(Graphics inG) { // Set up colours - final Color pointColour = Config.getColourScheme().getColour(ColourScheme.IDX_POINT); - final Color rangeColour = Config.getColourScheme().getColour(ColourScheme.IDX_SELECTION); - final Color currentColour = Config.getColourScheme().getColour(ColourScheme.IDX_PRIMARY); - final Color secondColour = Config.getColourScheme().getColour(ColourScheme.IDX_SECONDARY); - final Color textColour = Config.getColourScheme().getColour(ColourScheme.IDX_TEXT); + final ColourScheme cs = Config.getColourScheme(); + final int[] opacities = {255, 190, 130, 80, 40, 0}; + int opacity = 255; + if (_transparencySlider.getValue() < 0) + opacity = opacities[-1 - _transparencySlider.getValue()]; + final Color pointColour = makeTransparentColour(cs.getColour(ColourScheme.IDX_POINT), opacity); + final Color rangeColour = makeTransparentColour(cs.getColour(ColourScheme.IDX_SELECTION), opacity); + final Color currentColour = makeTransparentColour(cs.getColour(ColourScheme.IDX_PRIMARY), opacity); + final Color secondColour = makeTransparentColour(cs.getColour(ColourScheme.IDX_SECONDARY), opacity); + final Color textColour = makeTransparentColour(cs.getColour(ColourScheme.IDX_TEXT), opacity); // try to set line width for painting if (inG instanceof Graphics2D) @@ -740,6 +749,17 @@ public class MapCanvas extends JPanel implements MouseListener, MouseMotionListe return false; } + /** + * Make a semi-transparent colour for drawing with + * @param inColour base colour (fully opaque) + * @param inOpacity opacity where 0=invisible and 255=full + * @return new colour object + */ + private static Color makeTransparentColour(Color inColour, int inOpacity) + { + if (inOpacity > 240) return inColour; + return new Color(inColour.getRed(), inColour.getGreen(), inColour.getBlue(), inOpacity); + } /** * Inform that tiles have been updated and the map can be repainted @@ -869,7 +889,8 @@ public class MapCanvas extends JPanel implements MouseListener, MouseMotionListe point.setSegmentStart(false); } } - else if (inE.getClickCount() == 2) { + else if (inE.getClickCount() == 2) + { // double click if (_drawMode == MODE_DEFAULT) { panMap(inE.getX() - getWidth()/2, inE.getY() - getHeight()/2); @@ -927,8 +948,9 @@ public class MapCanvas extends JPanel implements MouseListener, MouseMotionListe if (_drawMode == MODE_ZOOM_RECT && Math.abs(_dragToX - _dragFromX) > 20 && Math.abs(_dragToY - _dragFromY) > 20) { - //System.out.println("Finished zoom: " + _dragFromX + ", " + _dragFromY + " to " + _dragToX + ", " + _dragToY); _mapPosition.zoomToPixels(_dragFromX, _dragToX, _dragFromY, _dragToY, getWidth(), getHeight()); + } + if (_drawMode == MODE_ZOOM_RECT) { _drawMode = MODE_DEFAULT; } _dragFromX = _dragFromY = -1; @@ -1024,6 +1046,8 @@ public class MapCanvas extends JPanel implements MouseListener, MouseMotionListe // Check for Ctrl key (for Linux/Win) or meta key (Clover key for Mac) if (inE.isControlDown() || inE.isMetaDown()) { + // Shift as well makes things faster + final int pointIncrement = inE.isShiftDown()?3:1; // Check for arrow keys to zoom in and out if (code == KeyEvent.VK_UP) zoomIn(); @@ -1031,9 +1055,9 @@ public class MapCanvas extends JPanel implements MouseListener, MouseMotionListe zoomOut(); // Key nav for next/prev point else if (code == KeyEvent.VK_LEFT && currPointIndex > 0) - _trackInfo.selectPoint(currPointIndex-1); + _trackInfo.incrementPointIndex(-pointIncrement); else if (code == KeyEvent.VK_RIGHT) - _trackInfo.selectPoint(currPointIndex+1); + _trackInfo.incrementPointIndex(pointIncrement); else if (code == KeyEvent.VK_PAGE_UP) _trackInfo.selectPoint(Checker.getPreviousSegmentStart( _trackInfo.getTrack(), _trackInfo.getSelection().getCurrentPointIndex())); diff --git a/tim/prune/gui/map/MapSourceLibrary.java b/tim/prune/gui/map/MapSourceLibrary.java index df30219..24833ce 100644 --- a/tim/prune/gui/map/MapSourceLibrary.java +++ b/tim/prune/gui/map/MapSourceLibrary.java @@ -41,8 +41,8 @@ public abstract class MapSourceLibrary _sourceList.add(new OsmMapSource("Mapnik", "http://tile.openstreetmap.org/")); _sourceList.add(new OsmMapSource("Osma", "http://tah.openstreetmap.org/Tiles/tile/")); _sourceList.add(new OsmMapSource("Cyclemap", "http://andy.sandbox.cloudmade.com/tiles/cycle/")); - _sourceList.add(new OsmMapSource("Reitkarte", "http://topo.geofabrik.de/hills/", - "http://topo.openstreetmap.de/topo/", 18)); + _sourceList.add(new OsmMapSource("Reitkarte", "http://wanderreitkarte.de/hills/", + "http://topo2.wanderreitkarte.de/topo/", 18)); _sourceList.add(new MffMapSource("Mapsforfree", "http://maps-for-free.com/layer/relief/", ".jpg", "http://maps-for-free.com/layer/water/", ".gif", 11)); _sourceList.add(new CloudmadeMapSource("Pale Dawn", "998", 18)); diff --git a/tim/prune/gui/map/MapTileManager.java b/tim/prune/gui/map/MapTileManager.java index 9f1fbfe..f7a281b 100644 --- a/tim/prune/gui/map/MapTileManager.java +++ b/tim/prune/gui/map/MapTileManager.java @@ -126,7 +126,8 @@ public class MapTileManager implements ImageObserver if (useDisk) { tile = DiskTileCacher.getTile(diskCachePath, _mapSource.makeFilePath(inLayer, _zoom, inX, inY), onlineMode); - if (tile != null) { + if (tile != null) + { // Pass tile to memory cache tempCache.setTile(tile, inX, inY); if (tile.getWidth(this) > 0) {return tile;} @@ -139,11 +140,13 @@ public class MapTileManager implements ImageObserver try { URL tileUrl = new URL(_mapSource.makeURL(inLayer, _zoom, inX, inY)); - if (useDisk) { - // Copy image directly from URL stream to disk cache - DiskTileCacher.saveTile(tileUrl, diskCachePath, _mapSource.makeFilePath(inLayer, _zoom, inX, inY), this); + if (useDisk && DiskTileCacher.saveTile(tileUrl, diskCachePath, + _mapSource.makeFilePath(inLayer, _zoom, inX, inY), this)) + { + // Image now copied directly from URL stream to disk cache } - else { + else + { // Load image asynchronously, using observer tile = Toolkit.getDefaultToolkit().createImage(tileUrl); // Pass to memory cache diff --git a/tim/prune/gui/map/ScaleBar.java b/tim/prune/gui/map/ScaleBar.java index fdd2949..3f3f848 100644 --- a/tim/prune/gui/map/ScaleBar.java +++ b/tim/prune/gui/map/ScaleBar.java @@ -10,7 +10,7 @@ import tim.prune.config.ColourScheme; import tim.prune.config.Config; /** - * Class to show a scale bar on the main map of Prune + * Class to show a scale bar on the main map of GpsPrune */ public class ScaleBar extends JPanel { diff --git a/tim/prune/gui/profile/AltitudeData.java b/tim/prune/gui/profile/AltitudeData.java index 7f2e10f..f92046a 100644 --- a/tim/prune/gui/profile/AltitudeData.java +++ b/tim/prune/gui/profile/AltitudeData.java @@ -30,28 +30,35 @@ public class AltitudeData extends ProfileData initArrays(); _hasData = false; _altitudeFormat = Altitude.Format.NO_FORMAT; - if (_track != null) { + if (_track != null) + { for (int i=0; i<_track.getNumPoints(); i++) { - DataPoint point = _track.getPoint(i); - if (point != null && point.hasAltitude()) + try { - // Point has an altitude - if it's the first one, use its format - if (_altitudeFormat == Altitude.Format.NO_FORMAT) + DataPoint point = _track.getPoint(i); + if (point != null && point.hasAltitude()) { - _altitudeFormat = point.getAltitude().getFormat(); - _minValue = _maxValue = point.getAltitude().getValue(); + // Point has an altitude - if it's the first one, use its format + if (_altitudeFormat == Altitude.Format.NO_FORMAT) + { + _altitudeFormat = point.getAltitude().getFormat(); + _minValue = _maxValue = point.getAltitude().getValue(); + } + // Store the value and maintain max and min values + double value = point.getAltitude().getValue(_altitudeFormat); + _pointValues[i] = value; + if (value < _minValue) {_minValue = value;} + if (value > _maxValue) {_maxValue = value;} + + _hasData = true; + _pointHasData[i] = true; } - // Store the value and maintain max and min values - double value = point.getAltitude().getValue(_altitudeFormat); - _pointValues[i] = value; - if (value < _minValue) {_minValue = value;} - if (value > _maxValue) {_maxValue = value;} - - _hasData = true; - _pointHasData[i] = true; + else _pointHasData[i] = false; } - else _pointHasData[i] = false; + catch (ArrayIndexOutOfBoundsException obe) + {} // must be due to the track size changing during calculation + // assume that a redraw will be triggered } } } diff --git a/tim/prune/jpeg/ExternalExifLibrary.java b/tim/prune/jpeg/ExternalExifLibrary.java index cff2346..0d94f03 100644 --- a/tim/prune/jpeg/ExternalExifLibrary.java +++ b/tim/prune/jpeg/ExternalExifLibrary.java @@ -5,6 +5,7 @@ import java.io.File; import com.drew.lang.Rational; import com.drew.metadata.Directory; import com.drew.metadata.Metadata; +import com.drew.metadata.MetadataException; import com.drew.metadata.exif.ExifDirectory; import com.drew.metadata.exif.ExifReader; import com.drew.metadata.exif.GpsDirectory; @@ -12,7 +13,7 @@ import com.drew.metadata.exif.GpsDirectory; /** * Class to act as a gateway into the external exif library functions. * This should be the only class with dependence on the lib-metadata-extractor-java - * classes (which are NOT delivered with Prune). + * classes (which are NOT delivered with GpsPrune). * This class will not compile without this extra dependency (but is not required if * the ExifGateway uses the InternalExifLibrary instead). * Should not be included if the internal library will be used (from jpeg.drew package). @@ -60,16 +61,29 @@ public class ExternalExifLibrary implements ExifLibrary data.setAltitudeRef(altRef); } - // Timestamp and datestamp (if present) - final int TAG_GPS_DATESTAMP = 0x001d; - if (gpsdir.containsTag(GpsDirectory.TAG_GPS_TIME_STAMP) && gpsdir.containsTag(TAG_GPS_DATESTAMP)) + try { - Rational[] times = gpsdir.getRationalArray(GpsDirectory.TAG_GPS_TIME_STAMP); - data.setGpsTimestamp(new int[] {times[0].intValue(), times[1].intValue(), - times[2].intValue()}); - Rational[] dates = gpsdir.getRationalArray(TAG_GPS_DATESTAMP); - if (dates != null) { - data.setGpsDatestamp(new int[] {dates[0].intValue(), dates[1].intValue(), dates[2].intValue()}); + // Timestamp and datestamp (if present) + final int TAG_GPS_DATESTAMP = 0x001d; + if (gpsdir.containsTag(GpsDirectory.TAG_GPS_TIME_STAMP) && gpsdir.containsTag(TAG_GPS_DATESTAMP)) + { + Rational[] times = gpsdir.getRationalArray(GpsDirectory.TAG_GPS_TIME_STAMP); + data.setGpsTimestamp(new int[] {times[0].intValue(), times[1].intValue(), + times[2].intValue()}); + Rational[] dates = gpsdir.getRationalArray(TAG_GPS_DATESTAMP); + if (dates != null) { + data.setGpsDatestamp(new int[] {dates[0].intValue(), dates[1].intValue(), dates[2].intValue()}); + } + } + } + catch (MetadataException me) {} // ignore, use other tags instead + + // Image bearing (if present) + if (gpsdir.containsTag(GpsDirectory.TAG_GPS_IMG_DIRECTION) && gpsdir.containsTag(GpsDirectory.TAG_GPS_IMG_DIRECTION_REF)) + { + Rational bearing = gpsdir.getRational(GpsDirectory.TAG_GPS_IMG_DIRECTION); + if (bearing != null) { + data.setBearing(bearing.doubleValue()); } } } @@ -108,6 +122,7 @@ public class ExternalExifLibrary implements ExifLibrary } catch (Exception e) { // Exception reading metadata, just ignore it + //System.err.println("Error: " + e.getClass().getName() + " - " + e.getMessage()); } return data; } diff --git a/tim/prune/jpeg/JpegData.java b/tim/prune/jpeg/JpegData.java index 62e54af..8a25f6d 100644 --- a/tim/prune/jpeg/JpegData.java +++ b/tim/prune/jpeg/JpegData.java @@ -21,6 +21,7 @@ public class JpegData private String _digitizedTimestamp = null; private int _orientationCode = -1; private byte[] _thumbnail = null; + private double _bearing = -1.0; private ArrayList _errors = null; @@ -145,6 +146,15 @@ public class JpegData } } + /** + * Set the bearing (0 - 360) + * @param inBearing bearing in degrees + */ + public void setBearing(double inBearing) + { + _bearing = inBearing; + } + /** @return latitude ref as char */ public char getLatitudeRef() { return _latitudeRef; } /** @return latitude as array of 3 Rationals */ @@ -169,6 +179,8 @@ public class JpegData public String getOriginalTimestamp() { return _originalTimestamp; } /** @return digitized timestamp as string */ public String getDigitizedTimestamp() { return _digitizedTimestamp; } + /** @return bearing in degrees or -1 */ + public double getBearing() { return _bearing; } /** * Set the thumbnail diff --git a/tim/prune/jpeg/drew/ExifReader.java b/tim/prune/jpeg/drew/ExifReader.java index 384778d..08f3012 100644 --- a/tim/prune/jpeg/drew/ExifReader.java +++ b/tim/prune/jpeg/drew/ExifReader.java @@ -85,6 +85,8 @@ public class ExifReader private static final int TAG_THUMBNAIL_LENGTH = 0x0202; /** Orientation of image */ private static final int TAG_ORIENTATION = 0x0112; + /** Bearing direction of image */ + private static final int TAG_BEARING = 0x0011; /** @@ -369,7 +371,8 @@ public class ExifReader if (dates != null) { inMetadata.setGpsDatestamp(new int[] {dates[0].intValue(), dates[1].intValue(), dates[2].intValue()}); } - else { + else + { // Not in rational array format, but maybe as String? String date = readString(inTagValueOffset, inFormatCode, inComponentCount); if (date != null && date.length() == 10) { @@ -378,6 +381,12 @@ public class ExifReader } } break; + case TAG_BEARING: + Rational val = readRational(inTagValueOffset, inFormatCode, inComponentCount); + if (val != null) { + inMetadata.setBearing(val.doubleValue()); + } + break; default: // ignore all other tags } } diff --git a/tim/prune/lang/prune-texts_af.properties b/tim/prune/lang/prune-texts_af.properties index 2c0b6ce..58618b8 100644 --- a/tim/prune/lang/prune-texts_af.properties +++ b/tim/prune/lang/prune-texts_af.properties @@ -1,4 +1,4 @@ -# Text entries for the Prune application +# Text entries for the GpsPrune application # Afrikaans entries as extra # Menu entries @@ -6,32 +6,30 @@ menu.file=L\u00eaer menu.file.addphotos=Voeg Fotos By menu.file.save=Stoor menu.file.exit=Gaan Uit +menu.track=Spoor menu.track.undo=Herroep menu.track.clearundo=Herroep Lys Skoonmaak -menu.point.editpoint=Redigeer Punt -menu.point.deletepoint=Punt Uitvee -menu.range.deleterange=Reeks Uitvee menu.track.deletemarked=Gemerkde Punt Uitvee -menu.range.interpolate=Interpoleer -menu.range.average=Gemiddelde Seleksie -menu.range.reverse=Reeks Omkeer -menu.range.mergetracksegments=Saamvoeg van spoor segmente menu.track.rearrange=Herrangskik bakens menu.track.rearrange.start=Bakens na begin van l\u00eaer menu.track.rearrange.end=Bakens na einde van l\u00eaer menu.track.rearrange.nearest=Beweeg elk na naaste spoor punt -menu.range.cutandmove=Sny en skuif seleksie menu.range=Reeks -menu.point=Punt menu.range.all=Selekteer Alles menu.range.none=Selekteer Niks menu.range.start=Stel Reeks Begin menu.range.end=Stel Reeks Einde +menu.range.deleterange=Reeks Uitvee +menu.range.interpolate=Interpoleer +menu.range.average=Gemiddelde Seleksie +menu.range.reverse=Reeks Omkeer +menu.range.mergetracksegments=Saamvoeg van spoor segmente +menu.range.cutandmove=Sny en skuif seleksie +menu.point=Punt +menu.point.editpoint=Redigeer Punt +menu.point.deletepoint=Punt Uitvee menu.photo=Foto menu.photo.saveexif=Stoor na EXIF -function.connecttopoint=Las foto by huidige punt -function.disconnectfrompoint=Ontkoppel vanaf huidige punt -function.removephoto=Verwyder foto menu.view=Kyk menu.view.browser=Kaart in werf blaaier menu.view.browser.google=Google Kaarte @@ -49,6 +47,7 @@ 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 +menu.map.showscalebar=Wys SkalleerStaaf # Alt keys for menus altkey.menu.file=L @@ -75,16 +74,32 @@ function.sendtogps=Stuur van GPS data function.exportkml=KML Uitvoer function.exportgpx=GPS Uitvoer function.exportpov=POV Uitvoer +function.exportsvg=SVG Uitvoer function.editwaypointname=Redigeer Baken Naam function.compress=Kompakteer spoor function.addtimeoffset=Voeg tyd spruit by +function.addaltitudeoffset=Voeg hoogte spruit by +function.convertnamestotimes=Omskakel baken name na tye function.findwaypoint=Vind Baken +function.pastecoordinates=Enter nuwe koordinate function.charts=Grafieke function.show3d=3D Kyk function.distances=Afstande +function.fullrangedetails=Vol reeks besonderhede function.setmapbg=Stel Kaart agtergrond +function.setpaths=Stel program paaie function.getgpsies=Kry GPS spore +function.duplicatepoint=Dupliseer Punt +function.setcolours=Stel kleure +function.setlanguage=Stel tale +function.connecttopoint=Las foto by huidige punt +function.disconnectfrompoint=Ontkoppel vanaf huidige punt +function.removephoto=Verwyder foto function.correlatephotos=Korreleer Fotos +function.rearrangephotos=Herrangskik fotos +function.rotatephotoleft=Roteer foto links +function.rotatephotoright=Roteer foto regs +function.ignoreexifthumb=Ignoreer EXIF thumbnail function.help=Hulp function.showkeys=Wys Kortpad sleutels function.about=Omtrent Prune @@ -125,6 +140,7 @@ dialog.gpsload.device=Apparaat naam dialog.gpsload.format=Formaat dialog.gpsload.getwaypoints=Laai Bakens dialog.gpsload.gettracks=Laai spore +dialog.gpsload.save=Stoor na l\u00eaer dialog.gpssend.sendwaypoints=Stuur Bakens dialog.gpssend.sendtracks=Stuur Spore dialog.gpssend.trackname=Spoor name @@ -139,13 +155,16 @@ 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.save.notypesselected=Geen punt tipes is geselekteer nie 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.exportkml.trackcolour=Spoor kleur dialog.exportgpx.name=Naam dialog.exportgpx.desc=Beskrywing dialog.exportgpx.includetimestamps=Tydstempel Insluit +dialog.exportgpx.copysource=Kopieer bron xml dialog.exportpov.text=Steutel asseblief parameters in vir POV uitvoer dialog.exportpov.font=Font dialog.exportpov.camerax=Kamera X @@ -172,3 +191,18 @@ 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 +dialog.pointedit.table.field=Veld +dialog.pointedit.table.value=Waarde +dialog.pointedit.table.changed=Verander +dialog.pointnameedit.name=Baken naam +dialog.pointnameedit.uppercase=Hoof letter +dialog.pointnameedit.lowercase=Klein letter +dialog.addtimeoffset.add=Voeg tyd by +dialog.addtimeoffset.subtract=Vat tyd weg +dialog.addtimeoffset.days=Dae +dialog.addtimeoffset.hours=Ure +dialog.addtimeoffset.minutes=Minute +dialog.findwaypoint.search=Soek +dialog.saveexif.title=Stoor Exif +dialog.saveexif.table.status=Status +dialog.saveexif.table.save=Stoor diff --git a/tim/prune/lang/prune-texts_cz.properties b/tim/prune/lang/prune-texts_cz.properties index 37ab637..ae344ca 100644 --- a/tim/prune/lang/prune-texts_cz.properties +++ b/tim/prune/lang/prune-texts_cz.properties @@ -1,9 +1,10 @@ -# Text entries for the Prune application +# Text entries for the GpsPrune application # Czech entries thanks to prot_d # Menu entries menu.file=Soubor menu.file.addphotos=P\u0159idat fotografie +menu.file.recentfiles=Naposledy otev\u0159en\u00e9 menu.file.save=Ulo\u017eit jako text menu.file.exit=Konec menu.track=Trasa @@ -41,6 +42,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.autosave=P\u0159i ukon\u010den\u00ed automaticky ukl\u00e1dat menu.help=Pomoc # Popup menu for map menu.map.zoomin=P\u0159ibl\u00ed\u017eit @@ -75,6 +77,7 @@ shortcut.menu.help.help=P # Functions function.open=Otev\u0159\u00edt soubor +function.importwithgpsbabel=Importovat p\u0159es GPSBabel function.loadfromgps=Na\u010d\u00edst data z GPS function.sendtogps=Poslat data do GPS function.exportkml=Export KML @@ -126,9 +129,10 @@ function.about=O programu function.checkversion=Zkontrolovat existenci nov\u00e9 verze function.saveconfig=Ulo\u017eit nastaven\u00ed function.diskcache=Ulo\u017eit mapy na disk +function.managetilecache=Upravit cache map # Dialogs -dialog.exit.confirm.title=Ukon\u010dit Prune +dialog.exit.confirm.title=Ukon\u010dit GpsPrune dialog.exit.confirm.text=Data nejsou ulo\u017eena. Opravdu chcete ukon\u010dit program? dialog.openappend.title=P\u0159ipojit k na\u010dten\u00fdm dat\u016fm dialog.openappend.text=P\u0159ipojit tato data k ji\u017e na\u010dten\u00fdm dat\u016fm? @@ -189,6 +193,9 @@ dialog.exportgpx.name=N\u00e1zev dialog.exportgpx.desc=Popis dialog.exportgpx.includetimestamps=Ulo\u017eit \u010dasov\u00e9 zna\u010dky dialog.exportgpx.copysource=Zkop\u00edrovat zdrojov\u00e9 xml +dialog.exportgpx.encoding=K\u00f3dov\u00e1n\u00ed +dialog.exportgpx.encoding.system=Implicitn\u00ed dle OS +dialog.exportgpx.encoding.utf8=UTF-8 dialog.exportpov.text=Pros\u00edm vlo\u017ete paramerty exportu do POV dialog.exportpov.font=Font dialog.exportpov.camerax=Kamera X @@ -341,14 +348,16 @@ dialog.compress.wackypoints.paramdesc=Koeficient vzd\u00e1lnosti dialog.compress.singletons.title=Odstran\u011bn\u00ed osamocen\u00fdch bod\u016f dialog.compress.singletons.paramdesc=Koeficient vzd\u00e1lenosti dialog.compress.duplicates.title=Odstran\u011bn\u00ed zdvojen\u00fdch bod\u016f +dialog.compress.douglaspeucker.title=Douglasova-Peuckerova komprese +dialog.compress.douglaspeucker.paramdesc=Povolen\u00e1 odchylka dialog.compress.summarylabel=Bod\u016f ke smaz\u00e1n\u00ed dialog.pastecoordinates.desc=Zadejte sou\u0159adnice dialog.pastecoordinates.coords=Sou\u0159adnice dialog.pastecoordinates.nothingfound=Pros\u00edm ov\u011b\u0159te sou\u0159adnice a zkuste znovu -dialog.help.help=V\u00edce informac\u00ed v\u010detn\u011b manu\u00e1l\u016f (bohu\u017eel nikoli v \u010de\u0161tin\u011b) naleznete na adrese:\n http://activityworkshop.net/software/prune/ +dialog.help.help=V\u00edce informac\u00ed v\u010detn\u011b manu\u00e1l\u016f (bohu\u017eel nikoli v \u010de\u0161tin\u011b) naleznete na adrese:\n http://activityworkshop.net/software/gpsprune/ dialog.about.version=Verze dialog.about.build=Build -dialog.about.summarytext1=Prune je program k na\u010d\u00edt\u00e1n\u00ed, zobrazov\u00e1n\u00ed a editaci dat z navigac\u00ed GPS. +dialog.about.summarytext1=GpsPrune je program k na\u010d\u00edt\u00e1n\u00ed, zobrazov\u00e1n\u00ed a editaci dat z navigac\u00ed GPS. dialog.about.summarytext2=Je vyd\u00e1n pod licenc\u00ed GNU GPL, tak\u017ee je zdarma a voln\u011b k u\u017e\u00edv\u00e1n\u00ed a vylep\u0161ov\u00e1n\u00ed.
Kop\u00edrov\u00e1n\u00ed, redistribuce a \u00fapravy jsou povoleny a podporov\u00e1ny
podle podm\u00ednek popsan\u00fdch v souboru licence.txt. dialog.about.summarytext3=V\u00edce informac\u00ed v\u010detn\u011b manu\u00e1l\u016f (bohu\u017eel nikoli v \u010de\u0161tin\u011b) naleznete
na adrese: http://activityworkshop.net/. dialog.about.languages=Dostupn\u00e9 jazyky @@ -379,12 +388,12 @@ dialog.about.credits.othertools=Dal\u0161\u00ed n\u00e1stroje dialog.about.credits.thanks=D\u011bkujeme dialog.about.readme=Readme dialog.checkversion.error=\u010c\u00edslo verze se nepoda\u0159ilo zkontrolovat.\nPros\u00edm ov\u011b\u0159te p\u0159ipojen\u00ed k internetu. -dialog.checkversion.uptodate=Pou\u017e\u00edv\u00e1te posledn\u00ed verzi Prune. -dialog.checkversion.newversion1=Nov\u00e1 verze Prune je u\u017e dostupn\u00e1! Posledn\u00ed verze m\u00e1 \u010d\u00edslo +dialog.checkversion.uptodate=Pou\u017e\u00edv\u00e1te posledn\u00ed verzi GpsPrune. +dialog.checkversion.newversion1=Nov\u00e1 verze GpsPrune je u\u017e dostupn\u00e1! Posledn\u00ed verze m\u00e1 \u010d\u00edslo dialog.checkversion.newversion2=. dialog.checkversion.releasedate1=Tato verze byla vyd\u00e1na dialog.checkversion.releasedate2=. -dialog.checkversion.download=Novou verzi m\u016f\u017eete st\u00e1hnout na adrese http://activityworkshop.net/software/prune/download.html. +dialog.checkversion.download=Novou verzi m\u016f\u017eete st\u00e1hnout na adrese http://activityworkshop.net/software/gpsprune/download.html. dialog.keys.intro=M\u00edsto my\u0161i m\u016f\u017eete pou\u017e\u00edvat n\u00e1sleduj\u00edc\u00ed kl\u00e1vesov\u00e9 zkratky dialog.keys.keylist=
\u0160ipkyPosunout mapu vlevo, vpravo, nahoru, dol\u016f
Ctrl + \u0161ipka vlevo, vpravoVybrat p\u0159edchoz\u00ed nebo n\u00e1sleduj\u00edc\u00ed bod
Ctrl + \u0161ipka nahoru, dol\u016fP\u0159ibl\u00ed\u017eit, odd\u00e1lit
Ctrl + PgUp, PgDownVybrat p\u0159edchoz\u00ed, n\u00e1sleduj\u00edc\u00ed \u010d\u00e1st trasy
Ctrl + Home, EndVybrat prvn\u00ed, posledn\u00ed bod
DelSmazat aktu\u00e1ln\u00ed bod
dialog.keys.normalmodifier=Ctrl @@ -409,6 +418,7 @@ dialog.saveconfig.prune.kmzimageheight=V\u00fd\u0161ka bitmapy KMZ dialog.saveconfig.prune.colourscheme=Barevn\u00e9 sch\u00e9ma dialog.saveconfig.prune.linewidth=Tlou\u0161\u0165ka \u010d\u00e1ry dialog.saveconfig.prune.kmltrackcolour=Barva trasy v KML +dialog.saveconfig.prune.autosavesettings=Mo\u017enosti ukl\u00e1d\u00e1n\u00ed dialog.setpaths.intro=Je-li to t\u0159eba, m\u016f\u017eete nastavit cesty k extern\u00edm aplikac\u00edm: dialog.setpaths.found=Cesta nalezena? dialog.addaltitude.noaltitudes=Vybran\u00e9 rozmez\u00ed neobsahuje nadmo\u0159skou v\u00fd\u0161ku @@ -428,23 +438,35 @@ dialog.colourchooser.red=\u010cerven\u00e1 dialog.colourchooser.green=Zelen\u00e1 dialog.colourchooser.blue=Modr\u00e1 dialog.setlanguage.firstintro=M\u016f\u017eete bu\u010f zvolit jeden z vypsan\u00fdch jazyk\u016f,

nebo vybrat textov\u00fd soubor -dialog.setlanguage.secondintro=Aby do\u0161lo ke zm\u011bn\u011b jazyka, je t\u0159eba ulo\u017eit nastaven\u00ed

a potom restartovat program Prune. +dialog.setlanguage.secondintro=Aby do\u0161lo ke zm\u011bn\u011b jazyka, je t\u0159eba ulo\u017eit nastaven\u00ed

a potom restartovat program GpsPrune. dialog.setlanguage.language=Jazyk dialog.setlanguage.languagefile=Jazykov\u00fd soubor -dialog.setlanguage.endmessage=Aby do\u0161lo ke zm\u011bn\u011b jazyka, nyn\u00ed ulo\u017ete nastaven\u00ed\na spus\u0165te Prune nanovo. +dialog.setlanguage.endmessage=Aby do\u0161lo ke zm\u011bn\u011b jazyka, nyn\u00ed ulo\u017ete nastaven\u00ed\na spus\u0165te GpsPrune nanovo. +dialog.setlanguage.endmessagewithautosave=Aby byla dokon\u010dena zm\u011bna jazyka, pros\u00edm restartujte program. dialog.diskcache.save=Ukl\u00e1dat mapov\u00e9 podklady na disk dialog.diskcache.dir=Adres\u00e1\u0159 s cache dialog.diskcache.createdir=Vytvo\u0159it adres\u00e1\u0159 dialog.diskcache.nocreate=Adres\u00e1\u0159 nebyl vytvo\u0159en +dialog.diskcache.table.path=Cesta +dialog.diskcache.table.usedby=Pou\u017e\u00edv\u00e1 +dialog.diskcache.table.zoom=Zv\u011bt\u0161en\u00ed +dialog.diskcache.table.tiles=Dla\u017edic +dialog.diskcache.table.megabytes=Megabyt\u016f +dialog.diskcache.tileset=Mapov\u00fd podklad +dialog.diskcache.tileset.multiple=v\u00edce sad +dialog.diskcache.deleteold=Smazat star\u00e9 soubory +dialog.diskcache.deleteall=Smazat v\u0161echny soubory +dialog.diskcache.deleted1=Smaz\u00e1no +dialog.diskcache.deleted2=soubor\u016f z cache dialog.deletefieldvalues.intro=Vyberte pole, kter\u00e9 se m\u00e1 z aktu\u00e1ln\u00edho rozmez\u00ed odstranit dialog.setlinewidth.text=Zvolte tlou\u0161\u0165ku \u010d\u00e1ry, kterou se nakresl\u00ed trasa (1-4) dialog.downloadosm.desc=Potvr\u010fte, \u017ee se maj\u00ed k dan\u00e9 oblasti st\u00e1hnout data OSM: dialog.searchwikipedianames.search=Vyhledat: # 3d window -dialog.3d.title=Trojrozm\u011brn\u00e9 zobrazen\u00ed Prune +dialog.3d.title=Trojrozm\u011brn\u00e9 zobrazen\u00ed GpsPrune dialog.3d.altitudefactor=Faktor zd\u016frazn\u011bn\u00ed v\u00fd\u0161ky -dialog.3dlines.title=Linky m\u0159\u00ed\u017eky Prune +dialog.3dlines.title=Linky m\u0159\u00ed\u017eky GpsPrune dialog.3dlines.empty=Nejsou \u017e\u00e1dn\u00e9 linky k zobrazen\u00ed! dialog.3dlines.intro=Toto jsou linky m\u0159\u00ed\u017eky trojrozm\u011brn\u00e9ho zobrazen\u00ed @@ -516,6 +538,7 @@ button.resettodefaults=Resetovat button.browse=Proch\u00e1zet... button.addnew=P\u0159idat nov\u00e9 button.delete=Smazat +button.manage=Upravit # File types filetype.txt=soubory TXT @@ -567,6 +590,7 @@ details.lists.audio=Audionahr\u00e1vky details.photodetails=Detaily fotografie details.nophoto=Fotografie nevybr\u00e1na details.photo.loading=Na\u010d\u00edt\u00e1m +details.photo.bearing=Azimut details.media.connected=P\u0159ipojeno details.audiodetails=Detaily audionahr\u00e1vky details.noaudio=Audionahr\u00e1vka nevybr\u00e1na @@ -590,6 +614,7 @@ fieldname.movingdistance=Najeto fieldname.duration=Celkov\u00fd \u010das fieldname.speed=Rychlost fieldname.verticalspeed=Vertik. rychlost +fieldname.description=Popis # Measurement units units.original=P\u016fvodn\u00ed @@ -684,10 +709,13 @@ error.3d=P\u0159i trojrozm\u011brn\u00e9m zobrazen\u00ed do\u0161lo k chyb\u011b error.readme.notfound=Nenalezen soubor readme error.osmimage.dialogtitle=Chyba p\u0159i na\u010d\u00edt\u00e1n\u00ed mapov\u00fdch podklad\u016f error.osmimage.failed=Selhalo na\u010dten\u00ed mapov\u00fdch podklad\u016f. Pros\u00edm zkontrolujte p\u0159ipojen\u00ed k internetu. -error.language.wrongfile=Vybran\u00fd soubor nevypad\u00e1 jako jazykov\u00fd soubor pro Prune +error.language.wrongfile=Vybran\u00fd soubor nevypad\u00e1 jako jazykov\u00fd soubor pro GpsPrune error.convertnamestotimes.nonames=N\u00e1zvy nemohou b\u00fdt p\u0159evedeny na \u010dasov\u00e9 zna\u010dky error.lookupsrtm.nonefound=Pro tyto body nen\u00ed k dispozici informace o nadmo\u0159sk\u00e9 v\u00fd\u0161ce error.lookupsrtm.nonerequired=U v\u0161ech bod\u016f u\u017e je informaci o v\u00fd\u0161ce, tak\u017ee nen\u00ed co dohled\u00e1vat error.gpsies.uploadnotok=Server gpsies vr\u00e1til hl\u00e1\u0161en\u00ed error.gpsies.uploadfailed=Chyba - nepoda\u0159ilo se nahr\u00e1t data. error.playaudiofailed=Nepoda\u0159ilo se p\u0159ehr\u00e1t zvukov\u00fd soubor. +error.cache.notthere=Nepoda\u0159ilo se nal\u00e9zt adres\u00e1\u0159 s cache map. +error.cache.empty=Adres\u00e1\u0159 s cache map je pr\u00e1zdn\u00fd. +error.cache.cannotdelete=Nelze smazat soubory map. diff --git a/tim/prune/lang/prune-texts_de.properties b/tim/prune/lang/prune-texts_de.properties index a2a45ba..6e102d4 100644 --- a/tim/prune/lang/prune-texts_de.properties +++ b/tim/prune/lang/prune-texts_de.properties @@ -1,14 +1,15 @@ -# Text entries for the Prune application +# Text entries for the GpsPrune application # German entries as extra # Menu entries menu.file=Datei menu.file.addphotos=Fotos laden +menu.file.recentfiles=Zuletzt verwendete Dateien menu.file.save=Als Text Speichern menu.file.exit=Beenden menu.track=Track menu.track.undo=R\u00fcckg\u00e4ngig -menu.track.clearundo=Liste der letzten Änderungen l\u00f6schen +menu.track.clearundo=Liste der letzten \u00c4nderungen l\u00f6schen menu.track.deletemarked=Komprimierte Punkte l\u00f6schen menu.track.rearrange=Wegpunkte reorganisieren menu.track.rearrange.start=Alle Wegpunkte zum Anfang @@ -30,15 +31,13 @@ menu.point.editpoint=Punkt bearbeiten menu.point.deletepoint=Punkt l\u00f6schen menu.photo=Foto menu.photo.saveexif=Exif Daten speichern -function.connecttopoint=Mit Punkt verkn\u00fcpfen -function.disconnectfrompoint=Vom Punkt trennen -function.removephoto=Foto entfernen menu.audio=Audio menu.view=Ansicht menu.view.showsidebars=Seitenleisten anzeigen menu.view.browser=Karte in Browser menu.settings=Einstellungen menu.settings.onlinemode=Karten aus dem Internet laden +menu.settings.autosave=Einstellungen automatisch speichern menu.help=Hilfe # Popup menu for map menu.map.zoomin=Hineinzoomen @@ -73,6 +72,7 @@ shortcut.menu.help.help=H # Functions function.open=Datei \u00f6ffnen +function.importwithgpsbabel=Datei mit GPSBabel importieren function.loadfromgps=Vom GPS laden function.sendtogps=zum GPS schicken function.exportkml=KML exportieren @@ -84,7 +84,7 @@ function.compress=Track komprimieren function.addtimeoffset=Zeitverschiebung aufrechnen function.addaltitudeoffset=H\u00f6henverschiebung aufrechnen function.convertnamestotimes=Wegpunktenamen in Zeitstempel umwandeln -function.deletefieldvalues=Werte eines Feldes löschen +function.deletefieldvalues=Werte eines Feldes l\u00f6schen function.findwaypoint=Wegpunkt finden function.pastecoordinates=Neue Koordinaten eingeben function.charts=Diagramme @@ -97,13 +97,16 @@ function.setpaths=Programmpfade setzen function.getgpsies=Gpsies Tracks holen function.uploadgpsies=Daten zum Gpsies hochladen function.lookupsrtm=H\u00f6hendaten von SRTM holen -function.getwikipedia=Wikipediaartikeln in der N\u00e4he nachschlagen +function.getwikipedia=Wikipediaartikel in der N\u00e4he nachschlagen function.searchwikipedianames=Wikipedia mit Name durchsuchen function.downloadosm=OSM Daten f\u00fcr dieses Gebiet herunterladen function.duplicatepoint=Punkt verdoppeln function.setcolours=Farben einstellen -function.setlinewidth=Liniedicke einstellen +function.setlinewidth=Liniendicke einstellen function.setlanguage=Sprache einstellen +function.connecttopoint=Mit Punkt verkn\u00fcpfen +function.disconnectfrompoint=Vom Punkt trennen +function.removephoto=Foto entfernen function.correlatephotos=Fotos korrelieren function.rearrangephotos=Fotos reorganisieren function.rotatephotoleft=Foto nach Links drehen @@ -117,13 +120,14 @@ function.playaudio=Audiodatei abspielen function.stopaudio=Abspielen abbrechen function.help=Hilfe function.showkeys=Tastenkombinationen anzeigen -function.about=\u00dcber Prune +function.about=\u00dcber GpsPrune function.checkversion=Nach neuen Versionen suchen function.saveconfig=Einstellungen speichern function.diskcache=Karten auf Festplatte speichern +function.managetilecache=Kartenkacheln verwalten # Dialogs -dialog.exit.confirm.title=Prune beenden +dialog.exit.confirm.title=GpsPrune beenden dialog.exit.confirm.text=Ihre Daten wurden nicht gespeichert. Wollen Sie das Programm trotzdem beenden? dialog.openappend.title=Daten anh\u00e4ngen oder ersetzen dialog.openappend.text=Diese Daten an die aktuellen Daten anh\u00e4ngen? @@ -142,9 +146,9 @@ dialog.delimiter.tab=Tab dialog.delimiter.space=Leerzeichen dialog.delimiter.semicolon=Strichpunkt ; dialog.delimiter.other=Andere -dialog.openoptions.deliminfo.records=Aufnahmen, mit +dialog.openoptions.deliminfo.records=Datens\u00e4tze, mit dialog.openoptions.deliminfo.fields=Feldern -dialog.openoptions.deliminfo.norecords=Keine Rekords +dialog.openoptions.deliminfo.norecords=Keine Datens\u00e4tze dialog.openoptions.altitudeunits=H\u00f6he Ma\u00dfeinheiten dialog.open.contentsdoubled=Diese Datei enth\u00e4lt zwei Kopien von jedem Punkt,\neinmal als Waypoint und einmal als Trackpunkt. dialog.selecttracks.intro=W\u00e4hlen Sie den Track oder die Tracks aus, die Sie laden m\u00f6chten @@ -184,6 +188,9 @@ dialog.exportgpx.name=Name dialog.exportgpx.desc=Beschreibung dialog.exportgpx.includetimestamps=Zeitstempel mit exportieren dialog.exportgpx.copysource=Xml von Quelle kopieren +dialog.exportgpx.encoding=Enkodierung +dialog.exportgpx.encoding.system=System +dialog.exportgpx.encoding.utf8=UTF-8 dialog.exportpov.text=Geben Sie die Parameter f\u00fcr den POV Export ein dialog.exportpov.font=Font dialog.exportpov.camerax=Kamera X @@ -193,10 +200,10 @@ dialog.exportpov.modelstyle=Modellstil dialog.exportpov.ballsandsticks=B\u00e4lle und Stangen dialog.exportpov.tubesandwalls=R\u00f6hren und W\u00e4nde dialog.exportpov.warningtracksize=Dieser Track hat sehr viele Punkte, die Java3D vielleicht nicht bearbeiten kann.\nM\u00f6chten Sie den Vorgang trotzdem fortsetzen? -dialog.exportsvg.text=Wählen Sie die Parameter für den SVG Export aus -dialog.exportsvg.phi=Richtungswinkel \u03D5 -dialog.exportsvg.theta=Neigungswinkel \u03B8 -dialog.exportsvg.gradients=Farbverläufe verwenden +dialog.exportsvg.text=W\u00e4hlen Sie die Parameter f\u00fcr den SVG Export aus +dialog.exportsvg.phi=Richtungswinkel \u03d5 +dialog.exportsvg.theta=Neigungswinkel \u03b8 +dialog.exportsvg.gradients=Farbverl\u00e4ufe verwenden dialog.pointtype.desc=Folgende Punkttypen speichern: dialog.pointtype.track=Trackpunkte dialog.pointtype.waypoint=Wegpunkte @@ -277,7 +284,7 @@ dialog.gpsies.nonefound=Keine Tracks gefunden dialog.gpsies.username=Gpsies Username dialog.gpsies.password=Gpsies Passwort dialog.gpsies.keepprivate=Track privat halten -dialog.gpsies.confirmopenpage=Webseite für den hochgeladenen Track öffnen? +dialog.gpsies.confirmopenpage=Webseite f\u00fcr den hochgeladenen Track \u00f6ffnen? dialog.gpsies.activities=Aktivit\u00e4ten dialog.gpsies.activity.trekking=Wandern dialog.gpsies.activity.walking=Walking @@ -336,14 +343,16 @@ dialog.compress.wackypoints.paramdesc=Distanzfaktor dialog.compress.singletons.title=Singletons (isolierte Punkte) entfernen dialog.compress.singletons.paramdesc=Distanzfaktor dialog.compress.duplicates.title=Duplikate entfernen +dialog.compress.douglaspeucker.title=Douglas-Peucker Komprimierung +dialog.compress.douglaspeucker.paramdesc=Span Faktor dialog.compress.summarylabel=Punkte zu entfernen dialog.pastecoordinates.desc=Geben Sie die Koordinaten ein dialog.pastecoordinates.coords=Koordinaten dialog.pastecoordinates.nothingfound=Bitte pr\u00fcfen Sie die Koordinaten und versuchen Sie es nochmals -dialog.help.help=Weitere Informationen und Benutzeranleitungen finden Sie unter\n http://activityworkshop.net/software/prune/ +dialog.help.help=Weitere Informationen und Benutzeranleitungen finden Sie unter\n http://activityworkshop.net/software/gpsprune/ dialog.about.version=Version dialog.about.build=Build -dialog.about.summarytext1=Prune ist ein Programm zum Laden, Darstellen und Editieren von Daten von GPS Ger\u00e4ten. +dialog.about.summarytext1=GpsPrune ist ein Programm zum Laden, Darstellen und Editieren von Daten von GPS Ger\u00e4ten. dialog.about.summarytext2=Es wird unter der Gnu GPL zur Verf\u00fcgung gestellt, zum freien, kostenlosen und offenen Gebrauch und zur Weiterentwicklung.
Kopieren, Weiterverbreitung und Ver\u00e4nderungen 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 Informationen und Bedienungsanleitungen. dialog.about.languages=Verf\u00fcgbare Sprachen @@ -364,7 +373,7 @@ dialog.about.systeminfo.exiflib.external.failed=Extern (nicht gefunden) dialog.about.yes=Ja dialog.about.no=Nein dialog.about.credits=Credits -dialog.about.credits.code=Prune Code geschrieben von +dialog.about.credits.code=GpsPrune Code geschrieben von dialog.about.credits.exifcode=Exif Code von dialog.about.credits.icons=Einige Bilder von dialog.about.credits.translators=Dolmetscher @@ -374,12 +383,12 @@ dialog.about.credits.othertools=Andere Programme dialog.about.credits.thanks=Dank an dialog.about.readme=Liesmich dialog.checkversion.error=Die Versionnummer konnte nicht ermittelt werden.\nBitte pr\u00fcfen Sie die Internet Verbindung. -dialog.checkversion.uptodate=Sie haben schon die neueste Version von Prune. -dialog.checkversion.newversion1=Eine neue Version vom Prune ist jetzt verf\u00fcgbar! Die neue Version ist Version +dialog.checkversion.uptodate=Sie haben schon die neueste Version von GpsPrune. +dialog.checkversion.newversion1=Eine neue Version vom GpsPrune ist jetzt verf\u00fcgbar! Die neue Version ist Version dialog.checkversion.newversion2=. dialog.checkversion.releasedate1=Diese neue Version ist am dialog.checkversion.releasedate2=ver\u00f6ffentlicht worden. -dialog.checkversion.download=Um die neue Version herunterzuladen, gehen Sie zu http://activityworkshop.net/software/prune/download.html. +dialog.checkversion.download=Um die neue Version herunterzuladen, gehen Sie zu http://activityworkshop.net/software/gpsprune/download.html. dialog.keys.intro=Anstelle der Maus k\u00f6nnen Sie folgende Tastenkombinationen nutzen dialog.keys.keylist=
Pfeil TastenKarte verschieben
Strg + links, rechts PfeilVorherigen oder n\u00e4chsten Punkt markieren
Strg + auf, abw\u00e4rts PfeilEin- oder Auszoomen
Strg + Bild auf, abVorherigen oder n\u00e4chsten Segment markieren
Strg + Pos1, EndeErsten oder letzten Punkt markieren
EntfAktuellen Punkt entfernen
dialog.keys.normalmodifier=Strg @@ -404,6 +413,7 @@ dialog.saveconfig.prune.kmzimageheight=Bildh\u00f6he in KMZ dialog.saveconfig.prune.colourscheme=Farbschema dialog.saveconfig.prune.linewidth=Liniedicke dialog.saveconfig.prune.kmltrackcolour=KML Trackfarbe +dialog.saveconfig.prune.autosavesettings=Einstellungen speichern dialog.setpaths.intro=Sie k\u00f6nnen hier die Pfade f\u00fcr externe Applikationen setzen: dialog.setpaths.found=Pfad gefunden? dialog.addaltitude.noaltitudes=Der markierte Bereich enth\u00e4lt keine H\u00f6henangaben @@ -423,23 +433,35 @@ dialog.colourchooser.red=Rot dialog.colourchooser.green=Gr\u00fcn dialog.colourchooser.blue=Blau dialog.setlanguage.firstintro=Sie k\u00f6nnen entweder eine von den mitgelieferten Sprachen

oder eine Text-Datei ausw\u00e4hlen. -dialog.setlanguage.secondintro=Sie m\u00fcssen Ihre Einstellungen speichern und dann

Prune neu starten um die Sprache zu \u00e4ndern. +dialog.setlanguage.secondintro=Sie m\u00fcssen Ihre Einstellungen speichern und dann

GpsPrune neu starten um die Sprache zu \u00e4ndern. dialog.setlanguage.language=Sprache dialog.setlanguage.languagefile=Sprachdatei -dialog.setlanguage.endmessage=Speichern Sie nun Ihre Einstellungen und starten Sie Prune neu\num die neue Sprache zu verwenden. +dialog.setlanguage.endmessage=Speichern Sie nun Ihre Einstellungen und starten Sie GpsPrune neu\num die neue Sprache zu verwenden. +dialog.setlanguage.endmessagewithautosave=Starten Sie GpsPrune neu um die neue Sprache zu verwenden. dialog.diskcache.save=Karten auf Festplatte speichern dialog.diskcache.dir=Kartenordner dialog.diskcache.createdir=Ordner anlegen dialog.diskcache.nocreate=Ordner wurde nicht angelegt +dialog.diskcache.table.path=Pfad +dialog.diskcache.table.usedby=Anwender +dialog.diskcache.table.zoom=Zoom +dialog.diskcache.table.tiles=Kacheln +dialog.diskcache.table.megabytes=Megabytes +dialog.diskcache.tileset=Ordner +dialog.diskcache.tileset.multiple=mehrere +dialog.diskcache.deleteold=Veraltete Kacheln l\u00f6schen +dialog.diskcache.deleteall=Alle Kacheln l\u00f6schen +dialog.diskcache.deleted1=Es wurden +dialog.diskcache.deleted2=Dateien aus dem Ordner gel\u00f6scht dialog.deletefieldvalues.intro=W\u00e4hlen Sie das Feld aus, die Sie l\u00f6schen m\u00f6chten dialog.setlinewidth.text=Geben Sie die Dicke der Linien ein (1-4) dialog.downloadosm.desc=Best\u00e4tigen um rohe OSM Daten f\u00fcr den Gebiet herunterzuladen: dialog.searchwikipedianames.search=Suche nach: # 3d window -dialog.3d.title=Prune 3D Ansicht -dialog.3d.altitudefactor=Vervielfachungsfaktor für Höhen -dialog.3dlines.title=Prune Gitterlinien +dialog.3d.title=GpsPrune 3D Ansicht +dialog.3d.altitudefactor=Vervielfachungsfaktor f\u00fcr H\u00f6hen +dialog.3dlines.title=GpsPrune Gitterlinien dialog.3dlines.empty=Keine Linien zum Anzeigen! dialog.3dlines.intro=Hier sind die Linien f\u00fcr die 3D Ansicht @@ -467,6 +489,7 @@ confirm.jpegload.multi=Fotos wurden geladen confirm.media.connect=Media verbunden confirm.photo.disconnect=Foto getrennt confirm.audio.disconnect=Audio getrennt +confirm.media.removed=entfernt confirm.correlatephotos.single=Foto wurde korreliert confirm.correlatephotos.multi=Fotos wurden korreliert confirm.createpoint=Punkt erzeugt @@ -474,9 +497,8 @@ confirm.rotatephoto=Foto gedreht confirm.running=In Bearbeitung ... confirm.lookupsrtm1=Es wurden confirm.lookupsrtm2=H\u00f6henwerte gefunden -confirm.deletefieldvalues=Feldwerte gelöscht +confirm.deletefieldvalues=Feldwerte gel\u00f6scht confirm.audioload=Audiodateien geladen -confirm.media.removed=entfernt confirm.correlateaudios.single=Audio wurde korreliert confirm.correlateaudios.multi=Audios wurden korreliert @@ -487,8 +509,8 @@ button.next=Vorw\u00e4rts button.finish=Fertig button.cancel=Abbrechen button.overwrite=\u00dcberschreiben -button.moveup=Nach oben verschieben -button.movedown=Nach unten verschieben +button.moveup=Nach oben +button.movedown=Nach unten button.showlines=Linien anzeigen button.edit=Bearbeiten button.exit=Beenden @@ -511,6 +533,7 @@ button.resettodefaults=Zur\u00fccksetzen button.browse=Durchsuchen... button.addnew=Hinzuf\u00fcgen button.delete=Entfernen +button.manage=Verwalten # File types filetype.txt=TXT Dateien @@ -551,18 +574,19 @@ display.range.time.mins=m display.range.time.hours=h display.range.time.days=T details.range.avespeed=Durchschnittsgeschwindigkeit -details.range.avemovingspeed=Durchschnittsgeschwindigkeit unterwegs +details.range.avemovingspeed=Durchschnittsgeschwindigkeit gleitend details.range.maxspeed=H\u00f6chstgeschwindigkeit details.range.numsegments=Anzahl Abschnitte details.range.pace=Tempo details.range.gradient=Gef\u00e4lle details.lists.waypoints=Wegpunkte details.lists.photos=Fotos +details.lists.audio=Audio details.photodetails=Fotodetails details.nophoto=Kein Foto ausgew\u00e4hlt details.photo.loading=Laden +details.photo.bearing=Richtung details.media.connected=Verbunden -details.lists.audio=Audio details.audiodetails=Audiodetails details.noaudio=Keine Audiodatei ausgew\u00e4hlt details.audio.file=Audiodatei @@ -585,6 +609,7 @@ fieldname.movingdistance=Wegstrecke fieldname.duration=Zeitdauer fieldname.speed=Geschwindigkeit fieldname.verticalspeed=Vertikale Geschwindigkeit +fieldname.description=Beschreibung # Measurement units units.original=Original @@ -636,7 +661,7 @@ undo.createpoint=Punkt erzeugen undo.rotatephoto=Foto umdrehen undo.convertnamestotimes=Namen in Zeitstempel umwandeln undo.lookupsrtm=H\u00f6hendaten von SRTM holen -undo.deletefieldvalues=Feldwerte löschen +undo.deletefieldvalues=Feldwerte l\u00f6schen undo.correlateaudios=Audios korrelieren # Error messages @@ -673,10 +698,13 @@ error.3d=Ein Fehler ist bei der 3D Darstellung aufgetreten error.readme.notfound=Liesmich Datei nicht gefunden error.osmimage.dialogtitle=Laden von Karten-Bildern fehlgeschlagen error.osmimage.failed=Laden von Karten-Bildern fehlgeschlagen. Bitte pr\u00fcfen Sie die Internetverbindung. -error.language.wrongfile=Die ausgew\u00e4hlte Datei scheint keine Sprachdatei f\u00fcr Prune zu sein +error.language.wrongfile=Die ausgew\u00e4hlte Datei scheint keine Sprachdatei f\u00fcr GpsPrune zu sein error.convertnamestotimes.nonames=Es konnten keine Namen umgewandelt werden -error.lookupsrtm.nonefound=Keine H\u00f6hendaten verfügbar für diese Punkte -error.lookupsrtm.nonerequired=Alle Punkte haben schon Höhendaten +error.lookupsrtm.nonefound=Keine H\u00f6hendaten verf\u00fcgbar f\u00fcr diese Punkte +error.lookupsrtm.nonerequired=Alle Punkte haben schon H\u00f6hendaten error.gpsies.uploadnotok=Der Gpsies Server hat geantwortet error.gpsies.uploadfailed=Das Hochladen ist fehlgeschlagen error.playaudiofailed=Das Abspielen der Audiodatei ist fehlgeschlagen +error.cache.notthere=Der Ordner wurde nicht gefunden +error.cache.empty=Der Ordner ist leer +error.cache.cannotdelete=Es konnte keine Kacheln gel\u00f6scht werden diff --git a/tim/prune/lang/prune-texts_de_CH.properties b/tim/prune/lang/prune-texts_de_CH.properties index b4a3cb0..4e6f73f 100644 --- a/tim/prune/lang/prune-texts_de_CH.properties +++ b/tim/prune/lang/prune-texts_de_CH.properties @@ -1,9 +1,10 @@ -# Text entries for the Prune application +# Text entries for the GpsPrune application # Swiss-German entries as extra # Menu entries menu.file=File menu.file.addphotos=Fötelis innätue +menu.file.recentfiles=Letzschti aagluegte Files menu.file.save=Als Text Speichere menu.file.exit=Beände menu.track=Track @@ -38,7 +39,8 @@ menu.view=Aasicht menu.view.showsidebars=Seiteleischten aazeige menu.view.browser=Karte inem Browser menu.settings=Iistellige -menu.settings.onlinemode=Karte uusem Internet lade +menu.settings.onlinemode=Karten uusem Internet lade +menu.settings.autosave=Iistellige automatisch speichere menu.help=Hilfe # Popup menu for map menu.map.zoomin=Innezoome @@ -73,6 +75,7 @@ shortcut.menu.help.help=H # Functions function.open=File öffne +function.importwithgpsbabel=mit GPSBabel importiere function.loadfromgps=uusem GPS lade function.sendtogps=zum GPS schicke function.exportkml=KML exportierä @@ -117,13 +120,14 @@ function.setlinewidth=Liniedicke setz function.setlanguage=Sproch setzä function.help=Hilfe function.showkeys=Tastekombinatione aazeige -function.about=Über Prune +function.about=Über GpsPrune function.checkversion=Pruef nach ne noie Version function.saveconfig=Iistellige speichere -function.diskcache=Karte uufem Disk speichere +function.diskcache=Karten uufem Disk speichere +function.managetilecache=Kartebildli verwolte # Dialogs -dialog.exit.confirm.title=Prune beände +dialog.exit.confirm.title=GpsPrune beände dialog.exit.confirm.text=Ihri Date sind nonig gspeicheret worde. Wend Sie trotzdem s Programm beände? dialog.openappend.title=Date aahänge oder ersätze dialog.openappend.text=Häng diese Date zur aktuelli Daten aa? @@ -184,6 +188,9 @@ dialog.exportgpx.name=Name dialog.exportgpx.desc=Beschriibig dialog.exportgpx.includetimestamps=Au Ziitstämpel dialog.exportgpx.copysource=Xml-Quälle kopierä +dialog.exportgpx.encoding=Enkodierig +dialog.exportgpx.encoding.system=System +dialog.exportgpx.encoding.utf8=UTF-8 dialog.exportpov.text=Gäbet Sie die Parameter ii fürs POV Export dialog.exportpov.font=Font dialog.exportpov.camerax=Kamera X @@ -336,14 +343,16 @@ dialog.compress.wackypoints.title=Komischi Punkte entf dialog.compress.wackypoints.paramdesc=Distanz Faktor dialog.compress.singletons.title=Singletons entfärnä dialog.compress.singletons.paramdesc=Distanz faktor +dialog.compress.douglaspeucker.title=Douglas-Peucker Komprimierig +dialog.compress.douglaspeucker.paramdesc=Span Faktor dialog.compress.summarylabel=Punkte zu entfärnä dialog.pastecoordinates.desc=Gäbet Sie hier die Koordinaten innä dialog.pastecoordinates.coords=Koordinate dialog.pastecoordinates.nothingfound=Prüefet Sie die Koordinate und versuechet nomal -dialog.help.help=Bitte lueg na\n http://activityworkshop.net/software/prune/\nfür wiitere Information und Benutzeraaleitige. +dialog.help.help=Bitte lueg na\n http://activityworkshop.net/software/gpsprune/\nfür wiitere Information und Benutzeraaleitige. dialog.about.version=Version dialog.about.build=Build -dialog.about.summarytext1=Prune isch s Programm fürs Lade, Darstelle und Editiere vo Date von GPS Geräte. +dialog.about.summarytext1=GpsPrune isch s Programm fürs Lade, Darstelle und Editiere vo Date von GPS Geräte. dialog.about.summarytext2=Es isch unter den Gnu GPL zur Verfüegig gstellt,für frei, gratis und offen Gebruuch und Wiiterentwicklig.
Kopiere, Wiiterverbreitig und Veränderige sin erlaubt und willkomme
unter die Bedingige im enthaltene license.txt File. dialog.about.summarytext3=Bitte lueget Sie na http://activityworkshop.net/ für wiitere Informatione und Benutzeraaleitige. dialog.about.languages=Verfüegbare Sproche @@ -364,7 +373,7 @@ dialog.about.systeminfo.exiflib.external.failed=Ext dialog.about.yes=Ja dialog.about.no=Nei dialog.about.credits=Credits -dialog.about.credits.code=Prune Code gschriebä vo +dialog.about.credits.code=GpsPrune Code gschriebä vo dialog.about.credits.exifcode=Exif Code vo dialog.about.credits.icons=Einigi Bilder vo dialog.about.credits.translators=Dolmätscher @@ -374,12 +383,12 @@ dialog.about.credits.othertools=Anderi W dialog.about.credits.thanks=Danke an dialog.about.readme=Läsmi dialog.checkversion.error=Die Versionnummer könne nöd gefprüft werdä.\nGits ne internet Verbindig? -dialog.checkversion.uptodate=Sie han die noischti Version vonem Prune scho. -dialog.checkversion.newversion1=Ne noii Version vonem Prune isch jetzt usse! Die heisst jetzt Version +dialog.checkversion.uptodate=Sie han die noischti Version vonem GpsPrune scho. +dialog.checkversion.newversion1=Ne noii Version vonem GpsPrune isch jetzt usse! Die heisst jetzt Version 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.checkversion.download=Um die noii Version runterzlade, schauet Sie na http://activityworkshop.net/software/gpsprune/download.html. dialog.keys.intro=Aastatt d'Muus könnet Sie diese Tastekombinationen nutze dialog.keys.keylist=
Pfiil TasteKarte verschiebe
Strg + links, rächts PfiilVorherigi oder nöchsti Punkt markiere
Strg + uuf, aba PfiilIi- oder Uusezoome
Strg + Bild uuf, abVorherigi oder nöchsti Segmänt markiere
Strg + Pos1, ÄndeErschti oder letschti Punkt markiere
EntfAktuelli Punkt lösche
dialog.keys.normalmodifier=Strg @@ -404,6 +413,7 @@ dialog.saveconfig.prune.kmzimageheight=Bildh dialog.saveconfig.prune.colourscheme=Farbeschema dialog.saveconfig.prune.linewidth=Liniedicke dialog.saveconfig.prune.kmltrackcolour=KML Trackfarb +dialog.saveconfig.prune.autosavesettings=Iistellige speichere dialog.setpaths.intro=Sie könnet dann die Pfade für dia Applikatione setzä: dialog.setpaths.found=Pfad gfunde? dialog.addaltitude.noaltitudes=Dr seläktierte Beriich hät keini Höchiinformation @@ -423,23 +433,35 @@ dialog.colourchooser.red=Rot dialog.colourchooser.green=Grüen dialog.colourchooser.blue=Blau dialog.setlanguage.firstintro=Sie könnet entweder eini vo den iigebouti Sproche

oder ne Text-Datei uuswähle. -dialog.setlanguage.secondintro=Sie münt Ihri Iistellige speichere und dann

Prune wieder neustarte um die Sproch z'ändere. +dialog.setlanguage.secondintro=Sie münt Ihri Iistellige speichere und dann

GpsPrune wieder neustarte um die Sproch z'ändere. dialog.setlanguage.language=Sproch dialog.setlanguage.languagefile=Sproch Datei -dialog.setlanguage.endmessage=Jetze speicheret Sie Ihri Iistellige und startet Sie Prune neu\num t noii Sproch z' verwände. +dialog.setlanguage.endmessage=Jetze speicheret Sie Ihri Iistellige und startet Sie GpsPrune neu\num t noii Sproch z' verwände. +dialog.setlanguage.endmessagewithautosave=Startet Sie GpsPrune neu um t noii Sproch z' verwände. dialog.diskcache.save=Karten uufem Disk speichere dialog.diskcache.dir=Kartenordner dialog.diskcache.createdir=Ordner kreiere dialog.diskcache.nocreate=Ordner isch nöd kreiert worde +dialog.diskcache.table.path=Pfad +dialog.diskcache.table.usedby=Aawänder +dialog.diskcache.table.zoom=Zoom +dialog.diskcache.table.tiles=Kachle +dialog.diskcache.table.megabytes=Megabytes +dialog.diskcache.tileset=Ordner +dialog.diskcache.tileset.multiple=mehreri +dialog.diskcache.deleteold=Uualti Kachle l\u00f6sche +dialog.diskcache.deleteall=Alli Kachle l\u00f6sche +dialog.diskcache.deleted1=Es sin +dialog.diskcache.deleted2=Files uusem Ordner gl\u00f6scht worde dialog.deletefieldvalues.intro=Wählet Sie s Fäld uus zum lösche dialog.setlinewidth.text=Gäbet Sie die Dicke vonen Linien ii (1-4) dialog.downloadosm.desc=Best\ätige um rohi OSM Date fürn Gebiet aba zlade: dialog.searchwikipedianames.search=Sueche na: # 3d window -dialog.3d.title=Prune Drüü-d Aasicht +dialog.3d.title=GpsPrune Drüü-d Aasicht dialog.3d.altitudefactor=Höchivervilfachigsfaktor -dialog.3dlines.title=Prune Gitterlinie +dialog.3dlines.title=GpsPrune Gitterlinie dialog.3dlines.empty=Kei Linie zum aazeigä! dialog.3dlines.intro=Hier sin die Linie für die drüü-D Aasicht @@ -511,6 +533,7 @@ button.resettodefaults=Zur button.browse=Durasuechä... button.addnew=Hinzuefügä button.delete=Entfärnä +button.manage=Verwoltä # File types filetype.txt=TXT Dateie @@ -561,6 +584,7 @@ details.lists.photos=F details.photodetails=Details vonem Föteli details.nophoto=Kei föteli selektiert details.photo.loading=Ladä +details.photo.bearing=Richtig details.media.connected=Verbundä details.lists.audio=Audio details.audiodetails=Audiodetails @@ -585,6 +609,7 @@ fieldname.movingdistance=Wegl fieldname.duration=Ziitlängi fieldname.speed=Gschwindikeit fieldname.verticalspeed=Uf/Ab Gschwindikeit +fieldname.description=Bschriibig # Measurement units units.original=Original @@ -673,10 +698,13 @@ error.3d=N F error.readme.notfound=Läs mi File nöd gfunde error.osmimage.dialogtitle=Fähle bim Bildli-Lade error.osmimage.failed=Map Bildli könne nöd glade werde. Gits ne Internet Verbindig? -error.language.wrongfile=Die uusgewählti Datei scheint kei Sproch-Datei für Prune z'sii +error.language.wrongfile=Die uusgewählti Datei scheint kei Sproch-Datei für GpsPrune z'sii error.convertnamestotimes.nonames=Kei Namen han könnet verwondlet werde error.lookupsrtm.nonefound=Kei Höhendate verfüegbar für d'Punkte error.lookupsrtm.nonerequired=Alle Punkte han die Höhendate scho. Nüüt z'tue. error.gpsies.uploadnotok=Der Gpsies Server hät gseit gha error.gpsies.uploadfailed=S Uufalade isch fehlgschlage error.playaudiofailed=S Abschpiele vonem File isch fehlgschlage +error.cache.notthere=D Ordner isch nöd gfunde worde +error.cache.empty=D Ordner hät nüüt drinne +error.cache.cannotdelete=Es sin kei Kachle gl\u00f6scht worde diff --git a/tim/prune/lang/prune-texts_en.properties b/tim/prune/lang/prune-texts_en.properties index 869af6d..d105404 100644 --- a/tim/prune/lang/prune-texts_en.properties +++ b/tim/prune/lang/prune-texts_en.properties @@ -1,9 +1,10 @@ -# Text entries for the Prune application +# Text entries for the GpsPrune application # English entries as default - others can be added # Menu entries menu.file=File menu.file.addphotos=Add photos +menu.file.recentfiles=Recent files menu.file.save=Save as text menu.file.exit=Exit menu.track=Track @@ -41,6 +42,7 @@ menu.view.browser.yahoo=Yahoo maps menu.view.browser.bing=Bing maps menu.settings=Settings menu.settings.onlinemode=Load maps from internet +menu.settings.autosave=Autosave settings on exit menu.help=Help # Popup menu for map menu.map.zoomin=Zoom in @@ -75,6 +77,7 @@ shortcut.menu.help.help=H # Functions function.open=Open file +function.importwithgpsbabel=Import file with GPSBabel function.loadfromgps=Load data from GPS function.sendtogps=Send data to GPS function.exportkml=Export KML @@ -109,11 +112,11 @@ function.rotatephotoleft=Rotate photo left function.rotatephotoright=Rotate photo right function.photopopup=Show photo popup function.ignoreexifthumb=Ignore exif thumbnail -function.loadaudio=Add audio files -function.removeaudio=Remove audio file +function.loadaudio=Add audio clips +function.removeaudio=Remove audio clip function.correlateaudios=Correlate audios -function.playaudio=Play audio file -function.stopaudio=Stop audio file +function.playaudio=Play audio clip +function.stopaudio=Stop audio clip function.setmapbg=Set map background function.setkmzimagesize=Set KMZ image size function.setpaths=Set program paths @@ -122,13 +125,14 @@ function.setlinewidth=Set line width function.setlanguage=Set language function.help=Help function.showkeys=Show shortcut keys -function.about=About Prune +function.about=About GpsPrune function.checkversion=Check for new version function.saveconfig=Save settings function.diskcache=Save maps to disk +function.managetilecache=Manage tile cache # Dialogs -dialog.exit.confirm.title=Exit Prune +dialog.exit.confirm.title=Exit GpsPrune dialog.exit.confirm.text=Your data is not saved. Are you sure you want to exit? dialog.openappend.title=Append to existing data dialog.openappend.text=Append this data to the data already loaded? @@ -189,6 +193,9 @@ dialog.exportgpx.name=Name dialog.exportgpx.desc=Description dialog.exportgpx.includetimestamps=Include timestamps dialog.exportgpx.copysource=Copy source xml +dialog.exportgpx.encoding=Encoding +dialog.exportgpx.encoding.system=System +dialog.exportgpx.encoding.utf8=UTF-8 dialog.exportpov.text=Please enter the parameters for the POV export dialog.exportpov.font=Font dialog.exportpov.camerax=Camera X @@ -341,14 +348,16 @@ dialog.compress.wackypoints.title=Wacky point removal dialog.compress.wackypoints.paramdesc=Distance factor dialog.compress.singletons.title=Singleton removal dialog.compress.singletons.paramdesc=Distance factor +dialog.compress.douglaspeucker.title=Douglas-Peucker compression +dialog.compress.douglaspeucker.paramdesc=Span factor dialog.compress.summarylabel=Points to delete dialog.pastecoordinates.desc=Enter or paste the coordinates here dialog.pastecoordinates.coords=Coordinates dialog.pastecoordinates.nothingfound=Please check the coordinates and try again -dialog.help.help=Please see\n http://activityworkshop.net/software/prune/\nfor more information and user guides. +dialog.help.help=Please see\n http://activityworkshop.net/software/gpsprune/\nfor more information and user guides. dialog.about.version=Version dialog.about.build=Build -dialog.about.summarytext1=Prune is a program for loading, displaying and editing data from GPS receivers. +dialog.about.summarytext1=GpsPrune is a program for loading, displaying and editing data from GPS receivers. dialog.about.summarytext2=It is released under the Gnu GPL for free, open, worldwide use and enhancement.
Copying, redistribution and modification are permitted and encouraged
according to the conditions in the included license.txt file. dialog.about.summarytext3=Please see http://activityworkshop.net/ for more information and user guides. dialog.about.languages=Available languages @@ -369,7 +378,7 @@ dialog.about.systeminfo.exiflib.external.failed=External (not found) dialog.about.yes=Yes dialog.about.no=No dialog.about.credits=Credits -dialog.about.credits.code=Prune code written by +dialog.about.credits.code=GpsPrune code written by dialog.about.credits.exifcode=Exif code by dialog.about.credits.icons=Some icons taken from dialog.about.credits.translators=Translators @@ -379,12 +388,12 @@ dialog.about.credits.othertools=Other tools dialog.about.credits.thanks=Thanks to dialog.about.readme=Readme dialog.checkversion.error=The version number couldn't be checked.\nPlease check the internet connection. -dialog.checkversion.uptodate=You are using the latest version of Prune. -dialog.checkversion.newversion1=A new version of Prune is now available! The latest version is now version +dialog.checkversion.uptodate=You are using the latest version of GpsPrune. +dialog.checkversion.newversion1=A new version of GpsPrune is now available! The latest version is now version 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.checkversion.download=To download the new version, go to http://activityworkshop.net/software/gpsprune/download.html. dialog.keys.intro=You can use the following shortcut keys instead of using the mouse dialog.keys.keylist=
Arrow keysPan map left right, up, down
Ctrl + left, right arrowSelect previous or next point
Ctrl + up, down arrowZoom in or out
Ctrl + PgUp, PgDownSelect previous, next segment
Ctrl + Home, EndSelect first, last point
DelDelete current point
dialog.keys.normalmodifier=Ctrl @@ -409,6 +418,7 @@ dialog.saveconfig.prune.kmzimageheight=KMZ image height dialog.saveconfig.prune.colourscheme=Colour scheme dialog.saveconfig.prune.linewidth=Line width dialog.saveconfig.prune.kmltrackcolour=KML track colour +dialog.saveconfig.prune.autosavesettings=Autosave settings dialog.setpaths.intro=If you need to, you can choose the paths to the external applications: dialog.setpaths.found=Path found? dialog.addaltitude.noaltitudes=The selected range does not contain altitudes @@ -428,23 +438,35 @@ dialog.colourchooser.red=Red dialog.colourchooser.green=Green dialog.colourchooser.blue=Blue dialog.setlanguage.firstintro=You can either select one of the included languages,

or select a text file to use instead. -dialog.setlanguage.secondintro=You need to save your settings and then

restart Prune to change the language. +dialog.setlanguage.secondintro=You need to save your settings and then

restart GpsPrune to change the language. dialog.setlanguage.language=Language dialog.setlanguage.languagefile=Language file -dialog.setlanguage.endmessage=Now save your settings and restart Prune\nfor the language change to take effect. +dialog.setlanguage.endmessage=Now save your settings and restart GpsPrune\nfor the language change to take effect. +dialog.setlanguage.endmessagewithautosave=Please restart GpsPrune for the language change to take effect. dialog.diskcache.save=Save map images to disk dialog.diskcache.dir=Cache directory dialog.diskcache.createdir=Create directory dialog.diskcache.nocreate=Cache directory not created +dialog.diskcache.table.path=Path +dialog.diskcache.table.usedby=Used by +dialog.diskcache.table.zoom=Zoom +dialog.diskcache.table.tiles=Tiles +dialog.diskcache.table.megabytes=Megabytes +dialog.diskcache.tileset=Tileset +dialog.diskcache.tileset.multiple=multiple +dialog.diskcache.deleteold=Delete old tiles +dialog.diskcache.deleteall=Delete all tiles +dialog.diskcache.deleted1=Deleted +dialog.diskcache.deleted2=files from the cache dialog.deletefieldvalues.intro=Select the field to delete for the current range dialog.setlinewidth.text=Enter the thickness of lines to draw for the tracks (1-4) dialog.downloadosm.desc=Confirm to download the raw OSM data for the specified area: dialog.searchwikipedianames.search=Search for: # 3d window -dialog.3d.title=Prune Three-d view +dialog.3d.title=GpsPrune Three-d view dialog.3d.altitudefactor=Altitude exaggeration factor -dialog.3dlines.title=Prune gridlines +dialog.3dlines.title=GpsPrune gridlines dialog.3dlines.empty=No gridlines to display! dialog.3dlines.intro=These are the gridlines for the three-d view @@ -516,6 +538,7 @@ button.resettodefaults=Reset to defaults button.browse=Browse... button.addnew=Add new button.delete=Delete +button.manage=Manage # File types filetype.txt=TXT files @@ -567,9 +590,10 @@ details.lists.audio=Audio details.photodetails=Photo details details.nophoto=No photo selected details.photo.loading=Loading +details.photo.bearing=Bearing details.media.connected=Connected details.audiodetails=Audio details -details.noaudio=No audio file selected +details.noaudio=No audio clip selected details.audio.file=Audio file details.audio.playing=playing... map.overzoom=No maps available at this zoom level @@ -590,6 +614,7 @@ fieldname.movingdistance=Moving distance fieldname.duration=Duration fieldname.speed=Speed fieldname.verticalspeed=Vertical speed +fieldname.description=Description # Measurement units units.original=Original @@ -625,11 +650,11 @@ cardinal.w=W # Undo operations undo.load=load data undo.loadphotos=load photos -undo.loadaudios=load audio files +undo.loadaudios=load audio clips undo.editpoint=edit point undo.deletepoint=delete point undo.removephoto=remove photo -undo.removeaudio=remove audio file +undo.removeaudio=remove audio clip undo.deleterange=delete range undo.compress=compress track undo.insert=insert points @@ -672,7 +697,7 @@ error.jpegload.nofilesfound=No files found error.jpegload.nojpegsfound=No jpeg files found error.jpegload.nogpsfound=No GPS information found error.jpegload.exifreadfailed=Failed to read EXIF information. No EXIF information can be read\nwithout either an internal or external library. -error.audioload.nofilesfound=No audio files found +error.audioload.nofilesfound=No audio clips found error.gpsload.unknown=Unknown error error.undofailed.title=Undo failed error.undofailed.text=Failed to undo operation @@ -684,10 +709,13 @@ error.3d=An error occurred with the 3d display error.readme.notfound=Readme file not found error.osmimage.dialogtitle=Error loading map images error.osmimage.failed=Failed to load map images. Please check internet connection. -error.language.wrongfile=The selected file doesn't appear to be a language file for Prune +error.language.wrongfile=The selected file doesn't appear to be a language file for GpsPrune error.convertnamestotimes.nonames=No names could be converted into times error.lookupsrtm.nonefound=No altitude values available for these points error.lookupsrtm.nonerequired=All points already have altitudes, so there's nothing to lookup error.gpsies.uploadnotok=The gpsies server returned the message error.gpsies.uploadfailed=The upload failed with the error -error.playaudiofailed=Failed to play audio file +error.playaudiofailed=Failed to play audio clip +error.cache.notthere=The tile cache directory was not found +error.cache.empty=The tile cache directory is empty +error.cache.cannotdelete=No tiles could be deleted diff --git a/tim/prune/lang/prune-texts_es.properties b/tim/prune/lang/prune-texts_es.properties index c554ab3..6cd6654 100644 --- a/tim/prune/lang/prune-texts_es.properties +++ b/tim/prune/lang/prune-texts_es.properties @@ -1,9 +1,10 @@ -# Text entries for the Prune application +# Text entries for the GpsPrune application # Spanish entries as extra # Menu entries menu.file=Archivo menu.file.addphotos=Cargar fotos +menu.file.recentfiles=Archivos recientes menu.file.save=Guardar menu.file.exit=Salir menu.track=Track @@ -41,6 +42,7 @@ menu.view.browser.yahoo=Mapas Yahoo menu.view.browser.bing=Mapas Bing menu.settings=Preferencias menu.settings.onlinemode=Cargar mapas de Internet +menu.settings.autosave=Auto Guardar menu.help=Ayuda # Popup menu for map menu.map.zoomin=Ampliar zoom @@ -75,6 +77,7 @@ shortcut.menu.help.help=H # Functions function.open=Abrir archivo +function.importwithgpsbabel=Importar archivo con GPSBabel function.loadfromgps=Cargar datos del GPS function.sendtogps=Enviar datos al GPS function.exportkml=Exportar KML @@ -122,14 +125,15 @@ function.playaudio=Reproducir archivo de audio function.stopaudio=Detener reproducci\u00f3n de audio function.help=Ayuda function.showkeys=Mostrar teclas o combinaciones de atajo -function.about=Acerca de Prune +function.about=Acerca de GpsPrune function.checkversion=Buscar una nueva versi\u00f3n function.saveconfig=Guardar preferencias function.diskcache=Guardar mapas en disco +function.managetilecache=Administrar cache de mapas # Dialogs -dialog.exit.confirm.title=Salir de Prune -dialog.exit.confirm.text=\u00bfLos datos han sido modificados. Desea salir de Prune? +dialog.exit.confirm.title=Salir de GpsPrune +dialog.exit.confirm.text=\u00bfLos datos han sido modificados. Desea salir de GpsPrune? dialog.openappend.title=\u00bfAgregar a datos existentes dialog.openappend.text=\u00bfAgregar estos datos a los datos ya guardados? dialog.deletepoint.title=Borrar punto @@ -189,6 +193,9 @@ dialog.exportgpx.name=Nombre dialog.exportgpx.desc=Descripci\u00f3n dialog.exportgpx.includetimestamps=Tiempo tambien dialog.exportgpx.copysource=Copiar la fuente +dialog.exportgpx.encoding=Codificaci\u00f3n +dialog.exportgpx.encoding.system=Sistema +dialog.exportgpx.encoding.utf8=UTF-8 dialog.exportpov.text=Introdzca los Parametros para exportar dialog.exportpov.font=Fuente dialog.exportpov.camerax=C\u00e1mara X @@ -341,14 +348,16 @@ dialog.compress.wackypoints.paramdesc=Factor distancia dialog.compress.singletons.title=Eliminar puntos aislados dialog.compress.singletons.paramdesc=Factor distancia dialog.compress.duplicates.title=Eliminar duplicados +dialog.compress.douglaspeucker.title=Compresion Douglas-Peucker +dialog.compress.douglaspeucker.paramdesc=Factor de extensi\u00f3n dialog.compress.summarylabel=Puntos para eliminar dialog.pastecoordinates.desc=Ingresar o pegar las coordenadas aqu\u00ed dialog.pastecoordinates.coords=Coordenadas dialog.pastecoordinates.nothingfound=Por favor verificar las coordenadas e intentar nuevamente -dialog.help.help=Por favor, ver\n http://activityworkshop.net/software/prune/\npara m\u00e1s informaci\u00f3n y gu\u00edas del usuario. +dialog.help.help=Por favor, ver\n http://activityworkshop.net/software/gpsprune/\npara m\u00e1s informaci\u00f3n y gu\u00edas del usuario. dialog.about.version=Versi\u00f3n dialog.about.build=Construcci\u00f3n -dialog.about.summarytext1=Prune es un programa para cargar, mostrar y editar datos de receptores GPS. +dialog.about.summarytext1=GpsPrune 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\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 @@ -369,7 +378,7 @@ dialog.about.systeminfo.exiflib.external.failed=Externa (no encontrada) dialog.about.yes=Si dialog.about.no=No dialog.about.credits=Cr\u00e9ditos -dialog.about.credits.code=El c\u00f3digo de Prune fue escrito por +dialog.about.credits.code=El c\u00f3digo de GpsPrune 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 @@ -379,14 +388,16 @@ dialog.about.credits.othertools=Otras herramientas dialog.about.credits.thanks=Gracias a dialog.about.readme=Readme dialog.checkversion.error=El numero de versi\u00f3n no pudo ser verificada.\n Por favor verificar la conexi\u00f3n de Internet -dialog.checkversion.uptodate=Esta usted utilizando la \u00faltima versi\u00f3n de Prune -dialog.checkversion.newversion1=¡Una nueva versi\u00f3n de Prune est\u00e1 disponible! La \u00faltima es ahora la versi\u00f3n +dialog.checkversion.uptodate=Esta usted utilizando la \u00faltima versi\u00f3n de GpsPrune +dialog.checkversion.newversion1=¡Una nueva versi\u00f3n de GpsPrune est\u00e1 disponible! La \u00faltima es ahora la versi\u00f3n dialog.checkversion.newversion2=. dialog.checkversion.releasedate1=La nueva versi\u00f3n fue lanzada en dialog.checkversion.releasedate2=. -dialog.checkversion.download=Para descargar la nueva versi\u00f3n visite http://activityworkshop.net/software/prune/download.html. +dialog.checkversion.download=Para descargar la nueva versi\u00f3n visite http://activityworkshop.net/software/gpsprune/download.html. dialog.keys.intro=Usted puede usar el siguiente atajo en lugar de usar el rat\u00f3n dialog.keys.keylist=
Teclas de cursorDesplazar a la izquierde, derecha, arriba, abajo
Ctrl + cursor izquierda, derechaSeleccionar punto siguiente o anterior
Ctrl + cursor arriba, abajoAmpliar o reducir zoom
Ctrl + Av Pag, Re PagSeleccionar segmento siguiente, anterior
Ctrl + Inicio, FinSeleccionar primer, \u00faltimo punto
SuprEliminar punto actual
+dialog.keys.normalmodifier=Ctrl +dialog.keys.macmodifier=Command dialog.saveconfig.desc=La siguiente configuraci\u00f3n puede ser salvada en un archivo de configuraci\u00f3n dialog.saveconfig.prune.trackdirectory=Directorio de pista dialog.saveconfig.prune.photodirectory=Directorio de foto @@ -407,6 +418,7 @@ dialog.saveconfig.prune.kmzimageheight=Alto de im\u00e1genes en KMZ dialog.saveconfig.prune.colourscheme=Color de esquema dialog.saveconfig.prune.linewidth=Ancho de l\u00ednea dialog.saveconfig.prune.kmltrackcolour=Color de pista de KML +dialog.saveconfig.prune.autosavesettings=Guardar preferencias al salir dialog.setpaths.intro=Si usted necesita, puede escoger las rutas a aplicaciones externas dialog.setpaths.found=\u00bfRuta encontrada? dialog.addaltitude.noaltitudes=Los rangos seleccionados no contienen altitudes @@ -426,23 +438,35 @@ dialog.colourchooser.red=Rojo dialog.colourchooser.green=Verde dialog.colourchooser.blue=Azul dialog.setlanguage.firstintro=Puede usted seleccionar algunos de los lenguajes incluidos,

o puede en lugar de esto seleccionar un archivo de texto -dialog.setlanguage.secondintro=Usted necesita guardar sus preferencias y luego

reiniciar Prune para cambiar el lenguaje +dialog.setlanguage.secondintro=Usted necesita guardar sus preferencias y luego

reiniciar GpsPrune para cambiar el lenguaje dialog.setlanguage.language=Lenguaje dialog.setlanguage.languagefile=Archivo de lenguaje -dialog.setlanguage.endmessage=Ahora guarde sus preferencias y reinicie Prune\npara que los cambios tomen efecto. +dialog.setlanguage.endmessage=Ahora guarde sus preferencias y reinicie GpsPrune\npara que los cambios tomen efecto. +dialog.setlanguage.endmessagewithautosave=Ahora reinicie GpsPrune para que los cambios tomen efecto. dialog.diskcache.save=Guardar im\u00e1genes de mapa a disco dialog.diskcache.dir=Directorio de mapas dialog.diskcache.createdir=Crear directorio dialog.diskcache.nocreate=No se ha creado el directorio de mapas +dialog.diskcache.table.path=Ruta +dialog.diskcache.table.usedby=Utilizado por +dialog.diskcache.table.zoom=Zoom +dialog.diskcache.table.tiles=Recuadros +dialog.diskcache.table.megabytes=Megabytes +dialog.diskcache.tileset=Conjunto de recuadros +dialog.diskcache.tileset.multiple=varios +dialog.diskcache.deleteold=Borrar recuadros antiguos +dialog.diskcache.deleteall=Borrar todos los recuadros +dialog.diskcache.deleted1=Borrado +dialog.diskcache.deleted2=Archivos del cache dialog.deletefieldvalues.intro=Seleccionar el campo a eliminar para el rango actual dialog.setlinewidth.text=Introduzca la anchura de las l\u00edneas a dibujar para los recorridos (1-4) dialog.downloadosm.desc=Confirmar la descarga de datos en bruto de OSM para el \u00e1rea especificada. dialog.searchwikipedianames.search=Buscar: # 3d window -dialog.3d.title=Prune vista 3-D +dialog.3d.title=GpsPrune vista 3-D dialog.3d.altitudefactor=Factor de exageraci\u00f3n de altura -dialog.3dlines.title=Cuadr\u00edcula Prune +dialog.3dlines.title=Cuadr\u00edcula GpsPrune dialog.3dlines.empty=¡No hay ninguna cuadr\u00edcula! dialog.3dlines.intro=Informaci\u00f3n de la cuadr\u00edcula @@ -514,6 +538,7 @@ button.resettodefaults=Restablecer valores a los predeterminados button.browse=Navegar... button.addnew=A\u00f1adir nuevo button.delete=Eliminar +button.manage=Administrar # File types filetype.txt=Archivos TXT @@ -565,6 +590,7 @@ details.lists.audio=Audio details.photodetails=Detalles de la foto details.nophoto=Ninguna foto seleccionada details.photo.loading=Cargando +details.photo.bearing=Rumbo details.media.connected=Conectada details.audiodetails=Detalles de audio details.noaudio=No se ha seleccionado ning\u00fan archivo de audio @@ -588,6 +614,7 @@ fieldname.movingdistance=Distancia en movimiento fieldname.duration=Duraci\u00f3n fieldname.speed=Velocidad fieldname.verticalspeed=Velocidad vertical +fieldname.description=Descripci\u00f3n # Measurement units units.original=Original @@ -682,10 +709,13 @@ 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\u00f3n a internet. -error.language.wrongfile=El archivo seleccionado no parece ser un archivo de lenguaje para Prune +error.language.wrongfile=El archivo seleccionado no parece ser un archivo de lenguaje para GpsPrune error.convertnamestotimes.nonames=Los nombres no pudieron ser convertidos en tiempos error.lookupsrtm.nonefound=No se encontraron valores de altitud error.lookupsrtm.nonerequired=Todos los puntos tienen altitudes, as\u00ed que no hay nada que buscar. error.gpsies.uploadnotok=El servidor de gpsies ha devuelto el mensaje error.gpsies.uploadfailed=La carga ha fallado con el error error.playaudiofailed=Fallo reproduciendo archivo de audio +error.cache.notthere=No se encontr\u00f3 la carpeta del cache de recuadros +error.cache.empty=La carpeta del cache de recuadros esta vac\u00edo +error.cache.cannotdelete=No se pudieron borrar recuadros diff --git a/tim/prune/lang/prune-texts_fr.properties b/tim/prune/lang/prune-texts_fr.properties index 8c7f1b3..1e0164b 100644 --- a/tim/prune/lang/prune-texts_fr.properties +++ b/tim/prune/lang/prune-texts_fr.properties @@ -1,9 +1,10 @@ -# Text entries for the Prune application +# Text entries for the GpsPrune application # French entries as extra # Menu entries menu.file=Fichier menu.file.addphotos=Ajouter photos +menu.file.recentfiles=Derniers Fichiers utilis\u00e9s menu.file.save=Enregistrer menu.file.exit=Quitter menu.track=Trace @@ -26,14 +27,13 @@ menu.range.reverse=Inverser l'\u00e9tendue menu.range.mergetracksegments=Fusionner les segments de trace menu.range.cutandmove=Couper et bouger la s\u00e9lection menu.point=Point -menu.point.editpoint=Editer le point +menu.point.editpoint=\u00c9diter le point menu.point.deletepoint=Supprimer le point menu.photo=Photo menu.photo.saveexif=Enregistrer dans les Exif -function.connecttopoint=Relier au point -function.disconnectfrompoint=D\u00e9tacher du point -function.removephoto=Retirer la photo +menu.audio=Audio menu.view=Affichage +menu.view.showsidebars=Montrer les barres lat\u00e9rales menu.view.browser=Ouvrir la carte dans le navigateur menu.view.browser.google=Google maps menu.view.browser.openstreetmap=Openstreetmap @@ -41,13 +41,15 @@ menu.view.browser.mapquest=Mapquest menu.view.browser.yahoo=Yahoo maps menu.view.browser.bing=Cartes dans Bing menu.settings=Pr\u00e9f\u00e9rences -menu.settings.onlinemode=Charger une carte depuis internet +menu.settings.onlinemode=Charger cartes depuis internet +menu.settings.autosave=Sauver automatiquement en quittant menu.help=Aide # Popup menu for map menu.map.zoomin=Zoom avant menu.map.zoomout=Zoom arri\u00e8re menu.map.zoomfull=Adapter \u00e0 la vue menu.map.newpoint=Ajouter un point +menu.map.drawpoints=Ajouter une s\u00e9rie des points menu.map.connect=Relier les points de trace menu.map.autopan=D\u00e9placement automatique menu.map.showmap=Montrer la carte @@ -60,6 +62,7 @@ altkey.menu.range=E altkey.menu.point=P altkey.menu.view=A altkey.menu.photo=H +altkey.menu.audio=U altkey.menu.settings=R altkey.menu.help=I @@ -79,11 +82,13 @@ function.sendtogps=Envoyer donn\u00e9es 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.exportsvg=Exporter en SVG +function.editwaypointname=\u00c9diter le nom du waypoint function.compress=Compresser la trace function.addtimeoffset=Ajouter un d\u00e9calage d'horaire function.addaltitudeoffset=Ajouter un d\u00e9calage d'altitude function.convertnamestotimes=Convertir les noms de waypoints en horodatages +function.deletefieldvalues=Effacer les valeurs du champ function.findwaypoint=Trouver un waypoint function.pastecoordinates=Coller les coordonn\u00e9es function.charts=Graphiques @@ -94,26 +99,39 @@ 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.getgpsies=R\u00e9cup\u00e9rer les traces Gpsies +function.uploadgpsies=T\u00e9l\u00e9charger la trace sur Gpsies function.lookupsrtm=R\u00e9cup\u00e9rer les altitudes depuis SRTM -function.duplicatepoint=Duppliquer le point -function.setcolours=R\u00e9gler les couleurs -function.setlanguage=R\u00e9gler la langue +function.getwikipedia=Obtenir les articles de Wikip\u00e9dia \u00e0 proxilit\u00e9 +function.searchwikipedianames=Rechercher dans Wikip\u00e9dia par nom +function.downloadosm=T\u00e9l\u00e9charger les donn\u00e9es OSM de la zone +function.duplicatepoint=Dupliquer le point +function.setcolours=Choisir les couleurs +function.setlinewidth=Choisir la largeur de ligne +function.setlanguage=Choisir la langue +function.connecttopoint=Relier au point +function.disconnectfrompoint=D\u00e9tacher du point +function.removephoto=Retirer la photo function.correlatephotos=Corr\u00e9ler les photos function.rearrangephotos=R\u00e9arranger les photos function.rotatephotoleft=Tourner la photo vers la gauche function.rotatephotoright=Tourner la photo vers la droite function.photopopup=Montrer la photo function.ignoreexifthumb=Ignorer l\u2019aper\u00e7u Exif +function.loadaudio=Ajouter des fichiers audio +function.removeaudio=Retirer des fichiers audio +function.correlateaudios=Corr\u00e9ler les fichiers audio +function.playaudio=Lire le fichier audio +function.stopaudio=Arr\u00eater la lecture du fichier audio function.help=Aide function.showkeys=Montrer les raccourcis clavier -function.about=À propos de Prune +function.about=\u00c0 propos de GpsPrune function.checkversion=Chercher une mise \u00e0 jour function.saveconfig=Enregistrer les pr\u00e9f\u00e9rences function.diskcache=Enregistrer les cartes sur le disque # Dialogs -dialog.exit.confirm.title=Quitter Prune -dialog.exit.confirm.text=Les donn\u00e9es ont \u00e9t\u00e9 modifi\u00e9es. Souhaitez-vous quitter Prune sans les enregistrer ? +dialog.exit.confirm.title=Quitter GpsPrune +dialog.exit.confirm.text=Les donn\u00e9es ont \u00e9t\u00e9 modifi\u00e9es. Souhaitez-vous quitter GpsPrune 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 @@ -135,6 +153,9 @@ dialog.openoptions.deliminfo.records=enregistrements, avec dialog.openoptions.deliminfo.fields=champs dialog.openoptions.deliminfo.norecords=Pas d'enregistrements dialog.openoptions.altitudeunits=Unit\u00e9s d'altitude +dialog.open.contentsdoubled=Ce fichier contient deux copies de chaque point,\nune fois comme waypoint, une autre comme point de trace. +dialog.selecttracks.intro=S\u00e9lectionner la ou les traces \u00e0 charger +dialog.selecttracks.noname=Sans titre dialog.jpegload.subdirectories=Inclure les sous-dossiers dialog.jpegload.loadjpegswithoutcoords=Inclure les photos sans coordonn\u00e9es dialog.jpegload.loadjpegsoutsidearea=Inclure des photos en dehors de la zone actuel @@ -170,6 +191,8 @@ dialog.exportgpx.name=Nom dialog.exportgpx.desc=L\u00e9gende dialog.exportgpx.includetimestamps=Inclure l'heure pour chaque point dialog.exportgpx.copysource=Copier la source xml +dialog.exportgpx.encoding.system=Syst\u00e8me +dialog.exportgpx.encoding.utf8=UTF-8 dialog.exportpov.text=Entrez les param\u00e8tres pour l'export POV dialog.exportpov.font=Police dialog.exportpov.camerax=Cam\u00e9ra X @@ -179,10 +202,15 @@ 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\u00e8de un grand nombre de points, Java3D peut ne pas pouvoir l'afficher.\n\u00cates-vous s\u00fbr de vouloir continuer ? +dialog.exportsvg.text=S\u00e9lectionner les param\u00e8tres de l'export SVG +dialog.exportsvg.phi=Angle d'azimuth \u03d5 +dialog.exportsvg.theta=Angle d'\u00e9l\u00e9vation \u03b8 +dialog.exportsvg.gradients=Utiliser des d\u00e9grad\u00e9s pour l'ombrage 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.pointtype.audio=Points audio dialog.pointtype.selection=Uniquement la s\u00e9lection dialog.confirmreversetrack.title=Confirmer l'inversion 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 ? @@ -195,14 +223,14 @@ dialog.undo.pretext=S\u00e9lectionnez les actions \u00e0 annuler dialog.undo.none.title=Annulation impossible dialog.undo.none.text=Pas d'op\u00e9ration \u00e0 annuler ! dialog.clearundo.title=Purger la liste d'annulation -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\u00e9lectionner chaque champ \u00e0 \u00e9diter et utiliser le bouton 'Editer' pour changer la valeur +dialog.clearundo.text=\u00cates-vous s\u00fbr de vouloir effacer la liste d'annulation ?\nToutes les informations d'annulation seront perdues ! +dialog.pointedit.title=\u00c9diter le point +dialog.pointedit.text=S\u00e9lectionner chaque champ \u00e0 \u00e9diter et utiliser le bouton '\u00c9diter' pour changer la valeur dialog.pointedit.table.field=Champ dialog.pointedit.table.value=Valeur 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.pointedit.changevalue.title=\u00c9diter le champ dialog.pointnameedit.name=Nom de waypoint dialog.pointnameedit.uppercase=CASSE MAJUSCULES dialog.pointnameedit.lowercase=casse minuscules @@ -225,7 +253,7 @@ dialog.saveexif.table.save=Enregistrer 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.saveexif.overwrite=\u00c9craser les fichiers dialog.saveexif.force=Ignorer les erreurs mineures dialog.charts.xaxis=Axe des x dialog.charts.yaxis=Axe des y @@ -248,13 +276,17 @@ dialog.addmapsource.sourcename=Nom de la source dialog.addmapsource.layer1url=URL de la premi\u00e8re couche dialog.addmapsource.layer2url=URL optionnelle de la deuxi\u00e8me couche dialog.addmapsource.maxzoom=Niveau de zoom maximum -dialog.addmapsource.cloudstyle=Taille -dialog.addmapsource.noname=Sans-titre +dialog.addmapsource.cloudstyle=Num\u00e9ro du style +dialog.addmapsource.noname=Sans titre 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.gpsies.nonefound=Aucune trace trouv\u00e9e +dialog.gpsies.username=Nom d'utilisateur Gpsies +dialog.gpsies.password=Mot de passe Gpsies +dialog.gpsies.keepprivate=Trace priv\u00e9e +dialog.gpsies.confirmopenpage=Ouvrir la page web de la trace t\u00e9l\u00e9charg\u00e9e ? dialog.gpsies.activities=Activit\u00e9 dialog.gpsies.activity.trekking=Trekking dialog.gpsies.activity.walking=Randonn\u00e9e @@ -264,6 +296,8 @@ dialog.gpsies.activity.motorbiking=Moto dialog.gpsies.activity.snowshoe=Raquette dialog.gpsies.activity.sailing=Volle dialog.gpsies.activity.skating=Skating +dialog.wikipedia.column.name=Nom de l'article +dialog.wikipedia.column.distance=Distance 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 @@ -279,6 +313,8 @@ dialog.correlate.options.offset.minutes=minutes et dialog.correlate.options.offset.seconds=secondes dialog.correlate.options.photolater=Photo post\u00e9rieure au point dialog.correlate.options.pointlaterphoto=Point post\u00e9rieur \u00e0 la photo +dialog.correlate.options.audiolater=Audio post\u00e9rieur au point +dialog.correlate.options.pointlateraudio=Point post\u00e9rieur \u00e0 l'audio dialog.correlate.options.limitspanel=Limites de corr\u00e9lation dialog.correlate.options.notimelimit=Pas de limite de temps dialog.correlate.options.timelimit=Limite de temps @@ -286,6 +322,15 @@ dialog.correlate.options.nodistancelimit=Pas de limite de distance dialog.correlate.options.distancelimit=Limite de distance 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.correlate.filetimes=La date du fichier indique : +dialog.correlate.filetimes2=de l'extrait audio +dialog.correlate.correltimes=Pour la corr\u00e9lation, utiliser : +dialog.correlate.timestamp.beginning=Le d\u00e9but +dialog.correlate.timestamp.middle=Le milieu +dialog.correlate.timestamp.end=La fin +dialog.correlate.audioselect.intro=Choisir un de ces fichiers audio corr\u00e9l\u00e9s comme d\u00e9calage de temps +dialog.correlate.select.audioname=Nom du fichier audio +dialog.correlate.select.audiolater=Audio apr\u00e8s dialog.rearrangephotos.desc=Choisissez la destination et l\u2019ordre des points des photos dialog.rearrangephotos.tostart=Aller au d\u00e9but dialog.rearrangephotos.toend=Aller \u00e0 la fin @@ -300,14 +345,16 @@ dialog.compress.wackypoints.paramdesc=Distance dialog.compress.singletons.title=Suppression des points isol\u00e9s dialog.compress.singletons.paramdesc=Distance dialog.compress.duplicates.title=Suppression des doublons +dialog.compress.douglaspeucker.title=Compression Douglas-Peucker +dialog.compress.douglaspeucker.paramdesc=Taille du voisinage dialog.compress.summarylabel=Points \u00e0 supprimer dialog.pastecoordinates.desc=Entrez ou collez les coordonn\u00e9es ici dialog.pastecoordinates.coords=Coordonn\u00e9es dialog.pastecoordinates.nothingfound=V\u00e9rifier les coordonn\u00e9es et essayez \u00e0 nouveau -dialog.help.help=Consultez la page\n http://activityworkshop.net/software/prune/\npour plus de d\u00e9tails et des manuels utilisateur. +dialog.help.help=Consultez la page\n http://activityworkshop.net/software/gpsprune/\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 \u00e9diter des donn\u00e9es de r\u00e9cepteurs GPS. +dialog.about.summarytext1=GpsPrune 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 @@ -328,7 +375,7 @@ dialog.about.systeminfo.exiflib.external.failed=Externe (non-trouv\u00e9) dialog.about.yes=Oui dialog.about.no=Non dialog.about.credits=Cr\u00e9dits -dialog.about.credits.code=Code de Prune \u00e9crit par +dialog.about.credits.code=Code de GpsPrune \u00e9crit par dialog.about.credits.exifcode=Code Exif par dialog.about.credits.icons=Quelques ic\u00f4nes provenant de dialog.about.credits.translators=Interpr\u00e8tes @@ -338,14 +385,16 @@ dialog.about.credits.othertools=Autre outils dialog.about.credits.thanks=Merci \u00e0 dialog.about.readme=Lisez-moi 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.uptodate=Vous utilisez d\u00e9j\u00e0 la version actuelle de GpsPrune. 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\u00e9l\u00e9charger la nouvelle version, aller \u00e0 http://activityworkshop.net/software/prune/download.html. +dialog.checkversion.download=Pour t\u00e9l\u00e9charger la nouvelle version, aller \u00e0 http://activityworkshop.net/software/gpsprune/download.html. dialog.keys.intro=Vous pouvez utiliser ces raccourcis clavier \u00e0 la place de la souris -dialog.keys.keylist=
Touches-fl\u00e8chesFaire d\u00e9filer la carte horizontallement et verticallement
Ctrl + gauche, Ctrl + droiteChoisir le point pr\u00e9c\u00e9dent ou suivant
Ctrl + haut, Ctrl + basZoomer, s'\u00e9loigner
SupprEffacer le point courant
+dialog.keys.keylist=
Touches-fl\u00e8chesFaire d\u00e9filer la carte horizontalement et verticalement
Ctrl + gauche, Ctrl + droiteChoisir le point pr\u00e9c\u00e9dent ou suivant
Ctrl + haut, Ctrl + basZoomer, s'\u00e9loigner
SupprEffacer le point courant
+dialog.keys.normalmodifier=Ctrl +dialog.keys.macmodifier=Command 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 @@ -358,19 +407,20 @@ 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.mapsource=Carte source s\u00e9lectionn\u00e9e dialog.saveconfig.prune.mapsourcelist=Sources de cartes dialog.saveconfig.prune.diskcache=Cache de carte dialog.saveconfig.prune.kmzimagewidth=Largeur de l'image KMZ dialog.saveconfig.prune.kmzimageheight=Hauteur de l'image KMZ dialog.saveconfig.prune.colourscheme=Mod\u00e8le de couleurs +dialog.saveconfig.prune.linewidth=Largeur de ligne dialog.saveconfig.prune.kmltrackcolour=Couleur de la trace KML +dialog.saveconfig.prune.autosavesettings=R\u00e9glages de sauvegarde automatique dialog.setpaths.intro=Si vous le souhaitez, vous pouvez d\u00e9finir les chemins des applications externes: dialog.setpaths.found=Chemin trouv\u00e9 ? dialog.addaltitude.noaltitudes=L'\u00e9tendue s\u00e9lectionn\u00e9e de contient pas d'altitudes -dialog.addaltitude.desc=D\u00e9callage d'altitude \u00e0 ajouter +dialog.addaltitude.desc=D\u00e9calage d'altitude \u00e0 ajouter +dialog.lookupsrtm.overwritezeros=Ramener les valeurs d'altitude \u00e0 z\u00e9ro ? dialog.setcolours.intro=Cliquez sur une couleur pour la changer dialog.setcolours.background=Arri\u00e8re-plan dialog.setcolours.borders=Bordures @@ -385,22 +435,28 @@ dialog.colourchooser.red=Rouge dialog.colourchooser.green=Vert dialog.colourchooser.blue=Bleu dialog.setlanguage.firstintro=Vous pouvez s\u00e9lectionner l'une des langues disponibles,

ou bien un fichier de langue \u00e0 utiliser. -dialog.setlanguage.secondintro=Vous devez sauvegarder vos param\u00e8tres puis

red\u00e9marrer Prune pour changer de langue. +dialog.setlanguage.secondintro=Vous devez sauvegarder vos param\u00e8tres puis

red\u00e9marrer GpsPrune pour changer de langue. dialog.setlanguage.language=Langue dialog.setlanguage.languagefile=Fichier de langue -dialog.setlanguage.endmessage=Enregistrez vos r\u00e9glages et red\u00e9marrez Prune\npour que le changement de langue soit effectif. +dialog.setlanguage.endmessage=Enregistrez vos r\u00e9glages et red\u00e9marrez GpsPrune\npour que le changement de langue soit effectif. +dialog.setlanguage.endmessagewithautosave=Red\u00e9marrez GpsPrune pour que le changement de langue soit effectif. dialog.diskcache.save=Enregistrer les images de carte sur le disque dialog.diskcache.dir=R\u00e9pertoire cache dialog.diskcache.createdir=Cr\u00e9er r\u00e9pertoire dialog.diskcache.nocreate=Le r\u00e9pertoire cache n'est pas cr\u00e9\u00e9 +dialog.deletefieldvalues.intro=Choisir le champ \u00e0 effacer pour l'\u00e9tendue actuelle +dialog.setlinewidth.text=Entrer l'\u00e9paisseur des lignes des traces (1-4) +dialog.downloadosm.desc=Confirmer le t\u00e9l\u00e9chargement des donn\u00e9es OSM brutes pour la zone indiqu\u00e9e : +dialog.searchwikipedianames.search=Chercher : # 3d window -dialog.3d.title=Vue 3D de Prune -dialog.3dlines.title=Grille de Prune +dialog.3d.title=Vue 3D de GpsPrune +dialog.3d.altitudefactor=Facteur d'exag\u00e9ration de l'altitude +dialog.3dlines.title=Grille de GpsPrune 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 messages confirm.loadfile=Donn\u00e9es charg\u00e9es depuis le fichier confirm.save.ok1=Enregistrement r\u00e9ussi de confirm.save.ok2=points dans le fichier @@ -408,7 +464,7 @@ 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.reverserange=\u00c9tendue invers\u00e9e confirm.addtimeoffset=D\u00e9calage ajout\u00e9 confirm.addaltitudeoffset=D\u00e9calage d'altitude ajout\u00e9 confirm.rearrangewaypoints=Waypoints r\u00e9arrang\u00e9s @@ -423,6 +479,8 @@ confirm.jpegload.single=la photo a \u00e9t\u00e9 ajout\u00e9e confirm.jpegload.multi=les photos ont \u00e9t\u00e9 ajout\u00e9es confirm.media.connect=m\u00e9dia reli\u00e9e confirm.photo.disconnect=photo d\u00e9tach\u00e9e +confirm.audio.disconnect=audio d\u00e9tach\u00e9 +confirm.media.removed=retir\u00e9 confirm.correlatephotos.single=photo a \u00e9t\u00e9 corr\u00e9l\u00e9e confirm.correlatephotos.multi=photos ont \u00e9t\u00e9 corr\u00e9l\u00e9es confirm.createpoint=Point cr\u00e9\u00e9 @@ -430,6 +488,10 @@ confirm.rotatephoto=Photo tourn\u00e9e confirm.running=En cours... confirm.lookupsrtm1=Trouv\u00e9 confirm.lookupsrtm2=valeurs d'altitude +confirm.deletefieldvalues=Valeurs effac\u00e9es +confirm.audioload=Fichiers audio ajout\u00e9s +confirm.correlateaudios.single=fichier audio a \u00e9t\u00e9 corr\u00e9l\u00e9 +confirm.correlateaudios.multi=fichiers audio ont \u00e9t\u00e9 corr\u00e9l\u00e9s # Buttons button.ok=OK @@ -454,6 +516,7 @@ button.selectall=Tout s\u00e9lectionner button.selectnone=Ne rien s\u00e9lectionner button.preview=Aper\u00e7u button.load=T\u00e9l\u00e9charger +button.upload=Envoyer button.guessfields=Deviner les champs button.showwebpage=Montrer page web button.check=V\u00e9rifier @@ -471,8 +534,9 @@ filetype.kmz=Fichiers KMZ filetype.gpx=Fichiers GPX filetype.pov=Fichiers POV filetype.svg=Fichiers SVG +filetype.audio=Fichiers MP3, OGG, WAV -# Display components || These are all for the side panels showing point/range details +# Display components display.nodata=Pas de donn\u00e9es charg\u00e9es display.noaltitudes=La trace ne comporte pas d'information d'altitude display.notimestamps=La trace ne comporte pas d'information de temps @@ -507,10 +571,15 @@ details.range.pace=Allure details.range.gradient=Pente details.lists.waypoints=Waypoints details.lists.photos=Photos +details.lists.audio=Audio details.photodetails=D\u00e9tails de la photo details.nophoto=Pas de photo details.photo.loading=Chargement details.media.connected=Reli\u00e9e +details.audiodetails=D\u00e9tails de l'audio +details.noaudio=Pas de fichier audio s\u00e9lectionner +details.audio.file=Fichier audio +details.audio.playing=Lecture en cours... map.overzoom=Aucune carte disponible \u00e0 ce niveau de zoom # Field names @@ -529,6 +598,7 @@ fieldname.movingdistance=Distance continue fieldname.duration=Dur\u00e9e fieldname.speed=Vitesse fieldname.verticalspeed=Vitesse verticale +fieldname.description=Description # Measurement units units.original=Original @@ -561,12 +631,14 @@ cardinal.s=S cardinal.e=E cardinal.w=O -# Undo operations || These will be displayed in the undo list after you've performed the operation, to tell you what you did +# Undo operations undo.load=charger les donn\u00e9es undo.loadphotos=charger les photos +undo.loadaudios=charger les fichiers audio undo.editpoint=\u00e9diter le point undo.deletepoint=effacer le point undo.removephoto=retirer la photo +undo.removeaudio=retirer le fichier audio undo.deleterange=effacer l'\u00e9tendue undo.compress=compresser la trace undo.insert=ins\u00e9rer les points @@ -579,16 +651,18 @@ undo.cutandmove=d\u00e9placer la s\u00e9lection undo.connect=relier undo.disconnect=d\u00e9tacher undo.correlatephotos=corr\u00e9ler les photos -undo.rearrangephotos=R\u00e9arranger les photos +undo.rearrangephotos=r\u00e9arranger les photos undo.createpoint=ajouter un point -undo.rotatephoto=Tourner la photo -undo.convertnamestotimes=Convertir les noms en points -undo.lookupsrtm=Rechercher les altitudes depuis SRTM +undo.rotatephoto=tourner la photo +undo.convertnamestotimes=convertir les noms en points +undo.lookupsrtm=rechercher les altitudes depuis SRTM +undo.deletefieldvalues=effacer les valeurs +undo.correlateaudios=corr\u00e9ler les fichiers audio # Error messages 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.save.failed=\u00c9chec 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 \u00eatre \u00e9craser. Enregistrer sur une copie ? @@ -607,9 +681,10 @@ error.jpegload.nofilesfound=Aucun fichier trouv\u00e9 error.jpegload.nojpegsfound=Aucun fichier jpeg trouv\u00e9 error.jpegload.nogpsfound=Aucune information GPS trouv\u00e9e error.jpegload.exifreadfailed=Information EXIF illisible. Aucune information EXIF ne peut \u00eatre lue\nsans une librairie interne ou externe. +error.audioload.nofilesfound=Aucun fichier audio trouv\u00e9 error.gpsload.unknown=Erreur inconnue -error.undofailed.title=Echec de l'annulation -error.undofailed.text=Echec de l'op\u00e9ration d'annulation +error.undofailed.title=\u00c9chec de l'annulation +error.undofailed.text=\u00c9chec de l'op\u00e9ration d'annulation error.function.noop.title=Fonction sans effet error.rearrange.noop=R\u00e9arrangement des points sans effet error.function.notavailable.title=Function non-disponible @@ -618,6 +693,10 @@ 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\u00e9rifiez votre connexion internet. -error.language.wrongfile=Le fichier s\u00e9lectionn\u00e9 n'est pas un fichier de langue pour Prune +error.language.wrongfile=Le fichier s\u00e9lectionn\u00e9 n'est pas un fichier de langue pour GpsPrune error.convertnamestotimes.nonames=Aucun nom n'a pu \u00eatre converti en horaire error.lookupsrtm.nonefound=Aucune valeur d'altitude trouv\u00e9e pour les points +error.lookupsrtm.nonerequired=Tous les points ont d\u00e9j\u00e0 une altitude, il n'y a rien \u00e0 r\u00e9cup\u00e9rer +error.gpsies.uploadnotok=Le serveur de Gpsies \u00e0 renvoy\u00e9 le message +error.gpsies.uploadfailed=L'envoi a \u00e9chou\u00e9 avec l'erreur +error.playaudiofailed=\u00c9chec de la lecture du fichier audio diff --git a/tim/prune/lang/prune-texts_hu.properties b/tim/prune/lang/prune-texts_hu.properties index 29840dd..1336c01 100644 --- a/tim/prune/lang/prune-texts_hu.properties +++ b/tim/prune/lang/prune-texts_hu.properties @@ -1,9 +1,10 @@ -# Text entries for the Prune application +# Text entries for the GpsPrune application # Hungarian entries thanks to Gy\u00f6rgy Ball\u00f3 # Menu entries menu.file=F\u00e1jl menu.file.addphotos=F\u00e9nyk\u00e9pek hozz\u00e1ad\u00e1sa +menu.file.recentfiles=Legut\u00f3bbi f\u00e1jlok menu.file.save=Ment\u00e9s sz\u00f6vegk\u00e9nt menu.file.exit=Kil\u00e9p\u00e9s menu.track=Nyomvonal @@ -41,6 +42,7 @@ menu.view.browser.yahoo=Yahoo! Maps menu.view.browser.bing=Bing Maps menu.settings=Be\u00e1ll\u00edt\u00e1sok menu.settings.onlinemode=T\u00e9rk\u00e9pek bet\u00f6lt\u00e9se az internetr\u0151l +menu.settings.autosave=Be\u00e1ll\u00edt\u00e1sok automatikus ment\u00e9se a programb\u00f3l t\u00f6rt\u00e9n\u0151 kil\u00e9p\u00e9skor menu.help=S\u00fag\u00f3 # Popup menu for map menu.map.zoomin=Nagy\u00edt\u00e1s @@ -75,6 +77,7 @@ shortcut.menu.help.help=H # Functions function.open=F\u00e1jl megnyit\u00e1sa +function.importwithgpsbabel=F\u00e1jl import\u00e1l\u00e1sa GPSBabellel function.loadfromgps=Adatok let\u00f6lt\u00e9se GPS-r\u0151l function.sendtogps=Adatok felt\u00f6lt\u00e9se GPS-re function.exportkml=Export\u00e1l\u00e1s KML-be @@ -122,13 +125,14 @@ function.playaudio=Hangf\u00e1jl lej\u00e1tsz\u00e1sa function.stopaudio=Hangf\u00e1jl meg\u00e1ll\u00edt\u00e1sa function.help=S\u00fag\u00f3 function.showkeys=Gyorsbillenty\u0171k megjelen\u00edt\u00e9se -function.about=A Prune n\u00e9vjegye +function.about=A GpsPrune n\u00e9vjegye function.checkversion=\u00daj verzi\u00f3 keres\u00e9se function.saveconfig=Be\u00e1ll\u00edt\u00e1sok ment\u00e9se function.diskcache=T\u00e9rk\u00e9pek ment\u00e9se lemezre +function.managetilecache=Csempegyors\u00edt\u00f3t\u00e1r kezel\u00e9se # Dialogs -dialog.exit.confirm.title=Kil\u00e9p\u00e9s a Prune-b\u00f3l +dialog.exit.confirm.title=Kil\u00e9p\u00e9s a GpsPrune-b\u00f3l dialog.exit.confirm.text=Az adatok nincsenek elmentve. Biztos benne, hogy kil\u00e9p? dialog.openappend.title=Hozz\u00e1f\u0171z\u00e9s a megl\u00e9v\u0151 adatokhoz dialog.openappend.text=Hozz\u00e1f\u0171zi ezeket az adatokat a m\u00e1r bet\u00f6lt\u00f6tt adatokhoz? @@ -189,6 +193,9 @@ dialog.exportgpx.name=N\u00e9v dialog.exportgpx.desc=Le\u00edr\u00e1s dialog.exportgpx.includetimestamps=Id\u0151b\u00e9lyegek is dialog.exportgpx.copysource=Forr\u00e1s xml m\u00e1sol\u00e1sa +dialog.exportgpx.encoding=Karakterk\u00f3dol\u00e1s +dialog.exportgpx.encoding.system=Rendszer +dialog.exportgpx.encoding.utf8=UTF-8 dialog.exportpov.text=Adja meg a param\u00e9tereket a POV exporthoz dialog.exportpov.font=Bet\u0171t\u00edpus dialog.exportpov.camerax=X kamera @@ -341,14 +348,16 @@ dialog.compress.wackypoints.paramdesc=T\u00e1vols\u00e1gt\u00e9nyez\u0151 dialog.compress.singletons.title=Egyke pontok elt\u00e1vol\u00edt\u00e1sa dialog.compress.singletons.paramdesc=T\u00e1vols\u00e1gt\u00e9nyez\u0151 dialog.compress.duplicates.title=Kett\u0151z\u00f6tt pontok elt\u00e1vol\u00edt\u00e1sa +dialog.compress.douglaspeucker.title=Douglas-Peucker t\u00f6m\u00f6r\u00edt\u00e9s +dialog.compress.douglaspeucker.paramdesc=T\u00f6m\u00f6r\u00edt\u00e9si t\u00e9nyez\u0151 dialog.compress.summarylabel=T\u00f6rlend\u0151 pontok dialog.pastecoordinates.desc=Adja meg vagy illessze be a koordin\u00e1t\u00e1kat ide dialog.pastecoordinates.coords=Koordin\u00e1t\u00e1k dialog.pastecoordinates.nothingfound=Ellen\u0151rizze a koordin\u00e1t\u00e1kat, \u00e9s pr\u00f3b\u00e1lja \u00f3jra -dialog.help.help=Tov\u00e1bbi inform\u00e1ci\u00f3k\u00e9rt \u00e9s kezel\u00e9si \u00fatmutat\u00f3\u00e9rt l\u00e1sd a \n http://activityworkshop.net/software/prune/\nwebhelyet. +dialog.help.help=Tov\u00e1bbi inform\u00e1ci\u00f3k\u00e9rt \u00e9s kezel\u00e9si \u00fatmutat\u00f3\u00e9rt l\u00e1sd a \n http://activityworkshop.net/software/gpsprune/\nwebhelyet. dialog.about.version=Verzi\u00f3 dialog.about.build=Build -dialog.about.summarytext1=A Prune egy program GPS vev\u0151kr\u0151l sz\u00e1rmaz\u00f3 adatok bet\u00f6lt\u00e9s\u00e9re, megjelen\u00edt\u00e9s\u00e9re \u00e9s szerkeszt\u00e9s\u00e9re. +dialog.about.summarytext1=A GpsPrune egy program GPS vev\u0151kr\u0151l sz\u00e1rmaz\u00f3 adatok bet\u00f6lt\u00e9s\u00e9re, megjelen\u00edt\u00e9s\u00e9re \u00e9s szerkeszt\u00e9s\u00e9re. dialog.about.summarytext2=Gnu GPL licenc alatt ker\u00fclt kiad\u00e1sra a szabad, ny\u00edlt, vil\u00e1gm\u00e9ret\u0171 haszn\u00e1lathoz \u00e9s fejleszt\u00e9shez.
M\u00e1sol\u00e1sa, terjeszt\u00e9se \u00e9s m\u00f3dos\u00edt\u00e1sa megengedett \u00e9s \u00f6szt\u00f6nz\u00f6tt
a mell\u00e9kelt license.txt f\u00e1jlban r\u00f6gz\u00edtett felt\u00e9telek szerint dialog.about.summarytext3=Tov\u00e1bbi inform\u00e1ci\u00f3k\u00e9rt \u00e9s kezel\u00e9si \u00fatmutat\u00f3\u00e9rt l\u00e1sd a http://activityworkshop.net/ webhelyet. dialog.about.languages=El\u00e9rhet\u0151 nyelvek @@ -369,7 +378,7 @@ dialog.about.systeminfo.exiflib.external.failed=K\u00fcls\u0151 (nem tal\u00e1lh dialog.about.yes=Igen dialog.about.no=Nem dialog.about.credits=K\u00e9sz\u00edt\u0151k -dialog.about.credits.code=Prune k\u00f3dj\u00e1t \u00edrta: +dialog.about.credits.code=GpsPrune k\u00f3dj\u00e1t \u00edrta: dialog.about.credits.exifcode=Exif k\u00f3d: dialog.about.credits.icons=N\u00e9h\u00e1ny ikon sz\u00e1rmazik: dialog.about.credits.translators=Ford\u00edt\u00f3k @@ -379,12 +388,12 @@ dialog.about.credits.othertools=Egy\u00e9b eszk\u00f6z\u00f6k dialog.about.credits.thanks=K\u00f6sz\u00f6net: dialog.about.readme=Olvassel dialog.checkversion.error=A verzi\u00f3sz\u00e1m nem ellen\u0151rizhet\u0151.\nEllen\u0151rizze az internetkapcsolatot. -dialog.checkversion.uptodate=A Prune leg\u00fajabb verzi\u00f3j\u00e1t haszn\u00e1lja. -dialog.checkversion.newversion1=El\u00e9rhet\u0151 a Prune \u00faj verzi\u00f3ja! A leg\u00fajabb veri\u00f3 most: +dialog.checkversion.uptodate=A GpsPrune leg\u00fajabb verzi\u00f3j\u00e1t haszn\u00e1lja. +dialog.checkversion.newversion1=El\u00e9rhet\u0151 a GpsPrune \u00faj verzi\u00f3ja! A leg\u00fajabb verzi\u00f3 most: dialog.checkversion.newversion2=. dialog.checkversion.releasedate1=Ez az \u00faj verzi\u00f3 kiad\u00e1sra ker\u00fclt: dialog.checkversion.releasedate2=. -dialog.checkversion.download=Az \u00faj verzi\u00f3 let\u00f6lt\u00e9s\u00e9hez keresse fel a http://activityworkshop.net/software/prune/download.html webhelyet. +dialog.checkversion.download=Az \u00faj verzi\u00f3 let\u00f6lt\u00e9s\u00e9hez keresse fel a http://activityworkshop.net/software/gpsprune/download.html webhelyet. dialog.keys.intro=A k\u00f6vetkez\u0151 gyorsbillenty\u0171k haszn\u00e1lhat\u00f3k az eg\u00e9r haszn\u00e1lata helyett dialog.keys.keylist=
Ny\u00edlbillenty\u0171kT\u00e9rk\u00e9p mozgat\u00e1sa balra, jobbra, fel, le
Ctrl + bal, jobb ny\u00edlEl\u0151z\u0151 vagy k\u00f6vetkez\u0151 pont kiv\u00e1laszt\u00e1sa
Ctrl + fel, le ny\u00edlNagy\u00edt\u00e1s vagy kicsiny\u00edt\u00e9s
Ctrl + PgUp, PgDownEl\u0151z\u0151, k\u00f6vetkez\u0151 szakasz kiv\u00e1laszt\u00e1sa
Ctrl + Home, EndEls\u0151, utols\u00f3 pont kiv\u00e1laszt\u00e1sa
DelJelenlegi pont t\u00f6rl\u00e9se
dialog.keys.normalmodifier=Ctrl @@ -409,6 +418,7 @@ dialog.saveconfig.prune.kmzimageheight=KMZ k\u00e9pmagass\u00e1g dialog.saveconfig.prune.colourscheme=Sz\u00edns\u00e9ma dialog.saveconfig.prune.linewidth=Vonalsz\u00e9less\u00e9g dialog.saveconfig.prune.kmltrackcolour=KML nyomvonal sz\u00edne +dialog.saveconfig.prune.autosavesettings=Automatikus ment\u00e9s be\u00e1ll\u00edt\u00e1sai dialog.setpaths.intro=Ha sz\u00fcks\u00e9ges, kiv\u00e1laszthatja a k\u00fcls\u0151 alkalmaz\u00e1sok \u00fatvonalait: dialog.setpaths.found=\u00datvonal megtal\u00e1lhat\u00f3? dialog.addaltitude.noaltitudes=A kiv\u00e1lasztott tartom\u00e1ny nem tartalmaz magass\u00e1gi \u00e9rt\u00e9keket @@ -428,23 +438,35 @@ dialog.colourchooser.red=Piros dialog.colourchooser.green=Z\u00f6ld dialog.colourchooser.blue=K\u00e9k dialog.setlanguage.firstintro=Kiv\u00e1laszthat egy be\u00e9p\u00edtett nyelvet,

vagy v\u00e1lasszon egy sz\u00f6vegf\u00e1jlt helyette. -dialog.setlanguage.secondintro=Mentenie kell a be\u00e1ll\u00edt\u00e1sokat, majd

a nyelv v\u00e1lt\u00e1s\u00e1hoz ind\u00edtsa \u00fajra a Prune-t. +dialog.setlanguage.secondintro=Mentenie kell a be\u00e1ll\u00edt\u00e1sokat, majd

a nyelv v\u00e1lt\u00e1s\u00e1hoz ind\u00edtsa \u00fajra a GpsPrune-t. dialog.setlanguage.language=Nyelv dialog.setlanguage.languagefile=Nyelvi f\u00e1jl -dialog.setlanguage.endmessage=Most mentse a be\u00e1ll\u00edt\u00e1sokat, \u00e9s ind\u00edtsa \u00fajra a Prune-t,\nhogy a nyelv v\u00e1lt\u00e1sa \u00e9rv\u00e9nybe l\u00e9pjen +dialog.setlanguage.endmessage=Most mentse a be\u00e1ll\u00edt\u00e1sokat, \u00e9s ind\u00edtsa \u00fajra a GpsPrune-t,\nhogy a nyelv v\u00e1lt\u00e1sa \u00e9rv\u00e9nybe l\u00e9pjen +dialog.setlanguage.endmessagewithautosave=A nyelv megv\u00e1ltoztat\u00e1s\u00e1nak \u00e9rv\u00e9nyes\u00edt\u00e9s\u00e9hez ind\u00edtsa \u00fajra a GpsPrune-t. dialog.diskcache.save=T\u00e9rk\u00e9pek ment\u00e9se a lemezre dialog.diskcache.dir=Gyors\u00edt\u00f3t\u00e1r k\u00f6nyvt\u00e1ra dialog.diskcache.createdir=K\u00f6nyvt\u00e1r l\u00e9trehoz\u00e1sa dialog.diskcache.nocreate=A gyors\u00edt\u00f3t\u00e1r k\u00f6nyvt\u00e1ra nem ker\u00fclt l\u00e9trehoz\u00e1sra +dialog.diskcache.table.path=El\u00e9r\u00e9si \u00fat +dialog.diskcache.table.usedby=Haszn\u00e1lja +dialog.diskcache.table.zoom=Nagy\u00edt\u00e1s +dialog.diskcache.table.tiles=Csemp\u00e9k +dialog.diskcache.table.megabytes=Megab\u00e1jt +dialog.diskcache.tileset=Csempecsoport +dialog.diskcache.tileset.multiple=t\u00f6bb +dialog.diskcache.deleteold=R\u00e9gi csemp\u00e9k t\u00f6rl\u00e9se +dialog.diskcache.deleteall=Az \u00f6sszes csempe t\u00f6rl\u00e9se +dialog.diskcache.deleted1= +dialog.diskcache.deleted2=f\u00e1jl t\u00f6r\u00f6lve a gyors\u00edt\u00f3t\u00e1rb\u00f3l dialog.deletefieldvalues.intro=V\u00e1lassza ki a t\u00f6rlend\u0151 mez\u0151t a jelenlegi tartom\u00e1nyban dialog.setlinewidth.text=Adja meg a rajzoland\u00f3 vonalak vastags\u00e1g\u00e1t a nyomvonalak sz\u00e1m\u00e1ra (1-4) dialog.downloadosm.desc=Nyers OSM adatok let\u00f6lt\u00e9s\u00e9nek meger\u0151s\u00edt\u00e9se a megadott ter\u00fcletre: dialog.searchwikipedianames.search=Keres\u00e9s erre: # 3d window -dialog.3d.title=Prune 3D n\u00e9zet +dialog.3d.title=GpsPrune 3D n\u00e9zet dialog.3d.altitudefactor=Magass\u00e1gi ny\u00fajt\u00e1si t\u00e9nyez\u0151 -dialog.3dlines.title=Prune r\u00e1csvonalak +dialog.3dlines.title=GpsPrune r\u00e1csvonalak dialog.3dlines.empty=Nincsenek megjelen\u00edthet\u0151 r\u00e1csvonalak! dialog.3dlines.intro=Ezek a r\u00e1csvonalak a 3D n\u00e9zethez @@ -516,6 +538,7 @@ button.resettodefaults=Vissza\u00e1ll\u00edt\u00e1s az alap\u00e9rtelmezettre button.browse=B\u00f6ng\u00e9sz\u00e9s... button.addnew=\u00daj hozz\u00e1ad\u00e1sa button.delete=T\u00f6rl\u00e9s +button.manage=Kezel\u00e9s # File types filetype.txt=TXT f\u00e1jlok @@ -567,9 +590,10 @@ details.lists.audio=Hang details.photodetails=F\u00e9nyk\u00e9p r\u00e9szletei details.nophoto=Nincs f\u00e9nyk\u00e9p kiv\u00e1lasztva details.photo.loading=Bet\u00f6lt\u00e9s +details.photo.bearing=Ir\u00e1ny details.media.connected=\u00d6sszekapcsolva details.audiodetails=Hang r\u00e9szletei -details.noaudio=Nincs hang kiv\u00e1lasztva +details.noaudio=Nincs hangf\u00e1jl kiv\u00e1lasztva details.audio.file=Hangf\u00e1jl details.audio.playing=lej\u00e1tsz\u00e1s... map.overzoom=Nem \u00e9rhet\u0151 el t\u00e9rk\u00e9p ezen a nagy\u00edt\u00e1si szinten @@ -590,6 +614,7 @@ fieldname.movingdistance=Mozg\u00e1si t\u00e1vols\u00e1g fieldname.duration=Id\u0151tartam fieldname.speed=Sebess\u00e9g fieldname.verticalspeed=F\u00fcgg\u0151leges sebess\u00e9g +fieldname.description=Le\u00edr\u00e1s # Measurement units units.original=Eredeti @@ -684,10 +709,13 @@ error.3d=Hiba t\u00f6rt\u00e9nt a 3d megjelen\u00edt\u00e9ssel error.readme.notfound=Az olvassel f\u00e1jl nem tal\u00e1lhat\u00f3 error.osmimage.dialogtitle=Hiba a t\u00e9rk\u00e9p bet\u00f6lt\u00e9sekor error.osmimage.failed=A t\u00e9rk\u00e9p bet\u00f6lt\u00e9se nem siker\u00fclt. Ellen\u0151rizze az internetkapcsolatot. -error.language.wrongfile=\u00dagy t\u0171nik, hogy a kiv\u00e1lasztott f\u00e1jl nem egy nyelvi f\u00e1jl a Prune-hoz +error.language.wrongfile=\u00dagy t\u0171nik, hogy a kiv\u00e1lasztott f\u00e1jl nem egy nyelvi f\u00e1jl a GpsPrune-hoz error.convertnamestotimes.nonames=A nevek nem konvert\u00e1lhat\u00f3k id\u0151adatokk\u00e1 error.lookupsrtm.nonefound=Nem \u00e9rhet\u0151 el magass\u00e1gi \u00e9rt\u00e9k ezekhez a pontokhoz error.lookupsrtm.nonerequired=Az \u00f6sszes pont m\u00e1r rendelkezik magass\u00e1gadatokkal, \u00edgy nincs mit keresni error.gpsies.uploadnotok=A gpsies szerver a k\u00f6vetkez\u0151 \u00fczenetet adta vissza error.gpsies.uploadfailed=A felt\u00f6lt\u00e9s nem siker\u00fclt a k\u00f6vetkez\u0151 hib\u00e1val error.playaudiofailed=A hangf\u00e1jl lej\u00e1tsz\u00e1sa nem siker\u00fclt +error.cache.notthere=A csempegyors\u00edt\u00f3t\u00e1r k\u00f6nyvt\u00e1ra nem tal\u00e1lhat\u00f3 +error.cache.empty=A csempegyors\u00edt\u00f3t\u00e1r k\u00f6nyvt\u00e1ra \u00fcres +error.cache.cannotdelete=Nincs t\u00f6r\u00f6lhet\u0151 csempe diff --git a/tim/prune/lang/prune-texts_it.properties b/tim/prune/lang/prune-texts_it.properties index bf19b95..eb4d1ff 100644 --- a/tim/prune/lang/prune-texts_it.properties +++ b/tim/prune/lang/prune-texts_it.properties @@ -1,9 +1,10 @@ -# Text entries for the Prune application +# Text entries for the GpsPrune application # Italian entries thanks to josatoc # Menu entries menu.file=File menu.file.addphotos=Aggiungi foto +menu.file.recentfiles=File recenti menu.file.save=Salva menu.file.exit=Esci menu.track=Traccia @@ -122,13 +123,13 @@ function.playaudio=Riproduci ripresa audio function.stopaudio=Ferma ripresa audio function.help=Aiuto function.showkeys=Visualizza tasti scelta rapida -function.about=Informazioni su Prune +function.about=Informazioni su GpsPrune function.checkversion=Controlla gli aggiornamenti function.saveconfig=Salva configurazione function.diskcache=Salva mappe su disco # Dialogs -dialog.exit.confirm.title=Esci da Prune +dialog.exit.confirm.title=Esci da GpsPrune 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\u00e0 caricati? @@ -189,6 +190,8 @@ dialog.exportgpx.name=Nome dialog.exportgpx.desc=Descrizione dialog.exportgpx.includetimestamps=Includi dati temporali dialog.exportgpx.copysource=Copia xml sorgente +dialog.exportgpx.encoding.system=Sistema +dialog.exportgpx.encoding.utf8=UTF-8 dialog.exportpov.text=Per favore inserisci i parametri per l'esportazione in POV dialog.exportpov.font=Font dialog.exportpov.camerax=Camera X @@ -345,10 +348,10 @@ dialog.compress.summarylabel=Punti da cancellare dialog.pastecoordinates.desc=Inserisci o incolla qui le coordinate dialog.pastecoordinates.coords=Coordinate dialog.pastecoordinates.nothingfound=Per favore, controlla le coordinate e riprova -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/gpsprune/\nper maggiori informazioni e per la guida utente. dialog.about.version=Versione dialog.about.build=Build -dialog.about.summarytext1=Prune \u00e8 un programma per il caricamento, la visione e l'edit di dati provenienti da un GPS. +dialog.about.summarytext1=GpsPrune \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 @@ -369,7 +372,7 @@ dialog.about.systeminfo.exiflib.external.failed=Esterna (non trovata) dialog.about.yes=S\u00ec dialog.about.no=No dialog.about.credits=Crediti -dialog.about.credits.code=Il codice Prune code \u00e8 scritto da +dialog.about.credits.code=Il codice GpsPrune 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 @@ -379,12 +382,12 @@ dialog.about.credits.othertools=Altri tool 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 \u00e8 disponibile! L'ultima versione \u00e8 ora la versione +dialog.checkversion.uptodate=Stai usando l'ultima versione di GpsPrune +dialog.checkversion.newversion1=Una nuova versione di GpsPrune \u00e8 disponibile! L'ultima versione \u00e8 ora la versione dialog.checkversion.newversion2=. 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.checkversion.download=Per scaricare la nuova versione vai a http://activityworkshop.net/software/gpsprune/download.html. dialog.keys.intro=Puoi utilizzare i seguenti tast di scelta rapida al posto del mouse dialog.keys.keylist=
Tasti frecciaMuovi mappa destra, sinistra, su, giu'
Ctrl + freccia destra, sinistraSelezione punto successivo o precedente
Ctrl + freccia su, giu'Zoom in o out
DelCancella punto attuale
dialog.keys.normalmodifier=Ctrl @@ -428,10 +431,10 @@ dialog.colourchooser.red=Rosso dialog.colourchooser.green=Verde dialog.colourchooser.blue=Blu dialog.setlanguage.firstintro=Puoi selezionare una delle lingue incluse,

oppure selezionare un file di testo. -dialog.setlanguage.secondintro=Devi salvare le impostazioni e

riavviare Prune per cambiare la lingua. +dialog.setlanguage.secondintro=Devi salvare le impostazioni e

riavviare GpsPrune per cambiare la lingua. dialog.setlanguage.language=Lingua dialog.setlanguage.languagefile=File della lingua -dialog.setlanguage.endmessage=Ora salva le tue preferenze e riavvia Prune\n per rendere effettivo il cambio di lingua +dialog.setlanguage.endmessage=Ora salva le tue preferenze e riavvia GpsPrune\n per rendere effettivo il cambio di lingua dialog.diskcache.save=Salva la mappa sul disco dialog.diskcache.dir=Cartella della cache dialog.diskcache.createdir=Crea cartella @@ -442,9 +445,9 @@ dialog.downloadosm.desc=Conferma lo scarico dei dati raw OSM per l'area specific dialog.searchwikipedianames.search=Cerca per: # 3d window -dialog.3d.title=Visione Prune in 3D +dialog.3d.title=Visione GpsPrune in 3D dialog.3d.altitudefactor=Fattore di moltiplicazione della quota -dialog.3dlines.title=Griglia di Prune +dialog.3dlines.title=Griglia di GpsPrune dialog.3dlines.empty=Nessuna griglia mostrata! dialog.3dlines.intro=Queste sono le linee della griglia per la visione 3D @@ -684,7 +687,7 @@ 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.language.wrongfile=Il file selezionato non sembra essere un file di lingua per Prune +error.language.wrongfile=Il file selezionato non sembra essere un file di lingua per GpsPrune error.convertnamestotimes.nonames=Nomi non convertibili in orari error.lookupsrtm.nonefound=Valori di quota non trovati error.lookupsrtm.nonerequired=Tutti i punti hanno gi\u00e0 una quota, non c'\u00e8 niente da cercare diff --git a/tim/prune/lang/prune-texts_ja.properties b/tim/prune/lang/prune-texts_ja.properties index c6b1653..30c3556 100644 --- a/tim/prune/lang/prune-texts_ja.properties +++ b/tim/prune/lang/prune-texts_ja.properties @@ -1,4 +1,4 @@ -# Text entries for the Prune application +# Text entries for the GpsPrune application # Japanese entries as extra # Menu entries @@ -84,12 +84,12 @@ function.rotatephotoright=\u5199\u771f\u3092\u53f3\u306b\u56de\u3059 function.ignoreexifthumb=EXIF\u30b5\u30e0\u30cd\u30a4\u30eb\u3092\u7121\u8996 function.help=\u30d8\u30eb\u30d7 function.showkeys=\u30b7\u30e7\u30fc\u30c8\u30ab\u30c3\u30c8\u30ad\u30fc\u3092\u8868\u793a -function.about=Prune \u306b\u3064\u3044\u3066 +function.about=GpsPrune \u306b\u3064\u3044\u3066 function.checkversion=\u65b0\u3057\u3044\u30d0\u30fc\u30b8\u30e7\u30f3\u3092\u8868\u793a function.saveconfig=\u8a2d\u5b9a\u3092\u4fdd\u5b58 # Dialogs -dialog.exit.confirm.title=Prune \u3092\u7d42\u4e86 +dialog.exit.confirm.title=GpsPrune \u3092\u7d42\u4e86 dialog.exit.confirm.text=\u30c7\u30fc\u30bf\u306f\u4fdd\u5b58\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002\u672c\u5f53\u306b\u7d42\u4e86\u3057\u307e\u3059\u304b\uff1f dialog.openappend.title=\u65e2\u5b58\u306e\u30c7\u30fc\u30bf\u3092\u52a0\u3048\u308b dialog.openappend.text=\u3053\u306e\u30c7\u30fc\u30bf\u306b\u65e2\u5b58\u306e\u30c7\u30fc\u30bf\u30fc\u3092\u8aad\u307f\u8fbc\u3080\u3002 @@ -277,10 +277,10 @@ dialog.compress.summarylabel=\u524a\u9664\u3059\u308b\u70b9 dialog.pastecoordinates.desc=\u5ea7\u6a19\u3092\u3053\u3053\u306b\u5165\u529b\u3059\u308b\u304b\u30da\u30fc\u30b9\u30c8\u3057\u3066\u304f\u3060\u3055\u3044\u3002 dialog.pastecoordinates.coords=\u5ea7\u6a19 dialog.pastecoordinates.nothingfound=\u5ea7\u6a19\u306e\u78ba\u8a8d\u3092\u3057\u3066\u3001\u3082\u3046\u4e00\u5ea6\u8a66\u3057\u3066\u304f\u3060\u3055\u3044\u3002 -dialog.help.help=\u8a73\u3057\u3044\u60c5\u5831\u3084\u3001\u30e6\u30fc\u30b6\u30fc\u30ac\u30a4\u30c9\u306a\u3069\u306f\u3001\nhttp://activityworkshop.net/software/prune/ \u3092\u898b\u3066\u304f\u3060\u3055\u3044\u3002 +dialog.help.help=\u8a73\u3057\u3044\u60c5\u5831\u3084\u3001\u30e6\u30fc\u30b6\u30fc\u30ac\u30a4\u30c9\u306a\u3069\u306f\u3001\nhttp://activityworkshop.net/software/gpsprune/ \u3092\u898b\u3066\u304f\u3060\u3055\u3044\u3002 dialog.about.version=\u30d0\u30fc\u30b8\u30e7\u30f3 dialog.about.build=Build -dialog.about.summarytext1=Prune \u306f\u3001GPS\u53d7\u4fe1\u6a5f\u304b\u3089\u306e\u30c7\u30fc\u30bf\u3092\u8aad\u307f\u8fbc\u307f\u3001\u8868\u793a\u3057\u3001\u7de8\u96c6\u3059\u308b\u305f\u3081\u306e\u30d7\u30ed\u30b0\u30e9\u30e0\u3067\u3059\u3002 +dialog.about.summarytext1=GpsPrune \u306f\u3001GPS\u53d7\u4fe1\u6a5f\u304b\u3089\u306e\u30c7\u30fc\u30bf\u3092\u8aad\u307f\u8fbc\u307f\u3001\u8868\u793a\u3057\u3001\u7de8\u96c6\u3059\u308b\u305f\u3081\u306e\u30d7\u30ed\u30b0\u30e9\u30e0\u3067\u3059\u3002 dialog.about.summarytext2=\u3053\u308c\u306f\u3001Gnu GPL\u306e\u4e0b\u306b\u516c\u958b\u3055\u308c\u3001\u81ea\u7531\u3067\u3001\u30aa\u30fc\u30d7\u30f3\u3067\u3001\u4e16\u754c\u4e2d\u3067\u3064\u304b\u3048\u3001\u62e1\u5f35\u53ef\u80fd\u3067\u3059\u3002
"license.txt"\u306b\u304b\u304b\u308c\u3066\u3044\u308b\u6761\u4ef6\u306b\u3088\u308b\u3068\u3001
\u8907\u88fd\u30fb\u518d\u914d\u5e03\u30fb\u6539\u5909\u306f\u3001\u8a31\u3055\u308c\u3066\u304a\u308a\u3001\u304b\u3064\u5968\u52b1\u3055\u308c\u3066\u3044\u307e\u3059\u3002 dialog.about.summarytext3=\u3082\u3063\u3068\u8a73\u3057\u3044\u60c5\u5831\u3084\u30e6\u30fc\u30b6\u30fc\u30ac\u30a4\u30c9\u306a\u3069\u306f\u3001http://activityworkshop.net/\u3092\u898b\u3066\u304f\u3060\u3055\u3044\u3002 dialog.about.languages=\u5229\u7528\u53ef\u80fd\u306a\u8a00\u8a9e @@ -296,7 +296,7 @@ dialog.about.systeminfo.gnuplot=Gnuplot \u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u6e dialog.about.yes=\u306f\u3044 dialog.about.no=\u3044\u3044\u3048 dialog.about.credits=\u30af\u30ec\u30b8\u30c3\u30c8 -dialog.about.credits.code=Prune \u306e\u30b3\u30fc\u30c9\u306e\u4f5c\u8005 +dialog.about.credits.code=GpsPrune \u306e\u30b3\u30fc\u30c9\u306e\u4f5c\u8005 dialog.about.credits.exifcode=Exif \u306e\u30b3\u30fc\u30c9\u306e\u4f5c\u8005 dialog.about.credits.icons=\u3044\u304f\u3064\u304b\u306e\u30a2\u30a4\u30b3\u30f3 dialog.about.credits.translators=\u7ffb\u8a33\u8005 @@ -306,12 +306,12 @@ dialog.about.credits.othertools=\u305d\u306e\u4ed6\u30c4\u30fc\u30eb dialog.about.credits.thanks=\u611f\u8b1d dialog.about.readme=\u521d\u3081\u306b\u8aad\u3093\u3067\u304f\u3060\u3055\u3044 dialog.checkversion.error=\u30d0\u30fc\u30b8\u30e7\u30f3\u756a\u53f7\u304c\u30c1\u30a7\u30c3\u30af\u3067\u304d\u307e\u305b\u3093\u3002\n\u30a4\u30f3\u30bf\u30fc\u30cd\u30c3\u30c8\u63a5\u7d9a\u306e\u78ba\u8a8d\u3092\u3057\u3066\u304f\u3060\u3055\u3044\u3002 -dialog.checkversion.uptodate=\u3042\u306a\u305f\u306f\u6700\u65b0\u30d0\u30fc\u30b8\u30e7\u30f3\u306ePrune\u3092\u4f7f\u3063\u3066\u3044\u307e\u3059\u3002 -dialog.checkversion.newversion1=\u65b0\u30d0\u30fc\u30b8\u30e7\u30f3\u306e Prune \u304c\u5165\u624b\u53ef\u80fd\u3067\u3059\u3002\u6700\u65b0\u30d0\u30fc\u30b8\u30e7\u30f3\u306f\u73fe\u5728 +dialog.checkversion.uptodate=\u3042\u306a\u305f\u306f\u6700\u65b0\u30d0\u30fc\u30b8\u30e7\u30f3\u306eGpsPrune\u3092\u4f7f\u3063\u3066\u3044\u307e\u3059\u3002 +dialog.checkversion.newversion1=\u65b0\u30d0\u30fc\u30b8\u30e7\u30f3\u306e GpsPrune \u304c\u5165\u624b\u53ef\u80fd\u3067\u3059\u3002\u6700\u65b0\u30d0\u30fc\u30b8\u30e7\u30f3\u306f\u73fe\u5728 dialog.checkversion.newversion2=\u3067\u3059\u3002 dialog.checkversion.releasedate1=\u65b0\u30d0\u30fc\u30b8\u30e7\u30f3\u306f\u3001 dialog.checkversion.releasedate2=\u306b\u30ea\u30ea\u30fc\u30b9\u3057\u307e\u3057\u305f\u3002 -dialog.checkversion.download=\u65b0\u30d0\u30fc\u30b8\u30e7\u30f3\u3092\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3059\u308b\u306b\u306f\u3001 http://activityworkshop.net/software/prune/download.html \u3078\u884c\u3063\u3066\u304f\u3060\u3055\u3044\u3002 +dialog.checkversion.download=\u65b0\u30d0\u30fc\u30b8\u30e7\u30f3\u3092\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3059\u308b\u306b\u306f\u3001 http://activityworkshop.net/software/gpsprune/download.html \u3078\u884c\u3063\u3066\u304f\u3060\u3055\u3044\u3002 dialog.keys.intro=\u30de\u30a6\u30b9\u306e\u4ee3\u308f\u308a\u306b\u6b21\u306e\u30b7\u30e7\u30fc\u30c8\u30ab\u30c3\u30c8\u30ad\u30fc\u3092\u4f7f\u3046\u4e8b\u304c\u3067\u304d\u307e\u3059\u3002 dialog.keys.keylist=
\u77e2\u5370\u30ad\u30fc\u5730\u56f3\u3092\u4e0a\u4e0b\u5de6\u53f3\u306b\u79fb\u52d5
Ctrl + \u5de6\u30fb\u53f3\u77e2\u5370\u524d\u30fb\u6b21\u306e\u70b9\u3092\u9078\u629e
Ctrl + \u4e0a\u30fb\u4e0b\u77e2\u5370\u62e1\u5927\u30fb\u7e2e\u5c0f
Del\u73fe\u5728\u306e\u70b9\u3092\u524a\u9664
dialog.saveconfig.desc=\u4e0b\u8a18\u306e\u8a2d\u5b9a\u304c\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u306b\u4fdd\u5b58\u3055\u308c\u307e\u3059 @@ -349,14 +349,14 @@ dialog.colourchooser.red=\u8d64 dialog.colourchooser.green=\u7dd1 dialog.colourchooser.blue=\u9752 dialog.setlanguage.firstintro=\u642d\u8f09\u3055\u308c\u3066\u3044\u308b\u8a00\u8a9e\u306e\u4e00\u3064\u3092\u9078\u3076\u304b\u3001

\u4ee3\u308f\u308a\u306b\u4f7f\u3046\u30c6\u30ad\u30b9\u30c8\u30d5\u30a1\u30a4\u30eb\u3092\u9078\u3073\u307e\u3059\u3002 -dialog.setlanguage.secondintro=\u8a00\u8a9e\u3092\u5207\u308a\u66ff\u3048\u308b\u306b\u306f\u3001\u8a2d\u5b9a\u3092\u4fdd\u5b58\u3057\u3066

Prune \u3092\u518d\u8d77\u52d5\u3057\u3066\u304f\u3060\u3055\u3044\u3002 +dialog.setlanguage.secondintro=\u8a00\u8a9e\u3092\u5207\u308a\u66ff\u3048\u308b\u306b\u306f\u3001\u8a2d\u5b9a\u3092\u4fdd\u5b58\u3057\u3066

GpsPrune \u3092\u518d\u8d77\u52d5\u3057\u3066\u304f\u3060\u3055\u3044\u3002 dialog.setlanguage.language=\u8a00\u8a9e dialog.setlanguage.languagefile=\u8a00\u8a9e\u30d5\u30a1\u30a4\u30eb -dialog.setlanguage.endmessage=\u8a2d\u5b9a\u3092\u4fdd\u5b58\u3057\u3001\u8a00\u8a9e\u306e\u5909\u66f4\u3092\u6709\u52b9\u306b\u3059\u308b\u305f\u3081\u306b\nPrune \u3092\u518d\u8d77\u52d5\u3057\u3066\u304f\u3060\u3055\u3044\u3002 +dialog.setlanguage.endmessage=\u8a2d\u5b9a\u3092\u4fdd\u5b58\u3057\u3001\u8a00\u8a9e\u306e\u5909\u66f4\u3092\u6709\u52b9\u306b\u3059\u308b\u305f\u3081\u306b\nGpsPrune \u3092\u518d\u8d77\u52d5\u3057\u3066\u304f\u3060\u3055\u3044\u3002 # 3d window -dialog.3d.title=Prune 3D \u8868\u793a -dialog.3dlines.title=Prune \u683c\u5b50\u7dda +dialog.3d.title=GpsPrune 3D \u8868\u793a +dialog.3dlines.title=GpsPrune \u683c\u5b50\u7dda dialog.3dlines.empty=\u683c\u5b50\u7dda\u304c\u8868\u793a\u3055\u308c\u307e\u305b\u3093 dialog.3dlines.intro=\u3053\u308c\u3089\u304c 3D \u8868\u793a\u7528\u306e\u683c\u5b50\u7dda\u3067\u3059\u3002 @@ -569,5 +569,5 @@ error.3d=3D \u8868\u793a\u3067\u30a8\u30e9\u30fc\u304c\u8d77\u304d\u307e\u3057\u error.readme.notfound=Readme \u30d5\u30a1\u30a4\u30eb\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093 error.osmimage.dialogtitle=\u5730\u56f3\u753b\u50cf\u3092\u8aad\u307f\u8fbc\u307f\u6642\u306e\u30a8\u30e9\u30fc error.osmimage.failed=\u5730\u56f3\u753b\u50cf\u3092\u8aad\u307f\u8fbc\u307f\u306b\u5931\u6557\u3057\u307e\u3057\u305f\u3002\u30a4\u30f3\u30bf\u30fc\u30cd\u30c3\u30c8\u63a5\u7d9a\u3092\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044\u3002 -error.language.wrongfile=\u9078\u629e\u3055\u308c\u305f\u30d5\u30a1\u30a4\u30eb\u306fPrune \u7528\u306e\u8a00\u8a9e\u30d5\u30a1\u30a4\u30eb\u306b\u898b\u3048\u307e\u305b\u3093\u3002 +error.language.wrongfile=\u9078\u629e\u3055\u308c\u305f\u30d5\u30a1\u30a4\u30eb\u306fGpsPrune \u7528\u306e\u8a00\u8a9e\u30d5\u30a1\u30a4\u30eb\u306b\u898b\u3048\u307e\u305b\u3093\u3002 error.convertnamestotimes.nonames=\u3069\u306e\u540d\u524d\u3082\u6642\u9593\u306b\u5909\u63db\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002 diff --git a/tim/prune/lang/prune-texts_ko.properties b/tim/prune/lang/prune-texts_ko.properties index eb4ef92..be9b40e 100644 --- a/tim/prune/lang/prune-texts_ko.properties +++ b/tim/prune/lang/prune-texts_ko.properties @@ -1,4 +1,4 @@ -# Text entries for the Prune application +# Text entries for the GpsPrune application # Korean entries thanks to HooAU # Menu entries @@ -122,13 +122,13 @@ function.playaudio=\uc18c\ub9ac\ud30c\uc77c \uc7ac\uc0dd function.stopaudio=\uc18c\ub9ac\ud30c\uc77c \uba48\ucda4 function.help=\ub3c4\uc6c0\ub9d0 function.showkeys=\ub2e8\ucd95\ud0a4 \ubcf4\uae30 -function.about=Prune \uc815\ubcf4 +function.about=GpsPrune \uc815\ubcf4 function.checkversion=\uc0c8\ubc84\uc804\uc774 \uc788\ub294\uc9c0 \uac80\uc0ac function.saveconfig=\uc124\uc815 \uc800\uc7a5\ud558\uae30 function.diskcache=\ub514\uc2a4\ud06c\uc5d0 \ub9f5 \uc800\uc7a5 # Dialogs -dialog.exit.confirm.title=Prune \uc885\ub8cc +dialog.exit.confirm.title=GpsPrune \uc885\ub8cc dialog.exit.confirm.text=\ub370\uc774\ud0c0\uac00 \uc800\uc7a5\ub418\uc9c0 \uc54a\uc558\uc2b5\ub2c8\ub2e4. \uadf8\ub798\ub3c4 \ub098\uac00\uc2dc\uac8c\uc2b5\ub2c8\uae4c? dialog.openappend.title=\ub370\uc774\ud130 \ucd94\uac00\ud558\uae30 dialog.openappend.text=\uc774\uc804\uc5d0 \ubd88\ub7ec\uc628 \ub370\uc774\ud0c0\ub85c \ucd94\uac00\ud558\uae30\uaca0\uc2b5\ub2c8\uae4c? @@ -345,10 +345,10 @@ dialog.compress.summarylabel=\uc0ad\uc81c\ud560 \uc9c0\uc810 dialog.pastecoordinates.desc=\uc790\ud45c\ub97c \ub123\uc73c\uc138\uc694 dialog.pastecoordinates.coords=\uc88c\ud45c dialog.pastecoordinates.nothingfound=\uc88c\ud45c\ub97c \ud655\uc778\ud558\uc2dc\uace0 \ub2e4\uc2dc \uc2dc\ub3c4\ud574 \ubcf4\uc138\uc694. -dialog.help.help=http://activityworkshop.net/software/prun +dialog.help.help=\ub354 \uc790\uc138\ud55c \uc815\ubcf4\ub098 \uc0ac\uc6a9\uc790\uc124\uba85\uc740 \uc774\uacf3\uc744 \ucc38\uace0\ud574\uc8fc\uc138\uc694.\n http://activityworkshop.net/software/gpsprune/ dialog.about.version=\ubc84\uc804 dialog.about.build=\ube4c\ub4dc -dialog.about.summarytext1=Prune\uc740 GPS\uc218\uc2e0\uae30\uc5d0\uc11c \uc704\uce58 \uc815\ubcf4\ub97c \ubc1b\uace0, \ud654\uba74\uc5d0 \ubcf4\uc5ec\uc8fc\uace0, \uc218\uc815\ud558\uac8c \ud574\uc8fc\ub294 \ud504\ub85c\uadf8\ub7a8\uc785\ub2c8\ub2e4. +dialog.about.summarytext1=GpsPrune\uc740 GPS\uc218\uc2e0\uae30\uc5d0\uc11c \uc704\uce58 \uc815\ubcf4\ub97c \ubc1b\uace0, \ud654\uba74\uc5d0 \ubcf4\uc5ec\uc8fc\uace0, \uc218\uc815\ud558\uac8c \ud574\uc8fc\ub294 \ud504\ub85c\uadf8\ub7a8\uc785\ub2c8\ub2e4. dialog.about.summarytext2=\uc774 \ud504\ub85c\uadf8\ub7a8\uc740 \uc790\uc720\ub86d\uac8c, \uac1c\ubc29\uc801\uc73c\ub85c, \uadf8\ub9ac\uace0 \uc804\uc138\uacc4\uc801\uc73c\ub85c \uc0ac\uc6a9\ud558\uace0 \uac1c\uc120\ud558\uae30 \uc704\ud574 Gnu GPL \uc5d0 \ub530\ub77c\uc11c \ubc30\ud3ec\ub429\ub2c8\ub2e4.
\uc774 \ud504\ub85c\uadf8\ub7a8\uc5d0 \ud3ec\ud568\ub41c license.txt \ud30c\uc77c\uc758 \uc870\uac74\uc5d0 \ub530\ub77c \ubcf5\uc81c, \uc7ac\ubc30\ud3ec, \uc218\uc815\uc774 \ud5c8\uac00\ub418\uace0, \uc7a5\ub824\ub429\ub2c8\ub2e4. dialog.about.summarytext3=\ub354 \uc790\uc138\ud55c \uc815\ubcf4\ub098 \uc0ac\uc6a9\uc790\uc124\uba85\uc740 \uc774\uacf3\uc744 \ucc38\uace0\ud574\uc8fc\uc138\uc694.http://activityworkshop.net/ dialog.about.languages=\uc0ac\uc6a9 \uac00\ub2a5\ud55c \uc5b8\uc5b4\ub4e4 @@ -369,7 +369,7 @@ dialog.about.systeminfo.exiflib.external.failed=\uc678\uc7a5(\ucc3e\uc9c0\ubabb\ dialog.about.yes=\uc608 dialog.about.no=\uc544\ub2c8\uc624 dialog.about.credits=\uc5d0\uac8c \uac10\uc0ac\ub97c -dialog.about.credits.code=Prune \ucf54\ub4dc\ub97c \uc791\uc131\ud574\uc900 +dialog.about.credits.code=GpsPrune \ucf54\ub4dc\ub97c \uc791\uc131\ud574\uc900 dialog.about.credits.exifcode=Exif \ucf54\ub4dc\ub97c \uc791\uc131\ud574\uc900 dialog.about.credits.icons=\uc77c\ubd80 \uc544\uc774\ucf58\uc744 \uac00\uc838\uc628 dialog.about.credits.translators=\ubc88\uc5ed\uc790\ub4e4 @@ -379,12 +379,12 @@ dialog.about.credits.othertools=\ub2e4\ub978 \ub3c4\uad6c\ub4e4 dialog.about.credits.thanks=\uac10\uc0ac\ud569\ub2c8\ub2e4. dialog.about.readme=\uc77d\uc5b4\uc8fc\uc138\uc694 dialog.checkversion.error=\ubc84\uc804\uc774 \ud655\uc778\ub418\uc9c0 \uc54a\uc558\uc5b4\uc694./n \uc778\ud130\ub137 \uc5f0\uacb0\uc744 \ud655\uc778\ud574\uc8fc\uc138\uc694. -dialog.checkversion.uptodate=\ub2f9\uc2e0\uc740 Prune\uc758 \ucd5c\uc2e0 \ubc84\uc804\uc744 \uc0ac\uc6a9\ud558\uace0 \uacc4\uc2ed\ub2c8\ub2e4. -dialog.checkversion.newversion1=Prune\uc758 \uc0c8 \ubc84\uc804\uc744 \uc9c0\uae08 \uc0ac\uc6a9\ud560 \uc218 \uc788\uaca0\ub124\uc694. \ucd5c\uc2e0\ubc84\uc804\uc740 +dialog.checkversion.uptodate=\ub2f9\uc2e0\uc740 GpsPrune\uc758 \ucd5c\uc2e0 \ubc84\uc804\uc744 \uc0ac\uc6a9\ud558\uace0 \uacc4\uc2ed\ub2c8\ub2e4. +dialog.checkversion.newversion1=GpsPrune\uc758 \uc0c8 \ubc84\uc804\uc744 \uc9c0\uae08 \uc0ac\uc6a9\ud560 \uc218 \uc788\uaca0\ub124\uc694. \ucd5c\uc2e0\ubc84\uc804\uc740 dialog.checkversion.newversion2=\ubc84\uc804\uc785\ub2c8\ub2e4. dialog.checkversion.releasedate1=\uc0c8 \ubc84\uc804\uc740 dialog.checkversion.releasedate2=\uc5d0 \ubc30\ud3ec\ub418\uc5c8\uc2b5\ub2c8\ub2e4. -dialog.checkversion.download=\uc0c8 \ubc84\uc804\uc744 \ub2e4\uc6b4\ubc1b\uace0 \uc2f6\uc73c\uc138\uc694? \uadf8\ub7fc \uc544\ub798 URL\ub85c \uc640\uc8fc\uc138\uc694. /n http://activityworkshop.net/software/prune/download.html. +dialog.checkversion.download=\uc0c8 \ubc84\uc804\uc744 \ub2e4\uc6b4\ubc1b\uace0 \uc2f6\uc73c\uc138\uc694? \uadf8\ub7fc \uc544\ub798 URL\ub85c \uc640\uc8fc\uc138\uc694. /n http://activityworkshop.net/software/gpsprune/download.html. dialog.keys.intro=\ub9c8\uc6b0\uc2a4\ub97c \uc0ac\uc6a9\ud558\uc9c0 \ub9c8\uc2dc\uace0 \uc544\ub798 \ub2e8\ucd95\ud0a4\ub97c \uc0ac\uc6a9\ud574\ubcf4\uc138\uc694. dialog.keys.keylist=
\ud654\uc0b4\ud45c \ud0a4\uc88c,\uc6b0,\uc544\ub798,\uc704\ub85c \uc9c0\ub3c4 \uc774\ub3d9
Ctrl + \uc67c\ucabd, \uc624\ub978\ucabd \ud654\uc0b4\ud45c\uc9c0\uc810 \uc120\ud0dd \uc774\ub3d9
Ctrl + \uc704, \uc544\ub798 \ud654\uc0b4\ud45c\uc9c0\ub3c4 \ud655\ub300 \ucd95\uc18c
Ctrl + PgUp, PgDown\uc774\uc804 \uc774\ud6c4 \ubd80\ubd84 \uc120\ud0dd
Ctrl + Home, End\ucc98\uc74c \uc9c0\uc810, \ub9c8\uc9c0\ub9c9 \uc9c0\uc810 \uc120\ud0dd
Del\ud604\uc7ac \uc9c0\uc810 \uc0ad\uc81c
dialog.keys.normalmodifier=Ctrl @@ -428,10 +428,10 @@ dialog.colourchooser.red=\ube68\uac15 dialog.colourchooser.green=\ub179\uc0c9 dialog.colourchooser.blue=\ud30c\ub791 dialog.setlanguage.firstintro=\ud3ec\ud568\ub41c \uc5b8\uc5b4\ub4e4 \uc911 \ud558\ub098\ub97c \uc120\ud0dd\ud558\uc2e4 \uc218 \uc788\uc5b4\uc694,

\ud639\uc740 \ub300\uc2e0 \uc0ac\uc6a9\ud560 \ud14d\uc2a4\ud2b8 \ud30c\uc77c\uc744 \uc120\ud0dd\ud558\uc138\uc694. -dialog.setlanguage.secondintro=\uc124\uc815\uc744 \uc800\uc7a5\ud558\uace0,

\uc5b8\uc5b4\ub97c \ubc14\uafb8\uae30\uc704\ud574\uc11c\ub294 Prune\uc744 \uc7ac\uc2dc\uc791\ud558\uc154\uc57c \ud574\uc694. +dialog.setlanguage.secondintro=\uc124\uc815\uc744 \uc800\uc7a5\ud558\uace0,

\uc5b8\uc5b4\ub97c \ubc14\uafb8\uae30\uc704\ud574\uc11c\ub294 GpsPrune\uc744 \uc7ac\uc2dc\uc791\ud558\uc154\uc57c \ud574\uc694. dialog.setlanguage.language=\uc5b8\uc5b4 dialog.setlanguage.languagefile=\uc5b8\uc5b4 \ud30c\uc77c -dialog.setlanguage.endmessage=\ubcc0\uacbd\ub41c \uc5b8\uc5b4\ub97c \uc801\uc6a9\ud558\uc2e4\ub824\uba74/n\uc124\uc815\uc744 \uc800\uc7a5\ud558\uace0 Prune\uc744 \uc7ac\uc2dc\uc791\ud558\uc138\uc694. +dialog.setlanguage.endmessage=\ubcc0\uacbd\ub41c \uc5b8\uc5b4\ub97c \uc801\uc6a9\ud558\uc2e4\ub824\uba74/n\uc124\uc815\uc744 \uc800\uc7a5\ud558\uace0 GpsPrune\uc744 \uc7ac\uc2dc\uc791\ud558\uc138\uc694. dialog.diskcache.save=\ub514\uc2a4\ud06c\ub85c \uc9c0\ub3c4 \uc774\ubbf8\uc9c0\ub97c \uc800\uc7a5 dialog.diskcache.dir=\uce90\uc2dc \ub514\ub809\ud1a0\ub9ac dialog.diskcache.createdir=\ub514\ub809\ud1a0\ub9ac \ub9cc\ub4e4\uae30 @@ -442,9 +442,9 @@ dialog.downloadosm.desc=\ud2b9\uc815\uc9c0\uc5ed\uc758 raw OSM \ub370\uc774\ud13 dialog.searchwikipedianames.search=\ucc3e\uae30 # 3d window -dialog.3d.title=Prune 3D \ubcf4\uae30 +dialog.3d.title=GpsPrune 3D \ubcf4\uae30 dialog.3d.altitudefactor=\uace0\ub3c4 \uacfc\uc7a5 \uacc4\uc218 -dialog.3dlines.title=Prune \uaca9\uc790\uc120 +dialog.3dlines.title=GpsPrune \uaca9\uc790\uc120 dialog.3dlines.empty=\uaca9\uc790\uc120 \uc5c6\uc774 \ud45c\uc2dc\ud558\uae30 dialog.3dlines.intro=3D \ubcf4\uae30\ub97c \uc704\ud55c \uaca9\uc790\uc120\uc785\ub2c8\ub2e4. @@ -684,7 +684,7 @@ error.3d=3D \ud45c\uc2dc\ud558\ub2e4\uac00 \uc5d0\ub7ec\ubc1c\uc0dd error.readme.notfound=Readme \ud30c\uc77c\uc744 \ubabb \ucc3e\uc74c error.osmimage.dialogtitle=\uc9c0\ub3c4 \uc774\ubbf8\uc9c0 \ubd88\ub7ec\uc624\uae30\uc911 \uc624\ub958 error.osmimage.failed=\uc9c0\ub3c4 \uc774\ubbf8\uc9c0 \ubd88\ub7ec\uc624\uae30 \uc2e4\ud328./n\uc778\ud130\ub137 \uc5f0\uacb0\uc744 \ud655\uc778\ud574\uc8fc\uc138\uc694. -error.language.wrongfile=\uc120\ud0dd\ud558\uc2e0 \ud30c\uc77c\uc774 Prune\uc744 \uc704\ud55c \uc5b8\uc5b4\ud30c\uc77c\uc774 \uc544\ub2cc\uac70 \uac19\uc544\uc694. +error.language.wrongfile=\uc120\ud0dd\ud558\uc2e0 \ud30c\uc77c\uc774 GpsPrune\uc744 \uc704\ud55c \uc5b8\uc5b4\ud30c\uc77c\uc774 \uc544\ub2cc\uac70 \uac19\uc544\uc694. error.convertnamestotimes.nonames=\uc774\ub984\uc744 \uc2dc\uac04\uc73c\ub85c \ubcc0\ud658 \ud560 \uc218 \uc5c6\uc5b4\uc694./n(\uacbd\uc720\uc9c0\uc774\ub984\uc744 \ucc3e\uc9c0 \ubabb\ud588\uac70\ub098 \ubcc0\ud658\ud560 \uc218 \uc5c6\ub294 \uacbd\uc6b0\uc5d0\uc694.) error.lookupsrtm.nonefound=\uc774 \uc9c0\uc810\ub4e4\uc5d0\uc11c \uace0\ub3c4\uac12\uc744 \uc0ac\uc6a9\ud560 \uc218 \uc5c6\uc5b4\uc694./n\uc774 \uc601\uc5ed\uc5d0\uc11c \ud0c0\uc77c\uc774 \uc5c6\uac70\ub098, \uc790\ub8cc\uac00 \uc54c\uc218 \uc5c6\ub294 \uac83\ub4e4\uc744 \ud3ec\ud568\ud558\uace0 \uc788\ub294 \uacbd\uc720. error.lookupsrtm.nonerequired=\ubaa8\ub4e0 \uc9c0\uc810\uc774 \uace0\ub3c4 \uc815\ubcf4\uac00 \uc788\uc5b4\uc11c, \ucc3e\uc744\uac8c \uc544\ubb34\uac83\ub3c4 \uc5c6\ub124\uc694. diff --git a/tim/prune/lang/prune-texts_nl.properties b/tim/prune/lang/prune-texts_nl.properties index 162b160..ec9efa5 100644 --- a/tim/prune/lang/prune-texts_nl.properties +++ b/tim/prune/lang/prune-texts_nl.properties @@ -1,9 +1,10 @@ -# Text entries for the Prune application +# Text entries for the GpsPrune application # Dutch entries as extra # Menu entries menu.file=Bestand menu.file.addphotos=Foto's toevoegen +menu.file.recentfiles=Onlangs geopend menu.file.save=Opslaan als tekst menu.file.exit=Afsluiten menu.track=Route @@ -41,6 +42,7 @@ menu.view.browser.yahoo=Yahoo maps menu.view.browser.bing=Bing maps menu.settings=Instellingen menu.settings.onlinemode=Kaarten van internet ophalen +menu.settings.autosave=Automatisch opslaan bij afsluiten menu.help=Help # Popup menu for map menu.map.zoomin=Zoom + @@ -75,6 +77,7 @@ shortcut.menu.help.help=H # Functions function.open=Open bestand +function.importwithgpsbabel=Bestand importeren met GPSBabel function.loadfromgps=Gegevens lezen van GPS function.sendtogps=Gegevens verzenden naar GPS function.exportkml=Export KML @@ -122,13 +125,14 @@ function.playaudio=Afspelen audiobestand function.stopaudio=Stop audiobestand function.help=Help function.showkeys=Toon sneltoetsen -function.about=Over Prune +function.about=Over GpsPrune function.checkversion=Controleer op nieuwe versie function.saveconfig=Instellingen opslaan function.diskcache=Kaart opslaan op schijf +function.managetilecache=Beheer tegelcache # Dialogs -dialog.exit.confirm.title=Prune afsluiten +dialog.exit.confirm.title=GpsPrune afsluiten dialog.exit.confirm.text=Uw data is niet opgeslagen. Weet u zeker dat u wilt afsluiten? dialog.openappend.title=Toevoegen aan bestaande data dialog.openappend.text=Wilt u deze data toevoegen aan de reeds geladen data? @@ -189,6 +193,9 @@ dialog.exportgpx.name=Naam dialog.exportgpx.desc=Omschrijving dialog.exportgpx.includetimestamps=Tijden meenemen dialog.exportgpx.copysource=Kopieer bron xml +dialog.exportgpx.encoding=Coderen +dialog.exportgpx.encoding.system=Systeem +dialog.exportgpx.encoding.utf8=UTF-8 dialog.exportpov.text=Geef parameters voor POV export dialog.exportpov.font=Lettertype dialog.exportpov.camerax=Camera X @@ -341,14 +348,16 @@ dialog.compress.wackypoints.paramdesc=Afstandfactor dialog.compress.singletons.title=Singletons verwijderen dialog.compress.singletons.paramdesc=Afstandfactor dialog.compress.duplicates.title=Verwijderen duplicaten +dialog.compress.douglaspeucker.title=Douglas-Peucker compressie +dialog.compress.douglaspeucker.paramdesc=Span factor dialog.compress.summarylabel=Te verwijderen punten dialog.pastecoordinates.desc=Geef co\u00f6rdinaten in dialog.pastecoordinates.coords=Co\u00f6rdinaten dialog.pastecoordinates.nothingfound=Controleer de co\u00f6rdinaten en probeer het nogmaals -dialog.help.help=Ga naar\n http://activityworkshop.net/software/prune/\nvoor meer informatie en handleidingen. +dialog.help.help=Ga naar\n http://activityworkshop.net/software/gpsprune/\nvoor meer informatie en handleidingen. dialog.about.version=Versie dialog.about.build=Build -dialog.about.summarytext1=Prune is een programma voor het laden, tonen en wijzigen van data uit GPS ontvangers. +dialog.about.summarytext1=GpsPrune is een programma voor het laden, tonen en wijzigen van data uit GPS ontvangers. dialog.about.summarytext2=Uitgebracht onder de Gnu GPL voor gratis, open, wereldwijd gebruik en verbetering
Kopieren, verspreiding en aanpassing is toegestaan en aangemoedigd
volgens de voorwaarden in het bestand license.txt. dialog.about.summarytext3=Ga naar http://activityworkshop.net/ voor meer informatie en handleidingen. dialog.about.languages=Beschikbare talen @@ -369,7 +378,7 @@ dialog.about.systeminfo.exiflib.external.failed=Extern (niet gevonden) dialog.about.yes=Ja dialog.about.no=Nee dialog.about.credits=Credits -dialog.about.credits.code=Prune code geschreven door +dialog.about.credits.code=GpsPrune code geschreven door dialog.about.credits.exifcode=Exif code door dialog.about.credits.icons=Sommige iconen overgenomen van dialog.about.credits.translators=Vertalers @@ -379,12 +388,12 @@ dialog.about.credits.othertools=Overige tools dialog.about.credits.thanks=Dank aan dialog.about.readme=Leesmij dialog.checkversion.error=Versienummer kon niet worden gecontroleerd.\nControleer de internetverbinding. -dialog.checkversion.uptodate=U gebruikt de laatste versie van Prune. -dialog.checkversion.newversion1=Een nieuwe versie van Prune is beschikbaar. De nieuwste versie is nu versie +dialog.checkversion.uptodate=U gebruikt de laatste versie van GpsPrune. +dialog.checkversion.newversion1=Een nieuwe versie van GpsPrune is beschikbaar. De nieuwste versie is nu versie dialog.checkversion.newversion2=. dialog.checkversion.releasedate1=Deze nieuwe versie was vrijgegeven op dialog.checkversion.releasedate2=. -dialog.checkversion.download=Om de nieuwst versie te downloaden, ga naar http://activityworkshop.net/software/prune/download.html. +dialog.checkversion.download=Om de nieuwst versie te downloaden, ga naar http://activityworkshop.net/software/gpsprune/download.html. dialog.keys.intro=De volgende sneltoetsen vervangen muisacties dialog.keys.keylist=
Pijltjestoetsenverschuif de kaart links, rechts, omhoog, omlaag
Ctrl + pijltje naar links, rechtsSelecteer volgende, vorige punt
Ctrl + pijltje omhoog, omlaagZoom in of uit
Ctrl + PgUp, PgDownSelecteer vorig, volgend segment
Ctrl + Home, EndSelect eerste, laatste punt
DelVerwijder huidige punt
dialog.keys.normalmodifier=Ctrl @@ -409,6 +418,7 @@ dialog.saveconfig.prune.kmzimageheight=KMZ afbeelding hoogte dialog.saveconfig.prune.colourscheme=Kleurenschema dialog.saveconfig.prune.linewidth=Lijndikte dialog.saveconfig.prune.kmltrackcolour=KML routekleur +dialog.saveconfig.prune.autosavesettings=Instellingen automatisch opslaan dialog.setpaths.intro=Indien nodig kan je de paden naar externe applicaties kiezen: dialog.setpaths.found=Pad gevonden? dialog.addaltitude.noaltitudes=De geselecteerde reeks bevat geen hoogtes @@ -428,23 +438,35 @@ dialog.colourchooser.red=Rood dialog.colourchooser.green=Groen dialog.colourchooser.blue=Blauw dialog.setlanguage.firstintro=U kunt kiezen uit \u00e9\u00e9n van de meegeleverde talen,

of selecteer een tekstbestand. -dialog.setlanguage.secondintro=U dient uw instellingen op te slaan en

Prune te herstarten om de taal te kunnen wijzigen +dialog.setlanguage.secondintro=U dient uw instellingen op te slaan en

GpsPrune te herstarten om de taal te kunnen wijzigen dialog.setlanguage.language=Taal dialog.setlanguage.languagefile=Taal bestand -dialog.setlanguage.endmessage=Sla nu uw instellingen op en herstart Prune\nom de taalwijziging te activeren +dialog.setlanguage.endmessage=Sla nu uw instellingen op en herstart GpsPrune\nom de taalwijziging te activeren +dialog.setlanguage.endmessagewithautosave=Herstart GpsPrune om te taalwijziging actief te maken. dialog.diskcache.save=Kaartafbeeldingen opslaan op schijf dialog.diskcache.dir=Cache map dialog.diskcache.createdir=Cre\u00eber map dialog.diskcache.nocreate=Cache map niet aangemaakt +dialog.diskcache.table.path=Pad +dialog.diskcache.table.usedby=Gebruikt door +dialog.diskcache.table.zoom=Zoom +dialog.diskcache.table.tiles=Tegels +dialog.diskcache.table.megabytes=Megabytes +dialog.diskcache.tileset=Tegelset +dialog.diskcache.tileset.multiple=meerdere +dialog.diskcache.deleteold=Verwijder oude tegels +dialog.diskcache.deleteall=Verwijder alle tegels +dialog.diskcache.deleted1= +dialog.diskcache.deleted2=bestanden uit de cache verwijderd dialog.deletefieldvalues.intro=Selecteer het te verwijderen veld voor de huidige reeks dialog.setlinewidth.text=Geef lijndikte voor routes (1-4) dialog.downloadosm.desc=Bevestig het downloaden van ruwe OSM data voor dit gebied: dialog.searchwikipedianames.search=Zoeken naar: # 3d window -dialog.3d.title=Prune in 3D +dialog.3d.title=GpsPrune in 3D dialog.3d.altitudefactor=Hoogte overdrijvingsfactor -dialog.3dlines.title=Prune raster +dialog.3dlines.title=GpsPrune raster dialog.3dlines.empty=Geen raster om af te beelden dialog.3dlines.intro=Dit is het raster voor 3D @@ -516,6 +538,7 @@ button.resettodefaults=Terug naar beginwaarden button.browse=Browse... button.addnew=Nieuwe toevoegen button.delete=Verwijderen +button.manage=Beheer # File types filetype.txt=TXT bestand @@ -567,6 +590,7 @@ details.lists.audio=Audio details.photodetails=Foto details details.nophoto=Geen foto geselecteerd details.photo.loading=Bezig met laden +details.photo.bearing=Richting details.media.connected=Geconnecteerd details.audiodetails=Audio details details.noaudio=Geen audiobestand geselecteerd @@ -590,6 +614,7 @@ fieldname.movingdistance=Snelheid in beweging fieldname.duration=Duur fieldname.speed=Snelheid fieldname.verticalspeed=Verticale snelheid +fieldname.description=Omschrijving # Measurement units units.original=Oorspronkelijke @@ -684,10 +709,13 @@ error.3d=Er is een fout opgetreden bij de 3d afbeelding error.readme.notfound=Leesmij bestand niet gevonden error.osmimage.dialogtitle=Fout bij inlezen kaart afbeeldingen error.osmimage.failed=Fout bij inlezen kaart afbeeldingen. Controleer je internet verbinding -error.language.wrongfile=Het geselecteerde bestand is vermoedelijk geen taalbestand voor Prune +error.language.wrongfile=Het geselecteerde bestand is vermoedelijk geen taalbestand voor GpsPrune error.convertnamestotimes.nonames=Namen konden niet naar tijden worden geconverteerd error.lookupsrtm.nonefound=Geen hoogtewaarden beschikbaar voor deze punten error.lookupsrtm.nonerequired=Alle punten hebben reeds hoogte, er hoeft niets te worden opgezocht. error.gpsies.uploadnotok=Gpsies server antwoordde met error.gpsies.uploadfailed=De upload is mislukt. Fout error.playaudiofailed=Kon audiobestand niet afspelen +error.cache.notthere=De tegelcache map niet gevonden +error.cache.empty=De tegelcache map is leeg +error.cache.cannotdelete=Er konden geen tegels verwijderd worden diff --git a/tim/prune/lang/prune-texts_pl.properties b/tim/prune/lang/prune-texts_pl.properties index 378c08d..c0f9982 100644 --- a/tim/prune/lang/prune-texts_pl.properties +++ b/tim/prune/lang/prune-texts_pl.properties @@ -1,9 +1,10 @@ -# Text entries for the Prune application +# Text entries for the GpsPrune application # Polish entries as extra # Menu entries menu.file=Plik menu.file.addphotos=Dodaj zdj\u0119cia +menu.file.recentfiles=Ostatnio u\u017cywane menu.file.save=Zapisz menu.file.exit=Zako\u0144cz menu.track=\u015acie\u017cka @@ -41,6 +42,7 @@ menu.view.browser.yahoo=Mapy Yahoo menu.view.browser.bing=Mapy Bing menu.settings=Ustawienia menu.settings.onlinemode=\u0141aduj mapy z sieci +menu.settings.autosave=Autozapis ustawie\u0144 przy wyj\u015bciu menu.help=Pomoc # Popup menu for map menu.map.zoomin=Powi\u0119ksz @@ -75,6 +77,7 @@ shortcut.menu.help.help=H # Functions function.open=Otw\u00f3rz +function.importwithgpsbabel=Importuj plik z GPSBabel function.loadfromgps=\u0141aduj z GPS function.sendtogps=Wy\u015blij dane do urz\u0105dzenia GPS function.exportkml=Eksportuj KML @@ -122,13 +125,14 @@ function.playaudio=Odtw\u00f3rz plik audio function.stopaudio=Zatrzymaj plik audio function.help=Pomoc function.showkeys=Poka\u017c klawisze skr\u00f3tu -function.about=O Prune +function.about=O GpsPrune function.checkversion=Sprawd\u017a czy jest nowa wersja function.saveconfig=Zapisz ustawienia function.diskcache=Zapisz mapy na dysk +function.managetilecache=Zarz\u0105dzaj keszem p\u0142ytek # Dialogs -dialog.exit.confirm.title=Zako\u0144cz Prune +dialog.exit.confirm.title=Zako\u0144cz GpsPrune 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 dane do ju\u017c za\u0142adowanych? @@ -189,6 +193,9 @@ dialog.exportgpx.name=Nazwa dialog.exportgpx.desc=Opis dialog.exportgpx.includetimestamps=Do\u0142\u0105cz znaczniki czasu dialog.exportgpx.copysource=Kopiuj \u017ar\u00f3d\u0142owy xml +dialog.exportgpx.encoding=Kodowanie +dialog.exportgpx.encoding.system=Systemowe +dialog.exportgpx.encoding.utf8=UTF-8 dialog.exportpov.text=Wprowad\u017a dodatkowe parametry eksportu do formatu POV dialog.exportpov.font=Czcionka dialog.exportpov.camerax=Kamera X @@ -341,14 +348,16 @@ dialog.compress.wackypoints.paramdesc=Wsp\u00f3\u0142czynnik odleg\u0142o\u015bc dialog.compress.singletons.title=Usuwanie odosobnionych punkt\u00f3w dialog.compress.singletons.paramdesc=Wsp\u00f3\u0142czynnik odleg\u0142o\u015bci dialog.compress.duplicates.title=Usuwanie duplikat\u00f3w +dialog.compress.douglaspeucker.title=kompresja Douglasa-Peuckera +dialog.compress.douglaspeucker.paramdesc=wsp\u00f3\u0142czynnik rozpi\u0119to\u015bci (szeroko\u015bci korytarza) dialog.compress.summarylabel=Punkty do usuni\u0119cia dialog.pastecoordinates.desc=Wprowad\u017a lub wklej wsp\u00f3\u0142rz\u0119dne dialog.pastecoordinates.coords=Wsp\u00f3\u0142rz\u0119dne dialog.pastecoordinates.nothingfound=Sprawd\u017a wsp\u00f3\u0142rz\u0119dne i spr\u00f3buj jeszcze raz -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/gpsprune/ \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.summarytext1=GpsPrune 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 @@ -369,7 +378,7 @@ dialog.about.systeminfo.exiflib.external.failed=Zewn\u0119trzny (nie znaleziony) dialog.about.yes=Tak dialog.about.no=Nie dialog.about.credits=Podzi\u0119kowania -dialog.about.credits.code=Kod Prune napisany przez +dialog.about.credits.code=Kod GpsPrune napisany przez dialog.about.credits.exifcode=Kod Exif przez dialog.about.credits.icons=Niekt\u00f3re ikony z dialog.about.credits.translators=T\u0142umacze @@ -379,12 +388,12 @@ dialog.about.credits.othertools=Inne narz\u0119dzia dialog.about.credits.thanks=Podzi\u0119kowania dla dialog.about.readme=Czytaj to dialog.checkversion.error=Nie mo\u017cna sprawdzi\u0107 numeru wersji.\nSprawd\u017a po\u0142\u0105czenie z internetem. -dialog.checkversion.uptodate=U\u017cywasz najnowszej wersji Prune. -dialog.checkversion.newversion1=Dost\u0119pna jest nowa wersja Prune! Najnowsz\u0105 wersj\u0105 jest wersja +dialog.checkversion.uptodate=U\u017cywasz najnowszej wersji GpsPrune. +dialog.checkversion.newversion1=Dost\u0119pna jest nowa wersja GpsPrune! 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/gpsprune/download.html. dialog.keys.intro=U\u017cuwaj nast\u0119puj\u0105cych klawiszy skr\u00f3t\u00f3w zamiast myszki dialog.keys.keylist=
klawisze strza\u0142ekPrzesuwa map\u0119 w lewo, w prawo, w g\u00f3r\u0119, w d\u00f3\u0142
Ctrl + lewa, prawa strza\u0142kaWybierz punkt poprzedni lub nast\u0119pny
Ctrl + strza\u0142ka w g\u00f3r\u0119, w d\u00f3\u0142Powi\u0119ksz, pomniejsz
DelUsun bie\u017c\u0105cy punkt
dialog.keys.normalmodifier=Ctrl @@ -409,6 +418,7 @@ dialog.saveconfig.prune.kmzimageheight=wysoko\u015b\u0107 obrazka w KMZ dialog.saveconfig.prune.colourscheme=Schemat kolor\u00f3w dialog.saveconfig.prune.linewidth=Szeroko\u015b\u0107 linii dialog.saveconfig.prune.kmltrackcolour=Kolor \u015bcie\u017cki w pliku KML +dialog.saveconfig.prune.autosavesettings=ustawienia autozapisu dialog.setpaths.intro=Je\u015bli zachodzi tak potrzeba, mo\u017cesz wybra\u0107 \u015bcie\u017cki do aplikacji zewn\u0119trznych dialog.setpaths.found=Znalezione \u015bcie\u017cki? dialog.addaltitude.noaltitudes=Wybrany zakres nie zawiera danych o wysoko\u015bciach @@ -428,21 +438,33 @@ dialog.colourchooser.red=Czerwony dialog.colourchooser.green=Zielony dialog.colourchooser.blue=Niebieski dialog.setlanguage.firstintro=Mo\u017cesz wybra\u0107 jeden z do\u0142\u0105czonych j\u0119zyk\u00f3w

Albo wybra\u0107 wybrany przez siebie plik tekstowy. -dialog.setlanguage.secondintro=B\u0119dziesz musia\u0142 zapisa\u0107 ustawienia

i zrestartowa\u0107 Prune by zmieni\u0107 j\u0119zyk. +dialog.setlanguage.secondintro=B\u0119dziesz musia\u0142 zapisa\u0107 ustawienia

i zrestartowa\u0107 GpsPrune by zmieni\u0107 j\u0119zyk. dialog.setlanguage.language=J\u0119zyk dialog.setlanguage.languagefile=Plik t\u0142umaczenia -dialog.setlanguage.endmessage=Zapisz ustawienia i zrestartuj Prune\n by zmiana j\u0119zyka odnios\u0142a skutek. +dialog.setlanguage.endmessage=Zapisz ustawienia i zrestartuj GpsPrune\n by zmiana j\u0119zyka odnios\u0142a skutek. +dialog.setlanguage.endmessagewithautosave=Zrestartuj GpsPrune by zmiana j\u0119zyka odnios\u0142a skutek. dialog.diskcache.save=Zapisz mapy na dysk dialog.diskcache.dir=katalog pami\u0119ci podr\u0119cznej dialog.diskcache.createdir=stw\u00f3rz katalog dialog.diskcache.nocreate=Nie utworzono katalogu pami\u0119ci podr\u0119cznej +dialog.diskcache.table.path=\u015acie\u017cka +dialog.diskcache.table.usedby=u\u017cywane przez +dialog.diskcache.table.zoom=Powi\u0119kszenie +dialog.diskcache.table.tiles=p\u0142ytek +dialog.diskcache.table.megabytes=megabajt\u00f3w +dialog.diskcache.tileset=zestaw p\u0142ytek +dialog.diskcache.tileset.multiple=wiele +dialog.diskcache.deleteold=Usu\u0144 stare p\u0142ytki +dialog.diskcache.deleteall=Usu\u0144 wszystkie p\u0142ytki +dialog.diskcache.deleted1=Usuni\u0119to +dialog.diskcache.deleted2=plik\u00f3w z kesza dialog.deletefieldvalues.intro=Wybierz pola do skasowania z wybranego zakresu dialog.setlinewidth.text=Wprowad\u017a grubo\u015b\u0107 linii do rysowania \u015bcie\u017cek dialog.downloadosm.desc=Potwierd\u017a \u015bci\u0105gni\u0119cie danych dla tego obszaru z OSM: dialog.searchwikipedianames.search=Szukaj # 3d window -dialog.3d.title=Prune widok tr\u00f3jwymiarowy +dialog.3d.title=GpsPrune widok tr\u00f3jwymiarowy dialog.3d.altitudefactor=Wsp\u00f3\u0142czynnik skalowania wysoko\u015bci dialog.3dlines.title=Linie siatki dialog.3dlines.empty=Brak siatki do wy\u015bwietlenia! @@ -516,6 +538,7 @@ button.resettodefaults=Przywr\u00f3\u0107 domy\u015blne button.browse=Przegl\u0105daj... button.addnew=Dodaj nowy button.delete=Usu\u0144 +button.manage=Zarz\u0105dzaj # File types filetype.txt=Pliki TXT @@ -567,6 +590,7 @@ details.lists.audio=Audio details.photodetails=Szczeg\u00f3\u0142y zdj\u0119cia details.nophoto=Brak zaznaczonego zdj\u0119cia details.photo.loading=Wczytywanie +details.photo.bearing=Kierunek details.media.connected=Pod\u0142\u0105czony details.audiodetails=Szczeg\u00f3\u0142y audio details.noaudio=Brak zaznaczonego audio @@ -590,6 +614,7 @@ 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.description=Opis # Measurement units units.original=Oryginalny @@ -684,10 +709,13 @@ 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.language.wrongfile=Wybrany plik nie jest plikiem z t\u0142umaczeniem dla Prune +error.language.wrongfile=Wybrany plik nie jest plikiem z t\u0142umaczeniem dla GpsPrune error.convertnamestotimes.nonames=\u017badne nazwy nie mog\u0142y zosta\u0107 zmienione na czas error.lookupsrtm.nonefound=Nie znaleziono danych o wysoko\u015bci. error.lookupsrtm.nonerequired=Wszystkie pola maj\u0105 informacj\u0119 o wysoko\u015bci, nie ma czego szuka\u0107 error.gpsies.uploadnotok=Serwer Gpsies zwr\u00f3ci\u0142 informacj\u0119 error.gpsies.uploadfailed=B\u0142\u0105d wysy\u0142ania error.playaudiofailed=Nie powiod\u0142o si\u0119 odtwarzanie pliku audio +error.cache.notthere=Nie znaleziono katalogu kesza +error.cache.empty=Katalog kesza jest pusty +error.cache.cannotdelete=\u017badne p\u0142ytki nie mog\u0142y zosta\u0107 usuni\u0119te diff --git a/tim/prune/lang/prune-texts_pt.properties b/tim/prune/lang/prune-texts_pt.properties index 8596b39..8d09afe 100644 --- a/tim/prune/lang/prune-texts_pt.properties +++ b/tim/prune/lang/prune-texts_pt.properties @@ -1,9 +1,10 @@ -# Text entries for the Prune application +# Text entries for the GpsPrune application # (Brazilian) Portuguese entries as extra # Menu entries menu.file=Arquivo menu.file.addphotos=Adicionar fotos +menu.file.recentfiles=Arquivos recentes menu.file.save=Salvar menu.file.exit=Sair menu.track=Rota @@ -41,6 +42,7 @@ menu.view.browser.yahoo=Mapas do Yahoo menu.view.browser.bing=Mapas do Bing menu.settings=Configura\u00e7\u00f5es menu.settings.onlinemode=Carregar mapas da Internet +menu.settings.autosave=Autosalvar configura\u00e7\u00f5es ao sair menu.help=Ajuda # Popup menu for map menu.map.zoomin=Ampliar @@ -75,6 +77,7 @@ shortcut.menu.help.help=J # Functions function.open=Abrir +function.importwithgpsbabel=Importar arquivo com GPSBabel function.loadfromgps=Carregar dados do GPS function.sendtogps=Enviar dados para o GPS function.exportkml=Exportar para KML @@ -122,13 +125,14 @@ function.playaudio=Reproduzir arquivo de \u00e1udio function.stopaudio=Parar arquivo de \u00e1udio function.help=Ajuda function.showkeys=Mostrar atalhos de teclado -function.about=Sobre o Prune +function.about=Sobre o GpsPrune function.checkversion=Verificar novas vers\u00f5es function.saveconfig=Salvar configura\u00e7\u00f5es function.diskcache=Salvar mapas para o disco +function.managetilecache=Gerenciar cache de fundos # Dialogs -dialog.exit.confirm.title=Sair do Prune +dialog.exit.confirm.title=Sair do GpsPrune dialog.exit.confirm.text=Seus dados n\u00e3o foram salvos. Voc\u00ea tem certeza que deseja sair? dialog.openappend.title=Adicionar aos dados existentes dialog.openappend.text=Adicionar estes dados aos dados j\u00e1 carregados? @@ -189,6 +193,9 @@ dialog.exportgpx.name=Nome dialog.exportgpx.desc=Descri\u00e7\u00e3o dialog.exportgpx.includetimestamps=Incluir data-hora dialog.exportgpx.copysource=Copiar fonte xml +dialog.exportgpx.encoding=Codifica\u00e7\u00e3o +dialog.exportgpx.encoding.system=Sistema +dialog.exportgpx.encoding.utf8=UTF-8 dialog.exportpov.text=Por favor, insira os par\u00e2metros para a exporta\u00e7\u00e3o POV dialog.exportpov.font=Fonte dialog.exportpov.camerax=X da C\u00e2mera @@ -335,20 +342,22 @@ dialog.rearrangephotos.sortbyfilename=Ordenar pelo nome do arquivo dialog.rearrangephotos.sortbytime=Ordenar pela hora dialog.compress.nonefound=Nenhum dado dos pontos pode ser removido dialog.compress.closepoints.title=Remo\u00e7\u00e3o de ponto pr\u00f3ximo -dialog.compress.closepoints.paramdesc=Fator de 'span' +dialog.compress.closepoints.paramdesc=Fator de deslocamento dialog.compress.wackypoints.title=Remo\u00e7\u00e3o de ponto exc\u00eantrica dialog.compress.wackypoints.paramdesc=Fator de dist\u00e3ncia dialog.compress.singletons.title=Remo\u00e7\u00e3o avulsa dialog.compress.singletons.paramdesc=Fator de dist\u00e2ncia dialog.compress.duplicates.title=Remo\u00e7\u00e3o de duplicado +dialog.compress.douglaspeucker.title=Compress\u00e3o Douglas-Peucker +dialog.compress.douglaspeucker.paramdesc=Fator de deslocamento dialog.compress.summarylabel=Pontos para remover dialog.pastecoordinates.desc=Insira ou cole as coordenadas aqui dialog.pastecoordinates.coords=Coordenadas dialog.pastecoordinates.nothingfound=Por favor, verifique as coordenadas novamente -dialog.help.help=Por favor, veja\n http://activityworkshop.net/software/prune/\npara mais informa\u00e7\u00f5es e guia do usu\u00e1rio. +dialog.help.help=Por favor, veja\n http://activityworkshop.net/software/gpsprune/\npara mais informa\u00e7\u00f5es e guia do usu\u00e1rio. dialog.about.version=Vers\u00e3o dialog.about.build=Compila\u00e7\u00e3o -dialog.about.summarytext1=Prune \u00e9 um programa para carregar, exibir e editar dados de receptores de GPS. +dialog.about.summarytext1=GpsPrune \u00e9 um programa para carregar, exibir e editar dados de receptores de GPS. dialog.about.summarytext2=Isto est\u00e1 lan\u00e7ado sob a Gnu GPL para uso e melhoria livre, aberto e em todo o mundo.
A c\u00f3pia, redistribui\u00e7\u00e3o e modifica\u00e7\u00e3o s\u00e3o permitidas e encorajadas
de acordo coma as condi\u00e7\u00f5es no arquivo license.txtinclu\u00eddo. dialog.about.summarytext3=Por favor, veja http://activityworkshop.net/ para mais informa\u00e7\u00f5es e guia do usu\u00e1rio. dialog.about.languages=Idiomas dispon\u00edveis @@ -369,7 +378,7 @@ dialog.about.systeminfo.exiflib.external.failed=Externa (n\u00e3o encontrada) dialog.about.yes=Sim dialog.about.no=N\u00e3o dialog.about.credits=Cr\u00e9ditos -dialog.about.credits.code=C\u00f3digo do Prune escrito por +dialog.about.credits.code=C\u00f3digo do GpsPrune escrito por dialog.about.credits.exifcode=C\u00f3digo do Exif por dialog.about.credits.icons=Alguns \u00edcones obtidos de dialog.about.credits.translators=Tradutores @@ -379,12 +388,12 @@ dialog.about.credits.othertools=Outras ferramentas dialog.about.credits.thanks=Agradecimentos a dialog.about.readme=Leiame dialog.checkversion.error=O n\u00famero da vers\u00e3o n\u00e3o pode ser verificado.\n Por favor, verifique a conex\u00e3o \u00e0 Internet. -dialog.checkversion.uptodate=Voc\u00ea est\u00e1 usando a \u00faltima vers\u00e3o do Prune. -dialog.checkversion.newversion1=Uma nova vers\u00e3o do Prune est\u00e1 dispon\u00edvel! A \u00faltima vers\u00e3o \u00e9 agora a vers\u00e3o +dialog.checkversion.uptodate=Voc\u00ea est\u00e1 usando a \u00faltima vers\u00e3o do GpsPrune. +dialog.checkversion.newversion1=Uma nova vers\u00e3o do GpsPrune est\u00e1 dispon\u00edvel! A \u00faltima vers\u00e3o \u00e9 agora a vers\u00e3o dialog.checkversion.newversion2=. dialog.checkversion.releasedate1=Esta nova vers\u00e3o foi lan\u00e7ada em dialog.checkversion.releasedate2=. -dialog.checkversion.download=Para baixar a nova vers\u00e3o, v\u00e1 para http://activityworkshop.net/software/prune/download.html. +dialog.checkversion.download=Para baixar a nova vers\u00e3o, v\u00e1 para http://activityworkshop.net/software/gpsprune/download.html. dialog.keys.intro=Voc\u00ea pode usar os seguintes atalhos de teclado ao inv\u00e9s de usar o mouse dialog.keys.keylist=
CursoresMove o mapa para esquerda, direita, acima e abaixo
Ctrl + cursores esquerdo e direitoSeleciona o pr\u00f3ximo ponto ou o anterior
Ctrl + cursores acima e abaixoAmplia ou reduz
DelRemove o ponto atual
dialog.keys.normalmodifier=Ctrl @@ -409,6 +418,7 @@ dialog.saveconfig.prune.kmzimageheight=Altura da imagem KMZ dialog.saveconfig.prune.colourscheme=Esquema de cores dialog.saveconfig.prune.linewidth=Espessura da linha dialog.saveconfig.prune.kmltrackcolour=Cor da rota KML +dialog.saveconfig.prune.autosavesettings=Configura\u00e7\u00f5es para salvamento autom\u00e1tico dialog.setpaths.intro=Se voc\u00ea precisar, voc\u00ea pode escolher os caminhos para as aplica\u00e7\u00f5es externas: dialog.setpaths.found=Caminho encontrado? dialog.addaltitude.noaltitudes=O intervalo selecionado n\u00e3o cont\u00e9m altitudes @@ -428,23 +438,35 @@ dialog.colourchooser.red=Vermelho dialog.colourchooser.green=Verde dialog.colourchooser.blue=Azul dialog.setlanguage.firstintro=Voc\u00ea pode selecionar um dos idiomas inclu\u00eddos,

ou selecionar um arquivo de texto para usar. -dialog.setlanguage.secondintro=Voc\u00ea precisa salvar suas configura\u00e7\u00f5es e ent\u00e3o

reiniciar o Prune para mudar o idioma. +dialog.setlanguage.secondintro=Voc\u00ea precisa salvar suas configura\u00e7\u00f5es e ent\u00e3o

reiniciar o GpsPrune para mudar o idioma. dialog.setlanguage.language=Idioma dialog.setlanguage.languagefile=Arquivo de idioma -dialog.setlanguage.endmessage=Agora salve suas configura\u00e7\u00f5es e reinicie o Prune\npara que a mudan\u00e7a de idioma ocorra. +dialog.setlanguage.endmessage=Agora salve suas configura\u00e7\u00f5es e reinicie o GpsPrune\npara que a mudan\u00e7a de idioma ocorra. +dialog.setlanguage.endmessagewithautosave=Por favor, reinicie o GpsPrune para que a mudan\u00e7a de idioma tenha efeito. dialog.diskcache.save=Salvar imagens do mapa para o disco dialog.diskcache.dir=Diret\u00f3rio da cache dialog.diskcache.createdir=Criar diret\u00f3rio dialog.diskcache.nocreate=Diret\u00f3rio da cache n\u00e3o foi criado +dialog.diskcache.table.path=Caminho +dialog.diskcache.table.usedby=Usado por +dialog.diskcache.table.zoom=Zoom +dialog.diskcache.table.tiles=Fundos +dialog.diskcache.table.megabytes=Megabytes +dialog.diskcache.tileset=Conjunto de fundos +dialog.diskcache.tileset.multiple=m\u00faltiplos +dialog.diskcache.deleteold=Apagar fundos antigos +dialog.diskcache.deleteall=Apagar todos os fundos +dialog.diskcache.deleted1=Removidos +dialog.diskcache.deleted2=arquivos do cache dialog.deletefieldvalues.intro=Selecione o campo a remover para o intervalo atual dialog.setlinewidth.text=Insira a espessura das linhas para desenhar as rotas (1-4) dialog.downloadosm.desc=Confirmar a transfer\u00eancia de dados OSM brutos para a \u00e1rea especificada: dialog.searchwikipedianames.search=Procurar por: # 3d window -dialog.3d.title=Vista 3D do Prune +dialog.3d.title=Vista 3D do GpsPrune dialog.3d.altitudefactor=Fator de exagera\u00e7\u00e3o de altitude -dialog.3dlines.title=Linhas da grade do Prune +dialog.3dlines.title=Linhas da grade do GpsPrune dialog.3dlines.empty=Nenhuma linha de grade para exibir! dialog.3dlines.intro=Estas s\u00e3o as linhas da grade para a vista 3D. @@ -516,6 +538,7 @@ button.resettodefaults=Restaurar para os padr\u00f5es button.browse=Navegar... button.addnew=Adicionar novo button.delete=Remover +button.manage=Gerenciar # File types filetype.txt=Arquivos TXT @@ -567,6 +590,7 @@ details.lists.audio=\u00c1udio details.photodetails=Detalhes da foto details.nophoto=Nenhuma foto selecionada details.photo.loading=Carregando +details.photo.bearing=Apontando details.media.connected=Conectada details.audiodetails=Detalhes do \u00e1udio details.noaudio=Nenhum arquivo de \u00e1udio selecionado @@ -590,6 +614,7 @@ fieldname.movingdistance=Dist\u00e2ncia de movimento fieldname.duration=Dura\u00e7\u00e3o fieldname.speed=Velocidade fieldname.verticalspeed=Velocidade vertical +fieldname.description=Descri\u00e7\u00e3o # Measurement units units.original=Original @@ -684,10 +709,13 @@ error.3d=Um erro ocorreu com a exibi\u00e7\u00e3o 3D error.readme.notfound=Arquivo Leiame n\u00e3o encontrado error.osmimage.dialogtitle=Erro ao carregar imagens do mapa error.osmimage.failed=Falha ao carregar imagens do mapa. Por favor, verifique a conex\u00e3o \u00e0 Internet. -error.language.wrongfile=O arquivo selecionado n\u00e3o parece ser um arquivo de idioma do Prune +error.language.wrongfile=O arquivo selecionado n\u00e3o parece ser um arquivo de idioma do GpsPrune error.convertnamestotimes.nonames=Nenhum nome pode ser convertido para tempo error.lookupsrtm.nonefound=Nenhum valor de altitude encontrado error.lookupsrtm.nonerequired=Todos os pontos j\u00e1 possuem altitude, assim n\u00e3o h\u00e1 nada a procurar error.gpsies.uploadnotok=O servidor Gpsies retornou a mensagem error.gpsies.uploadfailed=O envio falhou com o erro error.playaudiofailed=Falha ao reproduzir arquivo de \u00e1udio +error.cache.notthere=A paste de cache de fundos n\u00e3o foi encontrada +error.cache.empty=A pasta de cache de fundos est\u00e1 vazia +error.cache.cannotdelete=Nenhum fundo pode ser removido diff --git a/tim/prune/lang/prune-texts_ro.properties b/tim/prune/lang/prune-texts_ro.properties index f6dd803..cfb6a17 100644 --- a/tim/prune/lang/prune-texts_ro.properties +++ b/tim/prune/lang/prune-texts_ro.properties @@ -1,4 +1,4 @@ -# Text entries for the Prune application +# Text entries for the GpsPrune application # Romanian entries as extra # Menu entries @@ -81,11 +81,11 @@ function.setcolours=Selectare culorile function.setlanguage=Selectare limba function.help=Ajutor function.showkeys=Arat\u0103 tastele scurt\u0103turi -function.about=Despre Prune +function.about=Despre GpsPrune function.checkversion=Verific\u0103 pentru o versiune noua # Dialogs -dialog.exit.confirm.title=Ie\u015fire din programul Prune +dialog.exit.confirm.title=Ie\u015fire din programul GpsPrune dialog.exit.confirm.text=Datele dumneavoastra nu sunt salvate.\nSunte\u0163i sigur ca\u0103 dori\u0163i s\u0103 ie\u015fiti? dialog.openappend.title=Adauga la datele existente dialog.openappend.text=Adauga la datele deja incarcate? diff --git a/tim/prune/lang/prune-texts_tr.properties b/tim/prune/lang/prune-texts_tr.properties index ad0ea20..8160265 100644 --- a/tim/prune/lang/prune-texts_tr.properties +++ b/tim/prune/lang/prune-texts_tr.properties @@ -1,4 +1,4 @@ -# Text entries for the Prune application +# Text entries for the GpsPrune application # Turkish entries as extra # Menu entries @@ -100,12 +100,12 @@ function.rotatephotoright=Fotoyu sa\u011fa d\u00f6nd\u00fcr function.ignoreexifthumb=Exif t\u0131rnak resmi bo\u015fver function.help=Yard\u0131m function.showkeys=K\u0131sayol tu\u015flar\u0131 g\u00f6ster -function.about=Prune hakk\u0131nda +function.about=GpsPrune hakk\u0131nda function.checkversion=Yeni s\u00fcr\u00fcm\u00fc i\u00e7in denetle function.saveconfig=Ayarlar\u0131 kaydet # Dialogs -dialog.exit.confirm.title=Prune'dan \u00e7\u0131k +dialog.exit.confirm.title=GpsPrune'dan \u00e7\u0131k dialog.exit.confirm.text=Ver\u0131 kaydetmedin -Ger\u00e7ekten \u00e7\u0131kmak istiyor musun? dialog.openappend.title=Varolan verisine ekle dialog.openappend.text=Append this data to the data already loaded? @@ -231,12 +231,12 @@ dialog.correlate.options.offset.seconds=saniye dialog.correlate.options.photolater=Foto noktadan sonra dialog.correlate.options.pointlaterphoto=Nokta fotodan sonra dialog.pastecoordinates.coords=Koordinatlar -dialog.help.help=Ayr\u0131nt\u0131l\u0131 bilgi ve kullanma k\u0131lavuzu i\u00e7in l\u00fctfen\n http://activityworkshop.net/software/prune/\n sitesinde bak. +dialog.help.help=Ayr\u0131nt\u0131l\u0131 bilgi ve kullanma k\u0131lavuzu i\u00e7in l\u00fctfen\n http://activityworkshop.net/software/gpsprune/\n sitesinde bak. dialog.about.version=S\u00fcr\u00fcm dialog.about.build=Build -dialog.about.summarytext1=Prune GPS ayg\u0131tlardan veri y\u00fckler, g\u00f6r\u00fcnt\u00fcler ver d\u00fczenler bir uygulamad\u0131r. +dialog.about.summarytext1=GpsPrune GPS ayg\u0131tlardan veri y\u00fckler, g\u00f6r\u00fcnt\u00fcler ver d\u00fczenler bir uygulamad\u0131r. dialog.about.summarytext3=Ayr\u0131nt\u0131l\u0131 bilgi ve kullanma k\u0131lavuzu i\u00e7in l\u00fctfen\n http://activityworkshop.net/ sitesinde bak. -dialog.about.languages=Prune ile kullanabilir diller +dialog.about.languages=GpsPrune ile kullanabilir diller dialog.about.translatedby=Turkish text by katpatuka dialog.about.systeminfo=Sistem bilgisi dialog.about.systeminfo.os=\u0130\u015fletim Sistemi @@ -251,12 +251,12 @@ dialog.about.no=Hay\u0131r dialog.about.credits.translators=Çevirmen dialog.about.credits.thanks=Te\u015fekk\u00fcrler dialog.about.readme=Beni oku -dialog.checkversion.uptodate=Prune'nin so s\u00fcr\u00fcm\u00fc kullan\u0131yorsun. -dialog.checkversion.newversion1=Prune'nin yeni bir s\u00fcr\u00fcm\u00fc \u00e7\u0131kt\u0131! Son s\u00fcr\u00fcm \u015fimdi +dialog.checkversion.uptodate=GpsPrune'nin so s\u00fcr\u00fcm\u00fc kullan\u0131yorsun. +dialog.checkversion.newversion1=GpsPrune'nin yeni bir s\u00fcr\u00fcm\u00fc \u00e7\u0131kt\u0131! Son s\u00fcr\u00fcm \u015fimdi dialog.checkversion.newversion2=. dialog.checkversion.releasedate1=Yeni s\u00fcr\u00fcm\u00fcn\u00fcn devir tarihi dialog.checkversion.releasedate2=. -dialog.checkversion.download=Yeni s\u00fcr\u00fcm indirmek i\u00e7in http://activityworkshop.net/software/prune/download.html adresine git. +dialog.checkversion.download=Yeni s\u00fcr\u00fcm indirmek i\u00e7in http://activityworkshop.net/software/gpsprune/download.html adresine git. dialog.keys.intro=Fare yerinde a\u015fa\u011f\u0131daki k\u0131sayol tu\u015flar\u0131 kullanabilirsin: dialog.keys.keylist=
Ok tu\u015flar\u0131Haritay\u0131 sola/sa\u011fa/a\u015fa\u011f\u0131/yukar\u0131 kayd\u0131r
Ctrl + sol, sa\u011f\u00d6nceki/sonraki noktay\u0131 se\u00e7
Ctrl + yukar/a\u015fa\u011f\u0131Yak\u0131nla\u015ft\u0131r/Uzakla\u015ft\u0131r
DelSe\u00e7ili noltay\u0131 sil
dialog.saveconfig.desc=A\u011fa\u015f\u0131daki ayarlar\u0131 bir dasyada kaydedilir: diff --git a/tim/prune/lang/prune-texts_zh.properties b/tim/prune/lang/prune-texts_zh.properties index 4dfc88a..290c1fe 100644 --- a/tim/prune/lang/prune-texts_zh.properties +++ b/tim/prune/lang/prune-texts_zh.properties @@ -1,9 +1,10 @@ -# Text entries for the Prune application +# Text entries for the GpsPrune application # Chinese entries as extra # Menu entries menu.file=\u6587\u4ef6 menu.file.addphotos=\u6dfb\u52a0\u76f8\u7247 +menu.file.recentfiles=\u6700\u8fd1\u6253\u5f00\u8fc7\u6587\u4ef6 menu.file.save=\u4fdd\u5b58 menu.file.exit=\u9000\u51fa menu.track=\u8f68\u8ff9 @@ -41,6 +42,7 @@ menu.view.browser.yahoo=Yahoo\u5730\u56fe menu.view.browser.bing=Bing(\u5fc5\u5e94\uff09\u5730\u56fe menu.settings=\u8bbe\u7f6e menu.settings.onlinemode=\u4ece\u7f51\u4e0a\u5bfc\u5165\u5730\u56fe +menu.settings.autosave=\u9000\u51fa\u65f6\u81ea\u52a8\u4fdd\u5b58\u8bbe\u7f6e menu.help=\u5e2e\u52a9 # Popup menu for map menu.map.zoomin=\u653e\u5927 @@ -53,8 +55,29 @@ 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=F +altkey.menu.track=T +altkey.menu.range=R +altkey.menu.point=P +altkey.menu.view=V +altkey.menu.photo=O +altkey.menu.audio=A +altkey.menu.settings=S +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.track.undo=Z +shortcut.menu.edit.compress=C +shortcut.menu.range.all=A +shortcut.menu.help.help=H + # Functions function.open=\u6253\u5f00 +function.importwithgpsbabel=\u7528GPSBabel\u5bfc\u5165\u6587\u4ef6 function.loadfromgps=\u4eceGPS\u5bfc\u5165 function.sendtogps=\u53d1\u9001\u81f3GPS function.exportkml=\u8f93\u51faKML\u6587\u4ef6 @@ -102,10 +125,11 @@ function.playaudio=\u64ad\u653e\u58f0\u97f3\u6587\u4ef6 function.stopaudio=\u505c\u6b62\u64ad\u653e function.help=\u5e2e\u52a9 function.showkeys=\u663e\u793a\u5feb\u6377\u952e -function.about=\u5173\u4e8ePrune +function.about=\u5173\u4e8eGpsPrune function.checkversion=\u68c0\u67e5\u66f4\u65b0 function.saveconfig=\u4fdd\u5b58\u8bbe\u7f6e function.diskcache=\u4fdd\u5b58\u5730\u56fe +function.managetilecache=\u7ba1\u7406\u5730\u56fe\u533a\u57df\u6570\u636e\u7f13\u5b58 # Dialogs dialog.exit.confirm.title=\u9000\u51fa @@ -169,6 +193,9 @@ dialog.exportgpx.name=\u540d\u79f0 dialog.exportgpx.desc=\u63cf\u8ff0 dialog.exportgpx.includetimestamps=\u5305\u542b\u65f6\u95f4 dialog.exportgpx.copysource=\u4ece\u6e90XML\u6587\u4ef6\u590d\u5236 +dialog.exportgpx.encoding=\u7f16\u7801 +dialog.exportgpx.encoding.system=\u9ed8\u8ba4\u7cfb\u7edf\u7f16\u7801 +dialog.exportgpx.encoding.utf8=\u4f7f\u7528UTF-8 dialog.exportpov.text=\u8bf7\u8f93\u5165POV\u53c2\u6570 dialog.exportpov.font=\u5b57\u4f53 dialog.exportpov.camerax=X\u76f8\u673a @@ -321,14 +348,16 @@ 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.duplicates.title=\u91cd\u590d\u70b9\u5220\u9664 +dialog.compress.douglaspeucker.title=Douglas-Peucker \u538b\u7f29 +dialog.compress.douglaspeucker.paramdesc=\u95f4\u8ddd\u7cfb\u6570 dialog.compress.summarylabel=\u8981\u5220\u9664\u7684\u70b9 dialog.pastecoordinates.desc=\u5728\u6b64\u8f93\u5165\u6216\u7c98\u8d34\u5750\u6807\u70b9 dialog.pastecoordinates.coords=\u5750\u6807\u70b9 dialog.pastecoordinates.nothingfound=\u8bf7\u68c0\u67e5\u5750\u6807\u6570\u636e\u5e76\u91cd\u8bd5 -dialog.help.help=\u66f4\u591a\u4fe1\u606f\u548c\u7528\u6cd5\uff0c\u8bf7\u53c2\u8003\u7f51\u7ad9\nhttp://activityworkshop.net/software/prune/// +dialog.help.help=\u66f4\u591a\u4fe1\u606f\u548c\u7528\u6cd5\uff0c\u8bf7\u53c2\u8003\u7f51\u7ad9\nhttp://activityworkshop.net/software/gpsprune/ 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.summarytext1=GpsPrune\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 @@ -349,7 +378,7 @@ dialog.about.systeminfo.exiflib.external.failed=\u5916\u90e8\uff08\u672a\u627e\u 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.code=GpsPrune \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 @@ -364,7 +393,7 @@ dialog.checkversion.newversion1=\u65b0\u7248\u672c\u5b58\u5728\uff0c \u6700\u65b 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.checkversion.download=\u4e0b\u8f7d\u6700\u65b0\u7248\u672c\uff0c\u8bf7\u767b\u9646\u7f51\u7ad9\uff1a\nhttp:activityworkshop.net/software/gpsprune/download.html dialog.keys.intro=\u53ef\u7528\u4e0b\u5217\u5feb\u6377\u952e\u66ff\u4ee3\u9f20\u6807 dialog.keys.keylist=
\u7bad\u5934\u4e0a\u4e0b\u5de6\u53f3\u79fb\u52a8\u5730\u56fe
Ctrl + \u5de6\u53f3\u7bad\u5934\u9009\u53d6\u524d\uff0c\u540e\u70b9
Ctrl + \u4e0a\u4e0b\u7bad\u5934\u653e\u5927\u7f29\u5c0f
Ctrl + PgUp, PgDown\u9009\u62e9\u524d\u540e\u6bb5
Ctrl + Home, End\u9009\u62e9\u9996\u672b\u70b9
Del\u5220\u9664\u5f53\u524d\u70b9
dialog.keys.normalmodifier=Ctrl @@ -389,6 +418,7 @@ dialog.saveconfig.prune.kmzimageheight=KMZ\u56fe\u50cf\u9ad8\u5ea6 dialog.saveconfig.prune.colourscheme=\u989c\u8272 dialog.saveconfig.prune.linewidth=\u7ebf\u4f53\u5bbd\u5ea6 dialog.saveconfig.prune.kmltrackcolour=KML\u8f68\u8ff9\u989c\u8272 +dialog.saveconfig.prune.autosavesettings=\u81ea\u52a8\u4fdd\u5b58\u8bbe\u7f6e dialog.setpaths.intro=\u82e5\u9700\u8981\uff0c\u53ef\u8bbe\u5b9a\u5916\u6302\u7a0b\u5e8f\u8def\u5f84 dialog.setpaths.found=\u627e\u5230\u8def\u5f84\uff1f dialog.addaltitude.noaltitudes=\u8f68\u8ff9\u4e0d\u542b\u9ad8\u5ea6\u4fe1\u606f @@ -408,23 +438,35 @@ dialog.colourchooser.red=\u7ea2 dialog.colourchooser.green=\u7eff dialog.colourchooser.blue=\u84dd dialog.setlanguage.firstintro=\u4f60\u53ef\u4ee5\u9009\u62e9\u5df2\u6709\u8bed\u8a00,

\u6216\u9009\u62e9\u5916\u6302\u8bed\u8a00\u5305 -dialog.setlanguage.secondintro=\u8bf7\u4fdd\u5b58\u8bbe\u7f6e

\u5e76\u91cd\u542fPrune\u4f7f\u8bbe\u7f6e\u751f\u6548 +dialog.setlanguage.secondintro=\u8bf7\u4fdd\u5b58\u8bbe\u7f6e

\u5e76\u91cd\u542fGpsPrune\u4f7f\u8bbe\u7f6e\u751f\u6548 dialog.setlanguage.language=\u8bed\u8a00 dialog.setlanguage.languagefile=\u8bed\u8a00\u5305 -dialog.setlanguage.endmessage=\u73b0\u5728\u8bf7\u4fdd\u5b58\u8bbe\u7f6e\u5e76\u91cd\u542fPrune\n\u4f7f\u8bbe\u7f6e\u751f\u6548 +dialog.setlanguage.endmessage=\u73b0\u5728\u8bf7\u4fdd\u5b58\u8bbe\u7f6e\u5e76\u91cd\u542fGpsPrune\n\u4f7f\u8bbe\u7f6e\u751f\u6548 +dialog.setlanguage.endmessagewithautosave=\u8981\u4f7f\u6240\u9009\u8bed\u8a00\u751f\u6548\uff0c\u8bf7\u91cd\u65b0\u542f\u52a8GosPrune dialog.diskcache.save=\u5730\u56fe\u56fe\u7247\u4fdd\u5b58\u5230\u7535\u8111 dialog.diskcache.dir=\u4fdd\u5b58\u8def\u5f84 dialog.diskcache.createdir=\u65b0\u5efa\u8def\u5f84 dialog.diskcache.nocreate=\u672a\u65b0\u5efa\u8def\u5f84 +dialog.diskcache.table.path=\u8def\u5f84 +dialog.diskcache.table.usedby=\u4f7f\u7528\u8005 +dialog.diskcache.table.zoom=\u653e\u5927\u7f29\u5c0f +dialog.diskcache.table.tiles=\u627e\u5230\u7684\u5730\u56fe\u533a\u57df\u6570\u636e +dialog.diskcache.table.megabytes=MB +dialog.diskcache.tileset=\u5730\u56fe\u533a\u57df\u6570\u5b58\u653e\u8def\u5f84 +dialog.diskcache.tileset.multiple=\u6570\u76ee +dialog.diskcache.deleteold=\u5220\u9664\u65e7\u533a\u57df\u6570\u636e +dialog.diskcache.deleteall=\u5220\u9664\u6240\u6709\u533a\u57df\u6570\u636e +dialog.diskcache.deleted1=\u5df2\u5220\u9664 +dialog.diskcache.deleted2=\u7f13\u5b58\u5185\u6587\u4ef6 dialog.deletefieldvalues.intro=\u9009\u62e9\u5f53\u524d\u8303\u56f4\u5185\u8981\u5220\u9664\u7684\u533a\u57df dialog.setlinewidth.text=\u8f93\u5165\u8f68\u8ff9\u7ebf\u5bbd\u50cf\u7d20\u503c\uff081-4\uff09 dialog.downloadosm.desc=\u786e\u8ba4\u4eceOSM\u4e0b\u8f7d\u8be5\u5730\u533a\u539f\u59cb\u6570\u636e dialog.searchwikipedianames.search=\u67e5\u627e # 3d window -dialog.3d.title=Prune 3D \u663e\u793a +dialog.3d.title=GpsPrune 3D \u663e\u793a dialog.3d.altitudefactor=\u9ad8\u5ea6\u653e\u5927\u7cfb\u6570 -dialog.3dlines.title=Prune \u7f51\u683c\u7ebf +dialog.3dlines.title=GpsPrune \u7f51\u683c\u7ebf dialog.3dlines.empty=\u65e0\u6cd5\u663e\u793a\u7f51\u683c\u7ebf dialog.3dlines.intro=3D \u7f51\u683c\u7ebf @@ -496,6 +538,7 @@ button.resettodefaults=\u6062\u590d\u9ed8\u8ba4 button.browse=\u6d4f\u89c8... button.addnew=\u6dfb\u52a0 button.delete=\u5220\u9664 +button.manage=\u7ba1\u7406 # File types filetype.txt=TXT\u6587\u4ef6 @@ -547,6 +590,7 @@ details.lists.audio=\u58f0\u97f3 details.photodetails=\u76f8\u7247\u4fe1\u606f details.nophoto=\u65e0\u76f8\u7247\u88ab\u9009\u4e2d details.photo.loading=\u6b63\u5bfc\u5165 +details.photo.bearing=\u65b9\u5411 details.media.connected=\u5df2\u94fe\u63a5 details.audiodetails=\u8be6\u7ec6\u4fe1\u606f details.noaudio=\u672a\u9009\u62e9\u58f0\u97f3\u6587\u4ef6 @@ -570,6 +614,7 @@ fieldname.movingdistance=\u79fb\u52a8\u8ddd\u79bb fieldname.duration=\u65f6\u957f fieldname.speed=\u901f\u5ea6 fieldname.verticalspeed=\u5782\u76f4\u901f\u5ea6 +fieldname.description=\u63cf\u8ff0 # Measurement units units.original=\u539f\u59cb @@ -671,3 +716,6 @@ error.lookupsrtm.nonerequired=\u6240\u6709\u70b9\u5747\u542b\u9ad8\u5ea6\u4fe1\u error.gpsies.uploadnotok=gpsies\u670d\u52a1\u5668\u8fd4\u56de\u4fe1\u606f\uff1a error.gpsies.uploadfailed=\u4e0a\u4f20\u51fa\u9519\u5931\u8d25 error.playaudiofailed=\u65e0\u6cd5\u64ad\u653e\u58f0\u97f3\u6587\u4ef6 +error.cache.notthere=\u672a\u627e\u5230\u533a\u57df\u6570\u636e\u7f13\u5b58\u6587\u4ef6\u5939 +error.cache.empty=\u533a\u57df\u6570\u636e\u6587\u4ef6\u5939\u7a7a +error.cache.cannotdelete=\u65e0\u53ef\u5220\u9664\u533a\u57df\u6570\u636e diff --git a/tim/prune/load/AudioLoader.java b/tim/prune/load/AudioLoader.java index 1997db2..9da33d2 100644 --- a/tim/prune/load/AudioLoader.java +++ b/tim/prune/load/AudioLoader.java @@ -9,17 +9,17 @@ import tim.prune.GenericFunction; import tim.prune.I18nManager; import tim.prune.UpdateMessageBroker; import tim.prune.config.Config; -import tim.prune.data.AudioFile; +import tim.prune.data.AudioClip; import tim.prune.undo.UndoLoadAudios; /** - * Class to manage the loading of audio files + * Class to manage the loading of audio clips */ public class AudioLoader extends GenericFunction { private JFileChooser _fileChooser = null; private GenericFileFilter _fileFilter = null; - private TreeSet _fileList = null; + private TreeSet _fileList = null; /** @@ -58,7 +58,7 @@ public class AudioLoader extends GenericFunction // Show file dialog to choose file / directory(ies) if (_fileChooser.showOpenDialog(_parentFrame) == JFileChooser.APPROVE_OPTION) { - _fileList = new TreeSet(new MediaSorter()); + _fileList = new TreeSet(new MediaSorter()); processFileList(_fileChooser.getSelectedFiles()); final int numFiles = _fileList.size(); if (numFiles == 0) { @@ -87,7 +87,7 @@ public class AudioLoader extends GenericFunction { if (file.isFile()) { if (_fileFilter.accept(file)) { - _fileList.add(new AudioFile(file)); + _fileList.add(new AudioClip(file)); } } else if (file.isDirectory()) { diff --git a/tim/prune/load/BabelFileFormats.java b/tim/prune/load/BabelFileFormats.java new file mode 100644 index 0000000..ed7e627 --- /dev/null +++ b/tim/prune/load/BabelFileFormats.java @@ -0,0 +1,216 @@ +package tim.prune.load; + +/** + * Class to manage the list of file formats supported by Gpsbabel + * (older versions of gpsbabel might not support all of these, of course). + * Certain supported formats such as txt, csv, gpx are not included here + * as GpsPrune can already load them directly. + */ +public abstract class BabelFileFormats +{ + /** + * @return an object array for the format descriptions + */ + public static Object[] getDescriptions() { + return getColumn(0); + } + + /** + * Find the (first) appropriate file format for the given file suffix + * @param inSuffix end of filename including . + * @return matching index or -1 if not found + */ + public static int getIndexForFileSuffix(String inSuffix) + { + if (inSuffix != null && inSuffix.length() > 1) + { + final String[] suffixes = getColumn(2); + for (int i=0; i= 0 && inIndex < formats.length) + return formats[inIndex]; + return null; + } + + /** + * Extract the specified column of the data array + * @param inIndex column index from 0 to 2 + * @return string array containing required data + */ + private static String[] getColumn(int inIndex) + { + final String[] allFormats = { + "Alan Map500 tracklogs", "alantrl", ".trl", + "Alan Map500 waypoints and routes", "alanwpr", ".wpr", + "Brauniger IQ Series Barograph Download", "baroiq", null, + "Bushnell GPS Trail file", "bushnell_trl", null, + "Bushnell GPS Waypoint file", "bushnell", null, + "Cambridge/Winpilot glider software", "cambridge", null, + "CarteSurTable data file", "cst", null, + "Cetus for Palm/OS", "cetus", null, + "CoastalExplorer XML", "coastexp", null, + "Columbus/Visiontac V900 files", "v900", ".csv", + "CompeGPS data files", "compegps", ".wpt/.trk/.rte", + "CoPilot Flight Planner for Palm/OS", "copilot", null, + "cotoGPS for Palm/OS", "coto", null, + "Data Logger iBlue747 csv", "iblue747", null, + "Dell Axim Navigation System file format", "axim_gpb", ".gpb", + "DeLorme .an1 (drawing) file", "an1", null, + "DeLorme GPL", "gpl", null, + "DeLorme PN-20/PN-30/PN-40 USB protocol", "delbin", null, + "DeLorme Street Atlas Plus", "saplus", null, + "DeLorme Street Atlas Route", "saroute", null, + "DeLorme XMap HH Native .WPT", "xmap", null, + "DeLorme XMap/SAHH 2006 Native .TXT", "xmap2006", null, + "DeLorme XMat HH Street Atlas USA .WPT (PPC)", "xmapwpt", null, + "Destinator Itineraries", "destinator_itn", ".dat", + "Destinator Points of Interest", "destinator_poi", ".dat", + "Destinator TrackLogs", "destinator_trl", ".dat", + "EasyGPS binary format", "easygps", null, + "Enigma binary waypoint file", "enigma", ".ert", + "FAI/IGC Flight Recorder Data Format", "igc", null, + "Franson GPSGate Simulation", "gpssim", null, + "Fugawi", "fugawi", null, + "G7ToWin data files", "g7towin", ".g7t", + "Garmin 301 Custom position and heartrate", "garmin301", null, + "Garmin Logbook XML", "glogbook", null, + "Garmin MapSource - gdb", "gdb", null, + "Garmin MapSource - mps", "mapsource", null, + "Garmin PCX5", "pcx", null, + "Garmin POI database", "garmin_poi", null, + "Garmin Points of Interest", "garmin_gpi", ".gpi", + "Garmin Training Center", "gtrnctr", null, + "Garmin Training Center", "gtrnctr", ".tcx", + "Geocaching.com .loc", "geo", null, + "GeocachingDB for Palm/OS", "gcdb", null, + "Geogrid-Viewer ascii overlay file", "ggv_ovl", ".ovl", + "Geogrid-Viewer tracklogs", "ggv_log", ".log", + "GEOnet Names Server (GNS)", "geonet", null, + "GeoNiche .pdb", "geoniche", null, + "GlobalSat DG-100/BT-335 Download", "dg-100", null, + "Google Maps XML", "google", null, + "Google Navigator Tracklines", "gnav_trl", ".trl", + "GoPal GPS track log", "gopal", ".trk", + "GpilotS", "gpilots", null, + "GPS TrackMaker", "gtm", null, + "GpsDrive Format", "gpsdrive", null, + "GpsDrive Format for Tracks", "gpsdrivetrack", null, + "GPSman", "gpsman", null, + "GPSPilot Tracker for Palm/OS", "gpspilot", null, + "gpsutil", "gpsutil", null, + "HikeTech", "hiketech", null, + "Holux (gm-100) .wpo Format", "holux", null, + "Holux M-241 (MTK based) Binary File Format", "m241-bin", null, + "Holux M-241 (MTK based) download", "m241", null, + "Honda/Acura Navigation System VP Log File Format", "vpl", null, + "HSA Endeavour Navigator export File", "hsandv", null, + "Humminbird tracks", "humminbird_ht", ".ht", + "Humminbird waypoints and routes", "humminbird", ".hwr", + "IGN Rando track files", "ignrando", null, + "iGO2008 points of interest", "igo2008_poi", ".upoi", + "IGO8 .trk", "igo8", null, + "Jelbert GeoTagger data file", "jtr", null, + "Jogmap.de XML format", "jogmap", null, + "Kartex 5 Track File", "ktf2", null, + "Kartex 5 Waypoint File", "kwf2", null, + "Kompass (DAV) Track", "kompass_tk", ".tk", + "Kompass (DAV) Waypoints", "kompass_wp", ".wp", + "KuDaTa PsiTrex text", "psitrex", null, + "Lowrance USR", "lowranceusr", null, + "Magellan Explorist Geocaching", "maggeo", null, + "Magellan Mapsend", "mapsend", null, + "Magellan NAV Companion for Palm/OS", "magnav", null, + "Magellan SD files (as for eXplorist)", "magellanx", null, + "Magellan SD files (as for Meridian)", "magellan", null, + "Magellan serial protocol", "magellan", null, + "MagicMaps IK3D project file", "ik3d", ".ikt", + "Map&Guide 'TourExchangeFormat' XML", "tef", null, + "Map&Guide to Palm/OS exported files", "mag_pdb", ".pdb", + "MapAsia track file", "mapasia_tr7", ".tr7", + "Mapopolis.com Mapconverter CSV", "mapconverter", null, + "MapTech Exchange Format", "mxf", null, + "Memory-Map Navigator overlay files", "mmo", ".mmo", + "Microsoft AutoRoute 2002 (pin/route reader)", "msroute", null, + "Microsoft Streets and Trips (pin/route reader)", "msroute", null, + "Microsoft Streets and Trips 2002-2007", "s_and_t", null, + "Mobile Garmin XT Track files", "garmin_xt", null, + "Motorrad Routenplaner (Map&Guide) .bcr files", "bcr", null, + "MS PocketStreets 2002 Pushpin", "psp", null, + "MTK Logger (iBlue 747,...) Binary File Format", "mtk-bin", null, + "MTK Logger (iBlue 747,Qstarz BT-1000,...) download", "mtk", null, + "National Geographic Topo .tpg (waypoints)", "tpg", null, + "National Geographic Topo 2.x .tpo", "tpo2", null, + "National Geographic Topo 3.x/4.x .tpo", "tpo3", null, + "Navicache.com XML", "navicache", null, + "Navigon Mobile Navigator .rte files", "nmn4", null, + "Navigon Waypoints", "navigonwpt", null, + "NaviGPS GT-11/BGT-11 Download", "navilink", null, + "NaviGPS GT-31/BGT-31 datalogger", "sbp", ".sbp", + "NaviGPS GT-31/BGT-31 SiRF binary logfile", "sbn", ".sbn", + "Naviguide binary route file", "naviguide", ".twl", + "Navitel binary track", "navitel_trk", ".bin", + "Navitrak DNA marker format", "dna", null, + "NetStumbler Summary File", "netstumbler", "text", + "NIMA/GNIS Geographic Names File", "nima", null, + "Nokia Landmark Exchange", "lmx", null, + "OpenStreetMap data files", "osm", ".osm", + "OziExplorer", "ozi", null, + "PalmDoc Output", "palmdoc", null, + "PathAway Database for Palm/OS", "pathaway", null, + "PocketFMS breadcrumbs", "pocketfms_bc", null, + "PocketFMS flightplan", "pocketfms_fp", ".xml", + "PocketFMS waypoints", "pocketfms_wp", ".txt", + "Quovadis", "quovadis", null, + "Raymarine Waypoint File", "raymarine", ".rwf", + "Ricoh GPS Log File", "ricoh", null, + "See You flight analysis data", "cup", null, + "Skymap / KMD150 ascii files", "skyforce", null, + "SkyTraq Venus based loggers (download)", "skytraq", null, + "SkyTraq Venus based loggers Binary File Format", "skytraq-bin", null, + "Sportsim track files (part of zipped .ssz files)", "sportsim", null, + "SubRip subtitles for video mapping", "subrip", ".srt", + "Suunto Trek Manager (STM) .sdf files", "stmsdf", null, + "Suunto Trek Manager (STM) WaypointPlus files", "stmwpp", null, + "Swiss Map 25/50/100", "xol", ".xol", + "TomTom Itineraries", "tomtom_itn", ".itn", + "TomTom Places Itineraries", "tomtom_itn_places", ".itn", + "TomTom POI file", "tomtom_asc", ".asc", + "TomTom POI file", "tomtom", ".ov2", + "TopoMapPro Places File", "tmpro", null, + "TrackLogs digital mapping", "dmtlog", ".trl", + "U.S. Census Bureau Tiger Mapping Service", "tiger", null, + "Vcard Output (for iPod)", "vcard", null, + "VidaOne GPS for Pocket PC", "vidaone", ".gpb", + "Vito Navigator II tracks", "vitosmt", null, + "Vito SmartMap tracks", "vitovtt", ".vtt", + "WiFiFoFum 2.0 for PocketPC XML", "wfff", null, + "Wintec TES file", "wintec_tes", null, + "Wintec WBT-100/200 Binary File Format", "wbt-bin", null, + "Wintec WBT-100/200 GPS Download", "wbt", null, + "Wintec WBT-201/G-Rays 2 Binary File Format", "wbt-tk1", null, + "XAiOX iTrackU Logger", "itracku", null, + "XAiOX iTrackU Logger Binary File Format", "itracku-bin", null, + "Yahoo Geocode API data", "yahoo", null, + }; + // Copy elements into new array + final int numRows = allFormats.length / 3; + String[] result = new String[numRows]; + for (int i=0; i 0 ? filename.substring(dotPos) : null); + if (suffix != null && !suffix.equals(".") && (_lastSuffix == null || !suffix.equalsIgnoreCase(_lastSuffix))) + { + // New suffix chosen, so select first appropriate format (if any) + int selIndex = BabelFileFormats.getIndexForFileSuffix(suffix); + if (selIndex >= 0) { + _formatDropdown.setSelectedIndex(selIndex); + } + } + _lastSuffix = suffix; + } + + /** + * Save settings in config + */ + protected void saveConfigValues() + { + // nothing needed + } +} diff --git a/tim/prune/load/BabelLoadFromGps.java b/tim/prune/load/BabelLoadFromGps.java new file mode 100644 index 0000000..8c4b4dd --- /dev/null +++ b/tim/prune/load/BabelLoadFromGps.java @@ -0,0 +1,175 @@ +package tim.prune.load; + +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 javax.swing.BorderFactory; +import javax.swing.BoxLayout; +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JProgressBar; +import javax.swing.JTextField; +import javax.swing.SwingConstants; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; + +import tim.prune.App; +import tim.prune.I18nManager; +import tim.prune.config.Config; +import tim.prune.data.SourceInfo; +import tim.prune.data.SourceInfo.FILE_TYPE; + +/** + * Class to manage the loading of data from a GPS device using GpsBabel + */ +public class BabelLoadFromGps extends BabelLoader +{ + // Text fields for entering device and format + private JTextField _deviceField = null, _formatField = null; + + + /** + * Constructor + * @param inApp Application object to inform of data load + */ + public BabelLoadFromGps(App inApp) { + super(inApp); + } + + /** Get the name key */ + public String getNameKey() { + return "function.loadfromgps"; + } + + /** @return device name as file path */ + protected String getFilePath() { + return _deviceField.getText(); + } + + /** @return Source info */ + protected SourceInfo getSourceInfo() { + return new SourceInfo(_deviceField.getText(), FILE_TYPE.GPSBABEL); + } + + /** @return input format */ + protected String getInputFormat() { + return _formatField.getText(); + } + + /** @return true if function can be run */ + protected boolean isInputOk() { + return _waypointCheckbox.isSelected() || _trackCheckbox.isSelected(); + } + + /** + * @return a panel containing the main dialog components + */ + protected JPanel makeDialogComponents() + { + JPanel outerPanel = new JPanel(); + outerPanel.setLayout(new BorderLayout()); + // Main panel with options etc + JPanel mainPanel = new JPanel(); + mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS)); + + // text fields for options + JPanel gridPanel = new JPanel(); + gridPanel.setLayout(new GridLayout(0, 2, 10, 3)); + JLabel deviceLabel = new JLabel(I18nManager.getText("dialog.gpsload.device")); + deviceLabel.setHorizontalAlignment(SwingConstants.RIGHT); + gridPanel.add(deviceLabel); + _deviceField = new JTextField(Config.getConfigString(Config.KEY_GPS_DEVICE), 12); + KeyAdapter escapeListener = new KeyAdapter() { + public void keyReleased(KeyEvent e) + { + // close dialog if escape pressed + if (e.getKeyCode() == KeyEvent.VK_ESCAPE) { + _dialog.dispose(); + } + } + }; + _deviceField.addKeyListener(escapeListener); + gridPanel.add(_deviceField); + JLabel formatLabel = new JLabel(I18nManager.getText("dialog.gpsload.format")); + formatLabel.setHorizontalAlignment(SwingConstants.RIGHT); + gridPanel.add(formatLabel); + _formatField = new JTextField(Config.getConfigString(Config.KEY_GPS_FORMAT), 12); + _formatField.addKeyListener(escapeListener); + gridPanel.add(_formatField); + gridPanel.setAlignmentX(Component.CENTER_ALIGNMENT); + gridPanel.setBorder(BorderFactory.createEmptyBorder(10, 5, 5, 20)); + mainPanel.add(gridPanel); + + // checkboxes + ChangeListener checkboxListener = new ChangeListener() { + public void stateChanged(ChangeEvent e) + { + enableOkButton(); + } + }; + _waypointCheckbox = new JCheckBox(I18nManager.getText("dialog.gpsload.getwaypoints"), true); + _waypointCheckbox.addChangeListener(checkboxListener); + _waypointCheckbox.setAlignmentX(Component.CENTER_ALIGNMENT); + mainPanel.add(_waypointCheckbox); + _trackCheckbox = new JCheckBox(I18nManager.getText("dialog.gpsload.gettracks"), true); + _trackCheckbox.addChangeListener(checkboxListener); + _trackCheckbox.setAlignmentX(Component.CENTER_ALIGNMENT); + mainPanel.add(_trackCheckbox); + // Checkbox for immediately saving to file + _saveCheckbox = new JCheckBox(I18nManager.getText("dialog.gpsload.save")); + _saveCheckbox.setAlignmentX(Component.CENTER_ALIGNMENT); + mainPanel.add(_saveCheckbox); + + // progress bar (initially invisible) + _progressBar = new JProgressBar(0, 10); + mainPanel.add(_progressBar); + outerPanel.add(mainPanel, BorderLayout.NORTH); + + // Lower panel with ok and cancel buttons + JPanel buttonPanel = new JPanel(); + buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT)); + _okButton = new JButton(I18nManager.getText("button.ok")); + ActionListener okListener = new ActionListener() { + public void actionPerformed(ActionEvent e) + { + // start thread to call gpsbabel + _cancelled = false; + new Thread(BabelLoadFromGps.this).start(); + } + }; + _okButton.addActionListener(okListener); + _deviceField.addActionListener(okListener); + _formatField.addActionListener(okListener); + buttonPanel.add(_okButton); + JButton cancelButton = new JButton(I18nManager.getText("button.cancel")); + cancelButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) + { + _cancelled = true; + _dialog.dispose(); + } + }); + buttonPanel.add(cancelButton); + outerPanel.add(buttonPanel, BorderLayout.SOUTH); + return outerPanel; + } + + /** + * Save GPS settings in config + */ + protected void saveConfigValues() + { + final String device = _deviceField.getText().trim(); + final String format = _formatField.getText().trim(); + Config.setConfigString(Config.KEY_GPS_DEVICE, device); + Config.setConfigString(Config.KEY_GPS_FORMAT, format); + } +} diff --git a/tim/prune/load/GpsLoader.java b/tim/prune/load/BabelLoader.java similarity index 53% rename from tim/prune/load/GpsLoader.java rename to tim/prune/load/BabelLoader.java index 2196e0c..b970665 100644 --- a/tim/prune/load/GpsLoader.java +++ b/tim/prune/load/BabelLoader.java @@ -1,32 +1,17 @@ package tim.prune.load; -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.io.BufferedReader; import java.io.File; import java.io.InputStreamReader; import java.util.ArrayList; -import javax.swing.BorderFactory; -import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JDialog; -import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JProgressBar; -import javax.swing.JTextField; -import javax.swing.SwingConstants; import javax.swing.SwingUtilities; -import javax.swing.event.ChangeEvent; -import javax.swing.event.ChangeListener; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; @@ -42,35 +27,32 @@ import tim.prune.load.xml.XmlHandler; import tim.prune.save.GpxExporter; /** - * Class to manage the loading of GPS data using GpsBabel + * Superclass to manage the loading of data using GpsBabel + * Subclasses handle either from GPS or from file */ -public class GpsLoader extends GenericFunction implements Runnable +public abstract class BabelLoader extends GenericFunction implements Runnable { private boolean _gpsBabelChecked = false; - private JDialog _dialog = null; - private JTextField _deviceField = null, _formatField = null; - private JCheckBox _waypointCheckbox = null, _trackCheckbox = null; - private JCheckBox _saveCheckbox = null; - private JButton _okButton = null; - private JProgressBar _progressBar = null; - private File _saveFile = null; - private boolean _cancelled = false; + protected JDialog _dialog = null; + // Checkboxes for which kinds of points to load + protected JCheckBox _waypointCheckbox = null, _trackCheckbox = null; + // Checkbox to save to file or not + protected JCheckBox _saveCheckbox = null; + protected JButton _okButton = null; + protected JProgressBar _progressBar = null; + protected File _saveFile = null; + protected boolean _cancelled = false; /** * Constructor * @param inApp Application object to inform of data load */ - public GpsLoader(App inApp) + public BabelLoader(App inApp) { super(inApp); } - /** Get the name key */ - public String getNameKey() { - return "function.loadfromgps"; - } - /** * Open the GUI to select options and start the load */ @@ -96,6 +78,7 @@ public class GpsLoader extends GenericFunction implements Runnable // Initialise progress bars, buttons enableOkButton(); setupProgressBar(true); + initDialog(); // do any subclass-specific init here _dialog.setVisible(true); } } @@ -104,91 +87,11 @@ public class GpsLoader extends GenericFunction implements Runnable /** * @return a panel containing the main dialog components */ - private JPanel makeDialogComponents() - { - JPanel outerPanel = new JPanel(); - outerPanel.setLayout(new BorderLayout()); - // Main panel with options etc - JPanel mainPanel = new JPanel(); - mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS)); - - // text fields for options - JPanel gridPanel = new JPanel(); - gridPanel.setLayout(new GridLayout(0, 2, 10, 3)); - JLabel deviceLabel = new JLabel(I18nManager.getText("dialog.gpsload.device")); - deviceLabel.setHorizontalAlignment(SwingConstants.RIGHT); - gridPanel.add(deviceLabel); - _deviceField = new JTextField(Config.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.getConfigString(Config.KEY_GPS_FORMAT), 12); - gridPanel.add(_formatField); - gridPanel.setAlignmentX(Component.CENTER_ALIGNMENT); - gridPanel.setBorder(BorderFactory.createEmptyBorder(10, 5, 5, 20)); - mainPanel.add(gridPanel); - - // checkboxes - ChangeListener checkboxListener = new ChangeListener() { - public void stateChanged(ChangeEvent e) - { - enableOkButton(); - } - }; - _waypointCheckbox = new JCheckBox(I18nManager.getText("dialog.gpsload.getwaypoints"), true); - _waypointCheckbox.addChangeListener(checkboxListener); - _waypointCheckbox.setAlignmentX(Component.CENTER_ALIGNMENT); - mainPanel.add(_waypointCheckbox); - _trackCheckbox = new JCheckBox(I18nManager.getText("dialog.gpsload.gettracks"), true); - _trackCheckbox.addChangeListener(checkboxListener); - _trackCheckbox.setAlignmentX(Component.CENTER_ALIGNMENT); - mainPanel.add(_trackCheckbox); - // Checkbox for immediately saving to file - _saveCheckbox = new JCheckBox(I18nManager.getText("dialog.gpsload.save")); - _saveCheckbox.setAlignmentX(Component.CENTER_ALIGNMENT); - mainPanel.add(_saveCheckbox); + protected abstract JPanel makeDialogComponents(); - // progress bar (initially invisible) - _progressBar = new JProgressBar(0, 10); - mainPanel.add(_progressBar); - outerPanel.add(mainPanel, BorderLayout.NORTH); - - // Lower panel with ok and cancel buttons - JPanel buttonPanel = new JPanel(); - buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT)); - _okButton = new JButton(I18nManager.getText("button.ok")); - _okButton.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) - { - // start thread to call gpsbabel - _cancelled = false; - new Thread(GpsLoader.this).start(); - } - }); - buttonPanel.add(_okButton); - JButton cancelButton = new JButton(I18nManager.getText("button.cancel")); - cancelButton.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) - { - _cancelled = true; - _dialog.dispose(); - } - }); - buttonPanel.add(cancelButton); - outerPanel.add(buttonPanel, BorderLayout.SOUTH); - return outerPanel; - } + /** Do any subclass-specific dialog initialisation necessary */ + protected void initDialog() {} /** * @param inStart true if the dialog is restarting @@ -206,11 +109,15 @@ public class GpsLoader extends GenericFunction implements Runnable /** * Enable or disable the ok button */ - private void enableOkButton() + protected void enableOkButton() { - _okButton.setEnabled(_waypointCheckbox.isSelected() || _trackCheckbox.isSelected()); + _okButton.setEnabled(isInputOk()); } + /** + * @return true if input fields of dialog are valid + */ + protected abstract boolean isInputOk(); /** * Run method for performing tasks in separate thread @@ -219,7 +126,7 @@ public class GpsLoader extends GenericFunction implements Runnable { _okButton.setEnabled(false); setupProgressBar(false); - if (_waypointCheckbox.isSelected() || _trackCheckbox.isSelected()) + if (isInputOk()) { _progressBar.setIndeterminate(true); _saveFile = null; @@ -249,12 +156,9 @@ public class GpsLoader extends GenericFunction implements Runnable private void callGpsBabel() throws Exception { // Set up command to call gpsbabel - final String device = _deviceField.getText().trim(); - final String format = _formatField.getText().trim(); - String[] commands = getCommandArray(device, format); + String[] commands = getCommandArray(); // Save GPS settings in config - Config.setConfigString(Config.KEY_GPS_DEVICE, device); - Config.setConfigString(Config.KEY_GPS_FORMAT, format); + saveConfigValues(); String errorMessage = "", errorMessage2 = ""; XmlHandler handler = null; @@ -326,7 +230,7 @@ public class GpsLoader extends GenericFunction implements Runnable // Send data back to app _app.informDataLoaded(handler.getFieldArray(), handler.getDataArray(), Altitude.Format.METRES, - new SourceInfo(_deviceField.getText(), SourceInfo.FILE_TYPE.GPSBABEL), + getSourceInfo(), handler.getTrackNameList()); } } @@ -334,11 +238,9 @@ public class GpsLoader extends GenericFunction implements Runnable /** * Get the commands to call - * @param inDevice device name to use - * @param inFormat format to use * @return String array containing commands */ - private String[] getCommandArray(String inDevice, String inFormat) + private String[] getCommandArray() { String[] commands = null; final String command = Config.getConfigString(Config.KEY_GPSBABEL_PATH); @@ -346,14 +248,14 @@ public class GpsLoader extends GenericFunction implements Runnable final boolean loadTrack = _trackCheckbox.isSelected(); if (loadWaypoints && loadTrack) { // Both waypoints and track points selected - commands = new String[] {command, "-w", "-t", "-i", inFormat, - "-f", inDevice, "-o", "gpx", "-F", "-"}; + commands = new String[] {command, "-w", "-t", "-i", getInputFormat(), + "-f", getFilePath(), "-o", "gpx", "-F", "-"}; } else { // Only waypoints OR track points selected - commands = new String[] {command, "-w", "-i", inFormat, - "-f", inDevice, "-o", "gpx", "-F", "-"}; + commands = new String[] {command, "-w", "-i", getInputFormat(), + "-f", getFilePath(), "-o", "gpx", "-F", "-"}; if (loadTrack) { commands[1] = "-t"; } @@ -368,4 +270,24 @@ public class GpsLoader extends GenericFunction implements Runnable } return commands; } + + /** + * @return SourceInfo object corresponding to the load + */ + protected abstract SourceInfo getSourceInfo(); + + /** + * @return complete file path or device path for gpsbabel call + */ + protected abstract String getFilePath(); + + /** + * @return file name or device name + */ + protected abstract String getInputFormat(); + + /** + * Save any config values necessary + */ + protected abstract void saveConfigValues(); } diff --git a/tim/prune/load/ByteScooper.java b/tim/prune/load/ByteScooper.java new file mode 100644 index 0000000..facf1c5 --- /dev/null +++ b/tim/prune/load/ByteScooper.java @@ -0,0 +1,52 @@ +package tim.prune.load; + +import java.io.IOException; +import java.io.InputStream; + +/** + * Class to scoop bytes from an input stream into an array. + * The size of the array doesn't have to be known in advance. + * This is used for getting images and sound files out of zip + * files or from remote URLs. + */ +public class ByteScooper +{ + /** Bucket size in bytes */ + private static final int BUCKET_SIZE = 5000; + /** Amount by which barrel size is increased on demand */ + private static final int BARREL_SIZE_INCREMENT = 100000; + + /** + * Scoop bytes from the given input stream and return the result + * @param inIs input stream to scoop bytes from + * @return byte array + */ + public static byte[] scoop(InputStream inIs) throws IOException + { + byte[] _barrel = new byte[BARREL_SIZE_INCREMENT]; + byte[] _bucket = new byte[BUCKET_SIZE]; + int numBytesInBarrel = 0; + // read from stream into the bucket + int numBytesRead = inIs.read(_bucket); + while (numBytesRead >= 0) + { + // expand barrel if necessary + if ((numBytesInBarrel + numBytesRead) > _barrel.length) + { + byte[] newBarrel = new byte[_barrel.length + BARREL_SIZE_INCREMENT]; + System.arraycopy(_barrel, 0, newBarrel, 0, numBytesInBarrel); + _barrel = newBarrel; + } + // copy from bucket into barrel + System.arraycopy(_bucket, 0, _barrel, numBytesInBarrel, numBytesRead); + numBytesInBarrel += numBytesRead; + // read next lot from stream into the bucket + numBytesRead = inIs.read(_bucket); + } + // Now we know how many bytes there are, so crop to size + if (numBytesInBarrel == 0) return null; + byte[] result = new byte[numBytesInBarrel]; + System.arraycopy(_barrel, 0, result, 0, numBytesInBarrel); + return result; + } +} diff --git a/tim/prune/load/JpegLoader.java b/tim/prune/load/JpegLoader.java index a6a45c6..8a376d8 100644 --- a/tim/prune/load/JpegLoader.java +++ b/tim/prune/load/JpegLoader.java @@ -1,20 +1,13 @@ package tim.prune.load; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; import java.io.File; import java.util.TreeSet; -import javax.swing.BorderFactory; import javax.swing.BoxLayout; -import javax.swing.JButton; import javax.swing.JCheckBox; -import javax.swing.JDialog; import javax.swing.JFileChooser; import javax.swing.JFrame; -import javax.swing.JLabel; import javax.swing.JPanel; -import javax.swing.JProgressBar; import tim.prune.App; import tim.prune.I18nManager; @@ -27,13 +20,14 @@ import tim.prune.data.Latitude; import tim.prune.data.Longitude; import tim.prune.data.Photo; import tim.prune.data.Timestamp; +import tim.prune.function.Cancellable; import tim.prune.jpeg.ExifGateway; import tim.prune.jpeg.JpegData; /** * Class to manage the loading of Jpegs and dealing with the GPS data from them */ -public class JpegLoader implements Runnable +public class JpegLoader implements Runnable, Cancellable { private App _app = null; private JFrame _parentFrame = null; @@ -42,8 +36,7 @@ public class JpegLoader implements Runnable private JCheckBox _subdirCheckbox = null; private JCheckBox _noExifCheckbox = null; private JCheckBox _outsideAreaCheckbox = null; - private JDialog _progressDialog = null; - private JProgressBar _progressBar = null; + private MediaLoadProgressDialog _progressDialog = null; private int[] _fileCounts = null; private boolean _cancelled = false; private LatLonRectangle _trackRectangle = null; @@ -101,45 +94,16 @@ public class JpegLoader implements Runnable if (_fileChooser.showOpenDialog(_parentFrame) == JFileChooser.APPROVE_OPTION) { // Bring up dialog before starting - if (_progressDialog == null) { - createProgressDialog(); - } - // reset dialog and show it - _progressBar.setValue(0); - _progressBar.setString(""); - _progressDialog.setVisible(true); + _progressDialog = new MediaLoadProgressDialog(_parentFrame, this); + _progressDialog.show(); // start thread for processing new Thread(this).start(); } } - - /** - * Create the dialog to show the progress - */ - private void createProgressDialog() - { - _progressDialog = new JDialog(_parentFrame, I18nManager.getText("dialog.jpegload.progress.title")); - _progressDialog.setLocationRelativeTo(_parentFrame); - _progressBar = new JProgressBar(0, 100); - _progressBar.setValue(0); - _progressBar.setStringPainted(true); - _progressBar.setString(""); - JPanel panel = new JPanel(); - panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS)); - panel.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3)); - panel.add(new JLabel(I18nManager.getText("dialog.jpegload.progress"))); - panel.add(_progressBar); - JButton cancelButton = new JButton(I18nManager.getText("button.cancel")); - cancelButton.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) - { - _cancelled = true; - } - }); - panel.add(cancelButton); - _progressDialog.getContentPane().add(panel); - _progressDialog.pack(); + /** Cancel */ + public void cancel() { + _cancelled = true; } @@ -155,14 +119,12 @@ public class JpegLoader implements Runnable // Loop recursively over selected files/directories to count files int numFiles = countFileList(files, true, _subdirCheckbox.isSelected()); // Set up the progress bar for this number of files - _progressBar.setMaximum(numFiles); - _progressBar.setValue(0); + _progressDialog.showProgress(0, numFiles); _cancelled = false; // Process the files recursively and build lists of photos processFileList(files, true, _subdirCheckbox.isSelected()); - _progressDialog.setVisible(false); - _progressDialog.dispose(); // Sometimes dialog doesn't disappear without this dispose + _progressDialog.close(); if (_cancelled) {return;} if (_fileCounts[0] == 0) @@ -196,29 +158,27 @@ public class JpegLoader implements Runnable */ private void processFileList(File[] inFiles, boolean inFirstDir, boolean inDescend) { - if (inFiles != null) + if (inFiles == null) return; + // Loop over elements in array + for (int i=0; i 0) + { + data = ByteScooper.scoop(zf.getInputStream(entry)); + // System.out.println("Size of data " + (data.length == entry.getSize()?"matches":"DOESN'T match")); + } + } + catch (IOException ioe) { + System.err.println("Got ioe from zip file: " + ioe.getMessage()); + } + } + // Clean up input streams + if (is != null) try { + is.close(); + } catch (IOException ioe) {} + if (zf != null) try { + zf.close(); + } catch (IOException ioe) {} + + if (data != null) + { + // Create Photo or AudioClip using this entry + String filename = new File(inPath).getName(); + initFilters(); + if (_jpegFilter.acceptFilename(inPath)) { + return new Photo(data, filename, url); + } + else if (_audioFilter.acceptFilename(inPath)) { + return new AudioClip(data, filename, url); + } + return null; + } + else + // If we haven't got a result by now, try to just load plain file + return createMediaObject(inPath); + } + /** - * Construct a MediaFile object for the given path + * Construct a MediaObject for the given path * @param inPath path to file - * @return either Photo or AudioFile object as appropriate, or null + * @return either Photo or AudioClip object as appropriate, or null */ - public static MediaFile createMediaFile(String inPath) + private static MediaObject createMediaObject(String inPath) { if (inPath == null) {return null;} File file = new File(inPath); if (!file.exists() || !file.canRead() || !file.isFile()) {return null;} - // Initialise filters if necessary - if (_jpegFilter == null) { - _jpegFilter = new JpegFileFilter(); - _audioFilter = new AudioFileFilter(); - } + initFilters(); // Check if filename looks like a jpeg if (_jpegFilter.acceptFilename(file.getName())) { return JpegLoader.createPhoto(file); } - // Check if filename looks like an audio file + // Check if filename looks like an audio clip if (_audioFilter.acceptFilename(file.getName())) { - return new AudioFile(file); + return new AudioClip(file); } // Neither photo nor audio return null; } /** - * Add all the media from the given track into the specified list - * @param inTrack track from which media to take - * @param inMediaList list to which media should be added - * @param inMediaClass class of media, either Photo or AudioFile + * Initialise filters if necessary */ - public static void addMediaFromTrack(Track inTrack, MediaList inMediaList, - Class inMediaClass) + private static void initFilters() { - final int numPoints = inTrack.getNumPoints(); - for (int i=0; i 0) + _progressBar.setMaximum(inMax); + _progressBar.setValue(inCurrent); + _progressBar.setString("" + inCurrent + " / " + _progressBar.getMaximum()); + // TODO: Need to repaint? + } + + /** + * Close the dialog + */ + public void close() + { + if (_progressDialog != null) + _progressDialog.dispose(); + } +} diff --git a/tim/prune/load/MediaSorter.java b/tim/prune/load/MediaSorter.java index 897b5aa..e67a32b 100644 --- a/tim/prune/load/MediaSorter.java +++ b/tim/prune/load/MediaSorter.java @@ -2,31 +2,39 @@ package tim.prune.load; import java.io.File; import java.util.Comparator; -import tim.prune.data.MediaFile; - +import tim.prune.data.MediaObject; /** - * Class to sort photos by name + * Class to sort photos, audios by name */ -public class MediaSorter implements Comparator +public class MediaSorter implements Comparator { - /** - * Compare two media files + * Compare two media objects * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object) */ - public int compare(MediaFile o1, MediaFile o2) + public int compare(MediaObject o1, MediaObject o2) { + int nameComp = o1.getName().compareTo(o2.getName()); + if (nameComp != 0) { + // names different + return nameComp; + } File file1 = o1.getFile(); File file2 = o2.getFile(); - int nameComp = file1.getName().compareTo(file2.getName()); - if (nameComp == 0) + if (file1 != null && file2 != null) { // names same, maybe in different directories - return file1.getAbsolutePath().compareTo(file2.getAbsolutePath()); + nameComp = file1.getAbsolutePath().compareTo(file2.getAbsolutePath()); + } + else if (o1.getByteData() != null && o2.getByteData() != null) { + // compare data lengths instead + nameComp = o1.getByteData().length - o2.getByteData().length; + } + else { + // one's a file, one's from data + nameComp = 1; } - // names different return nameComp; } - } diff --git a/tim/prune/load/xml/GpxHandler.java b/tim/prune/load/xml/GpxHandler.java index ec52f8b..4208014 100644 --- a/tim/prune/load/xml/GpxHandler.java +++ b/tim/prune/load/xml/GpxHandler.java @@ -22,7 +22,8 @@ public class GpxHandler extends XmlHandler private GpxTag _name = new GpxTag(), _trackName = new GpxTag(); private String _latitude = null, _longitude = null; private GpxTag _elevation = new GpxTag(), _time = new GpxTag(); - private GpxTag _type = new GpxTag(), _link = new GpxTag(); + private GpxTag _type = new GpxTag(), _description = new GpxTag(); + private GpxTag _link = new GpxTag(); private GpxTag _currentTag = null; private ArrayList _pointList = new ArrayList(); private ArrayList _linkList = new ArrayList(); @@ -55,6 +56,7 @@ public class GpxHandler extends XmlHandler _time.setValue(null); _type.setValue(null); _link.setValue(null); + _description.setValue(null); } else if (tag.equals("ele")) { _currentTag = _elevation; @@ -68,6 +70,9 @@ public class GpxHandler extends XmlHandler else if (tag.equals("type")) { _currentTag = _type; } + else if (tag.equals("description")) { + _currentTag = _description; + } else if (tag.equals("link")) { _link.setValue(attributes.getValue("href")); } @@ -137,17 +142,19 @@ public class GpxHandler extends XmlHandler private void processPoint() { // Put the values into a String array matching the order in getFieldArray() - String[] values = new String[7]; + String[] values = new String[8]; values[0] = _latitude; values[1] = _longitude; values[2] = _elevation.getValue(); if (_insideWaypoint) {values[3] = _name.getValue();} values[4] = _time.getValue(); - if (_startSegment && !_insideWaypoint) { + if (_startSegment && !_insideWaypoint) + { values[5] = "1"; _startSegment = false; } values[6] = _type.getValue(); + values[7] = _description.getValue(); _pointList.add(values); _trackNameList.addPoint(_trackNum, _trackName.getValue(), _isTrackPoint); _linkList.add(_link.getValue()); @@ -160,7 +167,8 @@ public class GpxHandler extends XmlHandler public Field[] getFieldArray() { final Field[] fields = {Field.LATITUDE, Field.LONGITUDE, Field.ALTITUDE, - Field.WAYPT_NAME, Field.TIMESTAMP, Field.NEW_SEGMENT, Field.WAYPT_TYPE}; + Field.WAYPT_NAME, Field.TIMESTAMP, Field.NEW_SEGMENT, + Field.WAYPT_TYPE, Field.DESCRIPTION}; return fields; } diff --git a/tim/prune/load/xml/GzipFileLoader.java b/tim/prune/load/xml/GzipFileLoader.java index 55b88f1..98ef946 100644 --- a/tim/prune/load/xml/GzipFileLoader.java +++ b/tim/prune/load/xml/GzipFileLoader.java @@ -9,6 +9,7 @@ import tim.prune.App; import tim.prune.I18nManager; import tim.prune.data.Altitude; import tim.prune.data.SourceInfo; +import tim.prune.load.MediaLinkInfo; /** * Class to handle the loading of gzipped xml files @@ -48,15 +49,18 @@ public class GzipFileLoader if (handler == null) { _app.showErrorMessage("error.load.dialogtitle", "error.load.noread"); } - else { + else + { // Send back to app SourceInfo sourceInfo = new SourceInfo(inFile, (handler instanceof GpxHandler?SourceInfo.FILE_TYPE.GPX:SourceInfo.FILE_TYPE.KML)); _app.informDataLoaded(handler.getFieldArray(), handler.getDataArray(), - Altitude.Format.METRES, sourceInfo, handler.getTrackNameList(), handler.getLinkArray()); + Altitude.Format.METRES, sourceInfo, handler.getTrackNameList(), + new MediaLinkInfo(inFile, handler.getLinkArray())); } } - catch (Exception e) { + catch (Exception e) + { // Error occurred, could be a non-xml file borking the parser _app.showErrorMessageNoLookup("error.load.dialogtitle", I18nManager.getText("error.load.othererror") + " " + e.getClass().getName()); diff --git a/tim/prune/load/xml/KmlHandler.java b/tim/prune/load/xml/KmlHandler.java index 787dd0b..47fc721 100644 --- a/tim/prune/load/xml/KmlHandler.java +++ b/tim/prune/load/xml/KmlHandler.java @@ -12,12 +12,16 @@ import tim.prune.data.Field; */ public class KmlHandler extends XmlHandler { - private boolean _insidePlacemark = false; - private boolean _insideName = false; private boolean _insideCoordinates = false; - private String _name = null; + private String _value = null; + private String _name = null, _desc = null; + private String _imgLink = null; private StringBuffer _coordinates = null; private ArrayList _pointList = new ArrayList(); + private ArrayList _linkList = new ArrayList(); + // variables for gx extensions + private ArrayList _whenList = new ArrayList(); + private ArrayList _whereList = new ArrayList(); /** @@ -25,13 +29,12 @@ public class KmlHandler extends XmlHandler * @see org.xml.sax.ContentHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes) */ public void startElement(String uri, String localName, String qName, - Attributes attributes) throws SAXException + Attributes attributes) throws SAXException { String tagName = localName; if (tagName == null || tagName.equals("")) {tagName = qName;} - if (tagName.equalsIgnoreCase("Placemark")) _insidePlacemark = true; - else if (tagName.equalsIgnoreCase("coordinates")) {_insideCoordinates = true; _coordinates = null;} - else if (tagName.equalsIgnoreCase("name")) {_insideName = true; _name = null;} + if (tagName.equalsIgnoreCase("coordinates")) {_insideCoordinates = true; _coordinates = null;} + _value = null; super.startElement(uri, localName, qName, attributes); } @@ -48,10 +51,23 @@ public class KmlHandler extends XmlHandler if (tagName.equalsIgnoreCase("Placemark")) { processPlacemark(); - _insidePlacemark = false; + _name = _desc = _imgLink = null; } else if (tagName.equalsIgnoreCase("coordinates")) _insideCoordinates = false; - else if (tagName.equalsIgnoreCase("name")) _insideName = false; + else if (tagName.equalsIgnoreCase("name")) _name = _value; + else if (tagName.equalsIgnoreCase("description")) { + _desc = _value; + _imgLink = getImgLink(_desc); + } + else if (tagName.equalsIgnoreCase("when")) { + _whenList.add(_value); + } + else if (tagName.equalsIgnoreCase("gx:coord")) { + _whereList.add(_value); + } + else if (tagName.equalsIgnoreCase("gx:Track")) { + processGxTrack(); + } super.endElement(uri, localName, qName); } @@ -63,18 +79,19 @@ public class KmlHandler extends XmlHandler public void characters(char[] ch, int start, int length) throws SAXException { - if (_insidePlacemark && (_insideName || _insideCoordinates)) + String val = new String(ch, start, length); + if (_insideCoordinates) { - String value = new String(ch, start, length); - if (_insideName) {_name = value;} - else if (_insideCoordinates) - { - if (_coordinates == null) - { - _coordinates = new StringBuffer(); - } - _coordinates.append(value); + if (_coordinates == null) { + _coordinates = new StringBuffer(); } + _coordinates.append(val); + } + else + { + // Store string in _value + if (_value == null) _value = val; + else _value = _value + val; } super.characters(ch, start, length); } @@ -92,7 +109,8 @@ public class KmlHandler extends XmlHandler if (numPoints == 1) { // Add single waypoint to list - _pointList.add(makeStringArray(allCoords, _name)); + _pointList.add(makeStringArray(allCoords, _name, _desc)); + _linkList.add(_imgLink); } else if (numPoints > 1) { @@ -102,28 +120,94 @@ 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";} // start of segment flag + String[] pointArray = makeStringArray(coordArray[p], null, null); + if (firstPoint) {pointArray[5] = "1";} // start of segment flag firstPoint = false; _pointList.add(pointArray); } + _linkList.add(null); } } } + /** + * Process a Gx track including timestamps + */ + private void processGxTrack() + { + if (_whenList.size() > 0 && _whenList.size() == _whereList.size()) + { + // Add each of the unnamed track points to list + boolean firstPoint = true; + final int numPoints = _whenList.size(); + for (int p=0; p < numPoints; p++) + { + String when = _whenList.get(p); + String where = _whereList.get(p); + if (where != null) + { + String[] coords = where.split(" "); + if (coords.length == 3) + { + String[] pointArray = new String[7]; + pointArray[0] = coords[0]; + pointArray[1] = coords[1]; + pointArray[2] = coords[2]; + // leave name and description empty + if (firstPoint) {pointArray[5] = "1";} // start of segment flag + firstPoint = false; + pointArray[6] = when; // timestamp + _pointList.add(pointArray); + } + } + _linkList.add(null); + } + } + _whenList.clear(); + _whereList.clear(); + } + + /** + * Extract an image link from the point description + * @param inDesc description tag contents + * @return image link if found or null + */ + private static String getImgLink(String inDesc) + { + if (inDesc == null || inDesc.equals("")) {return null;} + // Pull out ', spos + 10); + if (spos < 0 || epos < 0) return null; + String imgtag = inDesc.substring(spos + 4, epos); + // Find the src attribute from img tag + int quotepos = imgtag.toLowerCase().indexOf("src="); + if (quotepos < 0) return null; + // source may be quoted with single or double quotes + char quotechar = imgtag.charAt(quotepos + 4); + int equotepos = imgtag.indexOf(quotechar, quotepos + 7); + if (equotepos < 0) return null; + return imgtag.substring(quotepos + 5, equotepos); + } /** * Construct the String array for the given coordinates and name * @param inCoordinates coordinate string in Kml format * @param inName name of waypoint, or null if track point + * @param inDesc description of waypoint, if any * @return String array for point */ - private static String[] makeStringArray(String inCoordinates, String inName) + private static String[] makeStringArray(String inCoordinates, + String inName, String inDesc) { - String[] result = new String[5]; + String[] result = new String[7]; String[] values = inCoordinates.split(","); - if (values.length == 3) {System.arraycopy(values, 0, result, 0, 3);} + final int numValues = values.length; + if (numValues == 3 || numValues == 2) { + System.arraycopy(values, 0, result, 0, numValues); + } result[3] = inName; + result[4] = inDesc; return result; } @@ -133,7 +217,8 @@ public class KmlHandler extends XmlHandler */ public Field[] getFieldArray() { - final Field[] fields = {Field.LONGITUDE, Field.LATITUDE, Field.ALTITUDE, Field.WAYPT_NAME, Field.NEW_SEGMENT}; + final Field[] fields = {Field.LONGITUDE, Field.LATITUDE, Field.ALTITUDE, + Field.WAYPT_NAME, Field.DESCRIPTION, Field.NEW_SEGMENT, Field.TIMESTAMP}; return fields; } @@ -147,11 +232,26 @@ public class KmlHandler extends XmlHandler int numPoints = _pointList.size(); // construct data array String[][] result = new String[numPoints][]; - for (int i=0; i"); - inWriter.write((inDesc != null && !inDesc.equals(""))?inDesc:"Export from Prune"); + inWriter.write((inDesc != null && !inDesc.equals(""))?inDesc:"Export from GpsPrune"); inWriter.write("\n"); int i = 0; @@ -333,21 +378,20 @@ public class GpxExporter extends GenericFunction implements Runnable for (i=0; i=selStart && i<=selEnd)) { + if (!exportSelection || (i>=selStart && i<=selEnd)) + { // Make a wpt element for each waypoint - if (point.isWaypoint()) { - if (exportWaypoints) - { - String pointSource = (inUseCopy?getPointSource(gpxCachers, point):null); - if (pointSource != null) { - inWriter.write(pointSource); - inWriter.write('\n'); - } - else { - exportWaypoint(point, inWriter, exportTimestamps, exportPhotos, exportAudios); - } - numSaved++; + if (point.isWaypoint() && exportWaypoints) + { + String pointSource = (inUseCopy?getPointSource(gpxCachers, point):null); + if (pointSource != null) { + inWriter.write(pointSource); + inWriter.write('\n'); + } + else { + exportWaypoint(point, inWriter, exportTimestamps, exportPhotos, exportAudios); } + numSaved++; } } } @@ -369,6 +413,7 @@ public class GpxExporter extends GenericFunction implements Runnable return numSaved; } + /** * Loop through the track outputting the relevant track points * @param inWriter writer object for output @@ -451,7 +496,12 @@ public class GpxExporter extends GenericFunction implements Runnable source = replaceGpxTags(source, "lon=\"", "\"", inPoint.getLongitude().output(Coordinate.FORMAT_DECIMAL_FORCE_POINT)); source = replaceGpxTags(source, "", "", inPoint.getAltitude().getStringValue(Altitude.Format.METRES)); source = replaceGpxTags(source, "", inPoint.getTimestamp().getText(Timestamp.FORMAT_ISO_8601)); - if (inPoint.isWaypoint()) {source = replaceGpxTags(source, "", "", inPoint.getWaypointName());} // only for waypoints + if (inPoint.isWaypoint()) + { + source = replaceGpxTags(source, "", "", inPoint.getWaypointName()); + source = replaceGpxTags(source, "", "", + XmlUtils.fixCdata(inPoint.getFieldValue(Field.DESCRIPTION))); + } // photo / audio links if (source != null && (inPoint.hasMedia() || source.indexOf("") > 0)) { source = replaceMediaLinks(source, makeMediaLink(inPoint)); @@ -494,6 +544,7 @@ public class GpxExporter extends GenericFunction implements Runnable return null; } + /** * Replace the media tags in the given XML string * @param inSource source XML for point @@ -531,19 +582,73 @@ public class GpxExporter extends GenericFunction implements Runnable return null; } + /** * Get the header string for the xml document including encoding * @param inWriter writer object * @return header string defining encoding */ private static String getXmlHeaderString(OutputStreamWriter inWriter) + { + return "\n"; + } + + + /** + * Get the default system encoding using a writer + * @param inWriter writer object + * @return string defining encoding + */ + private static String getEncoding(OutputStreamWriter inWriter) { String encoding = inWriter.getEncoding(); try { encoding = Charset.forName(encoding).name(); } catch (Exception e) {} // ignore failure to find encoding - return "\n"; + // Hack to fix bugs with Mac OSX (which reports MacRoman but is actually UTF-8) + if (encoding == null || encoding.toLowerCase().startsWith("macroman")) { + encoding = "UTF-8"; + } + return encoding; + } + + + /** + * Use a temporary file to obtain the name of the default system encoding + * @return name of default system encoding, or null if write failed + */ + private static String getSystemEncoding() + { + File tempFile = null; + String encoding = null; + try + { + tempFile = File.createTempFile("prune", null); + OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(tempFile)); + encoding = getEncoding(writer); + writer.close(); + } + catch (IOException e) {} // value stays null + // Delete temp file + if (tempFile != null && tempFile.exists()) { + if (!tempFile.delete()) { + System.err.println("Cannot delete temp file: " + tempFile.getAbsolutePath()); + } + } + // If writing failed (eg permissions) then just ask system for default + if (encoding == null) encoding = Charset.defaultCharset().name(); + return encoding; + } + + /** + * Creates temp file if necessary to check system encoding + * @return true if system uses UTF-8 by default + */ + private static boolean isSystemUtf8() + { + if (_systemEncoding == null) _systemEncoding = getSystemEncoding(); + return (_systemEncoding != null && _systemEncoding.toUpperCase().equals("UTF-8")); } /** @@ -566,6 +671,7 @@ public class GpxExporter extends GenericFunction implements Runnable return gpxHeader + "\n"; } + /** * Export the specified waypoint into the file * @param inPoint waypoint to export @@ -602,6 +708,14 @@ public class GpxExporter extends GenericFunction implements Runnable inWriter.write("\t\t"); inWriter.write(inPoint.getWaypointName().trim()); inWriter.write("\n"); + // description, if any + String desc = XmlUtils.fixCdata(inPoint.getFieldValue(Field.DESCRIPTION)); + if (desc != null && !desc.equals("")) + { + inWriter.write("\t\t"); + inWriter.write(desc); + inWriter.write("\n"); + } // Media links, if any if (inPhoto && inPoint.getPhoto() != null) { @@ -672,6 +786,7 @@ public class GpxExporter extends GenericFunction implements Runnable inWriter.write("\n"); } + /** * Make the xml for the media link(s) * @param inPoint point to generate text for @@ -680,7 +795,7 @@ public class GpxExporter extends GenericFunction implements Runnable private static String makeMediaLink(DataPoint inPoint) { Photo photo = inPoint.getPhoto(); - AudioFile audio = inPoint.getAudio(); + AudioClip audio = inPoint.getAudio(); if (photo == null && audio == null) { return null; } @@ -699,8 +814,15 @@ public class GpxExporter extends GenericFunction implements Runnable * @param inMedia media item, either photo or audio * @return link for this media */ - private static String makeMediaLink(MediaFile inMedia) + private static String makeMediaLink(MediaObject inMedia) { - return "" + inMedia.getFile().getName() + ""; + if (inMedia.getFile() != null) + // file link + return "" + inMedia.getName() + ""; + if (inMedia.getUrl() != null) + // url link + return "" + inMedia.getName() + ""; + // No link available, must have been loaded from zip file - no link possible + return ""; } } diff --git a/tim/prune/save/KmlExporter.java b/tim/prune/save/KmlExporter.java index 7f90dbc..e1cc151 100644 --- a/tim/prune/save/KmlExporter.java +++ b/tim/prune/save/KmlExporter.java @@ -45,6 +45,7 @@ import tim.prune.data.Altitude; import tim.prune.data.Coordinate; import tim.prune.data.DataPoint; import tim.prune.data.Field; +import tim.prune.data.RecentFile; import tim.prune.data.Track; import tim.prune.data.TrackInfo; import tim.prune.gui.ColourChooser; @@ -52,6 +53,7 @@ import tim.prune.gui.ColourPatch; import tim.prune.gui.DialogCloser; import tim.prune.gui.ImageUtils; import tim.prune.load.GenericFileFilter; +import tim.prune.save.xml.XmlUtils; /** * Class to export track information @@ -378,7 +380,10 @@ public class KmlExporter extends GenericFunction implements Runnable _imageDimensions = null; // Store directory in config for later Config.setConfigString(Config.KEY_TRACK_DIR, _exportFile.getParentFile().getAbsolutePath()); + // Add to recent file list + Config.getRecentFileList().addFile(new RecentFile(_exportFile, true)); // show confirmation + UpdateMessageBroker.informSubscribers(); UpdateMessageBroker.informSubscribers(I18nManager.getText("confirm.save.ok1") + " " + numPoints + " " + I18nManager.getText("confirm.save.ok2") + " " + _exportFile.getAbsolutePath()); @@ -422,7 +427,7 @@ public class KmlExporter extends GenericFunction implements Runnable inWriter.write(_descriptionField.getText()); } else { - inWriter.write("Export from Prune"); + inWriter.write("Export from GpsPrune"); } inWriter.write("\n"); @@ -472,7 +477,7 @@ public class KmlExporter extends GenericFunction implements Runnable exportPhotoPoint(point, inWriter, inExportImages, i, photoNum, absoluteAltitudes); numSaved++; } - // Make a blob with description for each audio file + // Make a blob with description for each audio clip if (point.getAudio() != null && writeAudios && writeCurrentPoint) { if (!writtenAudioHeader) @@ -552,7 +557,7 @@ public class KmlExporter extends GenericFunction implements Runnable private void exportWaypoint(DataPoint inPoint, Writer inWriter, boolean inAbsoluteAltitude) throws IOException { String name = inPoint.getWaypointName().trim(); - exportNamedPoint(inPoint, inWriter, name, null, null, inAbsoluteAltitude); + exportNamedPoint(inPoint, inWriter, name, inPoint.getFieldValue(Field.DESCRIPTION), null, inAbsoluteAltitude); } @@ -565,8 +570,11 @@ public class KmlExporter extends GenericFunction implements Runnable */ private void exportAudioPoint(DataPoint inPoint, Writer inWriter, boolean inAbsoluteAltitude) throws IOException { - String name = inPoint.getAudio().getFile().getName(); - String desc = inPoint.getAudio().getFile().getAbsolutePath(); + String name = inPoint.getAudio().getName(); + String desc = null; + if (inPoint.getAudio().getFile() != null) { + desc = inPoint.getAudio().getFile().getAbsolutePath(); + } exportNamedPoint(inPoint, inWriter, name, desc, "audio_icon", inAbsoluteAltitude); } @@ -585,7 +593,7 @@ public class KmlExporter extends GenericFunction implements Runnable int inPointNumber, int inImageNumber, boolean inAbsoluteAltitude) throws IOException { - String name = inPoint.getPhoto().getFile().getName(); + String name = inPoint.getPhoto().getName(); String desc = null; if (inImageLink) { @@ -593,7 +601,7 @@ public class KmlExporter extends GenericFunction implements Runnable // Create html for the thumbnail images desc = "" - + "
" + inPoint.getPhoto().getFile().getName() + "
]]>"; + + "

" + name + "
]]>"; } // Export point exportNamedPoint(inPoint, inWriter, name, desc, "camera_icon", inAbsoluteAltitude); @@ -620,9 +628,9 @@ public class KmlExporter extends GenericFunction implements Runnable if (inDesc != null) { // Write out description - inWriter.write(""); - inWriter.write(inDesc); - inWriter.write(""); + inWriter.write("\t\t"); + inWriter.write(XmlUtils.fixCdata(inDesc)); + inWriter.write("\n"); } if (inStyle != null) { @@ -714,9 +722,9 @@ public class KmlExporter extends GenericFunction implements Runnable ZipEntry entry = new ZipEntry("images/image" + photoNum + ".jpg"); inZipStream.putNextEntry(entry); // Load image and write to outstream - ImageIcon icon = new ImageIcon(point.getPhoto().getFile().getAbsolutePath()); + ImageIcon icon = point.getPhoto().createImageIcon(); - // Scale and smooth image to required size + // Scale image to required size TODO: should it also be smoothed, or only if it's smaller than a certain size? BufferedImage bufferedImage = ImageUtils.rotateImage(icon.getImage(), inThumbWidth, inThumbHeight, point.getPhoto().getRotationDegrees()); // Store image dimensions so that it doesn't have to be calculated again for the points diff --git a/tim/prune/save/PhotoTableEntry.java b/tim/prune/save/PhotoTableEntry.java index 34fd2b9..f42720e 100644 --- a/tim/prune/save/PhotoTableEntry.java +++ b/tim/prune/save/PhotoTableEntry.java @@ -22,7 +22,7 @@ public class PhotoTableEntry _photo = inPhoto; if (inPhoto != null) { - _photoName = inPhoto.getFile().getName(); + _photoName = inPhoto.getName(); _status = getStatusString(inPhoto.getOriginalStatus(), inPhoto.getCurrentStatus()); } } diff --git a/tim/prune/save/PovExporter.java b/tim/prune/save/PovExporter.java index 313b72a..e360878 100644 --- a/tim/prune/save/PovExporter.java +++ b/tim/prune/save/PovExporter.java @@ -377,7 +377,7 @@ public class PovExporter extends Export3dFunction private void writeStartOfFile(FileWriter inWriter, double inModelSize, String inLineSeparator) throws IOException { - inWriter.write("// Pov file produced by Prune - see http://activityworkshop.net/"); + inWriter.write("// Pov file produced by GpsPrune - see http://activityworkshop.net/"); inWriter.write(inLineSeparator); inWriter.write(inLineSeparator); // Select font based on user input diff --git a/tim/prune/save/SvgExporter.java b/tim/prune/save/SvgExporter.java index 5bfd7c0..69f5168 100644 --- a/tim/prune/save/SvgExporter.java +++ b/tim/prune/save/SvgExporter.java @@ -316,7 +316,7 @@ public class SvgExporter extends Export3dFunction { inWriter.write(""); inWriter.write(inLineSeparator); - inWriter.write(""); + inWriter.write(""); inWriter.write(inLineSeparator); inWriter.write(""); inWriter.write(inLineSeparator); diff --git a/tim/prune/save/xml/XmlUtils.java b/tim/prune/save/xml/XmlUtils.java new file mode 100644 index 0000000..a4f9cae --- /dev/null +++ b/tim/prune/save/xml/XmlUtils.java @@ -0,0 +1,37 @@ +package tim.prune.save.xml; + +/** + * Collection of utility functions for handling XML + */ +public abstract class XmlUtils +{ + /** Start of Cdata sequence */ + private static final String CDATA_START = ""; + /** End of Cdata sequence */ + private static final String CDATA_END = ""; + + /** + * Fix the CDATA blocks in the given String to give valid xml + * @param inString String to modify + * @return fixed String + */ + public static String fixCdata(String inString) + { + if (inString == null) return ""; + if (inString.indexOf('<') < 0 && inString.indexOf('>') < 0) { + return inString; + } + String result = inString; + // Remove cdata block at start if present + if (result.startsWith(CDATA_START)) { + result = result.substring(CDATA_START.length()); + } + // Remove all instances of end block + result = result.replaceAll(CDATA_END, ""); + // Now check whether cdata block is required + if (result.indexOf('<') < 0 && result.indexOf('>') < 0) { + return result; + } + return CDATA_START + result + CDATA_END; + } +} diff --git a/tim/prune/undo/UndoConnectMedia.java b/tim/prune/undo/UndoConnectMedia.java index e75f02f..d7feb63 100644 --- a/tim/prune/undo/UndoConnectMedia.java +++ b/tim/prune/undo/UndoConnectMedia.java @@ -2,7 +2,7 @@ package tim.prune.undo; import tim.prune.I18nManager; import tim.prune.UpdateMessageBroker; -import tim.prune.data.AudioFile; +import tim.prune.data.AudioClip; import tim.prune.data.DataPoint; import tim.prune.data.Photo; import tim.prune.data.TrackInfo; @@ -62,7 +62,7 @@ public class UndoConnectMedia implements UndoOperation if (_audioFilename != null) { // Disconnect audio - AudioFile audio = _point.getAudio(); + AudioClip audio = _point.getAudio(); if (audio != null) { _point.setAudio(null); diff --git a/tim/prune/undo/UndoCorrelateAudios.java b/tim/prune/undo/UndoCorrelateAudios.java index e0c1f95..60cfbe6 100644 --- a/tim/prune/undo/UndoCorrelateAudios.java +++ b/tim/prune/undo/UndoCorrelateAudios.java @@ -1,7 +1,7 @@ package tim.prune.undo; import tim.prune.I18nManager; -import tim.prune.data.AudioFile; +import tim.prune.data.AudioClip; import tim.prune.data.DataPoint; import tim.prune.data.TrackInfo; @@ -60,9 +60,9 @@ public class UndoCorrelateAudios implements UndoOperation // restore audio association for (int i=0; i<_audioPoints.length; i++) { - AudioFile audio = inTrackInfo.getAudioList().getAudio(i); + AudioClip audio = inTrackInfo.getAudioList().getAudio(i); // Only need to look at connected ones, since correlation wouldn't disconnect - if (audio.getCurrentStatus() == AudioFile.Status.CONNECTED) + if (audio.getCurrentStatus() == AudioClip.Status.CONNECTED) { DataPoint prevPoint = _audioPoints[i]; DataPoint currPoint = audio.getDataPoint(); diff --git a/tim/prune/undo/UndoDeleteAudio.java b/tim/prune/undo/UndoDeleteAudio.java index e413426..0a49732 100644 --- a/tim/prune/undo/UndoDeleteAudio.java +++ b/tim/prune/undo/UndoDeleteAudio.java @@ -2,7 +2,7 @@ package tim.prune.undo; import tim.prune.I18nManager; import tim.prune.UpdateMessageBroker; -import tim.prune.data.AudioFile; +import tim.prune.data.AudioClip; import tim.prune.data.DataPoint; import tim.prune.data.TrackInfo; @@ -12,7 +12,7 @@ import tim.prune.data.TrackInfo; public class UndoDeleteAudio implements UndoOperation { private int _audioIndex = -1; - private AudioFile _audio = null; + private AudioClip _audio = null; private int _pointIndex = -1; private DataPoint _point = null; @@ -24,7 +24,7 @@ public class UndoDeleteAudio implements UndoOperation * @param inPoint data point * @param inPointIndex index number of point within track */ - public UndoDeleteAudio(AudioFile inAudio, int inAudioIndex, DataPoint inPoint, int inPointIndex) + public UndoDeleteAudio(AudioClip inAudio, int inAudioIndex, DataPoint inPoint, int inPointIndex) { _audio = inAudio; _audioIndex = inAudioIndex; @@ -37,7 +37,7 @@ public class UndoDeleteAudio implements UndoOperation * @return description of operation including filename */ public String getDescription() { - return I18nManager.getText("undo.removeaudio") + " " + _audio.getFile().getName(); + return I18nManager.getText("undo.removeaudio") + " " + _audio.getName(); } diff --git a/tim/prune/undo/UndoDeletePhoto.java b/tim/prune/undo/UndoDeletePhoto.java index 4c37e61..5edd37b 100644 --- a/tim/prune/undo/UndoDeletePhoto.java +++ b/tim/prune/undo/UndoDeletePhoto.java @@ -38,7 +38,7 @@ public class UndoDeletePhoto implements UndoOperation */ public String getDescription() { - String desc = I18nManager.getText("undo.removephoto") + " " + _photo.getFile().getName(); + String desc = I18nManager.getText("undo.removephoto") + " " + _photo.getName(); return desc; } diff --git a/tim/prune/undo/UndoDeletePoint.java b/tim/prune/undo/UndoDeletePoint.java index 57abc98..adb2ea3 100644 --- a/tim/prune/undo/UndoDeletePoint.java +++ b/tim/prune/undo/UndoDeletePoint.java @@ -65,7 +65,9 @@ public class UndoDeletePoint implements UndoOperation inTrackInfo.getPhotoList().addPhoto(_point.getPhoto(), _photoIndex); } // Ensure that photo is associated with point - _point.getPhoto().setDataPoint(_point); + if (_point.getPhoto().getDataPoint() != _point) { + _point.getPhoto().setDataPoint(_point); + } } // Restore previous status of following track point if necessary if (!_segmentStart) diff --git a/tim/prune/undo/UndoDisconnectMedia.java b/tim/prune/undo/UndoDisconnectMedia.java index 51b310f..f40ab2d 100644 --- a/tim/prune/undo/UndoDisconnectMedia.java +++ b/tim/prune/undo/UndoDisconnectMedia.java @@ -1,7 +1,7 @@ package tim.prune.undo; import tim.prune.I18nManager; -import tim.prune.data.AudioFile; +import tim.prune.data.AudioClip; import tim.prune.data.DataPoint; import tim.prune.data.Photo; import tim.prune.data.TrackInfo; @@ -13,7 +13,7 @@ public class UndoDisconnectMedia implements UndoOperation { private DataPoint _point = null; private Photo _photo = null; - private AudioFile _audio = null; + private AudioClip _audio = null; private String _filename = null; diff --git a/tim/prune/undo/UndoLoadAudios.java b/tim/prune/undo/UndoLoadAudios.java index c5b49fc..7a48cd2 100644 --- a/tim/prune/undo/UndoLoadAudios.java +++ b/tim/prune/undo/UndoLoadAudios.java @@ -8,7 +8,7 @@ import tim.prune.data.TrackInfo; */ public class UndoLoadAudios implements UndoOperation { - /** Number of audio files added */ + /** Number of audio clips added */ private int _numAudios = -1; diff --git a/tim/prune/undo/UndoRotatePhoto.java b/tim/prune/undo/UndoRotatePhoto.java index 495effa..72cf40f 100644 --- a/tim/prune/undo/UndoRotatePhoto.java +++ b/tim/prune/undo/UndoRotatePhoto.java @@ -31,7 +31,7 @@ public class UndoRotatePhoto implements UndoOperation */ public String getDescription() { - return I18nManager.getText("undo.rotatephoto") + " " + _photo.getFile().getName(); + return I18nManager.getText("undo.rotatephoto") + " " + _photo.getName(); }