| package org.eclipse.dltk.ui.browsing.ext; |
| |
| import java.util.ArrayList; |
| import java.util.Iterator; |
| import java.util.List; |
| |
| import org.eclipse.core.resources.IContainer; |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.resources.IMarker; |
| import org.eclipse.core.runtime.IAdaptable; |
| import org.eclipse.core.runtime.IConfigurationElement; |
| import org.eclipse.core.runtime.IExecutableExtension; |
| import org.eclipse.core.runtime.ListenerList; |
| import org.eclipse.dltk.core.DLTKCore; |
| import org.eclipse.dltk.core.DLTKLanguageManager; |
| import org.eclipse.dltk.core.ElementChangedEvent; |
| import org.eclipse.dltk.core.IDLTKLanguageToolkit; |
| import org.eclipse.dltk.core.IElementChangedListener; |
| import org.eclipse.dltk.core.IModelElement; |
| import org.eclipse.dltk.core.IModelElementDelta; |
| import org.eclipse.dltk.core.IProjectFragment; |
| import org.eclipse.dltk.core.IScriptProject; |
| import org.eclipse.dltk.core.search.SearchEngine; |
| import org.eclipse.dltk.internal.ui.actions.BuildActionGroup; |
| import org.eclipse.dltk.internal.ui.actions.CCPActionGroup; |
| import org.eclipse.dltk.internal.ui.actions.CompositeActionGroup; |
| import org.eclipse.dltk.internal.ui.actions.ImportActionGroup; |
| import org.eclipse.dltk.internal.ui.actions.NewWizardsActionGroup; |
| import org.eclipse.dltk.internal.ui.actions.refactoring.RefactorActionGroup; |
| import org.eclipse.dltk.internal.ui.search.SearchUtil; |
| import org.eclipse.dltk.ui.DLTKExecuteExtensionHelper; |
| import org.eclipse.dltk.ui.DLTKUILanguageManager; |
| import org.eclipse.dltk.ui.DLTKUIPlugin; |
| import org.eclipse.dltk.ui.ModelElementSorter; |
| import org.eclipse.dltk.ui.actions.OpenEditorActionGroup; |
| import org.eclipse.dltk.ui.actions.OpenViewActionGroup; |
| import org.eclipse.dltk.ui.actions.SearchActionGroup; |
| import org.eclipse.dltk.ui.infoviews.AbstractInfoView; |
| import org.eclipse.dltk.ui.viewsupport.IViewPartInputProvider; |
| import org.eclipse.jface.action.IAction; |
| import org.eclipse.jface.action.IMenuListener; |
| import org.eclipse.jface.action.IMenuManager; |
| import org.eclipse.jface.action.MenuManager; |
| 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.jface.viewers.StructuredSelection; |
| import org.eclipse.jface.viewers.TreeViewer; |
| import org.eclipse.jface.viewers.Viewer; |
| import org.eclipse.search.ui.ISearchResultViewPart; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.layout.FillLayout; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.Control; |
| import org.eclipse.swt.widgets.Menu; |
| import org.eclipse.ui.IPartListener2; |
| import org.eclipse.ui.ISelectionListener; |
| import org.eclipse.ui.IWorkbenchPage; |
| import org.eclipse.ui.IWorkbenchPart; |
| import org.eclipse.ui.IWorkbenchPartReference; |
| import org.eclipse.ui.actions.ActionContext; |
| import org.eclipse.ui.actions.ActionGroup; |
| import org.eclipse.ui.contexts.IContextActivation; |
| import org.eclipse.ui.contexts.IContextService; |
| import org.eclipse.ui.part.ViewPart; |
| |
| public class ExtendedClassesView extends ViewPart |
| implements IViewPartInputProvider, ISelectionListener, |
| ISelectionProvider, IExecutableExtension, IMenuListener { |
| |
| private final class IElementChangedListenerImplementation |
| implements IElementChangedListener { |
| @Override |
| public void elementChanged(ElementChangedEvent event) { |
| // We need to update |
| // if (event.getType() == ElementChangedEvent.POST_CHANGE) { |
| IModelElementDelta delta = event.getDelta(); |
| if (browsingPane != null && !browsingPane.isDisposed() |
| && typesChanged(delta)) { |
| browsingPane.getDisplay() |
| .asyncExec(() -> browsingPane.refresh()); |
| } |
| // } |
| } |
| |
| private boolean typesChanged(IModelElementDelta delta) { |
| IModelElementDelta[] affectedChildren = delta.getAffectedChildren(); |
| for (int i = 0; i < affectedChildren.length; i++) { |
| if (affectedChildren[i].getElement() |
| .getElementType() == IModelElement.TYPE) { |
| return true; |
| } else { |
| if (typesChanged(affectedChildren[i])) { |
| return true; |
| } |
| } |
| } |
| return false; |
| } |
| } |
| |
| private OpenEditorActionGroup fOpenEditorGroup; |
| private CCPActionGroup fCCPActionGroup; |
| private BuildActionGroup fBuildActionGroup; |
| // private ToggleLinkingAction fToggleLinkingAction; |
| protected CompositeActionGroup fActionGroups; |
| |
| // private boolean fHasCustomFilter = true; |
| |
| // Filters |
| // private CustomFiltersActionGroup fCustomFiltersActionGroup; |
| |
| private MultiSelectionListViewer browsingPane; |
| private ISelection fLastOpenSelection; |
| private IContextActivation fContextActivation; |
| |
| public ExtendedClassesView() { |
| elementChangedListenerImplementation = new IElementChangedListenerImplementation(); |
| DLTKCore.addElementChangedListener( |
| elementChangedListenerImplementation); |
| } |
| |
| @Override |
| public void dispose() { |
| if (fContextActivation != null) { |
| IContextService ctxService = getSite() |
| .getService(IContextService.class); |
| if (ctxService != null) { |
| ctxService.deactivateContext(fContextActivation); |
| } |
| } |
| super.dispose(); |
| DLTKCore.removeElementChangedListener( |
| elementChangedListenerImplementation); |
| } |
| |
| // |
| @Override |
| public void createPartControl(Composite parent) { |
| parent.setLayout(new FillLayout()); |
| browsingPane = new MultiSelectionListViewer(parent, SWT.NONE) { |
| @Override |
| public void elementSelectionChanged(ISelection selection) { |
| SelectionChangedEvent event = new SelectionChangedEvent( |
| ExtendedClassesView.this, convertSelection(selection)); |
| for (ISelectionChangedListener listener : listenerList) { |
| listener.selectionChanged(event); |
| } |
| } |
| |
| @Override |
| protected void configureViewer(TreeViewer viewer) { |
| // viewer.setCom |
| viewer.setUseHashlookup(true); |
| viewer.setComparator(new ModelElementSorter() { |
| @Override |
| public int compare(Viewer viewer, Object e1, Object e2) { |
| e1 = unWrap(e1); |
| e2 = unWrap(e2); |
| return super.compare(viewer, e1, e2); |
| } |
| |
| private Object unWrap(Object e1) { |
| if (e1 instanceof MixedClass) { |
| MixedClass cl = ((MixedClass) e1); |
| if (cl.getElements().size() > 0) { |
| e1 = cl.getElements().get(0); |
| } |
| } |
| return e1; |
| } |
| |
| @Override |
| protected String getElementName(Object element) { |
| element = unWrap(element); |
| return super.getElementName(element); |
| } |
| |
| @Override |
| public int category(Object element) { |
| return super.category(unWrap(element)); |
| } |
| |
| }); |
| |
| viewer.addDoubleClickListener(event -> { |
| IAction openAction = fOpenEditorGroup.getOpenAction(); |
| if (openAction != null && openAction.isEnabled()) { |
| openAction.run(); |
| return; |
| } |
| fLastOpenSelection = event.getSelection(); |
| }); |
| |
| viewer.addOpenListener(event -> { |
| IAction openAction = fOpenEditorGroup.getOpenAction(); |
| if (openAction != null && openAction.isEnabled()) { |
| openAction.run(); |
| return; |
| } |
| fLastOpenSelection = event.getSelection(); |
| }); |
| |
| // Initialize menu |
| createContextMenu(viewer.getControl()); |
| } |
| |
| }; |
| browsingPane.setContentProvider(new ExtendedClasesContentProvider(this, |
| SearchEngine.createWorkspaceScope(this.fToolkit), parent, |
| this.fToolkit)); |
| |
| browsingPane.setLabelProvider( |
| new ExtendedClasesLabelProvider(DLTKUILanguageManager |
| .createLabelProvider(this.fToolkit.getNatureId()))); |
| |
| getSite().setSelectionProvider(this); |
| getViewSite().getPage().addPostSelectionListener(this); |
| getViewSite().getPage().addPartListener(fPartListener); |
| |
| createActions(); |
| IContextService ctxService = getSite() |
| .getService(IContextService.class); |
| if (ctxService != null) { |
| fContextActivation = ctxService |
| .activateContext(DLTKUIPlugin.CONTEXT_VIEWS); |
| } |
| } |
| |
| protected void createActions() { |
| fActionGroups = new CompositeActionGroup(new ActionGroup[] { |
| new NewWizardsActionGroup(this.getSite()), |
| fOpenEditorGroup = new OpenEditorActionGroup(this), |
| new OpenViewActionGroup(this), |
| fCCPActionGroup = new CCPActionGroup(this), |
| // new GenerateActionGroup(this), |
| new RefactorActionGroup(this), new ImportActionGroup(this), |
| fBuildActionGroup = new BuildActionGroup(this), |
| new SearchActionGroup(this, this.fToolkit) }); |
| |
| // fToggleLinkingAction = new ToggleLinkingAction(this); |
| } |
| |
| protected void createContextMenu(Control parent) { |
| MenuManager menuManager = new MenuManager("#PopupMenu"); //$NON-NLS-1$ |
| menuManager.setRemoveAllWhenShown(true); |
| menuManager.addMenuListener(this); |
| Menu contextMenu = menuManager.createContextMenu(this.browsingPane); |
| // this.browsingPane.setMenu(contextMenu); |
| parent.setMenu(contextMenu); |
| getSite().registerContextMenu(menuManager, this); |
| } |
| |
| /** |
| * We need to prefer local elements with same name |
| * |
| * @param selection |
| * @return |
| */ |
| protected ISelection convertSelection(ISelection selection) { |
| List result = new ArrayList(); |
| if (selection instanceof StructuredSelection) { |
| StructuredSelection sel = (StructuredSelection) selection; |
| List list = sel.toList(); |
| for (Iterator iterator = list.iterator(); iterator.hasNext();) { |
| Object o = iterator.next(); |
| if (o instanceof MixedClass) { |
| List mixedElements = ((MixedClass) o).getElements(); |
| result.addAll(mixedElements); |
| } else { |
| result.add(o); |
| } |
| } |
| } |
| if (result.size() > 0) { |
| return new StructuredSelection(result); |
| } |
| return new StructuredSelection(); |
| } |
| |
| @Override |
| public void setFocus() { |
| } |
| |
| @Override |
| public Object getViewPartInput() { |
| return browsingPane.getSelection(); |
| } |
| |
| private boolean isSearchResultView(IWorkbenchPart part) { |
| return SearchUtil.isSearchPlugInActivated() |
| && part instanceof ISearchResultViewPart; |
| } |
| |
| protected IWorkbenchPart fPreviousSelectionProvider; |
| protected Object fPreviousSelectedElement; |
| |
| protected boolean needsToProcessSelectionChanged(IWorkbenchPart part, |
| ISelection selection) { |
| if (!fProcessSelectionEvents || part == this || isSearchResultView(part) |
| || part instanceof AbstractInfoView) { |
| if (part == this) |
| fPreviousSelectionProvider = part; |
| return false; |
| } |
| return true; |
| } |
| |
| protected final Object getSingleElementFromSelection(ISelection selection) { |
| if (!(selection instanceof IStructuredSelection) || selection.isEmpty()) |
| return null; |
| |
| Iterator iter = ((IStructuredSelection) selection).iterator(); |
| Object firstElement = iter.next(); |
| if (!(firstElement instanceof IModelElement)) { |
| if (firstElement instanceof IMarker) |
| firstElement = ((IMarker) firstElement).getResource(); |
| if (firstElement instanceof IAdaptable) { |
| IModelElement je = ((IAdaptable) firstElement) |
| .getAdapter(IModelElement.class); |
| if (je == null && firstElement instanceof IFile) { |
| IContainer parent = ((IFile) firstElement).getParent(); |
| if (parent != null) |
| return parent.getAdapter(IModelElement.class); |
| else |
| return null; |
| } else |
| return je; |
| |
| } else |
| return firstElement; |
| } |
| Object currentInput = browsingPane.getInput(); |
| List elements = new ArrayList(); |
| if (currentInput == null || !currentInput.equals(firstElement)) |
| if (iter.hasNext() && selection instanceof StructuredSelection) { |
| // multi-selection and view is empty |
| return ((StructuredSelection) selection).toList(); |
| } else |
| // OK: single selection and view is empty |
| return firstElement; |
| |
| // be nice to multi-selection |
| while (iter.hasNext()) { |
| Object element = iter.next(); |
| if (!(element instanceof IModelElement)) |
| return null; |
| if (!currentInput.equals(element)) |
| return null; |
| } |
| return firstElement; |
| } |
| |
| @Override |
| public void selectionChanged(IWorkbenchPart part, ISelection selection) { |
| if (!needsToProcessSelectionChanged(part, selection)) |
| return; |
| if (!(selection instanceof IStructuredSelection)) |
| return; |
| // Set selection |
| Object selectedElement = getSingleElementFromSelection(selection); |
| if (!checkElementNature(selectedElement)) { |
| return; |
| } |
| if (selectedElement instanceof List) { |
| List newList = new ArrayList(); |
| List list = (List) selectedElement; |
| for (Iterator iterator = list.iterator(); iterator.hasNext();) { |
| Object obj = iterator.next(); |
| if (checkElementNature(obj)) { |
| newList.add(obj); |
| } |
| } |
| if (newList.size() > 0) { |
| selectedElement = newList; |
| } else { |
| return; |
| } |
| } |
| |
| if (selectedElement != null |
| && (part == null || part.equals(fPreviousSelectionProvider)) |
| && selectedElement.equals(fPreviousSelectedElement)) |
| return; |
| fPreviousSelectedElement = selectedElement; |
| |
| if (selectedElement != null |
| && (selectedElement instanceof IScriptProject |
| || selectedElement instanceof IProjectFragment)) { |
| browsingPane.setInput(selectedElement); |
| } |
| |
| fLastOpenSelection = null; |
| } |
| |
| private boolean checkElementNature(Object selectedElement) { |
| if (selectedElement instanceof IModelElement) { |
| String natureId = this.fToolkit.getNatureId(); |
| IDLTKLanguageToolkit languageToolkit = DLTKLanguageManager |
| .getLanguageToolkit((IModelElement) selectedElement); |
| if (languageToolkit != null |
| && natureId.equals(languageToolkit.getNatureId())) { |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| private boolean fProcessSelectionEvents = true; |
| private IPartListener2 fPartListener = new IPartListener2() { |
| @Override |
| public void partActivated(IWorkbenchPartReference ref) { |
| } |
| |
| @Override |
| public void partBroughtToTop(IWorkbenchPartReference ref) { |
| } |
| |
| @Override |
| public void partInputChanged(IWorkbenchPartReference ref) { |
| } |
| |
| @Override |
| public void partClosed(IWorkbenchPartReference ref) { |
| } |
| |
| @Override |
| public void partDeactivated(IWorkbenchPartReference ref) { |
| } |
| |
| @Override |
| public void partOpened(IWorkbenchPartReference ref) { |
| } |
| |
| @Override |
| public void partVisible(IWorkbenchPartReference ref) { |
| if (ref != null && ref.getId() == getSite().getId()) { |
| fProcessSelectionEvents = true; |
| IWorkbenchPage page = getSite().getWorkbenchWindow() |
| .getActivePage(); |
| if (page != null) |
| selectionChanged(page.getActivePart(), page.getSelection()); |
| } |
| } |
| |
| @Override |
| public void partHidden(IWorkbenchPartReference ref) { |
| if (ref != null && ref.getId() == getSite().getId()) |
| fProcessSelectionEvents = false; |
| } |
| }; |
| |
| ListenerList<ISelectionChangedListener> listenerList = new ListenerList<>(); |
| private IDLTKLanguageToolkit fToolkit; |
| private IElementChangedListenerImplementation elementChangedListenerImplementation; |
| |
| @Override |
| public void addSelectionChangedListener( |
| ISelectionChangedListener listener) { |
| listenerList.add(listener); |
| } |
| |
| @Override |
| public ISelection getSelection() { |
| return convertSelection(browsingPane.getSelection()); |
| } |
| |
| @Override |
| public void removeSelectionChangedListener( |
| ISelectionChangedListener listener) { |
| listenerList.remove(listener); |
| } |
| |
| @Override |
| public void setSelection(ISelection selection) { |
| } |
| |
| @Override |
| public void setInitializationData(IConfigurationElement config, |
| String propertyName, Object data) { |
| super.setInitializationData(config, propertyName, data); |
| this.fToolkit = DLTKExecuteExtensionHelper.getLanguageToolkit(config, |
| propertyName, data); |
| } |
| |
| @Override |
| public void menuAboutToShow(IMenuManager menu) { |
| DLTKUIPlugin.createStandardGroups(menu); |
| |
| IStructuredSelection selection = (IStructuredSelection) getSelection(); |
| // int size = selection.size(); |
| // Object element = selection.getFirstElement(); |
| |
| fActionGroups.setContext(new ActionContext(selection)); |
| fActionGroups.fillContextMenu(menu); |
| fActionGroups.setContext(null); |
| } |
| } |