/*******************************************************************************
* Copyright (c) 2006-2013 The RCP Company 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:
* The RCP Company - initial API and implementation
*******************************************************************************/
package com.rcpcompany.uibindings.internal.handlers;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.commands.IHandler2;
import org.eclipse.core.expressions.IEvaluationContext;
import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.common.command.CompoundCommand;
import org.eclipse.emf.common.command.UnexecutableCommand;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature.Setting;
import org.eclipse.emf.edit.command.DeleteCommand;
import org.eclipse.emf.edit.command.RemoveCommand;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.ui.handlers.HandlerUtil;
import com.rcpcompany.uibindings.Constants;
import com.rcpcompany.uibindings.IBinding;
import com.rcpcompany.uibindings.IElementParentage;
import com.rcpcompany.uibindings.IManager;
import com.rcpcompany.uibindings.IViewerBinding;
import com.rcpcompany.uibindings.internal.Activator;
import com.rcpcompany.uibindings.utils.UIBEcoreUtils;
import com.rcpcompany.utils.logging.LogUtils;
/**
* Deletes the current object in a viewer.
*
* @author Tonny Madsen, The RCP Company
*/
public class DeleteHandler extends AbstractHandler implements IHandler2 {
@Override
public Object execute(ExecutionEvent ee) throws ExecutionException {
if (Activator.getDefault().TRACE_HANDLERS) {
LogUtils.debug(this, "");
}
// The binding
final IBinding bb = (IBinding) HandlerUtil.getVariableChecked(ee, Constants.SOURCES_ACTIVE_CONTAINER_BINDING);
if (!(bb instanceof IViewerBinding)) return null;
// The viewer
final IViewerBinding vb = (IViewerBinding) bb;
final Command cmd = createCommand(vb, true);
/*
* Execute if possible...
*/
if (cmd == null || !cmd.canExecute()) throw new ExecutionException("Cannot delete selected objects");
// LogUtils.debug(this, "execute");
vb.getEditingDomain().getCommandStack().execute(cmd);
return null;
}
@Override
public void setEnabled(Object evaluationContext) {
if (!(evaluationContext instanceof IEvaluationContext)) return;
final IEvaluationContext context = (IEvaluationContext) evaluationContext;
// The binding
final Object bbo = context.getVariable(Constants.SOURCES_ACTIVE_CONTAINER_BINDING);
if (!(bbo instanceof IViewerBinding)) {
setBaseEnabled(false);
return;
}
// The viewer
final IViewerBinding vb = (IViewerBinding) bbo;
final Command cmd = createCommand(vb, false);
/*
* Execute if possible...
*/
if (cmd == null || !cmd.canExecute()) {
setBaseEnabled(false);
return;
}
if (IManager.Factory.getManager().isDeleteHandlerCheckEnabled()) {
final Collection<EObject> list = vb.getSelection();
final Map<EObject, Collection<Setting>> references = UIBEcoreUtils.findIncomingRequiredReferences(list);
if (references != null) {
setBaseEnabled(false);
return;
}
}
setBaseEnabled(true);
}
@Override
protected void setBaseEnabled(boolean state) {
super.setBaseEnabled(state);
}
/**
* Creates and returns a command that can delete the current objects of the specified viewer.
*
* @param vb the viewer binding
* @param queryUser TODO
* @return the command that will delete the current objects or <code>null</code>
*/
public static Command createCommand(IViewerBinding vb, boolean queryUser) {
/*
* TODO: find a way to cache the result - this method is called far too many times!
*/
// Then find the selected objects
final Collection<EObject> list = vb.getSelection();
if (list.size() == 0) return null;
final EditingDomain domain = vb.getEditingDomain();
final CompoundCommand cc = new CompoundCommand();
final List<EObject> deleteObjects = new ArrayList<EObject>();
for (final EObject element : list) {
/*
* Find the parentage for the element. Especially important - and difficult - for trees.
*/
final IElementParentage ep = vb.getElementParentage(element);
if (ep == null) {
continue;
}
final EObject parent = ep.getParent();
final EReference ref = ep.getReference();
if (parent == null || ref == null) {
continue;
}
Command cmd = null;
if (ref.isContainment()) {
deleteObjects.add(element);
} else {
cmd = RemoveCommand.create(domain, parent, ref, element);
}
cc.append(cmd);
}
if (!deleteObjects.isEmpty()) {
cc.append(DeleteCommand.create(domain, deleteObjects));
final Command deleteCommands = IManager.Factory.getManager().deleteObjects(domain, deleteObjects, false);
if (deleteCommands == null) return UnexecutableCommand.INSTANCE;
cc.append(deleteCommands);
}
return cc.unwrap();
}
}