From 1ee49ae3c8ef3aa2e63eadd458531e5f8bd4f92c Mon Sep 17 00:00:00 2001 From: activityworkshop Date: Sat, 14 Feb 2015 15:25:57 +0100 Subject: [PATCH] Version 9, February 2010 --- tim/prune/App.java | 93 ++- tim/prune/ExternalTools.java | 3 +- tim/prune/FunctionLibrary.java | 34 +- tim/prune/GpsPruner.java | 23 +- tim/prune/I18nManager.java | 19 +- tim/prune/config/ColourScheme.java | 89 +++ tim/prune/config/ColourUtils.java | 65 ++ tim/prune/{ => config}/Config.java | 45 +- tim/prune/{ => config}/ConfigException.java | 2 +- tim/prune/copyright.txt | 8 + tim/prune/data/Coordinate.java | 32 +- tim/prune/data/DataPoint.java | 45 +- tim/prune/data/FileInfo.java | 72 ++- tim/prune/data/Photo.java | 31 +- tim/prune/data/Selection.java | 16 +- tim/prune/data/SourceInfo.java | 111 ++++ tim/prune/data/Track.java | 26 +- tim/prune/data/TrackInfo.java | 23 + tim/prune/drew/jpeg/ExifReader.java | 12 +- tim/prune/drew/jpeg/JpegData.java | 26 +- tim/prune/function/AboutScreen.java | 15 +- tim/prune/function/AddAltitudeOffset.java | 3 +- tim/prune/function/ConvertNamesToTimes.java | 73 +++ tim/prune/function/DuplicatePoint.java | 38 ++ tim/prune/function/FullRangeDetails.java | 219 +++++++ tim/prune/function/IgnoreExifThumb.java | 42 ++ tim/prune/function/PasteCoordinates.java | 269 ++++++++ .../function/RearrangePhotosFunction.java | 220 +++++++ tim/prune/function/RotatePhoto.java | 50 ++ tim/prune/function/SaveConfig.java | 2 +- tim/prune/function/SetColours.java | 205 +++++++ tim/prune/function/SetKmzImageSize.java | 2 +- tim/prune/function/SetLanguage.java | 332 ++++++++++ tim/prune/function/SetMapBgFunction.java | 2 +- tim/prune/function/SetPathsFunction.java | 2 +- tim/prune/function/browser/UrlGenerator.java | 33 +- tim/prune/function/charts/Charter.java | 2 +- .../compress/CompressTrackFunction.java | 1 - .../function/distance/DistanceTableModel.java | 2 +- tim/prune/function/edit/PointEditor.java | 2 +- .../function/gpsies/GetGpsiesFunction.java | 10 +- tim/prune/function/gpsies/TrackListModel.java | 2 +- tim/prune/gui/ColourChooser.java | 151 +++++ tim/prune/gui/ColourPatch.java | 34 ++ tim/prune/gui/DetailsDisplay.java | 111 ++-- tim/prune/gui/DisplayUtils.java | 28 + tim/prune/gui/GenericChart.java | 16 +- tim/prune/gui/GuiGridLayout.java | 61 ++ tim/prune/gui/IconManager.java | 4 + tim/prune/gui/ImageUtils.java | 56 +- tim/prune/gui/MenuManager.java | 323 ++++++---- tim/prune/gui/PhotoThumbnail.java | 79 +-- tim/prune/gui/ProfileChart.java | 70 ++- tim/prune/gui/WaypointListModel.java | 1 + tim/prune/gui/images/rotate_left_icon.png | Bin 0 -> 286 bytes tim/prune/gui/images/rotate_right_icon.png | Bin 0 -> 286 bytes tim/prune/gui/map/MapCanvas.java | 174 +++--- tim/prune/gui/map/MapTileConfig.java | 2 +- tim/prune/gui/map/ScaleBar.java | 30 +- tim/prune/lang/prune-texts_af.properties | 1 + tim/prune/lang/prune-texts_de.properties | 128 ++-- tim/prune/lang/prune-texts_de_CH.properties | 105 +++- tim/prune/lang/prune-texts_en.properties | 87 ++- tim/prune/lang/prune-texts_es.properties | 221 ++++--- tim/prune/lang/prune-texts_fr.properties | 85 ++- tim/prune/lang/prune-texts_in.properties | 15 +- tim/prune/lang/prune-texts_it.properties | 104 ++-- tim/prune/lang/prune-texts_ja.properties | 573 ++++++++++++++++++ tim/prune/lang/prune-texts_pl.properties | 113 +++- tim/prune/lang/prune-texts_pt.properties | 548 ++++++++++++++++- tim/prune/lang/prune-texts_ro.properties | 131 +++- tim/prune/lang/prune-texts_tr.properties | 436 +++++++++++++ tim/prune/lang/prune-texts_zh.properties | 41 +- tim/prune/load/FieldGuesser.java | 33 + tim/prune/load/FileLoader.java | 10 +- tim/prune/load/GpsLoader.java | 167 +++-- tim/prune/load/JpegLoader.java | 30 +- tim/prune/load/NmeaFileLoader.java | 3 +- tim/prune/load/TextFileLoader.java | 5 +- tim/prune/load/xml/GpxHandler.java | 29 +- tim/prune/load/xml/GzipFileLoader.java | 73 +++ tim/prune/load/xml/XmlFileLoader.java | 5 +- tim/prune/load/xml/ZipFileLoader.java | 7 +- tim/prune/readme.txt | 32 +- tim/prune/save/ExifSaver.java | 60 +- tim/prune/save/FileSaver.java | 347 ++++++----- tim/prune/save/GpsSaver.java | 6 +- tim/prune/save/GpxCacher.java | 198 ++++++ tim/prune/save/GpxCacherList.java | 68 +++ tim/prune/save/GpxExporter.java | 269 +++++--- tim/prune/save/KmlExporter.java | 129 +++- tim/prune/save/PointTypeSelector.java | 24 +- tim/prune/save/PovExporter.java | 2 +- tim/prune/undo/UndoConnectPhotoWithClone.java | 41 -- tim/prune/undo/UndoConvertNamesToTimes.java | 81 +++ tim/prune/undo/UndoCutAndMove.java | 1 - tim/prune/undo/UndoEditPoint.java | 2 +- tim/prune/undo/UndoLoad.java | 18 +- tim/prune/undo/UndoRearrangePhotos.java | 19 + tim/prune/undo/UndoRearrangeWaypoints.java | 29 +- tim/prune/undo/UndoReorder.java | 46 ++ tim/prune/undo/UndoRotatePhoto.java | 48 ++ 102 files changed, 6535 insertions(+), 1276 deletions(-) create mode 100644 tim/prune/config/ColourScheme.java create mode 100644 tim/prune/config/ColourUtils.java rename tim/prune/{ => config}/Config.java (82%) rename tim/prune/{ => config}/ConfigException.java (82%) create mode 100644 tim/prune/copyright.txt create mode 100644 tim/prune/data/SourceInfo.java create mode 100644 tim/prune/function/ConvertNamesToTimes.java create mode 100644 tim/prune/function/DuplicatePoint.java create mode 100644 tim/prune/function/FullRangeDetails.java create mode 100644 tim/prune/function/IgnoreExifThumb.java create mode 100644 tim/prune/function/PasteCoordinates.java create mode 100644 tim/prune/function/RearrangePhotosFunction.java create mode 100644 tim/prune/function/RotatePhoto.java create mode 100644 tim/prune/function/SetColours.java create mode 100644 tim/prune/function/SetLanguage.java create mode 100644 tim/prune/gui/ColourChooser.java create mode 100644 tim/prune/gui/ColourPatch.java create mode 100644 tim/prune/gui/DisplayUtils.java create mode 100644 tim/prune/gui/GuiGridLayout.java create mode 100644 tim/prune/gui/images/rotate_left_icon.png create mode 100644 tim/prune/gui/images/rotate_right_icon.png create mode 100644 tim/prune/lang/prune-texts_ja.properties create mode 100644 tim/prune/lang/prune-texts_tr.properties create mode 100644 tim/prune/load/xml/GzipFileLoader.java create mode 100644 tim/prune/save/GpxCacher.java create mode 100644 tim/prune/save/GpxCacherList.java delete mode 100644 tim/prune/undo/UndoConnectPhotoWithClone.java create mode 100644 tim/prune/undo/UndoConvertNamesToTimes.java create mode 100644 tim/prune/undo/UndoRearrangePhotos.java create mode 100644 tim/prune/undo/UndoReorder.java create mode 100644 tim/prune/undo/UndoRotatePhoto.java diff --git a/tim/prune/App.java b/tim/prune/App.java index 091a37c..ab9724b 100644 --- a/tim/prune/App.java +++ b/tim/prune/App.java @@ -1,24 +1,22 @@ package tim.prune; +import java.io.File; import java.util.ArrayList; import java.util.EmptyStackException; import java.util.Set; import java.util.Stack; -import java.io.File; import javax.swing.JFrame; import javax.swing.JOptionPane; import tim.prune.data.Altitude; -import tim.prune.data.Coordinate; import tim.prune.data.DataPoint; import tim.prune.data.Field; import tim.prune.data.LatLonRectangle; -import tim.prune.data.Latitude; -import tim.prune.data.Longitude; import tim.prune.data.NumberUtils; import tim.prune.data.Photo; import tim.prune.data.PhotoList; +import tim.prune.data.SourceInfo; import tim.prune.data.Track; import tim.prune.data.TrackInfo; import tim.prune.function.browser.BrowserLauncher; @@ -32,7 +30,24 @@ import tim.prune.load.FileLoader; import tim.prune.load.JpegLoader; import tim.prune.save.ExifSaver; import tim.prune.save.FileSaver; -import tim.prune.undo.*; +import tim.prune.undo.UndoAddAltitudeOffset; +import tim.prune.undo.UndoAddTimeOffset; +import tim.prune.undo.UndoCompress; +import tim.prune.undo.UndoConnectPhoto; +import tim.prune.undo.UndoCreatePoint; +import tim.prune.undo.UndoCutAndMove; +import tim.prune.undo.UndoDeletePhoto; +import tim.prune.undo.UndoDeletePoint; +import tim.prune.undo.UndoDeleteRange; +import tim.prune.undo.UndoDisconnectPhoto; +import tim.prune.undo.UndoEditPoint; +import tim.prune.undo.UndoException; +import tim.prune.undo.UndoInsert; +import tim.prune.undo.UndoLoad; +import tim.prune.undo.UndoLoadPhotos; +import tim.prune.undo.UndoMergeTrackSegments; +import tim.prune.undo.UndoOperation; +import tim.prune.undo.UndoReverseSection; /** @@ -178,7 +193,7 @@ public class App else { if (_fileSaver == null) { - _fileSaver = new FileSaver(this, _frame, _track); + _fileSaver = new FileSaver(this, _frame); } char delim = ','; if (_fileLoader != null) {delim = _fileLoader.getLastUsedDelimiter();} @@ -239,7 +254,7 @@ public class App // add information to undo stack UndoOperation undo = new UndoEditPoint(currentPoint, inUndoList); // pass to track for completion - if (_track.editPoint(currentPoint, inEditList)) + if (_track.editPoint(currentPoint, inEditList, false)) { _undoStack.push(undo); // Confirm point edit @@ -556,18 +571,18 @@ public class App /** - * Create a new point at the given lat/long coordinates - * @param inLat latitude - * @param inLong longitude + * Create a new point at the given position + * @param inPoint point to add */ - public void createPoint(double inLat, double inLong) + public void createPoint(DataPoint inPoint) { // create undo object UndoCreatePoint undo = new UndoCreatePoint(); - // create point and add to track - DataPoint point = new DataPoint(new Latitude(inLat, Coordinate.FORMAT_NONE), new Longitude(inLong, Coordinate.FORMAT_NONE), null); - point.setSegmentStart(true); - _track.appendPoints(new DataPoint[] {point}); + // add point to track + inPoint.setSegmentStart(true); + _track.appendPoints(new DataPoint[] {inPoint}); + // ensure track's field list contains point's fields + _track.extendFieldList(inPoint.getFieldList()); _trackInfo.selectPoint(_trackInfo.getTrack().getNumPoints()-1); // add undo object to stack _undoStack.add(undo); @@ -630,10 +645,10 @@ public class App * @param inFieldArray array of fields * @param inDataArray array of data * @param inAltFormat altitude format - * @param inFilename filename used + * @param inSourceInfo information about the source of the data */ public void informDataLoaded(Field[] inFieldArray, Object[][] inDataArray, Altitude.Format inAltFormat, - String inFilename) + SourceInfo inSourceInfo) { // Check whether loaded array can be properly parsed into a Track Track loadedTrack = new Track(); @@ -665,15 +680,9 @@ public class App // append data to current Track _undoStack.add(new UndoLoad(_track.getNumPoints(), loadedTrack.getNumPoints())); _track.combine(loadedTrack); - // set filename if currently empty - if (_trackInfo.getFileInfo().getNumFiles() == 0) - { - _trackInfo.getFileInfo().setFile(inFilename); - } - else - { - _trackInfo.getFileInfo().addFile(); - } + // set source information + inSourceInfo.populatePointObjects(_track, loadedTrack.getNumPoints()); + _trackInfo.getFileInfo().addSource(inSourceInfo); } else if (answer == JOptionPane.NO_OPTION) { @@ -687,7 +696,8 @@ public class App _lastSavePosition = _undoStack.size(); _trackInfo.getSelection().clearAll(); _track.load(loadedTrack); - _trackInfo.getFileInfo().setFile(inFilename); + inSourceInfo.populatePointObjects(_track, _track.getNumPoints()); + _trackInfo.getFileInfo().replaceSource(inSourceInfo); if (photos != null) { _trackInfo.getPhotoList().removeCorrelatedPhotos(); @@ -701,11 +711,12 @@ public class App _lastSavePosition = _undoStack.size(); _trackInfo.getSelection().clearAll(); _track.load(loadedTrack); - _trackInfo.getFileInfo().setFile(inFilename); + inSourceInfo.populatePointObjects(_track, _track.getNumPoints()); + _trackInfo.getFileInfo().addSource(inSourceInfo); } UpdateMessageBroker.informSubscribers(); // Update status bar - UpdateMessageBroker.informSubscribers(I18nManager.getText("confirm.loadfile") + " '" + inFilename + "'"); + UpdateMessageBroker.informSubscribers(I18nManager.getText("confirm.loadfile") + " '" + inSourceInfo.getName() + "'"); // update menu _menuManager.informFileLoaded(); // load next file if there's a queue @@ -784,29 +795,7 @@ public class App DataPoint point = _trackInfo.getCurrentPoint(); if (photo != null && point != null) { - if (point.getPhoto() != null) - { - // point already has a photo, confirm cloning of new point - if (JOptionPane.showConfirmDialog(_frame, - I18nManager.getText("dialog.connectphoto.clonepoint"), - I18nManager.getText("dialog.connect.title"), - JOptionPane.OK_CANCEL_OPTION) == JOptionPane.OK_OPTION) - { - // Create undo, clone point and attach - int pointIndex = _trackInfo.getSelection().getCurrentPointIndex() + 1; - // insert new point after current one - point = point.clonePoint(); - UndoConnectPhotoWithClone undo = new UndoConnectPhotoWithClone( - point, photo.getFile().getName(), pointIndex); - _track.insertPoint(point, pointIndex); - photo.setDataPoint(point); - point.setPhoto(photo); - _undoStack.add(undo); - UpdateMessageBroker.informSubscribers(DataSubscriber.SELECTION_CHANGED); - UpdateMessageBroker.informSubscribers(I18nManager.getText("confirm.photo.connect")); - } - } - else + if (point.getPhoto() == null) { // point doesn't currently have a photo, so just connect it _undoStack.add(new UndoConnectPhoto(point, photo.getFile().getName())); diff --git a/tim/prune/ExternalTools.java b/tim/prune/ExternalTools.java index a2d3e56..31c0302 100644 --- a/tim/prune/ExternalTools.java +++ b/tim/prune/ExternalTools.java @@ -2,6 +2,8 @@ package tim.prune; import java.io.IOException; +import tim.prune.config.Config; + /** * Class to manage interfaces to external tools, like exiftool @@ -65,7 +67,6 @@ public abstract class ExternalTools */ private static boolean check(String inCommand) { - // System.out.println("Checking tool '" + inCommand + "'"); try { Runtime.getRuntime().exec(inCommand); diff --git a/tim/prune/FunctionLibrary.java b/tim/prune/FunctionLibrary.java index 1a2518c..0e642dd 100644 --- a/tim/prune/FunctionLibrary.java +++ b/tim/prune/FunctionLibrary.java @@ -1,24 +1,12 @@ package tim.prune; import tim.prune.correlate.PhotoCorrelator; -import tim.prune.function.AboutScreen; -import tim.prune.function.AddAltitudeOffset; -import tim.prune.function.AddTimeOffset; -import tim.prune.function.CheckVersionScreen; -import tim.prune.function.FindWaypoint; -import tim.prune.function.HelpScreen; -import tim.prune.function.RearrangeWaypointsFunction; -import tim.prune.function.SaveConfig; -import tim.prune.function.SetKmzImageSize; -import tim.prune.function.SetMapBgFunction; -import tim.prune.function.ShowKeysScreen; -import tim.prune.function.ShowThreeDFunction; +import tim.prune.function.*; import tim.prune.function.charts.Charter; import tim.prune.function.compress.CompressTrackFunction; import tim.prune.function.distance.DistanceFunction; import tim.prune.function.edit.PointNameEditor; import tim.prune.function.gpsies.GetGpsiesFunction; -import tim.prune.function.SetPathsFunction; import tim.prune.load.GpsLoader; import tim.prune.save.GpsSaver; import tim.prune.save.GpxExporter; @@ -38,18 +26,28 @@ public abstract class FunctionLibrary public static GenericFunction FUNCTION_SAVECONFIG = null; public static GenericFunction FUNCTION_EDIT_WAYPOINT_NAME = null; public static RearrangeWaypointsFunction FUNCTION_REARRANGE_WAYPOINTS = null; + public static GenericFunction FUNCTION_REARRANGE_PHOTOS = null; public static GenericFunction FUNCTION_COMPRESS = null; public static GenericFunction FUNCTION_ADD_TIME_OFFSET = null; public static GenericFunction FUNCTION_ADD_ALTITUDE_OFFSET = null; + public static GenericFunction FUNCTION_CONVERT_NAMES_TO_TIMES = null; + public static GenericFunction FUNCTION_PASTE_COORDINATES = null; public static GenericFunction FUNCTION_FIND_WAYPOINT = null; + public static GenericFunction FUNCTION_DUPLICATE_POINT = null; public static GenericFunction FUNCTION_CORRELATE_PHOTOS = null; + public static GenericFunction FUNCTION_ROTATE_PHOTO_LEFT = null; + public static GenericFunction FUNCTION_ROTATE_PHOTO_RIGHT = null; + public static GenericFunction FUNCTION_IGNORE_EXIF_THUMB = null; public static GenericFunction FUNCTION_CHARTS = null; public static GenericFunction FUNCTION_3D = null; public static GenericFunction FUNCTION_DISTANCES = null; + public static GenericFunction FUNCTION_FULL_RANGE_DETAILS = null; public static GenericFunction FUNCTION_GET_GPSIES = null; public static GenericFunction FUNCTION_SET_MAP_BG = null; public static GenericFunction FUNCTION_SET_PATHS = null; public static GenericFunction FUNCTION_SET_KMZ_IMAGE_SIZE = null; + public static GenericFunction FUNCTION_SET_COLOURS = null; + public static GenericFunction FUNCTION_SET_LANGUAGE = null; public static GenericFunction FUNCTION_HELP = null; public static GenericFunction FUNCTION_SHOW_KEYS = null; public static GenericFunction FUNCTION_ABOUT = null; @@ -70,18 +68,28 @@ public abstract class FunctionLibrary FUNCTION_SAVECONFIG = new SaveConfig(inApp); FUNCTION_EDIT_WAYPOINT_NAME = new PointNameEditor(inApp); FUNCTION_REARRANGE_WAYPOINTS = new RearrangeWaypointsFunction(inApp); + FUNCTION_REARRANGE_PHOTOS = new RearrangePhotosFunction(inApp); FUNCTION_COMPRESS = new CompressTrackFunction(inApp); FUNCTION_ADD_TIME_OFFSET = new AddTimeOffset(inApp); FUNCTION_ADD_ALTITUDE_OFFSET = new AddAltitudeOffset(inApp); + FUNCTION_CONVERT_NAMES_TO_TIMES = new ConvertNamesToTimes(inApp); + FUNCTION_PASTE_COORDINATES = new PasteCoordinates(inApp); FUNCTION_FIND_WAYPOINT = new FindWaypoint(inApp); + FUNCTION_DUPLICATE_POINT = new DuplicatePoint(inApp); FUNCTION_CORRELATE_PHOTOS = new PhotoCorrelator(inApp); + FUNCTION_ROTATE_PHOTO_LEFT = new RotatePhoto(inApp, false); + FUNCTION_ROTATE_PHOTO_RIGHT = new RotatePhoto(inApp, true); + FUNCTION_IGNORE_EXIF_THUMB = new IgnoreExifThumb(inApp); FUNCTION_CHARTS = new Charter(inApp); FUNCTION_3D = new ShowThreeDFunction(inApp); FUNCTION_DISTANCES = new DistanceFunction(inApp); + FUNCTION_FULL_RANGE_DETAILS = new FullRangeDetails(inApp); FUNCTION_GET_GPSIES = new GetGpsiesFunction(inApp); FUNCTION_SET_MAP_BG = new SetMapBgFunction(inApp); FUNCTION_SET_PATHS = new SetPathsFunction(inApp); FUNCTION_SET_KMZ_IMAGE_SIZE = new SetKmzImageSize(inApp); + FUNCTION_SET_COLOURS = new SetColours(inApp); + FUNCTION_SET_LANGUAGE = new SetLanguage(inApp); FUNCTION_HELP = new HelpScreen(inApp); FUNCTION_SHOW_KEYS = new ShowKeysScreen(inApp); FUNCTION_ABOUT = new AboutScreen(inApp); diff --git a/tim/prune/GpsPruner.java b/tim/prune/GpsPruner.java index 29f7eb5..7a172a4 100644 --- a/tim/prune/GpsPruner.java +++ b/tim/prune/GpsPruner.java @@ -12,6 +12,8 @@ import javax.swing.JSplitPane; import javax.swing.JToolBar; import javax.swing.WindowConstants; +import tim.prune.config.Config; +import tim.prune.config.ConfigException; import tim.prune.gui.DetailsDisplay; import tim.prune.gui.IconManager; import tim.prune.gui.MenuManager; @@ -22,16 +24,18 @@ import tim.prune.gui.Viewport; import tim.prune.gui.map.MapCanvas; /** - * Tool to visualize, edit, convert and prune GPS data + * Prune 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 and made available through the Gnu GPL + * This software is copyright activityworkshop.net 2006-2010 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 */ public class GpsPruner { /** Version number of application, used in about screen and for version check */ - public static final String VERSION_NUMBER = "8"; + public static final String VERSION_NUMBER = "9"; /** Build number, just used for about screen */ - public static final String BUILD_NUMBER = "155"; + public static final String BUILD_NUMBER = "176"; /** Static reference to App object */ private static App APP = null; @@ -104,7 +108,8 @@ public class GpsPruner catch (ConfigException ce) { System.err.println("Failed to load config file: " + configFilename); } - if (locale != null) { + boolean overrideLang = (locale != null); + if (overrideLang) { // Make sure Config holds chosen language Config.setConfigString(Config.KEY_LANGUAGE_CODE, localeCode); } @@ -117,9 +122,15 @@ public class GpsPruner } } I18nManager.init(locale); - if (langFilename != null) { + // Load the external language file, either from config file or from command line params + if (langFilename == null && !overrideLang) { + // If langfilename is blank on command line parameters then don't use setting from config + langFilename = Config.getConfigString(Config.KEY_LANGUAGE_FILE); + } + if (langFilename != null && !langFilename.equals("")) { try { I18nManager.addLanguageFile(langFilename); + Config.setConfigString(Config.KEY_LANGUAGE_FILE, langFilename); } catch (FileNotFoundException fnfe) { System.err.println("Failed to load language file: " + langFilename); diff --git a/tim/prune/I18nManager.java b/tim/prune/I18nManager.java index b9ce3cc..143d7c8 100644 --- a/tim/prune/I18nManager.java +++ b/tim/prune/I18nManager.java @@ -86,22 +86,19 @@ public abstract class I18nManager */ public static String getText(String inKey) { - String value = null; // look in external props file if available - if (ExternalPropsFile != null) + if (ExternalPropsFile != null && ExternalPropsFile.containsKey(inKey)) { - value = ExternalPropsFile.getProperty(inKey); - if (value != null && !value.equals("")) - return value; + return ExternalPropsFile.getProperty(inKey); } // look in extra texts if available if (LocalTexts != null) { try { - value = LocalTexts.getString(inKey); - if (value != null && !value.equals("")) - return value; + if (LocalTexts.containsKey(inKey)) { + return LocalTexts.getString(inKey); + } } catch (MissingResourceException mre) {} } @@ -110,9 +107,9 @@ public abstract class I18nManager { try { - value = EnglishTexts.getString(inKey); - if (value != null && !value.equals("")) - return value; + if (EnglishTexts.containsKey(inKey)) { + return EnglishTexts.getString(inKey); + } } catch (MissingResourceException mre) {} } diff --git a/tim/prune/config/ColourScheme.java b/tim/prune/config/ColourScheme.java new file mode 100644 index 0000000..5f3e0cd --- /dev/null +++ b/tim/prune/config/ColourScheme.java @@ -0,0 +1,89 @@ +package tim.prune.config; + +import java.awt.Color; + +/** + * Class to hold a colour scheme for Prune, including + * colours for background, points, selections and texts + */ +public class ColourScheme +{ + // Current colours + private Color[] _colours = new Color[NUM_COLOURS]; + + // Default colours + private static final Color[] DEFAULT_COLOURS = {Color.WHITE, Color.BLUE, Color.GREEN, + Color.BLACK, Color.RED, Color.ORANGE, Color.BLACK, Color.GRAY}; + + // Colour indices + public static final int IDX_BACKGROUND = 0; + public static final int IDX_POINT = 1; + public static final int IDX_SELECTION = 2; + public static final int IDX_TEXT = 3; + public static final int IDX_PRIMARY = 4; + public static final int IDX_SECONDARY = 5; + public static final int IDX_BORDERS = 6; + public static final int IDX_LINES = 7; + // Number of colours + private static final int NUM_COLOURS = 8; + + + /** + * Load the colour scheme from the given String + * @param inCodes comma-separated hex codes describing colours + */ + public void loadFromHex(String inCodes) + { + if (inCodes != null && inCodes.length() > 5) + { + String[] codes = inCodes.split(","); + final int numCodes = (codes.length > NUM_COLOURS ? NUM_COLOURS : codes.length); + for (int i=0; i= 0 && inIndex < NUM_COLOURS); + Color currColour = _colours[inIndex]; + return (currColour != null ? currColour : DEFAULT_COLOURS[inIndex]); + } + + /** + * @return default colour for given index + */ + public static Color getDefaultColour(int inIndex) + { + assert (inIndex >= 0 && inIndex < NUM_COLOURS); + return DEFAULT_COLOURS[inIndex]; + } + + /** + * Edit one of the colours to a new value + * @param inIndex index of colour + * @param inColour colour to set + */ + public void setColour(int inIndex, Color inColour) + { + assert (inIndex >= 0 && inIndex < NUM_COLOURS); + _colours[inIndex] = inColour; + } + + /** + * @return colour scheme as string of concatenated hex codes + */ + public String toString() + { + StringBuffer buff = new StringBuffer(); + for (int i=0; i= -180.0 && x <= 360.0); + } + catch (NumberFormatException nfe) {} // flag remains false + return justNum; + } /** * Create a String representation for debug diff --git a/tim/prune/data/DataPoint.java b/tim/prune/data/DataPoint.java index 966b560..7acd4f9 100644 --- a/tim/prune/data/DataPoint.java +++ b/tim/prune/data/DataPoint.java @@ -1,6 +1,6 @@ package tim.prune.data; -import tim.prune.Config; +import tim.prune.config.Config; /** * Class to represent a single data point in the series @@ -21,7 +21,7 @@ public class DataPoint private String _waypointName = null; private boolean _startOfSegment = false; private boolean _markedForDeletion = false; - + private int _modifyCount = 0; /** * Constructor @@ -62,7 +62,8 @@ public class DataPoint if (inField == null || inField == Field.WAYPT_NAME) { _waypointName = getFieldValue(Field.WAYPT_NAME); } - if (inField == null || inField == Field.NEW_SEGMENT) { + if (inField == null || inField == Field.NEW_SEGMENT) + { String segmentStr = getFieldValue(Field.NEW_SEGMENT); if (segmentStr != null) {segmentStr = segmentStr.trim();} _startOfSegment = (segmentStr != null && (segmentStr.equals("1") || segmentStr.toUpperCase().equals("Y"))); @@ -83,15 +84,15 @@ public class DataPoint Field[] fields = {Field.LATITUDE, Field.LONGITUDE, Field.ALTITUDE}; _fieldList = new FieldList(fields); _latitude = inLatitude; - _fieldValues[0] = inLatitude.output(Coordinate.FORMAT_DEG_MIN_SEC); + _fieldValues[0] = inLatitude.output(Coordinate.FORMAT_NONE); _longitude = inLongitude; - _fieldValues[1] = inLongitude.output(Coordinate.FORMAT_DEG_MIN_SEC); + _fieldValues[1] = inLongitude.output(Coordinate.FORMAT_NONE); if (inAltitude == null) { _altitude = Altitude.NONE; } else { _altitude = inAltitude; - _fieldValues[2] = "" + inAltitude.getValue(Altitude.Format.METRES); // units are ignored + _fieldValues[2] = "" + inAltitude.getValue(); } _timestamp = new Timestamp(null); } @@ -125,8 +126,9 @@ public class DataPoint * Set (or edit) the specified field value * @param inField Field to set * @param inValue value to set + * @param inUndo true if undo operation, false otherwise */ - public void setFieldValue(Field inField, String inValue) + public void setFieldValue(Field inField, String inValue, boolean inUndo) { // See if this data point already has this field int fieldIndex = _fieldList.getFieldIndex(inField); @@ -148,6 +150,15 @@ public class DataPoint } // Set field value in array _fieldValues[fieldIndex] = inValue; + // Increment edit count on all field edits except segment + if (inField != Field.NEW_SEGMENT) { + if (!inUndo) { + _modifyCount++; + } + else { + _modifyCount--; + } + } // Change Coordinate, Altitude, Name or Timestamp fields after edit if (_altitude != null && _altitude.getFormat() != Altitude.Format.NO_FORMAT) { // Altitude already present so reuse format @@ -159,10 +170,18 @@ public class DataPoint } } + /** + * @return field list for this point + */ + public FieldList getFieldList() + { + return _fieldList; + } + /** @param inFlag true for start of track segment */ public void setSegmentStart(boolean inFlag) { - setFieldValue(Field.NEW_SEGMENT, inFlag?"1":null); + setFieldValue(Field.NEW_SEGMENT, inFlag?"1":null, false); } /** @@ -229,6 +248,13 @@ public class DataPoint return (_waypointName != null && !_waypointName.equals("")); } + /** + * @return true if point has been modified since loading + */ + public boolean isModified() + { + return _modifyCount > 0; + } /** * Compare two DataPoint objects to see if they are duplicates @@ -287,7 +313,6 @@ public class DataPoint return _latitude.isValid() && _longitude.isValid(); } - /** * Interpolate a set of points between this one and the given one * @param inEndPoint end point of interpolation @@ -373,7 +398,7 @@ public class DataPoint */ public DataPoint clonePoint() { - // Copy all values + // Copy all values (note that photo not copied) String[] valuesCopy = new String[_fieldValues.length]; System.arraycopy(_fieldValues, 0, valuesCopy, 0, _fieldValues.length); // Make new object to hold cloned data diff --git a/tim/prune/data/FileInfo.java b/tim/prune/data/FileInfo.java index 41fd10c..1fd56b9 100644 --- a/tim/prune/data/FileInfo.java +++ b/tim/prune/data/FileInfo.java @@ -1,60 +1,94 @@ package tim.prune.data; +import java.util.ArrayList; + /** * Class to hold the information about the file(s) * from which the data was loaded from / saved to */ public class FileInfo { - private String _filename = null; - private int _numFiles = 0; + /** List of sources */ + private ArrayList _sources = new ArrayList(); /** - * Set the file information to the specified file - * @param inFilename filename of file + * Empty constructor */ - public void setFile(String inFilename) + public FileInfo() + {} + + /** + * Private constructor for creating clone + * @param inList list of sources + */ + private FileInfo(ArrayList inList) { - _filename = inFilename; - _numFiles = 1; + _sources = inList; } - /** - * Add a file to the data + * Add a data source to the list + * @param inInfo info object to add */ - public void addFile() + public void addSource(SourceInfo inInfo) { - _numFiles++; + _sources.add(inInfo); } - /** - * Undo a load file + * Replace the list of data sources with the given source + * @param inInfo new source */ - public void removeFile() + public void replaceSource(SourceInfo inInfo) { - _numFiles--; + _sources.clear(); + addSource(inInfo); } + /** + * remove the last source added + */ + public void removeSource() + { + _sources.remove(_sources.size()-1); + } /** * @return the number of files loaded */ public int getNumFiles() { - return _numFiles; + return _sources.size(); } /** - * @return The filename, if a single file + * @return The source name, if a single file */ public String getFilename() { - if (_numFiles == 1 && _filename != null) - return _filename; + if (getNumFiles() == 1) + return _sources.get(0).getName(); return ""; } + + /** + * @param inIndex index number + * @return source info object + */ + public SourceInfo getSource(int inIndex) { + return _sources.get(inIndex); + } + + /** + * Clone contents of file info + */ + @SuppressWarnings("unchecked") + public FileInfo clone() + { + // copy source list + ArrayList copy = (ArrayList) _sources.clone(); + return new FileInfo(copy); + } } diff --git a/tim/prune/data/Photo.java b/tim/prune/data/Photo.java index 4fdb612..9eacac2 100644 --- a/tim/prune/data/Photo.java +++ b/tim/prune/data/Photo.java @@ -22,6 +22,8 @@ public class Photo private Status _originalStatus = Status.NOT_CONNECTED; /** Current photo status */ private Status _currentStatus = Status.NOT_CONNECTED; + /** rotation flag (clockwise from 0 to 3) */ + private int _rotation = 0; // TODO: Need to store caption for image? // thumbnail for image (from exif) private byte[] _exifThumbnail = null; @@ -36,7 +38,6 @@ public class Photo CONNECTED }; - /** * Constructor * @param inFile File object for photo @@ -225,4 +226,32 @@ public class Photo return (inOther != null && inOther.getFile() != null && getFile() != null && inOther.getFile().equals(getFile())); } + + /** + * @param inRotation initial rotation value (from exif) + */ + public void setRotation(int inRotation) + { + if (inRotation >= 0 && inRotation <= 3) { + _rotation = inRotation; + } + } + + /** + * Rotate the image by 90 degrees + * @param inRight true to rotate right, false for left + */ + public void rotate(boolean inRight) + { + int dir = inRight?1:3; + _rotation = (_rotation + dir) % 4; + } + + /** + * @return rotation status + */ + public int getRotationDegrees() + { + return _rotation * 90; + } } diff --git a/tim/prune/data/Selection.java b/tim/prune/data/Selection.java index 6924d13..cbfb350 100644 --- a/tim/prune/data/Selection.java +++ b/tim/prune/data/Selection.java @@ -19,7 +19,7 @@ public class Selection private Altitude.Format _altitudeFormat = Altitude.Format.NO_FORMAT; private long _totalSeconds = 0L, _movingSeconds = 0L; private double _angDistance = -1.0, _angMovingDistance = -1.0; - private boolean _multipleSegments = false; + private int _numSegments = 0; /** @@ -65,7 +65,7 @@ public class Selection private void recalculate() { _altitudeFormat = Altitude.Format.NO_FORMAT; - _multipleSegments = false; + _numSegments = 0; if (_track.getNumPoints() > 0 && hasRangeSelected()) { _altitudeRange = new IntegerRange(); @@ -121,13 +121,15 @@ public class Selection double radians = DataPoint.calculateRadiansBetween(lastPoint, currPoint); _angDistance += radians; if (currPoint.getSegmentStart()) { - _multipleSegments = true; + _numSegments++; } else { _angMovingDistance += radians; } } lastPoint = currPoint; + // If it's a track point then there must be at least one segment + if (_numSegments == 0) {_numSegments = 1;} } } if (endTime != null) { @@ -232,11 +234,11 @@ public class Selection } /** - * @return true if track has multiple segments + * @return number of segments in selection */ - public boolean getHasMultipleSegments() + public int getNumSegments() { - return _multipleSegments; + return _numSegments; } /** @@ -252,7 +254,7 @@ public class Selection /** - * Deselect range + * Select range from start to end * @param inStartIndex index of start of range * @param inEndIndex index of end of range */ diff --git a/tim/prune/data/SourceInfo.java b/tim/prune/data/SourceInfo.java new file mode 100644 index 0000000..bbe8baa --- /dev/null +++ b/tim/prune/data/SourceInfo.java @@ -0,0 +1,111 @@ +package tim.prune.data; + +import java.io.File; + +/** + * Class to hold the source of the point data, + * including original file and file type, and + * also file offsets for source copying + */ +public class SourceInfo +{ + /** File type of source file */ + public enum FILE_TYPE {TEXT, GPX, KML, NMEA, GPSBABEL, GPSIES}; + + /** Source file */ + private File _sourceFile = null; + /** Name of source */ + private String _sourceName = null; + /** File type */ + private FILE_TYPE _fileType = null; + + /** Array of datapoints */ + private DataPoint[] _points = null; + + + /** + * Constructor + * @param inFile source file + * @param inType type of file + */ + public SourceInfo(File inFile, FILE_TYPE inType) + { + _sourceFile = inFile; + _sourceName = inFile.getName(); + _fileType = inType; + } + + /** + * Constructor + * @param inName name of source (without file) + * @param inType type of file + */ + public SourceInfo(String inName, FILE_TYPE inType) + { + _sourceFile = null; + _sourceName = inName; + _fileType = inType; + } + + /** + * @return source file + */ + public File getFile() + { + return _sourceFile; + } + + /** + * @return source name + */ + public String getName() + { + return _sourceName; + } + + /** + * @return file type of source + */ + public FILE_TYPE getFileType() + { + return _fileType; + } + + /** + * @return number of points from this source + */ + public int getNumPoints() + { + return _points.length; + } + + /** + * Take the points from the given track and store + * @param inTrack track object containing points + * @param inNumPoints number of points loaded + */ + public void populatePointObjects(Track inTrack, int inNumPoints) + { + if (inNumPoints > 0) + { + _points = new DataPoint[inNumPoints]; + int trackLen = inTrack.getNumPoints(); + System.arraycopy(inTrack.cloneContents(), trackLen-inNumPoints, _points, 0, inNumPoints); + // Note data copied twice here but still more efficient than looping + } + } + + /** + * Look for the given point in the array + * @param inPoint point to look for + * @return index, or -1 if not found + */ + public int getIndex(DataPoint inPoint) + { + int idx = -1; + for (int i=0; i<_points.length && (idx < 0); i++) { + if (_points[i] == inPoint) {idx = i;} + } + return idx; + } +} diff --git a/tim/prune/data/Track.java b/tim/prune/data/Track.java index 08168d1..d33886e 100644 --- a/tim/prune/data/Track.java +++ b/tim/prune/data/Track.java @@ -2,8 +2,8 @@ package tim.prune.data; import java.util.List; -import tim.prune.Config; import tim.prune.UpdateMessageBroker; +import tim.prune.config.Config; import tim.prune.function.edit.FieldEdit; import tim.prune.function.edit.FieldEditList; import tim.prune.gui.map.MapUtils; @@ -101,6 +101,23 @@ public class Track _scaled = false; } + /** + * Request that a rescale be done to recalculate derived values + */ + public void requestRescale() + { + _scaled = false; + } + + /** + * Extend the track's field list with the given additional fields + * @param inFieldList list of fields to be added + */ + public void extendFieldList(FieldList inFieldList) + { + _masterFieldList = _masterFieldList.merge(inFieldList); + } + ////////////////// Modification methods ////////////////////// @@ -331,8 +348,6 @@ public class Track return foundAlt; } - // TODO: Function to collect and sort photo points by time or photo filename - // TODO: Function to convert waypoint names into timestamps /** * Collect all waypoints to the start or end of the track @@ -1120,9 +1135,10 @@ public class Track * Edit the specified point * @param inPoint point to edit * @param inEditList list of edits to make + * @param inUndo true if undo operation, false otherwise * @return true if successful */ - public boolean editPoint(DataPoint inPoint, FieldEditList inEditList) + public boolean editPoint(DataPoint inPoint, FieldEditList inEditList, boolean inUndo) { if (inPoint != null && inEditList != null && inEditList.getNumEdits() > 0) { @@ -1134,7 +1150,7 @@ public class Track { FieldEdit edit = inEditList.getEdit(i); Field editField = edit.getField(); - inPoint.setFieldValue(editField, edit.getValue()); + inPoint.setFieldValue(editField, edit.getValue(), inUndo); // Check that master field list has this field already (maybe point name has been added) if (!_masterFieldList.contains(editField)) { _masterFieldList.extendList(editField); diff --git a/tim/prune/data/TrackInfo.java b/tim/prune/data/TrackInfo.java index eddea09..254de93 100644 --- a/tim/prune/data/TrackInfo.java +++ b/tim/prune/data/TrackInfo.java @@ -55,6 +55,14 @@ public class TrackInfo return _fileInfo; } + /** + * Replace the file info with a previously made clone + * @param inInfo cloned file info + */ + public void setFileInfo(FileInfo inInfo) { + _fileInfo = inInfo; + } + /** * @return the PhotoList object */ @@ -382,4 +390,19 @@ public class TrackInfo } } } + + /** + * Extend the current selection to end at the given point, eg by shift-clicking + * @param inPointNum index of end point + */ + public void extendSelection(int inPointNum) + { + // See whether to start selection from current range start or current point + int rangeStart = _selection.getStart(); + if (rangeStart < 0) {rangeStart = _selection.getCurrentPointIndex();} + selectPoint(inPointNum); + if (rangeStart < inPointNum) { + _selection.selectRange(rangeStart, inPointNum); + } + } } diff --git a/tim/prune/drew/jpeg/ExifReader.java b/tim/prune/drew/jpeg/ExifReader.java index 9e0fd59..0084b87 100644 --- a/tim/prune/drew/jpeg/ExifReader.java +++ b/tim/prune/drew/jpeg/ExifReader.java @@ -78,6 +78,8 @@ public class ExifReader private static final int TAG_THUMBNAIL_OFFSET = 0x0201; /** Thumbnail length */ private static final int TAG_THUMBNAIL_LENGTH = 0x0202; + /** Orientation of image */ + private static final int TAG_ORIENTATION = 0x0112; /** @@ -383,6 +385,11 @@ public class ExifReader _thumbnailLength = get16Bits(inTagValueOffset); extractThumbnail(inMetadata); } + else if (inTagType == TAG_ORIENTATION) { + if (inMetadata.getOrientationCode() < 1) { + inMetadata.setOrientationCode(get16Bits(inTagValueOffset)); + } + } } /** @@ -411,7 +418,7 @@ public class ExifReader if (inByteCount > 4) { // If it's bigger than 4 bytes, the dir entry contains an offset. - // dirEntryOffset must be passed, as some makernote implementations (e.g. FujiFilm) incorrectly use an + // dirEntryOffset must be passed, as some makers (e.g. FujiFilm) incorrectly use an // offset relative to the start of the makernote itself, not the TIFF segment. final int offsetVal = get32Bits(inDirEntryOffset + 8); if (offsetVal + inByteCount > _data.length) @@ -506,7 +513,8 @@ public class ExifReader private int get16Bits(int offset) { if (offset<0 || offset+2>_data.length) - throw new ArrayIndexOutOfBoundsException("attempt to read data outside of exif segment (index " + offset + " where max index is " + (_data.length - 1) + ")"); + throw new ArrayIndexOutOfBoundsException("attempt to read data outside of exif segment (index " + + offset + " where max index is " + (_data.length - 1) + ")"); if (_isMotorolaByteOrder) { // Motorola - MSB first diff --git a/tim/prune/drew/jpeg/JpegData.java b/tim/prune/drew/jpeg/JpegData.java index f8be61a..623fc34 100644 --- a/tim/prune/drew/jpeg/JpegData.java +++ b/tim/prune/drew/jpeg/JpegData.java @@ -5,7 +5,6 @@ import java.util.List; /** * Class to hold the GPS data extracted from a Jpeg including position and time - * All contents are in Rational format */ public class JpegData { @@ -19,6 +18,7 @@ public class JpegData private Rational[] _gpsTimestamp = null; private Rational[] _gpsDatestamp = null; private String _originalTimestamp = null; + private int _orientationCode = -1; private byte[] _thumbnail = null; private ArrayList _errors = null; @@ -141,6 +141,17 @@ public class JpegData _originalTimestamp = inStamp; } + /** + * Set the orientation code + * @param inCode code from exif (1 to 8) + */ + public void setOrientationCode(int inCode) + { + if (inCode >= 1 && inCode <= 8) { + _orientationCode = inCode; + } + } + /** @return latitude ref as char */ public char getLatitudeRef() { return _latitudeRef; } /** @return latitude as array of 3 Rationals */ @@ -157,6 +168,8 @@ public class JpegData public Rational[] getGpsTimestamp() { return _gpsTimestamp; } /** @return Gps datestamp as array of 3 Rationals */ public Rational[] getGpsDatestamp() { return _gpsDatestamp; } + /** @return orientation code (1 to 8) */ + public int getOrientationCode() { return _orientationCode; } /** @return original timestamp as string */ public String getOriginalTimestamp() { return _originalTimestamp; } @@ -172,6 +185,17 @@ public class JpegData return _thumbnail; } + /** + * @return rotation required to display photo properly (0 to 3) + */ + public int getRequiredRotation() + { + if (_orientationCode <= 2) { return 0; } // no rotation required + if (_orientationCode <= 4) { return 2; } // 180 degrees + if (_orientationCode <= 6) { return 1; } // 270 degrees, so need to rotate by 90 + return 3; // 90 degrees, so need to rotate by 270 + } + /** * @return true if data looks valid, ie has at least lat and long * (altitude and timestamp optional). diff --git a/tim/prune/function/AboutScreen.java b/tim/prune/function/AboutScreen.java index 2835d41..3c97a6d 100644 --- a/tim/prune/function/AboutScreen.java +++ b/tim/prune/function/AboutScreen.java @@ -91,7 +91,8 @@ public class AboutScreen extends GenericFunction descBuffer.append("

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

"); descBuffer.append("

").append(I18nManager.getText("dialog.about.languages")).append(" : ") .append("deutsch, english, espa\u00F1ol, fran\u00E7ais, italiano, polski, \u4e2d\u6587; (chinese)
" + - "schwiizerd\u00FC\u00FCtsch, portugu\u00EAs, bahasa indonesia, rom\u00E2n\u0103").append("

"); + "schwiizerd\u00FC\u00FCtsch, \u65E5\u672C\u8A9E (japanese), t\u00FCrk\u00E7e, portugu\u00EAs, " + + "bahasa indonesia, rom\u00E2n\u0103").append("

"); descBuffer.append("

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

"); JEditorPane descPane = new JEditorPane("text/html", descBuffer.toString()); descPane.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3)); @@ -177,7 +178,7 @@ public class AboutScreen extends GenericFunction new JLabel("Ramon, Miguel, In\u00E9s, Piotr, Petrovsk, Josatoc, Weehal,"), 1, 3); addToGridBagPanel(creditsPanel, gridBag, constraints, - new JLabel(" theYinYeti, Rothermographer, Sam, Rudolph"), + new JLabel(" theYinYeti, Rothermographer, Sam, Rudolph, nazotoko, katpatuka"), 1, 4); addToGridBagPanel(creditsPanel, gridBag, constraints, new JLabel(I18nManager.getText("dialog.about.credits.translations") + " : "), @@ -189,13 +190,13 @@ public class AboutScreen extends GenericFunction new JLabel(I18nManager.getText("dialog.about.credits.devtools") + " : "), 0, 6); addToGridBagPanel(creditsPanel, gridBag, constraints, - new JLabel("Mandriva Linux, Sun Java, Eclipse, Svn, Gimp"), + new JLabel("Debian Linux, Sun Java, Eclipse, Svn, Gimp, Inkscape"), 1, 6); addToGridBagPanel(creditsPanel, gridBag, constraints, new JLabel(I18nManager.getText("dialog.about.credits.othertools") + " : "), 0, 7); addToGridBagPanel(creditsPanel, gridBag, constraints, - new JLabel("Kate, Povray, Exiftool, Inkscape, Google Earth, Gpsbabel, Gnuplot"), + new JLabel("Openstreetmap, Povray, Exiftool, Google Earth, Gpsbabel, Gnuplot"), 1, 7); addToGridBagPanel(creditsPanel, gridBag, constraints, new JLabel(I18nManager.getText("dialog.about.credits.thanks") + " : "), @@ -242,7 +243,7 @@ public class AboutScreen extends GenericFunction } /** - * Helper function to reduce complexity of gui making code + * Helper function to reduce complexity of gui-making code * when adding labels to a GridBagLayout * @param inPanel panel to add to * @param inLayout GridBagLayout object @@ -251,8 +252,8 @@ public class AboutScreen extends GenericFunction * @param inX grid x * @param inY grid y */ - private static void addToGridBagPanel(JPanel inPanel, GridBagLayout inLayout, GridBagConstraints inConstraints, - JLabel inLabel, int inX, int inY) + private static void addToGridBagPanel(JPanel inPanel, GridBagLayout inLayout, + GridBagConstraints inConstraints, JLabel inLabel, int inX, int inY) { // set x and y in constraints inConstraints.gridx = inX; diff --git a/tim/prune/function/AddAltitudeOffset.java b/tim/prune/function/AddAltitudeOffset.java index 14adb83..1032fcf 100644 --- a/tim/prune/function/AddAltitudeOffset.java +++ b/tim/prune/function/AddAltitudeOffset.java @@ -1,7 +1,6 @@ package tim.prune.function; import java.awt.BorderLayout; -import java.awt.Component; import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; @@ -81,7 +80,7 @@ public class AddAltitudeOffset extends GenericFunction * Create dialog components * @return Panel containing all gui elements in dialog */ - private Component makeDialogComponents() + private JPanel makeDialogComponents() { JPanel dialogPanel = new JPanel(); dialogPanel.setLayout(new BorderLayout()); diff --git a/tim/prune/function/ConvertNamesToTimes.java b/tim/prune/function/ConvertNamesToTimes.java new file mode 100644 index 0000000..c0286ab --- /dev/null +++ b/tim/prune/function/ConvertNamesToTimes.java @@ -0,0 +1,73 @@ +package tim.prune.function; + +import tim.prune.App; +import tim.prune.DataSubscriber; +import tim.prune.GenericFunction; +import tim.prune.I18nManager; +import tim.prune.UpdateMessageBroker; +import tim.prune.data.DataPoint; +import tim.prune.data.Field; +import tim.prune.data.Timestamp; +import tim.prune.data.Track; +import tim.prune.undo.UndoConvertNamesToTimes; + +/** + * Class to provide the function to convert waypoint names to timestamps + */ +public class ConvertNamesToTimes extends GenericFunction +{ + /** + * Constructor + * @param inApp application object for callback + */ + public ConvertNamesToTimes(App inApp) + { + super(inApp); + } + + /** Get the name key */ + public String getNameKey() { + return "function.convertnamestotimes"; + } + + /** + * Begin the function + */ + public void begin() + { + int selStart = _app.getTrackInfo().getSelection().getStart(); + int selEnd = _app.getTrackInfo().getSelection().getEnd(); + final Track track = _app.getTrackInfo().getTrack(); + if (!track.hasData(Field.WAYPT_NAME, selStart, selEnd)) + { + _app.showErrorMessage(getNameKey(), "error.convertnamestotimes.nonames"); + return; + } + UndoConvertNamesToTimes undo = new UndoConvertNamesToTimes(_app.getTrackInfo()); + int numConverted = 0; + // Loop over all points in selection + for (int i=selStart; i<=selEnd; i++) + { + DataPoint point = track.getPoint(i); + if (point.isWaypoint()) + { + Timestamp tstamp = new Timestamp(point.getWaypointName()); + if (tstamp.isValid()) { + // timestamp could be parsed! + point.setFieldValue(Field.TIMESTAMP, point.getWaypointName(), false); + // set waypoint name to nothing (track point) + point.setFieldValue(Field.WAYPT_NAME, null, false); + // increment counter + numConverted++; + } + } + } + if (numConverted > 0) + { + _app.getTrackInfo().getTrack().requestRescale(); + UpdateMessageBroker.informSubscribers(DataSubscriber.DATA_EDITED); + _app.completeFunction(undo, I18nManager.getText("confirm.convertnamestotimes")); + } + } + +} diff --git a/tim/prune/function/DuplicatePoint.java b/tim/prune/function/DuplicatePoint.java new file mode 100644 index 0000000..341066a --- /dev/null +++ b/tim/prune/function/DuplicatePoint.java @@ -0,0 +1,38 @@ +package tim.prune.function; + +import tim.prune.App; +import tim.prune.GenericFunction; +import tim.prune.data.DataPoint; + +/** + * Class to provide the function to duplicate + * the current point and add to the end of the track + */ +public class DuplicatePoint extends GenericFunction +{ + /** + * Constructor + * @param inApp application object for callback + */ + public DuplicatePoint(App inApp) + { + super(inApp); + } + + /** Get the name key */ + public String getNameKey() { + return "function.duplicatepoint"; + } + + /** + * Begin the function + */ + public void begin() + { + DataPoint point = _app.getTrackInfo().getCurrentPoint(); + if (point != null) { + // Pass information back to App to complete function + _app.createPoint(point.clonePoint()); + } + } +} diff --git a/tim/prune/function/FullRangeDetails.java b/tim/prune/function/FullRangeDetails.java new file mode 100644 index 0000000..ed86ef9 --- /dev/null +++ b/tim/prune/function/FullRangeDetails.java @@ -0,0 +1,219 @@ +package tim.prune.function; + +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.FlowLayout; +import java.awt.GridLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.text.NumberFormat; + +import javax.swing.BorderFactory; +import javax.swing.JButton; +import javax.swing.JDialog; +import javax.swing.JLabel; +import javax.swing.JPanel; + +import tim.prune.App; +import tim.prune.GenericFunction; +import tim.prune.I18nManager; +import tim.prune.config.Config; +import tim.prune.data.Altitude; +import tim.prune.data.Distance; +import tim.prune.data.Selection; +import tim.prune.gui.DisplayUtils; + +/** + * Class to show the full range details in a separate popup + */ +public class FullRangeDetails extends GenericFunction +{ + /** Dialog */ + private JDialog _dialog = null; + /** Label for number of segments */ + private JLabel _numSegsLabel = null; + /** Label for pace */ + private JLabel _paceLabel = null; + /** Label for gradient */ + private JLabel _gradientLabel = null; + /** Moving distance, speed */ + private JLabel _movingDistanceLabel = null, _aveMovingSpeedLabel = null; + /** Number formatter for one decimal place */ + private static final NumberFormat FORMAT_ONE_DP = NumberFormat.getNumberInstance(); + /** Flexible number formatter for different decimal places */ + private NumberFormat _distanceFormatter = NumberFormat.getInstance(); + + /** + * Constructor + * @param inApp App object + */ + public FullRangeDetails(App inApp) + { + super(inApp); + FORMAT_ONE_DP.setMaximumFractionDigits(1); + FORMAT_ONE_DP.setMinimumFractionDigits(1); + } + + /** Get the name key */ + public String getNameKey() { + return "function.fullrangedetails"; + } + + /** + * Begin the function + */ + public void begin() + { + if (_dialog == null) + { + _dialog = new JDialog(_parentFrame, I18nManager.getText(getNameKey()), true); + _dialog.setLocationRelativeTo(_parentFrame); + _dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); + _dialog.getContentPane().add(makeDialogComponents()); + _dialog.pack(); + } + updateDetails(); + _dialog.setVisible(true); + } + + /** + * Create dialog components + * @return Panel containing all gui elements in dialog + */ + private Component makeDialogComponents() + { + JPanel dialogPanel = new JPanel(); + dialogPanel.setLayout(new BorderLayout(5, 5)); + // Label at top + JLabel topLabel = new JLabel(I18nManager.getText("dialog.fullrangedetails.intro")); + topLabel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); + dialogPanel.add(topLabel, BorderLayout.NORTH); + + // Details panel in middle + JPanel midPanel = new JPanel(); + midPanel.setLayout(new GridLayout(0, 2, 6, 2)); + midPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 15)); + // Number of segments + JLabel segLabel = new JLabel(I18nManager.getText("details.range.numsegments") + ": "); + segLabel.setHorizontalAlignment(JLabel.RIGHT); + midPanel.add(segLabel); + _numSegsLabel = new JLabel("100"); + midPanel.add(_numSegsLabel); + // Pace + JLabel paceLabel = new JLabel(I18nManager.getText("details.range.pace") + ": "); + paceLabel.setHorizontalAlignment(JLabel.RIGHT); + midPanel.add(paceLabel); + _paceLabel = new JLabel("8 min/km"); + midPanel.add(_paceLabel); + // Gradient + JLabel gradientLabel = new JLabel(I18nManager.getText("details.range.gradient") + ": "); + gradientLabel.setHorizontalAlignment(JLabel.RIGHT); + midPanel.add(gradientLabel); + _gradientLabel = new JLabel("10 %"); + midPanel.add(_gradientLabel); + // Moving distance + JLabel movingDistLabel = new JLabel(I18nManager.getText("fieldname.movingdistance") + ": "); + movingDistLabel.setHorizontalAlignment(JLabel.RIGHT); + midPanel.add(movingDistLabel); + _movingDistanceLabel = new JLabel("5 km"); + midPanel.add(_movingDistanceLabel); + // Moving speed + JLabel movingSpeedLabel = new JLabel(I18nManager.getText("details.range.avemovingspeed") + ": "); + movingSpeedLabel.setHorizontalAlignment(JLabel.RIGHT); + midPanel.add(movingSpeedLabel); + _aveMovingSpeedLabel = new JLabel("5 km/h"); + midPanel.add(_aveMovingSpeedLabel); + + dialogPanel.add(midPanel, BorderLayout.CENTER); + // button panel at bottom + JPanel buttonPanel = new JPanel(); + buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT)); + JButton closeButton = new JButton(I18nManager.getText("button.close")); + closeButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) + { + _dialog.dispose(); + } + }); + buttonPanel.add(closeButton); + dialogPanel.add(buttonPanel, BorderLayout.SOUTH); + return dialogPanel; + } + + + /** + * Update the labels with the current details + */ + private void updateDetails() + { + Selection selection = _app.getTrackInfo().getSelection(); + // Number of segments + _numSegsLabel.setText("" + selection.getNumSegments()); + // Pace value + if (selection.getNumSeconds() > 0) + { + boolean useMetric = Config.getConfigBoolean(Config.KEY_METRIC_UNITS); + Distance.Units distUnits = useMetric?Distance.Units.KILOMETRES:Distance.Units.MILES; + String distUnitsStr = I18nManager.getText(useMetric?"units.kilometres.short":"units.miles.short"); + _paceLabel.setText(DisplayUtils.buildDurationString( + (long) (selection.getNumSeconds()/selection.getDistance(distUnits))) + + " / " + distUnitsStr); + } + else { + _paceLabel.setText(""); + } + // Gradient + Altitude firstAlt = _app.getTrackInfo().getTrack().getPoint(selection.getStart()).getAltitude(); + Altitude lastAlt = _app.getTrackInfo().getTrack().getPoint(selection.getEnd()).getAltitude(); + double metreDist = selection.getDistance(Distance.Units.METRES); + if (firstAlt.isValid() && lastAlt.isValid() && metreDist > 0.0) + { + // got an altitude and range + int altDiffInMetres = lastAlt.getValue(Altitude.Format.METRES) - firstAlt.getValue(Altitude.Format.METRES); + double gradient = altDiffInMetres * 100.0 / metreDist; + _gradientLabel.setText(FORMAT_ONE_DP.format(gradient) + " %"); + } + else { + // no altitude given + _gradientLabel.setText(""); + } + + // Show moving distance and average even when number of segments is 1 + final boolean isMetric = Config.getConfigBoolean(Config.KEY_METRIC_UNITS); + final Distance.Units distUnits = isMetric?Distance.Units.KILOMETRES:Distance.Units.MILES; + final String distUnitsStr = I18nManager.getText(isMetric?"units.kilometres.short":"units.miles.short"); + final String speedUnitsStr = I18nManager.getText(isMetric?"units.kmh":"units.mph"); + // Moving distance + _movingDistanceLabel.setText(roundedNumber(selection.getMovingDistance(distUnits)) + " " + distUnitsStr); + // Moving average speed + long numSecs = selection.getMovingSeconds(); + if (numSecs > 0) { + _aveMovingSpeedLabel.setText(roundedNumber(selection.getMovingDistance(distUnits)/numSecs*3600.0) + + " " + speedUnitsStr); + } + else { + _aveMovingSpeedLabel.setText(""); + } + } + + /** + * Format a number to a sensible precision + * @param inDist distance + * @return formatted String + */ + private String roundedNumber(double inDist) + { + // Set precision of formatter + int numDigits = 0; + if (inDist < 1.0) + numDigits = 3; + else if (inDist < 10.0) + numDigits = 2; + else if (inDist < 100.0) + numDigits = 1; + // set formatter + _distanceFormatter.setMaximumFractionDigits(numDigits); + _distanceFormatter.setMinimumFractionDigits(numDigits); + return _distanceFormatter.format(inDist); + } +} diff --git a/tim/prune/function/IgnoreExifThumb.java b/tim/prune/function/IgnoreExifThumb.java new file mode 100644 index 0000000..8b292e5 --- /dev/null +++ b/tim/prune/function/IgnoreExifThumb.java @@ -0,0 +1,42 @@ +package tim.prune.function; + +import tim.prune.App; +import tim.prune.DataSubscriber; +import tim.prune.GenericFunction; +import tim.prune.UpdateMessageBroker; +import tim.prune.data.Photo; + +/** + * Class to provide the function to disable the exif thumbnail + * for the current photo so that the full image must be loaded + */ +public class IgnoreExifThumb extends GenericFunction +{ + /** + * Constructor + * @param inApp application object for callback + */ + public IgnoreExifThumb(App inApp) + { + super(inApp); + } + + /** Get the name key */ + public String getNameKey() { + return "function.ignoreexifthumb"; + } + + /** + * Begin the function + */ + public void begin() + { + Photo photo = _app.getTrackInfo().getCurrentPhoto(); + if (photo != null) + { + // no undo necessary, no data being edited + photo.setExifThumbnail(null); + UpdateMessageBroker.informSubscribers(DataSubscriber.PHOTOS_MODIFIED); + } + } +} diff --git a/tim/prune/function/PasteCoordinates.java b/tim/prune/function/PasteCoordinates.java new file mode 100644 index 0000000..1106001 --- /dev/null +++ b/tim/prune/function/PasteCoordinates.java @@ -0,0 +1,269 @@ +package tim.prune.function; + +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.FlowLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.awt.event.MouseAdapter; + +import javax.swing.BorderFactory; +import javax.swing.JButton; +import javax.swing.JComboBox; +import javax.swing.JDialog; +import javax.swing.JLabel; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JTextField; +import javax.swing.SwingConstants; + +import tim.prune.App; +import tim.prune.GenericFunction; +import tim.prune.I18nManager; +import tim.prune.config.Config; +import tim.prune.data.Altitude; +import tim.prune.data.DataPoint; +import tim.prune.data.Field; +import tim.prune.data.Latitude; +import tim.prune.data.Longitude; +import tim.prune.gui.GuiGridLayout; + +/** + * Class to provide the function to paste coordinates + * - see wikipedia, opencaching.de, waymarking.com etc + */ +public class PasteCoordinates extends GenericFunction +{ + private JDialog _dialog = null; + private JTextField _nameField = null; + private JTextField _coordField = null; + private JButton _okButton = null; + private JComboBox _altUnitsDropDown; + + + /** + * Constructor + * @param inApp application object for callback + */ + public PasteCoordinates(App inApp) + { + super(inApp); + } + + /** Get the name key */ + public String getNameKey() { + return "function.pastecoordinates"; + } + + /** + * Begin the function + */ + public void begin() + { + // Make dialog window + if (_dialog == null) + { + _dialog = new JDialog(_parentFrame, I18nManager.getText(getNameKey()), true); + _dialog.setLocationRelativeTo(_parentFrame); + _dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); + _dialog.getContentPane().add(makeDialogComponents()); + _dialog.pack(); + } + // MAYBE: Paste clipboard into the edit field + _coordField.setText(""); + _nameField.setText(""); + boolean metric = Config.getConfigBoolean(Config.KEY_METRIC_UNITS); + _altUnitsDropDown.setSelectedIndex(metric?0:1); + enableOK(); + _dialog.setVisible(true); + } + + + /** + * Create dialog components + * @return Panel containing all gui elements in dialog + */ + private Component makeDialogComponents() + { + JPanel dialogPanel = new JPanel(); + dialogPanel.setLayout(new BorderLayout(0, 10)); + dialogPanel.add(new JLabel(I18nManager.getText("dialog.pastecoordinates.desc")), BorderLayout.NORTH); + JPanel mainPanel = new JPanel(); + GuiGridLayout grid = new GuiGridLayout(mainPanel); + _coordField = new JTextField("", 25); + // Listeners to enable/disable ok button + KeyAdapter keyListener = new KeyAdapter() { + /** Key released */ + public void keyReleased(KeyEvent arg0) { + enableOK(); + } + }; + MouseAdapter mouseListener = new MouseAdapter() { + public void mouseReleased(java.awt.event.MouseEvent arg0) { + enableOK(); + }; + }; + _coordField.addKeyListener(keyListener); + _coordField.addMouseListener(mouseListener); + JLabel coordLabel = new JLabel(I18nManager.getText("dialog.pastecoordinates.coords")); + coordLabel.setHorizontalAlignment(SwingConstants.RIGHT); + grid.add(coordLabel); + grid.add(_coordField); + // Altitude format (if any) + JLabel formatLabel = new JLabel(I18nManager.getText("dialog.openoptions.altitudeunits")); + formatLabel.setHorizontalAlignment(SwingConstants.RIGHT); + grid.add(formatLabel); + final String[] altunits = {I18nManager.getText("units.metres"), I18nManager.getText("units.feet")}; + _altUnitsDropDown = new JComboBox(altunits); + grid.add(_altUnitsDropDown); + // Waypoint name + JLabel nameLabel = new JLabel(I18nManager.getText("dialog.pointnameedit.name")); + nameLabel.setHorizontalAlignment(SwingConstants.RIGHT); + grid.add(nameLabel); + _nameField = new JTextField("", 12); + grid.add(_nameField); + dialogPanel.add(mainPanel, BorderLayout.CENTER); + // button panel at bottom + JPanel buttonPanel = new JPanel(); + buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT)); + _okButton = new JButton(I18nManager.getText("button.ok")); + ActionListener okListener = new ActionListener() { + public void actionPerformed(ActionEvent e) + { + finish(); + } + }; + _okButton.addActionListener(okListener); + _okButton.setEnabled(false); + _coordField.addActionListener(okListener); + _nameField.addActionListener(okListener); + buttonPanel.add(_okButton); + JButton cancelButton = new JButton(I18nManager.getText("button.cancel")); + cancelButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) + { + _dialog.dispose(); + } + }); + buttonPanel.add(cancelButton); + dialogPanel.add(buttonPanel, BorderLayout.SOUTH); + dialogPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 15)); + return dialogPanel; + } + + /** + * Enable or disable the OK button based on the contents of the text field + */ + private void enableOK() + { + String text = _coordField.getText(); + _okButton.setEnabled(text != null && text.length() > 10 + && (text.indexOf(' ') >= 0 || text.indexOf(',') >= 0)); + } + + /** + * Finish the dialog when OK pressed + */ + private void finish() + { + DataPoint point = null; + // Try to split using commas + String[] items = _coordField.getText().split(","); + if (items.length == 2) { + point = parseValues(items[0].trim(), items[1].trim(), null); + } + else if (items.length == 3) { + point = parseValues(items[0].trim(), items[1].trim(), items[2].trim()); + } + else { + // Splitting with commas didn't work, so try spaces + items = _coordField.getText().split(" "); + if (items.length == 2) { + point = parseValues(items[0], items[1], null); + } + else if (items.length == 3 && items[1].length() == 1) { + point = parseValues(items[0], items[2], null); + } + else if (items.length == 4) { + point = parseValues(items[0] + " " + items[1], + items[2] + " " + items[3], null); + } + else if (items.length == 6) { + point = parseValues(items[0] + " " + items[1] + " " + items[2], + items[3] + " " + items[4] + " " + items[5], null); + } + else if (items.length == 8) { + point = parseValues(items[0] + " " + items[1] + " " + items[2] + " " + items[3], + items[4] + " " + items[5] + " " + items[6] + " " + items[7], null); + } + } + + if (point == null) { + JOptionPane.showMessageDialog(_parentFrame, + I18nManager.getText("dialog.pastecoordinates.nothingfound"), + I18nManager.getText(getNameKey()), JOptionPane.ERROR_MESSAGE); + } + else { + // See if name was entered + String name = _nameField.getText(); + if (name != null && name.length() > 0) { + point.setFieldValue(Field.WAYPT_NAME, name, false); + } + // Pass information back to App to complete function + _app.createPoint(point); + _dialog.dispose(); + } + } + + + /** + * Try to parse the three given Strings into lat, lon and alt + * @param inValue1 first value (either lat/lon) + * @param inValue2 second value (either lon/lat) + * @param inValue3 altitude value or null if absent + * @return DataPoint object or null if failed + */ + private DataPoint parseValues(String inValue1, String inValue2, String inValue3) + { + // Check for parseable altitude + Altitude alt = null; + if (inValue3 != null) + { + // Look at altitude units dropdown + final Altitude.Format altFormat = (_altUnitsDropDown.getSelectedIndex()==0? + Altitude.Format.METRES:Altitude.Format.FEET); + alt = new Altitude(inValue3, altFormat); + if (!alt.isValid()) {alt = null;} + } + // See if value1 can be lat and value2 lon: + Latitude coord1 = new Latitude(inValue1); + Longitude coord2 = new Longitude(inValue2); + if (coord1.isValid() && !coord1.getCardinalGuessed() + && coord2.isValid() && !coord2.getCardinalGuessed()) + { + return new DataPoint(coord1, coord2, alt); + } + // Now see if lat/lon are reversed + Longitude coord3 = new Longitude(inValue1); + Latitude coord4 = new Latitude(inValue2); + if (coord3.isValid() && !coord3.getCardinalGuessed() + && coord4.isValid() && !coord4.getCardinalGuessed()) + { + // reversed order + return new DataPoint(coord4, coord3, alt); + } + // Didn't work without guessing cardinals, so accept latitude, longitude order (if valid) + if (coord1.isValid() && coord2.isValid()) { + return new DataPoint(coord1, coord2, alt); + } + // Or accept other order (if valid) + if (coord3.isValid() && coord4.isValid()) { + // reversed order + return new DataPoint(coord4, coord3, alt); + } + // Couldn't be parsed either way + return null; + } +} diff --git a/tim/prune/function/RearrangePhotosFunction.java b/tim/prune/function/RearrangePhotosFunction.java new file mode 100644 index 0000000..7a408c0 --- /dev/null +++ b/tim/prune/function/RearrangePhotosFunction.java @@ -0,0 +1,220 @@ +package tim.prune.function; + +import java.awt.BorderLayout; +import java.awt.FlowLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.Arrays; +import java.util.Comparator; + +import javax.swing.BoxLayout; +import javax.swing.ButtonGroup; +import javax.swing.JButton; +import javax.swing.JDialog; +import javax.swing.JLabel; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JRadioButton; + +import tim.prune.App; +import tim.prune.GenericFunction; +import tim.prune.I18nManager; +import tim.prune.data.DataPoint; +import tim.prune.data.Track; +import tim.prune.undo.UndoRearrangePhotos; + +/** + * Class to provide the function for rearranging photo points + */ +public class RearrangePhotosFunction extends GenericFunction +{ + /** Function dialog */ + private JDialog _dialog = null; + /** Radio buttons for start/end */ + private JRadioButton[] _positionRadios = null; + /** Radio buttons for sorting */ + private JRadioButton[] _sortRadios = null; + + + /** + * Constructor + * @param inApp app object + */ + public RearrangePhotosFunction(App inApp) + { + super(inApp); + } + + /** Begin the rearrange */ + public void begin() + { + // Make dialog window + if (_dialog == null) + { + _dialog = new JDialog(_parentFrame, I18nManager.getText(getNameKey()), true); + _dialog.setLocationRelativeTo(_parentFrame); + _dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); + _dialog.getContentPane().add(makeDialogComponents()); + _dialog.pack(); + } + // Reset dialog and show + _dialog.setVisible(true); + } + + /** Get the name key (not needed) */ + public String getNameKey() { + return "function.rearrangephotos"; + } + + + /** + * Create dialog components + * @return Panel containing all gui elements in dialog + */ + private JPanel makeDialogComponents() + { + JPanel dialogPanel = new JPanel(); + dialogPanel.setLayout(new BorderLayout()); + dialogPanel.add(new JLabel(I18nManager.getText("dialog.rearrangephotos.desc")), BorderLayout.NORTH); + // Radios for position (start / end) + _positionRadios = new JRadioButton[2]; + final String[] posNames = {"tostart", "toend"}; + ButtonGroup posGroup = new ButtonGroup(); + JPanel posPanel = new JPanel(); + posPanel.setLayout(new FlowLayout(FlowLayout.CENTER)); + for (int i=0; i<2; i++) + { + _positionRadios[i] = new JRadioButton(I18nManager.getText("dialog.rearrangephotos." + posNames[i])); + posGroup.add(_positionRadios[i]); + posPanel.add(_positionRadios[i]); + } + _positionRadios[0].setSelected(true); + // Radios for sort (none / filename / time) + _sortRadios = new JRadioButton[3]; + final String[] sortNames = {"nosort", "sortbyfilename", "sortbytime"}; + ButtonGroup sortGroup = new ButtonGroup(); + JPanel sortPanel = new JPanel(); + sortPanel.setLayout(new FlowLayout(FlowLayout.CENTER)); + for (int i=0; i<3; i++) + { + _sortRadios[i] = new JRadioButton(I18nManager.getText("dialog.rearrangephotos." + sortNames[i])); + sortGroup.add(_sortRadios[i]); + sortPanel.add(_sortRadios[i]); + } + _sortRadios[0].setSelected(true); + // add to middle of dialog + JPanel centrePanel = new JPanel(); + centrePanel.setLayout(new BoxLayout(centrePanel, BoxLayout.Y_AXIS)); + centrePanel.add(posPanel); + centrePanel.add(sortPanel); + dialogPanel.add(centrePanel, BorderLayout.CENTER); + // button panel at bottom + JPanel buttonPanel = new JPanel(); + buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT)); + JButton okButton = new JButton(I18nManager.getText("button.ok")); + okButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + finish(); + _dialog.dispose(); + } + }); + buttonPanel.add(okButton); + JButton cancelButton = new JButton(I18nManager.getText("button.cancel")); + cancelButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + _dialog.dispose(); + } + }); + buttonPanel.add(cancelButton); + dialogPanel.add(buttonPanel, BorderLayout.SOUTH); + return dialogPanel; + } + + /** + * Perform the rearrange + */ + private void finish() + { + Track track = _app.getTrackInfo().getTrack(); + UndoRearrangePhotos undo = new UndoRearrangePhotos(track); + // Loop through track collecting non-photo points and photo points + final int numPoints = track.getNumPoints(); + DataPoint[] nonPhotos = new DataPoint[numPoints]; + DataPoint[] photos = new DataPoint[numPoints]; + int numNonPhotos = 0; + int numPhotos = 0; + for (int i=0; i 1) { + sortPhotos(photos, _sortRadios[1].isSelected()); + } + // Put the non-photo points and photo points together + DataPoint[] neworder = new DataPoint[numPoints]; + if (_positionRadios[0].isSelected()) { + // photos at front + System.arraycopy(photos, 0, neworder, 0, numPhotos); + System.arraycopy(nonPhotos, 0, neworder, numPhotos, numNonPhotos); + } + else { + // photos at end + System.arraycopy(nonPhotos, 0, neworder, 0, numNonPhotos); + System.arraycopy(photos, 0, neworder, numNonPhotos, numPhotos); + } + // Give track the new point order + if (track.replaceContents(neworder)) + { + _app.getTrackInfo().getSelection().clearAll(); + _app.completeFunction(undo, I18nManager.getText("confirm.rearrangephotos")); + // Note: subscribers are informed up to three times now + } + else + { + JOptionPane.showMessageDialog(_parentFrame, I18nManager.getText("error.rearrange.noop"), + I18nManager.getText("error.function.noop.title"), JOptionPane.WARNING_MESSAGE); + } + } + + /** + * Sort the given photo list either by filename or by time + * @param inPhotos array of DataPoint objects to sort + * @param inSortByFile true to sort by filename, false to sort by timestamp + * @return sorted array + */ + private static void sortPhotos(DataPoint[] inPhotos, boolean inSortByFile) + { + Comparator comparator = null; + 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; + return inP1.getPhoto().getFile().compareTo(inP2.getPhoto().getFile()); + } + }; + } + else { + // sort by photo timestamp + comparator = new Comparator() { + public int compare(DataPoint inP1, DataPoint inP2) { + if (inP2 == null) return -1; // all nulls at end + if (inP1 == null) return 1; + long secDiff = inP1.getPhoto().getTimestamp().getSecondsSince(inP2.getPhoto().getTimestamp()); + return (secDiff<0?-1:(secDiff==0?0:1)); + } + }; + } + Arrays.sort(inPhotos, comparator); + } +} diff --git a/tim/prune/function/RotatePhoto.java b/tim/prune/function/RotatePhoto.java new file mode 100644 index 0000000..493f7ce --- /dev/null +++ b/tim/prune/function/RotatePhoto.java @@ -0,0 +1,50 @@ +package tim.prune.function; + +import tim.prune.App; +import tim.prune.DataSubscriber; +import tim.prune.GenericFunction; +import tim.prune.I18nManager; +import tim.prune.UpdateMessageBroker; +import tim.prune.data.Photo; +import tim.prune.undo.UndoRotatePhoto; + +/** + * Class to provide the function to rotate a photo + * either clockwise or anticlockwise + */ +public class RotatePhoto extends GenericFunction +{ + /** Direction of rotation */ + private boolean _direction = true; + + /** + * Constructor + * @param inApp application object for callback + * @param inDir true for clockwise, false for anticlockwise + */ + public RotatePhoto(App inApp, boolean inDir) + { + super(inApp); + _direction = inDir; + } + + /** Get the name key */ + public String getNameKey() { + return _direction?"function.rotatephotoright":"function.rotatephotoleft"; + } + + /** + * Begin the function + */ + public void begin() + { + Photo photo = _app.getTrackInfo().getCurrentPhoto(); + if (photo != null) + { + UndoRotatePhoto undo = new UndoRotatePhoto(photo, _direction); + photo.rotate(_direction); + UpdateMessageBroker.informSubscribers(DataSubscriber.PHOTOS_MODIFIED); + _app.completeFunction(undo, I18nManager.getText("confirm.rotatephoto")); + } + } +} diff --git a/tim/prune/function/SaveConfig.java b/tim/prune/function/SaveConfig.java index 0f2339f..125b4b7 100644 --- a/tim/prune/function/SaveConfig.java +++ b/tim/prune/function/SaveConfig.java @@ -20,9 +20,9 @@ import javax.swing.JLabel; import javax.swing.JPanel; import tim.prune.App; -import tim.prune.Config; import tim.prune.GenericFunction; import tim.prune.I18nManager; +import tim.prune.config.Config; /** * Class to provide the function to save the config settings diff --git a/tim/prune/function/SetColours.java b/tim/prune/function/SetColours.java new file mode 100644 index 0000000..1329d05 --- /dev/null +++ b/tim/prune/function/SetColours.java @@ -0,0 +1,205 @@ +package tim.prune.function; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.GridLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +import javax.swing.BorderFactory; +import javax.swing.Box; +import javax.swing.BoxLayout; +import javax.swing.JButton; +import javax.swing.JDialog; +import javax.swing.JLabel; +import javax.swing.JPanel; + +import tim.prune.App; +import tim.prune.GenericFunction; +import tim.prune.I18nManager; +import tim.prune.UpdateMessageBroker; +import tim.prune.config.ColourScheme; +import tim.prune.config.Config; +import tim.prune.gui.ColourChooser; +import tim.prune.gui.ColourPatch; + +/** + * Class to show the popup window for setting the colours + */ +public class SetColours extends GenericFunction +{ + private JDialog _dialog = null; + private JButton _okButton = null; + /** Array of 8 colour patches */ + private ColourPatch[] _patches = null; + /** Single colour chooser */ + private ColourChooser _colourChooser = null; + + /** Array of label keys for the 8 patches */ + private static final String[] LABEL_KEYS = {"background", "primary", "point", "secondary", + "selection", "borders", "text", "lines"}; + /** Array of indices for the 8 patches */ + private static final int[] INDICES = {ColourScheme.IDX_BACKGROUND, ColourScheme.IDX_PRIMARY, + ColourScheme.IDX_POINT, ColourScheme.IDX_SECONDARY, + ColourScheme.IDX_SELECTION, ColourScheme.IDX_BORDERS, + ColourScheme.IDX_TEXT, ColourScheme.IDX_LINES + }; + + /** + * Inner class to react to patch clicks + */ + class PatchListener extends MouseAdapter + { + /** Associated patch */ + private ColourPatch _patch = null; + /** Constructor */ + public PatchListener(ColourPatch inPatch) { + _patch = inPatch; + } + /** React to mouse clicks */ + public void mouseClicked(MouseEvent e) + { + _colourChooser.showDialog(_patch.getBackground()); + Color colour = _colourChooser.getChosenColour(); + if (colour != null) _patch.setColour(colour); + } + } + + /** + * Constructor + * @param inApp app object + */ + public SetColours(App inApp) + { + super(inApp); + } + + /** + * Return the name key for this function + */ + public String getNameKey() + { + return "function.setcolours"; + } + + /** + * @return the contents of the window as a Component + */ + private Component makeContents() + { + JPanel mainPanel = new JPanel(); + mainPanel.setLayout(new BorderLayout(0, 10)); + + JLabel intro = new JLabel(I18nManager.getText("dialog.setcolours.intro")); + intro.setBorder(BorderFactory.createEmptyBorder(5, 5, 0, 0)); + mainPanel.add(intro, BorderLayout.NORTH); + JPanel centralPanel = new JPanel(); + centralPanel.setLayout(new GridLayout()); + _patches = new ColourPatch[8]; + + ColourScheme scheme = Config.getColourScheme(); + ColourPatch patch = null; + // Loop over four columns of patches + for (int i=0; i<4; i++) + { + JPanel colPanel = new JPanel(); + colPanel.setLayout(new BoxLayout(colPanel, BoxLayout.Y_AXIS)); + // Top label and patch + colPanel.add(new JLabel(I18nManager.getText("dialog.setcolours." + LABEL_KEYS[i*2]))); + patch = new ColourPatch(scheme.getColour(INDICES[i*2])); + patch.addMouseListener(new PatchListener(patch)); + colPanel.add(patch); + _patches[i*2] = patch; + // separator + colPanel.add(Box.createRigidArea(new Dimension(0, 5))); + // Bottom label and patch + colPanel.add(new JLabel(I18nManager.getText("dialog.setcolours." + LABEL_KEYS[i*2+1]))); + patch = new ColourPatch(scheme.getColour(INDICES[i*2+1])); + patch.addMouseListener(new PatchListener(patch)); + colPanel.add(patch); + _patches[i*2+1] = patch; + + // Add column to panel + colPanel.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2)); + centralPanel.add(colPanel); + } + mainPanel.add(centralPanel, BorderLayout.CENTER); + + // Buttons at the bottom + JPanel buttonPanel = new JPanel(); + buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.LINE_AXIS)); + _okButton = new JButton(I18nManager.getText("button.ok")); + _okButton.addActionListener(new ActionListener() + { + public void actionPerformed(ActionEvent e) + { + updateConfigColours(); + _dialog.dispose(); + } + }); + JButton cancelButton = new JButton(I18nManager.getText("button.cancel")); + cancelButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) + { + _dialog.dispose(); + } + }); + JButton resetButton = new JButton(I18nManager.getText("button.resettodefaults")); + resetButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + for (int i=0; i<8; i++) { + _patches[i].setColour(ColourScheme.getDefaultColour(INDICES[i])); + } + } + }); + buttonPanel.add(resetButton); + buttonPanel.add(Box.createHorizontalGlue()); + buttonPanel.add(_okButton); + buttonPanel.add(Box.createHorizontalStrut(5)); + buttonPanel.add(cancelButton); + buttonPanel.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2)); + mainPanel.add(buttonPanel, BorderLayout.SOUTH); + return mainPanel; + } + + + /** + * Show window + */ + public void begin() + { + if (_dialog == null) + { + _dialog = new JDialog(_parentFrame, I18nManager.getText(getNameKey())); + _dialog.setLocationRelativeTo(_parentFrame); + _dialog.getContentPane().add(makeContents()); + _dialog.pack(); + _colourChooser = new ColourChooser(_dialog); + } + // Reset colours to current ones + ColourScheme scheme = Config.getColourScheme(); + for (int i=0; i<8; i++) { + _patches[i].setColour(scheme.getColour(INDICES[i])); + } + _dialog.setVisible(true); + _okButton.requestFocus(); + } + + /** + * Update the current colour scheme with the selected colours + */ + private void updateConfigColours() + { + ColourScheme scheme = Config.getColourScheme(); + for (int i=0; i<_patches.length; i++) + { + scheme.setColour(INDICES[i], _patches[i].getBackground()); + } + Config.updateColourScheme(); + UpdateMessageBroker.informSubscribers(); + } +} diff --git a/tim/prune/function/SetKmzImageSize.java b/tim/prune/function/SetKmzImageSize.java index 1677e54..c63d4fe 100644 --- a/tim/prune/function/SetKmzImageSize.java +++ b/tim/prune/function/SetKmzImageSize.java @@ -18,9 +18,9 @@ import javax.swing.JPanel; import javax.swing.SwingConstants; import tim.prune.App; -import tim.prune.Config; import tim.prune.GenericFunction; import tim.prune.I18nManager; +import tim.prune.config.Config; import tim.prune.gui.WholeNumberField; /** diff --git a/tim/prune/function/SetLanguage.java b/tim/prune/function/SetLanguage.java new file mode 100644 index 0000000..d54e1be --- /dev/null +++ b/tim/prune/function/SetLanguage.java @@ -0,0 +1,332 @@ +package tim.prune.function; + +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.FlowLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.util.Locale; + +import javax.swing.BorderFactory; +import javax.swing.Box; +import javax.swing.BoxLayout; +import javax.swing.JButton; +import javax.swing.JComboBox; +import javax.swing.JDialog; +import javax.swing.JFileChooser; +import javax.swing.JLabel; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JTextField; +import javax.swing.SwingConstants; +import javax.swing.border.EtchedBorder; + +import tim.prune.App; +import tim.prune.GenericFunction; +import tim.prune.I18nManager; +import tim.prune.config.Config; +import tim.prune.load.GenericFileFilter; + +/** + * Class to show the popup window for setting the language code / file + */ +public class SetLanguage extends GenericFunction +{ + private JDialog _dialog = null; + private JComboBox _languageDropDown = null; + private JTextField _langFileBox = null; + private int _startIndex = 0; + + /** Names of languages for display in dropdown (not translated) */ + private static final String[] LANGUAGE_NAMES = {"deutsch", "english", "espa\u00F1ol", "fran\u00E7ais", + "italiano", "polski", "\u4e2d\u6587 (chinese)", "\u65E5\u672C\u8A9E (japanese)", + "schwiizerd\u00FC\u00FCtsch", "t\u00FCrk\u00E7e", "portugu\u00EAs", "bahasa indonesia", "rom\u00E2n\u0103" + }; + /** Associated language codes (must be in same order as names!) */ + private static final String[] LANGUAGE_CODES = {"de", "en", "es", "fr", "it", "pl", "zh", "ja", + "de_ch", "tr", "pt", "in", "ro" + }; + + + /** + * Constructor + * @param inApp app object + */ + public SetLanguage(App inApp) + { + super(inApp); + } + + /** + * Return the name key for this function + */ + public String getNameKey() + { + return "function.setlanguage"; + } + + /** + * @return the contents of the window as a Component + */ + private Component makeContents() + { + JPanel mainPanel = new JPanel(); + mainPanel.setLayout(new BorderLayout(0, 5)); + JPanel midPanel = new JPanel(); + midPanel.setLayout(new BoxLayout(midPanel, BoxLayout.Y_AXIS)); + midPanel.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3)); + // description labels + JLabel label1 = new JLabel("" + I18nManager.getText("dialog.setlanguage.firstintro") + ""); + label1.setAlignmentX(Component.LEFT_ALIGNMENT); + label1.setHorizontalAlignment(SwingConstants.LEFT); + midPanel.add(label1); + JLabel label2 = new JLabel("" + I18nManager.getText("dialog.setlanguage.secondintro") + ""); + label2.setAlignmentX(Component.LEFT_ALIGNMENT); + label2.setHorizontalAlignment(SwingConstants.LEFT); + midPanel.add(label2); + midPanel.add(Box.createVerticalStrut(10)); + + // built-in languages + JPanel builtinPanel = new JPanel(); + builtinPanel.setBorder(BorderFactory.createCompoundBorder( + BorderFactory.createEtchedBorder(EtchedBorder.LOWERED), BorderFactory.createEmptyBorder(3, 3, 3, 3)) + ); + builtinPanel.setLayout(new BoxLayout(builtinPanel, BoxLayout.X_AXIS)); + builtinPanel.add(new JLabel(I18nManager.getText("dialog.setlanguage.language") + " : ")); + // Language dropdown + _languageDropDown = new JComboBox(LANGUAGE_NAMES); + builtinPanel.add(_languageDropDown); + builtinPanel.add(Box.createHorizontalGlue()); + JButton selectLangButton = new JButton(I18nManager.getText("button.select")); + selectLangButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + selectLanguage(); + } + }); + builtinPanel.add(selectLangButton); + builtinPanel.setAlignmentX(Component.LEFT_ALIGNMENT); + midPanel.add(builtinPanel); + midPanel.add(Box.createVerticalStrut(4)); + + // external language file + JPanel extraPanel = new JPanel(); + extraPanel.setBorder(BorderFactory.createCompoundBorder( + BorderFactory.createEtchedBorder(EtchedBorder.LOWERED), BorderFactory.createEmptyBorder(3, 3, 3, 3)) + ); + extraPanel.setLayout(new BoxLayout(extraPanel, BoxLayout.X_AXIS)); + extraPanel.add(new JLabel(I18nManager.getText("dialog.setlanguage.languagefile") + " : ")); + _langFileBox = new JTextField("some_long_example_file_path.txt"); + extraPanel.add(_langFileBox); + // browse button + JButton browseButton = new JButton(I18nManager.getText("button.browse")); + extraPanel.add(browseButton); + browseButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent arg0) { + chooseFile(); + } + }); + extraPanel.add(Box.createHorizontalStrut(5)); + JButton selectFileButton = new JButton(I18nManager.getText("button.select")); + selectFileButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + selectLanguageFile(); + } + }); + extraPanel.add(selectFileButton); + extraPanel.setAlignmentX(Component.LEFT_ALIGNMENT); + midPanel.add(Box.createVerticalStrut(5)); + midPanel.add(extraPanel); + midPanel.add(Box.createVerticalGlue()); + mainPanel.add(midPanel, BorderLayout.CENTER); + + // Cancel button at the bottom + JPanel buttonPanel = new JPanel(); + buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT)); + JButton cancelButton = new JButton(I18nManager.getText("button.cancel")); + cancelButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) + { + _dialog.dispose(); + } + }); + buttonPanel.add(cancelButton); + mainPanel.add(buttonPanel, BorderLayout.SOUTH); + return mainPanel; + } + + + /** + * Show window + */ + public void begin() + { + if (_dialog == null) + { + _dialog = new JDialog(_parentFrame, I18nManager.getText(getNameKey())); + _dialog.setLocationRelativeTo(_parentFrame); + _dialog.getContentPane().add(makeContents()); + _dialog.pack(); + } + // Try to use code from config + String code = Config.getConfigString(Config.KEY_LANGUAGE_CODE); + int index = getLanguageIndex(code); + // If it's not present, then use system locale settings + if (index < 0) { + Locale locale = Locale.getDefault(); + index = getLanguageIndex(locale.getLanguage() + "_" + locale.getCountry()); + if (index < 0) { + index = getLanguageIndex(locale.getLanguage()); + } + } + // Select appropriate language from dropdown + if (index >= 0) { + _languageDropDown.setSelectedIndex(index); + } + _startIndex = _languageDropDown.getSelectedIndex(); + // Get language file from config + String langfile = Config.getConfigString(Config.KEY_LANGUAGE_FILE); + _langFileBox.setText(langfile==null?"":langfile); + _dialog.setVisible(true); + } + + /** + * Find the index of the given language code + * @param inCode code to look for + * @return index if found or -1 + */ + private static int getLanguageIndex(String inCode) + { + int idx = -1; + if (inCode != null && !inCode.equals("")) { + for (int i=0; i= 0 && index != _startIndex) + { + String code = LANGUAGE_CODES[index]; + // Set code and langfile in config + Config.setConfigString(Config.KEY_LANGUAGE_CODE, code); + Config.setConfigString(Config.KEY_LANGUAGE_FILE, null); + _dialog.dispose(); + showEndMessage(); + } + } + + /** + * Select the currently selected language file to use for texts + */ + private void selectLanguageFile() + { + final String oldPath = Config.getConfigString(Config.KEY_LANGUAGE_FILE); + String filename = _langFileBox.getText(); + // Check there is an entry in the box + if (filename != null && !filename.equals("")) + { + // Check the file exists and is readable + File textsFile = new File(filename); + if (!textsFile.exists() || !textsFile.canRead()) + { + _app.showErrorMessage(getNameKey(), "error.load.noread"); + } + else if (!languageFileLooksOk(textsFile)) + { + _app.showErrorMessage(getNameKey(), "error.language.wrongfile"); + } + else if (oldPath == null || !textsFile.getAbsolutePath().equalsIgnoreCase(oldPath)) + { + // Set in Config + Config.setConfigString(Config.KEY_LANGUAGE_FILE, textsFile.getAbsolutePath()); + _dialog.dispose(); + showEndMessage(); + } + } + else { + // if file was previously selected, and now it's blank, then reset Config + if (oldPath != null && oldPath.length() > 0) + { + Config.setConfigString(Config.KEY_LANGUAGE_FILE, null); + _dialog.dispose(); + showEndMessage(); + } + } + } + + /** + * Check the given file to see if it looks like a language file + * @param inFile File object to load + * @return true if file looks ok + */ + private static boolean languageFileLooksOk(File inFile) + { + boolean ok = false; + boolean wrong = false; + BufferedReader reader = null; + try + { + // Read through text file looking for lines with the right start + reader = new BufferedReader(new FileReader(inFile)); + String currLine = reader.readLine(); + while (currLine != null && !ok && !wrong) + { + if (currLine.trim().length() > 0 && currLine.matches("[a-z.]+=.+")) { + ok = true; + } + if (currLine.indexOf('\0', 0) >= 0) { + wrong = true; + } + currLine = reader.readLine(); + } + } + catch (Exception e) {} // ignore exceptions, flag remains as set + finally { + try {reader.close();} catch (Exception e2) {} + } + return ok && !wrong; + } + + /** + * Function activated by the "Browse..." button to select a file + */ + private void chooseFile() + { + JFileChooser chooser = new JFileChooser(); + chooser.addChoosableFileFilter( + new GenericFileFilter("filetype.txt", new String[] {"txt", "text"})); + chooser.setAcceptAllFileFilterUsed(true); + // Set start path from currently selected file + String currPath = _langFileBox.getText(); + if (currPath != null && currPath.length() > 1) { + chooser.setSelectedFile(new File(currPath)); + } + if (chooser.showOpenDialog(_parentFrame) == JFileChooser.APPROVE_OPTION) + { + _langFileBox.setText(chooser.getSelectedFile().getAbsolutePath()); + } + } + + /** + * Show message to remind about saving settings and restarting + */ + private void showEndMessage() + { + JOptionPane.showMessageDialog(_parentFrame, + I18nManager.getText("dialog.setlanguage.endmessage"), + I18nManager.getText(getNameKey()), JOptionPane.INFORMATION_MESSAGE); + } +} diff --git a/tim/prune/function/SetMapBgFunction.java b/tim/prune/function/SetMapBgFunction.java index a683634..cadacf9 100644 --- a/tim/prune/function/SetMapBgFunction.java +++ b/tim/prune/function/SetMapBgFunction.java @@ -18,11 +18,11 @@ import javax.swing.JRadioButton; import javax.swing.JTextField; import tim.prune.App; -import tim.prune.Config; import tim.prune.DataSubscriber; import tim.prune.GenericFunction; import tim.prune.I18nManager; import tim.prune.UpdateMessageBroker; +import tim.prune.config.Config; /** * Function to set the tile server for the map backgrounds diff --git a/tim/prune/function/SetPathsFunction.java b/tim/prune/function/SetPathsFunction.java index 65c3c41..3ded223 100644 --- a/tim/prune/function/SetPathsFunction.java +++ b/tim/prune/function/SetPathsFunction.java @@ -15,10 +15,10 @@ import javax.swing.JTextField; import javax.swing.SwingConstants; import tim.prune.App; -import tim.prune.Config; import tim.prune.ExternalTools; import tim.prune.GenericFunction; import tim.prune.I18nManager; +import tim.prune.config.Config; /** * Function to set the paths for the external programs (eg gnuplot) diff --git a/tim/prune/function/browser/UrlGenerator.java b/tim/prune/function/browser/UrlGenerator.java index 14d1577..8d264be 100644 --- a/tim/prune/function/browser/UrlGenerator.java +++ b/tim/prune/function/browser/UrlGenerator.java @@ -30,8 +30,8 @@ public abstract class UrlGenerator public static final int MAP_SOURCE_MAPQUEST = 2; /** Constant for Yahoo */ public static final int MAP_SOURCE_YAHOO = 3; - - // TODO: Add other map sources, eg MSN, search.ch ? + /** Constant for Bing */ + public static final int MAP_SOURCE_BING = 4; /** * Generate a URL for the given source and track info @@ -50,6 +50,9 @@ public abstract class UrlGenerator else if (inSource == MAP_SOURCE_YAHOO) { return generateYahooUrl(inTrackInfo); } + else if (inSource == MAP_SOURCE_BING) { + return generateBingUrl(inTrackInfo); + } return generateOpenStreetMapUrl(inTrackInfo); } @@ -82,7 +85,6 @@ public abstract class UrlGenerator url = url + "(" + currPoint.getWaypointName() + ")"; } } - //System.out.println(url); return url; } @@ -154,7 +156,30 @@ public abstract class UrlGenerator return url; } -/** + /** + * Generate a url for Bing maps + * @param inTrackInfo track information + * @return URL + */ + private static String generateBingUrl(TrackInfo inTrackInfo) + { + // Check if any data to display + if (inTrackInfo == null || inTrackInfo.getTrack() == null || inTrackInfo.getTrack().getNumPoints() < 1) + { + return null; + } + double medianLat = getMedianValue(inTrackInfo.getTrack().getLatRange()); + double medianLon = getMedianValue(inTrackInfo.getTrack().getLonRange()); + // Build basic url with centre position + String latStr = FIVE_DP.format(medianLat); + String lonStr = FIVE_DP.format(medianLon); + String url = "http://bing.com/maps/default.aspx?cp=" + latStr + "~" + lonStr + + "&where1=" + latStr + "%2C%20" + lonStr; + return url; + } + + + /** * Get the median value from the given lat/long range * @param inRange range of values * @return median value diff --git a/tim/prune/function/charts/Charter.java b/tim/prune/function/charts/Charter.java index 01bf16c..4b3fd37 100644 --- a/tim/prune/function/charts/Charter.java +++ b/tim/prune/function/charts/Charter.java @@ -25,10 +25,10 @@ import javax.swing.JTextField; import javax.swing.SwingConstants; import tim.prune.App; -import tim.prune.Config; import tim.prune.ExternalTools; import tim.prune.GenericFunction; import tim.prune.I18nManager; +import tim.prune.config.Config; import tim.prune.data.Altitude; import tim.prune.data.DataPoint; import tim.prune.data.Distance; diff --git a/tim/prune/function/compress/CompressTrackFunction.java b/tim/prune/function/compress/CompressTrackFunction.java index 62bf1f1..35ff61d 100644 --- a/tim/prune/function/compress/CompressTrackFunction.java +++ b/tim/prune/function/compress/CompressTrackFunction.java @@ -72,7 +72,6 @@ public class CompressTrackFunction extends GenericFunction */ private boolean[] preview() { - // System.out.println("track dialog preview"); int numToDelete = 0; boolean[] deleteFlags = new boolean[_track.getNumPoints()]; for (int i=0; i<_algorithms.length; i++) diff --git a/tim/prune/function/distance/DistanceTableModel.java b/tim/prune/function/distance/DistanceTableModel.java index 8dadc3a..48ba172 100644 --- a/tim/prune/function/distance/DistanceTableModel.java +++ b/tim/prune/function/distance/DistanceTableModel.java @@ -1,7 +1,7 @@ package tim.prune.function.distance; -import tim.prune.Config; import tim.prune.I18nManager; +import tim.prune.config.Config; import tim.prune.data.DataPoint; import tim.prune.data.Distance; diff --git a/tim/prune/function/edit/PointEditor.java b/tim/prune/function/edit/PointEditor.java index 6808e6a..9e02a1e 100644 --- a/tim/prune/function/edit/PointEditor.java +++ b/tim/prune/function/edit/PointEditor.java @@ -89,7 +89,7 @@ public class PointEditor private Component makeDialogComponents() { JPanel panel = new JPanel(); - panel.setLayout(new BorderLayout()); + panel.setLayout(new BorderLayout(1, 10)); // Create GUI layout for point editor _table = new JTable(_model); _table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); diff --git a/tim/prune/function/gpsies/GetGpsiesFunction.java b/tim/prune/function/gpsies/GetGpsiesFunction.java index 493aedf..d1d83f3 100644 --- a/tim/prune/function/gpsies/GetGpsiesFunction.java +++ b/tim/prune/function/gpsies/GetGpsiesFunction.java @@ -9,6 +9,7 @@ import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.io.IOException; +import java.io.InputStream; import java.net.URL; import java.util.ArrayList; @@ -227,6 +228,7 @@ public class GetGpsiesFunction extends GenericFunction implements Runnable ArrayList trackList = null; URL url = null; String descMessage = ""; + InputStream inStream = null; // Loop for each page of the results do { @@ -240,12 +242,16 @@ public class GetGpsiesFunction extends GenericFunction implements Runnable { url = new URL(urlString); SAXParser saxParser = SAXParserFactory.newInstance().newSAXParser(); - saxParser.parse(url.openStream(), xmlHandler); + inStream = url.openStream(); + saxParser.parse(inStream, xmlHandler); } catch (Exception e) { descMessage = e.getClass().getName() + " - " + e.getMessage(); } - // TODO: Close streams somehow? Haven't got a reference to the input stream to close it! + // Close stream and ignore errors + try { + inStream.close(); + } catch (Exception e) {} // Add track list to model trackList = xmlHandler.getTrackList(); _trackListModel.addTracks(trackList); diff --git a/tim/prune/function/gpsies/TrackListModel.java b/tim/prune/function/gpsies/TrackListModel.java index 275ae83..3bdeb16 100644 --- a/tim/prune/function/gpsies/TrackListModel.java +++ b/tim/prune/function/gpsies/TrackListModel.java @@ -5,8 +5,8 @@ import java.util.ArrayList; import javax.swing.table.AbstractTableModel; -import tim.prune.Config; import tim.prune.I18nManager; +import tim.prune.config.Config; import tim.prune.data.Distance; /** diff --git a/tim/prune/gui/ColourChooser.java b/tim/prune/gui/ColourChooser.java new file mode 100644 index 0000000..93691ac --- /dev/null +++ b/tim/prune/gui/ColourChooser.java @@ -0,0 +1,151 @@ +package tim.prune.gui; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import javax.swing.BoxLayout; +import javax.swing.JButton; +import javax.swing.JDialog; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JSlider; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; + +import tim.prune.I18nManager; + +/** + * Class to offer a dialog to choose a colour. + * Normally a JColorChooser would be used, but this is too buggy + * in Java 1.6 and extremely prone to thread-locking, meaning + * that the application has to be killed (and all data lost). + */ +public class ColourChooser +{ + /** main dialog object */ + private JDialog _dialog = null; + /** array of three slider objects for rgb */ + private JSlider[] _rgbSliders = null; + /** array of labels for rgb values */ + private JLabel[] _rgbLabels = null; + /** colour patch */ + private ColourPatch _patch = null; + /** chosen colour */ + private Color _chosenColour = null; + + + /** + * Constructor + * @param inParent parent dialog + */ + public ColourChooser(JDialog inParent) + { + _dialog = new JDialog(inParent, I18nManager.getText("dialog.colourchooser.title"), true); + _dialog.setLocationRelativeTo(inParent); + _dialog.getContentPane().add(makeContents()); + _dialog.pack(); + } + + /** + * Make the dialog contents + * @return JPanel containing dialog elements + */ + private JPanel makeContents() + { + JPanel mainPanel = new JPanel(); + mainPanel.setLayout(new BorderLayout()); + _rgbSliders = new JSlider[3]; + _rgbLabels = new JLabel[3]; + _patch = new ColourPatch(Color.WHITE); + JPanel centrePanel = new JPanel(); + centrePanel.setLayout(new BorderLayout()); + centrePanel.add(_patch, BorderLayout.CENTER); + + JPanel sliderPanel = new JPanel(); + sliderPanel.setLayout(new BoxLayout(sliderPanel, BoxLayout.Y_AXIS)); + final String[] labelKeys = {"red", "green", "blue"}; + for (int i=0; i<3; i++) + { + String key = I18nManager.getText("dialog.colourchooser." + labelKeys[i]); + sliderPanel.add(new JLabel(key)); + _rgbSliders[i] = new JSlider(0, 255); + _rgbSliders[i].addChangeListener(new ChangeListener() { + public void stateChanged(ChangeEvent arg0) { + updatePatch(); + } + }); + _rgbSliders[i].setToolTipText(key); + JPanel sliderHolder = new JPanel(); + sliderHolder.setLayout(new BorderLayout(5, 0)); + sliderHolder.add(_rgbSliders[i], BorderLayout.CENTER); + _rgbLabels[i] = new JLabel("255"); + _rgbLabels[i].setPreferredSize(new Dimension(40, 1)); + sliderHolder.add(_rgbLabels[i], BorderLayout.EAST); + sliderPanel.add(sliderHolder); + } + centrePanel.add(sliderPanel, BorderLayout.SOUTH); + mainPanel.add(centrePanel, BorderLayout.CENTER); + + // Button panel for ok, cancel + JPanel buttonPanel = new JPanel(); + buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT)); + JButton okButton = new JButton(I18nManager.getText("button.ok")); + okButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + _chosenColour = _patch.getBackground(); + _dialog.setVisible(false); + } + }); + buttonPanel.add(okButton); + JButton cancelButton = new JButton(I18nManager.getText("button.cancel")); + cancelButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + _chosenColour = null; + _dialog.setVisible(false); + } + }); + buttonPanel.add(cancelButton); + mainPanel.add(buttonPanel, BorderLayout.SOUTH); + return mainPanel; + } + + /** + * Show the dialog to choose a colour + * @param inStartColour current colour + */ + public void showDialog(Color inStartColour) + { + // Initialise sliders + _rgbSliders[0].setValue(inStartColour.getRed()); + _rgbSliders[1].setValue(inStartColour.getGreen()); + _rgbSliders[2].setValue(inStartColour.getBlue()); + updatePatch(); + _dialog.setLocationRelativeTo(_dialog.getParent()); + _dialog.setVisible(true); + } + + /** + * Update the patch colour from the slider values + */ + private void updatePatch() + { + for (int i=0; i<3; i++) { + _rgbLabels[i].setText("" + _rgbSliders[i].getValue()); + } + final Color colour = new Color(_rgbSliders[0].getValue(), + _rgbSliders[1].getValue(),_rgbSliders[2].getValue()); + _patch.setColour(colour); + } + + /** + * @return the selected colour, or null if cancel pressed + */ + public Color getChosenColour() + { + return _chosenColour; + } +} diff --git a/tim/prune/gui/ColourPatch.java b/tim/prune/gui/ColourPatch.java new file mode 100644 index 0000000..d5b9fd2 --- /dev/null +++ b/tim/prune/gui/ColourPatch.java @@ -0,0 +1,34 @@ +package tim.prune.gui; + +import java.awt.Color; +import java.awt.Dimension; +import javax.swing.JPanel; + +import tim.prune.config.ColourUtils; + +/** + * Class to act as a colour patch to illustrate a chosen colour + */ +public class ColourPatch extends JPanel +{ + /** + * Constructor + */ + public ColourPatch(Color inColour) + { + Dimension size = new Dimension(80, 50); + setMinimumSize(size); + setPreferredSize(size); + setColour(inColour); + } + + /** + * Set the colour of the patch + * @param inColour Color to use + */ + public void setColour(Color inColour) + { + super.setBackground(inColour); + setToolTipText(ColourUtils.makeHexCode(inColour)); + } +} diff --git a/tim/prune/gui/DetailsDisplay.java b/tim/prune/gui/DetailsDisplay.java index c40f8c2..5e31a4e 100644 --- a/tim/prune/gui/DetailsDisplay.java +++ b/tim/prune/gui/DetailsDisplay.java @@ -4,6 +4,7 @@ import java.awt.BorderLayout; import java.awt.Component; import java.awt.Dimension; import java.awt.Font; +import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.text.NumberFormat; @@ -11,18 +12,22 @@ import java.text.NumberFormat; import javax.swing.BorderFactory; import javax.swing.Box; import javax.swing.BoxLayout; +import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.border.EtchedBorder; -import tim.prune.Config; import tim.prune.DataSubscriber; +import tim.prune.FunctionLibrary; +import tim.prune.GenericFunction; import tim.prune.I18nManager; +import tim.prune.config.Config; import tim.prune.data.Altitude; import tim.prune.data.Coordinate; import tim.prune.data.DataPoint; import tim.prune.data.Distance; +import tim.prune.data.Field; import tim.prune.data.IntegerRange; import tim.prune.data.Photo; import tim.prune.data.Selection; @@ -37,22 +42,23 @@ public class DetailsDisplay extends GenericDisplay // Point details private JLabel _indexLabel = null; private JLabel _latLabel = null, _longLabel = null; - private JLabel _altLabel = null, _nameLabel = null; + private JLabel _altLabel = null; private JLabel _timeLabel = null, _speedLabel = null; + private JLabel _nameLabel = null, _typeLabel = null; // Range details private JLabel _rangeLabel = null; - private JLabel _distanceLabel = null, _movingDistanceLabel = null; + private JLabel _distanceLabel = null; private JLabel _durationLabel = null; private JLabel _altRangeLabel = null, _updownLabel = null; - private JLabel _aveSpeedLabel = null, _aveMovingSpeedLabel = null; - private JLabel _paceLabel = null; + private JLabel _aveSpeedLabel = null; // Photo details private JLabel _photoLabel = null; private PhotoThumbnail _photoThumbnail = null; private JLabel _photoTimestampLabel = null; private JLabel _photoConnectedLabel = null; + private JPanel _rotationButtons = null; // Units private JComboBox _coordFormatDropdown = null; @@ -67,10 +73,10 @@ public class DetailsDisplay extends GenericDisplay private static final String LABEL_POINT_ALTITUDE = I18nManager.getText("fieldname.altitude") + ": "; private static final String LABEL_POINT_TIMESTAMP = I18nManager.getText("fieldname.timestamp") + ": "; private static final String LABEL_POINT_WAYPOINTNAME = I18nManager.getText("fieldname.waypointname") + ": "; + private static final String LABEL_POINT_WAYPOINTTYPE = I18nManager.getText("fieldname.waypointtype") + ": "; private static final String LABEL_RANGE_SELECTED = I18nManager.getText("details.range.selected") + ": "; private static final String LABEL_RANGE_DURATION = I18nManager.getText("fieldname.duration") + ": "; private static final String LABEL_RANGE_DISTANCE = I18nManager.getText("fieldname.distance") + ": "; - private static final String LABEL_RANGE_MOVINGDISTANCE = I18nManager.getText("fieldname.movingdistance") + ": "; private static final String LABEL_RANGE_ALTITUDE = I18nManager.getText("fieldname.altitude") + ": "; private static final String LABEL_RANGE_CLIMB = I18nManager.getText("details.range.climb") + ": "; private static final String LABEL_RANGE_DESCENT = ", " + I18nManager.getText("details.range.descent") + ": "; @@ -116,6 +122,8 @@ public class DetailsDisplay extends GenericDisplay pointDetailsPanel.add(_speedLabel); _nameLabel = new JLabel(""); pointDetailsPanel.add(_nameLabel); + _typeLabel = new JLabel(""); + pointDetailsPanel.add(_typeLabel); pointDetailsPanel.setAlignmentX(Component.LEFT_ALIGNMENT); // range details panel @@ -131,16 +139,10 @@ public class DetailsDisplay extends GenericDisplay rangeDetailsPanel.add(_rangeLabel); _distanceLabel = new JLabel(""); rangeDetailsPanel.add(_distanceLabel); - _movingDistanceLabel = new JLabel(""); - rangeDetailsPanel.add(_movingDistanceLabel); _durationLabel = new JLabel(""); rangeDetailsPanel.add(_durationLabel); _aveSpeedLabel = new JLabel(""); rangeDetailsPanel.add(_aveSpeedLabel); - _aveMovingSpeedLabel = new JLabel(""); - rangeDetailsPanel.add(_aveMovingSpeedLabel); - _paceLabel = new JLabel(""); - rangeDetailsPanel.add(_paceLabel); _altRangeLabel = new JLabel(""); rangeDetailsPanel.add(_altRangeLabel); _updownLabel = new JLabel(""); @@ -166,6 +168,15 @@ public class DetailsDisplay extends GenericDisplay _photoThumbnail.setVisible(false); _photoThumbnail.setPreferredSize(new Dimension(100, 100)); photoDetailsPanel.add(_photoThumbnail); + // Rotate buttons + JButton rotLeft = makeRotateButton(IconManager.ROTATE_LEFT, FunctionLibrary.FUNCTION_ROTATE_PHOTO_LEFT); + JButton rotRight = makeRotateButton(IconManager.ROTATE_RIGHT, FunctionLibrary.FUNCTION_ROTATE_PHOTO_RIGHT); + _rotationButtons = new JPanel(); + _rotationButtons.add(rotLeft); + _rotationButtons.add(rotRight); + _rotationButtons.setAlignmentX(Component.LEFT_ALIGNMENT); + _rotationButtons.setVisible(false); + photoDetailsPanel.add(_rotationButtons); // add the details panels to the main panel mainPanel.add(pointDetailsPanel); @@ -235,6 +246,7 @@ public class DetailsDisplay extends GenericDisplay _altLabel.setText(""); _timeLabel.setText(""); _nameLabel.setText(""); + _typeLabel.setText(""); } else { @@ -271,12 +283,19 @@ public class DetailsDisplay extends GenericDisplay else { _timeLabel.setText(""); } - String name = currentPoint.getWaypointName(); + // Waypoint name + final String name = currentPoint.getWaypointName(); if (name != null && !name.equals("")) { _nameLabel.setText(LABEL_POINT_WAYPOINTNAME + name); } else _nameLabel.setText(""); + // Waypoint type + final String type = currentPoint.getFieldValue(Field.WAYPT_TYPE); + if (type != null && !type.equals("")) { + _typeLabel.setText(LABEL_POINT_WAYPOINTTYPE + type); + } + else _typeLabel.setText(""); } // Update range details @@ -284,13 +303,10 @@ public class DetailsDisplay extends GenericDisplay { _rangeLabel.setText(I18nManager.getText("details.norangeselection")); _distanceLabel.setText(""); - _movingDistanceLabel.setText(""); _durationLabel.setText(""); _altRangeLabel.setText(""); _updownLabel.setText(""); _aveSpeedLabel.setText(""); - _aveMovingSpeedLabel.setText(""); - _paceLabel.setText(""); } else { @@ -298,38 +314,15 @@ public class DetailsDisplay extends GenericDisplay + (selection.getStart()+1) + " " + I18nManager.getText("details.range.to") + " " + (selection.getEnd()+1)); _distanceLabel.setText(LABEL_RANGE_DISTANCE + roundedNumber(selection.getDistance(distUnits)) + " " + distUnitsStr); - if (selection.getHasMultipleSegments()) { - _movingDistanceLabel.setText(LABEL_RANGE_MOVINGDISTANCE + roundedNumber(selection.getMovingDistance(distUnits)) + " " + distUnitsStr); - } - else { - _movingDistanceLabel.setText(null); - } if (selection.getNumSeconds() > 0) { - _durationLabel.setText(LABEL_RANGE_DURATION + buildDurationString(selection.getNumSeconds())); + _durationLabel.setText(LABEL_RANGE_DURATION + DisplayUtils.buildDurationString(selection.getNumSeconds())); _aveSpeedLabel.setText(I18nManager.getText("details.range.avespeed") + ": " + roundedNumber(selection.getDistance(distUnits)/selection.getNumSeconds()*3600.0) + " " + speedUnitsStr); - if (selection.getHasMultipleSegments()) { - _aveMovingSpeedLabel.setText(I18nManager.getText("details.range.avemovingspeed") + ": " - + roundedNumber(selection.getMovingDistance(distUnits)/selection.getMovingSeconds()*3600.0) + " " + speedUnitsStr); - } - else { - _aveMovingSpeedLabel.setText(null); - } - if (Config.getConfigBoolean(Config.KEY_SHOW_PACE)) { - _paceLabel.setText(I18nManager.getText("details.range.pace") + ": " - + buildDurationString((long) (selection.getNumSeconds()/selection.getDistance(distUnits))) - + " / " + distUnitsStr); - } - else { - _paceLabel.setText(""); - } } else { _durationLabel.setText(""); _aveSpeedLabel.setText(""); - _aveMovingSpeedLabel.setText(""); - _paceLabel.setText(""); } String altUnitsLabel = getAltitudeUnitsLabel(selection.getAltitudeFormat()); IntegerRange altRange = selection.getAltitudeRange(); @@ -357,6 +350,7 @@ public class DetailsDisplay extends GenericDisplay _photoTimestampLabel.setText(""); _photoConnectedLabel.setText(""); _photoThumbnail.setVisible(false); + _rotationButtons.setVisible(false); } else { @@ -368,6 +362,8 @@ public class DetailsDisplay extends GenericDisplay I18nManager.getText("dialog.about.no"):I18nManager.getText("dialog.about.yes"))); _photoThumbnail.setVisible(true); _photoThumbnail.setPhoto(currentPhoto); + _rotationButtons.setVisible(true); + if ((inUpdateType & DataSubscriber.PHOTOS_MODIFIED) > 0) {_photoThumbnail.refresh();} } _photoThumbnail.repaint(); } @@ -413,26 +409,6 @@ public class DetailsDisplay extends GenericDisplay } - /** - * Build a String to describe a time duration - * @param inNumSecs number of seconds - * @return time as a string, days, hours, mins, secs as appropriate - */ - private static String buildDurationString(long inNumSecs) - { - if (inNumSecs <= 0L) return ""; - if (inNumSecs < 60L) return "" + inNumSecs + I18nManager.getText("display.range.time.secs"); - if (inNumSecs < 3600L) return "" + (inNumSecs / 60) + I18nManager.getText("display.range.time.mins") - + " " + (inNumSecs % 60) + I18nManager.getText("display.range.time.secs"); - if (inNumSecs < 86400L) return "" + (inNumSecs / 60 / 60) + I18nManager.getText("display.range.time.hours") - + " " + ((inNumSecs / 60) % 60) + I18nManager.getText("display.range.time.mins"); - if (inNumSecs < 432000L) return "" + (inNumSecs / 86400L) + I18nManager.getText("display.range.time.days") - + " " + (inNumSecs / 60 / 60) % 24 + I18nManager.getText("display.range.time.hours"); - if (inNumSecs < 8640000L) return "" + (inNumSecs / 86400L) + I18nManager.getText("display.range.time.days"); - return "big"; - } - - /** * Format a number to a sensible precision * @param inDist distance @@ -453,4 +429,19 @@ public class DetailsDisplay extends GenericDisplay _distanceFormatter.setMinimumFractionDigits(numDigits); return _distanceFormatter.format(inDist); } + + /** + * Create a little button for rotating the current photo + * @param inIcon icon to use (from IconManager) + * @param inFunction function to call (from FunctionLibrary) + * @return button object + */ + private static JButton makeRotateButton(String inIcon, GenericFunction inFunction) + { + JButton button = new JButton(IconManager.getImageIcon(inIcon)); + button.setToolTipText(I18nManager.getText(inFunction.getNameKey())); + button.setMargin(new Insets(0, 2, 0, 2)); + button.addActionListener(new FunctionLauncher(inFunction)); + return button; + } } diff --git a/tim/prune/gui/DisplayUtils.java b/tim/prune/gui/DisplayUtils.java new file mode 100644 index 0000000..f34afd7 --- /dev/null +++ b/tim/prune/gui/DisplayUtils.java @@ -0,0 +1,28 @@ +package tim.prune.gui; + +import tim.prune.I18nManager; + +/** + * Class to provide general display util methods + */ +public abstract class DisplayUtils +{ + /** + * Build a String to describe a time duration + * @param inNumSecs number of seconds + * @return time as a string, days, hours, mins, secs as appropriate + */ + public static String buildDurationString(long inNumSecs) + { + if (inNumSecs <= 0L) return ""; + if (inNumSecs < 60L) return "" + inNumSecs + I18nManager.getText("display.range.time.secs"); + if (inNumSecs < 3600L) return "" + (inNumSecs / 60) + I18nManager.getText("display.range.time.mins") + + " " + (inNumSecs % 60) + I18nManager.getText("display.range.time.secs"); + if (inNumSecs < 86400L) return "" + (inNumSecs / 60 / 60) + I18nManager.getText("display.range.time.hours") + + " " + ((inNumSecs / 60) % 60) + I18nManager.getText("display.range.time.mins"); + if (inNumSecs < 432000L) return "" + (inNumSecs / 86400L) + I18nManager.getText("display.range.time.days") + + " " + (inNumSecs / 60 / 60) % 24 + I18nManager.getText("display.range.time.hours"); + if (inNumSecs < 8640000L) return "" + (inNumSecs / 86400L) + I18nManager.getText("display.range.time.days"); + return "big"; + } +} diff --git a/tim/prune/gui/GenericChart.java b/tim/prune/gui/GenericChart.java index 731b91c..ae2feac 100644 --- a/tim/prune/gui/GenericChart.java +++ b/tim/prune/gui/GenericChart.java @@ -7,6 +7,8 @@ import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import tim.prune.I18nManager; +import tim.prune.config.ColourScheme; +import tim.prune.config.Config; import tim.prune.data.TrackInfo; @@ -19,9 +21,6 @@ public abstract class GenericChart extends GenericDisplay implements MouseListen protected static final int BORDER_WIDTH = 8; // Colours - private static final Color COLOR_BORDER_BG = Color.WHITE; - private static final Color COLOR_CHART_BG = Color.WHITE; - private static final Color COLOR_CHART_LINE = Color.BLACK; private static final Color COLOR_NODATA_TEXT = Color.GRAY; @@ -51,12 +50,17 @@ public abstract class GenericChart extends GenericDisplay implements MouseListen super.paint(inG); int width = getWidth(); int height = getHeight(); + // Get colours + ColourScheme colourScheme = Config.getColourScheme(); + final Color borderColour = colourScheme.getColour(ColourScheme.IDX_BORDERS); + final Color backgroundColour = colourScheme.getColour(ColourScheme.IDX_BACKGROUND); + final Color insideColour = backgroundColour; // border background - inG.setColor(COLOR_BORDER_BG); + inG.setColor(backgroundColour); inG.fillRect(0, 0, width, height); if (width < 2*BORDER_WIDTH || height < 2*BORDER_WIDTH) return; // blank graph area, with line border - inG.setColor(COLOR_CHART_BG); + inG.setColor(insideColour); inG.fillRect(BORDER_WIDTH, BORDER_WIDTH, width - 2*BORDER_WIDTH, height-2*BORDER_WIDTH); // Display message if no data to be displayed if (_track == null || _track.getNumPoints() <= 0) @@ -65,7 +69,7 @@ public abstract class GenericChart extends GenericDisplay implements MouseListen inG.drawString(I18nManager.getText("display.nodata"), 50, height/2); } else { - inG.setColor(COLOR_CHART_LINE); + inG.setColor(borderColour); inG.drawRect(BORDER_WIDTH, BORDER_WIDTH, width - 2*BORDER_WIDTH, height-2*BORDER_WIDTH); } } diff --git a/tim/prune/gui/GuiGridLayout.java b/tim/prune/gui/GuiGridLayout.java new file mode 100644 index 0000000..cb3572b --- /dev/null +++ b/tim/prune/gui/GuiGridLayout.java @@ -0,0 +1,61 @@ +package tim.prune.gui; + +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; + +import javax.swing.JComponent; +import javax.swing.JPanel; + +/** + * Class to make it easier to use GridBagLayout + * for a two-column, non-equal-width layout + */ +public class GuiGridLayout +{ + private GridBagLayout _layout = null; + private GridBagConstraints _constraints = null; + private JPanel _panel = null; + private int _x = 0; + private int _y = 0; + + /** + * Constructor + * @param inPanel panel using layout + */ + public GuiGridLayout(JPanel inPanel) + { + _panel = inPanel; + _layout = new GridBagLayout(); + _constraints = new GridBagConstraints(); + _constraints.weightx = 1.0; + _constraints.weighty = 0.0; + _constraints.ipadx = 10; + _constraints.ipady = 1; + _constraints.insets = new Insets(1, 5, 1, 5); + // Apply layout to panel + _panel.setLayout(_layout); + } + + /** + * Add the given component to the grid + * @param inComponent component to add + */ + public void add(JComponent inComponent) + { + _constraints.gridx = _x; + _constraints.gridy = _y; + _constraints.weightx = (_x==0?0.5:1.0); + // set anchor + _constraints.anchor = (_x == 0?GridBagConstraints.LINE_END:GridBagConstraints.LINE_START); + _layout.setConstraints(inComponent, _constraints); + // add to panel + _panel.add(inComponent); + // work out next position + _x++; + if (_x > 1) { + _x = 0; + _y++; + } + } +} diff --git a/tim/prune/gui/IconManager.java b/tim/prune/gui/IconManager.java index 85a182a..a42d759 100644 --- a/tim/prune/gui/IconManager.java +++ b/tim/prune/gui/IconManager.java @@ -56,6 +56,10 @@ public abstract class IconManager /** Icon for cut range and move */ public static final String CUT_AND_MOVE = "cut_and_move.gif"; + /** Icon for rotating photos leftwards */ + public static final String ROTATE_LEFT = "rotate_left_icon.png"; + /** Icon for rotating photos rightwards */ + public static final String ROTATE_RIGHT = "rotate_right_icon.png"; /** * Get the specified image diff --git a/tim/prune/gui/ImageUtils.java b/tim/prune/gui/ImageUtils.java index 4b46959..3fa7a1a 100644 --- a/tim/prune/gui/ImageUtils.java +++ b/tim/prune/gui/ImageUtils.java @@ -2,6 +2,7 @@ package tim.prune.gui; import java.awt.Dimension; import java.awt.Graphics; +import java.awt.Graphics2D; import java.awt.Image; import java.awt.image.BufferedImage; import java.awt.image.ConvolveOp; @@ -69,11 +70,7 @@ public abstract class ImageUtils */ public static Dimension getThumbnailSize(int inOrigWidth, int inOrigHeight, int inMaxWidth, int inMaxHeight) { - if (inMaxWidth <= 0 || inMaxHeight <= 0) - { - //System.out.println("Can't do it - maxwidth=" + inMaxWidth + ", maxheight=" + inMaxHeight); - return new Dimension(0,0); - } + assert(inMaxWidth > 0 && inMaxHeight > 0); // work out maximum zoom ratio available so that thumbnail isn't too big double xZoom = inMaxWidth * 1.0 / inOrigWidth; double yZoom = inMaxHeight * 1.0 / inOrigHeight; @@ -83,4 +80,53 @@ public abstract class ImageUtils // calculate new width and height return new Dimension ((int) (zoom * inOrigWidth), (int) (zoom * inOrigHeight)); } + + + /** + * Create a new image by rotating and scaling the given one + * @param inImage input image + * @param inMaxWidth maximum width of output image + * @param inMaxHeight maximum height of output image + * @param inRotationDegrees number of degrees to rotate clockwise (0, 90, 180 or 270) + * @return rotated, scaled image + */ + public static BufferedImage rotateImage(Image inImage, int inMaxWidth, int inMaxHeight, int inRotationDegrees) + { + // Create scaled image of suitable size + boolean isRotated = (inRotationDegrees % 180 != 0); + int origWidth = inImage.getWidth(null); + int origHeight = inImage.getHeight(null); + int thumbWidth = isRotated?origHeight:origWidth; + int thumbHeight = isRotated?origWidth:origHeight; + Dimension scaledSize = getThumbnailSize(thumbWidth, thumbHeight, inMaxWidth, inMaxHeight); + BufferedImage result = new BufferedImage(scaledSize.width, scaledSize.height, BufferedImage.TYPE_INT_RGB); + // Do different things according to rotation angle (a bit messy, sorry!) + if (inRotationDegrees == 0) + { + // Not rotated, so just copy image directly + result.getGraphics().drawImage(inImage, 0, 0, scaledSize.width, scaledSize.height, null); + } + else + { + // Need to use Graphics2D for rotation, not Graphics + Graphics2D g2d = result.createGraphics(); + switch (inRotationDegrees) + { + case 90: + g2d.rotate(Math.PI / 2, 0.0, 0.0); + g2d.drawImage(inImage, 0, -scaledSize.width, scaledSize.height, scaledSize.width, null); + break; + case 180: + g2d.rotate(Math.PI, scaledSize.width/2.0, scaledSize.height/2.0); + g2d.drawImage(inImage, 0, 0, scaledSize.width, scaledSize.height, null); + break; + case 270: + g2d.rotate(Math.PI * 3/2, 0.0, 0.0); + g2d.drawImage(inImage, -scaledSize.height, 0, scaledSize.height, scaledSize.width, null); + } + // Clear up memory + g2d.dispose(); + } + return result; + } } diff --git a/tim/prune/gui/MenuManager.java b/tim/prune/gui/MenuManager.java index cbf25af..998a533 100644 --- a/tim/prune/gui/MenuManager.java +++ b/tim/prune/gui/MenuManager.java @@ -14,12 +14,13 @@ import javax.swing.JToolBar; import javax.swing.KeyStroke; import tim.prune.App; -import tim.prune.Config; import tim.prune.DataSubscriber; import tim.prune.FunctionLibrary; import tim.prune.GenericFunction; import tim.prune.I18nManager; import tim.prune.UpdateMessageBroker; +import tim.prune.config.Config; +import tim.prune.data.Photo; import tim.prune.data.PhotoList; import tim.prune.data.Selection; import tim.prune.data.Track; @@ -59,23 +60,30 @@ public class MenuManager implements DataSubscriber private JMenuItem _selectStartItem = null; private JMenuItem _selectEndItem = null; private JMenuItem _findWaypointItem = null; + private JMenuItem _duplicatePointItem = null; private JMenuItem _reverseItem = null; private JMenuItem _addTimeOffsetItem = null; private JMenuItem _addAltitudeOffsetItem = null; private JMenuItem _mergeSegmentsItem = null; private JMenu _rearrangeMenu = null; private JMenuItem _cutAndMoveItem = null; + private JMenuItem _convertNamesToTimesItem = null; + private JCheckBoxMenuItem _mapCheckbox = null; private JMenuItem _show3dItem = null; private JMenu _browserMapMenu = null; private JMenuItem _chartItem = null; - private JCheckBoxMenuItem _paceCheckbox = null; private JMenuItem _getGpsiesItem = null; private JMenuItem _distanceItem = null; + private JMenuItem _fullRangeDetailsItem = null; private JMenuItem _saveExifItem = null; private JMenuItem _connectPhotoItem = null; private JMenuItem _deletePhotoItem = null; private JMenuItem _disconnectPhotoItem = null; private JMenuItem _correlatePhotosItem = null; + private JMenuItem _rearrangePhotosItem = null; + private JMenuItem _rotatePhotoLeft = null; + private JMenuItem _rotatePhotoRight = null; + private JMenuItem _ignoreExifThumb = null; // ActionListeners for reuse by menu and toolbar private ActionListener _openFileAction = null; @@ -196,9 +204,9 @@ public class MenuManager implements DataSubscriber }); fileMenu.add(exitMenuItem); menubar.add(fileMenu); - // Edit menu - JMenu editMenu = new JMenu(I18nManager.getText("menu.edit")); - setAltKey(editMenu, "altkey.menu.edit"); + // Track menu + JMenu trackMenu = new JMenu(I18nManager.getText("menu.track")); + setAltKey(trackMenu, "altkey.menu.track"); _undoItem = new JMenuItem(I18nManager.getText("menu.edit.undo")); setShortcut(_undoItem, "shortcut.menu.edit.undo"); _undoAction = new ActionListener() { @@ -209,7 +217,7 @@ public class MenuManager implements DataSubscriber }; _undoItem.addActionListener(_undoAction); _undoItem.setEnabled(false); - editMenu.add(_undoItem); + trackMenu.add(_undoItem); _clearUndoItem = new JMenuItem(I18nManager.getText("menu.edit.clearundo")); _clearUndoItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) @@ -218,46 +226,12 @@ public class MenuManager implements DataSubscriber } }); _clearUndoItem.setEnabled(false); - editMenu.add(_clearUndoItem); - editMenu.addSeparator(); - _editPointItem = new JMenuItem(I18nManager.getText("menu.edit.editpoint")); - _editPointAction = new ActionListener() { - public void actionPerformed(ActionEvent e) - { - _app.editCurrentPoint(); - } - }; - _editPointItem.addActionListener(_editPointAction); - _editPointItem.setEnabled(false); - editMenu.add(_editPointItem); - _editWaypointNameItem = makeMenuItem(FunctionLibrary.FUNCTION_EDIT_WAYPOINT_NAME); - _editWaypointNameItem.setEnabled(false); - editMenu.add(_editWaypointNameItem); - _deletePointItem = new JMenuItem(I18nManager.getText("menu.edit.deletepoint")); - _deletePointAction = new ActionListener() { - public void actionPerformed(ActionEvent e) - { - _app.deleteCurrentPoint(); - } - }; - _deletePointItem.addActionListener(_deletePointAction); - _deletePointItem.setEnabled(false); - editMenu.add(_deletePointItem); - _deleteRangeItem = new JMenuItem(I18nManager.getText("menu.edit.deleterange")); - _deleteRangeAction = new ActionListener() { - public void actionPerformed(ActionEvent e) - { - _app.deleteSelectedRange(); - } - }; - _deleteRangeItem.addActionListener(_deleteRangeAction); - _deleteRangeItem.setEnabled(false); - editMenu.add(_deleteRangeItem); - editMenu.addSeparator(); + trackMenu.add(_clearUndoItem); + trackMenu.addSeparator(); _compressItem = makeMenuItem(FunctionLibrary.FUNCTION_COMPRESS); setShortcut(_compressItem, "shortcut.menu.edit.compress"); _compressItem.setEnabled(false); - editMenu.add(_compressItem); + trackMenu.add(_compressItem); _deleteMarkedPointsItem = new JMenuItem(I18nManager.getText("menu.edit.deletemarked")); _deleteMarkedPointsItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) @@ -266,50 +240,8 @@ public class MenuManager implements DataSubscriber } }); _deleteMarkedPointsItem.setEnabled(false); - editMenu.add(_deleteMarkedPointsItem); - editMenu.addSeparator(); - _interpolateItem = new JMenuItem(I18nManager.getText("menu.edit.interpolate")); - _interpolateItem.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) - { - _app.interpolateSelection(); - } - }); - _interpolateItem.setEnabled(false); - editMenu.add(_interpolateItem); - _averageItem = new JMenuItem(I18nManager.getText("menu.edit.average")); - _averageItem.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) - { - _app.averageSelection(); - } - }); - _averageItem.setEnabled(false); - editMenu.add(_averageItem); - _reverseItem = new JMenuItem(I18nManager.getText("menu.edit.reverse")); - _reverseItem.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) - { - _app.reverseRange(); - } - }); - _reverseItem.setEnabled(false); - editMenu.add(_reverseItem); - _addTimeOffsetItem = makeMenuItem(FunctionLibrary.FUNCTION_ADD_TIME_OFFSET); - _addTimeOffsetItem.setEnabled(false); - editMenu.add(_addTimeOffsetItem); - _addAltitudeOffsetItem = makeMenuItem(FunctionLibrary.FUNCTION_ADD_ALTITUDE_OFFSET); - _addAltitudeOffsetItem.setEnabled(false); - editMenu.add(_addAltitudeOffsetItem); - _mergeSegmentsItem = new JMenuItem(I18nManager.getText("menu.edit.mergetracksegments")); - _mergeSegmentsItem.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) - { - _app.mergeTrackSegments(); - } - }); - _mergeSegmentsItem.setEnabled(false); - editMenu.add(_mergeSegmentsItem); + trackMenu.add(_deleteMarkedPointsItem); + trackMenu.addSeparator(); // Rearrange waypoints _rearrangeMenu = new JMenu(I18nManager.getText("menu.edit.rearrange")); _rearrangeMenu.setEnabled(false); @@ -340,21 +272,16 @@ public class MenuManager implements DataSubscriber }); rearrangeNearestItem.setEnabled(true); _rearrangeMenu.add(rearrangeNearestItem); - editMenu.add(_rearrangeMenu); - _cutAndMoveItem = new JMenuItem(I18nManager.getText("menu.edit.cutandmove")); - _cutAndMoveItem.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) - { - _app.cutAndMoveSelection(); - } - }); - _cutAndMoveItem.setEnabled(false); - editMenu.add(_cutAndMoveItem); - menubar.add(editMenu); + trackMenu.add(_rearrangeMenu); + // Get gpsies tracks + _getGpsiesItem = makeMenuItem(FunctionLibrary.FUNCTION_GET_GPSIES); + _getGpsiesItem.setEnabled(false); + trackMenu.add(_getGpsiesItem); + menubar.add(trackMenu); - // Select menu - JMenu selectMenu = new JMenu(I18nManager.getText("menu.select")); - setAltKey(selectMenu, "altkey.menu.select"); + // Range menu + JMenu rangeMenu = new JMenu(I18nManager.getText("menu.range")); + setAltKey(rangeMenu, "altkey.menu.range"); _selectAllItem = new JMenuItem(I18nManager.getText("menu.select.all")); setShortcut(_selectAllItem, "shortcut.menu.select.all"); _selectAllItem.setEnabled(false); @@ -364,7 +291,7 @@ public class MenuManager implements DataSubscriber _selection.selectRange(0, _track.getNumPoints()-1); } }); - selectMenu.add(_selectAllItem); + rangeMenu.add(_selectAllItem); _selectNoneItem = new JMenuItem(I18nManager.getText("menu.select.none")); _selectNoneItem.setEnabled(false); _selectNoneItem.addActionListener(new ActionListener() { @@ -373,8 +300,8 @@ public class MenuManager implements DataSubscriber _app.selectNone(); } }); - selectMenu.add(_selectNoneItem); - selectMenu.addSeparator(); + rangeMenu.add(_selectNoneItem); + rangeMenu.addSeparator(); _selectStartItem = new JMenuItem(I18nManager.getText("menu.select.start")); _selectStartItem.setEnabled(false); _selectStartAction = new ActionListener() { @@ -384,7 +311,7 @@ public class MenuManager implements DataSubscriber } }; _selectStartItem.addActionListener(_selectStartAction); - selectMenu.add(_selectStartItem); + rangeMenu.add(_selectStartItem); _selectEndItem = new JMenuItem(I18nManager.getText("menu.select.end")); _selectEndItem.setEnabled(false); _selectEndAction = new ActionListener() { @@ -394,16 +321,128 @@ public class MenuManager implements DataSubscriber } }; _selectEndItem.addActionListener(_selectEndAction); - selectMenu.add(_selectEndItem); - selectMenu.addSeparator(); + rangeMenu.add(_selectEndItem); + rangeMenu.addSeparator(); + _deleteRangeItem = new JMenuItem(I18nManager.getText("menu.edit.deleterange")); + _deleteRangeAction = new ActionListener() { + public void actionPerformed(ActionEvent e) + { + _app.deleteSelectedRange(); + } + }; + _deleteRangeItem.addActionListener(_deleteRangeAction); + _deleteRangeItem.setEnabled(false); + rangeMenu.add(_deleteRangeItem); + _reverseItem = new JMenuItem(I18nManager.getText("menu.edit.reverse")); + _reverseItem.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) + { + _app.reverseRange(); + } + }); + _reverseItem.setEnabled(false); + rangeMenu.add(_reverseItem); + _addTimeOffsetItem = makeMenuItem(FunctionLibrary.FUNCTION_ADD_TIME_OFFSET); + _addTimeOffsetItem.setEnabled(false); + rangeMenu.add(_addTimeOffsetItem); + _addAltitudeOffsetItem = makeMenuItem(FunctionLibrary.FUNCTION_ADD_ALTITUDE_OFFSET); + _addAltitudeOffsetItem.setEnabled(false); + rangeMenu.add(_addAltitudeOffsetItem); + _mergeSegmentsItem = new JMenuItem(I18nManager.getText("menu.edit.mergetracksegments")); + _mergeSegmentsItem.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) + { + _app.mergeTrackSegments(); + } + }); + _mergeSegmentsItem.setEnabled(false); + rangeMenu.add(_mergeSegmentsItem); + rangeMenu.addSeparator(); + _interpolateItem = new JMenuItem(I18nManager.getText("menu.edit.interpolate")); + _interpolateItem.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) + { + _app.interpolateSelection(); + } + }); + _interpolateItem.setEnabled(false); + rangeMenu.add(_interpolateItem); + _averageItem = new JMenuItem(I18nManager.getText("menu.edit.average")); + _averageItem.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) + { + _app.averageSelection(); + } + }); + _averageItem.setEnabled(false); + rangeMenu.add(_averageItem); + _cutAndMoveItem = new JMenuItem(I18nManager.getText("menu.edit.cutandmove")); + _cutAndMoveItem.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) + { + _app.cutAndMoveSelection(); + } + }); + _cutAndMoveItem.setEnabled(false); + rangeMenu.add(_cutAndMoveItem); + _convertNamesToTimesItem = makeMenuItem(FunctionLibrary.FUNCTION_CONVERT_NAMES_TO_TIMES); + _convertNamesToTimesItem.setEnabled(false); + rangeMenu.add(_convertNamesToTimesItem); + menubar.add(rangeMenu); + + // Point menu + JMenu pointMenu = new JMenu(I18nManager.getText("menu.point")); + setAltKey(pointMenu, "altkey.menu.point"); + _editPointItem = new JMenuItem(I18nManager.getText("menu.edit.editpoint")); + _editPointAction = new ActionListener() { + public void actionPerformed(ActionEvent e) + { + _app.editCurrentPoint(); + } + }; + _editPointItem.addActionListener(_editPointAction); + _editPointItem.setEnabled(false); + pointMenu.add(_editPointItem); + _editWaypointNameItem = makeMenuItem(FunctionLibrary.FUNCTION_EDIT_WAYPOINT_NAME); + _editWaypointNameItem.setEnabled(false); + pointMenu.add(_editWaypointNameItem); + _deletePointItem = new JMenuItem(I18nManager.getText("menu.edit.deletepoint")); + _deletePointAction = new ActionListener() { + public void actionPerformed(ActionEvent e) + { + _app.deleteCurrentPoint(); + } + }; + _deletePointItem.addActionListener(_deletePointAction); + _deletePointItem.setEnabled(false); + pointMenu.add(_deletePointItem); + pointMenu.addSeparator(); + // find a waypoint _findWaypointItem = makeMenuItem(FunctionLibrary.FUNCTION_FIND_WAYPOINT); _findWaypointItem.setEnabled(false); - selectMenu.add(_findWaypointItem); - menubar.add(selectMenu); + pointMenu.add(_findWaypointItem); + // duplicate current point + _duplicatePointItem = makeMenuItem(FunctionLibrary.FUNCTION_DUPLICATE_POINT); + _duplicatePointItem.setEnabled(false); + pointMenu.add(_duplicatePointItem); + // paste coordinates function + JMenuItem pasteCoordsItem = makeMenuItem(FunctionLibrary.FUNCTION_PASTE_COORDINATES); + pointMenu.add(pasteCoordsItem); + menubar.add(pointMenu); // Add view menu JMenu viewMenu = new JMenu(I18nManager.getText("menu.view")); setAltKey(viewMenu, "altkey.menu.view"); + // Turn map display on/off + _mapCheckbox = new JCheckBoxMenuItem( + I18nManager.getText("menu.map.showmap"), false); + _mapCheckbox.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + Config.setConfigBoolean(Config.KEY_SHOW_MAP, _mapCheckbox.isSelected()); + UpdateMessageBroker.informSubscribers(); + } + }); + viewMenu.add(_mapCheckbox); _show3dItem = makeMenuItem(FunctionLibrary.FUNCTION_3D); _show3dItem.setEnabled(false); viewMenu.add(_show3dItem); @@ -442,6 +481,14 @@ public class MenuManager implements DataSubscriber } }); _browserMapMenu.add(yahooMapsItem); + JMenuItem bingMapsItem = new JMenuItem(I18nManager.getText("menu.view.browser.bing")); + bingMapsItem.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) + { + _app.showExternalMap(UrlGenerator.MAP_SOURCE_BING); + } + }); + _browserMapMenu.add(bingMapsItem); viewMenu.add(_browserMapMenu); // Charts _chartItem = makeMenuItem(FunctionLibrary.FUNCTION_CHARTS); @@ -451,10 +498,10 @@ public class MenuManager implements DataSubscriber _distanceItem = makeMenuItem(FunctionLibrary.FUNCTION_DISTANCES); _distanceItem.setEnabled(false); viewMenu.add(_distanceItem); - // Get gpsies tracks - _getGpsiesItem = makeMenuItem(FunctionLibrary.FUNCTION_GET_GPSIES); - _getGpsiesItem.setEnabled(false); - viewMenu.add(_getGpsiesItem); + // full range details + _fullRangeDetailsItem = makeMenuItem(FunctionLibrary.FUNCTION_FULL_RANGE_DETAILS); + _fullRangeDetailsItem.setEnabled(false); + viewMenu.add(_fullRangeDetailsItem); menubar.add(viewMenu); // Add photo menu @@ -502,11 +549,25 @@ public class MenuManager implements DataSubscriber }); _deletePhotoItem.setEnabled(false); photoMenu.add(_deletePhotoItem); + // Rotate current photo + _rotatePhotoLeft = makeMenuItem(FunctionLibrary.FUNCTION_ROTATE_PHOTO_LEFT); + _rotatePhotoLeft.setEnabled(false); + photoMenu.add(_rotatePhotoLeft); + _rotatePhotoRight = makeMenuItem(FunctionLibrary.FUNCTION_ROTATE_PHOTO_RIGHT); + _rotatePhotoRight.setEnabled(false); + photoMenu.add(_rotatePhotoRight); + _ignoreExifThumb = makeMenuItem(FunctionLibrary.FUNCTION_IGNORE_EXIF_THUMB); + _ignoreExifThumb.setEnabled(false); + photoMenu.add(_ignoreExifThumb); photoMenu.addSeparator(); // correlate all photos _correlatePhotosItem = makeMenuItem(FunctionLibrary.FUNCTION_CORRELATE_PHOTOS); _correlatePhotosItem.setEnabled(false); photoMenu.add(_correlatePhotosItem); + // rearrange photo points + _rearrangePhotosItem = makeMenuItem(FunctionLibrary.FUNCTION_REARRANGE_PHOTOS); + _rearrangePhotosItem.setEnabled(false); + photoMenu.add(_rearrangePhotosItem); menubar.add(photoMenu); // Settings menu @@ -515,22 +576,18 @@ public class MenuManager implements DataSubscriber // Set the map background JMenuItem mapBgItem = makeMenuItem(FunctionLibrary.FUNCTION_SET_MAP_BG); settingsMenu.add(mapBgItem); - // Turn pace display on/off - _paceCheckbox = new JCheckBoxMenuItem( - I18nManager.getText("menu.settings.showpace"), false); - _paceCheckbox.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - Config.setConfigBoolean(Config.KEY_SHOW_PACE, _paceCheckbox.isSelected()); - UpdateMessageBroker.informSubscribers(); - } - }); - settingsMenu.add(_paceCheckbox); // Set kmz image size JMenuItem setKmzImageSizeItem = makeMenuItem(FunctionLibrary.FUNCTION_SET_KMZ_IMAGE_SIZE); settingsMenu.add(setKmzImageSizeItem); // Set program paths JMenuItem setPathsItem = makeMenuItem(FunctionLibrary.FUNCTION_SET_PATHS); settingsMenu.add(setPathsItem); + // Set colours + JMenuItem setColoursItem = makeMenuItem(FunctionLibrary.FUNCTION_SET_COLOURS); + settingsMenu.add(setColoursItem); + // Set language + JMenuItem setLanguageItem = makeMenuItem(FunctionLibrary.FUNCTION_SET_LANGUAGE); + settingsMenu.add(setLanguageItem); settingsMenu.addSeparator(); // Save configuration JMenuItem saveConfigMenuItem = makeMenuItem(FunctionLibrary.FUNCTION_SAVECONFIG); @@ -729,20 +786,25 @@ public class MenuManager implements DataSubscriber _selectStartButton.setEnabled(hasPoint); _selectEndItem.setEnabled(hasPoint); _selectEndButton.setEnabled(hasPoint); + _duplicatePointItem.setEnabled(hasPoint); // are there any photos? boolean anyPhotos = _photos != null && _photos.getNumPhotos() > 0; _saveExifItem.setEnabled(anyPhotos); // is there a current photo? boolean hasPhoto = anyPhotos && _selection.getCurrentPhotoIndex() >= 0; // connect is available if photo and point selected, and photo has no point - boolean connectAvailable = hasPhoto && hasPoint && _photos.getPhoto(_selection.getCurrentPhotoIndex()) != null - && _photos.getPhoto(_selection.getCurrentPhotoIndex()).getDataPoint() == null; + Photo currentPhoto = _photos.getPhoto(_selection.getCurrentPhotoIndex()); + boolean connectAvailable = hasPhoto && hasPoint && currentPhoto != null + && currentPhoto.getDataPoint() == null; _connectPhotoItem.setEnabled(connectAvailable); _connectPhotoButton.setEnabled(connectAvailable); - _disconnectPhotoItem.setEnabled(hasPhoto && _photos.getPhoto(_selection.getCurrentPhotoIndex()) != null - && _photos.getPhoto(_selection.getCurrentPhotoIndex()).getDataPoint() != null); + _disconnectPhotoItem.setEnabled(hasPhoto && currentPhoto != null && currentPhoto.getDataPoint() != null); _correlatePhotosItem.setEnabled(anyPhotos && hasData); + _rearrangePhotosItem.setEnabled(anyPhotos && hasData && _track.getNumPoints() > 1); _deletePhotoItem.setEnabled(hasPhoto); + _rotatePhotoLeft.setEnabled(hasPhoto); + _rotatePhotoRight.setEnabled(hasPhoto); + _ignoreExifThumb.setEnabled(hasPhoto && currentPhoto != null && currentPhoto.getExifThumbnail() != null); // is there a current range? boolean hasRange = (hasData && _selection.hasRangeSelected()); _deleteRangeItem.setEnabled(hasRange); @@ -754,10 +816,17 @@ public class MenuManager implements DataSubscriber _reverseItem.setEnabled(hasRange); _addTimeOffsetItem.setEnabled(hasRange); _addAltitudeOffsetItem.setEnabled(hasRange); + _convertNamesToTimesItem.setEnabled(hasRange && _track.hasWaypoints()); + _fullRangeDetailsItem.setEnabled(hasRange); // Is the currently selected point outside the current range? _cutAndMoveItem.setEnabled(hasRange && hasPoint && (_selection.getCurrentPointIndex() < _selection.getStart() || _selection.getCurrentPointIndex() > (_selection.getEnd()+1))); + // Has the map been switched on/off? + boolean mapsOn = Config.getConfigBoolean(Config.KEY_SHOW_MAP); + if (_mapCheckbox.isSelected() != mapsOn) { + _mapCheckbox.setSelected(mapsOn); + } } diff --git a/tim/prune/gui/PhotoThumbnail.java b/tim/prune/gui/PhotoThumbnail.java index 2ad22fa..101f1a3 100644 --- a/tim/prune/gui/PhotoThumbnail.java +++ b/tim/prune/gui/PhotoThumbnail.java @@ -18,11 +18,9 @@ public class PhotoThumbnail extends JPanel implements Runnable { private Photo _photo = null; private BufferedImage _thumbnail = null; - private int _lastWidth = -1; - private int _lastHeight = -1; private boolean _loadingImage = false; /** String to show before photo is loaded */ - private static final String _loadingString = I18nManager.getText("details.photo.loading") + " ..."; + private static final String LOADING_STRING = I18nManager.getText("details.photo.loading") + " ..."; /** @@ -30,7 +28,6 @@ public class PhotoThumbnail extends JPanel implements Runnable */ public PhotoThumbnail() { - // TODO: Make size of thumbnail dynamic, as big as it can be setOpaque(true); } @@ -42,11 +39,19 @@ public class PhotoThumbnail extends JPanel implements Runnable public void setPhoto(Photo inPhoto) { // Check whether the photo has changed - if (_photo == inPhoto) {return;} - _photo = inPhoto; - _thumbnail = null; + if (_photo != inPhoto) { + _photo = inPhoto; + _thumbnail = null; + } + repaint(); } + /** + * Force a refresh / reload + */ + public void refresh() { + _thumbnail = null; + } /** * Override paint method @@ -57,29 +62,34 @@ public class PhotoThumbnail extends JPanel implements Runnable super.paint(inG); if (_photo != null) { - // recalculate thumbnail if photo has changed - if (_thumbnail == null || getWidth() != _lastWidth || getHeight() != _lastHeight) + // read thumbnail in separate thread + if (_thumbnail == null && !_loadingImage) { - // initiate load if not already started - if (!_loadingImage) - { - _loadingImage = true; - new Thread(this).start(); - } + _loadingImage = true; + new Thread(this).start(); } - // Set width and height - _lastWidth = getWidth(); - _lastHeight = getHeight(); - // if loading, display image + // if loading, display message if (_loadingImage) { inG.setColor(Color.BLACK); - inG.drawString(_loadingString, 10, 30); + inG.drawString(LOADING_STRING, 10, 30); } else { - // Copy scaled, smoothed image onto the screen - inG.drawImage(_thumbnail, 0, 0, _thumbnail.getWidth(), _thumbnail.getHeight(), null); + // Copy scaled, smoothed (and rotated) image into scaled + int usableWidth = getParent().getWidth()-10; + Image scaled = ImageUtils.rotateImage(_thumbnail, usableWidth, usableWidth, _photo.getRotationDegrees()); + int scaleWidth = scaled.getWidth(null); + int scaleHeight = scaled.getHeight(null); + // Draw scaled / rotated image to component + int horizOffset = (getWidth() - scaleWidth) / 2; + int vertOffset = (getHeight() - scaleHeight) / 2; + inG.drawImage(scaled, horizOffset, vertOffset, scaleWidth, scaleHeight, null); + if (getHeight() < getWidth()) + { + setPreferredSize(new Dimension(usableWidth, usableWidth)); + invalidate(); + } } } } @@ -104,24 +114,15 @@ public class PhotoThumbnail extends JPanel implements Runnable int picHeight = _photo.getHeight(); if (picWidth > -1 && picHeight > -1) { - int displayWidth = Math.min(getWidth(), getParent().getWidth()); - int displayHeight = Math.min(getHeight(), getParent().getHeight()); - + // Just set a "reasonable" thumbnail size for now + final int DEFAULT_THUMB_SIZE = 400; // calculate maximum thumbnail size - Dimension thumbSize = ImageUtils.getThumbnailSize(picWidth, picHeight, displayWidth, displayHeight); - // Work out if need to remake image - boolean needToRemake = (_thumbnail == null) - || _thumbnail.getWidth() != thumbSize.width || _thumbnail.getHeight() != thumbSize.height; - if (thumbSize.width > 0 && thumbSize.height > 0 && needToRemake) - { - // Make icon to load image into - Image image = new ImageIcon(_photo.getFile().getAbsolutePath()).getImage(); - // save scaled, smoothed thumbnail for reuse - _thumbnail = ImageUtils.createScaledImage(image, thumbSize.width, thumbSize.height); - image = null; - // TODO: Calculate and set size of thumbnail here - // setPreferredSize(new Dimension(200, 200)); - } + Dimension thumbSize = ImageUtils.getThumbnailSize(picWidth, picHeight, DEFAULT_THUMB_SIZE, DEFAULT_THUMB_SIZE); + // Make icon to load image into + Image image = new ImageIcon(_photo.getFile().getAbsolutePath()).getImage(); + // save scaled, smoothed thumbnail for reuse + _thumbnail = ImageUtils.createScaledImage(image, thumbSize.width, thumbSize.height); + image = null; } } _loadingImage = false; diff --git a/tim/prune/gui/ProfileChart.java b/tim/prune/gui/ProfileChart.java index f7ae105..7c7b4c5 100644 --- a/tim/prune/gui/ProfileChart.java +++ b/tim/prune/gui/ProfileChart.java @@ -6,6 +6,8 @@ import java.awt.Graphics; import java.awt.event.MouseEvent; import tim.prune.I18nManager; +import tim.prune.config.ColourScheme; +import tim.prune.config.Config; import tim.prune.data.Altitude; import tim.prune.data.AltitudeRange; import tim.prune.data.Track; @@ -16,14 +18,10 @@ import tim.prune.data.TrackInfo; */ public class ProfileChart extends GenericChart { + /** Current scale factor in x direction*/ private double _xScaleFactor = 0.0; + /** Possible altitude scales to use */ private static final int[] ALTITUDE_SCALES = {10000, 5000, 2000, 1000, 500, 200, 100, 50}; - private static final Color COLOR_LINES = Color.GRAY; - private static final Color COLOR_ALT_BARS = Color.BLUE; - private static final Color COLOR_CURR_RANGE = Color.GREEN; - private static final Color COLOR_SELECTED = Color.RED; - private static final Color COLOR_SELECTED_BG = Color.ORANGE; - private static final Color COLOR_ALT_SCALE = Color.RED; /** @@ -50,10 +48,17 @@ public class ProfileChart extends GenericChart int width = getWidth(); int height = getHeight(); + // Set up colours + final Color barColour = 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 lineColour = Config.getColourScheme().getColour(ColourScheme.IDX_LINES); + // message if no altitudes in track if (!_track.hasAltitudeData()) { - g.setColor(COLOR_LINES); + g.setColor(lineColour); g.drawString(I18nManager.getText("display.noaltitudes"), 50, height/2); return; } @@ -63,7 +68,7 @@ public class ProfileChart extends GenericChart int minAltitude = altitudeRange.getMinimum(); int maxAltitude = altitudeRange.getMaximum(); int numPoints = _track.getNumPoints(); - _xScaleFactor = 1.0 * (width - 2 * BORDER_WIDTH) / numPoints; + _xScaleFactor = 1.0 * (width - 2 * BORDER_WIDTH - 1) / numPoints; double yScaleFactor = 1.0 * (height - 2 * BORDER_WIDTH) / (maxAltitude - minAltitude); int barWidth = (int) (_xScaleFactor + 1.0); int selectedPoint = _trackInfo.getSelection().getCurrentPointIndex(); @@ -77,10 +82,10 @@ public class ProfileChart extends GenericChart // horizontal lines for scale - set to round numbers eg 500m int lineScale = getLineScale(minAltitude, maxAltitude); int altitude = 0; - int y = 0; + int x = 0, y = 0; if (lineScale > 1) { - g.setColor(COLOR_LINES); + g.setColor(lineColour); while (altitude < maxAltitude) { if (altitude > minAltitude) @@ -96,22 +101,14 @@ public class ProfileChart extends GenericChart { // loop through points Altitude.Format chartFormat = altitudeRange.getFormat(); + g.setColor(barColour); for (int p = 0; p < numPoints; p++) { - int x = (int) (_xScaleFactor * p); - if (p == selectedPoint) - { - g.setColor(COLOR_SELECTED_BG); - g.fillRect(BORDER_WIDTH + x, BORDER_WIDTH+1, barWidth, height-2*BORDER_WIDTH-2); - g.setColor(COLOR_SELECTED); - } - else - { - g.setColor(COLOR_ALT_BARS); - if (p >= selectionStart && p <= selectionEnd) { - g.setColor(COLOR_CURR_RANGE); - } - } + x = (int) (_xScaleFactor * p) + 1; + if (p == selectionStart) + g.setColor(rangeColour); + else if (p == (selectionEnd+1)) + g.setColor(barColour); if (_track.getPoint(p).getAltitude().isValid()) { altitude = _track.getPoint(p).getAltitude().getValue(chartFormat); @@ -119,6 +116,21 @@ public class ProfileChart extends GenericChart g.fillRect(BORDER_WIDTH+x, height-BORDER_WIDTH - y, barWidth, y); } } + // current point (make sure it's drawn last) + if (selectedPoint > -1) + { + Altitude alt = _track.getPoint(selectedPoint).getAltitude(); + if (alt.isValid()) + { + x = (int) (_xScaleFactor * selectedPoint) + 1; + g.setColor(secondColour); + g.fillRect(BORDER_WIDTH + x, BORDER_WIDTH+1, barWidth, height-2*BORDER_WIDTH-2); + g.setColor(currentColour); + altitude = alt.getValue(chartFormat); + y = (int) (yScaleFactor * (altitude - minAltitude)); + g.fillRect(BORDER_WIDTH + x, height-BORDER_WIDTH - y, barWidth, y); + } + } } catch (NullPointerException npe) { // ignore, probably due to data being changed } @@ -128,7 +140,7 @@ public class ProfileChart extends GenericChart int textHeight = g.getFontMetrics().getHeight(); altitude = 0; y = 0; - g.setColor(COLOR_ALT_SCALE); + g.setColor(currentColour); while (altitude < maxAltitude) { if (altitude > minAltitude) @@ -217,7 +229,13 @@ public class ProfileChart extends GenericChart { // work out which data point is nearest and select it int pointNum = (int) ((e.getX() - BORDER_WIDTH) / _xScaleFactor); - _trackInfo.selectPoint(pointNum); + // If shift clicked, then extend selection + if (e.isShiftDown()) { + _trackInfo.extendSelection(pointNum); + } + else { + _trackInfo.selectPoint(pointNum); + } } } } diff --git a/tim/prune/gui/WaypointListModel.java b/tim/prune/gui/WaypointListModel.java index cbab59c..e5b4186 100644 --- a/tim/prune/gui/WaypointListModel.java +++ b/tim/prune/gui/WaypointListModel.java @@ -38,6 +38,7 @@ public class WaypointListModel extends AbstractListModel */ public Object getElementAt(int inIndex) { + if (inIndex < 0 || inIndex >= getSize()) return ""; return _waypoints.get(inIndex).getWaypointName(); } diff --git a/tim/prune/gui/images/rotate_left_icon.png b/tim/prune/gui/images/rotate_left_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..7bd3ae1f5453c1d6e7cad2d700efb6f87e12d079 GIT binary patch literal 286 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~e!3-p0EYEHRQjEnx?oJHr&dIz4a?ApJLR=X- z85iY>uC9>W+#tQLPw(h-t4q7eZyf2md9?r4jpc72?ECY0{-3AI|Ge1z_sxO7AI|^# zdi&q6_l+S(|AUMx3GxeOaCmkj4a7lHxyijpJRieg<~*45uDxt_A7f6&Y}b~;kc2!t3Ay+K+UuY7 Z=Y48s{Bbva%X*;s44$rjF6*2UngHi_Z%hCH literal 0 HcmV?d00001 diff --git a/tim/prune/gui/images/rotate_right_icon.png b/tim/prune/gui/images/rotate_right_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..cf2fd4098e71708cbe89b846a6c3d5d3f92ec4aa GIT binary patch literal 286 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~e!3-p0EYEHRQjEnx?oJHr&dIz4a?ApJLR=X- z85iY>uC9>W+#tQLPw(h-t4q7eZyf2md9?r4jpc72?ECY0{-3AI|Ge1z_sxO7AI|^# zdi&q6_l+S(|AUMx3GxeOaCmkj4a7R8Yg+e@C978y+=k_&n9Z=wK3C>FKT;kMbRy8`GZ%_Ga7#Td<Qy& literal 0 HcmV?d00001 diff --git a/tim/prune/gui/map/MapCanvas.java b/tim/prune/gui/map/MapCanvas.java index 2af4ae8..d2f36ce 100644 --- a/tim/prune/gui/map/MapCanvas.java +++ b/tim/prune/gui/map/MapCanvas.java @@ -37,7 +37,14 @@ import tim.prune.App; import tim.prune.DataSubscriber; import tim.prune.FunctionLibrary; import tim.prune.I18nManager; +import tim.prune.UpdateMessageBroker; +import tim.prune.config.ColourScheme; +import tim.prune.config.Config; +import tim.prune.data.Coordinate; +import tim.prune.data.DataPoint; import tim.prune.data.DoubleRange; +import tim.prune.data.Latitude; +import tim.prune.data.Longitude; import tim.prune.data.Selection; import tim.prune.data.Track; import tim.prune.data.TrackInfo; @@ -114,14 +121,7 @@ public class MapCanvas extends JPanel implements MouseListener, MouseMotionListe private static final int AUTOPAN_DISTANCE = 75; // Colours - private static final Color COLOR_BG = Color.WHITE; private static final Color COLOR_MESSAGES = Color.GRAY; - private static final Color COLOR_POINT = Color.BLUE; - private static final Color COLOR_POINT_DELETED = Color.RED; - private static final Color COLOR_CURR_RANGE = Color.GREEN; - private static final Color COLOR_CROSSHAIRS = Color.RED; - private static final Color COLOR_WAYPT_NAME = Color.BLACK; - private static final Color COLOR_PHOTO_PT = Color.ORANGE; /** @@ -155,7 +155,8 @@ public class MapCanvas extends JPanel implements MouseListener, MouseMotionListe { _tileCacher.clearAll(); _recalculate = true; - repaint(); + Config.setConfigBoolean(Config.KEY_SHOW_MAP, e.getStateChange() == ItemEvent.SELECTED); + UpdateMessageBroker.informSubscribers(); // to let menu know } }; _topPanel = new JPanel(); @@ -304,8 +305,10 @@ public class MapCanvas extends JPanel implements MouseListener, MouseMotionListe newPointItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { - _app.createPoint(MapUtils.getLatitudeFromY(_mapPosition.getYFromPixels(_popupMenuY, getHeight())), - MapUtils.getLongitudeFromX(_mapPosition.getXFromPixels(_popupMenuX, getWidth()))); + double lat = MapUtils.getLatitudeFromY(_mapPosition.getYFromPixels(_popupMenuY, getHeight())); + double lon = MapUtils.getLongitudeFromX(_mapPosition.getXFromPixels(_popupMenuX, getWidth())); + _app.createPoint(new DataPoint(new Latitude(lat, Coordinate.FORMAT_NONE), + new Longitude(lon, Coordinate.FORMAT_NONE), null)); }}); newPointItem.setEnabled(true); _popup.add(newPointItem); @@ -391,7 +394,7 @@ public class MapCanvas extends JPanel implements MouseListener, MouseMotionListe } else { - inG.setColor(COLOR_BG); + inG.setColor(Config.getColourScheme().getColour(ColourScheme.IDX_BACKGROUND)); inG.fillRect(0, 0, getWidth(), getHeight()); inG.setColor(COLOR_MESSAGES); inG.drawString(I18nManager.getText("display.nodata"), 50, getHeight()/2); @@ -414,14 +417,18 @@ public class MapCanvas extends JPanel implements MouseListener, MouseMotionListe // Clear map Graphics g = _mapImage.getGraphics(); - // Clear to white - g.setColor(COLOR_BG); + // Clear to background + g.setColor(Config.getColourScheme().getColour(ColourScheme.IDX_BACKGROUND)); g.fillRect(0, 0, getWidth(), getHeight()); + // Check whether maps are on or not + boolean showMap = Config.getConfigBoolean(Config.KEY_SHOW_MAP); + _mapCheckBox.setSelected(showMap); + // reset error message - if (!_mapCheckBox.isSelected()) {_shownOsmErrorAlready = false;} + if (!showMap) {_shownOsmErrorAlready = false;} // Only get map tiles if selected - if (_mapCheckBox.isSelected()) + if (showMap) { // init tile cacher _tileCacher.centreMap(_mapPosition.getZoom(), _mapPosition.getCentreTileX(), _mapPosition.getCentreTileY()); @@ -487,7 +494,7 @@ public class MapCanvas extends JPanel implements MouseListener, MouseMotionListe } _checkBounds = false; // enable / disable transparency slider - _transparencySlider.setEnabled(_mapCheckBox.isSelected()); + _transparencySlider.setEnabled(showMap); } @@ -498,33 +505,44 @@ 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); + int pointsPainted = 0; // draw track points - inG.setColor(COLOR_POINT); + inG.setColor(pointColour); int prevX = -1, prevY = -1; boolean connectPoints = _connectCheckBox.isSelected(); boolean prevPointVisible = false, currPointVisible = false; + boolean anyWaypoints = false; + boolean isWaypoint = false; for (int i=0; i<_track.getNumPoints(); i++) { int px = getWidth() / 2 + _mapPosition.getXFromCentre(_track.getX(i)); int py = getHeight() / 2 + _mapPosition.getYFromCentre(_track.getY(i)); currPointVisible = px >= 0 && px < getWidth() && py >= 0 && py < getHeight(); + isWaypoint = _track.getPoint(i).isWaypoint(); + anyWaypoints = anyWaypoints || isWaypoint; if (currPointVisible) { - if (!_track.getPoint(i).isWaypoint()) + if (!isWaypoint) { // Draw rectangle for track point if (_track.getPoint(i).getDeleteFlag()) { - inG.setColor(COLOR_POINT_DELETED); + inG.setColor(currentColour); } else { - inG.setColor(COLOR_POINT); + inG.setColor(pointColour); } inG.drawRect(px-2, py-2, 3, 3); pointsPainted++; } } - if (!_track.getPoint(i).isWaypoint()) + if (!isWaypoint) { // Connect track points if either of them are visible if (connectPoints && (currPointVisible || prevPointVisible) @@ -539,56 +557,58 @@ public class MapCanvas extends JPanel implements MouseListener, MouseMotionListe } // Loop over points, just drawing blobs for waypoints - inG.setColor(COLOR_WAYPT_NAME); + inG.setColor(textColour); FontMetrics fm = inG.getFontMetrics(); int nameHeight = fm.getHeight(); int width = getWidth(); int height = getHeight(); - for (int i=0; i<_track.getNumPoints(); i++) - { - if (_track.getPoint(i).isWaypoint()) + if (anyWaypoints) { + for (int i=0; i<_track.getNumPoints(); i++) { - int px = getWidth() / 2 + _mapPosition.getXFromCentre(_track.getX(i)); - int py = getHeight() / 2 + _mapPosition.getYFromCentre(_track.getY(i)); - if (px >= 0 && px < getWidth() && py >= 0 && py < getHeight()) + if (_track.getPoint(i).isWaypoint()) { - inG.fillRect(px-3, py-3, 6, 6); - pointsPainted++; + int px = getWidth() / 2 + _mapPosition.getXFromCentre(_track.getX(i)); + int py = getHeight() / 2 + _mapPosition.getYFromCentre(_track.getY(i)); + if (px >= 0 && px < getWidth() && py >= 0 && py < getHeight()) + { + inG.fillRect(px-3, py-3, 6, 6); + pointsPainted++; + } } } - } - // Loop over points again, now draw names for waypoints - for (int i=0; i<_track.getNumPoints(); i++) - { - if (_track.getPoint(i).isWaypoint()) + // Loop over points again, now draw names for waypoints + for (int i=0; i<_track.getNumPoints(); i++) { - int px = getWidth() / 2 + _mapPosition.getXFromCentre(_track.getX(i)); - int py = getHeight() / 2 + _mapPosition.getYFromCentre(_track.getY(i)); - if (px >= 0 && px < getWidth() && py >= 0 && py < getHeight()) + if (_track.getPoint(i).isWaypoint()) { - // Figure out where to draw waypoint name so it doesn't obscure track - String waypointName = _track.getPoint(i).getWaypointName(); - int nameWidth = fm.stringWidth(waypointName); - boolean drawnName = false; - // Make arrays for coordinates right left up down - int[] nameXs = {px + 2, px - nameWidth - 2, px - nameWidth/2, px - nameWidth/2}; - int[] nameYs = {py + (nameHeight/2), py + (nameHeight/2), py - 2, py + nameHeight + 2}; - for (int extraSpace = 4; extraSpace < 13 && !drawnName; extraSpace+=2) + int px = getWidth() / 2 + _mapPosition.getXFromCentre(_track.getX(i)); + int py = getHeight() / 2 + _mapPosition.getYFromCentre(_track.getY(i)); + if (px >= 0 && px < getWidth() && py >= 0 && py < getHeight()) { - // Shift arrays for coordinates right left up down - nameXs[0] += 2; nameXs[1] -= 2; - nameYs[2] -= 2; nameYs[3] += 2; - // Check each direction in turn right left up down - for (int a=0; a<4; a++) + // Figure out where to draw waypoint name so it doesn't obscure track + String waypointName = _track.getPoint(i).getWaypointName(); + int nameWidth = fm.stringWidth(waypointName); + boolean drawnName = false; + // Make arrays for coordinates right left up down + int[] nameXs = {px + 2, px - nameWidth - 2, px - nameWidth/2, px - nameWidth/2}; + int[] nameYs = {py + (nameHeight/2), py + (nameHeight/2), py - 2, py + nameHeight + 2}; + for (int extraSpace = 4; extraSpace < 13 && !drawnName; extraSpace+=2) { - if (nameXs[a] > 0 && (nameXs[a] + nameWidth) < width - && nameYs[a] < height && (nameYs[a] - nameHeight) > 0 - && !overlapsPoints(nameXs[a], nameYs[a], nameWidth, nameHeight)) + // Shift arrays for coordinates right left up down + nameXs[0] += 2; nameXs[1] -= 2; + nameYs[2] -= 2; nameYs[3] += 2; + // Check each direction in turn right left up down + for (int a=0; a<4; a++) { - // Found a rectangle to fit - draw name here and quit - inG.drawString(waypointName, nameXs[a], nameYs[a]); - drawnName = true; - break; + if (nameXs[a] > 0 && (nameXs[a] + nameWidth) < width + && nameYs[a] < height && (nameYs[a] - nameHeight) > 0 + && !overlapsPoints(nameXs[a], nameYs[a], nameWidth, nameHeight, textColour)) + { + // Found a rectangle to fit - draw name here and quit + inG.drawString(waypointName, nameXs[a], nameYs[a]); + drawnName = true; + break; + } } } } @@ -596,7 +616,7 @@ public class MapCanvas extends JPanel implements MouseListener, MouseMotionListe } } // Loop over points, drawing blobs for photo points - inG.setColor(COLOR_PHOTO_PT); + inG.setColor(secondColour); for (int i=0; i<_track.getNumPoints(); i++) { if (_track.getPoint(i).getPhoto() != null) @@ -615,7 +635,7 @@ public class MapCanvas extends JPanel implements MouseListener, MouseMotionListe // Draw selected range if (_selection.hasRangeSelected()) { - inG.setColor(COLOR_CURR_RANGE); + inG.setColor(rangeColour); for (int i=_selection.getStart(); i<=_selection.getEnd(); i++) { int px = getWidth() / 2 + _mapPosition.getXFromCentre(_track.getX(i)); @@ -630,7 +650,7 @@ public class MapCanvas extends JPanel implements MouseListener, MouseMotionListe { int px = getWidth() / 2 + _mapPosition.getXFromCentre(_track.getX(selectedPoint)); int py = getHeight() / 2 + _mapPosition.getYFromCentre(_track.getY(selectedPoint)); - inG.setColor(COLOR_CROSSHAIRS); + inG.setColor(currentColour); // crosshairs inG.drawLine(px, 0, px, getHeight()); inG.drawLine(0, py, getWidth(), py); @@ -649,12 +669,17 @@ public class MapCanvas extends JPanel implements MouseListener, MouseMotionListe * @param inY bottom Y coordinate * @param inWidth width of rectangle * @param inHeight height of rectangle - * @return true if there's at least one data point in the rectangle + * @param inTextColour colour of text + * @return true if the rectangle overlaps stuff too close to the given colour */ - private boolean overlapsPoints(int inX, int inY, int inWidth, int inHeight) + private boolean overlapsPoints(int inX, int inY, int inWidth, int inHeight, Color inTextColour) { - // each of the colour channels must be brighter than this to count as empty - final int BRIGHTNESS_LIMIT = 210; + // each of the colour channels must be further away than this to count as empty + final int BRIGHTNESS_LIMIT = 80; + final int textRGB = inTextColour.getRGB(); + final int textLow = textRGB & 255; + final int textMid = (textRGB >> 8) & 255; + final int textHigh = (textRGB >> 16) & 255; try { // loop over x coordinate of rectangle @@ -665,11 +690,14 @@ public class MapCanvas extends JPanel implements MouseListener, MouseMotionListe { int pixelColor = _mapImage.getRGB(inX + x, inY - y); // split into four components rgba - int lowestBit = pixelColor & 255; - int secondBit = (pixelColor >> 8) & 255; - int thirdBit = (pixelColor >> 16) & 255; + int pixLow = pixelColor & 255; + int pixMid = (pixelColor >> 8) & 255; + int pixHigh = (pixelColor >> 16) & 255; //int fourthBit = (pixelColor >> 24) & 255; // alpha ignored - if (lowestBit < BRIGHTNESS_LIMIT || secondBit < BRIGHTNESS_LIMIT || thirdBit < BRIGHTNESS_LIMIT) return true; + // If colours are too close in any channel then it's an overlap + if (Math.abs(pixLow-textLow) < BRIGHTNESS_LIMIT || + Math.abs(pixMid-textMid) < BRIGHTNESS_LIMIT || + Math.abs(pixHigh-textHigh) < BRIGHTNESS_LIMIT) {return true;} } } } @@ -767,7 +795,13 @@ public class MapCanvas extends JPanel implements MouseListener, MouseMotionListe _mapPosition.getXFromPixels(inE.getX(), getWidth()), _mapPosition.getYFromPixels(inE.getY(), getHeight()), _mapPosition.getBoundsFromPixels(CLICK_SENSITIVITY), false); - _trackInfo.selectPoint(pointIndex); + // Extend selection for shift-click + if (inE.isShiftDown()) { + _trackInfo.extendSelection(pointIndex); + } + else { + _trackInfo.selectPoint(pointIndex); + } } else { diff --git a/tim/prune/gui/map/MapTileConfig.java b/tim/prune/gui/map/MapTileConfig.java index 1f9c387..e545125 100644 --- a/tim/prune/gui/map/MapTileConfig.java +++ b/tim/prune/gui/map/MapTileConfig.java @@ -3,7 +3,7 @@ package tim.prune.gui.map; import java.net.MalformedURLException; import java.net.URL; -import tim.prune.Config; +import tim.prune.config.Config; /** * Class to hold the config for the map tiles diff --git a/tim/prune/gui/map/ScaleBar.java b/tim/prune/gui/map/ScaleBar.java index 0f65db9..1daa19e 100644 --- a/tim/prune/gui/map/ScaleBar.java +++ b/tim/prune/gui/map/ScaleBar.java @@ -5,8 +5,9 @@ import java.awt.Dimension; import java.awt.Graphics; import javax.swing.JPanel; -import tim.prune.Config; import tim.prune.I18nManager; +import tim.prune.config.ColourScheme; +import tim.prune.config.Config; /** * Class to show a scale bar on the main map of Prune @@ -81,18 +82,37 @@ public class ScaleBar extends JPanel if (scale < 1) {return;} } + // Determine colours to use + Color barColour = Config.getColourScheme().getColour(ColourScheme.IDX_TEXT); + Color blankColour = new Color(255-barColour.getRed(), 255-barColour.getGreen(), 255-barColour.getBlue()); + // Should this blank colour be set to saturation zero? + // Draw blank bars behind + inG.setColor(blankColour); + inG.drawLine(LEFT_OFFSET, Y_OFFSET-1, rightSide+2, Y_OFFSET-1); + inG.drawLine(LEFT_OFFSET, Y_OFFSET+2, rightSide+2, Y_OFFSET+2); + inG.drawLine(LEFT_OFFSET-1, Y_OFFSET+2, LEFT_OFFSET-1, Y_OFFSET-TICK_HEIGHT); + inG.drawLine(LEFT_OFFSET+2, Y_OFFSET+2, LEFT_OFFSET+2, Y_OFFSET-TICK_HEIGHT); + inG.drawLine(rightSide-1, Y_OFFSET+2, rightSide-1, Y_OFFSET-TICK_HEIGHT); + inG.drawLine(rightSide+2, Y_OFFSET+2, rightSide+2, Y_OFFSET-TICK_HEIGHT); // horizontal - inG.setColor(Color.BLACK); + inG.setColor(barColour); inG.drawLine(LEFT_OFFSET, Y_OFFSET, rightSide, Y_OFFSET); inG.drawLine(LEFT_OFFSET, Y_OFFSET+1, rightSide, Y_OFFSET+1); // 0 tick inG.drawLine(LEFT_OFFSET, Y_OFFSET, LEFT_OFFSET, Y_OFFSET-TICK_HEIGHT); inG.drawLine(LEFT_OFFSET+1, Y_OFFSET, LEFT_OFFSET+1, Y_OFFSET-TICK_HEIGHT); // end tick - inG.drawLine(rightSide, Y_OFFSET, rightSide, Y_OFFSET-TICK_HEIGHT); - inG.drawLine(rightSide+1, Y_OFFSET, rightSide+1, Y_OFFSET-TICK_HEIGHT); + inG.drawLine(rightSide, Y_OFFSET+1, rightSide, Y_OFFSET-TICK_HEIGHT); + inG.drawLine(rightSide+1, Y_OFFSET+1, rightSide+1, Y_OFFSET-TICK_HEIGHT); // text - String text = (scale>0?(""+scale):("1/"+(-scale))) + " " + I18nManager.getText(useMetric?"units.kilometres.short":"units.miles.short"); + String text = (scale>0?(""+scale):("1/"+(-scale))) + " " + + I18nManager.getText(useMetric?"units.kilometres.short":"units.miles.short"); + inG.setColor(blankColour); + inG.drawString(text, rightSide+MARGIN_WIDTH-1, Y_OFFSET); + inG.drawString(text, rightSide+MARGIN_WIDTH+1, Y_OFFSET); + inG.drawString(text, rightSide+MARGIN_WIDTH, Y_OFFSET-1); + inG.drawString(text, rightSide+MARGIN_WIDTH, Y_OFFSET+1); + inG.setColor(barColour); inG.drawString(text, rightSide+MARGIN_WIDTH, Y_OFFSET); } catch (ArrayIndexOutOfBoundsException ai) {} diff --git a/tim/prune/lang/prune-texts_af.properties b/tim/prune/lang/prune-texts_af.properties index 42875f6..11de10f 100644 --- a/tim/prune/lang/prune-texts_af.properties +++ b/tim/prune/lang/prune-texts_af.properties @@ -39,6 +39,7 @@ menu.view.browser.google=Google Kaarte menu.view.browser.openstreetmap=Openstreetmap menu.view.browser.mapquest=Mapquest menu.view.browser.yahoo=Yahoo Kaarte +menu.view.browser.bing=Bing Kaarte menu.help=Hulp # Popup menu for map menu.map.zoomin=Zoom in diff --git a/tim/prune/lang/prune-texts_de.properties b/tim/prune/lang/prune-texts_de.properties index daf49fe..26e2b65 100644 --- a/tim/prune/lang/prune-texts_de.properties +++ b/tim/prune/lang/prune-texts_de.properties @@ -7,7 +7,7 @@ menu.file.open=Datei menu.file.addphotos=Fotos laden menu.file.save=Speichern menu.file.exit=Beenden -menu.edit=Bearbeiten +menu.track=Track menu.edit.undo=Rückgängig menu.edit.clearundo=Liste der letzten Änderungen löschen menu.edit.editpoint=Punkt bearbeiten @@ -23,24 +23,20 @@ menu.edit.rearrange.start=Alle Wegpunkte zum Anfang menu.edit.rearrange.end=Alle Wegpunkte ans Ende menu.edit.rearrange.nearest=Jeden Wegpunkt zum nächsten Trackpunkt verschieben menu.edit.cutandmove=Schneiden und verschieben -menu.select=Markieren +menu.range=Bereich +menu.point=Punkt menu.select.all=Alles markieren menu.select.none=Nichts markieren menu.select.start=Startpunkt setzen menu.select.end=Endpunkt setzen menu.photo=Foto menu.photo.saveexif=Exif Daten speichern -menu.photo.connect=Mit Punkt verbinden +menu.photo.connect=Mit Punkt verknüpfen menu.photo.disconnect=Vom Punkt trennen menu.photo.delete=Foto entfernen menu.view=Ansicht menu.view.browser=Karte in Browser -menu.view.browser.google=Google Maps -menu.view.browser.openstreetmap=Openstreetmap -menu.view.browser.mapquest= -menu.view.browser.yahoo= menu.settings=Einstellungen -menu.settings.showpace=Tempo anzeigen menu.help=Hilfe # Popup menu for map menu.map.zoomin=Hineinzoomen @@ -54,8 +50,9 @@ menu.map.showscalebar=Ma # Alt keys for menus altkey.menu.file=D -altkey.menu.edit=B -altkey.menu.select=M +altkey.menu.track=T +altkey.menu.range=B +altkey.menu.point=P altkey.menu.view=A altkey.menu.photo=F altkey.menu.settings=E @@ -81,14 +78,24 @@ function.compress=Track komprimieren function.addtimeoffset=Zeitverschiebung aufrechnen function.addaltitudeoffset=Höhenverschiebung aufrechnen function.findwaypoint=Wegpunkt finden +function.convertnamestotimes=Wegpunktenamen in Zeitstempeln verwandeln +function.pastecoordinates=Neue Koordinaten eingeben function.charts=Diagramme function.show3d=3D Ansicht -function.distances=Distanzen +function.distances=Entfernungen +function.fullrangedetails=Zusätzliche Bereichdetails function.setmapbg=Karte Hintergrund setzen function.setkmzimagesize=Bildgröße im KMZ setzen -function.setpaths=Programmenpfade setzen +function.setpaths=Programmpfade setzen +function.setcolours=Farben einstellen +function.setlanguage=Sprache einstellen function.getgpsies=Gpsies Tracks holen +function.duplicatepoint=Punkt verdoppeln function.correlatephotos=Fotos korrelieren +function.rearrangephotos=Fotos reorganisieren +function.rotatephotoleft=Foto nach Links drehen +function.rotatephotoright=Foto nach Rechts drehen +function.ignoreexifthumb=Exif Vorschaubild ignorieren function.help=Hilfe function.showkeys=Tastenkombinationen anzeigen function.about=Über Prune @@ -107,19 +114,19 @@ dialog.deletephoto.deletepoint=Den zu diesem Foto geh dialog.openoptions.title=Öffnen dialog.openoptions.filesnippet=Dateiausschnitt dialog.load.table.field=Feld -dialog.load.table.datatype=Daten Typ +dialog.load.table.datatype=Datentyp dialog.load.table.description=Beschreibung dialog.delimiter.label=Feld Trennzeichen dialog.delimiter.comma=Komma , dialog.delimiter.tab=Tab -dialog.delimiter.space=Leerstelle +dialog.delimiter.space=Leerzeichen dialog.delimiter.semicolon=Strichpunkt ; dialog.delimiter.other=Andere dialog.openoptions.deliminfo.records=Aufnahmen, mit dialog.openoptions.deliminfo.fields=Feldern dialog.openoptions.deliminfo.norecords=Keine Rekords dialog.openoptions.altitudeunits=Höhe Maßeinheiten -dialog.jpegload.subdirectories=Unterordner auch durchsuchen +dialog.jpegload.subdirectories=Unterordner mit durchsuchen dialog.jpegload.loadjpegswithoutcoords=Auch Fotos ohne Koordinaten laden dialog.jpegload.loadjpegsoutsidearea=Auch Fotos ausserhalb vom Track laden dialog.jpegload.progress.title=Fotos werden geladen @@ -129,6 +136,7 @@ dialog.gpsload.device=Ger dialog.gpsload.format=Format dialog.gpsload.getwaypoints=Wegpunkte laden dialog.gpsload.gettracks=Tracks laden +dialog.gpsload.save=nach Datei speichern dialog.gpssend.sendwaypoints=Wegpunkte senden dialog.gpssend.sendtracks=Tracks senden dialog.gpssend.trackname=Track Name @@ -143,13 +151,16 @@ dialog.save.altitudeunits=H dialog.save.timestampformat=Zeitstempelformat dialog.save.overwrite.title=Datei schon vorhanden dialog.save.overwrite.text=Diese Datei gibt es schon. Wollen Sie die vorhandene Datei überschreiben? +dialog.save.notypesselected=Keine Punktetypen sind ausgewählt dialog.exportkml.text=Titel für die Daten dialog.exportkml.altitude=Absolute Höheninformation (für Luftfahrt) dialog.exportkml.kmz=Daten in kmz Datei komprimieren dialog.exportkml.exportimages=Vorschaubilder mit in kmz exportieren +dialog.exportkml.trackcolour=Trackfarbe dialog.exportgpx.name=Name dialog.exportgpx.desc=Beschreibung dialog.exportgpx.includetimestamps=Zeitstempel mit exportieren +dialog.exportgpx.copysource=Xml von Quelle kopieren dialog.exportpov.text=Geben Sie die Parameter für den POV Export ein dialog.exportpov.font=Font dialog.exportpov.camerax=Kamera X @@ -163,6 +174,7 @@ dialog.pointtype.desc=Folgende Punkttypen speichern: dialog.pointtype.track=Trackpunkte dialog.pointtype.waypoint=Wegpunkte dialog.pointtype.photo=Fotopunkte +dialog.pointtype.selection=Nur aktuellen Bereich dialog.confirmreversetrack.title=Umkehrung bestätigen dialog.confirmreversetrack.text=Diese Daten enthalten Zeitangaben, die bei einer Umkehrung in falscher Reihenfolge erscheinen würden.\nSind Sie sicher, dass Sie diesen Bereich umkehren wollen? dialog.confirmcutandmove.title=Verschieben bestätigen @@ -174,7 +186,7 @@ dialog.undo.pretext=Bitte die Operationen, die r dialog.undo.none.title=Undo nicht möglich dialog.undo.none.text=Keine Operationen können rückgängig gemacht werden. dialog.clearundo.title=Undo-Liste löschen -dialog.clearundo.text=Sind Sie sicher, Sie wollen die Undo-Liste löschen?\nAlle Undo Information wird veloren gehen! +dialog.clearundo.text=Wollen Sie wirklich die Undo-Liste löschen?\nAlle Undo- Informationen werden verloren gehen! dialog.pointedit.title=Punkt bearbeiten dialog.pointedit.text=Wählen Sie die Felder aus, die Sie bearbeiten möchten, und verwenden Sie den 'Bearbeiten' Knopf, um den Wert zu ändern dialog.pointedit.table.field=Feld @@ -191,11 +203,9 @@ dialog.addtimeoffset.subtract=Zeit subtrahieren dialog.addtimeoffset.days=Tage dialog.addtimeoffset.hours=Stunde dialog.addtimeoffset.minutes=Minute -dialog.addtimeoffset.notimestamps=Zeitdifferenz kann nicht addiert werden weil dieser Bereich keine Zeitinformation hat -dialog.findwaypoint.intro=Geben Sie einen Teil von dem Namen ein +dialog.addtimeoffset.notimestamps=Zeitdifferenz kann nicht addiert werden, weil dieser Bereich keine Zeitinformation hat +dialog.findwaypoint.intro=Geben Sie einen Teil des Namens ein dialog.findwaypoint.search=Suche -dialog.connect.title=Foto mit Punkt verbinden -dialog.connectphoto.clonepoint=Diesem Punkt ist schon ein Foto zugeordnet.\nWollen Sie eine Kopie dieses Punktes machen? dialog.saveexif.title=Exif speichern dialog.saveexif.intro=Wählen Sie die Fotos zum Speichern aus dialog.saveexif.nothingtosave=Koordinaten sind unverändert. Es gibt nichts zu speichern. @@ -207,23 +217,22 @@ dialog.saveexif.photostatus.connected=Verbunden dialog.saveexif.photostatus.disconnected=Getrennt dialog.saveexif.photostatus.modified=Modifiziert dialog.saveexif.overwrite=Dateien überschreiben +dialog.saveexif.force=Forzieren trotz Warnungen dialog.charts.xaxis=X Achse dialog.charts.yaxis=Y Achse dialog.charts.output=Ausgabe -dialog.charts.screen=zum Bildschirm -dialog.charts.svg=zur SVG Datei +dialog.charts.screen=Ausgabe zum Bildschirm +dialog.charts.svg=Ausgabe in SVG Datei dialog.charts.svgwidth=SVG Breite dialog.charts.svgheight=SVG Höhe dialog.charts.needaltitudeortimes=Ohne Daten über Höhe und Zeit kann kein Diagramm erzeugt werden. -dialog.charts.gnuplotpath=Gnuplot Pfad dialog.charts.gnuplotnotfound=Gnuplot konnte im angegebenen Pfad nicht gefunden werden -dialog.distances.intro=Luftlinienentfernung zwischen Punkte +dialog.distances.intro=Luftlinienentfernung zwischen Punkten dialog.distances.column.from=Vom Punkt dialog.distances.column.to=Zum Punkt dialog.distances.currentpoint=Aktueller Punkt dialog.distances.toofewpoints=Diese Funktion braucht Wegpunkte um die Distanzen zu berechnen -dialog.setmapbg.mapnik= -dialog.setmapbg.osma= +dialog.fullrangedetails.intro=Hier sind die Details vom markierten Bereich dialog.setmapbg.cyclemap=Fahrradkarte dialog.setmapbg.other=Andere dialog.setmapbg.server=Server URL @@ -254,6 +263,12 @@ dialog.correlate.options.nodistancelimit=Keine Distanzgrenzen dialog.correlate.options.distancelimit=Distanzgrenzen dialog.correlate.options.correlate=Korrelieren dialog.correlate.alloutsiderange=Alle Fotos sind außerhalb vom Track Zeitraum. Sie können nicht korreliert werden.\nVersuchen Sie es mit einem anderen Offset oder binden Sie manuell mindestens ein Foto ein. +dialog.rearrangephotos.desc=Setzen Sie das Ziel und die Reihenfolge der Fotopunkte +dialog.rearrangephotos.tostart=Am Anfang +dialog.rearrangephotos.toend=Am Ende +dialog.rearrangephotos.nosort=Nicht sortieren +dialog.rearrangephotos.sortbyfilename=per Dateiname sortieren +dialog.rearrangephotos.sortbytime=per Zeitstempel sortieren dialog.compress.nonefound=Es konnten keine Punkte entfernt werden dialog.compress.duplicates.title=Duplikate entfernen dialog.compress.closepoints.title=Nahegelegene Punkte entfernen @@ -263,7 +278,10 @@ dialog.compress.wackypoints.paramdesc=Distanzfaktor dialog.compress.singletons.title=Singletons (isolierte Punkte) entfernen dialog.compress.singletons.paramdesc=Distanzfaktor dialog.compress.summarylabel=Punkte zu entfernen -dialog.help.help=Bitte sehen Sie\n http://activityworkshop.net/software/prune/\nfür weitere Information und Benutzeranleitungen. +dialog.pastecoordinates.desc=Geben Sie die Koordinaten ein +dialog.pastecoordinates.coords=Koordinaten +dialog.pastecoordinates.nothingfound=Bitte prüfen Sie die Koordinaten und versuchen nochmals +dialog.help.help=Weitere Informationen und Benutzeranleitungen finden Sie unter\n http://activityworkshop.net/software/prune/ 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äten. @@ -304,6 +322,7 @@ dialog.saveconfig.desc=Die folgende Einstellungen k dialog.saveconfig.prune.trackdirectory=Datenverzeichnis dialog.saveconfig.prune.photodirectory=Fotoverzeichnis dialog.saveconfig.prune.languagecode=Sprachecode (DE) +dialog.saveconfig.prune.languagefile=Sprachedatei dialog.saveconfig.prune.gpsdevice=GPS Gerätename dialog.saveconfig.prune.gpsformat=GPS Format dialog.saveconfig.prune.povrayfont=Povray Font @@ -313,12 +332,31 @@ dialog.saveconfig.prune.gpsbabelpath=Gpsbabel Pfad dialog.saveconfig.prune.exiftoolpath=Exiftool Pfad dialog.saveconfig.prune.mapserverindex=Kartenserver Index dialog.saveconfig.prune.mapserverurl=Kartenserver URL -dialog.saveconfig.prune.showpace=Tempo anzeigen dialog.saveconfig.prune.kmzimagewidth=Bildbreite in KMZ dialog.saveconfig.prune.kmzimageheight=Bildhöhe in KMZ +dialog.saveconfig.prune.colourscheme=Farbenschema +dialog.saveconfig.prune.kmltrackcolour=KML Trackfarbe dialog.setpaths.intro=Sie können hier die Pfade für externe Applikationen setzen: dialog.addaltitude.noaltitudes=Der markierten Bereich enthält keine Höhenangaben dialog.addaltitude.desc=Höhenverschiebung aufzurechnen +dialog.setcolours.intro=Klicken Sie auf einer Farbe um sie zu ändern +dialog.setcolours.background=Hintergrund +dialog.setcolours.borders=Umrandungen +dialog.setcolours.lines=Linien +dialog.setcolours.primary=Primär +dialog.setcolours.secondary=Secondär +dialog.setcolours.point=Punkte +dialog.setcolours.selection=Bereich +dialog.setcolours.text=Texte +dialog.colourchooser.title=Farbe auswählen +dialog.colourchooser.red=Rot +dialog.colourchooser.green=Grün +dialog.colourchooser.blue=Blau +dialog.setlanguage.firstintro=Sie können entweder eine von den eingebauten Sprachen

oder eine Text-Datei auswählen. +dialog.setlanguage.secondintro=Sie müssen Ihre Einstellungen speichern und dann

Prune wieder neustarten um die Sprache zu ändern. +dialog.setlanguage.language=Sprache +dialog.setlanguage.languagefile=Sprache Datei +dialog.setlanguage.endmessage=Nun speichern Sie Ihre Einstellungen und starten Sie Prune neu\num die neue Sprache zu verwenden. # 3d window dialog.3d.title=Prune 3D Ansicht @@ -339,7 +377,9 @@ confirm.reverserange=Bereich umgekehrt confirm.addtimeoffset=Zeitverschiebung aufgerechnet confirm.addaltitudeoffset=Höhenverschiebung aufgerechnet confirm.rearrangewaypoints=Wegpunkte reorganisiert +confirm.rearrangephotos=Fotos reorganisiert confirm.cutandmove=Bereich verschoben +confirm.convertnamestotimes=Wegpunktnamen verwandelt confirm.saveexif.ok1=Es wurden confirm.saveexif.ok2=Fotodateien geschrieben confirm.undo.single=Operation rückgängig gemacht @@ -351,6 +391,7 @@ confirm.photo.disconnect=Foto getrennt confirm.correlate.single=Foto wurde korreliert confirm.correlate.multi=Fotos wurden korreliert confirm.createpoint=Punkt kreiert +confirm.rotatephoto=Foto umgedreht confirm.running=In Bearbeitung ... # Buttons @@ -371,13 +412,16 @@ button.yes=Ja button.no=Nein button.yestoall=Ja für alle button.notoall=Nein für alle -button.selectall=Alle selektieren -button.selectnone=Nichts selektieren +button.select=Auswählen +button.selectall=Alle auswählen +button.selectnone=Nichts auswählen button.preview=Vorschau button.load=Laden button.guessfields=Felder erraten button.showwebpage=Webseite anzeigen button.check=Prüfen +button.resettodefaults=Zurücksetzen +button.browse=Durchsuchen... # File types filetype.txt=TXT Dateien @@ -417,7 +461,9 @@ display.range.time.hours=h display.range.time.days=T details.range.avespeed=Geschwindigkeit details.range.avemovingspeed=Geschwindigkeit unterwegs +details.range.numsegments=Anzahl Abschnitte details.range.pace=Tempo +details.range.gradient=Gefälle details.waypointsphotos.waypoints=Wegpunkte details.waypointsphotos.photos=Fotos details.photodetails=Fotodetails @@ -447,15 +493,9 @@ fieldname.verticalspeed=Vertikale Geschwindigkeit units.original=Original units.default=Standard units.metres=Meter -units.metres.short= -units.feet= -units.feet.short= units.kilometres=Kilometer units.kilometres.short=km units.kmh=km/h -units.miles= -units.miles.short= -units.mph= units.metrespersec=m/s units.feetpersec=ft/s units.hours=Std @@ -491,15 +531,22 @@ undo.cutandmove=Bereich verschieben undo.connectphoto=Foto verbinden undo.disconnectphoto=Foto trennen undo.correlate=Fotos korrelieren -undo.createpoint=Punkt kreieren +undo.rearrangephotos=Fotos reorganisieren +undo.rotatephoto=Foto umdrehen +undo.createpoint=Punkt erzeugen +undo.convertnamestotimes=Namen in Zeitstempeln verwandeln # Error messages error.save.dialogtitle=Fehler beim Speichern error.save.nodata=Keine Daten zum Sichern vorhanden -error.save.failed=Speichern von der Datei fehlgeschlagen +error.save.failed=Speichern von Daten in Datei fehlgeschlagen error.saveexif.filenotfound=Foto Datei nicht gefunden error.saveexif.cannotoverwrite1=Foto Datei error.saveexif.cannotoverwrite2=ist schreib-geschützt. Als Kopie speichern? +error.saveexif.failed1= +error.saveexif.failed2=von den Bildern konnten nicht gespeichert werden +error.saveexif.forced1= +error.saveexif.forced2=von den Bildern mussten forziert werden error.load.dialogtitle=Fehler beim Laden error.load.noread=Datei konnte nicht gelesen werden error.load.nopoints=Keine gültigen Daten in Datei gefunden @@ -511,13 +558,16 @@ error.jpegload.nofilesfound=Keine Dateien gefunden error.jpegload.nojpegsfound=Keine Jpeg Dateien gefunden error.jpegload.noexiffound=Keine EXIF Information gefunden error.jpegload.nogpsfound=Keine GPS Information gefunden +error.gpsload.unknown=Unbekanntes Fehler error.undofailed.title=Undo fehlgeschlagen error.undofailed.text=Operation konnte nicht rückgängig gemacht werden error.function.noop.title=Funktion hat nichts bewirkt -error.rearrange.noop=Die Wegpunkte zu reorganisieren hatte keinen Effekt +error.rearrange.noop=Die Punkte zu reorganisieren hatte keinen Effekt error.function.notavailable.title=Funktion nicht verfügbar error.function.nojava3d=Diese Funktion benötigt die Java3d Library,\nvon Sun.com erhältlich. error.3d=Ein Fehler ist bei der 3D Darstellung aufgetreten error.readme.notfound=Liesmich Datei nicht gefunden error.osmimage.dialogtitle=Laden von Karten-Bildern fehlgeschlagen error.osmimage.failed=Laden von Karten-Bildern fehlgeschlagen. Bitte prüfen Sie die Internetverbindung. +error.language.wrongfile=Die ausgewählte Datei scheint keine Sprache-Datei für Prune zu sein +error.convertnamestotimes.nonames=Keine Namen konnten verwandelt werden diff --git a/tim/prune/lang/prune-texts_de_CH.properties b/tim/prune/lang/prune-texts_de_CH.properties index b00f39d..5ce66f6 100644 --- a/tim/prune/lang/prune-texts_de_CH.properties +++ b/tim/prune/lang/prune-texts_de_CH.properties @@ -7,7 +7,7 @@ menu.file.open=File menu.file.addphotos=Fötelis innätue menu.file.save=Speichere menu.file.exit=Beände -menu.edit=Editiere +menu.track=Track menu.edit.undo=Undo menu.edit.clearundo=Undo-Liste lösche menu.edit.editpoint=Punkt editiere @@ -23,7 +23,8 @@ menu.edit.rearrange.start=Alli zum Aafang menu.edit.rearrange.end=Alli zum Ände menu.edit.rearrange.nearest=Jede zum nöchsti Trackpunkt menu.edit.cutandmove=Schniide und move -menu.select=Selektiere +menu.range=Beriich +menu.point=Punkt menu.select.all=Alles selektiere menu.select.none=Nüüt selektiere menu.select.start=Start setzä @@ -35,12 +36,7 @@ menu.photo.disconnect=Vonem Punkt tr menu.photo.delete=Föteli entfernä menu.view=Aasicht menu.view.browser=Karte inem Browser -menu.view.browser.google= -menu.view.browser.openstreetmap= -menu.view.browser.mapquest= -menu.view.browser.yahoo= menu.settings=Iistellige -menu.settings.showpace=Tempo aazeige menu.help=Hilfe # Popup menu for map menu.map.zoomin=Innezoome @@ -49,13 +45,14 @@ menu.map.zoomfull=Zoome zum ganzes Bild menu.map.newpoint=Noii Punkt menu.map.connect=Trackpünktli verbindä menu.map.autopan=Autopan -menu.map.showmap=Kate zeigä +menu.map.showmap=Karte zeigä menu.map.showscalebar=Massstab aazeige # Alt keys for menus altkey.menu.file=F -altkey.menu.edit=E -altkey.menu.select=S +altkey.menu.track=T +altkey.menu.range=B +altkey.menu.point=P altkey.menu.view=A altkey.menu.photo=F altkey.menu.settings=I @@ -80,15 +77,25 @@ function.editwaypointname=Waypoint Name editiere function.compress=Track komprimierä function.addtimeoffset=Ziitverschiebig zutue function.addaltitudeoffset=Höchiverschiebig zutue -function.findwaypoint=Waypoint findä +function.findwaypoint=Waypoint suechä +function.convertnamestotimes=Waypointname ins Ziitstämple verwondle +function.pastecoordinates=Noii Koordinaten iigebe function.charts=Diagramme function.show3d=Drüü-D Aasicht function.distances=Distanze +function.fullrangedetails=Zuesätzlichi Beriichinfos function.setmapbg=Karte Hintegrund setzä function.getgpsies=Gpsies Tracks holä +function.duplicatepoint=Punkt verdopplä function.correlatephotos=Fötelis korrelierä +function.rearrangephotos=Fötelis reorganisierä +function.rotatephotoleft=Föteli nach Links dräyä +function.rotatephotoright=Föteli nach Rächts dräyä +function.ignoreexifthumb=Exif Vorschaubildli ignorierä function.setkmzimagesize=Bildligrösse inem KMZ setze function.setpaths=Programmepfade setze +function.setcolours=Farben setze +function.setlanguage=Sproch setze function.help=Hilfe function.showkeys=Tastekombinatione aazeige function.about=Über Prune @@ -129,6 +136,7 @@ dialog.gpsload.device=Device Name dialog.gpsload.format=Format dialog.gpsload.getwaypoints=Waypoints lade dialog.gpsload.gettracks=Tracks lade +dialog.gpsload.save=nach nem File speicherä dialog.gpssend.sendwaypoints=Waypoints schicke dialog.gpssend.sendtracks=Tracks schicke dialog.gpssend.trackname=Track Name @@ -143,13 +151,16 @@ dialog.save.altitudeunits=H dialog.save.timestampformat=Ziitstämpelformat dialog.save.overwrite.title=s'File existiert scho dialog.save.overwrite.text=s'File existiert scho. Sind Sie sicher, Sie wend s'File überschriibe? +dialog.save.notypesselected=Kei Punktetype sin uusgewählt worde dialog.exportkml.text=Titel für die Date dialog.exportkml.altitude=Absolut Höchiinformation (fürs Fliege) dialog.exportkml.kmz=Date ins kmz File komprimierä dialog.exportkml.exportimages=Bildli ins Kmz exportierä +dialog.exportkml.trackcolour=Trackfarb dialog.exportgpx.name=Name dialog.exportgpx.desc=Beschriibig dialog.exportgpx.includetimestamps=Au Ziitstämpel +dialog.exportgpx.copysource=Xml-Quälle kopierä dialog.exportpov.text=Gäbet Sie die Parameter ii fürs POV Export dialog.exportpov.font=Font dialog.exportpov.camerax=Kamera X @@ -163,6 +174,7 @@ dialog.pointtype.desc=Folgende Punkttype speichere: dialog.pointtype.track=Trackpunkte dialog.pointtype.waypoint=Waypoints dialog.pointtype.photo=Fötelipunkte +dialog.pointtype.selection=Nur aktuelli Beriich dialog.confirmreversetrack.title=Umdrehig bestätige dialog.confirmreversetrack.text=Diese Daten enthalte Ziitstämpel Informatione, die bei dr Umkehrig usser Reihefolge erschiene würdi.\nSind Sie sicher, Sie wend dn Beriich umkehre? dialog.confirmcutandmove.title=Move bestätige @@ -194,8 +206,6 @@ dialog.addtimeoffset.minutes=Minute dialog.addtimeoffset.notimestamps=Ziitverschiebig nöd möglech wil dr Beriich kei Ziitinfo hät dialog.findwaypoint.intro=Gebet Sie en Teil vonem Namen ina dialog.findwaypoint.search=Sueche -dialog.connect.title=Föteli verknüpfe -dialog.connectphoto.clonepoint=Derer Punkt hät scho s Föteli.\nWend sie ne Kopie vonem Punkt machä? dialog.saveexif.title=Exif go speicherä dialog.saveexif.intro=Wählet Sie die Fötelis uus zum speicherä dialog.saveexif.nothingtosave=Koordinaten sin nöd geänderet, nüüt zum speicherä @@ -207,6 +217,7 @@ dialog.saveexif.photostatus.connected=Verbund dialog.saveexif.photostatus.disconnected=Gtrännt dialog.saveexif.photostatus.modified=Gänderet dialog.saveexif.overwrite=Files überschriebä +dialog.saveexif.force=Forzierä trotz Warnige dialog.charts.xaxis=X Achse dialog.charts.yaxis=Y Achse dialog.charts.output=Uusgabe @@ -215,15 +226,13 @@ dialog.charts.svg=SVG File dialog.charts.svgwidth=SVG Breiti dialog.charts.svgheight=SVG Höhi dialog.charts.needaltitudeortimes=Ohni Höhi Date und au ohne Ziit, isch es nöd möglech, Diagramme z zeigä. -dialog.charts.gnuplotpath=Gnuplot Pfad dialog.charts.gnuplotnotfound=Gnuplot isch mit dem Pfad nöd gfunde worde dialog.distances.intro=Dischtanze per Luftlinie zwüschet Punkte dialog.distances.column.from=Vom Punkt dialog.distances.column.to=Zum Punkt dialog.distances.currentpoint=Aktuelli Punkt dialog.distances.toofewpoints=d'Funktion bruucht Waypoints um die Dischtanze z berächne -dialog.setmapbg.mapnik= -dialog.setmapbg.osma= +dialog.fullrangedetails.intro=Hier sind die Infos vonem aktuelli Beriich dialog.setmapbg.cyclemap=Velokarte dialog.setmapbg.other=Anderi dialog.setmapbg.server=Server URL @@ -254,6 +263,12 @@ dialog.correlate.options.nodistancelimit=Kei Distanzgr dialog.correlate.options.distancelimit=Distanzgränzä dialog.correlate.options.correlate=Korrelierä dialog.correlate.alloutsiderange=Alli Fötelis sin uusserhalb vonem Track Ziitruum, so chönne nöd korreliert werdä.\nVersuechet Sie mitenem anderen Offset oder verbindet Sie manuell mindeschtens eis Föteli. +dialog.rearrangephotos.desc=Bitte Ziel und Reihefolge von den Punkten setze +dialog.rearrangephotos.tostart=zum Aafang +dialog.rearrangephotos.toend=zum Ende +dialog.rearrangephotos.nosort=Nöd sortiere +dialog.rearrangephotos.sortbyfilename=per Filename sortiere +dialog.rearrangephotos.sortbytime=per Ziit sortiere dialog.compress.nonefound=Kei Punkte hätte gelöscht werde könne dialog.compress.duplicates.title=Duplikate entfärnä dialog.compress.closepoints.title=Nöchiglägeni Punkte entfärnä @@ -263,6 +278,9 @@ dialog.compress.wackypoints.paramdesc=Distanz Faktor dialog.compress.singletons.title=Singletons entfärnä dialog.compress.singletons.paramdesc=Distanz faktor dialog.compress.summarylabel=Punkte zu entfärnä +dialog.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.about.version=Version dialog.about.build=Build @@ -304,6 +322,7 @@ dialog.saveconfig.desc=Die folgendi Iinstellige k dialog.saveconfig.prune.trackdirectory=Trackverzeichnis dialog.saveconfig.prune.photodirectory=Föteliverzeichnis dialog.saveconfig.prune.languagecode=Sprochecode (DE_ch) +dialog.saveconfig.prune.languagefile=Sprochedatei dialog.saveconfig.prune.gpsdevice=GPS Gerätename dialog.saveconfig.prune.gpsformat=GPS Format dialog.saveconfig.prune.povrayfont=Povray Font @@ -313,12 +332,31 @@ dialog.saveconfig.prune.gpsbabelpath=Gpsbabel Pfad dialog.saveconfig.prune.exiftoolpath=Exiftool Pfad dialog.saveconfig.prune.mapserverindex=Kartenserver Index dialog.saveconfig.prune.mapserverurl=Kartenserver URL -dialog.saveconfig.prune.showpace=Tempo aazeige dialog.saveconfig.prune.kmzimagewidth=Bildbreiti im KMZ dialog.saveconfig.prune.kmzimageheight=Bildhöchi im KMZ +dialog.saveconfig.prune.colourscheme=Farbeschema +dialog.saveconfig.prune.kmltrackcolour=KML Trackfarb dialog.setpaths.intro=Sie könnet dann die Pfade für dia Applikatione setzä: dialog.addaltitude.noaltitudes=Dr seläktierte Beriich hät keini Höchiinformation dialog.addaltitude.desc=Höchiverschiebig zuzutue +dialog.setcolours.intro=Klicket Sie uuf ne Farb um sie z'verändere +dialog.setcolours.background=Hintergrund +dialog.setcolours.borders=Rande +dialog.setcolours.lines=Linie +dialog.setcolours.primary=Primär +dialog.setcolours.secondary=Secondär +dialog.setcolours.point=Punkte +dialog.setcolours.selection=Beriich +dialog.setcolours.text=Texte +dialog.colourchooser.title=Farbe uuswähle +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.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. # 3d window dialog.3d.title=Prune Drüü-d Aasicht @@ -339,7 +377,9 @@ confirm.reverserange=Beriich umgdr confirm.addtimeoffset=Ziitverschiebig zutue confirm.addaltitudeoffset=Höchiverschiebig zutue confirm.rearrangewaypoints=Waypoints umorganisiert +confirm.rearrangephotos=Fotos umorganisiert confirm.cutandmove=Beriich gmoved +confirm.convertnamestotimes=Waypointname verwondlet confirm.saveexif.ok1=Es sin confirm.saveexif.ok2=Fötelis gschriebe worde confirm.undo.single=Operation rückgängig gmacht worde. @@ -351,6 +391,7 @@ confirm.photo.disconnect=F confirm.correlate.single=Föteli isch korreliert worde confirm.correlate.multi=Fötelis sin korreliert worde confirm.createpoint=Punkt kreiert worde +confirm.rotatephoto=Föteli umgedräit worde confirm.running=Am Laufe ... # Buttons @@ -371,14 +412,16 @@ button.yes=Ja button.no=Nei button.yestoall=Ja für alli button.notoall=Nei für alli -button.selectall=Alli selektierä -button.selectnone=Nüüt selektierä +button.select=Uuswähle +button.selectall=Alli uuswähle +button.selectnone=Nüüt uuswähle button.preview=Vorschauä button.load=Ladä button.guessfields=Fälde erratä button.showwebpage=Websiite aazeigä button.check=Prüefa - +button.resettodefaults=Zurücksetzä +button.browse=Durasuechä... # File types filetype.txt=TXT Dateie @@ -418,7 +461,9 @@ display.range.time.hours=Std display.range.time.days=T details.range.avespeed=Gschwindikeit details.range.avemovingspeed=Gschwindikeit ufem Wäg +details.range.numsegments=Aazahl Segmänte details.range.pace=Tempo +details.range.gradient=Gefälle details.waypointsphotos.waypoints=Waypoints details.waypointsphotos.photos=Fötelis details.photodetails=Details vonem Föteli @@ -448,15 +493,9 @@ fieldname.verticalspeed=Uf/Ab Gschwindikeit units.original=Original units.default=Default units.metres=Meter -units.metres.short= -units.feet= -units.feet.short= units.kilometres=Kilometer units.kilometres.short=km units.kmh=km/h -units.miles= -units.miles.short= -units.mph= units.metrespersec=m/s units.feetpersec=ft/s units.hours=Std @@ -492,7 +531,10 @@ undo.cutandmove=Selektion mov undo.connectphoto=Föteli verbindä undo.disconnectphoto=Föteli trännä undo.correlate=Fötelis korrelierä +undo.rearrangephotos=Fötelis reorganisierä undo.createpoint=Punkt kreierä +undo.rotatephoto=Föteli umadräya +undo.convertnamestotimes=Name ins Ziitstämple verwondlä # Error messages error.save.dialogtitle=Fähle bim Speichere @@ -501,6 +543,10 @@ error.save.failed=Speichere vom File fehlgschlage error.saveexif.filenotfound=Föteli File nöd gfunde error.saveexif.cannotoverwrite1=Föteli File error.saveexif.cannotoverwrite2=isch nöd schriibbar. Speichere na einer Kopie? +error.saveexif.failed1= +error.saveexif.failed2=von d Bilder han i nöd speichere könne +error.saveexif.forced1= +error.saveexif.forced2=von d Bilder han i müsse forziere error.load.dialogtitle=Fähle bim Lade error.load.noread=File cha nöd glase werde error.load.nopoints=Kei gültigi Information inem File gfunde @@ -512,13 +558,16 @@ error.jpegload.nofilesfound=Kei Dateie gfunde error.jpegload.nojpegsfound=Kei Jpegs gfunde error.jpegload.noexiffound=Kei EXIF Information gfunde error.jpegload.nogpsfound=Kei GPS Information gfunde +error.gpsload.unknown=Unbekannts Fähler error.undofailed.title=Undo isch fehlgschlage worde error.undofailed.text=Operation kann nöd rückgängig gmacht werde error.function.noop.title=Funktion hät gar nüüt gmacht -error.rearrange.noop=Waypoints Reorganisierig hät kei Effäkt gha +error.rearrange.noop=Punkte Reorganisierig hät kei Effäkt gha error.function.notavailable.title=Funktion nöd verfüegbar error.function.nojava3d=Sorry, d'Funktion brucht d Java3d Library,\nvo Sun.com erhältlech. -error.3d=N Fähler isch mitere 3d Darstellig ufgtrete +error.3d=N Fähler isch mitere 3d Darstellig ufgträte 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.convertnamestotimes.nonames=Kei Namen han könnet verwondlet werde diff --git a/tim/prune/lang/prune-texts_en.properties b/tim/prune/lang/prune-texts_en.properties index 85f4024..47ccdc6 100644 --- a/tim/prune/lang/prune-texts_en.properties +++ b/tim/prune/lang/prune-texts_en.properties @@ -7,7 +7,7 @@ menu.file.open=Open file menu.file.addphotos=Add photos menu.file.save=Save menu.file.exit=Exit -menu.edit=Edit +menu.track=Track menu.edit.undo=Undo menu.edit.clearundo=Clear undo list menu.edit.editpoint=Edit point @@ -23,7 +23,8 @@ menu.edit.rearrange.start=All to start of file menu.edit.rearrange.end=All to end of file menu.edit.rearrange.nearest=Each to nearest track point menu.edit.cutandmove=Cut and move selection -menu.select=Select +menu.range=Range +menu.point=Point menu.select.all=Select all menu.select.none=Select none menu.select.start=Set range start @@ -39,8 +40,8 @@ menu.view.browser.google=Google maps menu.view.browser.openstreetmap=Openstreetmap menu.view.browser.mapquest=Mapquest menu.view.browser.yahoo=Yahoo maps +menu.view.browser.bing=Bing maps menu.settings=Settings -menu.settings.showpace=Show pace in range display menu.help=Help # Popup menu for map menu.map.zoomin=Zoom in @@ -54,11 +55,12 @@ menu.map.showscalebar=Show scalebar # Alt keys for menus altkey.menu.file=F -altkey.menu.edit=E -altkey.menu.select=S +altkey.menu.range=R +altkey.menu.track=T +altkey.menu.point=P altkey.menu.view=V -altkey.menu.photo=P -altkey.menu.settings=T +altkey.menu.photo=O +altkey.menu.settings=S altkey.menu.help=H # Ctrl shortcuts for menu items @@ -81,14 +83,24 @@ function.compress=Compress track function.addtimeoffset=Add time offset function.addaltitudeoffset=Add altitude offset function.findwaypoint=Find waypoint +function.convertnamestotimes=Convert waypoint names to times +function.pastecoordinates=Enter new coordinates function.charts=Charts function.show3d=Three-D view function.distances=Distances +function.fullrangedetails=Full range details function.getgpsies=Get Gpsies tracks +function.duplicatepoint=Duplicate point function.correlatephotos=Correlate photos +function.rearrangephotos=Rearrange photos +function.rotatephotoleft=Rotate photo left +function.rotatephotoright=Rotate photo right +function.ignoreexifthumb=Ignore exif thumbnail function.setmapbg=Set map background function.setkmzimagesize=Set KMZ image size function.setpaths=Set program paths +function.setcolours=Set colours +function.setlanguage=Set language function.help=Help function.showkeys=Show shortcut keys function.about=About Prune @@ -129,6 +141,7 @@ dialog.gpsload.device=Device name dialog.gpsload.format=Format dialog.gpsload.getwaypoints=Load waypoints dialog.gpsload.gettracks=Load tracks +dialog.gpsload.save=Save to file dialog.gpssend.sendwaypoints=Send waypoints dialog.gpssend.sendtracks=Send tracks dialog.gpssend.trackname=Track name @@ -143,13 +156,16 @@ dialog.save.altitudeunits=Altitude units dialog.save.timestampformat=Timestamp format dialog.save.overwrite.title=File already exists dialog.save.overwrite.text=This file already exists. Are you sure you want to overwrite the file? +dialog.save.notypesselected=No point types have been selected dialog.exportkml.text=Title for the data dialog.exportkml.altitude=Absolute altitudes (for aviation) dialog.exportkml.kmz=Compress to make kmz file dialog.exportkml.exportimages=Export image thumbnails to kmz +dialog.exportkml.trackcolour=Track colour dialog.exportgpx.name=Name dialog.exportgpx.desc=Description dialog.exportgpx.includetimestamps=Include timestamps +dialog.exportgpx.copysource=Copy source xml dialog.exportpov.text=Please enter the parameters for the POV export dialog.exportpov.font=Font dialog.exportpov.camerax=Camera X @@ -163,6 +179,7 @@ dialog.pointtype.desc=Save the following point types: dialog.pointtype.track=Track points dialog.pointtype.waypoint=Waypoints dialog.pointtype.photo=Photo points +dialog.pointtype.selection=Just selection dialog.confirmreversetrack.title=Confirm reversal dialog.confirmreversetrack.text=This track contains timestamp information, which will be out of sequence after a reversal.\nAre you sure you want to reverse this section? dialog.confirmcutandmove.title=Confirm cut and move @@ -194,8 +211,6 @@ dialog.addtimeoffset.minutes=Minutes dialog.addtimeoffset.notimestamps=Cannot add a time offset as this selection doesn't contain any timestamp information dialog.findwaypoint.intro=Enter part of the waypoint name dialog.findwaypoint.search=Search -dialog.connect.title=Connect photo to point -dialog.connectphoto.clonepoint=This point already has a photo.\nDo you want to make a copy of the point? dialog.saveexif.title=Save Exif dialog.saveexif.intro=Select the photos to save using the checkboxes dialog.saveexif.nothingtosave=Coordinate data is unchanged, nothing to save @@ -207,6 +222,7 @@ dialog.saveexif.photostatus.connected=Connected dialog.saveexif.photostatus.disconnected=Disconnected dialog.saveexif.photostatus.modified=Modified dialog.saveexif.overwrite=Overwrite files +dialog.saveexif.force=Force despite minor errors dialog.charts.xaxis=X axis dialog.charts.yaxis=Y axes dialog.charts.output=Output @@ -215,13 +231,13 @@ dialog.charts.svg=Output to SVG file dialog.charts.svgwidth=SVG width dialog.charts.svgheight=SVG height dialog.charts.needaltitudeortimes=The track must have either altitudes or time information in order to create charts -dialog.charts.gnuplotpath=Path to gnuplot dialog.charts.gnuplotnotfound=Could not find gnuplot with the given path dialog.distances.intro=Straight line distances between points dialog.distances.column.from=From point dialog.distances.column.to=To point dialog.distances.currentpoint=Current point dialog.distances.toofewpoints=This function needs waypoints in order to calculate the distances between them +dialog.fullrangedetails.intro=Here are the details for the selected range dialog.setmapbg.mapnik=Mapnik (default) dialog.setmapbg.osma=Osma dialog.setmapbg.cyclemap=Cyclemap @@ -254,6 +270,12 @@ dialog.correlate.options.nodistancelimit=No distance limit dialog.correlate.options.distancelimit=Distance limit dialog.correlate.options.correlate=Correlate dialog.correlate.alloutsiderange=All photos are outside the time range of the track, so none can be correlated.\nTry changing the offset or manually correlating at least one photo. +dialog.rearrangephotos.desc=Select the destination and sort order of the photo points +dialog.rearrangephotos.tostart=Move to start +dialog.rearrangephotos.toend=Move to end +dialog.rearrangephotos.nosort=Don't sort +dialog.rearrangephotos.sortbyfilename=Sort by filename +dialog.rearrangephotos.sortbytime=Sort by time dialog.compress.nonefound=No data points could be removed dialog.compress.duplicates.title=Duplicate removal dialog.compress.closepoints.title=Nearby point removal @@ -263,6 +285,9 @@ dialog.compress.wackypoints.paramdesc=Distance factor dialog.compress.singletons.title=Singleton removal dialog.compress.singletons.paramdesc=Distance factor dialog.compress.summarylabel=Points to delete +dialog.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.about.version=Version dialog.about.build=Build @@ -304,6 +329,7 @@ dialog.saveconfig.desc=The following settings can be saved to a configuration fi dialog.saveconfig.prune.trackdirectory=Track directory dialog.saveconfig.prune.photodirectory=Photo directory dialog.saveconfig.prune.languagecode=Language code (EN) +dialog.saveconfig.prune.languagefile=Language file dialog.saveconfig.prune.gpsdevice=GPS device dialog.saveconfig.prune.gpsformat=GPS format dialog.saveconfig.prune.povrayfont=Povray font @@ -313,12 +339,31 @@ dialog.saveconfig.prune.gpsbabelpath=Path to gpsbabel dialog.saveconfig.prune.exiftoolpath=Path to exiftool dialog.saveconfig.prune.mapserverindex=Index of map server dialog.saveconfig.prune.mapserverurl=URL of map server -dialog.saveconfig.prune.showpace=Show pace dialog.saveconfig.prune.kmzimagewidth=KMZ image width dialog.saveconfig.prune.kmzimageheight=KMZ image height +dialog.saveconfig.prune.colourscheme=Colour scheme +dialog.saveconfig.prune.kmltrackcolour=KML track colour dialog.setpaths.intro=If you need to, you can choose the paths to the external applications: dialog.addaltitude.noaltitudes=The selected range does not contain altitudes dialog.addaltitude.desc=Altitude offset to add +dialog.setcolours.intro=Click on a colour patch to change the colour +dialog.setcolours.background=Background +dialog.setcolours.borders=Borders +dialog.setcolours.lines=Lines +dialog.setcolours.primary=Primary +dialog.setcolours.secondary=Secondary +dialog.setcolours.point=Points +dialog.setcolours.selection=Selection +dialog.setcolours.text=Text +dialog.colourchooser.title=Choose colour +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.language=Language +dialog.setlanguage.languagefile=Language file +dialog.setlanguage.endmessage=Now save your settings and restart Prune\nfor the language change to take effect. # 3d window dialog.3d.title=Prune Three-d view @@ -339,7 +384,9 @@ confirm.reverserange=Range reversed confirm.addtimeoffset=Time offset added confirm.addaltitudeoffset=Altitude offset added confirm.rearrangewaypoints=Waypoints rearranged +confirm.rearrangephotos=Photos rearranged confirm.cutandmove=Selection moved +confirm.convertnamestotimes=Waypoint names converted confirm.saveexif.ok1=Saved confirm.saveexif.ok2=photo files confirm.undo.single=operation undone @@ -350,6 +397,7 @@ confirm.photo.connect=photo connected confirm.photo.disconnect=photo disconnected confirm.correlate.single=photo was correlated confirm.correlate.multi=photos were correlated +confirm.rotatephoto=photo rotated confirm.createpoint=point created confirm.running=Running ... @@ -371,6 +419,7 @@ button.yes=Yes button.no=No button.yestoall=Yes to all button.notoall=No to all +button.select=Select button.selectall=Select all button.selectnone=Select none button.preview=Preview @@ -378,6 +427,8 @@ button.load=Load button.guessfields=Guess fields button.showwebpage=Show webpage button.check=Check +button.resettodefaults=Reset to defaults +button.browse=Browse... # File types filetype.txt=TXT files @@ -417,7 +468,9 @@ display.range.time.hours=h display.range.time.days=d details.range.avespeed=Ave speed details.range.avemovingspeed=Moving ave +details.range.numsegments=Number of segments details.range.pace=Pace +details.range.gradient=Gradient details.waypointsphotos.waypoints=Waypoints details.waypointsphotos.photos=Photos details.photodetails=Photo details @@ -491,7 +544,10 @@ undo.cutandmove=move section undo.connectphoto=connect photo undo.disconnectphoto=disconnect photo undo.correlate=correlate photos +undo.rearrangephotos=rearrange photos +undo.rotatephoto=rotate photo undo.createpoint=create point +undo.convertnamestotimes=convert names to times # Error messages error.save.dialogtitle=Error saving data @@ -500,6 +556,10 @@ error.save.failed=Failed to save the data to file error.saveexif.filenotfound=Failed to find photo file error.saveexif.cannotoverwrite1=Photo file error.saveexif.cannotoverwrite2=is read-only and can't be overwritten. Write to copy? +error.saveexif.failed1=Failed to save +error.saveexif.failed2=of the images +error.saveexif.forced1= +error.saveexif.forced2=of the images required forcing error.load.dialogtitle=Error loading data error.load.noread=Cannot read file error.load.nopoints=No coordinate information found in the file @@ -511,13 +571,16 @@ error.jpegload.nofilesfound=No files found error.jpegload.nojpegsfound=No jpeg files found error.jpegload.noexiffound=No EXIF information found error.jpegload.nogpsfound=No GPS information found +error.gpsload.unknown=Unknown error error.undofailed.title=Undo failed error.undofailed.text=Failed to undo operation error.function.noop.title=Function had no effect -error.rearrange.noop=Rearranging waypoints had no effect +error.rearrange.noop=Rearranging points had no effect error.function.notavailable.title=Function not available error.function.nojava3d=This function requires the Java3d library,\navailable from Sun.com. 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.convertnamestotimes.nonames=No names could be converted into times diff --git a/tim/prune/lang/prune-texts_es.properties b/tim/prune/lang/prune-texts_es.properties index b8baa47..e610064 100644 --- a/tim/prune/lang/prune-texts_es.properties +++ b/tim/prune/lang/prune-texts_es.properties @@ -8,6 +8,7 @@ menu.file.addphotos=Cargar fotos menu.file.save=Guardar menu.file.exit=Salir menu.edit=Editar +menu.track=Track menu.edit.undo=Deshacer menu.edit.clearundo=Despejar la lista de deshacer menu.edit.editpoint=Editar punto @@ -24,6 +25,8 @@ menu.edit.rearrange.end=Ir al final menu.edit.rearrange.nearest=Ir al m\u00e1s pr\u00f3ximo menu.edit.cutandmove=Cortar y mover selecci\u00f3n menu.select=Seleccionar +menu.range=Rango +menu.point=Punto menu.select.all=Seleccionar todo menu.select.none=No seleccionar nada menu.select.start=Fijar comienzo @@ -38,9 +41,9 @@ menu.view.browser=Mapa en un navegador menu.view.browser.google=Google maps menu.view.browser.openstreetmap=Openstreetmap menu.view.browser.mapquest=Mapquest -menu.view.browser.yahoo=mapas Yahoo +menu.view.browser.yahoo=Mapas Yahoo +menu.view.browser.bing=Mapas Bing menu.settings=Preferencias -menu.settings.showpace= menu.help=Ayuda # Popup menu for map menu.map.zoomin=Ampliar zoom @@ -50,12 +53,15 @@ menu.map.newpoint=Crear uno punto nuevo menu.map.connect=Conectar puntos de track menu.map.autopan=Posicionar autom\u00e1ticamente menu.map.showmap=Mostrar el mapa -menu.map.showscalebar= +menu.map.showscalebar=Mostrar barra de escala # Alt keys for menus altkey.menu.file=A altkey.menu.edit=E altkey.menu.select=S +altkey.menu.track=T +altkey.menu.range=R +altkey.menu.point=U altkey.menu.view=V altkey.menu.photo=F altkey.menu.settings=P @@ -80,17 +86,27 @@ function.editwaypointname=Editar nombre de waypoint function.compress=Comprimir track function.addtimeoffset=A\u00f1adir compensar tiempo function.addaltitudeoffset=A\u00f1adir compensar altitud +function.convertnamestotimes=Convertir los nombres de los "waypoints" a tiempo function.findwaypoint=Buscar waypoint +function.pastecoordinates=Insertar nuevas coordenadas function.charts=Diagramas function.show3d=Mostrar en 3-D function.distances=Distancias -function.getgpsies=Bajar ruta de Gpsies -function.correlatephotos=Correlacionar fotos +function.fullrangedetails=Detalles adicionales de rango function.setmapbg=Configurar fondo de mapa function.setkmzimagesize=Configurar tama\u00f1os de las im\u00e1genes KMZ function.setpaths=Configurar rutas del programas +function.getgpsies=Bajar ruta de Gpsies +function.duplicatepoint=Duplicar punto +function.setcolours=Establecer color +function.setlanguage=Establecer lenguaje +function.correlatephotos=Correlacionar fotos +function.rearrangephotos=Reacomodar fotos +function.rotatephotoleft=Girar a la izquierda +function.rotatephotoright=Girar a la derecha +function.ignoreexifthumb=Ignorar "thumbnail" de exif function.help=Ayuda -function.showkeys= +function.showkeys=Mostrar teclas o combinaciones de atajo function.about=Acerca de Prune function.checkversion=Buscar una nueva versi\u00f3n function.saveconfig=Guardar preferencias @@ -125,12 +141,13 @@ dialog.jpegload.loadjpegsoutsidearea=Incluir fotos fuera del \u00e1rea dialog.jpegload.progress.title=Cargando fotos dialog.jpegload.progress=Por favor espere mientras se buscan las fotos dialog.gpsload.nogpsbabel=gpsbabel program no encontrado. Desea continuar? -dialog.gpsload.device= +dialog.gpsload.device=Dispositivo dialog.gpsload.format=Formato dialog.gpsload.getwaypoints=Cargar waypoints dialog.gpsload.gettracks=Cargar tracks -dialog.gpssend.sendwaypoints= -dialog.gpssend.sendtracks= +dialog.gpsload.save=Salvar al archivo +dialog.gpssend.sendwaypoints=enviar "waypoints" +dialog.gpssend.sendtracks=enviar tracks dialog.gpssend.trackname=Nombre del track dialog.saveoptions.title=Guardar archivo dialog.save.fieldstosave=Campos a guardar @@ -143,13 +160,16 @@ dialog.save.altitudeunits=Unidades de las altitudes dialog.save.timestampformat=Format del tiempo dialog.save.overwrite.title=El archivo ya existe dialog.save.overwrite.text=El archivo ya existe, desea sobreescribirlo? +dialog.save.notypesselected=No se han seleccionado tipos de puntos dialog.exportkml.text=Descripci\u00f3n para los datos dialog.exportkml.altitude=Absoluta altitudes (para aviaci\u00f3n) dialog.exportkml.kmz=Comprimir al archivo kmz dialog.exportkml.exportimages=Exportar fotos al kmz +dialog.exportkml.trackcolour=Color del track dialog.exportgpx.name=Nombre dialog.exportgpx.desc=Descripci\u00f3n dialog.exportgpx.includetimestamps=Tiempo tambien +dialog.exportgpx.copysource=Copiar la fuente dialog.exportpov.text=Introdzca los Parametros para exportar dialog.exportpov.font=Fuente dialog.exportpov.camerax=C\u00e1mara X @@ -159,13 +179,13 @@ dialog.exportpov.modelstyle=Estilo dialog.exportpov.ballsandsticks=Balas en palos dialog.exportpov.tubesandwalls=Tubos y paredes dialog.exportpov.warningtracksize=Este track contiene un gran numero de puntos. Puede ser que Java3D no los pueda visualizar. Est\u00e1 seguro de que desea continuar? -dialog.pointtype.desc= -dialog.pointtype.track= -dialog.pointtype.waypoint= -dialog.pointtype.photo= +dialog.pointtype.desc=Salvar los siguientes tipos de puntos: +dialog.pointtype.track=Puntos de track +dialog.pointtype.photo=Puntos de foto +dialog.pointtype.selection=Solo selecci\u00f3n dialog.confirmreversetrack.title=Confirmar inversi\u00f3n dialog.confirmreversetrack.text=Este track contiene informaci\u00f3n sobre la fecha, que estar\u00e1 fuera de secuencia despu\u00e9s de la inversi\u00f3n. Esta seguro que desea invertir esta secci\u00f3n? -dialog.confirmcutandmove.title=Confirmar ... +dialog.confirmcutandmove.title=Confirmar accion cortar/pegar dialog.confirmcutandmove.text=Este track contiene informaci\u00f3n sobre la fecha, que estar\u00e1 fuera de secuencia despu\u00e9s de la .... Esta seguro que desea ... esta secci\u00f3n? dialog.interpolate.title=Interpolar puntos dialog.interpolate.parameter.text=N\u00famero de los puntos a insertar entre los puntos elegidos @@ -186,16 +206,16 @@ dialog.pointnameedit.name=Nombre de waypoint dialog.pointnameedit.uppercase=May\u00fasculas dialog.pointnameedit.lowercase=min\u00fasculas dialog.pointnameedit.sentencecase=Mezcla -dialog.addtimeoffset.add= -dialog.addtimeoffset.subtract= +dialog.addtimeoffset.add=a\u00f1adir tiempo +dialog.addtimeoffset.subtract=sustraer tiempo dialog.addtimeoffset.days=Dias dialog.addtimeoffset.hours=Horas dialog.addtimeoffset.minutes=Minutos -dialog.addtimeoffset.notimestamps= -dialog.findwaypoint.intro= -dialog.findwaypoint.search= +dialog.addtimeoffset.notimestamps=No se puede a\u00f1adir tiempo de puesta a esta selecci\u00f3n si \u00e9sta no contiene ninguna informaci\u00f3n de "timestamp" +dialog.findwaypoint.intro=Ingresar parte del nombre de "waypoint" +dialog.findwaypoint.search=Buscar dialog.connect.title=Conectar foto -dialog.connectphoto.clonepoint= +dialog.connectphoto.clonepoint=Este punto ya tiene una foto.\n Quisiera usted hacer una copia de este? dialog.saveexif.title=Guardar Exif dialog.saveexif.intro=Seleccione fotos a guardar dialog.saveexif.nothingtosave=Coordenadas no modificadas, nada que guardar @@ -207,31 +227,30 @@ dialog.saveexif.photostatus.connected=Conectada dialog.saveexif.photostatus.disconnected=Desconectada dialog.saveexif.photostatus.modified=Modificada dialog.saveexif.overwrite=Sobreescribirlar archivos? +dialog.saveexif.force=Fuerza despreciar errores menores dialog.charts.xaxis=Eje de abscisas dialog.charts.yaxis=Eje vertical dialog.charts.output=Resultado -dialog.charts.screen= -dialog.charts.svg= -dialog.charts.svgwidth= -dialog.charts.svgheight= -dialog.charts.needaltitudeortimes= -dialog.charts.gnuplotpath= -dialog.charts.gnuplotnotfound= -dialog.distances.intro= +dialog.charts.screen=Salida a pantalla +dialog.charts.svg=Salida a archivo SVG +dialog.charts.svgwidth=Ancho de SVG +dialog.charts.svgheight=Alto de SVG +dialog.charts.needaltitudeortimes=La pista debe tener altitudes o informaci\u00f3n de tiempo en orden para crear las tablas +dialog.charts.gnuplotnotfound=No pudo ser encontrado gnuplot con el camino o la direcci\u00f3n proporcionada +dialog.distances.intro=L\u00edneas rectas entre puntos dialog.distances.column.from=De punto dialog.distances.column.to=Al punto dialog.distances.currentpoint=Punto actual -dialog.distances.toofewpoints= -dialog.setmapbg.mapnik=Mapnik (por defecto) -dialog.setmapbg.osma= -dialog.setmapbg.cyclemap= +dialog.distances.toofewpoints=Esta funcion necesita "waypoints" para poder calcular las distancias entre ellos +dialog.fullrangedetails.intro=Aqui estan los detalles para la selecci\u00f3n de rangos +dialog.setmapbg.mapnik=Mapnik (predeterminado) dialog.setmapbg.other=Otro -dialog.setmapbg.server= -dialog.gpsies.column.name=Nombre -dialog.gpsies.column.length= +dialog.setmapbg.server=Direcci\u00f3n URL del servidor +dialog.gpsies.column.name=Nombre del track +dialog.gpsies.column.length=Distancia dialog.gpsies.description=Descripci\u00f3n -dialog.gpsies.nodescription=Ning\u00fan descripci\u00f3n -dialog.gpsies.nonefound= +dialog.gpsies.nodescription=Sin Descripci\u00f3n +dialog.gpsies.nonefound=No se encontraron pistas dialog.correlate.notimestamps=No hay informaci\u00f3n de tiempo para los puntos, as\u00ed que no hay nada que correlacionar con las fotos. dialog.correlate.nouncorrelatedphotos=No hay fotos no correlacionadas.\nEst\u00e1 seguro de que desea continuar? dialog.correlate.photoselect.intro=Seleccione una de estas fotos correlacionadas para usar como margen de tiempo @@ -254,18 +273,24 @@ dialog.correlate.options.nodistancelimit=Sin l\u00edmite de distancia dialog.correlate.options.distancelimit=L\u00edmite de distancia dialog.correlate.options.correlate=Correlacionar dialog.correlate.alloutsiderange=Todas las fotos est\u00e1n fuera del margen horario del track, por lo que ninguna puede ser correlada.\nIntente cambiar el margen o correle manualmente al menos una foto. +dialog.rearrangephotos.desc=Seleccionar el destino y sortear el orden de los puntos de las fotos +dialog.rearrangephotos.tostart=Mover al comienzo +dialog.rearrangephotos.toend=Mover al final +dialog.rearrangephotos.nosort=No sortear +dialog.rearrangephotos.sortbyfilename=Sortear por nombre del archivo +dialog.rearrangephotos.sortbytime=Sortear por tiempo dialog.compress.nonefound=Ning\u00fan punto eliminado +dialog.compress.closepoints.title=remover puntos cercanos +dialog.compress.wackypoints.paramdesc=Factor distancia +dialog.compress.singletons.paramdesc=Factor distancia dialog.compress.duplicates.title=Eliminar duplicados -dialog.compress.closepoints.title= -dialog.compress.closepoints.paramdesc= -dialog.compress.wackypoints.title= -dialog.compress.wackypoints.paramdesc= -dialog.compress.singletons.title= -dialog.compress.singletons.paramdesc= -dialog.compress.summarylabel= +dialog.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.about.version=Versi\u00f3n -dialog.about.build=Construir +dialog.about.build=Construcci\u00f3n dialog.about.summarytext1=Prune es un programa para cargar, mostrar y editar datos de receptores GPS. dialog.about.summarytext2=Distribuido bajo el GNU GPL para uso libre y gratuito.
Se permite (y se anima) la copia, redistribuci\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. @@ -281,7 +306,7 @@ dialog.about.systeminfo.gpsbabel=Gpsbabel instalado dialog.about.systeminfo.gnuplot=Gnuplot instalado dialog.about.yes=Si dialog.about.no=No -dialog.about.credits=Credits +dialog.about.credits=Creditos dialog.about.credits.code=El c\u00f3digo de Prune fue escrito por dialog.about.credits.exifcode=El c\u00f3digo Exif por dialog.about.credits.icons=Algunos iconos se tomaron de @@ -291,34 +316,52 @@ dialog.about.credits.devtools=Herramientas de desarrollo dialog.about.credits.othertools=Otras herramientas dialog.about.credits.thanks=Gracias a dialog.about.readme=Readme -dialog.checkversion.error= -dialog.checkversion.uptodate= -dialog.checkversion.newversion1= -dialog.checkversion.newversion2= -dialog.checkversion.releasedate1= -dialog.checkversion.releasedate2= -dialog.checkversion.download=To download the new version, go to http://activityworkshop.net/software/prune/download.html. -dialog.keys.intro= -dialog.keys.keylist= -dialog.saveconfig.desc= -dialog.saveconfig.prune.trackdirectory= -dialog.saveconfig.prune.photodirectory= -dialog.saveconfig.prune.languagecode= -dialog.saveconfig.prune.gpsdevice= -dialog.saveconfig.prune.gpsformat= +dialog.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 \u00daltima versi\u00f3n es ahora versi\u00f3n +dialog.checkversion.newversion2=. +dialog.checkversion.releasedate1=La nueva versi\u00f3n fue lanzada en +dialog.checkversion.releasedate2=. +dialog.keys.intro=Usted puede usar el siguiente atajo en lugar de usar el rat\u00f3n +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 +dialog.saveconfig.prune.languagecode=C\u00f3digo de lenguaje (ES) +dialog.saveconfig.prune.languagefile=Archivo de lenguaje +dialog.saveconfig.prune.gpsdevice=Dispositivo GPS +dialog.saveconfig.prune.gpsformat=Formato GPS dialog.saveconfig.prune.povrayfont=Fuente povray -dialog.saveconfig.prune.metricunits= -dialog.saveconfig.prune.gnuplotpath= -dialog.saveconfig.prune.gpsbabelpath= -dialog.saveconfig.prune.exiftoolpath= -dialog.saveconfig.prune.mapserverindex= -dialog.saveconfig.prune.mapserverurl= -dialog.saveconfig.prune.showpace= -dialog.saveconfig.prune.kmzimagewidth= -dialog.saveconfig.prune.kmzimageheight= -dialog.setpaths.intro= -dialog.addaltitude.noaltitudes= +dialog.saveconfig.prune.metricunits=Usar unidades m\u00e9tricas? +dialog.saveconfig.prune.gnuplotpath=Camino a gnuplot +dialog.saveconfig.prune.gpsbabelpath=Camino a gpsbabel +dialog.saveconfig.prune.exiftoolpath=Camino a exiftool +dialog.saveconfig.prune.mapserverindex=\u00cdndice de mapa del servidor +dialog.saveconfig.prune.mapserverurl=Direcci\u00f3n URL de mapa del servidor +dialog.saveconfig.prune.kmzimagewidth=Ancho de im\u00e1genes en kmz +dialog.saveconfig.prune.kmzimageheight=Alto de im\u00e1genes en kmz +dialog.saveconfig.prune.colourscheme=Color de esquema +dialog.saveconfig.prune.kmltrackcolour=Color de pista de KML +dialog.setpaths.intro=Si usted necesita, puede escoger las rutas a aplicaciones externas +dialog.addaltitude.noaltitudes=Los rangos seleccionados no contienen altitudes dialog.addaltitude.desc= +dialog.setcolours.intro=Clickear sobre una placa de color para cambiar el color +dialog.setcolours.background=Fondo +dialog.setcolours.borders=Bordes +dialog.setcolours.lines=L\u00edneas +dialog.setcolours.primary=Primario +dialog.setcolours.secondary=Secundario +dialog.setcolours.point=Puntos +dialog.setcolours.selection=Selecci\u00f3n +dialog.setcolours.text=Texto +dialog.colourchooser.title=Elegir color +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 salvar su configuraci\u00f3n y luego

reiniciar Prune para cambiar el lenguaje +dialog.setlanguage.language=Lenguaje +dialog.setlanguage.languagefile=Archivo de lenguaje +dialog.setlanguage.endmessage=Ahora salve su configuraci\u00f3n y reinicie Prune\npara que los cambios tomen efecto. # 3d window dialog.3d.title=Prune vista 3-D @@ -336,10 +379,9 @@ confirm.deletepoint.multi=puntos eliminados confirm.point.edit=Punto editado confirm.mergetracksegments=Segmentos unidos confirm.reverserange=Rango invertido -confirm.addtimeoffset= -confirm.addaltitudeoffset= confirm.rearrangewaypoints=Waypoints reorganizados -confirm.cutandmove= +confirm.rearrangephotos=Fotos reacomodadas +confirm.cutandmove=Mover Selecci\u00f3n confirm.saveexif.ok1=Guardando confirm.saveexif.ok2=fotos confirm.undo.single=operaci\u00f3n no realizada @@ -351,9 +393,10 @@ confirm.photo.disconnect=Foto desconectado confirm.correlate.single=foto fue correlada confirm.correlate.multi=fotos fueron correladas confirm.createpoint=punto creado +confirm.rotatephoto=Foto rotada confirm.running=Trabajando ... -# Buttons +# Buttons || These are all the texts for buttons button.ok=Aceptar button.back=Anterior button.next=Siguiente @@ -371,6 +414,7 @@ button.yes=Si button.no=No button.yestoall=Si por todo button.notoall=No por todo +button.select=Seleccionar button.selectall=Seleccionar todo button.selectnone=Seleccionar nada button.preview=Previsualizaci\u00f3n @@ -378,6 +422,7 @@ button.load=Cargar button.guessfields=Adivinar campos button.showwebpage=Mostrar p\u00e1gina web button.check=Verificar +button.resettodefaults=Restablecer valores a los predeterminados # File types filetype.txt=Archivos TXT @@ -389,7 +434,7 @@ filetype.gpx=Archivos GPX filetype.pov=Archivos POV filetype.svg=Archivos SVG -# Display components +# Display components || These are all for the side panels showing point/range details display.nodata=Ning\u00fan dato cargado display.noaltitudes=Los datos del track no incluyen altitudes details.trackdetails=Detalles del track @@ -416,15 +461,16 @@ display.range.time.mins=m display.range.time.hours=h display.range.time.days=d details.range.avespeed=Velocidad media -details.range.avemovingspeed= -details.range.pace= +details.range.avemovingspeed=Moviendo promedio +details.range.numsegments=N\u00famero de segmentos +details.range.gradient=Gradiente details.waypointsphotos.waypoints=Waypoints details.waypointsphotos.photos=Fotos details.photodetails=Detalles del Foto details.nophoto=Ninguna foto seleccionada details.photo.loading=Cargando details.photo.connected=Conectada -map.overzoom= +map.overzoom=No existen mapas disponibles con este nivel de enfoque # Field names fieldname.latitude=Latitud @@ -438,7 +484,7 @@ fieldname.newsegment=Segmento fieldname.custom=Personalizado fieldname.prefix=Campo fieldname.distance=Distancia -fieldname.movingdistance= +fieldname.movingdistance=Distancia en movimiento fieldname.duration=Duraci\u00f3n fieldname.speed=Velocidad fieldname.verticalspeed=Velocidad vertical @@ -473,7 +519,7 @@ cardinal.s=S cardinal.e=E cardinal.w=O -# Undo operations +# Undo operations || These will be displayed in the undo list after you've performed the operation, to tell you what you did undo.load=cargar datos undo.loadphotos=cargar fotos undo.editpoint=editar punto @@ -484,13 +530,11 @@ undo.compress=comprimir track undo.insert=insertar puntos undo.reverse=invertir rango undo.mergetracksegments=unir los segmentos de track -undo.addtimeoffset= -undo.addaltitudeoffset= undo.rearrangewaypoints=reordenar waypoints -undo.cutandmove= undo.connectphoto=conectar foto undo.disconnectphoto=desconectar foto undo.correlate=correlacionar fotos +undo.rotatephoto=girar foto undo.createpoint=crear punto # Error messages @@ -500,6 +544,8 @@ error.save.failed=Fallo al guardar datos al archivo error.saveexif.filenotfound=Archivo no encontrado error.saveexif.cannotoverwrite1=No se puede guardar error.saveexif.cannotoverwrite2=. Guardar a una copia? +error.saveexif.failed1=Fall\u00f3 al salvar +error.saveexif.failed2=de las im\u00e1genes error.load.dialogtitle=Fallo al cargar datos error.load.noread=No se puede leer el fichero error.load.nopoints=Ninguna informaci\u00f3n coordenadas encontrada @@ -511,13 +557,16 @@ error.jpegload.nofilesfound=Ning\u00fan archivo encontrado error.jpegload.nojpegsfound=Ning\u00fan archivo jpeg encontrado error.jpegload.noexiffound=Ninguna informaci\u00f3n EXIF encontrada error.jpegload.nogpsfound=Ninguna informaci\u00f3n GPS encontrada +error.gpsload.unknown=Error desconocido error.undofailed.title=Fallo al deshacer error.undofailed.text=No ha sido posible deshacer la operaci\u00f3n error.function.noop.title=La funci\u00f3n no se ha efectuado -error.rearrange.noop=Reordenaci\u00f3n de waypoints no se ha efectuado +error.rearrange.noop=Reordenaci\u00f3n de puntos no se ha efectuado error.function.notavailable.title=Funci\u00f3n no disponible error.function.nojava3d=Esta funci\u00f3n requiere la librer\u00eda Java3d, disponible en Sun.com. error.3d=Ha ocurrido un error con la funci\u00f3n 3-D error.readme.notfound=Archivo readme no encontrado error.osmimage.dialogtitle=Error al cargar el mapa error.osmimage.failed=Imposible cargar el mapa. Por favor, compruebe la conexi\u00f3n a internet. +error.language.wrongfile=El archivo seleccionado no parece ser un archivo de lenguaje para Prune +error.convertnamestotimes.nonames=Los nombres no pudieron ser convertidos en tiempos diff --git a/tim/prune/lang/prune-texts_fr.properties b/tim/prune/lang/prune-texts_fr.properties index a3e16ec..b5d9e27 100644 --- a/tim/prune/lang/prune-texts_fr.properties +++ b/tim/prune/lang/prune-texts_fr.properties @@ -8,6 +8,7 @@ menu.file.addphotos=Ajouter photos menu.file.save=Enregistrer menu.file.exit=Quitter menu.edit=\u00c9dition +menu.track=Trace menu.edit.undo=Annuler menu.edit.clearundo=Purger la liste d'annulation menu.edit.editpoint=Editer le point @@ -24,6 +25,8 @@ menu.edit.rearrange.end=Tous \u00e0 la fin du fichier menu.edit.rearrange.nearest=Chacun au point de trace le plus proche menu.edit.cutandmove=Couper et bouger la s\u00e9lection menu.select=S\u00e9lectionner +menu.range=\u00c9tendue +menu.point=Point menu.select.all=Tout s\u00e9lectionner menu.select.none=Rien s\u00e9lectionner menu.select.start=D\u00e9finir le d\u00e9but de l'\u00e9tendue @@ -39,6 +42,7 @@ menu.view.browser.google=Google maps menu.view.browser.openstreetmap=Openstreetmap 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.showpace=Montrer allure dans les d\u00e9tails menu.help=Aide @@ -56,8 +60,11 @@ menu.map.showscalebar=Montrer l'echelle altkey.menu.file=F altkey.menu.edit=E altkey.menu.select=S +altkey.menu.track=T +altkey.menu.range=E +altkey.menu.point=P altkey.menu.view=A -altkey.menu.photo=P +altkey.menu.photo=H altkey.menu.settings=R altkey.menu.help=I @@ -80,15 +87,25 @@ function.editwaypointname=Editer 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.findwaypoint=Trouver un waypoint +function.pastecoordinates=Coller les coordonn\u00e9es function.charts=Graphiques function.show3d=Montrer en 3D function.distances=Distances -function.getgpsies=R\u00e9cup\u00e9rer les traces Gpsies -function.correlatephotos=Corr\u00e9ler les photos +function.fullrangedetails=Montrer tous les d\u00e9tails 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.duplicatepoint=Duppliquer le point +function.setcolours=R\u00e9gler les couleurs +function.setlanguage=R\u00e9gler la langue +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.ignoreexifthumb=Ignorer l\u2019aper\u00e7u Exif function.help=Aide function.showkeys=Montrer les raccourcis clavier function.about=À propos de Prune @@ -129,6 +146,7 @@ dialog.gpsload.device=Chemin du p\u00e9riph\u00e9rique dialog.gpsload.format=Format dialog.gpsload.getwaypoints=T\u00e9l\u00e9charger les waypoints dialog.gpsload.gettracks=T\u00e9l\u00e9charger les traces +dialog.gpsload.save=Enregistrer dans un fichier dialog.gpssend.sendwaypoints=Envoyer les waypoints dialog.gpssend.sendtracks=Envoyer les traces dialog.gpssend.trackname=Nom de trace @@ -143,13 +161,16 @@ dialog.save.altitudeunits=Unit\u00e9s d'altitude dialog.save.timestampformat=Format de l'heure dialog.save.overwrite.title=Le fichier existe d\u00e9j\u00e0 dialog.save.overwrite.text=Ce fichier existe d\u00e9j\u00e0. \u00cates-vous s\u00fbr de vouloir \u00e9craser ce fichier ? +dialog.save.notypesselected=Aucun type de point n\u2019a \u00e9t\u00e9 s\u00e9lectionn\u00e9 dialog.exportkml.text=Titre pour les donn\u00e9es dialog.exportkml.altitude=Absolues altitudes (pour aviation) dialog.exportkml.kmz=Compresser au format kmz dialog.exportkml.exportimages=Exporter les vignettes au format kmz +dialog.exportkml.trackcolour=Couleur de la trace dialog.exportgpx.name=Nom dialog.exportgpx.desc=L\u00e9gende dialog.exportgpx.includetimestamps=Inclure l'heure pour chaque point +dialog.exportgpx.copysource=Copier le XML source dialog.exportpov.text=Entrez les param\u00e8tres pour l'export POV dialog.exportpov.font=Police dialog.exportpov.camerax=Cam\u00e9ra X @@ -163,6 +184,7 @@ 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.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 ? dialog.confirmcutandmove.title=Confirmer le d\u00e9placement @@ -207,6 +229,7 @@ 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.force=Ignorer les erreurs mineures dialog.charts.xaxis=Axe des x dialog.charts.yaxis=Axe des y dialog.charts.output=Sortie @@ -215,13 +238,13 @@ dialog.charts.svg=Sortie dans un fichier SVG dialog.charts.svgwidth=Largeur de l'image SVG dialog.charts.svgheight=Hauteur de l'image SVG dialog.charts.needaltitudeortimes=La trace ne peut g\u00e9n\u00e9rer des graphiques sans disposer d'altitudes ou d'indications temporelles -dialog.charts.gnuplotpath=Chemin gnuplot dialog.charts.gnuplotnotfound=Gnuplot est introuvable dans le chemin indiqu\u00e9 dialog.distances.intro=Distances \u00e0 vol d'oiseau entre des points dialog.distances.column.from=Du point dialog.distances.column.to=Vers le point dialog.distances.currentpoint=Point courant dialog.distances.toofewpoints=Cette fonction a besoin de waypoints pour calculer les distances entre eux +dialog.fullrangedetails.intro=Voici les d\u00e9tails pour l\u2019\u00e9tendue s\u00e9lectionn\u00e9e dialog.setmapbg.mapnik=Mapnik (d\u00e9faut) dialog.setmapbg.osma=Osma dialog.setmapbg.cyclemap=Cyclemap @@ -254,21 +277,30 @@ 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.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 +dialog.rearrangephotos.nosort=Ne pas trier +dialog.rearrangephotos.sortbyfilename=Trier par nom de fichier +dialog.rearrangephotos.sortbytime=Trier par horodatage dialog.compress.nonefound=Pas de donn\u00e9es \u00e0 effacer -dialog.compress.duplicates.title=Suppression des doublons dialog.compress.closepoints.title=Suppression des points voisins dialog.compress.closepoints.paramdesc=Taille du voisinage dialog.compress.wackypoints.title=Suppression des points anormaux dialog.compress.wackypoints.paramdesc=Distance dialog.compress.singletons.title=Suppression des points isol\u00e9s dialog.compress.singletons.paramdesc=Distance +dialog.compress.duplicates.title=Suppression des doublons 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.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.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.summarytext3=Consultez la page http://activityworkshop.net/ pour plus de d\u00e9tails et des manuels utilisateur. dialog.about.languages=Langues disponibles dialog.about.translatedby=Texte en fran\u00e7ais par Petrovsk et theYinYeti. dialog.about.systeminfo=Info Syst\u00e8me @@ -304,6 +336,7 @@ dialog.saveconfig.desc=Les param\u00e8tres suivants peuvent \u00eatre sauvegard\ dialog.saveconfig.prune.trackdirectory=Dossier des traces dialog.saveconfig.prune.photodirectory=Dossier des Photos dialog.saveconfig.prune.languagecode=Code langue (FR) +dialog.saveconfig.prune.languagefile=Fichier de langue dialog.saveconfig.prune.gpsdevice=Chemin du p\u00e9riph\u00e9rique GPS dialog.saveconfig.prune.gpsformat=Format GPS dialog.saveconfig.prune.povrayfont=Police povray @@ -316,9 +349,26 @@ dialog.saveconfig.prune.mapserverurl=URL du serveur de carte dialog.saveconfig.prune.showpace=Montrer l'allure dialog.saveconfig.prune.kmzimagewidth=Largeur de l'image KMZ dialog.saveconfig.prune.kmzimageheight=Hauteur de l'image KMZ +dialog.saveconfig.prune.colourscheme=Mod\u00e8le de couleurs +dialog.saveconfig.prune.kmltrackcolour=Couleur de la trace KML dialog.setpaths.intro=Si vous le souhaitez, vous pouvez d\u00e9finir les chemins des applications externes: dialog.addaltitude.noaltitudes=L'\u00e9tendue s\u00e9lectionn\u00e9e de contient pas d'altitudes dialog.addaltitude.desc=D\u00e9callage d'altitude \u00e0 ajouter +dialog.setcolours.intro=Cliquez sur une couleur pour la changer +dialog.setcolours.background=Arri\u00e8re-plan +dialog.setcolours.borders=Bordures +dialog.setcolours.lines=Lignes +dialog.setcolours.primary=Primaires +dialog.setcolours.secondary=Secondaires +dialog.setcolours.point=Points +dialog.setcolours.selection=S\u00e9lection +dialog.setcolours.text=Texte +dialog.colourchooser.title=Choisissez la couleur +dialog.colourchooser.red=Rouge +dialog.colourchooser.green=Vert +dialog.colourchooser.blue=Bleu +dialog.setlanguage.language=Langue +dialog.setlanguage.languagefile=Fichier de langue # 3d window dialog.3d.title=Vue 3D de Prune @@ -339,7 +389,9 @@ confirm.reverserange=Etendue invers\u00e9e confirm.addtimeoffset=D\u00e9calage ajout\u00e9 confirm.addaltitudeoffset=D\u00e9calage d'altitude ajout\u00e9 confirm.rearrangewaypoints=Waypoints r\u00e9arrang\u00e9s +confirm.rearrangephotos=Photos r\u00e9arrang\u00e9es confirm.cutandmove=S\u00e9lection d\u00e9plac\u00e9e +confirm.convertnamestotimes=Noms de waypoints convertis confirm.saveexif.ok1=Enregistrement de confirm.saveexif.ok2=fichiers photo confirm.undo.single=op\u00e9ration annul\u00e9e @@ -351,9 +403,10 @@ confirm.photo.disconnect=photo d\u00e9tach\u00e9e confirm.correlate.single=photo a \u00e9t\u00e9 corr\u00e9l\u00e9e confirm.correlate.multi=photos ont \u00e9t\u00e9 corr\u00e9l\u00e9es confirm.createpoint=Point cr\u00e9\u00e9 +confirm.rotatephoto=Photo tourn\u00e9e confirm.running=En cours... -# Buttons +# Buttons || These are all the texts for buttons button.ok=OK button.back=Retour button.next=Prochain @@ -371,6 +424,7 @@ button.yes=Oui button.no=Non button.yestoall=Oui pour tous button.notoall=Non pour tous +button.select=S\u00e9lectionner button.selectall=Tout s\u00e9lectionner button.selectnone=Ne rien s\u00e9lectionner button.preview=Aper\u00e7u @@ -378,6 +432,7 @@ button.load=T\u00e9l\u00e9charger button.guessfields=Deviner les champs button.showwebpage=Montrer page web button.check=V\u00e9rifier +button.resettodefaults=Revenir aux valeurs par d\u00e9faut # File types filetype.txt=Fichiers TXT @@ -389,7 +444,7 @@ filetype.gpx=Fichiers GPX filetype.pov=Fichiers POV filetype.svg=Fichiers SVG -# Display components +# Display components || These are all for the side panels showing point/range details display.nodata=Pas de donn\u00e9es charg\u00e9es display.noaltitudes=La trace ne comporte pas d'information d'altitude details.trackdetails=D\u00e9tails de la trace @@ -417,7 +472,9 @@ display.range.time.hours=h display.range.time.days=j details.range.avespeed=Vitesse moyenne details.range.avemovingspeed=Moyenne continue +details.range.numsegments=Nombre de segments details.range.pace=Allure +details.range.gradient=Pente details.waypointsphotos.waypoints=Waypoints details.waypointsphotos.photos=Photos details.photodetails=D\u00e9tails de la photo @@ -473,7 +530,7 @@ cardinal.s=S cardinal.e=E cardinal.w=O -# Undo operations +# Undo operations || These will be displayed in the undo list after you've performed the operation, to tell you what you did undo.load=charger les donn\u00e9es undo.loadphotos=charger les photos undo.editpoint=\u00e9diter le point @@ -491,7 +548,10 @@ undo.cutandmove=d\u00e9placer la s\u00e9lection undo.connectphoto=relier la photo undo.disconnectphoto=d\u00e9tacher la photo undo.correlate=corr\u00e9ler 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 # Error messages error.save.dialogtitle=Erreur \u00e0 l'enregistrement des donn\u00e9es @@ -500,6 +560,10 @@ error.save.failed=Echec de l'enregistrement des donn\u00e9es dans le fichier error.saveexif.filenotfound=Fichier photo introuvable error.saveexif.cannotoverwrite1=Le fichier photo error.saveexif.cannotoverwrite2=est en lecture seule et ne peut pas \u00eatre \u00e9craser. Enregistrer sur une copie ? +error.saveexif.failed1=\u00c9chec de la sauvegarde de +error.saveexif.failed2=images +error.saveexif.forced1=Enregistrement forc\u00e9 pour +error.saveexif.forced2=images error.load.dialogtitle=Erreur au chargement des donn\u00e9es error.load.noread=Fichier illisible error.load.nopoints=Aucune coordonn\u00e9e trouv\u00e9e dans le fichier @@ -511,10 +575,11 @@ error.jpegload.nofilesfound=Aucun fichier trouv\u00e9 error.jpegload.nojpegsfound=Aucun fichier jpeg trouv\u00e9 error.jpegload.noexiffound=Aucune information EXIF trouv\u00e9e error.jpegload.nogpsfound=Aucune information GPS trouv\u00e9e +error.gpsload.unknown=Erreur inconnue error.undofailed.title=Echec de l'annulation error.undofailed.text=Echec de l'op\u00e9ration d'annulation error.function.noop.title=Fonction sans effet -error.rearrange.noop=R\u00e9arrangement des waypoints sans effet +error.rearrange.noop=R\u00e9arrangement des points sans effet error.function.notavailable.title=Function non-disponible error.function.nojava3d=Cette fonction n\u00e9cessite la librairie Java3d,\ndisponible sur Sun.com. error.3d=Un probl\u00e8me est survenu avec l'affichage 3D diff --git a/tim/prune/lang/prune-texts_in.properties b/tim/prune/lang/prune-texts_in.properties index d31df3f..d76fa2e 100644 --- a/tim/prune/lang/prune-texts_in.properties +++ b/tim/prune/lang/prune-texts_in.properties @@ -7,13 +7,16 @@ menu.file.open=Buka menu.file.addphotos=Muat foto menu.file.save=Simpan menu.file.exit=Keluar -menu.edit=Ubah +#menu.edit=Ubah +menu.track=Track menu.edit.undo=Batal menu.edit.editpoint=Perbaiki titik menu.edit.deletepoint=Hapus titik menu.edit.deleterange=Hapus jarak -menu.select=Pilih +#menu.select=Pilih +menu.range=Jangkauan +menu.point=Titik menu.select.all=Pilih semua menu.select.none=Tidak memilih menu.photo=Foto @@ -34,8 +37,11 @@ menu.map.showmap=Tampilkan peta # Alt keys for menus altkey.menu.file=B -altkey.menu.edit=U -altkey.menu.select=P +#altkey.menu.edit=U +#altkey.menu.select=P +altkey.menu.track=T +altkey.menu.range=J +altkey.menu.point=K altkey.menu.view=L altkey.menu.photo=F altkey.menu.settings=G @@ -85,6 +91,7 @@ button.next=Lanjut button.close=Tutup button.yes=Ya button.no=Tidak +button.select=Pilih button.guessfields=Deteksi otomatis # File types diff --git a/tim/prune/lang/prune-texts_it.properties b/tim/prune/lang/prune-texts_it.properties index a219fab..0eb5179 100644 --- a/tim/prune/lang/prune-texts_it.properties +++ b/tim/prune/lang/prune-texts_it.properties @@ -8,6 +8,7 @@ menu.file.addphotos=Aggiungi foto menu.file.save=Salva menu.file.exit=Esci menu.edit=Edita +menu.track=Traccia menu.edit.undo=Annulla menu.edit.clearundo=Cancella lista ultime modifiche menu.edit.editpoint=Edita punto @@ -24,6 +25,8 @@ menu.edit.rearrange.end=Tutti alla fine del file menu.edit.rearrange.nearest=Sul punto pi\u00f9 vicino menu.edit.cutandmove=Taglia e muovi la selezione menu.select=Seleziona +menu.range=Serie +menu.point=Punto menu.select.all=Seleziona tutto menu.select.none=Deseleziona tutto menu.select.start=Imposta inizio serie @@ -39,8 +42,9 @@ menu.view.browser.google=Google maps menu.view.browser.openstreetmap=Openstreetmap menu.view.browser.mapquest=Mapquest menu.view.browser.yahoo=mappe Yahoo +menu.view.browser.bing=mappe Bing menu.settings=Preferenze -menu.settings.showpace= +menu.settings.showpace=Mostra passo nel display serie menu.help=Aiuto # Popup menu for map menu.map.zoomin=Zoom + @@ -50,15 +54,18 @@ menu.map.newpoint=Crea punto nuovo menu.map.connect=Aggancia ai punti menu.map.autopan=Autopan menu.map.showmap=Mostra sulla mappa -menu.map.showscalebar= +menu.map.showscalebar=Mostra scala # Alt keys for menus altkey.menu.file=F altkey.menu.edit=E altkey.menu.select=S +altkey.menu.track=T +altkey.menu.range=S +altkey.menu.point=P altkey.menu.view=V altkey.menu.photo=O -altkey.menu.settings=P +altkey.menu.settings=R altkey.menu.help=A # Ctrl shortcuts for menu items @@ -79,21 +86,21 @@ function.exportpov=Esporta in POV function.editwaypointname=Edita nome waypoint function.compress=Comprimi la traccia function.addtimeoffset=Aggiungi uno scarto temporale -function.addaltitudeoffset= -function.findwaypoint= +function.addaltitudeoffset=Aggiungi uno scarto di altitudine +function.findwaypoint=Trova waypoint function.charts=Diagrammi function.show3d=Mostra in 3D function.distances=Mostra distanze -function.getgpsies= -function.correlatephotos=Correla le foto function.setmapbg=Configura sfondo mappa -function.setkmzimagesize= -function.setpaths= +function.setkmzimagesize=Configura dimensione immagine KMZ +function.setpaths=Configura percorsi programmi +function.getgpsies=Ottieni traccie da Gpsies +function.correlatephotos=Correla le foto function.help=Aiuto -function.showkeys= +function.showkeys=Visualizza tasti scelta rapida function.about=Informazioni su Prune function.checkversion=Controlla gli aggiornamenti -function.saveconfig= +function.saveconfig=Salva configurazione # Dialogs dialog.exit.confirm.title=Esci da Prune @@ -159,10 +166,10 @@ dialog.exportpov.modelstyle=Stile del modello dialog.exportpov.ballsandsticks=Palle e bacchette dialog.exportpov.tubesandwalls=Tubi e pareti dialog.exportpov.warningtracksize=Questa traccia ha un elevato numero di punti, e Java3D pu\u00f2 non essere in grado di visualizzarli.\nSei sicuro di voler continuare? -dialog.pointtype.desc= -dialog.pointtype.track= -dialog.pointtype.waypoint= -dialog.pointtype.photo= +dialog.pointtype.desc=Salva i tipi di punti seguenti: +dialog.pointtype.track=Punti traccia +dialog.pointtype.waypoint=Waypoints +dialog.pointtype.photo=Punti foto dialog.confirmreversetrack.title=Conferma l'inversione dialog.confirmreversetrack.text=Questa traccia contiene informazioni sull'orario di scatto che possono essere messe fuori sequenza dopo l'inversione.\nSei sicuro di voler invertire questa sezione? dialog.confirmcutandmove.title=Conferma il taglio e lo spostamento @@ -192,8 +199,8 @@ dialog.addtimeoffset.days=Giorni dialog.addtimeoffset.hours=Ore dialog.addtimeoffset.minutes=Minuti dialog.addtimeoffset.notimestamps=Non posso aggiungere uno scarto temporale a questa selezione perch\u00e9 non contiene informazioni temporali -dialog.findwaypoint.intro= -dialog.findwaypoint.search= +dialog.findwaypoint.intro=Inserisci parte del nome del waypoint +dialog.findwaypoint.search=Cerca dialog.connect.title=Collega la foto al punto dialog.connectphoto.clonepoint=Questo punto ha gi\u00e0 una foto collegata.\nVuoi fare una copia del punto? dialog.saveexif.title=Salva Exif @@ -215,7 +222,6 @@ dialog.charts.svg=Output a file SVG dialog.charts.svgwidth=larghezza SVG dialog.charts.svgheight=altezza SVG dialog.charts.needaltitudeortimes=La traccia necessita di dati altitudine o tempo per creare diagrammi -dialog.charts.gnuplotpath=Path gnuplot dialog.charts.gnuplotnotfound=Gnuplot non trovato nel path indicato dialog.distances.intro=Distanze dirette tra punti dialog.distances.column.from=Dal punto @@ -227,11 +233,10 @@ dialog.setmapbg.osma=Osma dialog.setmapbg.cyclemap=Mappa ciclistica dialog.setmapbg.other=Altro dialog.setmapbg.server=URL server -dialog.gpsies.column.name= -dialog.gpsies.column.length= -dialog.gpsies.description= -dialog.gpsies.nodescription= -dialog.gpsies.nonefound= +dialog.gpsies.column.name=Nome traccia +dialog.gpsies.column.length=Lunghezza +dialog.gpsies.description=Descrizione +dialog.gpsies.nodescription=Senza descrizione dialog.correlate.notimestamps=Non ci sono informazioni temporali tra i dati dei punti, non c'\u00e8 niente per collegarli con le foto. dialog.correlate.nouncorrelatedphotos=Non ci sono foto non correlate.\nSei sicuro di voler continuare? dialog.correlate.photoselect.intro=Selezione una delle foto correlate da usare come scarto dell'orario @@ -255,13 +260,13 @@ dialog.correlate.options.distancelimit=Distanza limite dialog.correlate.options.correlate=Correlate dialog.correlate.alloutsiderange=Tutte le foto sono fuori dall'orario della traccia, e nessuna pu\u00f2 essere correlata.\nProva a cambiare lo scarto o correla manualmente almeno una foto. dialog.compress.nonefound=Nessun punto rimosso -dialog.compress.duplicates.title=Cancella duplicati dialog.compress.closepoints.title=Cancella punti vicini dialog.compress.closepoints.paramdesc=Fattore vicinanza dialog.compress.wackypoints.title=Cancella punti strani dialog.compress.wackypoints.paramdesc=Fattore distanza dialog.compress.singletons.title=Cancella solitari dialog.compress.singletons.paramdesc=Fattore distanza +dialog.compress.duplicates.title=Cancella duplicati dialog.compress.summarylabel=Punti da cancellare dialog.help.help=Per favore vedi\n http://activityworkshop.net/software/prune/\nper maggiori informazioni e per la guida utente. dialog.about.version=Versione @@ -298,31 +303,31 @@ 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.keys.intro= -dialog.keys.keylist= -dialog.saveconfig.desc= -dialog.saveconfig.prune.trackdirectory= -dialog.saveconfig.prune.photodirectory= -dialog.saveconfig.prune.languagecode= +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.saveconfig.desc=Le configurazioni seguenti possono essere salvati in un file di configurazione: +dialog.saveconfig.prune.trackdirectory=Cartella traccie +dialog.saveconfig.prune.photodirectory=Cartella foto +dialog.saveconfig.prune.languagecode=Codice linguaggio (EN) dialog.saveconfig.prune.gpsdevice=Nome del Dispositivo GPS dialog.saveconfig.prune.gpsformat=Formato GPS dialog.saveconfig.prune.povrayfont=Font povray -dialog.saveconfig.prune.metricunits= +dialog.saveconfig.prune.metricunits=Utilizza unita' metrica? dialog.saveconfig.prune.gnuplotpath=Path gnuplot dialog.saveconfig.prune.gpsbabelpath=Path gpsbabel dialog.saveconfig.prune.exiftoolpath=Path exiftool -dialog.saveconfig.prune.mapserverindex= -dialog.saveconfig.prune.mapserverurl= -dialog.saveconfig.prune.showpace= -dialog.saveconfig.prune.kmzimagewidth= -dialog.saveconfig.prune.kmzimageheight= -dialog.setpaths.intro= -dialog.addaltitude.noaltitudes= -dialog.addaltitude.desc= +dialog.saveconfig.prune.mapserverindex=Indice server mappe +dialog.saveconfig.prune.mapserverurl=URL del server mappe +dialog.saveconfig.prune.showpace=Mostra passo +dialog.saveconfig.prune.kmzimagewidth=larghezza immagine KMZ +dialog.saveconfig.prune.kmzimageheight=altezza immagine KMZ +dialog.setpaths.intro=Se necessario, puoi indicare il percorso delle applicazioni esterne: +dialog.addaltitude.noaltitudes=L'intervallo selezionato non contiene altitudini +dialog.addaltitude.desc=Scarto altitudine da aggiungere # 3d window dialog.3d.title=Visione Prune in 3D -dialog.3d.altitudecap=Minimo intervallo si altitudine +dialog.3d.altitudecap=Intervallo altitudine minimo dialog.3dlines.title=Griglia di Prune dialog.3dlines.empty=Nessuna griglia mostrata! dialog.3dlines.intro=Queste sono le linee della griglia per la visione 3D @@ -337,7 +342,7 @@ confirm.point.edit=punto editato confirm.mergetracksegments=segmeni di traccia uniti confirm.reverserange=Intervallo invertito confirm.addtimeoffset=Scarto temporale aggiunto -confirm.addaltitudeoffset= +confirm.addaltitudeoffset=Scarto altitudine aggiunto confirm.rearrangewaypoints=Waypoint riorganizzati confirm.cutandmove=Selezione spostata confirm.saveexif.ok1=Salvato @@ -351,9 +356,9 @@ confirm.photo.disconnect=foto scollegata confirm.correlate.single=foto era correlata confirm.correlate.multi=foto erano correlate confirm.createpoint=punto creato -confirm.running= +confirm.running=Operazione in corso... -# Buttons +# Buttons || These are all the texts for buttons button.ok=OK button.back=Precedente button.next=Prossimo @@ -371,13 +376,14 @@ button.yes=S\u00ec button.no=No button.yestoall=Si a tutto button.notoall=No a tutto +button.select=Seleziona button.selectall=Seleziona tutto button.selectnone=Deseleziona tutto button.preview=Anteprima button.load=Carica button.guessfields=Campi soluzione button.showwebpage=Mostra pagina -button.check= +button.check=Controlla # File types filetype.txt=File TXT @@ -389,7 +395,7 @@ filetype.gpx=File GPX filetype.pov=File POV filetype.svg=File SVG -# Display components +# Display components || These are all for the side panels showing point/range details display.nodata=Nessun dato caricato display.noaltitudes=I dati della traccia non includono l'altitudine details.trackdetails=Dettagli della traccia @@ -417,7 +423,7 @@ display.range.time.hours=h display.range.time.days=g details.range.avespeed=Velocit\u00e0 media details.range.avemovingspeed=Velocit\u00e0 media in movimento -details.range.pace= +details.range.pace=Passo details.waypointsphotos.waypoints=Waypoint details.waypointsphotos.photos=Foto details.photodetails=Dettagli foto @@ -473,7 +479,7 @@ cardinal.s=S cardinal.e=E cardinal.w=O -# Undo operations +# Undo operations || These will be displayed in the undo list after you've performed the operation, to tell you what you did undo.load=carica dati undo.loadphotos=carica foto undo.editpoint=edita punto @@ -485,7 +491,7 @@ undo.insert=inserisci punti undo.reverse=inverti l'intervallo undo.mergetracksegments=unisci segmenti traccia undo.addtimeoffset=aggiungi scarto temporale -undo.addaltitudeoffset= +undo.addaltitudeoffset=aggiungi scarto altitudine undo.rearrangewaypoints=riorganizza waypoint undo.cutandmove=muovi selezione undo.connectphoto=collega foto @@ -520,4 +526,4 @@ error.function.nojava3d=Questa funzione richiede la libreria Java3d,\ndisponibil 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. \ No newline at end of file +error.osmimage.failed=Impossibile caricare le immagini della mappa. Per favore verifica la connessione a internet. diff --git a/tim/prune/lang/prune-texts_ja.properties b/tim/prune/lang/prune-texts_ja.properties new file mode 100644 index 0000000..a54fa2e --- /dev/null +++ b/tim/prune/lang/prune-texts_ja.properties @@ -0,0 +1,573 @@ +# Text entries for the Prune application +# Japanese entries as extra + +# Menu entries +menu.file=\u30d5\u30a1\u30a4\u30eb +menu.file.open=\u30d5\u30a1\u30a4\u30eb\u3092\u958b\u304f +menu.file.addphotos=\u5199\u771f\u3092\u8ffd\u52a0 +menu.file.save=\u4fdd\u5b58 +menu.file.exit=\u7d42\u4e86 +menu.edit=\u7de8\u96c6 +menu.track=\u30c8\u30e9\u30c3\u30af +menu.edit.undo=\u30a2\u30f3\u30c9\u30a5 +menu.edit.clearundo=\u30a2\u30f3\u30c9\u30a5\u30ea\u30b9\u30c8\u3092\u7a7a\u306b\u3059\u308b +menu.edit.editpoint=\u70b9\u3092\u7de8\u96c6 +menu.edit.deletepoint=\u70b9\u3092\u524a\u9664 +menu.edit.deleterange=\u7bc4\u56f2\u3092\u524a\u9664 +menu.edit.deletemarked=\u5370\u306e\u4ed8\u3044\u305f\u70b9\u3092\u524a\u9664 +menu.edit.interpolate=\u88dc\u5b8c +menu.edit.average=\u9078\u629e\u7bc4\u56f2\u3092\u5e73\u5747\u5316 +menu.edit.reverse=\u7bc4\u56f2\u3092\u53cd\u8ee2 +menu.edit.mergetracksegments=\u30c8\u30e9\u30c3\u30af\u30bb\u30b0\u30e1\u30f3\u30c8\u3092\u7d71\u5408 +menu.edit.rearrange=\u30a6\u30a7\u30a4\u30dd\u30a4\u30f3\u30c8\u3092\u4e26\u3079\u66ff\u3048 +menu.edit.rearrange.start=\u5168\u3066\u3092\u30d5\u30a1\u30a4\u30eb\u306e\u59cb\u70b9\u306b +menu.edit.rearrange.end=\u5168\u3066\u3092\u30d5\u30a1\u30a4\u30eb\u306e\u7d42\u70b9\u306b +menu.edit.rearrange.nearest=\u305d\u308c\u305e\u308c\u3092\u6700\u8fd1\u306e\u30c8\u30e9\u30c3\u30af\u30dd\u30a4\u30f3\u30c8\u306b +menu.edit.cutandmove=\u9078\u629e\u7bc4\u56f2\u3092\u79fb\u52d5 +menu.select=\u9078\u629e +menu.range=\u7bc4\u56f2 +menu.point=\u70b9 +menu.select.all=\u5168\u3066\u9078\u629e +menu.select.none=\u9078\u629e\u89e3\u9664 +menu.select.start=\u958b\u59cb\u70b9\u3092\u7f6e\u304f +menu.select.end=\u7d42\u4e86\u70b9\u3092\u7f6e\u304f +menu.photo=\u5199\u771f +menu.photo.saveexif=Exif\u306b\u4fdd\u5b58 +menu.photo.connect=\u70b9\u306b\u63a5\u7d9a +menu.photo.disconnect=\u70b9\u304b\u3089\u63a5\u7d9a\u89e3\u9664 +menu.photo.delete=\u5199\u771f\u3092\u53d6\u308a\u9664\u304f +menu.view=\u30d3\u30e5\u30fc +menu.view.browser=\u5730\u56f3\u3092\u30d6\u30e9\u30a6\u30b6\u30fc\u3067\u898b\u308b +menu.view.browser.google=Google \u30de\u30c3\u30d7 +menu.view.browser.openstreetmap=OpenStreetMap +menu.view.browser.mapquest=Mapquest +menu.view.browser.yahoo=Yahoo \u5730\u56f3 +menu.view.browser.bing=Bing \u5730\u56f3 +menu.settings=\u8a2d\u5b9a +menu.settings.showpace=\u8868\u793a\u7bc4\u56f2\u306e\u901f\u5ea6\u3092\u8868\u793a +menu.help=\u30d8\u30eb\u30d7 +# Popup menu for map +menu.map.zoomin=\u62e1\u5927 +menu.map.zoomout=\u7e2e\u5c0f +menu.map.zoomfull=\u6700\u5927\u62e1\u5927 +menu.map.newpoint=\u70b9\u3092\u4f5c\u308b +menu.map.connect=\u30c8\u30e9\u30c3\u30af\u30dd\u30a4\u30f3\u30c8\u306b\u63a5\u7d9a +menu.map.autopan=\u81ea\u52d5\u79fb\u52d5 +menu.map.showmap=\u5730\u56f3\u3092\u8868\u793a +menu.map.showscalebar=\u7e2e\u5c3a\u8868\u793a + +# Functions +function.loadfromgps=GPS\u304b\u3089\u30c7\u30fc\u30bf\u3092\u8aad\u3080 +function.sendtogps=GPS\u3078\u4fdd\u5b58 +function.exportkml=KML\u306b\u30a8\u30af\u30b9\u30dd\u30fc\u30c8 +function.exportgpx=GPX\u306b\u30a8\u30af\u30b9\u30dd\u30fc\u30c8 +function.exportpov=POV\u306b\u30a8\u30af\u30b9\u30dd\u30fc\u30c8 +function.editwaypointname=\u30a6\u30a7\u30a4\u30dd\u30a4\u30f3\u30c8\u306e\u540d\u524d\u3092\u7de8\u96c6 +function.compress=\u30c8\u30e9\u30c3\u30af\u3092\u5727\u7e2e +function.addtimeoffset=\u6642\u9593\u306e\u504f\u4f4d\u3092\u52a0\u3048\u308b +function.addaltitudeoffset=\u9ad8\u5ea6\u306b\u504f\u4f4d\u3092\u52a0\u3048\u308b +function.convertnamestotimes=\u30a6\u30a7\u30a4\u30dd\u30a4\u30f3\u30c8\u540d\u3092\u6642\u9593\u306b\u5909\u63db +function.findwaypoint=\u30a6\u30a7\u30a4\u30dd\u30a4\u30f3\u30c8\u3092\u63a2\u3059 +function.pastecoordinates=\u65b0\u3057\u3044\u5ea7\u6a19\u3092\u5165\u529b +function.charts=\u9ad8\u5ea6\u901f\u5ea6\u30c1\u30e3\u30fc\u30c8 +function.show3d=3-D\u30d3\u30e5\u30fc +function.distances=\u8ddd\u96e2 +function.fullrangedetails=\u5168\u7bc4\u56f2\u8a73\u7d30 +function.setmapbg=\u80cc\u666f\u5730\u56f3 +function.setkmzimagesize=KML \u30a4\u30e1\u30fc\u30b8\u30b5\u30a4\u30ba +function.setpaths=\u5916\u90e8\u30d7\u30ed\u30b0\u30e9\u30e0\u30d1\u30b9\u3092\u8a2d\u5b9a +function.getgpsies=Gpsies\u30c8\u30e9\u30c3\u30af\u3092\u5f97\u308b +function.duplicatepoint=\u91cd\u8907\u70b9 +function.setcolours=\u8272\u3092\u8a2d\u5b9a +function.setlanguage=\u8a00\u8a9e\u8a2d\u5b9a +function.correlatephotos=\u5199\u771f\u3068\u95a2\u9023\u3055\u305b\u308b +function.rearrangephotos=\u5199\u771f\u306e\u4e26\u3079\u76f4\u3057 +function.rotatephotoleft=\u5199\u771f\u3092\u5de6\u306b\u56de\u3059 +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.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.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 +dialog.deletepoint.title=\u70b9\u3092\u524a\u9664 +dialog.deletepoint.deletephoto=\u3053\u306e\u70b9\u63a5\u7d9a\u3055\u308c\u3066\u3044\u308b\u5199\u771f\u3092\u53d6\u308a\u9664\u304d\u307e\u3059\u304b\uff1f +dialog.deletephoto.title=\u5199\u771f\u3092\u524a\u9664 +dialog.deletephoto.deletepoint=\u3053\u306e\u5199\u771f\u306b\u63a5\u7d9a\u3055\u308c\u3066\u3044\u308b\u5199\u771f\u3092\u53d6\u308a\u9664\u304d\u307e\u3059\u304b\uff1f +dialog.openoptions.title=\u30aa\u30d7\u30b7\u30e7\u30f3\u3092\u958b\u304f +dialog.openoptions.filesnippet=\u30d5\u30a1\u30a4\u30eb\u3092\u5c55\u958b +dialog.load.table.field=\u30d5\u30a3\u30fc\u30eb\u30c9 +dialog.load.table.datatype=\u30c7\u30fc\u30bf\u30bf\u30a4\u30d7 +dialog.load.table.description=\u8a18\u8ff0 +dialog.delimiter.label=\u30d5\u30a3\u30fc\u30eb\u30c9\u533a\u5207\u308a +dialog.delimiter.comma=\u30b3\u30f3\u30de , +dialog.delimiter.tab=\u30bf\u30d6 +dialog.delimiter.space=\u30b9\u30da\u30fc\u30b9 +dialog.delimiter.semicolon=\u30bb\u30df\u30b3\u30ed\u30f3 ; +dialog.delimiter.other=\u305d\u306e\u4ed6 +dialog.openoptions.deliminfo.records=\u8a18\u9332\uff0c +dialog.openoptions.deliminfo.fields=\u30d5\u30a3\u30fc\u30eb\u30c9 +dialog.openoptions.deliminfo.norecords=\u8a18\u9332\u306a\u3057 +dialog.openoptions.altitudeunits=\u9ad8\u5ea6\u5358\u4f4d +dialog.jpegload.subdirectories=\u30b5\u30d6\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u30fc\u3092\u542b\u3081\u308b +dialog.jpegload.loadjpegswithoutcoords=\u5ea7\u6a19\u3092\u542b\u307e\u306a\u3044\u5199\u771f\u3092\u542b\u3081\u308b +dialog.jpegload.loadjpegsoutsidearea=\u73fe\u5728\u898b\u3066\u3044\u308b\u5730\u57df\u5916\u306e\u5199\u771f\u3092\u542b\u3081\u308b +dialog.jpegload.progress.title=\u5199\u771f\u3092\u8aad\u307f\u8fbc\u307f +dialog.jpegload.progress=\u691c\u7d22\u4e2d\u3067\u3059\u3002\u3057\u3070\u3057\u304a\u5f85\u3061\u304f\u3060\u3055\u3044\u3002 +dialog.gpsload.nogpsbabel=Gpsbabel\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093\u3002\u7d9a\u3051\u307e\u3059\u304b\uff1f +dialog.gpsload.device=GPS\u3068\u7d99\u304c\u3063\u3066\u3044\u308b\u30c7\u30d0\u30a4\u30b9\u540d +dialog.gpsload.format=GPS \u30c7\u30d0\u30a4\u30b9\u306e\u30d5\u30a9\u30fc\u30de\u30c3\u30c8 +dialog.gpsload.getwaypoints=\u30a6\u30a7\u30a4\u30dd\u30a4\u30f3\u30c8\u3092\u8aad\u307f\u8fbc\u3080 +dialog.gpsload.gettracks=\u30c8\u30e9\u30c3\u30af\u3092\u8aad\u307f\u8fbc\u3080 +dialog.gpsload.save=\u30d5\u30a1\u30a4\u30eb\u306b\u4fdd\u5b58 +dialog.gpssend.sendwaypoints=\u30a6\u30a7\u30a4\u30dd\u30a4\u30f3\u30c8\u3092\u9001\u308b +dialog.gpssend.sendtracks=\u30c8\u30e9\u30c3\u30af\u3092\u9001\u308b +dialog.gpssend.trackname=\u30c8\u30e9\u30c3\u30af\u540d +dialog.saveoptions.title=\u4fdd\u5b58 +dialog.save.fieldstosave=\u30d5\u30a3\u30fc\u30eb\u30c9\u306b\u4fdd\u5b58 +dialog.save.table.field=\u30d5\u30a3\u30fc\u30eb\u30c9 +dialog.save.table.hasdata=\u30c7\u30fc\u30bf\u304c\u3042\u308b +dialog.save.table.save=\u4fdd\u5b58 +dialog.save.headerrow=\u30d8\u30c3\u30c0\u30fc\u884c\u3092\u51fa\u529b +dialog.save.coordinateunits=\u5ea7\u6a19\u5358\u4f4d +dialog.save.altitudeunits=\u9ad8\u5ea6\u5358\u4f4d +dialog.save.timestampformat=\u6642\u9593\u8a18\u9332\u30d5\u30a9\u30fc\u30de\u30c3\u30c8 +dialog.save.overwrite.title=\u30d5\u30a1\u30a4\u30eb\u304c\u65e2\u306b\u5b58\u5728\u3057\u307e\u3059\u3002 +dialog.save.overwrite.text=\u30d5\u30a1\u30a4\u30eb\u304c\u65e2\u306b\u5b58\u5728\u3057\u307e\u3059\u3002\u4e0a\u66f8\u304d\u3057\u307e\u3059\u304b\uff1f +dialog.save.notypesselected=\u70b9\u306e\u7a2e\u985e\u304c\u9078\u629e\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002 +dialog.exportkml.text=\u30c7\u30fc\u30bf\u306e\u30bf\u30a4\u30c8\u30eb +dialog.exportkml.altitude=\u7d76\u5bfe\u9ad8\u5ea6\uff08\u822a\u7a7a\u7528\uff09 +dialog.exportkml.kmz=KMZ\u30d5\u30a1\u30a4\u30eb\u3092\u5727\u7e2e +dialog.exportkml.exportimages=KMZ\u3078\u753b\u50cf\u306e\u7e2e\u5c0f\u7248\u3092\u4fdd\u5b58 +dialog.exportkml.trackcolour=\u30c8\u30e9\u30c3\u30af\u306e\u8272 +dialog.exportgpx.name=\u540d\u524d +dialog.exportgpx.desc=\u8a18\u8ff0 +dialog.exportgpx.includetimestamps=\u6642\u9593\u8a18\u9332\u3092\u542b\u3080 +dialog.exportgpx.copysource=XML\u30bd\u30fc\u30b9\u3092\u30b3\u30d4\u30fc +dialog.exportpov.text=POV\u7528\u30d1\u30e9\u30e1\u30fc\u30bf\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002 +dialog.exportpov.font=\u30d5\u30a9\u30f3\u30c8 +dialog.exportpov.camerax=\u30ab\u30e1\u30e9 X +dialog.exportpov.cameray=\u30ab\u30e1\u30e9 Y +dialog.exportpov.cameraz=\u30ab\u30e1\u30e9 Z +dialog.exportpov.modelstyle=\u30e2\u30c7\u30eb\u30b9\u30bf\u30a4\u30eb +dialog.exportpov.ballsandsticks=\u7403\u3068\u68d2 +dialog.exportpov.tubesandwalls=\u7ba1\u3068\u58c1 +dialog.exportpov.warningtracksize=\u3053\u306e\u30c8\u30e9\u30c3\u30af\u306f\u975e\u5e38\u306b\u591a\u304f\u306e\u70b9\u304c\u3042\u308b\u306e\u3067\u3001Java3D \u3067\u306f\u8868\u793a\u3057\u5207\u308c\u306a\u3044\u3068\u601d\u308f\u308c\u307e\u3059\u3002\n\u7d9a\u3051\u307e\u3059\u304b\uff1f +dialog.pointtype.desc=\u6b21\u306e\u70b9\u3092\u4fdd\u5b58\u3057\u307e\u3059\uff1a +dialog.pointtype.track=\u30c8\u30e9\u30c3\u30af\u30dd\u30a4\u30f3\u30c8 +dialog.pointtype.waypoint=\u30a6\u30a7\u30a4\u30dd\u30a4\u30f3\u30c8 +dialog.pointtype.photo=\u5199\u771f\u70b9 +dialog.pointtype.selection=\u9078\u629e\u7bc4\u56f2\u306e\u307f +dialog.confirmreversetrack.title=\u53cd\u8ee2\u306e\u78ba\u8a8d +dialog.confirmreversetrack.text=\u3053\u306e\u30c8\u30e9\u30c3\u30af\u306f\u30bf\u30a4\u30e0\u30b9\u30bf\u30f3\u30d7\u3092\u542b\u3093\u3067\u3044\u3066\u3001\u53cd\u8ee2\u3059\u308b\u3068\u306a\u304f\u306a\u308a\u307e\u3059\u3002\n\u672c\u5f53\u306b\u53cd\u8ee2\u3055\u305b\u307e\u3059\u304b\uff1f +dialog.confirmcutandmove.title=\u5207\u308a\u53d6\u308a\u3068\u79fb\u52d5\u306e\u78ba\u8a8d +dialog.confirmcutandmove.text=\u3053\u306e\u30c8\u30e9\u30c3\u30af\u306f\u30bf\u30a4\u30e0\u30b9\u30bf\u30f3\u30d7\u3092\u542b\u3093\u3067\u3044\u3066\u3001\u79fb\u52d5\u3059\u308b\u3068\u306a\u304f\u306a\u308a\u307e\u3059\u3002\n\u672c\u5f53\u306b\u53cd\u8ee2\u3055\u305b\u307e\u3059\u304b\uff1f +dialog.interpolate.title=\u70b9\u3092\u88dc\u5b8c\u3059\u308b +dialog.interpolate.parameter.text=\u9078\u629e\u3057\u305f\u70b9\u306e\u9593\u306b\u633f\u5165\u3055\u308c\u308b\u70b9\u306e\u6570 +dialog.undo.title=\u4f5c\u696d\u3092\u30a2\u30f3\u30c9\u30a5 +dialog.undo.pretext=\u30a2\u30f3\u30c9\u30a5\u3059\u308b\u4f5c\u696d\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044\u3002 +dialog.undo.none.title=\u30a2\u30f3\u30c9\u30a5\u3067\u304d\u307e\u305b\u3093 +dialog.undo.none.text=\u30a2\u30f3\u30c9\u30a5\u3067\u304d\u308b\u4f5c\u696d\u753b\u3042\u308a\u307e\u305b\u3093! +dialog.clearundo.title=\u30a2\u30f3\u30c9\u30a5\u30ea\u30b9\u30c8\u3092\u7a7a\u306b\u3059\u308b +dialog.clearundo.text=\u672c\u5f53\u306b\u30a2\u30f3\u30c9\u30a5\u30ea\u30b9\u30c8\u3092\u7a7a\u306b\u3057\u307e\u3059\u304b?\n\u5168\u3066\u306e\u30a2\u30f3\u30c9\u30a5\u60c5\u5831\u304c\u5931\u308f\u308c\u307e\u3059\u3002 +dialog.pointedit.title=\u70b9\u3092\u7de8\u96c6 +dialog.pointedit.text=\u7de8\u96c6\u3059\u308b\u30d5\u30a3\u30fc\u30eb\u30c9\u3092\u9078\u629e\u3057\u3001'\u7de8\u96c6' \u30dc\u30bf\u30f3\u3067\u5024\u3092\u7de8\u96c6\u3057\u3066\u304f\u3060\u3055\u3044\u3002 +dialog.pointedit.table.field=\u30d5\u30a3\u30fc\u30eb\u30c9 +dialog.pointedit.table.value=\u503c +dialog.pointedit.table.changed=\u5909\u66f4\u6e08 +dialog.pointedit.changevalue.text=\u65b0\u3057\u3044\u5024\u3092\u30d5\u30a3\u30fc\u30eb\u30c9\u306b\u5165\u308c\u3066\u304f\u3060\u3055\u3044\u3002 +dialog.pointedit.changevalue.title=\u30d5\u30a3\u30fc\u30eb\u30c9\u306e\u7de8\u96c6 +dialog.pointnameedit.name=\u30a6\u30a7\u30a4\u30dd\u30a4\u30f3\u30c8\u540d +dialog.pointnameedit.uppercase=\u5927\u6587\u5b57 +dialog.pointnameedit.lowercase=\u5c0f\u6587\u5b57 +dialog.pointnameedit.sentencecase=\u982d\u6587\u5b57\u306e\u307f\u5927\u6587\u5b57 +dialog.addtimeoffset.add=\u6642\u9593\u3092\u8db3\u3059 +dialog.addtimeoffset.subtract=\u6642\u9593\u3092\u5f15\u304f +dialog.addtimeoffset.days=\u65e5 +dialog.addtimeoffset.hours=\u6642\u9593 +dialog.addtimeoffset.minutes=\u5206 +dialog.addtimeoffset.notimestamps=\u3053\u306e\u9078\u629e\u7bc4\u56f2\u306f\u30bf\u30a4\u30e0\u30b9\u30bf\u30f3\u30d7\u3092\u6301\u3063\u3066\u306a\u3044\u306e\u3067\u3001\u504f\u4f4d\u3092\u8db3\u305b\u307e\u305b\u3093\u3002 +dialog.findwaypoint.intro=\u30a6\u30a7\u30a4\u30dd\u30a4\u30f3\u30c8\u540d\u306e\u4e00\u90e8\u3092\u5165\u529b +dialog.findwaypoint.search=\u691c\u7d22 +dialog.connect.title=\u70b9\u306b\u5199\u771f\u3092\u63a5\u7d9a +dialog.connectphoto.clonepoint=\u3053\u306e\u70b9\u306f\u65e2\u306b\u5199\u771f\u3092\u6301\u3063\u3066\u307e\u3059\u3002\n\u30a6\u30a7\u30a4\u30dd\u30a4\u30f3\u30c8\u3092\u30b3\u30d4\u30fc\u3057\u307e\u3059\u304b\uff1f +dialog.saveexif.title=EXIF\u3092\u4fdd\u5b58 +dialog.saveexif.intro=\u30c1\u30a7\u30c3\u30af\u30dc\u30c3\u30af\u30b9\u3092\u4f7f\u3063\u3066\u3001\u4fdd\u5b58\u3059\u308b\u5199\u771f\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044\u3002 +dialog.saveexif.nothingtosave=\u5ea7\u6a19\u60c5\u5831\u306f\u7121\u5909\u66f4\u3067\u3059\u3002\u4fdd\u5b58\u3059\u308b\u3082\u306e\u306f\u3042\u308a\u307e\u305b\u3093\u3002 +dialog.saveexif.noexiftool=exiftool \u30d7\u30ed\u30b0\u30e9\u30e0\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093\u3002\u7d9a\u3051\u307e\u3059\u304b\uff1f +dialog.saveexif.table.photoname=\u5199\u771f\u540d +dialog.saveexif.table.status=\u72b6\u614b +dialog.saveexif.table.save=\u4fdd\u5b58 +dialog.saveexif.photostatus.connected=\u63a5\u7d9a\u6e08 +dialog.saveexif.photostatus.disconnected=\u672a\u63a5\u7d9a +dialog.saveexif.photostatus.modified=\u6539\u5909\u6e08 +dialog.saveexif.overwrite=\u30d5\u30a1\u30a4\u30eb\u306e\u4e0a\u66f8\u304d +dialog.saveexif.force=\u5c0f\u3055\u306a\u8aa4\u5dee\u3092\u7121\u8996\u3057\u3066\u5f37\u884c +dialog.charts.xaxis=X\u8ef8 +dialog.charts.yaxis=Y\u8ef8 +dialog.charts.output=\u51fa\u529b +dialog.charts.screen=\u753b\u9762\u3078\u51fa\u529b +dialog.charts.svg=SVG\u30d5\u30a1\u30a4\u30eb\u306b\u51fa\u529b +dialog.charts.svgwidth=SVG\u5e45 +dialog.charts.svgheight=SVG\u9ad8 +dialog.charts.needaltitudeortimes=\u30c1\u30e3\u30fc\u30c8\u3092\u4f5c\u308b\u306b\u306f\u3001\u9ad8\u5ea6\u306e\u60c5\u5831\u304b\u3001\u6642\u9593\u306e\u60c5\u5831\u304c\u30c8\u30e9\u30c3\u30af\u306b\u306a\u3051\u308c\u3070\u3044\u3051\u307e\u305b\u3093\u3002 +dialog.charts.gnuplotnotfound=gnuplot\u304c\u6307\u5b9a\u3055\u308c\u305f\u30d1\u30b9\u306b\u3042\u308a\u307e\u305b\u3093\u3002 +dialog.distances.intro=\u70b9\u9593\u306e\u76f4\u7dda\u8ddd\u96e2 +dialog.distances.column.from=\u958b\u59cb\u70b9 +dialog.distances.column.to=\u7d42\u70b9 +dialog.distances.currentpoint=\u73fe\u5728\u306e\u70b9 +dialog.distances.toofewpoints=\u3053\u306e\u6a5f\u80fd\u306f\u30a6\u30a7\u30a4\u30dd\u30a4\u30f3\u30c8\u9593\u306e\u8ddd\u96e2\u3092\u8a08\u7b97\u3059\u308b\u305f\u3081\u306b\u3001\u30a6\u30a7\u30a4\u30dd\u30a4\u30f3\u30c8\u304c\u5fc5\u8981\u3067\u3059\u3002 +dialog.fullrangedetails.intro=\u9078\u629e\u7bc4\u56f2\u306b\u306f\u8a73\u7d30\u304c\u3042\u308a\u307e\u3059\u3002 +dialog.setmapbg.mapnik=Mapnik(\u521d\u671f\u5024) +dialog.setmapbg.osma=Osma +dialog.setmapbg.cyclemap=Cyclemap +dialog.setmapbg.other=\u305d\u306e\u4ed6(URL\u306b\u5165\u529b) +dialog.setmapbg.server=\u5730\u56f3\u30b5\u30fc\u30d0\u30fcURL +dialog.gpsies.column.name=\u30c8\u30e9\u30c3\u30af\u540d +dialog.gpsies.column.length=\u9577\u3055 +dialog.gpsies.description=\u8a18\u8ff0 +dialog.gpsies.nodescription=\u8a18\u8ff0\u304c\u3042\u308a\u307e\u305b\u3093 +dialog.gpsies.nonefound=\u30c8\u30e9\u30c3\u30af\u304c\u3042\u308a\u307e\u305b\u3093 +dialog.correlate.notimestamps=\u30c7\u30fc\u30bf\u30dd\u30a4\u30f3\u30c8\u306b\u306f\u30bf\u30a4\u30e0\u30b9\u30bf\u30f3\u30d7\u304c\u306a\u3044\u306e\u3067\u3001\u5199\u771f\u3092\u95a2\u9023\u4ed8\u3051\u3089\u308c\u308b\u7269\u304c\u3042\u308a\u307e\u305b\u3093\u3002 +dialog.correlate.nouncorrelatedphotos=\u95a2\u9023\u4ed8\u3051\u3089\u308c\u306a\u304b\u3063\u305f\u5199\u771f\u306f\u3042\u308a\u307e\u305b\u3093\u3002\n\u7d9a\u3051\u307e\u3059\u304b\uff1f +dialog.correlate.photoselect.intro=\u6642\u9593\u504f\u4f4d\u3092\u4f5c\u308b\u305f\u3081\u306e\u5199\u771f\u3092\u4e00\u3064\u9078\u3093\u3067\u304f\u3060\u3055\u3044\u3002 +dialog.correlate.photoselect.photoname=\u5199\u771f\u540d +dialog.correlate.photoselect.timediff=\u6642\u9593\u5dee +dialog.correlate.photoselect.photolater=\u5199\u771f\u304c\u5f8c +dialog.correlate.options.tip=\u63d0\u793a\uff1a\u5c11\u306a\u304f\u3068\u3082\u4e00\u3064\u306e\u5199\u771f\u3092\u624b\u52d5\u3067\u95a2\u9023\u4ed8\u3051\u308b\u3068\u3001\u6642\u9593\u504f\u4f4d\u3092\u8a08\u7b97\u3059\u308b\u4e8b\u304c\u3067\u304d\u307e\u3059\u3002 +dialog.correlate.options.intro=\u81ea\u52d5\u95a2\u9023\u4ed8\u3051\u30aa\u30d7\u30b7\u30e7\u30f3\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044\u3002 +dialog.correlate.options.offsetpanel=\u6642\u9593\u504f\u4f4d +dialog.correlate.options.offset=\u504f\u4f4d +dialog.correlate.options.offset.hours=\u6642\u9593 +dialog.correlate.options.offset.minutes=\u5206 +dialog.correlate.options.offset.seconds=\u79d2 +dialog.correlate.options.photolater=\u3053\u306e\u70b9\u3088\u308a\u5f8c\u308d\u306e\u5199\u771f +dialog.correlate.options.pointlater=\u5199\u771f\u3088\u308a\u5f8c\u308d\u306e\u70b9 +dialog.correlate.options.limitspanel=\u95a2\u9023\u4ed8\u3051\u5236\u9650 +dialog.correlate.options.notimelimit=\u6642\u9593\u5236\u9650\u306a\u3057 +dialog.correlate.options.timelimit=\u6642\u9593\u5236\u9650 +dialog.correlate.options.nodistancelimit=\u8ddd\u96e2\u5236\u9650\u306a\u3057 +dialog.correlate.options.distancelimit=\u8ddd\u96e2\u5236\u9650 +dialog.correlate.options.correlate=\u95a2\u9023\u4ed8\u3051 +dialog.correlate.alloutsiderange=\u5168\u3066\u306e\u5199\u771f\u304c\u30c8\u30e9\u30c3\u30af\u306e\u7bc4\u56f2\u5916\u3067\u3059\u3002\u3060\u304b\u3089\u3001\u4f55\u3082\u95a2\u9023\u4ed8\u3051\u3089\u308c\u307e\u305b\u3093\u3067\u3057\u305f\u3002\n\u6642\u9593\u504f\u4f4d\u3092\u5909\u3048\u308b\u304b\u3001\u5c11\u306a\u304f\u3068\u3082\u4e00\u3064\u306e\u5199\u771f\u3092\u624b\u52d5\u95a2\u9023\u4ed8\u3051\u3092\u3059\u308b\u306a\u3069\u3057\u3066\u898b\u3066\u304f\u3060\u3055\u3044\u3002 +dialog.rearrangephotos.desc=\u5411\u304b\u3046\u5148\u3092\u9078\u629e\u3057\u3066\u3001\u5199\u771f\u306e\u70b9\u3092\u4e26\u3079\u76f4\u3059\u3002 +dialog.rearrangephotos.tostart=\u79fb\u52d5\u958b\u59cb +dialog.rearrangephotos.toend=\u79fb\u52d5\u7d42\u4e86 +dialog.rearrangephotos.nosort=\u4e26\u3079\u66ff\u3048\u306a\u3044 +dialog.rearrangephotos.sortbyfilename=\u30d5\u30a1\u30a4\u30eb\u540d\u3067\u4e26\u3079\u66ff\u3048 +dialog.rearrangephotos.sortbytime=\u6642\u9593\u3067\u4e26\u3079\u66ff\u3048 +dialog.compress.nonefound=\u9664\u304f\u3053\u3068\u304c\u3067\u304d\u308b\u30c7\u30fc\u30bf\u30dd\u30a4\u30f3\u30c8\u304c\u3042\u308a\u307e\u305b\u3093\u3002 +dialog.compress.closepoints.title=\u8fd1\u508d\u70b9\u3092\u524a\u9664 +dialog.compress.closepoints.paramdesc=\u8fd1\u508d\u4fc2\u6570 +dialog.compress.wackypoints.title=\u304a\u304b\u3057\u306a\u70b9\u306e\u524a\u9664 +dialog.compress.wackypoints.paramdesc=\u8ddd\u96e2\u4fc2\u6570 +dialog.compress.singletons.title=\u96e2\u6563\u70b9\u306e\u524a\u9664 +dialog.compress.singletons.paramdesc=\u8ddd\u96e2\u4fc2\u6570 +dialog.compress.duplicates.title=\u91cd\u8907\u70b9\u3092\u524a\u9664 +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.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.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 +dialog.about.translatedby=\u65e5\u672c\u8a9e\u7ffb\u8a33\uff1aOpenStreetMap \u8ca2\u732e\u8005\u306enazotoko +dialog.about.systeminfo=\u30b7\u30b9\u30c6\u30e0\u60c5\u5831 +dialog.about.systeminfo.os=\u30aa\u30da\u30ec\u30fc\u30c6\u30a3\u30f3\u30b0\u30b7\u30b9\u30c6\u30e0 +dialog.about.systeminfo.java=Java Runtime +dialog.about.systeminfo.java3d=Java 3D \u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u6e08 +dialog.about.systeminfo.povray=Povray \u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u6e08 +dialog.about.systeminfo.exiftool=Exiftool \u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u6e08 +dialog.about.systeminfo.gpsbabel=Gpsbabel \u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u6e08 +dialog.about.systeminfo.gnuplot=Gnuplot \u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u6e08 +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.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 +dialog.about.credits.translations=\u7ffb\u8a33\u52a9\u8005 +dialog.about.credits.devtools=\u958b\u767a\u30c4\u30fc\u30eb +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.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.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 +dialog.saveconfig.prune.trackdirectory=\u30c8\u30e9\u30c3\u30af\u30c7\u30a3\u30ec\u30af\u30c8\u30ea +dialog.saveconfig.prune.photodirectory=\u5199\u771f\u30c7\u30a3\u30ec\u30af\u30c8\u30ea +dialog.saveconfig.prune.languagecode=\u8a00\u8a9e\u30b3\u30fc\u30c9(JA) +dialog.saveconfig.prune.languagefile=\u8a00\u8a9e\u30d5\u30a1\u30a4\u30eb +dialog.saveconfig.prune.gpsdevice=GPS\u30c7\u30d0\u30a4\u30b9 +dialog.saveconfig.prune.gpsformat=GPS\u30d5\u30a9\u30fc\u30de\u30c3\u30c8 +dialog.saveconfig.prune.povrayfont=Povray \u30d5\u30a9\u30f3\u30c8 +dialog.saveconfig.prune.metricunits=\u30e1\u30fc\u30c8\u30eb\u6cd5\u3092\u4f7f\u3046\uff1f +dialog.saveconfig.prune.gnuplotpath=gnuplot\u3078\u306e\u30d1\u30b9 +dialog.saveconfig.prune.gpsbabelpath=gpsbabel\u3078\u306e\u30d1\u30b9 +dialog.saveconfig.prune.exiftoolpath=exiftool\u3078\u306e\u30d1\u30b9 +dialog.saveconfig.prune.mapserverindex=\u80cc\u666f\u5730\u56f3\u30b5\u30fc\u30d0\u30fc\u306e\u7d22\u5f15(1-4) +dialog.saveconfig.prune.mapserverurl=\u5730\u56f3\u30b5\u30fc\u30d0\u30fc\u306eURL +dialog.saveconfig.prune.showpace=\u30da\u30fc\u30b9\u3092\u8868\u793a +dialog.saveconfig.prune.kmzimagewidth=KML \u753b\u50cf\u5e45 +dialog.saveconfig.prune.kmzimageheight=KML \u753b\u50cf\u9ad8 +dialog.saveconfig.prune.colourscheme=\u8272\u306e\u30b9\u30ad\u30fc\u30e0 +dialog.saveconfig.prune.kmltrackcolour=KML \u30c8\u30e9\u30c3\u30af\u306e\u8272 +dialog.setpaths.intro=\u5fc5\u8981\u306a\u3089\u3001\u5916\u90e8\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306e\u30d1\u30b9\u3092\u9078\u3076\u4e8b\u304c\u3067\u304d\u307e\u3059 +dialog.addaltitude.noaltitudes=\u9078\u629e\u7bc4\u56f2\u306f\u3001\u9ad8\u5ea6\u3092\u542b\u3093\u3067\u307e\u305b\u3093\u3002 +dialog.addaltitude.desc=\u52a0\u3048\u305f\u9ad8\u5ea6\u504f\u4f4d +dialog.setcolours.intro=\u8272\u3092\u5909\u3048\u308b\u305f\u3081\u306b\u3001\u8272\u306e\u7bb1\u3092\u30af\u30ea\u30c3\u30af\u3057\u3066\u304f\u3060\u3055\u3044\u3002 +dialog.setcolours.background=\u80cc\u666f +dialog.setcolours.borders=\u5883\u754c +dialog.setcolours.lines=\u7dda +dialog.setcolours.primary=\u4e3b\u8981 +dialog.setcolours.secondary=\u526f\u6b21 +dialog.setcolours.point=\u70b9 +dialog.setcolours.selection=\u9078\u629e +dialog.setcolours.text=\u30c6\u30ad\u30b9\u30c8 +dialog.colourchooser.title=\u8272\u3092\u9078\u3093\u3067\u304f\u3060\u3055\u3044 +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.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 + +# 3d window +dialog.3d.title=Prune 3D \u8868\u793a +dialog.3d.altitudecap=\u6700\u4f4e\u9ad8\u5ea6\u7bc4\u56f2 +dialog.3dlines.title=Prune \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 + +# Confirm messages || These are displayed as confirmation in the status bar +confirm.loadfile=\u30d5\u30a1\u30a4\u30eb\u304b\u3089\u30c7\u30fc\u30bf\u3092\u8aad\u307f\u8fbc\u3080 +confirm.save.ok1=\u4fdd\u5b58\u6210\u529f +confirm.save.ok2=\u30d5\u30a1\u30a4\u30eb\u304b\u3089\u70b9 +confirm.deletepoint.single=\u30c7\u30fc\u30bf\u70b9\u306f\u524a\u9664\u3055\u308c\u305f +confirm.deletepoint.multi=\u30c7\u30fc\u30bf\u70b9\u306f\u524a\u9664\u3055\u308c\u305f +confirm.point.edit=\u7de8\u96c6\u3055\u308c\u305f\u70b9 +confirm.mergetracksegments=\u30c8\u30e9\u30c3\u30af\u30bb\u30b0\u30e1\u30f3\u30c8\u304c\u7d71\u5408\u6e08\u307f +confirm.reverserange=\u7bc4\u56f2\u304c\u53cd\u8ee2\u3055\u308c\u305f +confirm.addtimeoffset=\u6642\u9593\u504f\u4f4d\u304c\u52a0\u3048\u3089\u308c\u3066\u3044\u308b +confirm.addaltitudeoffset=\u9ad8\u5ea6\u504f\u4f4d\u304c\u52a0\u3048\u3089\u308c\u3066\u3044\u308b +confirm.rearrangewaypoints=\u30a6\u30a7\u30a4\u30dd\u30a4\u30f3\u30c8\u304c\u4e26\u3079\u66ff\u3048\u3089\u308c\u305f +confirm.rearrangephotos=\u5199\u771f\u304c\u4e26\u3079\u66ff\u3048\u3089\u308c\u305f +confirm.cutandmove=\u9078\u629e\u304c\u52d5\u304b\u3055\u308c\u305f +confirm.convertnamestotimes=\u30a6\u30a7\u30a4\u30dd\u30a4\u30f3\u30c8\u306e\u540d\u524d\u304c\u5909\u63db\u3055\u308c\u305f +confirm.saveexif.ok1=\u4fdd\u5b58\u3055\u308c\u305f +confirm.saveexif.ok2=\u5199\u771f\u30d5\u30a1\u30a4\u30eb +confirm.undo.single=\u64cd\u4f5c\u306f\u30a2\u30f3\u30c9\u30a5\u3055\u308c\u305f +confirm.undo.multi=\u64cd\u4f5c\u306f\u30a2\u30f3\u30c9\u30a5\u3055\u308c\u305f +confirm.jpegload.single=\u5199\u771f\u304c\u52a0\u3048\u3089\u308c\u305f +confirm.jpegload.multi=\u5199\u771f\u304c\u52a0\u3048\u3089\u308c\u305f +confirm.photo.connect=\u5199\u771f\u304c\u63a5\u7d9a\u3055\u308c\u305f +confirm.photo.disconnect=\u5199\u771f\u304c\u63a5\u7d9a\u3055\u308c\u305f +confirm.correlate.single=\u5199\u771f\u304c\u95a2\u9023\u4ed8\u3051\u3089\u308c\u305f +confirm.correlate.multi=\u5199\u771f\u304c\u95a2\u9023\u4ed8\u3051\u3089\u308c\u305f +confirm.createpoint=\u70b9\u304c\u4f5c\u3089\u308c\u305f +confirm.rotatephoto=\u5199\u771f\u3092\u56de\u8ee2\u3057\u305f +confirm.running=\u5b9f\u884c\u4e2d... + +# Buttons || These are all the texts for buttons +button.ok=\u6c7a\u5b9a +button.back=\u623b\u308b +button.next=\u6b21 +button.finish=\u5b8c\u6210 +button.cancel=\u53d6\u6d88 +button.overwrite=\u4e0a\u66f8\u304d +button.moveup=\u4e0a\u3078 +button.movedown=\u4e0b\u3078 +button.showlines=\u7dda\u3092\u8868\u793a +button.edit=\u7de8\u96c6 +button.exit=\u7d42\u4e86 +button.close=\u9589\u3058\u308b +button.continue=\u7d9a\u3051\u308b +button.yes=\u306f\u3044 +button.no=\u3044\u3044\u3048 +button.yestoall=\u5168\u90e8\u306b\u306f\u3044 +button.notoall=\u5168\u90e8\u306b\u3044\u3044\u3048 +button.select=\u9078\u629e +button.selectall=\u5168\u9078\u629e +button.selectnone=\u9078\u629e\u89e3\u9664 +button.preview=\u30d7\u30ec\u30d3\u30e5\u30fc +button.load=\u8aad\u307f\u8fbc\u307f +button.guessfields=\u30d5\u30a3\u30fc\u30eb\u30c9\u4e88\u6e2c +button.showwebpage=\u30a6\u30a7\u30d6\u30da\u30fc\u30b8\u3092\u8868\u793a +button.check=\u691c\u67fb +button.resettodefaults=\u521d\u671f\u5024\u306b\u623b\u3059 +button.browse=\u95b2\u89a7... + +# File types +filetype.txt=TXT\u30d5\u30a1\u30a4\u30eb +filetype.jpeg=JPG\u30d5\u30a1\u30a4\u30eb +filetype.kmlkmz=KML,KMZ\u30d5\u30a1\u30a4\u30eb +filetype.kml=KML\u30d5\u30a1\u30a4\u30eb +filetype.kmz=KMZ\u30d5\u30a1\u30a4\u30eb +filetype.gpx=GPX\u30d5\u30a1\u30a4\u30eb +filetype.pov=POV\u30d5\u30a1\u30a4\u30eb +filetype.svg=SVG\u30d5\u30a1\u30a4\u30eb + +# Display components || These are all for the side panels showing point/range details +display.nodata=\u8aad\u307f\u8fbc\u307e\u308c\u305f\u30c7\u30fc\u30bf\u306a\u3057 +display.noaltitudes=\u30c8\u30e9\u30c3\u30af\u30c7\u30fc\u30bf\u306f\u9ad8\u5ea6\u3092\u542b\u307f\u307e\u305b\u3093 +details.trackdetails=\u30c8\u30e9\u30c3\u30af\u8a73\u7d30 +details.notrack=\u8aad\u307f\u8fbc\u307e\u308c\u305f\u30c8\u30e9\u30c3\u30af\u306a\u3057 +details.track.points=\u70b9 +details.track.file=\u30d5\u30a1\u30a4\u30eb +details.track.numfiles=\u30d5\u30a1\u30a4\u30eb\u6570 +details.pointdetails=\u70b9\u306e\u8a73\u7d30 +details.index.selected=\u7b2c +details.index.of=\u756a \u5168: +details.nopointselection=\u70b9\u304c\u9078\u629e\u3055\u308c\u3066\u3044\u307e\u305b\u3093 +details.photofile=\u5199\u771f\u30d5\u30a1\u30a4\u30eb +details.norangeselection=\u7bc4\u56f2\u304c\u9078\u629e\u3055\u308c\u3066\u3044\u307e\u305b\u3093 +details.rangedetails=\u7bc4\u56f2\u8a73\u7d30 +details.range.selected=\u9078\u629e\u6e08 +details.range.to=\u304b\u3089 +details.altitude.to=\u304b\u3089 +details.range.climb=\u4e0a\u308a +details.range.descent=\u4e0b\u308a +details.coordformat=\u5ea7\u6a19\u30d5\u30a9\u30fc\u30de\u30c3\u30c8 +details.distanceunits=\u8ddd\u96e2\u5358\u4f4d +display.range.time.secs=\u79d2 +display.range.time.mins=\u5206 +display.range.time.hours=\u6642 +display.range.time.days=\u65e5 +details.range.avespeed=\u5e73\u5747\u901f\u5ea6 +details.range.avemovingspeed=\u5e73\u5747\u79fb\u52d5 +details.range.numsegments=\u30bb\u30b0\u30e1\u30f3\u30c8\u6570 +details.range.pace=\u30da\u30fc\u30b9 +details.range.gradient=\u52fe\u914d +details.waypointsphotos.waypoints=\u30a6\u30a7\u30a4\u30dd\u30a4\u30f3\u30c8 +details.waypointsphotos.photos=\u5199\u771f +details.photodetails=\u5199\u771f\u8a73\u7d30 +details.nophoto=\u5199\u771f\u304c\u9078\u629e\u3055\u308c\u3066\u3044\u307e\u305b\u3093 +details.photo.loading=\u8aad\u307f\u8fbc\u307f\u4e2d +details.photo.connected=\u63a5\u7d9a\u6e08 +map.overzoom=\u3053\u306e\u30ba\u30fc\u30e0\u30ec\u30d9\u30eb\u3067\u306f\u5730\u56f3\u304c\u5165\u624b\u3067\u304d\u307e\u305b\u3093\u3002 + +# Field names +fieldname.latitude=\u7def\u5ea6 +fieldname.longitude=\u7d4c\u5ea6 +fieldname.altitude=\u9ad8\u5ea6 +fieldname.timestamp=\u6642\u9593 +fieldname.time=\u6642\u9593 +fieldname.waypointname=\u540d\u524d +fieldname.waypointtype=\u7a2e\u985e +fieldname.newsegment=\u30bb\u30b0\u30e1\u30f3\u30c8 +fieldname.custom=\u30ab\u30b9\u30bf\u30e0 +fieldname.prefix=\u30d5\u30a3\u30fc\u30eb\u30c9 +fieldname.distance=\u8ddd\u96e2 +fieldname.movingdistance=\u79fb\u52d5\u8ddd\u96e2 +fieldname.duration=\u9593\u9694 +fieldname.speed=\u901f\u5ea6 +fieldname.verticalspeed=\u5782\u76f4\u901f\u5ea6 + +# Measurement units +units.original=\u30aa\u30ea\u30b8\u30ca\u30eb +units.default=\u521d\u671f\u5024 +units.metres=\u30e1\u30fc\u30c8\u30eb +units.metres.short=m +units.feet=\u30d5\u30a3\u30fc\u30c8 +units.feet.short=ft +units.kilometres=\u30ad\u30ed\u30e1\u30fc\u30c8\u30eb +units.kilometres.short=km +units.kmh=km/h +units.miles=\u30de\u30a4\u30eb +units.miles.short=mi +units.mph=mph +units.metrespersec=m/s +units.feetpersec=ft/s +units.hours=\u6642\u9593 +units.degminsec=\u5ea6-\u5206-\u79d2 +units.degmin=\u5ea6-\u5206 +units.deg=\u5ea6 +units.iso8601=ISO 8601 + +# External urls +url.googlemaps=maps.google.co.jp + +# Cardinals for 3d plots +cardinal.n=N +cardinal.s=S +cardinal.e=E +cardinal.w=W + +# Undo operations || These will be displayed in the undo list after you've performed the operation, to tell you what you did +undo.load=\u30c7\u30fc\u30bf\u3092\u8aad\u307f\u8fbc\u307f +undo.loadphotos=\u5199\u771f\u306e\u8aad\u307f\u8fbc\u307f +undo.editpoint=\u70b9\u306e\u7de8\u96c6 +undo.deletepoint=\u70b9\u306e\u524a\u9664 +undo.deletephoto=\u5199\u771f\u306e\u53d6\u308a\u9664\u304d +undo.deleterange=\u7bc4\u56f2\u306e\u524a\u9664 +undo.compress=\u30c8\u30e9\u30c3\u30af\u306e\u5727\u7e2e +undo.insert=\u70b9\u306e\u633f\u5165 +undo.reverse=\u7bc4\u56f2\u306e\u53cd\u8ee2 +undo.mergetracksegments=\u30c8\u30e9\u30c3\u30af\u30bb\u30b0\u30e1\u30f3\u30c8\u306e\u7d71\u5408 +undo.addtimeoffset=\u6642\u9593\u504f\u4f4d\u3092\u52a0\u3048\u308b +undo.addaltitudeoffset=\u9ad8\u5ea6\u504f\u4f4d\u3092\u52a0\u3048\u308b +undo.rearrangewaypoints=\u30a6\u30a7\u30a4\u30dd\u30a4\u30f3\u30c8\u3092\u633f\u5165 +undo.cutandmove=\u30bb\u30af\u30b7\u30e7\u30f3\u306e\u79fb\u52d5 +undo.connectphoto=\u5199\u771f\u306e\u63a5\u7d9a +undo.disconnectphoto=\u5199\u771f\u306e\u63a5\u7d9a\u89e3\u9664 +undo.correlate=\u5199\u771f\u306e\u95a2\u9023\u4ed8\u3051 +undo.rearrangephotos=\u5199\u771f\u306e\u4e26\u3079\u66ff\u3048 +undo.createpoint=\u70b9\u306e\u4f5c\u6210 +undo.rotatephoto=\u5199\u771f\u306e\u56de\u8ee2 +undo.convertnamestotimes=\u540d\u524d\u3092\u6642\u9593\u306b\u5909\u63db\u3059\u308b + +# Error messages +error.save.dialogtitle=\u30c7\u30fc\u30bf\u4fdd\u5b58\u306e\u30a8\u30e9\u30fc +error.save.nodata=\u4fdd\u5b58\u3059\u308b\u30c7\u30fc\u30bf\u304c\u3042\u308a\u307e\u305b\u3093 +error.save.failed=\u30c7\u30fc\u30bf\u3092\u30d5\u30a1\u30a4\u30eb\u306b\u4fdd\u5b58\u3059\u308b\u306e\u306b\u5931\u6557\u3057\u307e\u3057\u305f +error.saveexif.filenotfound=\u5199\u771f\u30d5\u30a1\u30a4\u30eb\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093\u3067\u3057\u305f +error.saveexif.cannotoverwrite1=\u5199\u771f\u30d5\u30a1\u30a4\u30eb +error.saveexif.cannotoverwrite2=\u8aad\u307f\u8fbc\u307f\u5c02\u7528\u3067\u4e0a\u66f8\u304d\u3067\u304d\u307e\u305b\u3093\u3002\u8907\u88fd\u3092\u4f5c\u308a\u307e\u3059\u304b\uff1f +error.saveexif.failed1= +error.saveexif.failed2=\u679a\u306e\u753b\u50cf\u306e\u4fdd\u5b58\u306b\u5931\u6557\u3057\u307e\u3057\u305f +error.saveexif.forced1= +error.saveexif.forced2=\u679a\u306e\u753b\u50cf\u304c\u5f37\u884c\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002 +error.load.dialogtitle=\u30c7\u30fc\u30bf\u306e\u8aad\u307f\u8fbc\u307f\u30a8\u30e9\u30fc +error.load.noread=\u30d5\u30a1\u30a4\u30eb\u304c\u8aad\u3081\u307e\u305b\u3093 +error.load.nopoints=\u30d5\u30a1\u30a4\u30eb\u306e\u4e2d\u306b\u5ea7\u6a19\u60c5\u5831\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093 +error.load.unknownxml=XML\u30d5\u30a9\u30fc\u30de\u30c3\u30c8\u304c\u89e3\u91c8\u3067\u304d\u307e\u305b\u3093 +error.load.noxmlinzip=Zip\u30d5\u30a1\u30a4\u30eb\u4e2d\u306bXML\u30d5\u30a1\u30a4\u30eb\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093 +error.load.othererror=\u30d5\u30a1\u30a4\u30eb\u3092\u8aad\u307f\u8fbc\u307f\u30a8\u30e9\u30fc: +error.jpegload.dialogtitle=\u5199\u771f\u306e\u8aad\u307f\u8fbc\u307f\u30a8\u30e9\u30fc: +error.jpegload.nofilesfound=\u30d5\u30a1\u30a4\u30eb\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093 +error.jpegload.nojpegsfound=Jpeg\u30d5\u30a1\u30a4\u30eb\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093 +error.jpegload.noexiffound=EXIF\u60c5\u5831\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093 +error.jpegload.nogpsfound=GPS\u60c5\u5831\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093 +error.gpsload.unknown=\u4e0d\u660e\u306a\u30a8\u30e9\u30fc +error.undofailed.title=\u30a2\u30f3\u30c9\u30a5\u5931\u6557 +error.undofailed.text=\u30a2\u30f3\u30c9\u30a5\u64cd\u4f5c\u306e\u5931\u6557 +error.function.noop.title=\u305d\u306e\u6a5f\u80fd\u306f\u52b9\u679c\u3042\u308a\u307e\u305b\u3093 +error.rearrange.noop=\u70b9\u306e\u518d\u914d\u7f6e\u306f\u52b9\u679c\u3042\u308a\u307e\u305b\u3093 +error.function.notavailable.title=\u305d\u306e\u6a5f\u80fd\u306f\u4f7f\u3048\u307e\u305b\u3093 +error.function.nojava3d=\u3053\u306e\u6a5f\u80fd\u306f Java3d \u30e9\u30a4\u30d6\u30e9\u30ea\u3092\u5fc5\u8981\u3068\u3057\u307e\u3059\u3002\nSun.com \u3088\u308a\u5165\u624b\u3057\u3066\u304f\u3060\u3055\u3044 +error.3d=3D \u8868\u793a\u3067\u30a8\u30e9\u30fc\u304c\u8d77\u304d\u307e\u3057\u305f +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.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_pl.properties b/tim/prune/lang/prune-texts_pl.properties index 8e05b67..c731f84 100644 --- a/tim/prune/lang/prune-texts_pl.properties +++ b/tim/prune/lang/prune-texts_pl.properties @@ -7,7 +7,7 @@ menu.file.open=Otw\u00f3rz menu.file.addphotos=Dodaj zdj\u0119cia menu.file.save=Zapisz menu.file.exit=Zako\u0144cz -menu.edit=Edycja +menu.track=\u015acie\u017cka menu.edit.undo=Cofnij menu.edit.clearundo=Wyczy\u015b\u0107 list\u0119 zmian menu.edit.editpoint=Edytuj punkt @@ -23,7 +23,8 @@ menu.edit.rearrange.start=Wszystkie na pocz\u0105tek \u015bcie\u017cki menu.edit.rearrange.end=Wszystkie na koniec \u015bcie\u017cki menu.edit.rearrange.nearest=Do najbli\u017cszego punktu menu.edit.cutandmove=Wytnij i przesu\u0144 zaznaczenie -menu.select=Zaznacz +menu.range=Zakres +menu.point=Punkt menu.select.all=Zaznacz wszystko menu.select.none=Usu\u0144 zaznaczenie menu.select.start=Zaznacz pocz\u0105tek zakresu @@ -39,8 +40,8 @@ menu.view.browser.google=Mapy Google menu.view.browser.openstreetmap=Openstreetmap menu.view.browser.mapquest=Mapquest menu.view.browser.yahoo=Mapy Yahoo +menu.view.browser.bing=Mapy Bing menu.settings=Ustawienia -menu.settings.showpace=Poka\u017c tempo przy wy\u015bwietlaniu zakresu menu.help=Pomoc # Popup menu for map menu.map.zoomin=Powi\u0119ksz @@ -54,8 +55,9 @@ menu.map.showscalebar=Poka\u017c skal\u0119 # Alt keys for menus altkey.menu.file=P -altkey.menu.edit=E -altkey.menu.select=A +altkey.menu.track=C +altkey.menu.range=Z +altkey.menu.point=U altkey.menu.view=W altkey.menu.photo=Z altkey.menu.settings=T @@ -80,15 +82,25 @@ function.editwaypointname=Zmie\u0144 nazw\u0119 punktu po\u015bredniego function.compress=Kompresuj \u015bcie\u017ck\u0119 function.addtimeoffset=Dodaj przesuni\u0119cie czasu function.addaltitudeoffset=Dodaj przesuni\u0119cie wysoko\u015bci +function.convertnamestotimes=Zamie\u0144 nazwy punkt\u00f3w na czas function.findwaypoint=Znajd\u017a punkt po\u015bredni +function.pastecoordinates=Wprowad\u017a nowe wsp\u00f3\u0142rz\u0119dne function.charts=Wykres function.show3d=Poka\u017c model 3D function.distances=Odleg\u0142o\u015bci -function.getgpsies=Pobierz \u015bcie\u017cki z Gpsies -function.correlatephotos=Powi\u0105\u017c zdj\u0119cia -function.setmapbg=Wybierz map\u0119 +function.fullrangedetails=Wszystkie detale +function.setmapbg=Wybierz map\u0119 t\u0142a function.setkmzimagesize=Ustaw rozmiar zdj\u0119\u0107 w KMZ function.setpaths=Ustaw \u015bcie\u017cki do program\u00f3w +function.getgpsies=Pobierz \u015bcie\u017cki z Gpsies +function.duplicatepoint=Duplikuj plik +function.setcolours=Ustaw kolory +function.setlanguage=Zmie\u0144 j\u0119zyk +function.correlatephotos=Powi\u0105\u017c zdj\u0119cia +function.rearrangephotos=Zmie\u0144 kolejno\u015b\u0107 zdj\u0119\u0107 +function.rotatephotoleft=Obr\u00f3\u0107 zdj\u0119cie w lewo +function.rotatephotoright=Obr\u00f3\u0107 zdj\u0119cie wprawo +function.ignoreexifthumb=Ignoruj miniaturk\u0119 z exif function.help=Pomoc function.showkeys=Poka\u017c klawisze skr\u00f3tu function.about=O Prune @@ -129,6 +141,7 @@ dialog.gpsload.device=Nazwa urz\u0105dzenia dialog.gpsload.format=Format dialog.gpsload.getwaypoints=\u0141aduj punkty po\u015brednie dialog.gpsload.gettracks=\u0141aduj \u015bcie\u017cki +dialog.gpsload.save=Zapisz do pliku dialog.gpssend.sendwaypoints=Wy\u015blij punkty po\u015brednie dialog.gpssend.sendtracks=Wy\u015blij \u015bcie\u017cki dialog.gpssend.trackname=Nazwa \u015bcie\u017cki @@ -143,13 +156,16 @@ dialog.save.altitudeunits=Jednostki wysoko\u015bci dialog.save.timestampformat=Format znacznika czasu dialog.save.overwrite.title=Plik ju\u017c istnieje dialog.save.overwrite.text=Ten plik ju\u017c istnieje. Czy na pewno chcesz go nadpisa\u0107? +dialog.save.notypesselected=Nie zosta\u0142 wybrany \u017caden typ punkt\u00f3w dialog.exportkml.text=Tytu\u0142 dla danych dialog.exportkml.altitude=Do\u0142\u0105cz wysoko\u015bci (dla cel\u00f3w lotniczych) dialog.exportkml.kmz=Skompresuj do pliku KMZ dialog.exportkml.exportimages=Eksportuj miniaturki zdj\u0119\u0107 do KMZ +dialog.exportkml.trackcolour=Kolor \u015bcie\u017cki 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.exportpov.text=Wprowad\u017a dodatkowe parametry eksportu do formatu POV dialog.exportpov.font=Czcionka dialog.exportpov.camerax=Kamera X @@ -163,6 +179,7 @@ dialog.pointtype.desc=Zapisz punkty nast\u0119puj\u0105cych typ\u00f3w: dialog.pointtype.track=punkty \u015bcie\u017cki dialog.pointtype.waypoint=punkty po\u015brednie dialog.pointtype.photo=punkty zdj\u0119\u0107 +dialog.pointtype.selection=Tylko wybrane dialog.confirmreversetrack.title=Potwierd\u017a odwr\u00f3cenie dialog.confirmreversetrack.text=Ta \u015bcie\u017cka zawiera znaczniki czasu, kt\u00f3re po odwr\u00f3ceniu nie b\u0119d\u0105 ustawione w kolejno\u015bci.\nCzy na pewno chcesz odwr\u00f3ci\u0107 ten fragment? dialog.confirmcutandmove.title=Potwierd\u017a wytnij i przesu\u0144 @@ -192,10 +209,8 @@ dialog.addtimeoffset.days=Dni dialog.addtimeoffset.hours=Godziny dialog.addtimeoffset.minutes=Minuty dialog.addtimeoffset.notimestamps=Nie mo\u017cna przesun\u0105\u0107 czasu, poniewa\u017c zaznaczenie nie zawiera znacznik\u00f3w czasu -dialog.findwaypoint.intro= -dialog.findwaypoint.search= -dialog.connect.title=Po\u0142\u0105cz zdj\u0119cie do punktu -dialog.connectphoto.clonepoint=Ten punkt po\u0142\u0105czono ju\u017c ze zdj\u0119ciem.\nCzy chcesz zrobi\u0107 kopi\u0119 tego punktu? +dialog.findwaypoint.intro=Wprowad\u017a nazw\u0119 punktu po\u015bredniego +dialog.findwaypoint.search=Szukaj dialog.saveexif.title=Zapisz Exif dialog.saveexif.intro=Zaznacz zdj\u0119cia do zapisu u\u017cywaj\u0105c znacznik\u00f3w dialog.saveexif.nothingtosave=Wsp\u00f3\u0142rz\u0119dne nie zosta\u0142y zmienione, nie ma nic do zapisu @@ -207,6 +222,7 @@ dialog.saveexif.photostatus.connected=Po\u0142\u0105czony dialog.saveexif.photostatus.disconnected=Roz\u0142\u0105czony dialog.saveexif.photostatus.modified=Zmodyfikowany dialog.saveexif.overwrite=Nadpisz pliki +dialog.saveexif.force=Wymu\u015b pomimo niewielkich b\u0142\u0119d\u00f3w dialog.charts.xaxis=O\u015b X dialog.charts.yaxis=O\u015b Y dialog.charts.output=Wykres @@ -215,13 +231,13 @@ dialog.charts.svg=Zapisz do pliku SVG dialog.charts.svgwidth=szeroko\u015b\u0107 SVG dialog.charts.svgheight=wysoko\u015b\u0107 SVG dialog.charts.needaltitudeortimes=\u015acie\u017cka musi posiada\u0107 zapisane wysoko\u015bci lub znaczniki czasu aby mo\u017cliwe by\u0142o utworzenie wykres\u00f3w -dialog.charts.gnuplotpath=\u015acie\u017cka do programu gnuplot dialog.charts.gnuplotnotfound=Nie znalaz\u0142em programu gnuplot dialog.distances.intro=Odleg\u0142o\u015b\u0107 mi\u0119dzy punktami w linii prostej dialog.distances.column.from=Z punktu dialog.distances.column.to=Do punktu dialog.distances.currentpoint=Wybrany punkt dialog.distances.toofewpoints=Ta funkcja wymaga przynajmniej dw\u00f3ch punkt\u00f3w po\u015brednich, aby mo\u017cna by\u0142o obliczy\u0107 odleg\u0142o\u015bci +dialog.fullrangedetails.intro=Szczeg\u00f3\u0142y wybranego zakresu dialog.setmapbg.mapnik=Mapnik (domy\u015blny) dialog.setmapbg.osma=Osma dialog.setmapbg.cyclemap=Cyclemap @@ -231,7 +247,7 @@ dialog.gpsies.column.name=Nazwa \u015bcie\u017cki dialog.gpsies.column.length=D\u0142ugo\u015b\u0107 dialog.gpsies.description=Opis dialog.gpsies.nodescription=Brak opisu -dialog.gpsies.nonefound= +dialog.gpsies.nonefound=Nie znalaz\u0142em \u015bcie\u017cek dialog.correlate.notimestamps=Punkty nie maj\u0105 znacznik\u00f3w czasu, nie mo\u017cna ich powi\u0105za\u0107 ze zdj\u0119ciami. dialog.correlate.nouncorrelatedphotos=Nie ma nie powi\u0105zanych zdj\u0119\u0107.\nCzy na pewno chcesz kontynuowa\u0107? dialog.correlate.photoselect.intro=Wybierz jedno z powi\u0105zanych zdj\u0119\u0107 i u\u017cyj go jako wzorca do przesuni\u0119cia czasu @@ -254,15 +270,24 @@ dialog.correlate.options.nodistancelimit=Bez limitu odleg\u0142o\u015bci dialog.correlate.options.distancelimit=Limit odleg\u0142o\u015bci dialog.correlate.options.correlate=Powi\u0105\u017c ze sob\u0105 dialog.correlate.alloutsiderange=Wszystkie zdj\u0119cia s\u0105 poza zakresem czasu \u015bcie\u017cki, tak \u017ce \u017cadne nie mo\u017ce zosta\u0107 z ni\u0105 skorelowane.\nSpr\u00f3buj zmieni\u0107 przesuni\u0119cie lub r\u0119cznie skoreluj przynajmniej jedno zdj\u0119cie. +dialog.rearrangephotos.desc=Wybierz przeznaczenie i porz\u0105dek sortowania punkt\u00f3w ze zdj\u0119ciami +dialog.rearrangephotos.tostart=Przesu\u0144 na pocz\u0105tek +dialog.rearrangephotos.toend=Przesu\u0144 na koniec +dialog.rearrangephotos.nosort=Nie sortuj +dialog.rearrangephotos.sortbyfilename=Sortuj po nazwie pliku +dialog.rearrangephotos.sortbytime=Sortuj wed\u0142ug czasu dialog.compress.nonefound=Nie mo\u017cna usun\u0105\u0107 \u017cadnych punkt\u00f3w -dialog.compress.duplicates.title=Usuwanie duplikat\u00f3w -dialog.compress.closepoints.title=Usuwanie punkt\u00f3w bliskich sobie +dialog.compress.closepoints.title=Usuwanie bliskich sobie punkt\u00f3w dialog.compress.closepoints.paramdesc=Wsp\u00f3\u0142czynnik rozpi\u0119to\u015bci dialog.compress.wackypoints.title=Usuwanie dziwacznych punkt\u00f3w dialog.compress.wackypoints.paramdesc=Wsp\u00f3\u0142czynnik odleg\u0142o\u015bci dialog.compress.singletons.title=Usuwanie odosobnionych punkt\u00f3w dialog.compress.singletons.paramdesc=Wsp\u00f3\u0142czynnik odleg\u0142o\u015bci +dialog.compress.duplicates.title=Usuwanie duplikat\u00f3w 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.about.version=Wersja dialog.about.build=Build @@ -304,6 +329,7 @@ dialog.saveconfig.desc=Nast\u0119puj\u0105ce ustawienia mog\u0105 zosta\u0107 za dialog.saveconfig.prune.trackdirectory=Katalog ze \u015bcie\u017ckami dialog.saveconfig.prune.photodirectory=Katalog ze zdj\u0119ciami dialog.saveconfig.prune.languagecode=Kod j\u0119zyka (PL) +dialog.saveconfig.prune.languagefile=Plik t\u0142umaczenia dialog.saveconfig.prune.gpsdevice=Urz\u0105dzenie GPS dialog.saveconfig.prune.gpsformat=Format pliku GPS dialog.saveconfig.prune.povrayfont=czcionka dla Povray-a @@ -313,12 +339,31 @@ dialog.saveconfig.prune.gpsbabelpath=\u015bcie\u017cka do gpsbabel dialog.saveconfig.prune.exiftoolpath=\u015bcie\u017cka do exiftool dialog.saveconfig.prune.mapserverindex=kolejny numer serwera map dialog.saveconfig.prune.mapserverurl=URL serwera map -dialog.saveconfig.prune.showpace=Pokazuj tempo dialog.saveconfig.prune.kmzimagewidth=szeroko\u015b\u0107 obrazka w KMZ dialog.saveconfig.prune.kmzimageheight=wysoko\u015b\u0107 obrazka w KMZ +dialog.saveconfig.prune.colourscheme=Schemat kolor\u00f3w +dialog.saveconfig.prune.kmltrackcolour=Kolor \u015bcie\u017cki w pliku KML dialog.setpaths.intro=Je\u015bli zachodzi tak potrzeba, mo\u017cesz wybra\u0107 \u015bcie\u017cki do aplikacji zewn\u0119trznych dialog.addaltitude.noaltitudes=Wybrany zakres nie zawiera danych o wysoko\u015bciach dialog.addaltitude.desc=Warto\u015b\u0107 przesuni\u0119cia wysoko\u015bci +dialog.setcolours.intro=Kliknij na kolor by go wybra\u0107 +dialog.setcolours.background=T\u0142o +dialog.setcolours.borders=Ramki +dialog.setcolours.lines=Linie +dialog.setcolours.primary=G\u0142\u00f3wny +dialog.setcolours.secondary=Drugorz\u0119dny +dialog.setcolours.point=Punkty +dialog.setcolours.selection=Wyb\u00f3r +dialog.setcolours.text=Tekst +dialog.colourchooser.title=Wybierz kolor +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.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. # 3d window dialog.3d.title=Prune widok tr\u00f3jwymiarowy @@ -339,7 +384,9 @@ confirm.reverserange=Odwr\u00f3cono zakres confirm.addtimeoffset=Dodano przesuni\u0119cie czasowe confirm.addaltitudeoffset=Dodano przesuni\u0119cie wysoko\u015bci confirm.rearrangewaypoints=Przestawiono punkty po\u015brednie +confirm.rearrangephotos=Zmieniono kolejno\u015b\u0107 zdj\u0119\u0107 confirm.cutandmove=Przesuni\u0119to zaznaczenie +confirm.convertnamestotimes=Zmieniono nazwy punkt\u00f3w po\u015brednich confirm.saveexif.ok1=Zapisano confirm.saveexif.ok2=pliki zdj\u0119\u0107 confirm.undo.single=cofni\u0119to operacj\u0119 @@ -351,9 +398,10 @@ confirm.photo.disconnect=od\u0142\u0105czono zdj\u0119cie confirm.correlate.single=zdj\u0119cie zosta\u0142o po\u0142\u0105czone confirm.correlate.multi=zdj\u0119cia zosta\u0142y po\u0142\u0105czone confirm.createpoint=stworzono punkt +confirm.rotatephoto=obr\u00f3cono zdj\u0119cie confirm.running=Przetwarzam dane ... -# Buttons +# Buttons || These are all the texts for buttons button.ok=OK button.back=Poprzedni button.next=Nast\u0119pny @@ -371,6 +419,7 @@ button.yes=Tak button.no=Nie button.yestoall=Tak na wszystko button.notoall=Nie na wszystko +button.select=Zaznacz button.selectall=Zaznacz wszystko button.selectnone=Odznacz button.preview=Podgl\u0105d @@ -378,6 +427,8 @@ button.load=\u0141aduj button.guessfields=Zgadnij pola button.showwebpage=Poka\u017c stron\u0119 web button.check=Sprawd\u017a +button.resettodefaults=Przywr\u00f3\u0107 domy\u015blne +button.browse=Przegl\u0105daj... # File types filetype.txt=Pliki TXT @@ -389,7 +440,7 @@ filetype.gpx=Pliki GPX filetype.pov=Pliki POV filetype.svg=Pliki SVG -# Display components +# Display components || These are all for the side panels showing point/range details display.nodata=Nie za\u0142adowano danych display.noaltitudes=\u015acie\u017cki nie zawieraj\u0105 informacji o wysoko\u015bci details.trackdetails=Szczeg\u00f3\u0142y \u015bcie\u017cki @@ -417,7 +468,9 @@ display.range.time.hours=h display.range.time.days=d details.range.avespeed=\u015arednia pr\u0119dko\u015b\u0107 details.range.avemovingspeed=\u015arednie przesuni\u0119cie +details.range.numsegments=Liczba segment\u00f3w details.range.pace=Tempo +details.range.gradient=Nachylenie details.waypointsphotos.waypoints=Punkty po\u015brednie details.waypointsphotos.photos=Zdj\u0119cia details.photodetails=Szczeg\u00f3\u0142y zdj\u0119cia @@ -473,7 +526,7 @@ cardinal.s=S cardinal.e=E cardinal.w=W -# Undo operations +# Undo operations || These will be displayed in the undo list after you've performed the operation, to tell you what you did undo.load=za\u0142aduj dane undo.loadphotos=za\u0142aduj zdj\u0119cia undo.editpoint=edycja punktu @@ -491,15 +544,22 @@ undo.cutandmove=przesu\u0144 fragment undo.connectphoto=do\u0142\u0105cz zdj\u0119cie undo.disconnectphoto=od\u0142\u0105cz zdj\u0119cie undo.correlate=po\u0142\u0105cz ze zdj\u0119ciami +undo.rearrangephotos=zmie\u0144 kolejno\u015b\u0107 zdj\u0119\u0107 undo.createpoint=stw\u00f3rz punkt +undo.rotatephoto=obr\u00f3\u0107 zdj\u0119cie +undo.convertnamestotimes=zamie\u0144 nazwy punkt\u00f3w # Error messages error.save.dialogtitle=B\u0142\u0105d zapisu danych error.save.nodata=Brak danych do zapisu -error.save.failed=Nie powi\u00f3d\u0142 si\u0119 zapis danych do pliku: -error.saveexif.filenotfound=Nie znaleziono pliku zdj\u0119cia +error.save.failed=Nie powi\u00f3d\u0142 si\u0119 zapis danych do pliku +error.saveexif.filenotfound=Nie znaleziono pliku ze zdj\u0119ciem error.saveexif.cannotoverwrite1=Plik ze zdj\u0119ciem -error.saveexif.cannotoverwrite2=jest w trybie tylko do odczytu i nie mo\u017ce zosta\u0107 nadpisany. Zapisa\u0107 do kopii? +error.saveexif.cannotoverwrite2=jest w trybie tylko do odczytu i nie mo\u017ce zosta\u0107 nadpisany. Zapisa\u0107 kopi\u0119? +error.saveexif.failed1=B\u0142\u0105d zapisu +error.saveexif.failed2=zdj\u0119\u0107 +error.saveexif.forced1= +error.saveexif.forced2=zdj\u0119\u0107 z wymuszonym zapisem error.load.dialogtitle=B\u0142\u0105d \u0142adowania danych error.load.noread=Nie mo\u017cna przeczyta\u0107 pliku error.load.nopoints=Nie znaleziono informacji o wsp\u00f3\u0142rz\u0119dnych w pliku @@ -511,13 +571,16 @@ error.jpegload.nofilesfound=Nie znaleziono plik\u00f3w error.jpegload.nojpegsfound=Nie znaleziono plik\u00f3w jpeg error.jpegload.noexiffound=Nie znaleziono informacji EXIF error.jpegload.nogpsfound=Nie znaleziono informacji GPS +error.gpsload.unknown=Nieznany b\u0142\u0105d error.undofailed.title=Cofnij nie powiod\u0142o si\u0119 error.undofailed.text=Nie mo\u017cna cofn\u0105\u0107 error.function.noop.title=Funkcja nie ma skutku -error.rearrange.noop=Przestawienie punkt\u00f3w po\u015brednich nie przyniesie skutku +error.rearrange.noop=Przestawienie punkt\u00f3w nie przyniesie skutku error.function.notavailable.title=Funkcja nie dost\u0119pna error.function.nojava3d=Ta funkcja wymaga biblioteki Java3d,\ndost\u0119pnej na Sun.com. error.3d=Nast\u0105pi\u0142 b\u0142\u0105d z wy\u015bwietlaniem 3D error.readme.notfound=Nie znaleziono pliku Readme error.osmimage.dialogtitle=B\u0142\u0105d przy \u0142adowaniu obraz\u00f3w map -error.osmimage.failed=B\u0142\u0105d przy \u0142adowaniu obraz\u00f3w map. Sprawd\u017a po\u0142\u0105czenie z internetem. \ No newline at end of file +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.convertnamestotimes.nonames=\u017badne nazwy nie mog\u0142y zosta\u0107 zmienione na czas diff --git a/tim/prune/lang/prune-texts_pt.properties b/tim/prune/lang/prune-texts_pt.properties index 53e0142..cc444d0 100644 --- a/tim/prune/lang/prune-texts_pt.properties +++ b/tim/prune/lang/prune-texts_pt.properties @@ -1,88 +1,592 @@ # Text entries for the Prune application -# Portuguese entries as extra +# (Brazilian) Portuguese entries as extra # Menu entries menu.file=Arquivo menu.file.open=Abrir +menu.file.addphotos=Adicionar fotos menu.file.save=Salvar menu.file.exit=Sair menu.edit=Editar +menu.track=Track menu.edit.undo=Desfazer +menu.edit.clearundo=Limpar lista de desfazer menu.edit.editpoint=Editar ponto +menu.edit.deletepoint=Remover ponto +menu.edit.deleterange=Remover intervalo +menu.edit.deletemarked=Remover pontos marcados +menu.edit.interpolate=Interpolar +menu.edit.average=Sele\u00e7\u00e3o m\u00e9dia +menu.edit.reverse=Reverter intervalo +menu.edit.mergetracksegments=Mesclar trechos da rota +menu.edit.rearrange=Rearrumar pontos +menu.edit.rearrange.start=Tudo para o in\u00edcio do arquivo +menu.edit.rearrange.end=Tudo para o fim do arquivo +menu.edit.rearrange.nearest=Cada um para o ponto da rota mais pr\u00f3ximo +menu.edit.cutandmove=Recortar e mover sele\u00e7\u00e3o menu.select=Selecionar +menu.range=Intervalo +menu.point=Ponto menu.select.all=Selectionar tudo -menu.select.none=Não selecionar nenhuns +menu.select.none=N\u00e3o selecionar nenhuns +menu.select.start=Definir in\u00edcio do intervalo +menu.select.end=Definir fim do intervalo menu.photo=Foto -menu.photo.saveexif=Salvar exif -menu.photo.delete=Remover Foto +menu.photo.saveexif=Salvar para Exif +menu.photo.connect=Conectar ao ponto +menu.photo.disconnect=Desconectar do ponto +menu.photo.delete=Remover foto menu.view=Exibir +menu.view.browser=Mapear no navegador +menu.view.browser.google=Mapas do Google +menu.view.browser.openstreetmap=Mapas do Openstreetmap +menu.view.browser.mapquest=Mapas do Mapquest +menu.view.browser.yahoo=Mapas do Yahoo +menu.view.browser.bing=Mapas do Bing +menu.settings=Configura\u00e7\u00f5es menu.help=Ajuda # Popup menu for map -menu.map.zoomin=Ampliar zoom -menu.map.zoomout=Reduzir zoom +menu.map.zoomin=Ampliar +menu.map.zoomout=Reduzir +menu.map.zoomfull=Ajustar para tela +menu.map.newpoint=Criar novo ponto +menu.map.connect=Conectar pontos da rota +menu.map.autopan=Auto-ajustar menu.map.showmap=Mostrar o mapa +menu.map.showscalebar=Mostrar barra de escala # Alt keys for menus altkey.menu.file=A altkey.menu.edit=E altkey.menu.select=S +altkey.menu.track=T +altkey.menu.range=I +altkey.menu.point=P altkey.menu.view=X altkey.menu.photo=F -altkey.menu.help=A +altkey.menu.settings=C +altkey.menu.help=J # Ctrl shortcuts for menu items shortcut.menu.file.open=A +shortcut.menu.file.load=C shortcut.menu.file.save=S shortcut.menu.edit.undo=Z +shortcut.menu.edit.compress=C shortcut.menu.select.all=T -shortcut.menu.help.help=H +shortcut.menu.help.help=J # Functions -function.exportkml=Exportar KML -function.exportgpx=Exportar GPX -function.exportpov=Exportar POV -function.editwaypointname=Editar nome do waypoint -function.charts=Diagramas -function.show3d=Visualizar 3d -function.distances=Distâncias +function.loadfromgps=Carregar dados do GPS +function.sendtogps=Enviar dados para o GPS +function.exportkml=Exportar para KML +function.exportgpx=Exportar para GPX +function.exportpov=Exportar para POV +function.editwaypointname=Editar nome do ponto +function.compress=Comprimir rota +function.addtimeoffset=Adicionar diferen\u00e7a de tempo +function.addaltitudeoffset=Adicionar diferen\u00e7a de altitude +function.convertnamestotimes=Converter nomes dos pontos para tempos +function.findwaypoint=Encontrar ponto +function.pastecoordinates=Inserir novas coordenadas +function.charts=Gr\u00e1ficos +function.show3d=Visualizar 3D +function.distances=Dist\u00e2ncias +function.fullrangedetails=Todos os detalhes +function.setmapbg=Definir como fundo do mapa +function.setkmzimagesize=Definir tamanho da imagem KMZ +function.setpaths=Definir caminhos do programa +function.getgpsies=Obter rotas Gpsies +function.duplicatepoint=Duplicar ponto +function.setcolours=Definir cores +function.setlanguage=Definir idioma +function.correlatephotos=Correlacionar fotos +function.rearrangephotos=Rearrumar fotos +function.rotatephotoleft=Roda foto \u00e0 esquerda +function.rotatephotoright=Roda foto \u00e0 direita +function.ignoreexifthumb=Ignorar miniatura do exif function.help=Ajuda +function.showkeys=Mostrar atalhos de teclado function.about=Sobre o Prune +function.checkversion=Verificar novas vers\u00f5es +function.saveconfig=Salvar configura\u00e7\u00f5es # Dialogs +dialog.exit.confirm.title=Sair do Prune +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? +dialog.deletepoint.title=Remover Ponto +dialog.deletepoint.deletephoto=Remover foto anexada a este ponto? +dialog.deletephoto.title=Remover Foto +dialog.deletephoto.deletepoint=Remover ponto anexado a esta foto? +dialog.openoptions.title=Op\u00e7\u00f5es de abertura +dialog.openoptions.filesnippet=Extrair do arquivo +dialog.load.table.field=Campo +dialog.load.table.datatype=Tipo de Dado +dialog.load.table.description=Descri\u00e7\u00e3o +dialog.delimiter.label=Delimitador do campo +dialog.delimiter.comma=V\u00edrgula , +dialog.delimiter.tab=Tabula\u00e7\u00e3o +dialog.delimiter.space=Espa\u00e7o +dialog.delimiter.semicolon=Ponto e v\u00edrgula ; +dialog.delimiter.other=Outro +dialog.openoptions.deliminfo.records=registros, com +dialog.openoptions.deliminfo.fields=campos +dialog.openoptions.deliminfo.norecords=Sem registros +dialog.openoptions.altitudeunits=Unidades de altitude +dialog.jpegload.subdirectories=Incluir subpastas +dialog.jpegload.loadjpegswithoutcoords=Incluir fotos sem coordenadas +dialog.jpegload.loadjpegsoutsidearea=Incluir fotos fora da \u00e1rea atual +dialog.jpegload.progress.title=Carregando fotos +dialog.jpegload.progress=Por favor, espere enquanto as fotos s\u00e3o procuradas +dialog.gpsload.nogpsbabel=Nenhum programa gpsbabel pode ser encontrado. Continuar? +dialog.gpsload.device=Nome do dispositivo +dialog.gpsload.format=Formato +dialog.gpsload.getwaypoints=Carregar pontos +dialog.gpsload.gettracks=Carregar rotas +dialog.gpsload.save=Salvar para arquivo +dialog.gpssend.sendwaypoints=Enviar pontos +dialog.gpssend.sendtracks=Enviar rotas +dialog.gpssend.trackname=Nome da rota +dialog.saveoptions.title=Salvar arquivo +dialog.save.fieldstosave=Campos a salvar +dialog.save.table.field=Campo +dialog.save.table.hasdata=Possui dados +dialog.save.table.save=Salvar +dialog.save.headerrow=Sa\u00edda da linha de cabe\u00e7alho +dialog.save.coordinateunits=Unidades das coordenadas +dialog.save.altitudeunits=Unidades da altitude +dialog.save.timestampformat=Formato da data-hora +dialog.save.overwrite.title=Arquivo j\u00e1 existe +dialog.save.overwrite.text=Este arquivo j\u00e1 existe. Voc\u00ea tem certeza que deseja sobrescrev\u00ea-lo? +dialog.save.notypesselected=Nenhum tipo de ponto foi selecionado +dialog.exportkml.text=T\u00edtulo para os dados +dialog.exportkml.altitude=Incluir altitudes (para avia\u00e7\u00e3o) +dialog.exportkml.kmz=Comprimir para criar arquivo kmz +dialog.exportkml.exportimages=Exportar miniaturas de imagem para o kmz +dialog.exportkml.trackcolour=Cor da rota +dialog.exportgpx.name=Nome +dialog.exportgpx.desc=Descri\u00e7\u00e3o +dialog.exportgpx.includetimestamps=Incluir data-hora +dialog.exportgpx.copysource=Copiar fonte xml +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 +dialog.exportpov.cameray=Y da C\u00e2mera +dialog.exportpov.cameraz=Z da C\u00e2mera +dialog.exportpov.modelstyle=Estilo do modelo +dialog.exportpov.ballsandsticks=Bolas e galhos +dialog.exportpov.tubesandwalls=Tubos e muros +dialog.exportpov.warningtracksize=Esta rota possui um grande n\u00famero de pontos, os quais o Java3D n\u00e3o ser\u00e1 capaz de exibir.\n Voc\u00ea tem certeza que deseja continuar? +dialog.pointtype.desc=Salvar os seguintes tipos de ponto: +dialog.pointtype.track=Pontos de rotas +dialog.pointtype.waypoint=Pontos +dialog.pointtype.photo=Pontos de foto +dialog.pointtype.selection=Apenas sele\u00e7\u00e3o +dialog.confirmreversetrack.title=Confirmar invers\u00e3o +dialog.confirmreversetrack.text=Esta rota possui informa\u00e7\u00f5es de data-hora, as quais estar\u00e3o fora de sequ\u00eancia ap\u00f3s a revers\u00e3o.\n Voc\u00ea tem certeza que deseja reverter esta se\u00e7\u00e3o? +dialog.confirmcutandmove.title=Confirmar cortar e mover +dialog.confirmcutandmove.text=A rota cont\u00e9m informa\u00e7\u00f5es de data-hora, as quais estar\u00e3o fora de sequ\u00eancia ap\u00f3s o movimento.\n Voc\u00ea tem certeza que deseja mover esta se\u00e7\u00e3o? +dialog.interpolate.title=Interpolar pontos +dialog.interpolate.parameter.text=N\u00famero de pontos para inserir entre os pontos selecionados +dialog.undo.title=A\u00e7\u00e3o(\u00f5es) de desfazer +dialog.undo.pretext=Por favor, selecione a a\u00e7\u00e3o(\u00f5es) a desfazer +dialog.undo.none.title=N\u00e3o foi poss\u00edvel desfazer +dialog.undo.none.text=Nenhuma opera\u00e7\u00e3o a desfazer! +dialog.clearundo.title=Limpar lista de desfazer +dialog.clearundo.text=Voc\u00ea tem certeza que deseja limpar a lista de desfazer?\n Todas as informa\u00e7\u00f5es para desfazer ser\u00e3o perdidas! +dialog.pointedit.title=Editar ponto +dialog.pointedit.text=Selecionar cada campo para editar e usar o bot\u00e3o 'Editar' para mudar o valor +dialog.pointedit.table.field=Campo +dialog.pointedit.table.value=Valor +dialog.pointedit.table.changed=Alterado +dialog.pointedit.changevalue.text=Insira o novo valor para este campo +dialog.pointedit.changevalue.title=Editar campo +dialog.pointnameedit.name=Nome do ponto +dialog.pointnameedit.uppercase=MAI\u00daSCULAS +dialog.pointnameedit.lowercase=min\u00fasculas +dialog.pointnameedit.sentencecase=Frase +dialog.addtimeoffset.add=Adicionar tempo +dialog.addtimeoffset.subtract=Subtrair tempo +dialog.addtimeoffset.days=Dias +dialog.addtimeoffset.hours=Horas +dialog.addtimeoffset.minutes=Minutos +dialog.addtimeoffset.notimestamps=N\u00e3o foi poss\u00edvel adicionar uma diferen\u00e7a de tempo uma vez que esta sele\u00e7\u00e3o n\u00e3o possui nenhuma informa\u00e7\u00e3o de data-hora +dialog.findwaypoint.intro=Insira parte do nome do ponto +dialog.findwaypoint.search=Pesquisar +dialog.connect.title=Conectar foto ao ponto +dialog.connectphoto.clonepoint=Este ponto j\u00e1 possui uma foto.\n Voc\u00ea deseja fazer uma c\u00f3pia deste ponto? +dialog.saveexif.title=Salvar Exif +dialog.saveexif.intro=Selecionar as fotos para salvar usando as caixas de sele\u00e7\u00e3o +dialog.saveexif.nothingtosave=Dados das coordenadas n\u00e3o foram alterados, nada para salvar +dialog.saveexif.noexiftool=Nenhum programa exiftool pode ser encontrado. Continuar? +dialog.saveexif.table.photoname=Nome da foto +dialog.saveexif.table.status=Estado +dialog.saveexif.table.save=Salvar +dialog.saveexif.photostatus.connected=Conectada +dialog.saveexif.photostatus.disconnected=Desconectada +dialog.saveexif.photostatus.modified=Modificada +dialog.saveexif.overwrite=Sobrescrever arquivos +dialog.saveexif.force=For\u00e7ar ignorar erros menores +dialog.charts.xaxis=Eixo X +dialog.charts.yaxis=Eixo Y +dialog.charts.output=Sa\u00edda +dialog.charts.screen=Sa\u00edda para tela +dialog.charts.svg=Sa\u00edda para arquivo SVG +dialog.charts.svgwidth=Largura do SVG +dialog.charts.svgheight=Altura do SVG +dialog.charts.needaltitudeortimes=A rota deve possuir informa\u00e7\u00f5es de tempo ou altitude para criar gr\u00e1ficos +dialog.charts.gnuplotnotfound=N\u00e3o foi poss\u00edvel encontrar o gnuplot com o caminho fornecido +dialog.distances.intro=Dist\u00e2ncias em linha reta entre pontos +dialog.distances.column.from=Do ponto +dialog.distances.column.to=Para o ponto +dialog.distances.currentpoint=Ponto atual +dialog.distances.toofewpoints=Esta fun\u00e7\u00e3o precisa de pontos para calcular a dist\u00e3ncia entre eles +dialog.fullrangedetails.intro=Aqui est\u00e3o os detalhes para o intervalo selecionado +dialog.setmapbg.mapnik=Mapnik (padr\u00e3o) +dialog.setmapbg.osma=Osma +dialog.setmapbg.cyclemap=Cyclemap +dialog.setmapbg.other=Outro +dialog.setmapbg.server=URL do Servidor +dialog.gpsies.column.name=Nome da rota +dialog.gpsies.column.length=Extens\u00e3o +dialog.gpsies.description=Descri\u00e7\u00e3o +dialog.gpsies.nodescription=Sem descri\u00e7\u00e3o +dialog.gpsies.nonefound=Nenhuma rota encontrada +dialog.correlate.notimestamps=N\u00e3o existem data-hora nos dados dos pontos, assim n\u00e3o h\u00e1 nada para correlacionar com as fotos +dialog.correlate.nouncorrelatedphotos=Existem fotos n\u00e3o correlacionadas.\nVoc\u00ea tem certeza que deseja continuar? +dialog.correlate.photoselect.intro=Selecione uma destas fotos correlacionadas para usar como diferen\u00e7a de tempo +dialog.correlate.photoselect.photoname=Nome da foto +dialog.correlate.photoselect.timediff=Diferen\u00e7a de tempo +dialog.correlate.photoselect.photolater=Foto \u00e9 mais recente +dialog.correlate.options.tip=Dica: Correlacionando pelo menos uma foto manualmente, a diferen\u00e7a de tempo pode ser calculada para voc\u00ea. +dialog.correlate.options.intro=Selecione as op\u00e7\u00f5es para correla\u00e7\u00e3o autom\u00e1tica +dialog.correlate.options.offsetpanel=Diferen\u00e7a de tempo +dialog.correlate.options.offset=Diferen\u00e7a +dialog.correlate.options.offset.hours=horas. +dialog.correlate.options.offset.minutes=minutos e +dialog.correlate.options.offset.seconds=segundos +dialog.correlate.options.photolater=Foto mais recente que o ponto +dialog.correlate.options.pointlater=Ponto mais recente que a foto +dialog.correlate.options.limitspanel=Limites de correla\u00e7\u00e3o +dialog.correlate.options.notimelimit=Nenhum limite de tempo +dialog.correlate.options.timelimit=Limite de tempo +dialog.correlate.options.nodistancelimit=Nenhum limite de dist\u00e2ncia +dialog.correlate.options.distancelimit=Limite de dist\u00e2ncia +dialog.correlate.options.correlate=Correlacionar +dialog.correlate.alloutsiderange=Todas as fotos est\u00e3o fora do intervalo de tempo da rota, assim nenhuma pode ser correlacionada.\n Tente mudar a diferen\u00e7a de tempo ou manualmente correlacionar pelo menos uma foto. +dialog.rearrangephotos.desc=Selecione o destino e a ordena\u00e7\u00e3o dos pontos das fotos +dialog.rearrangephotos.tostart=Mover para o in\u00edcio +dialog.rearrangephotos.toend=Mover para o fim +dialog.rearrangephotos.nosort=N\u00e3o ordenar +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.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.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.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.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 +dialog.about.translatedby=Texto em portugu\u00eas por amigo anónimo. +dialog.about.systeminfo=Informa\u00e7\u00f5es do sistema +dialog.about.systeminfo.os=Sistema Operacional +dialog.about.systeminfo.java=M\u00f3dulo Java +dialog.about.systeminfo.java3d=Java3d instalado +dialog.about.systeminfo.povray=Povray instalado +dialog.about.systeminfo.exiftool=Exittool instalado +dialog.about.systeminfo.gpsbabel=Gpsbabel instalado +dialog.about.systeminfo.gnuplot=Gnuplot instalado dialog.about.yes=Sim -dialog.about.no=Não +dialog.about.no=N\u00e3o +dialog.about.credits=Cr\u00e9ditos +dialog.about.credits.code=C\u00f3digo do Prune escrito por +dialog.about.credits.exifcode=C\u00f3digo do Exif por +dialog.about.credits.icons=Alguns \u00edcones obtidos de +dialog.about.credits.translators=Tradutores +dialog.about.credits.translations=Tradu\u00e7\u00f5es auxiliadas por +dialog.about.credits.devtools=Ferramentas de desenvolvimento +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.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.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.saveconfig.desc=As seguintes configura\u00e7\u00f5es podem ser salvas para um arquivo de configura\u00e7\u00e3o. +dialog.saveconfig.prune.trackdirectory=Pasta de rotas +dialog.saveconfig.prune.photodirectory=Pasta de fotos +dialog.saveconfig.prune.languagecode=C\u00f3digo do idioma (PT_BR) +dialog.saveconfig.prune.languagefile=Arquivo de idioma +dialog.saveconfig.prune.gpsdevice=Dispositivo de GPS +dialog.saveconfig.prune.gpsformat=Formato do GPS +dialog.saveconfig.prune.povrayfont=Fonte Povray +dialog.saveconfig.prune.metricunits=Usar unidades m\u00e9tricas? +dialog.saveconfig.prune.gnuplotpath=Caminho para o gnuplot +dialog.saveconfig.prune.gpsbabelpath=Caminho para o gpsbabel +dialog.saveconfig.prune.exiftoolpath=Caminho para o exiftool +dialog.saveconfig.prune.mapserverindex=\u00cdndice do servidor de mapas +dialog.saveconfig.prune.mapserverurl=URL do servidor de mapas +dialog.saveconfig.prune.kmzimagewidth=Largura da imagem KMZ +dialog.saveconfig.prune.kmzimageheight=Altura da imagem KMZ +dialog.saveconfig.prune.colourscheme=Esquema de cores +dialog.saveconfig.prune.kmltrackcolour=Cor da rota KML +dialog.setpaths.intro=Se voc\u00ea precisar, voc\u00ea pode escolher os caminhos para as aplica\u00e7\u00f5es externas: +dialog.addaltitude.noaltitudes=O intervalo selecionado n\u00e3o cont\u00e9m altitudes +dialog.addaltitude.desc=Diferen\u00e7a de altitude a adicionar +dialog.setcolours.intro=Clique em um trecho de cor para mudar a cor +dialog.setcolours.background=Fundo +dialog.setcolours.borders=Bordas +dialog.setcolours.lines=Linhas +dialog.setcolours.primary=Prim\u00e1rio +dialog.setcolours.secondary=Secund\u00e1rio +dialog.setcolours.point=Pontos +dialog.setcolours.selection=Sele\u00e7\u00e3o +dialog.setcolours.text=Texto +dialog.colourchooser.title=Selecionar cor +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.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. -# Buttons +# 3d window +dialog.3d.title=Vista 3D do Prune +dialog.3d.altitudecap=Intervalo de altitude m\u00ednimo +dialog.3dlines.title=Linhas da grade do Prune +dialog.3dlines.empty=Nenhuma linha de grade para exibir! +dialog.3dlines.intro=Estas s\u00e3o as linhas da grade para a vista 3D. + +# Confirm messages || These are displayed as confirmation in the status bar +confirm.loadfile=Dados carregados do arquivo +confirm.save.ok1=Salvo com sucesso +confirm.save.ok2=pontos para arquivo +confirm.deletepoint.single=dados do ponto foram removidos +confirm.deletepoint.multi=dados dos pontos foram removidos +confirm.point.edit=ponto editado +confirm.mergetracksegments=Segmento da rota mesclado +confirm.reverserange=Intervalo invertido +confirm.addtimeoffset=Diferen\u00e7a de tempo adicionada +confirm.addaltitudeoffset=Diferen\u00e7a de altitude adicionadas +confirm.rearrangewaypoints=Pontos rearrumados +confirm.rearrangephotos=Fotos rearrumadas +confirm.cutandmove=Sele\u00e7\u00e3o movida +confirm.convertnamestotimes=Nomes dos pontos convertidos +confirm.saveexif.ok1=Salvo +confirm.saveexif.ok2=arquivos de foto +confirm.undo.single=opera\u00e7\u00e3o desfeita +confirm.undo.multi=opera\u00e7\u00f5es desfeitas +confirm.jpegload.single=foto foi adicionada +confirm.jpegload.multi=fotos foram adicionadas +confirm.photo.connect=foto conectada +confirm.photo.disconnect=foto desconectada +confirm.correlate.single=foto foi correlacionada +confirm.correlate.multi=fotos foram correlacionadas +confirm.createpoint=ponto criado +confirm.rotatephoto=foto rotacionada +confirm.running=Rodando... + +# Buttons || These are all the texts for buttons +button.ok=Ok +button.back=Voltar +button.next=P\u0155oximo +button.finish=Terminar button.cancel=Cancelar +button.overwrite=Sobrescrever +button.moveup=Mover acima +button.movedown=Mover abaixo +button.showlines=Mostrar linhas button.edit=Editar button.exit=Sair button.close=Fechar +button.continue=Continuar button.yes=Sim -button.no=Não +button.no=N\u00e3o +button.yestoall=Sim para todos +button.notoall=N\u00e3o para todos +button.select=Selecionar +button.selectall=Selecionar todos +button.selectnone=Selecionar nenhum +button.preview=Previs\u00e3o +button.load=Carregar +button.guessfields=Campos adivinhados +button.showwebpage=Mostrar p\u00e1gina Web +button.check=Verificar +button.resettodefaults=Restaurar para os padr\u00f5es +button.browse=Navegar... -# Display components -display.nodata=Nenhum dados foi carregado +# File types +filetype.txt=Arquivos TXT +filetype.jpeg=Arquivos JPG +filetype.kmlkmz=Arquivos KML, KMZ +filetype.kml=Arquivos KML +filetype.kmz=Arquivos KMZ +filetype.gpx=Arquivos GPX +filetype.pov=Arquivos POV +filetype.svg=Arquivos SVG + +# Display components || These are all for the side panels showing point/range details +display.nodata=Nenhum dado carregado +display.noaltitudes=Dados da rota n\u00e3o incluem altitudes details.trackdetails=Detalhes da track +details.notrack=Nenhuma rota carrgeada details.track.points=Pontos details.track.file=Arquivo -details.track.numfiles=Número de arquivos +details.track.numfiles=N\u00famero de arquivos details.pointdetails=Detalhes da ponto +details.index.selected=\u00cdndice details.index.of=de +details.nopointselection=Nenhum ponto selecionado +details.photofile=Arquivo de foto +details.norangeselection=Nenhum intervalo selecionado details.rangedetails=Detalhes da range details.range.selected=Selecionado details.range.to=a details.altitude.to=a +details.range.climb=Subir +details.range.descent=Descer +details.coordformat=Formato das coordenadas +details.distanceunits=Unidades de dist\u00e2ncia +display.range.time.secs=s +display.range.time.mins=m +display.range.time.hours=h +display.range.time.days=d +details.range.avespeed=Velocidade m\u00e9dia +details.range.avemovingspeed=Movimento m\u00e9dio +details.range.numsegments=N\u00famero de segmentos +details.range.pace=Passo +details.range.gradient=Gradiente +details.waypointsphotos.waypoints=Pontos details.waypointsphotos.photos=Fotos details.photodetails=Detalhes da foto +details.nophoto=Nenhuma foto selecionada details.photo.loading=Carregando +details.photo.connected=Conectada +map.overzoom=Nenhum mapa dispon\u00edvel neste n\u00edvel de amplia\u00e7\u00e3o # Field names fieldname.latitude=Latitude fieldname.longitude=Longitude fieldname.altitude=Altura +fieldname.timestamp=Tempo fieldname.time=Tempo -fieldname.distance=Distância +fieldname.waypointname=Nome +fieldname.waypointtype=Tipo +fieldname.newsegment=Segmento +fieldname.custom=Personalizado +fieldname.prefix=Campo +fieldname.distance=Dist\u00e2ncia +fieldname.movingdistance=Dist\u00e2ncia de movimento +fieldname.duration=Dura\u00e7\u00e3o fieldname.speed=Velocidade +fieldname.verticalspeed=Velocidade vertical + +# Measurement units +units.original=Original +units.default=Padr\u00e3o +units.metres=Metros +units.metres.short=m +units.feet=P\u00e9s +units.feet.short=ft +units.kilometres=Quil\u00f4metros +units.kilometres.short=km +units.kmh=km/h +units.miles=Milhas +units.miles.short=mi +units.mph=mph +units.metrespersec=m/s +units.feetpersec=ft/s +units.hours=horas +units.degminsec=Graus-min-seg +units.degmin=Graus-min +units.deg=Graus +units.iso8601=ISO 8601 # External urls url.googlemaps=maps.google.pt + +# Cardinals for 3d plots +cardinal.n=N +cardinal.s=S +cardinal.e=L +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.load=carregar dados +undo.loadphotos=carregar fotos +undo.editpoint=editar ponto +undo.deletepoint=remover ponto +undo.deletephoto=remover foto +undo.deleterange=remover intervalo +undo.compress=comprimir rota +undo.insert=inserir pontos +undo.reverse=inverter intervalo +undo.mergetracksegments=mesclar segmentos de rota +undo.addtimeoffset=adicionar diferen\u00e7a de tempo +undo.addaltitudeoffset=adicionar diferen\u00e7a de altitude +undo.rearrangewaypoints=rearrumar pontos +undo.cutandmove=mover se\u00e7\u00e3o +undo.connectphoto=conectar foto +undo.disconnectphoto=desconectar foto +undo.correlate=conectar fotos +undo.rearrangephotos=rearrumar fotos +undo.createpoint=criar ponto +undo.rotatephoto=rotacionar foto +undo.convertnamestotimes=converter nomes para tempos + +# Error messages +error.save.dialogtitle=Erro ao salvar dados +error.save.nodata=Nenhum dado para salvar +error.save.failed=Falha ao salvar dados para arquivo +error.saveexif.filenotfound=Falha ao procurar o arquivo de foto +error.saveexif.cannotoverwrite1=Arquivo de foto +error.saveexif.cannotoverwrite2=\u00e9 somente leitura e n\u00e3o pode ser sobrescrito. Gravar para c\u00f3pia? +error.saveexif.failed1=Falha ao salvar +error.saveexif.failed2=das imagens +error.saveexif.forced1= +error.saveexif.forced2=das imagens for\u00e7adas por solicita\u00e7\u00e3o +error.load.dialogtitle=Erro ao carregar dados +error.load.noread=N\u00e3o foi poss\u00edvel ler arquivo +error.load.nopoints=Nenhuma informa\u00e7\u00e3o de coordenadas encontrada no arquivo +error.load.unknownxml=Formato xml n\u00e3o reconhecido: +error.load.noxmlinzip=Nenhum arquivo xml encontrado dentro do arquivo zip +error.load.othererror=Erro ao ler arquivo: +error.jpegload.dialogtitle=Erro ao carregar fotos +error.jpegload.nofilesfound=Nenhum arquivo encontrado +error.jpegload.nojpegsfound=Nenhum arquivo jpeg encontrado +error.jpegload.noexiffound=Nenhuma informa\u00e7\u00e3o EXIF encontrada +error.jpegload.nogpsfound=Nenhuma informa\u00e7\u00e3o de GPS encontrada +error.gpsload.unknown=Erro desconhecido +error.undofailed.title=Falha ao desfazer +error.undofailed.text=Falha para desfazer opera\u00e7\u00e3o +error.function.noop.title=Fun\u00e7\u00e3o sem nenhum efeito +error.rearrange.noop=Rearruma\u00e7\u00e3o de pontos n\u00e3o teve efeito +error.function.notavailable.title=Fun\u00e7\u00e3o n\u00e3o dispon\u00edvel +error.function.nojava3d=Esta fun\u00e7\u00e3o precisa da biblioteca Java3d,\ndispon\u00edvel em Sun.com +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.convertnamestotimes.nonames=Nenhum nome pode ser convertido para tempo diff --git a/tim/prune/lang/prune-texts_ro.properties b/tim/prune/lang/prune-texts_ro.properties index 9e9b22e..e416762 100644 --- a/tim/prune/lang/prune-texts_ro.properties +++ b/tim/prune/lang/prune-texts_ro.properties @@ -2,18 +2,19 @@ # Romanian entries as extra # Menu entries -menu.file=Fi\u015Fier -menu.file.open=Deschidere fi\u015Fier +menu.file=Fi\u015fier +menu.file.open=Deschidere fi\u015fier menu.file.addphotos=Adaugare foto menu.file.save=Salvare menu.file.exit=Iesire +menu.track=Traseu menu.edit=Editare menu.edit.undo=Anulare -menu.edit.clearundo=\u015Etergere lista de anulari +menu.edit.clearundo=\u015etergere lista de anulari menu.edit.editpoint=Editare punct -menu.edit.deletepoint=\u015Etergere punct -menu.edit.deleterange=\u015Etergere gama -menu.edit.deletemarked=\u015Etergere puncte marcate +menu.edit.deletepoint=\u015etergere punct +menu.edit.deleterange=\u015etergere gama +menu.edit.deletemarked=\u015etergere puncte marcate menu.edit.interpolate=Interpolare menu.edit.average=Mediere selectie menu.edit.reverse=Inversare selectie @@ -23,6 +24,7 @@ menu.edit.rearrange.start=Toate la inceputul fisierului menu.edit.rearrange.end=Toate la sfarsitul fisierului menu.edit.rearrange.nearest=Fiecare la punctul cel mai apropiat al traseului menu.edit.cutandmove=Taiere si mutare selectie +menu.point=Punct menu.select=Selectare menu.select.all=Selectare toate menu.select.none=Nu selecta niciun punct @@ -39,12 +41,16 @@ menu.view.browser.google=Harti Google menu.view.browser.openstreetmap=Openstreetmap menu.view.browser.mapquest=Mapquest menu.view.browser.yahoo=Harti Yahoo +menu.view.browser.bing=Harti Bing menu.help=Ajutor # Popup menu for map -menu.map.zoomin=Apropie in -menu.map.zoomout=Apropie out +menu.map.zoomin=Apropie +menu.map.zoomout=Departeaza +menu.map.zoomfull=Departeaza la maxim menu.map.newpoint=Adaug\u0103 punct -menu.map.connect=Traseaz\u0103 linii între puncte +menu.map.connect=Traseaz\u0103 linii \u00eentre puncte +menu.map.autopan=Autovizualizare punct ales +menu.map.showmap=Arata harta # Alt keys for menus altkey.menu.file=F @@ -61,31 +67,107 @@ shortcut.menu.edit.undo=Z shortcut.menu.select.all=T # Functions -function.exportkml=Export\u0103 într-un fi\u015Fier KML -function.exportgpx=Export\u0103 într-un fi\u015Fier GPX -function.exportpov=Export\u0103 într-un fi\u015Fier POV +function.loadfromgps=\u00cencarc\u0103 date de la GPS +function.sendtogps=Trimite date spre GPS +function.exportkml=Export\u0103 \u00eentr-un fi\u015fier KML +function.exportgpx=Export\u0103 \u00eentr-un fi\u015fier GPX +function.exportpov=Export\u0103 \u00eentr-un fi\u015fier POV function.editwaypointname=Editare nume waypoint +function.compress=Comprima traseu +function.charts=Grafice +function.show3d=Vizualizare arborescenta +function.distances=Distan\u0163e +function.setmapbg=Fundal +function.correlatephotos=Corela fotografii +function.setcolours=Selectare culorile +function.setlanguage=Selectare limba function.help=Ajutor +function.showkeys=Arat\u0103 tastele scurt\u0103turi function.about=Despre Prune +function.checkversion=Verific\u0103 pentru o versiune noua # Dialogs -dialog.save.overwrite.text=Fi\u015Fierul exist\u0103. Îl suprascriu? -dialog.pointedit.text=V\u0103 rog selecta\u0163i rândul care va fi editat +dialog.exit.confirm.title=Ie\u015fire din programul Prune +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? +dialog.deletepoint.title=Sterge Punct +dialog.deletepoint.deletephoto=Sterg fotografiile atasate acestui punct? +dialog.deletephoto.title=Sterge Foto +dialog.deletephoto.deletepoint=Sterg punct atasat acestei fotografii? +dialog.openoptions.title=Optiuni deschidere +dialog.load.table.field=Cimp +dialog.load.table.datatype=Tip data +dialog.load.table.description=Descriere +dialog.delimiter.label=Delimitator cimp +dialog.delimiter.comma=Virgula , +dialog.delimiter.tab=Tab +dialog.delimiter.space=Spatiu +dialog.delimiter.semicolon=Punct si virgula : +dialog.delimiter.other=Altul +dialog.openoptions.deliminfo.fields=cimpuri +dialog.openoptions.deliminfo.norecords=Nu sunt inregistrari +dialog.save.overwrite.text=Fi\u015fierul exist\u0103. \u00cel suprascriu? +dialog.pointedit.text=V\u0103 rog selecta\u0163i r\u00e2ndul care va fi editat +dialog.pointedit.table.field=Cimp dialog.pointedit.table.value=Valoare +dialog.pointedit.table.changed=Schimbat +dialog.pointedit.changevalue.text=Introdu noua valoare pentru acest cimp +dialog.pointedit.changevalue.title=Modifica cimp +dialog.pointnameedit.uppercase=Litere MARI +dialog.pointnameedit.lowercase=Litere mici +dialog.addtimeoffset.days=Zile +dialog.addtimeoffset.hours=Ore +dialog.addtimeoffset.minutes=Minute dialog.findwaypoint.search=C\u0103utare +dialog.saveexif.table.status=Stare +dialog.saveexif.table.save=Salveaza +dialog.saveexif.photostatus.connected=Conectat +dialog.saveexif.photostatus.disconnected=Deconectat +dialog.saveexif.photostatus.modified=Modificat +dialog.saveexif.overwrite=Suprascrie fisiere +dialog.charts.xaxis=Axa X +dialog.charts.yaxis=Axa Y +dialog.distances.currentpoint=Punct curent dialog.setmapbg.mapnik=Mapnik (implicit) dialog.setmapbg.server=Adres\u0103 server +dialog.gpsies.column.length=Lungime +dialog.gpsies.description=Descriere +dialog.gpsies.nodescription=Fara descriere dialog.correlate.options.tip=Indiciu: By manually correlating at least one photo, the time offset can be calculated for you. dialog.about.version=Versiunea -dialog.about.readme=Cite\u015Fte-m\u0103 +dialog.about.readme=Cite\u015fte-m\u0103 +dialog.checkversion.releasedate1=Aceasta versiune noua a fost lansapa pe +dialog.checkversion.releasedate2=. + +# Confirm messages || These are displayed as confirmation in the status bar +confirm.loadfile=Date incarcate din fisier +confirm.save.ok1=Salvat cu succes # Buttons button.ok=OK +button.back=Inapoi +button.next=Urmator +button.finish=Terminat button.cancel=Renun\u0163\u0103 +button.overwrite=Suprascrie +button.moveup=Muta in sus +button.movedown=Muta in jos button.edit=Editare button.exit=Iesire +button.close=Inchide +button.continue=Continua +button.yes=Da +button.no=Nu +button.yestoall=Da pentru tot +button.notoall=Nu pentru tot +button.select=Selectare +button.selectall=Selecteaza tot +button.selectnone=Deselecteaza tot +button.load=Incarca # File types +filetype.txt=Fisier text filetype.jpeg=Imagine JPEG (*.jpg) # Display components @@ -94,9 +176,28 @@ details.pointdetails=Punct details.range.selected=Selectat details.range.to=la details.altitude.to=la +details.coordformat=Format coordonate +details.distanceunits=Unitati de distanta +display.range.time.secs=s +display.range.time.mins=m +display.range.time.hours=h +display.range.time.days=z +details.range.avespeed=Viteza medie # Field names +fieldname.latitude=Latitudine +fieldname.longitude=Longitudine +fieldname.altitude=Altitudine fieldname.waypointname=Nume +fieldname.distance=Distanta +fieldname.duration=Durata +fieldname.speed=Viteza # Measurement units units.default=Implicit + +# Cardinals for 3d plots +cardinal.n=N +cardinal.s=S +cardinal.e=E +cardinal.w=V diff --git a/tim/prune/lang/prune-texts_tr.properties b/tim/prune/lang/prune-texts_tr.properties new file mode 100644 index 0000000..20fe689 --- /dev/null +++ b/tim/prune/lang/prune-texts_tr.properties @@ -0,0 +1,436 @@ +# Text entries for the Prune application +# Turkish entries as extra + +# Menu entries +menu.file=Dosya +menu.file.open=Dosya a\u00e7 +menu.file.addphotos=Foto ekle +menu.file.save=Kaydet +menu.file.exit=Ç\u0131k\u0131\u015f +menu.edit=D\u00fczenle +menu.track=\u0130z +menu.edit.undo=Geri al +menu.edit.clearundo=Geri alma listesi s\u0131f\u0131rla +menu.edit.editpoint=Nokta d\u00fczenle +menu.edit.deletepoint=Noktay\u0131 sil +menu.edit.deleterange=S\u0131ray\u0131 sil +menu.edit.deletemarked=Se\u00e7ili noktalar\u0131 sil +menu.edit.interpolate=\u0130nterpolasyon +menu.edit.average=Se\u00e7me ortala +menu.edit.reverse=S\u0131ra tersine \u00e7evir +menu.edit.mergetracksegments=\u0130z par\u00e7alar\u0131 birle\u015ftir +menu.edit.rearrange=Yol noktalar\u0131 yeniden diz +menu.edit.rearrange.start=Hepsini dosyan\u0131n ba\u015f\u0131na +menu.edit.rearrange.end=Hepsini dosyan\u0131n sonuna +menu.edit.rearrange.nearest=En yak\u0131n iz noktaya +menu.edit.cutandmove=Se\u00e7me kes ve ta\u015f\u0131 +menu.select=Se\u00e7 +menu.range=S\u0131ra +menu.point=Nokta +menu.select.all=Hepsini se\u00e7 +menu.select.none=Hi\u00e7 se\u00e7 +menu.select.start=S\u0131ran\u0131n ba\u015fkang\u0131c\u0131 se\u00e7 +menu.select.end=S\u0131ran\u0131n sonu se\u00e7 +menu.photo=Foto +menu.photo.saveexif=Exif'te kaydet +menu.photo.connect=Noktaya ba\u011flan +menu.photo.disconnect=Noktadan kopart +menu.photo.delete=Fotoyu kald\u0131r +menu.view=G\u00f6r\u00fcn\u00fcm +menu.view.browser=Taray\u0131c\u0131n\u0131n haritas\u0131 +menu.view.browser.google=Google haritalar\u0131 +menu.view.browser.openstreetmap=OpenStreetMap +menu.view.browser.mapquest=Mapquest +menu.view.browser.yahoo=Yahoo haritalar\u0131 +menu.view.browser.bing=Bing haritalar\u0131 +menu.settings=Ayarlar +menu.settings.showpace=H\u0131z\u0131 g\u00f6r\u00fcnt\u00fcle +menu.help=Yard\u0131m +# Popup menu for map +menu.map.zoomin=Yak\u0131nla\u015ft\u0131r +menu.map.zoomout=Uzakla\u015f +menu.map.newpoint=Yeni nokta olu\u015ftur +menu.map.connect=\u0130z noktalar\u0131 ba\u011flan +menu.map.showmap=Harita g\u00f6ster +menu.map.showscalebar=\u00d6l\u00e7e\u011fi g\u00f6r\u00fcnt\u00fcle + +# Alt keys for menus +altkey.menu.file=D +altkey.menu.edit=Z +altkey.menu.select=S +altkey.menu.track=Z +altkey.menu.range=S +altkey.menu.point=N +altkey.menu.view=G +altkey.menu.photo=F +altkey.menu.settings=A +altkey.menu.help=Y + +# Ctrl shortcuts for menu items +shortcut.menu.file.open=A +shortcut.menu.file.load=L +shortcut.menu.file.save=K +shortcut.menu.edit.undo=Z +shortcut.menu.edit.compress=C +shortcut.menu.select.all=A +shortcut.menu.help.help=Y + +# Functions +function.loadfromgps=GPS'den veri al +function.sendtogps=GPS'e veri g\u00f6nder +function.exportkml=Ver KML olarak +function.exportgpx=Ver GPX olarak +function.exportpov=Ver POV olarak +function.editwaypointname=Noktan\u0131n ad\u0131 d\u00fczenle +function.compress=Yolunu s\u0131k\u0131\u015ft\u0131r +function.addtimeoffset=Zaman ofseti ekle +function.addaltitudeoffset=Y\u00fckseklik ofseti ekle +function.findwaypoint=Noktay\u0131 bul +function.pastecoordinates=Yeni korrdinatlar gir +function.charts=Krokiler +function.show3d=3B g\u00fcr\u00fcnt\u00fcs\u00fc +function.distances=Uzakl\u0131klar +function.fullrangedetails=S\u0131ran\u0131n b\u00fct\u00fcn ayr\u0131nt\u0131lar +function.setmapbg=Arkafonun haritas\u0131 se\u00e7 +function.setkmzimagesize=KMZ resim boyutu ayarla +function.setpaths=Uygulamalar\u0131n yollar\u0131 ayarla +function.getgpsies=Gpsies.com'dan yolu al +function.duplicatepoint=Noktay\u0131 kopyala +function.setcolours=Renkleri ayarla +function.setlanguage=Dil se\u00e7 +function.correlatephotos=Fotolar\u0131n ba\u011fl\u0131la\u015ft\u0131r +function.rearrangephotos=Fotolar\u0131 yeniden diz +function.rotatephotoleft=Fotoyu sola d\u00f6nd\u00fcr +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.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.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? +dialog.deletepoint.title=Noktay\u0131 sil +dialog.deletepoint.deletephoto=Noktaya ba\u011fl\u0131 olan foto silmek ister misin? +dialog.deletephoto.title=Fotoyu sil +dialog.deletephoto.deletepoint=Fotoya ba\u011fl\u0131 olan nokta silmek ister misin? +dialog.openoptions.title=Se\u00e7enekleri a\u00e7 +dialog.openoptions.filesnippet=Dosyan\u0131n par\u00e7as\u0131 +dialog.load.table.field=Alan +dialog.load.table.datatype=Veri t\u00fcr\u00fc +dialog.load.table.description=A\u00e7\u0131klama +dialog.delimiter.label=Alan s\u0131n\u0131rlay\u0131c\u0131 +dialog.delimiter.comma=Virg\u00fcl , +dialog.delimiter.tab=Sekme +dialog.delimiter.space=Bo\u015fluk +dialog.delimiter.semicolon=Noktal\u0131 virg\u00fcl ; +dialog.delimiter.other=Di\u011fer +dialog.openoptions.deliminfo.records=sat\u0131rlar, ve +dialog.openoptions.deliminfo.fields=alanlar +dialog.openoptions.deliminfo.norecords=Hi\u00e7 bir sat\u0131r bulunmad\u0131 +dialog.openoptions.altitudeunits=Y\u00fckseklik birimi +dialog.jpegload.subdirectories=Alt dizileri dahil et +dialog.jpegload.loadjpegswithoutcoords=Koordinats\u0131z fotolar\u0131 dahil et +dialog.jpegload.loadjpegsoutsidearea=Se\u00e7ili alan\u0131n d\u0131\u015f\u0131ndaki fotolar\u0131 dahil et +dialog.jpegload.progress.title=Fotolar y\u00fckleniyor +dialog.jpegload.progress=Fotolar\u0131 taran\u0131yor - l\u00fctfen bekle +dialog.gpsload.nogpsbabel=gpsbabel uygulamas\u0131 bulunmad\u0131. Devam? +dialog.gpsload.device=Ayg\u0131t ad\u0131 +dialog.gpsload.format=Bi\u00e7im +dialog.gpsload.getwaypoints=Noktalar y\u00fckle +dialog.gpsload.gettracks=Yollar y\u00fckle +dialog.gpsload.save=Dosyaya kaydet +dialog.gpssend.sendwaypoints=Noktalar\u0131 g\u00f6nder +dialog.gpssend.sendtracks=Yollar g\u00f6nder +dialog.gpssend.trackname=\u0130z ad\u0131 +dialog.saveoptions.title=Dosya kaydet +dialog.save.fieldstosave=Kaydedecek alanlar +dialog.save.table.field=Alan +dialog.save.table.hasdata=Veri var +dialog.save.table.save=Kaydet +dialog.save.headerrow=Ba\u015fl\u0131k sat\u0131r\u0131 dahil et +dialog.save.coordinateunits=Koordinat birimleri +dialog.save.altitudeunits=Y\u00fckseklik birimleri +dialog.save.timestampformat=Tarih ve saat bi\u00e7imi +dialog.save.overwrite.title=Dosya zaten var +dialog.save.overwrite.text=Bu dosya zaten var. Ger\u00e7ekten \u00fczerinde yazmak ister misin? +dialog.exportkml.text=Verinin ba\u015fl\u0131\u011f\u0131 +dialog.exportkml.altitude=Absolut y\u00fckseklikleri (u\u00e7u\u015f i\u00e7in) +dialog.exportkml.kmz=kmz dosyas\u0131 olu\u015fturmak i\u00e7in s\u0131k\u0131\u015ft\u0131r +dialog.exportkml.exportimages=Fotolar\u0131n t\u0131rnak resimleri kmz dosyada dahil et +dialog.exportkml.trackcolour=\u0130z rengi +dialog.exportgpx.name=Ad\u0131 +dialog.exportgpx.desc=A\u00e7\u0131klama +dialog.exportgpx.includetimestamps=Tarih ve saat dahil et +dialog.exportgpx.copysource=Kaynak xml'i kopyala +dialog.exportpov.font=Yaz\u0131tipi +dialog.exportpov.camerax=Kamera X +dialog.exportpov.cameray=Kamera Y +dialog.exportpov.cameraz=Kamera Z +dialog.pointtype.track=\u0130z noktalar +dialog.pointtype.waypoint=Noktalar (POI) +dialog.undo.title=Geri al +dialog.undo.pretext=Geri alacaklar\u0131 se\u00e7 +dialog.undo.none.title=Geri alacak bir \u015fey yok +dialog.undo.none.text=Geri alacak bir \u015fey yok! +dialog.clearundo.title=Geri alma listesi s\u0131f\u0131rla +dialog.clearundo.text=Ger\u00e7ekten geri alma listesi s\u0131f\u0131rlamak ister misin?\nGeri alma bilgileri tamamen silinecektir! +dialog.pointedit.title=Nokta d\u00fczenle +dialog.pointedit.table.field=Alan +dialog.pointedit.table.value=De\u011fer +dialog.pointedit.table.changed=De\u011fi\u015fmi\u015f +dialog.pointedit.changevalue.text=Yeni de\u011feri gir +dialog.pointedit.changevalue.title=Alan d\u00fczenle +dialog.pointnameedit.name=Nokta ad\u0131 +dialog.pointnameedit.uppercase=B\u00dcY\u00dcK HARFLER +dialog.pointnameedit.lowercase=k\u00fc\u00e7\u00fck harfler +dialog.pointnameedit.sentencecase=\u0130lk Harfi B\u00fcy\u00fck +dialog.addtimeoffset.add=Zaman ekle +dialog.addtimeoffset.subtract=Zaman \u00e7\u0131kart +dialog.addtimeoffset.days=G\u00fcn +dialog.addtimeoffset.hours=Saat +dialog.addtimeoffset.minutes=Dakika +dialog.findwaypoint.search=Ara +dialog.saveexif.title=Exif kaydet +dialog.saveexif.table.photoname=Foto ad\u0131 +dialog.saveexif.table.status=Durum +dialog.saveexif.table.save=Kaydet +dialog.saveexif.photostatus.connected=Ba\u011fland\u0131 +dialog.saveexif.photostatus.disconnected=Ba\u011flant\u0131 kesildi +dialog.saveexif.photostatus.modified=De\u011fi\u015ftirildi +dialog.saveexif.overwrite=Dosyalar\u0131n \u00fczerinde yaz +dialog.saveexif.force=Ufak hatalar\u0131 bo\u015fver +dialog.charts.xaxis=X axis +dialog.charts.yaxis=Y axis +dialog.charts.output=Ç\u0131kt\u0131 +dialog.charts.screen=Ekranda g\u00f6ster +dialog.charts.svg=SVG dosya olarak g\u00f6ster +dialog.charts.svgwidth=SVG geni\u015fli\u011fi +dialog.charts.svgheight=SVG y\u00fcksekli\u011fi +dialog.setmapbg.mapnik=Mapnik (default) +dialog.setmapbg.osma=Osma +dialog.setmapbg.cyclemap=Cyclemap +dialog.setmapbg.other=Di\u011fer +dialog.setmapbg.server=Sunucu URL +dialog.gpsies.column.name=Yol ad\u0131 +dialog.gpsies.column.length=Uzunlu\u011fu +dialog.gpsies.description=A\u00e7\u0131klama +dialog.gpsies.nodescription=A\u00e7\u0131klama yok +dialog.gpsies.nonefound=Herhangi bir yol bulunmad\u0131 +dialog.correlate.photoselect.photoname=Foto ad\u0131 +dialog.correlate.photoselect.photolater=Foto sonra +dialog.correlate.options.offset.hours=saat, +dialog.correlate.options.offset.minutes=dakika ve +dialog.correlate.options.offset.seconds=saniye +dialog.correlate.options.photolater=Foto noktadan sonra +dialog.correlate.options.pointlater=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.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.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.translatedby=Turkish text by katpatuka +dialog.about.systeminfo=Sistem bilgisi +dialog.about.systeminfo.os=\u0130\u015fletim Sistemi +dialog.about.systeminfo.java=Java Runtime +dialog.about.systeminfo.java3d=Java3d kuruldu +dialog.about.systeminfo.povray=Povray kuruldu +dialog.about.systeminfo.exiftool=Exiftool kuruldu +dialog.about.systeminfo.gpsbabel=Gpsbabel kuruldu +dialog.about.systeminfo.gnuplot=Gnuplot kuruldu +dialog.about.yes=Evet +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.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.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: +dialog.saveconfig.prune.trackdirectory=\u0130z klas\u00f6r\u00fc +dialog.saveconfig.prune.photodirectory=Foto klas\u00f6r\u00fc +dialog.saveconfig.prune.languagecode=Dil kodu (TR) +dialog.saveconfig.prune.gpsdevice=GPS ayg\u0131t +dialog.saveconfig.prune.gpsformat=GPS bi\u00e7imi +dialog.saveconfig.prune.povrayfont=Povray yaz\u0131tipi +dialog.saveconfig.prune.metricunits=Metrik sistemi +dialog.saveconfig.prune.gnuplotpath=gnuplot'un yeriyolu +dialog.saveconfig.prune.gpsbabelpath=gpsbabel'in yeriyolu +dialog.saveconfig.prune.exiftoolpath=exiftool'un yeriyolu +dialog.saveconfig.prune.mapserverindex=Harita sunucunun index +dialog.saveconfig.prune.mapserverurl=Harita sunucunun adresi +dialog.saveconfig.prune.showpace=H\u0131z\u0131 g\u00f6r\u00fcnt\u00fcle +dialog.saveconfig.prune.kmzimagewidth=KMZ resim geni\u015fli\u011fi +dialog.saveconfig.prune.kmzimageheight=KMZ resim y\u00fcksekli\u011fi +dialog.setpaths.intro=\u0130ste\u011fe ba\u011fl\u0131 a\u015fa\u011f\u0131daki uygulamalar\u0131n veriyolu kaydedebilirsin: +dialog.addaltitude.noaltitudes=Se\u00e7ili s\u0131rada y\u00fckseklik bilgisi bulunmad\u0131 +dialog.addaltitude.desc=Eklenecek y\u00fckseklik ofseti +dialog.setcolours.background=Arkafonu +dialog.setcolours.borders=Kenarlar +dialog.setcolours.lines=Çizgiler +dialog.setcolours.primary=Birincil +dialog.setcolours.secondary=\u0130kincil +dialog.setcolours.point=Noktalar +dialog.setcolours.selection=Se\u00e7im +dialog.setcolours.text=Metin +dialog.colourchooser.title=Rengi se\u00e7 +dialog.colourchooser.red=K\u0131rm\u0131z\u0131 +dialog.colourchooser.green=Ye\u015fil +dialog.colourchooser.blue=Mavi + +# Confirm messages || These are displayed as confirmation in the status bar +confirm.save.ok1=Ba\u011far\u0131yla kaydedildi +confirm.save.ok2=points to file +confirm.mergetracksegments=\u0130z par\u00e7alar\u0131 birle\u015ftirildi + +# Buttons || These are all the texts for buttons +button.ok=Tamam +button.back=Geri +button.next=\u0130leri +button.finish=Son +button.cancel=\u0130ptal +button.overwrite=\u00dczerinde yaz +button.moveup=Yukar\u0131 +button.movedown=A\u015fa\u011f\u0131 +button.showlines=Çizgiler g\u00f6r\u00fcnt\u00fcle +button.edit=D\u00fczenle +button.exit=Ç\u0131k\u0131\u015f +button.close=Kapat +button.continue=Devam +button.yes=Evet +button.no=Hay\u0131r +button.yestoall=Hepsini evet +button.notoall=Hepsini hay\u0131r +button.select=Se\u00e7 +button.selectall=Hepsini se\u00e7 +button.selectnone=Hi\u00e7 se\u00e7me +button.preview=\u00d6ng\u00f6r\u00fcn\u00fcm +button.load=Y\u00fckle +button.guessfields=Alanlar\u0131 tahmin et +button.showwebpage=Websayfas\u0131 g\u00f6r\u00fcnt\u00fcle +button.check=Denetle + +# File types +filetype.txt=TXT dosyalar\u0131 +filetype.jpeg=JPG dosyalar\u0131 +filetype.kmlkmz=KML, KMZ dosyalar\u0131 +filetype.kml=KML dosyalar\u0131 +filetype.kmz=KMZ dosyalar\u0131 +filetype.gpx=GPX dosyalar\u0131 +filetype.pov=POV dosyalar\u0131 +filetype.svg=SVG dosyalar\u0131 + +# Display components || These are all for the side panels showing point/range details +display.nodata=Hergangi veri y\u00fcklenmedi +display.noaltitudes=Track verisinde y\u00fckseklik bilgisi yok +details.trackdetails=\u0130z ayr\u0131nt\u0131lar\u0131 +details.notrack=Herhangi track y\u00fcklenmedi +details.track.points=Noktalar +details.track.file=Dosya +details.track.numfiles=Dosya say\u0131s\u0131 +details.pointdetails=Nokta ayr\u0131nt\u0131lar\u0131 +details.index.selected=Endeks +details.index.of=toplam: +details.nopointselection=Herhangi nokta se\u00e7ili de\u011fil +details.photofile=Foto dosyas\u0131 +details.norangeselection=Herhangi s\u0131ra se\u00e7ili de\u011fil +details.rangedetails=S\u0131ra ayr\u0131nt\u0131lar\u0131 +details.range.selected=Se\u00e7ili +details.range.to=- +details.altitude.to=- +details.range.climb=T\u0131rman\u0131\u015f +details.range.descent=\u0130ni\u015f +details.coordformat=Koordinat bi\u00e7imi +details.distanceunits=Uzakl\u0131k birimi +display.range.time.secs=san +display.range.time.mins=dak +display.range.time.hours=saat +display.range.time.days=g\u011fn +details.range.avespeed=Ortalama h\u0131z\u0131 +details.range.avemovingspeed=Ortalama hareketi +details.waypointsphotos.waypoints=Noktalar +details.waypointsphotos.photos=Fotolar +details.photodetails=Foto ayr\u0131nt\u0131lar\u0131 +details.nophoto=Herhangi foto se\u00e7ili de\u011fil +details.photo.loading=Y\u00fckleniyor +details.photo.connected=Ba\u011fland\u0131 +map.overzoom=Fazla yak\u0131nla\u015ft\u0131n salak - harita g\u00f6r\u00fcnt\u00fclenmiyor + +# Field names +fieldname.latitude=Enlem (lat) +fieldname.longitude=Boylam (lon) +fieldname.altitude=Y\u00fckseklik +fieldname.timestamp=Zaman +fieldname.time=Zaman +fieldname.waypointname=Ad\u0131 +fieldname.waypointtype=T\u00fcr +fieldname.newsegment=Par\u00e7a +fieldname.custom=Di\u011fer +fieldname.prefix=Alan +fieldname.distance=Uzakl\u0131k +fieldname.duration=S\u00fcre +fieldname.speed=H\u0131z +fieldname.verticalspeed=Dikey h\u0131z\u0131 + +# Measurement units +units.original=Orijinal +units.default=Varsay\u0131lan +units.metres=Metre +units.metres.short=m +units.feet=Ayak +units.feet.short=ft +units.kilometres=Kilometre +units.kilometres.short=km +units.kmh=km/h +units.miles=Mil +units.miles.short=mi +units.mph=mph +units.metrespersec=m/s +units.feetpersec=ft/s +units.hours=saat +units.degminsec=Derece/Dakika/Saniye +units.degmin=Derece/Dakika +units.deg=Derece +units.iso8601=ISO 8601 + +# External urls +url.googlemaps=maps.google.com + +# Cardinals for 3d plots +cardinal.n=K +cardinal.s=G +cardinal.e=D +cardinal.w=B + +# Undo operations || These will be displayed in the undo list after you've performed the operation, to tell you what you did +undo.load=veri y\u00fckle +undo.loadphotos=fotolar y\u00fckle +undo.editpoint=noktay\u0131 d\u00fczenle +undo.deletepoint=noktay\u0131 sil +undo.deletephoto=foto kald\u0131r +undo.deleterange=s\u0131ra sil +undo.compress=izi s\u0131k\u0131\u015ft\u0131r +undo.insert=noktalar\u0131 ekle +undo.reverse=s\u0131ra tersine d\u00f6nd\u00fcr +undo.mergetracksegments=iz par\u00e7alar\u0131 birle\u015ftir +undo.addtimeoffset=zaman de\u011fi\u015ftir +undo.addaltitudeoffset=y\u00fckseklik de\u011fi\u015ftir +undo.rearrangewaypoints=noktalar\u0131 yeniden diz +undo.cutandmove=par\u00e7as\u0131 ta\u015f\u0131 +undo.connectphoto=fotoyu ba\u011flan +undo.disconnectphoto=fotonun ba\u011flant\u0131s\u0131 kes +undo.correlate=fotolar\u0131n ba\u011fl\u0131la\u015f\u0131m\u0131 +undo.rearrangephotos=fotolar\u0131 yeniden diz +undo.createpoint=noktay\u0131 olu\u015ftur +undo.rotatephoto=fotoyu d\u00f6nder diff --git a/tim/prune/lang/prune-texts_zh.properties b/tim/prune/lang/prune-texts_zh.properties index d91fea7..ba1c391 100644 --- a/tim/prune/lang/prune-texts_zh.properties +++ b/tim/prune/lang/prune-texts_zh.properties @@ -52,24 +52,6 @@ menu.map.autopan=\u81ea\u52a8\u7f29\u653e menu.map.showmap=\u663e\u793a\u5730\u56fe menu.map.showscalebar=\u663e\u793a\u6bd4\u4f8b\u5c3a -# Alt keys for menus -altkey.menu.file= -altkey.menu.edit= -altkey.menu.select= -altkey.menu.view= -altkey.menu.photo= -altkey.menu.settings= -altkey.menu.help= - -# Ctrl shortcuts for menu items -shortcut.menu.file.open= -shortcut.menu.file.load= -shortcut.menu.file.save= -shortcut.menu.edit.undo= -shortcut.menu.edit.compress= -shortcut.menu.select.all= -shortcut.menu.help.help= - # Functions function.loadfromgps=\u4eceGPS\u5bfc\u5165 function.sendtogps=\u53d1\u9001\u81f3GPS @@ -84,11 +66,11 @@ function.findwaypoint=\u67e5\u627e\u822a\u70b9 function.charts=\u9ad8\u5ea6\u901f\u5ea6\u56fe\u8868 function.show3d=3-D\u89c6\u56fe function.distances=\u8ddd\u79bb -function.getgpsies=Gpsies\u8f68\u8ff9 -function.correlatephotos=\u94fe\u63a5\u76f8\u7247 function.setmapbg=\u80cc\u666f\u5730\u56fe -function.setkmzimagesize= +function.setkmzimagesize=\u8bbe\u7f6eKMZ\u56fe\u50cf\u5c3a\u5bf8 function.setpaths=\u8bbe\u7f6e\u7a0b\u5e8f\u8def\u5f84 +function.getgpsies=Gpsies\u8f68\u8ff9 +function.correlatephotos=\u94fe\u63a5\u76f8\u7247 function.help=\u5e2e\u52a9 function.showkeys=\u663e\u793a\u5feb\u6377\u952e function.about=\u5173\u4e8ePrune @@ -215,7 +197,6 @@ dialog.charts.svg=\u8f93\u51fa\u81f3SVG\u6587\u4ef6 dialog.charts.svgwidth=SVG\u5bbd\u5ea6 dialog.charts.svgheight=SVG\u9ad8\u5ea6 dialog.charts.needaltitudeortimes=\u8f68\u8ff9\u5fc5\u987b\u542b\u6709\u9ad8\u5ea6\u6216\u65f6\u95f4\u4fe1\u606f -dialog.charts.gnuplotpath=gnuplot\u8def\u5f84 dialog.charts.gnuplotnotfound=\u8def\u5f84\u9519\u8bef\uff0c\u65e0\u6cd5\u627e\u5230gnuplot dialog.distances.intro=\u822a\u70b9\u4e4b\u95f4\u76f4\u7ebf\u8ddd\u79bb dialog.distances.column.from=\u4ece\u6b64\u70b9 @@ -231,7 +212,6 @@ dialog.gpsies.column.name=\u8f68\u8ff9\u540d\u79f0 dialog.gpsies.column.length=\u957f\u5ea6 dialog.gpsies.description=\u63cf\u8ff0 dialog.gpsies.nodescription=\u65e0\u63cf\u8ff0 -dialog.gpsies.nonefound= dialog.correlate.notimestamps=\u6570\u636e\u70b9\u4e2d\u65e0\u65f6\u95f4\u4fe1\u606f\uff0c\u76f8\u7247\u65e0\u6cd5\u94fe\u63a5 dialog.correlate.nouncorrelatedphotos=\u6240\u6709\u76f8\u7247\u5df2\u94fe\u63a5\n\u7ee7\u7eed\uff1f dialog.correlate.photoselect.intro=\u9009\u62e9\u5df2\u94fe\u63a5\u76f8\u7247\u4f5c\u4e3a\u65f6\u95f4\u504f\u79fb @@ -255,13 +235,13 @@ dialog.correlate.options.distancelimit=\u8ddd\u79bb\u9650\u5236 dialog.correlate.options.correlate=\u94fe\u63a5 dialog.correlate.alloutsiderange=\u65e0\u6cd5\u94fe\u63a5\uff0c\u6240\u6709\u76f8\u7247\u8d85\u51fa\u8f68\u8ff9\u65f6\u95f4\u8303\u56f4\n\u8bf7\u6539\u53d8\u65f6\u95f4\u504f\u79fb\u6216\u624b\u52a8\u94fe\u63a5\u81f3\u5c11\u4e00\u5f20\u76f8\u7247 dialog.compress.nonefound=\u65e0\u6cd5\u5220\u9664\u6570\u636e\u70b9 -dialog.compress.duplicates.title=\u91cd\u590d\u70b9\u5220\u9664 dialog.compress.closepoints.title=\u90bb\u8fd1\u70b9\u5220\u9664 dialog.compress.closepoints.paramdesc=\u8303\u56f4\u7cfb\u6570 dialog.compress.wackypoints.title=\u5f02\u5e38\u70b9\u5220\u9664 dialog.compress.wackypoints.paramdesc=\u8ddd\u79bb\u7cfb\u6570 dialog.compress.singletons.title=\u79bb\u6563\u70b9\u5220\u9664 dialog.compress.singletons.paramdesc=\u8ddd\u79bb\u7cfb\u6570 +dialog.compress.duplicates.title=\u91cd\u590d\u70b9\u5220\u9664 dialog.compress.summarylabel=\u8981\u5220\u9664\u7684\u70b9 dialog.help.help=\u66f4\u591a\u4fe1\u606f\u548c\u7528\u6cd5\uff0c\u8bf7\u53c2\u8003\u7f51\u7ad9\nhttp://activityworkshop.net/software/prune/// dialog.about.version=\u7248\u672c @@ -299,7 +279,6 @@ dialog.checkversion.releasedate1=\u65b0\u7248\u672c\u53d1\u884c\u4e8e dialog.checkversion.releasedate2= dialog.checkversion.download=\u4e0b\u8f7d\u6700\u65b0\u7248\u672c\uff0c\u8bf7\u767b\u9646\u7f51\u7ad9\uff1a\nhttp://activityworkshop.net/software/prune/download.html dialog.keys.intro=\u53ef\u7528\u4e0b\u5217\u5feb\u6377\u952e\u66ff\u4ee3\u9f20\u6807 -dialog.keys.keylist= dialog.saveconfig.desc=\u4e0b\u5217\u8bbe\u7f6e\u5c06\u4fdd\u5b58\u5230\u8bbe\u7f6e\u6587\u4ef6 dialog.saveconfig.prune.trackdirectory=\u8f68\u8ff9\u6587\u4ef6\u5939 dialog.saveconfig.prune.photodirectory=\u76f8\u7247\u6587\u4ef6\u5939 @@ -314,8 +293,8 @@ dialog.saveconfig.prune.exiftoolpath=exiftool\u8def\u5f84 dialog.saveconfig.prune.mapserverindex=\u80cc\u666f\u5730\u56fe\u7801(1-4) dialog.saveconfig.prune.mapserverurl=\u90094\u65f6\u5730\u56fe\u670d\u52a1\u5668URL dialog.saveconfig.prune.showpace=\u663e\u793a\u6b65\u901f -dialog.saveconfig.prune.kmzimagewidth= -dialog.saveconfig.prune.kmzimageheight= +dialog.saveconfig.prune.kmzimagewidth=KMZ\u56fe\u50cf\u5bbd\u5ea6 +dialog.saveconfig.prune.kmzimageheight=KMZ\u56fe\u50cf\u9ad8\u5ea6 dialog.setpaths.intro=\u82e5\u9700\u8981\uff0c\u53ef\u8bbe\u5b9a\u5916\u6302\u7a0b\u5e8f\u8def\u5f84 dialog.addaltitude.noaltitudes=\u8f68\u8ff9\u4e0d\u542b\u9ad8\u5ea6\u4fe1\u606f dialog.addaltitude.desc=\u9ad8\u5ea6\u504f\u79fb @@ -337,7 +316,6 @@ confirm.point.edit=\u5df2\u7f16\u8f91\u7684\u8f68\u8ff9\u70b9 confirm.mergetracksegments=\u5df2\u5408\u5e76\u7684\u8f68\u8ff9\u6bb5 confirm.reverserange=\u53cd\u5411\u7684\u8303\u56f4 confirm.addtimeoffset=\u5df2\u52a0\u4e0a\u65f6\u95f4\u504f\u5dee -confirm.addaltitudeoffset= confirm.rearrangewaypoints=\u91cd\u65b0\u914d\u7f6e\u7684\u822a\u70b9 confirm.cutandmove=\u5df2\u79fb\u52a8\u7684\u8f68\u8ff9\u6bb5 confirm.saveexif.ok1=\u5df2\u4fdd\u5b58 @@ -353,7 +331,7 @@ confirm.correlate.multi=\u76f8\u7247\u5df2\u94fe\u63a5 confirm.createpoint=\u5df2\u521b\u5efa\u70b9 confirm.running=\u8bf7\u7a0d\u7b49... -# Buttons +# Buttons || These are all the texts for buttons button.ok=\u786e\u5b9a button.back=\u8fd4\u56de button.next=\u4e0b\u4e00\u6b65 @@ -371,6 +349,7 @@ button.yes=\u662f button.no=\u5426 button.yestoall=\u5168\u90e8\u662f button.notoall=\u5168\u90e8\u5426 +button.select=\u9009\u62e9 button.selectall=\u5168\u9009 button.selectnone=\u5168\u4e0d\u9009 button.preview=\u9884\u89c8 @@ -389,7 +368,7 @@ filetype.gpx=GPX\u6587\u4ef6 filetype.pov=POV\u6587\u4ef6 filetype.svg=SVG\u6587\u4ef6 -# Display components +# Display components || These are all for the side panels showing point/range details display.nodata=\u65e0\u6570\u636e display.noaltitudes=\u8f68\u8ff9\u6570\u636e\u4e0d\u542b\u9ad8\u5ea6\u4fe1\u606f details.trackdetails=\u8f68\u8ff9\u4fe1\u606f @@ -473,7 +452,7 @@ cardinal.s=S cardinal.e=E cardinal.w=W -# Undo operations +# Undo operations || These will be displayed in the undo list after you've performed the operation, to tell you what you did undo.load=\u5bfc\u5165\u6570\u636e undo.loadphotos=\u5bfc\u5165\u76f8\u7247 undo.editpoint=\u7f16\u8f91\u8f68\u8ff9\u70b9 diff --git a/tim/prune/load/FieldGuesser.java b/tim/prune/load/FieldGuesser.java index 7a67096..6b29379 100644 --- a/tim/prune/load/FieldGuesser.java +++ b/tim/prune/load/FieldGuesser.java @@ -86,6 +86,12 @@ public abstract class FieldGuesser fields[f] = Field.NEW_SEGMENT; continue; } + // check for waypoint type + if (!checkArrayHasField(fields, Field.WAYPT_TYPE) && fieldLooksLikeWaypointType(value, isHeader)) + { + fields[f] = Field.WAYPT_TYPE; + continue; + } } } // Fill in the rest of the fields using just custom fields @@ -115,6 +121,10 @@ public abstract class FieldGuesser else if (!checkArrayHasField(fields, Field.LONGITUDE)) { fields[1] = Field.LONGITUDE; } + // Longitude _could_ have overwritten latitude in position 1 + if (!checkArrayHasField(fields, Field.LATITUDE)) { + fields[0] = Field.LATITUDE; + } return fields; } @@ -298,4 +308,27 @@ public abstract class FieldGuesser return false; } } + + /** + * Check whether the given String looks like a waypoint type + * @param inValue value from file + * @param inIsHeader true if this is a header line, false for data + * @return true if it could be a waypoint type + */ + private static boolean fieldLooksLikeWaypointType(String inValue, boolean inIsHeader) + { + if (inValue == null || inValue.equals("")) {return false;} + if (inIsHeader) + { + String upperValue = inValue.toUpperCase(); + // This is a header line so look for english or local text + return (upperValue.equals("TYPE") + || upperValue.equals(I18nManager.getText("fieldname.waypointtype").toUpperCase())); + } + else + { + // can't reliably identify it just using the value + return false; + } + } } diff --git a/tim/prune/load/FileLoader.java b/tim/prune/load/FileLoader.java index 889f1d7..c6d9827 100644 --- a/tim/prune/load/FileLoader.java +++ b/tim/prune/load/FileLoader.java @@ -6,7 +6,8 @@ import javax.swing.JFileChooser; import javax.swing.JFrame; import tim.prune.App; -import tim.prune.Config; +import tim.prune.config.Config; +import tim.prune.load.xml.GzipFileLoader; import tim.prune.load.xml.XmlFileLoader; import tim.prune.load.xml.ZipFileLoader; @@ -24,6 +25,7 @@ public class FileLoader private NmeaFileLoader _nmeaFileLoader = null; private XmlFileLoader _xmlFileLoader = null; private ZipFileLoader _zipFileLoader = null; + private GzipFileLoader _gzipFileLoader = null; /** @@ -39,6 +41,7 @@ public class FileLoader _nmeaFileLoader = new NmeaFileLoader(inApp); _xmlFileLoader = new XmlFileLoader(inApp); _zipFileLoader = new ZipFileLoader(inApp, _xmlFileLoader); + _gzipFileLoader = new GzipFileLoader(inApp, _xmlFileLoader); } @@ -117,6 +120,11 @@ public class FileLoader // Use zip loader for zipped kml (or zipped gpx) _zipFileLoader.openFile(inFile); } + else if (fileExtension.endsWith(".gz") || fileExtension.equals("gzip")) + { + // Use gzip loader for gzipped xml + _gzipFileLoader.openFile(inFile); + } else if (fileExtension.equals("nmea")) { _nmeaFileLoader.openFile(inFile); diff --git a/tim/prune/load/GpsLoader.java b/tim/prune/load/GpsLoader.java index 3ec3c6b..c0ca754 100644 --- a/tim/prune/load/GpsLoader.java +++ b/tim/prune/load/GpsLoader.java @@ -9,7 +9,9 @@ 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; @@ -22,19 +24,22 @@ 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; import tim.prune.App; -import tim.prune.Config; import tim.prune.ExternalTools; import tim.prune.GenericFunction; import tim.prune.I18nManager; +import tim.prune.config.Config; import tim.prune.data.Altitude; +import tim.prune.data.SourceInfo; import tim.prune.load.xml.XmlFileLoader; import tim.prune.load.xml.XmlHandler; +import tim.prune.save.GpxExporter; /** * Class to manage the loading of GPS data using GpsBabel @@ -45,8 +50,10 @@ public class GpsLoader extends GenericFunction implements Runnable 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; @@ -146,6 +153,11 @@ public class GpsLoader extends GenericFunction implements Runnable _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); @@ -210,14 +222,13 @@ public class GpsLoader extends GenericFunction implements Runnable if (_waypointCheckbox.isSelected() || _trackCheckbox.isSelected()) { _progressBar.setIndeterminate(true); + _saveFile = null; try { - callGpsBabel(_waypointCheckbox.isSelected(), _trackCheckbox.isSelected()); + callGpsBabel(); } catch (Exception e) { - // System.err.println("Error: " + e.getClass().getName()); - // System.err.println("Error: " + e.getMessage()); _app.showErrorMessageNoLookup(getNameKey(), e.getMessage()); _cancelled = true; } @@ -234,70 +245,126 @@ public class GpsLoader extends GenericFunction implements Runnable /** * Execute the call to gpsbabel and pass the results back to the app - * @param inWaypoints true to load waypoints - * @param inTracks true to load track points */ - private void callGpsBabel(boolean inWaypoints, boolean inTracks) throws Exception + private void callGpsBabel() throws Exception { // Set up command to call gpsbabel - String[] commands = null; final String device = _deviceField.getText().trim(); final String format = _formatField.getText().trim(); - final String command = Config.getConfigString(Config.KEY_GPSBABEL_PATH); - if (inWaypoints && inTracks) { - // Both waypoints and track points selected - commands = new String[] {command, "-w", "-t", "-i", format, - "-f", device, "-o", "gpx", "-F", "-"}; - } - else - { - // Only waypoints OR track points selected - commands = new String[] {command, "-w", "-i", format, - "-f", device, "-o", "gpx", "-F", "-"}; - if (inTracks) { - commands[1] = "-t"; - } - } + String[] commands = getCommandArray(device, format); // Save GPS settings in config Config.setConfigString(Config.KEY_GPS_DEVICE, device); Config.setConfigString(Config.KEY_GPS_FORMAT, format); - String errorMessage = ""; + String errorMessage = "", errorMessage2 = ""; XmlHandler handler = null; Process process = Runtime.getRuntime().exec(commands); + String line = null; - // Pass input stream to try to parse the xml - try + if (_saveFile != null) { - XmlFileLoader xmlLoader = new XmlFileLoader(_app); - SAXParser saxParser = SAXParserFactory.newInstance().newSAXParser(); - saxParser.parse(process.getInputStream(), xmlLoader); - handler = xmlLoader.getHandler(); - if (handler == null) { - errorMessage = "Null handler"; + // data is being saved to file, so need to wait for it to finish + process.waitFor(); + // try to read error message, if any + try { + BufferedReader r = new BufferedReader(new InputStreamReader(process.getErrorStream())); + while ((line = r.readLine()) != null) { + errorMessage += line + "\n"; + } + // Close error stream + try { + r.close(); + } catch (Exception e) {} } + catch (Exception e) {} // couldn't get error message + + // Trigger it to be loaded by app + if (process.exitValue() == 0) + { + SwingUtilities.invokeLater(new Runnable() { + public void run() { + ArrayList fileList = new ArrayList(); + fileList.add(_saveFile); + _app.loadDataFiles(fileList); + } + }); + } + else if (errorMessage.length() > 0) { + throw new Exception(errorMessage); + } + else throw new Exception(I18nManager.getText("error.gpsload.unknown")); } - catch (Exception e) { - errorMessage = e.getMessage(); - } + else + { + // Pass input stream to try to parse the xml + try + { + XmlFileLoader xmlLoader = new XmlFileLoader(_app); + SAXParser saxParser = SAXParserFactory.newInstance().newSAXParser(); + saxParser.parse(process.getInputStream(), xmlLoader); + handler = xmlLoader.getHandler(); + if (handler == null) { + errorMessage = "Null handler"; + } + } + catch (Exception e) { + errorMessage = e.getMessage(); + } - // Read the error stream to see if there's a better error message there - BufferedReader r = new BufferedReader(new InputStreamReader(process.getErrorStream())); - String line = null; - String errorMessage2 = ""; - while ((line = r.readLine()) != null) { - errorMessage2 += line + "\n"; + // Read the error stream to see if there's a better error message there + BufferedReader r = new BufferedReader(new InputStreamReader(process.getErrorStream())); + while ((line = r.readLine()) != null) { + errorMessage2 += line + "\n"; + } + // Close error stream + try { + r.close(); + } catch (Exception e) {} + + if (errorMessage2.length() > 0) {errorMessage = errorMessage2;} + if (errorMessage.length() > 0) {throw new Exception(errorMessage);} + + // Send data back to app + _app.informDataLoaded(handler.getFieldArray(), handler.getDataArray(), Altitude.Format.METRES, + new SourceInfo(_deviceField.getText(), SourceInfo.FILE_TYPE.GPSBABEL)); } - // Close error stream - try { - r.close(); - } catch (Exception e) {} + } - if (errorMessage2.length() > 0) {errorMessage = errorMessage2;} - if (errorMessage.length() > 0) {throw new Exception(errorMessage);} - // Send data back to app - _app.informDataLoaded(handler.getFieldArray(), handler.getDataArray(), - Altitude.Format.METRES, _deviceField.getText()); + /** + * 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) + { + String[] commands = null; + final String command = Config.getConfigString(Config.KEY_GPSBABEL_PATH); + final boolean loadWaypoints = _waypointCheckbox.isSelected(); + 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", "-"}; + } + else + { + // Only waypoints OR track points selected + commands = new String[] {command, "-w", "-i", inFormat, + "-f", inDevice, "-o", "gpx", "-F", "-"}; + if (loadTrack) { + commands[1] = "-t"; + } + } + // Do we want to save the gpx straight to file? + if (_saveCheckbox.isSelected()) { + // Select file to save to + _saveFile = GpxExporter.chooseGpxFile(_parentFrame); + if (_saveFile != null) { + commands[commands.length-1] = _saveFile.getAbsolutePath(); + } + } + return commands; } } diff --git a/tim/prune/load/JpegLoader.java b/tim/prune/load/JpegLoader.java index 194f2b7..08b29fa 100644 --- a/tim/prune/load/JpegLoader.java +++ b/tim/prune/load/JpegLoader.java @@ -17,8 +17,8 @@ import javax.swing.JPanel; import javax.swing.JProgressBar; import tim.prune.App; -import tim.prune.Config; import tim.prune.I18nManager; +import tim.prune.config.Config; import tim.prune.data.Altitude; import tim.prune.data.DataPoint; import tim.prune.data.LatLonRectangle; @@ -103,16 +103,23 @@ public class JpegLoader implements Runnable if (_fileChooser.showOpenDialog(_parentFrame) == JFileChooser.APPROVE_OPTION) { // Bring up dialog before starting - showDialog(); + if (_progressDialog == null) { + createProgressDialog(); + } + // reset dialog and show it + _progressBar.setValue(0); + _progressBar.setString(""); + _progressDialog.setVisible(true); + // start thread for processing new Thread(this).start(); } } /** - * Show the main dialog + * Create the dialog to show the progress */ - private void showDialog() + private void createProgressDialog() { _progressDialog = new JDialog(_parentFrame, I18nManager.getText("dialog.jpegload.progress.title")); _progressDialog.setLocationRelativeTo(_parentFrame); @@ -135,7 +142,6 @@ public class JpegLoader implements Runnable panel.add(cancelButton); _progressDialog.getContentPane().add(panel); _progressDialog.pack(); - _progressDialog.setVisible(true); } @@ -158,6 +164,7 @@ public class JpegLoader implements Runnable // 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 if (_cancelled) {return;} //System.out.println("Finished - counts are: " + _fileCounts[0] + ", " + _fileCounts[1] @@ -201,7 +208,7 @@ public class JpegLoader implements Runnable if (inFiles != null) { // Loop over elements in array - for (int i=0; i 0) { _app.informDataLoaded(getFieldArray(), makeDataArray(messages), - Altitude.Format.METRES, inFile.getName()); + Altitude.Format.METRES, new SourceInfo(inFile, SourceInfo.FILE_TYPE.NMEA)); } } diff --git a/tim/prune/load/TextFileLoader.java b/tim/prune/load/TextFileLoader.java index 64c9eba..f72893d 100644 --- a/tim/prune/load/TextFileLoader.java +++ b/tim/prune/load/TextFileLoader.java @@ -21,6 +21,7 @@ import tim.prune.App; import tim.prune.I18nManager; import tim.prune.data.Altitude; import tim.prune.data.Field; +import tim.prune.data.SourceInfo; /** @@ -527,9 +528,9 @@ public class TextFileLoader } _lastAltitudeFormat = altitudeFormat; // give data to App + SourceInfo sourceInfo = new SourceInfo(_file, SourceInfo.FILE_TYPE.TEXT); _app.informDataLoaded(_fieldTableModel.getFieldArray(), - _fileExtractTableModel.getData(), altitudeFormat, - _file.getName()); + _fileExtractTableModel.getData(), altitudeFormat, sourceInfo); // clear up file cacher _fileCacher.clear(); // dispose of dialog diff --git a/tim/prune/load/xml/GpxHandler.java b/tim/prune/load/xml/GpxHandler.java index 8ab3e17..b4ae07a 100644 --- a/tim/prune/load/xml/GpxHandler.java +++ b/tim/prune/load/xml/GpxHandler.java @@ -17,16 +17,14 @@ public class GpxHandler extends XmlHandler private boolean _insideName = false; private boolean _insideElevation = false; private boolean _insideTime = false; -// private boolean _insideType = false; + private boolean _insideType = false; private boolean _startSegment = true; private String _name = null, _latitude = null, _longitude = null; private String _elevation = null; private String _time = null; -// private String _type = null; + private String _type = null; private ArrayList _pointList = new ArrayList(); - // FIXME: Read waypoint type too - /** * Receive the start of a tag * @see org.xml.sax.ContentHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes) @@ -35,7 +33,7 @@ public class GpxHandler extends XmlHandler Attributes attributes) throws SAXException { // Read the parameters for waypoints and track points - if (qName.equalsIgnoreCase("wpt") || qName.equalsIgnoreCase("trkpt")) + if (qName.equalsIgnoreCase("wpt") || qName.equalsIgnoreCase("trkpt") || qName.equalsIgnoreCase("rtept")) { _insideWaypoint = qName.equalsIgnoreCase("wpt"); int numAttributes = attributes.getLength(); @@ -48,6 +46,7 @@ public class GpxHandler extends XmlHandler _elevation = null; _name = null; _time = null; + _type = null; } else if (qName.equalsIgnoreCase("ele")) { @@ -61,10 +60,10 @@ public class GpxHandler extends XmlHandler { _insideTime = true; } -// else if (qName.equalsIgnoreCase("type")) -// { -// _insideType = true; -// } + else if (qName.equalsIgnoreCase("type")) + { + _insideType = true; + } else if (qName.equalsIgnoreCase("trkseg")) { _startSegment = true; @@ -80,7 +79,7 @@ public class GpxHandler extends XmlHandler public void endElement(String uri, String localName, String qName) throws SAXException { - if (qName.equalsIgnoreCase("wpt") || qName.equalsIgnoreCase("trkpt")) + if (qName.equalsIgnoreCase("wpt") || qName.equalsIgnoreCase("trkpt") || qName.equalsIgnoreCase("rtept")) { processPoint(); } @@ -96,6 +95,10 @@ public class GpxHandler extends XmlHandler { _insideTime = false; } + else if (qName.equalsIgnoreCase("type")) + { + _insideType = false; + } super.endElement(uri, localName, qName); } @@ -111,6 +114,7 @@ public class GpxHandler extends XmlHandler if (_insideName && _insideWaypoint) {_name = checkCharacters(_name, value);} else if (_insideElevation) {_elevation = checkCharacters(_elevation, value);} else if (_insideTime) {_time = checkCharacters(_time, value);} + else if (_insideType) {_type = checkCharacters(_type, value);} super.characters(ch, start, length); } @@ -134,7 +138,7 @@ public class GpxHandler extends XmlHandler private void processPoint() { // Put the values into a String array matching the order in getFieldArray() - String[] values = new String[6]; + String[] values = new String[7]; values[0] = _latitude; values[1] = _longitude; values[2] = _elevation; values[3] = _name; values[4] = _time; @@ -142,6 +146,7 @@ public class GpxHandler extends XmlHandler values[5] = "1"; _startSegment = false; } + values[6] = _type; _pointList.add(values); } @@ -152,7 +157,7 @@ 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_NAME, Field.TIMESTAMP, Field.NEW_SEGMENT, Field.WAYPT_TYPE}; return fields; } diff --git a/tim/prune/load/xml/GzipFileLoader.java b/tim/prune/load/xml/GzipFileLoader.java new file mode 100644 index 0000000..e21e984 --- /dev/null +++ b/tim/prune/load/xml/GzipFileLoader.java @@ -0,0 +1,73 @@ +package tim.prune.load.xml; + +import java.io.File; +import java.io.FileInputStream; +import java.util.zip.GZIPInputStream; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; +import tim.prune.App; +import tim.prune.I18nManager; +import tim.prune.data.Altitude; +import tim.prune.data.SourceInfo; + +/** + * Class to handle the loading of gzipped xml files + */ +public class GzipFileLoader +{ + /** App for callback of file loading */ + private App _app = null; + /** Object to do the handling of the xml */ + XmlFileLoader _xmlLoader = null; + + /** + * Constructor + * @param inApp App object + * @param inXmlLoader object to do the xml handling + */ + public GzipFileLoader(App inApp, XmlFileLoader inXmlLoader) + { + _app = inApp; + _xmlLoader = inXmlLoader; + } + + /** + * Open the selected file and select appropriate xml loader + * @param inFile File to open + */ + public void openFile(File inFile) + { + GZIPInputStream istream = null; + try + { + istream = new GZIPInputStream(new FileInputStream(inFile)); + _xmlLoader.reset(); + SAXParser saxParser = SAXParserFactory.newInstance().newSAXParser(); + saxParser.parse(istream, _xmlLoader); + XmlHandler handler = _xmlLoader.getHandler(); + if (handler == null) { + _app.showErrorMessage("error.load.dialogtitle", "error.load.noread"); + } + 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); + } + } + 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()); + // It would be nice to verify the filename of the file inside the gz, + // but the java classes don't give access to this information + } + finally { + try { + istream.close(); + } + catch (Exception e2) {} + } + } +} diff --git a/tim/prune/load/xml/XmlFileLoader.java b/tim/prune/load/xml/XmlFileLoader.java index 3f1b2eb..7fa5ec1 100644 --- a/tim/prune/load/xml/XmlFileLoader.java +++ b/tim/prune/load/xml/XmlFileLoader.java @@ -10,6 +10,7 @@ import org.xml.sax.helpers.DefaultHandler; import tim.prune.App; import tim.prune.I18nManager; import tim.prune.data.Altitude; +import tim.prune.data.SourceInfo; /** * Class for handling loading of Xml files, and passing the @@ -76,8 +77,10 @@ public class XmlFileLoader extends DefaultHandler implements Runnable else { // Pass information back to app + SourceInfo sourceInfo = new SourceInfo(_file, + (_handler instanceof GpxHandler?SourceInfo.FILE_TYPE.GPX:SourceInfo.FILE_TYPE.KML)); _app.informDataLoaded(_handler.getFieldArray(), _handler.getDataArray(), - Altitude.Format.METRES, _file.getName()); + Altitude.Format.METRES, sourceInfo); } } catch (Exception e) diff --git a/tim/prune/load/xml/ZipFileLoader.java b/tim/prune/load/xml/ZipFileLoader.java index ba9407c..dfeec52 100644 --- a/tim/prune/load/xml/ZipFileLoader.java +++ b/tim/prune/load/xml/ZipFileLoader.java @@ -12,6 +12,7 @@ import javax.xml.parsers.SAXParserFactory; import tim.prune.App; import tim.prune.data.Altitude; +import tim.prune.data.SourceInfo; /** * Class to handle the loading of zipped xml files @@ -63,8 +64,10 @@ public class ZipFileLoader } 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, inFile.getName()); + Altitude.Format.METRES, sourceInfo); xmlFound = true; } } @@ -110,7 +113,7 @@ public class ZipFileLoader else { // Send back to app _app.informDataLoaded(handler.getFieldArray(), handler.getDataArray(), - Altitude.Format.METRES, "gpsies"); + Altitude.Format.METRES, new SourceInfo("gpsies", SourceInfo.FILE_TYPE.GPSIES)); xmlFound = true; } } diff --git a/tim/prune/readme.txt b/tim/prune/readme.txt index 51d9cc7..8108b00 100644 --- a/tim/prune/readme.txt +++ b/tim/prune/readme.txt @@ -1,11 +1,11 @@ -Prune version 8 +Prune version 9 =============== Prune is an application for viewing, editing and managing coordinate data from GPS systems, including format conversion, charting and photo correlation. Full details can be found at http://activityworkshop.net/software/prune/ -Prune is copyright activityworkshop.net and distributed under the terms of the Gnu GPL version 2. +Prune is copyright 2006-2010 activityworkshop.net and distributed under the terms of the Gnu GPL version 2. You may freely use the software, and may help others to freely use it too. For further information on your rights and how they are protected, see the included license.txt file. @@ -17,7 +17,7 @@ Running ======= To run Prune from the jar file, simply call it from a command prompt or shell: - java -jar prune_08.jar + java -jar prune_09.jar If the jar file is saved in a different directory, you will need to include the path. Depending on your system settings, you may be able to click or double-click on the jar file @@ -25,7 +25,21 @@ in a file manager window to execute it. A shortcut, menu item, alias, desktop i or other link can of course be made should you wish. To specify a language other than the default, use an additional parameter, eg: - java -jar prune_08.jar --lang=DE + java -jar prune_09.jar --lang=DE + +New with version 9 +================== + +The following features were added since version 8: + - Ability to paste coordinates (eg from wikipedia or geocaching sites) to create new points + - Configurable colour settings + - Function to convert waypoint names into timestamps + - Function to reorganise and sort photos either by filename or time + - Ability to load gzipped xml files + - New "full range details" dialog including pace and average gradient + - Preservation of unrecognised gpx tags by copying source xml + - Improved photo handling and ability to rotate photos + - Japanese, Portuguese and Turkish languages thanks to generous user input New with version 8 ================== @@ -119,6 +133,16 @@ The following features were added since version 1: - Waypoint list - Spanish language +Features of version 1 +===================== + +The following features were included in version 1: + - Loading of text files, display in overhead and profile views + - Display of track details such as distances, speeds + - Deletion of points and ranges, and variable compression + - Export to KML format + - English, German and Swiss German languages + Further information and updates =============================== diff --git a/tim/prune/save/ExifSaver.java b/tim/prune/save/ExifSaver.java index f8e04de..986a07e 100644 --- a/tim/prune/save/ExifSaver.java +++ b/tim/prune/save/ExifSaver.java @@ -19,10 +19,10 @@ import javax.swing.JProgressBar; import javax.swing.JScrollPane; import javax.swing.JTable; -import tim.prune.Config; import tim.prune.ExternalTools; import tim.prune.I18nManager; import tim.prune.UpdateMessageBroker; +import tim.prune.config.Config; import tim.prune.data.Altitude; import tim.prune.data.Coordinate; import tim.prune.data.DataPoint; @@ -38,6 +38,7 @@ public class ExifSaver implements Runnable private JDialog _dialog = null; private JButton _okButton = null; private JCheckBox _overwriteCheckbox = null; + private JCheckBox _forceCheckbox = null; private JProgressBar _progressBar = null; private PhotoTableModel _photoTableModel = null; private boolean _saveCancelled = false; @@ -139,9 +140,16 @@ public class ExifSaver implements Runnable JScrollPane scrollPane = new JScrollPane(photoTable); scrollPane.setPreferredSize(new Dimension(300, 160)); tablePanel.add(scrollPane, BorderLayout.CENTER); + // Pair of checkboxes + JPanel checkPanel = new JPanel(); + checkPanel.setLayout(new BoxLayout(checkPanel, BoxLayout.Y_AXIS)); _overwriteCheckbox = new JCheckBox(I18nManager.getText("dialog.saveexif.overwrite")); _overwriteCheckbox.setSelected(false); - tablePanel.add(_overwriteCheckbox, BorderLayout.SOUTH); + checkPanel.add(_overwriteCheckbox); + _forceCheckbox = new JCheckBox(I18nManager.getText("dialog.saveexif.force")); + _forceCheckbox.setSelected(false); + checkPanel.add(_forceCheckbox); + tablePanel.add(checkPanel, BorderLayout.SOUTH); centrePanel.add(tablePanel, BorderLayout.CENTER); // progress bar below main controls _progressBar = new JProgressBar(0, 100); @@ -223,7 +231,7 @@ public class ExifSaver implements Runnable _progressBar.setValue(0); _progressBar.setVisible(true); boolean overwriteFlag = _overwriteCheckbox.isSelected(); - int numSaved = 0; + int numSaved = 0, numFailed = 0, numForced = 0; // Loop over all photos in list for (int i=0; i 0) + { + JOptionPane.showMessageDialog(_parentFrame, + I18nManager.getText("error.saveexif.failed1") + " " + numFailed + " " + + I18nManager.getText("error.saveexif.failed2"), + I18nManager.getText("dialog.saveexif.title"), JOptionPane.ERROR_MESSAGE); + } + if (numForced > 0) + { + JOptionPane.showMessageDialog(_parentFrame, + I18nManager.getText("error.saveexif.forced1") + " " + numForced + " " + + I18nManager.getText("error.saveexif.forced2"), + I18nManager.getText("dialog.saveexif.title"), JOptionPane.WARNING_MESSAGE); + } // close dialog, all finished _dialog.dispose(); } @@ -257,9 +287,10 @@ public class ExifSaver implements Runnable * Save the details for the given photo * @param inPhoto Photo object * @param inOverwriteFlag true to overwrite file, false otherwise + * @param inForceFlag true to force write, ignoring minor errors * @return true if details saved ok */ - private boolean savePhoto(Photo inPhoto, boolean inOverwriteFlag) + private boolean savePhoto(Photo inPhoto, boolean inOverwriteFlag, boolean inForceFlag) { // Check whether photo file still exists if (!inPhoto.getFile().exists()) @@ -299,9 +330,10 @@ public class ExifSaver implements Runnable else { // Photo is now connected, so write new gps tags - command = getWriteGpsExifTagsCommand(inPhoto.getFile(), inPhoto.getDataPoint(), inOverwriteFlag); + command = getWriteGpsExifTagsCommand(inPhoto.getFile(), inPhoto.getDataPoint(), inOverwriteFlag, inForceFlag); } // Execute exif command + boolean saved = false; try { Process process = Runtime.getRuntime().exec(command); @@ -310,15 +342,15 @@ public class ExifSaver implements Runnable process.waitFor(); } catch (InterruptedException ie) {} + saved = (process.exitValue() == 0); } catch (Exception e) { // show error message JOptionPane.showMessageDialog(_parentFrame, "Exception: '" + e.getClass().getName() + "' : " + e.getMessage(), I18nManager.getText("dialog.saveexif.title"), JOptionPane.ERROR_MESSAGE); - return false; } - return true; + return saved; } @@ -348,16 +380,22 @@ public class ExifSaver implements Runnable * @param inFile file to which to write the tags * @param inPoint DataPoint object containing coordinate information * @param inOverwrite true to overwrite file, false to create copy + * @param inForce true to force write, ignoring minor errors * @return external command to write gps tags */ - private static String[] getWriteGpsExifTagsCommand(File inFile, DataPoint inPoint, boolean inOverwrite) + private static String[] getWriteGpsExifTagsCommand(File inFile, DataPoint inPoint, + boolean inOverwrite, boolean inForce) { // Make a string array to construct the command and its parameters - String[] result = new String[inOverwrite?10:9]; + String[] result = new String[(inOverwrite?10:9) + (inForce?1:0)]; result[0] = Config.getConfigString(Config.KEY_EXIFTOOL_PATH); result[1] = "-P"; if (inOverwrite) {result[2] = "-overwrite_original_in_place";} int paramOffset = inOverwrite?3:2; + if (inForce) { + result[paramOffset] = "-m"; + paramOffset++; + } // To set latitude : -GPSLatitude='12 34 56.78' -GPSLatitudeRef='N' // (latitude as space-separated deg min sec, reference as either N or S) result[paramOffset] = "-GPSLatitude='" + inPoint.getLatitude().output(Coordinate.FORMAT_DEG_MIN_SEC_WITH_SPACES) diff --git a/tim/prune/save/FileSaver.java b/tim/prune/save/FileSaver.java index 3ea60db..6381014 100644 --- a/tim/prune/save/FileSaver.java +++ b/tim/prune/save/FileSaver.java @@ -32,9 +32,9 @@ import javax.swing.ListSelectionModel; import javax.swing.table.TableModel; import tim.prune.App; -import tim.prune.Config; import tim.prune.I18nManager; import tim.prune.UpdateMessageBroker; +import tim.prune.config.Config; import tim.prune.data.Altitude; import tim.prune.data.Coordinate; import tim.prune.data.DataPoint; @@ -47,13 +47,12 @@ import tim.prune.load.OneCharDocument; /** * Class to manage the saving of track data - * into a user-specified file + * as text into a user-specified file */ public class FileSaver { private App _app = null; private JFrame _parentFrame = null; - private Track _track = null; private JDialog _dialog = null; private JFileChooser _fileChooser = null; private JPanel _cards = null; @@ -80,13 +79,11 @@ public class FileSaver * Constructor * @param inApp application object to inform of success * @param inParentFrame parent frame - * @param inTrack track object to save */ - public FileSaver(App inApp, JFrame inParentFrame, Track inTrack) + public FileSaver(App inApp, JFrame inParentFrame) { _app = inApp; _parentFrame = inParentFrame; - _track = inTrack; } @@ -104,13 +101,14 @@ public class FileSaver _dialog.pack(); } // Check field list - FieldList fieldList = _track.getFieldList(); + Track track = _app.getTrackInfo().getTrack(); + FieldList fieldList = track.getFieldList(); int numFields = fieldList.getNumFields(); _model = new FieldSelectionTableModel(numFields); for (int i=0; i=selStart && p<=selEnd)); + if (!savePoint) {continue;} + numSaved++; + firstField = true; + buffer = new StringBuffer(); + for (int f=0; f'); + } + if (inTagName.equalsIgnoreCase("wpt") || inTagName.equalsIgnoreCase("trkpt") + || inTagName.equalsIgnoreCase("rtept")) + { + _strings[_pointNum] = _builder.toString(); + _pointNum++; + _insidePoint = false; + } + super.endElement(inUri, inLocalName, inTagName); + } + + + /** + * Append the current tag to the supplied StringBuilder + * @param inBuilder Stringbuilder object to append tag to + * @param inTagName name of tag + * @param inAttributes attributes of tag + */ + private static void appendTag(StringBuilder inBuilder, String inTagName, Attributes inAttributes) + { + inBuilder.append('<').append(inTagName); + int numAtts = inAttributes.getLength(); + for (int i=0; i'); + } + + + /** + * @return the header string from the GPX tag + */ + public String getHeaderString() + { + return _headerString; + } + + /** + * Get the source string for the given point + * @param inPoint point to retrieve + * @return string if found, otherwise null + */ + public String getSourceString(DataPoint inPoint) + { + int index = _sourceInfo.getIndex(inPoint); + if (index >= 0) { + return _strings[index]; + } + return null; + } + + /** + * Get an inputstream of a GPX file inside a zip + * @param inFile File object describing zip file + * @return input stream for Xml parser + */ + private static InputStream getZipInputStream(File inFile) + { + try + { + ZipInputStream zis = new ZipInputStream(new FileInputStream(inFile)); + while (zis.available() > 0) + { + ZipEntry entry = zis.getNextEntry(); + String entryName = entry.toString(); + if (entryName != null && entryName.length() > 4) + { + String suffix = entryName.substring(entryName.length()-4).toLowerCase(); + if (suffix.equals(".gpx") || suffix.equals(".xml")) { + // First matching file so must be gpx + return zis; + } + } + } + } + catch (Exception e) {} // ignore errors + // not found - error! + return null; + } +} diff --git a/tim/prune/save/GpxCacherList.java b/tim/prune/save/GpxCacherList.java new file mode 100644 index 0000000..126c22d --- /dev/null +++ b/tim/prune/save/GpxCacherList.java @@ -0,0 +1,68 @@ +package tim.prune.save; + +import tim.prune.data.DataPoint; +import tim.prune.data.FileInfo; +import tim.prune.data.SourceInfo; + +/** + * Class to hold a list of GpxCacher objects + * and get the original source xml for data points + */ +public class GpxCacherList +{ + /** Array of Gpx Cachers */ + private GpxCacher[] _cacherList = null; + + /** + * Constructor + * @param inInfo file info object + */ + public GpxCacherList(FileInfo inInfo) + { + int numFiles = inInfo.getNumFiles(); + _cacherList = new GpxCacher[numFiles]; + for (int i=0; i\n\n"); + // Instantiate source file cachers in case we want to copy output + GpxCacherList gpxCachers = null; + if (inUseCopy) gpxCachers = new GpxCacherList(inInfo.getFileInfo()); + // Write or copy header + inWriter.write(getHeaderString(gpxCachers)); // Name field String trackName = "PruneTrack"; if (inName != null && !inName.equals("")) @@ -280,8 +304,7 @@ public class GpxExporter extends GenericFunction implements Runnable if (inDesc != null && !inDesc.equals("")) { inWriter.write(inDesc); } - else - { + else { inWriter.write("Export from Prune"); } inWriter.write("\n"); @@ -292,56 +315,141 @@ public class GpxExporter extends GenericFunction implements Runnable final boolean exportTrackpoints = inSaveFlags[0]; final boolean exportWaypoints = inSaveFlags[1]; final boolean exportPhotos = inSaveFlags[2]; - final boolean exportTimestamps = inSaveFlags[3]; + final boolean exportSelection = inSaveFlags[3]; + final boolean exportTimestamps = inSaveFlags[4]; + // Examine selection + int selStart = -1, selEnd = -1; + if (exportSelection) { + selStart = inInfo.getSelection().getStart(); + selEnd = inInfo.getSelection().getEnd(); + } // Loop over waypoints - final int numPoints = inTrack.getNumPoints(); + final int numPoints = inInfo.getTrack().getNumPoints(); int numSaved = 0; for (i=0; i=selStart && i<=selEnd)) { + // Make a wpt element for each waypoint + if (point.isWaypoint()) { + if (exportWaypoints) + { + String pointSource = (inUseCopy?gpxCachers.getSourceString(point):null); + if (pointSource != null) { + inWriter.write(pointSource); + inWriter.write('\n'); + } + else { + exportWaypoint(point, inWriter, exportTimestamps); + } + numSaved++; + } + } + else { + hasTrackpoints = true; } } - else - { - hasTrackpoints = true; - } } - // Output the track, if there is one - if (hasTrackpoints) + // Export both route points and then track points + if (hasTrackpoints && (exportTrackpoints || exportPhotos)) + { + // Output all route points (if any) + numSaved += writeTrackPoints(inWriter, inInfo, exportSelection, exportTrackpoints, exportPhotos, + exportTimestamps, true, gpxCachers, "1\n", null, "\t\n"); + // Output all track points, if any + String trackStart = "\t" + trackName + "1\n"; + numSaved += writeTrackPoints(inWriter, inInfo, exportSelection, exportTrackpoints, exportPhotos, + exportTimestamps, false, gpxCachers, "\n\t\n", + "\t\n"); + } + + inWriter.write("\n"); + return numSaved; + } + + /** + * Loop through the track outputting the relevant track points + * @param inWriter writer object for output + * @param inInfo track info object containing track + * @param inExportSelection true to just output current selection + * @param inExportTrackpoints true to output track points + * @param inExportPhotos true to output photo points + * @param exportTimestamps true to include timestamps in export + * @param inOnlyCopies true to only export if source can be copied + * @param inCachers list of GpxCachers + * @param inPointTag tag to match for each point + * @param inStartTag start tag to output + * @param inSegmentTag tag to output between segments (or null) + * @param inEndTag end tag to output + */ + private static int writeTrackPoints(OutputStreamWriter inWriter, + TrackInfo inInfo, boolean inExportSelection, boolean inExportTrackpoints, + boolean inExportPhotos, boolean exportTimestamps, boolean inOnlyCopies, + GpxCacherList inCachers, String inPointTag, String inStartTag, + String inSegmentTag, String inEndTag) + throws IOException + { + // Note: far too many input parameters to this method but avoids duplication + // of output functionality for writing track points and route points + int numPoints = inInfo.getTrack().getNumPoints(); + int selStart = inInfo.getSelection().getStart(); + int selEnd = inInfo.getSelection().getEnd(); + int numSaved = 0; + // Loop over track points + for (int i=0; i" + trackName + "1\n"); - // Loop over track points - for (i=0; i=selStart && i<=selEnd)) && !point.isWaypoint()) { - point = inTrack.getPoint(i); - // restart track segment if necessary - if (point.getSegmentStart() && !firstPoint) { - inWriter.write("\t\n\t\n"); - } - if (!point.isWaypoint()) + if ((point.getPhoto()==null && inExportTrackpoints) || (point.getPhoto()!=null && inExportPhotos)) { - if ((point.getPhoto()==null && exportTrackpoints) || (point.getPhoto()!=null && exportPhotos)) + // get the source from the point (if any) + String pointSource = (inCachers!=null?inCachers.getSourceString(point):null); + boolean writePoint = (pointSource != null && pointSource.toLowerCase().startsWith(inPointTag)) + || (pointSource == null && !inOnlyCopies); + if (writePoint) { - // export the point - exportTrackpoint(point, inWriter, exportTimestamps); + // restart track segment if necessary + if ((numSaved > 0) && point.getSegmentStart() && (inSegmentTag != null)) { + inWriter.write(inSegmentTag); + } + if (numSaved == 0) {inWriter.write(inStartTag);} + if (pointSource != null) { + inWriter.write(pointSource); + inWriter.write('\n'); + } + else { + if (!inOnlyCopies) {exportTrackpoint(point, inWriter, exportTimestamps);} + } numSaved++; - firstPoint = false; } } } - inWriter.write("\t\n"); } - inWriter.write("\n"); + if (numSaved > 0) {inWriter.write(inEndTag);} return numSaved; } + /** + * Get the header string for the gpx + * @param inCachers cacher list to ask for headers, if available + * @return header string from cachers or as default + */ + private static String getHeaderString(GpxCacherList inCachers) + { + String gpxHeader = null; + if (inCachers != null) {gpxHeader = inCachers.getFirstHeader();} + if (gpxHeader == null || gpxHeader.length() < 5) + { + // Create default (1.0) header + gpxHeader = "\n"; + } + return "\n" + gpxHeader + "\n"; + } + /** * Export the specified waypoint into the file * @param inPoint waypoint to export @@ -364,10 +472,6 @@ public class GpxExporter extends GenericFunction implements Runnable inWriter.write("" + inPoint.getAltitude().getStringValue(Altitude.Format.METRES)); inWriter.write("\n"); } - // write waypoint name after elevation - inWriter.write("\t\t"); - inWriter.write(inPoint.getWaypointName().trim()); - inWriter.write("\n"); // timestamp if available (point might have timestamp and then be turned into a waypoint) if (inPoint.hasTimestamp() && inTimestamps) { @@ -375,7 +479,22 @@ public class GpxExporter extends GenericFunction implements Runnable inWriter.write(inPoint.getTimestamp().getText(Timestamp.FORMAT_ISO_8601)); inWriter.write("\n"); } - // TODO: Include waypt type in Gpx + // write waypoint name after elevation and time + inWriter.write("\t\t"); + inWriter.write(inPoint.getWaypointName().trim()); + inWriter.write("\n"); + // write waypoint type if any + String type = inPoint.getFieldValue(Field.WAYPT_TYPE); + if (type != null) + { + type = type.trim(); + if (!type.equals("")) + { + inWriter.write("\t\t"); + inWriter.write(type); + inWriter.write("\n"); + } + } inWriter.write("\t\n"); } diff --git a/tim/prune/save/KmlExporter.java b/tim/prune/save/KmlExporter.java index 42ba748..a5a4ee2 100644 --- a/tim/prune/save/KmlExporter.java +++ b/tim/prune/save/KmlExporter.java @@ -1,11 +1,14 @@ package tim.prune.save; import java.awt.BorderLayout; +import java.awt.Color; import java.awt.Component; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; import java.awt.image.BufferedImage; import java.io.File; import java.io.FileOutputStream; @@ -33,22 +36,25 @@ import javax.swing.JTextField; import javax.swing.SwingConstants; import tim.prune.App; -import tim.prune.Config; import tim.prune.GenericFunction; import tim.prune.I18nManager; import tim.prune.UpdateMessageBroker; +import tim.prune.config.ColourUtils; +import tim.prune.config.Config; import tim.prune.data.Altitude; import tim.prune.data.Coordinate; import tim.prune.data.DataPoint; import tim.prune.data.Field; import tim.prune.data.Track; import tim.prune.data.TrackInfo; +import tim.prune.gui.ColourChooser; +import tim.prune.gui.ColourPatch; import tim.prune.gui.ImageUtils; import tim.prune.load.GenericFileFilter; /** * Class to export track information - * into a specified Kml file + * into a specified Kml or Kmz file */ public class KmlExporter extends GenericFunction implements Runnable { @@ -60,21 +66,26 @@ public class KmlExporter extends GenericFunction implements Runnable private JCheckBox _altitudesCheckbox = null; private JCheckBox _kmzCheckbox = null; private JCheckBox _exportImagesCheckbox = null; + private ColourPatch _colourPatch = null; private JLabel _progressLabel = null; private JProgressBar _progressBar = null; + private Dimension[] _imageDimensions = null; private JFileChooser _fileChooser = null; private File _exportFile = null; private JButton _okButton = null; private boolean _cancelPressed = false; + private ColourChooser _colourChooser = null; // Filename of Kml file within zip archive private static final String KML_FILENAME_IN_KMZ = "doc.kml"; // Default width and height of thumbnail images in Kmz private static final int DEFAULT_THUMBNAIL_WIDTH = 240; - private static final int DEFAULT_THUMBNAIL_HEIGHT = 180; + private static final int DEFAULT_THUMBNAIL_HEIGHT = 240; // Actual selected width and height of thumbnail images in Kmz private static int THUMBNAIL_WIDTH = 0; private static int THUMBNAIL_HEIGHT = 0; + // Default track colour + private static final Color DEFAULT_TRACK_COLOUR = new Color(204, 0, 0); // red /** @@ -106,6 +117,7 @@ public class KmlExporter extends GenericFunction implements Runnable _dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); _dialog.getContentPane().add(makeDialogComponents()); _dialog.pack(); + _colourChooser = new ColourChooser(_dialog); } enableCheckboxes(); _descriptionField.setEnabled(true); @@ -139,6 +151,23 @@ public class KmlExporter extends GenericFunction implements Runnable _pointTypeSelector = new PointTypeSelector(); _pointTypeSelector.setAlignmentX(Component.CENTER_ALIGNMENT); mainPanel.add(_pointTypeSelector); + // Colour definition + Color trackColour = ColourUtils.colourFromHex(Config.getConfigString(Config.KEY_KML_TRACK_COLOUR)); + if (trackColour == null) { + trackColour = DEFAULT_TRACK_COLOUR; + } + _colourPatch = new ColourPatch(trackColour); + _colourPatch.addMouseListener(new MouseAdapter() { + public void mouseClicked(MouseEvent e) { + _colourChooser.showDialog(_colourPatch.getBackground()); + Color colour = _colourChooser.getChosenColour(); + if (colour != null) _colourPatch.setColour(colour); + } + }); + JPanel colourPanel = new JPanel(); + colourPanel.add(new JLabel(I18nManager.getText("dialog.exportkml.trackcolour"))); + colourPanel.add(_colourPatch); + mainPanel.add(colourPanel); // Checkbox for altitude export _altitudesCheckbox = new JCheckBox(I18nManager.getText("dialog.exportkml.altitude")); _altitudesCheckbox.setHorizontalTextPosition(SwingConstants.LEFT); @@ -217,6 +246,8 @@ public class KmlExporter extends GenericFunction implements Runnable { // OK pressed, now validate selection checkboxes if (!_pointTypeSelector.getAnythingSelected()) { + JOptionPane.showMessageDialog(_parentFrame, I18nManager.getText("dialog.save.notypesselected"), + I18nManager.getText("dialog.saveoptions.title"), JOptionPane.WARNING_MESSAGE); return; } // Choose output file @@ -230,12 +261,10 @@ public class KmlExporter extends GenericFunction implements Runnable if (configDir != null) {_fileChooser.setCurrentDirectory(new File(configDir));} } String requiredExtension = null, otherExtension = null; - if (_kmzCheckbox.isSelected()) - { + if (_kmzCheckbox.isSelected()) { requiredExtension = ".kmz"; otherExtension = ".kml"; } - else - { + else { requiredExtension = ".kml"; otherExtension = ".kmz"; } _fileChooser.setAcceptAllFileFilterUsed(false); @@ -300,6 +329,8 @@ public class KmlExporter extends GenericFunction implements Runnable if (THUMBNAIL_WIDTH < DEFAULT_THUMBNAIL_WIDTH) {THUMBNAIL_WIDTH = DEFAULT_THUMBNAIL_WIDTH;} THUMBNAIL_HEIGHT = Config.getConfigInt(Config.KEY_KMZ_IMAGE_HEIGHT); if (THUMBNAIL_HEIGHT < DEFAULT_THUMBNAIL_HEIGHT) {THUMBNAIL_HEIGHT = DEFAULT_THUMBNAIL_HEIGHT;} + // Create array for image dimensions in case it's required + _imageDimensions = new Dimension[_track.getNumPoints()]; OutputStreamWriter writer = null; ZipOutputStream zipOutputStream = null; @@ -329,6 +360,8 @@ public class KmlExporter extends GenericFunction implements Runnable } // write file final int numPoints = exportData(writer, exportImages); + // update config with selected track colour + Config.setConfigString(Config.KEY_KML_TRACK_COLOUR, ColourUtils.makeHexCode(_colourPatch.getBackground())); // update progress bar _progressBar.setValue(1); @@ -343,6 +376,7 @@ public class KmlExporter extends GenericFunction implements Runnable // close file writer.close(); + _imageDimensions = null; // Store directory in config for later Config.setConfigString(Config.KEY_TRACK_DIR, _exportFile.getParentFile().getAbsolutePath()); // show confirmation @@ -355,7 +389,6 @@ public class KmlExporter extends GenericFunction implements Runnable } catch (IOException ioe) { - // System.out.println("Exception: " + ioe.getClass().getName() + " - " + ioe.getMessage()); try { if (writer != null) writer.close(); } @@ -381,6 +414,7 @@ public class KmlExporter extends GenericFunction implements Runnable boolean writeTrack = _pointTypeSelector.getTrackpointsSelected(); boolean writeWaypoints = _pointTypeSelector.getWaypointsSelected(); boolean writePhotos = _pointTypeSelector.getPhotopointsSelected(); + boolean justSelection = _pointTypeSelector.getJustSelection(); inWriter.write("\n\n\n"); inWriter.write("\t"); if (_descriptionField != null && _descriptionField.getText() != null && !_descriptionField.getText().equals("")) @@ -393,11 +427,17 @@ public class KmlExporter extends GenericFunction implements Runnable } inWriter.write("\n"); + // Examine selection if required + int selStart = -1, selEnd = -1; + if (justSelection) { + selStart = _trackInfo.getSelection().getStart(); + selEnd = _trackInfo.getSelection().getEnd(); + } + boolean absoluteAltitudes = _altitudesCheckbox.isSelected(); int i = 0; DataPoint point = null; boolean hasTrackpoints = false; - // Loop over waypoints (if any) boolean writtenPhotoHeader = false; final int numPoints = _track.getNumPoints(); int numSaved = 0; @@ -406,10 +446,12 @@ public class KmlExporter extends GenericFunction implements Runnable for (i=0; i=selStart && i<=selEnd); // Make a blob for each waypoint if (point.isWaypoint()) { - if (writeWaypoints) { + if (writeWaypoints && writeCurrentPoint) + { exportWaypoint(point, inWriter, absoluteAltitudes); numSaved++; } @@ -420,7 +462,7 @@ public class KmlExporter extends GenericFunction implements Runnable } // Make a blob with description for each photo // Photos have already been written so picture sizes already known - if (point.getPhoto() != null && writePhotos) + if (point.getPhoto() != null && writePhotos && writeCurrentPoint) { if (!writtenPhotoHeader) { @@ -428,7 +470,7 @@ public class KmlExporter extends GenericFunction implements Runnable writtenPhotoHeader = true; } photoNum++; - exportPhotoPoint(point, inWriter, inExportImages, photoNum, absoluteAltitudes); + exportPhotoPoint(point, inWriter, inExportImages, i, photoNum, absoluteAltitudes); numSaved++; } } @@ -437,7 +479,8 @@ public class KmlExporter extends GenericFunction implements Runnable { // Set up strings for start and end of track segment String trackStart = "\t\n\t\ttrack\n\t\t\n\t\t\n"; if (absoluteAltitudes) { @@ -456,16 +499,20 @@ public class KmlExporter extends GenericFunction implements Runnable for (i=0; i=selStart && i<=selEnd); + if (!point.isWaypoint() && writeCurrentPoint) { - exportTrackpoint(point, inWriter); - numSaved++; - firstTrackpoint = false; + // start new track segment if necessary + if (point.getSegmentStart() && !firstTrackpoint) { + inWriter.write(trackEnd); + inWriter.write(trackStart); + } + if (point.getPhoto() == null) + { + exportTrackpoint(point, inWriter); + numSaved++; + firstTrackpoint = false; + } } } // end segment @@ -475,6 +522,15 @@ public class KmlExporter extends GenericFunction implements Runnable return numSaved; } + /** + * Reverse the hex code for the colours for KML's stupid backwards format + * @param inCode colour code rrggbb + * @return kml code bbggrr + */ + private static String reverse(String inCode) + { + return inCode.substring(4, 6) + inCode.substring(2, 4) + inCode.substring(0, 2); + } /** * Export the specified waypoint into the file @@ -515,12 +571,13 @@ public class KmlExporter extends GenericFunction implements Runnable * @param inPoint data point including photo * @param inWriter writer object * @param inImageLink flag to set whether to export image links or not + * @param inPointNumber number of point for accessing dimensions * @param inImageNumber number of image for filename * @param inAbsoluteAltitude true for absolute altitudes * @throws IOException on write failure */ private void exportPhotoPoint(DataPoint inPoint, Writer inWriter, boolean inImageLink, - int inImageNumber, boolean inAbsoluteAltitude) + int inPointNumber, int inImageNumber, boolean inAbsoluteAltitude) throws IOException { inWriter.write("\t\n\t\t"); @@ -528,13 +585,11 @@ public class KmlExporter extends GenericFunction implements Runnable inWriter.write("\n"); if (inImageLink) { - // Work out image dimensions of thumbnail - Dimension picSize = inPoint.getPhoto().getSize(); - Dimension thumbSize = ImageUtils.getThumbnailSize(picSize.width, picSize.height, THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT); + Dimension imageSize = _imageDimensions[inPointNumber]; // Write out some html for the thumbnail images inWriter.write("" - + "
Caption for the photo
]]>
"); + + inImageNumber + ".jpg' width='" + imageSize.width + "' height='" + imageSize.height + "'>" + + "

" + inPoint.getPhoto().getFile().getName() + "
]]>"); } inWriter.write("#camera_icon\n"); inWriter.write("\t\t\n"); @@ -596,6 +651,14 @@ public class KmlExporter extends GenericFunction implements Runnable } ImageWriter imageWriter = writers.next(); + // Check selection checkbox + boolean justSelection = _pointTypeSelector.getJustSelection(); + int selStart = -1, selEnd = -1; + if (justSelection) { + selStart = _trackInfo.getSelection().getStart(); + selEnd = _trackInfo.getSelection().getEnd(); + } + int numPoints = _track.getNumPoints(); DataPoint point = null; int photoNum = 0; @@ -603,7 +666,7 @@ public class KmlExporter extends GenericFunction implements Runnable for (int i=0; i=selStart && i<=selEnd))) { photoNum++; // Make a new entry in zip file @@ -613,10 +676,10 @@ public class KmlExporter extends GenericFunction implements Runnable ImageIcon icon = new ImageIcon(point.getPhoto().getFile().getAbsolutePath()); // Scale and smooth image to required size - Dimension outputSize = ImageUtils.getThumbnailSize( - point.getPhoto().getWidth(), point.getPhoto().getHeight(), - THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT); - BufferedImage bufferedImage = ImageUtils.createScaledImage(icon.getImage(), outputSize.width, outputSize.height); + BufferedImage bufferedImage = ImageUtils.rotateImage(icon.getImage(), + THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT, point.getPhoto().getRotationDegrees()); + // Store image dimensions so that it doesn't have to be calculated again for the points + _imageDimensions[i] = new Dimension(bufferedImage.getWidth(), bufferedImage.getHeight()); imageWriter.setOutput(ImageIO.createImageOutputStream(inZipStream)); imageWriter.write(bufferedImage); diff --git a/tim/prune/save/PointTypeSelector.java b/tim/prune/save/PointTypeSelector.java index 6dcd1ea..91632b4 100644 --- a/tim/prune/save/PointTypeSelector.java +++ b/tim/prune/save/PointTypeSelector.java @@ -14,12 +14,13 @@ import tim.prune.data.TrackInfo; /** * GUI element to allow the selection of point types for saving, - * including three checkboxes for track points, waypoints, photo points + * including checkboxes for track points, waypoints, photo points + * and also a checkbox for the current selection */ public class PointTypeSelector extends JPanel { - /** Array of three checkboxes */ - private JCheckBox[] _checkboxes = new JCheckBox[3]; + /** Array of checkboxes */ + private JCheckBox[] _checkboxes = new JCheckBox[4]; /** @@ -39,20 +40,21 @@ public class PointTypeSelector extends JPanel private void createComponents() { setLayout(new BorderLayout()); - // Need JLabel to explain what it is + // Need label to explain what it is add(new JLabel(I18nManager.getText("dialog.pointtype.desc")), BorderLayout.NORTH); // panel for the checkboxes JPanel gridPanel = new JPanel(); - gridPanel.setLayout(new GridLayout(1, 3, 15, 3)); + gridPanel.setLayout(new GridLayout(0, 3, 15, 3)); final String[] keys = {"track", "waypoint", "photo"}; for (int i=0; i<3; i++) { _checkboxes[i] = new JCheckBox(I18nManager.getText("dialog.pointtype." + keys[i])); - _checkboxes[i].setEnabled(true); _checkboxes[i].setSelected(true); gridPanel.add(_checkboxes[i]); } add(gridPanel, BorderLayout.CENTER); + _checkboxes[3] = new JCheckBox(I18nManager.getText("dialog.pointtype.selection")); + add(_checkboxes[3], BorderLayout.SOUTH); } /** @@ -77,6 +79,8 @@ public class PointTypeSelector extends JPanel _checkboxes[i].setEnabled(false); } } + _checkboxes[3].setEnabled(inTrackInfo.getSelection().hasRangeSelected()); + _checkboxes[3].setSelected(false); } /** @@ -103,6 +107,14 @@ public class PointTypeSelector extends JPanel return _checkboxes[2].isSelected(); } + /** + * @return true if only the current selection should be saved + */ + public boolean getJustSelection() + { + return _checkboxes[3].isSelected(); + } + /** * @return true if at least one type selected */ diff --git a/tim/prune/save/PovExporter.java b/tim/prune/save/PovExporter.java index 654aac6..1b0edfb 100644 --- a/tim/prune/save/PovExporter.java +++ b/tim/prune/save/PovExporter.java @@ -25,10 +25,10 @@ import javax.swing.JTextField; import javax.swing.SwingConstants; import tim.prune.App; -import tim.prune.Config; import tim.prune.GenericFunction; import tim.prune.I18nManager; import tim.prune.UpdateMessageBroker; +import tim.prune.config.Config; import tim.prune.data.Track; import tim.prune.load.GenericFileFilter; import tim.prune.threedee.LineDialog; diff --git a/tim/prune/undo/UndoConnectPhotoWithClone.java b/tim/prune/undo/UndoConnectPhotoWithClone.java deleted file mode 100644 index 2fb2ca6..0000000 --- a/tim/prune/undo/UndoConnectPhotoWithClone.java +++ /dev/null @@ -1,41 +0,0 @@ -package tim.prune.undo; - -import tim.prune.data.DataPoint; -import tim.prune.data.TrackInfo; - -/** - * Operation to undo the connection of a photo to a point - * where the point had to be cloned - */ -public class UndoConnectPhotoWithClone extends UndoConnectPhoto -{ - /** Additional undo object for removing inserted point */ - private UndoInsert _undoInsert = null; - - - /** - * Constructor - * @param inPoint data point - * @param inFilename filename of photo - * @param inIndex index of cloned point - */ - public UndoConnectPhotoWithClone(DataPoint inPoint, String inFilename, int inIndex) - { - super(inPoint, inFilename); - // Make an undo object for the insert - _undoInsert = new UndoInsert(inIndex, 1); - } - - /** - * Perform the undo operation on the given Track - * @param inTrackInfo TrackInfo object on which to perform the operation - */ - public void performUndo(TrackInfo inTrackInfo) throws UndoException - { - //System.out.println("Performing undo: (" + super.getDescription() + ", " + _undoInsert.getDescription() + ")"); - // Firstly, undo connect - super.performUndo(inTrackInfo); - // Next, undo insert to remove cloned point - _undoInsert.performUndo(inTrackInfo); - } -} diff --git a/tim/prune/undo/UndoConvertNamesToTimes.java b/tim/prune/undo/UndoConvertNamesToTimes.java new file mode 100644 index 0000000..dc0ffbe --- /dev/null +++ b/tim/prune/undo/UndoConvertNamesToTimes.java @@ -0,0 +1,81 @@ +package tim.prune.undo; + +import tim.prune.I18nManager; +import tim.prune.UpdateMessageBroker; +import tim.prune.data.DataPoint; +import tim.prune.data.Field; +import tim.prune.data.Track; +import tim.prune.data.TrackInfo; + +/** + * Operation to undo a conversion from names to times + */ +public class UndoConvertNamesToTimes implements UndoOperation +{ + /** Start and end indices of section */ + private int _startIndex, _endIndex; + /** Waypoint names before operation */ + private String[] _waypointNames = null; + /** Timestamp strings before operation */ + private String[] _timestamps = null; + + /** + * Constructor + * @param inTrackInfo track info object to copy values from + */ + public UndoConvertNamesToTimes(TrackInfo inTrackInfo) + { + _startIndex = inTrackInfo.getSelection().getStart(); + _endIndex = inTrackInfo.getSelection().getEnd(); + final int numPoints = _endIndex - _startIndex + 1; + _waypointNames = new String[numPoints]; + _timestamps = new String[numPoints]; + // Loop over points in selection, and copy names and timestamps + for (int i=_startIndex; i<=_endIndex; i++) + { + DataPoint point = inTrackInfo.getTrack().getPoint(i); + if (point.isWaypoint()) + { + _waypointNames[i-_startIndex] = point.getWaypointName(); + _timestamps[i-_startIndex] = point.getFieldValue(Field.TIMESTAMP); + } + } + } + + + /** + * @return description of operation + */ + public String getDescription() + { + return I18nManager.getText("undo.convertnamestotimes"); + } + + + /** + * Perform the undo operation on the given Track + * @param inTrackInfo TrackInfo object on which to perform the operation + */ + public void performUndo(TrackInfo inTrackInfo) throws UndoException + { + // Sanity check + Track track = inTrackInfo.getTrack(); + if (track.getNumPoints() <= _endIndex || _endIndex <= _startIndex) { + throw new UndoException("Cannot undo conversion, track length doesn't match"); + } + // Loop over points in selection and replace names and timestamps + for (int i=_startIndex; i<=_endIndex; i++) + { + String storedName = _waypointNames[i-_startIndex]; + if (storedName != null) + { + // point had a name before the operation, so might have been converted + DataPoint point = track.getPoint(i); + point.setFieldValue(Field.WAYPT_NAME, storedName, true); + point.setFieldValue(Field.TIMESTAMP, _timestamps[i-_startIndex], true); + } + } + track.requestRescale(); + UpdateMessageBroker.informSubscribers(); + } +} diff --git a/tim/prune/undo/UndoCutAndMove.java b/tim/prune/undo/UndoCutAndMove.java index 8f61392..4287bab 100644 --- a/tim/prune/undo/UndoCutAndMove.java +++ b/tim/prune/undo/UndoCutAndMove.java @@ -32,7 +32,6 @@ public class UndoCutAndMove implements UndoOperation */ public UndoCutAndMove(Track inTrack, int inStart, int inEnd, int inMoveTo) { - // System.out.println("Construct undo with params " + inStart + ", "+ inEnd + ", " + inMoveTo); _startIndex = inStart; _endIndex = inEnd; _moveToIndex = inMoveTo; diff --git a/tim/prune/undo/UndoEditPoint.java b/tim/prune/undo/UndoEditPoint.java index 1ee16dc..228795b 100644 --- a/tim/prune/undo/UndoEditPoint.java +++ b/tim/prune/undo/UndoEditPoint.java @@ -49,7 +49,7 @@ public class UndoEditPoint implements UndoOperation public void performUndo(TrackInfo inTrackInfo) throws UndoException { // Restore contents of point into track - if (!inTrackInfo.getTrack().editPoint(_originalPoint, _undoFieldList)) + if (!inTrackInfo.getTrack().editPoint(_originalPoint, _undoFieldList, true)) { // throw exception if failed throw new UndoException(getDescription()); diff --git a/tim/prune/undo/UndoLoad.java b/tim/prune/undo/UndoLoad.java index c9aee48..5c0818f 100644 --- a/tim/prune/undo/UndoLoad.java +++ b/tim/prune/undo/UndoLoad.java @@ -2,6 +2,7 @@ package tim.prune.undo; import tim.prune.I18nManager; import tim.prune.data.DataPoint; +import tim.prune.data.FileInfo; import tim.prune.data.PhotoList; import tim.prune.data.TrackInfo; @@ -13,8 +14,8 @@ public class UndoLoad implements UndoOperation private int _cropIndex = -1; private int _numLoaded = -1; private DataPoint[] _contents = null; - private String _previousFilename = null; private PhotoList _photoList = null; + private FileInfo _oldFileInfo = null; /** @@ -27,7 +28,6 @@ public class UndoLoad implements UndoOperation _cropIndex = inIndex; _numLoaded = inNumLoaded; _contents = null; - _previousFilename = null; } @@ -42,8 +42,7 @@ public class UndoLoad implements UndoOperation _cropIndex = -1; _numLoaded = inNumLoaded; _contents = inOldTrackInfo.getTrack().cloneContents(); - if (inOldTrackInfo.getFileInfo().getNumFiles() == 1) - _previousFilename = inOldTrackInfo.getFileInfo().getFilename(); + _oldFileInfo = inOldTrackInfo.getFileInfo().clone(); _photoList = inPhotoList; } @@ -66,11 +65,12 @@ public class UndoLoad implements UndoOperation */ public void performUndo(TrackInfo inTrackInfo) throws UndoException { - // remove file from fileinfo - inTrackInfo.getFileInfo().removeFile(); - if (_previousFilename != null) - { - inTrackInfo.getFileInfo().setFile(_previousFilename); + // remove source from fileinfo + if (_oldFileInfo == null) { + inTrackInfo.getFileInfo().removeSource(); + } + else { + inTrackInfo.setFileInfo(_oldFileInfo); } // Crop / replace if (_contents == null) diff --git a/tim/prune/undo/UndoRearrangePhotos.java b/tim/prune/undo/UndoRearrangePhotos.java new file mode 100644 index 0000000..282611e --- /dev/null +++ b/tim/prune/undo/UndoRearrangePhotos.java @@ -0,0 +1,19 @@ +package tim.prune.undo; + +import tim.prune.data.Track; + +/** + * Operation to undo a photo rearrangement + */ +public class UndoRearrangePhotos extends UndoReorder +{ + /** + * Constructor + * @param inTrack track contents to copy + */ + public UndoRearrangePhotos(Track inTrack) + { + super(inTrack, "undo.rearrangephotos"); + } + +} \ No newline at end of file diff --git a/tim/prune/undo/UndoRearrangeWaypoints.java b/tim/prune/undo/UndoRearrangeWaypoints.java index d48dc2a..5073bfe 100644 --- a/tim/prune/undo/UndoRearrangeWaypoints.java +++ b/tim/prune/undo/UndoRearrangeWaypoints.java @@ -1,44 +1,19 @@ package tim.prune.undo; -import tim.prune.I18nManager; -import tim.prune.data.DataPoint; import tim.prune.data.Track; -import tim.prune.data.TrackInfo; /** * Operation to undo a waypoint rearrangement */ -public class UndoRearrangeWaypoints implements UndoOperation +public class UndoRearrangeWaypoints extends UndoReorder { - private DataPoint[] _contents = null; - - /** * Constructor * @param inTrack track contents to copy */ public UndoRearrangeWaypoints(Track inTrack) { - _contents = inTrack.cloneContents(); + super(inTrack, "undo.rearrangewaypoints"); } - - /** - * @return description of operation - */ - public String getDescription() - { - return I18nManager.getText("undo.rearrangewaypoints"); - } - - - /** - * Perform the undo operation on the given Track - * @param inTrackInfo TrackInfo object on which to perform the operation - */ - public void performUndo(TrackInfo inTrackInfo) throws UndoException - { - // restore track to previous values - inTrackInfo.getTrack().replaceContents(_contents); - } } \ No newline at end of file diff --git a/tim/prune/undo/UndoReorder.java b/tim/prune/undo/UndoReorder.java new file mode 100644 index 0000000..e1d5539 --- /dev/null +++ b/tim/prune/undo/UndoReorder.java @@ -0,0 +1,46 @@ +package tim.prune.undo; + +import tim.prune.I18nManager; +import tim.prune.data.DataPoint; +import tim.prune.data.Track; +import tim.prune.data.TrackInfo; + +/** + * Abstract operation to undo a reordering by replacing track contents with a shallow copy + */ +public abstract class UndoReorder implements UndoOperation +{ + /** Shallow copy of whole track contents */ + private DataPoint[] _contents = null; + /** Description */ + private String _description = null; + + /** + * Constructor + * @param inTrack track contents to copy + * @param inDescKey description key + */ + public UndoReorder(Track inTrack, String inDescKey) + { + _contents = inTrack.cloneContents(); + _description = I18nManager.getText(inDescKey); + } + + /** + * @return description + */ + public String getDescription() { + return _description; + } + + + /** + * Perform the undo operation on the given Track + * @param inTrackInfo TrackInfo object on which to perform the operation + */ + public void performUndo(TrackInfo inTrackInfo) throws UndoException + { + // restore track to previous values + inTrackInfo.getTrack().replaceContents(_contents); + } +} \ No newline at end of file diff --git a/tim/prune/undo/UndoRotatePhoto.java b/tim/prune/undo/UndoRotatePhoto.java new file mode 100644 index 0000000..495effa --- /dev/null +++ b/tim/prune/undo/UndoRotatePhoto.java @@ -0,0 +1,48 @@ +package tim.prune.undo; + +import tim.prune.I18nManager; +import tim.prune.UpdateMessageBroker; +import tim.prune.data.Photo; +import tim.prune.data.TrackInfo; + +/** + * Operation to undo the rotation of a photo + */ +public class UndoRotatePhoto implements UndoOperation +{ + private Photo _photo = null; + private boolean _rightwards = true; + + + /** + * Constructor + * @param inPhoto photo + * @param inDir true if original operation was rightwards (clockwise) rotation + */ + public UndoRotatePhoto(Photo inPhoto, boolean inDir) + { + _photo = inPhoto; + _rightwards = inDir; + } + + + /** + * @return description of operation including photo name + */ + public String getDescription() + { + return I18nManager.getText("undo.rotatephoto") + " " + _photo.getFile().getName(); + } + + + /** + * Perform the undo operation on the given Track + * @param inTrackInfo TrackInfo object on which to perform the operation + */ + public void performUndo(TrackInfo inTrackInfo) throws UndoException + { + _photo.rotate(!_rightwards); + // inform subscribers + UpdateMessageBroker.informSubscribers(); + } +} \ No newline at end of file -- 2.43.0