package org.simantics.plant3d.dialog; import java.util.HashSet; import java.util.List; import java.util.Set; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.layout.GridDataFactory; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.ListViewer; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.swt.SWT; import org.eclipse.swt.events.KeyAdapter; import org.eclipse.swt.events.KeyEvent; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.ExpandBar; import org.eclipse.swt.widgets.ExpandItem; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; import org.simantics.db.exception.DatabaseException; import org.simantics.plant3d.scenegraph.controlpoint.PipeControlPoint.PositionType; import org.simantics.plant3d.utils.Item; import org.simantics.plant3d.utils.Item.Type; import org.simantics.plant3d.utils.P3DUtil; import org.simantics.utils.ui.ExceptionUtils; public class ComponentSelectionDialog extends Dialog implements ISelectionChangedListener{ private Item selected; private Set allowed; private Set filterAllowed; private Double angle; private Double length; private Text lengthText; private Text angleText; private Double diameter; private Double turnRadius; private Text diameterText; private Text turnRadiusText; private boolean inlineSplit = false; public ComponentSelectionDialog(Shell parentShell, Set allowed) { super(parentShell); this.allowed = allowed; filterAllowed = new HashSet(); } @Override protected Control createDialogArea(Composite parent) { Composite composite = new Composite(parent, SWT.NONE); GridLayout layout = new GridLayout(2,false); layout.marginHeight = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN); layout.marginWidth = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN); layout.verticalSpacing = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING); layout.horizontalSpacing = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING); composite.setLayout(layout); composite.setLayoutData(new GridData(GridData.FILL_BOTH)); applyDialogFont(composite); // TODO : we need better classification than inline,turn, and end: // * fixed length inlines // * fixed angle turns // * size changes (requires input for pipe run specs) // * variable length inlines (input for length) // * variable angle turns (input for angle) // * ends List ends = null; List turns = null; List inlines = null; try { ends = P3DUtil.getEnds(); turns= P3DUtil.getTurns(); inlines = P3DUtil.getInlines(); } catch (DatabaseException e) { Label label = new Label(composite, SWT.NONE); label.setText("Cannot load pipeline components: " + e.getMessage()); ExceptionUtils.logError(e); return composite; } ExpandBar expandBar = new ExpandBar(composite, SWT.NONE); ExpandItem inlineItem = new ExpandItem(expandBar, SWT.NONE); inlineItem.setText("Inline"); ListViewer inlineViewer = new ListViewer(expandBar); inlineViewer.setLabelProvider(new ComponentLabelProvider()); inlineViewer.setContentProvider(new ComponentContentProvider()); ExpandItem turnItem = new ExpandItem(expandBar, SWT.NONE); turnItem.setText("Turn"); ListViewer turnViewer = new ListViewer(expandBar); turnViewer.setLabelProvider(new ComponentLabelProvider()); turnViewer.setContentProvider(new ComponentContentProvider()); ExpandItem endItem = new ExpandItem(expandBar, SWT.NONE); endItem.setText("End"); ListViewer endViewer = new ListViewer(expandBar); endViewer.setLabelProvider(new ComponentLabelProvider()); endViewer.setContentProvider(new ComponentContentProvider()); inlineItem.setControl(inlineViewer.getList()); turnItem.setControl(turnViewer.getList()); endItem.setControl(endViewer.getList()); inlineViewer.setInput(inlines); turnViewer.setInput(turns); endViewer.setInput(ends); inlineItem.setHeight(inlineViewer.getList().computeSize(SWT.DEFAULT, SWT.DEFAULT).y); turnItem.setHeight(turnViewer.getList().computeSize(SWT.DEFAULT, SWT.DEFAULT).y); endItem.setHeight(endViewer.getList().computeSize(SWT.DEFAULT, SWT.DEFAULT).y); inlineViewer.addSelectionChangedListener(this); turnViewer.addSelectionChangedListener(this); endViewer.addSelectionChangedListener(this); GridDataFactory.fillDefaults().grab(true, true).align(SWT.FILL, SWT.FILL).span(2, 1).applyTo(expandBar); GridDataFactory.fillDefaults().minSize(500, 500).hint(500, 500).applyTo(composite); Label label = new Label(composite, SWT.NONE); label.setText("Length"); lengthText = new Text(composite, SWT.SINGLE|SWT.BORDER); label = new Label(composite, SWT.NONE); label.setText("Angle"); angleText = new Text(composite, SWT.SINGLE|SWT.BORDER); label = new Label(composite, SWT.NONE); label.setText("Diameter"); diameterText = new Text(composite, SWT.SINGLE|SWT.BORDER); label = new Label(composite, SWT.NONE); label.setText("Turn Radius"); turnRadiusText = new Text(composite, SWT.SINGLE|SWT.BORDER); lengthText.setEnabled(false); angleText.setEnabled(false); turnRadiusText.setEnabled(false); diameterText.setEnabled(false); lengthText.addKeyListener(new KeyAdapter() { @Override public void keyReleased(KeyEvent e) { try { length = Double.parseDouble(lengthText.getText()); } catch (NumberFormatException err) { length = null; } validate(); } }); angleText.addKeyListener(new KeyAdapter() { @Override public void keyReleased(KeyEvent e) { try { angle = Double.parseDouble(angleText.getText()); } catch (NumberFormatException err) { angle = null; } validate(); } }); diameterText.addKeyListener(new KeyAdapter() { @Override public void keyReleased(KeyEvent e) { try { diameter = Double.parseDouble(diameterText.getText()); } catch (NumberFormatException err) { diameter = null; } validate(); } }); turnRadiusText.addKeyListener(new KeyAdapter() { @Override public void keyReleased(KeyEvent e) { try { turnRadius = Double.parseDouble(turnRadiusText.getText()); } catch (NumberFormatException err) { turnRadius = null; } validate(); } }); GridDataFactory.fillDefaults().grab(true, false).align(SWT.FILL, SWT.TOP).applyTo(lengthText); GridDataFactory.fillDefaults().grab(true, false).align(SWT.FILL, SWT.TOP).applyTo(angleText); GridDataFactory.fillDefaults().grab(true, false).align(SWT.FILL, SWT.TOP).applyTo(diameterText); GridDataFactory.fillDefaults().grab(true, false).align(SWT.FILL, SWT.TOP).applyTo(turnRadiusText); if (!allowed.contains(PositionType.NEXT) && !allowed.contains(PositionType.PREVIOUS)) { turnViewer.getList().setEnabled(false); endViewer.getList().setEnabled(false); inlineSplit = true; } return composite; } @Override public void selectionChanged(SelectionChangedEvent event) { IStructuredSelection sel = (IStructuredSelection)event.getSelection(); selected = (Item)sel.getFirstElement(); validate(); } private void validate() { filterAllowed.clear(); Set filterAllowed = new HashSet(); boolean ok = true; if (selected.isCode())// TODO : instead of disabling the button, we should filter the content. ok = false; if (selected.isVariable()) { if (selected.getType() == Type.INLINE) { filterAllowed.add(PositionType.NEXT); filterAllowed.add(PositionType.PREVIOUS); if (inlineSplit) { lengthText.setEnabled(false); angleText.setEnabled(false); ok = false; } else { lengthText.setEnabled(true); angleText.setEnabled(false); if (length == null) ok = false; } } else if (selected.getType() == Type.TURN) { filterAllowed.add(PositionType.NEXT); filterAllowed.add(PositionType.PREVIOUS); lengthText.setEnabled(false); angleText.setEnabled(true); if (angle == null) ok = false; } else { // this should not happen lengthText.setEnabled(false); angleText.setEnabled(false); } } else { lengthText.setEnabled(false); angleText.setEnabled(false); } if (selected.isSizeChange()) { filterAllowed.add(PositionType.NEXT); filterAllowed.add(PositionType.PREVIOUS); if (inlineSplit) { turnRadiusText.setEnabled(false); diameterText.setEnabled(false); ok = false; } else { turnRadiusText.setEnabled(true); diameterText.setEnabled(true); if (diameter == null || turnRadius == null) ok = false; } } else { turnRadiusText.setEnabled(false); diameterText.setEnabled(false); } if (!selected.isSizeChange() && !selected.isVariable()) { switch (selected.getType()) { case END: filterAllowed.add(PositionType.NEXT); filterAllowed.add(PositionType.PREVIOUS); break; case NOZZLE: case EQUIPMENT: break; case INLINE: filterAllowed.add(PositionType.NEXT); filterAllowed.add(PositionType.PREVIOUS); filterAllowed.add(PositionType.SPLIT); case TURN: filterAllowed.add(PositionType.NEXT); filterAllowed.add(PositionType.PREVIOUS); } } for (PositionType t : filterAllowed) { if (allowed.contains(t)) this.filterAllowed.add(t); } getButton(OK).setEnabled(ok); } public Item getSelected() { return selected; } public Double getAngle() { return angle; } public Double getLength() { return length; } public Double getDiameter() { return diameter; } public Double getTurnRadius() { return turnRadius; } public Set filterAllowed() { return filterAllowed; } }