| /******************************************************************************* |
| * Copyright (c) 2010, 2017 IBM Corporation and others. |
| * 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: |
| * IBM Corporation - initial API and implementation |
| * Lars Vogel <Lars.Vogel@vogella.com> - Bug 472654 |
| ******************************************************************************/ |
| |
| package org.eclipse.ui.internal.e4.compatibility; |
| |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.Map; |
| import java.util.Set; |
| import javax.annotation.PreDestroy; |
| import javax.inject.Inject; |
| import javax.inject.Named; |
| import org.eclipse.core.runtime.ListenerList; |
| import org.eclipse.e4.core.contexts.IEclipseContext; |
| import org.eclipse.e4.core.di.annotations.Optional; |
| import org.eclipse.e4.ui.model.application.MApplication; |
| import org.eclipse.e4.ui.model.application.ui.basic.MPart; |
| import org.eclipse.e4.ui.services.IServiceConstants; |
| import org.eclipse.e4.ui.workbench.modeling.ESelectionService; |
| import org.eclipse.jface.viewers.ISelection; |
| import org.eclipse.jface.viewers.ISelectionChangedListener; |
| import org.eclipse.jface.viewers.ISelectionProvider; |
| import org.eclipse.jface.viewers.SelectionChangedEvent; |
| import org.eclipse.jface.viewers.StructuredSelection; |
| import org.eclipse.ui.INullSelectionListener; |
| import org.eclipse.ui.ISelectionListener; |
| import org.eclipse.ui.ISelectionService; |
| import org.eclipse.ui.ISources; |
| import org.eclipse.ui.IWorkbenchPart; |
| import org.eclipse.ui.internal.E4PartWrapper; |
| import org.eclipse.ui.internal.WorkbenchPage; |
| |
| public class SelectionService implements ISelectionChangedListener, ISelectionService { |
| |
| @Inject |
| private IEclipseContext context; |
| |
| @Inject |
| private MApplication application; |
| |
| private ESelectionService selectionService; |
| |
| @Inject |
| @Optional |
| @Named("org.eclipse.ui.IWorkbenchPage") |
| private WorkbenchPage page; |
| |
| private IWorkbenchPart activePart; |
| |
| private ListenerList<ISelectionListener> listeners = new ListenerList<>(); |
| private ListenerList<ISelectionListener> postSelectionListeners = new ListenerList<>(); |
| private Map<String, Set<ISelectionListener>> targetedListeners = new HashMap<>(); |
| private Map<String, Set<ISelectionListener>> targetedPostSelectionListeners = new HashMap<>(); |
| |
| private org.eclipse.e4.ui.workbench.modeling.ISelectionListener listener = (part, selection) -> handleSelectionChanged(part, selection, false); |
| |
| private org.eclipse.e4.ui.workbench.modeling.ISelectionListener targetedListener = (part, selection) -> handleSelectionChanged(part, selection, true); |
| |
| private org.eclipse.e4.ui.workbench.modeling.ISelectionListener postListener = (part, selection) -> handlePostSelectionChanged(part, selection, false); |
| |
| private org.eclipse.e4.ui.workbench.modeling.ISelectionListener targetedPostListener = (part, selection) -> handlePostSelectionChanged(part, selection, true); |
| |
| private void handleSelectionChanged(MPart part, Object selection, boolean targeted) { |
| selection = createCompatibilitySelection(selection); |
| context.set(ISources.ACTIVE_CURRENT_SELECTION_NAME, selection); |
| |
| IEclipseContext applicationContext = application.getContext(); |
| if (applicationContext.getActiveChild() == context) { |
| application.getContext().set(ISources.ACTIVE_CURRENT_SELECTION_NAME, selection); |
| } |
| |
| Object client = part.getObject(); |
| if (client instanceof CompatibilityPart) { |
| IWorkbenchPart workbenchPart = ((CompatibilityPart) client).getPart(); |
| if (targeted) { |
| notifyListeners(workbenchPart, (ISelection) selection, part.getElementId(), |
| targetedListeners); |
| } else { |
| notifyListeners(workbenchPart, (ISelection) selection, listeners); |
| } |
| } else if (client != null) { |
| if (part.getTransientData().get(E4PartWrapper.E4_WRAPPER_KEY) instanceof E4PartWrapper) { |
| IWorkbenchPart workbenchPart = (IWorkbenchPart) part.getTransientData() |
| .get(E4PartWrapper.E4_WRAPPER_KEY); |
| if (targeted) { |
| notifyListeners(workbenchPart, (ISelection) selection, part.getElementId(), targetedListeners); |
| } else { |
| notifyListeners(workbenchPart, (ISelection) selection, listeners); |
| } |
| } |
| } |
| } |
| |
| private void handlePostSelectionChanged(MPart part, Object selection, boolean targeted) { |
| selection = createCompatibilitySelection(selection); |
| |
| Object client = part.getObject(); |
| if (client instanceof CompatibilityPart) { |
| IWorkbenchPart workbenchPart = ((CompatibilityPart) client).getPart(); |
| if (targeted) { |
| notifyListeners(workbenchPart, (ISelection) selection, part.getElementId(), |
| targetedPostSelectionListeners); |
| } else { |
| notifyListeners(workbenchPart, (ISelection) selection, postSelectionListeners); |
| } |
| } else if (client != null) { |
| if (part.getTransientData().get(E4PartWrapper.E4_WRAPPER_KEY) instanceof E4PartWrapper) { |
| IWorkbenchPart workbenchPart = (IWorkbenchPart) part.getTransientData() |
| .get(E4PartWrapper.E4_WRAPPER_KEY); |
| if (targeted) { |
| notifyListeners(workbenchPart, (ISelection) selection, part.getElementId(), |
| targetedPostSelectionListeners); |
| } else { |
| notifyListeners(workbenchPart, (ISelection) selection, postSelectionListeners); |
| } |
| } |
| } |
| } |
| |
| private static ISelection createCompatibilitySelection(Object selection) { |
| if (selection instanceof ISelection) { |
| return (ISelection) selection; |
| } |
| return selection == null ? StructuredSelection.EMPTY : new StructuredSelection( |
| selection); |
| } |
| |
| /** |
| * Updates the selection of the workbench window with that of the active |
| * part's. |
| * |
| * @param activePart |
| * the currently active part |
| */ |
| public void updateSelection(IWorkbenchPart activePart) { |
| if (activePart != null) { |
| ISelectionProvider selectionProvider = activePart.getSite().getSelectionProvider(); |
| if (selectionProvider != null) { |
| ISelection selection = selectionProvider.getSelection(); |
| context.set(ISources.ACTIVE_CURRENT_SELECTION_NAME, selection); |
| |
| IEclipseContext applicationContext = application.getContext(); |
| if (applicationContext.getActiveChild() == context) { |
| application.getContext().set(ISources.ACTIVE_CURRENT_SELECTION_NAME, selection); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Notifies selection listeners about selection change caused by active part |
| * change. |
| * |
| * @param activePart |
| * the currently active part |
| */ |
| public void notifyListeners(IWorkbenchPart activePart) { |
| if (activePart != null) { |
| ISelectionProvider selectionProvider = activePart.getSite().getSelectionProvider(); |
| if (selectionProvider != null) { |
| ISelection selection = selectionProvider.getSelection(); |
| |
| notifyListeners(activePart, selection, listeners); |
| notifyListeners(activePart, selection, activePart.getSite().getId(), targetedListeners); |
| notifyListeners(activePart, selection, postSelectionListeners); |
| notifyListeners(activePart, selection, activePart.getSite().getId(), targetedPostSelectionListeners); |
| } |
| } |
| } |
| |
| @Inject |
| void setPart(@Optional @Named(IServiceConstants.ACTIVE_PART) final MPart part) { |
| activePart = null; |
| if (part != null) { |
| Object client = part.getObject(); |
| if (client instanceof CompatibilityPart) { |
| IWorkbenchPart workbenchPart = ((CompatibilityPart) client).getPart(); |
| activePart = workbenchPart; |
| } else if (client != null) { |
| if (part.getTransientData().get(E4PartWrapper.E4_WRAPPER_KEY) instanceof E4PartWrapper) { |
| activePart = (IWorkbenchPart) part.getTransientData().get( |
| E4PartWrapper.E4_WRAPPER_KEY); |
| } |
| } |
| } |
| } |
| |
| @Inject |
| void setSelectionService(@Optional ESelectionService selectionService) { |
| if (this.selectionService != null) { |
| this.selectionService.removeSelectionListener(listener); |
| for (String partId : targetedListeners.keySet()) { |
| this.selectionService.removeSelectionListener(partId, targetedListener); |
| } |
| |
| this.selectionService.removePostSelectionListener(postListener); |
| for (String partId : targetedPostSelectionListeners.keySet()) { |
| this.selectionService.removePostSelectionListener(partId, targetedPostListener); |
| } |
| } |
| |
| if (selectionService != null) { |
| selectionService.addSelectionListener(listener); |
| for (String partId : targetedListeners.keySet()) { |
| selectionService.addSelectionListener(partId, targetedListener); |
| } |
| |
| selectionService.addPostSelectionListener(postListener); |
| for (String partId : targetedPostSelectionListeners.keySet()) { |
| selectionService.addPostSelectionListener(partId, targetedPostListener); |
| } |
| this.selectionService = selectionService; |
| } |
| } |
| |
| @PreDestroy |
| public void dispose() { |
| setSelectionService(null); |
| selectionService = null; |
| listeners.clear(); |
| postSelectionListeners.clear(); |
| targetedListeners.clear(); |
| targetedPostSelectionListeners.clear(); |
| } |
| |
| private void notifyListeners(IWorkbenchPart workbenchPart, ISelection selection, |
| ListenerList<ISelectionListener> listenerList) { |
| for (ISelectionListener listener : listenerList) { |
| if (selection != null || listener instanceof INullSelectionListener) { |
| listener.selectionChanged(workbenchPart, selection); |
| } |
| } |
| } |
| |
| private void notifyListeners(IWorkbenchPart workbenchPart, ISelection selection, String id, |
| Map<String, Set<ISelectionListener>> listenerMap) { |
| if (id != null) { |
| Set<ISelectionListener> listeners = listenerMap.get(id); |
| if (listeners != null) { |
| for (ISelectionListener listener : listeners) { |
| if (selection != null || listener instanceof INullSelectionListener) { |
| listener.selectionChanged(workbenchPart, selection); |
| } |
| } |
| } |
| } |
| } |
| |
| @Override |
| public void addSelectionListener(ISelectionListener listener) { |
| listeners.add(listener); |
| } |
| |
| @Override |
| public void addSelectionListener(String partId, ISelectionListener listener) { |
| Set<ISelectionListener> listeners = targetedListeners.get(partId); |
| if (listeners == null) { |
| listeners = new HashSet<>(); |
| targetedListeners.put(partId, listeners); |
| } |
| if (listeners.size() == 0 && selectionService != null) { |
| selectionService.addSelectionListener(partId, this.targetedListener); |
| } |
| listeners.add(listener); |
| } |
| |
| @Override |
| public void addPostSelectionListener(ISelectionListener listener) { |
| postSelectionListeners.add(listener); |
| } |
| |
| @Override |
| public void addPostSelectionListener(String partId, ISelectionListener listener) { |
| Set<ISelectionListener> listeners = targetedPostSelectionListeners.get(partId); |
| if (listeners == null) { |
| listeners = new HashSet<>(); |
| targetedPostSelectionListeners.put(partId, listeners); |
| } |
| if (listeners.size() == 0 && selectionService != null) { |
| selectionService.addPostSelectionListener(partId, targetedPostListener); |
| } |
| listeners.add(listener); |
| } |
| |
| @Override |
| public ISelection getSelection() { |
| if (activePart != null) { |
| // get the selection from the active part |
| ISelectionProvider selectionProvider = activePart.getSite().getSelectionProvider(); |
| return selectionProvider == null ? null : selectionProvider.getSelection(); |
| } |
| |
| Object selection = selectionService.getSelection(); |
| if (selection == null || selection instanceof ISelection) { |
| return (ISelection) selection; |
| } |
| return new StructuredSelection(selection); |
| } |
| |
| @Override |
| public ISelection getSelection(String partId) { |
| Object selection = selectionService.getSelection(partId); |
| if (selection == null || selection instanceof ISelection) { |
| return (ISelection) selection; |
| } |
| return new StructuredSelection(selection); |
| } |
| |
| @Override |
| public void removeSelectionListener(ISelectionListener listener) { |
| listeners.remove(listener); |
| } |
| |
| @Override |
| public void removeSelectionListener(String partId, ISelectionListener listener) { |
| Set<ISelectionListener> listeners = targetedListeners.get(partId); |
| if (listeners != null) { |
| listeners.remove(listener); |
| if (listeners.size() == 0 && selectionService != null) { |
| selectionService.removeSelectionListener(partId, this.targetedListener); |
| } |
| } |
| } |
| |
| @Override |
| public void removePostSelectionListener(ISelectionListener listener) { |
| postSelectionListeners.remove(listener); |
| } |
| |
| @Override |
| public void removePostSelectionListener(String partId, ISelectionListener listener) { |
| Set<ISelectionListener> listeners = targetedPostSelectionListeners.get(partId); |
| if (listeners != null) { |
| listeners.remove(listener); |
| if (listeners.size() == 0 && selectionService != null) { |
| selectionService.removePostSelectionListener(partId, targetedPostListener); |
| } |
| } |
| } |
| |
| @Override |
| public void selectionChanged(SelectionChangedEvent e) { |
| MPart part = page.findPart(activePart); |
| ESelectionService selectionService = part.getContext().get(ESelectionService.class); |
| selectionService.setSelection(e.getSelection()); |
| } |
| |
| } |