/*******************************************************************************
* Copyright (c) 2014, 2015 itemis AG and others.
* 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:
* Alexander Nyßen (itemis AG) - initial API and implementation
*
*******************************************************************************/
package org.eclipse.gef.mvc.fx.policies;
import org.eclipse.gef.mvc.fx.operations.AbstractCompositeOperation;
import org.eclipse.gef.mvc.fx.operations.AddContentChildOperation;
import org.eclipse.gef.mvc.fx.operations.AttachToContentAnchorageOperation;
import org.eclipse.gef.mvc.fx.operations.DetachFromContentAnchorageOperation;
import org.eclipse.gef.mvc.fx.operations.ITransactionalOperation;
import org.eclipse.gef.mvc.fx.operations.RemoveContentChildOperation;
import org.eclipse.gef.mvc.fx.operations.ReverseUndoCompositeOperation;
import org.eclipse.gef.mvc.fx.parts.IContentPart;
import org.eclipse.gef.mvc.fx.parts.IVisualPart;
import javafx.scene.Node;
/**
* A (transaction) policy to handle content changes, i.e. adding/removing of
* content children as well as attaching/detaching to/from content anchorages.
* All changes are wrapped into {@link ITransactionalOperation}s that delegate
* to respective operations of the host {@link IContentPart} upon execution.
* <p>
* In detail, the following delegations are performed to operations of the host
* {@link IContentPart}:
* <ul>
* <li>{@link #addContentChild(Object, int)} will delegate through a
* {@link AddContentChildOperation} to
* {@link IContentPart#addContentChild(Object, int)}</li>
* <li>{@link #removeContentChild(Object)} will delegate through a
* {@link RemoveContentChildOperation} to
* {@link IContentPart#removeContentChild(Object)}</li>
* <li>{@link #attachToContentAnchorage(Object, String)} will delegate through a
* {@link AttachToContentAnchorageOperation} to
* {@link IContentPart#attachToContentAnchorage(Object, String)}</li>
* <li>{@link #detachFromContentAnchorage(Object, String)} will delegate through
* a {@link DetachFromContentAnchorageOperation} to
* IContentPart#detachFromContentAnchorage(Object, String)}</li>
* </ul>
* <p>
* This policy should be registered on each {@link IContentPart}.
*
* @author anyssen
*
*/
public class ContentPolicy extends AbstractPolicy {
/**
* Creates and records operations to add the given <i>contentChild</i> to
* the {@link #getHost() host} of this {@link ContentPolicy} at the
* specified <i>index</i>.
*
* @param contentChild
* The content {@link Object} that is to be added to the
* {@link #getHost() host} of this {@link ContentPolicy}.
* @param index
* The index of the new content child.
*/
public void addContentChild(Object contentChild, int index) {
checkInitialized();
getCompositeOperation().add(
new AddContentChildOperation(getHost(), contentChild, index));
locallyExecuteOperation();
}
/**
* Creates and records operations to attach the {@link #getHost() host} of
* this {@link ContentPolicy} to the specified <i>contentAnchorage</i> under
* the specified <i>role</i>.
*
* @param contentAnchorage
* The content {@link Object} to which the {@link #getHost()
* host} of this {@link ContentPolicy} is to be attached.
* @param role
* The role for the attachment.
*
*/
public void attachToContentAnchorage(Object contentAnchorage, String role) {
checkInitialized();
getCompositeOperation().add(new AttachToContentAnchorageOperation(
getHost(), contentAnchorage, role));
locallyExecuteOperation();
}
@Override
protected ITransactionalOperation createOperation() {
return new ReverseUndoCompositeOperation("Content Change");
}
/**
* Creates and records operations to detach the {@link #getHost() host} of
* this {@link ContentPolicy} from the specified <i>contentAnchorage</i>
* under the specified <i>role</i>.
*
* @param contentAnchorage
* The content {@link Object} from which the {@link #getHost()}
* of this {@link ContentPolicy} is detached.
* @param role
* The role under which the anchorage is detached.
*/
public void detachFromContentAnchorage(Object contentAnchorage,
String role) {
checkInitialized();
getCompositeOperation().add(new DetachFromContentAnchorageOperation(
getHost(), contentAnchorage, role));
locallyExecuteOperation();
}
/**
* Extracts a {@link AbstractCompositeOperation} from the operation created
* by {@link #createOperation()}. The composite operation is used to combine
* individual content change operations.
*
* @return The {@link AbstractCompositeOperation} that is used to combine
* the individual content change operations.
*/
protected AbstractCompositeOperation getCompositeOperation() {
return (AbstractCompositeOperation) getOperation();
}
@Override
public IContentPart<? extends Node> getHost() {
return (IContentPart<? extends Node>) super.getHost();
}
/**
* Creates and records operations to remove the given <i>contentChild</i>
* from the content children of the {@link #getHost() host} of this
* {@link ContentPolicy}.
*
* @param contentChild
* The content {@link Object} that is removed from content
* children of the {@link #getHost() host} of this
* {@link ContentPolicy}.
*/
public void removeContentChild(Object contentChild) {
checkInitialized();
getCompositeOperation()
.add(new RemoveContentChildOperation(getHost(), contentChild));
locallyExecuteOperation();
}
@Override
public void setAdaptable(IVisualPart<? extends Node> adaptable) {
if (adaptable != null && !(adaptable instanceof IContentPart)) {
throw new IllegalStateException(
"A ContentPolicy may only be attached to an IContentPart.");
}
super.setAdaptable(adaptable);
}
}