Index: /applications/editors/josm/plugins/public_transport/src/public_transport/StopImporterAction.java
===================================================================
--- /applications/editors/josm/plugins/public_transport/src/public_transport/StopImporterAction.java	(revision 20727)
+++ /applications/editors/josm/plugins/public_transport/src/public_transport/StopImporterAction.java	(revision 20728)
@@ -4,7 +4,5 @@
 import static org.openstreetmap.josm.tools.I18n.tr;
 
-// import java.awt.BorderLayout;
 import java.awt.Container;
-// import java.awt.Dimension;
 import java.awt.Frame;
 import java.awt.GridBagConstraints;
@@ -18,21 +16,11 @@
 import java.text.DecimalFormat;
 import java.text.Format;
-// import java.util.Collection;
 import java.util.Collections;
 import java.util.Iterator;
-// import java.util.LinkedList;
-// import java.util.List;
-// import java.util.ListIterator;
-// import java.util.Map;
-// import java.util.TreeMap;
-// import java.util.TreeSet;
 import java.util.Vector;
 import java.util.zip.GZIPInputStream;
-// 
-// import javax.swing.DefaultCellEditor;
+
 import javax.swing.DefaultListModel;
 import javax.swing.JButton;
-// import javax.swing.JCheckBox;
-// import javax.swing.JComboBox;
 import javax.swing.JDialog;
 import javax.swing.JFileChooser;
@@ -51,5 +39,4 @@
 import javax.swing.event.TableModelListener;
 import javax.swing.table.DefaultTableModel;
-// import javax.swing.table.TableCellEditor;
 
 import org.openstreetmap.josm.Main;
@@ -66,13 +53,6 @@
 import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
-// import org.openstreetmap.josm.data.osm.Relation;
-// import org.openstreetmap.josm.data.osm.RelationMember;
-// import org.openstreetmap.josm.data.osm.Way;
 import org.openstreetmap.josm.data.osm.visitor.BoundingXYVisitor;
-// import org.openstreetmap.josm.gui.ExtendedDialog;
 import org.openstreetmap.josm.io.GpxReader;
-// import org.openstreetmap.josm.tools.GBC;
-// import org.openstreetmap.josm.tools.Shortcut;
-// import org.openstreetmap.josm.tools.UrlLabel;
 
 import org.xml.sax.SAXException;
@@ -183,5 +163,7 @@
 	if (stoplistTM.nodes.elementAt(e.getFirstRow()) == null)
 	{
-	  createNode(e.getFirstRow(), latLon, (String)stoplistTM.getValueAt(e.getFirstRow(), 1));
+	  Node node = createNode
+	      (latLon, (String)stoplistTM.getValueAt(e.getFirstRow(), 1));
+	  stoplistTM.nodes.set(e.getFirstRow(), node);
 	}
 	else
@@ -251,23 +233,4 @@
     }
     
-    public void createNode(int index, LatLon latLon, String name)
-    {
-      Node node = new Node(latLon);
-      node.put("highway", "bus_stop");
-      node.put("name", name);
-      if (Main.main.getCurrentDataSet() == null)
-      {
-	JOptionPane.showMessageDialog(null, "There exists no dataset."
-	    + " Try to download data from the server or open an OSM file.",
-     "No data found", JOptionPane.ERROR_MESSAGE);
-      
-	System.out.println("Public Transport: StopInserter: No data found");
-	    
-	return;
-      }
-      Main.main.getCurrentDataSet().addPrimitive(node);
-      stoplistTM.nodes.set(index, node);
-    }
-    
     public void relocateNodes()
     {
@@ -399,5 +362,6 @@
 	  time -= timeDelta;
 	  stoplistTM.insertRow(-1, timeOf(time));
-	  createNode(stoplistTM.getRowCount()-1, latLon, "");
+	  Node node = createNode(latLon, "");
+	  stoplistTM.nodes.set(stoplistTM.getRowCount()-1, node);
 	}
 	
@@ -472,5 +436,6 @@
     }
     
