001: /* uDig - User Friendly Desktop Internet GIS client
002: * http://udig.refractions.net
003: * (C) 2004, Refractions Research Inc.
004: *
005: * This library is free software; you can redistribute it and/or
006: * modify it under the terms of the GNU Lesser General Public
007: * License as published by the Free Software Foundation;
008: * version 2.1 of the License.
009: *
010: * This library is distributed in the hope that it will be useful,
011: * but WITHOUT ANY WARRANTY; without even the implied warranty of
012: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
013: * Lesser General Public License for more details.
014: */
015: package net.refractions.udig.tools.edit.commands;
016:
017: import java.util.ArrayList;
018: import java.util.Collections;
019: import java.util.HashSet;
020: import java.util.List;
021:
022: import net.refractions.udig.project.command.AbstractCommand;
023: import net.refractions.udig.project.command.Command;
024: import net.refractions.udig.project.command.UndoableMapCommand;
025: import net.refractions.udig.project.ui.AnimationUpdater;
026: import net.refractions.udig.tool.edit.internal.Messages;
027: import net.refractions.udig.tools.edit.EditState;
028: import net.refractions.udig.tools.edit.EditToolHandler;
029: import net.refractions.udig.tools.edit.animation.AddVertexAnimation;
030: import net.refractions.udig.tools.edit.animation.DeleteVertexAnimation;
031: import net.refractions.udig.tools.edit.support.EditBlackboard;
032: import net.refractions.udig.tools.edit.support.EditGeom;
033: import net.refractions.udig.tools.edit.support.Point;
034: import net.refractions.udig.tools.edit.support.PrimitiveShape;
035: import net.refractions.udig.tools.edit.support.Selection;
036: import net.refractions.udig.tools.edit.support.ShapeType;
037: import net.refractions.udig.ui.PlatformGIS;
038: import net.refractions.udig.ui.WaitCondition;
039:
040: import org.eclipse.core.runtime.IProgressMonitor;
041:
042: import com.vividsolutions.jts.geom.Coordinate;
043:
044: /**
045: * Removes the set of selected vertices from the blackboard.
046: *
047: * @author jones
048: * @since 1.1.0
049: */
050: public class RemoveSelectedVerticesCommand extends AbstractCommand
051: implements Command, UndoableMapCommand {
052:
053: private EditToolHandler handler;
054: private List<Bag> undoData;
055: private boolean runAnimation;
056:
057: public RemoveSelectedVerticesCommand(EditToolHandler handler) {
058: this .handler = handler;
059: }
060:
061: public void run(IProgressMonitor monitor) throws Exception {
062: EditBlackboard blackboard = handler.getEditBlackboard(handler
063: .getEditLayer());
064: blackboard.startBatchingEvents();
065: Selection selection = blackboard.getSelection();
066: undoData = new ArrayList<Bag>();
067: EditState oldState = handler.getCurrentState();
068: try {
069: handler.setCurrentState(EditState.BUSY);
070: DeleteVertexAnimation deleteVertexAnimation = null;
071: if (runAnimation) {
072: for (Point point : selection) {
073: deleteVertexAnimation = new DeleteVertexAnimation(
074: point);
075: AnimationUpdater.runTimer(handler.getContext()
076: .getMapDisplay(), deleteVertexAnimation);
077: }
078: if (deleteVertexAnimation != null) {
079: final DeleteVertexAnimation finalDeleteVertexAnim = deleteVertexAnimation;
080: PlatformGIS.wait(deleteVertexAnimation
081: .getFrameInterval(), 5000,
082: new WaitCondition() {
083:
084: public boolean isTrue() {
085: return !finalDeleteVertexAnim
086: .isValid();
087: }
088:
089: }, null);
090: }
091: }
092: HashSet<Point> points = new HashSet<Point>(selection);
093: for (Point point : points) {
094: List<EditGeom> geoms = blackboard.getGeoms(
095: point.getX(), point.getY());
096: for (EditGeom geom : geoms) {
097: for (PrimitiveShape shape : geom) {
098: if (geom.getShapeType() == ShapeType.POLYGON) {
099: if (point.equals(shape.getPoint(0))) {
100: List<Coordinate> singletonList = Collections
101: .singletonList(shape
102: .getCoordsAt(1).get(0));
103: blackboard.insertCoords(shape
104: .getNumPoints(), shape
105: .getPoint(1), singletonList,
106: shape);
107: Bag bag = new Bag();
108: bag.p = shape.getPoint(1);
109: bag.coords = singletonList;
110: bag.shape = shape;
111: bag.index = -1;
112: bag.action = Action.ADD;
113: undoData.add(bag);
114: }
115: }
116: int deletes = 0;
117: for (int i = 0; i < shape.getNumPoints(); i++) {
118: Point shapePoint = shape.getPoint(i);
119: if (point.equals(shapePoint)) {
120: Bag bag = new Bag();
121: bag.p = point;
122: bag.coords = shape.getCoordsAt(i);
123: bag.shape = shape;
124: bag.index = i - deletes;
125: bag.action = Action.REMOVE;
126: deletes++;
127: undoData.add(bag);
128: }
129: }
130:
131: }
132: }
133: blackboard.removeCoordsAtPoint(point.getX(), point
134: .getY());
135: }
136: } finally {
137: handler.setCurrentState(oldState);
138: blackboard.fireBatchedEvents();
139: }
140: }
141:
142: public String getName() {
143: return Messages.RemoveSelectedVerticesCommand_name;
144: }
145:
146: public void rollback(IProgressMonitor monitor) throws Exception {
147: EditBlackboard blackboard = handler.getEditBlackboard(handler
148: .getEditLayer());
149: blackboard.startBatchingEvents();
150:
151: try {
152: for (int i = undoData.size() - 1; i > -1; i--) {
153: Bag bag = undoData.get(i);
154: switch (bag.action) {
155: case ADD:
156: blackboard.removeCoordinate(bag.shape
157: .getNumPoints() - 1, bag.coords.get(0),
158: bag.shape);
159: break;
160: case REMOVE:
161: if (runAnimation)
162: AnimationUpdater.runTimer(handler.getContext()
163: .getMapDisplay(),
164: new AddVertexAnimation(bag.p.getX(),
165: bag.p.getY()));
166: blackboard.insertCoords(bag.index, bag.p,
167: bag.coords, bag.shape);
168: blackboard.selectionAdd(bag.p);
169: break;
170:
171: default:
172: break;
173: }
174: }
175: } finally {
176: blackboard.fireBatchedEvents();
177: }
178: }
179:
180: enum Action {
181: ADD, REMOVE
182: }
183:
184: static class Bag {
185: Action action;
186: Point p;
187: int index;
188: List<Coordinate> coords;
189: PrimitiveShape shape;
190:
191: @Override
192: public String toString() {
193: return action + " " + coords; //$NON-NLS-1$
194: }
195: }
196:
197: /**
198: * If run is true then the animations will be run otherwise not.
199: *
200: * @param run whether animations should be ran
201: */
202: public void setRunAnimation(boolean run) {
203: this.runAnimation = run;
204: }
205:
206: }
|