diff --git a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/.ratings b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/.ratings index 4850e6d5cc854062f8760986309dc09fbbc41974..e664805a7626a79fb7643ca63ad570c7424a16af 100644 --- a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/.ratings +++ b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/.ratings @@ -3,6 +3,6 @@ DynamicTreeItem.java 75dc5534b119ffdb3c10a65810c2a0f330b7955e GREEN DynamicTreeTableUIProviderBase.java 7bfc1395283d3dc10026aff5e2e65df88d25f3a7 GREEN DynamicTreeTableViewer.java 43757359b3071192ae79710bcbc0e9577bb6f62d GREEN DynamicTreeUIProviderBase.java 56fe4df4577b35f1e5e6e4c4be189b706c852d52 GREEN -DynamicTreeViewer.java da5e24ae57777a482d8e12c8262513d8143bfa93 GREEN +DynamicTreeViewer.java 6fc80215348ddb8bb0f79f5b1b66bad1d73adace YELLOW DynamicTreeViewerBase.java 47124c847de322a0ae26eb7a114f85ce4bd02d7e GREEN IDoubleClickHandler.java 447f7769dead9a106b3ea3139ef0da51eb0b9a89 GREEN diff --git a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeViewer.java b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeViewer.java index da5e24ae57777a482d8e12c8262513d8143bfa93..6fc80215348ddb8bb0f79f5b1b66bad1d73adace 100644 --- a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeViewer.java +++ b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeViewer.java @@ -169,6 +169,19 @@ public final class DynamicTreeViewer<T> extends DynamicTreeViewerBase<T> { } } + /** Expands the whole tree. */ + public void expandAllItems() { + expandAllItems(rootItem); + } + + /** Recursively expands the whole tree. */ + private void expandAllItems(TreeItem<T> item) { + item.setExpanded(true); + for(TreeItem<T> child : item.getChildren()) { + expandAllItems(child); + } + } + /** Returns the underlying {@link TreeView}. */ public TreeView<T> getControl() { return view; diff --git a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/internal/views/.ratings b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/internal/views/.ratings index 4cd930debce94e88ea390a945cafba3295c259da..6a45de1ab4384717bf779777e0716b4f3b66b50a 100644 --- a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/internal/views/.ratings +++ b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/internal/views/.ratings @@ -2,11 +2,10 @@ DoubleClick.java fd00e7737c0bad903433c0adb67dad92220ff451 GREEN GenericNewMenu.java 7e0dd435cb5ca6d4b486235ec17eef3e5c7aa5f6 GREEN LibraryView.java 44107622da7bcf431e1177e462d711646488957f GREEN LibraryViewDragSourceAdapter.java 56ef61b214ef5d6cb5b751791a92158bda0391ec GREEN -LibraryViewFX.java 5d9a95ee3362c9610728d6f9cee33672994640c2 RED LinkWithEditorPartListener.java c5ab74424378e7b158a805c4dd14fc03c8abeded GREEN MarkerViewContentProvider.java 4cb1192baebe21bca951c439c163d0c171512515 GREEN MarkerViewPart.java cbb650271b6877af205421b7cb11f930440a7ef9 GREEN -ModelElementsViewFX.java 77a93fe5ca28e4ce0c18deeca9cb4735a05032f8 RED +ModelElementsViewFX.java 395402b845f6ce997ab8dac96a8fc70e715f88ab YELLOW NavigatorNewMenu.java a35e391960d1dacbe7f77982e53e1891e9382d5a GREEN NavigatorTreeContentComparator.java d9f1354cfdff78b104b28887d2397e5ca0e9755b GREEN NavigatorTreeContentProvider.java 1fbe97bebf3805cc1af190cecd784fc1cfd12306 GREEN diff --git a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/internal/views/ModelElementsViewFX.java b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/internal/views/ModelElementsViewFX.java index 77a93fe5ca28e4ce0c18deeca9cb4735a05032f8..395402b845f6ce997ab8dac96a8fc70e715f88ab 100644 --- a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/internal/views/ModelElementsViewFX.java +++ b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/internal/views/ModelElementsViewFX.java @@ -15,15 +15,36 @@ +--------------------------------------------------------------------------*/ package org.fortiss.tooling.kernel.ui.internal.views; +import static java.util.Arrays.asList; import static java.util.Collections.emptyList; +import static org.fortiss.tooling.kernel.utils.EcoreUtils.filterOutInstanceOf; +import static org.fortiss.tooling.kernel.utils.KernelModelElementUtils.getParentElement; import java.util.Collection; +import java.util.List; +import java.util.Set; +import java.util.function.Predicate; +import org.conqat.ide.commons.ui.ui.EmptyPartListener; +import org.conqat.lib.commons.collections.IdentityHashSet; +import org.eclipse.emf.ecore.EObject; import org.eclipse.fx.ui.workbench3.FXViewPart; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IWorkbenchPart; import org.fortiss.tooling.common.ui.javafx.control.treetableview.DynamicTreeContentProviderBase; import org.fortiss.tooling.common.ui.javafx.control.treetableview.DynamicTreeUIProviderBase; import org.fortiss.tooling.common.ui.javafx.control.treetableview.DynamicTreeViewer; +import org.fortiss.tooling.kernel.extension.data.LibraryPrototype; +import org.fortiss.tooling.kernel.extension.data.Prototype; +import org.fortiss.tooling.kernel.extension.data.PrototypeCategory; +import org.fortiss.tooling.kernel.model.ILibraryElement; +import org.fortiss.tooling.kernel.service.IPrototypeService; +import org.fortiss.tooling.kernel.ui.extension.base.EditorBase; +import org.fortiss.tooling.kernel.ui.internal.editor.ExtendableMultiPageEditor; +import org.fortiss.tooling.kernel.ui.listener.ExtendableMultiPageEditorPageChangeListener; +import org.fortiss.tooling.kernel.ui.service.IModelElementHandlerService; +import javafx.scene.Node; import javafx.scene.Scene; import javafx.scene.control.TextField; import javafx.scene.layout.BorderPane; @@ -34,24 +55,45 @@ import javafx.scene.layout.BorderPane; * @author hoelzl */ public final class ModelElementsViewFX extends FXViewPart { + /** A dummy object serving as hidden root element of the tree view. */ + private static final Object DUMMY_ROOT = new Object(); /** The tree-table viewer. */ private DynamicTreeViewer<Object> treeViewer; /** The filter text field if filtering is enabled in content provider. */ private TextField filterWidget; + /** Current active {@link ExtendableMultiPageEditor}. */ + private ExtendableMultiPageEditor activeBindingEditor = null; + /** Stores the editor activation listener. */ + private EditorActivationListener editorActivationListener = new EditorActivationListener(); + /** The container object used. */ + private EObject containerObject = null; + /** The prototypes supported by the current editor. */ + private Set<Prototype> supportedBaseClasses = new IdentityHashSet<Prototype>(); + /** Listener for reacting to changes of the embedded editor. */ + private final ExtendableMultiPageEditorPageChangeListener bindingEditorPageChangeListener = + new ExtendableMultiPageEditorPageChangeListener() { + @Override + public void pageChanged() { + updateEditorFilters(activeBindingEditor.getActiveModelEditor()); + } + }; /** {@inheritDoc} */ @Override protected Scene createFxScene() { + getSite().getWorkbenchWindow().getPartService().addPartListener(editorActivationListener); + BorderPane pane = new BorderPane(); + ContentProvider contentProvider = new ContentProvider(); + UIProvider uiProvider = new UIProvider(); filterWidget = new TextField(); filterWidget.textProperty().addListener((obs, oVal, nVal) -> { - // contentProvider.setFilterExpression(nVal); + contentProvider.setFilterExpression(nVal); treeViewer.update(); }); - treeViewer = new DynamicTreeViewer<>(new Object(), true, 2, new LibraryContentProvider(), - new LibraryUIProvider()); + treeViewer = new DynamicTreeViewer<>(DUMMY_ROOT, false, 2, contentProvider, uiProvider); pane.setTop(filterWidget); pane.setCenter(treeViewer.getControl()); @@ -65,17 +107,151 @@ public final class ModelElementsViewFX extends FXViewPart { filterWidget.requestFocus(); } + /** Updates the filters according to the given editor. */ + @SuppressWarnings("unchecked") + private void updateEditorFilters(IEditorPart editor) { + supportedBaseClasses.clear(); + if(editor instanceof EditorBase && + ((EditorBase<? extends EObject>)editor).enableLibraryView()) { + EditorBase<? extends EObject> editorBase = (EditorBase<? extends EObject>)editor; + containerObject = editorBase.getEditedObject(); + + for(Class<? extends EObject> clazz : editorBase.getVisibleEObjectTypes()) { + List<Prototype> composablePrototypes = + IPrototypeService.getInstance().getComposablePrototypes(clazz); + if(getParentElement(containerObject, ILibraryElement.class, true) == null) { + supportedBaseClasses.addAll(composablePrototypes); + } else { + supportedBaseClasses.addAll( + filterOutInstanceOf(LibraryPrototype.class, composablePrototypes)); + } + } + } else { + containerObject = null; + } + + treeViewer.update(); + treeViewer.expandAllItems(); + } + + /** Switches to the given workbench editor part. */ + private void switchWorkbenchEditor(IEditorPart editor) { + if(activeBindingEditor != null) { + activeBindingEditor.removeBindingEditorListener(bindingEditorPageChangeListener); + activeBindingEditor = null; + } + + if(editor instanceof ExtendableMultiPageEditor) { + activeBindingEditor = (ExtendableMultiPageEditor)editor; + activeBindingEditor.addBindingEditorListener(bindingEditorPageChangeListener); + updateEditorFilters(activeBindingEditor.getActiveModelEditor()); + } else if(editor != null) { + updateEditorFilters(editor); + } + } + /** {@link DynamicTreeContentProviderBase} for the library view. */ - private class LibraryContentProvider extends DynamicTreeContentProviderBase<Object> { + private class ContentProvider extends DynamicTreeContentProviderBase<Object> { /** {@inheritDoc} */ @Override protected Collection<? extends Object> getChildren(Object parent) { - return emptyList(); // FIXME + if(parent instanceof PrototypeCategory) { + PrototypeCategory protoCat = (PrototypeCategory)parent; + return asList(protoCat.getChildren()); + } + if(parent == DUMMY_ROOT) { + return IPrototypeService.getInstance().getAllTopLevelPrototypesCategories(); + } + return emptyList(); + } + + /** {@inheritDoc} */ + @Override + protected boolean filter(Object element, String filterValue) { + if(containerObject == null || supportedBaseClasses.isEmpty()) { + return false; + } + if(element instanceof PrototypeCategory) { + PrototypeCategory protoCat = (PrototypeCategory)element; + for(Object child : protoCat.getChildren()) { + if(filter(child, filterValue)) { + return true; + } + } + return false; + } + if(supportedBaseClasses.contains(element)) { + if(filterValue == null || "".equals(filterValue)) { + return true; + } + if(element instanceof Prototype) { + Prototype proto = (Prototype)element; + return proto.getName().contains(filterValue); + } + } + return false; + } + + /** {@inheritDoc} */ + @Override + protected Predicate<Object> getFilterPredicate(String filterValue) { + // this override is needed, because super implementation does not + // call filter(Object, String) when filter value is null. + if(filterValue == null || "".equals(filterValue)) { + return (o) -> { + return filter(o, null); + }; + } + return super.getFilterPredicate(filterValue); } } /** {@link DynamicTreeUIProviderBase} for the library view. */ - private class LibraryUIProvider extends DynamicTreeUIProviderBase<Object> { - // TODO: go on here + private class UIProvider extends DynamicTreeUIProviderBase<Object> { + /** {@inheritDoc} */ + @Override + public String getLabel(Object element) { + if(element instanceof Prototype) { + Prototype proto = (Prototype)element; + return proto.getName(); + } + if(element instanceof PrototypeCategory) { + PrototypeCategory protoCat = (PrototypeCategory)element; + return protoCat.getName(); + } + return element == null ? "" : element.toString(); + } + + /** {@inheritDoc} */ + @Override + public Node getIconNode(Object element) { + if(element instanceof Prototype) { + Prototype proto = (Prototype)element; + EObject eoPrototype = proto.getPrototype(); + return IModelElementHandlerService.getInstance().getFXIcon(eoPrototype); + } + if(element instanceof PrototypeCategory) { + PrototypeCategory protoCat = (PrototypeCategory)element; + if(protoCat.getChildren().length > 0) { + return getIconNode(protoCat.getChildren()[0]); + } + } + return null; + } + } + + /** If an editor in a different Project is opened the Model is reinitialized */ + private class EditorActivationListener extends EmptyPartListener { + /** Change the tree viewer content whenever workbench part changes. */ + @Override + public void partActivated(IWorkbenchPart workbenchPart) { + if(!(workbenchPart instanceof IEditorPart)) { + return; + } + + IEditorPart part = (IEditorPart)workbenchPart; + treeViewer.update(); + switchWorkbenchEditor(part); + } } }