1 package org.simantics.plant3d.dialog;
3 import java.util.HashSet;
7 import org.eclipse.jface.dialogs.Dialog;
8 import org.eclipse.jface.dialogs.IDialogConstants;
9 import org.eclipse.jface.layout.GridDataFactory;
10 import org.eclipse.jface.layout.GridLayoutFactory;
11 import org.eclipse.jface.resource.JFaceResources;
12 import org.eclipse.jface.resource.LocalResourceManager;
13 import org.eclipse.jface.resource.ResourceManager;
14 import org.eclipse.jface.viewers.ISelectionChangedListener;
15 import org.eclipse.jface.viewers.IStructuredSelection;
16 import org.eclipse.jface.viewers.ListViewer;
17 import org.eclipse.jface.viewers.SelectionChangedEvent;
18 import org.eclipse.jface.viewers.StructuredSelection;
19 import org.eclipse.swt.SWT;
20 import org.eclipse.swt.events.KeyAdapter;
21 import org.eclipse.swt.events.KeyEvent;
22 import org.eclipse.swt.events.SelectionAdapter;
23 import org.eclipse.swt.events.SelectionEvent;
24 import org.eclipse.swt.layout.GridData;
25 import org.eclipse.swt.layout.GridLayout;
26 import org.eclipse.swt.widgets.Button;
27 import org.eclipse.swt.widgets.Composite;
28 import org.eclipse.swt.widgets.Control;
29 import org.eclipse.swt.widgets.ExpandBar;
30 import org.eclipse.swt.widgets.ExpandItem;
31 import org.eclipse.swt.widgets.Label;
32 import org.eclipse.swt.widgets.Shell;
33 import org.eclipse.swt.widgets.Text;
34 import org.simantics.db.exception.DatabaseException;
35 import org.simantics.plant3d.Activator;
36 import org.simantics.plant3d.ontology.Plant3D;
37 import org.simantics.plant3d.scenegraph.EndComponent;
38 import org.simantics.plant3d.scenegraph.InlineComponent;
39 import org.simantics.plant3d.scenegraph.Nozzle;
40 import org.simantics.plant3d.scenegraph.PipelineComponent;
41 import org.simantics.plant3d.scenegraph.TurnComponent;
42 import org.simantics.plant3d.scenegraph.controlpoint.PipeControlPoint.PositionType;
43 import org.simantics.plant3d.utils.Item;
44 import org.simantics.plant3d.utils.Item.Type;
45 import org.simantics.plant3d.utils.P3DUtil;
46 import org.simantics.utils.ui.ExceptionUtils;
48 public class ComponentSelectionDialog extends Dialog implements ISelectionChangedListener{
50 private ResourceManager resourceManager;
52 private String libUri;
54 private Item selected;
55 private Set<PositionType> allowed;
56 private Set<PositionType> filterAllowed;
57 //private boolean positionAdjustment;
58 private PipelineComponent component;
59 private boolean insertAdjustable;
60 private boolean lenghtAdjustable;
61 private PositionType insertPosition = PositionType.NEXT;
64 private Double length;
65 private Double rotationAngle;
68 private Text lengthText;
70 private Text angleText;
71 // Rotated In-line, or turn conponent.
72 private Text rotationAngleText;
74 // Input for new PipeRun
75 private Double diameter;
76 private Double turnRadius;
78 private Text diameterText;
79 private Text turnRadiusText;
82 private Button startButton;
83 private Button middleButton;
84 private Button endButton;
86 private boolean inlineSplit = false;
88 ListViewer inlineViewer;
89 ListViewer turnViewer;
93 public ComponentSelectionDialog(Shell parentShell, Set<PositionType> allowed, PipelineComponent component){
94 this(parentShell, allowed, component, Plant3D.URIs.Builtin);
97 public ComponentSelectionDialog(Shell parentShell, Set<PositionType> allowed, PipelineComponent component, String libUri){
99 this.allowed = allowed;
100 this.component = component;
101 filterAllowed = new HashSet<PositionType>();
102 insertAdjustable = component instanceof InlineComponent ? ((InlineComponent)component).isVariableLength() : false;
103 lenghtAdjustable = false;
104 this.libUri = libUri;
107 protected List<Item> getItems(Class c, String libUri) throws DatabaseException{
108 if (InlineComponent.class.equals(c)) {
109 return P3DUtil.getInlines(libUri);
110 } else if (TurnComponent.class.equals(c)) {
111 return P3DUtil.getTurns(libUri);
112 } else if (EndComponent.class.equals(c)) {
113 return P3DUtil.getEnds(libUri);
120 protected Control createDialogArea(Composite parent) {
121 resourceManager = new LocalResourceManager(JFaceResources.getResources(), parent);
123 Composite composite = new Composite(parent, SWT.NONE);
124 GridLayout layout = new GridLayout(2,false);
125 layout.marginHeight = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN);
126 layout.marginWidth = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN);
127 layout.verticalSpacing = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING);
128 layout.horizontalSpacing = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING);
129 composite.setLayout(layout);
130 composite.setLayoutData(new GridData(GridData.FILL_BOTH));
131 applyDialogFont(composite);
133 // TODO : we need better classification than inline,turn, and end:
134 // * fixed length inlines
135 // * fixed angle turns
136 // * size changes (requires input for pipe run specs)
137 // * variable length inlines (input for length)
138 // * variable angle turns (input for angle)
141 List<Item> ends = null;
142 List<Item> turns = null;
143 List<Item> inlines = null;
145 ends = getItems(EndComponent.class, libUri);
146 turns= getItems(TurnComponent.class, libUri);
147 inlines = getItems(InlineComponent.class, libUri);
148 } catch (DatabaseException e) {
149 Label label = new Label(composite, SWT.NONE);
150 label.setText("Cannot load pipeline components: " + e.getMessage());
151 ExceptionUtils.logError(e);
154 ends = P3DUtil.filterUserComponents(ends);
155 turns = P3DUtil.filterUserComponents(turns);
156 inlines = P3DUtil.filterUserComponents(inlines);
158 ExpandBar expandBar = new ExpandBar(composite, SWT.NONE);
161 ExpandItem inlineItem = new ExpandItem(expandBar, SWT.NONE);
162 inlineItem.setText("Inline");
163 inlineViewer = new ListViewer(expandBar);
164 inlineViewer.setLabelProvider(new ComponentLabelProvider());
165 inlineViewer.setContentProvider(new ComponentContentProvider());
167 ExpandItem turnItem = new ExpandItem(expandBar, SWT.NONE);
168 turnItem.setText("Turn");
169 turnViewer = new ListViewer(expandBar);
170 turnViewer.setLabelProvider(new ComponentLabelProvider());
171 turnViewer.setContentProvider(new ComponentContentProvider());
173 ExpandItem endItem = new ExpandItem(expandBar, SWT.NONE);
174 endItem.setText("End");
175 endViewer = new ListViewer(expandBar);
176 endViewer.setLabelProvider(new ComponentLabelProvider());
177 endViewer.setContentProvider(new ComponentContentProvider());
180 inlineItem.setControl(inlineViewer.getList());
181 turnItem.setControl(turnViewer.getList());
182 endItem.setControl(endViewer.getList());
184 inlineViewer.setInput(inlines);
185 turnViewer.setInput(turns);
186 endViewer.setInput(ends);
188 inlineItem.setHeight(inlineViewer.getList().computeSize(SWT.DEFAULT, SWT.DEFAULT).y);
189 turnItem.setHeight(turnViewer.getList().computeSize(SWT.DEFAULT, SWT.DEFAULT).y);
190 endItem.setHeight(endViewer.getList().computeSize(SWT.DEFAULT, SWT.DEFAULT).y);
192 inlineViewer.addSelectionChangedListener(this);
193 turnViewer.addSelectionChangedListener(this);
194 endViewer.addSelectionChangedListener(this);
196 GridDataFactory.fillDefaults().grab(true, true).align(SWT.FILL, SWT.FILL).span(2, 1).applyTo(expandBar);
197 GridDataFactory.fillDefaults().minSize(500, 500).hint(500, 500).applyTo(composite);
199 Label label = new Label(composite, SWT.NONE);
200 label.setText("Position");
201 Composite buttonComposite = new Composite(composite, SWT.NONE);
202 startButton = new Button(buttonComposite, SWT.TOGGLE);
203 middleButton = new Button(buttonComposite, SWT.TOGGLE);
204 endButton = new Button(buttonComposite, SWT.TOGGLE);
205 startButton.setImage(resourceManager.createImage(Activator.imageDescriptorFromPlugin(Activator.PLUGIN_ID, "icons/insert_start.png")));
206 middleButton.setImage(resourceManager.createImage(Activator.imageDescriptorFromPlugin(Activator.PLUGIN_ID, "icons/insert_middle.png")));
207 endButton.setImage(resourceManager.createImage(Activator.imageDescriptorFromPlugin(Activator.PLUGIN_ID, "icons/insert_end.png")));
208 startButton.setToolTipText("Overlapping insert");
209 middleButton.setToolTipText("Cutting insert");
210 endButton.setToolTipText("Adding insert");
211 GridDataFactory.fillDefaults().grab(true, false).align(SWT.FILL, SWT.TOP).applyTo(buttonComposite);
212 GridLayoutFactory.fillDefaults().numColumns(3).applyTo(buttonComposite);
214 startButton.setEnabled(false);
215 middleButton.setEnabled(false);
216 endButton.setEnabled(false);
218 startButton.addSelectionListener(new SelectionAdapter() {
220 public void widgetSelected(SelectionEvent e) {
221 updateInsertPosition(PositionType.PREVIOUS);
225 middleButton.addSelectionListener(new SelectionAdapter() {
227 public void widgetSelected(SelectionEvent e) {
228 updateInsertPosition(PositionType.SPLIT);
231 endButton.addSelectionListener(new SelectionAdapter() {
233 public void widgetSelected(SelectionEvent e) {
234 updateInsertPosition(PositionType.NEXT);
237 endButton.setSelection(true);
239 label = new Label(composite, SWT.NONE);
240 label.setText("Length");
241 lengthText = new Text(composite, SWT.SINGLE|SWT.BORDER);
242 label = new Label(composite, SWT.NONE);
243 label.setText("Angle");
244 angleText = new Text(composite, SWT.SINGLE|SWT.BORDER);
245 label = new Label(composite, SWT.NONE);
246 label.setText("Rotation angle");
247 rotationAngleText = new Text(composite, SWT.SINGLE|SWT.BORDER);
249 label = new Label(composite, SWT.NONE);
250 label.setText("Diameter");
251 diameterText = new Text(composite, SWT.SINGLE|SWT.BORDER);
252 label = new Label(composite, SWT.NONE);
253 label.setText("Turn Radius");
254 turnRadiusText = new Text(composite, SWT.SINGLE|SWT.BORDER);
256 lengthText.setEnabled(false);
257 angleText.setEnabled(false);
258 rotationAngleText.setEnabled(false);
259 turnRadiusText.setEnabled(false);
260 diameterText.setEnabled(false);
263 lengthText.addKeyListener(new KeyAdapter() {
265 public void keyReleased(KeyEvent e) {
267 length = Double.parseDouble(lengthText.getText());
268 } catch (NumberFormatException err) {
275 angleText.addKeyListener(new KeyAdapter() {
277 public void keyReleased(KeyEvent e) {
279 angle = Double.parseDouble(angleText.getText());
280 } catch (NumberFormatException err) {
287 rotationAngleText.addKeyListener(new KeyAdapter() {
289 public void keyReleased(KeyEvent e) {
291 rotationAngle = Double.parseDouble(rotationAngleText.getText());
292 } catch (NumberFormatException err) {
293 rotationAngle = null;
299 diameterText.addKeyListener(new KeyAdapter() {
301 public void keyReleased(KeyEvent e) {
303 diameter = Double.parseDouble(diameterText.getText());
304 } catch (NumberFormatException err) {
311 turnRadiusText.addKeyListener(new KeyAdapter() {
313 public void keyReleased(KeyEvent e) {
315 turnRadius = Double.parseDouble(turnRadiusText.getText());
316 } catch (NumberFormatException err) {
323 GridDataFactory.fillDefaults().grab(true, false).align(SWT.FILL, SWT.TOP).applyTo(lengthText);
324 GridDataFactory.fillDefaults().grab(true, false).align(SWT.FILL, SWT.TOP).applyTo(angleText);
325 GridDataFactory.fillDefaults().grab(true, false).align(SWT.FILL, SWT.TOP).applyTo(rotationAngleText);
326 GridDataFactory.fillDefaults().grab(true, false).align(SWT.FILL, SWT.TOP).applyTo(diameterText);
327 GridDataFactory.fillDefaults().grab(true, false).align(SWT.FILL, SWT.TOP).applyTo(turnRadiusText);
329 if (!allowed.contains(PositionType.NEXT) && !allowed.contains(PositionType.PREVIOUS)) {
330 turnViewer.getList().setEnabled(false);
331 endViewer.getList().setEnabled(false);
339 private void updateInsertPosition(PositionType type) {
340 if (insertPosition == type)
342 endButton.setSelection(type == PositionType.NEXT);
343 middleButton.setSelection(type == PositionType.SPLIT);
344 startButton.setSelection(type == PositionType.PREVIOUS);
345 insertPosition = type;
349 public void selectionChanged(SelectionChangedEvent event) {
350 IStructuredSelection sel = (IStructuredSelection)event.getSelection();
351 Item i = (Item)sel.getFirstElement();
354 if (event.getSource() == inlineViewer) {
355 turnViewer.setSelection(new StructuredSelection());
356 endViewer.setSelection(new StructuredSelection());
357 } else if (event.getSource() == turnViewer) {
358 inlineViewer.setSelection(new StructuredSelection());
359 endViewer.setSelection(new StructuredSelection());
360 } else if (event.getSource() == endViewer) {
361 inlineViewer.setSelection(new StructuredSelection());
362 turnViewer.setSelection(new StructuredSelection());
368 private void validate() {
369 filterAllowed.clear();
370 Set<PositionType> filterAllowed = new HashSet<PositionType>();
372 if (selected == null) {
374 } else if (selected.isCode()) {// TODO : instead of disabling the button, we should filter the content.
377 lenghtAdjustable = ((selected.getType() == Type.INLINE) && (selected.isVariable() || selected.isModifiable()));
378 if (insertAdjustable) {
379 switch (selected.getType()) {
381 startButton.setEnabled(false);
382 middleButton.setEnabled(false);
383 endButton.setEnabled(true);
384 updateInsertPosition(PositionType.NEXT);
387 if (!selected.isVariable()) {
388 startButton.setEnabled(true);
389 middleButton.setEnabled(true);
390 endButton.setEnabled(true);
392 startButton.setEnabled(false);
393 middleButton.setEnabled(false);
394 endButton.setEnabled(true);
395 updateInsertPosition(PositionType.NEXT);
399 startButton.setEnabled(false);
400 middleButton.setEnabled(false);
401 endButton.setEnabled(true);
402 updateInsertPosition(PositionType.NEXT);
405 startButton.setEnabled(false);
406 middleButton.setEnabled(true);
407 endButton.setEnabled(true);
408 if (insertPosition == PositionType.PREVIOUS)
409 updateInsertPosition(PositionType.NEXT);
412 throw new RuntimeException("Expected component, got equipment " + selected);
414 } else if (lenghtAdjustable) {
415 if (component instanceof InlineComponent) {
416 startButton.setEnabled(true);
417 middleButton.setEnabled(true);
418 endButton.setEnabled(true);
419 } else if (component instanceof TurnComponent) {
420 startButton.setEnabled(false);
421 middleButton.setEnabled(true);
422 endButton.setEnabled(true);
423 if (insertPosition == PositionType.PREVIOUS)
424 updateInsertPosition(PositionType.NEXT);
425 } else if (component instanceof EndComponent || component instanceof Nozzle) {
426 startButton.setEnabled(false);
427 middleButton.setEnabled(false);
428 endButton.setEnabled(true);
429 updateInsertPosition(PositionType.NEXT);
432 startButton.setEnabled(false);
433 middleButton.setEnabled(false);
434 endButton.setEnabled(true);
436 if (selected.isVariable() || selected.isModifiable()) {
437 if (selected.getType() == Type.INLINE) {
438 filterAllowed.add(PositionType.NEXT);
439 filterAllowed.add(PositionType.PREVIOUS);
441 lengthText.setEnabled(false);
442 angleText.setEnabled(false);
443 rotationAngleText.setEnabled(selected.isRotated());
447 lengthText.setEnabled(true);
448 angleText.setEnabled(false);
449 rotationAngleText.setEnabled(selected.isRotated());
453 } else if (selected.getType() == Type.TURN) {
454 filterAllowed.add(PositionType.NEXT);
455 filterAllowed.add(PositionType.PREVIOUS);
456 lengthText.setEnabled(false);
457 angleText.setEnabled(true);
458 rotationAngleText.setEnabled(true);
462 // this should not happen, since end components should not have variable, or modifiable flag.
463 lengthText.setEnabled(false);
464 angleText.setEnabled(false);
465 rotationAngleText.setEnabled(false);
469 lengthText.setEnabled(false);
470 angleText.setEnabled(false);
471 rotationAngleText.setEnabled(selected.getType() == Type.TURN || selected.isRotated());
474 if (selected.isSizeChange()) {
475 filterAllowed.add(PositionType.NEXT);
476 filterAllowed.add(PositionType.PREVIOUS);
478 turnRadiusText.setEnabled(false);
479 diameterText.setEnabled(false);
482 turnRadiusText.setEnabled(true);
483 diameterText.setEnabled(true);
484 if (diameter == null || turnRadius == null)
489 turnRadiusText.setEnabled(false);
490 diameterText.setEnabled(false);
493 if (!selected.isSizeChange() && !selected.isVariable()) {
494 switch (selected.getType()) {
496 filterAllowed.add(PositionType.NEXT);
497 filterAllowed.add(PositionType.PREVIOUS);
503 filterAllowed.add(PositionType.NEXT);
504 filterAllowed.add(PositionType.PREVIOUS);
505 filterAllowed.add(PositionType.SPLIT);
507 filterAllowed.add(PositionType.NEXT);
508 filterAllowed.add(PositionType.PREVIOUS);
512 for (PositionType t : filterAllowed) {
513 if (allowed.contains(t))
514 this.filterAllowed.add(t);
517 getButton(OK).setEnabled(ok);
520 public Item getSelected() {
524 public Double getAngle() {
528 public Double getLength() {
532 public Double getRotationAngle() {
533 return rotationAngle;
536 public Double getDiameter() {
540 public Double getTurnRadius() {
544 public Set<PositionType> filterAllowed() {
545 return filterAllowed;
548 public PositionType getInsertPosition() {
549 return insertPosition;
552 public boolean isInsertAdjustable() {
553 return insertAdjustable;
556 public boolean isLenghtAdjustable() {
557 return lenghtAdjustable;