Changeset 18287 in josm
- Timestamp:
- 2021-10-19T01:26:15+02:00 (3 years ago)
- Location:
- trunk
- Files:
-
- 3 added
- 24 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/actions/SaveAction.java
r16913 r18287 15 15 import javax.swing.SwingConstants; 16 16 17 import org.openstreetmap.josm.data.gpx.Gpx Data.GpxDataChangeListener;17 import org.openstreetmap.josm.data.gpx.GpxConstants; 18 18 import org.openstreetmap.josm.gui.ExtendedDialog; 19 19 import org.openstreetmap.josm.gui.MainApplication; 20 import org.openstreetmap.josm.gui.layer.AbstractModifiableLayer; 20 21 import org.openstreetmap.josm.gui.layer.GpxLayer; 21 22 import org.openstreetmap.josm.gui.layer.Layer; 22 23 import org.openstreetmap.josm.gui.layer.LayerManager.LayerAddEvent; 23 24 import org.openstreetmap.josm.gui.layer.LayerManager.LayerRemoveEvent; 24 import org.openstreetmap.josm.gui.layer.OsmDataLayer;25 25 import org.openstreetmap.josm.gui.layer.SaveToFile; 26 26 import org.openstreetmap.josm.gui.util.GuiHelper; … … 38 38 39 39 private final PropertyChangeListener updateOnRequireSaveChange = evt -> { 40 if ( OsmDataLayer.REQUIRES_SAVE_TO_DISK_PROP.equals(evt.getPropertyName())) {40 if (AbstractModifiableLayer.REQUIRES_SAVE_TO_DISK_PROP.equals(evt.getPropertyName())) { 41 41 updateEnabledState(); 42 42 } 43 43 }; 44 45 private final GpxDataChangeListener updateOnRequireSaveChangeGpx = evt -> updateEnabledState();46 44 47 45 /** … … 69 67 public void layerAdded(LayerAddEvent e) { 70 68 Layer l = e.getAddedLayer(); 71 if (l instanceof OsmDataLayer) {69 if (l instanceof AbstractModifiableLayer) { 72 70 l.addPropertyChangeListener(updateOnRequireSaveChange); 73 }74 if (l instanceof GpxLayer) {75 ((GpxLayer) l).data.addWeakChangeListener(updateOnRequireSaveChangeGpx);76 71 } 77 72 super.layerAdded(e); … … 81 76 public void layerRemoving(LayerRemoveEvent e) { 82 77 Layer l = e.getRemovedLayer(); 83 if (l instanceof OsmDataLayer) {78 if (l instanceof AbstractModifiableLayer) { 84 79 l.removePropertyChangeListener(updateOnRequireSaveChange); 85 }86 if (l instanceof GpxLayer) {87 ((GpxLayer) l).data.removeChangeListener(updateOnRequireSaveChangeGpx);88 80 } 89 81 super.layerRemoving(e); … … 114 106 115 107 // Ask for overwrite in case of GpxLayer 116 if (f != null && layer instanceof GpxLayer && !Config.getPref().getBoolean("gpx.export.overwrite", false)) { 108 if (f != null 109 && layer instanceof GpxLayer 110 && (((GpxLayer) layer).data == null 111 || !GpxConstants.JOSM_CREATOR_NAME.equals(((GpxLayer) layer).data.creator)) 112 && !Config.getPref().getBoolean("gpx.export.overwrite", false)) { 113 117 114 JPanel p = new JPanel(new GridBagLayout()); 118 JLabel label = new JLabel(tr("File {0} exists. Overwrite?", f.getName())); 115 JLabel label = new JLabel("<html>" 116 + tr("The file \"{0}\" will be modified.<br>Would you like to overwrite the existing file?", f.getName()) 117 + "</html>"); 119 118 label.setHorizontalAlignment(SwingConstants.CENTER); 120 JCheckBox remember = new JCheckBox(tr(" Remember choice"));119 JCheckBox remember = new JCheckBox(tr("Always overwrite GPX files without asking")); 121 120 remember.setHorizontalAlignment(SwingConstants.CENTER); 122 121 p.add(label, GBC.eol().fill(GBC.HORIZONTAL).insets(5, 5, 5, 10)); … … 125 124 MainApplication.getMainFrame(), 126 125 tr("Overwrite"), 127 tr("Overwrite"), tr(" Cancel"))128 .setButtonIcons("save _as", "cancel")126 tr("Overwrite"), tr("Save As..."), tr("Cancel")) 127 .setButtonIcons("save", "save_as", "cancel") 129 128 .setContent(p); 130 if (dialog.showDialog().getValue() != 1) { 129 int val = dialog.showDialog().getValue(); 130 if (val == 1) { 131 Config.getPref().putBoolean("gpx.export.overwrite", remember.isSelected()); 132 } else if (val == 2) { 131 133 f = null; 132 } else if (remember.isSelected()){133 Config.getPref().putBoolean("gpx.export.overwrite", true);134 } else { 135 return null; 134 136 } 135 137 } -
trunk/src/org/openstreetmap/josm/actions/SessionSaveAsAction.java
r18135 r18287 20 20 import java.util.Set; 21 21 import java.util.stream.Collectors; 22 import java.util.stream.Stream; 22 23 23 24 import javax.swing.BorderFactory; … … 33 34 import javax.swing.filechooser.FileFilter; 34 35 36 import org.openstreetmap.josm.data.preferences.BooleanProperty; 35 37 import org.openstreetmap.josm.gui.ExtendedDialog; 36 38 import org.openstreetmap.josm.gui.HelpAwareOptionPane; … … 39 41 import org.openstreetmap.josm.gui.MapFrameListener; 40 42 import org.openstreetmap.josm.gui.Notification; 43 import org.openstreetmap.josm.gui.layer.AbstractModifiableLayer; 41 44 import org.openstreetmap.josm.gui.layer.Layer; 42 45 import org.openstreetmap.josm.gui.util.WindowGeometry; … … 61 64 private transient MultiMap<Layer, Layer> dependencies; 62 65 66 private static final BooleanProperty SAVE_LOCAL_FILES_PROPERTY = new BooleanProperty("session.savelocal", true); 67 63 68 /** 64 69 * Constructs a new {@code SessionSaveAsAction}. … … 158 163 .filter(layer -> exporters.get(layer) != null && exporters.get(layer).shallExport()) 159 164 .collect(Collectors.toList()); 165 166 Stream<Layer> layersToSaveStream = layersOut.stream() 167 .filter(layer -> layer.isSavable() 168 && layer instanceof AbstractModifiableLayer 169 && ((AbstractModifiableLayer) layer).requiresSaveToFile() 170 && exporters.get(layer) != null 171 && !exporters.get(layer).requiresZip()); 172 173 if (SAVE_LOCAL_FILES_PROPERTY.get()) { 174 // individual files must be saved before the session file as the location may change 175 if (layersToSaveStream 176 .map(layer -> SaveAction.getInstance().doSave(layer, true)) 177 .collect(Collectors.toList()) // force evaluation of all elements 178 .contains(false)) { 179 180 new Notification(tr("Not all local files referenced by the session file could be saved." 181 + "<br>Make sure you save them before closing JOSM.")) 182 .setIcon(JOptionPane.WARNING_MESSAGE) 183 .setDuration(Notification.TIME_LONG) 184 .show(); 185 } 186 } else if (layersToSaveStream.anyMatch(l -> true)) { 187 new Notification(tr("Not all local files referenced by the session file are saved yet." 188 + "<br>Make sure you save them before closing JOSM.")) 189 .setIcon(JOptionPane.INFORMATION_MESSAGE) 190 .setDuration(Notification.TIME_LONG) 191 .show(); 192 } 160 193 161 194 int active = -1; … … 251 284 252 285 protected final Component build() { 286 JPanel op = new JPanel(new GridBagLayout()); 253 287 JPanel ip = new JPanel(new GridBagLayout()); 254 288 for (Layer layer : layers) { … … 273 307 final JTabbedPane tabs = new JTabbedPane(); 274 308 tabs.addTab(tr("Layers"), p); 275 return tabs; 309 op.add(tabs, GBC.eol().fill()); 310 JCheckBox chkSaveLocal = new JCheckBox(tr("Save all local files to disk"), SAVE_LOCAL_FILES_PROPERTY.get()); 311 chkSaveLocal.addChangeListener(l -> { 312 SAVE_LOCAL_FILES_PROPERTY.put(chkSaveLocal.isSelected()); 313 }); 314 op.add(chkSaveLocal); 315 return op; 276 316 } 277 317 -
trunk/src/org/openstreetmap/josm/data/gpx/GpxConstants.java
r17333 r18287 99 99 */ 100 100 String META_BOUNDS = META_PREFIX + "bounds"; 101 102 /** 103 * The creator element that will be written when exporting a GPX file 104 * @since 18287 105 */ 106 String JOSM_CREATOR_NAME = "JOSM GPX export"; 101 107 102 108 /** -
trunk/src/org/openstreetmap/josm/data/gpx/GpxData.java
r18207 r18287 44 44 * @author Raphael Mack <ramack@raphael-mack.de> 45 45 */ 46 public class GpxData extends WithAttributes implements Data {46 public class GpxData extends WithAttributes implements Data, IGpxLayerPrefs { 47 47 48 48 /** … … 68 68 */ 69 69 public boolean fromServer; 70 /** 71 * A boolean flag indicating if the data was read from a session file. 72 * @since 18287 73 */ 74 public boolean fromSession; 70 75 71 76 /** … … 1017 1022 } 1018 1023 1019 /** 1020 * The layer specific prefs formerly saved in the preferences, e.g. drawing options. 1021 * NOT the track specific settings (e.g. color, width) 1022 * @return Modifiable map 1023 * @since 15496 1024 */ 1024 @Override 1025 1025 public Map<String, String> getLayerPrefs() { 1026 1026 return layerPrefs; … … 1137 1137 } else { 1138 1138 if (setModified) { 1139 modified = true;1139 setModified(true); 1140 1140 } 1141 1141 if (listeners.hasListeners()) { … … 1179 1179 */ 1180 1180 void gpxDataChanged(GpxDataChangeEvent e); 1181 1182 /** 1183 * Called when the modified state of the data changed 1184 * @param modified the new modified state 1185 */ 1186 default void modifiedStateChanged(boolean modified) { 1187 // Override if needed 1188 } 1181 1189 } 1182 1190 … … 1217 1225 * @since 15496 1218 1226 */ 1227 @Override 1219 1228 public void setModified(boolean value) { 1220 modified = value; 1229 if (!initializing && modified != value) { 1230 modified = value; 1231 if (listeners.hasListeners()) { 1232 listeners.fireEvent(l -> l.modifiedStateChanged(modified)); 1233 } 1234 } 1221 1235 } 1222 1236 -
trunk/src/org/openstreetmap/josm/gui/MainFrame.java
r17730 r18287 26 26 27 27 import org.openstreetmap.josm.data.UserIdentityManager; 28 import org.openstreetmap.josm.gui.layer.AbstractModifiableLayer; 28 29 import org.openstreetmap.josm.gui.layer.LayerManager.LayerAddEvent; 29 30 import org.openstreetmap.josm.gui.layer.LayerManager.LayerChangeListener; … … 46 47 47 48 private final transient PropertyChangeListener updateTitleOnSaveChange = evt -> { 48 if (evt.getPropertyName().equals( OsmDataLayer.REQUIRES_SAVE_TO_DISK_PROP)49 if (evt.getPropertyName().equals(AbstractModifiableLayer.REQUIRES_SAVE_TO_DISK_PROP) 49 50 || evt.getPropertyName().equals(OsmDataLayer.REQUIRES_UPLOAD_TO_SERVER_PROP)) { 50 OsmDataLayer layer = (OsmDataLayer) evt.getSource();51 AbstractModifiableLayer layer = (AbstractModifiableLayer) evt.getSource(); 51 52 onLayerChange(layer); 52 53 } … … 187 188 } 188 189 189 private void onLayerChange( OsmDataLayer layer) {190 private void onLayerChange(AbstractModifiableLayer layer) { 190 191 if (layer == MainApplication.getLayerManager().getEditLayer()) { 191 192 refreshTitle(); -
trunk/src/org/openstreetmap/josm/gui/io/importexport/GpxImporter.java
r16877 r18287 148 148 if (data.gpxLayer != null) { 149 149 MainApplication.getLayerManager().addLayer(data.gpxLayer); 150 MainApplication.getLayerManager().setActiveLayer(data.gpxLayer); 150 151 } 151 152 data.postLayerTask.run(); -
trunk/src/org/openstreetmap/josm/gui/layer/AbstractModifiableLayer.java
r16553 r18287 16 16 */ 17 17 public abstract class AbstractModifiableLayer extends Layer implements DownloadFromServer, UploadToServer, SaveToFile, Lockable { 18 19 /** 20 * Property used to know if this layer has to be saved on disk. 21 * @since 18287 22 */ 23 public static final String REQUIRES_SAVE_TO_DISK_PROP = AbstractModifiableLayer.class.getName() + ".requiresSaveToDisk"; 24 static final String IS_DIRTY_SYMBOL = "*"; 18 25 19 26 /** … … 53 60 // Override if needed 54 61 return false; 62 } 63 64 /** 65 * Determines if this layer is "dirty", i.e. requires save or upload 66 * @return if this layer is "dirty" 67 * @since 18287 68 */ 69 public boolean isDirty() { 70 // Override if needed 71 return requiresSaveToFile() || (requiresUploadToServer() && !isUploadDiscouraged()); 55 72 } 56 73 -
trunk/src/org/openstreetmap/josm/gui/layer/GpxLayer.java
r18078 r18287 34 34 import org.openstreetmap.josm.data.gpx.GpxConstants; 35 35 import org.openstreetmap.josm.data.gpx.GpxData; 36 import org.openstreetmap.josm.data.gpx.GpxData.GpxDataChangeEvent; 37 import org.openstreetmap.josm.data.gpx.GpxData.GpxDataChangeListener; 36 38 import org.openstreetmap.josm.data.gpx.GpxDataContainer; 37 import org.openstreetmap.josm.data.gpx.GpxData.GpxDataChangeListener;38 39 import org.openstreetmap.josm.data.gpx.IGpxTrack; 39 40 import org.openstreetmap.josm.data.gpx.IGpxTrackSegment; … … 59 60 import org.openstreetmap.josm.gui.layer.markerlayer.MarkerLayer; 60 61 import org.openstreetmap.josm.gui.preferences.display.GPXSettingsPanel; 62 import org.openstreetmap.josm.gui.util.GuiHelper; 61 63 import org.openstreetmap.josm.gui.widgets.HtmlPanel; 62 64 import org.openstreetmap.josm.tools.ImageProvider; … … 86 88 * Added as field to be kept as reference. 87 89 */ 88 private final GpxDataChangeListener dataChangeListener = e -> this.invalidate(); 90 private final GpxDataChangeListener dataChangeListener = new GpxDataChangeListener() { 91 @Override 92 public void gpxDataChanged(GpxDataChangeEvent e) { 93 invalidate(); 94 } 95 96 @Override 97 public void modifiedStateChanged(boolean modified) { 98 GuiHelper.runInEDT(() -> propertyChangeSupport.firePropertyChange(REQUIRES_SAVE_TO_DISK_PROP, !modified, modified)); 99 } 100 }; 89 101 /** 90 102 * The MarkerLayer imported from the same file. … … 376 388 377 389 @Override 390 public String getLabel() { 391 return isDirty() ? super.getLabel() + ' ' + IS_DIRTY_SYMBOL : super.getLabel(); 392 } 393 394 @Override 378 395 public void visitBoundingBox(BoundingXYVisitor v) { 379 396 if (data != null) { … … 555 572 @Override 556 573 public boolean requiresSaveToFile() { 557 return isModified() && isLocalFile();574 return data != null && isModified() && (isLocalFile() || data.fromSession); 558 575 } 559 576 … … 622 639 @Override 623 640 public synchronized void destroy() { 641 if (linkedMarkerLayer != null && MainApplication.getLayerManager().containsLayer(linkedMarkerLayer)) { 642 linkedMarkerLayer.data.transferLayerPrefs(data.getLayerPrefs()); 643 } 624 644 data.clear(); 625 645 data = null; -
trunk/src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java
r18233 r18287 149 149 // U+2205 EMPTY SET 150 150 private static final String IS_EMPTY_SYMBOL = "\u2205"; 151 private static final String IS_DIRTY_SYMBOL = "*";152 /** Property used to know if this layer has to be saved on disk */153 public static final String REQUIRES_SAVE_TO_DISK_PROP = OsmDataLayer.class.getName() + ".requiresSaveToDisk";154 151 /** Property used to know if this layer has to be uploaded */ 155 152 public static final String REQUIRES_UPLOAD_TO_SERVER_PROP = OsmDataLayer.class.getName() + ".requiresUploadToServer"; … … 1073 1070 } 1074 1071 1075 /**1076 * Determines if this layer is "dirty", i.e., requires save or upload1077 * @return if this layer is "dirty"1078 * @since 176261079 */1080 public boolean isDirty() {1081 return requiresSaveToFile() || (requiresUploadToServer() && !isUploadDiscouraged());1082 }1083 1084 1072 @Override 1085 1073 public String getLabel() { -
trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/Marker.java
r17047 r18287 190 190 public WayPoint convertToWayPoint() { 191 191 WayPoint wpt = new WayPoint(getCoor()); 192 wpt.setTimeInMillis((long) (time * 1000)); 192 if (time > 0d) { 193 wpt.setTimeInMillis((long) (time * 1000)); 194 } 193 195 if (text != null) { 194 196 wpt.getExtensions().add("josm", "text", text); -
trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/MarkerLayer.java
r17047 r18287 21 21 import java.util.Collection; 22 22 import java.util.Comparator; 23 import java.util.HashMap; 23 24 import java.util.List; 25 import java.util.Map; 24 26 import java.util.Optional; 25 27 … … 38 40 import org.openstreetmap.josm.data.gpx.GpxExtension; 39 41 import org.openstreetmap.josm.data.gpx.GpxLink; 42 import org.openstreetmap.josm.data.gpx.IGpxLayerPrefs; 40 43 import org.openstreetmap.josm.data.gpx.WayPoint; 41 44 import org.openstreetmap.josm.data.osm.visitor.BoundingXYVisitor; … … 57 60 import org.openstreetmap.josm.io.audio.AudioPlayer; 58 61 import org.openstreetmap.josm.spi.preferences.Config; 62 import org.openstreetmap.josm.tools.ColorHelper; 59 63 import org.openstreetmap.josm.tools.ImageProvider; 60 64 import org.openstreetmap.josm.tools.Logging; … … 77 81 * A list of markers. 78 82 */ 79 public final List<Marker>data;83 public final MarkerData data; 80 84 private boolean mousePressed; 81 85 public GpxLayer fromLayer; … … 101 105 super(name); 102 106 this.setAssociatedFile(associatedFile); 103 this.data = new ArrayList<>();107 this.data = new MarkerData(); 104 108 this.fromLayer = fromLayer; 105 109 double firstTime = -1.0; 106 110 String lastLinkedFile = ""; 107 111 112 if (fromLayer == null || fromLayer.data == null) { 113 data.ownLayerPrefs = indata.getLayerPrefs(); 114 } 115 116 String cs = GPXSettingsPanel.tryGetDataPrefLocal(data, "markers.color"); 108 117 Color c = null; 109 String cs = GPXSettingsPanel.tryGetLayerPrefLocal(indata, "markers.color");110 118 if (cs != null) { 111 try { 112 c = Color.decode(cs); 113 } catch (NumberFormatException ex) { 119 c = ColorHelper.html2color(cs); 120 if (c == null) { 114 121 Logging.warn("Could not read marker color: " + cs); 115 122 } … … 460 467 */ 461 468 private boolean isTextOrIconShown() { 462 return Boolean.parseBoolean(GPXSettingsPanel.get LayerPref(fromLayer, "markers.show-text"));469 return Boolean.parseBoolean(GPXSettingsPanel.getDataPref(data, "markers.show-text")); 463 470 } 464 471 … … 476 483 public void setColor(Color color) { 477 484 setPrivateColors(color); 478 if (fromLayer != null) { 479 String cs = null; 480 if (color != null) { 481 cs = String.format("#%02X%02X%02X", color.getRed(), color.getGreen(), color.getBlue()); 482 } 483 GPXSettingsPanel.putLayerPrefLocal(fromLayer, "markers.color", cs); 484 } 485 String cs = null; 486 if (color != null) { 487 cs = ColorHelper.color2html(color); 488 } 489 GPXSettingsPanel.putDataPrefLocal(data, "markers.color", cs); 485 490 invalidate(); 486 491 } … … 534 539 @Override 535 540 public void actionPerformed(ActionEvent e) { 536 GPXSettingsPanel.put LayerPrefLocal(layer.fromLayer, "markers.show-text", Boolean.toString(!layer.isTextOrIconShown()));541 GPXSettingsPanel.putDataPrefLocal(layer.data, "markers.show-text", Boolean.toString(!layer.isTextOrIconShown())); 537 542 layer.invalidate(); 538 543 } … … 618 623 } 619 624 } 625 626 /** 627 * the data of a MarkerLayer 628 * @since 18287 629 */ 630 public class MarkerData extends ArrayList<Marker> implements IGpxLayerPrefs { 631 632 private Map<String, String> ownLayerPrefs; 633 634 @Override 635 public Map<String, String> getLayerPrefs() { 636 if (ownLayerPrefs == null && fromLayer != null && fromLayer.data != null) { 637 return fromLayer.data.getLayerPrefs(); 638 } 639 // fallback to own layerPrefs if the corresponding gpxLayer has already been deleted 640 // by the user or never existed when loaded from a session file 641 if (ownLayerPrefs == null) { 642 ownLayerPrefs = new HashMap<>(); 643 } 644 return ownLayerPrefs; 645 } 646 647 /** 648 * Transfers the layerPrefs from the GpxData to MarkerData (when GpxData is deleted) 649 * @param gpxLayerPrefs the layerPrefs from the GpxData object 650 */ 651 public void transferLayerPrefs(Map<String, String> gpxLayerPrefs) { 652 ownLayerPrefs = new HashMap<>(gpxLayerPrefs); 653 } 654 655 @Override 656 public void setModified(boolean value) { 657 if (fromLayer != null && fromLayer.data != null) { 658 fromLayer.data.setModified(value); 659 } 660 } 661 } 620 662 } -
trunk/src/org/openstreetmap/josm/gui/preferences/display/GPXSettingsPanel.java
r18211 r18287 30 30 import org.openstreetmap.josm.actions.ExpertToggleAction; 31 31 import org.openstreetmap.josm.data.gpx.GpxData; 32 import org.openstreetmap.josm.data.gpx.IGpxLayerPrefs; 32 33 import org.openstreetmap.josm.gui.MainApplication; 33 34 import org.openstreetmap.josm.gui.layer.GpxLayer; … … 174 175 */ 175 176 public static String getLayerPref(GpxLayer layer, String key) { 177 GpxData data = layer != null ? layer.data : null; 178 return getDataPref(data, key); 179 } 180 181 /** 182 * Reads the preference for the given layer or the default preference if not available 183 * @param data the data. Can be <code>null</code>, default preference will be returned then 184 * @param key the drawing key to be read, without "draw.rawgps." 185 * @return the value 186 * @since 18287 187 */ 188 public static String getDataPref(IGpxLayerPrefs data, String key) { 176 189 Object d = DEFAULT_PREFS.get(key); 177 190 String ds; … … 182 195 ds = null; 183 196 } 184 return Optional.ofNullable(tryGet LayerPrefLocal(layer, key)).orElse(Config.getPref().get("draw.rawgps." + key, ds));197 return Optional.ofNullable(tryGetDataPrefLocal(data, key)).orElse(Config.getPref().get("draw.rawgps." + key, ds)); 185 198 } 186 199 … … 192 205 */ 193 206 public static int getLayerPrefInt(GpxLayer layer, String key) { 194 String s = getLayerPref(layer, key); 207 GpxData data = layer != null ? layer.data : null; 208 return getDataPrefInt(data, key); 209 } 210 211 /** 212 * Reads the integer preference for the given data or the default preference if not available 213 * @param data the data. Can be <code>null</code>, default preference will be returned then 214 * @param key the drawing key to be read, without "draw.rawgps." 215 * @return the integer value 216 * @since 18287 217 */ 218 public static int getDataPrefInt(IGpxLayerPrefs data, String key) { 219 String s = getDataPref(data, key); 195 220 if (s != null) { 196 221 try { … … 215 240 */ 216 241 public static String tryGetLayerPrefLocal(GpxLayer layer, String key) { 217 return layer != null ? tryGet LayerPrefLocal(layer.data, key) : null;242 return layer != null ? tryGetDataPrefLocal(layer.data, key) : null; 218 243 } 219 244 … … 224 249 * @return the value or <code>null</code> if not found 225 250 */ 226 public static String tryGet LayerPrefLocal(GpxDatadata, String key) {251 public static String tryGetDataPrefLocal(IGpxLayerPrefs data, String key) { 227 252 return data != null ? data.getLayerPrefs().get(key) : null; 228 253 } … … 238 263 if (layers != null) { 239 264 for (GpxLayer l : layers) { 240 put LayerPrefLocal(l.data, key, v);265 putDataPrefLocal(l.data, key, v); 241 266 } 242 267 } else { … … 253 278 public static void putLayerPrefLocal(GpxLayer layer, String key, String value) { 254 279 if (layer == null || layer.data == null) return; 255 put LayerPrefLocal(layer.data, key, value);280 putDataPrefLocal(layer.data, key, value); 256 281 } 257 282 … … 261 286 * @param key the drawing key to be written, without "draw.rawgps." 262 287 * @param value the value or <code>null</code> to remove key 263 */ 264 public static void putLayerPrefLocal(GpxData data, String key, String value) { 288 * @since 18287 289 */ 290 public static void putDataPrefLocal(IGpxLayerPrefs data, String key, String value) { 291 if (data == null) return; 292 data.setModified(true); 265 293 if (Utils.isBlank(value) || 266 294 (getLayerPref(null, key).equals(value) && DEFAULT_PREFS.get(key) != null && DEFAULT_PREFS.get(key).toString().equals(value))) { -
trunk/src/org/openstreetmap/josm/io/GpxWriter.java
r18219 r18287 149 149 validprefixes = namespaces.stream().map(n -> n.getPrefix()).collect(Collectors.toList()); 150 150 151 data.creator = JOSM_CREATOR_NAME; 151 152 out.println("<?xml version='1.0' encoding='UTF-8'?>"); 152 out.println("<gpx version=\"1.1\" creator=\"JOSM GPX export\" xmlns=\"http://www.topografix.com/GPX/1/1\""); 153 154 out.print("<gpx version=\"1.1\" creator=\""); 155 out.print(JOSM_CREATOR_NAME); 156 out.println("\" xmlns=\"http://www.topografix.com/GPX/1/1\""); 153 157 154 158 StringBuilder schemaLocations = new StringBuilder("http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd"); -
trunk/src/org/openstreetmap/josm/io/session/GpxTracksSessionExporter.java
r18133 r18287 7 7 import java.io.Writer; 8 8 import java.nio.charset.StandardCharsets; 9 import java.time.Instant; 9 10 10 11 import org.openstreetmap.josm.gui.layer.GpxLayer; … … 16 17 */ 17 18 public class GpxTracksSessionExporter extends GenericSessionExporter<GpxLayer> { 19 20 private Instant metaTime; 18 21 19 22 /** … … 37 40 Writer writer = new OutputStreamWriter(out, StandardCharsets.UTF_8); 38 41 GpxWriter w = new GpxWriter(new PrintWriter(writer)); 42 if (metaTime != null) { 43 w.setMetaTime(metaTime); 44 } 39 45 w.write(layer.data); 40 46 w.flush(); 41 47 } 48 49 protected void setMetaTime(Instant metaTime) { 50 this.metaTime = metaTime; 51 } 42 52 } -
trunk/src/org/openstreetmap/josm/io/session/GpxTracksSessionImporter.java
r18208 r18287 55 55 importData = GpxImporter.loadLayers(in, support.getFile(fileStr), support.getLayerName(), progressMonitor); 56 56 } 57 if (importData.getGpxLayer() != null && importData.getGpxLayer().data != null) { 58 importData.getGpxLayer().data.fromSession = true; 59 } 57 60 58 61 support.addPostLayersTask(importData.getPostLayerTask()); -
trunk/src/org/openstreetmap/josm/io/session/MarkerSessionExporter.java
r17733 r18287 10 10 import java.io.Writer; 11 11 import java.nio.charset.StandardCharsets; 12 import java.time.Instant; 12 13 import java.util.Collection; 13 14 import java.util.Collections; … … 32 33 */ 33 34 public class MarkerSessionExporter extends AbstractSessionExporter<MarkerLayer> { 35 36 private Instant metaTime; 34 37 35 38 /** … … 87 90 Writer writer = new OutputStreamWriter(out, StandardCharsets.UTF_8); 88 91 MarkerWriter w = new MarkerWriter(new PrintWriter(writer)); 92 if (metaTime != null) { 93 w.setMetaTime(metaTime); 94 } 89 95 w.write(layer); 90 96 w.flush(); 97 } 98 99 protected void setMetaTime(Instant metaTime) { 100 this.metaTime = metaTime; 91 101 } 92 102 … … 110 120 public void write(MarkerLayer layer) { 111 121 GpxData data = new GpxData(); 122 layer.data.getLayerPrefs().forEach((k, v) -> { 123 if (k != null && k.indexOf("markers.") == 0) { 124 data.getLayerPrefs().put(k, v); 125 } 126 }); 112 127 data.put(GpxData.META_DESC, "exported JOSM marker layer"); 113 128 for (Marker m : layer.data) { -
trunk/src/org/openstreetmap/josm/io/session/MarkerSessionImporter.java
r18208 r18287 6 6 import java.io.IOException; 7 7 import java.io.InputStream; 8 import java.util.List;9 8 10 9 import javax.xml.xpath.XPath; … … 15 14 16 15 import org.openstreetmap.josm.gui.io.importexport.GpxImporter; 17 import org.openstreetmap.josm.gui.layer.GpxLayer;18 16 import org.openstreetmap.josm.gui.layer.Layer; 19 17 import org.openstreetmap.josm.gui.layer.markerlayer.MarkerLayer; … … 51 49 support.addPostLayersTask(importData.getPostLayerTask()); 52 50 53 GpxLayer gpxLayer = null; 54 List<SessionReader.LayerDependency> deps = support.getLayerDependencies(); 55 if (!deps.isEmpty()) { 56 Layer layer = deps.get(0).getLayer(); 57 if (layer instanceof GpxLayer) { 58 gpxLayer = (GpxLayer) layer; 59 } 60 } 61 62 MarkerLayer markerLayer = importData.getMarkerLayer(); 63 if (markerLayer != null) { 64 markerLayer.fromLayer = gpxLayer; 65 } 66 67 return markerLayer; 51 return importData.getMarkerLayer(); 68 52 } 69 53 } catch (XPathExpressionException e) { -
trunk/src/org/openstreetmap/josm/io/session/SessionReader.java
r17659 r18287 4 4 import static org.openstreetmap.josm.tools.I18n.tr; 5 5 6 import java.awt.Color;7 6 import java.awt.GraphicsEnvironment; 8 7 import java.io.BufferedInputStream; … … 47 46 import org.openstreetmap.josm.io.IllegalDataException; 48 47 import org.openstreetmap.josm.tools.CheckParameterUtil; 49 import org.openstreetmap.josm.tools.ColorHelper;50 48 import org.openstreetmap.josm.tools.JosmRuntimeException; 51 49 import org.openstreetmap.josm.tools.Logging; … … 620 618 } 621 619 } 622 String colorString = el.getAttribute("color");623 if (colorString != null) {624 try {625 Color color = ColorHelper.html2color(colorString);626 layer.setColor(color);627 } catch (RuntimeException ex) {628 Logging.warn("Cannot parse color " + colorString);629 }630 }631 620 layer.setName(names.get(entry.getKey())); 632 621 layers.add(layer); -
trunk/src/org/openstreetmap/josm/io/session/SessionWriter.java
r18133 r18287 44 44 import org.openstreetmap.josm.gui.layer.markerlayer.MarkerLayer; 45 45 import org.openstreetmap.josm.gui.preferences.projection.ProjectionPreference; 46 import org.openstreetmap.josm.tools.ColorHelper;47 46 import org.openstreetmap.josm.tools.JosmRuntimeException; 48 47 import org.openstreetmap.josm.tools.Logging; … … 241 240 if (!Utils.equalsEpsilon(layer.getOpacity(), 1.0)) { 242 241 el.setAttribute("opacity", Double.toString(layer.getOpacity())); 243 }244 if (layer.getColor() != null) {245 el.setAttribute("color", ColorHelper.color2html(layer.getColor()));246 242 } 247 243 Set<Layer> deps = dependencies.get(layer); -
trunk/test/data/sessions/gpx_markers.jos
r17659 r18287 16 16 <file>layers/01/data.gpx</file> 17 17 </layer> 18 <layer color="#34567812"index="2" name="Marker layer name" opacity="0.5" type="markers" version="0.1" visible="true">18 <layer index="2" name="Marker layer name" opacity="0.5" type="markers" version="0.1" visible="true"> 19 19 <file>layers/02/data.gpx</file> 20 20 </layer> -
trunk/test/unit/org/openstreetmap/josm/data/gpx/GpxDataTest.java
r18207 r18287 504 504 EqualsVerifier.forClass(GpxData.class).usingGetClass() 505 505 .suppress(Warning.NONFINAL_FIELDS) 506 .withIgnoredFields("creator", "fromServer", " storageFile", "initializing", "updating",506 .withIgnoredFields("creator", "fromServer", "fromSession", "storageFile", "initializing", "updating", 507 507 "suppressedInvalidate", "listeners", "tracks", "routes", "waypoints", "proxy", "segSpans", "modified") 508 508 .withPrefabValues(WayPoint.class, new WayPoint(LatLon.NORTH_POLE), new WayPoint(LatLon.SOUTH_POLE)) -
trunk/test/unit/org/openstreetmap/josm/data/gpx/GpxTrackTest.java
r17275 r18287 9 9 import java.util.HashMap; 10 10 11 import org.junit.jupiter.api.Test; 11 12 import org.junit.jupiter.api.extension.RegisterExtension; 12 import org.junit.jupiter.api.Test;13 13 import org.openstreetmap.josm.TestUtils; 14 14 import org.openstreetmap.josm.testutils.JOSMTestRules; … … 32 32 33 33 /** 34 * Tests w eather the track can read and write colors.34 * Tests whether the track can read and write colors. 35 35 */ 36 36 @Test -
trunk/test/unit/org/openstreetmap/josm/io/session/SessionWriterTest.java
r17659 r18287 1 1 // License: GPL. For details, see LICENSE file. 2 2 package org.openstreetmap.josm.io.session; 3 4 import static org.junit.jupiter.api.Assertions.assertEquals; 5 import static org.junit.jupiter.api.Assertions.fail; 3 6 4 7 import java.awt.Color; 5 8 import java.io.File; 6 9 import java.io.IOException; 7 import java.io.InputStream;8 10 import java.nio.charset.StandardCharsets; 9 11 import java.nio.file.Files; 10 12 import java.nio.file.Path; 11 13 import java.nio.file.Paths; 14 import java.time.Instant; 12 15 import java.util.Arrays; 13 16 import java.util.Collections; … … 15 18 import java.util.List; 16 19 import java.util.Map; 20 import java.util.stream.Collectors; 21 import java.util.zip.ZipEntry; 17 22 import java.util.zip.ZipFile; 18 23 … … 43 48 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; 44 49 45 import static org.junit.jupiter.api.Assertions.assertEquals;46 47 50 /** 48 51 * Unit tests for Session writing. … … 109 112 } 110 113 111 private byte[]testWrite(List<Layer> layers, final boolean zip) throws IOException {114 private Map<String, byte[]> testWrite(List<Layer> layers, final boolean zip) throws IOException { 112 115 Map<Layer, SessionLayerExporter> exporters = new HashMap<>(); 113 116 if (zip) { … … 119 122 } 120 123 for (final Layer l : layers) { 121 exporters.put(l, SessionWriter.getSessionLayerExporter(l)); 124 SessionLayerExporter s = SessionWriter.getSessionLayerExporter(l); 125 exporters.put(l, s); 126 if (s instanceof GpxTracksSessionExporter) { 127 ((GpxTracksSessionExporter) s).setMetaTime(Instant.parse("2021-10-16T18:27:12.351Z")); 128 } else if (s instanceof MarkerSessionExporter) { 129 ((MarkerSessionExporter) s).setMetaTime(Instant.parse("2021-10-16T18:27:12.351Z")); 130 } 122 131 } 123 132 SessionWriter sw = new SessionWriter(layers, -1, exporters, new MultiMap<Layer, Layer>(), zip); … … 128 137 return null; 129 138 } 130 try (ZipFile zipFile = new ZipFile(file); 131 InputStream input = zipFile.getInputStream(zipFile.getEntry("session.jos"))) { 132 return Utils.readBytesFromStream(input); 139 try (ZipFile zipFile = new ZipFile(file)) { 140 return Collections.list(zipFile.entries()).stream().collect(Collectors.toMap(ZipEntry::getName, e -> { 141 try { 142 return Utils.readBytesFromStream(zipFile.getInputStream(e)); 143 } catch (IOException ex) { 144 fail(ex); 145 } 146 return null; 147 })); 133 148 } 134 149 } finally { … … 147 162 private GpxLayer createGpxLayer() { 148 163 GpxData data = new GpxData(); 149 data.waypoints.add(new WayPoint(new LatLon(42.72665, -0.00747))); 164 WayPoint wp = new WayPoint(new LatLon(42.72665, -0.00747)); 165 wp.setInstant(Instant.parse("2021-01-01T10:15:30.00Z")); 166 data.waypoints.add(wp); 150 167 data.waypoints.add(new WayPoint(new LatLon(42.72659, -0.00749))); 151 168 GpxLayer layer = new GpxLayer(data, "GPX layer name"); … … 233 250 void testWriteGpxAndMarkerJoz() throws IOException { 234 251 GpxLayer gpx = createGpxLayer(); 235 byte[] bytes = testWrite(Arrays.asList(gpx, createMarkerLayer(gpx)), true); 252 Map<String, byte[]> bytes = testWrite(Arrays.asList(gpx, createMarkerLayer(gpx)), true); 253 236 254 Path path = Paths.get(TestUtils.getTestDataRoot() + "/sessions/gpx_markers.jos"); 237 255 String expected = new String(Files.readAllBytes(path), StandardCharsets.UTF_8).replace("\r", ""); 238 String actual = new String(bytes, StandardCharsets.UTF_8).replace("\r", ""); 256 String actual = new String(bytes.get("session.jos"), StandardCharsets.UTF_8).replace("\r", ""); 257 assertEquals(expected, actual); 258 259 path = Paths.get(TestUtils.getTestDataRoot() + "/sessions/data_export.gpx"); 260 expected = new String(Files.readAllBytes(path), StandardCharsets.UTF_8).replace("\r", ""); 261 actual = new String(bytes.get("layers/01/data.gpx"), StandardCharsets.UTF_8).replace("\r", ""); 262 assertEquals(expected, actual); 263 264 path = Paths.get(TestUtils.getTestDataRoot() + "/sessions/markers.gpx"); 265 expected = new String(Files.readAllBytes(path), StandardCharsets.UTF_8).replace("\r", ""); 266 actual = new String(bytes.get("layers/02/data.gpx"), StandardCharsets.UTF_8).replace("\r", ""); 239 267 assertEquals(expected, actual); 240 268 }
Note:
See TracChangeset
for help on using the changeset viewer.