/********************************************************************** * Copyright (c) 2003, 2015 Geoff Longman 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: * Geoff Longman - Initial API and implementation * IBM - Tightening integration with existing Platform * Geoff Longman - added ability to delete the marker selection **********************************************************************/ package org.eclipse.core.tools.resources.markers; import org.eclipse.core.resources.IResource; import org.eclipse.jface.viewers.ISelectionChangedListener; import java.lang.reflect.InvocationTargetException; import java.util.*; import java.util.List; import org.eclipse.core.resources.*; import org.eclipse.core.runtime.*; import org.eclipse.core.tools.resources.CoreResourcesToolsPlugin; import org.eclipse.jface.action.*; import org.eclipse.jface.dialogs.ErrorDialog; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.viewers.*; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.*; import org.eclipse.ui.*; import org.eclipse.ui.actions.SelectionProviderAction; import org.eclipse.ui.actions.WorkspaceModifyOperation; import org.eclipse.ui.part.EditorPart; import org.eclipse.ui.part.ViewPart; import org.eclipse.ui.progress.IProgressService; import org.eclipse.ui.views.properties.*; /** * This is a view that allows one to inspect the state of a resource's markers. * The view changes when a resource is selected in the workspace. */ public class MarkerView extends ViewPart implements ISelectionListener, IResourceChangeListener, IAdaptable { public static final String MEMENTO_TAG1 = "MarkerView"; public static final String MEMENTO_TAG2 = "IResourcePath"; public static final String NONE_SELECTED = "NONE_SELECTED"; protected static final IStructuredSelection emptySelection = new StructuredSelection(); protected int markerDepth = IResource.DEPTH_ZERO; protected MarkerExtensionModel model; protected ReadOnlyMarkerPropertySource propertySource; protected TreeViewer viewer; protected Action doubleClickAction; protected MarkerDepthAction depthZero; protected MarkerDepthAction depthOne; protected MarkerDepthAction depthInfinite; protected DeleteMarkersAction deleteMarkers; protected IResource currentResource; protected String errorMsg; protected String warningMsg; protected ImageDescriptor oneImageDesc; protected ImageDescriptor zeroImageDesc; protected ImageDescriptor infiniteImageDesc; protected PagePartListener pagePartListener; protected IWorkbenchPage currentPage; protected SelectionProvider selectionProvider; protected MarkerViewPropertySheetPage propertyPage; class SelectionProvider implements ISelectionProvider { private List<ISelectionChangedListener> listeners = new ArrayList<ISelectionChangedListener>(); private ISelection selection; @Override public void addSelectionChangedListener(ISelectionChangedListener listener) { listeners.add(listener); } @Override public ISelection getSelection() { return selection; } @Override public void removeSelectionChangedListener(ISelectionChangedListener listener) { listeners.remove(listener); } @Override public synchronized void setSelection(ISelection selection) { this.selection = selection; SelectionChangedEvent event = new SelectionChangedEvent(this, selection); for (ISelectionChangedListener listener : listeners) { listener.selectionChanged(event); } } } class MarkerViewPropertySheetPage extends PropertySheetPage { MarkerView view; public MarkerViewPropertySheetPage(MarkerView view) { super(); this.view = view; } @Override public void selectionChanged(IWorkbenchPart part, ISelection selection) { if (part == view) super.selectionChanged(part, selection); } } class MarkerDepthAction extends Action { private int depth; public MarkerDepthAction(int depth, String text, ImageDescriptor image) { super(text, image); this.depth = depth; } @Override public void run() { markerDepth = depth; updateActionChecks(); if (currentResource != null) viewer.setInput(currentResource); } } class DeleteMarkersAction extends SelectionProviderAction { public DeleteMarkersAction(ISelectionProvider provider, String text) { super(provider, text); } @Override public void selectionChanged(IStructuredSelection selection) { setEnabled(!selection.isEmpty()); } @Override public void run() { final IStructuredSelection selection = getStructuredSelection(); if (selection.isEmpty()) return; IRunnableWithProgress op = new WorkspaceModifyOperation() { @Override public void execute(IProgressMonitor monitor) { int count = selection.size(); int deleted = 1; monitor.beginTask("deleting #" + deleted + " of " + count + " markers.", count); for (Iterator<?> iter = selection.iterator(); iter.hasNext();) { IMarker marker = (IMarker) iter.next(); try { marker.delete(); monitor.worked(1); deleted++; monitor.setTaskName("deleting #" + deleted + " of " + count + " markers."); } catch (CoreException e) { // TODO Auto-generated catch block e.printStackTrace(); } } monitor.done(); } }; IProgressService progressService = PlatformUI.getWorkbench().getProgressService(); try { progressService.busyCursorWhile(op); } catch (InvocationTargetException e) { IStatus status = null; Throwable nested = e.getCause(); String message = nested.getMessage(); if (nested instanceof CoreException) status = ((CoreException) nested).getStatus(); ErrorDialog.openError(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), "Error", message, status); } catch (InterruptedException e) { // Do nothing } } } class PagePartListener implements IPartListener, IPageListener { @Override public void partActivated(IWorkbenchPart part) { if (part instanceof IEditorPart) viewer.setInput(part); } @Override public void partBroughtToTop(IWorkbenchPart part) { if (part instanceof IEditorPart) viewer.setInput(part); } @Override public void partClosed(IWorkbenchPart part) { // do nothing } @Override public void partDeactivated(IWorkbenchPart part) { // do nothing } @Override public void partOpened(IWorkbenchPart part) { // do nothing } @Override public void pageActivated(IWorkbenchPage page) { if (currentPage != null) currentPage.removePartListener(this); currentPage = page; page.addPartListener(this); } @Override public void pageClosed(IWorkbenchPage page) { // do nothing } @Override public void pageOpened(IWorkbenchPage page) { // do nothing } } class ViewContentProvider implements IStructuredContentProvider, ITreeContentProvider { IStructuredSelection selection; IMarker[] markers; String[] message = new String[1]; @Override public void inputChanged(Viewer v, Object oldInput, Object newInput) { errorMsg = null; warningMsg = null; markers = null; if (newInput instanceof IMarker) { findResourceMarkers(((IMarker) newInput).getResource()); } else if (newInput instanceof IResource) { findResourceMarkers((IResource) newInput); return; } else if (newInput instanceof EditorPart) { currentResource = ((EditorPart) newInput).getEditorInput().getAdapter(IResource.class); if (currentResource != null) { findResourceMarkers(currentResource); } else { warningMsg = "Could not obtain an IResource from: " + newInput; currentResource = null; } } else { // otherwise its a selection currentResource = null; selection = (IStructuredSelection) newInput; if (selection == null || selection.isEmpty()) { warningMsg = "No selection found"; } else if (selection.size() > 1) { warningMsg = "Select one resource to view its markers."; } else { Object selected = selection.getFirstElement(); if (selected != null) { if (selected instanceof IMarker) { currentResource = ((IMarker) selected).getResource(); } else if (selected instanceof IAdaptable) { currentResource = ((IAdaptable) selected).getAdapter(IResource.class); } if (currentResource != null) findResourceMarkers(currentResource); else warningMsg = "Could not obtain an IResource from: " + selected; } } } if (newInput != null) setTitle("MarkerView" + (currentResource == null ? "" : " " + currentResource.getFullPath().toString())); } protected void findResourceMarkers(IResource resource) { try { markers = resource.findMarkers(null, true, markerDepth); if (markers.length <= 0) warningMsg = "No markers found for: " + resource.getFullPath(); return; } catch (CoreException e) { errorMsg = "Exception" + e.getMessage() + " occured obtaining markers for" + resource.getFullPath(); return; } } @Override public void dispose() { // do nothing } @Override public Object[] getElements(Object parent) { if (parent.equals(viewer.getInput())) { if (warningMsg != null) { message[0] = warningMsg; return message; } if (errorMsg != null) { message[0] = errorMsg; return message; } return getChildren(parent); } return getChildren(parent); } @Override public Object getParent(Object child) { if (child instanceof String || child instanceof IMarker) return selection; return null; } @Override public Object[] getChildren(Object parent) { if (parent == viewer.getInput()) return markers; return new Object[0]; } @Override public boolean hasChildren(Object parent) { if (parent == viewer.getInput()) return true; return false; } } class ViewLabelProvider extends LabelProvider { @Override public String getText(Object obj) { try { if (obj instanceof IMarker) { IMarker marker = (IMarker) obj; String message = (String) marker.getAttribute(IMarker.MESSAGE); String type = marker.getType(); return message == null ? type : message + " : " + type; } } catch (CoreException e) { CoreResourcesToolsPlugin.logProblem(e); } return obj.toString(); } @Override public Image getImage(Object obj) { String imageKey = ISharedImages.IMG_OBJ_ELEMENT; if (obj instanceof String) { if (warningMsg != null) imageKey = ISharedImages.IMG_OBJS_WARN_TSK; else if (errorMsg != null) imageKey = ISharedImages.IMG_OBJS_ERROR_TSK; } else if (obj instanceof IMarker) { try { IMarker marker = (IMarker) obj; if (marker.isSubtypeOf(IMarker.BOOKMARK)) { imageKey = ISharedImages.IMG_OBJS_BKMRK_TSK; } else if (marker.isSubtypeOf(IMarker.PROBLEM)) { imageKey = ISharedImages.IMG_OBJS_ERROR_TSK; int severity = marker.getAttribute(IMarker.SEVERITY, IMarker.SEVERITY_WARNING); switch (severity) { case IMarker.SEVERITY_ERROR : imageKey = ISharedImages.IMG_OBJS_ERROR_TSK; break; case IMarker.SEVERITY_INFO : imageKey = ISharedImages.IMG_OBJS_INFO_TSK; break; case IMarker.SEVERITY_WARNING : imageKey = ISharedImages.IMG_OBJS_WARN_TSK; break; default : break; } } else if (marker.isSubtypeOf(IMarker.TASK)) imageKey = ISharedImages.IMG_OBJS_TASK_TSK; } catch (CoreException e) { CoreResourcesToolsPlugin.logProblem(e); } } return PlatformUI.getWorkbench().getSharedImages().getImage(imageKey); } } /** * The constructor. */ public MarkerView() { zeroImageDesc = CoreResourcesToolsPlugin.createImageDescriptor("zero.gif"); oneImageDesc = CoreResourcesToolsPlugin.createImageDescriptor("one.gif"); infiniteImageDesc = CoreResourcesToolsPlugin.createImageDescriptor("infinity.gif"); model = new MarkerExtensionModel(); propertySource = new ReadOnlyMarkerPropertySource(this, model); } /** * create the viewer and initialize it. */ @Override public void createPartControl(Composite parent) { IWorkbenchWindow window = CoreResourcesToolsPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow(); ISelectionService sel_service = window.getSelectionService(); sel_service.addSelectionListener(this); ResourcesPlugin.getWorkspace().addResourceChangeListener(this); viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL); viewer.setContentProvider(new ViewContentProvider()); viewer.setLabelProvider(new ViewLabelProvider()); viewer.addSelectionChangedListener(new ISelectionChangedListener() { @Override public void selectionChanged(SelectionChangedEvent event) { IStructuredSelection sel = (IStructuredSelection) event.getSelection(); IStructuredSelection newSelection = emptySelection; if (!sel.isEmpty() && sel.size() == 1) { Object first = sel.getFirstElement(); if (first instanceof IMarker) { IMarker marker = (IMarker) first; propertySource.setSourceMarker(marker); newSelection = new StructuredSelection(propertySource); } } getSite().getSelectionProvider().setSelection(newSelection); } }); pagePartListener = new PagePartListener(); currentPage = window.getActivePage(); window.addPageListener(pagePartListener); if (currentResource != null) { viewer.setInput(currentResource); } else { IWorkbenchPart activePart = currentPage == null ? null : currentPage.getActivePart(); if (activePart instanceof EditorPart) viewer.setInput(activePart); else viewer.setInput(sel_service.getSelection()); } makeActions(); hookContextMenu(); contributeToActionBars(); } @Override public void dispose() { super.dispose(); IWorkbenchWindow window = CoreResourcesToolsPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow(); ISelectionService sel_service = window.getSelectionService(); sel_service.removeSelectionListener(this); ResourcesPlugin.getWorkspace().removeResourceChangeListener(this); } void hookContextMenu() { MenuManager menuMgr = new MenuManager("#PopupMenu"); //$NON-NLS-1$ menuMgr.setRemoveAllWhenShown(true); menuMgr.addMenuListener(new IMenuListener() { @Override public void menuAboutToShow(IMenuManager manager) { MarkerView.this.fillContextMenu(manager); } }); Menu menu = menuMgr.createContextMenu(viewer.getControl()); viewer.getControl().setMenu(menu); getSite().registerContextMenu(menuMgr, viewer); } void contributeToActionBars() { IActionBars bars = getViewSite().getActionBars(); fillLocalPullDown(bars.getMenuManager()); fillLocalToolBar(bars.getToolBarManager()); } void fillLocalPullDown(IMenuManager manager) { manager.add(depthZero); manager.add(depthOne); manager.add(depthInfinite); } void fillContextMenu(IMenuManager manager) { manager.add(depthZero); manager.add(depthOne); manager.add(depthInfinite); manager.add(new Separator()); manager.add(deleteMarkers); manager.add(new Separator()); // Other plug-ins can contribute there actions here manager.add(new Separator("Additions")); } void fillLocalToolBar(IToolBarManager manager) { manager.add(depthZero); manager.add(depthOne); manager.add(depthInfinite); } private void makeActions() { depthZero = new MarkerDepthAction(IResource.DEPTH_ZERO, "IResource.DEPTH_ZERO", zeroImageDesc); depthOne = new MarkerDepthAction(IResource.DEPTH_ONE, "IResource.DEPTH_ONE", oneImageDesc); depthInfinite = new MarkerDepthAction(IResource.DEPTH_INFINITE, "IResource.DEPTH_INFINITE", infiniteImageDesc); deleteMarkers = new DeleteMarkersAction(viewer, "Delete"); updateActionChecks(); } void updateActionChecks() { switch (markerDepth) { case IResource.DEPTH_ZERO : depthZero.setChecked(true); depthOne.setChecked(false); depthInfinite.setChecked(false); break; case IResource.DEPTH_ONE : depthZero.setChecked(false); depthOne.setChecked(true); depthInfinite.setChecked(false); break; case IResource.DEPTH_INFINITE : depthZero.setChecked(false); depthOne.setChecked(false); depthInfinite.setChecked(true); break; default : depthZero.setChecked(false); depthOne.setChecked(false); depthInfinite.setChecked(false); } } /** * Passing the focus request to the viewer's control. */ @Override public void setFocus() { viewer.getControl().setFocus(); } /** * Pushes the windows selection into the viewer * * @see org.eclipse.ui.ISelectionListener#selectionChanged(IWorkbenchPart, ISelection) */ @Override public void selectionChanged(IWorkbenchPart part, ISelection selection) { if (part instanceof IEditorPart) viewer.setInput(part); else if (part != this && !(part instanceof PropertySheet) && selection instanceof IStructuredSelection) viewer.setInput(selection); } /** * @see org.eclipse.core.resources.IResourceChangeListener#resourceChanged(IResourceChangeEvent) */ @Override public void resourceChanged(IResourceChangeEvent event) { if (currentResource == null) return; IResourceDelta delta = event.getDelta().findMember(currentResource.getFullPath()); if (delta == null) return; // could have been called from a non-UI thread. // handle appropriately Display.getDefault().asyncExec(new Runnable() { @Override public void run() { viewer.setInput(currentResource); } }); } /** * @see org.eclipse.core.runtime.IAdaptable#getAdapter(Class) */ @Override public Object getAdapter(@SuppressWarnings("rawtypes") Class adapter) { if (adapter == IPropertySheetPage.class) { propertyPage = new MarkerViewPropertySheetPage(this); return propertyPage; } return super.getAdapter(adapter); } /** * @see org.eclipse.ui.IViewPart#init(IViewSite, IMemento) */ @Override public void init(IViewSite site, IMemento memento) throws PartInitException { super.init(site, memento); if (memento != null) restoreState(memento); selectionProvider = new SelectionProvider(); site.setSelectionProvider(selectionProvider); } private void restoreState(IMemento memento) { IMemento child = memento.getChild(MEMENTO_TAG1); if (child != null) { child = child.getChild(MEMENTO_TAG2); if (child != null) { try { String resourcePath = child.getTextData(); if (resourcePath != null && !NONE_SELECTED.equals(resourcePath)) { Path path = new Path(resourcePath); IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(path); if (file != null && file.exists()) { currentResource = file; } } } catch (Exception e) { } } } } /** * @see org.eclipse.ui.IViewPart#saveState(IMemento) */ @Override public void saveState(IMemento memento) { super.saveState(memento); IMemento child = memento.createChild(MEMENTO_TAG1); child = child.createChild(MEMENTO_TAG2); if (currentResource == null) child.putTextData(NONE_SELECTED); else child.putTextData(currentResource.getFullPath().toString()); } }