Bug 356090 - Patterns - DeleteFeature hasDone problem
diff --git a/plugins/org.eclipse.graphiti.pattern/src/org/eclipse/graphiti/pattern/AbstractPattern.java b/plugins/org.eclipse.graphiti.pattern/src/org/eclipse/graphiti/pattern/AbstractPattern.java
index 722e1a1..7c4c441 100644
--- a/plugins/org.eclipse.graphiti.pattern/src/org/eclipse/graphiti/pattern/AbstractPattern.java
+++ b/plugins/org.eclipse.graphiti.pattern/src/org/eclipse/graphiti/pattern/AbstractPattern.java
@@ -125,7 +125,8 @@
 	}
 
 	public boolean canMoveShape(IMoveShapeContext context) {
-		return context.getSourceContainer() != null && context.getSourceContainer().equals(context.getTargetContainer())
+		return context.getSourceContainer() != null
+				&& context.getSourceContainer().equals(context.getTargetContainer())
 				&& isPatternRoot(context.getPictogramElement());
 	}
 
@@ -214,11 +215,13 @@
 
 			shapeToMove.setContainer(newContainerShape);
 			if (shapeToMove.getGraphicsAlgorithm() != null) {
-				Graphiti.getGaService().setLocation(shapeToMove.getGraphicsAlgorithm(), x, y, avoidNegativeCoordinates());
+				Graphiti.getGaService().setLocation(shapeToMove.getGraphicsAlgorithm(), x, y,
+						avoidNegativeCoordinates());
 			}
 		} else { // move within the same container
 			if (shapeToMove.getGraphicsAlgorithm() != null) {
-				Graphiti.getGaService().setLocation(shapeToMove.getGraphicsAlgorithm(), x, y, avoidNegativeCoordinates());
+				Graphiti.getGaService().setLocation(shapeToMove.getGraphicsAlgorithm(), x, y,
+						avoidNegativeCoordinates());
 			}
 		}
 	}
@@ -718,4 +721,22 @@
 	public IProposalSupport getProposalSupport() {
 		return null;
 	}
+
+	/**
+	 * @since 0.9
+	 */
+	@Override
+	public boolean hasDoneChanges(Class<?> actionType) {
+		boolean ret = true;
+		if (IDelete.class.equals(actionType)) {
+			if (wrappedDeleteFeature != null) {
+				ret = wrappedDeleteFeature.hasDoneChanges();
+			}
+		} else if (IRemove.class.equals(actionType)) {
+			if (wrappedRemoveFeature != null) {
+				ret = wrappedRemoveFeature.hasDoneChanges();
+			}
+		}
+		return ret;
+	}
 }
diff --git a/plugins/org.eclipse.graphiti.pattern/src/org/eclipse/graphiti/pattern/DeleteFeatureForPattern.java b/plugins/org.eclipse.graphiti.pattern/src/org/eclipse/graphiti/pattern/DeleteFeatureForPattern.java
index 31f5140..78c12f6 100644
--- a/plugins/org.eclipse.graphiti.pattern/src/org/eclipse/graphiti/pattern/DeleteFeatureForPattern.java
+++ b/plugins/org.eclipse.graphiti.pattern/src/org/eclipse/graphiti/pattern/DeleteFeatureForPattern.java
@@ -24,6 +24,7 @@
 import org.eclipse.graphiti.features.IFeatureProvider;
 import org.eclipse.graphiti.features.context.IContext;
 import org.eclipse.graphiti.features.context.IDeleteContext;
