]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/outline/SCLModuleOutlinePage.java
Fix issue with updates of SCL module outline views.
[simantics/platform.git] / bundles / org.simantics.scl.ui / src / org / simantics / scl / ui / outline / SCLModuleOutlinePage.java
1 package org.simantics.scl.ui.outline;
2
3 import java.util.ArrayList;
4 import java.util.Comparator;
5 import java.util.List;
6
7 import org.eclipse.jface.resource.JFaceResources;
8 import org.eclipse.jface.resource.LocalResourceManager;
9 import org.eclipse.jface.viewers.DelegatingStyledCellLabelProvider;
10 import org.eclipse.jface.viewers.DelegatingStyledCellLabelProvider.IStyledLabelProvider;
11 import org.eclipse.jface.viewers.ILabelProviderListener;
12 import org.eclipse.jface.viewers.ISelection;
13 import org.eclipse.jface.viewers.ITreeContentProvider;
14 import org.eclipse.jface.viewers.SelectionChangedEvent;
15 import org.eclipse.jface.viewers.StyledString;
16 import org.eclipse.jface.viewers.TreeSelection;
17 import org.eclipse.jface.viewers.TreeViewer;
18 import org.eclipse.swt.graphics.Image;
19 import org.eclipse.swt.widgets.Composite;
20 import org.eclipse.ui.views.contentoutline.ContentOutlinePage;
21 import org.simantics.scl.compiler.elaboration.modules.SCLValue;
22 import org.simantics.scl.compiler.environment.filter.AcceptAllNamespaceFilter;
23 import org.simantics.scl.compiler.errors.Failable;
24 import org.simantics.scl.compiler.errors.Locations;
25 import org.simantics.scl.compiler.module.Module;
26 import org.simantics.scl.compiler.module.repository.UpdateListener;
27 import org.simantics.scl.compiler.source.ModuleSource;
28 import org.simantics.scl.compiler.types.TCon;
29 import org.simantics.scl.osgi.SCLOsgi;
30 import org.simantics.scl.ui.Activator;
31 import org.simantics.scl.ui.editor2.SCLModuleEditor2;
32 import org.simantics.scl.ui.editor2.SCLModuleEditorInput;
33 import org.simantics.utils.ui.SWTUtils;
34
35 public class SCLModuleOutlinePage extends ContentOutlinePage {
36
37     private TreeViewer outlineViewer;
38     private SCLModuleEditor2 moduleEditor;
39     private UpdateListener updateListener;
40     private LocalResourceManager resourceManager;
41     private Image publicImage;
42     private Image privateImage;
43     private Image typeImage;
44
45     public SCLModuleOutlinePage(SCLModuleEditor2 moduleEditor) {
46         this.moduleEditor = moduleEditor;
47         resourceManager = new LocalResourceManager(JFaceResources.getResources());
48         publicImage = resourceManager
49                 .createImage(Activator.imageDescriptorFromPlugin(Activator.PLUGIN_ID, "icons/public_co.gif"));
50         privateImage = resourceManager
51                 .createImage(Activator.imageDescriptorFromPlugin(Activator.PLUGIN_ID, "icons/private_co.gif"));
52         typeImage = resourceManager
53                 .createImage(Activator.imageDescriptorFromPlugin(Activator.PLUGIN_ID, "icons/typedef_obj.gif"));
54     }
55
56     @Override
57     public void createControl(Composite parent) {
58         super.createControl(parent);
59         outlineViewer = getTreeViewer();
60
61         SCLModuleOutlineProvider provider = new SCLModuleOutlineProvider();
62         DelegatingStyledCellLabelProvider labelProvider = new DelegatingStyledCellLabelProvider(provider);
63         outlineViewer.setContentProvider(provider);
64         outlineViewer.setLabelProvider(labelProvider);
65         outlineViewer.addSelectionChangedListener(this);
66
67         SCLModuleEditorInput input = (SCLModuleEditorInput) moduleEditor.getEditorInput();
68         ModuleSource moduleSource = input.getAdapter(ModuleSource.class);
69         updateListener = new UpdateListener() {
70
71             @Override
72             public void notifyAboutUpdate() {
73                 if (parent.isDisposed())
74                     return;
75                 
76                 Failable<Module> module = SCLOsgi.MODULE_REPOSITORY.getModule(moduleSource.getModuleName(), updateListener);
77                 SWTUtils.asyncExec(parent, () -> {
78                     if (!outlineViewer.getControl().isDisposed()) {
79                         outlineViewer.setInput(module.didSucceed() ? module.getResult() : null);
80                         outlineViewer.refresh();
81                     }
82                 });
83             }
84         };
85         
86         updateListener.notifyAboutUpdate();
87     }
88
89     @Override
90     public void selectionChanged(SelectionChangedEvent event) {
91         super.selectionChanged(event);
92         ISelection selection = event.getSelection();
93         TreeSelection tselection = (TreeSelection) selection;
94         if (tselection.getFirstElement() instanceof SCLValue) {
95             SCLValue value = (SCLValue) tselection.getFirstElement();
96             long location = value.definitionLocation;
97             int begin = Locations.beginOf(location);
98             int end = Locations.endOf(location);
99             moduleEditor.selectAndReveal(begin, end - begin);
100         } else {
101 //            TCon type = (TCon) tselection.getFirstElement();
102 //            type.loction; // this is missing? 
103         }
104     }
105
106     @Override
107     public void dispose() {
108         resourceManager.dispose();
109         super.dispose();
110     }
111
112     protected class SCLModuleOutlineProvider implements ITreeContentProvider, IStyledLabelProvider {
113
114         @Override
115         public Object[] getElements(Object inputElement) {
116             Module result = (Module) inputElement;
117             List<SCLValue> values = new ArrayList<>();
118             result.findValuesForPrefix("", AcceptAllNamespaceFilter.INSTANCE, value -> {
119                 values.add(value);
120             });
121             values.sort(new Comparator<SCLValue>() {
122
123                 @Override
124                 public int compare(SCLValue o1, SCLValue o2) {
125                     int isPrivate = Boolean.compare(o1.isPrivate(), o2.isPrivate());
126                     if (isPrivate != 0)
127                         return isPrivate;
128                     else
129                         return o1.getName().name.compareTo(o2.getName().name);
130                 }
131             });
132             List<TCon> types = new ArrayList<>();
133             result.findTypesForPrefix("", AcceptAllNamespaceFilter.INSTANCE, type -> {
134                 types.add(type);
135             });
136             types.sort(new Comparator<TCon>() {
137
138                 @Override
139                 public int compare(TCon o1, TCon o2) {
140                     return o1.name.compareTo(o2.name);
141                 }
142             });
143             List<Object> results = new ArrayList<>();
144             results.addAll(types);
145             results.addAll(values);
146             return results.toArray();
147         }
148
149         @Override
150         public Object[] getChildren(Object parentElement) {
151             return null;
152         }
153
154         @Override
155         public Object getParent(Object element) {
156             return null;
157         }
158
159         @Override
160         public boolean hasChildren(Object element) {
161             return false;
162         }
163
164         @Override
165         public void addListener(ILabelProviderListener listener) {
166
167         }
168
169         @Override
170         public boolean isLabelProperty(Object element, String property) {
171             return false;
172         }
173
174         @Override
175         public void removeListener(ILabelProviderListener listener) {
176
177         }
178
179         @Override
180         public Image getImage(Object element) {
181             if (element instanceof SCLValue) {
182                 SCLValue value = (SCLValue) element;
183                 if (value.isPrivate()) {
184                     return privateImage;
185                 } else {
186                     return publicImage;
187                 }
188             } else if (element instanceof TCon) {
189                 return typeImage;
190             } else {
191                 return null;
192             }
193         }
194
195         @Override
196         public void dispose() {
197             ITreeContentProvider.super.dispose();
198         }
199
200         @Override
201         public StyledString getStyledText(Object element) {
202             if (element instanceof SCLValue) {
203                 SCLValue value = (SCLValue) element;
204                 StyledString ss = new StyledString(value.getName().name);
205                 ss.append(" :: " + value.getType().toString(), StyledString.COUNTER_STYLER);
206                 return ss;
207             } else {
208                 TCon type = (TCon) element;
209                 return new StyledString(type.name);
210             }
211         }
212     }
213 }