blob: 95c202fab86bd826a22c6e9db589c91b58811b9a [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2003 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.ui.views.markers.internal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.dialogs.Dialog;
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.TableViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StackLayout;
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.KeyEvent;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Table;
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.actions.SelectionProviderAction;
import org.eclipse.ui.part.FileEditorInput;
import org.eclipse.ui.part.MarkerTransfer;
import org.eclipse.ui.views.navigator.ShowInNavigatorAction;
import org.eclipse.ui.views.tasklist.ITaskListResourceAdapter;
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$
protected IResource[] focusResources;
private TableViewer viewer;
private MarkerFilter filter;
private Clipboard clipboard;
protected ActionCopyMarker copyAction;
protected ActionPasteMarker pasteAction;
protected SelectionProviderAction revealAction;
protected SelectionProviderAction openAction;
protected SelectionProviderAction showInNavigatorAction;
protected SelectionProviderAction deleteAction;
protected SelectionProviderAction selectAllAction;
protected SelectionProviderAction propertiesAction;
protected Composite compositeMarkerLimitExceeded;
protected StackLayout stackLayout = new StackLayout();
private IItemsChangedListener itemsListener = new IItemsChangedListener() {
public void itemsChanged(List additions, List removals, List changes) {
MarkerView.this.itemsChanged(additions, removals, changes);
}
};
private ISelectionListener focusListener = new ISelectionListener() {
public void selectionChanged(IWorkbenchPart part, ISelection selection) {
MarkerView.this.focusSelectionChanged(part, selection);
}
};
/* (non-Javadoc)
* @see org.eclipse.ui.views.internal.tableview.TableView#init(org.eclipse.ui.IViewSite, org.eclipse.ui.IMemento)
*/
public void init(IViewSite site, IMemento memento) throws PartInitException {
super.init(site, memento);
}
/* (non-Javadoc)
* @see org.eclipse.ui.views.internal.tableview.TableView#createPartControl(org.eclipse.swt.widgets.Composite)
*/
public void createPartControl(Composite parent) {
getSite().getPage().addSelectionListener(focusListener);
getRegistry().addItemsChangedListener(itemsListener);
clipboard = new Clipboard(parent.getDisplay());
super.createPartControl(parent);
initDragAndDrop();
compositeMarkerLimitExceeded = new Composite(parent, SWT.NONE);
compositeMarkerLimitExceeded.setLayout(new GridLayout());
Label labelMarkerLimitExceeded =
new Label(compositeMarkerLimitExceeded, SWT.WRAP);
labelMarkerLimitExceeded.setText(Messages.getString("markerLimitExceeded.title")); //$NON-NLS-1$
parent.setLayout(stackLayout);
checkMarkerLimit();
updateTitle();
}
/* (non-Javadoc)
* @see org.eclipse.ui.views.internal.tableview.TableView#dispose()
*/
public void dispose() {
super.dispose();
getRegistry().removeItemsChangedListener(itemsListener);
getSite().getPage().removeSelectionListener(focusListener);
//dispose of selection provider actions
openAction.dispose();
copyAction.dispose();
selectAllAction.dispose();
deleteAction.dispose();
revealAction.dispose();
showInNavigatorAction.dispose();
propertiesAction.dispose();
}
/* (non-Javadoc)
* @see org.eclipse.ui.views.internal.tableview.TableView#createActions()
*/
protected void createActions() {
viewer = getViewer();
revealAction = new ActionRevealMarker(this, viewer);
openAction = new ActionOpenMarker(this, viewer);
copyAction = new ActionCopyMarker(this, viewer);
copyAction.setClipboard(clipboard);
copyAction.setProperties(getFields());
pasteAction = new ActionPasteMarker(this, viewer);
pasteAction.setClipboard(clipboard);
pasteAction.setPastableTypes(getRegistry().getTypes());
deleteAction = new ActionRemoveMarker(this, viewer);
selectAllAction = new ActionSelectAll(viewer, getRegistry());
showInNavigatorAction = new ShowInNavigatorAction(getViewSite().getPage(), viewer);
propertiesAction = new ActionMarkerProperties(this, viewer);
super.createActions();
}
/* (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(getAction(TableView.FILTERS_ACTION_ID));
tbm.update(false);
}
/* (non-Javadoc)
* @see org.eclipse.ui.views.internal.tableview.TableView#registerGlobalActions(org.eclipse.ui.IActionBars)
*/
protected void registerGlobalActions(IActionBars actionBars) {
actionBars.setGlobalActionHandler(IWorkbenchActionConstants.COPY, copyAction);
actionBars.setGlobalActionHandler(IWorkbenchActionConstants.PASTE, pasteAction);
actionBars.setGlobalActionHandler(IWorkbenchActionConstants.DELETE, deleteAction);
actionBars.setGlobalActionHandler(IWorkbenchActionConstants.SELECT_ALL, selectAllAction);
actionBars.setGlobalActionHandler(IWorkbenchActionConstants.PROPERTIES, propertiesAction);
}
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 = ((IStructuredSelection) getViewer().getSelection()).toArray();
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) {
}
}
}
/* (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);
manager.add(showInNavigatorAction);
manager.add(new Separator());
manager.add(copyAction);
pasteAction.updateEnablement();
manager.add(pasteAction);
manager.add(deleteAction);
manager.add(selectAllAction);
fillContextMenuAdditions(manager);
manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
manager.add(new Separator());
manager.add(propertiesAction);
}
protected void fillContextMenuAdditions(IMenuManager manager) {
}
/* (non-Javadoc)
* @see org.eclipse.ui.views.internal.tableview.TableView#getFilter()
*/
protected IFilter getFilter() {
if (filter == null) {
filter = new MarkerFilter(getRootTypes());
filter.restoreState(getDialogSettings());
}
return filter;
}
/* (non-Javadoc)
* @see org.eclipse.ui.views.internal.tableview.TableView#getContentProvider()
*/
protected ITableViewContentProvider getContentProvider() {
return getRegistry();
}
/* (non-Javadoc)
* @see org.eclipse.ui.views.internal.tableview.TableView#handleKeyPressed(org.eclipse.swt.events.KeyEvent)
*/
protected void handleKeyPressed(KeyEvent event) {
if (event.character == SWT.DEL && event.stateMask == 0 && deleteAction.isEnabled()) {
deleteAction.run();
}
}
/* (non-Javadoc)
* @see org.eclipse.ui.views.internal.tableview.TableView#handleOpenEvent(org.eclipse.jface.viewers.OpenEvent)
*/
protected void handleOpenEvent(OpenEvent event) {
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();) {
IMarker marker = (IMarker) iterator.next();
IMemento elementMem = selectionMem.createChild(TAG_MARKER);
elementMem.putString(TAG_RESOURCE, marker.getResource().getFullPath().toString());
elementMem.putString(TAG_ID, String.valueOf(marker.getId()));
}
}
/* (non-Javadoc)
* @see org.eclipse.ui.views.internal.tableview.TableView#restoreSelection(org.eclipse.ui.IMemento)
*/
protected IStructuredSelection restoreSelection(IMemento memento) {
if (memento == null) {
return new StructuredSelection();
}
IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
IMemento selectionMemento = memento.getChild(TAG_SELECTION);
if (selectionMemento == null) {
return new StructuredSelection();
}
ArrayList selectionList = new ArrayList();
IMemento[] markerMems = selectionMemento.getChildren(TAG_MARKER);
for (int i = 0; i < markerMems.length; i++) {
try {
long id = new Long(markerMems[i].getString(TAG_ID)).longValue();
IResource resource = root.findMember(markerMems[i].getString(TAG_RESOURCE));
if (resource != null) {
IMarker marker = resource.findMarker(id);
if (marker != null)
selectionList.add(marker);
}
}
catch (CoreException e) {
}
}
return new StructuredSelection(selectionList);
}
protected abstract String[] getRootTypes();
protected abstract MarkerRegistry getRegistry();
protected Dialog getFiltersDialog() {
IFilter filter = getFilter();
if (filter != null && filter instanceof MarkerFilter) {
return new DialogMarkerFilter(getSite().getShell(), (MarkerFilter) filter);
}
return null;
}
/**
* @param part
* @param selection
*/
protected void focusSelectionChanged(IWorkbenchPart part, ISelection selection) {
List resources = new ArrayList();
if (part instanceof IEditorPart) {
IEditorInput input = ((IEditorPart) part).getEditorInput();
if (input instanceof FileEditorInput) {
resources.add(((FileEditorInput) input).getFile());
}
}
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) {
resources.add(resource);
}
}
}
}
}
IResource[] focus = new IResource[resources.size()];
resources.toArray(focus);
updateFocusResource(focus);
}
void updateFocusResource(IResource[] resources) {
boolean updateNeeded = updateNeeded(focusResources, resources);
if (getFilter() != null && getFilter() instanceof MarkerFilter) {
((MarkerFilter) getFilter()).setFocusResource(resources);
}
focusResources = resources;
if (updateNeeded) {
filtersChanged();
}
}
private boolean updateNeeded(IResource[] oldResources, IResource[] newResources) {
//determine if an update if refiltering is required
IFilter iFilter = getFilter();
if (iFilter == null) {
return false;
}
MarkerFilter filter = (MarkerFilter) iFilter;
int onResource = filter.getOnResource();
if (onResource == MarkerFilter.ON_ANY_RESOURCE || onResource == MarkerFilter.ON_WORKING_SET) {
return false;
}
if (newResources == null || newResources.length < 1) {
return false;
}
if (oldResources == null || oldResources.length < 1) {
return true;
}
if (Arrays.equals(oldResources, newResources)) {
return false;
}
if (onResource == MarkerFilter.ON_ANY_RESOURCE_OF_SAME_PROJECT) {
List oldProjects = new ArrayList(newResources.length);
List newProjects = new ArrayList(newResources.length);
for (int i = 0; i < oldResources.length; i++) {
IProject project = oldResources[i].getProject();
if (!oldProjects.contains(project)) {
oldProjects.add(project);
}
}
for (int i = 0; i < newResources.length; i++) {
IProject project = newResources[i].getProject();
if (!newProjects.contains(project)) {
newProjects.add(project);
}
}
if (oldProjects.size() == newProjects.size()) {
for (int i = 0; i < oldProjects.size(); i++) {
if (!newProjects.contains(oldProjects.get(i))) {
return true;
}
}
}
else {
return true;
}
}
else {
return true;
}
return false;
}
/**
* @param additions
* @param removals
* @param changes
*/
protected void itemsChanged(List additions, List removals, List changes) {
getSite().getShell().getDisplay().asyncExec(new Runnable() {
public void run() {
checkMarkerLimit();
updateTitle();
}
});
}
/* (non-Javadoc)
* @see org.eclipse.ui.views.internal.tableview.TableView#filtersChanged()
*/
protected void filtersChanged() {
super.filtersChanged();
getSite().getShell().getDisplay().asyncExec(new Runnable() {
public void run() {
checkMarkerLimit();
updateTitle();
}
});
}
void checkMarkerLimit() {
IFilter iFilter = getFilter();
if (iFilter == null || !(iFilter instanceof MarkerFilter))
return;
MarkerFilter filter = (MarkerFilter) iFilter;
int itemCount = getRegistry().getItemCount();
if (getFilter() == null || !filter.getFilterOnMarkerLimit() || itemCount <= filter.getMarkerLimit()) {
if (stackLayout.topControl != viewer.getTable()) {
stackLayout.topControl = viewer.getTable();
TableViewer viewer = getViewer();
if (viewer != null) {
Table table = viewer.getTable();
if (table != null && !table.isDisposed()) {
Composite parent = table.getParent();
if (parent != null && !parent.isDisposed())
parent.layout();
}
}
}
}
else {
if (stackLayout.topControl != compositeMarkerLimitExceeded) {
stackLayout.topControl = compositeMarkerLimitExceeded;
TableViewer viewer = getViewer();
if (viewer != null) {
Table table = viewer.getTable();
if (table != null && !table.isDisposed()) {
Composite parent = table.getParent();
if (parent != null && !parent.isDisposed())
parent.layout();
}
}
}
}
}
void updateTitle() {
String currentTitle = getTitle();
String viewName = getConfigurationElement().getAttribute("name"); //$NON-NLS-1$
String status = ""; //$NON-NLS-1$
int filteredCount = getRegistry().getItemCount();
int totalCount = getRegistry().getRawItemCount();
if (filteredCount == totalCount) {
status = Messages.format("filter.itemsMessage", new Object[] {new Integer(totalCount)}); //$NON-NLS-1$
}
else {
status = Messages.format("filter.matchedMessage", new Object[] {new Integer(filteredCount), new Integer(totalCount)}); //$NON-NLS-1$
}
String newTitle = Messages.format("view.title", new String[] {viewName, status}); //$NON-NLS-1$
if (!newTitle.equals(currentTitle)) {
setTitle(newTitle);
}
}
public IStructuredSelection getSelection() {
return (IStructuredSelection) viewer.getSelection();
}
public void setSelection(IStructuredSelection structuredSelection, boolean reveal) {
for (Iterator i = structuredSelection.iterator(); i.hasNext();)
if (!(i.next() instanceof IMarker))
return;
if (viewer != null)
viewer.setSelection(structuredSelection, reveal);
}
}