]> gerrit.simantics Code Review - simantics/3d.git/blob - org.simantics.plant3d/src/org/simantics/plant3d/dialog/ComponentSelectionDialog.java
Tag user modifiable length
[simantics/3d.git] / org.simantics.plant3d / src / org / simantics / plant3d / dialog / ComponentSelectionDialog.java
1 package org.simantics.plant3d.dialog;
2
3 import java.util.HashSet;
4 import java.util.List;
5 import java.util.Set;
6
7 import org.eclipse.jface.dialogs.Dialog;
8 import org.eclipse.jface.dialogs.IDialogConstants;
9 import org.eclipse.jface.layout.GridDataFactory;
10 import org.eclipse.jface.layout.GridLayoutFactory;
11 import org.eclipse.jface.resource.JFaceResources;
12 import org.eclipse.jface.resource.LocalResourceManager;
13 import org.eclipse.jface.resource.ResourceManager;
14 import org.eclipse.jface.viewers.ISelectionChangedListener;
15 import org.eclipse.jface.viewers.IStructuredSelection;
16 import org.eclipse.jface.viewers.ListViewer;
17 import org.eclipse.jface.viewers.SelectionChangedEvent;
18 import org.eclipse.jface.viewers.StructuredSelection;
19 import org.eclipse.swt.SWT;
20 import org.eclipse.swt.events.KeyAdapter;
21 import org.eclipse.swt.events.KeyEvent;
22 import org.eclipse.swt.events.SelectionAdapter;
23 import org.eclipse.swt.events.SelectionEvent;
24 import org.eclipse.swt.layout.GridData;
25 import org.eclipse.swt.layout.GridLayout;
26 import org.eclipse.swt.widgets.Button;
27 import org.eclipse.swt.widgets.Composite;
28 import org.eclipse.swt.widgets.Control;
29 import org.eclipse.swt.widgets.ExpandBar;
30 import org.eclipse.swt.widgets.ExpandItem;
31 import org.eclipse.swt.widgets.Label;
32 import org.eclipse.swt.widgets.Shell;
33 import org.eclipse.swt.widgets.Text;
34 import org.simantics.db.exception.DatabaseException;
35 import org.simantics.plant3d.Activator;
36 import org.simantics.plant3d.ontology.Plant3D;
37 import org.simantics.plant3d.scenegraph.EndComponent;
38 import org.simantics.plant3d.scenegraph.InlineComponent;
39 import org.simantics.plant3d.scenegraph.Nozzle;
40 import org.simantics.plant3d.scenegraph.PipelineComponent;
41 import org.simantics.plant3d.scenegraph.TurnComponent;
42 import org.simantics.plant3d.scenegraph.controlpoint.PipeControlPoint.PositionType;
43 import org.simantics.plant3d.utils.Item;
44 import org.simantics.plant3d.utils.Item.Type;
45 import org.simantics.plant3d.utils.P3DUtil;
46 import org.simantics.utils.ui.ExceptionUtils;
47
48 public class ComponentSelectionDialog extends Dialog implements ISelectionChangedListener{
49
50         private ResourceManager resourceManager;
51         
52         private String libUri;
53         
54         private Item selected;
55         private Set<PositionType> allowed;
56         private Set<PositionType> filterAllowed;
57         //private boolean positionAdjustment;
58         private PipelineComponent component;
59         private boolean insertAdjustable;
60         private boolean lenghtAdjustable;
61         private PositionType insertPosition = PositionType.NEXT; 
62         
63         private Double angle;
64         private Double length;
65         
66         private Text lengthText;
67         private Text angleText;
68         
69         private Double diameter;
70         private Double turnRadius;
71         
72         private Text diameterText;
73         private Text turnRadiusText;
74         
75         private Button startButton;
76         private Button middleButton;
77         private Button endButton;
78         
79         private boolean inlineSplit = false;
80         
81         ListViewer inlineViewer;
82         ListViewer turnViewer;
83         ListViewer endViewer;
84         
85         
86         public ComponentSelectionDialog(Shell parentShell, Set<PositionType> allowed, PipelineComponent component){
87                 this(parentShell, allowed, component, Plant3D.URIs.Builtin);
88         }
89         
90         public ComponentSelectionDialog(Shell parentShell, Set<PositionType> allowed, PipelineComponent component, String libUri){
91         super(parentShell);
92         this.allowed = allowed;
93         this.component = component;
94         filterAllowed = new HashSet<PositionType>();
95         insertAdjustable = component instanceof InlineComponent ? ((InlineComponent)component).isVariableLength() : false;
96         lenghtAdjustable = false;
97         this.libUri = libUri;
98     }
99         
100         @Override
101         protected Control createDialogArea(Composite parent) {
102                 resourceManager = new LocalResourceManager(JFaceResources.getResources(), parent);
103                 
104                 Composite composite = new Composite(parent, SWT.NONE);
105                 GridLayout layout = new GridLayout(2,false);
106                 layout.marginHeight = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN);
107                 layout.marginWidth = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN);
108                 layout.verticalSpacing = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING);
109                 layout.horizontalSpacing = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING);
110                 composite.setLayout(layout);
111                 composite.setLayoutData(new GridData(GridData.FILL_BOTH));
112                 applyDialogFont(composite);
113                 
114                 // TODO : we need better classification than inline,turn, and end:
115                 // * fixed length inlines
116                 // * fixed angle turns
117                 // * size changes (requires input for pipe run specs)
118                 // * variable length inlines (input for length)
119                 // * variable angle turns (input for angle)
120                 // * ends
121                 
122                 List<Item> ends = null;
123                 List<Item> turns = null;
124                 List<Item> inlines = null;
125                 try {
126                         ends = P3DUtil.getEnds(libUri);
127                         turns= P3DUtil.getTurns(libUri);
128                         inlines = P3DUtil.getInlines(libUri);
129                 } catch (DatabaseException e) {
130                         Label label = new Label(composite, SWT.NONE);
131                         label.setText("Cannot load pipeline components: " + e.getMessage());
132                         ExceptionUtils.logError(e);
133                         return composite;
134                 }
135                 ends = P3DUtil.filterUserComponents(ends);
136                 turns = P3DUtil.filterUserComponents(turns);
137                 inlines = P3DUtil.filterUserComponents(inlines);
138                 
139                 ExpandBar expandBar = new ExpandBar(composite, SWT.NONE);
140                 
141                 
142                 ExpandItem inlineItem = new ExpandItem(expandBar, SWT.NONE);
143                 inlineItem.setText("Inline");
144                 inlineViewer = new ListViewer(expandBar);
145                 inlineViewer.setLabelProvider(new ComponentLabelProvider());
146                 inlineViewer.setContentProvider(new ComponentContentProvider());
147                 
148                 ExpandItem turnItem = new ExpandItem(expandBar, SWT.NONE);
149                 turnItem.setText("Turn");
150                 turnViewer = new ListViewer(expandBar);
151                 turnViewer.setLabelProvider(new ComponentLabelProvider());
152                 turnViewer.setContentProvider(new ComponentContentProvider());
153                 
154                 ExpandItem endItem = new ExpandItem(expandBar, SWT.NONE);
155                 endItem.setText("End");
156                 endViewer = new ListViewer(expandBar);
157                 endViewer.setLabelProvider(new ComponentLabelProvider());
158                 endViewer.setContentProvider(new ComponentContentProvider());
159                 
160                 
161                 inlineItem.setControl(inlineViewer.getList());
162                 turnItem.setControl(turnViewer.getList());
163                 endItem.setControl(endViewer.getList());
164                 
165                 inlineViewer.setInput(inlines);
166                 turnViewer.setInput(turns);
167                 endViewer.setInput(ends);
168                 
169                 inlineItem.setHeight(inlineViewer.getList().computeSize(SWT.DEFAULT, SWT.DEFAULT).y);
170                 turnItem.setHeight(turnViewer.getList().computeSize(SWT.DEFAULT, SWT.DEFAULT).y);
171                 endItem.setHeight(endViewer.getList().computeSize(SWT.DEFAULT, SWT.DEFAULT).y);
172                 
173                 inlineViewer.addSelectionChangedListener(this);
174                 turnViewer.addSelectionChangedListener(this);
175                 endViewer.addSelectionChangedListener(this);
176                 
177                 GridDataFactory.fillDefaults().grab(true, true).align(SWT.FILL, SWT.FILL).span(2, 1).applyTo(expandBar);
178                 GridDataFactory.fillDefaults().minSize(500, 500).hint(500, 500).applyTo(composite);
179                 
180                 Label label = new Label(composite, SWT.NONE);
181                 label.setText("Position");
182                 Composite buttonComposite = new Composite(composite, SWT.NONE);
183                 startButton = new Button(buttonComposite, SWT.TOGGLE);
184                 middleButton = new Button(buttonComposite, SWT.TOGGLE);
185                 endButton = new Button(buttonComposite, SWT.TOGGLE);
186                 startButton.setImage(resourceManager.createImage(Activator.imageDescriptorFromPlugin(Activator.PLUGIN_ID, "icons/insert_start.png")));
187                 middleButton.setImage(resourceManager.createImage(Activator.imageDescriptorFromPlugin(Activator.PLUGIN_ID, "icons/insert_middle.png")));
188                 endButton.setImage(resourceManager.createImage(Activator.imageDescriptorFromPlugin(Activator.PLUGIN_ID, "icons/insert_end.png")));
189                 GridDataFactory.fillDefaults().grab(true, false).align(SWT.FILL, SWT.TOP).applyTo(buttonComposite);
190                 GridLayoutFactory.fillDefaults().numColumns(3).applyTo(buttonComposite);
191                 
192                 startButton.setEnabled(false);
193                 middleButton.setEnabled(false);
194                 endButton.setEnabled(false);
195                 
196                 startButton.addSelectionListener(new SelectionAdapter() {
197                         @Override
198                         public void widgetSelected(SelectionEvent e) {
199                                 updateInsertPosition(PositionType.PREVIOUS);
200                         }
201                 });
202                 
203                 middleButton.addSelectionListener(new SelectionAdapter() {
204                         @Override
205                         public void widgetSelected(SelectionEvent e) {
206                                 updateInsertPosition(PositionType.SPLIT);
207                         }
208                 });
209                 endButton.addSelectionListener(new SelectionAdapter() {
210                         @Override
211                         public void widgetSelected(SelectionEvent e) {
212                                 updateInsertPosition(PositionType.NEXT);
213                         }
214                 });
215                 endButton.setSelection(true);
216                 
217                 label = new Label(composite, SWT.NONE);
218                 label.setText("Length");
219                 lengthText = new Text(composite, SWT.SINGLE|SWT.BORDER);
220                 label = new Label(composite, SWT.NONE);
221                 label.setText("Angle");
222                 angleText = new Text(composite, SWT.SINGLE|SWT.BORDER);
223                 
224                 label = new Label(composite, SWT.NONE);
225                 label.setText("Diameter");
226                 diameterText = new Text(composite, SWT.SINGLE|SWT.BORDER);
227                 label = new Label(composite, SWT.NONE);
228                 label.setText("Turn Radius");
229                 turnRadiusText = new Text(composite, SWT.SINGLE|SWT.BORDER);
230                 
231                 lengthText.setEnabled(false);
232                 angleText.setEnabled(false);
233                 turnRadiusText.setEnabled(false);
234                 diameterText.setEnabled(false);
235                 
236                 lengthText.addKeyListener(new KeyAdapter() {
237                         @Override
238                         public void keyReleased(KeyEvent e) {
239                                 try {
240                                         length = Double.parseDouble(lengthText.getText());
241                                 } catch (NumberFormatException err) {
242                                         length = null;
243                                 }
244                                 validate();
245                         }
246                 });
247                 
248                 angleText.addKeyListener(new KeyAdapter() {
249                         @Override
250                         public void keyReleased(KeyEvent e) {
251                                 try {
252                                         angle = Double.parseDouble(angleText.getText());
253                                 } catch (NumberFormatException err) {
254                                         angle = null;
255                                 }
256                                 validate();
257                         }
258                 });
259                 
260                 diameterText.addKeyListener(new KeyAdapter() {
261                         @Override
262                         public void keyReleased(KeyEvent e) {
263                                 try {
264                                         diameter = Double.parseDouble(diameterText.getText());
265                                 } catch (NumberFormatException err) {
266                                         diameter = null;
267                                 }
268                                 validate();
269                         }
270                 });
271                 
272                 turnRadiusText.addKeyListener(new KeyAdapter() {
273                         @Override
274                         public void keyReleased(KeyEvent e) {
275                                 try {
276                                         turnRadius = Double.parseDouble(turnRadiusText.getText());
277                                 } catch (NumberFormatException err) {
278                                         turnRadius = null;
279                                 }
280                                 validate();
281                         }
282                 });
283                 
284                 GridDataFactory.fillDefaults().grab(true, false).align(SWT.FILL, SWT.TOP).applyTo(lengthText);
285                 GridDataFactory.fillDefaults().grab(true, false).align(SWT.FILL, SWT.TOP).applyTo(angleText);
286                 GridDataFactory.fillDefaults().grab(true, false).align(SWT.FILL, SWT.TOP).applyTo(diameterText);
287                 GridDataFactory.fillDefaults().grab(true, false).align(SWT.FILL, SWT.TOP).applyTo(turnRadiusText);
288                 
289                 if (!allowed.contains(PositionType.NEXT) && !allowed.contains(PositionType.PREVIOUS)) {
290                         turnViewer.getList().setEnabled(false);
291                         endViewer.getList().setEnabled(false);
292                         inlineSplit = true;
293                 }
294                 
295                 return composite;
296         }
297         
298         
299         private void updateInsertPosition(PositionType type) {
300                 if (insertPosition == type)
301                         return;
302                 endButton.setSelection(type == PositionType.NEXT);
303                 middleButton.setSelection(type == PositionType.SPLIT);
304                 startButton.setSelection(type == PositionType.PREVIOUS);
305                 insertPosition = type;
306         }
307         
308         @Override
309         public void selectionChanged(SelectionChangedEvent event) {
310                 IStructuredSelection sel = (IStructuredSelection)event.getSelection();
311                 Item i = (Item)sel.getFirstElement();
312                 if (i != null) {
313                         selected = i;
314                         if (event.getSource() == inlineViewer) {
315                                 turnViewer.setSelection(new StructuredSelection());
316                                 endViewer.setSelection(new StructuredSelection());
317                         } else if (event.getSource() == turnViewer) {
318                                 inlineViewer.setSelection(new StructuredSelection());
319                                 endViewer.setSelection(new StructuredSelection());
320                         } else if (event.getSource() == endViewer) {
321                                 inlineViewer.setSelection(new StructuredSelection());
322                                 turnViewer.setSelection(new StructuredSelection());
323                         }
324                         validate();     
325                 }
326         }
327         
328         private void validate() {
329                 filterAllowed.clear();
330                 Set<PositionType> filterAllowed = new HashSet<PositionType>();
331                 boolean ok = true;
332                 if (selected == null) {
333                         ok = false;
334                 } else if (selected.isCode()) {// TODO : instead of disabling the button, we should filter the content.
335                         ok = false;
336                 } else {
337                         lenghtAdjustable = ((selected.getType() == Type.INLINE) && (selected.isVariable() || selected.isModifiable()));
338                         if (insertAdjustable) {
339                                 switch (selected.getType()) {
340                                 case END:
341                                         startButton.setEnabled(false);
342                                         middleButton.setEnabled(false);
343                                         endButton.setEnabled(true);
344                                         updateInsertPosition(PositionType.NEXT);
345                                         break;
346                                 case INLINE:
347                                         if (!selected.isVariable()) {
348                                                 startButton.setEnabled(true);
349                                                 middleButton.setEnabled(true);
350                                                 endButton.setEnabled(true);
351                                         } else {
352                                                 startButton.setEnabled(false);
353                                                 middleButton.setEnabled(false);
354                                                 endButton.setEnabled(true);
355                                                 updateInsertPosition(PositionType.NEXT);
356                                         }
357                                         break;
358                                 case NOZZLE:
359                                         startButton.setEnabled(false);
360                                         middleButton.setEnabled(false);
361                                         endButton.setEnabled(true);
362                                         updateInsertPosition(PositionType.NEXT);
363                                         break;
364                                 case TURN:
365                                         startButton.setEnabled(false);
366                                         middleButton.setEnabled(true);
367                                         endButton.setEnabled(true);
368                                         if (insertPosition == PositionType.PREVIOUS)
369                                                 updateInsertPosition(PositionType.NEXT);
370                                         break;
371                                 case EQUIPMENT:
372                                         throw new RuntimeException("Expected component, got equipment " + selected);
373                                 }
374                         } else if (lenghtAdjustable) {
375                                 if (component instanceof InlineComponent) {
376                                         startButton.setEnabled(true);
377                                         middleButton.setEnabled(true);
378                                         endButton.setEnabled(true);
379                                 } else if (component instanceof TurnComponent) {
380                                         startButton.setEnabled(false);
381                                         middleButton.setEnabled(true);
382                                         endButton.setEnabled(true);
383                                         if (insertPosition == PositionType.PREVIOUS)
384                                                 updateInsertPosition(PositionType.NEXT);
385                                 } else if (component instanceof EndComponent || component instanceof Nozzle) {
386                                         startButton.setEnabled(false);
387                                         middleButton.setEnabled(false);
388                                         endButton.setEnabled(true);
389                                         updateInsertPosition(PositionType.NEXT);
390                                 }
391                         } else {
392                                 startButton.setEnabled(false);
393                                 middleButton.setEnabled(false);
394                                 endButton.setEnabled(true);
395                         }
396                         if (selected.isVariable() || selected.isModifiable()) {
397                                 if (selected.getType() == Type.INLINE) {
398                                         filterAllowed.add(PositionType.NEXT);
399                                         filterAllowed.add(PositionType.PREVIOUS);
400                                         if (inlineSplit) {
401                                                 lengthText.setEnabled(false);
402                                                 angleText.setEnabled(false);
403                                                 ok = false;
404                                                 
405                                         } else {
406                                                 lengthText.setEnabled(true);
407                                                 angleText.setEnabled(false);
408                                                 if (length == null)
409                                                         ok = false;
410                                         }
411                                 } else if (selected.getType() == Type.TURN) {
412                                         filterAllowed.add(PositionType.NEXT);
413                                         filterAllowed.add(PositionType.PREVIOUS);
414                                         lengthText.setEnabled(false);
415                                         angleText.setEnabled(true);
416                                         if (angle == null)
417                                                 ok = false;
418                                 } else {
419                                         // this should not happen
420                                         lengthText.setEnabled(false);
421                                         angleText.setEnabled(false);
422                                 }
423                         } else {
424                                 lengthText.setEnabled(false);
425                                 angleText.setEnabled(false);                    
426                         }
427                 
428                         if (selected.isSizeChange()) {
429                                 filterAllowed.add(PositionType.NEXT);
430                                 filterAllowed.add(PositionType.PREVIOUS);
431                                 if (inlineSplit) {
432                                         turnRadiusText.setEnabled(false);
433                                         diameterText.setEnabled(false);
434                                         ok = false;
435                                 } else {
436                                         turnRadiusText.setEnabled(true);
437                                         diameterText.setEnabled(true);
438                                         if (diameter == null || turnRadius == null)
439                                                 ok = false;
440                                 }
441                                 
442                         } else {
443                                 turnRadiusText.setEnabled(false);
444                                 diameterText.setEnabled(false);
445                         }
446                         
447                         if (!selected.isSizeChange() && !selected.isVariable()) {
448                                 switch (selected.getType()) {
449                                         case END:
450                                                 filterAllowed.add(PositionType.NEXT);
451                                                 filterAllowed.add(PositionType.PREVIOUS);
452                                                 break;
453                                         case NOZZLE:
454                                         case EQUIPMENT:
455                                                 break;
456                                         case INLINE:
457                                                 filterAllowed.add(PositionType.NEXT);
458                                                 filterAllowed.add(PositionType.PREVIOUS);
459                                                 filterAllowed.add(PositionType.SPLIT);
460                                         case TURN:
461                                                 filterAllowed.add(PositionType.NEXT);
462                                                 filterAllowed.add(PositionType.PREVIOUS);
463                                 }
464                         }
465                 }
466                 for (PositionType t : filterAllowed) {
467                         if (allowed.contains(t))
468                                 this.filterAllowed.add(t);
469                 }
470         
471                 getButton(OK).setEnabled(ok); 
472         }
473         
474         public Item getSelected() {
475                 return selected;
476         }
477         
478         public Double getAngle() {
479                 return angle;
480         }
481         
482         public Double getLength() {
483                 return length;
484         }
485         
486         public Double getDiameter() {
487                 return diameter;
488         }
489         
490         public Double getTurnRadius() {
491                 return turnRadius;
492         }
493         
494         public Set<PositionType> filterAllowed() {
495                 return filterAllowed;
496         }
497         
498         public PositionType getInsertPosition() {
499                 return insertPosition;
500         }
501         
502         public boolean isInsertAdjustable() {
503                 return insertAdjustable;
504         }
505         
506         public boolean isLenghtAdjustable() {
507                 return lenghtAdjustable;
508         }
509
510 }