blob: 0660f8ae8cbd9d65f2c932ba65fc638d80d0b216 [file] [log] [blame]
/******************************************************************************
* Copyright (c) 2002, 2008 IBM Corporation 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:
* IBM Corporation - initial API and implementation
****************************************************************************/
package org.eclipse.gmf.runtime.diagram.ui.editpolicies;
import java.util.List;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.edit.domain.IEditingDomainProvider;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.Request;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.commands.CompoundCommand;
import org.eclipse.gef.commands.UnexecutableCommand;
import org.eclipse.gef.requests.GroupRequest;
import org.eclipse.gmf.runtime.common.core.command.CompositeCommand;
import org.eclipse.gmf.runtime.common.core.util.StringStatics;
import org.eclipse.gmf.runtime.diagram.core.commands.DeleteCommand;
import org.eclipse.gmf.runtime.diagram.core.util.ViewUtil;
import org.eclipse.gmf.runtime.diagram.ui.commands.ICommandProxy;
import org.eclipse.gmf.runtime.diagram.ui.editparts.GraphicalEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.GroupEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.IInsertableEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.SemanticListCompartmentEditPart;
import org.eclipse.gmf.runtime.diagram.ui.l10n.DiagramUIMessages;
import org.eclipse.gmf.runtime.diagram.ui.preferences.IPreferenceConstants;
import org.eclipse.gmf.runtime.diagram.ui.requests.EditCommandRequestWrapper;
import org.eclipse.gmf.runtime.diagram.ui.requests.GroupRequestViaKeyboard;
import org.eclipse.gmf.runtime.diagram.ui.requests.RequestConstants;
import org.eclipse.gmf.runtime.emf.type.core.requests.CreateElementRequest;
import org.eclipse.gmf.runtime.emf.type.core.requests.DestroyElementRequest;
import org.eclipse.gmf.runtime.notation.View;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialogWithToggle;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.swt.widgets.Display;
/**
* Concrete class that extends the GEF's <code>ComponentEditPolicy</code>.
* This edit policy will return a command in response to delete requests.
*
* @author Vishy Ramaswamy
*/
public class ComponentEditPolicy
extends org.eclipse.gef.editpolicies.ComponentEditPolicy {
private static final String DELETE_FROM_DIAGRAM_DLG_TITLE = DiagramUIMessages.PromptingDeleteAction_DeleteFromDiagramDialog_Title;
private static final String DELETE_FROM_DIAGRAM_DLG_MESSAGE = DiagramUIMessages.PromptingDeleteAction_DeleteFromDiagramDialog_Message;
private static final String DELETE_FROM_MODEL_DLG_TOGGLE_LABEL = DiagramUIMessages.MessageDialogWithToggle_DoNotPromptAgainToggle_label;
/**
* Returns a delete command to honour the supplied request.
* Calls {@link #createDeleteSemanticCommand(GroupRequest)} if
* {@link #shouldDeleteSemantic()} returns <tt>true</tt>; othwerise
* {@link #createDeleteViewCommand(GroupRequest)} is called.
* @see org.eclipse.gef.editpolicies.ComponentEditPolicy#createDeleteCommand(GroupRequest)
*/
protected final Command createDeleteCommand(GroupRequest deleteRequest) {
if (shouldDeleteSemantic()){
return createDeleteSemanticCommand(deleteRequest);
}
if (deleteRequest instanceof GroupRequestViaKeyboard) {
boolean shouldShowPrompt = ((GroupRequestViaKeyboard) deleteRequest)
.isShowInformationDialog();
if (shouldShowPrompt) {
((GroupRequestViaKeyboard) deleteRequest)
.setShowInformationDialog(false);
if (showPrompt() == false) {
return UnexecutableCommand.INSTANCE;
}
}
}
return createDeleteViewCommand(deleteRequest);
}
/**
* Return <tt>true</tt> if the host element should delete its semantic
* element; otherwise <tt>false</tt> to delete its view. A <tt>true</tt>
* return value implies that the host's parent is using a canonical
* model manager.
* @return true or false
*/
protected boolean shouldDeleteSemantic() {
EditPart parent = getHost().getParent();
if (parent instanceof SemanticListCompartmentEditPart){
SemanticListCompartmentEditPart semListCompartment =
(SemanticListCompartmentEditPart)parent;
return semListCompartment.isCanonicalOn();
} else {
// If the parent is a group, then we want to get the first parent
// that isn't a group and test for a canonical editpolicy there.
while (parent instanceof GroupEditPart) {
parent = parent.getParent();
}
}
EObject eObject = (EObject)getHost().getAdapter(EObject.class);
if (eObject != null && parent != null ) { //sanity checks
CanonicalEditPolicy cep = (CanonicalEditPolicy)parent.getEditPolicy(EditPolicyRoles.CANONICAL_ROLE);
return cep != null
&& cep.isEnabled()
&& cep.canCreate(eObject);
}
return false;
}
/**
* Return a command to delete the host's view. The host's primary view
* is deleted if {@link GroupRequest#getEditParts()} returns a
* <tt>null</tt> or empty list; otherwise each editpart's view is
* deleted.
* @param deleteRequest the original delete request.
* @return Command
*/
protected Command createDeleteViewCommand(GroupRequest deleteRequest) {
CompositeCommand cc = new CompositeCommand(StringStatics.BLANK);
TransactionalEditingDomain editingDomain = getEditingDomain();
if (editingDomain == null) {
return null;
}
List toDel = deleteRequest.getEditParts();
if (toDel == null || toDel.isEmpty()) {
cc.compose(new DeleteCommand(editingDomain, (View) getHost()
.getModel()));
} else {
for (int i = 0; i < toDel.size(); i++) {
IGraphicalEditPart gep = (IGraphicalEditPart) toDel.get(i);
cc.compose(new DeleteCommand(editingDomain, (View) gep
.getModel()));
}
}
return new ICommandProxy(cc.reduce());
}
/**
* Return a command to delete the host's semantic elements. This method is
* called if the host is canonical.
*
* @see #shouldDeleteSemantic()
* @param deleteRequest
* the original delete request.
* @return Command
*/
protected Command createDeleteSemanticCommand(GroupRequest deleteRequest) {
TransactionalEditingDomain editingDomain = ((IGraphicalEditPart) getHost()).getEditingDomain();
boolean shouldShowPrompt = (deleteRequest instanceof GroupRequestViaKeyboard) ? ((GroupRequestViaKeyboard) deleteRequest)
.isShowInformationDialog()
: false;
EditCommandRequestWrapper editCommandRequest = new EditCommandRequestWrapper(
new DestroyElementRequest(editingDomain, shouldShowPrompt),
deleteRequest.getExtendedData());
Command semanticCmd = getHost().getCommand(editCommandRequest);
if (semanticCmd != null && semanticCmd.canExecute()) {
CompoundCommand cc = new CompoundCommand();
cc.add(semanticCmd);
return cc;
}
return createDeleteViewCommand(deleteRequest);
}
/**
* Returns the view element to be deleted.
* @return the host's primary view element.
*/
protected View getView() {
if (getHost().getModel() instanceof View &&
getHost() instanceof GraphicalEditPart){
GraphicalEditPart ePart = (GraphicalEditPart)getHost();
return ePart.getPrimaryView();
}
return null;
}
/**
* Performs the delete action on the selected objects.
*/
private boolean showPrompt() {
boolean prompt = ((IPreferenceStore) ((IGraphicalEditPart) getHost())
.getDiagramPreferencesHint().getPreferenceStore())
.getBoolean(IPreferenceConstants.PREF_PROMPT_ON_DEL_FROM_DIAGRAM);
if(prompt)
if(showMessageDialog())
return true;
else
return false;
return true;
}
/**
* launches the prompting dialogBox on deletion of elements from the diagram for the end user.
*
* @return boolean true if user pressed YES; false otherwise
*/
private boolean showMessageDialog() {
MessageDialogWithToggle dialog = MessageDialogWithToggle
.openYesNoQuestion(Display.getCurrent().getActiveShell(),
DELETE_FROM_DIAGRAM_DLG_TITLE, DELETE_FROM_DIAGRAM_DLG_MESSAGE,
DELETE_FROM_MODEL_DLG_TOGGLE_LABEL, false,
(IPreferenceStore) ((IGraphicalEditPart) getHost())
.getDiagramPreferencesHint().getPreferenceStore(),
IPreferenceConstants.PREF_PROMPT_ON_DEL_FROM_DIAGRAM);
if (dialog.getReturnCode() == IDialogConstants.YES_ID)
return true;
else
return false;
}
/**
* getInsertableEditPart
* Returns the EditPart that can be recipient of the default insert command.
*
* @return IInsertableEditPart
*/
protected IInsertableEditPart getInsertableEditPart() {
if (getHost() instanceof IInsertableEditPart) {
return (IInsertableEditPart)getHost();
}
return null;
}
/**
* getInsertCommand
* Returns an creation command to honour the supplied request.
*
* @param insertRequest
* @return Command that will create the default sementic element responding to insert.
*/
protected Command getInsertCommand(GroupRequest insertRequest) {
IInsertableEditPart insertEP = getInsertableEditPart();
if (null == insertEP)
return null;
EObject hostElement = ViewUtil.resolveSemanticElement((View)insertEP.getModel());
if (hostElement != null) {
TransactionalEditingDomain editingDomain = getEditingDomain();
if (editingDomain == null) {
return null;
}
CreateElementRequest theReq = new CreateElementRequest(
editingDomain, hostElement, insertEP.getElementType());
EditCommandRequestWrapper editCommandRequest = new EditCommandRequestWrapper(
theReq, insertRequest.getExtendedData());
Command cmd = ((IGraphicalEditPart) getHost())
.getCommand(editCommandRequest);
return cmd;
}
return null;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.gef.editpolicies.ComponentEditPolicy#getCommand(org.eclipse.gef.Request)
*/
public Command getCommand(Request request) {
if (!(request instanceof GroupRequest))
return null;
GroupRequest grpRequest = (GroupRequest)request;
if (grpRequest instanceof GroupRequestViaKeyboard){
return getDeleteCommand(grpRequest);
}
else if (grpRequest.getType().equals(RequestConstants.REQ_INSERT_SEMANTIC)) {
return getInsertCommand(grpRequest);
}
return super.getCommand(request);
}
private TransactionalEditingDomain getEditingDomain() {
if (getHost() instanceof IGraphicalEditPart) {
return ((IGraphicalEditPart) getHost()).getEditingDomain();
} else if (getHost() instanceof IEditingDomainProvider) {
Object domain = ((IEditingDomainProvider) getHost())
.getEditingDomain();
if (domain instanceof TransactionalEditingDomain) {
return (TransactionalEditingDomain) domain;
}
}
return null;
}
}