Skip to content
Snippets Groups Projects
Commit 9c6a70bc authored by Simon Barner's avatar Simon Barner
Browse files

- Install {@link Adapter} to watch for the addition or removal of model...

- Install {@link Adapter} to watch for the addition or removal of model elements to/from elements visible in this {@link AnnotationViewPartBase} (to trigger according updates).
- Ensure that all annotations for all offspring of the currently selected are shown in the view
- AnnotationViewPartBase no longer maintains a protected attribute with the list of current annotation entries, but triggers the abstract update(Collection<AnnotationEntry>) method at the right occasions (to be implemented by concrete views).
- Possible improvement in GenericAnnotationView: efficient implementation of update(Collection<AnnotationEntry>) (instead of complete redraw).
refs 1841
parent 90c20e8f
No related branches found
No related tags found
No related merge requests found
......@@ -17,9 +17,16 @@ $Id$
+--------------------------------------------------------------------------*/
package org.fortiss.tooling.base.ui.annotation.view;
import java.util.ArrayList;
import java.util.List;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Set;
import java.util.TreeSet;
import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.ISelectionListener;
......@@ -30,7 +37,9 @@ import org.fortiss.tooling.base.ui.annotation.AnnotationEntry;
import org.fortiss.tooling.base.ui.annotation.IAnnotationValueService;
import org.fortiss.tooling.base.ui.editpart.DiagramEditPartBase;
import org.fortiss.tooling.base.ui.editpart.ElementEditPartBase;
import org.fortiss.tooling.kernel.model.IProjectRootElement;
import org.fortiss.tooling.kernel.ui.util.SelectionUtils;
import org.fortiss.tooling.kernel.utils.EcoreUtils;
/**
* This class provides a limited set of variables and methods to annotation views. Its main purposes
......@@ -47,8 +56,27 @@ public abstract class AnnotationViewPartBase extends ViewPart implements ISelect
/** the currently selected object */
private IModelElement currentlySelectedObject;
/** List of all Annotation entries of the {@link #currentlySelectedObject} */
protected List<AnnotationEntry> annotationEntryList = new ArrayList<AnnotationEntry>();
/**
* Set of {@link IModelElement}s for which the {@link #changeListener} has been installed to
* watch for model changes (to trigger an update of this {@link AnnotationViewPartBase}).
*/
Set<IModelElement> watchedModelElements = new HashSet<IModelElement>();
/**
* {@link Adapter} to watch for the addition or removal of model elements to/from elements
* visible in this {@link AnnotationViewPartBase} (to trigger according updates).
*/
private final Adapter changeListener = new AdapterImpl() {
@Override
public void notifyChanged(Notification notification) {
if((notification.getEventType() == Notification.ADD) ||
(notification.getEventType() == Notification.REMOVE)) {
if(notification.getNewValue() instanceof IModelElement) {
update((IModelElement)notification.getNewValue());
}
}
}
};
/** {@inheritDoc} */
@Override
......@@ -59,19 +87,99 @@ public abstract class AnnotationViewPartBase extends ViewPart implements ISelect
if(currentlySelectedObject == null) {
ElementEditPartBase<?> editPart =
SelectionUtils.checkAndPickFirst(selection, ElementEditPartBase.class);
if(editPart != null)
if(editPart != null) {
currentlySelectedObject = (IModelElement)editPart.getModel();
else {
} else {
// Not all editors are derived from ElementEditPartBase, most notably
// PlatformArchitectureDiagramEditPart
DiagramEditPartBase<?> diagramPart =
SelectionUtils.checkAndPickFirst(selection, DiagramEditPartBase.class);
if(diagramPart != null)
if(diagramPart != null) {
currentlySelectedObject = (IModelElement)diagramPart.getModel();
}
}
}
if(currentlySelectedObject != null) {
update(currentlySelectedObject);
}
}
/** Update registration of model listeners. */
private void updateChangeListener(Collection<AnnotationEntry> annotationEntryList) {
// Determine all root elements
Set<EObject> rootElements = new HashSet<EObject>();
for(AnnotationEntry entry : annotationEntryList) {
EObject rootElement = entry.getModelElement();
while(!(rootElement instanceof IProjectRootElement)) {
rootElement = rootElement.eContainer();
}
rootElements.add(rootElement);
}
// Determine all IModelElements below the current root elements
Set<IModelElement> currentWatchedModelElements = new HashSet<IModelElement>();
for(EObject rootElement : rootElements) {
for(EObject modelElement : EcoreUtils.getChildrenWithType(rootElement,
IModelElement.class)) {
currentWatchedModelElements.add((IModelElement)modelElement);
}
if(rootElement instanceof IModelElement) {
currentWatchedModelElements.add((IModelElement)rootElement);
}
}
// Add change listeners to IModelElements that are about to appear in the view
Set<IModelElement> tmpWatchedModelElements =
new HashSet<IModelElement>(currentWatchedModelElements);
tmpWatchedModelElements.removeAll(watchedModelElements);
for(EObject modelElement : tmpWatchedModelElements) {
modelElement.eAdapters().add(changeListener);
}
// Remove change listeners IModelElements that are about to disappear from the view
tmpWatchedModelElements = new HashSet<IModelElement>(watchedModelElements);
tmpWatchedModelElements.removeAll(currentWatchedModelElements);
for(EObject modelElement : tmpWatchedModelElements) {
modelElement.eAdapters().remove(changeListener);
}
annotationEntryList = IAnnotationValueService.INSTANCE.getValues(currentlySelectedObject);
watchedModelElements = currentWatchedModelElements;
}
/**
* Update the {@link AnnotationViewPartBase}: delegate update of concrete view to
* {@link #update(Collection)}, and update model change listeners.
*/
private void update(IModelElement modelElement) {
Set<AnnotationEntry> annotationEntries =
new TreeSet<AnnotationEntry>(new Comparator<AnnotationEntry>() {
/** Compare AnnotationEntries by the model element they refer to. */
@Override
public int compare(AnnotationEntry a1, AnnotationEntry a2) {
// Equality of model element implies equal hashCode(), order is arbitrary
// but not relevant for
// ensuring uniqueness of annotation entries.
return Integer.compare(a1.getModelElement().hashCode(), a2
.getModelElement().hashCode());
}
});
// Collect all AnnotationEntries for the current model element and its offspring
annotationEntries.addAll(IAnnotationValueService.INSTANCE.getValues(modelElement));
for(IModelElement childModelElement : EcoreUtils.getChildrenWithType(modelElement,
IModelElement.class)) {
annotationEntries.addAll(IAnnotationValueService.INSTANCE.getValues(childModelElement));
}
// Update the view
update(annotationEntries);
updateChangeListener(annotationEntries);
}
/** Update concrete view */
protected abstract void update(Collection<AnnotationEntry> annotationEntries);
/** {@inheritDoc} */
@Override
public void createPartControl(Composite parent) {
......@@ -87,6 +195,12 @@ public abstract class AnnotationViewPartBase extends ViewPart implements ISelect
@Override
public void dispose() {
getSite().getWorkbenchWindow().getSelectionService().removeSelectionListener(this);
for(EObject modelElement : watchedModelElements) {
modelElement.eAdapters().remove(changeListener);
}
watchedModelElements.clear();
super.dispose();
}
}
......@@ -18,6 +18,7 @@ $Id$
package org.fortiss.tooling.base.ui.annotation.view;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
......@@ -26,7 +27,6 @@ import org.eclipse.emf.common.util.EMap;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.jface.viewers.EditingSupport;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.swt.SWT;
......@@ -34,7 +34,6 @@ import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Table;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.wb.swt.SWTResourceManager;
import org.fortiss.tooling.base.model.element.IAnnotatedSpecification;
import org.fortiss.tooling.base.ui.annotation.AnnotationEntry;
......@@ -77,30 +76,14 @@ public class GenericAnnotationView extends AnnotationViewPartBase {
/** {@inheritDoc} */
@Override
public void createPartControl(Composite parent) {
super.createPartControl(parent);
Composite c = new Composite(parent, SWT.NULL);
c.setLayout(new FillLayout(SWT.HORIZONTAL));
tableViewer = new TableViewer(c, SWT.BORDER | SWT.FULL_SELECTION);
Table table = tableViewer.getTable();
table.setHeaderVisible(true);
table.setLinesVisible(true);
createModelElementColumn();
}
/** {@inheritDoc} */
@Override
public void selectionChanged(IWorkbenchPart part, ISelection selection) {
super.selectionChanged(part, selection);
createSingleInstanceAnnotationColumns();
createMultiInstanceAnnotationColumns();
protected void update(Collection<AnnotationEntry> annotationEntries) {
updateSingleInstanceAnnotationColumns(annotationEntries);
updateMultiInstanceAnnotationColumns(annotationEntries);
}
/** Create columns for ordinary (single instance) {@link IAnnotatedSpecification}s */
private void createSingleInstanceAnnotationColumns() {
private void
updateSingleInstanceAnnotationColumns(Collection<AnnotationEntry> annotationEntries) {
/*
* disposes all columns of the table viewer, except the first column, which holds the names
* of the model elements
......@@ -115,7 +98,7 @@ public class GenericAnnotationView extends AnnotationViewPartBase {
* is no additional columns created for those specification which already have an associated
* column or provide complex values.
*/
for(AnnotationEntry entry : annotationEntryList) {
for(AnnotationEntry entry : annotationEntries) {
for(IAnnotatedSpecification spec : entry.getSpecificationsList()) {
if(!isExistingColumn(spec) &&
!entry.allowsMultipleAnnoationInstances(spec.getClass())) {
......@@ -125,11 +108,12 @@ public class GenericAnnotationView extends AnnotationViewPartBase {
}
if(!tableViewer.getTable().isDisposed())
tableViewer.setInput(annotationEntryList);
tableViewer.setInput(annotationEntries);
}
/** Create columns for multi-instance {@link IAnnotatedSpecification}s */
private void createMultiInstanceAnnotationColumns() {
private void
updateMultiInstanceAnnotationColumns(Collection<AnnotationEntry> annotationEntries) {
for(CreateAnnotationInstanceColumn col : createColumns) {
col.dispose();
}
......@@ -144,7 +128,7 @@ public class GenericAnnotationView extends AnnotationViewPartBase {
* 'code specsAllowingMultipleValues'.
*/
List<String> specClassNamesMult = new ArrayList<String>();
for(AnnotationEntry entry : annotationEntryList) {
for(AnnotationEntry entry : annotationEntries) {
for(IAnnotatedSpecification spec : entry.getSpecificationsList()) {
if(entry.allowsMultipleAnnoationInstances(spec.getClass()) &&
!specClassNamesMult.contains(spec.getClass().getSimpleName())) {
......@@ -182,6 +166,21 @@ public class GenericAnnotationView extends AnnotationViewPartBase {
tableViewer.refresh();
}
/** {@inheritDoc} */
@Override
public void createPartControl(Composite parent) {
super.createPartControl(parent);
Composite c = new Composite(parent, SWT.NULL);
c.setLayout(new FillLayout(SWT.HORIZONTAL));
tableViewer = new TableViewer(c, SWT.BORDER | SWT.FULL_SELECTION);
Table table = tableViewer.getTable();
table.setHeaderVisible(true);
table.setLinesVisible(true);
createModelElementColumn();
}
/** Creates the (leading) column which displays the model elements */
protected void createModelElementColumn() {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment