| /******************************************************************************* |
| * Copyright (c) 2011-2015 EclipseSource Muenchen GmbH and others. |
| * |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * Johannes Faltermeier - initial API and implementation |
| ******************************************************************************/ |
| package org.eclipse.emfforms.internal.swt.treemasterdetail; |
| |
| import java.util.Collection; |
| |
| import org.eclipse.emf.common.notify.AdapterFactory; |
| import org.eclipse.emf.ecore.EObject; |
| import org.eclipse.emf.ecp.view.model.common.edit.provider.CustomReflectiveItemProviderAdapterFactory; |
| import org.eclipse.emf.edit.domain.EditingDomain; |
| import org.eclipse.emf.edit.provider.ComposedAdapterFactory; |
| import org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider; |
| import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider; |
| import org.eclipse.emfforms.common.Optional; |
| import org.eclipse.emfforms.internal.swt.treemasterdetail.defaultprovider.DefaultDNDProvider; |
| import org.eclipse.emfforms.internal.swt.treemasterdetail.defaultprovider.DefaultMenuProvider; |
| import org.eclipse.emfforms.internal.swt.treemasterdetail.defaultprovider.DefaultTreeViewerBuilder; |
| import org.eclipse.emfforms.internal.swt.treemasterdetail.defaultprovider.DefaultViewerFilterProvider; |
| import org.eclipse.emfforms.spi.swt.treemasterdetail.ContentProviderProvider; |
| import org.eclipse.emfforms.spi.swt.treemasterdetail.DNDProvider; |
| import org.eclipse.emfforms.spi.swt.treemasterdetail.DeleteActionBuilder; |
| import org.eclipse.emfforms.spi.swt.treemasterdetail.InitialSelectionProvider; |
| import org.eclipse.emfforms.spi.swt.treemasterdetail.LabelDecoratorProvider; |
| import org.eclipse.emfforms.spi.swt.treemasterdetail.LabelProviderProvider; |
| import org.eclipse.emfforms.spi.swt.treemasterdetail.MenuProvider; |
| import org.eclipse.emfforms.spi.swt.treemasterdetail.TreeViewerBuilder; |
| import org.eclipse.emfforms.spi.swt.treemasterdetail.TreeViewerCustomization; |
| import org.eclipse.emfforms.spi.swt.treemasterdetail.ViewerFilterProvider; |
| import org.eclipse.emfforms.spi.swt.treemasterdetail.actions.MasterDetailAction; |
| import org.eclipse.emfforms.spi.swt.treemasterdetail.util.CreateElementCallback; |
| import org.eclipse.emfforms.spi.swt.treemasterdetail.util.RootObject; |
| import org.eclipse.jface.viewers.IBaseLabelProvider; |
| import org.eclipse.jface.viewers.IContentProvider; |
| import org.eclipse.jface.viewers.ILabelDecorator; |
| import org.eclipse.jface.viewers.TreeViewer; |
| import org.eclipse.jface.viewers.ViewerFilter; |
| import org.eclipse.swt.dnd.DragSourceListener; |
| import org.eclipse.swt.dnd.DropTargetListener; |
| import org.eclipse.swt.dnd.Transfer; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.Menu; |
| |
| /** |
| * Default implementation of the {@link TreeViewerCustomization}. |
| * |
| * @author Johannes Faltermeier |
| * |
| */ |
| public class DefaultTreeViewerCustomization implements TreeViewerCustomization { |
| |
| private ViewerFilterProvider filters; |
| private TreeViewerBuilder tree; |
| private InitialSelectionProvider selection; |
| private MenuProvider menu; |
| private LabelProviderProvider labelProvider; |
| private LabelDecoratorProvider decorator; |
| private DNDProvider dnd; |
| private ContentProviderProvider contentProvider; |
| private ComposedAdapterFactory adapterFactory; |
| private AdapterFactoryContentProvider adapterFactoryContentProvider; |
| |
| /** |
| * Default constructor. |
| */ |
| public DefaultTreeViewerCustomization() { |
| filters = new DefaultViewerFilterProvider(); |
| tree = new DefaultTreeViewerBuilder(); |
| selection = new DefaultTreeMasterDetailSelectionProvider(); |
| menu = new DefaultMenuProvider(); |
| labelProvider = new DefaultLabelProviderProvider(); |
| dnd = new DefaultDNDProvider(); |
| contentProvider = new DefaultContentProviderProvider(); |
| decorator = new DefaultLabelDecoratorProvider(); |
| } |
| |
| /** |
| * Gives access to the composed adapter factory. |
| * |
| * @return the adapter factory |
| */ |
| protected ComposedAdapterFactory getComposedAdapterFactory() { |
| if (adapterFactory == null) { |
| adapterFactory = new ComposedAdapterFactory(new AdapterFactory[] { |
| new CustomReflectiveItemProviderAdapterFactory(), |
| new ComposedAdapterFactory(ComposedAdapterFactory.Descriptor.Registry.INSTANCE) }); |
| } |
| return adapterFactory; |
| } |
| |
| /** |
| * Returns the {@link AdapterFactoryContentProvider}. |
| * |
| * @return the content provider |
| */ |
| protected AdapterFactoryContentProvider getAdapterFactoryContentProvider() { |
| if (adapterFactoryContentProvider == null) { |
| final ComposedAdapterFactory adapterFactory = getComposedAdapterFactory(); |
| adapterFactoryContentProvider = new AdapterFactoryContentProvider( |
| adapterFactory) { |
| |
| @Override |
| public Object[] getElements(Object object) { |
| if (RootObject.class.isInstance(object)) { |
| return new Object[] { RootObject.class.cast(object).getRoot() }; |
| } |
| return super.getElements(object); |
| } |
| |
| @Override |
| public boolean hasChildren(Object object) { |
| return getChildren(object).length > 0; |
| } |
| }; |
| } |
| return adapterFactoryContentProvider; |
| } |
| |
| @Override |
| public TreeViewer createTree(Composite parent) { |
| return tree.createTree(parent); |
| } |
| |
| @Override |
| public boolean hasDND() { |
| return dnd.hasDND(); |
| } |
| |
| @Override |
| public int getDragOperations() { |
| return dnd.getDragOperations(); |
| } |
| |
| @Override |
| public Transfer[] getDragTransferTypes() { |
| return dnd.getDragTransferTypes(); |
| } |
| |
| @Override |
| public DragSourceListener getDragListener(TreeViewer treeViewer) { |
| return dnd.getDragListener(treeViewer); |
| } |
| |
| @Override |
| public int getDropOperations() { |
| return dnd.getDropOperations(); |
| } |
| |
| @Override |
| public Transfer[] getDropTransferTypes() { |
| return dnd.getDropTransferTypes(); |
| } |
| |
| @Override |
| public DropTargetListener getDropListener(EditingDomain editingDomain, TreeViewer treeViewer) { |
| return dnd.getDropListener(editingDomain, treeViewer); |
| } |
| |
| @Override |
| public IContentProvider getContentProvider() { |
| return contentProvider.getContentProvider(); |
| } |
| |
| @Override |
| public IBaseLabelProvider getLabelProvider() { |
| return labelProvider.getLabelProvider(); |
| } |
| |
| @Override |
| public Optional<ILabelDecorator> getLabelDecorator(TreeViewer viewer) { |
| return decorator.getLabelDecorator(viewer); |
| } |
| |
| @Override |
| public ViewerFilter[] getViewerFilters() { |
| return filters.getViewerFilters(); |
| } |
| |
| @Override |
| public EObject getInitialSelection(Object input) { |
| return selection.getInitialSelection(input); |
| } |
| |
| @Override |
| public Menu getMenu(TreeViewer treeViewer, EditingDomain editingDomain) { |
| return menu.getMenu(treeViewer, editingDomain); |
| } |
| |
| @Override |
| public void dispose() { |
| decorator.dispose(); |
| contentProvider.dispose(); |
| labelProvider.dispose(); |
| if (adapterFactoryContentProvider != null) { |
| adapterFactoryContentProvider.dispose(); |
| } |
| if (adapterFactory != null) { |
| adapterFactory.dispose(); |
| } |
| } |
| |
| /** |
| * Sets the content provider provider. |
| * |
| * @param contentProvider the content provider |
| */ |
| public void setContentProvider(ContentProviderProvider contentProvider) { |
| this.contentProvider = contentProvider; |
| } |
| |
| /** |
| * Sets the d&d support. |
| * |
| * @param dnd the dnd |
| */ |
| public void setDragAndDrop(DNDProvider dnd) { |
| this.dnd = dnd; |
| } |
| |
| /** |
| * Sets the label provider provider. |
| * |
| * @param labelProvider the provider |
| */ |
| public void setLabelProvider(LabelProviderProvider labelProvider) { |
| this.labelProvider = labelProvider; |
| } |
| |
| /** |
| * Sets the label decorator provider. |
| * |
| * @param decorator the provider |
| */ |
| public void setLabelDecorator(LabelDecoratorProvider decorator) { |
| this.decorator = decorator; |
| } |
| |
| /** |
| * Sets the menu provider. |
| * |
| * @param menu the provider |
| */ |
| public void setMenu(MenuProvider menu) { |
| this.menu = menu; |
| } |
| |
| /** |
| * Sets the right click actions of the menu. |
| * |
| * @param rightClickActions the actions |
| */ |
| public void customizeMenu(Collection<MasterDetailAction> rightClickActions) { |
| if (!DefaultMenuProvider.class.isInstance(menu)) { |
| menu = new DefaultMenuProvider(); |
| } |
| final DefaultMenuProvider defaultMenuProvider = DefaultMenuProvider.class.cast(menu); |
| defaultMenuProvider.setRightClickAction(rightClickActions); |
| } |
| |
| /** |
| * Sets the {@link CreateElementCallback}. |
| * |
| * @param createElementCallback the callback |
| */ |
| public void customizeMenu(CreateElementCallback createElementCallback) { |
| if (!DefaultMenuProvider.class.isInstance(menu)) { |
| menu = new DefaultMenuProvider(); |
| } |
| final DefaultMenuProvider defaultMenuProvider = DefaultMenuProvider.class.cast(menu); |
| defaultMenuProvider.setCreateElementCallback(createElementCallback); |
| } |
| |
| /** |
| * Sets the delete action. |
| * |
| * @param deleteActionBuilder the builder |
| */ |
| public void customizeMenu(DeleteActionBuilder deleteActionBuilder) { |
| if (!DefaultMenuProvider.class.isInstance(menu)) { |
| menu = new DefaultMenuProvider(); |
| } |
| final DefaultMenuProvider defaultMenuProvider = DefaultMenuProvider.class.cast(menu); |
| defaultMenuProvider.setDeleteAction(deleteActionBuilder); |
| } |
| |
| /** |
| * Sets the initial selection provider. |
| * |
| * @param selection the provider |
| */ |
| public void setInitialSelection(InitialSelectionProvider selection) { |
| this.selection = selection; |
| } |
| |
| /** |
| * Sets the tree builder. |
| * |
| * @param tree the tree builder |
| */ |
| public void setTree(TreeViewerBuilder tree) { |
| this.tree = tree; |
| } |
| |
| /** |
| * Sets the viewer filter provider. |
| * |
| * @param filters the provider |
| */ |
| public void setViewerFilters(ViewerFilterProvider filters) { |
| this.filters = filters; |
| } |
| |
| /** |
| * Provides no decorator. |
| * |
| * @author Johannes Faltermeier |
| * |
| */ |
| private static final class DefaultLabelDecoratorProvider implements LabelDecoratorProvider { |
| @Override |
| public Optional<ILabelDecorator> getLabelDecorator(TreeViewer viewer) { |
| return Optional.empty(); |
| } |
| |
| @Override |
| public void dispose() { |
| /* no op */ |
| |
| } |
| } |
| |
| /** |
| * Default {@link ContentProviderProvider}. |
| * |
| * @author jfaltermeier |
| * |
| */ |
| private final class DefaultContentProviderProvider implements ContentProviderProvider { |
| @Override |
| public IContentProvider getContentProvider() { |
| return getAdapterFactoryContentProvider(); |
| } |
| |
| @Override |
| public void dispose() { |
| /* disposed by build behaviour */ |
| } |
| } |
| |
| /** |
| * Default {@link LabelProviderProvider}. |
| * |
| * @author jfaltermeier |
| * |
| */ |
| private final class DefaultLabelProviderProvider implements LabelProviderProvider { |
| private AdapterFactoryLabelProvider provider; |
| |
| @Override |
| public IBaseLabelProvider getLabelProvider() { |
| final ComposedAdapterFactory adapterFactory = getComposedAdapterFactory(); |
| provider = new AdapterFactoryLabelProvider(adapterFactory); |
| return provider; |
| } |
| |
| @Override |
| public void dispose() { |
| /* adapter factory will be disposed by build behaviour */ |
| provider.dispose(); |
| } |
| } |
| |
| /** |
| * Default {@link InitialSelectionProvider}. |
| * |
| * @author jfaltermeier |
| * |
| */ |
| private final class DefaultTreeMasterDetailSelectionProvider implements InitialSelectionProvider { |
| @Override |
| public EObject getInitialSelection(Object input) { |
| final AdapterFactoryContentProvider contentProvider = getAdapterFactoryContentProvider(); |
| if (input instanceof EObject) { |
| return (EObject) input; |
| } |
| for (final Object child : contentProvider.getChildren(input)) { |
| final EObject childSelector = getInitialSelection(child); |
| if (childSelector != null) { |
| return childSelector; |
| } |
| } |
| return null; |
| } |
| } |
| |
| } |