From 8ca82855778c664420cd7352f251d05de793899a Mon Sep 17 00:00:00 2001 From: Andreas Bayha <bayha@fortiss.org> Date: Tue, 9 Jun 2020 18:04:48 +0200 Subject: [PATCH] Annotations: AnnotationFxView table First Durchstich to display annotations according to the current selection. Issue-Ref: 4014 Issue-Url: https://af3-developer.fortiss.org/issues/4014 Signed-off-by: Andreas Bayha <bayha@fortiss.org> --- org.fortiss.tooling.base.ui/.classpath | 3 +- .../META-INF/MANIFEST.MF | 3 +- org.fortiss.tooling.base.ui/plugin.xml | 7 + .../annotation/view/fx/AnnotationViewFx.fxml | 15 ++ .../view/fx/AnnotationFxViewPart.java | 49 ++++ .../view/fx/AnnotationViewFXController.java | 240 ++++++++++++++++++ .../base/annotation/AnnotationEntry.java | 2 +- 7 files changed, 316 insertions(+), 3 deletions(-) create mode 100644 org.fortiss.tooling.base.ui/res/org/fortiss/tooling/base/ui/annotation/view/fx/AnnotationViewFx.fxml create mode 100644 org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/annotation/view/fx/AnnotationFxViewPart.java create mode 100644 org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/annotation/view/fx/AnnotationViewFXController.java diff --git a/org.fortiss.tooling.base.ui/.classpath b/org.fortiss.tooling.base.ui/.classpath index f3432614c..180930d41 100644 --- a/org.fortiss.tooling.base.ui/.classpath +++ b/org.fortiss.tooling.base.ui/.classpath @@ -7,7 +7,7 @@ </classpathentry> <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> <classpathentry kind="src" path="src"/> - <classpathentry kind="output" path="build"/> + <classpathentry kind="src" path="res"/> <classpathentry kind="lib" path="lib/opal-1.0.4.jar" sourcepath="lib/opal-1.0.4-src.zip"/> <classpathentry exported="true" kind="lib" path="lib/com.google.guava-15.0.0.v201403281430.jar" sourcepath="lib/klay-layouters-2016-02-src.zip"/> <classpathentry exported="true" kind="lib" path="lib/de.cau.cs.kieler.core-0.15.0.201602160301.jar" sourcepath="lib/klay-layouters-2016-02-src.zip"/> @@ -16,4 +16,5 @@ <classpathentry exported="true" kind="lib" path="lib/de.cau.cs.kieler.klay.force-0.4.0.201602160301.jar" sourcepath="lib/klay-layouters-2016-02-src.zip"/> <classpathentry exported="true" kind="lib" path="lib/de.cau.cs.kieler.klay.layered-0.13.0.201602160301.jar" sourcepath="lib/klay-layouters-2016-02-src.zip"/> <classpathentry exported="true" kind="lib" path="lib/de.cau.cs.kieler.klay.tree-0.4.0.201602160301.jar" sourcepath="lib/klay-layouters-2016-02-src.zip"/> + <classpathentry kind="output" path="build"/> </classpath> diff --git a/org.fortiss.tooling.base.ui/META-INF/MANIFEST.MF b/org.fortiss.tooling.base.ui/META-INF/MANIFEST.MF index 171e250f8..5fe281bb2 100644 --- a/org.fortiss.tooling.base.ui/META-INF/MANIFEST.MF +++ b/org.fortiss.tooling.base.ui/META-INF/MANIFEST.MF @@ -6,7 +6,8 @@ Bundle-Version: 2.17.0.qualifier Bundle-Activator: org.fortiss.tooling.base.ui.ToolingBaseUIActivator Require-Bundle: org.fortiss.tooling.base;bundle-version="2.17.0";visibility:=reexport, org.fortiss.tooling.kernel.ui;bundle-version="2.17.0";visibility:=reexport, - org.eclipse.swt + org.eclipse.swt, + org.fortiss.tooling.common.ui Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: JavaSE-11 Bundle-Vendor: fortiss GmbH diff --git a/org.fortiss.tooling.base.ui/plugin.xml b/org.fortiss.tooling.base.ui/plugin.xml index 6fd4666af..231f48481 100644 --- a/org.fortiss.tooling.base.ui/plugin.xml +++ b/org.fortiss.tooling.base.ui/plugin.xml @@ -20,6 +20,13 @@ name="Annotations" restorable="true"> </view> + <view + class="org.fortiss.tooling.base.ui.annotation.view.fx.AnnotationFxViewPart" + icon="icons/annotation.gif" + id="org.fortiss.tooling.base.ui.annotationFxView" + name="Annotations FX" + restorable="true"> + </view> </extension> <extension point="org.fortiss.tooling.kernel.uiMessageHandler"> <uiMessageHandler diff --git a/org.fortiss.tooling.base.ui/res/org/fortiss/tooling/base/ui/annotation/view/fx/AnnotationViewFx.fxml b/org.fortiss.tooling.base.ui/res/org/fortiss/tooling/base/ui/annotation/view/fx/AnnotationViewFx.fxml new file mode 100644 index 000000000..a37630e2e --- /dev/null +++ b/org.fortiss.tooling.base.ui/res/org/fortiss/tooling/base/ui/annotation/view/fx/AnnotationViewFx.fxml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<?import javafx.scene.control.SplitPane?> +<?import javafx.scene.control.TreeTableView?> +<?import javafx.scene.layout.AnchorPane?> + +<SplitPane fx:id="annotationSplitPane" dividerPositions="0.6105527638190955" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" orientation="VERTICAL" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1"> + <items> + <AnchorPane fx:id="annotationTablePane" minHeight="0.0" minWidth="0.0" prefHeight="100.0" prefWidth="160.0"> + <children> + <TreeTableView fx:id="annotationTreeTableView" layoutX="328.0" layoutY="20.0" prefHeight="239.0" prefWidth="598.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" /> + </children></AnchorPane> + <AnchorPane fx:id="filterPane" minHeight="0.0" minWidth="0.0" prefHeight="219.0" prefWidth="598.0" /> + </items> +</SplitPane> diff --git a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/annotation/view/fx/AnnotationFxViewPart.java b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/annotation/view/fx/AnnotationFxViewPart.java new file mode 100644 index 000000000..f7ea5e728 --- /dev/null +++ b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/annotation/view/fx/AnnotationFxViewPart.java @@ -0,0 +1,49 @@ +/*-------------------------------------------------------------------------+ +| Copyright 2020 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.fx; + +import org.fortiss.tooling.common.ui.javafx.AF3FXViewPart; + +import javafx.scene.Scene; + +/** + * + * @author bayha + */ +public class AnnotationFxViewPart extends AF3FXViewPart { + + private static final AnnotationViewFXController VIEW_CONTROLLER = + new AnnotationViewFXController(); + + /** + * @param controller + * @param cssLocation + * @throws Exception + */ + public AnnotationFxViewPart() throws Exception { + super(VIEW_CONTROLLER, null); + } + + /** {@inheritDoc} */ + @Override + protected Scene createFxScene() { + Scene scene = super.createFxScene(); + + getSite().getWorkbenchWindow().getSelectionService().addSelectionListener(VIEW_CONTROLLER); + + return scene; + } +} diff --git a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/annotation/view/fx/AnnotationViewFXController.java b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/annotation/view/fx/AnnotationViewFXController.java new file mode 100644 index 000000000..3165397eb --- /dev/null +++ b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/annotation/view/fx/AnnotationViewFXController.java @@ -0,0 +1,240 @@ +/*-------------------------------------------------------------------------+ +| Copyright 2020 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.fx; + +import static java.util.Collections.emptyList; +import static org.fortiss.tooling.base.utils.AnnotationUtils.getAnnotationValueProvider; +import static org.fortiss.tooling.kernel.ui.util.SelectionUtils.checkAndPickFirst; +import static org.fortiss.tooling.kernel.utils.EcoreUtils.getChildrenWithType; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeSet; + +import org.eclipse.emf.common.util.EList; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.ui.ISelectionListener; +import org.eclipse.ui.IWorkbenchPart; +import org.fortiss.tooling.base.annotation.AnnotationEntry; +import org.fortiss.tooling.base.annotation.AnnotationValueService; +import org.fortiss.tooling.base.annotation.IAnnotationValueService; +import org.fortiss.tooling.base.annotation.valueprovider.IAnnotationValueProvider; +import org.fortiss.tooling.base.model.element.IAnnotatedSpecification; +import org.fortiss.tooling.base.model.element.IModelElement; +import org.fortiss.tooling.base.ui.annotation.view.generic.ColumnHandle; +import org.fortiss.tooling.common.ui.javafx.control.treetableview.DynamicTreeContentProviderBase; +import org.fortiss.tooling.common.ui.javafx.control.treetableview.DynamicTreeTableUIProviderBase; +import org.fortiss.tooling.common.ui.javafx.control.treetableview.DynamicTreeTableViewer; +import org.fortiss.tooling.common.ui.javafx.layout.CompositeFXControllerBase; +import org.fortiss.tooling.kernel.model.INamedCommentedElement; + +import javafx.fxml.FXML; +import javafx.scene.Node; +import javafx.scene.control.SplitPane; +import javafx.scene.control.TreeTableView; + +/** + * + * @author bayha + */ +@SuppressWarnings("unchecked") +public class AnnotationViewFXController extends CompositeFXControllerBase<SplitPane, Node> + implements ISelectionListener { + + /** */ + @FXML + private SplitPane annotationSplitPane; + + /** */ + @FXML + private TreeTableView<AnnotationEntry> annotationTreeTableView; + + /** */ + private DynamicTreeTableViewer<AnnotationEntry> annotationTreeViewer; + + /** */ + private IModelElement selectedElement; + + /** */ + private DynamicTreeContentProviderBase<AnnotationEntry> contentProvider = + new AnnotationTableContentProvider(); + + /** */ + private DynamicTreeTableUIProviderBase<AnnotationEntry> uiProvider = + new AnnotationTreeTableUIProvider(); + + /** + * Associates the handles of the annotations with their ordered column indexes. Used for the UI + * providers of cell items. + */ + Map<Integer, ColumnHandle<IAnnotatedSpecification>> colIdxAnnotationMap = new HashMap<>(); + + /** {@inheritDoc} */ + @Override + public String getFXMLLocation() { + return "AnnotationViewFx.fxml"; + } + + /** {@inheritDoc} */ + @Override + public void initialize() { + // EMPTY + } + + /** {@inheritDoc} */ + @Override + public void selectionChanged(IWorkbenchPart part, ISelection selection) { + selectedElement = checkAndPickFirst(selection, IModelElement.class); + + updateAnnotationTree(); + } + + /** + * + */ + private void updateAnnotationTree() { + if(selectedElement == null) { + return; + } + + EList<IModelElement> childElements = + getChildrenWithType(selectedElement, IModelElement.class); + + ArtificialRoot root = new ArtificialRoot(selectedElement); + + for(IModelElement elem : childElements) { + AnnotationEntry entry = IAnnotationValueService.getInstance().getAnnotationEntry(elem); + + if(entry != null) { + root.elements.add(entry); + } + } + + // Sorted set of {@link ColumnHandle} used to instantiate this {@link + // GenericAnnotationView}'s columns in the right order. + Set<ColumnHandle<IAnnotatedSpecification>> sortedColumnHandles = new TreeSet<>(); + Set<AnnotationEntry> annotationEntries = new HashSet<>(); + childElements.forEach(e -> annotationEntries + .add(AnnotationValueService.getInstance().getAnnotationEntry(e))); + + // Aggregate required columns. Column order is defined by ColumnHandle.compareTo(). + for(AnnotationEntry entry : annotationEntries) { + for(IAnnotatedSpecification spec : entry.getSpecificationsList()) { + ColumnHandle<IAnnotatedSpecification> columnHandle = + new ColumnHandle<IAnnotatedSpecification>(entry, spec); + sortedColumnHandles.add(columnHandle); + } + } + + annotationTreeTableView.getColumns().clear(); + + boolean showRoot = false; + int revealLevel = 1; + annotationTreeViewer = new DynamicTreeTableViewer<AnnotationEntry>(annotationTreeTableView, + root, showRoot, revealLevel, contentProvider, uiProvider); + + annotationTreeViewer.addColumn("Model Element", 200); + annotationTreeViewer.addColumn("Comment", 250); + + int columnIdx = 2; + for(ColumnHandle<IAnnotatedSpecification> handle : sortedColumnHandles) { + annotationTreeViewer.addColumn(handle.getColumnName(), 150); + colIdxAnnotationMap.put(columnIdx++, handle); + } + } + + /** + * + * @author bayha + */ + protected class AnnotationTreeTableUIProvider + extends DynamicTreeTableUIProviderBase<AnnotationEntry> { + + /** {@inheritDoc} */ + @Override + public String getLabel(AnnotationEntry entry, int column) { + IModelElement element = entry.getModelElement(); + + switch(column) { + case 0: + if(element instanceof INamedCommentedElement) { + return ((INamedCommentedElement)element).getName(); + } + return ""; + case 1: + if(element instanceof INamedCommentedElement) { + return ((INamedCommentedElement)element).getComment(); + } + return ""; + default: + ColumnHandle<IAnnotatedSpecification> colHandle = + colIdxAnnotationMap.get(column); + IAnnotationValueProvider<IAnnotatedSpecification> valProvider = + getAnnotationValueProvider(element, + colHandle.getAnnotatedSpecificationType()); + try { + return valProvider.getAnnotationValue(colHandle.getAnnotatedSpecification()) + .toString(); + } catch(Exception e) { + // For this demo class, it is expected that direct conversions to + // strings will fail for some annotations. Simple don't show anything in + // this case. + return ""; + } + } + } + } + + /** + * + * @author bayha + */ + protected class AnnotationTableContentProvider + extends DynamicTreeContentProviderBase<AnnotationEntry> { + + /** {@inheritDoc} */ + @Override + protected Collection<? extends AnnotationEntry> getChildren(AnnotationEntry parent) { + if(parent instanceof ArtificialRoot) { + return ((ArtificialRoot)parent).elements; + } + + return emptyList(); + } + } + + /** + * + * @author bayha + */ + protected class ArtificialRoot extends AnnotationEntry { + + /** + * @param modelElement + */ + public ArtificialRoot(IModelElement modelElement) { + super(modelElement); + } + + /** */ + List<AnnotationEntry> elements = new ArrayList<AnnotationEntry>(); + } +} diff --git a/org.fortiss.tooling.base/src/org/fortiss/tooling/base/annotation/AnnotationEntry.java b/org.fortiss.tooling.base/src/org/fortiss/tooling/base/annotation/AnnotationEntry.java index 928240a72..97a9d45cf 100644 --- a/org.fortiss.tooling.base/src/org/fortiss/tooling/base/annotation/AnnotationEntry.java +++ b/org.fortiss.tooling.base/src/org/fortiss/tooling/base/annotation/AnnotationEntry.java @@ -43,7 +43,7 @@ import org.fortiss.tooling.kernel.service.types.EMFTypeMap; * * @author eder, barner */ -public final class AnnotationEntry { +public class AnnotationEntry { /** * Model element for which the set of relevant {@link IAnnotatedSpecification}s is managed by -- GitLab