blob: ebb08a2f978f7032c19b57104006985853432974 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2005 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.navigator;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
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.DecoratingLabelProvider;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ILabelDecorator;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.IOpenListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.OpenEvent;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.ViewerSorter;
import org.eclipse.osgi.util.NLS;
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.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.IPartListener;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchPreferenceConstants;
import org.eclipse.ui.IWorkingSet;
import org.eclipse.ui.IWorkingSetManager;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.ResourceWorkingSetFilter;
import org.eclipse.ui.actions.ActionContext;
import org.eclipse.ui.ide.ResourceUtil;
import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
import org.eclipse.ui.internal.views.navigator.ResourceNavigatorMessages;
import org.eclipse.ui.model.WorkbenchContentProvider;
import org.eclipse.ui.model.WorkbenchLabelProvider;
import org.eclipse.ui.part.ISetSelectionTarget;
import org.eclipse.ui.part.IShowInSource;
import org.eclipse.ui.part.IShowInTarget;
import org.eclipse.ui.part.PluginTransfer;
import org.eclipse.ui.part.ResourceTransfer;
import org.eclipse.ui.part.ShowInContext;
import org.eclipse.ui.part.ViewPart;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.eclipse.ui.views.framelist.FrameList;
import org.eclipse.ui.views.framelist.TreeFrame;
/**
* Implements the Resource Navigator view.
*/
public class ResourceNavigator extends ViewPart implements ISetSelectionTarget,
IResourceNavigator {
private TreeViewer viewer;
private IDialogSettings settings;
private IMemento memento;
private FrameList frameList;
private ResourceNavigatorActionGroup actionGroup;
private ResourcePatternFilter patternFilter = new ResourcePatternFilter();
private ResourceWorkingSetFilter workingSetFilter = new ResourceWorkingSetFilter();
private boolean linkingEnabled;
private boolean dragDetected;
private Listener dragDetectListener;
/**
* Remembered working set.
*/
private IWorkingSet workingSet;
/**
* Marks whether the working set we're using is currently empty. In this
* event we're effectively not using a working set.
*/
private boolean emptyWorkingSet = false;
/**
* Settings constant for section name (value <code>ResourceNavigator</code>).
*/
private static final String STORE_SECTION = "ResourceNavigator"; //$NON-NLS-1$
/**
* Settings constant for sort order (value <code>ResourceViewer.STORE_SORT_TYPE</code>).
*/
private static final String STORE_SORT_TYPE = "ResourceViewer.STORE_SORT_TYPE"; //$NON-NLS-1$
/**
* Settings constant for working set (value <code>ResourceWorkingSetFilter.STORE_WORKING_SET</code>).
*/
private static final String STORE_WORKING_SET = "ResourceWorkingSetFilter.STORE_WORKING_SET"; //$NON-NLS-1$
/**
* @deprecated No longer used but preserved to avoid an api change.
*/
public static final String NAVIGATOR_VIEW_HELP_ID = INavigatorHelpContextIds.RESOURCE_VIEW;
/**
* True iff we've already scheduled an asynchronous call to linkToEditor
*/
private boolean linkScheduled = false;
// Persistance tags.
private static final String TAG_SORTER = "sorter"; //$NON-NLS-1$
private static final String TAG_FILTERS = "filters"; //$NON-NLS-1$
private static final String TAG_FILTER = "filter"; //$NON-NLS-1$
private static final String TAG_SELECTION = "selection"; //$NON-NLS-1$
private static final String TAG_EXPANDED = "expanded"; //$NON-NLS-1$
private static final String TAG_ELEMENT = "element"; //$NON-NLS-1$
private static final String TAG_IS_ENABLED = "isEnabled"; //$NON-NLS-1$
private static final String TAG_PATH = "path"; //$NON-NLS-1$
private static final String TAG_CURRENT_FRAME = "currentFrame"; //$NON-NLS-1$
private IPartListener partListener = new IPartListener() {
public void partActivated(IWorkbenchPart part) {
if (part instanceof IEditorPart)
editorActivated((IEditorPart) part);
}
public void partBroughtToTop(IWorkbenchPart part) {
}
public void partClosed(IWorkbenchPart part) {
}
public void partDeactivated(IWorkbenchPart part) {
}
public void partOpened(IWorkbenchPart part) {
}
};
private IPropertyChangeListener propertyChangeListener = new IPropertyChangeListener() {
public void propertyChange(PropertyChangeEvent event) {
String property = event.getProperty();
Object newValue = event.getNewValue();
Object oldValue = event.getOldValue();
if (IWorkingSetManager.CHANGE_WORKING_SET_REMOVE.equals(property)
&& oldValue == workingSet) {
setWorkingSet(null);
} else if (IWorkingSetManager.CHANGE_WORKING_SET_NAME_CHANGE
.equals(property)
&& newValue == workingSet) {
updateTitle();
} else if (IWorkingSetManager.CHANGE_WORKING_SET_CONTENT_CHANGE
.equals(property)
&& newValue == workingSet) {
if (workingSet.isAggregateWorkingSet() && workingSet.isEmpty()) {
// act as if the working set has been made null
if (!emptyWorkingSet) {
emptyWorkingSet = true;
workingSetFilter.setWorkingSet(null);
}
} else {
// we've gone from empty to non-empty on our set.
// Restore it.
if (emptyWorkingSet) {
emptyWorkingSet = false;
workingSetFilter.setWorkingSet(workingSet);
}
}
getViewer().refresh();
}
}
};
/**
* Constructs a new resource navigator view.
*/
public ResourceNavigator() {
IDialogSettings viewsSettings = getPlugin().getDialogSettings();
settings = viewsSettings.getSection(STORE_SECTION);
if (settings == null) {
settings = viewsSettings.addNewSection(STORE_SECTION);
migrateDialogSettings();
}
initLinkingEnabled();
}
/**
* Converts the given selection into a form usable by the viewer,
* where the elements are resources.
*/
private StructuredSelection convertSelection(ISelection selection) {
ArrayList list = new ArrayList();
if (selection instanceof IStructuredSelection) {
IStructuredSelection ssel = (IStructuredSelection) selection;
for (Iterator i = ssel.iterator(); i.hasNext();) {
Object o = i.next();
IResource resource = null;
if (o instanceof IResource) {
resource = (IResource) o;
} else {
if (o instanceof IAdaptable) {
resource = (IResource) ((IAdaptable) o)
.getAdapter(IResource.class);
}
}
if (resource != null) {
list.add(resource);
}
}
}
return new StructuredSelection(list);
}
/* (non-Javadoc)
* Method declared on IWorkbenchPart.
*/
public void createPartControl(Composite parent) {
TreeViewer viewer = createViewer(parent);
this.viewer = viewer;
if (memento != null) {
restoreFilters();
restoreLinkingEnabled();
}
frameList = createFrameList();
initDragAndDrop();
updateTitle();
initContextMenu();
initResourceSorter();
initWorkingSetFilter();
// make sure input is set after sorters and filters,
// to avoid unnecessary refreshes
viewer.setInput(getInitialInput());
// make actions after setting input, because some actions
// look at the viewer for enablement (e.g. the Up action)
makeActions();
// Fill the action bars and update the global action handlers'
// enabled state to match the current selection.
getActionGroup().fillActionBars(getViewSite().getActionBars());
updateActionBars((IStructuredSelection) viewer.getSelection());
getSite().setSelectionProvider(viewer);
getSite().getPage().addPartListener(partListener);
IWorkingSetManager workingSetManager = getPlugin().getWorkbench()
.getWorkingSetManager();
workingSetManager.addPropertyChangeListener(propertyChangeListener);
if (memento != null)
restoreState(memento);
memento = null;
// Set help for the view
getSite().getWorkbenchWindow().getWorkbench().getHelpSystem().setHelp(
viewer.getControl(), getHelpContextId());
}
/**
* Returns the help context id to use for this view.
*
* @since 2.0
*/
protected String getHelpContextId() {
return INavigatorHelpContextIds.RESOURCE_VIEW;
}
/**
* Initializes and registers the context menu.
*
* @since 2.0
*/
protected void initContextMenu() {
MenuManager menuMgr = new MenuManager("#PopupMenu"); //$NON-NLS-1$
menuMgr.setRemoveAllWhenShown(true);
menuMgr.addMenuListener(new IMenuListener() {
public void menuAboutToShow(IMenuManager manager) {
ResourceNavigator.this.fillContextMenu(manager);
}
});
TreeViewer viewer = getTreeViewer();
Menu menu = menuMgr.createContextMenu(viewer.getTree());
viewer.getTree().setMenu(menu);
getSite().registerContextMenu(menuMgr, viewer);
}
/**
* Creates the viewer.
*
* @param parent the parent composite
* @since 2.0
*/
protected TreeViewer createViewer(Composite parent) {
TreeViewer viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL
| SWT.V_SCROLL);
viewer.setUseHashlookup(true);
initContentProvider(viewer);
initLabelProvider(viewer);
initFilters(viewer);
initListeners(viewer);
return viewer;
}
/**
* Sets the content provider for the viewer.
*
* @param viewer the viewer
* @since 2.0
*/
protected void initContentProvider(TreeViewer viewer) {
viewer.setContentProvider(new WorkbenchContentProvider());
}
/**
* Sets the label provider for the viewer.
*
* @param viewer the viewer
* @since 2.0
*/
protected void initLabelProvider(TreeViewer viewer) {
viewer.setLabelProvider(new DecoratingLabelProvider(
new WorkbenchLabelProvider(), getPlugin().getWorkbench()
.getDecoratorManager().getLabelDecorator()));
}
/**
* Adds the filters to the viewer.
*
* @param viewer the viewer
* @since 2.0
*/
protected void initFilters(TreeViewer viewer) {
viewer.addFilter(patternFilter);
viewer.addFilter(workingSetFilter);
}
/**
* Initializes the linking enabled setting from the preference store.
*/
private void initLinkingEnabled() {
// Try the dialog settings first, which remember the last choice.
String setting = settings
.get(IWorkbenchPreferenceConstants.LINK_NAVIGATOR_TO_EDITOR);
if (setting != null) {
linkingEnabled = setting.equals("true"); //$NON-NLS-1$
return;
}
// If not in the dialog settings, check the preference store for the default setting.
// Use the UI plugin's preference store since this is a public preference.
AbstractUIPlugin uiPlugin = (AbstractUIPlugin) Platform
.getPlugin(PlatformUI.PLUGIN_ID);
linkingEnabled = uiPlugin.getPreferenceStore().getBoolean(
IWorkbenchPreferenceConstants.LINK_NAVIGATOR_TO_EDITOR);
}
/**
* Adds the listeners to the viewer.
*
* @param viewer the viewer
* @since 2.0
*/
protected void initListeners(TreeViewer viewer) {
viewer.addSelectionChangedListener(new ISelectionChangedListener() {
public void selectionChanged(SelectionChangedEvent event) {
handleSelectionChanged(event);
}
});
viewer.addDoubleClickListener(new IDoubleClickListener() {
public void doubleClick(DoubleClickEvent event) {
handleDoubleClick(event);
}
});
viewer.addOpenListener(new IOpenListener() {
public void open(OpenEvent event) {
handleOpen(event);
}
});
viewer.getControl().addKeyListener(new KeyListener() {
public void keyPressed(KeyEvent event) {
handleKeyPressed(event);
}
public void keyReleased(KeyEvent event) {
handleKeyReleased(event);
}
});
}
/* (non-Javadoc)
* Method declared on IWorkbenchPart.
*/
public void dispose() {
getSite().getPage().removePartListener(partListener);
IWorkingSetManager workingSetManager = getPlugin().getWorkbench()
.getWorkingSetManager();
workingSetManager.removePropertyChangeListener(propertyChangeListener);
if (getActionGroup() != null) {
getActionGroup().dispose();
}
Control control = viewer.getControl();
if (dragDetectListener != null && control != null
&& control.isDisposed() == false) {
control.removeListener(SWT.DragDetect, dragDetectListener);
}
super.dispose();
}
/**
* An editor has been activated. Sets the selection in this navigator
* to be the editor's input, if linking is enabled.
*
* @param editor the active editor
* @since 2.0
*/
protected void editorActivated(IEditorPart editor) {
if (!isLinkingEnabled()) {
return;
}
IFile file = ResourceUtil.getFile(editor.getEditorInput());
if (file != null) {
ISelection newSelection = new StructuredSelection(file);
if (getTreeViewer().getSelection().equals(newSelection)) {
getTreeViewer().getTree().showSelection();
} else {
getTreeViewer().setSelection(newSelection, true);
}
}
}
/**
* Called when the context menu is about to open.
* Delegates to the action group using the viewer's selection as the action context.
* @since 2.0
*/
protected void fillContextMenu(IMenuManager menu) {
IStructuredSelection selection = (IStructuredSelection) getViewer()
.getSelection();
getActionGroup().setContext(new ActionContext(selection));
getActionGroup().fillContextMenu(menu);
}
/*
* @see IResourceNavigatorPart
* @since 2.0
*/
public FrameList getFrameList() {
return frameList;
}
/**
* Returns the initial input for the viewer.
* Tries to convert the page input to a resource, either directly or via IAdaptable.
* If the resource is a container, it uses that.
* If the resource is a file, it uses its parent folder.
* If a resource could not be obtained, it uses the workspace root.
*
* @since 2.0
*/
protected IAdaptable getInitialInput() {
IAdaptable input = getSite().getPage().getInput();
if (input != null) {
IResource resource = null;
if (input instanceof IResource) {
resource = (IResource) input;
} else {
resource = (IResource) input.getAdapter(IResource.class);
}
if (resource != null) {
switch (resource.getType()) {
case IResource.FILE:
return resource.getParent();
case IResource.FOLDER:
case IResource.PROJECT:
case IResource.ROOT:
return (IContainer) resource;
default:
// Unknown resource type. Fall through.
break;
}
}
}
return ResourcesPlugin.getWorkspace().getRoot();
}
/**
* Returns the pattern filter for this view.
*
* @return the pattern filter
* @since 2.0
*/
public ResourcePatternFilter getPatternFilter() {
return this.patternFilter;
}
/**
* Returns the working set for this view.
*
* @return the working set
* @since 2.0
*/
public IWorkingSet getWorkingSet() {
return workingSetFilter.getWorkingSet();
}
/**
* Returns the navigator's plugin.
*/
public AbstractUIPlugin getPlugin() {
return IDEWorkbenchPlugin.getDefault();
}
/**
* Returns the sorter.
* @since 2.0
*/
public ResourceSorter getSorter() {
return (ResourceSorter) getTreeViewer().getSorter();
}
/**
* Returns the resource viewer which shows the resource hierarchy.
* @since 2.0
*/
public TreeViewer getViewer() {
return viewer;
}
/**
* Returns the tree viewer which shows the resource hierarchy.
* @return the tree viewer
* @since 2.0
*/
public TreeViewer getTreeViewer() {
return viewer;
}
/**
* Returns the shell to use for opening dialogs.
* Used in this class, and in the actions.
*
* @return the shell
* @deprecated use getViewSite().getShell()
*/
public Shell getShell() {
return getViewSite().getShell();
}
/**
* Returns the message to show in the status line.
*
* @param selection the current selection
* @return the status line message
* @since 2.0
*/
protected String getStatusLineMessage(IStructuredSelection selection) {
if (selection.size() == 1) {
Object o = selection.getFirstElement();
if (o instanceof IResource) {
return ((IResource) o).getFullPath().makeRelative().toString();
} else {
return ResourceNavigatorMessages.ResourceNavigator_oneItemSelected;
}
}
if (selection.size() > 1) {
return NLS.bind(ResourceNavigatorMessages.ResourceNavigator_statusLine, String.valueOf(selection.size()));
}
return ""; //$NON-NLS-1$
}
/**
* Returns the name for the given element.
* Used as the name for the current frame.
*/
String getFrameName(Object element) {
if (element instanceof IResource)
return ((IResource) element).getName();
String text = ((ILabelProvider) getTreeViewer().getLabelProvider())
.getText(element);
if(text == null)
return "";//$NON-NLS-1$
return text;
}
/**
* Returns the tool tip text for the given element.
* Used as the tool tip text for the current frame, and for the view title tooltip.
*/
String getFrameToolTipText(Object element) {
if (element instanceof IResource) {
IPath path = ((IResource) element).getFullPath();
if (path.isRoot())
return ResourceNavigatorMessages.ResourceManager_toolTip;
return path.makeRelative().toString();
}
String text = ((ILabelProvider) getTreeViewer().getLabelProvider())
.getText(element);
if(text == null)
return "";//$NON-NLS-1$
return text;
}
/**
* Handles an open event from the viewer.
* Opens an editor on the selected file.
*
* @param event the open event
* @since 2.0
*/
protected void handleOpen(OpenEvent event) {
IStructuredSelection selection = (IStructuredSelection) event
.getSelection();
getActionGroup().runDefaultAction(selection);
}
/**
* Handles a double-click event from the viewer.
* Expands or collapses a folder when double-clicked.
*
* @param event the double-click event
* @since 2.0
*/
protected void handleDoubleClick(DoubleClickEvent event) {
IStructuredSelection selection = (IStructuredSelection) event
.getSelection();
Object element = selection.getFirstElement();
// 1GBZIA0: ITPUI:WIN2000 - Double-clicking in navigator should expand/collapse containers
TreeViewer viewer = getTreeViewer();
if (viewer.isExpandable(element)) {
viewer.setExpandedState(element, !viewer.getExpandedState(element));
}
}
/**
* Handles a selection changed event from the viewer.
* Updates the status line and the action bars, and links to editor (if option enabled).
*
* @param event the selection event
* @since 2.0
*/
protected void handleSelectionChanged(SelectionChangedEvent event) {
final IStructuredSelection sel = (IStructuredSelection) event
.getSelection();
updateStatusLine(sel);
updateActionBars(sel);
dragDetected = false;
if (isLinkingEnabled() && !linkScheduled) {
// Ensure that if another selection change arrives while we're waiting for the *syncExec,
// we only do this work once.
linkScheduled = true;
getShell().getDisplay().asyncExec(new Runnable() {
public void run() {
// There's no telling what might have changed since the syncExec was scheduled.
// Check to make sure that the widgets haven't been disposed.
linkScheduled = false;
if (viewer == null || viewer.getControl() == null || viewer.getControl().isDisposed()) {
return;
}
if (dragDetected == false) {
ISelection sel = viewer.getSelection();
if (sel instanceof IStructuredSelection) {
IStructuredSelection selection = (IStructuredSelection)sel;
// only synchronize with editor when the selection is not the result
// of a drag. Fixes bug 22274.
linkToEditor(selection);
}
}
}
});
}
}
/**
* Handles a key press event from the viewer.
* Delegates to the action group.
*
* @param event the key event
* @since 2.0
*/
protected void handleKeyPressed(KeyEvent event) {
getActionGroup().handleKeyPressed(event);
}
/**
* Handles a key release in the viewer. Does nothing by default.
*
* @param event the key event
* @since 2.0
*/
protected void handleKeyReleased(KeyEvent event) {
}
/* (non-Javadoc)
* Method declared on IViewPart.
*/
public void init(IViewSite site, IMemento memento) throws PartInitException {
super.init(site, memento);
this.memento = memento;
}
/**
* Adds drag and drop support to the navigator.
*
* @since 2.0
*/
protected void initDragAndDrop() {
int ops = DND.DROP_COPY | DND.DROP_MOVE;
Transfer[] transfers = new Transfer[] {
LocalSelectionTransfer.getInstance(),
ResourceTransfer.getInstance(), FileTransfer.getInstance(),
PluginTransfer.getInstance() };
TreeViewer viewer = getTreeViewer();
viewer.addDragSupport(ops, transfers, new NavigatorDragAdapter(viewer));
NavigatorDropAdapter adapter = new NavigatorDropAdapter(viewer);
adapter.setFeedbackEnabled(false);
viewer.addDropSupport(ops | DND.DROP_DEFAULT, transfers, adapter);
dragDetectListener = new Listener() {
public void handleEvent(Event event) {
dragDetected = true;
}
};
viewer.getControl().addListener(SWT.DragDetect, dragDetectListener);
}
/**
* Creates the frame source and frame list, and connects them.
*
* @since 2.0
*/
protected FrameList createFrameList() {
NavigatorFrameSource frameSource = new NavigatorFrameSource(this);
FrameList frameList = new FrameList(frameSource);
frameSource.connectTo(frameList);
return frameList;
}
/**
* Initializes the sorter.
*/
protected void initResourceSorter() {
int sortType = ResourceSorter.NAME;
try {
int sortInt = 0;
if (memento != null) {
String sortStr = memento.getString(TAG_SORTER);
if (sortStr != null)
sortInt = new Integer(sortStr).intValue();
} else {
sortInt = settings.getInt(STORE_SORT_TYPE);
}
if (sortInt == ResourceSorter.NAME
|| sortInt == ResourceSorter.TYPE)
sortType = sortInt;
} catch (NumberFormatException e) {
}
setSorter(new ResourceSorter(sortType));
}
/**
* Restores the working set filter from the persistence store.
*/
void initWorkingSetFilter() {
String workingSetName = settings.get(STORE_WORKING_SET);
IWorkingSet workingSet = null;
if (workingSetName != null && workingSetName.equals("") == false) { //$NON-NLS-1$
IWorkingSetManager workingSetManager = getPlugin().getWorkbench()
.getWorkingSetManager();
workingSet = workingSetManager.getWorkingSet(workingSetName);
} else if (PlatformUI
.getPreferenceStore()
.getBoolean(
IWorkbenchPreferenceConstants.USE_WINDOW_WORKING_SET_BY_DEFAULT)) {
// use the window set by default if the global preference is set
workingSet = getSite().getPage().getAggregateWorkingSet();
}
if (workingSet != null) {
// Only initialize filter. Don't set working set into viewer.
// Working set is set via WorkingSetFilterActionGroup
// during action creation.
workingSetFilter.setWorkingSet(workingSet);
internalSetWorkingSet(workingSet);
}
}
/**
* Returns whether the navigator selection automatically tracks the active
* editor.
*
* @return <code>true</code> if linking is enabled, <code>false</code>
* if not
* @since 2.0 (this was protected in 2.0, but was made public in 2.1)
*/
public boolean isLinkingEnabled() {
return linkingEnabled;
}
/**
* Brings the corresponding editor to top if the selected resource is open.
*
* @since 2.0
*/
protected void linkToEditor(IStructuredSelection selection) {
Object obj = selection.getFirstElement();
if (obj instanceof IFile && selection.size() == 1) {
IFile file = (IFile) obj;
IWorkbenchPage page = getSite().getPage();
IEditorPart editor = ResourceUtil.findEditor(page, file);
if (editor != null) {
page.bringToTop(editor);
return;
}
}
}
/**
* Creates the action group, which encapsulates all actions for the view.
*/
protected void makeActions() {
setActionGroup(new MainActionGroup(this));
}
/**
* Migrates the dialog settings from the UI plugin store to the
* Views plugin store.
*/
private void migrateDialogSettings() {
AbstractUIPlugin uiPlugin = (AbstractUIPlugin) Platform
.getPlugin(PlatformUI.PLUGIN_ID);
IDialogSettings uiSettings = uiPlugin.getDialogSettings();
uiSettings = uiSettings.getSection(STORE_SECTION);
if (uiSettings != null) {
String workingSetName = uiSettings.get(STORE_WORKING_SET);
if (workingSetName != null && workingSetName.length() > 0) {
settings.put(STORE_WORKING_SET, workingSetName);
uiSettings.put(STORE_WORKING_SET, ""); //$NON-NLS-1$
}
String sortType = uiSettings.get(STORE_SORT_TYPE);
if (sortType != null && sortType.length() > 0) {
settings.put(STORE_SORT_TYPE, sortType);
uiSettings.put(STORE_SORT_TYPE, ""); //$NON-NLS-1$
}
}
}
/**
* Restores the saved filter settings.
*/
private void restoreFilters() {
IMemento filtersMem = memento.getChild(TAG_FILTERS);
if (filtersMem != null) { //filters have been defined
IMemento children[] = filtersMem.getChildren(TAG_FILTER);
// check if first element has new tag defined, indicates new version
if (children.length > 0
&& children[0].getString(TAG_IS_ENABLED) != null) {
ArrayList selectedFilters = new ArrayList();
ArrayList unSelectedFilters = new ArrayList();
for (int i = 0; i < children.length; i++) {
if (children[i].getString(TAG_IS_ENABLED).equals(
String.valueOf(true)))
selectedFilters.add(children[i].getString(TAG_ELEMENT));
else
//enabled == false
unSelectedFilters.add(children[i]
.getString(TAG_ELEMENT));
}
/* merge filters from Memento with selected = true filters from plugins
* ensure there are no duplicates & don't override user preferences */
List pluginFilters = FiltersContentProvider.getDefaultFilters();
for (Iterator iter = pluginFilters.iterator(); iter.hasNext();) {
String element = (String) iter.next();
if (!selectedFilters.contains(element)
&& !unSelectedFilters.contains(element))
selectedFilters.add(element);
}
//Convert to an array of Strings
String[] patternArray = new String[selectedFilters.size()];
selectedFilters.toArray(patternArray);
getPatternFilter().setPatterns(patternArray);
} else { //filters defined, old version: ignore filters from plugins
String filters[] = new String[children.length];
for (int i = 0; i < children.length; i++) {
filters[i] = children[i].getString(TAG_ELEMENT);
}
getPatternFilter().setPatterns(filters);
}
} else { //no filters defined, old version: ignore filters from plugins
getPatternFilter().setPatterns(new String[0]);
}
}
/**
* Restores the state of the receiver to the state described in the specified memento.
*
* @param memento the memento
* @since 2.0
*/
protected void restoreState(IMemento memento) {
TreeViewer viewer = getTreeViewer();
IMemento frameMemento = memento.getChild(TAG_CURRENT_FRAME);
if (frameMemento != null) {
TreeFrame frame = new TreeFrame(viewer);
frame.restoreState(frameMemento);
frame.setName(getFrameName(frame.getInput()));
frame.setToolTipText(getFrameToolTipText(frame.getInput()));
viewer.setSelection(new StructuredSelection(frame.getInput()));
frameList.gotoFrame(frame);
} else {
IContainer container = ResourcesPlugin.getWorkspace().getRoot();
IMemento childMem = memento.getChild(TAG_EXPANDED);
if (childMem != null) {
ArrayList elements = new ArrayList();
IMemento[] elementMem = childMem.getChildren(TAG_ELEMENT);
for (int i = 0; i < elementMem.length; i++) {
Object element = container.findMember(elementMem[i]
.getString(TAG_PATH));
if (element != null) {
elements.add(element);
}
}
viewer.setExpandedElements(elements.toArray());
}
childMem = memento.getChild(TAG_SELECTION);
if (childMem != null) {
ArrayList list = new ArrayList();
IMemento[] elementMem = childMem.getChildren(TAG_ELEMENT);
for (int i = 0; i < elementMem.length; i++) {
Object element = container.findMember(elementMem[i]
.getString(TAG_PATH));
if (element != null) {
list.add(element);
}
}
viewer.setSelection(new StructuredSelection(list));
}
}
}
/**
* Restores the linking enabled state.
*/
private void restoreLinkingEnabled() {
Integer val = memento
.getInteger(IWorkbenchPreferenceConstants.LINK_NAVIGATOR_TO_EDITOR);
if (val != null) {
linkingEnabled = val.intValue() != 0;
}
}
/**
* @see ViewPart#saveState
*/
public void saveState(IMemento memento) {
TreeViewer viewer = getTreeViewer();
if (viewer == null) {
if (this.memento != null) //Keep the old state;
memento.putMemento(this.memento);
return;
}
//save sorter
memento.putInteger(TAG_SORTER, getSorter().getCriteria());
//save filters
String filters[] = getPatternFilter().getPatterns();
List selectedFilters = Arrays.asList(filters);
List allFilters = FiltersContentProvider.getDefinedFilters();
IMemento filtersMem = memento.createChild(TAG_FILTERS);
for (Iterator iter = allFilters.iterator(); iter.hasNext();) {
String element = (String) iter.next();
IMemento child = filtersMem.createChild(TAG_FILTER);
child.putString(TAG_ELEMENT, element);
child.putString(TAG_IS_ENABLED, String.valueOf(selectedFilters
.contains(element)));
}
if (frameList.getCurrentIndex() > 0) {
//save frame, it's not the "home"/workspace frame
TreeFrame currentFrame = (TreeFrame) frameList.getCurrentFrame();
IMemento frameMemento = memento.createChild(TAG_CURRENT_FRAME);
currentFrame.saveState(frameMemento);
} else {
//save visible expanded elements
Object expandedElements[] = viewer.getVisibleExpandedElements();
if (expandedElements.length > 0) {
IMemento expandedMem = memento.createChild(TAG_EXPANDED);
for (int i = 0; i < expandedElements.length; i++) {
if (expandedElements[i] instanceof IResource) {
IMemento elementMem = expandedMem
.createChild(TAG_ELEMENT);
elementMem.putString(TAG_PATH,
((IResource) expandedElements[i]).getFullPath()
.toString());
}
}
}
//save selection
Object elements[] = ((IStructuredSelection) viewer.getSelection())
.toArray();
if (elements.length > 0) {
IMemento selectionMem = memento.createChild(TAG_SELECTION);
for (int i = 0; i < elements.length; i++) {
if (elements[i] instanceof IResource) {
IMemento elementMem = selectionMem
.createChild(TAG_ELEMENT);
elementMem.putString(TAG_PATH,
((IResource) elements[i]).getFullPath()
.toString());
}
}
}
}
saveLinkingEnabled(memento);
}
/**
* Saves the linking enabled state.
*/
private void saveLinkingEnabled(IMemento memento) {
memento.putInteger(
IWorkbenchPreferenceConstants.LINK_NAVIGATOR_TO_EDITOR,
linkingEnabled ? 1 : 0);
}
/**
* Selects and reveals the specified elements.
*/
public void selectReveal(ISelection selection) {
StructuredSelection ssel = convertSelection(selection);
if (!ssel.isEmpty()) {
getViewer().getControl().setRedraw(false);
getViewer().setSelection(ssel, true);
getViewer().getControl().setRedraw(true);
}
}
/**
* Saves the filters defined as strings in <code>patterns</code>
* in the preference store.
*/
public void setFiltersPreference(String[] patterns) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < patterns.length; i++) {
if (i != 0)
sb.append(ResourcePatternFilter.COMMA_SEPARATOR);
sb.append(patterns[i]);
}
getPlugin().getPreferenceStore().setValue(
ResourcePatternFilter.FILTERS_TAG, sb.toString());
// remove value in old workbench preference store location
IPreferenceStore preferenceStore = IDEWorkbenchPlugin.getDefault()
.getPreferenceStore();
String storedPatterns = preferenceStore
.getString(ResourcePatternFilter.FILTERS_TAG);
if (storedPatterns.length() > 0)
preferenceStore.setValue(ResourcePatternFilter.FILTERS_TAG, ""); //$NON-NLS-1$
}
/**
* @see IWorkbenchPart#setFocus()
*/
public void setFocus() {
getTreeViewer().getTree().setFocus();
}
/**
* Note: For experimental use only.
* Sets the decorator for the navigator.
* <p>
* As of 2.0, this method no longer has any effect.
* </p>
*
* @param decorator a label decorator or <code>null</code> for no decorations.
* @deprecated use the decorators extension point instead; see IWorkbench.getDecoratorManager()
*/
public void setLabelDecorator(ILabelDecorator decorator) {
// do nothing
}
/**
* @see IResourceNavigator#setLinkingEnabled(boolean)
* @since 2.1
*/
public void setLinkingEnabled(boolean enabled) {
this.linkingEnabled = enabled;
// remember the last setting in the dialog settings
settings.put(IWorkbenchPreferenceConstants.LINK_NAVIGATOR_TO_EDITOR,
enabled);
// if turning linking on, update the selection to correspond to the active editor
if (enabled) {
IEditorPart editor = getSite().getPage().getActiveEditor();
if (editor != null) {
editorActivated(editor);
}
}
}
/**
* Sets the resource sorter.
*
* @param sorter the resource sorter
* @since 2.0
*/
public void setSorter(ResourceSorter sorter) {
TreeViewer viewer = getTreeViewer();
ViewerSorter viewerSorter = viewer.getSorter();
viewer.getControl().setRedraw(false);
if (viewerSorter == sorter) {
viewer.refresh();
} else {
viewer.setSorter(sorter);
}
viewer.getControl().setRedraw(true);
settings.put(STORE_SORT_TYPE, sorter.getCriteria());
// update the sort actions' checked state
updateActionBars((IStructuredSelection) viewer.getSelection());
}
/*
* @see org.eclipse.ui.views.navigator.IResourceNavigatorPart#setWorkingSet(IWorkingSet)
* @since 2.0
*/
public void setWorkingSet(IWorkingSet workingSet) {
TreeViewer treeViewer = getTreeViewer();
Object[] expanded = treeViewer.getExpandedElements();
ISelection selection = treeViewer.getSelection();
internalSetWorkingSet(workingSet);
workingSetFilter.setWorkingSet(emptyWorkingSet ? null : workingSet);
if (workingSet != null) {
settings.put(STORE_WORKING_SET, workingSet.getName());
} else {
settings.put(STORE_WORKING_SET, ""); //$NON-NLS-1$
}
updateTitle();
treeViewer.refresh();
treeViewer.setExpandedElements(expanded);
if (selection.isEmpty() == false
&& selection instanceof IStructuredSelection) {
IStructuredSelection structuredSelection = (IStructuredSelection) selection;
treeViewer.reveal(structuredSelection.getFirstElement());
}
}
/**
* Set the internal working set fields specific to the navigator.
*
* @param workingSet
* the new working set
* @since 3.2
*/
private void internalSetWorkingSet(IWorkingSet workingSet) {
this.workingSet = workingSet;
emptyWorkingSet = workingSet != null && workingSet.isAggregateWorkingSet()
&& workingSet.isEmpty();
}
/**
* Updates the action bar actions.
*
* @param selection the current selection
* @since 2.0
*/
protected void updateActionBars(IStructuredSelection selection) {
ResourceNavigatorActionGroup group = getActionGroup();
if (group != null) {
group.setContext(new ActionContext(selection));
group.updateActionBars();
}
}
/**
* Updates the message shown in the status line.
*
* @param selection the current selection
*/
protected void updateStatusLine(IStructuredSelection selection) {
String msg = getStatusLineMessage(selection);
getViewSite().getActionBars().getStatusLineManager().setMessage(msg);
}
/**
* Updates the title text and title tool tip.
* Called whenever the input of the viewer changes.
* Called whenever the input of the viewer changes.
*
* @since 2.0
*/
public void updateTitle() {
Object input = getViewer().getInput();
IWorkspace workspace = ResourcesPlugin.getWorkspace();
IWorkingSet workingSet = workingSetFilter.getWorkingSet();
if (input == null || input.equals(workspace)
|| input.equals(workspace.getRoot())) {
setContentDescription(""); //$NON-NLS-1$
if (workingSet != null) {
setTitleToolTip(NLS.bind(ResourceNavigatorMessages.ResourceNavigator_workingSetToolTip, workingSet.getLabel()));
} else {
setTitleToolTip(""); //$NON-NLS-1$
}
} else {
ILabelProvider labelProvider = (ILabelProvider) getTreeViewer()
.getLabelProvider();
String inputToolTip = getFrameToolTipText(input);
String text = labelProvider.getText(input);
if(text != null)
setContentDescription(text);
if (workingSet != null) {
setTitleToolTip(NLS.bind(ResourceNavigatorMessages.ResourceNavigator_workingSetInputToolTip, inputToolTip, workingSet.getLabel()));
} else {
setTitleToolTip(inputToolTip);
}
}
}
/**
* Returns the action group.
*
* @return the action group
*/
protected ResourceNavigatorActionGroup getActionGroup() {
return actionGroup;
}
/**
* Sets the action group.
*
* @param actionGroup the action group
*/
protected void setActionGroup(ResourceNavigatorActionGroup actionGroup) {
this.actionGroup = actionGroup;
}
/*
* @see IWorkbenchPart#getAdapter(Class)
*/
public Object getAdapter(Class adapter) {
if (adapter == IShowInSource.class) {
return getShowInSource();
}
if (adapter == IShowInTarget.class) {
return getShowInTarget();
}
return null;
}
/**
* Returns the <code>IShowInSource</code> for this view.
*/
protected IShowInSource getShowInSource() {
return new IShowInSource() {
public ShowInContext getShowInContext() {
return new ShowInContext(getViewer().getInput(), getViewer()
.getSelection());
}
};
}
/**
* Returns the <code>IShowInTarget</code> for this view.
*/
protected IShowInTarget getShowInTarget() {
return new IShowInTarget() {
public boolean show(ShowInContext context) {
ArrayList toSelect = new ArrayList();
ISelection sel = context.getSelection();
if (sel instanceof IStructuredSelection) {
IStructuredSelection ssel = (IStructuredSelection) sel;
for (Iterator i = ssel.iterator(); i.hasNext();) {
Object o = i.next();
if (o instanceof IResource) {
toSelect.add(o);
} else if (o instanceof IMarker) {
IResource r = ((IMarker) o).getResource();
if (r.getType() != IResource.ROOT) {
toSelect.add(r);
}
} else if (o instanceof IAdaptable) {
IAdaptable adaptable = (IAdaptable) o;
o = adaptable.getAdapter(IResource.class);
if (o instanceof IResource) {
toSelect.add(o);
} else {
o = adaptable.getAdapter(IMarker.class);
if (o instanceof IMarker) {
IResource r = ((IMarker) o).getResource();
if (r.getType() != IResource.ROOT) {
toSelect.add(r);
}
}
}
}
}
}
if (toSelect.isEmpty()) {
Object input = context.getInput();
if (input instanceof IAdaptable) {
IAdaptable adaptable = (IAdaptable) input;
Object o = adaptable.getAdapter(IResource.class);
if (o instanceof IResource) {
toSelect.add(o);
}
}
}
if (!toSelect.isEmpty()) {
selectReveal(new StructuredSelection(toSelect));
return true;
}
return false;
}
};
}
}