1 package org.eclipse.e4.tools.emf.ui.internal.common.objectdata;
2 
3 import java.util.Collection;
4 import java.util.Collections;
5 
6 import org.eclipse.core.databinding.observable.value.IObservableValue;
7 import org.eclipse.core.databinding.property.value.IValueProperty;
8 import org.eclipse.core.runtime.CoreException;
9 import org.eclipse.core.runtime.IConfigurationElement;
10 import org.eclipse.core.runtime.IExtensionPoint;
11 import org.eclipse.core.runtime.IExtensionRegistry;
12 import org.eclipse.core.runtime.RegistryFactory;
13 import org.eclipse.e4.tools.emf.ui.common.IScriptingSupport;
14 import org.eclipse.e4.tools.emf.ui.internal.Messages;
15 import org.eclipse.e4.tools.emf.ui.internal.ResourceProvider;
16 import org.eclipse.e4.tools.emf.ui.internal.common.ModelEditor;
17 import org.eclipse.e4.tools.services.IResourcePool;
18 import org.eclipse.e4.ui.model.application.MApplicationElement;
19 import org.eclipse.e4.ui.model.internal.ModelUtils;
20 import org.eclipse.emf.databinding.EMFProperties;
21 import org.eclipse.emf.ecore.EStructuralFeature;
22 import org.eclipse.jface.action.Action;
23 import org.eclipse.jface.action.MenuManager;
24 import org.eclipse.jface.viewers.ColumnViewer;
25 import org.eclipse.jface.viewers.ColumnViewerToolTipSupport;
26 import org.eclipse.jface.viewers.IStructuredSelection;
27 import org.eclipse.jface.viewers.ITreeContentProvider;
28 import org.eclipse.jface.viewers.StyledCellLabelProvider;
29 import org.eclipse.jface.viewers.StyledString;
30 import org.eclipse.jface.viewers.TreeViewer;
31 import org.eclipse.jface.viewers.Viewer;
32 import org.eclipse.jface.viewers.ViewerCell;
33 import org.eclipse.jface.viewers.ViewerComparator;
34 import org.eclipse.jface.window.ToolTip;
35 import org.eclipse.swt.SWT;
36 import org.eclipse.swt.layout.GridData;
37 import org.eclipse.swt.layout.GridLayout;
38 import org.eclipse.swt.widgets.Composite;
39 import org.eclipse.swt.widgets.Event;
40 import org.eclipse.swt.widgets.Label;
41 
42 public class ObjectViewer {
createViewer(Composite parent, EStructuralFeature feature, final IObservableValue<?> master, IResourcePool resourcePool, final Messages messages)43 	public TreeViewer createViewer(Composite parent, EStructuralFeature feature, final IObservableValue<?> master,
44 			IResourcePool resourcePool, final Messages messages) {
45 		final TreeViewer viewer = new TreeViewer(parent);
46 		viewer.setContentProvider(new ContentProviderImpl());
47 		viewer.setLabelProvider(new LabelProviderImpl(resourcePool));
48 		viewer.setComparator(new ViewerComparatorImpl());
49 		@SuppressWarnings("unchecked")
50 		final IValueProperty<Object, Object> property = EMFProperties.value(feature);
51 		final IObservableValue<Object> value = property.observeDetail(master);
52 		value.addValueChangeListener(event -> {
53 			if (event.diff.getNewValue() != null) {
54 				viewer.setInput(Collections.singleton(new JavaObject(event.diff.getNewValue())));
55 				viewer.expandToLevel(2);
56 			} else {
57 				viewer.setInput(Collections.emptyList());
58 			}
59 		});
60 
61 		final IExtensionRegistry registry = RegistryFactory.getRegistry();
62 		final IExtensionPoint extPoint = registry.getExtensionPoint("org.eclipse.e4.tools.emf.ui.scripting"); //$NON-NLS-1$
63 		final IConfigurationElement[] elements = extPoint.getConfigurationElements();
64 
65 		if (elements.length > 0) {
66 			final MenuManager mgr = new MenuManager();
67 			mgr.setRemoveAllWhenShown(true);
68 			mgr.addMenuListener(manager -> {
69 				if (viewer.getSelection().isEmpty()) {
70 					return;
71 				}
72 
73 				final MenuManager scriptExecute = new MenuManager(messages.ObjectViewer_Script);
74 				mgr.add(scriptExecute);
75 				for (final IConfigurationElement e : elements) {
76 					final IConfigurationElement le = e;
77 					scriptExecute.add(new Action(e.getAttribute("label")) { //$NON-NLS-1$
78 						@Override
79 						public void run() {
80 							try {
81 								final IScriptingSupport support = (IScriptingSupport) le
82 										.createExecutableExtension("class"); //$NON-NLS-1$
83 								final Object o = ((IStructuredSelection) viewer.getSelection()).getFirstElement();
84 								Object mainObject = null;
85 								if (o instanceof JavaObject) {
86 									mainObject = ((JavaObject) o).getInstance();
87 								} else if (o instanceof JavaAttribute) {
88 									mainObject = ((JavaAttribute) o).getFieldValue();
89 								}
90 
91 								if (mainObject != null) {
92 									final MApplicationElement value = (MApplicationElement) master.getValue();
93 									support.openEditor(viewer.getControl().getShell(), mainObject,
94 											ModelUtils.getContainingContext(value));
95 								}
96 							} catch (final CoreException e) {
97 								// TODO Auto-generated catch block
98 								e.printStackTrace();
99 							}
100 						}
101 					});
102 				}
103 			});
104 
105 			viewer.getControl().setMenu(mgr.createContextMenu(viewer.getControl()));
106 		}
107 
108 		new TooltipSupportImpl(viewer, ToolTip.NO_RECREATE, false, resourcePool, messages);
109 		return viewer;
110 	}
111 
112 	class TooltipSupportImpl extends ColumnViewerToolTipSupport {
113 		private final IResourcePool resourcePool;
114 		private final Messages messages;
115 
TooltipSupportImpl(ColumnViewer viewer, int style, boolean manualActivation, IResourcePool resourcePool, Messages messages)116 		protected TooltipSupportImpl(ColumnViewer viewer, int style, boolean manualActivation,
117 				IResourcePool resourcePool, Messages messages) {
118 			super(viewer, style, manualActivation);
119 			this.resourcePool = resourcePool;
120 			this.messages = messages;
121 		}
122 
123 		@Override
createViewerToolTipContentArea(Event event, ViewerCell cell, Composite parent)124 		protected Composite createViewerToolTipContentArea(Event event, ViewerCell cell, Composite parent) {
125 			final JavaAttribute attribute = (JavaAttribute) cell.getElement();
126 
127 			final Composite container = new Composite(parent, SWT.NONE);
128 			container.setBackground(container.getDisplay().getSystemColor(SWT.COLOR_WHITE));
129 			container.setLayout(new GridLayout(2, false));
130 
131 			{
132 				final Composite headerContainer = new Composite(container, SWT.NONE);
133 				headerContainer.setBackgroundMode(SWT.INHERIT_DEFAULT);
134 				headerContainer.setData(ModelEditor.CSS_CLASS_KEY, "headerSectionContainer"); //$NON-NLS-1$
135 				final GridLayout fl = new GridLayout(2, false);
136 				fl.marginHeight = 5;
137 				fl.marginWidth = 5;
138 				headerContainer.setLayout(fl);
139 				headerContainer.setLayoutData(new GridData(GridData.FILL, GridData.BEGINNING, true, false, 2, 1));
140 
141 				final Label iconLabel = new Label(headerContainer, SWT.NONE);
142 				iconLabel.setImage(resourcePool.getImageUnchecked(ResourceProvider.IMG_Obj16_bullet_go));
143 
144 				final Label textLabel = new Label(headerContainer, SWT.NONE);
145 				textLabel.setText(attribute.getName());
146 				textLabel.setData(ModelEditor.CSS_CLASS_KEY, "sectionHeader"); //$NON-NLS-1$
147 			}
148 
149 			{
150 				Label l = new Label(container, SWT.NONE);
151 				l.setText(messages.ObjectViewer_Tooltip_Value);
152 
153 				l = new Label(container, SWT.NONE);
154 				l.setText(attribute.getValue());
155 			}
156 
157 			{
158 				Label l = new Label(container, SWT.NONE);
159 				l.setText(messages.ObjectViewer_Tooltip_InjectionKey);
160 
161 				l = new Label(container, SWT.NONE);
162 				l.setText(attribute.getContextKey());
163 			}
164 
165 			return container;
166 		}
167 	}
168 
169 	class ViewerComparatorImpl extends ViewerComparator {
170 		@Override
compare(Viewer viewer, Object e1, Object e2)171 		public int compare(Viewer viewer, Object e1, Object e2) {
172 			if (e1 instanceof JavaAttribute) {
173 				if (e2 instanceof JavaAttribute) {
174 					final JavaAttribute a1 = (JavaAttribute) e1;
175 					final JavaAttribute a2 = (JavaAttribute) e2;
176 
177 					if (a1.isStatic() && !a2.isStatic()) {
178 						return -1;
179 					} else if (!a1.isStatic() && a2.isStatic()) {
180 						return 1;
181 					}
182 
183 					final int rv = Integer.valueOf(a1.getAccessLevel().value).compareTo(a2.getAccessLevel().value);
184 					if (rv == 0) {
185 						return a1.getName().compareTo(a2.getName());
186 					}
187 					return rv;
188 				}
189 				return -1;
190 			}
191 			return super.compare(viewer, e1, e2);
192 		}
193 	}
194 
195 	class LabelProviderImpl extends StyledCellLabelProvider {
196 
197 		private final IResourcePool resourcePool;
198 
LabelProviderImpl(IResourcePool resourcePool)199 		public LabelProviderImpl(IResourcePool resourcePool) {
200 			this.resourcePool = resourcePool;
201 		}
202 
203 		@Override
getToolTipText(Object element)204 		public String getToolTipText(Object element) {
205 			if (element instanceof JavaAttribute && ((JavaAttribute) element).isInjected()) {
206 				return "Show Tooltip"; //$NON-NLS-1$
207 			}
208 			return super.getToolTipText(element);
209 		}
210 
211 		@Override
update(ViewerCell cell)212 		public void update(ViewerCell cell) {
213 			if (cell.getElement() instanceof JavaObject) {
214 				final JavaObject o = (JavaObject) cell.getElement();
215 				cell.setImage(resourcePool.getImageUnchecked(ResourceProvider.IMG_Obj16_class_obj));
216 				cell.setText(o.getName());
217 			} else if (cell.getElement() instanceof JavaAttribute) {
218 				final JavaAttribute o = (JavaAttribute) cell.getElement();
219 				final StyledString string = new StyledString();
220 				if (o.isInjected()) {
221 					string.append("<injected> ", StyledString.COUNTER_STYLER); //$NON-NLS-1$
222 				}
223 				string.append(o.getName());
224 				string.append(" : " + o.getType() + " - " + o.getValue(), StyledString.DECORATIONS_STYLER); //$NON-NLS-1$ //$NON-NLS-2$
225 				cell.setText(string.getString());
226 				cell.setStyleRanges(string.getStyleRanges());
227 				switch (o.getAccessLevel()) {
228 				case PUBLIC:
229 					cell.setImage(resourcePool.getImageUnchecked(ResourceProvider.IMG_Obj16_field_public_obj));
230 					break;
231 				case PRIVATE:
232 					cell.setImage(resourcePool.getImageUnchecked(ResourceProvider.IMG_Obj16_field_private_obj));
233 					break;
234 				case DEFAULT:
235 					cell.setImage(resourcePool.getImageUnchecked(ResourceProvider.IMG_Obj16_field_default_obj));
236 					break;
237 				default:
238 					cell.setImage(resourcePool.getImageUnchecked(ResourceProvider.IMG_Obj16_field_protected_obj));
239 					break;
240 				}
241 			}
242 
243 			super.update(cell);
244 		}
245 	}
246 
247 	class ContentProviderImpl implements ITreeContentProvider {
248 
249 		@Override
dispose()250 		public void dispose() {
251 
252 		}
253 
254 		@Override
inputChanged(Viewer viewer, Object oldInput, Object newInput)255 		public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
256 
257 		}
258 
259 		@Override
getElements(Object inputElement)260 		public Object[] getElements(Object inputElement) {
261 			return ((Collection<?>) inputElement).toArray();
262 
263 		}
264 
265 		@Override
getChildren(Object parentElement)266 		public Object[] getChildren(Object parentElement) {
267 			if (parentElement instanceof JavaObject) {
268 				return ((JavaObject) parentElement).getAttributes().toArray();
269 			} else if (parentElement instanceof JavaAttribute) {
270 				return ((JavaAttribute) parentElement).getAttributes().toArray();
271 			}
272 			return new Object[0];
273 		}
274 
275 		@Override
getParent(Object element)276 		public Object getParent(Object element) {
277 			// TODO Auto-generated method stub
278 			return null;
279 		}
280 
281 		@Override
hasChildren(Object element)282 		public boolean hasChildren(Object element) {
283 			return getChildren(element).length > 0;
284 		}
285 
286 	}
287 }
288