Skip to content

Package: AbstractJFaceTreeRenderer$2

AbstractJFaceTreeRenderer$2

nameinstructionbranchcomplexitylinemethod
hasChildren(Object)
M: 0 C: 53
100%
M: 0 C: 8
100%
M: 0 C: 5
100%
M: 0 C: 7
100%
M: 0 C: 1
100%
{...}
M: 0 C: 10
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%

Coverage

1: /*******************************************************************************
2: * Copyright (c) 2011-2019 EclipseSource Muenchen GmbH and others.
3: *
4: * All rights reserved. This program and the accompanying materials
5: * are made available under the terms of the Eclipse Public License 2.0
6: * which accompanies this distribution, and is available at
7: * https://www.eclipse.org/legal/epl-2.0/
8: *
9: * SPDX-License-Identifier: EPL-2.0
10: *
11: * Contributors:
12: * Edagr Mueller - initial API and implementation
13: * Eugen Neufeld - Refactoring
14: * Johannes Faltermeier - Refactoring
15: * Christian W. Damus - bug 548592
16: ******************************************************************************/
17: package org.eclipse.emf.ecp.view.spi.categorization.swt;
18:
19: import java.util.ArrayList;
20: import java.util.Iterator;
21: import java.util.List;
22:
23: import org.eclipse.core.runtime.IStatus;
24: import org.eclipse.core.runtime.Status;
25: import org.eclipse.emf.common.notify.AdapterFactory;
26: import org.eclipse.emf.common.util.EList;
27: import org.eclipse.emf.ecore.EObject;
28: import org.eclipse.emf.ecp.edit.internal.swt.util.OverlayImageDescriptor;
29: import org.eclipse.emf.ecp.view.internal.categorization.swt.Activator;
30: import org.eclipse.emf.ecp.view.spi.categorization.model.VAbstractCategorization;
31: import org.eclipse.emf.ecp.view.spi.categorization.model.VCategorizableElement;
32: import org.eclipse.emf.ecp.view.spi.categorization.model.VCategorizationElement;
33: import org.eclipse.emf.ecp.view.spi.categorization.model.VCategorizationPackage.Literals;
34: import org.eclipse.emf.ecp.view.spi.categorization.model.VCategory;
35: import org.eclipse.emf.ecp.view.spi.context.ViewModelContext;
36: import org.eclipse.emf.ecp.view.spi.model.ModelChangeListener;
37: import org.eclipse.emf.ecp.view.spi.model.ModelChangeNotification;
38: import org.eclipse.emf.ecp.view.spi.model.VElement;
39: import org.eclipse.emf.ecp.view.spi.model.reporting.StatusReport;
40: import org.eclipse.emf.ecp.view.spi.renderer.NoPropertyDescriptorFoundExeption;
41: import org.eclipse.emf.ecp.view.spi.renderer.NoRendererFoundException;
42: import org.eclipse.emf.ecp.view.spi.swt.reporting.RenderingFailedReport;
43: import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
44: import org.eclipse.emf.edit.provider.ITableItemLabelProvider;
45: import org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider;
46: import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider;
47: import org.eclipse.emfforms.spi.common.report.ReportService;
48: import org.eclipse.emfforms.spi.swt.core.AbstractSWTRenderer;
49: import org.eclipse.emfforms.spi.swt.core.EMFFormsNoRendererException;
50: import org.eclipse.emfforms.spi.swt.core.EMFFormsRendererFactory;
51: import org.eclipse.emfforms.spi.swt.core.SWTDataElementIdHelper;
52: import org.eclipse.emfforms.spi.swt.core.layout.GridDescriptionFactory;
53: import org.eclipse.emfforms.spi.swt.core.layout.SWTGridCell;
54: import org.eclipse.emfforms.spi.swt.core.layout.SWTGridDescription;
55: import org.eclipse.emfforms.spi.swt.core.ui.SWTValidationHelper;
56: import org.eclipse.jface.layout.GridDataFactory;
57: import org.eclipse.jface.layout.GridLayoutFactory;
58: import org.eclipse.jface.resource.ImageDescriptor;
59: import org.eclipse.jface.viewers.ISelectionChangedListener;
60: import org.eclipse.jface.viewers.SelectionChangedEvent;
61: import org.eclipse.jface.viewers.StructuredSelection;
62: import org.eclipse.jface.viewers.TreeSelection;
63: import org.eclipse.jface.viewers.TreeViewer;
64: import org.eclipse.jface.viewers.Viewer;
65: import org.eclipse.jface.viewers.ViewerFilter;
66: import org.eclipse.swt.SWT;
67: import org.eclipse.swt.custom.SashForm;
68: import org.eclipse.swt.custom.ScrolledComposite;
69: import org.eclipse.swt.custom.TreeEditor;
70: import org.eclipse.swt.events.DisposeEvent;
71: import org.eclipse.swt.events.DisposeListener;
72: import org.eclipse.swt.events.TreeEvent;
73: import org.eclipse.swt.events.TreeListener;
74: import org.eclipse.swt.graphics.Image;
75: import org.eclipse.swt.graphics.Point;
76: import org.eclipse.swt.widgets.Composite;
77: import org.eclipse.swt.widgets.Control;
78: import org.eclipse.swt.widgets.Tree;
79: import org.eclipse.swt.widgets.TreeColumn;
80: import org.eclipse.swt.widgets.TreeItem;
81: import org.eclipse.swt.widgets.Widget;
82:
83: /**
84: * Abstract class for a tree renderer.
85: *
86: * @author Eugen Neufeld
87: *
88: * @param <VELEMENT> the {@link VElement}
89: */
90: public abstract class AbstractJFaceTreeRenderer<VELEMENT extends VElement> extends AbstractSWTRenderer<VELEMENT> {
91:
92:         private final EMFFormsRendererFactory emfFormsRendererFactory;
93:
94:         private EMFFormsRendererFactory getEMFFormsRendererFactory() {
95:                 return emfFormsRendererFactory;
96:         }
97:
98:         /**
99:          * Default constructor.
100:          *
101:          * @param vElement the view model element to be rendered
102:          * @param viewContext the view context
103:          * @param reportService the {@link ReportService}
104:          * @param emfFormsRendererFactory The {@link EMFFormsRendererFactory}
105:          * @since 1.6
106:          */
107:         public AbstractJFaceTreeRenderer(VELEMENT vElement, ViewModelContext viewContext, ReportService reportService,
108:                 EMFFormsRendererFactory emfFormsRendererFactory) {
109:                 super(vElement, viewContext, reportService);
110:                 this.emfFormsRendererFactory = emfFormsRendererFactory;
111:         }
112:
113:         private SWTGridDescription gridDescription;
114:         private TreeViewer treeViewer;
115:         private AbstractJFaceTreeRenderer<VELEMENT>.TreeSelectionChangedListener treeSelectionChangedListener;
116:
117:         @Override
118:         public SWTGridDescription getGridDescription(SWTGridDescription gridDescription) {
119:                 if (this.gridDescription == null) {
120:                         this.gridDescription = GridDescriptionFactory.INSTANCE.createSimpleGrid(1, 1, this);
121:                 }
122:                 return this.gridDescription;
123:         }
124:
125:         /**
126:          * {@inheritDoc}
127:          *
128:          * @see org.eclipse.emfforms.spi.swt.core.AbstractSWTRenderer#dispose()
129:          */
130:         @Override
131:         protected void dispose() {
132:                 gridDescription = null;
133:                 getViewModelContext().unregisterViewChangeListener(treeSelectionChangedListener);
134:                 super.dispose();
135:         }
136:
137:         /**
138:          * {@inheritDoc}
139:          *
140:          * @see org.eclipse.emfforms.spi.swt.core.AbstractSWTRenderer#renderControl(int, org.eclipse.swt.widgets.Composite,
141:          * org.eclipse.emf.ecp.view.spi.model.VElement, org.eclipse.emf.ecp.view.spi.context.ViewModelContext)
142:          */
143:
144:         @Override
145:         protected Control renderControl(SWTGridCell cell, Composite parent) throws NoRendererFoundException,
146:                 NoPropertyDescriptorFoundExeption {
147:                 final EList<VAbstractCategorization> categorizations = getCategorizations();
148:
149:                 if (categorizations.size() == 1 && categorizations.get(0) instanceof VCategory) {
150:                         final VElement child = getCategorizations().get(0);
151:                         AbstractSWTRenderer<VElement> renderer;
152:                         try {
153:                                 renderer = getEMFFormsRendererFactory().getRendererInstance(child,
154:                                         getViewModelContext());
155:                         } catch (final EMFFormsNoRendererException ex) {
156:                                 getReportService().report(
157:                                         new StatusReport(
158:                                                 new Status(IStatus.INFO, Activator.PLUGIN_ID, String.format(
159:                                                         "No Renderer for %s found.", child.eClass().getName(), ex)))); //$NON-NLS-1$
160:                                 return null;
161:                         }
162:                         final Control render = renderer.render(cell, parent);
163:                         renderer.finalizeRendering(parent);
164:                         SWTDataElementIdHelper.setElementIdDataWithSubId(render, getVElement(), "vcategory", getViewModelContext()); //$NON-NLS-1$
165:                         return render;
166:
167:                 }
168:
169:                 final Object detailPane = getViewModelContext().getContextValue("detailPane"); //$NON-NLS-1$
170:                 if (detailPane != null && Composite.class.isInstance(detailPane)) {
171:                         treeViewer = createTreeViewer(parent);
172:
173:                         final ScrolledComposite editorComposite = createdEditorPane(Composite.class.cast(detailPane));
174:
175:                         setupTreeViewer(treeViewer, editorComposite);
176:
177:                         initTreeViewer(treeViewer);
178:                         Composite.class.cast(detailPane).layout();
179:                         SWTDataElementIdHelper.setElementIdDataWithSubId(treeViewer.getControl(), getVElement(), "tree", //$NON-NLS-1$
180:                                 getViewModelContext());
181:                         return treeViewer.getControl();
182:                 }
183:
184:                 final SashForm sashForm = new SashForm(parent, SWT.HORIZONTAL);
185:                 GridDataFactory.fillDefaults().grab(true, true).align(SWT.FILL, SWT.FILL).applyTo(sashForm);
186:
187:                 treeViewer = createTreeViewer(sashForm);
188:
189:                 final ScrolledComposite editorComposite = createdEditorPane(sashForm);
190:
191:                 setupTreeViewer(treeViewer, editorComposite);
192:
193:                 initTreeViewer(treeViewer);
194:                 sashForm.setWeights(new int[] { 1, 3 });
195:                 SWTDataElementIdHelper.setElementIdDataWithSubId(treeViewer.getControl(), getVElement(), "tree", //$NON-NLS-1$
196:                         getViewModelContext());
197:                 SWTDataElementIdHelper.setElementIdDataWithSubId(sashForm, getVElement(), "sash", getViewModelContext()); //$NON-NLS-1$
198:                 return sashForm;
199:         }
200:
201:         /**
202:          * Creates a {@link TreeViewer}. Sub classes can override to influence the {@link TreeViewer}.
203:          *
204:          * @param parent the parent {@link Composite}
205:          * @return a {@link TreeViewer}
206:          * @since 1.14
207:          */
208:         protected TreeViewer createTreeViewer(Composite parent) {
209:                 return new TreeViewer(parent, SWT.SINGLE);
210:         }
211:
212:         /**
213:          * The list of categorizations to display in the tree.
214:          *
215:          * @return the list of {@link VAbstractCategorization}
216:          */
217:         protected abstract EList<VAbstractCategorization> getCategorizations();
218:
219:         /**
220:          * The VCategorizationElement to set the current selection onto.
221:          *
222:          * @return the VCategorizationElement
223:          */
224:         protected abstract VCategorizationElement getCategorizationElement();
225:
226:         /**
227:          * Created editor pane.
228:          *
229:          * @param composite the composite
230:          * @return the created editor composite
231:          */
232:         protected ScrolledComposite createdEditorPane(Composite composite) {
233:                 final ScrolledComposite editorComposite = createScrolledComposite(composite);
234:                 editorComposite.setExpandHorizontal(true);
235:                 editorComposite.setExpandVertical(true);
236:                 editorComposite.setShowFocusedControl(true);
237:
238:                 GridDataFactory.fillDefaults().grab(true, true).align(SWT.FILL, SWT.FILL).applyTo(editorComposite);
239:
240:                 return editorComposite;
241:         }
242:
243:         /**
244:          * Creates the scrolled composite.
245:          *
246:          * @param parent the parent
247:          * @return the scrolled composite
248:          */
249:         private ScrolledComposite createScrolledComposite(Composite parent) {
250:                 final ScrolledComposite scrolledComposite = new ScrolledComposite(parent, SWT.V_SCROLL | SWT.H_SCROLL
251:                         | SWT.BORDER);
252:                 scrolledComposite.setShowFocusedControl(true);
253:                 scrolledComposite.setExpandVertical(true);
254:                 scrolledComposite.setExpandHorizontal(true);
255:                 scrolledComposite.setBackground(parent.getBackground());
256:
257:                 return scrolledComposite;
258:         }
259:
260:         /**
261:          * Configures the passed tree viewer.
262:          *
263:          * @param treeViewer the {@link TreeViewer} to configure
264:          * @param editorComposite the composite of the editor
265:          */
266:         protected void setupTreeViewer(final TreeViewer treeViewer,
267:
268:                 final ScrolledComposite editorComposite) {
269:                 treeViewer.addFilter(new ViewerFilter() {
270:
271:                         @Override
272:                         public boolean select(Viewer viewer, Object parentElement, Object element) {
273:                                 return VCategorizableElement.class.isInstance(element) && ((VCategorizableElement) element).isVisible();
274:                         }
275:                 });
276:                 GridDataFactory.fillDefaults().align(SWT.BEGINNING, SWT.FILL).grab(false, true).hint(400, SWT.DEFAULT)
277:                         .applyTo(treeViewer.getTree());
278:
279:                 final List<TreeEditor> editors = new ArrayList<TreeEditor>();
280:
281:                 final ComposedAdapterFactory adapterFactory = new ComposedAdapterFactory(
282:                         ComposedAdapterFactory.Descriptor.Registry.INSTANCE);
283:
284:                 final AdapterFactoryContentProvider contentProvider = new AdapterFactoryContentProvider(
285:                         adapterFactory) {
286:
287:                         @Override
288:                         public boolean hasChildren(Object object) {
289:
290:                                 final boolean hasChildren = super.hasChildren(object);
291:•                                if (hasChildren) {
292:•                                        for (final Object o : getChildren(object)) {
293:•                                                for (final ViewerFilter viewerFilter : treeViewer.getFilters()) {
294:•                                                        if (viewerFilter.select(treeViewer, object, o)) {
295:                                                                 return true;
296:                                                         }
297:                                                 }
298:                                         }
299:                                 }
300:                                 return false;
301:                         }
302:
303:                 };
304:
305:                 final TreeTableLabelProvider treeTableLabelProvider = getTreeLabelProvider(treeViewer, adapterFactory);
306:                 treeViewer.getTree().addDisposeListener(new DisposeListener() {
307:
308:                         @Override
309:                         public void widgetDisposed(DisposeEvent event) {
310:                                 contentProvider.dispose();
311:                                 treeTableLabelProvider.dispose();
312:                                 adapterFactory.dispose();
313:                         }
314:                 });
315:
316:                 treeViewer.setContentProvider(contentProvider);
317:                 treeViewer.setLabelProvider(treeTableLabelProvider);
318:
319:                 treeSelectionChangedListener = new TreeSelectionChangedListener(
320:                         getViewModelContext(), editorComposite,
321:                         getCategorizationElement(),
322:                         treeViewer, editors);
323:                 treeViewer.addSelectionChangedListener(treeSelectionChangedListener);
324:                 getViewModelContext().registerViewChangeListener(treeSelectionChangedListener);
325:
326:                 addTreeEditor(treeViewer, getVElement(), editors);
327:
328:         }
329:
330:         /**
331:          * The TreeTableLabel provider.
332:          *
333:          * @param treeViewer the {@link TreeViewer}
334:          * @param adapterFactory the {@link AdapterFactory} to use
335:          * @return the created {@link TreeTableLabelProvider}
336:          * @since 1.9
337:          */
338:         protected TreeTableLabelProvider getTreeLabelProvider(TreeViewer treeViewer, AdapterFactory adapterFactory) {
339:                 return new TreeTableLabelProvider(adapterFactory, treeViewer);
340:         }
341:
342:         /**
343:          * Inits the tree viewer.
344:          *
345:          * @param treeViewer the tree viewer
346:          */
347:         protected void initTreeViewer(final TreeViewer treeViewer) {
348:
349:                 treeViewer.setInput(getVElement());
350:                 treeViewer.expandAll();
351:                 if (getCategorizationElement().getCurrentSelection() != null) {
352:                         treeViewer.setSelection(new StructuredSelection(getCategorizationElement().getCurrentSelection()));
353:                 } else if (getCategorizations().size() != 0) {
354:                         treeViewer.setSelection(new StructuredSelection(getCategorizations().get(0)));
355:                 }
356:         }
357:
358:         /**
359:          * Creates the composite.
360:          *
361:          * @param parent the parent
362:          * @return the composite
363:          */
364:         private Composite createComposite(Composite parent) {
365:                 final Composite composite = new Composite(parent, SWT.NONE);
366:                 composite.setBackground(parent.getBackground());
367:
368:                 GridLayoutFactory.fillDefaults().numColumns(2).equalWidth(false).margins(7, 7).applyTo(composite);
369:                 GridDataFactory.fillDefaults().grab(true, true).align(SWT.FILL, SWT.FILL).applyTo(composite);
370:                 return composite;
371:         }
372:
373:         /**
374:          * Adds the tree editor.
375:          *
376:          * @param treeViewer the tree viewer
377:          * @param view the view
378:          * @param editors the list of tree editors
379:          */
380:         protected void addTreeEditor(final TreeViewer treeViewer, EObject view,
381:                 final List<TreeEditor> editors) {
382:                 // The text column
383:                 final Tree tree = treeViewer.getTree();
384:                 int maxActions = 0;
385:                 final Iterator<EObject> viewContents = view.eAllContents();
386:                 while (viewContents.hasNext()) {
387:                         final EObject object = viewContents.next();
388:                         if (VAbstractCategorization.class.isInstance(object)) {
389:                                 final VAbstractCategorization abstractCategorization = (VAbstractCategorization) object;
390:                                 if (maxActions < abstractCategorization.getActions().size()) {
391:                                         maxActions = abstractCategorization.getActions().size();
392:                                 }
393:
394:                                 // I render this view-model element
395:                                 register(abstractCategorization);
396:                         }
397:                 }
398:                 if (maxActions == 0) {
399:                         return;
400:                 }
401:                 final TreeColumn columnText = new TreeColumn(tree, SWT.NONE);
402:                 columnText.setWidth(300);
403:                 columnText.setAlignment(SWT.FILL);
404:
405:                 for (int i = 0; i < maxActions; i++) {
406:                         // The column
407:                         final TreeColumn column = new TreeColumn(tree, SWT.NONE);
408:                         column.setWidth(50);
409:
410:                         final TreeEditor editor = new TreeEditor(tree);
411:                         // The editor must have the same size as the cell and must
412:                         // not be any smaller than 50 pixels.
413:                         editor.horizontalAlignment = SWT.CENTER;
414:                         editor.grabHorizontal = true;
415:                         editor.minimumWidth = 50;
416:                         editor.setColumn(i + 1);
417:
418:                         editors.add(editor);
419:                 }
420:
421:                 tree.addTreeListener(new TreeListener() {
422:
423:                         @Override
424:                         public void treeExpanded(TreeEvent e) {
425:                         }
426:
427:                         @Override
428:                         public void treeCollapsed(TreeEvent e) {
429:                                 cleanUpTreeEditors(editors);
430:                         }
431:                 });
432:
433:         }
434:
435:         // Clean up any previous editor control
436:         /**
437:          * Clean up tree editors.
438:          */
439:         private void cleanUpTreeEditors(List<TreeEditor> editors) {
440:                 for (final TreeEditor editor : editors) {
441:                         final Control oldEditor = editor.getEditor();
442:                         if (oldEditor != null) {
443:                                 oldEditor.dispose();
444:                         }
445:                 }
446:         }
447:
448:         /**
449:          * Adds the buttons.
450:          *
451:          * @param treeViewer the tree viewer
452:          * @param treeSelection the tree selection
453:          * @param editors the list of tree editors
454:          */
455:         protected void addButtons(final TreeViewer treeViewer, TreeSelection treeSelection,
456:                 List<TreeEditor> editors) {
457:
458:                 cleanUpTreeEditors(editors);
459:
460:                 if (treeSelection.getPaths().length == 0) {
461:                         return;
462:                 }
463:
464:                 // Identify the selected row
465:                 final TreeItem item = treeViewer.getTree().getSelection()[0];
466:                 if (item == null) {
467:                         return;
468:                 }
469:
470:                 final VCategorizableElement object = (VCategorizableElement) treeSelection.getFirstElement();
471:                 if (object.getECPActions() == null) {
472:                         return;
473:                 }
474:                 for (int i = 0; i < object.getECPActions().size(); i++) {
475:                         final ECPTreeViewAction action = (ECPTreeViewAction) object.getECPActions().get(i);
476:                         final TreeEditor editor = editors.get(i);
477:                         action.init(treeViewer, treeSelection, editor);
478:                         action.execute();
479:                 }
480:         }
481:
482:         /**
483:          * Reveal the control that renders the given {@code categorization}.
484:          *
485:          * @param categorization a categorization to reveal
486:          * @return whether the {@code categorization} was successfully revealed
487:          *
488:          * @since 1.22
489:          */
490:         public boolean showCategorization(VAbstractCategorization categorization) {
491:                 // If there's only one categorization, we won't have a tree viewer. But then
492:                 // the categorization is always revealed, so we would have nothing to do
493:                 if (treeViewer != null) {
494:                         treeViewer.setSelection(new StructuredSelection(categorization));
495:                 }
496:                 return true;
497:         }
498:
499:         /**
500:          * The change listener for selections of the tree.
501:          *
502:          * @author Jonas Helming
503:          *
504:          */
505:         private final class TreeSelectionChangedListener implements ISelectionChangedListener, ModelChangeListener {
506:                 private final ViewModelContext viewModelContext;
507:                 private final ScrolledComposite editorComposite;
508:                 private final VCategorizationElement vCategorizationElement;
509:                 private final TreeViewer treeViewer;
510:                 private final List<TreeEditor> editors;
511:                 private Composite childComposite;
512:
513:                 private boolean busy;
514:
515:                 private TreeSelectionChangedListener(ViewModelContext viewModelContext,
516:                         ScrolledComposite editorComposite, VCategorizationElement vCategorizationElement, TreeViewer treeViewer,
517:                         List<TreeEditor> editors) {
518:                         this.viewModelContext = viewModelContext;
519:                         this.editorComposite = editorComposite;
520:                         this.vCategorizationElement = vCategorizationElement;
521:                         this.treeViewer = treeViewer;
522:                         this.editors = editors;
523:                 }
524:
525:                 @Override
526:                 public void selectionChanged(SelectionChangedEvent event) {
527:
528:                         final TreeSelection treeSelection = (TreeSelection) event.getSelection();
529:                         final Object selection = treeSelection.getFirstElement();
530:                         addButtons(treeViewer, treeSelection, editors);
531:
532:                         if (selection == null) {
533:                                 return;
534:                         }
535:                         onSelectionChanged(VElement.class.cast(selection));
536:                 }
537:
538:                 public void onSelectionChanged(VElement child) {
539:
540:                         if (busy) {
541:                                 return;
542:                         }
543:
544:                         busy = true;
545:                         try {
546:                                 if (childComposite != null) {
547:                                         childComposite.dispose();
548:                                         childComposite = null;
549:                                 }
550:                                 childComposite = createComposite(editorComposite);
551:
552:                                 childComposite.setBackground(editorComposite.getBackground());
553:                                 editorComposite.setContent(childComposite);
554:
555:                                 try {
556:
557:                                         AbstractSWTRenderer<VElement> renderer;
558:                                         try {
559:                                                 renderer = getEMFFormsRendererFactory().getRendererInstance(child,
560:                                                         viewModelContext);
561:                                         } catch (final EMFFormsNoRendererException ex) {
562:                                                 getReportService().report(
563:                                                         new StatusReport(
564:                                                                 new Status(IStatus.INFO, Activator.PLUGIN_ID, String.format(
565:                                                                         "No Renderer for %s found.", child.eClass().getName(), ex)))); //$NON-NLS-1$
566:                                                 return;
567:                                         }
568:                                         // we have a VCategory-> thus only one element in the grid
569:                                         final Control render = renderer.render(
570:                                                 renderer.getGridDescription(GridDescriptionFactory.INSTANCE.createEmptyGridDescription())
571:                                                         .getGrid()
572:                                                         .get(0),
573:                                                 childComposite);
574:                                         renderer.finalizeRendering(childComposite);
575:                                         GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).grab(true, true)
576:                                                 .minSize(SWT.DEFAULT, 200)
577:                                                 .applyTo(render);
578:                                         if (VCategorizableElement.class.isInstance(child)) {
579:                                                 vCategorizationElement.setCurrentSelection((VCategorizableElement) child);
580:                                         }
581:                                 } catch (final NoRendererFoundException e) {
582:                                         getReportService().report(new RenderingFailedReport(e));
583:                                 } catch (final NoPropertyDescriptorFoundExeption e) {
584:                                         getReportService().report(new RenderingFailedReport(e));
585:                                 }
586:
587:                                 childComposite.layout();
588:                                 final Point point = childComposite.computeSize(SWT.DEFAULT, SWT.DEFAULT);
589:                                 editorComposite.setMinSize(point);
590:
591:                         } finally {
592:                                 busy = false;
593:                         }
594:
595:                 }
596:
597:                 /**
598:                  * {@inheritDoc}
599:                  *
600:                  * @see org.eclipse.emf.ecp.view.spi.model.ModelChangeListener#notifyChange(org.eclipse.emf.ecp.view.spi.model.ModelChangeNotification)
601:                  */
602:                 @Override
603:                 public void notifyChange(ModelChangeNotification notification) {
604:                         if (notification.getNotifier() instanceof VCategorizationElement
605:                                 && notification.getStructuralFeature() == Literals.CATEGORIZATION_ELEMENT__CURRENT_SELECTION) {
606:                                 /* call on selection changed if the new child is part of our subtree */
607:                                 final Object currentSelection = notification.getRawNotification().getNewValue();
608:                                 if (VElement.class.isInstance(currentSelection)) {
609:                                         final VElement child = VElement.class.cast(currentSelection);
610:                                         EObject parent = child;
611:                                         while (EObject.class.isInstance(parent)) {
612:                                                 if (parent == getVElement()) {
613:                                                         onSelectionChanged(child);
614:                                                         break;
615:                                                 }
616:                                                 parent = parent.eContainer();
617:                                         }
618:                                 }
619:                         }
620:
621:                 }
622:
623:         }
624:
625:         /**
626:          * The Class TreeTableLabelProvider.
627:          */
628:         protected class TreeTableLabelProvider extends AdapterFactoryLabelProvider implements ITableItemLabelProvider {
629:
630:                 private final TreeViewer treeViewer;
631:
632:                 /**
633:                  * Instantiates a new tree table label provider.
634:                  *
635:                  * @param adapterFactory the adapter factory
636:                  * @param treeViewer the tree viewer
637:                  * @since 1.9
638:                  */
639:                 public TreeTableLabelProvider(AdapterFactory adapterFactory, TreeViewer treeViewer) {
640:                         super(adapterFactory);
641:                         this.treeViewer = treeViewer;
642:                 }
643:
644:                 @Override
645:                 public String getColumnText(Object object, int columnIndex) {
646:                         adjustItemData(object);
647:                         String text = super.getColumnText(object, columnIndex);
648:                         if (columnIndex == 0 && VCategorizableElement.class.isInstance(object)) {
649:                                 text = super.getColumnText(((VCategorizableElement) object).getLabelObject(), columnIndex);
650:                         }
651:                         return text;
652:                 }
653:
654:                 // XXX is there a better way to get informed when there are new TreeItems and to access the TreeItems?
655:                 // the problem is double-edged:
656:                 // 1. the content-provider is responsible for updating the tree, but we cannot listen to it
657:                 // 2. TreeItems might be removed/recreated without being able to listen for this
658:                 // the workaround is to plug in to the label provider. when a treeitem is created/changed it needs a display
659:                 // text, so we can access the treeitem and should be called on all relevant changes
660:                 private void adjustItemData(Object object) {
661:                         if (!VElement.class.isInstance(object)) {
662:                                 return;
663:                         }
664:                         final Widget widget = treeViewer.testFindItem(object);
665:                         if (widget == null) {
666:                                 return;
667:                         }
668:                         if (widget.getData(SWTDataElementIdHelper.ELEMENT_ID_KEY) != null) {
669:                                 /* already set */
670:                                 return;
671:                         }
672:                         final VElement element = VElement.class.cast(object);
673:                         SWTDataElementIdHelper.setElementIdDataWithSubId(widget, element, "treeItem", getViewModelContext()); //$NON-NLS-1$
674:                 }
675:
676:                 /**
677:                  * {@inheritDoc}
678:                  *
679:                  * @see org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider#getText(java.lang.Object)
680:                  */
681:                 @Override
682:                 public String getText(Object object) {
683:                         adjustItemData(object);
684:                         String text;
685:                         if (VCategorizableElement.class.isInstance(object)) {
686:                                 text = super.getText(((VCategorizableElement) object).getLabelObject());
687:                         } else {
688:                                 text = super.getText(object);
689:                         }
690:                         return text;
691:                 }
692:
693:                 @Override
694:                 public Image getColumnImage(Object object, int columnIndex) {
695:
696:                         if (columnIndex != 0) {
697:                                 return null;
698:                         }
699:                         Image image = super.getColumnImage(object, columnIndex);
700:                         if (VCategorizableElement.class.isInstance(object)) {
701:                                 image = super.getColumnImage(((VCategorizableElement) object).getLabelObject(), columnIndex);
702:                         }
703:
704:                         return getValidationOverlay(image, (VElement) object);
705:                 }
706:
707:                 /**
708:                  * {@inheritDoc}
709:                  *
710:                  * @see org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider#getImage(java.lang.Object)
711:                  */
712:                 @Override
713:                 public Image getImage(Object object) {
714:                         Image image;
715:                         if (VCategorizableElement.class.isInstance(object)) {
716:                                 image = super.getImage(((VCategorizableElement) object).getLabelObject());
717:                         } else {
718:                                 image = super.getImage(object);
719:                         }
720:
721:                         return getValidationOverlay(image, (VElement) object);
722:                 }
723:
724:                 /**
725:                  * This method generated an image with a validation overlay if necessary.
726:                  *
727:                  * @param image the image to overlay
728:                  * @param categorization the {@link VElement} to get the validation for
729:                  * @return the Image
730:                  */
731:                 protected Image getValidationOverlay(Image image, final VElement categorization) {
732:                         ImageDescriptor overlay = null;
733:
734:                         if (categorization.getDiagnostic() == null) {
735:                                 return image;
736:                         }
737:                         overlay = SWTValidationHelper.INSTANCE.getValidationOverlayDescriptor(categorization.getDiagnostic()
738:                                 .getHighestSeverity(), getVElement(), getViewModelContext());
739:
740:                         if (overlay == null) {
741:                                 return image;
742:                         }
743:                         final OverlayImageDescriptor imageDescriptor = new OverlayImageDescriptor(image, overlay,
744:                                 OverlayImageDescriptor.LOWER_RIGHT);
745:                         final Image resultImage = imageDescriptor.createImage();
746:
747:                         return resultImage;
748:                 }
749:
750:         }
751:
752: }