// License: GPL. For details, see LICENSE file. package org.openstreetmap.josm.plugins.utilsplugin2.multitagger; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; import javax.swing.JTable; import javax.swing.table.AbstractTableModel; import org.openstreetmap.josm.Main; import org.openstreetmap.josm.command.ChangePropertyCommand; import org.openstreetmap.josm.command.Command; import org.openstreetmap.josm.command.SequenceCommand; import org.openstreetmap.josm.data.SelectionChangedListener; import org.openstreetmap.josm.data.osm.OsmPrimitive; import org.openstreetmap.josm.data.osm.OsmPrimitiveType; import org.openstreetmap.josm.data.osm.Way; import org.openstreetmap.josm.tools.Geometry; public class MultiTaggerTableModel extends AbstractTableModel implements SelectionChangedListener { ArrayList<OsmPrimitive> list = new ArrayList<>(50); String[] mainTags = new String[]{}; boolean[] isSpecialTag = new boolean[]{}; Set<OsmPrimitiveType> shownTypes = new HashSet<>(); private boolean autoCommit = true; List<Command> cmds = new ArrayList<>(); private boolean watchSelection = true; private JTable table; public MultiTaggerTableModel() { Collections.addAll(shownTypes, OsmPrimitiveType.values()); } @Override public int getRowCount() { return list.size(); } @Override public int getColumnCount() { return mainTags.length+1; } public void setWatchSelection(boolean watchSelection) { this.watchSelection = watchSelection; if (watchSelection && Main.getLayerManager().getEditLayer() != null) selectionChanged(Main.getLayerManager().getEditDataSet().getSelected()); } @Override public Object getValueAt(int rowIndex, int columnIndex) { if (columnIndex == 0) { return list.get(rowIndex).getDisplayType(); } if (!isSpecialTag[columnIndex-1]) { return list.get(rowIndex).get(mainTags[columnIndex-1]); } String var = mainTags[columnIndex-1]; OsmPrimitive p = list.get(rowIndex); if (var.equals("id")) { return String.valueOf(p.getUniqueId()); } else if (var.equals("type")) { return OsmPrimitiveType.from(p).getAPIName().substring(0, 1).toUpperCase(); } else if (var.equals("area")) { if (p.getDisplayType() == OsmPrimitiveType.CLOSEDWAY) { return String.format("%.1f", Geometry.closedWayArea((Way) p)); } else { return ""; } } else if (var.equals("length")) { if (p instanceof Way) { return String.format("%.1f", ((Way) p).getLength()); } } return ""; } @Override public Class<?> getColumnClass(int columnIndex) { if (columnIndex == 0) { return OsmPrimitiveType.class; } else { return String.class; } } @Override public void selectionChanged(Collection<? extends OsmPrimitive> newSelection) { if (watchSelection) updateData(newSelection); } @Override public boolean isCellEditable(int rowIndex, int columnIndex) { if (columnIndex == 0) return false; return !isSpecialTag[columnIndex-1]; } @Override public void setValueAt(Object value, int rowIndex, int columnIndex) { if (columnIndex == 0 || isSpecialTag[columnIndex-1]) return; if (columnIndex >= getColumnCount() || rowIndex >= getRowCount()) return; if (value == null) value = ""; String val = ((String) value).trim(); OsmPrimitive sel = list.get(rowIndex); String key = mainTags[columnIndex-1]; String newValue = sel.get(key); if (newValue == null) newValue = ""; if (!val.equals(newValue)) { Command cmd = new ChangePropertyCommand(sel, key, (String) value); if (autoCommit) { Main.main.undoRedo.add(cmd); } else { cmds.add(cmd); } } } @Override public String getColumnName(int column) { if (column == 0) return ""; return mainTags[column-1]; } public OsmPrimitive getPrimitiveAt(int number) { if (number < 0 || number >= list.size()) { return null; } else { return list.get(number); } } public void setupColumnsFromText(String txt) { String[] tags = txt.trim().split("[\\s,]+"); mainTags = new String[tags.length]; isSpecialTag = new boolean[tags.length]; int i = 0; for (String t: tags) { if (t.startsWith("${") && t.endsWith("}")) { mainTags[i] = t.substring(2, t.length()-1).trim(); isSpecialTag[i] = true; } else { mainTags[i] = t; isSpecialTag[i] = false; } i++; } } public String getSearchExpression() { StringBuilder sb = new StringBuilder(); boolean notFirst = false; for (int i = 0; i < mainTags.length; i++) { if (!isSpecialTag[i]) { if (notFirst) sb.append(" | "); sb.append("\""); sb.append(mainTags[i]); sb.append("\":"); notFirst = true; } } return sb.toString(); } void updateData(Collection<? extends OsmPrimitive> sel) { if (table.isEditing()) table.getCellEditor().stopCellEditing(); list.clear(); for (OsmPrimitive p : sel) { if (shownTypes.contains(p.getDisplayType())) { list.add(p); } } fireTableDataChanged(); } void setAutoCommit(boolean b) { autoCommit = b; } void commit(String commandTitle) { Main.main.undoRedo.add(new SequenceCommand(commandTitle, cmds)); cmds.clear(); } void setTable(JTable t) { table = t; } }