blob: 2f17f6dbfa2ff2ffe554c5b7888e55e8ca2666d9 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2006 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:
* Roscoe Rush - Concept and prototype implementation
* IBM Corporation - current implementation
*******************************************************************************/
package org.eclipse.ant.internal.ui.views;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import org.eclipse.ant.internal.ui.IAntUIHelpContextIds;
import org.eclipse.ant.internal.ui.model.AntElementNode;
import org.eclipse.ant.internal.ui.model.AntModelLabelProvider;
import org.eclipse.ant.internal.ui.model.AntModelProblem;
import org.eclipse.ant.internal.ui.model.AntProjectNode;
import org.eclipse.ant.internal.ui.model.AntProjectNodeProxy;
import org.eclipse.ant.internal.ui.model.AntTargetNode;
import org.eclipse.ant.internal.ui.model.InternalTargetFilter;
import org.eclipse.ant.internal.ui.views.actions.AddBuildFilesAction;
import org.eclipse.ant.internal.ui.views.actions.AntOpenWithMenu;
import org.eclipse.ant.internal.ui.views.actions.FilterInternalTargetsAction;
import org.eclipse.ant.internal.ui.views.actions.RefreshBuildFilesAction;
import org.eclipse.ant.internal.ui.views.actions.RemoveAllAction;
import org.eclipse.ant.internal.ui.views.actions.RemoveProjectAction;
import org.eclipse.ant.internal.ui.views.actions.RunTargetAction;
import org.eclipse.ant.internal.ui.views.actions.SearchForBuildFilesAction;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.action.IMenuListener;
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.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
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.jface.viewers.ViewerFilter;
import org.eclipse.jface.viewers.ViewerSorter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.FileTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.XMLMemento;
import org.eclipse.ui.part.IShowInSource;
import org.eclipse.ui.part.ShowInContext;
import org.eclipse.ui.part.ViewPart;
import org.eclipse.ui.texteditor.IUpdate;
/**
* A view which displays a hierarchical view of ant build files and allows the
* user to run selected targets from those files.
*/
public class AntView extends ViewPart implements IResourceChangeListener, IShowInSource {
private Object[] restoredViewerInput= null;
private boolean filterInternalTargets= false;
private InternalTargetFilter fInternalTargetFilter= null;
/**
* This memento allows the Ant view to save and restore state
* when it is closed and opened within a session. A different
* memento is supplied by the platform for persistence at
* workbench shutdown.
*/
private static IMemento fgTempMemento = null;
/**
* XML tag used to identify an ant project in storage
*/
private static final String TAG_PROJECT = "project"; //$NON-NLS-1$
/**
* XML key used to store whether or not an Ant project is an error node.
* Persisting this data saved a huge amount of processing at startup.
*/
private static final String KEY_ERROR = "error"; //$NON-NLS-1$
/**
* XML key used to store whether or not an Ant project is an error node.
* Persisting this data saved a huge amount of processing at startup.
*/
private static final String KEY_WARNING = "warning"; //$NON-NLS-1$
/**
* XML key used to store an ant project's path
*/
private static final String KEY_PATH = "path"; //$NON-NLS-1$
/**
* XML key used to store an ant node's name
*/
private static final String KEY_NAME = "name"; //$NON-NLS-1$
/**
* XML key used to store an ant project's default target name
*/
private static final String KEY_DEFAULT = "default"; //$NON-NLS-1$
/**
* XML tag used to identify the "filter internal targets" preference.
*/
private static final String TAG_FILTER_INTERNAL_TARGETS = "filterInternalTargets"; //$NON-NLS-1$
/**
* XML key used to store the value of the "filter internal targets" preference.
*/
private static final String KEY_VALUE = "value"; //$NON-NLS-1$
/**
* The tree viewer that displays the users ant projects
*/
private TreeViewer projectViewer;
private AntViewContentProvider contentProvider;
/**
* Collection of <code>IUpdate</code> actions that need to update on
* selection changed in the project viewer.
*/
private List updateProjectActions;
// Ant View Actions
private AddBuildFilesAction addBuildFileAction;
private SearchForBuildFilesAction searchForBuildFilesAction;
private RefreshBuildFilesAction refreshBuildFilesAction;
private RemoveProjectAction removeProjectAction;
private RemoveAllAction removeAllAction;
private FilterInternalTargetsAction filterInternalTargetsAction;
private RunTargetAction runTargetAction;
// Context-menu-only actions
private AntOpenWithMenu openWithMenu;
/**
* The given build file has changed. Refresh the view to pick up any
* structural changes.
*/
private void handleBuildFileChanged(AntProjectNode project) {
((AntProjectNodeProxy)project).parseBuildFile(true);
Display.getDefault().asyncExec(new Runnable() {
public void run() {
//must do a full refresh to re-sort
projectViewer.refresh();
//update the status line
handleSelectionChanged((IStructuredSelection) projectViewer.getSelection());
}
});
}
/* (non-Javadoc)
* @see org.eclipse.ui.IWorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite)
*/
public void createPartControl(Composite parent) {
initializeActions();
createProjectViewer(parent);
initializeDragAndDrop();
fillMainToolBar();
if (getProjects().length > 0) {
// If any projects have been added to the view during startup,
// begin listening for resource changes
ResourcesPlugin.getWorkspace().addResourceChangeListener(this);
}
PlatformUI.getWorkbench().getHelpSystem().setHelp(parent, IAntUIHelpContextIds.ANT_VIEW);
updateProjectActions();
}
private void initializeDragAndDrop() {
int ops = DND.DROP_COPY | DND.DROP_DEFAULT;
Transfer[] transfers = new Transfer[] { FileTransfer.getInstance() };
TreeViewer viewer = getViewer();
AntViewDropAdapter adapter = new AntViewDropAdapter(this);
viewer.addDropSupport(ops, transfers, adapter);
}
/**
* Creates a pop-up menu on the given control
*
* @param menuControl the control with which the pop-up
* menu will be associated
*/
private void createContextMenu(Viewer viewer) {
Control menuControl = viewer.getControl();
MenuManager menuMgr = new MenuManager("#PopUp"); //$NON-NLS-1$
menuMgr.setRemoveAllWhenShown(true);
menuMgr.addMenuListener(new IMenuListener() {
public void menuAboutToShow(IMenuManager mgr) {
fillContextMenu(mgr);
}
});
Menu menu = menuMgr.createContextMenu(menuControl);
menuControl.setMenu(menu);
// register the context menu such that other plugins may contribute to it
getSite().registerContextMenu(menuMgr, viewer);
}
/**
* Adds actions to the context menu
*
* @param viewer the viewer who's menu we're configuring
* @param menu The menu to contribute to
*/
private void fillContextMenu(IMenuManager menu) {
addOpenWithMenu(menu);
menu.add(new Separator());
menu.add(addBuildFileAction);
menu.add(removeProjectAction);
menu.add(removeAllAction);
menu.add(refreshBuildFilesAction);
menu.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
}
private void addOpenWithMenu(IMenuManager menu) {
AntElementNode node= getSelectionNode();
if (node != null) {
IFile buildFile= node.getIFile();
if (buildFile != null) {
menu.add(new Separator("group.open")); //$NON-NLS-1$
IMenuManager submenu= new MenuManager(AntViewMessages.AntView_1);
openWithMenu.setNode(node);
submenu.add(openWithMenu);
menu.appendToGroup("group.open", submenu); //$NON-NLS-1$
}
}
}
/**
* Initialize the actions for this view
*/
private void initializeActions() {
updateProjectActions= new ArrayList(5);
addBuildFileAction = new AddBuildFilesAction(this);
removeProjectAction = new RemoveProjectAction(this);
updateProjectActions.add(removeProjectAction);
removeAllAction = new RemoveAllAction(this);
updateProjectActions.add(removeAllAction);
runTargetAction = new RunTargetAction(this);
updateProjectActions.add(runTargetAction);
searchForBuildFilesAction = new SearchForBuildFilesAction(this);
refreshBuildFilesAction = new RefreshBuildFilesAction(this);
updateProjectActions.add(refreshBuildFilesAction);
openWithMenu= new AntOpenWithMenu(this.getViewSite().getPage());
filterInternalTargetsAction= new FilterInternalTargetsAction(this);
}
/**
* Updates the enabled state of all <code>IUpdate</code> actions associated
* with the project viewer.
*/
private void updateProjectActions() {
Iterator iter = updateProjectActions.iterator();
while (iter.hasNext()) {
((IUpdate) iter.next()).update();
}
}
/**
* Create the viewer which displays the Ant projects
*/
private void createProjectViewer(Composite parent) {
projectViewer = new TreeViewer(parent, SWT.H_SCROLL | SWT.V_SCROLL | SWT.MULTI);
contentProvider = new AntViewContentProvider();
projectViewer.setContentProvider(contentProvider);
filterInternalTargetsAction.setChecked(filterInternalTargets);
setFilterInternalTargets(filterInternalTargets);
projectViewer.setLabelProvider(new AntModelLabelProvider());
if (fgTempMemento != null) {
restoreViewerInput(fgTempMemento);
fgTempMemento= null;
}
projectViewer.setInput(new Object[0]);
if (restoredViewerInput.length > 0) {
contentProvider.addAll(restoredViewerInput);
}
projectViewer.setSorter(new ViewerSorter() {
/**
* @see org.eclipse.jface.viewers.ViewerSorter#compare(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
*/
public int compare(Viewer viewer, Object e1, Object e2) {
if (e1 instanceof AntProjectNode && e2 instanceof AntProjectNode
|| e1 instanceof AntTargetNode && e2 instanceof AntTargetNode) {
return e1.toString().compareToIgnoreCase(e2.toString());
}
return 0;
}
});
projectViewer.addSelectionChangedListener(new ISelectionChangedListener() {
public void selectionChanged(SelectionChangedEvent event) {
handleSelectionChanged((IStructuredSelection)event.getSelection());
}
});
projectViewer.addDoubleClickListener(new IDoubleClickListener() {
public void doubleClick(DoubleClickEvent event) {
if (!event.getSelection().isEmpty()) {
handleProjectViewerDoubleClick();
}
}
});
projectViewer.getControl().addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent event) {
handleProjectViewerKeyPress(event);
}
});
createContextMenu(projectViewer);
getSite().setSelectionProvider(projectViewer);
}
private void handleProjectViewerKeyPress(KeyEvent event) {
if (event.character == SWT.DEL && event.stateMask == 0) {
if (removeProjectAction.isEnabled()) {
removeProjectAction.run();
}
} else if (event.keyCode == SWT.F5 && event.stateMask == 0) {
if (refreshBuildFilesAction.isEnabled()) {
refreshBuildFilesAction.run();
}
}
}
private void handleProjectViewerDoubleClick() {
AntElementNode node= getSelectionNode();
if (node != null) {
runTargetAction.run(node);
}
}
/**
* Updates the actions and status line for selection change in one of the
* viewers.
*/
private void handleSelectionChanged(IStructuredSelection selection) {
updateProjectActions();
Iterator selectionIter = selection.iterator();
AntElementNode selected = null;
if (selectionIter.hasNext()) {
selected = (AntElementNode) selectionIter.next();
}
String messageString= null;
if (!selectionIter.hasNext()) {
if (selected != null) {
String errorString= selected.getProblemMessage();
if (errorString != null) {
getViewSite().getActionBars().getStatusLineManager().setErrorMessage(errorString);
return;
}
}
getViewSite().getActionBars().getStatusLineManager().setErrorMessage(null);
messageString= getStatusLineText(selected);
}
getViewSite().getActionBars().getStatusLineManager().setMessage(messageString);
}
/**
* Returns text appropriate for display in the workbench status line for the
* given node.
*/
private String getStatusLineText(AntElementNode node) {
if (node instanceof AntProjectNode) {
AntProjectNode project = (AntProjectNode) node;
StringBuffer message= new StringBuffer(project.getBuildFileName());
String description= project.getDescription();
if (description != null && description.length() > 0) {
message.append(": "); //$NON-NLS-1$
message.append(description);
}
return message.toString();
} else if (node instanceof AntTargetNode) {
AntTargetNode target = (AntTargetNode) node;
StringBuffer message= new StringBuffer();
Enumeration depends= target.getTarget().getDependencies();
if (depends.hasMoreElements()) {
message.append(AntViewMessages.AntView_3);
message.append((String)depends.nextElement()); // Unroll the loop to avoid trailing comma
while (depends.hasMoreElements()) {
String dependancy = (String) depends.nextElement();
message.append(',').append(dependancy);
}
message.append('\"');
}
String description= target.getTarget().getDescription();
if (description != null && description.length() != 0) {
message.append(AntViewMessages.AntView_4);
message.append(description);
message.append('\"');
}
return message.toString();
}
return null;
}
/**
* Returns the tree viewer that displays the projects in this view
*
* @return TreeViewer this view's project viewer
*/
public TreeViewer getViewer() {
return projectViewer;
}
/**
* Returns the <code>AntProjectNode</code>s currently displayed in this view.
*
* @return AntProjectNode[] the <code>ProjectNode</code>s currently displayed
* in this view
*/
public AntProjectNode[] getProjects() {
Object[] objects= contentProvider.getElements(projectViewer.getInput());
AntProjectNode[] projects= new AntProjectNode[objects.length];
for (int i = 0; i < projects.length; i++) {
projects[i] = (AntProjectNode)objects[i];
}
return projects;
}
/**
* Adds the given project to the view
*
* @param project the project to add
*/
public void addProject(AntProjectNode project) {
contentProvider.add(project);
projectViewer.refresh();
ResourcesPlugin.getWorkspace().addResourceChangeListener(this);
handleSelectionChanged(new StructuredSelection(project));
}
/**
* Removes the given project from the view
*
* @param project the project to remove
*/
private void removeProject(AntProjectNode project) {
removeProjectFromContentProvider(project);
projectViewer.refresh();
setProjectViewerSelectionAfterDeletion();
}
private void setProjectViewerSelectionAfterDeletion() {
Object[] children= getProjects();
if (children.length > 0) {
ViewerSorter sorter= projectViewer.getSorter();
sorter.sort(projectViewer, children);
IStructuredSelection selection= new StructuredSelection(children[0]);
projectViewer.setSelection(selection);
handleSelectionChanged(selection);
}
}
/**
* Removes the given list of <code>AntProjectNode</code> objects from the view.
* This method should be called whenever multiple projects are to be removed
* because this method optimizes the viewer refresh associated with removing
* multiple items.
*
* @param projectNodes the list of <code>ProjectNode</code> objects to
* remove
*/
public void removeProjects(List projectNodes) {
Iterator iter = projectNodes.iterator();
while (iter.hasNext()) {
AntProjectNode project = (AntProjectNode) iter.next();
removeProjectFromContentProvider(project);
}
projectViewer.refresh();
setProjectViewerSelectionAfterDeletion();
}
/**
* Removes the given project node from the project content provider.
*
* @param project the project to remove
*/
private void removeProjectFromContentProvider(AntProjectNode project) {
project.dispose();
contentProvider.remove(project);
if (getProjects().length == 0) {
ResourcesPlugin.getWorkspace().removeResourceChangeListener(this);
}
}
/**
* Removes all projects from the view
*/
public void removeAllProjects() {
AntProjectNode[] projects= getProjects();
for (int i = 0; i < projects.length; i++) {
AntProjectNode node = projects[i];
node.dispose();
}
// Remove all projects
contentProvider.removeAll();
ResourcesPlugin.getWorkspace().removeResourceChangeListener(this);
updateProjectActions();
}
/* (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 {
init(site);
restoreViewerInput(memento);
if (memento != null) {
IMemento child= memento.getChild(TAG_FILTER_INTERNAL_TARGETS);
if (child != null) {
filterInternalTargets= Boolean.valueOf(child.getString(KEY_VALUE)).booleanValue();
}
}
}
/**
* Restore the viewer content that was persisted
*
* @param memento the memento containing the persisted viewer content
*/
private void restoreViewerInput(IMemento memento) {
if (memento == null) {
restoredViewerInput= new Object[0];
return;
}
IMemento[] projects = memento.getChildren(TAG_PROJECT);
if (projects.length < 1) {
restoredViewerInput= new Object[0];
return;
}
List projectNodes = new ArrayList(projects.length);
for (int i = 0; i < projects.length; i++) {
IMemento projectMemento = projects[i];
String pathString = projectMemento.getString(KEY_PATH);
if (!ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(pathString)).exists()) {
// If the file no longer exists, don't add it.
continue;
}
String nameString = projectMemento.getString(KEY_NAME);
String defaultTarget= projectMemento.getString(KEY_DEFAULT);
String errorString = projectMemento.getString(KEY_ERROR);
String warningString = projectMemento.getString(KEY_WARNING);
AntProjectNodeProxy project = null;
if (nameString == null) {
nameString = ""; //$NON-NLS-1$
}
project = new AntProjectNodeProxy(nameString, pathString);
if (errorString != null && Boolean.valueOf(errorString).booleanValue()) {
project.setProblemSeverity(AntModelProblem.SEVERITY_ERROR);
} else if (warningString != null && Boolean.valueOf(warningString).booleanValue()) {
project.setProblemSeverity(AntModelProblem.SEVERITY_WARNING);
}
if (defaultTarget != null) {
project.setDefaultTargetName(defaultTarget);
}
projectNodes.add(project);
}
restoredViewerInput= projectNodes.toArray(new AntProjectNode[projectNodes.size()]);
}
/* (non-Javadoc)
* @see org.eclipse.ui.IViewPart#saveState(org.eclipse.ui.IMemento)
*/
public void saveState(IMemento memento) {
// Save the projects
AntProjectNode[] projects = getProjects();
AntProjectNode project;
IMemento projectMemento;
for (int i = 0; i < projects.length; i++) {
project= projects[i];
projectMemento = memento.createChild(TAG_PROJECT);
projectMemento.putString(KEY_PATH, project.getBuildFileName());
projectMemento.putString(KEY_NAME, project.getLabel());
String defaultTarget= project.getDefaultTargetName();
if (project.isErrorNode()) {
projectMemento.putString(KEY_ERROR, String.valueOf(true));
} else {
if (project.isWarningNode()) {
projectMemento.putString(KEY_WARNING, String.valueOf(true));
}
if (defaultTarget != null) {
projectMemento.putString(KEY_DEFAULT, defaultTarget);
}
projectMemento.putString(KEY_ERROR, String.valueOf(false));
}
}
IMemento filterTargets= memento.createChild(TAG_FILTER_INTERNAL_TARGETS);
filterTargets.putString(KEY_VALUE, isFilterInternalTargets() ? String.valueOf(true) : String.valueOf(false));
}
/* (non-Javadoc)
* @see org.eclipse.ui.IWorkbenchPart#dispose()
*/
public void dispose() {
fgTempMemento= XMLMemento.createWriteRoot("AntViewMemento"); //$NON-NLS-1$
saveState(fgTempMemento);
super.dispose();
if (openWithMenu != null) {
openWithMenu.dispose();
}
ResourcesPlugin.getWorkspace().removeResourceChangeListener(this);
}
/* (non-Javadoc)
* @see org.eclipse.core.resources.IResourceChangeListener#resourceChanged(org.eclipse.core.resources.IResourceChangeEvent)
*/
public void resourceChanged(IResourceChangeEvent event) {
IResourceDelta delta = event.getDelta();
if (delta != null) {
AntProjectNode projects[]= getProjects();
IPath buildFilePath;
for (int i = 0; i < projects.length; i++) {
buildFilePath= new Path(projects[i].getBuildFileName());
IResourceDelta change= delta.findMember(buildFilePath);
if (change != null) {
handleChangeDelta(change, projects[i]);
}
}
}
}
/**
* Update the view for the given resource delta. The delta is a resource
* delta for the given build file in the view
*
* @param delta a delta for a build file in the view
* @param project the project node that has changed
*/
private void handleChangeDelta(IResourceDelta delta, final AntProjectNode project) {
IResource resource= delta.getResource();
if (resource.getType() != IResource.FILE) {
return;
}
if (delta.getKind() == IResourceDelta.REMOVED) {
Display.getDefault().asyncExec(new Runnable() {
public void run() {
removeProject(project);
}
});
} else if (delta.getKind() == IResourceDelta.CHANGED && (delta.getFlags() & IResourceDelta.CONTENT) != 0) {
handleBuildFileChanged(project);
}
}
private void fillMainToolBar() {
IToolBarManager toolBarMgr= getViewSite().getActionBars().getToolBarManager();
toolBarMgr.removeAll();
toolBarMgr.add(addBuildFileAction);
toolBarMgr.add(searchForBuildFilesAction);
toolBarMgr.add(filterInternalTargetsAction);
toolBarMgr.add(runTargetAction);
toolBarMgr.add(removeProjectAction);
toolBarMgr.add(removeAllAction);
toolBarMgr.update(false);
}
private AntElementNode getSelectionNode() {
IStructuredSelection selection= (IStructuredSelection)getViewer().getSelection();
if (selection.size() == 1) {
Object element= selection.getFirstElement();
if (element instanceof AntElementNode) {
AntElementNode node= (AntElementNode) element;
return node;
}
}
return null;
}
/* (non-Javadoc)
* @see org.eclipse.ui.part.IShowInSource#getShowInContext()
*/
public ShowInContext getShowInContext() {
AntElementNode node= getSelectionNode();
if (node != null) {
IFile buildFile= node.getIFile();
if (buildFile != null) {
ISelection selection= new StructuredSelection(buildFile);
return new ShowInContext(null, selection);
}
}
return null;
}
/**
* Returns whether internal targets are currently being filtered out of
* the view.
*
* @return whether or not internal targets are being filtered out
*/
public boolean isFilterInternalTargets() {
return filterInternalTargets;
}
/**
* Sets whether internal targets should be filtered out of the view.
*
* @param filter whether or not internal targets should be filtered out
*/
public void setFilterInternalTargets(boolean filter) {
filterInternalTargets= filter;
if (filter) {
projectViewer.addFilter(getInternalTargetsFilter());
} else {
projectViewer.removeFilter(getInternalTargetsFilter());
}
}
private ViewerFilter getInternalTargetsFilter() {
if (fInternalTargetFilter == null) {
fInternalTargetFilter= new InternalTargetFilter();
}
return fInternalTargetFilter;
}
/* (non-Javadoc)
* @see org.eclipse.ui.IWorkbenchPart#setFocus()
*/
public void setFocus() {
if (getViewer() != null) {
getViewer().getControl().setFocus();
}
}
}