// License: GPL. For details, see LICENSE file.
package org.openstreetmap.josm.gui.dialogs.changeset;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.swing.DefaultListSelectionModel;
import javax.swing.table.AbstractTableModel;
import org.openstreetmap.josm.data.osm.Changeset;
import org.openstreetmap.josm.data.osm.ChangesetCache;
import org.openstreetmap.josm.data.osm.ChangesetCacheEvent;
import org.openstreetmap.josm.data.osm.ChangesetCacheListener;
import org.openstreetmap.josm.gui.util.GuiHelper;
/**
* This is the model for the changeset cache manager dialog.
*
*/
public class ChangesetCacheManagerModel extends AbstractTableModel implements ChangesetCacheListener {
/** the name of the property for the currently selected changeset in the detail view */
public static final String CHANGESET_IN_DETAIL_VIEW_PROP = ChangesetCacheManagerModel.class.getName() + ".changesetInDetailView";
private final transient List<Changeset> data = new ArrayList<>();
private final DefaultListSelectionModel selectionModel;
private transient Changeset changesetInDetailView;
private final PropertyChangeSupport support = new PropertyChangeSupport(this);
public ChangesetCacheManagerModel(DefaultListSelectionModel selectionModel) {
this.selectionModel = selectionModel;
}
public void addPropertyChangeListener(PropertyChangeListener listener) {
support.addPropertyChangeListener(listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
support.removePropertyChangeListener(listener);
}
/**
* Sets the changeset currently displayed in the detail view. Fires a property change event
* for the property {@link #CHANGESET_IN_DETAIL_VIEW_PROP} if necessary.
*
* @param cs the changeset currently displayed in the detail view.
*/
public void setChangesetInDetailView(Changeset cs) {
Changeset oldValue = changesetInDetailView;
changesetInDetailView = cs;
if (oldValue != cs) {
support.firePropertyChange(CHANGESET_IN_DETAIL_VIEW_PROP, oldValue, changesetInDetailView);
}
}
/**
* Replies true if there is at least one selected changeset
*
* @return true if there is at least one selected changeset
*/
public boolean hasSelectedChangesets() {
return selectionModel.getMinSelectionIndex() >= 0;
}
/**
* Replies the list of selected changesets
*
* @return the list of selected changesets
*/
public List<Changeset> getSelectedChangesets() {
List<Changeset> ret = new ArrayList<>();
for (int i = 0; i < data.size(); i++) {
Changeset cs = data.get(i);
if (selectionModel.isSelectedIndex(i)) {
ret.add(cs);
}
}
return ret;
}
/**
* Replies a set of ids of the selected changesets
*
* @return a set of ids of the selected changesets
*/
public Set<Integer> getSelectedChangesetIds() {
Set<Integer> ret = new HashSet<>();
for (Changeset cs: getSelectedChangesets()) {
ret.add(cs.getId());
}
return ret;
}
/**
* Selects the changesets in <code>selected</code>.
*
* @param selected the collection of changesets to select. Ignored if empty.
*/
public void setSelectedChangesets(Collection<Changeset> selected) {
selectionModel.setValueIsAdjusting(true);
selectionModel.clearSelection();
if (selected != null) {
for (Changeset cs: selected) {
final int idx = data.indexOf(cs);
if (idx >= 0) {
selectionModel.addSelectionInterval(idx, idx);
}
}
}
GuiHelper.runInEDTAndWait(() -> selectionModel.setValueIsAdjusting(false));
}
@Override
public int getColumnCount() {
return 5;
}
@Override
public int getRowCount() {
return data.size();
}
@Override
public Object getValueAt(int row, int column) {
return data.get(row);
}
public void init() {
ChangesetCache cc = ChangesetCache.getInstance();
List<Changeset> selected = getSelectedChangesets();
data.clear();
data.addAll(cc.getChangesets());
sort();
fireTableDataChanged();
setSelectedChangesets(selected);
cc.addChangesetCacheListener(this);
}
public void tearDown() {
ChangesetCache.getInstance().removeChangesetCacheListener(this);
}
public DefaultListSelectionModel getSelectionModel() {
return selectionModel;
}
protected void sort() {
data.sort(Comparator.comparingInt(Changeset::getId).reversed());
}
/* ------------------------------------------------------------------------------ */
/* interface ChangesetCacheListener */
/* ------------------------------------------------------------------------------ */
@Override
public void changesetCacheUpdated(ChangesetCacheEvent event) {
List<Changeset> selected = getSelectedChangesets();
for (Changeset cs: event.getAddedChangesets()) {
data.add(cs);
}
for (Changeset cs: event.getRemovedChangesets()) {
data.remove(cs);
}
for (Changeset cs: event.getUpdatedChangesets()) {
int idx = data.indexOf(cs);
if (idx >= 0) {
Changeset mine = data.get(idx);
if (mine != cs) {
mine.mergeFrom(cs);
}
}
}
sort();
fireTableDataChanged();
setSelectedChangesets(selected);
}
}