X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.selectionview%2Fsrc%2Forg%2Fsimantics%2Fselectionview%2FPropertyTable.java;fp=bundles%2Forg.simantics.selectionview%2Fsrc%2Forg%2Fsimantics%2Fselectionview%2FPropertyTable.java;h=4bb45be716b3723ee1a3bc707d7902f5a059dee8;hb=969bd23cab98a79ca9101af33334000879fb60c5;hp=0000000000000000000000000000000000000000;hpb=866dba5cd5a3929bbeae85991796acb212338a08;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
new file mode 100644
index 000000000..4bb45be71
--- /dev/null
+++ b/bundles/org.simantics.selectionview/src/org/simantics/selectionview/PropertyTable.java
@@ -0,0 +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:
+ *
+ * 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