/*******************************************************************************
* <copyright>
*
* Copyright (c) 2005, 2011 SAP AG.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* SAP AG - initial API, implementation and documentation
* mwenz - Bug 356218 - Added hasDoneChanges updates to update diagram feature
* and called features via editor command stack to check it
*
* </copyright>
*
*******************************************************************************/
package org.eclipse.graphiti.features.impl;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.emf.common.util.EList;
import org.eclipse.graphiti.features.IFeatureProvider;
import org.eclipse.graphiti.features.IReason;
import org.eclipse.graphiti.features.IUpdateFeature;
import org.eclipse.graphiti.features.context.IUpdateContext;
import org.eclipse.graphiti.features.context.impl.UpdateContext;
import org.eclipse.graphiti.mm.pictograms.Connection;
import org.eclipse.graphiti.mm.pictograms.Diagram;
import org.eclipse.graphiti.mm.pictograms.PictogramElement;
import org.eclipse.graphiti.mm.pictograms.Shape;
/**
* The Class DefaultUpdateDiagramFeature. Updates the shapes directly contained
* in the diagram. Does not update the connections contained in the diagram,
* since in many cases the connections get already updated by the shapes they
* belong to.
*/
public class DefaultUpdateDiagramFeature extends AbstractUpdateFeature {
private boolean hasDoneChanges = false;
/**
* Creates a new {@link DefaultUpdateDiagramFeature}.
*
* @param fp
* the feature provider
*/
public DefaultUpdateDiagramFeature(IFeatureProvider fp) {
super(fp);
}
public boolean canUpdate(IUpdateContext context) {
return context.getPictogramElement() instanceof Diagram;
}
public boolean update(IUpdateContext context) {
PictogramElement pe = context.getPictogramElement();
if (pe instanceof Diagram) {
Diagram d = (Diagram) pe;
EList<Shape> children = d.getChildren();
// Collect PEs for update. Execute update later, because otherwise we could get a
// ConcurrentModificationException if PEs get deleted etc.
Map<IUpdateFeature, IUpdateContext> connToUpdate = new HashMap<IUpdateFeature, IUpdateContext>();
for (Shape shape : children) {
UpdateContext updateContext = new UpdateContext(shape);
IUpdateFeature updateFeature = getFeatureProvider().getUpdateFeature(updateContext);
if (updateFeature != null && updateFeature.canUpdate(updateContext)
&& updateFeature.updateNeeded(updateContext).toBoolean()) {
connToUpdate.put(updateFeature, updateContext);
}
}
// Reset hasDoneChanges flag because no changes have happened so far
hasDoneChanges = false;
for (IUpdateFeature feature : connToUpdate.keySet()) {
feature.update(connToUpdate.get(feature));
if (feature.hasDoneChanges()) {
// At least one sub feature did some changes
hasDoneChanges = true;
}
}
}
return true;
}
public IReason updateNeeded(IUpdateContext context) {
PictogramElement pe = context.getPictogramElement();
if (pe instanceof Diagram) {
Diagram d = (Diagram) pe;
EList<Shape> children = d.getChildren();
for (Shape shape : children) {
UpdateContext updateContext = new UpdateContext(shape);
IUpdateFeature updateFeature = getFeatureProvider().getUpdateFeature(updateContext);
if (updateFeature != null && updateFeature.updateNeeded(updateContext).toBoolean()) {
return Reason.createTrueReason();
}
}
EList<Connection> connections = d.getConnections();
for (Connection connection : connections) {
UpdateContext updateContext = new UpdateContext(connection);
IUpdateFeature updateFeature = getFeatureProvider().getUpdateFeature(updateContext);
if (updateFeature != null && updateFeature.updateNeeded(updateContext).toBoolean()) {
return Reason.createTrueReason();
}
}
}
return Reason.createFalseReason();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.graphiti.features.impl.AbstractFeature#hasDoneChanges()
*/
@Override
public boolean hasDoneChanges() {
return hasDoneChanges;
}
}