/***************************************************************************** * 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.core.ui; import java.util.HashMap; import java.util.List; import java.util.Map; import org.eclipse.core.runtime.Status; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EReference; import org.eclipse.emf.transaction.TransactionalEditingDomain; import org.eclipse.gef.EditPart; import org.eclipse.gef.EditPolicy; import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart; import org.eclipse.papyrus.commands.wrappers.GMFtoEMFCommandWrapper; import org.eclipse.papyrus.infra.widgets.toolbox.notification.builders.IContext; import org.eclipse.papyrus.uml.diagram.common.groups.Messages; import org.eclipse.papyrus.uml.diagram.common.groups.commands.ChangeGraphicalParentCommand; import org.eclipse.papyrus.uml.diagram.common.groups.commands.ChangeModelParentCommand; import org.eclipse.papyrus.uml.diagram.common.groups.commands.ChooseParentNotificationCommand; import org.eclipse.papyrus.uml.diagram.common.groups.core.PendingGroupNotificationsManager; import org.eclipse.papyrus.uml.diagram.common.groups.core.ui.utils.CreatorUtils; import org.eclipse.papyrus.uml.diagram.common.groups.core.utils.Utils; import org.eclipse.swt.SWT; import org.eclipse.swt.events.DisposeEvent; import org.eclipse.swt.events.DisposeListener; import org.eclipse.swt.layout.FormData; import org.eclipse.swt.layout.FormLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.ui.forms.widgets.FormText; import org.eclipse.ui.forms.widgets.FormToolkit; /** * ICompositor used to choose parent among a list. This IComposite handle graphical and model parent. * * @author adaussy * */ public class ChooseParentNotificationConfigurator extends NotificationConfigurator { /** * List of availables parents */ private List<IGraphicalEditPart> parents; /** * the mode to use this command with */ private boolean mode; /** * buttons for children */ private Map<Button, IGraphicalEditPart> childCheckBoxes; /** * Edit part of the children */ private IGraphicalEditPart mainEditPart; /** * {@link EditPart} hosting the {@link EditPolicy} */ private IGraphicalEditPart host; /** * * Constructor. * * @param parents * all available parents (model of graphical {@link #mode} * @param _childPart * IGraphicalEditPart of the child (the child has to be already created) * @param mode * Choose between graphical and model * Model : Change the model parent and the graphical parent * Graphical : Change only the graphical parent */ public ChooseParentNotificationConfigurator(List<IGraphicalEditPart> parents, IGraphicalEditPart _childPart, Boolean mode, IGraphicalEditPart getHost, PendingGroupNotificationsManager _manager, Mode messageMode, String label) { super(_childPart, _manager, label, messageMode); this.parents = parents; childCheckBoxes = new HashMap<Button, IGraphicalEditPart>(); mainEditPart = _childPart; this.mode = mode; this.host = getHost; } /** * * @see org.eclipse.papyrus.ui.toolbox.notification.ICompositeCreator#createComposite(org.eclipse.swt.widgets.Composite, * org.eclipse.ui.forms.widgets.FormToolkit) * * @param parent * @param toolkit * @return */ public Composite createComposite(Composite parent, FormToolkit toolkit) { if(toolkit == null) { toolkit = new FormToolkit(parent.getDisplay()); } Composite top = toolkit.createComposite(parent, SWT.NONE); top.setLayout(new FormLayout()); FormText textLabel = toolkit.createFormText(top, false); textLabel.setText(Messages.ChooseParentNotificationCommand_ChooseGraphicalParentMessage + CreatorUtils.getLabel(mainEditPart), false, true); FormData data = new FormData(); textLabel.setLayoutData(data); Control previousElement = textLabel; /* * Create for each parents a checkbox */ createCheckBoxes(toolkit, top, previousElement); return top; } public IGraphicalEditPart getChildPart() { return mainEditPart; } /** * Create for each parent a check box and select the default one * * @param toolkit * @param top * @param previousElement */ private void createCheckBoxes(FormToolkit toolkit, Composite top, Control previousElement) { FormData data; for(IGraphicalEditPart parentEditPart : parents) { String label = CreatorUtils.getLabel(parentEditPart); Button checkBox = toolkit.createButton(top, label, SWT.RADIO); EditPart childParent = mainEditPart.getParent(); if(childParent != null && childParent.equals(parentEditPart)) { checkBox.setSelection(true); } else { checkBox.setSelection(false); } data = CreatorUtils.getFormDataUnder(previousElement); checkBox.setLayoutData(data); previousElement = checkBox; childCheckBoxes.put(checkBox, parentEditPart); // add dispose listener to remove from handled widgets checkBox.addDisposeListener(new DisposeListener() { /** * Remove widget from handled ones * * @param e * the dispose event */ public void widgetDisposed(DisposeEvent e) { childCheckBoxes.remove(e.widget); } }); //checkBox.addSelectionListener( } } /** * * @see org.eclipse.papyrus.ui.toolbox.notification.NotificationRunnable#run(org.eclipse.papyrus.ui.toolbox.notification.builders.IContext) * * @param context */ public void run(IContext context) { IGraphicalEditPart newParent = null; for(Button checkBoxButton : childCheckBoxes.keySet()) { if(checkBoxButton.getSelection()) { newParent = childCheckBoxes.get(checkBoxButton); } } //If the system has found the edit part of the new parent if(newParent != null) { TransactionalEditingDomain editingDomain = mainEditPart.getEditingDomain(); /* * Change the model parent if needed */ changeModelParent(newParent, editingDomain); /* * Change the graphical parent */ changeGraphicalParent(newParent, editingDomain); } /* * Close the notification */ closeNotitfication(context); } /** * Change the graphical parent * * @param newParent * the new graphical parent of the child * @param editingDomain * to create an transactionnal command */ private void changeGraphicalParent(IGraphicalEditPart newParent, TransactionalEditingDomain editingDomain) { String label = "Change graphical parent" + " of " + CreatorUtils.getLabel(mainEditPart) + " to " + CreatorUtils.getLabel(newParent); ChangeGraphicalParentCommand reassignParent = new ChangeGraphicalParentCommand(editingDomain, label, newParent, mainEditPart, host); //If the command is valid the system execute it if(reassignParent != null && reassignParent.canExecute()) { //Execute the command editingDomain.getCommandStack().execute(new GMFtoEMFCommandWrapper(reassignParent)); } } /** * Change the model parent if the current mode is model * * @param newParent * New model parent of the child * @param editingDomain * to create the transactional command */ private void changeModelParent(IGraphicalEditPart newParent, TransactionalEditingDomain editingDomain) { if(mode == ChooseParentNotificationCommand.MODEL_MODE) { EObject childObject = mainEditPart.resolveSemanticElement(); EObject parentObject = newParent.resolveSemanticElement(); if(parentObject != null && childObject != null) { EReference ref = Utils.getContainmentEReference(parentObject.eClass(), childObject.eClass()); if(ref != null) { Map<EObject, EReference> chilrendToMove = new HashMap<EObject, EReference>(); chilrendToMove.put(childObject, ref); ChangeModelParentCommand reassignModelparent = new ChangeModelParentCommand(editingDomain, newParent, chilrendToMove, newParent); //If the command is valid the system execute it if(reassignModelparent != null && reassignModelparent.canExecute()) { //Execute the command editingDomain.getCommandStack().execute(new GMFtoEMFCommandWrapper(reassignModelparent)); } } } else { org.eclipse.papyrus.uml.diagram.common.groups.Activator.getDefault().getLog().log(new Status(Status.WARNING, org.eclipse.papyrus.uml.diagram.common.groups.Activator.PLUGIN_ID, "One of the needed element is unavailable")); } } } @Override protected void closeNotitfication(IContext context) { papyrusNotificationView.dispose(); notification.delete(); manager.removeChooseParentNotification(mainEditPart); } }