1 package org.simantics.plant3d.dialog;
3 import java.util.Collection;
4 import java.util.HashSet;
8 import org.eclipse.jface.dialogs.Dialog;
9 import org.eclipse.jface.dialogs.IDialogConstants;
10 import org.eclipse.jface.layout.GridDataFactory;
11 import org.eclipse.jface.layout.GridLayoutFactory;
12 import org.eclipse.jface.resource.JFaceResources;
13 import org.eclipse.jface.resource.LocalResourceManager;
14 import org.eclipse.jface.resource.ResourceLocator;
15 import org.eclipse.jface.resource.ResourceManager;
16 import org.eclipse.jface.viewers.ISelectionChangedListener;
17 import org.eclipse.jface.viewers.IStructuredSelection;
18 import org.eclipse.jface.viewers.ListViewer;
19 import org.eclipse.jface.viewers.SelectionChangedEvent;
20 import org.eclipse.jface.viewers.StructuredSelection;
21 import org.eclipse.swt.SWT;
22 import org.eclipse.swt.events.KeyAdapter;
23 import org.eclipse.swt.events.KeyEvent;
24 import org.eclipse.swt.events.SelectionAdapter;
25 import org.eclipse.swt.events.SelectionEvent;
26 import org.eclipse.swt.layout.GridData;
27 import org.eclipse.swt.layout.GridLayout;
28 import org.eclipse.swt.widgets.Button;
29 import org.eclipse.swt.widgets.Composite;
30 import org.eclipse.swt.widgets.Control;
31 import org.eclipse.swt.widgets.ExpandBar;
32 import org.eclipse.swt.widgets.ExpandItem;
33 import org.eclipse.swt.widgets.Label;
34 import org.eclipse.swt.widgets.Shell;
35 import org.eclipse.swt.widgets.Text;
36 import org.simantics.db.exception.DatabaseException;
37 import org.simantics.plant3d.Activator;
38 import org.simantics.plant3d.ontology.Plant3D;
39 import org.simantics.plant3d.scenegraph.EndComponent;
40 import org.simantics.plant3d.scenegraph.InlineComponent;
41 import org.simantics.plant3d.scenegraph.Nozzle;
42 import org.simantics.plant3d.scenegraph.PipelineComponent;
43 import org.simantics.plant3d.scenegraph.TurnComponent;
44 import org.simantics.plant3d.scenegraph.controlpoint.PipeControlPoint.PositionType;
45 import org.simantics.plant3d.utils.Item;
46 import org.simantics.plant3d.utils.Item.Type;
47 import org.simantics.plant3d.utils.P3DUtil;
48 import org.simantics.utils.ui.ExceptionUtils;
50 public class ComponentSelectionDialog extends Dialog implements ISelectionChangedListener {
52 private ResourceManager resourceManager;
54 private String libUri;
56 private Item selected;
57 private Set<PositionType> allowed;
58 private Set<PositionType> filterAllowed;
59 // private boolean positionAdjustment;
60 private PipelineComponent component;
61 private boolean insertAdjustable;
62 private boolean lenghtAdjustable;
63 private PositionType insertPosition = PositionType.NEXT;
66 private Double length;
67 private Double rotationAngle;
71 private Text nameText;
74 private Text lengthText;
76 private Text angleText;
77 // Rotated In-line, or turn conponent.
78 private Text rotationAngleText;
80 // Input for new PipeRun
81 private Double diameter;
82 private Double turnRadius;
84 private Text diameterText;
85 private Text turnRadiusText;
88 private Button startButton;
89 private Button middleButton;
90 private Button endButton;
92 private boolean inlineSplit = false;
94 ListViewer inlineViewer;
95 ListViewer turnViewer;
98 private Set<String> usedNames;
100 public ComponentSelectionDialog(Shell parentShell, Set<PositionType> allowed, PipelineComponent component) {
101 this(parentShell, allowed, component, Plant3D.URIs.Builtin);
104 public ComponentSelectionDialog(Shell parentShell, Set<PositionType> allowed, PipelineComponent component,
107 this.allowed = allowed;
108 this.component = component;
109 filterAllowed = new HashSet<PositionType>();
110 insertAdjustable = component instanceof InlineComponent ? ((InlineComponent) component).isVariableLength()
112 lenghtAdjustable = false;
113 this.libUri = libUri;
115 usedNames = new HashSet<>();
119 protected void configureShell(Shell newShell) {
120 super.configureShell(newShell);
121 newShell.setText("Create pipeline component");
124 public void addUsedNames(Collection<String> names) {
125 usedNames.addAll(names);
128 protected List<Item> getItems(Class<?> c, String libUri) throws DatabaseException {
129 if (InlineComponent.class.equals(c)) {
130 return P3DUtil.getInlines(libUri);
131 } else if (TurnComponent.class.equals(c)) {
132 return P3DUtil.getTurns(libUri);
133 } else if (EndComponent.class.equals(c)) {
134 return P3DUtil.getEnds(libUri);
141 protected Control createDialogArea(Composite parent) {
142 resourceManager = new LocalResourceManager(JFaceResources.getResources(), parent);
144 Composite composite = new Composite(parent, SWT.NONE);
145 GridLayout layout = new GridLayout(2, false);
146 layout.marginHeight = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN);
147 layout.marginWidth = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN);
148 layout.verticalSpacing = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING);
149 layout.horizontalSpacing = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING);
150 composite.setLayout(layout);
151 composite.setLayoutData(new GridData(GridData.FILL_BOTH));
152 applyDialogFont(composite);
154 // Grid layout data for fields that grab horizontal space
155 final GridDataFactory horizFillData = GridDataFactory.fillDefaults().grab(true, false).align(SWT.FILL, SWT.TOP);
157 // TODO : we need better classification than inline,turn, and end:
158 // * fixed length inlines
159 // * fixed angle turns
160 // * size changes (requires input for pipe run specs)
161 // * variable length inlines (input for length)
162 // * variable angle turns (input for angle)
165 List<Item> ends = null;
166 List<Item> turns = null;
167 List<Item> inlines = null;
169 ends = getItems(EndComponent.class, libUri);
170 turns = getItems(TurnComponent.class, libUri);
171 inlines = getItems(InlineComponent.class, libUri);
172 } catch (DatabaseException e) {
173 Label label = new Label(composite, SWT.NONE);
174 label.setText("Cannot load pipeline components: " + e.getMessage());
175 ExceptionUtils.logError(e);
178 ends = P3DUtil.filterUserComponents(ends);
179 turns = P3DUtil.filterUserComponents(turns);
180 inlines = P3DUtil.filterUserComponents(inlines);
182 ExpandBar expandBar = new ExpandBar(composite, SWT.NONE);
184 ExpandItem inlineItem = new ExpandItem(expandBar, SWT.NONE);
185 inlineItem.setText("Inline");
186 inlineViewer = new ListViewer(expandBar);
187 inlineViewer.setLabelProvider(new ComponentLabelProvider());
188 inlineViewer.setContentProvider(new ComponentContentProvider());
190 ExpandItem turnItem = new ExpandItem(expandBar, SWT.NONE);
191 turnItem.setText("Turn");
192 turnViewer = new ListViewer(expandBar);
193 turnViewer.setLabelProvider(new ComponentLabelProvider());
194 turnViewer.setContentProvider(new ComponentContentProvider());
196 ExpandItem endItem = new ExpandItem(expandBar, SWT.NONE);
197 endItem.setText("End");
198 endViewer = new ListViewer(expandBar);
199 endViewer.setLabelProvider(new ComponentLabelProvider());
200 endViewer.setContentProvider(new ComponentContentProvider());
202 inlineItem.setControl(inlineViewer.getList());
203 turnItem.setControl(turnViewer.getList());
204 endItem.setControl(endViewer.getList());
206 inlineViewer.setInput(inlines);
207 turnViewer.setInput(turns);
208 endViewer.setInput(ends);
210 inlineItem.setHeight(inlineViewer.getList().computeSize(SWT.DEFAULT, SWT.DEFAULT).y);
211 turnItem.setHeight(turnViewer.getList().computeSize(SWT.DEFAULT, SWT.DEFAULT).y);
212 endItem.setHeight(endViewer.getList().computeSize(SWT.DEFAULT, SWT.DEFAULT).y);
214 inlineViewer.addSelectionChangedListener(this);
215 turnViewer.addSelectionChangedListener(this);
216 endViewer.addSelectionChangedListener(this);
218 GridDataFactory.fillDefaults().grab(true, true).align(SWT.FILL, SWT.FILL).span(2, 1).applyTo(expandBar);
219 GridDataFactory.fillDefaults().minSize(500, 500).hint(500, 500).applyTo(composite);
221 Label label = new Label(composite, SWT.NONE);
222 label.setText("Position");
223 Composite buttonComposite = new Composite(composite, SWT.NONE);
224 startButton = new Button(buttonComposite, SWT.TOGGLE);
225 middleButton = new Button(buttonComposite, SWT.TOGGLE);
226 endButton = new Button(buttonComposite, SWT.TOGGLE);
227 startButton.setImage(resourceManager.createImage(
228 ResourceLocator.imageDescriptorFromBundle(Activator.PLUGIN_ID, "icons/insert_start.png").get()));
229 middleButton.setImage(resourceManager.createImage(
230 ResourceLocator.imageDescriptorFromBundle(Activator.PLUGIN_ID, "icons/insert_middle.png").get()));
231 endButton.setImage(resourceManager.createImage(
232 ResourceLocator.imageDescriptorFromBundle(Activator.PLUGIN_ID, "icons/insert_end.png").get()));
233 startButton.setToolTipText("Overlapping insert");
234 middleButton.setToolTipText("Cutting insert");
235 endButton.setToolTipText("Adding insert");
236 horizFillData.applyTo(buttonComposite);
237 GridLayoutFactory.fillDefaults().numColumns(3).applyTo(buttonComposite);
239 startButton.setEnabled(false);
240 middleButton.setEnabled(false);
241 endButton.setEnabled(false);
243 startButton.addSelectionListener(new SelectionAdapter() {
245 public void widgetSelected(SelectionEvent e) {
246 updateInsertPosition(PositionType.PREVIOUS);
250 middleButton.addSelectionListener(new SelectionAdapter() {
252 public void widgetSelected(SelectionEvent e) {
253 updateInsertPosition(PositionType.SPLIT);
256 endButton.addSelectionListener(new SelectionAdapter() {
258 public void widgetSelected(SelectionEvent e) {
259 updateInsertPosition(PositionType.NEXT);
262 endButton.setSelection(true);
264 label = new Label(composite, SWT.NONE);
265 label.setText("Name");
266 nameText = new Text(composite, SWT.SINGLE | SWT.BORDER);
268 label = new Label(composite, SWT.NONE);
269 label.setText("Length");
270 lengthText = new Text(composite, SWT.SINGLE | SWT.BORDER);
271 label = new Label(composite, SWT.NONE);
272 label.setText("Angle");
273 angleText = new Text(composite, SWT.SINGLE | SWT.BORDER);
274 label = new Label(composite, SWT.NONE);
275 label.setText("Rotation angle");
276 rotationAngleText = new Text(composite, SWT.SINGLE | SWT.BORDER);
278 label = new Label(composite, SWT.NONE);
279 label.setText("Diameter");
280 diameterText = new Text(composite, SWT.SINGLE | SWT.BORDER);
281 label = new Label(composite, SWT.NONE);
282 label.setText("Turn Radius");
283 turnRadiusText = new Text(composite, SWT.SINGLE | SWT.BORDER);
285 lengthText.setEnabled(false);
286 angleText.setEnabled(false);
287 rotationAngleText.setEnabled(false);
288 turnRadiusText.setEnabled(false);
289 diameterText.setEnabled(false);
291 nameText.addKeyListener(new KeyAdapter() {
293 public void keyReleased(KeyEvent e) {
294 name = nameText.getText();
299 lengthText.addKeyListener(new KeyAdapter() {
301 public void keyReleased(KeyEvent e) {
303 length = Double.parseDouble(lengthText.getText());
304 } catch (NumberFormatException err) {
311 angleText.addKeyListener(new KeyAdapter() {
313 public void keyReleased(KeyEvent e) {
315 angle = Double.parseDouble(angleText.getText());
316 } catch (NumberFormatException err) {
323 rotationAngleText.addKeyListener(new KeyAdapter() {
325 public void keyReleased(KeyEvent e) {
327 rotationAngle = Double.parseDouble(rotationAngleText.getText());
328 } catch (NumberFormatException err) {
329 rotationAngle = null;
335 diameterText.addKeyListener(new KeyAdapter() {
337 public void keyReleased(KeyEvent e) {
339 diameter = Double.parseDouble(diameterText.getText());
340 } catch (NumberFormatException err) {
347 turnRadiusText.addKeyListener(new KeyAdapter() {
349 public void keyReleased(KeyEvent e) {
351 turnRadius = Double.parseDouble(turnRadiusText.getText());
352 } catch (NumberFormatException err) {
359 horizFillData.applyTo(nameText);
360 horizFillData.applyTo(lengthText);
361 horizFillData.applyTo(angleText);
362 horizFillData.applyTo(rotationAngleText);
363 horizFillData.applyTo(diameterText);
364 horizFillData.applyTo(turnRadiusText);
366 if (!allowed.contains(PositionType.NEXT) && !allowed.contains(PositionType.PREVIOUS)) {
367 turnViewer.getList().setEnabled(false);
368 endViewer.getList().setEnabled(false);
375 private void updateInsertPosition(PositionType type) {
376 if (insertPosition == type)
378 endButton.setSelection(type == PositionType.NEXT);
379 middleButton.setSelection(type == PositionType.SPLIT);
380 startButton.setSelection(type == PositionType.PREVIOUS);
381 insertPosition = type;
385 public void selectionChanged(SelectionChangedEvent event) {
386 IStructuredSelection sel = (IStructuredSelection) event.getSelection();
387 Item i = (Item) sel.getFirstElement();
390 if (event.getSource() == inlineViewer) {
391 turnViewer.setSelection(new StructuredSelection());
392 endViewer.setSelection(new StructuredSelection());
393 } else if (event.getSource() == turnViewer) {
394 inlineViewer.setSelection(new StructuredSelection());
395 endViewer.setSelection(new StructuredSelection());
396 } else if (event.getSource() == endViewer) {
397 inlineViewer.setSelection(new StructuredSelection());
398 turnViewer.setSelection(new StructuredSelection());
401 name = generateUniqueName(selected.getName());
402 nameText.setText(name);
408 private void validate() {
409 filterAllowed.clear();
410 Set<PositionType> filterAllowed = new HashSet<PositionType>();
412 if (selected == null) {
414 } else if (selected.isCode()) {// TODO : instead of disabling the button, we should filter the content.
417 lenghtAdjustable = ((selected.getType() == Type.INLINE)
418 && (selected.isVariable() || selected.isModifiable()));
419 if (insertAdjustable) {
420 switch (selected.getType()) {
422 startButton.setEnabled(false);
423 middleButton.setEnabled(false);
424 endButton.setEnabled(true);
425 updateInsertPosition(PositionType.NEXT);
428 if (!selected.isVariable()) {
429 startButton.setEnabled(true);
430 middleButton.setEnabled(true);
431 endButton.setEnabled(true);
433 startButton.setEnabled(false);
434 middleButton.setEnabled(false);
435 endButton.setEnabled(true);
436 updateInsertPosition(PositionType.NEXT);
440 startButton.setEnabled(false);
441 middleButton.setEnabled(false);
442 endButton.setEnabled(true);
443 updateInsertPosition(PositionType.NEXT);
446 startButton.setEnabled(false);
447 middleButton.setEnabled(true);
448 endButton.setEnabled(true);
449 if (insertPosition == PositionType.PREVIOUS)
450 updateInsertPosition(PositionType.NEXT);
453 throw new RuntimeException("Expected component, got equipment " + selected);
455 } else if (lenghtAdjustable) {
456 if (component instanceof InlineComponent) {
457 startButton.setEnabled(true);
458 middleButton.setEnabled(true);
459 endButton.setEnabled(true);
460 } else if (component instanceof TurnComponent) {
461 startButton.setEnabled(false);
462 middleButton.setEnabled(true);
463 endButton.setEnabled(true);
464 if (insertPosition == PositionType.PREVIOUS)
465 updateInsertPosition(PositionType.NEXT);
466 } else if (component instanceof EndComponent || component instanceof Nozzle) {
467 startButton.setEnabled(false);
468 middleButton.setEnabled(false);
469 endButton.setEnabled(true);
470 updateInsertPosition(PositionType.NEXT);
473 startButton.setEnabled(false);
474 middleButton.setEnabled(false);
475 endButton.setEnabled(true);
477 if (selected.isVariable() || selected.isModifiable()) {
478 if (selected.getType() == Type.INLINE) {
479 filterAllowed.add(PositionType.NEXT);
480 filterAllowed.add(PositionType.PREVIOUS);
481 if (inlineSplit && selected.isVariable()) {
482 lengthText.setEnabled(false);
483 angleText.setEnabled(false);
484 rotationAngleText.setEnabled(selected.isRotated());
488 lengthText.setEnabled(true);
489 angleText.setEnabled(false);
490 rotationAngleText.setEnabled(selected.isRotated());
494 } else if (selected.getType() == Type.TURN) {
495 filterAllowed.add(PositionType.NEXT);
496 filterAllowed.add(PositionType.PREVIOUS);
497 lengthText.setEnabled(false);
498 angleText.setEnabled(true);
499 rotationAngleText.setEnabled(true);
503 // this should not happen, since end components should not have variable, or
505 lengthText.setEnabled(false);
506 angleText.setEnabled(false);
507 rotationAngleText.setEnabled(false);
511 lengthText.setEnabled(false);
512 angleText.setEnabled(false);
513 rotationAngleText.setEnabled(selected.getType() == Type.TURN || selected.isRotated());
516 if (selected.isSizeChange()) {
517 turnRadiusText.setEnabled(true);
518 diameterText.setEnabled(true);
519 if (diameter == null || turnRadius == null)
522 turnRadiusText.setEnabled(false);
523 diameterText.setEnabled(false);
526 if (!selected.isVariable()) {
527 switch (selected.getType()) {
529 filterAllowed.add(PositionType.NEXT);
530 filterAllowed.add(PositionType.PREVIOUS);
536 filterAllowed.add(PositionType.NEXT);
537 filterAllowed.add(PositionType.PREVIOUS);
538 filterAllowed.add(PositionType.SPLIT);
540 filterAllowed.add(PositionType.NEXT);
541 filterAllowed.add(PositionType.PREVIOUS);
545 for (PositionType t : filterAllowed) {
546 if (allowed.contains(t))
547 this.filterAllowed.add(t);
550 if (name.isEmpty() || usedNames.contains(name))
553 getButton(OK).setEnabled(ok);
556 private String generateUniqueName(String name) {
559 while (usedNames.contains((newName = name + "_" + i)))
564 public Item getSelected() {
568 public String getName() {
572 public Double getAngle() {
576 public Double getLength() {
580 public Double getRotationAngle() {
581 return rotationAngle;
584 public Double getDiameter() {
588 public Double getTurnRadius() {
592 public Set<PositionType> filterAllowed() {
593 return filterAllowed;
596 public PositionType getInsertPosition() {
597 return insertPosition;
600 public boolean isInsertAdjustable() {
601 return insertAdjustable;
604 public boolean isLenghtAdjustable() {
605 return lenghtAdjustable;