/*****************************************************************************
* Copyright (c) 2011 Atos Origin.
*
*
* 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:
* Atos Origin - Initial API and implementation
*
*****************************************************************************/
package org.eclipse.papyrus.uml.diagram.common.groups.commands;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.emf.transaction.Transaction;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.EditPolicy;
import org.eclipse.gmf.runtime.common.core.command.CommandResult;
import org.eclipse.gmf.runtime.diagram.ui.editparts.DiagramEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
import org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand;
import org.eclipse.gmf.runtime.notation.View;
import org.eclipse.papyrus.uml.diagram.common.groups.core.PendingGroupNotificationsManager;
import org.eclipse.papyrus.uml.diagram.common.groups.core.ui.ChooseChildrenNotificationConfigurator;
import org.eclipse.papyrus.uml.diagram.common.groups.core.ui.NotificationConfigurator;
import org.eclipse.papyrus.uml.diagram.common.util.DiagramEditPartsUtil;
/**
* This command will create a notification to ask the user to choose the graphical children of an element
*
* @author arthur daussy
*
*/
public class ChooseChildrenNotificationCommand extends AbstractTransactionalCommand {
/**
* All possible graphical children
*/
private List<IGraphicalEditPart> allChildren;
/**
* All children which are automatically chosen as graphical child
*/
private List<IGraphicalEditPart> automaticChildren;
/**
* {@link IAdaptable} of the view (used to retrieve the {@link EditPart})
*/
private IAdaptable adapter;
/**
* {@link EditPart} on which we have to choose the graphical children
*/
private IGraphicalEditPart mainEditPart;
/**
* {@link EditPart} hosting the {@link EditPolicy}
*/
private IGraphicalEditPart host;
/**
* Pending Group manager
*/
private PendingGroupNotificationsManager manager;
/**
* List of all notification created and modifed
*/
private List<ChooseChildrenNotificationConfigurator> createdNotificationConfigurator;
/**
* {@link DiagramEditPart}
*/
private DiagramEditPart diagramPart;
/**
* Construct the command for asking to choose graphical children of a adapter
* Constructor.
*
* @param domain
* @see {@link AbstractTransactionalCommand}
* @param label
* @see {@link AbstractTransactionalCommand}
* @param _allChildren
* @see {@link #allChildren}
* @param _automaticChildren
* @see {@link #automaticChildren}
* @param _adapter
* @see {@link #adapter}
*/
public ChooseChildrenNotificationCommand(TransactionalEditingDomain domain, String label, List<IGraphicalEditPart> _allChildren, List<IGraphicalEditPart> _automaticChildren, IAdaptable _adapter, IGraphicalEditPart getHost, DiagramEditPart _diagramPart) {
super(domain, label, null);
this.allChildren = _allChildren;
this.automaticChildren = _automaticChildren;
this.adapter = _adapter;
this.host = getHost;
this.diagramPart = _diagramPart;
this.manager = PendingGroupNotificationsManager.getInstanceForDiagram(DiagramEditPartsUtil.getDiagramEditPart(getHost));
}
@Override
protected CommandResult doExecuteWithResult(IProgressMonitor monitor, IAdaptable info) throws ExecutionException {
if(!getEditPartFromEditPartAdapter()) {
if(!allChildren.isEmpty()) {
getEditPartFromViewAdapter(allChildren.get(0));
}
}
if(mainEditPart != null) {
createdNotificationConfigurator = new ArrayList<ChooseChildrenNotificationConfigurator>();
NotificationConfigurator configurator = PendingGroupNotificationsManager.getInstanceForDiagram(diagramPart).getChooseChildrenPendingNotification(mainEditPart);
ChooseChildrenNotificationConfigurator notificationConfigurator = null;
if(configurator == null) {
//If there is no a pending notification for this main edit part then it create one
if(!allChildren.isEmpty() && isChildrenToChoose()) {
notificationConfigurator = new ChooseChildrenNotificationConfigurator(mainEditPart, allChildren, automaticChildren, host, manager);
notificationConfigurator.runConfigurator();
}
} else {
//Else update the old one if needed TODO TODO
// 1 - Compare if there is any modification TODO
if(configurator instanceof ChooseChildrenNotificationConfigurator) {
notificationConfigurator = (ChooseChildrenNotificationConfigurator)configurator;
if(notificationConfigurator.isThereAnyModification(mainEditPart, allChildren, automaticChildren, host)) {
// 2 - There are some update the old notification TODO
notificationConfigurator.closeNotification();
if(!allChildren.isEmpty() && isChildrenToChoose()) {
notificationConfigurator = new ChooseChildrenNotificationConfigurator(mainEditPart, allChildren, automaticChildren, host, manager);
notificationConfigurator.runConfigurator();
}
}
}
}
if(notificationConfigurator != null) {
createdNotificationConfigurator.add(notificationConfigurator);
}
return CommandResult.newOKCommandResult();
}
return CommandResult.newErrorCommandResult("The editPart of the adaptable element has not been found");//$NON-NLS-1$
}
/**
* Return true if there is some children on which the user should choose the graphical parent
*
* @return
*/
private boolean isChildrenToChoose() {
return (allChildren.size() > automaticChildren.size());
}
/**
* Set the main edit part attribute from the adapter
*
* @param any
* Any {@link IGraphicalEditPart} from which we can get the EditPartRegistery
* @return true if succeed
*/
private Boolean getEditPartFromEditPartAdapter() {
Object _mainEditPart = adapter.getAdapter(EditPart.class);
if(_mainEditPart instanceof IGraphicalEditPart) {
mainEditPart = (IGraphicalEditPart)_mainEditPart;
return true;
}
return false;
}
/**
* Get the {@link IGraphicalEditPart} from view adapter
*
* @param any
* @return
*/
private Boolean getEditPartFromViewAdapter(IGraphicalEditPart any) {
Object view = adapter.getAdapter(View.class);
Map<?, ?> registery = any.getViewer().getEditPartRegistry();
if(view instanceof View) {
View childView = (View)view;
Object auxPart = registery.get(childView);
if(auxPart instanceof IGraphicalEditPart) {
mainEditPart = (IGraphicalEditPart)auxPart;
return true;
}
}
return false;
}
/**
* Inform that the command has been undone and delete or update the created notification
*
* @see org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand#didUndo(org.eclipse.emf.transaction.Transaction)
* @param tx
* a transaction that has been undone.
*/
@Override
protected void didUndo(Transaction tx) {
for(ChooseChildrenNotificationConfigurator notifConfigurator : createdNotificationConfigurator) {
notifConfigurator.closeNotification();
}
super.didUndo(tx);
}
}