From 0888161dfc1e59a36d149bb29c32ce425508c593 Mon Sep 17 00:00:00 2001
From: Simon Barner <barner@fortiss.org>
Date: Thu, 11 Sep 2014 12:54:50 +0000
Subject: [PATCH] - Move AnnotationFilter to dedicate file - Add
 GenericAnnotationView.setFixedAnnotationFilter(). It can be used to install
 an externally created filter instead of the filter option GUI. This can be
 used to embed GenericAnnotationView in another widget, and to restrict its
 scope accordingly. refs 1841

---
 .../ui/annotation/view/AnnotationFilter.java  | 215 ++++++++++++
 .../view/GenericAnnotationView.java           | 315 ++++++------------
 2 files changed, 309 insertions(+), 221 deletions(-)
 create mode 100644 org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/view/AnnotationFilter.java

diff --git a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/view/AnnotationFilter.java b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/view/AnnotationFilter.java
new file mode 100644
index 000000000..05eb433e8
--- /dev/null
+++ b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/view/AnnotationFilter.java
@@ -0,0 +1,215 @@
+/*--------------------------------------------------------------------------+
+$Id$
+|                                                                          |
+| Copyright 2014 ForTISS GmbH                     |
+|                                                                          |
+| Licensed under the Apache License, Version 2.0 (the "License");          |
+| you may not use this file except in compliance with the License.         |
+| You may obtain a copy of the License at                                  |
+|                                                                          |
+|    http://www.apache.org/licenses/LICENSE-2.0                            |
+|                                                                          |
+| Unless required by applicable law or agreed to in writing, software      |
+| distributed under the License is distributed on an "AS IS" BASIS,        |
+| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
+| See the License for the specific language governing permissions and      |
+| limitations under the License.                                           |
++--------------------------------------------------------------------------*/
+package org.fortiss.tooling.base.ui.annotation.view;
+
+import java.util.Collection;
+
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+import org.fortiss.tooling.base.model.element.IAnnotatedSpecification;
+import org.fortiss.tooling.base.model.element.IModelElement;
+import org.fortiss.tooling.base.ui.annotation.AnnotationEntry;
+import org.fortiss.tooling.base.ui.annotation.view.GenericAnnotationView.ColumnHandle;
+import org.fortiss.tooling.kernel.model.INamedElement;
+import org.fortiss.tooling.kernel.model.IProjectRootElement;
+
+/**
+ * Row and column filter for the {@link GenericAnnotationView}. Row filtering is realized by
+ * inheriting {@link ViewerFilter}, whereas for column filtering is supported by
+ * {@link AnnotationFilter#passesColumnFilter(ColumnHandle)} that is evaluated in
+ * {@link GenericAnnotationView#update(Collection)}.
+ */
+class AnnotationFilter extends ViewerFilter {
+	/** Filter hint text. */
+	static final String FILTER_HINT_TEXT = "type filter text";
+
+	/** Hierarchy filter option: all model elements from any level */
+	static final String HIERARCHY_LEVELS_ALL = "Show all levels";
+
+	/** Hierarchy filter option: all model elements from current level */
+	static final String HIERARCHY_LEVELS_CURRENT = "Show current level";
+
+	/** Hierarchy filter option: currently selected model element and its offspring */
+	static final String HIERARCHY_LEVELS_SELECTED_SUBMODEL = "Show selected sub-model";
+
+	/** Current model element / annotation name filter pattern */
+	private String filterPattern;
+
+	/** Flag whether columns / annotation names should be filtered. */
+	private boolean filterColumnName;
+
+	/** Flag whether rows / model element names should be filtered */
+	private boolean filterRowName;
+
+	/** Currently selected model element (may be {@code null}). */
+	private IModelElement currentySelectedModelElement;
+
+	/**
+	 * Flag whether the displayed rows should be restricted to the currently selected model
+	 * element type.
+	 */
+	boolean restrictToSelectedModelElementType;
+
+	/** Row filter option based on hierarchy level of model element. */
+	private String hierarchyLevelFilter;
+
+	/** Column filter option based on annotation type */
+	private Class<? extends IAnnotatedSpecification> annotationTypeFilter;
+
+	/** {@inheritDoc} */
+	@Override
+	public boolean select(Viewer viewer, Object parentElement, Object element) {
+		if(!(element instanceof AnnotationEntry)) {
+			return true;
+		}
+
+		AnnotationEntry annotationEntry = ((AnnotationEntry)element);
+		if(!(annotationEntry.getModelElement() instanceof INamedElement)) {
+			return true;
+		}
+
+		return passesRowFilter(annotationEntry);
+	}
+
+	/**
+	 * Returns {@code true} if a given {@code input} passes an case-insensitive filter specified
+	 * by {@code filterString}.
+	 */
+	private boolean passesNameFilter(String input) {
+		// Null-filter accepts every input
+		if(filterPattern == null || filterPattern.equals(FILTER_HINT_TEXT)) {
+			return true;
+		}
+
+		// Null-input cannot be accepted by a non-null filter
+		if(input == null) {
+			return false;
+		}
+		return input.toLowerCase().contains(filterPattern.toLowerCase());
+	}
+
+	/**
+	 * Returns {@code true} if given annotation entry matches the currently selected model
+	 * element (or if this particular filter option is turned off).
+	 */
+	private boolean passesSelectedElementTypeFilter(AnnotationEntry annotationEntry) {
+		if(currentySelectedModelElement == null ||
+				currentySelectedModelElement instanceof IProjectRootElement ||
+				hierarchyLevelFilter == null) {
+			return true;
+		}
+
+		int currentlySelectedModelElementLevel =
+				GenericAnnotationView.getModelElementLevel(currentySelectedModelElement);
+		int modelElementLevel =
+				GenericAnnotationView.getModelElementLevel(annotationEntry.getModelElement());
+
+		if(hierarchyLevelFilter.equals(HIERARCHY_LEVELS_CURRENT)) {
+			if((GenericAnnotationView.getModelElementLevel(annotationEntry.getModelElement()) != currentlySelectedModelElementLevel) ||
+					(currentySelectedModelElement.eContainer() != GenericAnnotationView
+							.getModelElementAncestor(annotationEntry.getModelElement(),
+									modelElementLevel - (currentlySelectedModelElementLevel - 1)))) {
+				return false;
+			}
+		}
+		if(hierarchyLevelFilter.equals(HIERARCHY_LEVELS_SELECTED_SUBMODEL)) {
+			if(modelElementLevel < currentlySelectedModelElementLevel) {
+				return false;
+			}
+
+			if((modelElementLevel > currentlySelectedModelElementLevel) &&
+					((currentySelectedModelElement != GenericAnnotationView
+							.getModelElementAncestor(annotationEntry.getModelElement(),
+									modelElementLevel - currentlySelectedModelElementLevel))) ||
+					(currentySelectedModelElement != GenericAnnotationView.getModelElementAncestor(
+							annotationEntry.getModelElement(), modelElementLevel -
+									(currentlySelectedModelElementLevel - 0)))) {
+				return false;
+			}
+
+		}
+
+		return !restrictToSelectedModelElementType ||
+				annotationEntry.getModelElement().getClass()
+						.equals(currentySelectedModelElement.getClass());
+	}
+
+	/** Returns true if the given specification passes the current annotation type filter */
+	private boolean passesAnnotationTypeFilter(IAnnotatedSpecification spec) {
+		return annotationTypeFilter == null || spec.getClass().equals(annotationTypeFilter);
+	}
+
+	/**
+	 * Returns {@code true} if the column represented by the given column is visible in the
+	 * view.
+	 */
+	public boolean passesColumnFilter(ColumnHandle columnHandle) {
+		return (!filterColumnName || passesNameFilter(columnHandle.getColumnName())) &&
+				passesSelectedElementTypeFilter(columnHandle.getEntry()) &&
+				passesAnnotationTypeFilter(columnHandle.getAnnotatedSpecification());
+	}
+
+	/**
+	 * Returns {@code true} if the rows represented by {@code annotationEntry} are visible
+	 * in the view.
+	 */
+	public boolean passesRowFilter(AnnotationEntry annotationEntry) {
+		if(!(annotationEntry.getModelElement() instanceof INamedElement)) {
+			return true;
+		}
+
+		return (!filterRowName || passesNameFilter(((INamedElement)annotationEntry
+				.getModelElement()).getName())) && passesSelectedElementTypeFilter(annotationEntry);
+	}
+
+	/** Sets the model element / annotation name filter pattern. */
+	public void setNameFilterPattern(String filterPattern) {
+		this.filterPattern = filterPattern;
+	}
+
+	/** Sets the flag whether rows should be filtered by name. */
+	public void setFilterRowName(boolean filterRowName) {
+		this.filterRowName = filterRowName;
+	}
+
+	/** Sets the flag whether columns should be filtered by name. */
+	public void setFilterColumnName(boolean filterColumnName) {
+		this.filterColumnName = filterColumnName;
+	}
+
+	/** Sets the flag whether the view should be filtered by the selected model element type. */
+	public void setRestrictToSelectedModelElementType(boolean restrictToSelectedModelElementType) {
+		this.restrictToSelectedModelElementType = restrictToSelectedModelElementType;
+	}
+
+	/** Sets the model element hierarchy level filter option. */
+	public void setHierarchyLevelFilter(String hierarchyLevelFilter) {
+		this.hierarchyLevelFilter = hierarchyLevelFilter;
+	}
+
+	/** Sets the annotation type filter option. */
+	public void setAnnotationTypeFilter(
+			Class<? extends IAnnotatedSpecification> annotationTypeFilter) {
+		this.annotationTypeFilter = annotationTypeFilter;
+	}
+
+	/** Sets the currently selected model element (may be {@code null}). */
+	public void setCurrentySelectedModelElement(IModelElement currentySelectedModelElement) {
+		this.currentySelectedModelElement = currentySelectedModelElement;
+	}
+}
diff --git a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/view/GenericAnnotationView.java b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/view/GenericAnnotationView.java
index 6c1ae64c4..10ab1e7a0 100644
--- a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/view/GenericAnnotationView.java
+++ b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/view/GenericAnnotationView.java
@@ -31,13 +31,13 @@ import org.eclipse.jface.viewers.TableViewer;
 import org.eclipse.jface.viewers.TableViewerColumn;
 import org.eclipse.jface.viewers.Viewer;
 import org.eclipse.jface.viewers.ViewerComparator;
