// License: GPL. For details, see LICENSE file. package org.openstreetmap.josm.gui.dialogs.changeset; import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import javax.swing.DefaultListSelectionModel; import javax.swing.table.AbstractTableModel; import org.openstreetmap.josm.data.osm.ChangesetDataSet; import org.openstreetmap.josm.data.osm.ChangesetDataSet.ChangesetDataSetEntry; import org.openstreetmap.josm.data.osm.ChangesetDataSet.ChangesetModificationType; import org.openstreetmap.josm.data.osm.history.HistoryOsmPrimitive; /** * This is the table model for the content of a changeset. * @since 2689 */ public class ChangesetContentTableModel extends AbstractTableModel { private final transient List<ChangesetContentEntry> data = new ArrayList<>(); private final DefaultListSelectionModel selectionModel; /** * Constructs a new {@code ChangesetContentTableModel}. * @param selectionModel selection model */ public ChangesetContentTableModel(DefaultListSelectionModel selectionModel) { this.selectionModel = selectionModel; } /** * Replies true if there is at least one selected primitive in the table model * * @return true if there is at least one selected primitive in the table model */ public boolean hasSelectedPrimitives() { return selectionModel.getMinSelectionIndex() >= 0; } /** * Selects a single item by its index. * @param row index */ public void setSelectedByIdx(int row) { selectionModel.setSelectionInterval(row, row); } /** * Replies the selection model * @return the selection model */ public DefaultListSelectionModel getSelectionModel() { return selectionModel; } /** * Returns the selected history primitives. * @return the selected history primitives */ public Set<HistoryOsmPrimitive> getSelectedPrimitives() { Set<HistoryOsmPrimitive> ret = new HashSet<>(); for (int i = 0; i < data.size(); i++) { if (selectionModel.isSelectedIndex(i)) { ret.add(data.get(i).getPrimitive()); } } return ret; } /** * Populates the model with the content of a changeset. If ds is null, the table is cleared. * * @param ds the changeset content. */ public void populate(ChangesetDataSet ds) { this.data.clear(); if (ds == null) { fireTableDataChanged(); return; } for (Iterator<ChangesetDataSetEntry> it = ds.iterator(); it.hasNext();) { data.add(new ChangesetContentEntry(it.next())); } sort(); fireTableDataChanged(); } /** * Sort data. */ protected void sort() { data.sort((c1, c2) -> { if (c1.getModificationType().equals(c2.getModificationType())) { long id1 = c1.getPrimitive().getId(); long id2 = c2.getPrimitive().getId(); if (id1 == id2) return 0; else if (id1 < id2) return -1; return 1; } switch(c1.getModificationType()) { case CREATED: return -1; case UPDATED: switch(c2.getModificationType()) { case CREATED: return 1; default: return -1; } case DELETED: return 1; } // should not happen return 0; } ); } /* -------------------------------------------------------------- */ /* interface TableModel */ /* -------------------------------------------------------------- */ @Override public int getColumnCount() { return 3; } @Override public int getRowCount() { return data.size(); } @Override public Object getValueAt(int row, int col) { switch(col) { case 0: return data.get(row).getModificationType(); default: return data.get(row).getPrimitive(); } } /** * The type used internally to keep information about {@link HistoryOsmPrimitive} * with their {@link ChangesetModificationType}. */ private static class ChangesetContentEntry implements ChangesetDataSetEntry { private final ChangesetModificationType modificationType; private final HistoryOsmPrimitive primitive; ChangesetContentEntry(ChangesetModificationType modificationType, HistoryOsmPrimitive primitive) { this.modificationType = modificationType; this.primitive = primitive; } ChangesetContentEntry(ChangesetDataSetEntry entry) { this(entry.getModificationType(), entry.getPrimitive()); } @Override public ChangesetModificationType getModificationType() { return modificationType; } @Override public HistoryOsmPrimitive getPrimitive() { return primitive; } } }