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    /**
038     * Registers listeners (selection change and layer change).
039     */
040    public void register() {
041        DataSet.addSelectionListener(this);
042        MapView.addLayerChangeListener(this);
043    }
044
045    /**
046     * Unregisters listeners (selection change and layer change).
047     */
048    public void unregister() {
049        DataSet.removeSelectionListener(this);
050        MapView.removeLayerChangeListener(this);
051    }
052
053    @Override
054    public int getColumnCount() {
055        return 1;
056    }
057
058    @Override
059    public int getRowCount() {
060        if (Main.main.getEditLayer() != layer)
061            return 0;
062        return cache.size();
063    }
064
065    @Override
066    public Object getValueAt(int rowIndex, int columnIndex) {
067        return cache.get(rowIndex);
068    }
069
070    @Override
071    public void activeLayerChange(Layer oldLayer, Layer newLayer) {
072        if (oldLayer  == layer) {
073            cache.clear();
074        }
075        if (newLayer == layer) {
076            cache.addAll(((OsmDataLayer) newLayer).data.getAllSelected());
077        }
078        fireTableDataChanged();
079    }
080
081    @Override
082    public void layerAdded(Layer newLayer) {
083        // do nothing
084    }
085
086    @Override
087    public void layerRemoved(Layer oldLayer) {
088        if (oldLayer == layer) {
089            unregister();
090        }
091        this.cache.clear();
092        fireTableDataChanged();
093    }
094
095    @Override
096    public void selectionChanged(Collection<? extends OsmPrimitive> newSelection) {
097        if (layer == Main.main.getEditLayer()) {
098            cache.clear();
099            cache.addAll(newSelection);
100        } else {
101            cache.clear();
102        }
103        fireTableDataChanged();
104    }
105
106    public List<OsmPrimitive> getSelection() {
107        return cache;
108    }
109
110    /**
111     * populates the model with the primitives currently selected in
112     * <code>layer</code>
113     *
114     * @param layer  the data layer
115     */
116    protected void populateSelectedPrimitives(OsmDataLayer layer) {
117        selectionChanged(layer.data.getAllSelected());
118    }
119
120    /**
121     * Replies the primitive at row <code>row</code> in this model
122     *
123     * @param row the row
124     * @return the primitive at row <code>row</code> in this model
125     * @throws ArrayIndexOutOfBoundsException if index is invalid
126     */
127    public OsmPrimitive getPrimitive(int row) {
128        return cache.get(row);
129    }
130}