001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.gui.dialogs.relation;
003import java.util.ArrayList;
004import java.util.Collection;
005import java.util.List;
006
007import javax.swing.table.AbstractTableModel;
008
009import org.openstreetmap.josm.Main;
010import org.openstreetmap.josm.data.SelectionChangedListener;
011import org.openstreetmap.josm.data.osm.DataSet;
012import org.openstreetmap.josm.data.osm.OsmPrimitive;
013import org.openstreetmap.josm.gui.MapView;
014import org.openstreetmap.josm.gui.layer.Layer;
015import org.openstreetmap.josm.gui.layer.OsmDataLayer;
016import org.openstreetmap.josm.tools.CheckParameterUtil;
017
018public class SelectionTableModel extends AbstractTableModel implements SelectionChangedListener, MapView.LayerChangeListener {
019
020    /** this selection table model only displays selected primitives in this layer */
021    private final transient OsmDataLayer layer;
022    private final transient List<OsmPrimitive> cache;
023
024    /**
025     * constructor
026     *
027     * @param layer  the data layer. Must not be null.
028     * @throws IllegalArgumentException if layer is null
029     */
030    public SelectionTableModel(OsmDataLayer layer) {
031        CheckParameterUtil.ensureParameterNotNull(layer, "layer");
032        this.layer = layer;
033        cache = new ArrayList<>();
034        populateSelectedPrimitives(layer);
035    }
036
037    public void register() {
038        DataSet.addSelectionListener(this);
039        MapView.addLayerChangeListener(this);
040    }
041
042    public void unregister() {
043        DataSet.removeSelectionListener(this);
044        MapView.removeLayerChangeListener(this);
045    }
046
047    @Override
048    public int getColumnCount() {
049        return 1;
050    }
051
052    @Override
053    public int getRowCount() {
054        if (Main.main.getEditLayer() != layer)
055            return 0;
056        return cache.size();
057    }
058
059    @Override
060    public Object getValueAt(int rowIndex, int columnIndex) {
061        return cache.get(rowIndex);
062    }
063
064    @Override
065    public void activeLayerChange(Layer oldLayer, Layer newLayer) {
066        if (oldLayer  == layer) {
067            cache.clear();
068        }
069        if (newLayer == layer) {
070            cache.addAll(((OsmDataLayer) newLayer).data.getAllSelected());
071        }
072        fireTableDataChanged();
073    }
074
075    @Override
076    public void layerAdded(Layer newLayer) {
077        // do nothing
078    }
079
080    @Override
081    public void layerRemoved(Layer oldLayer) {
082        if (oldLayer == layer) {
083            unregister();
084        }
085        this.cache.clear();
086        fireTableDataChanged();
087    }
088
089    @Override
090    public void selectionChanged(Collection<? extends OsmPrimitive> newSelection) {
091        if (layer == Main.main.getEditLayer()) {
092            cache.clear();
093            cache.addAll(newSelection);
094        } else {
095            cache.clear();
096        }
097        fireTableDataChanged();
098    }
099
100    public List<OsmPrimitive> getSelection() {
101        return cache;
102    }
103
104    /**
105     * populates the model with the primitives currently selected in
106     * <code>layer</code>
107     *
108     * @param layer  the data layer
109     */
110    protected void populateSelectedPrimitives(OsmDataLayer layer) {
111        selectionChanged(layer.data.getAllSelected());
112    }
113
114    /**
115     * Replies the primitive at row <code>row</code> in this model
116     *
117     * @param row the row
118     * @return  the primitive at row <code>row</code> in this model
119     */
120    public OsmPrimitive getPrimitive(int row) {
121        return cache.get(row);
122    }
123}