Changeset 17 in josm for src


Ignore:
Timestamp:
2005-10-09T04:14:40+02:00 (19 years ago)
Author:
imi
Message:
  • added Layer support
  • added support for raw GPS data
  • fixed tooltips
  • added options for loading gpx files
Location:
src/org/openstreetmap/josm
Files:
10 added
1 deleted
31 edited

Legend:

Unmodified
Added
Removed
  • src/org/openstreetmap/josm/actions/ExitAction.java

    r11 r17  
    55
    66import javax.swing.AbstractAction;
    7 import javax.swing.ImageIcon;
    87
    9 import org.openstreetmap.josm.gui.Main;
     8import org.openstreetmap.josm.gui.ImageProvider;
    109
    1110/**
     
    2019         */
    2120        public ExitAction() {
    22                 super("Exit", new ImageIcon(Main.class.getResource("/images/exit.png")));
     21                super("Exit", ImageProvider.get("exit"));
    2322                putValue(MNEMONIC_KEY, KeyEvent.VK_X);
     23                putValue(SHORT_DESCRIPTION, "Exit the application.");
    2424        }
    2525       
  • src/org/openstreetmap/josm/actions/OpenGpxAction.java

    r16 r17  
    11package org.openstreetmap.josm.actions;
    22
     3import java.awt.GridBagLayout;
    34import java.awt.event.ActionEvent;
    45import java.awt.event.KeyEvent;
     
    89
    910import javax.swing.AbstractAction;
    10 import javax.swing.ImageIcon;
     11import javax.swing.Box;
     12import javax.swing.JCheckBox;
    1113import javax.swing.JFileChooser;
     14import javax.swing.JLabel;
    1215import javax.swing.JOptionPane;
     16import javax.swing.JPanel;
    1317import javax.swing.filechooser.FileFilter;
    1418
    1519import org.openstreetmap.josm.data.osm.DataSet;
     20import org.openstreetmap.josm.gui.GBC;
     21import org.openstreetmap.josm.gui.ImageProvider;
    1622import org.openstreetmap.josm.gui.Main;
    1723import org.openstreetmap.josm.gui.MapFrame;
     24import org.openstreetmap.josm.gui.layer.Layer;
     25import org.openstreetmap.josm.gui.layer.LayerFactory;
    1826import org.openstreetmap.josm.io.GpxReader;
    1927import org.openstreetmap.josm.io.DataReader.ConnectionException;
     
    3240         */
    3341        public OpenGpxAction() {
    34                 super("Open GPX", new ImageIcon(Main.class.getResource("/images/opengpx.png")));
     42                super("Open GPX", ImageProvider.get("opengpx"));
    3543                putValue(MNEMONIC_KEY, KeyEvent.VK_O);
     44                putValue(SHORT_DESCRIPTION, "Open a file in GPX format.");
    3645        }
    3746
     
    4857                                return "GPX or XML Files";
    4958                        }});
    50                 fc.showOpenDialog(Main.main);
     59               
     60                // additional options
     61                JCheckBox rawGps = new JCheckBox("Raw GPS data", true);
     62                rawGps.setToolTipText("Check this, if the data are obtained from a gps device.");
     63                JCheckBox newLayer = new JCheckBox("As Layer", true);
     64                newLayer.setToolTipText("Open as a new layer or replace all current layers.");
     65                if (Main.main.getMapFrame() == null) {
     66                        newLayer.setEnabled(false);
     67                        newLayer.setSelected(false);
     68                }
     69               
     70                JPanel p = new JPanel(new GridBagLayout());
     71                p.add(new JLabel("Options"), GBC.eop());
     72                p.add(rawGps, GBC.eol());
     73                p.add(newLayer, GBC.eol());
     74                p.add(Box.createVerticalGlue(), GBC.eol().fill());
     75                fc.setAccessory(p);
     76
     77                if (fc.showOpenDialog(Main.main) != JFileChooser.APPROVE_OPTION)
     78                        return;
     79               
    5180                File gpxFile = fc.getSelectedFile();
    5281                if (gpxFile == null)
     
    5483               
    5584                try {
    56                         DataSet dataSet = new GpxReader(new FileReader(gpxFile)).parse();
    57                         MapFrame map = new MapFrame(dataSet);
    58                         Main.main.setMapFrame(gpxFile.getName(), map);
     85                        DataSet dataSet = new GpxReader(new FileReader(gpxFile), rawGps.isSelected()).parse();
     86
     87                        Layer layer = LayerFactory.create(dataSet, gpxFile.getName(), rawGps.isSelected());
     88                       
     89                        if (Main.main.getMapFrame() == null || !newLayer.isSelected())
     90                                Main.main.setMapFrame(gpxFile.getName(), new MapFrame(layer));
     91                        else
     92                                Main.main.getMapFrame().mapView.addLayer(layer);
     93                       
    5994                } catch (ParseException x) {
    6095                        x.printStackTrace();
  • src/org/openstreetmap/josm/actions/PreferencesAction.java

    r11 r17  
    55
    66import javax.swing.AbstractAction;
    7 import javax.swing.ImageIcon;
    87
    9 import org.openstreetmap.josm.gui.Main;
     8import org.openstreetmap.josm.gui.ImageProvider;
    109import org.openstreetmap.josm.gui.PreferenceDialog;
    1110
     
    2120         */
    2221        public PreferencesAction() {
    23                 super("Preferences", new ImageIcon(Main.class.getResource("/images/preference.png")));
     22                super("Preferences", ImageProvider.get("preference"));
    2423                putValue(MNEMONIC_KEY, KeyEvent.VK_P);
     24                putValue(SHORT_DESCRIPTION, "Open a preferences page for global settings.");
    2525        }
    2626
  • src/org/openstreetmap/josm/actions/SaveGpxAction.java

    r16 r17  
    88
    99import javax.swing.AbstractAction;
    10 import javax.swing.ImageIcon;
    1110import javax.swing.JFileChooser;
    1211import javax.swing.JOptionPane;
    1312
     13import org.openstreetmap.josm.gui.ImageProvider;
    1414import org.openstreetmap.josm.gui.Main;
    1515import org.openstreetmap.josm.io.GpxWriter;
     
    2828         */
    2929        public SaveGpxAction() {
    30                 super("Save GPX", new ImageIcon(Main.class.getResource("/images/savegpx.png")));
     30                super("Save GPX", ImageProvider.get("savegpx"));
    3131                putValue(MNEMONIC_KEY, KeyEvent.VK_S);
     32                putValue(SHORT_DESCRIPTION, "Save the current active layer as GPX file.");
    3233        }
    3334       
     
    4647                try {
    4748                        FileWriter fileWriter = new FileWriter(gpxFile);
    48                         GpxWriter out = new GpxWriter(fileWriter, Main.main.getMapFrame().mapView.dataSet);
     49                        GpxWriter out = new GpxWriter(fileWriter, Main.main.getMapFrame().mapView.getActiveDataSet());
    4950                        out.output();
    5051                        fileWriter.close();
  • src/org/openstreetmap/josm/actions/mapmode/AddLineSegmentAction.java

    r16 r17  
    1010import javax.swing.JOptionPane;
    1111
     12import org.openstreetmap.josm.data.osm.DataSet;
    1213import org.openstreetmap.josm.data.osm.LineSegment;
    1314import org.openstreetmap.josm.data.osm.Node;
     
    129130               
    130131                if (start != end) {
     132                        DataSet ds = mv.getActiveDataSet();
     133
    131134                        // try to find a line segment
    132135                        for (Track t : ds.tracks())
     
    183186                hintDrawn = !hintDrawn;
    184187        }
     188
     189        @Override
     190        protected boolean isEditMode() {
     191                return true;
     192        }
    185193}
  • src/org/openstreetmap/josm/actions/mapmode/AddNodeAction.java

    r16 r17  
    2424         */
    2525        public AddNodeAction(MapFrame mapFrame) {
    26                 super("Add nodes", "addnode", "Add new nodes to the map.", KeyEvent.VK_A, mapFrame);
     26                super("Add nodes", "addnode", "Add nodes to the map.", KeyEvent.VK_N, mapFrame);
    2727        }
    2828
     
    4848                        Node node = new Node();
    4949                        node.coor = mv.getPoint(e.getX(), e.getY(), true);
    50                         ds.nodes.add(node);
     50                        mv.getActiveDataSet().nodes.add(node);
    5151                        mv.repaint();
    5252                }
    5353        }
     54
     55        @Override
     56        protected boolean isEditMode() {
     57                return true;
     58        }
    5459}
  • src/org/openstreetmap/josm/actions/mapmode/AddTrackAction.java

    r16 r17  
    66import java.util.LinkedList;
    77
     8import org.openstreetmap.josm.data.osm.DataSet;
    89import org.openstreetmap.josm.data.osm.LineSegment;
    910import org.openstreetmap.josm.data.osm.OsmPrimitive;
     
    7576                        return; // not allowed together
    7677
     78                DataSet ds = mv.getActiveDataSet();
     79               
    7780                if (!ctrl && !shift)
    7881                        ds.clearSelection(); // new selection will replace the old.
     
    105108                ds.clearSelection();
    106109        }
     110
     111        @Override
     112        protected boolean isEditMode() {
     113                return true;
     114        }
    107115}
  • src/org/openstreetmap/josm/actions/mapmode/CombineAction.java

    r16 r17  
    99import javax.swing.JOptionPane;
    1010
     11import org.openstreetmap.josm.data.osm.DataSet;
    1112import org.openstreetmap.josm.data.osm.LineSegment;
    1213import org.openstreetmap.josm.data.osm.Node;
     
    8283                mv.addMouseListener(this);
    8384                mv.addMouseMotionListener(this);
    84                 ds.clearSelection();
     85                mv.getActiveDataSet().clearSelection();
    8586        }
    8687
     
    165166                                else   
    166167                                        t1.keys.putAll(t2.keys);
    167                                 ds.removeTrack(t2);
     168                                mv.getActiveDataSet().removeTrack(t2);
    168169                        }
    169170                }
     
    178179         */
    179180        private void combine(LineSegment ls, Track t) {
     181                DataSet ds = mv.getActiveDataSet();
    180182                if (!ds.pendingLineSegments().contains(ls))
    181183                        throw new IllegalStateException("Should not be able to select non-pending line segments.");
     
    216218                        Point start = mv.getScreenPoint(ls.getStart().coor);
    217219                        Point end = mv.getScreenPoint(ls.getEnd().coor);
    218                         if (mv.dataSet.pendingLineSegments().contains(osm) && g.getColor() == Color.GRAY)
     220                        if (mv.getActiveDataSet().pendingLineSegments().contains(osm) && g.getColor() == Color.GRAY)
    219221                                g.drawLine(start.x, start.y, end.x, end.y);
    220222                        else
     
    225227                }
    226228        }
     229
     230        @Override
     231        protected boolean isEditMode() {
     232                return true;
     233        }
    227234}
  • src/org/openstreetmap/josm/actions/mapmode/DeleteAction.java

    r16 r17  
    1010import javax.swing.JOptionPane;
    1111
     12import org.openstreetmap.josm.data.osm.DataSet;
    1213import org.openstreetmap.josm.data.osm.Key;
    1314import org.openstreetmap.josm.data.osm.LineSegment;
     
    9394                        return;
    9495
     96                DataSet ds = mv.getActiveDataSet();
     97
    9598                if ((e.getModifiersEx() & MouseEvent.CTRL_DOWN_MASK) != 0)
    96                         deleteWithReferences(sel);
     99                        deleteWithReferences(sel, ds);
    97100                else
    98                         delete(sel);
     101                        delete(sel, ds);
    99102
    100103                mv.repaint();
     
    126129         * @param osm The object to delete.
    127130         */
    128         private void deleteWithReferences(OsmPrimitive osm) {
     131        private void deleteWithReferences(OsmPrimitive osm, DataSet ds) {
    129132                // collect all tracks, areas and pending line segments that should be deleted
    130133                ArrayList<Track> tracksToDelete = new ArrayList<Track>();
     
    172175                // removing all unreferenced nodes
    173176                for (Node n : checkUnreferencing) {
    174                         if (!isReferenced(n))
     177                        if (!isReferenced(n, ds))
    175178                                ds.nodes.remove(n);
    176179                }
     
    187190         * @param osm The object to delete.
    188191         */
    189         private void delete(OsmPrimitive osm) {
     192        private void delete(OsmPrimitive osm, DataSet ds) {
    190193                if (osm instanceof Node) {
    191194                        Node n = (Node)osm;
    192                         if (isReferenced(n)) {
    193                                 String combined = combine(n);
     195                        if (isReferenced(n, ds)) {
     196                                String combined = combine(n, ds);
    194197                                if (combined != null) {
    195198                                        JOptionPane.showMessageDialog(Main.main, combined);
     
    222225         * @return Whether the node is used by a track or area.
    223226         */
    224         private boolean isReferenced(Node n) {
     227        private boolean isReferenced(Node n, DataSet ds) {
    225228                for (Track t : ds.tracks())
    226229                        for (LineSegment ls : t.segments())
     
    243246         *              are problems combining the node.
    244247         */
    245         private String combine(Node n) {
     248        private String combine(Node n, DataSet ds) {
    246249                // first, check for pending line segments
    247250                for (LineSegment ls : ds.pendingLineSegments())
     
    365368                return first;
    366369        }
     370
     371        @Override
     372        protected boolean isEditMode() {
     373                return true;
     374        }
    367375}
  • src/org/openstreetmap/josm/actions/mapmode/MapMode.java

    r16 r17  
    77
    88import javax.swing.AbstractAction;
    9 import javax.swing.ImageIcon;
    109import javax.swing.JComponent;
    1110import javax.swing.KeyStroke;
    1211
    13 import org.openstreetmap.josm.data.osm.DataSet;
    14 import org.openstreetmap.josm.gui.Main;
     12import org.openstreetmap.josm.gui.ImageProvider;
    1513import org.openstreetmap.josm.gui.MapFrame;
    1614import org.openstreetmap.josm.gui.MapView;
     15import org.openstreetmap.josm.gui.MapView.LayerChangeListener;
     16import org.openstreetmap.josm.gui.layer.Layer;
    1717
    1818/**
     
    3434         */
    3535        protected final MapView mv;
    36         /**
    37          * Shortcut to the DataSet.
    38          */
    39         protected final DataSet ds;
    4036
    4137        /**
     
    4642         */
    4743        public MapMode(String name, String iconName, String tooltip, int mnemonic, MapFrame mapFrame) {
    48                 super(name, new ImageIcon(Main.class.getResource("/images/mapmode/"+iconName+".png")));
     44                super(name, ImageProvider.get("mapmode", iconName));
    4945                putValue(MNEMONIC_KEY, mnemonic);
    5046                putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(mnemonic,0));
     
    5450                this.mapFrame = mapFrame;
    5551                mv = mapFrame.mapView;
    56                 ds = mv.dataSet;
     52                mv.addLayerChangeListener(new LayerChangeListener(){
     53                        public void activeLayerChange(Layer oldLayer, Layer newLayer) {
     54                                setEnabled(!isEditMode() || newLayer.isEditable());
     55                        }
     56                        public void layerAdded(Layer newLayer) {}
     57                        public void layerRemoved(Layer oldLayer) {}
     58                });
    5759        }
    58        
     60
     61        /**
     62         * Subclasses should return whether they want to edit the map data or
     63         * whether they are read-only.
     64         */
     65        abstract protected boolean isEditMode();
     66
    5967        /**
    6068         * Register all listener to the mapView
  • src/org/openstreetmap/josm/actions/mapmode/MoveAction.java

    r16 r17  
    88import java.util.HashSet;
    99
     10import org.openstreetmap.josm.data.osm.DataSet;
    1011import org.openstreetmap.josm.data.osm.Node;
    1112import org.openstreetmap.josm.data.osm.OsmPrimitive;
     
    7980                        return;
    8081
    81                 Collection<OsmPrimitive> selection = ds.getSelected();
     82                Collection<OsmPrimitive> selection = mv.getActiveDataSet().getSelected();
    8283                // creating a list of all nodes that should be moved.
    8384                Collection<Node> movingNodes = new HashSet<Node>();
     
    110111                        return;
    111112
     113                DataSet ds = mv.getActiveDataSet();
     114
    112115                if (ds.getSelected().size() == 0) {
    113116                        OsmPrimitive osm = mv.getNearest(e.getPoint(), (e.getModifiersEx() & MouseEvent.ALT_DOWN_MASK) != 0);
     
    131134                mv.setCursor(oldCursor);
    132135                if (singleOsmPrimitive != null) {
    133                         singleOsmPrimitive.setSelected(false, ds);
     136                        singleOsmPrimitive.setSelected(false, mv.getActiveDataSet());
    134137                        mv.repaint();
    135138                }
    136139        }
     140
     141        @Override
     142        protected boolean isEditMode() {
     143                return true;
     144        }
    137145}
  • src/org/openstreetmap/josm/actions/mapmode/SelectionAction.java

    r16 r17  
    55import java.util.Collection;
    66
     7import org.openstreetmap.josm.data.osm.DataSet;
    78import org.openstreetmap.josm.data.osm.OsmPrimitive;
    89import org.openstreetmap.josm.gui.MapFrame;
     
    8687                        return; // not allowed together
    8788
     89                DataSet ds = mv.getActiveDataSet();
     90
    8891                if (!ctrl && !shift)
    8992                        ds.clearSelection(); // new selection will replace the old.
     
    9497                mv.repaint();
    9598        }
     99
     100        @Override
     101        protected boolean isEditMode() {
     102                return false;
     103        }
    96104}
  • src/org/openstreetmap/josm/actions/mapmode/ZoomAction.java

    r16 r17  
    6868                selectionManager.unregister(mv);
    6969        }
     70
     71        @Override
     72        protected boolean isEditMode() {
     73                return false;
     74        }
    7075}
  • src/org/openstreetmap/josm/data/GeoPoint.java

    r9 r17  
    5959        }
    6060       
    61        
     61        /**
     62         * @return <code>true</code>, if the other GeoPoint has the same lat/lon values.
     63         */
     64        public boolean equalsLatLon(GeoPoint other) {
     65                return lat == other.lat && lon == other.lon;
     66        }
    6267}
  • src/org/openstreetmap/josm/data/Preferences.java

    r16 r17  
    11package org.openstreetmap.josm.data;
    22
     3import java.beans.PropertyChangeEvent;
     4import java.beans.PropertyChangeListener;
    35import java.io.File;
    46import java.io.FileReader;
     
    3840
    3941
     42        /**
     43         * Whether lines should be drawn between track points of raw gps data.
     44         */
     45        private boolean drawRawGpsLines = false;
    4046        /**
    4147         * Whether nodes on the same place should be considered identical.
     
    100106
    101107                        mergeNodes = root.getChild("mergeNodes") != null;
     108                        drawRawGpsLines = root.getChild("drawRawGpsLines") != null;
    102109                } catch (Exception e) {
    103110                        if (e instanceof PreferencesException)
     
    120127                if (mergeNodes)
    121128                        children.add(new Element("mergeNodes"));
     129                if (drawRawGpsLines)
     130                        children.add(new Element("drawRawGpsLines"));
    122131
    123132                try {
     
    134143       
    135144        /**
    136          * This interface notifies any interested about changes in the projection
    137          * @author imi
    138          */
    139         public interface ProjectionChangeListener {
    140                 void projectionChanged(Projection oldProjection, Projection newProjection);
    141         }
    142         /**
    143145         * The list of all listeners to projection changes.
    144146         */
    145         private Collection<ProjectionChangeListener> listener = new LinkedList<ProjectionChangeListener>();
     147        private Collection<PropertyChangeListener> listener = new LinkedList<PropertyChangeListener>();
    146148        /**
    147149         * Add a listener of projection changes to the list of listeners.
    148150         * @param listener The listerner to add.
    149151         */
    150         public void addProjectionChangeListener(ProjectionChangeListener listener) {
     152        public void addPropertyChangeListener(PropertyChangeListener listener) {
    151153                if (listener != null)
    152154                        this.listener.add(listener);
     
    155157         * Remove the listener from the list.
    156158         */
    157         public void removeProjectionChangeListener(ProjectionChangeListener listener) {
     159        public void removePropertyChangeListener(PropertyChangeListener listener) {
    158160                this.listener.remove(listener);
    159161        }
     162        /**
     163         * Fires a PropertyChangeEvent if the old value differs from the new value.
     164         */
     165        private <T> void firePropertyChanged(String name, T oldValue, T newValue) {
     166                if (oldValue == newValue)
     167                        return;
     168                PropertyChangeEvent evt = null;
     169                for (PropertyChangeListener l : listener) {
     170                        if (evt == null)
     171                                evt = new PropertyChangeEvent(this, name, oldValue, newValue);
     172                        l.propertyChange(evt);
     173                }
     174        }
     175
     176        // getter / setter
     177       
    160178        /**
    161179         * Set the projection and fire an event to all ProjectionChangeListener
     
    165183                Projection old = this.projection;
    166184                this.projection = projection;
    167                 if (old != projection)
    168                         for (ProjectionChangeListener l : listener)
    169                                 l.projectionChanged(old, projection);
     185                firePropertyChanged("projection", old, projection);
    170186        }
    171187        /**
     
    176192                return projection;
    177193        }
     194        public void setDrawRawGpsLines(boolean drawRawGpsLines) {
     195                boolean old = this.drawRawGpsLines;
     196                this.drawRawGpsLines = drawRawGpsLines;
     197                firePropertyChanged("drawRawGpsLines", old, drawRawGpsLines);
     198        }
     199        public boolean isDrawRawGpsLines() {
     200                return drawRawGpsLines;
     201        }
    178202}
  • src/org/openstreetmap/josm/data/osm/DataSet.java

    r16 r17  
    186186
    187187        /**
     188         * Import the given dataset by merging all data with this dataset.
     189         * The objects imported are not cloned, so from now on, these data belong
     190         * to both datasets. So use mergeFrom only if you are about to abandon the
     191         * other dataset or this dataset.
     192         *
     193         * @param ds    The DataSet to merge into this one.
     194         * @param mergeEqualNodes If <code>true</code>, nodes with the same lat/lon
     195         *              are merged together.
     196         */
     197        public void mergeFrom(DataSet ds, boolean mergeEqualNodes) {
     198                if (mergeEqualNodes) {
     199                        LinkedList<Node> nodesToAdd = new LinkedList<Node>();
     200                        for (Node n : ds.nodes)
     201                                for (Node mynode : nodes) {
     202                                        if (mynode.coor.equalsLatLon(n.coor))
     203                                                mynode.mergeFrom(n);
     204                                        else
     205                                                nodesToAdd.add(n);
     206                                }
     207                } else
     208                        nodes.addAll(ds.nodes);
     209                tracks.addAll(ds.tracks);
     210                pendingLineSegments.addAll(ds.pendingLineSegments);
     211        }
     212
     213        /**
    188214         * Remove the selection from every value in the collection.
    189215         * @param list The collection to remove the selection from.
  • src/org/openstreetmap/josm/data/osm/Node.java

    r9 r17  
    3333                return Collections.unmodifiableCollection(parentSegment);
    3434        }
     35
     36        /**
     37         * Merge the node given at parameter with this node.
     38         * All parents of the parameter-node become parents of this node.
     39         *
     40         * The argument node is not changed.
     41         *
     42         * @param node Merge the node to this.
     43         */
     44        public void mergeFrom(Node node) {
     45                parentSegment.addAll(node.parentSegment);
     46                if (keys == null)
     47                        keys = node.keys;
     48                else if (node.keys != null)
     49                        keys.putAll(node.keys);
     50        }
    3551       
    3652        /**
  • src/org/openstreetmap/josm/data/osm/visitor/SelectionComponentVisitor.java

    r11 r17  
    77
    88import javax.swing.Icon;
    9 import javax.swing.ImageIcon;
    109
    1110import org.openstreetmap.josm.data.osm.Key;
     
    1312import org.openstreetmap.josm.data.osm.Node;
    1413import org.openstreetmap.josm.data.osm.Track;
    15 import org.openstreetmap.josm.gui.Main;
     14import org.openstreetmap.josm.gui.ImageProvider;
    1615
    1716/**
     
    3837        public void visit(Key k) {
    3938                name = k.name;
    40                 icon = new ImageIcon(Main.class.getResource("/images/data/key.png"));
     39                icon = ImageProvider.get("data", "key");
    4140        }
    4241
     
    5352                       
    5453                this.name = name;
    55                 icon = new ImageIcon("images/data/linesegment.png");
     54                icon = ImageProvider.get("data", "linesegment");
    5655        }
    5756
     
    6766               
    6867                this.name = name;
    69                 icon = new ImageIcon("images/data/node.png");
     68                icon = ImageProvider.get("data", "node");
    7069        }
    7170
     
    8786               
    8887                this.name = name;
    89                 icon = new ImageIcon("images/data/track.png");
     88                icon = ImageProvider.get("data", "track");
    9089        }
    9190
  • src/org/openstreetmap/josm/data/projection/UTM.java

    r16 r17  
    9898         * Combobox with all ellipsoids for the configuration panel
    9999         */
    100         private JComboBox ellipsoidCombo = new JComboBox(allEllipsoids);
     100        private JComboBox ellipsoidCombo;
    101101        /**
    102102         * Spinner with all possible zones for the configuration panel
    103103         */
    104         private JSpinner zoneSpinner = new JSpinner(new SpinnerNumberModel(1,1,60,1));
     104        private JSpinner zoneSpinner;
    105105        /**
    106106         * Hemisphere combo for the configuration panel
    107107         */
    108         private JComboBox hemisphereCombo = new JComboBox(Hemisphere.values());
     108        private JComboBox hemisphereCombo;
    109109
    110110       
     
    248248               
    249249                // ellipsoid
     250                if (ellipsoidCombo == null)
     251                        ellipsoidCombo = new JComboBox(allEllipsoids);
    250252                panel.add(new JLabel("Ellipsoid"), gbc);
    251253                panel.add(ellipsoidCombo, GBC.eol());
     
    253255               
    254256                // zone
     257                if (zoneSpinner == null)
     258                        zoneSpinner = new JSpinner(new SpinnerNumberModel(1,1,60,1));
    255259                panel.add(new JLabel("Zone"), gbc);
    256260                panel.add(zoneSpinner, GBC.eol().insets(0,5,0,5));
     
    259263               
    260264                // hemisphere
     265                if (hemisphereCombo == null)
     266                        hemisphereCombo = new JComboBox(Hemisphere.values());
    261267                panel.add(new JLabel("Hemisphere"), gbc);
    262268                panel.add(hemisphereCombo, GBC.eop());
     
    268274                        public void actionPerformed(ActionEvent e) {
    269275                                if (Main.main.getMapFrame() != null) {
    270                                         DataSet ds = Main.main.getMapFrame().mapView.dataSet;
     276                                        DataSet ds = Main.main.getMapFrame().mapView.getActiveDataSet();
    271277                                        ZoneData zd = autoDetect(ds);
    272278                                        if (zd.zone == 0)
     
    291297        @Override
    292298        public void commitConfigurationPanel() {
    293                 ellipsoid = (Ellipsoid)ellipsoidCombo.getSelectedItem();
    294                 zone = (Integer)zoneSpinner.getValue();
    295                 hemisphere = (Hemisphere)hemisphereCombo.getSelectedItem();
    296                 fireStateChanged();
     299                if (ellipsoidCombo != null && zoneSpinner != null && hemisphereCombo != null) {
     300                        ellipsoid = (Ellipsoid)ellipsoidCombo.getSelectedItem();
     301                        zone = (Integer)zoneSpinner.getValue();
     302                        hemisphere = (Hemisphere)hemisphereCombo.getSelectedItem();
     303                        fireStateChanged();
     304                }
    297305        }
    298306}
  • src/org/openstreetmap/josm/gui/Main.java

    r16 r17  
    55import java.awt.Container;
    66
    7 import javax.swing.ImageIcon;
    87import javax.swing.JFrame;
    98import javax.swing.JMenu;
     
    3635         * Global application preferences
    3736         */
    38         public static Preferences pref = new Preferences();
     37        public final static Preferences pref = new Preferences();
    3938       
    4039        /**
     
    141140                //TODO: Check for changes and ask user
    142141                this.name = name;
     142                if (this.mapFrame != null)
     143                        this.mapFrame.setVisible(false);
    143144                this.mapFrame = mapFrame;
    144145                panel.setVisible(false);
    145146                panel.removeAll();
    146                 panel.add(mapFrame, BorderLayout.CENTER);
    147                 panel.add(mapFrame.toolBarActions, BorderLayout.WEST);
    148                 panel.add(mapFrame.statusLine, BorderLayout.SOUTH);
    149                 panel.setVisible(true);
     147                if (mapFrame != null) {
     148                        mapFrame.fillPanel(panel);
     149                        panel.setVisible(true);
     150                        mapFrame.setVisible(true);
     151                }
    150152        }
    151153        /**
     
    167169         */
    168170        private static void setupUiDefaults() {
    169                 UIManager.put("OptionPane.okIcon", new ImageIcon(Main.class.getResource("/images/ok.png")));
     171                UIManager.put("OptionPane.okIcon", ImageProvider.get("ok"));
    170172                UIManager.put("OptionPane.yesIcon", UIManager.get("OptionPane.okIcon"));
    171                 UIManager.put("OptionPane.cancelIcon", new ImageIcon(Main.class.getResource("/images/cancel.png")));
     173                UIManager.put("OptionPane.cancelIcon", ImageProvider.get("cancel"));
    172174                UIManager.put("OptionPane.noIcon", UIManager.get("OptionPane.cancelIcon"));
    173175        }
  • src/org/openstreetmap/josm/gui/MapFrame.java

    r16 r17  
    33import java.awt.BorderLayout;
    44import java.awt.Component;
     5import java.awt.Container;
    56import java.awt.event.WindowAdapter;
    67import java.awt.event.WindowEvent;
     
    1415import javax.swing.JToolBar;
    1516
     17import org.openstreetmap.josm.actions.AutoScaleAction;
    1618import org.openstreetmap.josm.actions.mapmode.AddLineSegmentAction;
    1719import org.openstreetmap.josm.actions.mapmode.AddNodeAction;
    1820import org.openstreetmap.josm.actions.mapmode.AddTrackAction;
    1921import org.openstreetmap.josm.actions.mapmode.CombineAction;
    20 import org.openstreetmap.josm.actions.mapmode.DebugAction;
    2122import org.openstreetmap.josm.actions.mapmode.DeleteAction;
    2223import org.openstreetmap.josm.actions.mapmode.MapMode;
     
    2425import org.openstreetmap.josm.actions.mapmode.SelectionAction;
    2526import org.openstreetmap.josm.actions.mapmode.ZoomAction;
    26 import org.openstreetmap.josm.data.osm.DataSet;
     27import org.openstreetmap.josm.gui.dialogs.LayerList;
    2728import org.openstreetmap.josm.gui.dialogs.PropertiesDialog;
    2829import org.openstreetmap.josm.gui.dialogs.SelectionListDialog;
     30import org.openstreetmap.josm.gui.layer.Layer;
    2931
    3032/**
     
    5456
    5557        /**
    56          * Construct a map with a given DataSet. The set cannot be replaced after construction
    57          * (but of course, the data can be altered using the map's editing features).
     58         * Construct a map with a given DataSet. The set cannot be replaced after
     59         * construction (but of course, the data can be altered using the map's
     60         * editing features).
     61         *
     62         * @param layer The first layer in the mapView.
    5863         */
    59         public MapFrame(DataSet dataSet) {
     64        public MapFrame(Layer layer) {
    6065                setSize(400,400);
    6166                setLayout(new BorderLayout());
    6267
    63                 add(mapView = new MapView(dataSet), BorderLayout.CENTER);
     68                add(mapView = new MapView(layer), BorderLayout.CENTER);
    6469
    6570                // toolbar
     
    7378                toolBarActions.add(new IconToggleButton(this, new CombineAction(this)));
    7479                toolBarActions.add(new IconToggleButton(this, new DeleteAction(this)));
    75                 toolBarActions.add(new IconToggleButton(this, new DebugAction(this)));
    7680
    7781                // all map modes in one button group
     
    8488                // autoScale
    8589                toolBarActions.addSeparator();
    86                 final JToggleButton autoScaleButton = new IconToggleButton(this, mapView.new AutoScaleAction());
     90                final JToggleButton autoScaleButton = new IconToggleButton(this, new AutoScaleAction(this));
    8791                toolBarActions.add(autoScaleButton);
    8892                autoScaleButton.setText(null);
     
    9599                });
    96100
     101                // layer list
     102                toolBarActions.add(new IconToggleButton(this, new LayerList(this)));
     103               
    97104                // properties
    98105                toolBarActions.add(new IconToggleButton(this, new PropertiesDialog(this)));
    99106
    100107                // selection dialog
    101                 SelectionListDialog selectionList = new SelectionListDialog(dataSet);
     108                SelectionListDialog selectionList = new SelectionListDialog(this);
    102109                final IconToggleButton buttonSelection = new IconToggleButton(this, selectionList);
    103110                selectionList.addWindowListener(new WindowAdapter(){
     
    110117
    111118                // status line below the map
    112                 statusLine = new MapStatus(mapView);
     119                statusLine = new MapStatus(this);
    113120        }
     121
     122       
     123        /**
     124         * Fires an property changed event "visible".
     125         */
     126        @Override
     127        public void setVisible(boolean aFlag) {
     128                boolean old = isVisible();
     129                super.setVisible(aFlag);
     130                if (old != aFlag)
     131                        firePropertyChange("visible", old, aFlag);
     132        }
     133
     134
    114135
    115136        /**
     
    124145                mapMode.registerListener();
    125146        }
     147
     148        /**
     149         * Fill the given panel by adding all necessary components to the different
     150         * locations.
     151         *
     152         * @param panel The container to fill. Must have an BorderLayout.
     153         */
     154        public void fillPanel(Container panel) {
     155                panel.add(this, BorderLayout.CENTER);
     156                panel.add(toolBarActions, BorderLayout.WEST);
     157                panel.add(statusLine, BorderLayout.SOUTH);
     158        }
    126159}
  • src/org/openstreetmap/josm/gui/MapStatus.java

    r16 r17  
    88import java.awt.event.MouseEvent;
    99import java.awt.event.MouseMotionListener;
     10import java.beans.PropertyChangeEvent;
     11import java.beans.PropertyChangeListener;
    1012import java.util.Map.Entry;
    1113
     
    5052         */
    5153        private JTextField nameText = new JTextField(30);
    52         /**
    53          * The background thread thats collecting the data.
    54          */
    55         private Runnable collector;
    5654
    5755        /**
     
    7876                 */
    7977                private Popup popup;
     78                /**
     79                 * Signals the collector to shut down on next event.
     80                 */
     81                boolean exitCollector = false;
    8082
    8183                /**
     
    9092                                        ms.mousePos = mouseState.mousePos;
    9193                                }
     94                                if (exitCollector)
     95                                        return;
    9296                                if ((ms.modifiers & MouseEvent.CTRL_DOWN_MASK) != 0 || ms.mousePos == null)
    9397                                        continue; // freeze display when holding down ctrl
     
    119123                                        }
    120124                                        JLabel l = new JLabel(text.toString(), visitor.icon, JLabel.HORIZONTAL);
     125                                        l.setVerticalTextPosition(JLabel.TOP);
    121126                                       
    122127                                        Point p = mv.getLocationOnScreen();
     
    148153         * @param mv The MapView the status line is part of.
    149154         */
    150         public MapStatus(final MapView mv) {
    151                 this.mv = mv;
     155        public MapStatus(final MapFrame mapFrame) {
     156                this.mv = mapFrame.mapView;
    152157               
    153158                // Listen for mouse movements and set the position text field
     
    165170                });
    166171               
     172                positionText.setEditable(false);
     173                nameText.setEditable(false);
     174                setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
     175                setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
     176                add(new JLabel("Lat/Lon "));
     177                add(positionText);
     178                add(new JLabel(" Object "));
     179                add(nameText);
     180
     181                // The background thread
     182                final Collector collector = new Collector();
     183                new Thread(collector).start();
     184
    167185                // Listen to keyboard/mouse events for pressing/releasing alt key and
    168186                // inform the collector.
     
    177195                        }
    178196                }, AWTEvent.KEY_EVENT_MASK | AWTEvent.MOUSE_EVENT_MASK | AWTEvent.MOUSE_MOTION_EVENT_MASK);
    179 
    180                 positionText.setEditable(false);
    181                 nameText.setEditable(false);
    182                 setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
    183                 setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
    184                 add(new JLabel("Lat/Lon "));
    185                 add(positionText);
    186                 add(new JLabel(" Object "));
    187                 add(nameText);
    188 
    189                 // The background thread
    190                 collector = new Collector();
    191                 new Thread(collector).start();
     197               
     198                // listen for shutdowns to cancel the background thread
     199                mapFrame.addPropertyChangeListener("visible", new PropertyChangeListener(){
     200                        public void propertyChange(PropertyChangeEvent evt) {
     201                                if (evt.getNewValue() == Boolean.FALSE) {
     202                                        collector.exitCollector = true;
     203                                        synchronized (collector) {
     204                                                collector.notify();
     205                                        }
     206                                }
     207                        }
     208                });
    192209        }
    193210}
  • src/org/openstreetmap/josm/gui/MapView.java

    r16 r17  
    11package org.openstreetmap.josm.gui;
    22
     3import java.awt.Color;
    34import java.awt.Graphics;
    45import java.awt.Point;
    5 import java.awt.event.ActionEvent;
     6import java.awt.event.ComponentAdapter;
    67import java.awt.event.ComponentEvent;
    7 import java.awt.event.ComponentListener;
    8 import java.awt.event.KeyEvent;
    9 
    10 import javax.swing.AbstractAction;
    11 import javax.swing.ImageIcon;
     8import java.beans.PropertyChangeEvent;
     9import java.beans.PropertyChangeListener;
     10import java.util.ArrayList;
     11import java.util.Collection;
     12import java.util.Collections;
     13import java.util.LinkedList;
     14
    1215import javax.swing.JComponent;
    1316import javax.swing.event.ChangeEvent;
     
    1619import org.openstreetmap.josm.data.Bounds;
    1720import org.openstreetmap.josm.data.GeoPoint;
    18 import org.openstreetmap.josm.data.Preferences.ProjectionChangeListener;
    1921import org.openstreetmap.josm.data.osm.DataSet;
    2022import org.openstreetmap.josm.data.osm.LineSegment;
     
    2325import org.openstreetmap.josm.data.osm.Track;
    2426import org.openstreetmap.josm.data.projection.Projection;
    25 import org.openstreetmap.josm.gui.engine.Engine;
    26 import org.openstreetmap.josm.gui.engine.SimpleEngine;
     27import org.openstreetmap.josm.gui.layer.Layer;
    2728
    2829/**
     
    3637 * what projection the map is viewed etc..
    3738 *
     39 * MapView is able to administrate several layers, but there must be always at
     40 * least one layer with a dataset in it (Layer.getDataSet returning non-null).
     41 *
    3842 * @author imi
    3943 */
    40 public class MapView extends JComponent implements ComponentListener, ChangeListener, ProjectionChangeListener {
    41 
    42         /**
    43          * Toggles the autoScale feature of the mapView
     44public class MapView extends JComponent implements ChangeListener, PropertyChangeListener {
     45
     46        /**
     47         * Interface to notify listeners of the change of the active layer.
    4448         * @author imi
    4549         */
    46         public class AutoScaleAction extends AbstractAction {
    47                 public AutoScaleAction() {
    48                         super("Auto Scale", new ImageIcon(Main.class.getResource("/images/autoscale.png")));
    49                         putValue(MNEMONIC_KEY, KeyEvent.VK_A);
    50                 }
    51                 public void actionPerformed(ActionEvent e) {
    52                         autoScale = !autoScale;
    53                         recalculateCenterScale();
    54                 }
     50        public interface LayerChangeListener {
     51                void activeLayerChange(Layer oldLayer, Layer newLayer);
     52                void layerAdded(Layer newLayer);
     53                void layerRemoved(Layer oldLayer);
    5554        }
    5655
     
    5857         * Whether to adjust the scale property on every resize.
    5958         */
    60         private boolean autoScale = true;
     59        boolean autoScale = true;
    6160
    6261        /**
     
    7069
    7170        /**
    72          * The underlying DataSet.
    73          */
    74         public final DataSet dataSet;
    75 
    76         /**
    77          * The drawing engine.
    78          */
    79         private Engine engine;
     71         * A list of all layers currently loaded.
     72         */
     73        private ArrayList<Layer> layers = new ArrayList<Layer>();
     74        /**
     75         * The layer from the layers list that is currently active.
     76         */
     77        private Layer activeLayer;
     78        /**
     79         * The listener of the active layer changes.
     80         */
     81        private Collection<LayerChangeListener> listeners = new LinkedList<LayerChangeListener>();
    8082       
    8183        /**
    8284         * Construct a MapView.
    83          */
    84         public MapView(DataSet dataSet) {
    85                 this.dataSet = dataSet;
    86                 addComponentListener(this);
     85         * @param layer The first layer in the view.
     86         */
     87        public MapView(Layer layer) {
     88                if (layer.getDataSet() == null)
     89                        throw new IllegalArgumentException("Initial layer must have a dataset.");
     90
     91                addComponentListener(new ComponentAdapter(){
     92                        @Override
     93                        public void componentResized(ComponentEvent e) {
     94                                recalculateCenterScale();
     95                        }
     96                });
    8797
    8898                // initialize the movement listener
     
    90100
    91101                // initialize the projection
    92                 projectionChanged(null, Main.pref.getProjection());
    93                 Main.pref.addProjectionChangeListener(this);
    94                
    95                 // initialize the drawing engine
    96                 engine = new SimpleEngine(this);
     102                addLayer(layer);
     103                Main.pref.addPropertyChangeListener(this);
     104
     105                // init screen
     106                recalculateCenterScale();
     107        }
     108
     109        /**
     110         * Add a layer to the current MapView. The layer will be added at topmost
     111         * position.
     112         */
     113        public void addLayer(Layer layer) {
     114                layers.add(0,layer);
     115
     116                DataSet ds = layer.getDataSet();
     117
     118                if (ds != null) {
     119                        // initialize the projection if it was the first layer
     120                        if (layers.size() == 1)
     121                                Main.pref.getProjection().init(ds);
     122                       
     123                        // initialize the dataset in the new layer
     124                        for (Node n : ds.nodes)
     125                                Main.pref.getProjection().latlon2xy(n.coor);
     126                }
     127
     128                for (LayerChangeListener l : listeners)
     129                        l.layerAdded(layer);
     130
     131                setActiveLayer(layer);
     132        }
     133       
     134        /**
     135         * Remove the layer from the mapview. If the layer was in the list before,
     136         * an LayerChange event is fired.
     137         */
     138        public void removeLayer(Layer layer) {
     139                if (layers.remove(layer))
     140                        for (LayerChangeListener l : listeners)
     141                                l.layerRemoved(layer);
     142        }
     143
     144        /**
     145         * Moves the layer to the given new position. No event is fired.
     146         * @param layer         The layer to move
     147         * @param pos           The new position of the layer
     148         */
     149        public void moveLayer(Layer layer, int pos) {
     150                int curLayerPos = layers.indexOf(layer);
     151                if (curLayerPos == -1)
     152                        throw new IllegalArgumentException("layer not in list.");
     153                if (pos == curLayerPos)
     154                        return; // already in place.
     155                layers.remove(curLayerPos);
     156                if (pos >= layers.size())
     157                        layers.add(layer);
     158                else
     159                        layers.add(pos, layer);
    97160        }
    98161
     
    168231                double minDistanceSq = Double.MAX_VALUE;
    169232                OsmPrimitive minPrimitive = null;
     233
     234                // calculate the object based on the current active dataset.
     235                DataSet ds = getActiveDataSet();
    170236               
    171237                // nodes
    172                 for (Node n : dataSet.nodes) {
     238                for (Node n : ds.nodes) {
    173239                        Point sp = getScreenPoint(n.coor);
    174240                        double dist = p.distanceSq(sp);
     
    182248               
    183249                // pending line segments
    184                 for (LineSegment ls : dataSet.pendingLineSegments()) {
     250                for (LineSegment ls : ds.pendingLineSegments()) {
    185251                        Point A = getScreenPoint(ls.getStart().coor);
    186252                        Point B = getScreenPoint(ls.getEnd().coor);
     
    197263                // tracks & line segments
    198264                minDistanceSq = Double.MAX_VALUE;
    199                 for (Track t : dataSet.tracks()) {
     265                for (Track t : ds.tracks()) {
    200266                        for (LineSegment ls : t.segments()) {
    201267                                Point A = getScreenPoint(ls.getStart().coor);
     
    243309                        firePropertyChange("scale", oldScale, scale);
    244310        }
    245        
     311
    246312        /**
    247313         * Draw the component.
     
    249315        @Override
    250316        public void paint(Graphics g) {
    251                 engine.init(g);
    252                 engine.drawBackground(getPoint(0,0,true), getPoint(getWidth(), getHeight(), true));
    253 
    254                 for (Track t : dataSet.tracks())
    255                         engine.drawTrack(t);
    256                 for (LineSegment ls : dataSet.pendingLineSegments())
    257                         engine.drawPendingLineSegment(ls);
    258                 for (Node n : dataSet.nodes)
    259                         engine.drawNode(n);
     317                g.setColor(Color.BLACK);
     318                g.fillRect(0, 0, getWidth(), getHeight());
     319
     320                for (int i = layers.size()-1; i >= 0; --i) {
     321                        Layer l = layers.get(i);
     322                        if (l.isVisible())
     323                                l.paint(g, this);
     324                }
    260325        }
    261326
     
    265330         */
    266331        public void stateChanged(ChangeEvent e) {
    267                 for (Node n : dataSet.nodes)
    268                         Main.pref.getProjection().latlon2xy(n.coor);
     332                // reset all datasets.
     333                Projection p = Main.pref.getProjection();
     334                for (Layer l : layers) {
     335                        DataSet ds = l.getDataSet();
     336                        if (ds != null)
     337                                for (Node n : ds.nodes)
     338                                        p.latlon2xy(n.coor);
     339                }
    269340                recalculateCenterScale();
    270341        }
     
    292363                        this.autoScale = autoScale;
    293364                        firePropertyChange("autoScale", !autoScale, autoScale);
     365                        recalculateCenterScale();
    294366                }
    295367        }
     
    303375
    304376       
     377        /**
     378         * Return the dataSet for the current selected layer. If the active layer
     379         * does not have a dataset, return the DataSet from the next layer a.s.o.
     380         * 
     381         * @return The DataSet of the current active layer.
     382         */
     383        public DataSet getActiveDataSet() {
     384                if (activeLayer.getDataSet() != null)
     385                        return activeLayer.getDataSet();
     386                for (Layer l : layers) {
     387                        DataSet ds = l.getDataSet();
     388                        if (ds != null)
     389                                return ds;
     390                }
     391                throw new IllegalStateException("No dataset found.");
     392        }
    305393
    306394        /**
     
    310398         * @param newProjection The new projection. Register as state change listener.
    311399         */
    312         public void projectionChanged(Projection oldProjection, Projection newProjection) {
    313                 if (oldProjection != null)
    314                         oldProjection.removeChangeListener(this);
    315                 if (newProjection != null) {
    316                         newProjection.addChangeListener(this);
    317                         newProjection.init(dataSet);
    318                         for (Node n : dataSet.nodes)
    319                                 newProjection.latlon2xy(n.coor);
    320                 }
    321                 recalculateCenterScale();
     400        public void propertyChange(PropertyChangeEvent evt) {
     401                if (!evt.getPropertyName().equals("projection"))
     402                        return;
     403                if (evt.getOldValue() != null)
     404                        ((Projection)evt.getOldValue()).removeChangeListener(this);
     405                if (evt.getNewValue() != null) {
     406                        Projection p = (Projection)evt.getNewValue();
     407                        p.addChangeListener(this);
     408
     409                        stateChanged(new ChangeEvent(this));
     410                }
    322411        }
    323412       
     
    326415         * scale, if in autoScale mode.
    327416         */
    328         private void recalculateCenterScale() {
     417        void recalculateCenterScale() {
    329418                if (autoScale) {
    330419                        // -20 to leave some border
     
    335424                        if (h < 20)
    336425                                h = 20;
    337                         Bounds bounds = dataSet.getBoundsXY();
     426                       
     427                        Bounds bounds = getActiveDataSet().getBoundsXY();
    338428                       
    339429                        boolean oldAutoScale = autoScale;
     
    364454
    365455        /**
    366          * Call to recalculateCenterScale.
    367          */
    368         public void componentResized(ComponentEvent e) {
    369                 recalculateCenterScale();
    370         }
    371 
    372         /**
    373          * Does nothing. Just to satisfy ComponentListener.
    374          */
    375         public void componentMoved(ComponentEvent e) {}
    376         /**
    377          * Does nothing. Just to satisfy ComponentListener.
    378          */
    379         public void componentShown(ComponentEvent e) {}
    380         /**
    381          * Does nothing. Just to satisfy ComponentListener.
    382          */
    383         public void componentHidden(ComponentEvent e) {}
     456         * Add a listener for changes of active layer.
     457         * @param listener The listener that get added.
     458         */
     459        public void addLayerChangeListener(LayerChangeListener listener) {
     460                if (listener != null)
     461                        listeners.add(listener);
     462        }
     463
     464        /**
     465         * Remove the listener.
     466         * @param listener The listener that get removed from the list.
     467         */
     468        public void removeLayerChangeListener(LayerChangeListener listener) {
     469                listeners.remove(listener);
     470        }
     471
     472        /**
     473         * @return An unmodificable list of all layers
     474         */
     475        public Collection<Layer> getAllLayers() {
     476                return Collections.unmodifiableCollection(layers);
     477        }
     478
     479        /**
     480         * Set the active selection to the given value and raise an layerchange event.
     481         */
     482        public void setActiveLayer(Layer layer) {
     483                if (!layers.contains(layer))
     484                        throw new IllegalArgumentException("layer must be in layerlist");
     485                Layer old = activeLayer;
     486                activeLayer = layer;
     487                if (old != layer) {
     488                        if (old != null && old.getDataSet() != null)
     489                                old.getDataSet().clearSelection();
     490                        for (LayerChangeListener l : listeners)
     491                                l.activeLayerChange(old, layer);
     492                        recalculateCenterScale();
     493                }
     494        }
     495
     496        /**
     497         * @return The current active layer
     498         */
     499        public Layer getActiveLayer() {
     500                return activeLayer;
     501        }
    384502}
  • src/org/openstreetmap/josm/gui/PreferenceDialog.java

    r16 r17  
    77import java.awt.event.ActionEvent;
    88import java.awt.event.ActionListener;
    9 import java.io.File;
    109
    1110import javax.swing.AbstractAction;
     
    1312import javax.swing.Box;
    1413import javax.swing.DefaultListCellRenderer;
    15 import javax.swing.ImageIcon;
    1614import javax.swing.JButton;
    1715import javax.swing.JCheckBox;
     
    5452                        Main.pref.setProjection(projection);
    5553                        Main.pref.mergeNodes = mergeNodes.isSelected();
     54                        Main.pref.setDrawRawGpsLines(drawRawGpsLines.isSelected());
    5655                        try {
    5756                                Main.pref.save();
     
    9695         */
    9796        private JTabbedPane tabPane = new JTabbedPane(JTabbedPane.LEFT);
     97
    9898        /**
    9999         * The checkbox stating whether nodes should be merged together.
    100100         */
     101        private JCheckBox drawRawGpsLines = new JCheckBox("Draw lines between raw gps points.");
     102        /**
     103         * The checkbox stating whether nodes should be merged together.
     104         */
    101105        private JCheckBox mergeNodes = new JCheckBox("Merge nodes with equal latitude/longitude.");
    102106
    103        
    104107        /**
    105108         * Create a preference setting dialog from an preferences-file. If the file does not
     
    110113        public PreferenceDialog() {
    111114                super(Main.main, "Preferences");
    112 
    113                 Preferences pref = new Preferences();
    114                 try {
    115                         if (new File(Preferences.getPreferencesFile()).exists())
    116                                 pref.load();
    117                 } catch (PreferencesException e) {
    118                         JOptionPane.showMessageDialog(Main.main, "Preferences settings could not be parsed:\n"+e.getMessage());
    119                         e.printStackTrace();
    120                         return;
    121                 }
    122115
    123116                // look and feel combo box
     
    128121                                return oldRenderer.getListCellRendererComponent(list, ((LookAndFeelInfo)value).getName(), index, isSelected, cellHasFocus);
    129122                        }});
    130                 lafCombo.setSelectedItem(pref.laf);
     123                lafCombo.setSelectedItem(Main.pref.laf);
    131124                lafCombo.addActionListener(new ActionListener(){
    132125                        public void actionPerformed(ActionEvent e) {
     
    136129                // projection combo box
    137130                for (int i = 0; i < projectionCombo.getItemCount(); ++i) {
    138                         if (projectionCombo.getItemAt(i).getClass().equals(pref.getProjection().getClass())) {
     131                        if (projectionCombo.getItemAt(i).getClass().equals(Main.pref.getProjection().getClass())) {
    139132                                projectionCombo.setSelectedIndex(i);
    140133                                break;
     
    162155                });
    163156               
     157                // tooltips
     158                drawRawGpsLines.setToolTipText("If your gps device draw to few lines, select this to draw lines along your track.");
     159                drawRawGpsLines.setSelected(Main.pref.isDrawRawGpsLines());
     160                mergeNodes.setToolTipText("When importing GPX data, all nodes with exact the same lat/lon are merged.");
     161                mergeNodes.setSelected(Main.pref.mergeNodes);
    164162               
    165163                // Display tab
     
    168166                display.add(GBC.glue(5,0), GBC.std().fill(GBC.HORIZONTAL));
    169167                display.add(lafCombo, GBC.eol().fill(GBC.HORIZONTAL));
     168                display.add(drawRawGpsLines, GBC.eol().insets(20,0,0,0));
    170169                display.add(Box.createVerticalGlue(), GBC.eol().fill(GBC.VERTICAL));
    171170
     
    180179               
    181180                map.add(new JLabel("GPX import / export"), GBC.eol());
    182                 mergeNodes.setSelected(pref.mergeNodes);
    183                 map.add(mergeNodes, GBC.eol());
     181                map.add(mergeNodes, GBC.eol().insets(20,0,0,0));
    184182                map.add(Box.createVerticalGlue(), GBC.eol().fill(GBC.VERTICAL));
    185183
     
    222220                p.add(descLabel, GBC.eol().insets(5,0,5,20).fill(GBC.HORIZONTAL));
    223221
    224                 tabPane.addTab(null, new ImageIcon("images/preferences/"+icon+".png"), p);
     222                tabPane.addTab(null, ImageProvider.get("preferences", icon), p);
    225223                return p;
    226224        }
  • src/org/openstreetmap/josm/gui/SelectionManager.java

    r16 r17  
    1515import java.util.LinkedList;
    1616
     17import org.openstreetmap.josm.data.osm.DataSet;
    1718import org.openstreetmap.josm.data.osm.LineSegment;
    1819import org.openstreetmap.josm.data.osm.Node;
     
    271272                } else {
    272273                        // nodes
    273                         for (Node n : mv.dataSet.nodes) {
     274                        DataSet ds = mv.getActiveDataSet();
     275                        for (Node n : ds.nodes) {
    274276                                if (r.contains(mv.getScreenPoint(n.coor)))
    275277                                        selection.add(n);
     
    277279                       
    278280                        // pending line segments
    279                         for (LineSegment ls : mv.dataSet.pendingLineSegments())
     281                        for (LineSegment ls : ds.pendingLineSegments())
    280282                                if (rectangleContainLineSegment(r, alt, ls))
    281283                                        selection.add(ls);
    282284
    283285                        // tracks
    284                         for (Track t : mv.dataSet.tracks()) {
     286                        for (Track t : ds.tracks()) {
    285287                                boolean wholeTrackSelected = !t.segments().isEmpty();
    286288                                for (LineSegment ls : t.segments())
  • src/org/openstreetmap/josm/gui/dialogs/PropertiesDialog.java

    r16 r17  
    2121        /**
    2222         * Create a new PropertiesDialog
    23          * @param frame The mapFrame, this dialog is attached to.
    2423         */
    25         public PropertiesDialog(final MapFrame frame) {
    26                 super("Properties of "+Main.main.getNameOfLoadedMapFrame(), "Properties Dialog", "properties", KeyEvent.VK_P, "Property page for this map.");
     24        public PropertiesDialog(MapFrame mapFrame) {
     25                super(mapFrame, "Properties of "+Main.main.getNameOfLoadedMapFrame(), "Properties Dialog", "properties", KeyEvent.VK_P, "Property page for this map.");
    2726                putValue(MNEMONIC_KEY, KeyEvent.VK_P);
    2827
  • src/org/openstreetmap/josm/gui/dialogs/SelectionListDialog.java

    r11 r17  
    1010import javax.swing.DefaultListCellRenderer;
    1111import javax.swing.DefaultListModel;
    12 import javax.swing.ImageIcon;
    1312import javax.swing.JButton;
    1413import javax.swing.JLabel;
     
    2120import org.openstreetmap.josm.data.osm.OsmPrimitive;
    2221import org.openstreetmap.josm.data.osm.visitor.SelectionComponentVisitor;
     22import org.openstreetmap.josm.gui.ImageProvider;
    2323import org.openstreetmap.josm.gui.Main;
     24import org.openstreetmap.josm.gui.MapFrame;
     25import org.openstreetmap.josm.gui.MapView;
     26import org.openstreetmap.josm.gui.MapView.LayerChangeListener;
     27import org.openstreetmap.josm.gui.layer.Layer;
    2428
    2529/**
     
    3034 * @author imi
    3135 */
    32 public class SelectionListDialog extends ToggleDialog implements SelectionChangedListener {
     36public class SelectionListDialog extends ToggleDialog implements SelectionChangedListener, LayerChangeListener {
    3337
    3438        /**
     
    4347         * The dataset, all selections are part of.
    4448         */
    45         private final DataSet dataSet;
     49        private final MapView mapView;
    4650       
    4751        /**
    4852         * Create a SelectionList dialog.
    49          * @param dataSet The dataset this dialog operates on.
     53         * @param mapView The mapView to get the dataset from.
    5054         */
    51         public SelectionListDialog(DataSet dataSet) {
    52                 super("Current Selection", "Selection List", "selectionlist", KeyEvent.VK_E, "Open a selection list window.");
    53                 this.dataSet = dataSet;
     55        public SelectionListDialog(MapFrame mapFrame) {
     56                super(mapFrame, "Current Selection", "Selection List", "selectionlist", KeyEvent.VK_E, "Open a selection list window.");
     57                this.mapView = mapFrame.mapView;
    5458                setLayout(new BorderLayout());
    5559                setSize(300,400);
     
    7175                getContentPane().add(new JScrollPane(displaylist), BorderLayout.CENTER);
    7276
    73                 JButton button = new JButton("Select", new ImageIcon(Main.class.getResource("/images/mapmode/selection.png")));
     77                JButton button = new JButton("Select", ImageProvider.get("mapmode", "selection"));
     78                button.setToolTipText("Set the selected elements on the map to the selected items in the list above.");
    7479                button.addActionListener(new ActionListener(){
    7580                        public void actionPerformed(ActionEvent e) {
     
    7984                getContentPane().add(button, BorderLayout.SOUTH);
    8085
    81                 selectionChanged(dataSet.getSelected());
     86                selectionChanged(mapView.getActiveDataSet().getSelected());
    8287        }
    8388
     
    8590        public void setVisible(boolean b) {
    8691                if (b) {
    87                         dataSet.addSelectionChangedListener(this);
    88                         selectionChanged(dataSet.getSelected());
    89                 } else
    90                         dataSet.removeSelectionChangedListener(this);
     92                        mapView.addLayerChangeListener(this);
     93                        mapView.getActiveDataSet().addSelectionChangedListener(this);
     94                        selectionChanged(mapView.getActiveDataSet().getSelected());
     95                } else {
     96                        mapView.removeLayerChangeListener(this);
     97                        mapView.getActiveDataSet().removeSelectionChangedListener(this);
     98                }
    9199                super.setVisible(b);
    92100        }
     
    110118         */
    111119        public void updateMap() {
    112                 dataSet.clearSelection();
     120                DataSet ds = mapView.getActiveDataSet();
     121                ds.clearSelection();
    113122                for (int i = 0; i < list.getSize(); ++i)
    114123                        if (displaylist.isSelectedIndex(i))
    115                                 ((OsmPrimitive)list.get(i)).setSelected(true, dataSet);
     124                                ((OsmPrimitive)list.get(i)).setSelected(true, ds);
    116125                Main.main.getMapFrame().repaint();
    117126        }
     127
     128        public void activeLayerChange(Layer oldLayer, Layer newLayer) {
     129                DataSet ds = oldLayer.getDataSet();
     130                if (ds != null)
     131                        ds.removeSelectionChangedListener(this);
     132                ds = newLayer.getDataSet();
     133                if (ds != null)
     134                        ds.addSelectionChangedListener(this);
     135        }
     136
     137        /**
     138         * Does nothing. Only to satisfy LayerChangeListener
     139         */
     140        public void layerAdded(Layer newLayer) {}
     141        /**
     142         * Does nothing. Only to satisfy LayerChangeListener
     143         */
     144        public void layerRemoved(Layer oldLayer) {}
    118145}
  • src/org/openstreetmap/josm/gui/dialogs/ToggleDialog.java

    r16 r17  
    22
    33import java.awt.event.ActionEvent;
    4 import java.awt.event.KeyEvent;
     4import java.beans.PropertyChangeEvent;
     5import java.beans.PropertyChangeListener;
    56import java.util.HashMap;
    67import java.util.Map;
     
    89import javax.swing.AbstractButton;
    910import javax.swing.Action;
    10 import javax.swing.ImageIcon;
     11import javax.swing.JComponent;
    1112import javax.swing.JDialog;
    1213import javax.swing.KeyStroke;
    1314
     15import org.openstreetmap.josm.gui.ImageProvider;
    1416import org.openstreetmap.josm.gui.Main;
     17import org.openstreetmap.josm.gui.MapFrame;
    1518
    1619/**
     
    2629         * @param title The title of the dialog.
    2730         */
    28         public ToggleDialog(String title, String name, String iconName, int mnemonic, String tooltip) {
     31        public ToggleDialog(MapFrame mapFrame, String title, String name, String iconName, int mnemonic, String tooltip) {
    2932                super(Main.main, title, false);
    30                 putValue(SMALL_ICON, new ImageIcon(Main.class.getResource("/images/dialogs/"+iconName+".png")));
     33                putValue(SMALL_ICON, ImageProvider.get("dialogs", iconName));
    3134                putValue(NAME, name);
    3235                putValue(MNEMONIC_KEY, mnemonic);
    33                 putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_E,0));
    34                 putValue(LONG_DESCRIPTION, "Open a selection list window.");
     36                KeyStroke ks = KeyStroke.getKeyStroke(mnemonic,0);
     37                putValue(ACCELERATOR_KEY, ks);
     38                mapFrame.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(ks, this);
     39                mapFrame.getActionMap().put(this, this);
     40                putValue(LONG_DESCRIPTION, tooltip);
     41                mapFrame.addPropertyChangeListener("visible", new PropertyChangeListener(){
     42                        public void propertyChange(PropertyChangeEvent evt) {
     43                                if (evt.getNewValue() == Boolean.FALSE)
     44                                        setVisible(false);
     45                        }
     46                });
    3547        }
    3648
  • src/org/openstreetmap/josm/gui/engine/Engine.java

    r16 r17  
    22
    33import java.awt.Graphics;
    4 import java.beans.PropertyChangeEvent;
    5 import java.beans.PropertyChangeListener;
    64
    7 import org.openstreetmap.josm.data.GeoPoint;
    85import org.openstreetmap.josm.data.osm.LineSegment;
    96import org.openstreetmap.josm.data.osm.Node;
    107import org.openstreetmap.josm.data.osm.Track;
    11 import org.openstreetmap.josm.data.projection.Projection;
    128import org.openstreetmap.josm.gui.MapView;
    139
     
    1814 * @author imi
    1915 */
    20 abstract public class Engine implements PropertyChangeListener {
     16abstract public class Engine {
    2117
    22         /**
    23          * The projection method, this engine uses to render the graphics.
    24          */
    25         protected Projection projection;
    2618        /**
    2719         * The Graphics surface to draw on. This should be set before each painting
     
    3224         * The mapView, this engine was created for.
    3325         */
    34         protected final MapView mv;
     26        protected MapView mv;
    3527
    36        
    37         /**
    38          * Creates an Engine from an MapView it belongs to.
    39          * @param mapView The mapview this engine belongs to.
    40          */
    41         public Engine(MapView mapView) {
    42                 mv = mapView;
    43                 mv.addPropertyChangeListener(this);
    44         }
    4528       
    4629        /**
     
    4831         * @param g
    4932         */
    50         public void init(Graphics g) {
     33        public void init(Graphics g, MapView mv) {
    5134                this.g = g;
     35                this.mv = mv;
    5236        }
    53 
    54         /**
    55          * Draw the background. The coordinates are given as hint (e.g. to draw
    56          * an background image).
    57          */
    58         abstract public void drawBackground(GeoPoint ul, GeoPoint lr);
    5937
    6038        /**
     
    7351         */
    7452        abstract public void drawPendingLineSegment(LineSegment ls);
    75 
    76         /**
    77          * Called when the projection method for the map changed. Subclasses with
    78          * caches depending on the projection should empty the cache now.
    79          */
    80         public void propertyChange(PropertyChangeEvent e) {
    81                 if (e.getPropertyName().equals("projection"))
    82                         projection = (Projection)e.getNewValue();
    83         }
    8453}
  • src/org/openstreetmap/josm/gui/engine/SimpleEngine.java

    r16 r17  
    66import java.util.HashSet;
    77
    8 import org.openstreetmap.josm.data.GeoPoint;
    98import org.openstreetmap.josm.data.osm.LineSegment;
    109import org.openstreetmap.josm.data.osm.Node;
    1110import org.openstreetmap.josm.data.osm.Track;
    12 import org.openstreetmap.josm.gui.MapView;
    1311
    1412/**
     
    2220        private final static Color darkblue = new Color(0,0,128);
    2321        private final static Color darkgreen = new Color(0,128,0);
    24 
    25         public SimpleEngine(MapView mapView) {
    26                 super(mapView);
    27         }
    28 
    29         /**
    30          * Draws black background.
    31          */
    32         @Override
    33         public void drawBackground(GeoPoint ulGeo, GeoPoint lrGeo) {
    34                 g.setColor(Color.BLACK);
    35                 g.fillRect(0,0,mv.getWidth(),mv.getHeight());
    36         }
    3722
    3823        /**
  • src/org/openstreetmap/josm/io/GpxReader.java

    r16 r17  
    4040         */
    4141        public Reader source;
     42        /**
     43         * If <code>true</code>, only nodes and tracks are imported (but no key/value
     44         * pairs). That is to support background gps information as an hint for
     45         * real OSM data.
     46         */
     47        private final boolean rawGps;
    4248       
    4349        /**
    4450         * Construct a parser from a specific data source.
    4551         * @param source The data source, as example a FileReader to read from a file.
    46          */
    47         public GpxReader(Reader source) {
     52         * @param rawGps Whether the gpx file describes raw gps data. Only very few
     53         *              information (only nodes and line segments) imported for raw gps to
     54         *              save memory.
     55         */
     56        public GpxReader(Reader source, boolean rawGps) {
    4857                this.source = source;
     58                this.rawGps = rawGps;
    4959        }
    5060       
     
    5666                        final SAXBuilder builder = new SAXBuilder();
    5767                        Element root = builder.build(source).getRootElement();
    58                         System.out.println(root.getNamespacePrefix());
    5968                       
    6069                        // HACK, since the osm server seem to not provide a namespace.
     
    8594                        Float.parseFloat(e.getAttributeValue("lat")),
    8695                        Float.parseFloat(e.getAttributeValue("lon")));
     96               
     97                if (rawGps)
     98                        return data;
     99               
    87100                for (Object o : e.getChildren()) {
    88101                        Element child = (Element)o;
     
    126139                for (Object o : e.getChildren()) {
    127140                        Element child = (Element)o;
    128                         if (child.getName().equals("extensions"))
    129                                 parseKeyValueExtensions(track, child);
    130                         else if (child.getName().equals("link"))
    131                                 parseKeyValueLink(track, child);
    132                         else if (child.getName().equals("trkseg")) {
     141
     142                        if (child.getName().equals("trkseg")) {
    133143                                Node start = null;
    134144                                for (Object w : child.getChildren("trkpt", GPX)) {
     
    139149                                        else {
    140150                                                LineSegment lineSegment = new LineSegment(start, node);
    141                                                 parseKeyValueExtensions(lineSegment, ((Element)w).getChild("extensions", GPX));
     151                                                if (!rawGps)
     152                                                        parseKeyValueExtensions(lineSegment, ((Element)w).getChild("extensions", GPX));
    142153                                                track.add(lineSegment);
    143154                                                start = null;
    144155                                        }
    145156                                }
    146                         } else
     157                        }
     158                       
     159                        if (rawGps)
     160                                continue;
     161                       
     162                        if (child.getName().equals("extensions"))
     163                                parseKeyValueExtensions(track, child);
     164                        else if (child.getName().equals("link"))
     165                                parseKeyValueLink(track, child);
     166                        else
    147167                                parseKeyValueTag(track, child);
    148168                }
     
    156176         * to the node in the list (either the new added or the old found).
    157177         *
     178         * If reading raw gps data, mergeNodes are always on (To save memory. You
     179         * can't edit raw gps nodes anyway.)
     180         *
    158181         * @param data The DataSet to add the node to.
    159182         * @param node The node that should be added.
     
    161184         */
    162185        private Node addNode (DataSet data, Node node) {
    163                 if (Main.pref.mergeNodes)
     186                if (Main.pref.mergeNodes || rawGps)
    164187                        for (Node n : data.nodes)
    165                                 if (node.coor.lat == n.coor.lat && node.coor.lon == n.coor.lon)
     188                                if (node.coor.equalsLatLon(n.coor))
    166189                                        return n;
    167190                data.nodes.add(node);
Note: See TracChangeset for help on using the changeset viewer.