### Eclipse Workspace Patch 1.0 #P core Index: src/org/openstreetmap/josm/actions/SaveSessionAction.java =================================================================== --- src/org/openstreetmap/josm/actions/SaveSessionAction.java (revision 0) +++ src/org/openstreetmap/josm/actions/SaveSessionAction.java (revision 0) @@ -0,0 +1,48 @@ +// License: GPL. For details, see LICENSE file. +package org.openstreetmap.josm.actions; + +import static org.openstreetmap.josm.gui.help.HelpUtil.ht; +import static org.openstreetmap.josm.tools.I18n.tr; + +import java.awt.event.ActionEvent; +import java.io.File; + +import org.openstreetmap.josm.gui.layer.Layer; +import org.openstreetmap.josm.io.SessionExporter; + +public class SaveSessionAction extends SaveActionBase { + + public SaveSessionAction() { + super(tr("Save Session"), "savesession", tr("Save the current session."), + null); + putValue("help", ht("/Action/Save")); + } + + @Override + public void actionPerformed(ActionEvent arg0) { + doSave(); + + } + + @Override + public boolean doSave() { + File file = createAndOpenSaveFileChooser(tr("Save Session file"), "jos"); + + + SessionExporter exporter = new SessionExporter(); + + exporter.exportData(file); + + return true; + + + + } + + @Override + protected File getFile(Layer layer) { + // TODO Auto-generated method stub + return null; + } + +} Index: src/org/openstreetmap/josm/io/AllFormatsImporter.java =================================================================== --- src/org/openstreetmap/josm/io/AllFormatsImporter.java (revision 3616) +++ src/org/openstreetmap/josm/io/AllFormatsImporter.java (working copy) @@ -12,8 +12,8 @@ */ public class AllFormatsImporter extends FileImporter { public AllFormatsImporter() { - super(new ExtensionFileFilter("osm,xml,osm.gz,osm.bz2,osm.bz,gpx,gpx.gz,nmea,nme,nma,log,txt,wms,jpg", "", tr("All Formats") - + " (*.gpx *.osm *.nmea *.jpg ...)")); + super(new ExtensionFileFilter("osm,xml,osm.gz,osm.bz2,osm.bz,gpx,gpx.gz,nmea,nme,nma,log,txt,wms,jpg,jos", "", tr("All Formats") + + " (*.gpx *.osm *.nmea *.jpg ...)")); } @Override public boolean acceptFile(File pathname) { return false; Index: src/org/openstreetmap/josm/io/FileImporter.java =================================================================== --- src/org/openstreetmap/josm/io/FileImporter.java (revision 3616) +++ src/org/openstreetmap/josm/io/FileImporter.java (working copy) @@ -12,11 +12,13 @@ import org.openstreetmap.josm.Main; import org.openstreetmap.josm.actions.ExtensionFileFilter; import org.openstreetmap.josm.gui.HelpAwareOptionPane; +import org.openstreetmap.josm.gui.layer.Layer; import org.openstreetmap.josm.gui.progress.ProgressMonitor; public abstract class FileImporter implements Comparable { public final ExtensionFileFilter filter; + protected Layer layer; public FileImporter(ExtensionFileFilter filter) { this.filter = filter; @@ -94,4 +96,12 @@ return (new Double(this.getPriority())).compareTo(other.getPriority()); } + /* + * Returns the created layer + */ + public Layer getLayer() { + // TODO Auto-generated method stub + return layer; + } + } Index: src/org/openstreetmap/josm/io/GpxImporter.java =================================================================== --- src/org/openstreetmap/josm/io/GpxImporter.java (revision 3616) +++ src/org/openstreetmap/josm/io/GpxImporter.java (working copy) @@ -40,6 +40,7 @@ final boolean parsedProperly = r.parse(true); r.data.storageFile = file; final GpxLayer gpxLayer = new GpxLayer(r.data, fn, true); + this.layer=gpxLayer; // FIXME: remove UI stuff from the IO subsystem // Index: src/org/openstreetmap/josm/io/OsmImporter.java =================================================================== --- src/org/openstreetmap/josm/io/OsmImporter.java (revision 3616) +++ src/org/openstreetmap/josm/io/OsmImporter.java (working copy) @@ -14,6 +14,7 @@ import org.openstreetmap.josm.Main; import org.openstreetmap.josm.actions.ExtensionFileFilter; import org.openstreetmap.josm.data.osm.DataSet; +import org.openstreetmap.josm.gui.layer.Layer; import org.openstreetmap.josm.gui.layer.OsmDataLayer; import org.openstreetmap.josm.gui.progress.NullProgressMonitor; import org.openstreetmap.josm.gui.progress.ProgressMonitor; @@ -41,6 +42,7 @@ protected void importData(InputStream in, File associatedFile) throws IllegalDataException { DataSet dataSet = OsmReader.parseDataSet(in, NullProgressMonitor.INSTANCE); final OsmDataLayer layer = new OsmDataLayer(dataSet, associatedFile.getName(), associatedFile); + this.layer=layer; // FIXME: remove UI stuff from IO subsystem // Runnable uiStuff = new Runnable() { @@ -55,4 +57,10 @@ SwingUtilities.invokeLater(uiStuff); } } + + + @Override + public Layer getLayer() { + return layer; + } } Index: src/org/openstreetmap/josm/io/SessionWriter.java =================================================================== --- src/org/openstreetmap/josm/io/SessionWriter.java (revision 0) +++ src/org/openstreetmap/josm/io/SessionWriter.java (revision 0) @@ -0,0 +1,127 @@ +// License: GPL. For details, see LICENSE file. +package org.openstreetmap.josm.io; + +import java.io.PrintWriter; +import java.util.Collection; + +import org.openstreetmap.josm.Main; +import org.openstreetmap.josm.data.ProjectionBounds; +import org.openstreetmap.josm.gui.layer.GpxLayer; +import org.openstreetmap.josm.gui.layer.Layer; +import org.openstreetmap.josm.gui.layer.OsmDataLayer; +import org.openstreetmap.josm.gui.layer.geoimage.GeoImageLayer; +import org.openstreetmap.josm.gui.layer.geoimage.ImageEntry; + +public class SessionWriter extends XmlWriter { + + public SessionWriter(PrintWriter out) { + super(out); + // TODO Auto-generated constructor stub + } + + public void header() { + out.println(""); + out.print(""); + } + + public void writeView() { + + // What is the center? + ProjectionBounds box = Main.map.mapView.getProjectionBounds(); + + out.print(""); + } + + public void writeLayers() { + // Do we have layers? + Collection layers = null; + layers = Main.map.mapView.getAllLayers(); + + for (Layer layer: layers) + { + if (layer instanceof OsmDataLayer) { + writeOsmLayer(layer); + } + if (layer instanceof GpxLayer) { + writeGpxLayer(layer); + } + if (layer instanceof GeoImageLayer) { + writeGeoImageLayer(layer); + } + } + + } + + private void writeGeoImageLayer(Layer layer) { + GeoImageLayer geoImageLayer = (GeoImageLayer) layer; + out.print(""); + for (ImageEntry image: geoImageLayer.getImages()) { + out.print(""); + } + out.println(""); + } + + private void writeGenericLayer(String type, Layer layer) { + out.print("<"); + out.print(type); + out.print(" name='"); + out.print(layer.getAssociatedFile().getPath()); + out.print("'"); + out.print(" visible='"); + if (layer.isVisible()) { + out.print("yes"); + } + out.print("'"); + if (layer == Main.map.mapView.getActiveLayer()) { + out.print(" active='yes'"); + } + out.println(" />"); } + + + private void writeGpxLayer(Layer layer) { + writeGenericLayer("gpxlayer", layer); + } + + private void writeOsmLayer(Layer layer) { + writeGenericLayer("osmlayer", layer); + + } + + public void footer() { + out.println(""); + } + + public void close() { + out.close(); + } + + + +} + Index: src/org/openstreetmap/josm/gui/layer/geoimage/GeoImageLayer.java =================================================================== --- src/org/openstreetmap/josm/gui/layer/geoimage/GeoImageLayer.java (revision 3616) +++ src/org/openstreetmap/josm/gui/layer/geoimage/GeoImageLayer.java (working copy) @@ -258,9 +258,9 @@ } } - public static void create(Collection files, GpxLayer gpxLayer) { + public static Layer create(Collection files, GpxLayer gpxLayer) { Loader loader = new Loader(files, gpxLayer); - Main.worker.execute(loader); + return loader.layer; } private GeoImageLayer(final List data, GpxLayer gpxLayer) { @@ -799,4 +799,8 @@ } return copy; } + + public Layer getGpxLayer() { + return gpxLayer; + } } Index: src/org/openstreetmap/josm/io/SessionExporter.java =================================================================== --- src/org/openstreetmap/josm/io/SessionExporter.java (revision 0) +++ src/org/openstreetmap/josm/io/SessionExporter.java (revision 0) @@ -0,0 +1,56 @@ +// License: GPL. For details, see LICENSE file. +package org.openstreetmap.josm.io; + +import static org.openstreetmap.josm.tools.I18n.tr; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.io.Writer; + +import javax.swing.JOptionPane; + +import org.openstreetmap.josm.Main; +import org.openstreetmap.josm.actions.ExtensionFileFilter; + +public class SessionExporter extends FileExporter { + + public SessionExporter() { + super(new ExtensionFileFilter("jos", "jos", tr("JOSM Session Files") + " (*.jos)")); + } + + public void exportData(File file) { + try { + OutputStream out = getOutputStream(file); + Writer writer = new OutputStreamWriter(out, "UTF-8"); + + SessionWriter w = new SessionWriter(new PrintWriter(writer)); + + w.header(); + w.writeView(); + w.writeLayers(); + w.footer(); + w.close(); + + } catch (IOException e) { + e.printStackTrace(); + JOptionPane.showMessageDialog( + Main.parent, + tr("An error occurred while saving.
Error is:
{0}", e.getMessage()), + tr("Error"), + JOptionPane.ERROR_MESSAGE + ); + + } + } + + protected OutputStream getOutputStream(File file) throws FileNotFoundException, IOException { + return new FileOutputStream(file); + } + +} + Index: src/org/openstreetmap/josm/io/SessionReader.java =================================================================== --- src/org/openstreetmap/josm/io/SessionReader.java (revision 0) +++ src/org/openstreetmap/josm/io/SessionReader.java (revision 0) @@ -0,0 +1,264 @@ +// License: GPL. For details, see LICENSE file. +package org.openstreetmap.josm.io; + +import static org.openstreetmap.josm.tools.I18n.tr; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParserFactory; + +import org.openstreetmap.josm.Main; +import org.openstreetmap.josm.actions.ExtensionFileFilter; +import org.openstreetmap.josm.data.ProjectionBounds; +import org.openstreetmap.josm.data.coor.EastNorth; +import org.openstreetmap.josm.gui.layer.GpxLayer; +import org.openstreetmap.josm.gui.layer.Layer; +import org.openstreetmap.josm.gui.layer.geoimage.GeoImageLayer; +import org.openstreetmap.josm.gui.progress.NullProgressMonitor; +import org.openstreetmap.josm.gui.progress.ProgressMonitor; +import org.openstreetmap.josm.tools.CheckParameterUtil; +import org.xml.sax.Attributes; +import org.xml.sax.InputSource; +import org.xml.sax.Locator; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; +import org.xml.sax.helpers.DefaultHandler; + +public class SessionReader { + + private class Parser extends DefaultHandler { + // Global attributes + private Locator locator; + private Layer activeLayer; + private final List layers = new ArrayList(); + private final List tmpLayers = new ArrayList(); + private ProjectionBounds box; + + // per-layer attributes + private String layerName; + private boolean active; + private boolean visible; + private Collection files = new ArrayList(); + public String parentLayerName; + public String layerType=""; + + @Override + public void setDocumentLocator(Locator locator) { + this.locator = locator; + } + + @Override public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException { + + try { + if (qName.equals("view")) { + EastNorth min = new EastNorth(Double.parseDouble(atts.getValue("minEast")), Double.parseDouble(atts.getValue("minNorth"))); + EastNorth max = new EastNorth(Double.parseDouble(atts.getValue("maxEast")), Double.parseDouble(atts.getValue("maxNorth"))); + this.box = new ProjectionBounds(min, max); + } else if (qName.equals("osmlayer") || qName.equals("gpxlayer") || qName.equals("geoimagelayer")) { + newLayerCleanup(); + initLayer(qName, atts); + } else if (qName.equals("image")) { + String fileName = atts.getValue("name"); + File file = new File(fileName); + files.add(file); + } else { + System.out.println(tr("Undefined element ''{0}'' found in input stream. Skipping.", qName)); + } + } catch (Exception e) { + throw new SAXParseException(e.getMessage(), locator, e); + } + } + + private void initLayer(String qName, Attributes atts) { + String key; + layerType = qName; + layerName = atts.getValue("name"); + visible = false; + key = atts.getValue("visible"); + if (key !=null){ + visible = key.equals("yes"); + } + active = false; + key = atts.getValue("active"); + if (key !=null){ + active = key.equals("yes"); + } + parentLayerName = atts.getValue("gpxlayer"); + + } + + private void newLayerCleanup() { + if (layerType.equals("osmlayer")) { + loadGenericLayer(); + } + else if (layerType.equals("gpxlayer")) { + Layer layer = null; + for (Layer existingLayer: tmpLayers) { + if (existingLayer.getAssociatedFile().getAbsolutePath().equals(layerName)) { + layer = existingLayer; + break; + } + } + if (layer == null) { + // If not found create + loadGenericLayer(); + } else { + // If already loaded (as part of audio or images) put it in the main list + this.tmpLayers.remove(layer); + this.layers.add(layer); + } + } + else if (layerType.equals("geoimagelayer")) { + loadImageLayer(); + } + } + private void loadImageLayer() { + Layer gpxLayer=null; + + + // Look for parent layer + for (Layer existingLayer: layers) { + if (existingLayer.getAssociatedFile().getAbsolutePath().equals(parentLayerName)) { + gpxLayer=existingLayer; + break; + } + } + + // Load it if not existing + if (gpxLayer == null) { + gpxLayer=importLayer(parentLayerName); + this.tmpLayers.add(gpxLayer); + } + + Layer layer = GeoImageLayer.create(files, (GpxLayer)gpxLayer); + + + + /*JpgImporter importer = new JpgImporter((GpxLayer)layer); + try { + importer.importData(files, NullProgressMonitor.INSTANCE); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IllegalDataException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + layer=importer.getLayer();*/ + // FIXME : sometimes layer is null + if (layer != null) { + layer.setVisible(visible); + } + if (active) { + this.activeLayer=layer; + } + this.layers.add(layer); + + + } + + private void loadGenericLayer() { + Layer layer = importLayer(layerName); + this.layers.add(layer); + } + + private Layer importLayer(String fileName) { + Layer layer = null; + File file = new File(fileName); + FileImporter importer = null; + for (FileImporter imp : ExtensionFileFilter.importers) { + if (imp.acceptFile(file)) { + importer=imp; + break; + } + } + + if (importer != null) { + try { + importer.importData(file, NullProgressMonitor.INSTANCE); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IllegalDataException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + layer=importer.getLayer(); + layer.setVisible(visible); + if (active) { + this.activeLayer=layer; + } + } + return layer; + } + + public void manageLayers(){ + int i=0; + for (Layer layer: this.layers) { + // FIXME: sometime layer is not yet in main list + if (Main.map.mapView.getAllLayersAsList().indexOf(layer)>-1) { + Main.map.mapView.moveLayer(layer, i); + } + i+=1; + } + + if (this.activeLayer != null) { + Main.map.mapView.setActiveLayer(activeLayer); + } + } + + public void manageView() { + + Main.map.mapView.zoomTo(this.box); + + } + } + + public static void parseDataSet(InputStream source, ProgressMonitor progressMonitor) throws IllegalDataException { + if (progressMonitor == null) { + progressMonitor = NullProgressMonitor.INSTANCE; + } + CheckParameterUtil.ensureParameterNotNull(source, "source"); + SessionReader reader = new SessionReader(); + try { + progressMonitor.beginTask(tr("Prepare Session data...", 2)); + progressMonitor.indeterminateSubTask(tr("Parsing Session data...")); + + InputSource inputSource = new InputSource(UTFInputStreamReader.create(source, "UTF-8")); + Parser parser = reader.new Parser(); + SAXParserFactory.newInstance().newSAXParser().parse(inputSource, parser); + parser.newLayerCleanup(); + // FIXME: for some reason we have to wait or we get an exception as some layer not being in the list + // when calling Main.map.mapView.moveLayer + try { + Thread.currentThread(); + Thread.sleep(1000); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + parser.manageLayers(); + progressMonitor.worked(1); + parser.manageView(); + progressMonitor.worked(1); + } catch(ParserConfigurationException e) { + throw new IllegalDataException(e.getMessage(), e); + } catch (SAXParseException e) { + throw new IllegalDataException(tr("Line {0} column {1}: ", e.getLineNumber(), e.getColumnNumber()) + e.getMessage(), e); + } catch(SAXException e) { + throw new IllegalDataException(e.getMessage(), e); + } catch(Exception e) { + throw new IllegalDataException(e); + } finally { + progressMonitor.finishTask(); + } + } + + +} Index: src/org/openstreetmap/josm/actions/ExtensionFileFilter.java =================================================================== --- src/org/openstreetmap/josm/actions/ExtensionFileFilter.java (revision 3616) +++ src/org/openstreetmap/josm/actions/ExtensionFileFilter.java (working copy) @@ -44,6 +44,7 @@ "org.openstreetmap.josm.io.NMEAImporter", "org.openstreetmap.josm.io.OsmBzip2Importer", "org.openstreetmap.josm.io.JpgImporter", + "org.openstreetmap.josm.io.SessionImporter", "org.openstreetmap.josm.io.AllFormatsImporter" }; Index: src/org/openstreetmap/josm/io/SessionImporter.java =================================================================== --- src/org/openstreetmap/josm/io/SessionImporter.java (revision 0) +++ src/org/openstreetmap/josm/io/SessionImporter.java (revision 0) @@ -0,0 +1,41 @@ +// License: GPL. For details, see LICENSE file. +package org.openstreetmap.josm.io; + +import static org.openstreetmap.josm.tools.I18n.tr; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; + +import org.openstreetmap.josm.actions.ExtensionFileFilter; +import org.openstreetmap.josm.gui.progress.NullProgressMonitor; +import org.openstreetmap.josm.gui.progress.ProgressMonitor; + +public class SessionImporter extends FileImporter { + + public SessionImporter() { + super(new ExtensionFileFilter("jos", "jos", tr("OSM Session Files") + " (*.jos)")); + } + + public SessionImporter(ExtensionFileFilter filter) { + super(filter); + } + + @Override public void importData(File file, ProgressMonitor progressMonitor) throws IOException, IllegalDataException { + try { + FileInputStream in = new FileInputStream(file); + importData(in, file); + } catch (FileNotFoundException e) { + e.printStackTrace(); + throw new IOException(tr("File ''{0}'' does not exist.", file.getName())); + } + } + + protected void importData(InputStream in, File associatedFile) throws IllegalDataException { + SessionReader.parseDataSet(in, NullProgressMonitor.INSTANCE); + } + +} + Index: images/savesession.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: images/savesession.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: src/org/openstreetmap/josm/gui/MainMenu.java =================================================================== --- src/org/openstreetmap/josm/gui/MainMenu.java (revision 3616) +++ src/org/openstreetmap/josm/gui/MainMenu.java (working copy) @@ -59,6 +59,7 @@ import org.openstreetmap.josm.actions.ReverseWayAction; import org.openstreetmap.josm.actions.SaveAction; import org.openstreetmap.josm.actions.SaveAsAction; +import org.openstreetmap.josm.actions.SaveSessionAction; import org.openstreetmap.josm.actions.SelectAllAction; import org.openstreetmap.josm.actions.ShowStatusReportAction; import org.openstreetmap.josm.actions.SimplifyWayAction; @@ -103,6 +104,7 @@ public final OpenLocationAction openLocation = new OpenLocationAction(); public final JosmAction save = new SaveAction(); public final JosmAction saveAs = new SaveAsAction(); + public final JosmAction saveSession = new SaveSessionAction(); public final JosmAction gpxExport = new GpxExportAction(); public final DownloadAction download = new DownloadAction(); public final DownloadPrimitiveAction downloadPrimitive = new DownloadPrimitiveAction(); @@ -224,6 +226,7 @@ fileMenu.addSeparator(); add(fileMenu, save); add(fileMenu, saveAs); + add(fileMenu, saveSession); add(fileMenu, gpxExport); fileMenu.addSeparator(); add(fileMenu, download); Index: src/org/openstreetmap/josm/io/JpgImporter.java =================================================================== --- src/org/openstreetmap/josm/io/JpgImporter.java (revision 3616) +++ src/org/openstreetmap/josm/io/JpgImporter.java (working copy) @@ -47,7 +47,7 @@ if (files.isEmpty()) throw new IOException(tr("No image files found.")); - GeoImageLayer.create(files, gpx); + layer = GeoImageLayer.create(files, gpx); } finally { progressMonitor.finishTask(); }