+import org.eclipse.graphiti.func.IDelete;
 import org.eclipse.graphiti.ui.features.DefaultDeleteFeature;
 
 /**
@@ -103,4 +104,10 @@
 			((ICustomUndoablePattern) pattern).redo(this, context);
 		}
 	}
+
+	@Override
+	public boolean hasDoneChanges() {
+		IPattern pattern = delegate.getPattern();
+		return pattern.hasDoneChanges(IDelete.class);
+	}
 }
diff --git a/plugins/org.eclipse.graphiti.pattern/src/org/eclipse/graphiti/pattern/IPattern.java b/plugins/org.eclipse.graphiti.pattern/src/org/eclipse/graphiti/pattern/IPattern.java
index cc3db5d..54bc6dc 100644
--- a/plugins/org.eclipse.graphiti.pattern/src/org/eclipse/graphiti/pattern/IPattern.java
+++ b/plugins/org.eclipse.graphiti.pattern/src/org/eclipse/graphiti/pattern/IPattern.java
@@ -42,7 +42,8 @@
  * @noextend This interface is not intended to be extended by clients. Extend
  *           {@link AbstractPattern} instead
  */
-public interface IPattern extends ICreate, IAdd, IDelete, IRemove, IUpdate, ILayout, IResizeShape, IMoveShape, IDirectEditing {
+public interface IPattern extends ICreate, IAdd, IDelete, IRemove, IUpdate, ILayout, IResizeShape, IMoveShape,
+		IDirectEditing {
 
 	/**
 	 * Determines whether the pattern supports the creation of new business
@@ -125,4 +126,29 @@
 	 * @return the resize configuration object
 	 */
 	IResizeConfiguration getResizeConfiguration(IResizeShapeContext context);
+
+	/**
+	 * Is queried by the framework after a pattern has been executed to find out
+	 * if this pattern should appear in the undo stack. By default all patterns
+	 * should appear there (see implementation in AbstractPattern), but single
+	 * pattern may decide to override this behavior. Note that this is a dynamic
+	 * attribute of the pattern that is queried each time <b>after</b> the
+	 * pattern has been executed.
+	 * <p>
+	 * <b>IMPORTANT NOTE:</b> The implementor of the feature is responsible for
+	 * correctly implementing this method! It will lead to inconsistencies if
+	 * this method returns <code>false</code> although the pattern did changes.
+	 * 
+	 * @param actionType
+	 *            the followings types are currently supported:
+	 *            <code>IDelete.class, IRemove.class</code>
+	 * 
+	 * 
+	 * @return <code>true</code> if the last action of the pattern from this
+	 *         action type should appear in the undo stack, <code>false</code>
+	 *         otherwise
+	 * 
+	 * @since 0.9
+	 */
+	boolean hasDoneChanges(Class<?> actionType);
 }
diff --git a/plugins/org.eclipse.graphiti.pattern/src/org/eclipse/graphiti/pattern/RemoveFeatureForPattern.java b/plugins/org.eclipse.graphiti.pattern/src/org/eclipse/graphiti/pattern/RemoveFeatureForPattern.java
index 5117030..dadfe6f 100644
--- a/plugins/org.eclipse.graphiti.pattern/src/org/eclipse/graphiti/pattern/RemoveFeatureForPattern.java
+++ b/plugins/org.eclipse.graphiti.pattern/src/org/eclipse/graphiti/pattern/RemoveFeatureForPattern.java
@@ -25,6 +25,7 @@
 import org.eclipse.graphiti.features.context.IContext;
 import org.eclipse.graphiti.features.context.IRemoveContext;
 import org.eclipse.graphiti.features.impl.DefaultRemoveFeature;
+import org.eclipse.graphiti.func.IRemove;
 
 /**
  * This class is used by the {@link DefaultFeatureProviderWithPatterns} to wrap
@@ -61,7 +62,7 @@
 	}
 
 	// public void remove(IRemoveContext context)
-	// is final and cannot be overridden...	
+	// is final and cannot be overridden...
 
 	@Override
 	public void postRemove(IRemoveContext context) {
@@ -101,4 +102,10 @@
 			((ICustomUndoablePattern) pattern).redo(this, context);
 		}
 	}
+
+	@Override
+	public boolean hasDoneChanges() {
+		IPattern pattern = delegate.getPattern();
+		return pattern.hasDoneChanges(IRemove.class);
+	}
 }