-import org.eclipse.jface.viewers.ViewerFilter;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.custom.CCombo;
 import org.eclipse.swt.events.ModifyEvent;
 import org.eclipse.swt.events.ModifyListener;
 import org.eclipse.swt.events.SelectionAdapter;
 import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.layout.FillLayout;
 import org.eclipse.swt.layout.GridData;
 import org.eclipse.swt.layout.GridLayout;
 import org.eclipse.swt.layout.RowLayout;
@@ -56,7 +56,6 @@ import org.fortiss.tooling.base.ui.annotation.editingsupport.ElementNameEditingS
 import org.fortiss.tooling.base.ui.annotation.valueprovider.IAnnotationValueProvider;
 import org.fortiss.tooling.base.ui.widget.ExtendedCCombo;
 import org.fortiss.tooling.kernel.model.INamedElement;
-import org.fortiss.tooling.kernel.model.IProjectRootElement;
 
 /**
  * <p>
@@ -76,21 +75,17 @@ import org.fortiss.tooling.kernel.model.IProjectRootElement;
  * @ConQAT.Rating YELLOW Hash: D91763408246ECD3578DAD0E37BC4C41
  */
 public class GenericAnnotationView extends AnnotationViewPartBase {
+	/** Root composite of {@link GenericAnnotationView}. */
+	Composite rootComposite;
 
 	/** The table viewer */
 	protected TableViewer tableViewer;
 
-	/**
-	 * Character used to separate the annotation name from the instance name for multi-instance
-	 * annotations.
-	 */
-	private final static String MULTIINSTANCE_NAME_SEPARATOR = ":";
-
 	/** Row an column filter for annotations */
-	AnnotationFilter annotationFilter;
+	private AnnotationFilter annotationFilter;
 
 	/** Widget for filter options */
-	private AnnotationFilterWidget filterWidget;
+	private AnnotationFilterWidget annotationFilterWidget;
 
 	/**
 	 * Last set of {@link AnnotationEntry}s used to {@link #update(Collection)} the
@@ -105,7 +100,13 @@ public class GenericAnnotationView extends AnnotationViewPartBase {
 	 * a column of the {@link GenericAnnotationView}. Used to sort columns (see
 	 * {@link #compareTo(ColumnHandle)}).
 	 */
-	private class ColumnHandle implements Comparable<ColumnHandle> {
+	class ColumnHandle implements Comparable<ColumnHandle> {
+		/**
+		 * Character used to separate the annotation name from the instance name for multi-instance
+		 * annotations.
+		 */
+		private final static String MULTIINSTANCE_NAME_SEPARATOR = ":";
+
 		/**
 		 * {@link AnnotationEntry} from which a particular {@link IAnnotatedSpecification} is to be
 		 * displayed in the column represented by this {@link ColumnHandle}.
@@ -172,10 +173,32 @@ public class GenericAnnotationView extends AnnotationViewPartBase {
 			return isCreateColumn;
 		}
 
+		/**
+		 * Returns the name of a column for a given {@link IAnnotatedSpecification} represented by
+		 * the
+		 * given {@link ColumnHandle}.
+		 */
+		protected String getColumnName() {
+			// Determine column name
+			String specName =
+					getEntry().getSpecificationAnnotationName(
+							getAnnotatedSpecification().getClass());
+
+			if(getInstanceKey() != null) {
+				if(!specName.isEmpty()) {
+					specName += MULTIINSTANCE_NAME_SEPARATOR + " ";
+				}
+				specName += getInstanceKey();
+			} else if(specName == null || specName.isEmpty()) {
+				specName = "<Unnamed Annotation>";
+			}
+			return specName;
+		}
+
 		/** {@inheritDoc} */
 		@Override
 		public int compareTo(ColumnHandle other) {
-			String columnName = getColumnName(this);
+			String columnName = getColumnName();
 			String annotationName;
 
 			int columnNameSeparatorIndex = columnName.indexOf(MULTIINSTANCE_NAME_SEPARATOR);
@@ -185,7 +208,7 @@ public class GenericAnnotationView extends AnnotationViewPartBase {
 				annotationName = columnName;
 			}
 
-			String otherColumnName = getColumnName(other);
+			String otherColumnName = other.getColumnName();
 			String otherAnnotationName;
 			int otherColumnNameSeparatorIndex =
 					otherColumnName.indexOf(MULTIINSTANCE_NAME_SEPARATOR);
@@ -285,183 +308,6 @@ public class GenericAnnotationView extends AnnotationViewPartBase {
 		}
 	}
 
-	/**
-	 * Row and column filter for the {@link GenericAnnotationView}. Row filtering is realized by
-	 * inheriting {@link ViewerFilter}, whereas for column filtering is supported by
-	 * {@link AnnotationFilter#passesColumnFilter(ColumnHandle)} that is evaluated in
-	 * {@link GenericAnnotationView#update(Collection)}.
-	 */
-	private class AnnotationFilter extends ViewerFilter {
-		/** Filter hint text. */
-		private static final String FILTER_HINT_TEXT = "type filter text";
-
-		/** Hierarchy filter option: all model elements from any level */
-		private static final String HIERARCHY_LEVELS_ALL = "Show all levels";
-
-		/** Hierarchy filter option: all model elements from current level */
-		private static final String HIERARCHY_LEVELS_CURRENT = "Show current level";
-
-		/** Hierarchy filter option: currently selected model element and its offspring */
-		private static final String HIERARCHY_LEVELS_SELECTED_SUBMODEL = "Show selected sub-model";
-
-		/** Current model element / annotation name filter pattern */
-		private String filterPattern;
-
-		/** Flag whether columns / annotation names should be filtered. */
-		private boolean filterColumnName;
-
-		/** Flag whether rows / model element names should be filtered */
-		private boolean filterRowName;
-
-		/**
-		 * Flag whether the displayed rows should be restricted to the currently selected model
-		 * element type.
-		 */
-		boolean restrictToSelectedModelElementType;
-
-		/** Row filter option based on hierarchy level of model element. */
-		private String hierarchyLevelFilter;
-
-		/** Column filter option based on annotation type */
-		private Class<? extends IAnnotatedSpecification> annotationTypeFilter;
-
-		/** {@inheritDoc} */
-		@Override
-		public boolean select(Viewer viewer, Object parentElement, Object element) {
-			if(!(element instanceof AnnotationEntry)) {
-				return true;
-			}
-
-			AnnotationEntry annotationEntry = ((AnnotationEntry)element);
-			if(!(annotationEntry.getModelElement() instanceof INamedElement)) {
-				return true;
-			}
-
-			return passesRowFilter(annotationEntry);
-		}
-
-		/**
-		 * Returns {@code true} if a given {@code input} passes an case-insensitive filter specified
-		 * by {@code filterString}.
-		 */
-		private boolean passesNameFilter(String input) {
-			// Null-filter accepts every input
-			if(filterPattern == null || filterPattern.equals(FILTER_HINT_TEXT)) {
-				return true;
-			}
-
-			// Null-input cannot be accepted by a non-null filter
-			if(input == null) {
-				return false;
-			}
-			return input.toLowerCase().contains(filterPattern.toLowerCase());
-		}
-
-		/**
-		 * Returns {@code true} if given annotation entry matches the currently selected model
-		 * element (or if this particular filter option is turned off).
-		 */
-		private boolean passesSelectedElementTypeFilter(AnnotationEntry annotationEntry) {
-			if(getCurrentlySelectedObject() == null ||
-					getCurrentlySelectedObject() instanceof IProjectRootElement) {
-				return true;
-			}
-
-			int currentlySelectedObjectLevel = getModelElementLevel(getCurrentlySelectedObject());
-			int modelElementLevel = getModelElementLevel(annotationEntry.getModelElement());
-
-			if(hierarchyLevelFilter.equals(HIERARCHY_LEVELS_CURRENT)) {
-				if((getModelElementLevel(annotationEntry.getModelElement()) != currentlySelectedObjectLevel) ||
-						(getCurrentlySelectedObject().eContainer() != getModelElementAncestor(
-								annotationEntry.getModelElement(), modelElementLevel -
-										(currentlySelectedObjectLevel - 1)))) {
-					return false;
-				}
-			}
-			if(hierarchyLevelFilter.equals(HIERARCHY_LEVELS_SELECTED_SUBMODEL)) {
-				if(modelElementLevel < currentlySelectedObjectLevel) {
-					return false;
-				}
-
-				if((modelElementLevel > currentlySelectedObjectLevel) &&
-						((getCurrentlySelectedObject() != getModelElementAncestor(
-								annotationEntry.getModelElement(), modelElementLevel -
-										currentlySelectedObjectLevel))) ||
-						(getCurrentlySelectedObject() != getModelElementAncestor(
-								annotationEntry.getModelElement(), modelElementLevel -
-										(currentlySelectedObjectLevel - 0)))) {
-					return false;
-				}
-
-			}
-
-			return !restrictToSelectedModelElementType ||
-					annotationEntry.getModelElement().getClass()
-							.equals(getCurrentlySelectedObject().getClass());
-		}
-
-		/** Returns true if the given specification passes the current annotation type filter */
-		private boolean passesAnnotationTypeFilter(IAnnotatedSpecification spec) {
-			return annotationTypeFilter == null || spec.getClass().equals(annotationTypeFilter);
-		}
-
-		/**
-		 * Returns {@code true} if the column represented by the given column is visible in the
-		 * view.
-		 */
-		public boolean passesColumnFilter(ColumnHandle columnHandle) {
-			return (!filterColumnName || passesNameFilter(getColumnName(columnHandle))) &&
-					passesSelectedElementTypeFilter(columnHandle.getEntry()) &&
-					passesAnnotationTypeFilter(columnHandle.getAnnotatedSpecification());
-		}
-
-		/**
-		 * Returns {@code true} if the rows represented by {@code annotationEntry} are visible
-		 * in the view.
-		 */
-		public boolean passesRowFilter(AnnotationEntry annotationEntry) {
-			if(!(annotationEntry.getModelElement() instanceof INamedElement)) {
-				return true;
-			}
-
-			return (!filterRowName || passesNameFilter(((INamedElement)annotationEntry
-					.getModelElement()).getName())) &&
-					passesSelectedElementTypeFilter(annotationEntry);
-		}
-
-		/** Sets the model element / annotation name filter pattern. */
-		public void setNameFilterPattern(String filterPattern) {
-			this.filterPattern = filterPattern;
-		}
-
-		/** Sets the flag whether rows should be filtered by name. */
-		public void setFilterRowName(boolean filterRowName) {
-			this.filterRowName = filterRowName;
-		}
-
-		/** Sets the flag whether columns should be filtered by name. */
-		public void setColumnRowName(boolean filterColumnName) {
-			this.filterColumnName = filterColumnName;
-		}
-
-		/** Sets the flag whether the view should be filtered by the selected model element type. */
-		public void
-				setRestrictToSelectedModelElementType(boolean restrictToSelectedModelElementType) {
-			this.restrictToSelectedModelElementType = restrictToSelectedModelElementType;
-		}
-
-		/** Sets the model element hierarchy level filter option. */
-		public void setHierarchyLevelFilter(String hierarchyLevelFilter) {
-			this.hierarchyLevelFilter = hierarchyLevelFilter;
-		}
-
-		/** Sets the annotation type filter option. */
-		public void setAnnotationTypeFilter(
-				Class<? extends IAnnotatedSpecification> annotationTypeFilter) {
-			this.annotationTypeFilter = annotationTypeFilter;
-		}
-	}
-
 	/** Widget to set content filters for the {@link GenericAnnotationView}. */
 	private class AnnotationFilterWidget extends Composite {
 		/** Annotation type filter: all annotations */
@@ -606,7 +452,7 @@ public class GenericAnnotationView extends AnnotationViewPartBase {
 						return;
 					}
 					view.getAnnotationFilter().setFilterRowName(true);
-					view.getAnnotationFilter().setColumnRowName(false);
+					view.getAnnotationFilter().setFilterColumnName(false);
 					view.update();
 				}
 			});
@@ -625,7 +471,7 @@ public class GenericAnnotationView extends AnnotationViewPartBase {
 						return;
 					}
 					view.getAnnotationFilter().setFilterRowName(false);
-					view.getAnnotationFilter().setColumnRowName(true);
+					view.getAnnotationFilter().setFilterColumnName(true);
 					view.update();
 				}
 			});
