X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.selectionview%2Fsrc%2Forg%2Fsimantics%2Fselectionview%2FPropertyTable.java;h=31da15bb4ef1b6bbcecd48af6723fbd1acd8db3a;hb=HEAD;hp=4bb45be716b3723ee1a3bc707d7902f5a059dee8;hpb=969bd23cab98a79ca9101af33334000879fb60c5;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.selectionview/src/org/simantics/selectionview/PropertyTable.java b/bundles/org.simantics.selectionview/src/org/simantics/selectionview/PropertyTable.java index 4bb45be71..31da15bb4 100644 --- a/bundles/org.simantics.selectionview/src/org/simantics/selectionview/PropertyTable.java +++ b/bundles/org.simantics.selectionview/src/org/simantics/selectionview/PropertyTable.java @@ -1,449 +1,449 @@ -/******************************************************************************* - * 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.selectionview; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.function.Consumer; - -import org.eclipse.jface.action.ContributionItem; -import org.eclipse.jface.action.IContributionItem; -import org.eclipse.jface.layout.GridDataFactory; -import org.eclipse.jface.resource.JFaceResources; -import org.eclipse.jface.resource.LocalResourceManager; -import org.eclipse.jface.viewers.IPostSelectionProvider; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.ISelectionProvider; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.swt.SWT; -import org.eclipse.swt.dnd.DND; -import org.eclipse.swt.dnd.DragSource; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.ToolBar; -import org.eclipse.swt.widgets.ToolItem; -import org.eclipse.swt.widgets.Tree; -import org.eclipse.ui.IActionBars; -import org.eclipse.ui.IWorkbenchSite; -import org.simantics.browsing.ui.GraphExplorer; -import org.simantics.browsing.ui.common.ColumnKeys; -import org.simantics.browsing.ui.common.EvaluatorData; -import org.simantics.browsing.ui.common.EvaluatorData.Evaluator; -import org.simantics.browsing.ui.common.EvaluatorDataImpl; -import org.simantics.browsing.ui.common.comparators.AlphanumericComparatorFactory; -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.IFilterArea; -import org.simantics.browsing.ui.common.views.IFilterAreaProvider; -import org.simantics.browsing.ui.common.views.PropertyTableConstants; -import org.simantics.browsing.ui.graph.impl.ArrayPropertyLabelerFactory; -import org.simantics.browsing.ui.graph.impl.ArrayPropertyValueViewpointFactory; -import org.simantics.browsing.ui.graph.impl.AsyncReadGraphDataSource; -import org.simantics.browsing.ui.graph.impl.PropertyViewpointFactory; -import org.simantics.browsing.ui.graph.impl.ReadGraphDataSource; -import org.simantics.browsing.ui.graph.impl.RelationContextLabelerFactory; -import org.simantics.browsing.ui.graph.impl.ResourceProperty; -import org.simantics.browsing.ui.graph.impl.StringRepresentationLabelerFactory; -import org.simantics.browsing.ui.swt.ArrayPropertyImagerFactory; -import org.simantics.browsing.ui.swt.ComparatorSelector; -import org.simantics.browsing.ui.swt.ContextMenuInitializer; -import org.simantics.browsing.ui.swt.GraphExplorerFactory; -import org.simantics.browsing.ui.swt.PropertyTableUtil; -import org.simantics.browsing.ui.swt.RootFilterArea; -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.RelationContext; -import org.simantics.db.Resource; -import org.simantics.db.Session; -import org.simantics.db.Statement; -import org.simantics.db.common.ResourceArray; -import org.simantics.db.management.ISessionContext; -import org.simantics.ui.dnd.BasicDragSource; -import org.simantics.ui.dnd.SessionContainer; -import org.simantics.ui.utils.ResourceAdaptionUtils; -import org.simantics.utils.ObjectUtils; -import org.simantics.utils.ui.LayoutUtils; - - -/** - *

- * Subclasses may extend or reimplement the following methods as required: - *

- *

- * - * @author Tuukka Lehtonen - */ -public class PropertyTable extends Composite implements IFilterAreaProvider, IPropertyTab2 { - - protected IWorkbenchSite site; - protected GraphExplorer explorer; - protected Object dragSource; - protected ISessionContext sessionContext; - protected ISelection currentInput; - - protected UserSelectedComparableFactoryQueryProcessor userSelectedComparableFactoryQueryProcessor; - protected UserSelectedViewpointFactoryQueryProcessor userSelectedViewpointFactoryQueryProcessor; - protected FilterSelectionRequestQueryProcessor filterSelectionRequestQueryProcessor; - - protected LocalResourceManager resourceManager; - - private RootFilterArea filterArea; - private IContributionItem filterAreaContribution; - private IActionBars actionBars; - - public PropertyTable(IWorkbenchSite site, Composite parent, int style) { - super(parent, style); - this.site = site; - //System.out.println("created " + this + " " + System.identityHashCode(this)); - resourceManager = new LocalResourceManager(JFaceResources.getResources(parent.getDisplay())); - - addListener(SWT.Dispose, new Listener() { - @Override - public void handleEvent(Event event) { - //System.out.println("DISPOSING " + this + " " + System.identityHashCode(PropertyTable.this)); - tableDisposed(); - - PropertyTableUtil.setupDragSource(dragSource, null); - - PropertyTable.this.site = null; - explorer = null; - dragSource = null; - sessionContext = null; - currentInput = null; - - userSelectedComparableFactoryQueryProcessor = null; - userSelectedViewpointFactoryQueryProcessor = null; - filterSelectionRequestQueryProcessor = null; - - resourceManager.dispose(); - } - }); - } - - /** - * Override to perform actions when this property table is disposed. - * Remember to call super. - */ - protected void tableDisposed() { - getDisplay().asyncExec(new Runnable() { - @Override - public void run() { - if (filterAreaContribution != null) { - actionBars.getToolBarManager().remove(filterAreaContribution); - filterAreaContribution.dispose(); - filterAreaContribution = null; - actionBars.updateActionBars(); - } - } - }); - } - - @Override - public Control getControl() { - return this; - } - - @Override - public void createControl(final Composite parent, ISessionContext context) { - explorer = createExplorerControl(parent); - dragSource = createDragSource(explorer); - - Control control = explorer.getControl(); - - userSelectedComparableFactoryQueryProcessor = new UserSelectedComparableFactoryQueryProcessor(); - userSelectedViewpointFactoryQueryProcessor = new UserSelectedViewpointFactoryQueryProcessor(); - filterSelectionRequestQueryProcessor = new FilterSelectionRequestQueryProcessor(); - - parent.setLayout(LayoutUtils.createNoBorderGridLayout(2, false)); - GridDataFactory.fillDefaults().grab(true, true).span(2,1).applyTo(control); - - addControls(parent); - setSessionContext(context); - } - - protected void addControls(Composite parent) { - //createSelectors(parent); - //createFilterArea(parent); - } - - protected void createSelectors(Composite parent) { - Control control = explorer.getControl(); - ComparatorSelector comparatorSelector = new ComparatorSelector(explorer, userSelectedComparableFactoryQueryProcessor, parent, SWT.READ_ONLY); - comparatorSelector.moveAbove(control); - ViewpointSelector viewpointSelector = new ViewpointSelector(explorer, userSelectedViewpointFactoryQueryProcessor, parent, SWT.READ_ONLY); - viewpointSelector.moveAbove(control); - } - - protected void createFilterArea(IActionBars actionBars) { - this.filterAreaContribution = new ContributionItem("filterArea") { - ToolItem item; - @Override - public boolean isDynamic() { - return true; - } - @Override - public final void fill(ToolBar parent, int index) { - Control control = createControl(parent); - item = new ToolItem(parent, SWT.SEPARATOR, index); - item.setControl(control); - item.setWidth(computeWidth(control)); - } - protected Control createControl(Composite parent) { - filterArea = new RootFilterArea(explorer, filterSelectionRequestQueryProcessor, parent, SWT.NONE); - return filterArea; - } - protected int computeWidth(Control control) { - // FIXME: better size control? - return control.computeSize(150, SWT.DEFAULT, true).x; - } - @Override - public void dispose() { - if (filterArea != null) { - filterArea.dispose(); - filterArea = null; - } - if (item != null) { - item.dispose(); - item = null; - } - } - }; - this.actionBars = actionBars; - actionBars.getToolBarManager().add(filterAreaContribution); - } - - protected void createFilterArea(Composite parent) { - Control control = explorer.getControl(); - filterArea = new RootFilterArea(explorer, filterSelectionRequestQueryProcessor, parent, SWT.NONE); - filterArea.moveAbove(control); - } - - protected GraphExplorer createExplorerControl(Composite parent) { - GraphExplorer e = GraphExplorerFactory.getInstance().create(parent, SWT.FULL_SELECTION); - Control c = e.getControl(); - ISelectionProvider selectionProvider = (ISelectionProvider)e.getAdapter(ISelectionProvider.class); - new ContextMenuInitializer("#PropertiesPopup").createContextMenu(c, selectionProvider, site); - if (c instanceof Tree) - ((Tree) c).setLinesVisible(true); - e.setColumns(PropertyTableConstants.NORMAL_COLUMNS); - return e; - } - - /** - * Override to customize drag source initialization. This default - * implementation creates a {@link BasicDragSource}. The drag source is - * initialized when the active database session is set. - * - * @param explorer - * @return the object representing the drag source. If the object implements - * {@link SessionContainer}, its - * {@link SessionContainer#setSession(Session)} will be invoked - * every time the active database session changes. - */ - protected Object createDragSource(GraphExplorer explorer) { - Control c = explorer.getControl(); - DragSource existingSource = (DragSource) c.getData(DND.DRAG_SOURCE_KEY); - if (existingSource != null) - return existingSource; - return PropertyTableUtil.createResourceDragSource(explorer); - } - - protected void setupDragSource(ISessionContext sessionContext) { - PropertyTableUtil.setupDragSource(dragSource, sessionContext); - } - - @Override - public ISelectionProvider getSelectionProvider() { - GraphExplorer e = explorer; - if (e != null) { - IPostSelectionProvider selectionProvider = (IPostSelectionProvider)e.getAdapter(IPostSelectionProvider.class); - return selectionProvider; - } - return null; - } - - @Override - public void requestFocus() { - GraphExplorer e = explorer; - if (e != null) - e.setFocus(); - } - - @Override - public IFilterArea getFilterArea() { - return filterArea; - } - - protected ISessionContext getSessionContext() { - return sessionContext; - } - - protected Session getSession() { - return sessionContext != null ? sessionContext.getSession() : null; - } - - @Override - public void setInput(ISessionContext context, ISelection selection, boolean force) { - if (isDisposed()) - return; - if (sessionContext == null) - return; - - // Check if this is a duplicate of the previous selection to reduce unnecessary flicker. - if (!force && ObjectUtils.objectEquals(currentInput, selection)) - return; - - //Resource[] rs = ResourceAdaptionUtils.toResources(selection); - Object[] rs = toObjects(selection); -// System.out.println("resources: " + Arrays.toString(rs)); - - if (rs.length == 0) { - explorer.setRoot(GraphExplorer.EMPTY_INPUT); - } else { - if (rs.length == 1) { - explorer.setRoot(rs[0]); - } else { - explorer.setRoot(rs); - } - } - - currentInput = selection; - } - - protected Object[] toObjects(ISelection s) { - ResourceArray[] ras = ResourceAdaptionUtils.toResourceArrays(s); - if (ras.length > 0) - return ras; - Resource[] rs = ResourceAdaptionUtils.toResources(s); - if (rs.length > 0) - return rs; - - if (!(s instanceof IStructuredSelection)) - return new Object[0]; - IStructuredSelection ss = (IStructuredSelection) s; - List result = new ArrayList(); - for (Iterator iterator = ss.iterator(); iterator.hasNext();) - result.add(iterator.next()); - return result.toArray(); - } - - public void setSessionContext(ISessionContext sessionContext) { - if (isDisposed()) - return; - -// System.out.println("setSessionContext: " + sessionContext + " (" + this + ")"); - if (this.sessionContext == sessionContext) - return; - this.sessionContext = sessionContext; - Session session = sessionContext != null ? sessionContext.getSession() : null; - reinitializeExplorer(explorer, sessionContext, session); - } - - protected void reinitializeExplorer(GraphExplorer explorer, ISessionContext sessionContext, Session session) { - if (isDisposed()) - return; - - setupDragSource(sessionContext); - - // TODO: synchronize the explorer somehow to make sure nothing running in its background is trying to modify the explorer during this process - - EvaluatorData data = new EvaluatorDataImpl(); - - if (session != null) { - explorer.setDataSource(new AsyncReadGraphDataSource(session)); - explorer.setDataSource(new ReadGraphDataSource(session)); - - Evaluator resourceEvaluator = data.newEvaluator() - .addViewpoint(new PropertyViewpointFactory(), 1.0) - .addComparator(new AlphanumericComparatorFactory(ColumnKeys.PROPERTY), 2.0) - .addComparator(new AlphanumericComparatorFactory(ColumnKeys.PROPERTY, true), 1.0) - .addLabeler(new StringRepresentationLabelerFactory(ColumnKeys.PROPERTY), 1.0); - - Evaluator statementEvaluator = data.newEvaluator() - .addViewpoint(new PropertyViewpointFactory(), 1.0) - .addComparator(new AlphanumericComparatorFactory(ColumnKeys.PROPERTY), 2.0) - .addComparator(new AlphanumericComparatorFactory(ColumnKeys.PROPERTY, true), 1.0); - - Evaluator relationContextEvaluator = data.newEvaluator() - .addLabeler(new RelationContextLabelerFactory(), 1.0); - - Evaluator propertyEvaluator = data.newEvaluator() - .addViewpoint(new ArrayPropertyValueViewpointFactory(), 1.0) - .addLabeler(new ArrayPropertyLabelerFactory(), 1.0) - .addImager(new ArrayPropertyImagerFactory(), 1.0); - - data.addEvaluator(Resource.class, resourceEvaluator); - data.addEvaluator(ResourceArray.class, resourceEvaluator); - data.addEvaluator(Statement.class, statementEvaluator); - data.addEvaluator(RelationContext.class, relationContextEvaluator); - data.addEvaluator(ResourceProperty.class, propertyEvaluator); - - } else { - explorer.removeDataSource(AsyncReadGraph.class); - explorer.removeDataSource(ReadGraph.class); - } - - explorer.setProcessor(new ComparableFactoryResolver(data)); - explorer.setProcessor(new ViewpointFactoryResolver(data)); - explorer.setProcessor(new LabelerFactoryResolver(data)); - explorer.setProcessor(new ImagerFactoryResolver(data)); - explorer.setProcessor(new LabelDecoratorFactoryResolver(data)); - explorer.setProcessor(new ImageDecoratorFactoryResolver(data)); - explorer.setPrimitiveProcessor(new TypesQueryProcessor()); - - explorer.setPrimitiveProcessor(userSelectedViewpointFactoryQueryProcessor); - explorer.setProcessor(new ComparableSelectorQueryProcessor()); - explorer.setPrimitiveProcessor(userSelectedComparableFactoryQueryProcessor); - explorer.setPrimitiveProcessor(filterSelectionRequestQueryProcessor); - - // Make sure the explorer gets reset. - explorer.setRoot(GraphExplorer.EMPTY_INPUT); - } - - @Override - public void updatePartName(Consumer updateCallback) { - ISelection forSelection = currentInput; - if (forSelection instanceof IStructuredSelection) { - IStructuredSelection s = (IStructuredSelection) forSelection; - int size = s.size(); - if (size == 1) { - Object obj = s.getFirstElement(); - if (obj != null) - updateCallback.accept(obj.toString()); - else - updateCallback.accept("Properties"); - } else { - updateCallback.accept("Properties [" + size + "]"); - } - } else { - updateCallback.accept("Properties"); - } - } - -} +/******************************************************************************* + * 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.selectionview; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.function.Consumer; + +import org.eclipse.jface.action.ContributionItem; +import org.eclipse.jface.action.IContributionItem; +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.resource.LocalResourceManager; +import org.eclipse.jface.viewers.IPostSelectionProvider; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.dnd.DND; +import org.eclipse.swt.dnd.DragSource; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.ToolBar; +import org.eclipse.swt.widgets.ToolItem; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.ui.IActionBars; +import org.eclipse.ui.IWorkbenchSite; +import org.simantics.browsing.ui.GraphExplorer; +import org.simantics.browsing.ui.common.ColumnKeys; +import org.simantics.browsing.ui.common.EvaluatorData; +import org.simantics.browsing.ui.common.EvaluatorData.Evaluator; +import org.simantics.browsing.ui.common.EvaluatorDataImpl; +import org.simantics.browsing.ui.common.comparators.AlphanumericComparatorFactory; +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.IFilterArea; +import org.simantics.browsing.ui.common.views.IFilterAreaProvider; +import org.simantics.browsing.ui.common.views.PropertyTableConstants; +import org.simantics.browsing.ui.graph.impl.ArrayPropertyLabelerFactory; +import org.simantics.browsing.ui.graph.impl.ArrayPropertyValueViewpointFactory; +import org.simantics.browsing.ui.graph.impl.AsyncReadGraphDataSource; +import org.simantics.browsing.ui.graph.impl.PropertyViewpointFactory; +import org.simantics.browsing.ui.graph.impl.ReadGraphDataSource; +import org.simantics.browsing.ui.graph.impl.RelationContextLabelerFactory; +import org.simantics.browsing.ui.graph.impl.ResourceProperty; +import org.simantics.browsing.ui.graph.impl.StringRepresentationLabelerFactory; +import org.simantics.browsing.ui.swt.ArrayPropertyImagerFactory; +import org.simantics.browsing.ui.swt.ComparatorSelector; +import org.simantics.browsing.ui.swt.ContextMenuInitializer; +import org.simantics.browsing.ui.swt.GraphExplorerFactory; +import org.simantics.browsing.ui.swt.PropertyTableUtil; +import org.simantics.browsing.ui.swt.RootFilterArea; +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.RelationContext; +import org.simantics.db.Resource; +import org.simantics.db.Session; +import org.simantics.db.Statement; +import org.simantics.db.common.ResourceArray; +import org.simantics.db.management.ISessionContext; +import org.simantics.ui.dnd.BasicDragSource; +import org.simantics.ui.dnd.SessionContainer; +import org.simantics.ui.utils.ResourceAdaptionUtils; +import org.simantics.utils.ObjectUtils; +import org.simantics.utils.ui.LayoutUtils; + + +/** + *

+ * Subclasses may extend or reimplement the following methods as required: + *

    + *
  • createExplorerControl - reimplement to customize the way the IGraphExplorer control is created
  • + *
  • createControl - reimplement to customize the way other supplementary controls get created
  • + *
  • createDragSource - reimplement to customize the kind of DragSource this control provides
  • + *
+ *

+ * + * @author Tuukka Lehtonen + */ +public class PropertyTable extends Composite implements IFilterAreaProvider, IPropertyTab2 { + + protected IWorkbenchSite site; + protected GraphExplorer explorer; + protected Object dragSource; + protected ISessionContext sessionContext; + protected ISelection currentInput; + + protected UserSelectedComparableFactoryQueryProcessor userSelectedComparableFactoryQueryProcessor; + protected UserSelectedViewpointFactoryQueryProcessor userSelectedViewpointFactoryQueryProcessor; + protected FilterSelectionRequestQueryProcessor filterSelectionRequestQueryProcessor; + + protected LocalResourceManager resourceManager; + + private RootFilterArea filterArea; + private IContributionItem filterAreaContribution; + private IActionBars actionBars; + + public PropertyTable(IWorkbenchSite site, Composite parent, int style) { + super(parent, style); + this.site = site; + //System.out.println("created " + this + " " + System.identityHashCode(this)); + resourceManager = new LocalResourceManager(JFaceResources.getResources(parent.getDisplay())); + + addListener(SWT.Dispose, new Listener() { + @Override + public void handleEvent(Event event) { + //System.out.println("DISPOSING " + this + " " + System.identityHashCode(PropertyTable.this)); + tableDisposed(); + + PropertyTableUtil.setupDragSource(dragSource, null); + + PropertyTable.this.site = null; + explorer = null; + dragSource = null; + sessionContext = null; + currentInput = null; + + userSelectedComparableFactoryQueryProcessor = null; + userSelectedViewpointFactoryQueryProcessor = null; + filterSelectionRequestQueryProcessor = null; + + resourceManager.dispose(); + } + }); + } + + /** + * Override to perform actions when this property table is disposed. + * Remember to call super. + */ + protected void tableDisposed() { + getDisplay().asyncExec(new Runnable() { + @Override + public void run() { + if (filterAreaContribution != null) { + actionBars.getToolBarManager().remove(filterAreaContribution); + filterAreaContribution.dispose(); + filterAreaContribution = null; + actionBars.updateActionBars(); + } + } + }); + } + + @Override + public Control getControl() { + return this; + } + + @Override + public void createControl(final Composite parent, ISessionContext context) { + explorer = createExplorerControl(parent); + dragSource = createDragSource(explorer); + + Control control = explorer.getControl(); + + userSelectedComparableFactoryQueryProcessor = new UserSelectedComparableFactoryQueryProcessor(); + userSelectedViewpointFactoryQueryProcessor = new UserSelectedViewpointFactoryQueryProcessor(); + filterSelectionRequestQueryProcessor = new FilterSelectionRequestQueryProcessor(); + + parent.setLayout(LayoutUtils.createNoBorderGridLayout(2, false)); + GridDataFactory.fillDefaults().grab(true, true).span(2,1).applyTo(control); + + addControls(parent); + setSessionContext(context); + } + + protected void addControls(Composite parent) { + //createSelectors(parent); + //createFilterArea(parent); + } + + protected void createSelectors(Composite parent) { + Control control = explorer.getControl(); + ComparatorSelector comparatorSelector = new ComparatorSelector(explorer, userSelectedComparableFactoryQueryProcessor, parent, SWT.READ_ONLY); + comparatorSelector.moveAbove(control); + ViewpointSelector viewpointSelector = new ViewpointSelector(explorer, userSelectedViewpointFactoryQueryProcessor, parent, SWT.READ_ONLY); + viewpointSelector.moveAbove(control); + } + + protected void createFilterArea(IActionBars actionBars) { + this.filterAreaContribution = new ContributionItem("filterArea") { + ToolItem item; + @Override + public boolean isDynamic() { + return true; + } + @Override + public final void fill(ToolBar parent, int index) { + Control control = createControl(parent); + item = new ToolItem(parent, SWT.SEPARATOR, index); + item.setControl(control); + item.setWidth(computeWidth(control)); + } + protected Control createControl(Composite parent) { + filterArea = new RootFilterArea(explorer, filterSelectionRequestQueryProcessor, parent, SWT.NONE); + return filterArea; + } + protected int computeWidth(Control control) { + // FIXME: better size control? + return control.computeSize(150, SWT.DEFAULT, true).x; + } + @Override + public void dispose() { + if (filterArea != null) { + filterArea.dispose(); + filterArea = null; + } + if (item != null) { + item.dispose(); + item = null; + } + } + }; + this.actionBars = actionBars; + actionBars.getToolBarManager().add(filterAreaContribution); + } + + protected void createFilterArea(Composite parent) { + Control control = explorer.getControl(); + filterArea = new RootFilterArea(explorer, filterSelectionRequestQueryProcessor, parent, SWT.NONE); + filterArea.moveAbove(control); + } + + protected GraphExplorer createExplorerControl(Composite parent) { + GraphExplorer e = GraphExplorerFactory.getInstance().create(parent, SWT.FULL_SELECTION); + Control c = e.getControl(); + ISelectionProvider selectionProvider = (ISelectionProvider)e.getAdapter(ISelectionProvider.class); + new ContextMenuInitializer("#PropertiesPopup").createContextMenu(c, selectionProvider, site); + if (c instanceof Tree) + ((Tree) c).setLinesVisible(true); + e.setColumns(PropertyTableConstants.NORMAL_COLUMNS); + return e; + } + + /** + * Override to customize drag source initialization. This default + * implementation creates a {@link BasicDragSource}. The drag source is + * initialized when the active database session is set. + * + * @param explorer + * @return the object representing the drag source. If the object implements + * {@link SessionContainer}, its + * {@link SessionContainer#setSession(Session)} will be invoked + * every time the active database session changes. + */ + protected Object createDragSource(GraphExplorer explorer) { + Control c = explorer.getControl(); + DragSource existingSource = (DragSource) c.getData(DND.DRAG_SOURCE_KEY); + if (existingSource != null) + return existingSource; + return PropertyTableUtil.createResourceDragSource(explorer); + } + + protected void setupDragSource(ISessionContext sessionContext) { + PropertyTableUtil.setupDragSource(dragSource, sessionContext); + } + + @Override + public ISelectionProvider getSelectionProvider() { + GraphExplorer e = explorer; + if (e != null) { + IPostSelectionProvider selectionProvider = (IPostSelectionProvider)e.getAdapter(IPostSelectionProvider.class); + return selectionProvider; + } + return null; + } + + @Override + public void requestFocus() { + GraphExplorer e = explorer; + if (e != null) + e.setFocus(); + } + + @Override + public IFilterArea getFilterArea() { + return filterArea; + } + + protected ISessionContext getSessionContext() { + return sessionContext; + } + + protected Session getSession() { + return sessionContext != null ? sessionContext.getSession() : null; + } + + @Override + public void setInput(ISessionContext context, ISelection selection, boolean force) { + if (isDisposed()) + return; + if (sessionContext == null) + return; + + // Check if this is a duplicate of the previous selection to reduce unnecessary flicker. + if (!force && ObjectUtils.objectEquals(currentInput, selection)) + return; + + //Resource[] rs = ResourceAdaptionUtils.toResources(selection); + Object[] rs = toObjects(selection); +// System.out.println("resources: " + Arrays.toString(rs)); + + if (rs.length == 0) { + explorer.setRoot(GraphExplorer.EMPTY_INPUT); + } else { + if (rs.length == 1) { + explorer.setRoot(rs[0]); + } else { + explorer.setRoot(rs); + } + } + + currentInput = selection; + } + + protected Object[] toObjects(ISelection s) { + ResourceArray[] ras = ResourceAdaptionUtils.toResourceArrays(s); + if (ras.length > 0) + return ras; + Resource[] rs = ResourceAdaptionUtils.toResources(s); + if (rs.length > 0) + return rs; + + if (!(s instanceof IStructuredSelection)) + return new Object[0]; + IStructuredSelection ss = (IStructuredSelection) s; + List result = new ArrayList(); + for (Iterator iterator = ss.iterator(); iterator.hasNext();) + result.add(iterator.next()); + return result.toArray(); + } + + public void setSessionContext(ISessionContext sessionContext) { + if (isDisposed()) + return; + +// System.out.println("setSessionContext: " + sessionContext + " (" + this + ")"); + if (this.sessionContext == sessionContext) + return; + this.sessionContext = sessionContext; + Session session = sessionContext != null ? sessionContext.getSession() : null; + reinitializeExplorer(explorer, sessionContext, session); + } + + protected void reinitializeExplorer(GraphExplorer explorer, ISessionContext sessionContext, Session session) { + if (isDisposed()) + return; + + setupDragSource(sessionContext); + + // TODO: synchronize the explorer somehow to make sure nothing running in its background is trying to modify the explorer during this process + + EvaluatorData data = new EvaluatorDataImpl(); + + if (session != null) { + explorer.setDataSource(new AsyncReadGraphDataSource(session)); + explorer.setDataSource(new ReadGraphDataSource(session)); + + Evaluator resourceEvaluator = data.newEvaluator() + .addViewpoint(new PropertyViewpointFactory(), 1.0) + .addComparator(new AlphanumericComparatorFactory(ColumnKeys.PROPERTY), 2.0) + .addComparator(new AlphanumericComparatorFactory(ColumnKeys.PROPERTY, true), 1.0) + .addLabeler(new StringRepresentationLabelerFactory(ColumnKeys.PROPERTY), 1.0); + + Evaluator statementEvaluator = data.newEvaluator() + .addViewpoint(new PropertyViewpointFactory(), 1.0) + .addComparator(new AlphanumericComparatorFactory(ColumnKeys.PROPERTY), 2.0) + .addComparator(new AlphanumericComparatorFactory(ColumnKeys.PROPERTY, true), 1.0); + + Evaluator relationContextEvaluator = data.newEvaluator() + .addLabeler(new RelationContextLabelerFactory(), 1.0); + + Evaluator propertyEvaluator = data.newEvaluator() + .addViewpoint(new ArrayPropertyValueViewpointFactory(), 1.0) + .addLabeler(new ArrayPropertyLabelerFactory(), 1.0) + .addImager(new ArrayPropertyImagerFactory(), 1.0); + + data.addEvaluator(Resource.class, resourceEvaluator); + data.addEvaluator(ResourceArray.class, resourceEvaluator); + data.addEvaluator(Statement.class, statementEvaluator); + data.addEvaluator(RelationContext.class, relationContextEvaluator); + data.addEvaluator(ResourceProperty.class, propertyEvaluator); + + } else { + explorer.removeDataSource(AsyncReadGraph.class); + explorer.removeDataSource(ReadGraph.class); + } + + explorer.setProcessor(new ComparableFactoryResolver(data)); + explorer.setProcessor(new ViewpointFactoryResolver(data)); + explorer.setProcessor(new LabelerFactoryResolver(data)); + explorer.setProcessor(new ImagerFactoryResolver(data)); + explorer.setProcessor(new LabelDecoratorFactoryResolver(data)); + explorer.setProcessor(new ImageDecoratorFactoryResolver(data)); + explorer.setPrimitiveProcessor(new TypesQueryProcessor()); + + explorer.setPrimitiveProcessor(userSelectedViewpointFactoryQueryProcessor); + explorer.setProcessor(new ComparableSelectorQueryProcessor()); + explorer.setPrimitiveProcessor(userSelectedComparableFactoryQueryProcessor); + explorer.setPrimitiveProcessor(filterSelectionRequestQueryProcessor); + + // Make sure the explorer gets reset. + explorer.setRoot(GraphExplorer.EMPTY_INPUT); + } + + @Override + public void updatePartName(Consumer updateCallback) { + ISelection forSelection = currentInput; + if (forSelection instanceof IStructuredSelection) { + IStructuredSelection s = (IStructuredSelection) forSelection; + int size = s.size(); + if (size == 1) { + Object obj = s.getFirstElement(); + if (obj != null) + updateCallback.accept(obj.toString()); + else + updateCallback.accept("Properties"); + } else { + updateCallback.accept("Properties [" + size + "]"); + } + } else { + updateCallback.accept("Properties"); + } + } + +}