-    public void insertRow(int insPos, Node node, String time, String name) {
+    public void insertRow(int insPos, Node node, String time, String name)
+    {
       String[] buf = { "", "" };
       buf[0] = time;
@@ -492,4 +457,83 @@
       nodes.clear();
       super.setRowCount(0);
+    }
+  };
+  
+  private class WaypointTableModel extends DefaultTableModel
+      implements TableModelListener
+  {
+    public Vector< Node > nodes = new Vector< Node >();
+    public Vector< LatLon > coors = new Vector< LatLon >();
+    
+    public WaypointTableModel()
+    {
+      addColumn("Time");
+      addColumn("Stopname");
+      addTableModelListener(this);
+    }
+    
+    public boolean isCellEditable(int row, int column)
+    {
+      if (column == 1)
+	return true;
+      return false;
+    }
+    
+    public void addRow(Object[] obj)
+    {
+      throw new UnsupportedOperationException();
+    }
+    
+    public void insertRow(int insPos, Object[] obj)
+    {
+      throw new UnsupportedOperationException();
+    }
+    
+    public void addRow(WayPoint wp)
+    {
+      insertRow(-1, wp);
+    }
+    
+    public void insertRow(int insPos, WayPoint wp)
+    {
+      Node node = createNode(wp.getCoor(), "");
+      
+      String[] buf = { "", "" };
+      buf[0] = wp.getString("time");
+      if (buf[0] == null)
+	buf[0] = "";
+      buf[1] = wp.getString("name");
+      if (buf[1] == null)
+	buf[1] = "";
+      if (insPos == -1)
+      {
+	nodes.addElement(node);
+	coors.addElement(wp.getCoor());
+	super.addRow(buf);
+      }
+      else
+      {
+	nodes.insertElementAt(node, insPos);
+	coors.insertElementAt(wp.getCoor(), insPos);
+	super.insertRow(insPos, buf);
+      }
+    }
+    
+    public void clear()
+    {
+      nodes.clear();
+      super.setRowCount(0);
+    }
+  
+    public void tableChanged(TableModelEvent e)
+    {
+      if (e.getType() == TableModelEvent.UPDATE)
+      {
+	if (nodes.elementAt(e.getFirstRow()) != null)
+	{
+	  Node node = nodes.elementAt(e.getFirstRow());
+	  node.put("name", (String)getValueAt(e.getFirstRow(), 1));
+	}
+      }
     }
   };
@@ -504,6 +548,8 @@
   private static JTextField tfThreshold = null;
   private static JTable stoplistTable = null;
+  private static JTable waypointTable = null;
   private static GpxData data = null;
   private static TrackReference currentTrack = null;
+  private static WaypointTableModel waypointTM = null;
   
   public StopImporterAction()
@@ -528,7 +574,10 @@
       JPanel tabStops = new JPanel();
       tabbedPane.addTab(marktr("Stops"), tabStops);
+      JPanel tabWaypoints = new JPanel();
+      tabbedPane.addTab(marktr("Waypoints"), tabWaypoints);
       tabbedPane.setEnabledAt(0, true);
       tabbedPane.setEnabledAt(1, false);
       tabbedPane.setEnabledAt(2, false);
+      tabbedPane.setEnabledAt(3, true);
       jDialog.add(tabbedPane);
       
@@ -776,5 +825,5 @@
       layoutCons.gridx = 1;
       layoutCons.gridy = 1;
-      layoutCons.gridheight = 2;
+      layoutCons.gridheight = 1;
       layoutCons.gridwidth = 1;
       layoutCons.weightx = 1.0;
@@ -783,4 +832,18 @@
       gridbag.setConstraints(bMark, layoutCons);
       contentPane.add(bMark);
+      
+      JButton bDetach = new JButton("Detach");
+      bDetach.setActionCommand("stopImporter.stoplistDetach");
+      bDetach.addActionListener(this);
+      
+      layoutCons.gridx = 1;
+      layoutCons.gridy = 2;
+      layoutCons.gridheight = 1;
+      layoutCons.gridwidth = 1;
+      layoutCons.weightx = 1.0;
+      layoutCons.weighty = 0.0;
+      layoutCons.fill = GridBagConstraints.BOTH;
+      gridbag.setConstraints(bDetach, layoutCons);
+      contentPane.add(bDetach);
       
       JButton bAdd = new JButton("Add");
