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