/******************************************************************************* * Copyright (c) 2007, 2010 Association for Decentralized Information Management * in Industry THTH ry. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * VTT Technical Research Centre of Finland - initial API and implementation *******************************************************************************/ package org.simantics.browsing.ui.platform; import java.lang.reflect.Constructor; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.Set; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.Platform; import org.eclipse.jface.layout.GridDataFactory; import org.eclipse.jface.viewers.ISelectionProvider; import org.eclipse.swt.SWT; import org.eclipse.swt.dnd.DND; import org.eclipse.swt.dnd.DragSource; import org.eclipse.swt.dnd.DragSourceListener; import org.eclipse.swt.dnd.DropTarget; import org.eclipse.swt.dnd.DropTargetAdapter; import org.eclipse.swt.dnd.DropTargetEvent; import org.eclipse.swt.dnd.FileTransfer; import org.eclipse.swt.dnd.Transfer; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Tree; import org.eclipse.swt.widgets.TreeItem; import org.eclipse.ui.IWorkbenchPartSite; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.contexts.IContextService; import org.osgi.framework.Bundle; import org.simantics.browsing.ui.BuiltinKeys; import org.simantics.browsing.ui.GraphExplorer; import org.simantics.browsing.ui.NodeContext; import org.simantics.browsing.ui.common.EvaluatorData; import org.simantics.browsing.ui.common.EvaluatorDataImpl; import org.simantics.browsing.ui.common.node.IDropTargetNode; import org.simantics.browsing.ui.common.processors.ComparableFactoryResolver; import org.simantics.browsing.ui.common.processors.ComparableSelectorQueryProcessor; import org.simantics.browsing.ui.common.processors.FilterSelectionRequestQueryProcessor; import org.simantics.browsing.ui.common.processors.ImageDecoratorFactoryResolver; import org.simantics.browsing.ui.common.processors.ImagerFactoryResolver; import org.simantics.browsing.ui.common.processors.LabelDecoratorFactoryResolver; import org.simantics.browsing.ui.common.processors.LabelerFactoryResolver; import org.simantics.browsing.ui.common.processors.UserSelectedComparableFactoryQueryProcessor; import org.simantics.browsing.ui.common.processors.UserSelectedViewpointFactoryQueryProcessor; import org.simantics.browsing.ui.common.processors.ViewpointFactoryResolver; import org.simantics.browsing.ui.common.views.IFilterAreaProvider; import org.simantics.browsing.ui.graph.impl.AsyncReadGraphDataSource; import org.simantics.browsing.ui.graph.impl.Evaluators; import org.simantics.browsing.ui.graph.impl.GraphExplorerHints; import org.simantics.browsing.ui.graph.impl.InheritsQueryProcessor; import org.simantics.browsing.ui.graph.impl.ReadGraphDataSource; import org.simantics.browsing.ui.graph.impl.RelatedObjectsQueryProcessor; import org.simantics.browsing.ui.swt.ComparatorSelector; import org.simantics.browsing.ui.swt.FilterArea; import org.simantics.browsing.ui.swt.GraphExplorerViewBase; import org.simantics.browsing.ui.swt.StandardContextTypesQueryProcessor; import org.simantics.browsing.ui.swt.TypesQueryProcessor; import org.simantics.browsing.ui.swt.ViewpointSelector; import org.simantics.db.AsyncReadGraph; import org.simantics.db.ReadGraph; import org.simantics.db.Session; import org.simantics.db.management.ISessionContext; import org.simantics.selectionview.StandardPropertyPage; import org.simantics.ui.dnd.LocalObjectTransfer; import org.simantics.ui.dnd.LocalSelectionDragSourceListener; import org.simantics.ui.dnd.NoImageDragSourceEffect; import org.simantics.ui.workbench.IPropertyPage; import org.simantics.utils.datastructures.hints.HintContext; import org.simantics.utils.datastructures.hints.IHintContext; import org.simantics.utils.ui.ErrorLogger; import org.simantics.utils.ui.LayoutUtils; /** * Override: * * * @author Tuukka Lehtonen * @deprecated in favor of org.simantics.views.swt.ModelledView * **/ public class GraphExplorerView extends GraphExplorerViewBase { protected UserSelectedComparableFactoryQueryProcessor userSelectedComparableFactoryQueryProcessor; protected UserSelectedViewpointFactoryQueryProcessor userSelectedViewpointFactoryQueryProcessor; protected FilterSelectionRequestQueryProcessor filterSelectionRequestQueryProcessor; protected FilterArea filterArea; protected IHintContext factoryHints = new HintContext(); protected EvaluatorData evaluatorData; protected Set browseContexts = Collections.emptySet(); protected String contextMenuId; protected Set uiContexts = Collections.emptySet(); protected String propertyPageContributor; protected String propertyPageClassName; protected Set propertyBrowseContexts = Collections.emptySet(); protected boolean hideComparatorSelector = false; protected boolean hideViewpointSelector = false; protected boolean hideFilter = false; @Override public void setInitializationData(IConfigurationElement cfig, String propertyName, Object data) { super.setInitializationData(cfig, propertyName, data); if (data instanceof String) { Set browseContexts = new HashSet(); Set uiContexts = new HashSet(); Set propertyBrowseContexts = new HashSet(); String[] parameters = ((String) data).split(";"); IContextService service = (IContextService) PlatformUI.getWorkbench().getService(IContextService.class); Set definedContexts = new HashSet(); for (Object cid : service.getDefinedContextIds()) definedContexts.add((String) cid); for (String parameter : parameters) { String[] keyValue = parameter.split("="); if (keyValue.length > 2) { ErrorLogger.defaultLogWarning("Invalid parameter '" + parameter + ". Complete view argument: " + data, null); continue; } String key = keyValue[0]; String value = keyValue.length > 1 ? keyValue[1] : ""; if ("browseContext".equals(key)) { browseContexts.add(value); } else if ("contextMenuId".equals(key)) { this.contextMenuId = value; } else if ("uiContext".equals(key)) { if (!definedContexts.contains(value)) { ErrorLogger.defaultLogWarning("Parameter '" + parameter + "' references a non-existent Eclipse UI context '" + value + "'. Complete view argument: " + data, null); continue; } uiContexts.add(value); } else if ("propertyBrowseContext".equals(key)) { propertyBrowseContexts.add(value); } else if ("propertyPageClass".equals(key)) { this.propertyPageContributor = cfig.getContributor().getName(); this.propertyPageClassName = value; } else if ("hideComparatorSelector".equals(key)) { this.hideComparatorSelector = true; } else if ("hideViewpointSelector".equals(key)) { this.hideViewpointSelector = true; } else if ("hideFilter".equals(key)) { this.hideFilter = true; } } this.browseContexts = browseContexts; this.uiContexts = uiContexts; this.propertyBrowseContexts = propertyBrowseContexts; } } public GraphExplorer getExplorer() { return explorer; } public T getBrowseContext() { return evaluatorData.getBrowseContext(); } /** * Override this to specify which browse contexts are considered active for * this browser. This information is read only once during view * initialization, no change listening is implemented. * * @return */ protected Set getBrowseContexts() { return browseContexts; } /* (non-Javadoc) * @see org.simantics.browsing.ui.swt.GraphExplorerViewBase#getContextMenuId() */ @Override protected String getContextMenuId() { return contextMenuId; } /** * @return the set of org.eclipse.ui.context contexts to * activate for this view site */ protected Set getUiContexts() { return uiContexts; } @Override protected IPropertyPage getPropertyPage() { if (propertyPageContributor != null && propertyPageClassName != null) { try { Bundle b = Platform.getBundle(propertyPageContributor); if (b == null) { ErrorLogger.defaultLogError("property page '" + propertyPageClassName + "' contributor bundle '" + propertyPageContributor + "' was not found in the platform.", null); return null; } Class clazz = b.loadClass(propertyPageClassName); if (!IPropertyPage.class.isAssignableFrom(clazz)) { ErrorLogger.defaultLogError("property page class '" + propertyPageClassName + "' is not assignable to " + IPropertyPage.class + ".", null); return null; } Constructor ctor = clazz.getConstructor(IWorkbenchPartSite.class); return (IPropertyPage) ctor.newInstance(getSite()); } catch (Exception e) { ErrorLogger.defaultLogError("Failed to instantiate IPropertyPage implementation '" + propertyPageClassName + "' from bundle '" + propertyPageContributor + "'. See exception for details.", e); // Something failed, don't try to instantiate the property page anymore. propertyPageClassName = null; } } else if (!propertyBrowseContexts.isEmpty()) { return new StandardPropertyPage(getSite(), new HashSet(propertyBrowseContexts)); } return null; } @Override protected void createControls(Composite parent) { super.createControls(parent); Control control = explorer.getControl(); userSelectedComparableFactoryQueryProcessor = new UserSelectedComparableFactoryQueryProcessor(); userSelectedViewpointFactoryQueryProcessor = new UserSelectedViewpointFactoryQueryProcessor(); filterSelectionRequestQueryProcessor = new FilterSelectionRequestQueryProcessor(); createAuxiliaryControls(parent, control); setupDropTarget(control); setWorkbenchListeners(); activateUiContexts(); } protected void createAuxiliaryControls(Composite parent, Control explorerControl) { if (explorerControl instanceof Tree) parent.setLayout(LayoutUtils.createNoBorderGridLayout(3, false)); if (!hideComparatorSelector) { ComparatorSelector comparatorSelector = new ComparatorSelector(explorer, userSelectedComparableFactoryQueryProcessor, parent, SWT.READ_ONLY); comparatorSelector.moveAbove(explorerControl); } if (!hideViewpointSelector) { ViewpointSelector viewpointSelector = new ViewpointSelector(explorer, userSelectedViewpointFactoryQueryProcessor, parent, SWT.READ_ONLY); viewpointSelector.moveAbove(explorerControl); } if (!hideFilter) { filterArea = new FilterArea(explorer, filterSelectionRequestQueryProcessor, parent, SWT.READ_ONLY); filterArea.moveAbove(explorerControl); } GridDataFactory.fillDefaults().grab(true, true).span(3,1).applyTo(explorerControl); } protected void setupDropTarget(Control control) { DropTarget target = new DropTarget(control, DND.DROP_COPY | DND.DROP_LINK); target.setTransfer(getAcceptedDataTypes()); target.addDropListener(new DropTargetAdapter() { Tree tree = (Tree) explorer.getControl(); @Override public void dragEnter(DropTargetEvent event) { event.detail = DND.DROP_COPY; } @Override public void drop(DropTargetEvent event) { TreeItem item = tree.getItem(tree.toControl(event.x, event.y)); if (item != null) handleDrop(event.data, (NodeContext) item.getData()); else handleDrop(event.data, null); } }); } protected void activateUiContexts() { Collection contexts = getUiContexts(); if (!contexts.isEmpty()) { IContextService cs = (IContextService) getSite().getService(IContextService.class); for (String context : contexts) cs.activateContext(context); } } @SuppressWarnings("rawtypes") @Override public Object getAdapter(Class adapter) { if (adapter == IFilterAreaProvider.class) return filterArea; return super.getAdapter(adapter); } @Override public void dispose() { //System.out.println(this + ".GraphExplorerViewBase2.dispose()"); removeWorkbenchListeners(); userSelectedComparableFactoryQueryProcessor = null; userSelectedViewpointFactoryQueryProcessor = null; filterSelectionRequestQueryProcessor = null; super.dispose(); } @Override protected final void initializeExplorer(GraphExplorer explorer, ISessionContext context) { if (explorer.isDisposed()) return; super.initializeExplorer(explorer, context); Session session = context != null ? context.getSession() : null; if (session != null) { evaluatorData = createEvaluatorData(session); factoryHints.setHint(GraphExplorerHints.KEY_SESSION_CONTEXT, context); explorer.setDataSource(new AsyncReadGraphDataSource(session)); explorer.setDataSource(new ReadGraphDataSource(session)); } else { evaluatorData = new EvaluatorDataImpl(); explorer.removeDataSource(AsyncReadGraph.class); explorer.removeDataSource(ReadGraph.class); factoryHints.removeHint(GraphExplorerHints.KEY_SESSION_CONTEXT); } explorer.setProcessor(new ComparableFactoryResolver(evaluatorData)); explorer.setProcessor(new ViewpointFactoryResolver(evaluatorData)); explorer.setProcessor(new LabelerFactoryResolver(evaluatorData)); explorer.setProcessor(new ImagerFactoryResolver(evaluatorData)); explorer.setProcessor(new LabelDecoratorFactoryResolver(evaluatorData)); explorer.setProcessor(new ImageDecoratorFactoryResolver(evaluatorData)); explorer.setPrimitiveProcessor(new TypesQueryProcessor()); explorer.setPrimitiveProcessor(new StandardContextTypesQueryProcessor()); explorer.setPrimitiveProcessor(new InheritsQueryProcessor()); explorer.setPrimitiveProcessor(new RelatedObjectsQueryProcessor()); if(!hideViewpointSelector) { explorer.setPrimitiveProcessor(userSelectedViewpointFactoryQueryProcessor); explorer.setProcessor(new ComparableSelectorQueryProcessor()); } if(!hideComparatorSelector) { explorer.setPrimitiveProcessor(userSelectedComparableFactoryQueryProcessor); } explorer.setPrimitiveProcessor(filterSelectionRequestQueryProcessor); initializeExplorerWithEvaluator(explorer, context, evaluatorData); } protected void initializeExplorerWithEvaluator(GraphExplorer explorer, ISessionContext context, EvaluatorData data) { } protected EvaluatorData createEvaluatorData(Session session) { return Evaluators.load(session, getBrowseContexts(), resourceManager); } protected Transfer[] getAcceptedDataTypes() { return new Transfer[] { LocalObjectTransfer.getTransfer(), FileTransfer.getInstance() }; } protected void handleDrop(Object data, NodeContext target) { if (target != null) { Object input = target.getConstant(BuiltinKeys.INPUT); //System.out.println("DROPPED " + data + " ON " + target); if (input instanceof IDropTargetNode) ((IDropTargetNode) input).drop(data); } } @Override protected Object createDragSource(GraphExplorer explorer) { ISelectionProvider selectionProvider = (ISelectionProvider) explorer.getAdapter(ISelectionProvider.class); DragSourceListener listener = new LocalSelectionDragSourceListener(selectionProvider); Control control = explorer.getControl(); DragSource source = new DragSource(control, DND.DROP_LINK | DND.DROP_MOVE | DND.DROP_COPY | DND.DROP_DEFAULT); source.setTransfer(new Transfer[] {LocalObjectTransfer.getTransfer()}); source.addDragListener(listener); source.setDragSourceEffect(new NoImageDragSourceEffect(control)); return listener; } public EvaluatorData getEvaluatorData() { return evaluatorData; } }