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.layer.LayerManager.LayerAddEvent;
014import org.openstreetmap.josm.gui.layer.LayerManager.LayerChangeListener;
015import org.openstreetmap.josm.gui.layer.LayerManager.LayerOrderChangeEvent;
016import org.openstreetmap.josm.gui.layer.LayerManager.LayerRemoveEvent;
017import org.openstreetmap.josm.gui.layer.MainLayerManager.ActiveLayerChangeEvent;
018import org.openstreetmap.josm.gui.layer.MainLayerManager.ActiveLayerChangeListener;
019import org.openstreetmap.josm.gui.layer.OsmDataLayer;
020import org.openstreetmap.josm.tools.CheckParameterUtil;
021
022public class SelectionTableModel extends AbstractTableModel implements SelectionChangedListener, ActiveLayerChangeListener, LayerChangeListener {
023
024    /** this selection table model only displays selected primitives in this layer */
025    private final transient OsmDataLayer layer;
026    private final transient List<OsmPrimitive> cache;
027
028    /**
029     * constructor
030     *
031     * @param layer  the data layer. Must not be null.
032     * @throws IllegalArgumentException if layer is null
033     */
034    public SelectionTableModel(OsmDataLayer layer) {
035        CheckParameterUtil.ensureParameterNotNull(layer, "layer");
036        this.layer = layer;
037        cache = new ArrayList<>();
038        populateSelectedPrimitives(layer);
039    }
040
041    /**
042     * Registers listeners (selection change and layer change).
043     */
044    public void register() {
045        DataSet.addSelectionListener(this);
046        Main.getLayerManager().addActiveLayerChangeListener(this);
047    }
048
049    /**
050     * Unregisters listeners (selection change and layer change).
051     */
052    public void unregister() {
053        DataSet.removeSelectionListener(this);
054        Main.getLayerManager().removeActiveLayerChangeListener(this);
055    }
056
057    @Override
058    public int getColumnCount() {
059        return 1;
060    }
061
062    @Override
063    public int getRowCount() {
064        if (Main.getLayerManager().getEditLayer() != layer)
065            return 0;
066        return cache.size();
067    }
068
069    @Override
070    public Object getValueAt(int rowIndex, int columnIndex) {
071        return cache.get(rowIndex);
072    }
073
074    @Override
075    public void activeOrEditLayerChanged(ActiveLayerChangeEvent e) {
076        if (e.getPreviousActiveLayer() == layer) {
077            cache.clear();
078        }
079        if (e.getSource().getActiveLayer() == layer) {
080            cache.addAll(layer.data.getAllSelected());
081        }
082        fireTableDataChanged();
083    }
084
085    @Override
086    public void layerAdded(LayerAddEvent e) {
087        // do nothing
088    }
089
090    @Override
091    public void layerRemoving(LayerRemoveEvent e) {
092        if (e.getRemovedLayer() == layer) {
093            unregister();
094        }
095        this.cache.clear();
096        fireTableDataChanged();
097    }
098
099    @Override
100    public void layerOrderChanged(LayerOrderChangeEvent e) {
101        // do nothing
102    }
103
104    @Override
105    public void selectionChanged(Collection<? extends OsmPrimitive> newSelection) {
106        if (layer == Main.getLayerManager().getEditLayer()) {
107            cache.clear();
108            cache.addAll(newSelection);
109        } else {
110            cache.clear();
111        }
112        fireTableDataChanged();
113    }
114
115    public List<OsmPrimitive> getSelection() {
116        return cache;
117    }
118
119    /**
120     * populates the model with the primitives currently selected in
121     * <code>layer</code>
122     *
123     * @param layer  the data layer
124     */
125    protected void populateSelectedPrimitives(OsmDataLayer layer) {
126        selectionChanged(layer.data.getAllSelected());
127    }
128
129    /**
130     * Replies the primitive at row <code>row</code> in this model
131     *
132     * @param row the row
133     * @return the primitive at row <code>row</code> in this model
134     * @throws ArrayIndexOutOfBoundsException if index is invalid
135     */
136    public OsmPrimitive getPrimitive(int row) {
137        return cache.get(row);
138    }
139
140}