@@ -824,4 +887,103 @@
       gridbag.setConstraints(bSort, layoutCons);
       contentPane.add(bSort);
+      
+      //Waypoints Tab
+      contentPane = tabWaypoints;
+      gridbag = new GridBagLayout();
+      layoutCons = new GridBagConstraints();
+      contentPane.setLayout(gridbag);
+      
+      waypointTable = new JTable();
+      /*JScrollPane*/ tableSP = new JScrollPane(waypointTable);
+      
+      layoutCons.gridx = 0;
+      layoutCons.gridy = 0;
+      layoutCons.gridwidth = 3;
+      layoutCons.weightx = 1.0;
+      layoutCons.weighty = 1.0;
+      layoutCons.fill = GridBagConstraints.BOTH;
+      gridbag.setConstraints(tableSP, layoutCons);
+      contentPane.add(tableSP);
+      
+      /*JButton*/ bFind = new JButton("Find");
+      bFind.setActionCommand("stopImporter.waypointsFind");
+      bFind.addActionListener(this);
+      
+      layoutCons.gridx = 0;
+      layoutCons.gridy = 1;
+      layoutCons.gridwidth = 1;
+      layoutCons.weightx = 1.0;
+      layoutCons.weighty = 0.0;
+      layoutCons.fill = GridBagConstraints.BOTH;
+      gridbag.setConstraints(bFind, layoutCons);
+      contentPane.add(bFind);
+      
+      /*JButton*/ bShow = new JButton("Show");
+      bShow.setActionCommand("stopImporter.waypointsShow");
+      bShow.addActionListener(this);
+      
+      layoutCons.gridx = 0;
+      layoutCons.gridy = 2;
+      layoutCons.gridwidth = 1;
+      layoutCons.weightx = 1.0;
+      layoutCons.weighty = 0.0;
+      layoutCons.fill = GridBagConstraints.BOTH;
+      gridbag.setConstraints(bShow, layoutCons);
+      contentPane.add(bShow);
+      
+      /*JButton*/ bMark = new JButton("Mark");
+      bMark.setActionCommand("stopImporter.waypointsMark");
+      bMark.addActionListener(this);
+      
+      layoutCons.gridx = 1;
+      layoutCons.gridy = 1;
+      layoutCons.gridheight = 1;
+      layoutCons.gridwidth = 1;
+      layoutCons.weightx = 1.0;
+      layoutCons.weighty = 0.0;
+      layoutCons.fill = GridBagConstraints.BOTH;
+      gridbag.setConstraints(bMark, layoutCons);
+      contentPane.add(bMark);
+      
+      /*JButton*/ bDetach = new JButton("Detach");
+      bDetach.setActionCommand("stopImporter.waypointsDetach");
+      bDetach.addActionListener(this);
+      
+      layoutCons.gridx = 1;
+      layoutCons.gridy = 2;
+      layoutCons.gridheight = 1;
+      layoutCons.gridwidth = 1;
+      layoutCons.weightx = 1.0;
+      layoutCons.weighty = 0.0;
+      layoutCons.fill = GridBagConstraints.BOTH;
+      gridbag.setConstraints(bDetach, layoutCons);
+      contentPane.add(bDetach);
+      
+      /*JButton*/ bAdd = new JButton("Enable");
+      bAdd.setActionCommand("stopImporter.waypointsAdd");
+      bAdd.addActionListener(this);
+      
+      layoutCons.gridx = 2;
+      layoutCons.gridy = 1;
+      layoutCons.gridheight = 1;
+      layoutCons.gridwidth = 1;
+      layoutCons.weightx = 1.0;
+      layoutCons.weighty = 0.0;
+      layoutCons.fill = GridBagConstraints.BOTH;
+      gridbag.setConstraints(bAdd, layoutCons);
+      contentPane.add(bAdd);
+      
+      /*JButton*/ bDelete = new JButton("Disable");
+      bDelete.setActionCommand("stopImporter.waypointsDelete");
+      bDelete.addActionListener(this);
+      
+      layoutCons.gridx = 2;
+      layoutCons.gridy = 2;
+      layoutCons.gridwidth = 1;
+      layoutCons.weightx = 1.0;
+      layoutCons.weighty = 0.0;
+      layoutCons.fill = GridBagConstraints.BOTH;
+      gridbag.setConstraints(bDelete, layoutCons);
+      contentPane.add(bDelete);
       
       jDialog.pack();
