diff --git a/trunk/src/org/openstreetmap/josm/actions/SaveAction.java b/trunk/src/org/openstreetmap/josm/actions/SaveAction.java
a
|
b
|
|
115 | 115 | // Ask for overwrite in case of GpxLayer |
116 | 116 | if (f != null && layer instanceof GpxLayer && !Config.getPref().getBoolean("gpx.export.overwrite", false)) { |
117 | 117 | JPanel p = new JPanel(new GridBagLayout()); |
118 | | JLabel label = new JLabel(tr("File {0} exists. Overwrite?", f.getName())); |
| 118 | JLabel label = new JLabel("<html>" + tr("The file \"{0}\" has been changed.<br>Would you like to overwrite the existing file?", f.getName()) + "</html>"); |
119 | 119 | label.setHorizontalAlignment(SwingConstants.CENTER); |
120 | 120 | JCheckBox remember = new JCheckBox(tr("Remember choice")); |
121 | 121 | remember.setHorizontalAlignment(SwingConstants.CENTER); |
… |
… |
|
124 | 124 | ExtendedDialog dialog = new ExtendedDialog( |
125 | 125 | MainApplication.getMainFrame(), |
126 | 126 | tr("Overwrite"), |
127 | | tr("Overwrite"), tr("Cancel")) |
128 | | .setButtonIcons("save_as", "cancel") |
| 127 | tr("Overwrite"), tr("New file"), tr("Cancel")) |
| 128 | .setButtonIcons("save", "save_as", "cancel") |
129 | 129 | .setContent(p); |
130 | | if (dialog.showDialog().getValue() != 1) { |
| 130 | int val = dialog.showDialog().getValue(); |
| 131 | if (val == 1) { |
| 132 | Config.getPref().putBoolean("gpx.export.overwrite", remember.isSelected()); |
| 133 | } else if (val == 2) { |
131 | 134 | f = null; |
132 | | } else if (remember.isSelected()) { |
133 | | Config.getPref().putBoolean("gpx.export.overwrite", true); |
| 135 | } else { |
| 136 | return null; |
134 | 137 | } |
135 | 138 | } |
136 | 139 | return f == null ? layer.createAndOpenSaveFileChooser() : f; |
diff --git a/trunk/src/org/openstreetmap/josm/actions/SessionSaveAsAction.java b/trunk/src/org/openstreetmap/josm/actions/SessionSaveAsAction.java
a
|
b
|
|
19 | 19 | import java.util.Map; |
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; |
24 | 25 | import javax.swing.JCheckBox; |
… |
… |
|
32 | 33 | import javax.swing.border.EtchedBorder; |
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; |
37 | 39 | import org.openstreetmap.josm.gui.MainApplication; |
38 | 40 | import org.openstreetmap.josm.gui.MapFrame; |
39 | 41 | import org.openstreetmap.josm.gui.MapFrameListener; |
| 42 | import org.openstreetmap.josm.gui.Notification; |
| 43 | import org.openstreetmap.josm.gui.layer.AbstractModifiableLayer; |
40 | 44 | import org.openstreetmap.josm.gui.layer.Layer; |
41 | 45 | import org.openstreetmap.josm.gui.util.WindowGeometry; |
42 | 46 | import org.openstreetmap.josm.gui.widgets.AbstractFileChooser; |
… |
… |
|
58 | 62 | private transient Map<Layer, SessionLayerExporter> exporters; |
59 | 63 | private transient MultiMap<Layer, Layer> dependencies; |
60 | 64 | |
| 65 | private static final BooleanProperty SAVE_LOCAL_FILES_PROP = new BooleanProperty("session.savelocal", true); |
| 66 | |
61 | 67 | /** |
62 | 68 | * Constructs a new {@code SessionSaveAsAction}. |
63 | 69 | */ |
… |
… |
|
156 | 162 | .filter(layer -> exporters.get(layer) != null && exporters.get(layer).shallExport()) |
157 | 163 | .collect(Collectors.toList()); |
158 | 164 | |
| 165 | Stream<Layer> layersToSaveStream = layersOut.stream() |
| 166 | .filter(Layer::isSavable) |
| 167 | .filter(layer -> !(layer instanceof AbstractModifiableLayer) || ((AbstractModifiableLayer) layer).isModified()) |
| 168 | .filter(layer -> exporters.get(layer) != null && !exporters.get(layer).requiresZip()); |
| 169 | |
| 170 | if (SAVE_LOCAL_FILES_PROP.get()) { |
| 171 | // individual files must be saved before the session file as the location may change |
| 172 | |
| 173 | if (layersToSaveStream |
| 174 | .map(layer -> SaveAction.getInstance().doSave(layer, true)) |
| 175 | .collect(Collectors.toList()) //force evaluation of all elements |
| 176 | .contains(false)) { |
| 177 | |
| 178 | new Notification(tr("Not all local files referenced by the session file could be saved.<br>Make sure you save them before closing JOSM.")) |
| 179 | .setIcon(JOptionPane.WARNING_MESSAGE) |
| 180 | .setDuration(Notification.TIME_LONG) |
| 181 | .show(); |
| 182 | } |
| 183 | |
| 184 | } else if (layersToSaveStream.anyMatch(l -> l instanceof AbstractModifiableLayer)) { |
| 185 | new Notification(tr("Not all local files referenced by the session file are saved yet.<br>Make sure you save them before closing JOSM.")) |
| 186 | .setIcon(JOptionPane.INFORMATION_MESSAGE) |
| 187 | .setDuration(Notification.TIME_LONG) |
| 188 | .show(); |
| 189 | } |
| 190 | |
159 | 191 | int active = -1; |
160 | 192 | Layer activeLayer = getLayerManager().getActiveLayer(); |
161 | 193 | if (activeLayer != null) { |
… |
… |
|
241 | 273 | } |
242 | 274 | |
243 | 275 | protected final Component build() { |
| 276 | JPanel op = new JPanel(new GridBagLayout()); |
244 | 277 | JPanel ip = new JPanel(new GridBagLayout()); |
245 | 278 | for (Layer layer : layers) { |
246 | 279 | JPanel wrapper = new JPanel(new GridBagLayout()); |
… |
… |
|
263 | 296 | p.add(sp, GBC.eol().fill()); |
264 | 297 | final JTabbedPane tabs = new JTabbedPane(); |
265 | 298 | tabs.addTab(tr("Layers"), p); |
266 | | return tabs; |
| 299 | op.add(tabs, GBC.eol().fill()); |
| 300 | JCheckBox chkSaveLocal = new JCheckBox(tr("Save all local files to disk"), SAVE_LOCAL_FILES_PROP.get()); |
| 301 | chkSaveLocal.addChangeListener(l -> { |
| 302 | SAVE_LOCAL_FILES_PROP.put(chkSaveLocal.isSelected()); |
| 303 | }); |
| 304 | op.add(chkSaveLocal); |
| 305 | return op; |
267 | 306 | } |
268 | 307 | |
269 | 308 | protected final Component getDisabledExportPanel(Layer layer) { |
diff --git a/trunk/src/org/openstreetmap/josm/data/gpx/GpxData.java b/trunk/src/org/openstreetmap/josm/data/gpx/GpxData.java
a
|
b
|
|
41 | 41 | * |
42 | 42 | * @author Raphael Mack <ramack@raphael-mack.de> |
43 | 43 | */ |
44 | | public class GpxData extends WithAttributes implements Data { |
| 44 | public class GpxData extends WithAttributes implements Data, IGpxLayerPrefs { |
45 | 45 | |
46 | 46 | /** |
47 | 47 | * Constructs a new GpxData. |
… |
… |
|
981 | 981 | * @return Modifiable map |
982 | 982 | * @since 15496 |
983 | 983 | */ |
| 984 | @Override |
984 | 985 | public Map<String, String> getLayerPrefs() { |
985 | 986 | return layerPrefs; |
986 | 987 | } |
… |
… |
|
1175 | 1176 | * @param value modified flag |
1176 | 1177 | * @since 15496 |
1177 | 1178 | */ |
| 1179 | @Override |
1178 | 1180 | public void setModified(boolean value) { |
1179 | | modified = value; |
| 1181 | if (!initializing) { |
| 1182 | modified = value; |
| 1183 | } |
1180 | 1184 | } |
1181 | 1185 | |
1182 | 1186 | /** |
diff --git a/trunk/src/org/openstreetmap/josm/data/gpx/IGpxLayerPrefs.java b/trunk/src/org/openstreetmap/josm/data/gpx/IGpxLayerPrefs.java
new file mode 100644
a
|
b
|
|
| 1 | // License: GPL. For details, see LICENSE file. |
| 2 | package org.openstreetmap.josm.data.gpx; |
| 3 | |
| 4 | import java.util.Map; |
| 5 | |
| 6 | /** |
| 7 | * Interface containing the layer preferences. |
| 8 | * Implemented by GpxLayer and MarkerLayer |
| 9 | * @since xxx |
| 10 | */ |
| 11 | public interface IGpxLayerPrefs { |
| 12 | |
| 13 | /** |
| 14 | * The layer specific prefs formerly saved in the preferences, e.g. drawing options. |
| 15 | * NOT the track specific settings (e.g. color, width) |
| 16 | * @return Modifiable map |
| 17 | */ |
| 18 | Map<String, String> getLayerPrefs(); |
| 19 | |
| 20 | /** |
| 21 | * Sets the modified flag to the value. |
| 22 | * @param value modified flag |
| 23 | */ |
| 24 | void setModified(boolean value); |
| 25 | |
| 26 | } |
diff --git a/trunk/src/org/openstreetmap/josm/gui/layer/GpxLayer.java b/trunk/src/org/openstreetmap/josm/gui/layer/GpxLayer.java
a
|
b
|
|
1 | 1 | // License: GPL. For details, see LICENSE file. |
2 | 2 | package org.openstreetmap.josm.gui.layer; |
3 | 3 | |
| 4 | import static org.openstreetmap.josm.tools.I18n.tr; |
| 5 | import static org.openstreetmap.josm.tools.I18n.trn; |
| 6 | |
| 7 | import java.awt.Color; |
| 8 | import java.awt.Dimension; |
| 9 | import java.awt.Graphics2D; |
| 10 | import java.awt.event.ActionEvent; |
| 11 | import java.io.File; |
| 12 | import java.time.Instant; |
| 13 | import java.util.ArrayList; |
| 14 | import java.util.Arrays; |
| 15 | import java.util.Collections; |
| 16 | import java.util.List; |
| 17 | import java.util.NoSuchElementException; |
| 18 | import java.util.stream.Collectors; |
| 19 | |
| 20 | import javax.swing.AbstractAction; |
| 21 | import javax.swing.Action; |
| 22 | import javax.swing.Icon; |
| 23 | import javax.swing.JScrollPane; |
| 24 | import javax.swing.SwingUtilities; |
| 25 | |
4 | 26 | import org.openstreetmap.josm.actions.AutoScaleAction; |
5 | 27 | import org.openstreetmap.josm.actions.ExpertToggleAction; |
6 | 28 | import org.openstreetmap.josm.actions.ExpertToggleAction.ExpertModeChangeListener; |
… |
… |
|
41 | 63 | import org.openstreetmap.josm.tools.Utils; |
42 | 64 | import org.openstreetmap.josm.tools.date.Interval; |
43 | 65 | |
44 | | import javax.swing.AbstractAction; |
45 | | import javax.swing.Action; |
46 | | import javax.swing.Icon; |
47 | | import javax.swing.JScrollPane; |
48 | | import javax.swing.SwingUtilities; |
49 | | import java.awt.Color; |
50 | | import java.awt.Dimension; |
51 | | import java.awt.Graphics2D; |
52 | | import java.awt.event.ActionEvent; |
53 | | import java.io.File; |
54 | | import java.time.Instant; |
55 | | import java.util.ArrayList; |
56 | | import java.util.Arrays; |
57 | | import java.util.Collections; |
58 | | import java.util.List; |
59 | | import java.util.NoSuchElementException; |
60 | | import java.util.stream.Collectors; |
61 | | |
62 | | import static org.openstreetmap.josm.tools.I18n.tr; |
63 | | import static org.openstreetmap.josm.tools.I18n.trn; |
64 | | |
65 | 66 | /** |
66 | 67 | * A layer that displays data from a Gpx file / the OSM gpx downloads. |
67 | 68 | */ |
… |
… |
|
592 | 593 | |
593 | 594 | @Override |
594 | 595 | public synchronized void destroy() { |
| 596 | if (linkedMarkerLayer != null && MainApplication.getLayerManager().containsLayer(linkedMarkerLayer)) { |
| 597 | linkedMarkerLayer.data.transferLayerPrefs(data.getLayerPrefs()); |
| 598 | } |
595 | 599 | data.clear(); |
596 | 600 | data = null; |
597 | 601 | super.destroy(); |
diff --git a/trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/MarkerLayer.java b/trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/MarkerLayer.java
a
|
b
|
|
20 | 20 | import java.util.ArrayList; |
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 | |
26 | 28 | import javax.swing.AbstractAction; |
… |
… |
|
37 | 39 | import org.openstreetmap.josm.data.gpx.GpxData; |
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; |
42 | 45 | import org.openstreetmap.josm.data.preferences.IntegerProperty; |
… |
… |
|
56 | 59 | import org.openstreetmap.josm.gui.preferences.display.GPXSettingsPanel; |
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; |
61 | 65 | import org.openstreetmap.josm.tools.Utils; |
… |
… |
|
76 | 80 | /** |
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; |
82 | 86 | private Marker currentMarker; |
… |
… |
|
100 | 104 | public MarkerLayer(GpxData indata, String name, File associatedFile, 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 | |
108 | | Color c = null; |
109 | | String cs = GPXSettingsPanel.tryGetLayerPrefLocal(indata, "markers.color"); |
| 112 | String cs = GPXSettingsPanel.tryGetDataPrefLocal(indata, "markers.color"); |
110 | 113 | if (cs != null) { |
111 | | try { |
112 | | c = Color.decode(cs); |
113 | | } catch (NumberFormatException ex) { |
| 114 | Color c = ColorHelper.html2color(cs); |
| 115 | if (c != null) { |
| 116 | setPrivateColors(c); |
| 117 | } else { |
114 | 118 | Logging.warn("Could not read marker color: " + cs); |
115 | 119 | } |
116 | 120 | } |
117 | | setPrivateColors(c); |
118 | 121 | |
119 | 122 | for (WayPoint wpt : indata.waypoints) { |
120 | 123 | /* calculate time differences in waypoints */ |
… |
… |
|
459 | 462 | * @return <code>true</code> if text should be shown, <code>false</code> otherwise. |
460 | 463 | */ |
461 | 464 | private boolean isTextOrIconShown() { |
462 | | return Boolean.parseBoolean(GPXSettingsPanel.getLayerPref(fromLayer, "markers.show-text")); |
| 465 | return Boolean.parseBoolean(GPXSettingsPanel.getDataPref(data, "markers.show-text")); |
463 | 466 | } |
464 | 467 | |
465 | 468 | @Override |
… |
… |
|
475 | 478 | @Override |
476 | 479 | public void setColor(Color color) { |
477 | 480 | 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); |
| 481 | String cs = null; |
| 482 | if (color != null) { |
| 483 | cs = ColorHelper.color2html(color); |
484 | 484 | } |
| 485 | GPXSettingsPanel.putDataPrefLocal(data, "markers.color", cs); |
485 | 486 | invalidate(); |
486 | 487 | } |
487 | 488 | |
… |
… |
|
533 | 534 | |
534 | 535 | @Override |
535 | 536 | public void actionPerformed(ActionEvent e) { |
536 | | GPXSettingsPanel.putLayerPrefLocal(layer.fromLayer, "markers.show-text", Boolean.toString(!layer.isTextOrIconShown())); |
| 537 | GPXSettingsPanel.putDataPrefLocal(layer.data, "markers.show-text", Boolean.toString(!layer.isTextOrIconShown())); |
537 | 538 | layer.invalidate(); |
538 | 539 | } |
539 | 540 | |
… |
… |
|
617 | 618 | invalidate(); |
618 | 619 | } |
619 | 620 | } |
| 621 | |
| 622 | /** |
| 623 | * the data of a MarkerLayer |
| 624 | */ |
| 625 | public class MarkerData extends ArrayList<Marker> implements IGpxLayerPrefs { |
| 626 | |
| 627 | private Map<String, String> ownLayerPrefs; |
| 628 | |
| 629 | @Override |
| 630 | public Map<String, String> getLayerPrefs() { |
| 631 | if (ownLayerPrefs == null && fromLayer != null && fromLayer.data != null) { |
| 632 | return fromLayer.data.getLayerPrefs(); |
| 633 | } |
| 634 | // fallback to own layerPrefs if the corresponding gpxLayer has already been deleted |
| 635 | // by the user or never existed when loaded from a session file |
| 636 | if (ownLayerPrefs == null) { |
| 637 | ownLayerPrefs = new HashMap<>(); |
| 638 | } |
| 639 | return ownLayerPrefs; |
| 640 | } |
| 641 | |
| 642 | /** |
| 643 | * Transfers the layerPrefs from the GpxData to MarkerData (when GpxData is deleted) |
| 644 | * @param gpxLayerPrefs the layerPrefs from the GpxData object |
| 645 | */ |
| 646 | public void transferLayerPrefs(Map<String, String> gpxLayerPrefs) { |
| 647 | ownLayerPrefs = new HashMap<>(gpxLayerPrefs); |
| 648 | } |
| 649 | |
| 650 | @Override |
| 651 | public void setModified(boolean value) { |
| 652 | if (fromLayer != null && fromLayer.data != null) { |
| 653 | fromLayer.data.setModified(value); |
| 654 | } |
| 655 | } |
| 656 | |
| 657 | } |
620 | 658 | } |
diff --git a/trunk/src/org/openstreetmap/josm/gui/preferences/display/GPXSettingsPanel.java b/trunk/src/org/openstreetmap/josm/gui/preferences/display/GPXSettingsPanel.java
a
|
b
|
|
29 | 29 | import org.apache.commons.jcs3.access.exception.InvalidArgumentException; |
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; |
34 | 35 | import org.openstreetmap.josm.gui.layer.gpx.GpxDrawHelper; |
… |
… |
|
172 | 173 | * @return the value |
173 | 174 | */ |
174 | 175 | public static String getLayerPref(GpxLayer layer, String key) { |
| 176 | GpxData data = layer != null ? layer.data : null; |
| 177 | return getDataPref(data, key); |
| 178 | } |
| 179 | |
| 180 | /** |
| 181 | * Reads the preference for the given layer or the default preference if not available |
| 182 | * @param data the data. Can be <code>null</code>, default preference will be returned then |
| 183 | * @param key the drawing key to be read, without "draw.rawgps." |
| 184 | * @return the value |
| 185 | */ |
| 186 | public static String getDataPref(IGpxLayerPrefs data, String key) { |
175 | 187 | Object d = DEFAULT_PREFS.get(key); |
176 | 188 | String ds; |
177 | 189 | if (d != null) { |
… |
… |
|
180 | 192 | Logging.warn("No default value found for layer preference \"" + key + "\"."); |
181 | 193 | ds = null; |
182 | 194 | } |
183 | | return Optional.ofNullable(tryGetLayerPrefLocal(layer, key)).orElse(Config.getPref().get("draw.rawgps." + key, ds)); |
| 195 | return Optional.ofNullable(tryGetDataPrefLocal(data, key)).orElse(Config.getPref().get("draw.rawgps." + key, ds)); |
184 | 196 | } |
185 | 197 | |
186 | 198 | /** |
… |
… |
|
190 | 202 | * @return the integer value |
191 | 203 | */ |
192 | 204 | public static int getLayerPrefInt(GpxLayer layer, String key) { |
193 | | String s = getLayerPref(layer, key); |
| 205 | GpxData data = layer != null ? layer.data : null; |
| 206 | return getDataPrefInt(data, key); |
| 207 | } |
| 208 | |
| 209 | /** |
| 210 | * Reads the integer preference for the given data or the default preference if not available |
| 211 | * @param data the data. Can be <code>null</code>, default preference will be returned then |
| 212 | * @param key the drawing key to be read, without "draw.rawgps." |
| 213 | * @return the integer value |
| 214 | */ |
| 215 | public static int getDataPrefInt(IGpxLayerPrefs data, String key) { |
| 216 | String s = getDataPref(data, key); |
194 | 217 | if (s != null) { |
195 | 218 | try { |
196 | 219 | return Integer.parseInt(s); |
… |
… |
|
213 | 236 | * @return the value or <code>null</code> if not found |
214 | 237 | */ |
215 | 238 | public static String tryGetLayerPrefLocal(GpxLayer layer, String key) { |
216 | | return layer != null ? tryGetLayerPrefLocal(layer.data, key) : null; |
| 239 | return layer != null ? tryGetDataPrefLocal(layer.data, key) : null; |
217 | 240 | } |
218 | 241 | |
219 | 242 | /** |
… |
… |
|
222 | 245 | * @param key the drawing key to be read, without "draw.rawgps." |
223 | 246 | * @return the value or <code>null</code> if not found |
224 | 247 | */ |
225 | | public static String tryGetLayerPrefLocal(GpxData data, String key) { |
| 248 | public static String tryGetDataPrefLocal(IGpxLayerPrefs data, String key) { |
226 | 249 | return data != null ? data.getLayerPrefs().get(key) : null; |
227 | 250 | } |
228 | 251 | |
… |
… |
|
236 | 259 | String v = value == null ? null : value.toString(); |
237 | 260 | if (layers != null) { |
238 | 261 | for (GpxLayer l : layers) { |
239 | | putLayerPrefLocal(l.data, key, v); |
| 262 | putDataPrefLocal(l.data, key, v); |
240 | 263 | } |
241 | 264 | } else { |
242 | 265 | Config.getPref().put("draw.rawgps." + key, v); |
… |
… |
|
251 | 274 | */ |
252 | 275 | public static void putLayerPrefLocal(GpxLayer layer, String key, String value) { |
253 | 276 | if (layer == null) return; |
254 | | putLayerPrefLocal(layer.data, key, value); |
| 277 | putDataPrefLocal(layer.data, key, value); |
255 | 278 | } |
256 | 279 | |
257 | 280 | /** |
… |
… |
|
260 | 283 | * @param key the drawing key to be written, without "draw.rawgps." |
261 | 284 | * @param value the value or <code>null</code> to remove key |
262 | 285 | */ |
263 | | public static void putLayerPrefLocal(GpxData data, String key, String value) { |
| 286 | public static void putDataPrefLocal(IGpxLayerPrefs data, String key, String value) { |
| 287 | if (data == null) return; |
| 288 | data.setModified(true); |
264 | 289 | if (value == null || value.trim().isEmpty() || |
265 | 290 | (getLayerPref(null, key).equals(value) && DEFAULT_PREFS.get(key) != null && DEFAULT_PREFS.get(key).toString().equals(value))) { |
266 | 291 | data.getLayerPrefs().remove(key); |
diff --git a/trunk/src/org/openstreetmap/josm/io/session/MarkerSessionExporter.java b/trunk/src/org/openstreetmap/josm/io/session/MarkerSessionExporter.java
a
|
b
|
|
109 | 109 | */ |
110 | 110 | public void write(MarkerLayer layer) { |
111 | 111 | GpxData data = new GpxData(); |
| 112 | layer.data.getLayerPrefs().forEach((k, v) -> { |
| 113 | if (k != null && k.indexOf("markers.") == 0) { |
| 114 | data.getLayerPrefs().put(k, v); |
| 115 | } |
| 116 | }); |
112 | 117 | data.put(GpxData.META_DESC, "exported JOSM marker layer"); |
113 | 118 | for (Marker m : layer.data) { |
114 | 119 | data.waypoints.add(m.convertToWayPoint()); |
diff --git a/trunk/src/org/openstreetmap/josm/io/session/SessionReader.java b/trunk/src/org/openstreetmap/josm/io/session/SessionReader.java
a
|
b
|
|
3 | 3 | |
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; |
9 | 8 | import java.io.File; |
… |
… |
|
46 | 45 | import org.openstreetmap.josm.io.Compression; |
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; |
52 | 50 | import org.openstreetmap.josm.tools.MultiMap; |
… |
… |
|
619 | 617 | Logging.warn(ex); |
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); |
633 | 622 | } |
diff --git a/trunk/src/org/openstreetmap/josm/io/session/SessionWriter.java b/trunk/src/org/openstreetmap/josm/io/session/SessionWriter.java
a
|
b
|
|
43 | 43 | import org.openstreetmap.josm.gui.layer.geoimage.GeoImageLayer; |
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; |
49 | 48 | import org.openstreetmap.josm.tools.MultiMap; |
… |
… |
|
240 | 239 | if (!Utils.equalsEpsilon(layer.getOpacity(), 1.0)) { |
241 | 240 | el.setAttribute("opacity", Double.toString(layer.getOpacity())); |
242 | 241 | } |
243 | | if (layer.getColor() != null) { |
244 | | el.setAttribute("color", ColorHelper.color2html(layer.getColor())); |
245 | | } |
246 | 242 | Set<Layer> deps = dependencies.get(layer); |
247 | 243 | final String depends = deps == null ? "" : deps.stream().map(depLayer -> { |
248 | 244 | int depIndex = layers.indexOf(depLayer); |
diff --git a/trunk/test/data/sessions/gpx_markers.jos b/trunk/test/data/sessions/gpx_markers.jos
a
|
b
|
|
15 | 15 | <layer index="1" name="GPX layer name" type="tracks" version="0.1" visible="true"> |
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> |
21 | 21 | </layers> |
diff --git a/trunk/test/data/sessions/gpx_markers.joz b/trunk/test/data/sessions/gpx_markers.joz
GIT binary patch
literal 1636
zc$^FHW@Zs#;Nak3=q|eu#DD~ZfH)_yGPS5!-@s5mC9xz?FTJ2*Zji74V*`;r${*!*
z-Y;DKWAPSV7rz~Ey|gbVF$&$9ZC*J=XQS-Rwk7}Ta@(hgt#uIiIjQpVv$HnQbNW{~
zpHGO*F0p*va#rBQEt9oz(>LFq{r=|5H+!t?gkIO(xoDs+v-noimt)g@JYWCX`^)23
zd<Snxzc%EWbZhF5gTMDJD3M@$<ePsj?A~_emA#7^eJr2;_`%Vtf3bW2v6Zp@e-xLo
zzum+7!Ry-+Mk$*VgI^77;(FbB-$dQ6%kjwib!^PGO7FS6`*io~UyM`E+*+Vn%6mKP
zx|m+5o{w&A*Y|~mUlf(AR2OGoP-m{4CZGO5%T17LPtKC*S4DhG9=yuhC6p1cOGWjq
za>SLByb+GV4_p5nw|RL?@#-tTUqbrNROYXrmTsX~s4l78^R&C;L}CBtD8CbO>c>m8
ze`kGT<&5YFQ{fI5dv~zyIotZDx{O=4OMl^*E#$v0HX=V=$L;*4>L#Ij>qwpOpPKXE
zFKZ3^HE+j){5Kp`8;lLV$nEVcn~|;kB$`#!{&eKA3Jdcd(U*V3Os1-RRQMi$cgMBE
zbL(8gk6aJ<%N*d%&awE}Bf0sE3=9XD85jbHie4i`^oIE6&jCiS`>Fa3cMi|naQ1ke
zh-6XrQmsH`)v1f_#Z)MkFe=~Xe6xT3*=eyJx6dxSb8pYbJs)qh#eXerjdOSzWOnk9
zdQRhllPPg#uA6?8{XcnIXWgaK+;Lm}Hn!D1N}i%A;I@jT{%2Krv)z3=g%{B)dECM_
zUF57YTGp%ic2}Ro%~MXD$2Y0ZT(eR&c>b>+pO|juFF0<$bRB<ojAIISuNl{YD~nVu
z1706&z87(2*M)h-hM^nY{^4nj={)x?Z{3kJuf2Nd-*!*%2))o?IN$D0%>7jV0Pgi$
zZY?^Q5VPuZ1pnOZnViNfU(;A#__lrashYdE-0gGRze?kOa`*nPD>g2C_2{vw#6)i8
zOSLopwAbVn^}gD)vc<DNWJ2kNsJbJ}j~0EENX(J7bonBDE^DW|+8onmi{BLf%RiEI
zt~91oc11L6|AIGv+mowR9Fni_<t9#l;1d>f)rh?(&gCl)XIeYwG(UgNqF<+&mTz8L
zym*`PRzcGx?-C_1ut}<J(p}D6k!1c(^hopJFU|*)wk6H++fcvb2LH7Hnbw@UQeU)g
zR<5}`VL{WC{zJTxQ6IUM=>|ugX8c^+pS!2w?&eS#w!#zpimkTvo#Zw4k0=mNsQXnP
z)iF)Q=DJhCtwRC53wc_9i|(?x91lt(SwEbnKLMr@OICbogd2#9Q;Ul;^Yiqw@{5;F
zI+%UPK;r28L;u<*RL@@aYR#l;lPjb+cE6dmbiUp!Gu6)6zwf8J-CdQOyupG0es%wG
z{rFSUVwVPRAM=WRKI0gtTL5?LsjBIZ7vFZ1j1yDdc70oy&JDY7qW(!;-R**(+P4bb
zlg_=9$~UXwR-<FrZkhCtHqw_fXQi1e?Ju#5{F$}n*Q^(>QiZMNT`sYEZEKXXsY%;G
z^vA9hFYRwOe%j+Xr{(j^v?qKmrf%;YE%<G8{sbw1T(-2KQIctsPK()w6$d!pZAm<$
zT|To-T5iT0UY(z7=lp!?wDFeBdhy3OR>>-7!hhs%@cB6Tz5AVR-6s}D53fs5ikyDo
zXKF%7^&A=d!eWl>_h;h{d6>s|l)svv(>2lB)Gn-b#?kHXJEJn6uKu*o*!{rw@OxgY
zM`w1bOqp`$W5xB79+u=CEdsv;&GsHzXRdF)B;721hs7Uu-M`wmQa9D5r2Lp&{ScgM
zJ0+!+BY`m@2hO#OOd<@3I6=<QLJa5tvyevDj~v^m`tLJhD+SQ?BfE_oML#nON(u?^
RW@Q5l1K~~}J(U&20|2&tzI6Zq