/** * Copyright 2011 Edgar Soldin * * 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 */ package de.soldin.jumpcore; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.Vector; import javax.swing.undo.AbstractUndoableEdit; import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jump.feature.Feature; import com.vividsolutions.jump.workbench.model.Layer; /** * The <code>UndoableSetGeometry</code> is a implementation of a * {@link java.util.Collection}, as well as a {@link * javax.swing.undo.AbstractUndoableEdit}. The purpose is to have * an undoable swing component for modifying geometries. * <p> * With these capabilities joined it can act as a container for multiple * <code>UndoableSetGeometry</code> objects, which can be executed in * a batch and as a single action. * </p> */ public class UndoableSetGeometry extends AbstractUndoableEdit implements Collection { private static final long serialVersionUID = 1L; private Collection actions = new Vector(); private String name; private Layer layer; private HashMap proposed_geoms = new HashMap(); private HashMap original_geoms = new HashMap(); public void redo() { execute(); super.redo(); } public void undo() { unexecute(); super.undo(); } public String getPresentationName(){ return getName(); } public String getUndoPresentationName(){ return getName(); } public String getRedoPresentationName(){ return getName(); } public UndoableSetGeometry(Layer layer, String name) { this.layer = layer; this.name = name+" (Layer: "+layer.getName()+")"; } public UndoableSetGeometry(String name) { this.name = name; } public void execute() { //System.out.print("UT:execute() "+this+" "); if (layer!=null){ //List features = layer.getFeatureCollectionWrapper().getFeatures(); ArrayList modifiedFeatures = new ArrayList(); ArrayList modifiedFeaturesOldClones = new ArrayList(); for (Iterator iter = proposed_geoms.keySet().iterator(); iter.hasNext();) { Feature feature = (Feature) iter.next(); Geometry new_geom = (Geometry)proposed_geoms.get(feature); Geometry old_geom = feature.getGeometry(); original_geoms.put(feature,old_geom); modifiedFeatures.add(feature); modifiedFeaturesOldClones.add(feature.clone()); feature.setGeometry(new_geom); } refreshUI(modifiedFeatures,modifiedFeaturesOldClones); }else{ //System.out.print("batch "); for (Iterator iter = this.iterator(); iter.hasNext();) { UndoableSetGeometry transformation = (UndoableSetGeometry) iter.next(); transformation.execute(); } } } public void unexecute() { //System.out.print("UT:unexecute() "+this+" "); if (layer!=null && original_geoms.size()>0){ //List features = layer.getFeatureCollectionWrapper().getFeatures(); ArrayList modifiedFeatures = new ArrayList(); ArrayList modifiedFeaturesOldClones = new ArrayList(); for (Iterator iter = original_geoms.keySet().iterator(); iter.hasNext();) { Feature feature = (Feature) iter.next(); Geometry new_geom = (Geometry)original_geoms.get(feature); modifiedFeatures.add(feature); modifiedFeaturesOldClones.add(feature.clone()); feature.setGeometry(new_geom); //original_geoms.remove(feature); } original_geoms.clear(); refreshUI(modifiedFeatures,modifiedFeaturesOldClones); }else{ //System.out.print("batch "); for (Iterator iter = this.iterator(); iter.hasNext();) { UndoableSetGeometry transformation = (UndoableSetGeometry) iter.next(); transformation.unexecute(); } } //System.out.println(); } private void refreshUI(ArrayList modifiedFeatures, ArrayList modifiedFeaturesOldClones){ if (this.layer!=null) { Layer.tryToInvalidateEnvelope(this.layer); // fire the appropriate event, so everybody gets notified if (!modifiedFeatures.isEmpty()) { this.layer.getLayerManager().fireGeometryModified( modifiedFeatures, this.layer, modifiedFeaturesOldClones); } } } public String getName() { String out = ""; if (layer==null){ for (Iterator iter = actions.iterator(); iter.hasNext();) { out += (out.length()>0?", ":"")+((UndoableSetGeometry)iter.next()).getName(); } } return name+": "+out; } public void setGeom(Feature feature, Geometry geom){ proposed_geoms.put(feature,geom); } public Geometry getGeom(Feature in_feature){ //List features = layer.getFeatureCollectionWrapper().getFeatures(); //Feature feature = (Feature)features.get(features.indexOf(in_feature)); return (Geometry)in_feature.getGeometry().clone(); } // Start of implementation of the collection methods public boolean add(UndoableSetGeometry t){ return actions.add(t); } public int size() { return actions.size(); } public void clear() { actions.clear(); } public boolean isEmpty() { if (layer==null) { for (Iterator i = actions.iterator(); i.hasNext();) { Collection action = (Collection) i.next(); if (!action.isEmpty()) return false; } return true; } else return proposed_geoms.isEmpty(); } public Object[] toArray() { return actions.toArray(); } public boolean add(Object o) { return actions.add(o); } public boolean contains(Object o) { return actions.contains(o); } public boolean remove(Object o) { return actions.remove(o); } public boolean addAll(Collection c) { return actions.addAll(c); } public boolean containsAll(Collection c) { return actions.containsAll(c); } public boolean removeAll(Collection c) { return actions.removeAll(c); } public boolean retainAll(Collection c) { return actions.retainAll(c); } public Iterator iterator() { return actions.iterator(); } public Object[] toArray(Object[] a) { return actions.toArray(a); } }