@@ -982,4 +1144,27 @@
 	}
       }
+    }
+    else if ("stopImporter.stoplistDetach".equals(event.getActionCommand()))
+    {
+      if (stoplistTable.getSelectedRowCount() > 0)
+      {
+	for (int i = 0; i < currentTrack.stoplistTM.getRowCount(); ++i)
+	{
+	  if ((stoplistTable.isRowSelected(i)) &&
+		      (currentTrack.stoplistTM.nodes.elementAt(i) != null))
+	  {
+	    currentTrack.stoplistTM.nodes.set(i, null);
+	  }
+	}
+      }
+      else
+      {
+	for (int i = 0; i < currentTrack.stoplistTM.getRowCount(); ++i)
+	{
+	  if (currentTrack.stoplistTM.nodes.elementAt(i) != null)
+	    currentTrack.stoplistTM.nodes.set(i, null);
+	}
+      }
+      stoplistTable.clearSelection();
     }
     else if ("stopImporter.stoplistAdd".equals(event.getActionCommand()))
@@ -1058,4 +1243,135 @@
       }
     }
+    else if ("stopImporter.waypointsFind".equals(event.getActionCommand()))
+    {
+      if (Main.main.getCurrentDataSet() == null)
+	return;
+      
+      waypointTable.clearSelection();
+      
+      for (int i = 0; i < waypointTM.getRowCount(); ++i)
+      {
+	if ((waypointTM.nodes.elementAt(i) != null) &&
+		    (Main.main.getCurrentDataSet().isSelected(waypointTM.nodes.elementAt(i))))
+	  waypointTable.addRowSelectionInterval(i, i);
+      }
+    }
+    else if ("stopImporter.waypointsShow".equals(event.getActionCommand()))
+    {
+      BoundingXYVisitor box = new BoundingXYVisitor();
+      if (waypointTable.getSelectedRowCount() > 0)
+      {
+	for (int i = 0; i < waypointTM.getRowCount(); ++i)
+	{
+	  if ((waypointTable.isRowSelected(i)) &&
+		      (waypointTM.nodes.elementAt(i) != null))
+	  {
+	    waypointTM.nodes.elementAt(i).visit(box);
+	  }
+	}
+      }
+      else
+      {
+	for (int i = 0; i < waypointTM.getRowCount(); ++i)
+	{
+	  if (waypointTM.nodes.elementAt(i) != null)
+	    waypointTM.nodes.elementAt(i).visit(box);
+	}
+      }
+      if (box.getBounds() == null)
+	return;
+      box.enlargeBoundingBox();
+      Main.map.mapView.recalculateCenterScale(box);
+    }
+    else if ("stopImporter.waypointsMark".equals(event.getActionCommand()))
+    {
+      OsmPrimitive[] osmp = { null };
+      Main.main.getCurrentDataSet().setSelected(osmp);
+      if (waypointTable.getSelectedRowCount() > 0)
+      {
+	for (int i = 0; i < waypointTM.getRowCount(); ++i)
+	{
+	  if ((waypointTable.isRowSelected(i)) &&
+		      (waypointTM.nodes.elementAt(i) != null))
+	  {
+	    Main.main.getCurrentDataSet().addSelected(waypointTM.nodes.elementAt(i));
+	  }
+	}
+      }
+      else
+      {
+	for (int i = 0; i < waypointTM.getRowCount(); ++i)
+	{
+	  if (waypointTM.nodes.elementAt(i) != null)
+	    Main.main.getCurrentDataSet().addSelected(waypointTM.nodes.elementAt(i));
+	}
+      }
+    }
+    else if ("stopImporter.waypointsDetach".equals(event.getActionCommand()))
+    {
+      if (waypointTable.getSelectedRowCount() > 0)
+      {
+	for (int i = 0; i < waypointTM.getRowCount(); ++i)
+	{
+	  if ((waypointTable.isRowSelected(i)) &&
+		      (waypointTM.nodes.elementAt(i) != null))
+	  {
+	    waypointTM.nodes.set(i, null);
+	  }
+	}
+      }
+      else
+      {
+	for (int i = 0; i < waypointTM.getRowCount(); ++i)
+	{
+	  if (waypointTM.nodes.elementAt(i) != null)
+	    waypointTM.nodes.set(i, null);
+	}
+      }
+      waypointTable.clearSelection();
+    }
+    else if ("stopImporter.waypointsAdd".equals(event.getActionCommand()))
+    {
+      if (waypointTable.getSelectedRowCount() > 0)
+      {
+	for (int i = 0; i < waypointTM.getRowCount(); ++i)
+	{
+	  if ((waypointTable.isRowSelected(i)) &&
+		      (waypointTM.nodes.elementAt(i) == null))
+	  {
+	    Node node = createNode(waypointTM.coors.elementAt(i), (String)waypointTM.getValueAt(i, 1));
+	    waypointTM.nodes.set(i, node);
+	    Main.main.getCurrentDataSet().addSelected(waypointTM.nodes.elementAt(i));
+	  }
+	}
+      }
+      else
+      {
+	for (int i = 0; i < waypointTM.getRowCount(); ++i)
+	{
+	  if (waypointTM.nodes.elementAt(i) == null)
+	    Main.main.getCurrentDataSet().addSelected(waypointTM.nodes.elementAt(i));
+	}
+      }
+    }
+    else if ("stopImporter.waypointsDelete".equals(event.getActionCommand()))
+    {
+      Vector< Node > toDelete = new Vector< Node >();
+      for (int i = waypointTM.getRowCount()-1; i >=0; --i)
+      {
+	if (waypointTable.isRowSelected(i))
+	{
+	  if ((Node)waypointTM.nodes.elementAt(i) != null)
+	    toDelete.add((Node)waypointTM.nodes.elementAt(i));
+	  waypointTM.nodes.set(i, null);
+	}
+      }
+      Command cmd = DeleteCommand.delete
+	  (Main.main.getEditLayer(), toDelete);
+      if (cmd != null) {
+	// cmd can be null if the user cancels dialogs DialogCommand displays
+	Main.main.undoRedo.add(cmd);
+      }
+    }
   }
 
