package org.eclipse.uml2.diagram.sequence.edit.create;
import java.util.Arrays;
import java.util.Collections;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.viewers.IBaseLabelProvider;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.ListViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
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.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.List;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.uml2.uml.InteractionOperatorKind;
public class ChooseOperatorDialog extends Dialog {
private OperatorProperties myResult;
private ChooseOperatorPanel myChooseOperatorPanel;
private final InteractionOperatorKind[] myOperatorInfos;
public ChooseOperatorDialog(Shell parentShell) {
super(parentShell);
setShellStyle(SWT.DIALOG_TRIM | SWT.RESIZE | SWT.APPLICATION_MODAL );
myOperatorInfos = (InteractionOperatorKind[]) InteractionOperatorKind.VALUES.toArray(new InteractionOperatorKind[InteractionOperatorKind.VALUES.size()]);
Arrays.sort(myOperatorInfos);
}
OperatorProperties getResult() {
return myResult;
}
protected void configureShell(Shell shell) {
super.configureShell(shell);
shell.setText("New Combined Fragment");
}
protected Control createDialogArea(Composite parent) {
Composite composite = (Composite) super.createDialogArea(parent);
createChooseOperatorPanel(composite);
return composite;
}
protected void okPressed() {
myResult = myChooseOperatorPanel.getPropertyEditor().getResult();// create result before controls are disposed
super.okPressed();
}
private void createChooseOperatorPanel(Composite composite) {
myChooseOperatorPanel = new ChooseOperatorPanel(composite);
GridData gd = new GridData(GridData.FILL_BOTH);
gd.widthHint = 400;//XXX
gd.heightHint = 300;
// Point size = myChooseOperatorPanel.getRootControl().computeSize(SWT.DEFAULT, SWT.DEFAULT);
// gd.widthHint = size.x;
// gd.heightHint = size.y;
myChooseOperatorPanel.getRootControl().setLayoutData(gd);
}
private IStructuredContentProvider getContentProvider() {
return new IStructuredContentProvider() {
public Object[] getElements(Object inputElement) {
return myOperatorInfos;
}
public void dispose() {
}
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
}
};
}
static class OperatorProperties {
OperatorProperties(final InteractionOperatorKind operatorKind, final String arguments, final int numberOfOperands) {
super();
myOperatorKind = operatorKind;
myArguments = arguments;
myNumberOfOperands = numberOfOperands;
}
String getArguments() {
return myArguments;
}
int getNumberOfOperands() {
return myNumberOfOperands;
}
InteractionOperatorKind getOperatorKind() {
return myOperatorKind;
}
private final InteractionOperatorKind myOperatorKind;
private final String myArguments;
private final int myNumberOfOperands;
}
class ChooseOperatorPanel {
public ChooseOperatorPanel(Composite parent) {
myPanel = new Group(parent, SWT.NORMAL);
myPanel.setText("Combined Fragment Options");
myPanel.setLayout(new GridLayout(2,false));
createOperatorsList();
createOperatorPropertyEditor();
//initial selection
myList.setSelection(0);
myPropertyEditor.setCurrentOperatorInfo(myOperatorInfos[0]);
}
Control getRootControl() {
return myPanel;
}
OperatorPropertyEditor getPropertyEditor() {
return myPropertyEditor;
}
private void createOperatorsList() {
myList = new List(myPanel, SWT.V_SCROLL | SWT.BORDER);
GridData gd = new GridData(GridData.FILL_VERTICAL);
gd.widthHint = 90;//TODO: calculate it dynamically
myList.setLayoutData(gd);
myList.addMouseListener(new MouseAdapter() {
public void mouseDown(MouseEvent e) {
updateSelectedOperator();
}
});
myList.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
updateSelectedOperator();
}
});
myListViewer = new ListViewer(myList);
myListViewer.setContentProvider(getContentProvider());
myListViewer.setLabelProvider(new OperatorNameLabelProvider());
myListViewer.setInput(Collections.EMPTY_SET);
}
private void createOperatorPropertyEditor() {
myPropertyEditor = new OperatorPropertyEditor(myPanel);
GridData gd = new GridData(GridData.FILL_BOTH);
gd.grabExcessHorizontalSpace = true;
myPropertyEditor.setLayoutData(gd);
}
private void updateSelectedOperator() {
int index = myList.getSelectionIndex();
InteractionOperatorKind info = myOperatorInfos[index];
myPropertyEditor.setCurrentOperatorInfo(info);
}
private final Group myPanel;
private ListViewer myListViewer;
private OperatorPropertyEditor myPropertyEditor;
private List myList;
class OperatorNameLabelProvider extends LabelProvider implements IBaseLabelProvider {
public String getText(Object element) {
InteractionOperatorKind info = (InteractionOperatorKind)element;
return info.getName();
}
}
class OperatorPropertyEditor extends Composite {
private final Label myArgumentsLabel;
private final Text myArgumentsText;
private final Label myNumberOfOperandsLabel;
private final Text myNumberOfOperandsText;
private final Button myCancelUMLCheckBox;
private final Label myCancelUMLLabel;
private final Composite myCancelUMLPanel;
private final Label myOperatorNameLabel;
private final Text myOperatorNameText;
private InteractionOperatorKind myCurrentInfo;
public OperatorPropertyEditor(Composite parent) {
super(parent, SWT.NORMAL);
setLayout(new GridLayout());
myOperatorNameLabel = new Label(this, SWT.NORMAL);
GridData gd = new GridData(SWT.BEGINNING);
myOperatorNameLabel.setLayoutData(gd);
myOperatorNameLabel.setText("Operator name:");
myOperatorNameText = new Text(this, SWT.BORDER);
gd = new GridData(GridData.FILL_HORIZONTAL);
myOperatorNameText.setLayoutData(gd);
myArgumentsLabel = new Label(this, SWT.NORMAL);
gd = new GridData(SWT.BEGINNING);
myArgumentsLabel.setLayoutData(gd);
myArgumentsLabel.setText("Arguments:");
myArgumentsText = new Text(this, SWT.BORDER);
gd = new GridData(GridData.FILL_HORIZONTAL);
myArgumentsText.setLayoutData(gd);
myNumberOfOperandsLabel = new Label(this, SWT.NORMAL);
gd = new GridData(SWT.BEGINNING);
myNumberOfOperandsLabel.setLayoutData(gd);
myNumberOfOperandsLabel.setText("Number of operands:");
myNumberOfOperandsText = new Text(this, SWT.BORDER);
gd = new GridData(GridData.FILL_HORIZONTAL);
myNumberOfOperandsText.setLayoutData(gd);
myNumberOfOperandsText.addListener (SWT.Verify, new Listener () {
public void handleEvent (Event e) {
if (myNumberOfOperandsText.getText().length() >= 2 && e.text.length() > 0) {// at most 2 digits allowed
e.doit = false;
return;
}
String text = e.text;//Only digits allowed
char [] chars = new char [text.length ()];
text.getChars (0, chars.length, chars, 0);
for (int i=0; i<chars.length; i++) {
if (!('0' <= chars [i] && chars [i] <= '9')) {
e.doit = false;
return;
}
}
}
});
myCancelUMLPanel = new Composite(this, SWT.NORMAL);
gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
myCancelUMLPanel.setLayoutData(gd);
myCancelUMLPanel.setLayout(new GridLayout(2, false));
myCancelUMLCheckBox = new Button(myCancelUMLPanel, SWT.CHECK);
gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
myCancelUMLCheckBox.setLayoutData(gd);
myCancelUMLCheckBox.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
setUMLConstraints(myCancelUMLCheckBox.getSelection());
}
});
myCancelUMLLabel = new Label(myCancelUMLPanel, SWT.NORMAL);
gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
myCancelUMLLabel.setLayoutData(gd);
myCancelUMLLabel.setText("Cancel UML limitations");
}
void setCurrentOperatorInfo(InteractionOperatorKind info) {
myCurrentInfo = info;
myCancelUMLCheckBox.setSelection(false);
boolean operatorNameShouldBeSpecified = !operatorHasPredefinedName(info);
myOperatorNameLabel.setVisible(operatorNameShouldBeSpecified);
myOperatorNameText.setVisible(operatorNameShouldBeSpecified);
myOperatorNameText.setText(""); //$NON-NLS-1$
((GridData)myOperatorNameLabel.getLayoutData()).exclude = !myOperatorNameLabel.isVisible();
((GridData)myOperatorNameText.getLayoutData()).exclude = !myOperatorNameText.isVisible();
myArgumentsLabel.setEnabled(hasArguments(info));
myArgumentsText.setEnabled(hasArguments(info));
myArgumentsText.setText(""); //$NON-NLS-1$
myNumberOfOperandsLabel.setEnabled(!hasSingleOperand(info));
myNumberOfOperandsText.setEnabled(!hasSingleOperand(info));
myNumberOfOperandsText.setText(hasSingleOperand(info) ? "1":"2"); //$NON-NLS-1$ //$NON-NLS-2$
myCancelUMLPanel.setVisible(isUMLcompliant(info));
//CR #29549
((GridData)myCancelUMLPanel.getLayoutData()).exclude = !myCancelUMLPanel.getVisible();
this.layout();
}
void setUMLConstraints(boolean cancel) {
if (!cancel) {
myArgumentsText.setText(""); //$NON-NLS-1$
myNumberOfOperandsText.setText(hasSingleOperand(myCurrentInfo) ? "1":"2"); //$NON-NLS-1$ //$NON-NLS-2$
}
myArgumentsLabel.setEnabled(cancel || hasArguments(myCurrentInfo));
myArgumentsText.setEnabled(cancel || hasArguments(myCurrentInfo));
myNumberOfOperandsLabel.setEnabled(cancel || !hasSingleOperand(myCurrentInfo));
myNumberOfOperandsText.setEnabled(cancel || !hasSingleOperand(myCurrentInfo));
}
OperatorProperties getResult() {
int operandsNumber;
try {
operandsNumber = Integer.parseInt(myNumberOfOperandsText.getText());
} catch (NumberFormatException e) {
operandsNumber = hasSingleOperand(myCurrentInfo) ? 1 : 2;
}
OperatorProperties result = new OperatorProperties(myCurrentInfo, myArgumentsText.getText(), operandsNumber);
return result;
}
boolean operatorHasPredefinedName(InteractionOperatorKind info) {
return true;
}
}
}
private static boolean hasSingleOperand(InteractionOperatorKind kind){
switch (kind.getValue()){
case InteractionOperatorKind.SEQ:
case InteractionOperatorKind.ALT:
case InteractionOperatorKind.PAR:
case InteractionOperatorKind.STRICT:
return false;
default:
return true;
}
}
private static boolean hasArguments(InteractionOperatorKind kind){
switch (kind.getValue()){
case InteractionOperatorKind.LOOP:
case InteractionOperatorKind.IGNORE:
case InteractionOperatorKind.CONSIDER:
return true;
default:
return false;
}
}
private static boolean isUMLcompliant(InteractionOperatorKind kind){
return true;
}
}