/*
* The Unified Mapping Platform (JUMP) is an extensible, interactive GUI
* for visualizing and manipulating spatial features with geometry and attributes.
*
* Copyright (C) 2003 Vivid Solutions
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* For more information, contact:
*
* Vivid Solutions
* Suite #1A
* 2328 Government Street
* Victoria BC V8T 5G5
* Canada
*
* (250)385-6040
* www.vividsolutions.com
*/
package com.vividsolutions.jump.workbench.ui;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jump.feature.Feature;
import com.vividsolutions.jump.util.CollectionMap;
import com.vividsolutions.jump.workbench.model.Layer;
/**
* Superclass for holding a user-selected collection of {@link
* Feature} items.
*/
public abstract class AbstractSelection {
private Map layerMap = new HashMap();
public abstract String getRendererContentID();
private AbstractSelection child;
private AbstractSelection parent;
private SelectionManager selectionManager;
public AbstractSelection(SelectionManager selectionManager) {
this.selectionManager = selectionManager;
}
public abstract List items(Geometry geometry);
public Collection items(Geometry geometry, Collection indices) {
List allItems = items(geometry);
ArrayList items = new ArrayList();
for (Iterator i = indices.iterator(); i.hasNext();) {
Integer index = (Integer) i.next();
items.add(allItems.get(index.intValue()));
}
return items;
}
/**
* Note that some features in the map may not have selected items.
*/
public CollectionMap getFeatureToSelectedItemIndexCollectionMap(Layer layer) {
if (!layerMap.containsKey(layer)) {
layerMap.put(layer, new CollectionMap(HashMap.class, HashSet.class));
}
return (CollectionMap) layerMap.get(layer);
}
public Collection getSelectedItemIndices(Layer layer, Feature feature) {
Collection indices = getFeatureToSelectedItemIndexCollectionMap(layer).getItems(feature);
return indices == null ? new ArrayList() : indices;
}
/**
* Note that some features in the map may not have selected items.
*/
public CollectionMap getFeatureToSelectedItemCollectionMap(Layer layer) {
CollectionMap collectionMap = new CollectionMap();
for (Iterator i = getFeatureToSelectedItemIndexCollectionMap(layer).keySet().iterator();
i.hasNext();
) {
Feature feature = (Feature) i.next();
collectionMap.put(
feature,
items(
feature.getGeometry(),
getFeatureToSelectedItemIndexCollectionMap(layer).getItems(feature)));
}
return collectionMap;
}
public Collection getLayersWithSelectedItems() {
ArrayList layersWithSelectedItems = new ArrayList();
for (Iterator i = layerMap.keySet().iterator(); i.hasNext();) {
Layer layer = (Layer) i.next();
if (!getFeaturesWithSelectedItems(layer).isEmpty()) {
layersWithSelectedItems.add(layer);
}
}
return layersWithSelectedItems;
}
public Collection getFeaturesWithSelectedItems() {
ArrayList featuresWithSelectedItems = new ArrayList();
for (Iterator i = layerMap.keySet().iterator(); i.hasNext();) {
Layer layer = (Layer) i.next();
featuresWithSelectedItems.addAll(getFeaturesWithSelectedItems(layer));
}
return featuresWithSelectedItems;
}
public Collection getFeaturesWithSelectedItems(Layer layer) {
ArrayList featuresWithSelectedItems = new ArrayList();
for (Iterator i = getFeatureToSelectedItemIndexCollectionMap(layer).keySet().iterator();
i.hasNext();
) {
Feature feature = (Feature) i.next();
if (!getFeatureToSelectedItemIndexCollectionMap(layer).getItems(feature).isEmpty()) {
featuresWithSelectedItems.add(feature);
}
}
return featuresWithSelectedItems;
}
public Collection getSelectedItems() {
ArrayList selectedItems = new ArrayList();
for (Iterator i = new ArrayList(layerMap.keySet()).iterator(); i.hasNext();) {
Layer layer = (Layer) i.next();
selectedItems.addAll(getSelectedItems(layer));
}
return selectedItems;
}
public Collection getSelectedItems(Layer layer) {
ArrayList selectedItems = new ArrayList();
for (Iterator i = getFeatureToSelectedItemIndexCollectionMap(layer).keySet().iterator();
i.hasNext();
) {
Feature feature = (Feature) i.next();
selectedItems.addAll(getSelectedItems(layer, feature));
}
return selectedItems;
}
public Collection getSelectedItems(Layer layer, Feature feature) {
return getSelectedItems(layer, feature, feature.getGeometry());
}
/**
* @param geometry the feature's Geometry or equivalent; that is, a clone or
* similar enough Geometry from which Geometries can be retrieved using
* the selection indices.
*/
public Collection getSelectedItems(Layer layer, Feature feature, Geometry geometry) {
return items(
geometry,
getFeatureToSelectedItemIndexCollectionMap(layer).getItems(feature));
}
public Collection indices(Geometry geometry, Collection items) {
List allItems = items(geometry);
ArrayList indices = new ArrayList();
for (Iterator i = items.iterator(); i.hasNext();) {
Object item = i.next();
indices.add(new Integer(allItems.indexOf(item)));
}
return indices;
}
public void unselectItems(Layer layer, CollectionMap featureToItemCollectionMap) {
boolean originalPanelUpdatesEnabled = selectionManager.arePanelUpdatesEnabled();
selectionManager.setPanelUpdatesEnabled(false);
try {
for (Iterator i = featureToItemCollectionMap.keySet().iterator(); i.hasNext();) {
Feature feature = (Feature) i.next();
unselectItems(layer, feature, featureToItemCollectionMap.getItems(feature));
}
} finally {
selectionManager.setPanelUpdatesEnabled(originalPanelUpdatesEnabled);
}
updatePanel();
}
public void selectItems(Layer layer, CollectionMap featureToItemCollectionMap) {
boolean originalPanelUpdatesEnabled = selectionManager.arePanelUpdatesEnabled();
selectionManager.setPanelUpdatesEnabled(false);
try {
for (Iterator i = featureToItemCollectionMap.keySet().iterator(); i.hasNext();) {
Feature feature = (Feature) i.next();
selectItems(layer, feature, featureToItemCollectionMap.getItems(feature));
}
} finally {
selectionManager.setPanelUpdatesEnabled(originalPanelUpdatesEnabled);
}
updatePanel();
}
public void selectItems(Layer layer, Feature feature, Collection items) {
Collection itemsToSelect = itemsNotSelectedInAncestors(layer, feature, items);
boolean originalPanelUpdatesEnabled = selectionManager.arePanelUpdatesEnabled();
selectionManager.setPanelUpdatesEnabled(false);
try {
unselectInDescendants(layer, feature, itemsToSelect);
getFeatureToSelectedItemIndexCollectionMap(layer).addItems(
feature,
indices(feature.getGeometry(), itemsToSelect));
} finally {
selectionManager.setPanelUpdatesEnabled(originalPanelUpdatesEnabled);
}
updatePanel();
}
public void unselectItems(Layer layer, Feature feature, Collection items) {
boolean originalPanelUpdatesEnabled = selectionManager.arePanelUpdatesEnabled();
selectionManager.setPanelUpdatesEnabled(false);
try {
getFeatureToSelectedItemIndexCollectionMap(layer).removeItems(
feature,
indices(feature.getGeometry(), items));
} finally {
selectionManager.setPanelUpdatesEnabled(originalPanelUpdatesEnabled);
}
updatePanel();
}
public Collection itemsNotSelectedInAncestors(Layer layer, Feature feature, Collection items) {
ArrayList itemsNotSelectedInAncestors = new ArrayList();
if ( layer.isSelectable() ) {
for (Iterator i = items.iterator(); i.hasNext();) {
Geometry item = (Geometry) i.next();
if (!selectedInAncestors(layer, feature, item)) {
itemsNotSelectedInAncestors.add(item);
}
}
}
return itemsNotSelectedInAncestors;
}
protected abstract boolean selectedInAncestors(Layer layer, Feature feature, Geometry item);
protected abstract void unselectInDescendants(Layer layer, Feature feature, Collection items);
public void selectItems(Layer layer, Feature feature) {
selectItems(layer, feature, items(feature.getGeometry()));
}
public void selectItems(Layer layer, Collection features) {
boolean originalPanelUpdatesEnabled = selectionManager.arePanelUpdatesEnabled();
selectionManager.setPanelUpdatesEnabled(false);
try {
for (Iterator i = new ArrayList(features).iterator(); i.hasNext();) {
Feature feature = (Feature) i.next();
selectItems(layer, feature);
}
} finally {
selectionManager.setPanelUpdatesEnabled(originalPanelUpdatesEnabled);
}
updatePanel();
}
public void unselectFromFeaturesWithModifiedItemCounts(
Layer layer,
Collection features,
Collection oldFeatureClones) {
ArrayList featuresToUnselect = new ArrayList();
Iterator j = oldFeatureClones.iterator();
j.hasNext();
for (Iterator i = features.iterator(); i.hasNext();) {
Feature feature = (Feature) i.next();
Feature oldFeatureClone = (Feature) j.next();
if (items(feature.getGeometry()).size()
!= items(oldFeatureClone.getGeometry()).size()) {
featuresToUnselect.add(feature);
}
}
unselectItems(layer, featuresToUnselect);
}
public void unselectItems() {
layerMap.clear();
updatePanel();
}
public void unselectItems(Layer layer) {
layerMap.remove(layer);
updatePanel();
}
public void unselectItems(Layer layer, Collection features) {
boolean originalPanelUpdatesEnabled = selectionManager.arePanelUpdatesEnabled();
selectionManager.setPanelUpdatesEnabled(false);
try {
for (Iterator i = features.iterator(); i.hasNext();) {
Feature feature = (Feature) i.next();
unselectItems(layer, feature);
}
} finally {
selectionManager.setPanelUpdatesEnabled(originalPanelUpdatesEnabled);
}
updatePanel();
}
public void unselectItems(Layer layer, Feature feature) {
getFeatureToSelectedItemIndexCollectionMap(layer).remove(feature);
updatePanel();
}
public void unselectItem(Layer layer, Feature feature, int selectedItemIndex) {
getFeatureToSelectedItemIndexCollectionMap(layer).removeItem(
feature,
new Integer(selectedItemIndex));
}
private void updatePanel() {
selectionManager.updatePanel();
}
public void setChild(AbstractSelection child) {
this.child = child;
}
public void setParent(AbstractSelection parent) {
this.parent = parent;
}
protected AbstractSelection getChild() {
return child;
}
protected AbstractSelection getParent() {
return parent;
}
}