001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.gui.dialogs.changeset; 003 004import java.util.ArrayList; 005import java.util.HashSet; 006import java.util.Iterator; 007import java.util.List; 008import java.util.Set; 009 010import javax.swing.DefaultListSelectionModel; 011import javax.swing.table.AbstractTableModel; 012 013import org.openstreetmap.josm.data.osm.ChangesetDataSet; 014import org.openstreetmap.josm.data.osm.ChangesetDataSet.ChangesetDataSetEntry; 015import org.openstreetmap.josm.data.osm.ChangesetDataSet.ChangesetModificationType; 016import org.openstreetmap.josm.data.osm.history.HistoryOsmPrimitive; 017 018/** 019 * This is the table model for the content of a changeset. 020 * 021 */ 022public class ChangesetContentTableModel extends AbstractTableModel { 023 024 private final transient List<ChangesetContentEntry> data = new ArrayList<>(); 025 private final DefaultListSelectionModel selectionModel; 026 027 public ChangesetContentTableModel(DefaultListSelectionModel selectionModel) { 028 this.selectionModel = selectionModel; 029 } 030 031 /** 032 * Replies true if there is at least one selected primitive in the table model 033 * 034 * @return true if there is at least one selected primitive in the table model 035 */ 036 public boolean hasSelectedPrimitives() { 037 return selectionModel.getMinSelectionIndex() >= 0; 038 } 039 040 public void setSelectedByIdx(int row) { 041 selectionModel.setSelectionInterval(row, row); 042 } 043 044 /** 045 * Replies the selection model 046 * @return the selection model 047 */ 048 public DefaultListSelectionModel getSelectionModel() { 049 return selectionModel; 050 } 051 052 public Set<HistoryOsmPrimitive> getSelectedPrimitives() { 053 Set<HistoryOsmPrimitive> ret = new HashSet<>(); 054 for (int i = 0; i < data.size(); i++) { 055 if (selectionModel.isSelectedIndex(i)) { 056 ret.add(data.get(i).getPrimitive()); 057 } 058 } 059 return ret; 060 } 061 062 /** 063 * Populates the model with the content of a changeset. If ds is null, the table is cleared. 064 * 065 * @param ds the changeset content. 066 */ 067 public void populate(ChangesetDataSet ds) { 068 this.data.clear(); 069 if (ds == null) { 070 fireTableDataChanged(); 071 return; 072 } 073 for (Iterator<ChangesetDataSetEntry> it = ds.iterator(); it.hasNext();) { 074 data.add(new ChangesetContentEntry(it.next())); 075 } 076 sort(); 077 fireTableDataChanged(); 078 } 079 080 protected void sort() { 081 data.sort((c1, c2) -> { 082 if (c1.getModificationType().equals(c2.getModificationType())) { 083 long id1 = c1.getPrimitive().getId(); 084 long id2 = c2.getPrimitive().getId(); 085 086 if (id1 == id2) 087 return 0; 088 else if (id1 < id2) 089 return -1; 090 return 1; 091 } 092 switch(c1.getModificationType()) { 093 case CREATED: return -1; 094 case UPDATED: 095 switch(c2.getModificationType()) { 096 case CREATED: return 1; 097 default: return -1; 098 } 099 case DELETED: 100 return 1; 101 } 102 // should not happen 103 return 0; 104 } 105 ); 106 } 107 108 /* -------------------------------------------------------------- */ 109 /* interface TableModel */ 110 /* -------------------------------------------------------------- */ 111 @Override 112 public int getColumnCount() { 113 return 3; 114 } 115 116 @Override 117 public int getRowCount() { 118 return data.size(); 119 } 120 121 @Override 122 public Object getValueAt(int row, int col) { 123 switch(col) { 124 case 0: return data.get(row).getModificationType(); 125 default: return data.get(row).getPrimitive(); 126 } 127 } 128 129 /** 130 * The type used internally to keep information about {@link HistoryOsmPrimitive} 131 * with their {@link ChangesetModificationType}. 132 * 133 */ 134 private static class ChangesetContentEntry implements ChangesetDataSetEntry { 135 private final ChangesetModificationType modificationType; 136 private final HistoryOsmPrimitive primitive; 137 138 ChangesetContentEntry(ChangesetModificationType modificationType, HistoryOsmPrimitive primitive) { 139 this.modificationType = modificationType; 140 this.primitive = primitive; 141 } 142 143 ChangesetContentEntry(ChangesetDataSetEntry entry) { 144 this(entry.getModificationType(), entry.getPrimitive()); 145 } 146 147 @Override 148 public ChangesetModificationType getModificationType() { 149 return modificationType; 150 } 151 152 @Override 153 public HistoryOsmPrimitive getPrimitive() { 154 return primitive; 155 } 156 } 157}