blob: f15ad9efcaa80999d88b19ff3696d5ad421e9e2e [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2007, 2017 Wind River Systems, Inc. and others.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.dltk.internal.ui.viewsupport;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import org.eclipse.dltk.internal.core.ModelElement;
import org.eclipse.dltk.internal.ui.editor.ScriptOutlinePage;
import org.eclipse.dltk.ui.DLTKUIPlugin;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.ui.IPartListener2;
import org.eclipse.ui.IWindowListener;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchPartReference;
import org.eclipse.ui.IWorkbenchPartSite;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.contexts.IContextActivation;
import org.eclipse.ui.contexts.IContextService;
import org.eclipse.ui.navigator.CommonNavigator;
import org.eclipse.ui.part.IPage;
import org.eclipse.ui.views.contentoutline.ContentOutline;
/**
* Once registered as windows listener, observes all part activations. Whenever
* the DLTK outline view is brought to the front, the DLTK context is set.
*/
public class ContextActivator implements IWindowListener, IPartListener2 {
private static ContextActivator sInstance = new ContextActivator();
private Map<ContentOutline, IContextActivation> fActivationPerOutline = new HashMap<>();
private Map<CommonNavigator, SelectionListener> fActivationPerNavigator = new HashMap<>();
private Collection<IWorkbenchWindow> fWindows = new HashSet<>();
private ContextActivator() {
}
public static ContextActivator getInstance() {
return sInstance;
}
public void install() {
IWorkbench workbench = PlatformUI.getWorkbench();
if (workbench != null) {
// listen for new windows
workbench.addWindowListener(this);
IWorkbenchWindow[] wnds = workbench.getWorkbenchWindows();
for (int i = 0; i < wnds.length; i++) {
IWorkbenchWindow window = wnds[i];
register(window);
}
// register open windows
IWorkbenchWindow ww = PlatformUI.getWorkbench()
.getActiveWorkbenchWindow();
if (ww != null) {
IWorkbenchPage activePage = ww.getActivePage();
if (activePage != null) {
IWorkbenchPartReference part = activePage
.getActivePartReference();
if (part != null) {
partActivated(part);
}
}
}
}
}
public void uninstall() {
for (Iterator<IWorkbenchWindow> iterator = fWindows.iterator(); iterator
.hasNext();) {
IWorkbenchWindow window = iterator.next();
unregister(window);
}
for (Iterator<SelectionListener> iterator = fActivationPerNavigator
.values().iterator(); iterator.hasNext();) {
SelectionListener l = iterator.next();
l.uninstall();
}
}
private void register(IWorkbenchWindow wnd) {
wnd.getPartService().addPartListener(this);
fWindows.add(wnd);
}
private void unregister(IWorkbenchWindow wnd) {
wnd.getPartService().removePartListener(this);
fWindows.remove(wnd);
}
@Override
public void windowOpened(IWorkbenchWindow window) {
register(window);
}
@Override
public void windowClosed(IWorkbenchWindow window) {
unregister(window);
}
@Override
public void windowActivated(IWorkbenchWindow window) {
}
@Override
public void windowDeactivated(IWorkbenchWindow window) {
}
private void onContentOutlineClosed(ContentOutline outline) {
fActivationPerOutline.remove(outline);
}
private void onContentOutlineActivated(ContentOutline outline) {
IPage page = outline.getCurrentPage();
if (page instanceof ScriptOutlinePage) {
if (!fActivationPerOutline.containsKey(outline)) {
// dltk outline activated for the first time
IContextService ctxtService = outline.getViewSite()
.getService(IContextService.class);
IContextActivation activateContext = ctxtService
.activateContext(DLTKUIPlugin.CONTEXT_VIEWS);
fActivationPerOutline.put(outline, activateContext);
}
} else {
IContextActivation activation = fActivationPerOutline
.remove(outline);
if (activation != null) {
// other outline page brought to front
IContextService ctxtService = outline.getViewSite()
.getService(IContextService.class);
ctxtService.deactivateContext(activation);
}
}
}
private static class SelectionListener
implements ISelectionChangedListener {
private IWorkbenchPartSite fSite;
private IContextService fCtxService;
private IContextActivation fActivation;
public SelectionListener(IWorkbenchPartSite site) {
fSite = site;
fCtxService = fSite.getService(IContextService.class);
ISelectionProvider sp = site.getSelectionProvider();
if (sp != null && fCtxService != null) {
sp.addSelectionChangedListener(this);
onNewSelection(sp.getSelection());
}
}
public void uninstall() {
ISelectionProvider sp = fSite.getSelectionProvider();
if (sp != null && fCtxService != null) {
onNewSelection(null);
sp.removeSelectionChangedListener(this);
}
}
@Override
public void selectionChanged(SelectionChangedEvent event) {
onNewSelection(event.getSelection());
}
private void onNewSelection(ISelection selection) {
boolean isRelevant = false;
if (selection instanceof IStructuredSelection
&& !selection.isEmpty()) {
if (((IStructuredSelection) selection)
.getFirstElement() instanceof ModelElement) {
isRelevant = true;
}
}
if (isRelevant) {
if (fActivation == null) {
fActivation = fCtxService
.activateContext(DLTKUIPlugin.CONTEXT_VIEWS);
}
} else {
if (fActivation != null) {
fCtxService.deactivateContext(fActivation);
fActivation = null;
}
}
}
}
private void onCommonNavigatorActivated(CommonNavigator part) {
SelectionListener l = fActivationPerNavigator.get(part);
if (l == null) {
l = new SelectionListener(part.getSite());
fActivationPerNavigator.put(part, l);
}
}
private void onCommonNavigatorClosed(CommonNavigator part) {
fActivationPerNavigator.remove(part);
}
@Override
public void partActivated(IWorkbenchPartReference partRef) {
IWorkbenchPart part = partRef.getPart(false);
if (part instanceof ContentOutline) {
onContentOutlineActivated((ContentOutline) part);
} else if (part instanceof CommonNavigator) {
onCommonNavigatorActivated((CommonNavigator) part);
}
}
@Override
public void partClosed(IWorkbenchPartReference partRef) {
IWorkbenchPart part = partRef.getPart(false);
if (part instanceof ContentOutline) {
onContentOutlineClosed((ContentOutline) part);
} else if (part instanceof CommonNavigator) {
onCommonNavigatorClosed((CommonNavigator) part);
}
}
@Override
public void partBroughtToTop(IWorkbenchPartReference partRef) {
}
@Override
public void partDeactivated(IWorkbenchPartReference partRef) {
}
@Override
public void partOpened(IWorkbenchPartReference partRef) {
}
@Override
public void partHidden(IWorkbenchPartReference partRef) {
}
@Override
public void partVisible(IWorkbenchPartReference partRef) {
}
@Override
public void partInputChanged(IWorkbenchPartReference partRef) {
}
}