package org.simantics.processeditor.handlers; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.eclipse.core.commands.AbstractHandler; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ExecutionException; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; 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.layout.GridData; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.handlers.HandlerUtil; import org.simantics.db.Graph; import org.simantics.db.GraphRequestAdapter; import org.simantics.db.GraphRequestStatus; import org.simantics.db.Resource; import org.simantics.layer0.stubs.Library; import org.simantics.layer0.utils.EntityFactory; import org.simantics.layer0.utils.IEntity; import org.simantics.layer0.utils.instantiation.InstanceFactory; import org.simantics.processeditor.ProcessResource; import org.simantics.proconf.ui.ProConfUI; import org.simantics.proconf.ui.utils.ResourceAdaptionUtils; /** * Handler that creates new pipeline components. * * @author Marko Luukkainen * */ public class NewComponentHandler extends AbstractHandler { private Map nameMap; @Override public Object execute(ExecutionEvent event) throws ExecutionException { ISelection s = HandlerUtil.getCurrentSelectionChecked(event); IStructuredSelection ss = (IStructuredSelection) s; if (ss.size() != 1) return null; final Resource lib = ResourceAdaptionUtils.toSingleResource(ss); if (nameMap == null) { ProConfUI.getSession().syncRead(new GraphRequestAdapter(){ @Override public GraphRequestStatus perform(Graph g) throws Exception { nameMap = new HashMap(); for (Resource r : getComponentTypes()) { IEntity e = EntityFactory.create(g,r); nameMap.put(r, e.getName()); for (Resource r2 : getComponentOptions(r)) { IEntity e2 = EntityFactory.create(g,r2); nameMap.put(r2, e2.getName()); } } return GraphRequestStatus.transactionComplete(); } }); } ComponentTypeDialog dialog = new ComponentTypeDialog(Display.getDefault().getActiveShell()); if (dialog.open() == ComponentTypeDialog.CANCEL) return null; final List types = dialog.getSelection(); final String name = dialog.getName(); if (types.size() == 0 || name == null || name.length() == 0) return null; ProConfUI.getSession().asyncWrite(new GraphRequestAdapter() { @Override public GraphRequestStatus perform(Graph g) throws Exception { // instantiate component IEntity instance = EntityFactory.create(g, InstanceFactory.instantiate(g, types)); Library l = new Library(g, lib); l.addStatement(g.getBuiltins().ConsistsOf, instance); instance.setName(name); // TODO : is this correct (instance & inherits) for (Resource type : types) { instance.addStatement(ProcessResource.builtins.Inherits, type); } // instantiate control point(s) List cpTypes = getControlPointTypes(types); boolean isDual = (cpTypes.contains(ProcessResource.plant3Dresource.SizeChangeControlPoint) || cpTypes.contains(ProcessResource.plant3Dresource.OffsettingPoint)); IEntity cp = EntityFactory.create(g, InstanceFactory.instantiate(g, cpTypes)); instance.addStatement(ProcessResource.plant3Dresource.HasControlPoint, cp); if (isDual) { IEntity subCP = EntityFactory.create(g, InstanceFactory.instantiate(g, ProcessResource.plant3Dresource.DualSubControlPoint)); cp.addStatement(ProcessResource.plant3Dresource.HasSubPoint, subCP); } // instantiate model Resource modelType = g.getResourceByURI("http://www.vtt.fi/Simantics/CSG/1.0/Types#CSGModel"); IEntity model = EntityFactory.create(g, InstanceFactory.instantiate(g, modelType)); instance.addStatement(ProcessResource.plant3Dresource.HasGraphics, model); return GraphRequestStatus.transactionComplete(); } }); return null; } /** * Returns all possible types for a pipeline component * @return */ private List getComponentTypes() { List list = new ArrayList(); list.add(ProcessResource.plant3Dresource.FixedLengthInlineComponent); list.add(ProcessResource.plant3Dresource.VariableLengthInlineComponent); list.add(ProcessResource.plant3Dresource.VariableAngleTurnComponent); list.add(ProcessResource.plant3Dresource.FixedAngleTurnComponent); list.add(ProcessResource.plant3Dresource.EndComponent); list.add(ProcessResource.plant3Dresource.Nozzle); return list; } /** * Returns optional types for a component type * @param type * @return */ private List getComponentOptions(Resource type) { List list = new ArrayList(); if (type.equals(ProcessResource.plant3Dresource.FixedLengthInlineComponent)) { list.add(ProcessResource.plant3Dresource.SizeChangeComponent); list.add(ProcessResource.plant3Dresource.OffsetComponent); } return list; } /** * Returns control point type(s) for given control point type. * * @param types * @return */ private List getControlPointTypes(List types) { Resource primaryType = types.get(0); List cpTypes = new ArrayList(); if (primaryType == ProcessResource.plant3Dresource.FixedLengthInlineComponent) { if (types.size() == 1) { cpTypes.add(ProcessResource.plant3Dresource.FixedLengthControlPoint); } else { if (types.contains(ProcessResource.plant3Dresource.SizeChangeComponent)) { cpTypes.add(ProcessResource.plant3Dresource.SizeChangeControlPoint); } if (types.contains(ProcessResource.plant3Dresource.OffsetComponent)) { cpTypes.add(ProcessResource.plant3Dresource.OffsettingPoint); } if (cpTypes.size() == 0) { throw new RuntimeException("Cannot find control point type for " + primaryType); } } } else if (primaryType == ProcessResource.plant3Dresource.VariableLengthInlineComponent) { cpTypes.add(ProcessResource.plant3Dresource.VariableLengthControlPoint); } else if (primaryType == ProcessResource.plant3Dresource.FixedAngleTurnComponent) { cpTypes.add(ProcessResource.plant3Dresource.FixedAngleTurnControlPoint); } else if (primaryType == ProcessResource.plant3Dresource.VariableAngleTurnComponent) { cpTypes.add(ProcessResource.plant3Dresource.VariableAngleTurnControlPoint); } else if (primaryType == ProcessResource.plant3Dresource.EndComponent) { cpTypes.add(ProcessResource.plant3Dresource.EndComponentControlPoint); } else if (primaryType == ProcessResource.plant3Dresource.Nozzle) { cpTypes.add(ProcessResource.plant3Dresource.NozzleControlPoint); } else { throw new RuntimeException("Cannot find control point type for " + primaryType); } return cpTypes; } private class ComponentTypeDialog extends Dialog { List selected = new ArrayList(); String name; public ComponentTypeDialog(Shell shell) { super(shell); } @Override protected Control createDialogArea(Composite parent) { Composite composite = (Composite) super.createDialogArea(parent); Label label = new Label(composite,SWT.NONE); label.setText("Name:"); Text text = new Text(composite,SWT.SINGLE|SWT.BORDER); text.addModifyListener(new ModifyListener() { @Override public void modifyText(ModifyEvent e) { name = ((Text)e.widget).getText(); } }); GridData data = new GridData(); data.grabExcessHorizontalSpace = true; data.horizontalAlignment = SWT.FILL; text.setLayoutData(data); label = new Label(composite,SWT.NONE); label.setText("Type:"); for (Resource r : getComponentTypes()) { final Button b = new Button(composite,SWT.RADIO); b.setText(nameMap.get(r)); b.setData(r); b.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { Button button = (Button)e.widget; Resource res = (Resource)button.getData(); if (button.getSelection()) { selected.add(0,res); } else { selected.remove(res); } } }); data = new GridData(); b.setLayoutData(data); for (Resource r2 : getComponentOptions(r)) { final Button b2 = new Button(composite,SWT.CHECK); b2.setText(nameMap.get(r2)); b2.setData(r2); b.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { b2.setEnabled(b.getSelection()); Resource res = (Resource)b2.getData(); if (!b.getSelection()) { selected.remove(res); } else if (b2.getSelection()) { selected.add(res); } } }); b2.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { Button button = (Button)e.widget; Resource res = (Resource)button.getData(); if (button.getSelection()) { selected.add(res); } else { selected.remove(res); } } }); b2.setEnabled(false); data = new GridData(); data.horizontalIndent = convertWidthInCharsToPixels(2); b2.setLayoutData(data); } } return composite; } List getSelection() { return selected; } public String getName() { return name; } } }