/*****************************************************************************
* Copyright (c) 2010 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.activity.edit.dialogs;
import org.eclipse.papyrus.uml.diagram.activity.edit.helpers.ObjectFlowEditHelper;
import org.eclipse.papyrus.uml.diagram.activity.part.Messages;
import org.eclipse.papyrus.uml.diagram.activity.providers.UMLElementTypes;
import org.eclipse.papyrus.uml.diagram.common.ui.helper.HelpComponentFactory;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.forms.FormDialog;
import org.eclipse.ui.forms.IManagedForm;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.ImageHyperlink;
import org.eclipse.ui.forms.widgets.ScrolledForm;
import org.eclipse.ui.forms.widgets.Section;
import org.eclipse.uml2.uml.Action;
import org.eclipse.uml2.uml.ActivityNode;
import org.eclipse.uml2.uml.InputPin;
import org.eclipse.uml2.uml.OpaqueAction;
import org.eclipse.uml2.uml.OutputPin;
import org.eclipse.uml2.uml.Pin;
import org.eclipse.uml2.uml.Type;
import org.eclipse.uml2.uml.UMLFactory;
import org.eclipse.uml2.uml.UMLPackage;
/**
* This class provides a dialog to initialize a CallBehaviorAction at its
* creation.
*/
public class CreatePinsForObjectFlowDialog extends FormDialog {
private static final String TITLE = Messages.CreatePinsForObjectFlowDialog_Title;
private static final String PIN_CREATION_SECTION_TITLE = Messages.CreatePinsForObjectFlowDialog_PinCreationTitle;
private static final String NAME_LABEL = Messages.CreatePinsForObjectFlowDialog_Name;
private static final String TYPE_LABEL = Messages.CreatePinsForObjectFlowDialog_Type;
/** The initial value for pins name */
private static final String NAME_INITIAL_VALUE = "data";
/** The user chosen source node */
private ActivityNode initialSource = null;
/** The user chosen target node */
private ActivityNode initialTarget = null;
/** The object to use as object flow source */
private ActivityNode newSource = null;
/** The object to use as object flow target */
private ActivityNode newTarget = null;
private Text creationNameText = null;
private String creationName = NAME_INITIAL_VALUE;
private Text creationTypeText = null;
private Button creationTypeButton = null;
private Type creationType = null;
/**
* Create a new dialog to initialize a CallBehaviorAction.
*
* @param shell
* parent shell
* @param source
* the chosen source of the object flow
* @param target
* the chosen target of the object flow
*/
public CreatePinsForObjectFlowDialog(Shell shell, ActivityNode source, ActivityNode target) {
super(shell);
initialSource = source;
initialTarget = target;
}
@Override
public int open() {
if(ObjectFlowEditHelper.insertPinForStartingNewObjectFlow(initialSource) && ObjectFlowEditHelper.insertPinForEndingNewObjectFlow(initialTarget)) {
// create an object flow between actions : both pins must be created
return super.open();
} else {
boolean needInformation = false;
// use correct extremities or configure new one
if(ObjectFlowEditHelper.insertPinForStartingNewObjectFlow(initialSource)) {
newSource = createSource((Action)initialSource, initialTarget);
if(newSource == null) {
// ask for missing information
needInformation = true;
}
} else {
newSource = initialSource;
}
if(ObjectFlowEditHelper.insertPinForEndingNewObjectFlow(initialTarget)) {
newTarget = createTarget((Action)initialTarget, initialSource);
if(newTarget == null) {
// ask for missing information
needInformation = true;
}
} else {
newTarget = initialTarget;
}
if(needInformation) {
return super.open();
}
return OK;
}
}
/**
* Create a pin to use as target if all information is available
*
* @param parentAction
* the action containing the pin
* @param objectFlowSource
* the source of the object flow
* @return the created pin or null if information is missing
*/
private InputPin createTarget(Action parentAction, ActivityNode objectFlowSource) {
if(objectFlowSource instanceof Pin) {
return createInputPin(parentAction, objectFlowSource.getName(), ((Pin)objectFlowSource).getType());
} else {
// Source is not a pin, probably a control node. Ask for information
return null;
}
}
/**
* Create a pin to use as source if all information is available
*
* @param parentAction
* the action containing the pin
* @param objectFlowTarget
* the target of the object flow
* @return the created pin or null if information is missing
*/
private OutputPin createSource(Action parentAction, ActivityNode objectFlowTarget) {
if(objectFlowTarget instanceof Pin) {
return createOutputPin(parentAction, objectFlowTarget.getName(), ((Pin)objectFlowTarget).getType());
} else {
// Source is not a pin, probably a control node. Ask for information
return null;
}
}
/**
* Create an input pin
*
* @param parentAction
* the action containing this pin
* @param name
* pin name
* @param type
* pin type
* @return created pin
*/
private InputPin createInputPin(Action parentAction, String name, Type type) {
InputPin result = UMLFactory.eINSTANCE.createInputPin();
result.setName(name);
result.setType(type);
ObjectFlowEditHelper.insertInputPin(parentAction, result);
return result;
}
/**
* Create an output pin
*
* @param parentAction
* the action containing this pin
* @param name
* pin name
* @param type
* pin type
* @return created pin
*/
private OutputPin createOutputPin(Action parentAction, String name, Type type) {
OutputPin result = UMLFactory.eINSTANCE.createOutputPin();
result.setName(name);
result.setType(type);
ObjectFlowEditHelper.insertOutputPin(parentAction, result);
return result;
}
/**
* Create the form to :
*
* - ask the user the name of pins to create.
*
* - ask the user the type of pins to create.
*
* @see org.eclipse.ui.forms.FormDialog#createFormContent(org.eclipse.ui.forms.IManagedForm)
*/
@Override
protected void createFormContent(IManagedForm pForm) {
pForm.getForm().setText(TITLE);
ScrolledForm scrolledForm = pForm.getForm();
FormToolkit toolkit = pForm.getToolkit();
Composite parent = scrolledForm.getBody();
parent.setLayout(new GridLayout());
createPinCreationSection(scrolledForm.getBody(), toolkit);
hookListeners();
scrolledForm.reflow(true);
}
/**
* Create the section to ask the user to parameterize the pin.
*
* @param pParent
* the section's parent widget
* @param pToolkit
* the form toolkit
*/
private void createPinCreationSection(Composite pParent, FormToolkit pToolkit) {
// create the section
String lSectionTitle = PIN_CREATION_SECTION_TITLE;
Section lSection = pToolkit.createSection(pParent, Section.EXPANDED | Section.TITLE_BAR);
lSection.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
if(lSectionTitle != null) {
lSection.setText(lSectionTitle);
}
ImageHyperlink componentHelp = HelpComponentFactory.createHelpComponent(lSection, pToolkit, Messages.CreatePinsForObjectFlowDialog_PinCreationHelp, true);
lSection.setTextClient(componentHelp);
ScrolledForm lInsideScrolledForm = pToolkit.createScrolledForm(lSection);
lInsideScrolledForm.setExpandHorizontal(true);
lInsideScrolledForm.setExpandVertical(true);
Composite lBody = lInsideScrolledForm.getBody();
GridLayout lLayout = new GridLayout();
lLayout.numColumns = 3;
lBody.setLayout(lLayout);
// content of the section
pToolkit.createLabel(lBody, NAME_LABEL, SWT.NONE);
creationNameText = pToolkit.createText(lBody, NAME_INITIAL_VALUE, SWT.BORDER);
creationNameText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));
creationNameText.setFocus();
pToolkit.createLabel(lBody, TYPE_LABEL, SWT.NONE);
creationTypeText = pToolkit.createText(lBody, "", SWT.BORDER | SWT.READ_ONLY);
creationTypeText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
creationTypeButton = pToolkit.createButton(lBody, "...", SWT.FLAT);
Image image = UMLElementTypes.getImage(UMLPackage.eINSTANCE.getClass_());
creationTypeButton.setImage(image);
creationTypeButton.setLayoutData(new GridData(SWT.NONE));
lInsideScrolledForm.reflow(true);
lSection.setClient(lInsideScrolledForm);
}
/**
* Add listeners to widgets
*/
private void hookListeners() {
// listener to new pin name
ModifyListener lNameListener = new ModifyListener() {
/**
* @see org.eclipse.swt.events.ModifyListener#modifyText(org.eclipse.swt.events.ModifyEvent)
*/
public void modifyText(ModifyEvent e) {
creationName = creationNameText.getText();
}
};
creationNameText.addModifyListener(lNameListener);
// listener to select new pin type
SelectionListener selectTypeBtnListener = new SelectionAdapter() {
/**
* @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
*/
@Override
public void widgetSelected(SelectionEvent e) {
handleChooseType();
}
};
creationTypeButton.addSelectionListener(selectTypeBtnListener);
}
/**
* Open the dialog to choose the type of the pin(s) to create
*
*/
private void handleChooseType() {
/*
* TODO Backport
*/
// UMLMultiEClassifierTreeSelectorDialog dialog = new UMLMultiEClassifierTreeSelectorDialog(getShell(),initialSource, Sets.newHashSet(UMLPackage.Literals.TYPE));
// dialog.setMessage(Messages.UMLModelingAssistantProviderMessage);
// dialog.setTitle(Messages.UMLModelingAssistantProviderTitle);
// if(dialog.open() == Window.OK) {
// creationType = (Type)dialog.getTheResult();
// creationTypeText.setText(dialog.getText(creationType));
// }
}
/**
* Set correctly the invoked object, by creating it if needed. Then,
* notifies that the ok button of this dialog has been pressed.
*
* @see org.eclipse.jface.dialogs.Dialog#okPressed()
*
*/
@Override
protected void okPressed() {
// create pins if needed
if(newSource == null) {
newSource = createOutputPin((OpaqueAction)initialSource, creationName, creationType);
}
if(newTarget == null) {
newTarget = createInputPin((OpaqueAction)initialTarget, creationName, creationType);
}
super.okPressed();
}
/**
* Get the node to use as object flow source
*
* @return new source
*/
public ActivityNode getSource() {
return newSource;
}
/**
* Get the node to use as object flow target
*
* @return new target
*/
public ActivityNode getTarget() {
return newTarget;
}
}