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