// License: GPL. For details, see LICENSE file. package public_transport; import static org.openstreetmap.josm.tools.I18n.tr; import java.util.Vector; import javax.swing.event.TableModelEvent; import javax.swing.event.TableModelListener; import javax.swing.table.DefaultTableModel; import org.openstreetmap.josm.data.osm.Node; import org.openstreetmap.josm.data.osm.Way; public class ItineraryTableModel extends DefaultTableModel implements TableModelListener { public Vector<Way> ways = new Vector<>(); public boolean inEvent = false; @Override public boolean isCellEditable(int row, int column) { if (column != 1) return false; if (ways.elementAt(row) == null) return false; return true; } @Override public void addRow(Object[] obj) { ways.addElement(null); super.addRow(obj); } @Override public void insertRow(int insPos, Object[] obj) { if (insPos == -1) { ways.addElement(null); super.addRow(obj); } else { ways.insertElementAt(null, insPos); super.insertRow(insPos, obj); } } public void addRow(Way way, String role) { insertRow(-1, way, role); } public void insertRow(int insPos, Way way, String role) { String[] buf = {"", ""}; String curName = way.get("name"); if (way.isIncomplete()) buf[0] = tr("[incomplete]"); else if (way.getNodesCount() < 1) buf[0] = tr("[empty way]"); else if (curName != null) buf[0] = curName; else buf[0] = tr("[ID] {0}", (Long.valueOf(way.getId())).toString()); buf[1] = role; if (insPos == -1) { ways.addElement(way); super.addRow(buf); } else { ways.insertElementAt(way, insPos); super.insertRow(insPos, buf); } } public void clear() { ways.clear(); super.setRowCount(0); } public void cleanupGaps() { inEvent = true; Node lastNode = null; for (int i = 0; i < getRowCount(); ++i) { if (ways.elementAt(i) == null) { ++i; if (i >= getRowCount()) break; } while ((ways.elementAt(i) == null) && ((i == 0) || (ways.elementAt(i - 1) == null))) { ways.removeElementAt(i); removeRow(i); if (i >= getRowCount()) break; } if (i >= getRowCount()) break; boolean gapRequired = gapNecessary(ways.elementAt(i), (String) (getValueAt(i, 1)), lastNode); if ((i > 0) && (!gapRequired) && (ways.elementAt(i - 1) == null)) { ways.removeElementAt(i - 1); removeRow(i - 1); --i; } else if ((i > 0) && gapRequired && (ways.elementAt(i - 1) != null)) { String[] buf = {"", ""}; buf[0] = tr("[gap]"); insertRow(i, buf); ++i; } lastNode = getLastNode(ways.elementAt(i), (String) (getValueAt(i, 1))); } while ((getRowCount() > 0) && (ways.elementAt(getRowCount() - 1) == null)) { ways.removeElementAt(getRowCount() - 1); removeRow(getRowCount() - 1); } inEvent = false; } @Override public void tableChanged(TableModelEvent e) { if (e.getType() == TableModelEvent.UPDATE) { if (inEvent) return; cleanupGaps(); RoutePatternAction.rebuildWays(); } } private Node getLastNode(Way way, String role) { if ((way == null) || (way.isIncomplete()) || (way.getNodesCount() < 1)) return null; else { if ("backward".equals(role)) return way.getNode(0); else return way.getNode(way.getNodesCount() - 1); } } private boolean gapNecessary(Way way, String role, Node lastNode) { if ((way != null) && (!(way.isIncomplete())) && (way.getNodesCount() >= 1)) { Node firstNode = null; if ("backward".equals(role)) firstNode = way.getNode(way.getNodesCount() - 1); else firstNode = way.getNode(0); if ((lastNode != null) && (!lastNode.equals(firstNode))) return true; } return false; } }