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.Collection; 006 import java.util.Collections; 007 import java.util.Comparator; 008 import java.util.HashSet; 009 import java.util.List; 010 import java.util.Set; 011 012 import javax.swing.DefaultListModel; 013 import javax.swing.DefaultListSelectionModel; 014 015 import org.openstreetmap.josm.data.osm.Changeset; 016 import org.openstreetmap.josm.data.osm.ChangesetCache; 017 import org.openstreetmap.josm.data.osm.ChangesetCacheEvent; 018 import org.openstreetmap.josm.data.osm.ChangesetCacheListener; 019 import org.openstreetmap.josm.data.osm.DataSet; 020 import org.openstreetmap.josm.data.osm.OsmPrimitive; 021 import org.openstreetmap.josm.data.osm.Storage; 022 023 public class ChangesetListModel extends DefaultListModel implements ChangesetCacheListener{ 024 private final List<Changeset> data = new ArrayList<Changeset>(); 025 private final Storage<Changeset> shownChangesets = new Storage<Changeset>(true); 026 private DefaultListSelectionModel selectionModel; 027 028 public ChangesetListModel(DefaultListSelectionModel selectionModel) { 029 this.selectionModel = selectionModel; 030 } 031 032 public Set<Changeset> getSelectedChangesets() { 033 Set<Changeset> ret = new HashSet<Changeset>(); 034 for (int i=0; i < getSize(); i++) { 035 if (selectionModel.isSelectedIndex(i)) { 036 ret.add(data.get(i)); 037 } 038 } 039 return ret; 040 } 041 042 public Set<Integer> getSelectedChangesetIds() { 043 Set<Integer> ret = new HashSet<Integer>(); 044 for (int i=0; i < getSize(); i++) { 045 if (selectionModel.isSelectedIndex(i)) { 046 ret.add(data.get(i).getId()); 047 } 048 } 049 return ret; 050 } 051 052 public void setSelectedChangesets(Collection<Changeset> changesets) { 053 selectionModel.clearSelection(); 054 if (changesets == null) return; 055 for (Changeset cs: changesets) { 056 int idx = data.indexOf(cs); 057 if (idx < 0) { 058 continue; 059 } 060 selectionModel.addSelectionInterval(idx,idx); 061 } 062 } 063 064 protected void setChangesets(Collection<Changeset> changesets) { 065 shownChangesets.clear(); 066 if (changesets != null) { 067 shownChangesets.addAll(changesets); 068 } 069 updateModel(); 070 } 071 072 private void updateModel() { 073 Set<Changeset> sel = getSelectedChangesets(); 074 data.clear(); 075 data.addAll(shownChangesets); 076 ChangesetCache cache = ChangesetCache.getInstance(); 077 for (Changeset cs: data) { 078 if (cache.contains(cs) && cache.get(cs.getId()) != cs) { 079 cs.mergeFrom(cache.get(cs.getId())); 080 } 081 } 082 sort(); 083 fireIntervalAdded(this, 0, getSize()); 084 setSelectedChangesets(sel); 085 } 086 087 public void initFromChangesetIds(Collection<Integer> ids) { 088 if (ids == null || ids.isEmpty()) { 089 setChangesets(null); 090 return; 091 } 092 Set<Changeset> changesets = new HashSet<Changeset>(ids.size()); 093 for (int id: ids) { 094 if (id <= 0) { 095 continue; 096 } 097 changesets.add(new Changeset(id)); 098 } 099 setChangesets(changesets); 100 } 101 102 public void initFromPrimitives(Collection<? extends OsmPrimitive> primitives) { 103 if (primitives == null) { 104 setChangesets(null); 105 return; 106 } 107 Set<Changeset> changesets = new HashSet<Changeset>(); 108 for (OsmPrimitive p: primitives) { 109 if (p.getChangesetId() <= 0) { 110 continue; 111 } 112 changesets.add(new Changeset(p.getChangesetId())); 113 } 114 setChangesets(changesets); 115 } 116 117 public void initFromDataSet(DataSet ds) { 118 if (ds == null) { 119 setChangesets(null); 120 return; 121 } 122 Set<Changeset> changesets = new HashSet<Changeset>(); 123 for (OsmPrimitive p: ds.allPrimitives()) { 124 if (p.getChangesetId() <=0 ) { 125 continue; 126 } 127 changesets.add(new Changeset(p.getChangesetId())); 128 } 129 setChangesets(changesets); 130 } 131 132 @Override 133 public Object getElementAt(int idx) { 134 return data.get(idx); 135 } 136 137 @Override 138 public int getSize() { 139 return data.size(); 140 } 141 142 protected void sort() { 143 Collections.sort( 144 data, 145 new Comparator<Changeset>() { 146 public int compare(Changeset cs1, Changeset cs2) { 147 if (cs1.getId() > cs2.getId()) return -1; 148 if (cs1.getId() == cs2.getId()) return 0; 149 return 1; 150 } 151 } 152 ); 153 } 154 155 /** 156 * Replies true if there is at least one selected open changeset 157 * 158 * @return true if there is at least one selected open changeset 159 */ 160 public boolean hasSelectedOpenChangesets() { 161 return !getSelectedOpenChangesets().isEmpty(); 162 } 163 164 /** 165 * Replies the selected open changesets 166 * 167 * @return the selected open changesets 168 */ 169 public List<Changeset> getSelectedOpenChangesets() { 170 List<Changeset> ret = new ArrayList<Changeset>(); 171 for (int i=0; i< getSize(); i++) { 172 if (selectionModel.isSelectedIndex(i)) { 173 Changeset cs = data.get(i); 174 if (cs.isOpen()) { 175 ret.add(cs); 176 } 177 } 178 } 179 return ret; 180 } 181 182 /* ---------------------------------------------------------------------------- */ 183 /* Interface ChangesetCacheListener */ 184 /* ---------------------------------------------------------------------------- */ 185 public void changesetCacheUpdated(ChangesetCacheEvent event) { 186 Set<Changeset> sel = getSelectedChangesets(); 187 for(Changeset cs: event.getAddedChangesets()) { 188 int idx = data.indexOf(cs); 189 if (idx >= 0 && data.get(idx) != cs) { 190 data.get(idx).mergeFrom(cs); 191 } 192 } 193 for(Changeset cs: event.getUpdatedChangesets()) { 194 int idx = data.indexOf(cs); 195 if (idx >= 0 && data.get(idx) != cs) { 196 data.get(idx).mergeFrom(cs); 197 } 198 } 199 for(Changeset cs: event.getRemovedChangesets()) { 200 int idx = data.indexOf(cs); 201 if (idx >= 0) { 202 // replace with an incomplete changeset 203 data.set(idx, new Changeset(cs.getId())); 204 } 205 } 206 fireContentsChanged(this, 0, getSize()); 207 setSelectedChangesets(sel); 208 } 209 }