@@ -767,13 +613,47 @@ public class GenericAnnotationView extends AnnotationViewPartBase {
 		}
 	}
 
+	/**
+	 * Sets a fixed {@link AnnotationFilter}.
+	 * <ul>
+	 * <li>If the {@link AnnotationFilter} is non-{@code null}, it sets the filter and disables the
+	 * {@link AnnotationFilterWidget}. For instance, this can be used to embed / extend the
+	 * {@link GenericAnnotationView} into a specialized view dedicated to a particular model type.</li>
+	 * <li>Otherwise, this method reinitializes the {@link AnnotationFilterWidget}.</li>
+	 * </ul>
+	 */
+	public void setFixedAnnotationFilter(AnnotationFilter annotationFilter) {
+
+		// Remove old table row filter
+		tableViewer.removeFilter(this.annotationFilter);
+
+		if(annotationFilter != null) {
+			// Externally created filter -> remove filter option GUI
+			this.annotationFilter = annotationFilter;
+			if(annotationFilterWidget != null) {
+				annotationFilterWidget.dispose();
+				annotationFilterWidget = null;
+			}
+		} else {
+			// No externally created filter -> setup filter option GUI
+			this.annotationFilter = new AnnotationFilter();
+			setupAnnotationFilterWidget();
+		}
+
+		// Add new table row filter
+		tableViewer.addFilter(this.annotationFilter);
+
+		// Update layout
+		rootComposite.layout(true, true);
+	}
+
 	/** Returns the view's {@link AnnotationFilter}. */
 	private AnnotationFilter getAnnotationFilter() {
 		return annotationFilter;
 	}
 
 	/** Computes the level of an {@link IModelElement} in the tree */
