X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.diagram%2Fsrc%2Forg%2Fsimantics%2Fdiagram%2Fui%2FWorkbenchSelectionProvider.java;fp=bundles%2Forg.simantics.diagram%2Fsrc%2Forg%2Fsimantics%2Fdiagram%2Fui%2FWorkbenchSelectionProvider.java;h=5f46a373b2ecefbf85192cbb5be8380c4bee79a9;hp=5bd73f97a463b74f0ecb4f84842ac454a903212d;hb=0ae2b770234dfc3cbb18bd38f324125cf0faca07;hpb=24e2b34260f219f0d1644ca7a138894980e25b14 diff --git a/bundles/org.simantics.diagram/src/org/simantics/diagram/ui/WorkbenchSelectionProvider.java b/bundles/org.simantics.diagram/src/org/simantics/diagram/ui/WorkbenchSelectionProvider.java index 5bd73f97a..5f46a373b 100644 --- a/bundles/org.simantics.diagram/src/org/simantics/diagram/ui/WorkbenchSelectionProvider.java +++ b/bundles/org.simantics.diagram/src/org/simantics/diagram/ui/WorkbenchSelectionProvider.java @@ -1,227 +1,227 @@ -/******************************************************************************* - * 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.diagram.ui; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Optional; -import java.util.concurrent.CopyOnWriteArrayList; -import java.util.concurrent.TimeUnit; - -import org.eclipse.jface.viewers.IPostSelectionProvider; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.ISelectionChangedListener; -import org.eclipse.jface.viewers.SelectionChangedEvent; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.ui.IWorkbenchPartSite; -import org.simantics.db.exception.DatabaseException; -import org.simantics.diagram.elements.AdaptableImmutableProxyElement; -import org.simantics.g2d.canvas.ICanvasContext; -import org.simantics.g2d.canvas.impl.AbstractCanvasParticipant; -import org.simantics.g2d.canvas.impl.DependencyReflection.Dependency; -import org.simantics.g2d.canvas.impl.HintReflection.HintListener; -import org.simantics.g2d.diagram.participant.ElementJSON; -import org.simantics.g2d.diagram.participant.Selection; -import org.simantics.g2d.element.ElementHints; -import org.simantics.g2d.element.IElement; -import org.simantics.ui.selection.WorkbenchSelectionUtils; -import org.simantics.utils.datastructures.hints.IHintContext.Key; -import org.simantics.utils.datastructures.hints.IHintObservable; -import org.simantics.utils.threads.IThreadWorkQueue; -import org.simantics.utils.threads.ThreadUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * A canvas participant that listens to the #0 mouse selection and provides it - * forward through the {@link IPostSelectionProvider} interface. - * - * @author Tuukka Lehtonen - */ -public class WorkbenchSelectionProvider extends AbstractCanvasParticipant implements IPostSelectionProvider, ElementJSON { - - private static final Logger LOGGER = LoggerFactory.getLogger(WorkbenchSelectionProvider.class); - - private static final long POST_SELECTION_DELAY = 300; - - @Dependency protected Selection selection; - - protected IThreadWorkQueue swt; - protected IWorkbenchPartSite site; - protected ISelection currentSelection = StructuredSelection.EMPTY; - protected CopyOnWriteArrayList listeners = new CopyOnWriteArrayList(); - protected CopyOnWriteArrayList postListeners = new CopyOnWriteArrayList(); - - public WorkbenchSelectionProvider(IThreadWorkQueue swt) { - this(swt, null); - } - - public WorkbenchSelectionProvider(IThreadWorkQueue swt, IWorkbenchPartSite site) { - this.swt = swt; - this.site = site; - if (site != null) - site.setSelectionProvider(this); - } - - @Override - public void addedToContext(ICanvasContext ctx) { - super.addedToContext(ctx); - if (site != null && site.getSelectionProvider() != this) { - swt.asyncExec(new Runnable() { - @Override - public void run() { - if (site.getSelectionProvider() != WorkbenchSelectionProvider.this) - site.setSelectionProvider(WorkbenchSelectionProvider.this); - } - }); - } - } - - @Override - public void removedFromContext(ICanvasContext ctx) { - if (site != null && site.getSelectionProvider() == this) { - swt.asyncExec(new Runnable() { - @Override - public void run() { - if (site.getSelectionProvider() == WorkbenchSelectionProvider.this) - site.setSelectionProvider(null); - } - }); - } - super.removedFromContext(ctx); - } - - @HintListener(Class = Selection.class, Field = "SELECTION0") - public void hintChanged(IHintObservable sender, Key key, Object oldValue, Object newValue) { - Iterable selection = (Iterable) newValue; - final ISelection s = constructAdaptableSelection(selection); - swt.asyncExec(new Runnable() { - @Override - public void run() { - currentSelection = s; - fireSelectionChanged(s); - schedulePostSelectionChanged(s); - } - }); - } - - @HintListener(Class = Selection.class, Field = "SELECTION0") - public void hintRemoved(IHintObservable sender, Key key, Object oldValue) { - //System.out.println("selection removed: " + oldValue); - final ISelection s = constructAdaptableSelection(Collections.emptyList()); - swt.asyncExec(new Runnable() { - @Override - public void run() { - currentSelection = s; - fireSelectionChanged(s); - schedulePostSelectionChanged(s); - } - }); - } - - // Post selection changed scheduling helper. - private int modCount = 0; - - protected void schedulePostSelectionChanged(final ISelection s) { - final int count = ++modCount; - ThreadUtils.getNonBlockingWorkExecutor().schedule(new Runnable() { - @Override - public void run() { - int newCount = modCount; - if (count != newCount) - return; - if (isRemoved()) - return; - swt.asyncExec(new Runnable() { - @Override - public void run() { - if (isRemoved()) - return; - firePostSelectionChanged(s); - } - }); - } - }, POST_SELECTION_DELAY, TimeUnit.MILLISECONDS); - } - - protected ISelection constructAdaptableSelection(Iterable selection) { - ArrayList objects = new ArrayList(); - for (Object o : selection) { - if (o instanceof IElement) { - IElement e = (IElement) o; - Object object = e.getHint(ElementHints.KEY_OBJECT); - if (object != null) { - objects.add(new AdaptableImmutableProxyElement(e)); - } else { - System.out.println(" discarding element from selection, null object for " + e); - } - } else { - System.out.println(" unrecognized selection: " + o.getClass() + ": " + o); - } - } - return new StructuredSelection(objects); - } - - void fireSelectionChanged(ISelection selection) { - SelectionChangedEvent e = new SelectionChangedEvent(this, selection); - for (ISelectionChangedListener l : listeners) - l.selectionChanged(e); - } - - void firePostSelectionChanged(ISelection selection) { - SelectionChangedEvent e = new SelectionChangedEvent(this, selection); - for (ISelectionChangedListener l : postListeners) - l.selectionChanged(e); - } - - @Override - public void addPostSelectionChangedListener(ISelectionChangedListener listener) { - postListeners.add(listener); - } - - @Override - public void removePostSelectionChangedListener(ISelectionChangedListener listener) { - postListeners.remove(listener); - } - - @Override - public void addSelectionChangedListener(ISelectionChangedListener listener) { - listeners.add(listener); - } - - @Override - public void removeSelectionChangedListener(ISelectionChangedListener listener) { - listeners.remove(listener); - } - - @Override - public ISelection getSelection() { - return currentSelection; - } - - @Override - public void setSelection(ISelection selection) { - System.out.println("WorkbenchSelectionProvider: TODO: set selection: " + selection); - } - - @Override - public Optional getJSON(IElement element) { - ISelection sel = constructAdaptableSelection(Collections.singleton(element)); - try { - return Optional.ofNullable( WorkbenchSelectionUtils.getPossibleJSON(sel) ); - } catch (DatabaseException e) { - LOGGER.error("Unexpected failure while constructing JSON from element " + element, e); - return Optional.empty(); - } - } - -} +/******************************************************************************* + * 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.diagram.ui; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Optional; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.TimeUnit; + +import org.eclipse.jface.viewers.IPostSelectionProvider; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.ui.IWorkbenchPartSite; +import org.simantics.db.exception.DatabaseException; +import org.simantics.diagram.elements.AdaptableImmutableProxyElement; +import org.simantics.g2d.canvas.ICanvasContext; +import org.simantics.g2d.canvas.impl.AbstractCanvasParticipant; +import org.simantics.g2d.canvas.impl.DependencyReflection.Dependency; +import org.simantics.g2d.canvas.impl.HintReflection.HintListener; +import org.simantics.g2d.diagram.participant.ElementJSON; +import org.simantics.g2d.diagram.participant.Selection; +import org.simantics.g2d.element.ElementHints; +import org.simantics.g2d.element.IElement; +import org.simantics.ui.selection.WorkbenchSelectionUtils; +import org.simantics.utils.datastructures.hints.IHintContext.Key; +import org.simantics.utils.datastructures.hints.IHintObservable; +import org.simantics.utils.threads.IThreadWorkQueue; +import org.simantics.utils.threads.ThreadUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * A canvas participant that listens to the #0 mouse selection and provides it + * forward through the {@link IPostSelectionProvider} interface. + * + * @author Tuukka Lehtonen + */ +public class WorkbenchSelectionProvider extends AbstractCanvasParticipant implements IPostSelectionProvider, ElementJSON { + + private static final Logger LOGGER = LoggerFactory.getLogger(WorkbenchSelectionProvider.class); + + private static final long POST_SELECTION_DELAY = 300; + + @Dependency protected Selection selection; + + protected IThreadWorkQueue swt; + protected IWorkbenchPartSite site; + protected ISelection currentSelection = StructuredSelection.EMPTY; + protected CopyOnWriteArrayList listeners = new CopyOnWriteArrayList(); + protected CopyOnWriteArrayList postListeners = new CopyOnWriteArrayList(); + + public WorkbenchSelectionProvider(IThreadWorkQueue swt) { + this(swt, null); + } + + public WorkbenchSelectionProvider(IThreadWorkQueue swt, IWorkbenchPartSite site) { + this.swt = swt; + this.site = site; + if (site != null) + site.setSelectionProvider(this); + } + + @Override + public void addedToContext(ICanvasContext ctx) { + super.addedToContext(ctx); + if (site != null && site.getSelectionProvider() != this) { + swt.asyncExec(new Runnable() { + @Override + public void run() { + if (site.getSelectionProvider() != WorkbenchSelectionProvider.this) + site.setSelectionProvider(WorkbenchSelectionProvider.this); + } + }); + } + } + + @Override + public void removedFromContext(ICanvasContext ctx) { + if (site != null && site.getSelectionProvider() == this) { + swt.asyncExec(new Runnable() { + @Override + public void run() { + if (site.getSelectionProvider() == WorkbenchSelectionProvider.this) + site.setSelectionProvider(null); + } + }); + } + super.removedFromContext(ctx); + } + + @HintListener(Class = Selection.class, Field = "SELECTION0") + public void hintChanged(IHintObservable sender, Key key, Object oldValue, Object newValue) { + Iterable selection = (Iterable) newValue; + final ISelection s = constructAdaptableSelection(selection); + swt.asyncExec(new Runnable() { + @Override + public void run() { + currentSelection = s; + fireSelectionChanged(s); + schedulePostSelectionChanged(s); + } + }); + } + + @HintListener(Class = Selection.class, Field = "SELECTION0") + public void hintRemoved(IHintObservable sender, Key key, Object oldValue) { + //System.out.println("selection removed: " + oldValue); + final ISelection s = constructAdaptableSelection(Collections.emptyList()); + swt.asyncExec(new Runnable() { + @Override + public void run() { + currentSelection = s; + fireSelectionChanged(s); + schedulePostSelectionChanged(s); + } + }); + } + + // Post selection changed scheduling helper. + private int modCount = 0; + + protected void schedulePostSelectionChanged(final ISelection s) { + final int count = ++modCount; + ThreadUtils.getNonBlockingWorkExecutor().schedule(new Runnable() { + @Override + public void run() { + int newCount = modCount; + if (count != newCount) + return; + if (isRemoved()) + return; + swt.asyncExec(new Runnable() { + @Override + public void run() { + if (isRemoved()) + return; + firePostSelectionChanged(s); + } + }); + } + }, POST_SELECTION_DELAY, TimeUnit.MILLISECONDS); + } + + protected ISelection constructAdaptableSelection(Iterable selection) { + ArrayList objects = new ArrayList(); + for (Object o : selection) { + if (o instanceof IElement) { + IElement e = (IElement) o; + Object object = e.getHint(ElementHints.KEY_OBJECT); + if (object != null) { + objects.add(new AdaptableImmutableProxyElement(e)); + } else { + System.out.println(" discarding element from selection, null object for " + e); + } + } else { + System.out.println(" unrecognized selection: " + o.getClass() + ": " + o); + } + } + return new StructuredSelection(objects); + } + + void fireSelectionChanged(ISelection selection) { + SelectionChangedEvent e = new SelectionChangedEvent(this, selection); + for (ISelectionChangedListener l : listeners) + l.selectionChanged(e); + } + + void firePostSelectionChanged(ISelection selection) { + SelectionChangedEvent e = new SelectionChangedEvent(this, selection); + for (ISelectionChangedListener l : postListeners) + l.selectionChanged(e); + } + + @Override + public void addPostSelectionChangedListener(ISelectionChangedListener listener) { + postListeners.add(listener); + } + + @Override + public void removePostSelectionChangedListener(ISelectionChangedListener listener) { + postListeners.remove(listener); + } + + @Override + public void addSelectionChangedListener(ISelectionChangedListener listener) { + listeners.add(listener); + } + + @Override + public void removeSelectionChangedListener(ISelectionChangedListener listener) { + listeners.remove(listener); + } + + @Override + public ISelection getSelection() { + return currentSelection; + } + + @Override + public void setSelection(ISelection selection) { + System.out.println("WorkbenchSelectionProvider: TODO: set selection: " + selection); + } + + @Override + public Optional getJSON(IElement element) { + ISelection sel = constructAdaptableSelection(Collections.singleton(element)); + try { + return Optional.ofNullable( WorkbenchSelectionUtils.getPossibleJSON(sel) ); + } catch (DatabaseException e) { + LOGGER.error("Unexpected failure while constructing JSON from element " + element, e); + return Optional.empty(); + } + } + +}