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