-	private int getModelElementLevel(EObject o) {
+	public static int getModelElementLevel(EObject o) {
 		int level = 0;
 		while(o.eContainer() != null) {
 			level++;
@@ -788,7 +668,7 @@ public class GenericAnnotationView extends AnnotationViewPartBase {
 	 * {@code levelsUp} levels above model element in the hierarchy, or {@code null}, in case
 	 * {@code levelsUp} > depth(modelElement}.
 	 */
-	private EObject getModelElementAncestor(EObject o, int levelsUp) {
+	public static EObject getModelElementAncestor(EObject o, int levelsUp) {
 		while(o.eContainer() != null && levelsUp > 0) {
 			o = o.eContainer();
 			levelsUp--;
@@ -811,7 +691,12 @@ public class GenericAnnotationView extends AnnotationViewPartBase {
 	/** {@inheritDoc} */
 	@Override
 	protected void update(Collection<AnnotationEntry> annotationEntries) {
-		filterWidget.updateAnnotationTypeFilterOptionsComboBox(annotationEntries, this);
+		// Update filter
+		annotationFilter.setCurrentySelectedModelElement(getCurrentlySelectedObject());
+		if(annotationFilterWidget != null) {
+			annotationFilterWidget.updateAnnotationTypeFilterOptionsComboBox(annotationEntries,
+					this);
+		}
 
 		// Remember last annotation entries (required to re-draw table after changing the
 		// column/annotation filter
@@ -883,11 +768,17 @@ public class GenericAnnotationView extends AnnotationViewPartBase {
 		tableViewer.refresh();
 	}
 
+	/** Initializes the {@link AnnotationFilterWidget}. */
+	private void setupAnnotationFilterWidget() {
+		annotationFilterWidget = new AnnotationFilterWidget(rootComposite, SWT.NULL, this);
+		annotationFilterWidget.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
+	}
+
 	/** {@inheritDoc} */
 	@Override
 	public void createPartControl(Composite parent) {
 		super.createPartControl(parent);
-		Composite rootComposite = new Composite(parent, SWT.NULL);
+		rootComposite = new Composite(parent, SWT.NULL);
 		rootComposite.setLayout(new GridLayout(1, false));
 
 		tableViewer = new TableViewer(rootComposite, SWT.BORDER | SWT.FULL_SELECTION);
@@ -896,6 +787,11 @@ public class GenericAnnotationView extends AnnotationViewPartBase {
 		table.setLinesVisible(true);
 		table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
 
+		// Install layout for Table in order to ensure that it claims all available vertical space
+		// in case the
+		// filter option GUI is removed (see setFixedAnnotationFilter()).
+		table.setLayout(new FillLayout(SWT.VERTICAL));
+
 		createModelElementColumn();
 
 		tableViewer.setComparator(new HierarchicalNameComparator());
@@ -908,9 +804,7 @@ public class GenericAnnotationView extends AnnotationViewPartBase {
 		tableViewer.addFilter(annotationFilter);
 
 		// Add filter widget
-		filterWidget = new AnnotationFilterWidget(rootComposite, SWT.NULL, this);
-		filterWidget.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
-
+		setupAnnotationFilterWidget();
 	}
 
 	/** Creates the (leading) column which displays the model elements */
@@ -953,7 +847,7 @@ public class GenericAnnotationView extends AnnotationViewPartBase {
 				TableViewerColumn column = new TableViewerColumn(tableViewer, SWT.NONE);
 				tableColumn = column.getColumn();
 
-				String specName = getColumnName(columnHandle);
+				String specName = columnHandle.getColumnName();
 				tableColumn.setText(specName);
 
 				column.setEditingSupport(editingSupport);
@@ -974,27 +868,6 @@ public class GenericAnnotationView extends AnnotationViewPartBase {
 
 	}
 
-	/**
-	 * Returns the name of a column for a given {@link IAnnotatedSpecification} represented by the
-	 * given {@link ColumnHandle}.
-	 */
-	protected String getColumnName(ColumnHandle columnHandle) {
-		// Determine column name
-		String specName =
-				columnHandle.getEntry().getSpecificationAnnotationName(
-						columnHandle.getAnnotatedSpecification().getClass());
-
-		if(columnHandle.getInstanceKey() != null) {
-			if(!specName.isEmpty()) {
-				specName += MULTIINSTANCE_NAME_SEPARATOR + " ";
-			}
-			specName += columnHandle.getInstanceKey();
-		} else if(specName == null || specName.isEmpty()) {
-			specName = "<Unnamed Annotation>";
-		}
-		return specName;
-	}
-
 	/** {@inheritDoc} */
 	@Override
 	public void setFocus() {
-- 
GitLab