import org.eclipse.jface.viewers.ISelection;
import org.eclipse.ui.ISelectionListener;
import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.services.IDisposable;
import org.simantics.browsing.ui.GraphExplorer;
-public class DefaultExplorerSelectionListener implements ISelectionListener {
+public class DefaultExplorerSelectionListener implements ISelectionListener, IDisposable {
private static final boolean DEBUG = false;
this.filter = filter;
}
+ @Override
+ public void dispose() {
+ owner = null;
+ explorer = null;
+ filter = null;
+ }
+
@Override
public void selectionChanged(IWorkbenchPart part, ISelection selection) {
// Always disregard own selections.
if (DEBUG)
System.out.println("[" + owner + "] workbench selection changed: part=" + part + ", selection=" + selection);
ISelection s = selection;
+ WorkbenchSelectionFilter filter = this.filter;
if (filter != null)
s = filter.filterSelection(part, selection);
System.out.println("** [" + owner + "] workbench selection changed: part=" + part + ", selection=" + selection);
System.out.println(" SETTING NEW SELECTION");
}
- if(!explorer.isDisposed()) {
+ GraphExplorer explorer = this.explorer;
+ if(explorer != null && !explorer.isDisposed()) {
IPostSelectionProvider selectionProvider = (IPostSelectionProvider)explorer.getAdapter(IPostSelectionProvider.class);
- selectionProvider.setSelection(selection);
+ if (selectionProvider != null) {
+ selectionProvider.setSelection(selection);
+ }
}
} else {
if (DEBUG)
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.part.ViewPart;
+import org.eclipse.ui.services.IDisposable;
import org.simantics.browsing.ui.Column;
import org.simantics.browsing.ui.GraphExplorer;
import org.simantics.browsing.ui.NodeContext;
// Remember to remove the installed workbench selection listener
if (workbenchSelectionListener != null) {
getSite().getWorkbenchWindow().getSelectionService().removePostSelectionListener(workbenchSelectionListener);
+ if (workbenchSelectionListener instanceof IDisposable)
+ ((IDisposable) workbenchSelectionListener).dispose();
workbenchSelectionListener = null;
getSite().setSelectionProvider(null);
return true;
}
- @SuppressWarnings("rawtypes")
+ @SuppressWarnings("unchecked")
@Override
- public Object getAdapter(Class adapter) {
+ public <T> T getAdapter(Class<T> adapter) {
if (GraphExplorer.class == adapter)
- return explorer;
+ return (T) explorer;
else if(ISessionContextProvider.class == adapter)
- return getSessionContextProvider();
+ return (T) getSessionContextProvider();
else if(IPropertyPage.class == adapter)
- return getPropertyPage();
+ return (T) getPropertyPage();
return super.getAdapter(adapter);
import org.simantics.db.Session;
import org.simantics.db.common.procedure.adapter.ListenerAdapter;
import org.simantics.db.common.request.ParametrizedRead;
-import org.simantics.db.common.request.UnaryRead;
+import org.simantics.db.common.request.UniqueRead;
import org.simantics.db.event.ChangeEvent;
import org.simantics.db.event.ChangeListener;
import org.simantics.db.exception.DatabaseException;
import org.simantics.db.management.ISessionContext;
import org.simantics.db.management.ISessionContextProvider;
-import org.simantics.db.request.Read;
import org.simantics.db.service.GraphChangeListenerSupport;
import org.simantics.ui.SimanticsUI;
import org.simantics.utils.datastructures.map.Tuple;
import org.simantics.utils.ui.ExceptionUtils;
import org.simantics.utils.ui.SWTUtils;
import org.simantics.utils.ui.workbench.WorkbenchUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* A helper class for easing the attachment of a Simantics database session to
*/
public class ResourceEditorSupport implements IAdaptable, ChangeListener {
+ private static final Logger LOGGER = LoggerFactory.getLogger(ResourceEditorSupport.class);
+ private static final boolean DEBUG = false;
+
private IEditorPart editorPart;
private ChangeListener editorPartChangeListener;
return;
inputListener = new InputListener();
- getSession().asyncRequest(validationRequest(editorPart), inputListener);
+ getSession().asyncRequest(new ValidationRequest(), inputListener);
}
public synchronized void deactivateValidation() {
if (inputListener == null)
return;
inputListener.dispose();
+ inputListener = null;
}
public ISessionContext getSessionContext() {
return session;
}
- @SuppressWarnings("rawtypes")
+ @SuppressWarnings("unchecked")
@Override
- public Object getAdapter(Class adapter) {
+ public <T> T getAdapter(Class<T> adapter) {
if (adapter == ISessionContext.class)
- return getSessionContext();
+ return (T) getSessionContext();
if (adapter == Session.class)
- return getSession();
+ return (T) getSession();
return null;
}
@Override
public void graphChanged(ChangeEvent e) throws DatabaseException {
- //System.out.println(this + ": graph change: " + e);
// Only forward the update to the editor if the input is still valid and
// the editor implements ChangeListener
if (editorPart instanceof ChangeListener)
}
/**
- * @param input
- * @return a read request that returns <code>true</code> for valid inputs
- * and <code>false</code> for non-existent or invalid inputs.
+ * A read request that returns an {@link Evaluation} of the current state of
+ * <code>editorPart</code>.
+ *
+ * <p>
+ * This request class is not static but has no parameters that could get
+ * stuck in the database client caches. UniqueRead does not need arguments
+ * and without custom hashCode/equals implementations, each instance of this
+ * request is a different one. This is exactly the behaviour we want in this
+ * case.
*/
- private Read<Evaluation> validationRequest(IEditorPart editorPart) {
- return new UnaryRead<IEditorPart, Evaluation>(editorPart) {
- @Override
- public Evaluation perform(ReadGraph graph) throws DatabaseException {
- IEditorInput input = parameter.getEditorInput();
- IResourceEditorInput resourceInput = getResourceInput(parameter);
-
- //System.out.println(ResourceEditorSupport.this + ": checking input " + input);
-
- boolean exists = true;
- boolean valid = true;
- if (resourceInput != null) {
- exists = resourceInput.exists(graph);
- if (exists && inputValidator != null) {
- valid = graph.syncRequest(inputValidator.get(resourceInput));
- }
- } else {
- exists = input.exists();
+ private class ValidationRequest extends UniqueRead<Evaluation> {
+ @Override
+ public Evaluation perform(ReadGraph graph) throws DatabaseException {
+ IEditorPart part = editorPart;
+ if (part == null)
+ return new Evaluation(null, null, InputState.INVALID, "", "");
+
+ IEditorInput input = part.getEditorInput();
+ IResourceEditorInput resourceInput = getResourceInput(part);
+
+ if (DEBUG)
+ LOGGER.trace("ValidationRequest: checking input " + input);
+
+ boolean exists = true;
+ boolean valid = true;
+ if (resourceInput != null) {
+ exists = resourceInput.exists(graph);
+ if (exists && inputValidator != null) {
+ valid = graph.syncRequest(inputValidator.get(resourceInput));
}
+ } else {
+ exists = input.exists();
+ }
- InputState state = InputState.parse(exists, valid);
- if (state == InputState.VALID) {
- // Make sure any cached data in the editor input is up-to-date.
+ InputState state = InputState.parse(exists, valid);
+ if (state == InputState.VALID) {
+ // Make sure any cached data in the editor input is up-to-date.
+ if (resourceInput != null)
resourceInput.update(graph);
- }
-
- Evaluation eval = new Evaluation(parameter, input, state, input.getName(), input.getToolTipText());
- //System.out.println(ResourceEditorSupport.this + ": validation evaluation: " + eval);
- return eval;
}
- };
+
+ Evaluation eval = new Evaluation(part, input, state, input.getName(), input.getToolTipText());
+ if (DEBUG)
+ LOGGER.trace("ValidationRequest: evaluation result: " + eval);
+ return eval;
+ }
}
- private class InputListener extends ListenerAdapter<Evaluation> {
+ private static class InputListener extends ListenerAdapter<Evaluation> {
private boolean disposed = false;
@Override
public void execute(Evaluation evaluation) {
- //System.out.println("InputListener: " + evaluation);
+ if (DEBUG)
+ LOGGER.trace("InputListener: " + evaluation);
switch (evaluation.getInputState()) {
case VALID:
break;
-
case INVALID:
case NON_EXISTENT:
scheduleEditorClose(evaluation.getEditorPart());
@Override
public boolean isDisposed() {
- return disposed || ResourceEditorSupport.this.isDisposed();
+ return disposed;
}
}
- private void scheduleEditorClose(final IEditorPart editorPart) {
- SWTUtils.asyncExec(editorPart.getSite().getShell(), new Runnable() {
- @Override
- public void run() {
- // Don't have to check isDisposed since closeEditor
- // will ignore already closed editor parts.
- WorkbenchUtils.closeEditor(editorPart, false);
- }
+ private static void scheduleEditorClose(IEditorPart editorPart) {
+ SWTUtils.asyncExec(editorPart.getSite().getShell(), () -> {
+ // Don't have to check isDisposed since closeEditor
+ // will ignore already closed editor parts.
+ WorkbenchUtils.closeEditor(editorPart, false);
});
}