@@ -1107,5 +1423,5 @@
   private void refreshData()
   {
-    tracksListModel.clear();	
+    tracksListModel.clear();
     if (data != null)
     {
@@ -1123,9 +1439,18 @@
       while (iter.hasNext())
 	tracksListModel.addElement(iter.next());
+      
+      waypointTM = new WaypointTableModel();
+      Iterator< WayPoint > waypointIter = data.waypoints.iterator();
+      while (waypointIter.hasNext())
+      {
+	WayPoint waypoint = waypointIter.next();
+	waypointTM.addRow(waypoint);
+      }
+      waypointTable.setModel(waypointTM);
     }
     else
     {
       JOptionPane.showMessageDialog
-      (null, "The GPX file contained no tracks.", "No data found",
+      (null, "The GPX file contained no tracks or waypoints.", "No data found",
        JOptionPane.ERROR_MESSAGE);
       
@@ -1161,4 +1486,23 @@
   }
 
+  private Node createNode(LatLon latLon, String name)
+  {
+    Node node = new Node(latLon);
+    node.put("highway", "bus_stop");
+    node.put("name", name);
+    if (Main.main.getCurrentDataSet() == null)
+    {
+      JOptionPane.showMessageDialog(null, "There exists no dataset."
+	  + " Try to download data from the server or open an OSM file.",
+   "No data found", JOptionPane.ERROR_MESSAGE);
+      
+      System.out.println("Public Transport: StopInserter: No data found");
+	    
+      return null;
+    }
+    Main.main.getCurrentDataSet().addPrimitive(node);
+    return node;
+  }
+    
   private static double parseTime(String s)
   {
