]> gerrit.simantics Code Review - simantics/3d.git/blob - org.simantics.plant3d/src/org/simantics/plant3d/dialog/ComponentSelectionDialog.java
2321c1f9941fbd89f2251c6b64b9f89a2ec8efea
[simantics/3d.git] / org.simantics.plant3d / src / org / simantics / plant3d / dialog / ComponentSelectionDialog.java
1 package org.simantics.plant3d.dialog;
2
3 import java.util.Collection;
4 import java.util.HashSet;
5 import java.util.List;
6 import java.util.ListIterator;
7 import java.util.Set;
8
9 import org.eclipse.jface.dialogs.Dialog;
10 import org.eclipse.jface.dialogs.IDialogConstants;
11 import org.eclipse.jface.dialogs.IDialogSettings;
12 import org.eclipse.jface.layout.GridDataFactory;
13 import org.eclipse.jface.layout.GridLayoutFactory;
14 import org.eclipse.jface.resource.JFaceResources;
15 import org.eclipse.jface.resource.LocalResourceManager;
16 import org.eclipse.jface.resource.ResourceLocator;
17 import org.eclipse.jface.resource.ResourceManager;
18 import org.eclipse.jface.viewers.ISelectionChangedListener;
19 import org.eclipse.jface.viewers.IStructuredSelection;
20 import org.eclipse.jface.viewers.ListViewer;
21 import org.eclipse.jface.viewers.SelectionChangedEvent;
22 import org.eclipse.jface.viewers.StructuredSelection;
23 import org.eclipse.swt.SWT;
24 import org.eclipse.swt.events.KeyAdapter;
25 import org.eclipse.swt.events.KeyEvent;
26 import org.eclipse.swt.events.SelectionAdapter;
27 import org.eclipse.swt.events.SelectionEvent;
28 import org.eclipse.swt.layout.GridData;
29 import org.eclipse.swt.layout.GridLayout;
30 import org.eclipse.swt.widgets.Button;
31 import org.eclipse.swt.widgets.Composite;
32 import org.eclipse.swt.widgets.Control;
33 import org.eclipse.swt.widgets.ExpandBar;
34 import org.eclipse.swt.widgets.ExpandItem;
35 import org.eclipse.swt.widgets.Label;
36 import org.eclipse.swt.widgets.Shell;
37 import org.eclipse.swt.widgets.Text;
38 import org.simantics.Simantics;
39 import org.simantics.db.Session;
40 import org.simantics.db.exception.DatabaseException;
41 import org.simantics.plant3d.Activator;
42 import org.simantics.plant3d.ontology.Plant3D;
43 import org.simantics.plant3d.scenegraph.EndComponent;
44 import org.simantics.plant3d.scenegraph.InlineComponent;
45 import org.simantics.plant3d.scenegraph.Nozzle;
46 import org.simantics.plant3d.scenegraph.PipeRun;
47 import org.simantics.plant3d.scenegraph.PipelineComponent;
48 import org.simantics.plant3d.scenegraph.TurnComponent;
49 import org.simantics.plant3d.scenegraph.controlpoint.PipeControlPoint.PositionType;
50 import org.simantics.plant3d.utils.Item;
51 import org.simantics.plant3d.utils.Item.Type;
52 import org.simantics.plant3d.utils.P3DUtil;
53 import org.simantics.utils.ui.ExceptionUtils;
54
55 public class ComponentSelectionDialog extends Dialog implements ISelectionChangedListener {
56
57         private static final String DIALOG = "ComponentSelectionDialog"; //$NON-NLS-1$
58
59         private IDialogSettings dialogSettings;
60         
61         private double lengthFactor = 1.0;
62
63         private ResourceManager resourceManager;
64
65         private String libUri;
66
67         private Item selected;
68         private Set<PositionType> allowed;
69         private Set<PositionType> filterAllowed;
70         // private boolean positionAdjustment;
71         private PipelineComponent component;
72         private boolean insertAdjustable;
73         private boolean lenghtAdjustable;
74         private PositionType insertPosition = PositionType.NEXT;
75
76         private Double angle;
77         private Double length;
78         private Double rotationAngle;
79
80         private String name;
81         
82         private Text nameText;
83
84         // In-line component
85         private Text lengthText;
86         // Turn component
87         private Text angleText;
88         // Rotated In-line, or turn component.
89         private Text rotationAngleText;
90
91         // Input for new PipeRun
92         private Double diameter;
93         private Double thickness;
94         private Double turnRadius;
95
96         private Text diameterText;
97         private Text thicknessText;
98         private Text turnRadiusText;
99         
100         // Validation message label
101         private Label validationLabel;
102
103         // Position selection
104         private Button startButton;
105         private Button middleButton;
106         private Button endButton;
107
108         private boolean inlineSplit = false;
109
110         ListViewer inlineViewer;
111         ListViewer turnViewer;
112         ListViewer endViewer;
113
114         private Set<String> usedNames;
115
116         public ComponentSelectionDialog(Shell parentShell, Set<PositionType> allowed, PipelineComponent component) {
117                 this(parentShell, allowed, component, Plant3D.URIs.Builtin);
118         }
119
120         public ComponentSelectionDialog(Shell parentShell, Set<PositionType> allowed, PipelineComponent component,
121                         String libUri) {
122                 super(parentShell);
123                 this.allowed = allowed;
124                 this.component = component;
125                 filterAllowed = new HashSet<PositionType>();
126                 insertAdjustable = component instanceof InlineComponent ? ((InlineComponent) component).isVariableLength()
127                                 : false;
128                 lenghtAdjustable = false;
129                 this.libUri = libUri;
130
131                 usedNames = new HashSet<>();
132
133                 setShellStyle(getShellStyle() | SWT.RESIZE);
134
135                 IDialogSettings settings = Activator.getDefault().getDialogSettings();
136                 dialogSettings = settings.getSection(DIALOG);
137                 if (dialogSettings == null)
138                         dialogSettings = settings.addNewSection(DIALOG);
139                 
140                 if (component.getNext() != null && component.getPrevious() != null)
141                         insertPosition = PositionType.PREVIOUS;
142         }
143         
144         private void copyPipeRunParameters() {
145                 PipeRun run = component.getPipeRun();
146                 if (component.getNext() == null && component.getAlternativePipeRun() != null)
147                         run = component.getAlternativePipeRun();
148                 
149                 if (run == null)
150                         return;
151                 
152                 diameter = run.getPipeDiameter();
153                 thickness = run.getPipeThickness();
154                 turnRadius = run.getTurnRadius();
155                 
156                 diameterText.setText(Double.toString(diameter * lengthFactor));
157                 thicknessText.setText(Double.toString(thickness * lengthFactor));
158                 turnRadiusText.setText(Double.toString(turnRadius * lengthFactor));
159         }
160
161         public void setLengthFactor(double lengthFactor) {
162                 this.lengthFactor = lengthFactor;
163         }
164
165         @Override
166         protected IDialogSettings getDialogBoundsSettings() {
167                 return dialogSettings;
168         }
169
170         @Override
171         protected void configureShell(Shell newShell) {
172                 super.configureShell(newShell);
173                 newShell.setText("Create pipeline component");
174         }
175
176         public void addUsedNames(Collection<String> names) {
177                 usedNames.addAll(names);
178         }
179
180         protected List<Item> getItems(Class<?> c, String libUri) throws DatabaseException {
181                 Session session = Simantics.getSession();
182                 if (InlineComponent.class.equals(c)) {
183                         return P3DUtil.getInlines(session, libUri);
184                 } else if (TurnComponent.class.equals(c)) {
185                         return P3DUtil.getTurns(session, libUri);
186                 } else if (EndComponent.class.equals(c)) {
187                         return P3DUtil.getEnds(session, libUri);
188                 } else {
189                         return null;
190                 }
191         }
192
193         @Override
194         protected Control createDialogArea(Composite parent) {
195                 resourceManager = new LocalResourceManager(JFaceResources.getResources(), parent);
196
197                 Composite composite = new Composite(parent, SWT.NONE);
198                 GridLayout layout = new GridLayout(2, false);
199                 layout.marginHeight = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN);
200                 layout.marginWidth = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN);
201                 layout.verticalSpacing = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING);
202                 layout.horizontalSpacing = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING);
203                 composite.setLayout(layout);
204                 composite.setLayoutData(new GridData(GridData.FILL_BOTH));
205                 applyDialogFont(composite);
206
207                 // Grid layout data for fields that grab horizontal space
208                 final GridDataFactory horizFillData = GridDataFactory.fillDefaults().grab(true, false).align(SWT.FILL, SWT.TOP);
209                 
210                 // TODO : we need better classification than inline,turn, and end:
211                 // * fixed length inlines
212                 // * fixed angle turns
213                 // * size changes (requires input for pipe run specs)
214                 // * variable length inlines (input for length)
215                 // * variable angle turns (input for angle)
216                 // * ends
217
218                 List<Item> ends = null;
219                 List<Item> turns = null;
220                 List<Item> inlines = null;
221                 try {
222                         ends = getItems(EndComponent.class, libUri);
223                         turns = getItems(TurnComponent.class, libUri);
224                         inlines = getItems(InlineComponent.class, libUri);
225                 } catch (DatabaseException e) {
226                         Label label = new Label(composite, SWT.NONE);
227                         label.setText("Cannot load pipeline components: " + e.getMessage());
228                         ExceptionUtils.logError(e);
229                         return composite;
230                 }
231                 ends = P3DUtil.filterUserComponents(ends);
232                 turns = P3DUtil.filterUserComponents(turns);
233                 inlines = P3DUtil.filterUserComponents(inlines);
234
235                 ExpandBar expandBar = new ExpandBar(composite, SWT.V_SCROLL);
236
237                 boolean isOpen = component.getNext() == null || component.getPrevious() == null;
238                 if (!inlines.isEmpty()) {
239                         if (!isOpen) {
240                                 // Remove variable length pipe from options
241                                 ListIterator<Item> it = inlines.listIterator();
242                                 while (it.hasNext()) {
243                                         Item item = it.next();
244                                         if (item.isVariable())
245                                                 it.remove();
246                                 }
247                         }
248                         
249                         inlineViewer = createItemList(expandBar, inlines, "Inline");
250                 }
251
252                 // Only allow elbows and ends to be added to open ends of the pipelines
253                 if (isOpen) {
254                         if (!turns.isEmpty()) {
255                                 turnViewer = createItemList(expandBar, turns, "Elbow");
256                         }
257                         
258                         if (!ends.isEmpty()) {
259                                 turnViewer = createItemList(expandBar, ends, "End");
260                         }
261                 }
262
263                 GridDataFactory.fillDefaults().grab(true, true).align(SWT.FILL, SWT.FILL).span(2, 1).applyTo(expandBar);
264                 GridDataFactory.fillDefaults().grab(true, true).minSize(500, 500).hint(500, 500).applyTo(composite);
265
266                 // If there is only one item in the ExpandBar, expand it by default to avoid unnecessary clicks
267                 ExpandItem[] expandBarItems = expandBar.getItems();
268                 if (expandBarItems.length == 1) {
269                         expandBarItems[0].setExpanded(true);
270                 }
271
272                 Label label = new Label(composite, SWT.NONE);
273                 label.setText("Position");
274                 Composite buttonComposite = new Composite(composite, SWT.NONE);
275                 startButton = new Button(buttonComposite, SWT.TOGGLE);
276                 middleButton = new Button(buttonComposite, SWT.TOGGLE);
277                 endButton = new Button(buttonComposite, SWT.TOGGLE);
278                 startButton.setImage(resourceManager.createImage(
279                                 ResourceLocator.imageDescriptorFromBundle(Activator.PLUGIN_ID, "icons/insert_start.png").get()));
280                 middleButton.setImage(resourceManager.createImage(
281                                 ResourceLocator.imageDescriptorFromBundle(Activator.PLUGIN_ID, "icons/insert_middle.png").get()));
282                 endButton.setImage(resourceManager.createImage(
283                                 ResourceLocator.imageDescriptorFromBundle(Activator.PLUGIN_ID, "icons/insert_end.png").get()));
284                 startButton.setToolTipText("Overlapping insert");
285                 middleButton.setToolTipText("Cutting insert");
286                 endButton.setToolTipText("Adding insert");
287                 horizFillData.applyTo(buttonComposite);
288                 GridLayoutFactory.fillDefaults().numColumns(3).applyTo(buttonComposite);
289
290                 startButton.setSelection(insertPosition == PositionType.PREVIOUS);
291                 middleButton.setSelection(insertPosition == PositionType.SPLIT);
292                 endButton.setSelection(insertPosition == PositionType.NEXT);
293                 
294                 startButton.setEnabled(false);
295                 middleButton.setEnabled(false);
296                 endButton.setEnabled(false);
297
298                 startButton.addSelectionListener(new SelectionAdapter() {
299                         @Override
300                         public void widgetSelected(SelectionEvent e) {
301                                 updateInsertPosition(PositionType.PREVIOUS);
302                         }
303                 });
304
305                 middleButton.addSelectionListener(new SelectionAdapter() {
306                         @Override
307                         public void widgetSelected(SelectionEvent e) {
308                                 updateInsertPosition(PositionType.SPLIT);
309                         }
310                 });
311                 endButton.addSelectionListener(new SelectionAdapter() {
312                         @Override
313                         public void widgetSelected(SelectionEvent e) {
314                                 updateInsertPosition(PositionType.NEXT);
315                         }
316                 });
317                 
318                 if (!hasInsertPosition()) {
319                         label.setVisible(false);
320                         buttonComposite.setVisible(false);
321                 }
322
323                 label = new Label(composite, SWT.NONE);
324                 label.setText("Name");
325                 nameText = new Text(composite, SWT.SINGLE | SWT.BORDER);
326
327                 label = new Label(composite, SWT.NONE);
328                 label.setText("Length");
329                 lengthText = new Text(composite, SWT.SINGLE | SWT.BORDER);
330                 label = new Label(composite, SWT.NONE);
331                 label.setText("Angle");
332                 angleText = new Text(composite, SWT.SINGLE | SWT.BORDER);
333                 label = new Label(composite, SWT.NONE);
334                 label.setText("Rotation angle");
335                 rotationAngleText = new Text(composite, SWT.SINGLE | SWT.BORDER);
336
337                 label = new Label(composite, SWT.NONE);
338                 label.setText("Diameter");
339                 diameterText = new Text(composite, SWT.SINGLE | SWT.BORDER);
340                 label = new Label(composite, SWT.NONE);
341                 label.setText("Wall thickness");
342                 thicknessText = new Text(composite, SWT.SINGLE | SWT.BORDER);
343                 label = new Label(composite, SWT.NONE);
344                 label.setText("Elbow radius");
345                 turnRadiusText = new Text(composite, SWT.SINGLE | SWT.BORDER);
346                 
347                 validationLabel = new Label(composite, SWT.NONE);
348                 validationLabel.setText("");
349
350                 lengthText.setEnabled(false);
351                 angleText.setEnabled(false);
352                 rotationAngleText.setEnabled(false);
353                 turnRadiusText.setEnabled(false);
354                 diameterText.setEnabled(false);
355                 thicknessText.setEnabled(false);
356
357                 copyPipeRunParameters();
358
359                 nameText.addKeyListener(new KeyAdapter() {
360                         @Override
361                         public void keyReleased(KeyEvent e) {
362                                 name = nameText.getText();
363                                 validate();
364                         }
365                 });
366                 
367                 lengthText.addKeyListener(new KeyAdapter() {
368                         @Override
369                         public void keyReleased(KeyEvent e) {
370                                 try {
371                                         length = Double.parseDouble(lengthText.getText()) / lengthFactor;
372                                 } catch (NumberFormatException err) {
373                                         length = null;
374                                 }
375                                 validate();
376                         }
377                 });
378
379                 angleText.addKeyListener(new KeyAdapter() {
380                         @Override
381                         public void keyReleased(KeyEvent e) {
382                                 try {
383                                         angle = Double.parseDouble(angleText.getText());
384                                 } catch (NumberFormatException err) {
385                                         angle = null;
386                                 }
387                                 validate();
388                         }
389                 });
390
391                 rotationAngleText.addKeyListener(new KeyAdapter() {
392                         @Override
393                         public void keyReleased(KeyEvent e) {
394                                 try {
395                                         rotationAngle = Double.parseDouble(rotationAngleText.getText());
396                                 } catch (NumberFormatException err) {
397                                         rotationAngle = null;
398                                 }
399                                 validate();
400                         }
401                 });
402
403                 diameterText.addKeyListener(new KeyAdapter() {
404                         @Override
405                         public void keyReleased(KeyEvent e) {
406                                 try {
407                                         diameter = Double.parseDouble(diameterText.getText()) / lengthFactor;
408                                 } catch (NumberFormatException err) {
409                                         diameter = null;
410                                 }
411                                 validate();
412                         }
413                 });
414                 
415                 thicknessText.addKeyListener(new KeyAdapter() {
416                         @Override
417                         public void keyReleased(KeyEvent e) {
418                                 try {
419                                         thickness = Double.parseDouble(thicknessText.getText()) / lengthFactor;
420                                 } catch (NumberFormatException err) {
421                                         thickness = null;
422                                 }
423                                 validate();
424                         }
425                 });
426
427                 turnRadiusText.addKeyListener(new KeyAdapter() {
428                         @Override
429                         public void keyReleased(KeyEvent e) {
430                                 try {
431                                         turnRadius = Double.parseDouble(turnRadiusText.getText()) / lengthFactor;
432                                 } catch (NumberFormatException err) {
433                                         turnRadius = null;
434                                 }
435                                 validate();
436                         }
437                 });
438
439                 horizFillData.applyTo(nameText);
440                 horizFillData.applyTo(lengthText);
441                 horizFillData.applyTo(angleText);
442                 horizFillData.applyTo(rotationAngleText);
443                 horizFillData.applyTo(diameterText);
444                 horizFillData.applyTo(thicknessText);
445                 horizFillData.applyTo(turnRadiusText);
446                 
447                 GridDataFactory.fillDefaults().span(2, 1).align(SWT.END, SWT.END).grab(true, false).applyTo(validationLabel);
448
449                 if (!allowed.contains(PositionType.NEXT) && !allowed.contains(PositionType.PREVIOUS)) {
450                         if (turnViewer != null)
451                                 turnViewer.getList().setEnabled(false);
452                         if (endViewer != null)
453                                 endViewer.getList().setEnabled(false);
454                         inlineSplit = true;
455                 }
456
457                 return composite;
458         }
459
460         private ListViewer createItemList(ExpandBar expandBar, List<Item> items, String name) {
461                 ExpandItem expandItem = new ExpandItem(expandBar, SWT.NONE);
462                 expandItem.setText(name);
463                 ListViewer viewer = new ListViewer(expandBar);
464                 viewer.setLabelProvider(new ComponentLabelProvider());
465                 viewer.setContentProvider(new ComponentContentProvider());
466                 
467                 expandItem.setControl(viewer.getList());
468                 viewer.setInput(items);
469                 expandItem.setHeight(viewer.getList().computeSize(SWT.DEFAULT, SWT.DEFAULT).y);
470                 viewer.addSelectionChangedListener(this);
471                 return viewer;
472         }
473
474         private boolean hasInsertPosition() {
475                 return component.getNext() == null || component.getPrevious() == null;
476         }
477
478         private void updateInsertPosition(PositionType type) {
479                 if (insertPosition == type)
480                         return;
481                 startButton.setSelection(type == PositionType.PREVIOUS);
482                 middleButton.setSelection(type == PositionType.SPLIT);
483                 endButton.setSelection(type == PositionType.NEXT);
484                 insertPosition = type;
485         }
486
487         @Override
488         public void selectionChanged(SelectionChangedEvent event) {
489                 IStructuredSelection sel = (IStructuredSelection) event.getSelection();
490                 Item i = (Item) sel.getFirstElement();
491                 if (i != null) {
492                         selected = i;
493                         if (inlineViewer != null && event.getSource() == inlineViewer) {
494                                 clearSelection(turnViewer);
495                                 clearSelection(endViewer);
496                         } else if (turnViewer != null && event.getSource() == turnViewer) {
497                                 clearSelection(inlineViewer);
498                                 clearSelection(endViewer);
499                         } else if (endViewer != null && event.getSource() == endViewer) {
500                                 clearSelection(inlineViewer);
501                                 clearSelection(turnViewer);
502                         }
503                         
504                         name = generateUniqueName(selected.getName());
505                         nameText.setText(name);
506                         
507                         validate();
508                 }
509         }
510
511         private void clearSelection(ListViewer possibleListViewer) {
512                 if (possibleListViewer != null)
513                         possibleListViewer.setSelection(new StructuredSelection());
514         }
515
516         private void validate() {
517                 filterAllowed.clear();
518                 Set<PositionType> filterAllowed = new HashSet<PositionType>();
519                 boolean ok = true;
520                 String msg = null;
521                 
522                 if (name.isEmpty() || usedNames.contains(name)) {
523                         ok = false;
524                         if (msg == null) {
525                                 if (name.isEmpty())
526                                         msg = "Please provide a valid name";
527                                 else
528                                         msg = "Name \"" + name + "\" is already in use";
529                         }
530                 }
531                 
532                 if (selected == null) {
533                         ok = false;
534                 } else if (selected.isCode()) {// TODO : instead of disabling the button, we should filter the content.
535                         ok = false;
536                 } else {
537                         lenghtAdjustable = ((selected.getType() == Type.INLINE)
538                                         && (selected.isVariable() || selected.isModifiable()));
539                         
540                         if (!hasInsertPosition()) {
541                                 // We are inserting to a fully connected variable length component
542                                 // only allow insertion within the component
543                                 startButton.setEnabled(false);
544                                 middleButton.setEnabled(false);
545                                 endButton.setEnabled(false);
546                                 updateInsertPosition(PositionType.PREVIOUS);
547                         } else if (insertAdjustable) {
548                                 switch (selected.getType()) {
549                                 case END:
550                                         startButton.setEnabled(false);
551                                         middleButton.setEnabled(false);
552                                         endButton.setEnabled(true);
553                                         updateInsertPosition(PositionType.NEXT);
554                                         break;
555                                 case INLINE:
556                                         if (!selected.isVariable()) {
557                                                 startButton.setEnabled(true);
558                                                 middleButton.setEnabled(true);
559                                                 endButton.setEnabled(true);
560                                         } else {
561                                                 startButton.setEnabled(false);
562                                                 middleButton.setEnabled(false);
563                                                 endButton.setEnabled(true);
564                                                 updateInsertPosition(PositionType.NEXT);
565                                         }
566                                         break;
567                                 case NOZZLE:
568                                         startButton.setEnabled(false);
569                                         middleButton.setEnabled(false);
570                                         endButton.setEnabled(true);
571                                         updateInsertPosition(PositionType.NEXT);
572                                         break;
573                                 case TURN:
574                                         startButton.setEnabled(false);
575                                         middleButton.setEnabled(true);
576                                         endButton.setEnabled(true);
577                                         if (insertPosition == PositionType.PREVIOUS)
578                                                 updateInsertPosition(PositionType.NEXT);
579                                         break;
580                                 case EQUIPMENT:
581                                         throw new RuntimeException("Expected component, got equipment " + selected);
582                                 }
583                         } else if (lenghtAdjustable) {
584                                 if (component instanceof InlineComponent) {
585                                         startButton.setEnabled(true);
586                                         middleButton.setEnabled(true);
587                                         endButton.setEnabled(true);
588                                 } else if (component instanceof TurnComponent) {
589                                         startButton.setEnabled(false);
590                                         middleButton.setEnabled(true);
591                                         endButton.setEnabled(true);
592                                         if (insertPosition == PositionType.PREVIOUS)
593                                                 updateInsertPosition(PositionType.NEXT);
594                                 } else if (component instanceof EndComponent || component instanceof Nozzle) {
595                                         startButton.setEnabled(false);
596                                         middleButton.setEnabled(false);
597                                         endButton.setEnabled(true);
598                                         updateInsertPosition(PositionType.NEXT);
599                                 }
600                         } else {
601                                 startButton.setEnabled(false);
602                                 middleButton.setEnabled(false);
603                                 endButton.setEnabled(true);
604                         }
605                         if (selected.isVariable() || selected.isModifiable()) {
606                                 if (selected.getType() == Type.INLINE) {
607                                         filterAllowed.add(PositionType.NEXT);
608                                         filterAllowed.add(PositionType.PREVIOUS);
609                                         if (inlineSplit && selected.isVariable()) {
610                                                 lengthText.setEnabled(false);
611                                                 angleText.setEnabled(false);
612                                                 rotationAngleText.setEnabled(selected.isRotated());
613                                                 ok = false;
614                                                 if (msg == null) msg = "Cannot split a straight pipe with a straight pipe";
615                                         } else {
616                                                 lengthText.setEnabled(true);
617                                                 angleText.setEnabled(false);
618                                                 rotationAngleText.setEnabled(selected.isRotated());
619                                                 if (length == null || length <= 0.0) {
620                                                         ok = false;
621                                                         if (msg == null) msg = "Please provide a valid length";
622                                                 }
623                                         }
624                                 } else if (selected.getType() == Type.TURN) {
625                                         filterAllowed.add(PositionType.NEXT);
626                                         filterAllowed.add(PositionType.PREVIOUS);
627                                         lengthText.setEnabled(false);
628                                         angleText.setEnabled(true);
629                                         rotationAngleText.setEnabled(true);
630                                         if (angle == null) {
631                                                 ok = false;
632                                                 if (msg == null) msg = "Please provide a turn angle";
633                                         }
634                                 } else {
635                                         // this should not happen, since end components should not have variable, or
636                                         // modifiable flag.
637                                         lengthText.setEnabled(false);
638                                         angleText.setEnabled(false);
639                                         rotationAngleText.setEnabled(false);
640
641                                 }
642                         } else {
643                                 lengthText.setEnabled(false);
644                                 angleText.setEnabled(false);
645                                 rotationAngleText.setEnabled(selected.getType() == Type.TURN || selected.isRotated());
646                         }
647
648                         if (selected.isSizeChange()) {
649                                 turnRadiusText.setEnabled(true);
650                                 diameterText.setEnabled(true);
651                                 thicknessText.setEnabled(true);
652                                 if (diameter == null || diameter <= 0.0) {
653                                         ok = false;
654                                         if (msg == null) msg = "Please provide a valid diameter";
655                                 }
656                                 if (turnRadius == null || diameter != null && turnRadius < diameter / 2) {
657                                         ok = false;
658                                         if (msg == null) msg = "Please provide a valid turn radius";
659                                 }
660                                 if (thickness == null || thickness < 0.0 || diameter != null && thickness >= diameter / 2) {
661                                         ok = false;
662                                         if (msg == null) msg = "Please provide a valid wall thickness";
663                                 }
664                         } else {
665                                 turnRadiusText.setEnabled(false);
666                                 diameterText.setEnabled(false);
667                                 thicknessText.setEnabled(false);
668                         }
669
670                         if (!selected.isVariable()) {
671                                 switch (selected.getType()) {
672                                 case END:
673                                         filterAllowed.add(PositionType.NEXT);
674                                         filterAllowed.add(PositionType.PREVIOUS);
675                                         break;
676                                 case NOZZLE:
677                                 case EQUIPMENT:
678                                         break;
679                                 case INLINE:
680                                         filterAllowed.add(PositionType.NEXT);
681                                         filterAllowed.add(PositionType.PREVIOUS);
682                                         filterAllowed.add(PositionType.SPLIT);
683                                 case TURN:
684                                         filterAllowed.add(PositionType.NEXT);
685                                         filterAllowed.add(PositionType.PREVIOUS);
686                                 }
687                         }
688                 }
689                 for (PositionType t : filterAllowed) {
690                         if (allowed.contains(t))
691                                 this.filterAllowed.add(t);
692                 }
693
694                 validationLabel.setText(msg != null ? msg : "");
695                 validationLabel.requestLayout();
696                 
697                 getButton(OK).setEnabled(ok);
698         }
699
700         private String generateUniqueName(String name) {
701                 int i = 1;
702                 String newName;
703                 while (usedNames.contains((newName = name + "_" + i)))
704                         i++;
705                 return newName;
706         }
707
708         public Item getSelected() {
709                 return selected;
710         }
711         
712         public String getName() {
713                 return name;
714         }
715
716         public Double getAngle() {
717                 return angle;
718         }
719
720         public Double getLength() {
721                 return length;
722         }
723
724         public Double getRotationAngle() {
725                 return rotationAngle;
726         }
727
728         public Double getDiameter() {
729                 return diameter;
730         }
731
732         public Double getTurnRadius() {
733                 return turnRadius;
734         }
735
736         public Set<PositionType> filterAllowed() {
737                 return filterAllowed;
738         }
739
740         public PositionType getInsertPosition() {
741                 return insertPosition;
742         }
743
744         public boolean isInsertAdjustable() {
745                 return insertAdjustable;
746         }
747
748         public boolean isLenghtAdjustable() {
749                 return lenghtAdjustable;
750         }
751
752         public Double getThickness() {
753                 return thickness;
754         }
755
756 }