| /******************************************************************************* |
| * Copyright (c) 2000, 2007 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 |
| *******************************************************************************/ |
| |
| package org.eclipse.ui.views.markers.internal; |
| |
| import java.io.IOException; |
| import java.io.StringReader; |
| import java.io.StringWriter; |
| import java.text.MessageFormat; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.Collection; |
| import java.util.HashSet; |
| import java.util.Iterator; |
| import java.util.List; |
| |
| import org.eclipse.core.commands.operations.IUndoContext; |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.resources.IMarker; |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.resources.IResourceChangeEvent; |
| import org.eclipse.core.resources.IResourceChangeListener; |
| import org.eclipse.core.resources.ResourcesPlugin; |
| import org.eclipse.core.resources.mapping.ResourceMapping; |
| import org.eclipse.core.resources.mapping.ResourceMappingContext; |
| import org.eclipse.core.resources.mapping.ResourceTraversal; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IAdaptable; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.NullProgressMonitor; |
| import org.eclipse.core.runtime.Status; |
| import org.eclipse.core.runtime.jobs.IJobChangeListener; |
| import org.eclipse.core.runtime.jobs.Job; |
| import org.eclipse.help.HelpSystem; |
| import org.eclipse.help.IContext; |
| import org.eclipse.help.IContextProvider; |
| import org.eclipse.jface.action.IMenuManager; |
| import org.eclipse.jface.action.IToolBarManager; |
| import org.eclipse.jface.action.MenuManager; |
| import org.eclipse.jface.action.Separator; |
| import org.eclipse.jface.dialogs.Dialog; |
| import org.eclipse.jface.dialogs.IDialogSettings; |
| import org.eclipse.jface.preference.IPreferenceStore; |
| import org.eclipse.jface.util.IPropertyChangeListener; |
| import org.eclipse.jface.util.PropertyChangeEvent; |
| import org.eclipse.jface.viewers.AbstractTreeViewer; |
| import org.eclipse.jface.viewers.ISelection; |
| import org.eclipse.jface.viewers.IStructuredSelection; |
| import org.eclipse.jface.viewers.OpenEvent; |
| import org.eclipse.jface.viewers.StructuredSelection; |
| import org.eclipse.jface.viewers.TreeViewer; |
| import org.eclipse.jface.window.Window; |
| import org.eclipse.osgi.util.NLS; |
| import org.eclipse.swt.dnd.Clipboard; |
| import org.eclipse.swt.dnd.DND; |
| import org.eclipse.swt.dnd.DragSourceAdapter; |
| import org.eclipse.swt.dnd.DragSourceEvent; |
| import org.eclipse.swt.dnd.DragSourceListener; |
| import org.eclipse.swt.dnd.TextTransfer; |
| import org.eclipse.swt.dnd.Transfer; |
| import org.eclipse.swt.events.HelpEvent; |
| import org.eclipse.swt.events.HelpListener; |
| import org.eclipse.swt.events.TreeAdapter; |
| import org.eclipse.swt.events.TreeEvent; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.Tree; |
| import org.eclipse.ui.IActionBars; |
| import org.eclipse.ui.IEditorInput; |
| import org.eclipse.ui.IEditorPart; |
| import org.eclipse.ui.IMemento; |
| import org.eclipse.ui.ISelectionListener; |
| import org.eclipse.ui.IViewSite; |
| import org.eclipse.ui.IWorkbenchActionConstants; |
| import org.eclipse.ui.IWorkbenchPart; |
| import org.eclipse.ui.PartInitException; |
| import org.eclipse.ui.PlatformUI; |
| import org.eclipse.ui.WorkbenchException; |
| import org.eclipse.ui.XMLMemento; |
| import org.eclipse.ui.actions.ActionFactory; |
| import org.eclipse.ui.actions.ContributionItemFactory; |
| import org.eclipse.ui.actions.SelectionProviderAction; |
| import org.eclipse.ui.ide.IDE; |
| import org.eclipse.ui.ide.ResourceUtil; |
| import org.eclipse.ui.internal.ide.IDEWorkbenchMessages; |
| import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin; |
| import org.eclipse.ui.keys.IBindingService; |
| import org.eclipse.ui.operations.RedoActionHandler; |
| import org.eclipse.ui.operations.UndoActionHandler; |
| import org.eclipse.ui.part.IShowInSource; |
| import org.eclipse.ui.part.MarkerTransfer; |
| import org.eclipse.ui.part.ShowInContext; |
| import org.eclipse.ui.preferences.ViewPreferencesAction; |
| import org.eclipse.ui.progress.IWorkbenchSiteProgressService; |
| import org.eclipse.ui.progress.WorkbenchJob; |
| import org.eclipse.ui.views.markers.internal.MarkerAdapter.MarkerCategory; |
| import org.eclipse.ui.views.tasklist.ITaskListResourceAdapter; |
| |
| /** |
| * MarkerView is the abstract super class of the marker based views. |
| * |
| */ |
| public abstract class MarkerView extends TableView { |
| |
| private static final String TAG_SELECTION = "selection"; //$NON-NLS-1$ |
| |
| private static final String TAG_MARKER = "marker"; //$NON-NLS-1$ |
| |
| private static final String TAG_RESOURCE = "resource"; //$NON-NLS-1$ |
| |
| private static final String TAG_ID = "id"; //$NON-NLS-1$ |
| |
| private static final String TAG_FILTERS_SECTION = "filters"; //$NON-NLS-1$ |
| |
| private static final String TAG_FILTER_ENTRY = "filter"; //$NON-NLS-1$ |
| |
| private static final String MENU_FILTERS_GROUP = "group.filter";//$NON-NLS-1$ |
| |
| private static final String MENU_SHOW_IN_GROUP = "group.showIn";//$NON-NLS-1$ |
| |
| // Section from a 3.1 or earlier workbench |
| private static final String OLD_FILTER_SECTION = "filter"; //$NON-NLS-1$ |
| |
| static final Object MARKER_UPDATE_FAMILY = new Object(); |
| |
| class MarkerProcessJob extends Job { |
| |
| /** |
| * Create a new instance of the receiver. |
| */ |
| MarkerProcessJob() { |
| super(MarkerMessages.MarkerView_processUpdates); |
| setSystem(true); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor) |
| */ |
| protected IStatus run(IProgressMonitor monitor) { |
| updateForContentsRefresh(monitor); |
| return Status.OK_STATUS; |
| |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ui.progress.WorkbenchJob#shouldRun() |
| */ |
| public boolean shouldRun() { |
| // Do not run if the change came in before there is a viewer |
| return PlatformUI.isWorkbenchRunning(); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.core.runtime.jobs.Job#belongsTo(java.lang.Object) |
| */ |
| public boolean belongsTo(Object family) { |
| return MARKER_UPDATE_FAMILY == family; |
| } |
| |
| } |
| |
| MarkerProcessJob markerProcessJob = new MarkerProcessJob(); |
| |
| private class UpdateJob extends WorkbenchJob { |
| |
| private class MarkerDescriptor { |
| String description; |
| |
| String folder; |
| |
| String resource; |
| |
| int line; |
| |
| MarkerDescriptor(ConcreteMarker marker) { |
| description = marker.getDescription(); |
| folder = marker.getFolder(); |
| resource = marker.getResourceName(); |
| line = marker.getLine(); |
| } |
| |
| boolean isEquivalentTo(ConcreteMarker marker) { |
| return marker.getDescription().equals(description) |
| && marker.getFolder().equals(folder) |
| && marker.getResourceName().equals(resource) |
| && marker.getLine() == line; |
| } |
| |
| } |
| |
| private Collection categoriesToExpand = new HashSet(); |
| |
| private Collection preservedSelection = new ArrayList(); |
| |
| UpdateJob() { |
| super(MarkerMessages.MarkerView_queueing_updates); |
| setSystem(true); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ui.progress.UIJob#runInUIThread(org.eclipse.core.runtime.IProgressMonitor) |
| */ |
| public IStatus runInUIThread(IProgressMonitor monitor) { |
| |
| if (getViewer().getControl().isDisposed()) { |
| return Status.CANCEL_STATUS; |
| } |
| |
| if (monitor.isCanceled()) |
| return Status.CANCEL_STATUS; |
| |
| getViewer().refresh(true); |
| |
| Tree tree = getTree(); |
| |
| if (tree != null && !tree.isDisposed()) { |
| updateStatusMessage(); |
| updateTitle(); |
| // Expand all if the list is small |
| if (getCurrentMarkers().getSize() < 20) { |
| getViewer().expandAll(); |
| } else {// Reexpand the old categories |
| MarkerCategory[] categories = getMarkerAdapter() |
| .getCategories(); |
| if (categories == null) |
| categoriesToExpand.clear(); |
| else { |
| if (categories.length == 1) {// Expand if there is |
| // only |
| // one |
| getViewer().expandAll(); |
| categoriesToExpand.clear(); |
| if (monitor.isCanceled()) |
| return Status.CANCEL_STATUS; |
| categoriesToExpand.add(categories[0].getName()); |
| } else { |
| Collection newCategories = new HashSet(); |
| for (int i = 0; i < categories.length; i++) { |
| if (monitor.isCanceled()) |
| return Status.CANCEL_STATUS; |
| MarkerCategory category = categories[i]; |
| if (categoriesToExpand.contains(category |
| .getName())) { |
| getViewer().expandToLevel(category, |
| AbstractTreeViewer.ALL_LEVELS); |
| newCategories.add(category.getName()); |
| } |
| |
| } |
| categoriesToExpand = newCategories; |
| } |
| } |
| |
| } |
| } |
| |
| if (preservedSelection.size() > 0) { |
| |
| Collection newSelection = new ArrayList(); |
| ConcreteMarker[] markers = getCurrentMarkers().toArray(); |
| |
| for (int i = 0; i < markers.length; i++) { |
| Iterator preserved = preservedSelection.iterator(); |
| while (preserved.hasNext()) { |
| MarkerDescriptor next = (MarkerDescriptor) preserved |
| .next(); |
| if (next.isEquivalentTo(markers[i])) { |
| newSelection.add(markers[i]); |
| continue; |
| } |
| } |
| } |
| |
| getViewer().setSelection( |
| new StructuredSelection(newSelection.toArray()), true); |
| preservedSelection.clear(); |
| } |
| if (getViewer().getTree().getItemCount() > 0) |
| getViewer().getTree().setTopItem( |
| getViewer().getTree().getItem(0)); |
| |
| return Status.OK_STATUS; |
| } |
| |
| /** |
| * Add the category to the list of expanded categories. |
| * |
| * @param category |
| */ |
| public void addExpandedCategory(MarkerCategory category) { |
| categoriesToExpand.add(category.getName()); |
| |
| } |
| |
| /** |
| * Remove the category from the list of expanded ones. |
| * |
| * @param category |
| */ |
| public void removeExpandedCategory(MarkerCategory category) { |
| categoriesToExpand.remove(category.getName()); |
| |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.core.runtime.jobs.Job#belongsTo(java.lang.Object) |
| */ |
| public boolean belongsTo(Object family) { |
| return family == MARKER_UPDATE_FAMILY; |
| } |
| |
| /** |
| * Preserve the selection for reselection after the next update. |
| * |
| * @param selection |
| */ |
| public void saveSelection(ISelection selection) { |
| preservedSelection.clear(); |
| if (selection instanceof IStructuredSelection) { |
| IStructuredSelection structured = (IStructuredSelection) selection; |
| Iterator iterator = structured.iterator(); |
| while (iterator.hasNext()) { |
| MarkerNode next = (MarkerNode) iterator.next(); |
| if (next.isConcrete()) { |
| preservedSelection.add(new MarkerDescriptor(next |
| .getConcreteRepresentative())); |
| } |
| } |
| } |
| |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ui.progress.WorkbenchJob#shouldRun() |
| */ |
| public boolean shouldRun() { |
| return !getMarkerAdapter().isBuilding(); |
| } |
| |
| } |
| |
| private UpdateJob updateJob = new UpdateJob(); |
| |
| // A private field for keeping track of the number of markers |
| // before the busy testing started |
| private int preBusyMarkers = 0; |
| |
| protected Object[] focusElements; |
| |
| private Clipboard clipboard; |
| |
| IResourceChangeListener markerUpdateListener = new IResourceChangeListener() { |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.core.resources.IResourceChangeListener#resourceChanged(org.eclipse.core.resources.IResourceChangeEvent) |
| */ |
| public void resourceChanged(IResourceChangeEvent event) { |
| if (!hasMarkerDelta(event)) |
| return; |
| |
| if (event.getType() == IResourceChangeEvent.POST_BUILD) { |
| scheduleMarkerUpdate(Util.SHORT_DELAY); |
| return; |
| } |
| |
| // After 30 seconds do updates anyways |
| |
| IWorkbenchSiteProgressService progressService = getProgressService(); |
| if (progressService == null) |
| markerProcessJob.schedule(Util.LONG_DELAY); |
| else |
| getProgressService() |
| .schedule(markerProcessJob, Util.LONG_DELAY); |
| |
| } |
| |
| /** |
| * Returns whether or not the given even contains marker deltas for this |
| * view. |
| * |
| * @param event |
| * the resource change event |
| * @return <code>true</code> if the event contains at least one |
| * relevant marker delta |
| * @since 3.3 |
| */ |
| private boolean hasMarkerDelta(IResourceChangeEvent event) { |
| String[] markerTypes = getMarkerTypes(); |
| for (int i = 0; i < markerTypes.length; i++) { |
| if (event.findMarkerDeltas(markerTypes[i], true).length > 0) { |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| }; |
| |
| private class ContextProvider implements IContextProvider { |
| public int getContextChangeMask() { |
| return SELECTION; |
| } |
| |
| public IContext getContext(Object target) { |
| String contextId = null; |
| // See if there is a context registered for the current selection |
| ConcreteMarker marker = getSelectedConcreteMarker(); |
| if (marker != null) { |
| contextId = IDE.getMarkerHelpRegistry().getHelp( |
| marker.getMarker()); |
| } |
| |
| if (contextId == null) { |
| contextId = getStaticContextId(); |
| } |
| return HelpSystem.getContext(contextId); |
| } |
| |
| /** |
| * Return the currently selected concrete marker or <code>null</code> |
| * if there isn't one. |
| * |
| * @return ConcreteMarker |
| */ |
| private ConcreteMarker getSelectedConcreteMarker() { |
| |
| IStructuredSelection selection = (IStructuredSelection) getViewer() |
| .getSelection(); |
| if (selection.isEmpty()) |
| return null; |
| |
| if (selection.getFirstElement() instanceof ConcreteMarker) |
| return (ConcreteMarker) selection.getFirstElement(); |
| return null; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.help.IContextProvider#getSearchExpression(java.lang.Object) |
| */ |
| public String getSearchExpression(Object target) { |
| return null; |
| } |
| } |
| |
| private ContextProvider contextProvider = new ContextProvider(); |
| |
| protected ActionCopyMarker copyAction; |
| |
| protected ActionPasteMarker pasteAction; |
| |
| protected SelectionProviderAction revealAction; |
| |
| protected SelectionProviderAction openAction; |
| |
| protected SelectionProviderAction deleteAction; |
| |
| protected SelectionProviderAction selectAllAction; |
| |
| protected SelectionProviderAction propertiesAction; |
| |
| protected UndoActionHandler undoAction; |
| |
| protected RedoActionHandler redoAction; |
| |
| private ISelectionListener focusListener = new ISelectionListener() { |
| public void selectionChanged(IWorkbenchPart part, ISelection selection) { |
| MarkerView.this.focusSelectionChanged(part, selection); |
| } |
| }; |
| |
| private int totalMarkers = 0; |
| |
| private MarkerFilter[] markerFilters = new MarkerFilter[0]; |
| |
| // A cache of the enabled filters |
| private MarkerFilter[] enabledFilters = null; |
| |
| private MenuManager filtersMenu; |
| |
| private MenuManager showInMenu; |
| |
| private IPropertyChangeListener workingSetListener; |
| |
| private MarkerAdapter adapter; |
| |
| private IPropertyChangeListener preferenceListener; |
| |
| /** |
| * Create a new instance of the receiver, |
| */ |
| public MarkerView() { |
| super(); |
| preferenceListener = new IPropertyChangeListener() { |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent) |
| */ |
| public void propertyChange(PropertyChangeEvent event) { |
| if (event.getProperty().equals(getFiltersPreferenceName())) { |
| loadFiltersPreferences(); |
| clearEnabledFilters(); |
| refreshForFocusUpdate(); |
| } |
| } |
| }; |
| IDEWorkbenchPlugin.getDefault().getPreferenceStore() |
| .addPropertyChangeListener(preferenceListener); |
| } |
| |
| /** |
| * Get the current markers for the receiver. |
| * |
| * @return MarkerList |
| */ |
| public MarkerList getCurrentMarkers() { |
| return getMarkerAdapter().getCurrentMarkers(); |
| } |
| |
| /** |
| * Get the marker adapter for the receiver. |
| * |
| * @return MarkerAdapter |
| */ |
| protected MarkerAdapter getMarkerAdapter() { |
| return adapter; |
| } |
| |
| /** |
| * Update for the change in the contents. |
| * |
| * @param monitor |
| */ |
| public void updateForContentsRefresh(IProgressMonitor monitor) { |
| updateJob.cancel(); |
| getMarkerAdapter().buildAllMarkers(monitor); |
| getProgressService().schedule(updateJob); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ui.IViewPart#init(org.eclipse.ui.IViewSite, |
| * org.eclipse.ui.IMemento) |
| */ |
| public void init(IViewSite site, IMemento memento) throws PartInitException { |
| super.init(site, memento); |
| IWorkbenchSiteProgressService progressService = getProgressService(); |
| if (progressService != null) { |
| getProgressService().showBusyForFamily( |
| ResourcesPlugin.FAMILY_MANUAL_BUILD); |
| getProgressService().showBusyForFamily( |
| ResourcesPlugin.FAMILY_AUTO_BUILD); |
| getProgressService().showBusyForFamily(MARKER_UPDATE_FAMILY); |
| } |
| loadFiltersPreferences(); |
| |
| } |
| |
| /** |
| * Load the filters preference. |
| */ |
| private void loadFiltersPreferences() { |
| |
| String preference = IDEWorkbenchPlugin.getDefault() |
| .getPreferenceStore().getString(getFiltersPreferenceName()); |
| |
| if (preference.equals(IPreferenceStore.STRING_DEFAULT_DEFAULT)) { |
| createDefaultFilter(); |
| return; |
| } |
| |
| StringReader reader = new StringReader(preference); |
| try { |
| restoreFilters(XMLMemento.createReadRoot(reader)); |
| } catch (WorkbenchException e) { |
| IDEWorkbenchPlugin.log(e.getLocalizedMessage(), e); |
| } |
| |
| } |
| |
| /** |
| * Update for filter changes. Save the preference and clear the enabled |
| * cache. |
| */ |
| void updateForFilterChanges() { |
| |
| XMLMemento memento = XMLMemento.createWriteRoot(TAG_FILTERS_SECTION); |
| |
| writeFiltersSettings(memento); |
| |
| StringWriter writer = new StringWriter(); |
| try { |
| memento.save(writer); |
| } catch (IOException e) { |
| IDEWorkbenchPlugin.getDefault().getLog().log(Util.errorStatus(e)); |
| } |
| |
| IDEWorkbenchPlugin.getDefault().getPreferenceStore().putValue( |
| getFiltersPreferenceName(), writer.toString()); |
| IDEWorkbenchPlugin.getDefault().savePluginPreferences(); |
| |
| clearEnabledFilters(); |
| refreshFilterMenu(); |
| refreshViewer(); |
| } |
| |
| /** |
| * Write the filter settings to the memento. |
| * |
| * @param memento |
| */ |
| protected void writeFiltersSettings(XMLMemento memento) { |
| MarkerFilter[] filters = getUserFilters(); |
| for (int i = 0; i < filters.length; i++) { |
| IMemento child = memento.createChild(TAG_FILTER_ENTRY, filters[i] |
| .getName()); |
| filters[i].saveFilterSettings(child); |
| } |
| } |
| |
| /** |
| * Get the name of the filters preference for instances of the receiver. |
| * |
| * @return String |
| */ |
| abstract String getFiltersPreferenceName(); |
| |
| /** |
| * Restore the filters from the mimento. |
| * |
| * @param memento |
| */ |
| void restoreFilters(IMemento memento) { |
| |
| IMemento[] sections = null; |
| if (memento != null) { |
| sections = memento.getChildren(TAG_FILTER_ENTRY); |
| } |
| |
| if (sections == null) { |
| // Check if we have an old filter setting around |
| IDialogSettings mainSettings = getDialogSettings(); |
| IDialogSettings filtersSection = mainSettings |
| .getSection(OLD_FILTER_SECTION); |
| if (filtersSection != null) { |
| MarkerFilter markerFilter = createFilter(MarkerMessages.MarkerFilter_defaultFilterName); |
| markerFilter.restoreFilterSettings(filtersSection); |
| setFilters(new MarkerFilter[] { markerFilter }); |
| } |
| |
| } else { |
| MarkerFilter[] newFilters = new MarkerFilter[sections.length]; |
| |
| for (int i = 0; i < sections.length; i++) { |
| newFilters[i] = createFilter(sections[i].getID()); |
| newFilters[i].restoreState(sections[i]); |
| } |
| setFilters(newFilters); |
| } |
| |
| if (markerFilters.length == 0) {// Make sure there is at least a default |
| createDefaultFilter(); |
| } |
| |
| } |
| |
| /** |
| * Create a default filter for the receiver. |
| * |
| */ |
| private void createDefaultFilter() { |
| MarkerFilter filter = createFilter(MarkerMessages.MarkerFilter_defaultFilterName); |
| setFilters(new MarkerFilter[] { filter }); |
| } |
| |
| /** |
| * Create a filter called name. |
| * |
| * @param name |
| * @return MarkerFilter |
| */ |
| protected abstract MarkerFilter createFilter(String name); |
| |
| /** |
| * Return the memento tag for the receiver. |
| * |
| * @return String |
| */ |
| protected abstract String getSectionTag(); |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ui.views.internal.tableview.TableView#createPartControl(org.eclipse.swt.widgets.Composite) |
| */ |
| public void createPartControl(Composite parent) { |
| |
| clipboard = new Clipboard(parent.getDisplay()); |
| super.createPartControl(parent); |
| |
| initDragAndDrop(); |
| |
| getSite().getPage().addSelectionListener(focusListener); |
| focusSelectionChanged(getSite().getPage().getActivePart(), getSite() |
| .getPage().getSelection()); |
| PlatformUI.getWorkbench().getWorkingSetManager() |
| .addPropertyChangeListener(getWorkingSetListener()); |
| |
| // Set help on the view itself |
| getViewer().getControl().addHelpListener(new HelpListener() { |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.swt.events.HelpListener#helpRequested(org.eclipse.swt.events.HelpEvent) |
| */ |
| public void helpRequested(HelpEvent e) { |
| IContext context = contextProvider.getContext(getViewer() |
| .getControl()); |
| PlatformUI.getWorkbench().getHelpSystem().displayHelp(context); |
| } |
| }); |
| |
| // Hook up to the resource changes after all widget have been created |
| ResourcesPlugin.getWorkspace().addResourceChangeListener( |
| markerUpdateListener, |
| IResourceChangeEvent.POST_CHANGE |
| | IResourceChangeEvent.PRE_BUILD |
| | IResourceChangeEvent.POST_BUILD); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class) |
| */ |
| public Object getAdapter(Class adaptable) { |
| if (adaptable.equals(IContextProvider.class)) { |
| return contextProvider; |
| } |
| if (adaptable.equals(IShowInSource.class)) { |
| return new IShowInSource() { |
| public ShowInContext getShowInContext() { |
| ISelection selection = getViewer().getSelection(); |
| if (!(selection instanceof IStructuredSelection)) { |
| return null; |
| } |
| IStructuredSelection structured = (IStructuredSelection) selection; |
| Iterator markerIterator = structured.iterator(); |
| List newSelection = new ArrayList(); |
| while (markerIterator.hasNext()) { |
| ConcreteMarker element = (ConcreteMarker) markerIterator |
| .next(); |
| newSelection.add(element.getResource()); |
| } |
| return new ShowInContext(getViewer().getInput(), |
| new StructuredSelection(newSelection)); |
| } |
| |
| }; |
| } |
| return super.getAdapter(adaptable); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ui.views.markers.internal.TableView#viewerSelectionChanged(org.eclipse.jface.viewers.IStructuredSelection) |
| */ |
| protected void viewerSelectionChanged(IStructuredSelection selection) { |
| |
| Object[] rawSelection = selection.toArray(); |
| |
| List markers = new ArrayList(); |
| |
| for (int idx = 0; idx < rawSelection.length; idx++) { |
| |
| if (rawSelection[idx] instanceof ConcreteMarker) |
| markers.add(((ConcreteMarker) rawSelection[idx]).getMarker()); |
| } |
| |
| setSelection(new StructuredSelection(markers)); |
| |
| updateStatusMessage(selection); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ui.views.internal.tableview.TableView#dispose() |
| */ |
| public void dispose() { |
| super.dispose(); |
| cancelJobs(); |
| |
| ResourcesPlugin.getWorkspace().removeResourceChangeListener( |
| markerUpdateListener); |
| PlatformUI.getWorkbench().getWorkingSetManager() |
| .removePropertyChangeListener(workingSetListener); |
| IDEWorkbenchPlugin.getDefault().getPreferenceStore() |
| .removePropertyChangeListener(preferenceListener); |
| getSite().getPage().removeSelectionListener(focusListener); |
| |
| // dispose of selection provider actions (may not have been created yet |
| // if createPartControls was never called) |
| if (openAction != null) { |
| openAction.dispose(); |
| copyAction.dispose(); |
| selectAllAction.dispose(); |
| deleteAction.dispose(); |
| revealAction.dispose(); |
| propertiesAction.dispose(); |
| undoAction.dispose(); |
| redoAction.dispose(); |
| clipboard.dispose(); |
| } |
| if (showInMenu != null) { |
| showInMenu.dispose(); |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ui.views.internal.tableview.TableView#createActions() |
| */ |
| protected void createActions() { |
| revealAction = new ActionRevealMarker(this, getViewer()); |
| openAction = new ActionOpenMarker(this, getViewer()); |
| copyAction = new ActionCopyMarker(this, getViewer()); |
| copyAction.setClipboard(clipboard); |
| copyAction.setProperties(getSortingFields()); |
| pasteAction = new ActionPasteMarker(this, getViewer(), getMarkerName()); |
| pasteAction.setClipboard(clipboard); |
| pasteAction.setPastableTypes(getMarkerTypes()); |
| deleteAction = new ActionRemoveMarker(this, getViewer(), |
| getMarkerName()); |
| selectAllAction = new ActionSelectAll(this); |
| propertiesAction = new ActionMarkerProperties(this, getViewer(), |
| getMarkerName()); |
| |
| IUndoContext undoContext = getUndoContext(); |
| undoAction = new UndoActionHandler(getSite(), undoContext); |
| redoAction = new RedoActionHandler(getSite(), undoContext); |
| |
| super.createActions(); |
| |
| setFilterAction(new FiltersAction(this)); |
| |
| setPreferencesAction(new ViewPreferencesAction() { |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ui.preferences.ViewPreferencesAction#openViewPreferencesDialog() |
| */ |
| public void openViewPreferencesDialog() { |
| openPreferencesDialog(getMarkerEnablementPreferenceName(), |
| getMarkerLimitPreferenceName()); |
| |
| } |
| |
| }); |
| } |
| |
| /** |
| * Open a dialog to set the preferences. |
| * |
| * @param markerEnablementPreferenceName |
| * @param markerLimitPreferenceName |
| */ |
| private void openPreferencesDialog(String markerEnablementPreferenceName, |
| String markerLimitPreferenceName) { |
| |
| Dialog dialog = new MarkerViewPreferenceDialog(getSite() |
| .getWorkbenchWindow().getShell(), |
| markerEnablementPreferenceName, markerLimitPreferenceName, |
| MarkerMessages.MarkerPreferences_DialogTitle); |
| if (dialog.open() == Window.OK) { |
| refreshViewer(); |
| } |
| |
| } |
| |
| /** |
| * Get the name of the marker enablement preference. |
| * |
| * @return String |
| */ |
| abstract String getMarkerLimitPreferenceName(); |
| |
| abstract String[] getMarkerTypes(); |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ui.views.internal.tableview.TableView#initToolBar(org.eclipse.jface.action.IToolBarManager) |
| */ |
| protected void initToolBar(IToolBarManager tbm) { |
| tbm.add(deleteAction); |
| tbm.add(getFilterAction()); |
| tbm.update(false); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ui.views.internal.tableview.TableView#registerGlobalActions(org.eclipse.ui.IActionBars) |
| */ |
| protected void registerGlobalActions(IActionBars actionBars) { |
| copyAction.setActionDefinitionId("org.eclipse.ui.edit.copy"); //$NON-NLS-1$ |
| pasteAction.setActionDefinitionId("org.eclipse.ui.edit.paste"); //$NON-NLS-1$ |
| deleteAction.setActionDefinitionId("org.eclipse.ui.edit.delete"); //$NON-NLS-1$ |
| selectAllAction.setActionDefinitionId("org.eclipse.ui.edit.selectAll"); //$NON-NLS-1$ |
| propertiesAction |
| .setActionDefinitionId("org.eclipse.ui.file.properties"); //$NON-NLS-1$ |
| undoAction.setActionDefinitionId("org.eclipse.ui.edit.undo"); //$NON-NLS-1$ |
| redoAction.setActionDefinitionId("org.eclipse.ui.edit.redo"); //$NON-NLS-1$ |
| |
| actionBars.setGlobalActionHandler(ActionFactory.COPY.getId(), |
| copyAction); |
| actionBars.setGlobalActionHandler(ActionFactory.PASTE.getId(), |
| pasteAction); |
| actionBars.setGlobalActionHandler(ActionFactory.DELETE.getId(), |
| deleteAction); |
| actionBars.setGlobalActionHandler(ActionFactory.SELECT_ALL.getId(), |
| selectAllAction); |
| actionBars.setGlobalActionHandler(ActionFactory.PROPERTIES.getId(), |
| propertiesAction); |
| actionBars.setGlobalActionHandler(ActionFactory.UNDO.getId(), |
| undoAction); |
| actionBars.setGlobalActionHandler(ActionFactory.REDO.getId(), |
| redoAction); |
| } |
| |
| protected void initDragAndDrop() { |
| int operations = DND.DROP_COPY; |
| Transfer[] transferTypes = new Transfer[] { |
| MarkerTransfer.getInstance(), TextTransfer.getInstance() }; |
| DragSourceListener listener = new DragSourceAdapter() { |
| public void dragSetData(DragSourceEvent event) { |
| performDragSetData(event); |
| } |
| |
| public void dragFinished(DragSourceEvent event) { |
| } |
| }; |
| |
| getViewer().addDragSupport(operations, transferTypes, listener); |
| } |
| |
| /** |
| * The user is attempting to drag marker data. Add the appropriate data to |
| * the event depending on the transfer type. |
| */ |
| private void performDragSetData(DragSourceEvent event) { |
| if (MarkerTransfer.getInstance().isSupportedType(event.dataType)) { |
| |
| event.data = getSelectedMarkers(); |
| return; |
| } |
| if (TextTransfer.getInstance().isSupportedType(event.dataType)) { |
| List selection = ((IStructuredSelection) getViewer().getSelection()) |
| .toList(); |
| try { |
| IMarker[] markers = new IMarker[selection.size()]; |
| selection.toArray(markers); |
| if (markers != null) { |
| event.data = copyAction.createMarkerReport(markers); |
| } |
| } catch (ArrayStoreException e) { |
| } |
| } |
| } |
| |
| /** |
| * Get the array of selected markers. |
| * |
| * @return IMarker[] |
| */ |
| private IMarker[] getSelectedMarkers() { |
| Object[] selection = ((IStructuredSelection) getViewer().getSelection()) |
| .toArray(); |
| ArrayList markers = new ArrayList(); |
| for (int i = 0; i < selection.length; i++) { |
| if (selection[i] instanceof ConcreteMarker) { |
| markers.add(((ConcreteMarker) selection[i]).getMarker()); |
| } |
| } |
| return (IMarker[]) markers.toArray(new IMarker[markers.size()]); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ui.views.internal.tableview.TableView#fillContextMenu(org.eclipse.jface.action.IMenuManager) |
| */ |
| protected void fillContextMenu(IMenuManager manager) { |
| if (manager == null) { |
| return; |
| } |
| manager.add(openAction); |
| createShowInMenu(manager); |
| manager.add(new Separator()); |
| manager.add(copyAction); |
| pasteAction.updateEnablement(); |
| manager.add(pasteAction); |
| |
| if (canBeEditable()) { |
| manager.add(deleteAction); |
| } |
| manager.add(selectAllAction); |
| fillContextMenuAdditions(manager); |
| manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); |
| manager.add(new Separator()); |
| manager.add(propertiesAction); |
| } |
| |
| /** |
| * Return whether or not any of the types in the receiver can be editable. |
| * |
| * @return <code>true</code> if it is possible to have an editable marker |
| * in this view. |
| */ |
| boolean canBeEditable() { |
| return true; |
| } |
| |
| /** |
| * Fill the context menu for the receiver. |
| * |
| * @param manager |
| */ |
| abstract void fillContextMenuAdditions(IMenuManager manager); |
| |
| /** |
| * Get the filters for the receiver. |
| * |
| * @return MarkerFilter[] |
| */ |
| protected final MarkerFilter[] getUserFilters() { |
| return markerFilters; |
| } |
| |
| |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ui.views.internal.tableview.TableView#handleOpenEvent(org.eclipse.jface.viewers.OpenEvent) |
| */ |
| protected void handleOpenEvent(OpenEvent event) { |
| if (openAction.isEnabled()) { |
| openAction.run(); |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ui.views.internal.tableview.TableView#saveSelection(org.eclipse.ui.IMemento) |
| */ |
| protected void saveSelection(IMemento memento) { |
| IStructuredSelection selection = (IStructuredSelection) getViewer() |
| .getSelection(); |
| IMemento selectionMem = memento.createChild(TAG_SELECTION); |
| for (Iterator iterator = selection.iterator(); iterator.hasNext();) { |
| Object next = iterator.next(); |
| if (!(next instanceof ConcreteMarker)) { |
| continue; |
| } |
| ConcreteMarker marker = (ConcreteMarker) next; |
| IMemento elementMem = selectionMem.createChild(TAG_MARKER); |
| elementMem.putString(TAG_RESOURCE, marker.getMarker().getResource() |
| .getFullPath().toString()); |
| elementMem.putString(TAG_ID, String.valueOf(marker.getMarker() |
| .getId())); |
| } |
| } |
| |
| protected abstract String[] getRootTypes(); |
| |
| /** |
| * @param part |
| * @param selection |
| */ |
| protected void focusSelectionChanged(IWorkbenchPart part, |
| ISelection selection) { |
| |
| List selectedElements = new ArrayList(); |
| if (part instanceof IEditorPart) { |
| IEditorPart editor = (IEditorPart) part; |
| IFile file = ResourceUtil.getFile(editor.getEditorInput()); |
| if (file == null) { |
| IEditorInput editorInput = editor.getEditorInput(); |
| if (editorInput != null) { |
| Object mapping = editorInput |
| .getAdapter(ResourceMapping.class); |
| if (mapping != null) { |
| selectedElements.add(mapping); |
| } |
| } |
| } else { |
| selectedElements.add(file); |
| } |
| } else { |
| if (selection instanceof IStructuredSelection) { |
| for (Iterator iterator = ((IStructuredSelection) selection) |
| .iterator(); iterator.hasNext();) { |
| Object object = iterator.next(); |
| if (object instanceof IAdaptable) { |
| ITaskListResourceAdapter taskListResourceAdapter; |
| Object adapter = ((IAdaptable) object) |
| .getAdapter(ITaskListResourceAdapter.class); |
| if (adapter != null |
| && adapter instanceof ITaskListResourceAdapter) { |
| taskListResourceAdapter = (ITaskListResourceAdapter) adapter; |
| } else { |
| taskListResourceAdapter = DefaultMarkerResourceAdapter |
| .getDefault(); |
| } |
| |
| IResource resource = taskListResourceAdapter |
| .getAffectedResource((IAdaptable) object); |
| if (resource == null) { |
| Object mapping = ((IAdaptable) object) |
| .getAdapter(ResourceMapping.class); |
| if (mapping != null) { |
| selectedElements.add(mapping); |
| } |
| } else { |
| selectedElements.add(resource); |
| } |
| } |
| } |
| } |
| } |
| updateFocusMarkers(selectedElements.toArray()); |
| } |
| |
| /** |
| * Update the focus resources of the filters. |
| * |
| * @param elements |
| */ |
| protected final void updateFilterSelection(Object[] elements) { |
| |
| Collection resourceCollection = new ArrayList(); |
| for (int i = 0; i < elements.length; i++) { |
| if (elements[i] instanceof IResource) { |
| resourceCollection.add(elements[i]); |
| } else { |
| addResources(resourceCollection, |
| ((ResourceMapping) elements[i])); |
| } |
| } |
| |
| IResource[] resources = new IResource[resourceCollection.size()]; |
| resourceCollection.toArray(resources); |
| |
| for (int i = 0; i < markerFilters.length; i++) { |
| markerFilters[i].setFocusResource(resources); |
| } |
| |
| Iterator systemFilters = MarkerSupportRegistry.getInstance() |
| .getRegisteredFilters().iterator(); |
| |
| while (systemFilters.hasNext()) { |
| MarkerFilter filter = (MarkerFilter) systemFilters.next(); |
| filter.setFocusResource(resources); |
| |
| } |
| |
| } |
| |
| /** |
| * Add the resources for the mapping to resources. |
| * |
| * @param resources |
| * @param mapping |
| */ |
| private void addResources(Collection resources, ResourceMapping mapping) { |
| try { |
| ResourceTraversal[] traversals = mapping.getTraversals( |
| ResourceMappingContext.LOCAL_CONTEXT, |
| new NullProgressMonitor()); |
| for (int i = 0; i < traversals.length; i++) { |
| ResourceTraversal traversal = traversals[i]; |
| IResource[] result = traversal.getResources(); |
| for (int j = 0; j < result.length; j++) { |
| resources.add(result[j]); |
| } |
| } |
| } catch (CoreException e) { |
| Util.log(e); |
| return; |
| } |
| |
| } |
| |
| protected abstract String getStaticContextId(); |
| |
| /** |
| * Update the focus markers for the supplied elements. |
| * |
| * @param elements |
| */ |
| void updateFocusMarkers(Object[] elements) { |
| boolean updateNeeded = updateNeeded(focusElements, elements); |
| if (updateNeeded) { |
| focusElements = elements; |
| refreshForFocusUpdate(); |
| } |
| } |
| |
| private boolean updateNeeded(Object[] oldElements, Object[] newElements) { |
| // determine if an update if refiltering is required |
| MarkerFilter[] filters = getEnabledFilters(); |
| boolean updateNeeded = false; |
| |
| for (int i = 0; i < filters.length; i++) { |
| MarkerFilter filter = filters[i]; |
| if (!filter.isEnabled()) { |
| continue; |
| } |
| |
| int onResource = filter.getOnResource(); |
| if (onResource == MarkerFilter.ON_ANY |
| || onResource == MarkerFilter.ON_WORKING_SET) { |
| continue; |
| } |
| if (newElements == null || newElements.length < 1) { |
| continue; |
| } |
| if (oldElements == null || oldElements.length < 1) { |
| return true; |
| } |
| if (Arrays.equals(oldElements, newElements)) { |
| continue; |
| } |
| if (onResource == MarkerFilter.ON_ANY_IN_SAME_CONTAINER) { |
| Collection oldProjects = MarkerFilter |
| .getProjectsAsCollection(oldElements); |
| Collection newProjects = MarkerFilter |
| .getProjectsAsCollection(newElements); |
| |
| if (oldProjects.size() == newProjects.size()) { |
| if (newProjects.containsAll(oldProjects)) { |
| continue; |
| } |
| } |
| |
| return true; |
| } |
| updateNeeded = true;// We are updating as there is nothing to stop |
| // us |
| } |
| |
| return updateNeeded; |
| } |
| |
| void updateTitle() { |
| String status = Util.EMPTY_STRING; |
| int filteredCount = getCurrentMarkers().getItemCount(); |
| int totalCount = getTotalMarkers(); |
| if (filteredCount == totalCount) { |
| status = NLS.bind(MarkerMessages.filter_itemsMessage, new Integer( |
| totalCount)); |
| } else { |
| status = NLS.bind(MarkerMessages.filter_matchedMessage, |
| new Integer(filteredCount), new Integer(totalCount)); |
| } |
| setContentDescription(status); |
| } |
| |
| /** |
| * Updates the message displayed in the status line. This method is invoked |
| * in the following cases: |
| * <ul> |
| * <li>when this view is first created</li> |
| * <li>when new elements are added</li> |
| * <li>when something is deleted</li> |
| * <li>when the filters change</li> |
| * </ul> |
| * <p> |
| * By default, this method calls |
| * <code>updateStatusMessage(IStructuredSelection)</code> with the current |
| * selection or <code>null</code>. Classes wishing to override this |
| * functionality, should just override the method |
| * <code>updateStatusMessage(IStructuredSelection)</code>. |
| * </p> |
| */ |
| protected void updateStatusMessage() { |
| ISelection selection = getViewer().getSelection(); |
| |
| if (selection instanceof IStructuredSelection) { |
| updateStatusMessage((IStructuredSelection) selection); |
| } else { |
| updateStatusMessage(null); |
| } |
| } |
| |
| /** |
| * Updates that message displayed in the status line. If the selection |
| * parameter is <code>null</code> or its size is 0, the status area is |
| * blanked out. If only 1 marker is selected, the status area is updated |
| * with the contents of the message attribute of this marker. In other cases |
| * (more than one marker is selected) the status area indicates how many |
| * items have been selected. |
| * <p> |
| * This method may be overwritten. |
| * </p> |
| * <p> |
| * This method is called whenever a selection changes in this view. |
| * </p> |
| * |
| * @param selection |
| * a valid selection or <code>null</code> |
| */ |
| protected void updateStatusMessage(IStructuredSelection selection) { |
| String message = ""; //$NON-NLS-1$ |
| |
| if (selection == null || selection.size() == 0) { |
| // Show stats on all items in the view |
| message = updateSummaryVisible(); |
| } else if (selection.size() == 1) { |
| // Use the Message attribute of the marker |
| Object first = selection.getFirstElement(); |
| if (first instanceof ConcreteMarker) { |
| message = ((ConcreteMarker) first).getDescription(); |
| } |
| } else if (selection.size() > 1) { |
| // Show stats on only those items in the selection |
| message = updateSummarySelected(selection); |
| } |
| getViewSite().getActionBars().getStatusLineManager() |
| .setMessage(message); |
| } |
| |
| /** |
| * @param selection |
| * @return the summary status message |
| */ |
| protected String updateSummarySelected(IStructuredSelection selection) { |
| // Show how many items selected |
| return MessageFormat.format( |
| MarkerMessages.marker_statusSummarySelected, |
| new Object[] { new Integer(selection.size()) }); |
| } |
| |
| /** |
| * @return the update summary |
| */ |
| protected String updateSummaryVisible() { |
| return ""; //$NON-NLS-1$ |
| } |
| |
| /** |
| * Open a dialog on the filters |
| * |
| */ |
| public final void openFiltersDialog() { |
| |
| DialogMarkerFilter dialog = createFiltersDialog(); |
| |
| if (dialog.open() == Window.OK) { |
| |
| MarkerFilter[] result = dialog.getFilters(); |
| if (result == null) { |
| return; |
| } |
| if (result.length == 0) { |
| setFilters(new MarkerFilter[] { createFilter(MarkerMessages.MarkerFilter_defaultFilterName) }); |
| } else { |
| setFilters(result); |
| } |
| |
| updateForFilterChanges(); |
| } |
| } |
| |
| /** |
| * Refresh the contents of the viewer. |
| */ |
| public void refreshViewer() { |
| scheduleMarkerUpdate(Util.SHORT_DELAY); |
| } |
| |
| /** |
| * Set the filters to newFilters. |
| * |
| * @param newFilters |
| */ |
| void setFilters(MarkerFilter[] newFilters) { |
| markerFilters = newFilters; |
| } |
| |
| /** |
| * Clear the cache of enabled filters. |
| * |
| */ |
| void clearEnabledFilters() { |
| enabledFilters = null; |
| } |
| |
| /** |
| * Refresh the contents of the filter sub menu. |
| */ |
| private void refreshFilterMenu() { |
| if (filtersMenu == null) { |
| return; |
| } |
| filtersMenu.removeAll(); |
| MarkerFilter[] filters = getAllFilters(); |
| for (int i = 0; i < filters.length; i++) { |
| filtersMenu.add(new FilterEnablementAction(filters[i], this)); |
| } |
| |
| } |
| |
| /** |
| * Open a filter dialog on the receiver. |
| */ |
| protected abstract DialogMarkerFilter createFiltersDialog(); |
| |
| /** |
| * Given a selection of IMarker, reveals the corresponding elements in the |
| * viewer |
| * |
| * @param structuredSelection |
| * @param reveal |
| */ |
| public void setSelection(IStructuredSelection structuredSelection, |
| boolean reveal) { |
| TreeViewer viewer = getViewer(); |
| |
| List newSelection = new ArrayList(structuredSelection.size()); |
| |
| for (Iterator i = structuredSelection.iterator(); i.hasNext();) { |
| Object next = i.next(); |
| if (next instanceof IMarker) { |
| ConcreteMarker marker = getCurrentMarkers().getMarker( |
| (IMarker) next); |
| if (marker != null) { |
| newSelection.add(marker); |
| } |
| } |
| } |
| |
| if (viewer != null) { |
| viewer.setSelection(new StructuredSelection(newSelection), reveal); |
| } |
| } |
| |
| protected MarkerList getVisibleMarkers() { |
| return getCurrentMarkers(); |
| } |
| |
| /** |
| * Returns the total number of markers. Should not be called while the |
| * marker list is still updating. |
| * |
| * @return the total number of markers in the workspace (including |
| * everything that doesn't pass the filters) |
| */ |
| int getTotalMarkers() { |
| // The number of visible markers should never exceed the total number of |
| // markers in |
| // the workspace. If this assertation fails, it probably indicates some |
| // sort of concurrency problem |
| // (most likely, getTotalMarkers was called while we were still |
| // computing the marker lists) |
| // Assert.isTrue(totalMarkers >= currentMarkers.getItemCount()); |
| |
| return totalMarkers; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ui.part.WorkbenchPart#showBusy(boolean) |
| */ |
| public void showBusy(boolean busy) { |
| super.showBusy(busy); |
| |
| if (busy) { |
| preBusyMarkers = totalMarkers; |
| } else {// Only bold if there has been a change in count |
| if (totalMarkers != preBusyMarkers) { |
| getProgressService().warnOfContentChange(); |
| } |
| } |
| |
| } |
| |
| /** |
| * Get the filters that are currently enabled. |
| * |
| * @return MarkerFilter[] |
| */ |
| MarkerFilter[] getEnabledFilters() { |
| |
| if (enabledFilters == null) { |
| Collection filters = findEnabledFilters(); |
| |
| enabledFilters = new MarkerFilter[filters.size()]; |
| filters.toArray(enabledFilters); |
| } |
| return enabledFilters; |
| |
| } |
| |
| /** |
| * Find the filters enabled in the view. |
| * |
| * @return Collection of MarkerFilter |
| */ |
| protected Collection findEnabledFilters() { |
| MarkerFilter[] allFilters = getAllFilters(); |
| ArrayList filters = new ArrayList(0); |
| for (int i = 0; i < allFilters.length; i++) { |
| if (allFilters[i].isEnabled()) { |
| filters.add(allFilters[i]); |
| } |
| } |
| return filters; |
| } |
| |
| /** |
| * Get all of the filters applied to the receiver. |
| * |
| * @return MarkerFilter[] |
| */ |
| MarkerFilter[] getAllFilters() { |
| return getUserFilters(); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ui.views.markers.internal.TableView#addDropDownContributions(org.eclipse.jface.action.IMenuManager) |
| */ |
| void addDropDownContributions(IMenuManager menu) { |
| super.addDropDownContributions(menu); |
| |
| menu.add(new Separator(MENU_FILTERS_GROUP)); |
| // Don't add in the filters until they are set |
| filtersMenu = new MenuManager(MarkerMessages.filtersSubMenu_title); |
| refreshFilterMenu(); |
| menu.appendToGroup(MENU_FILTERS_GROUP, filtersMenu); |
| } |
| |
| /** |
| * Create the show in menu if there is a single selection. |
| * |
| * @param menu |
| */ |
| void createShowInMenu(IMenuManager menu) { |
| ISelection selection = getViewer().getSelection(); |
| if (!(selection instanceof IStructuredSelection)) { |
| return; |
| } |
| |
| IStructuredSelection structured = (IStructuredSelection) selection; |
| if (!Util.isSingleConcreteSelection(structured)) { |
| return; |
| } |
| |
| menu.add(new Separator(MENU_SHOW_IN_GROUP)); |
| // Don't add in the filters until they are set |
| |
| String showInLabel = IDEWorkbenchMessages.Workbench_showIn; |
| IBindingService bindingService = (IBindingService) PlatformUI |
| .getWorkbench().getAdapter(IBindingService.class); |
| if (bindingService != null) { |
| String keyBinding = bindingService |
| .getBestActiveBindingFormattedFor("org.eclipse.ui.navigate.showInQuickMenu"); //$NON-NLS-1$ |
| if (keyBinding != null) { |
| showInLabel += '\t' + keyBinding; |
| } |
| } |
| showInMenu = new MenuManager(showInLabel); |
| showInMenu.add(ContributionItemFactory.VIEWS_SHOW_IN |
| .create(getViewSite().getWorkbenchWindow())); |
| |
| menu.appendToGroup(MENU_SHOW_IN_GROUP, showInMenu); |
| |
| } |
| |
| /** |
| * Refresh the marker counts |
| * |
| * @param monitor |
| */ |
| void refreshMarkerCounts(IProgressMonitor monitor) { |
| monitor.subTask(MarkerMessages.MarkerView_refreshing_counts); |
| try { |
| totalMarkers = MarkerList.compute(getMarkerTypes()).length; |
| } catch (CoreException e) { |
| Util.log(e); |
| return; |
| } |
| |
| } |
| |
| /** |
| * Returns the marker limit or -1 if unlimited |
| * |
| * @return int |
| */ |
| int getMarkerLimit() { |
| |
| // If limits are enabled return it. Otherwise return -1 |
| if (IDEWorkbenchPlugin.getDefault().getPreferenceStore().getBoolean( |
| getMarkerEnablementPreferenceName())) { |
| return IDEWorkbenchPlugin.getDefault().getPreferenceStore().getInt( |
| getMarkerLimitPreferenceName()); |
| |
| } |
| return -1; |
| |
| } |
| |
| /** |
| * Get the name of the marker limit preference. |
| * |
| * @return String |
| */ |
| abstract String getMarkerEnablementPreferenceName(); |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ui.views.markers.internal.TableView#createViewerInput() |
| */ |
| Object createViewerInput() { |
| adapter = new MarkerAdapter(this); |
| return adapter; |
| } |
| |
| /** |
| * Add a listener for the end of the update. |
| * |
| * @param listener |
| */ |
| public void addUpdateFinishListener(IJobChangeListener listener) { |
| updateJob.addJobChangeListener(listener); |
| |
| } |
| |
| /** |
| * Remove a listener for the end of the update. |
| * |
| * @param listener |
| */ |
| public void removeUpdateFinishListener(IJobChangeListener listener) { |
| updateJob.removeJobChangeListener(listener); |
| |
| } |
| |
| /** |
| * Create a listener for working set changes. |
| * |
| * @return IPropertyChangeListener |
| */ |
| private IPropertyChangeListener getWorkingSetListener() { |
| workingSetListener = new IPropertyChangeListener() { |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent) |
| */ |
| public void propertyChange(PropertyChangeEvent event) { |
| clearEnabledFilters(); |
| refreshViewer(); |
| |
| } |
| }; |
| return workingSetListener; |
| } |
| |
| /** |
| * Schedule an update of the markers with a delay of time |
| * |
| * @param time |
| */ |
| void scheduleMarkerUpdate(int time) { |
| cancelJobs(); |
| getProgressService().schedule(markerProcessJob, time); |
| } |
| |
| /** |
| * Cancel the pending jobs in the receiver. |
| */ |
| private void cancelJobs() { |
| markerProcessJob.cancel(); |
| updateJob.cancel(); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ui.views.markers.internal.TableView#createTree(org.eclipse.swt.widgets.Composite) |
| */ |
| protected Tree createTree(Composite parent) { |
| Tree tree = super.createTree(parent); |
| tree.addTreeListener(new TreeAdapter() { |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.swt.events.TreeAdapter#treeCollapsed(org.eclipse.swt.events.TreeEvent) |
| */ |
| public void treeCollapsed(TreeEvent e) { |
| updateJob.removeExpandedCategory((MarkerCategory) e.item |
| .getData()); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.swt.events.TreeAdapter#treeExpanded(org.eclipse.swt.events.TreeEvent) |
| */ |
| public void treeExpanded(TreeEvent e) { |
| updateJob |
| .addExpandedCategory((MarkerCategory) e.item.getData()); |
| } |
| }); |
| |
| return tree; |
| } |
| |
| /** |
| * The focus elements have changed. Update accordingly. |
| */ |
| private void refreshForFocusUpdate() { |
| if (focusElements != null) { |
| updateFilterSelection(focusElements); |
| refreshViewer(); |
| } |
| } |
| |
| /** |
| * Save the current selection in the update for reselection after update. |
| */ |
| protected void preserveSelection() { |
| updateJob.saveSelection(getViewer().getSelection()); |
| |
| } |
| |
| /** |
| * Return the string name of the specific type of marker shown in this view. |
| */ |
| protected abstract String getMarkerName(); |
| |
| /** |
| * Return the undo context associated with operations performed in this |
| * view. By default, return the workspace undo context. Subclasses should |
| * override if a more specific undo context should be used. |
| */ |
| protected IUndoContext getUndoContext() { |
| return (IUndoContext) ResourcesPlugin.getWorkspace().getAdapter( |
| IUndoContext.class); |
| } |
| |
| } |