blob: 812f72893f70402e75656027caa8e3fe47ff3477 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2023 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.wst.jsdt.internal.ui.packageview;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Collections;
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.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.ISafeRunnable;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.PerformanceStats;
import org.eclipse.core.runtime.SafeRunner;
import org.eclipse.help.IContextProvider;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IStatusLineManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.LocalSelectionTransfer;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.util.TransferDragSourceListener;
import org.eclipse.jface.util.TransferDropTargetListener;
import org.eclipse.jface.viewers.AbstractTreeViewer;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IContentProvider;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.IElementComparer;
import org.eclipse.jface.viewers.ILabelDecorator;
import org.eclipse.jface.viewers.IOpenListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeSelection;
import org.eclipse.jface.viewers.ITreeViewerListener;
import org.eclipse.jface.viewers.OpenEvent;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeExpansionEvent;
import org.eclipse.jface.viewers.TreePath;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.ViewerFilter;
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.Item;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.swt.widgets.Widget;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorReference;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.IPageLayout;
import org.eclipse.ui.IPartListener2;
import org.eclipse.ui.IStorageEditorInput;
import org.eclipse.ui.IViewPart;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPartReference;
import org.eclipse.ui.IWorkbenchPartSite;
import org.eclipse.ui.IWorkingSet;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.WorkbenchException;
import org.eclipse.ui.XMLMemento;
import org.eclipse.ui.actions.ActionContext;
import org.eclipse.ui.part.ISetSelectionTarget;
import org.eclipse.ui.part.IShowInSource;
import org.eclipse.ui.part.IShowInTarget;
import org.eclipse.ui.part.IShowInTargetList;
import org.eclipse.ui.part.ResourceTransfer;
import org.eclipse.ui.part.ShowInContext;
import org.eclipse.ui.part.ViewPart;
import org.eclipse.ui.views.framelist.Frame;
import org.eclipse.ui.views.framelist.FrameAction;
import org.eclipse.ui.views.framelist.FrameList;
import org.eclipse.ui.views.framelist.IFrameSource;
import org.eclipse.ui.views.framelist.TreeFrame;
import org.eclipse.wst.jsdt.core.IClassFile;
import org.eclipse.wst.jsdt.core.IJarEntryResource;
import org.eclipse.wst.jsdt.core.IJavaScriptElement;
import org.eclipse.wst.jsdt.core.IJavaScriptModel;
import org.eclipse.wst.jsdt.core.IJavaScriptProject;
import org.eclipse.wst.jsdt.core.IJavaScriptUnit;
import org.eclipse.wst.jsdt.core.IPackageFragment;
import org.eclipse.wst.jsdt.core.IPackageFragmentRoot;
import org.eclipse.wst.jsdt.core.IType;
import org.eclipse.wst.jsdt.core.JavaScriptCore;
import org.eclipse.wst.jsdt.core.JavaScriptModelException;
import org.eclipse.wst.jsdt.internal.corext.util.Messages;
import org.eclipse.wst.jsdt.internal.ui.IJavaHelpContextIds;
import org.eclipse.wst.jsdt.internal.ui.IProductConstants;
import org.eclipse.wst.jsdt.internal.ui.JavaScriptPlugin;
import org.eclipse.wst.jsdt.internal.ui.ProductProperties;
import org.eclipse.wst.jsdt.internal.ui.dnd.DelegatingDropAdapter;
import org.eclipse.wst.jsdt.internal.ui.dnd.JdtViewerDragAdapter;
import org.eclipse.wst.jsdt.internal.ui.dnd.ResourceTransferDragAdapter;
import org.eclipse.wst.jsdt.internal.ui.javaeditor.EditorUtility;
import org.eclipse.wst.jsdt.internal.ui.preferences.MembersOrderPreferenceCache;
import org.eclipse.wst.jsdt.internal.ui.util.JavaUIHelp;
import org.eclipse.wst.jsdt.internal.ui.viewsupport.AppearanceAwareLabelProvider;
import org.eclipse.wst.jsdt.internal.ui.viewsupport.ColoredViewersManager;
import org.eclipse.wst.jsdt.internal.ui.viewsupport.DecoratingJavaLabelProvider;
import org.eclipse.wst.jsdt.internal.ui.viewsupport.FilterUpdater;
import org.eclipse.wst.jsdt.internal.ui.viewsupport.IViewPartInputProvider;
import org.eclipse.wst.jsdt.internal.ui.viewsupport.ProblemTreeViewer;
import org.eclipse.wst.jsdt.internal.ui.viewsupport.StatusBarUpdater;
import org.eclipse.wst.jsdt.internal.ui.workingsets.ConfigureWorkingSetAction;
import org.eclipse.wst.jsdt.internal.ui.workingsets.ViewActionGroup;
import org.eclipse.wst.jsdt.internal.ui.workingsets.WorkingSetFilterActionGroup;
import org.eclipse.wst.jsdt.internal.ui.workingsets.WorkingSetModel;
import org.eclipse.wst.jsdt.ui.IPackagesViewPart;
import org.eclipse.wst.jsdt.ui.JavaScriptElementComparator;
import org.eclipse.wst.jsdt.ui.JavaScriptElementLabels;
import org.eclipse.wst.jsdt.ui.JavaScriptUI;
import org.eclipse.wst.jsdt.ui.PreferenceConstants;
import org.eclipse.wst.jsdt.ui.StandardJavaScriptElementContentProvider;
import org.eclipse.wst.jsdt.ui.actions.CustomFiltersActionGroup;
/**
* The ViewPart for the ProjectExplorer. It listens to part activation events.
* When selection linking with the editor is enabled the view selection tracks
* the active editor page. Similarly when a resource is selected in the packages
* view the corresponding editor is activated.
*/
public class PackageExplorerPart extends ViewPart
implements ISetSelectionTarget, IMenuListener,
IShowInTarget,
IPackagesViewPart, IPropertyChangeListener,
IViewPartInputProvider {
private static final String PERF_CREATE_PART_CONTROL= "org.eclipse.wst.jsdt.ui/perf/explorer/createPartControl"; //$NON-NLS-1$
private static final String PERF_MAKE_ACTIONS= "org.eclipse.wst.jsdt.ui/perf/explorer/makeActions"; //$NON-NLS-1$
private static final int HIERARCHICAL_LAYOUT= 0x1;
private static final int FLAT_LAYOUT= 0x2;
private final static String VIEW_ID= JavaScriptUI.ID_PACKAGES;
// Persistence tags.
private static final String TAG_LAYOUT= "layout"; //$NON-NLS-1$
private static final String TAG_GROUP_LIBRARIES= "group_libraries"; //$NON-NLS-1$
private static final String TAG_ROOT_MODE= "rootMode"; //$NON-NLS-1$
private static final String TAG_LINK_EDITOR= "linkWithEditor"; //$NON-NLS-1$
private static final String TAG_MEMENTO= "memento"; //$NON-NLS-1$
private boolean fIsCurrentLayoutFlat = false; // true means flat, false means hierarchical
private boolean fShowLibrariesNode;
private boolean fLinkingEnabled;
private int fRootMode;
private WorkingSetModel fWorkingSetModel;
private PackageExplorerLabelProvider fLabelProvider;
private DecoratingJavaLabelProvider fDecoratingLabelProvider;
private PackageExplorerContentProvider fContentProvider;
private FilterUpdater fFilterUpdater;
private PackageExplorerActionGroup fActionSet;
private ProblemTreeViewer fViewer;
private Menu fContextMenu;
private IMemento fMemento;
private ISelection fLastOpenSelection;
private final ISelectionChangedListener fPostSelectionListener;
private String fWorkingSetLabel;
private IDialogSettings fDialogSettings;
private IPartListener2 fLinkWithEditorListener= new IPartListener2() {
public void partVisible(IWorkbenchPartReference partRef) {}
public void partBroughtToTop(IWorkbenchPartReference partRef) {}
public void partClosed(IWorkbenchPartReference partRef) {}
public void partDeactivated(IWorkbenchPartReference partRef) {}
public void partHidden(IWorkbenchPartReference partRef) {}
public void partOpened(IWorkbenchPartReference partRef) {}
public void partInputChanged(IWorkbenchPartReference partRef) {
if (partRef instanceof IEditorReference) {
editorActivated(((IEditorReference) partRef).getEditor(true));
}
}
public void partActivated(IWorkbenchPartReference partRef) {
if (partRef instanceof IEditorReference) {
editorActivated(((IEditorReference) partRef).getEditor(true));
}
}
};
private ITreeViewerListener fExpansionListener= new ITreeViewerListener() {
public void treeCollapsed(TreeExpansionEvent event) {
}
public void treeExpanded(TreeExpansionEvent event) {
Object element= event.getElement();
if (element instanceof IJavaScriptUnit ||
element instanceof IClassFile)
expandMainType(element);
}
};
private class PackageExplorerProblemTreeViewer extends ProblemTreeViewer {
// fix for 64372 Projects showing up in Package Explorer twice [package explorer]
private List fPendingRefreshes;
public PackageExplorerProblemTreeViewer(Composite parent, int style) {
super(parent, style);
fPendingRefreshes= Collections.synchronizedList(new ArrayList());
ColoredViewersManager.install(this);
}
public void add(Object parentElement, Object[] childElements) {
if (fPendingRefreshes.contains(parentElement)) {
return;
}
super.add(parentElement, childElements);
}
/* (non-Javadoc)
* @see org.eclipse.jface.viewers.AbstractTreeViewer#internalRefresh(java.lang.Object, boolean)
*/
protected void internalRefresh(Object element, boolean updateLabels) {
try {
fPendingRefreshes.add(element);
super.internalRefresh(element, updateLabels);
} finally {
fPendingRefreshes.remove(element);
}
}
protected boolean evaluateExpandableWithFilters(Object parent) {
if (parent instanceof IJavaScriptProject
|| parent instanceof IJavaScriptUnit || parent instanceof IClassFile
|| parent instanceof JsGlobalScopeContainer) {
return false;
}
if (parent instanceof IPackageFragmentRoot && ((IPackageFragmentRoot) parent).isArchive()) {
return false;
}
return true;
}
protected boolean isFiltered(Object object, Object parent, ViewerFilter[] filters) {
if (object instanceof PackageFragmentRootContainer) {
return !hasFilteredChildren(object);
}
boolean res= super.isFiltered(object, parent, filters);
if (res && isEssential(object)) {
return false;
}
return res;
}
/* Checks if a filtered object in essential (i.e. is a parent that
* should not be removed).
*/
private boolean isEssential(Object object) {
try {
if (!isFlatLayout() && object instanceof IPackageFragment) {
IPackageFragment fragment = (IPackageFragment) object;
if (!fragment.isDefaultPackage() && fragment.hasSubpackages()) {
return hasFilteredChildren(fragment);
}
}
} catch (JavaScriptModelException e) {
JavaScriptPlugin.log(e);
}
return false;
}
protected void handleInvalidSelection(ISelection invalidSelection, ISelection newSelection) {
IStructuredSelection is= (IStructuredSelection)invalidSelection;
List ns= null;
if (newSelection instanceof IStructuredSelection) {
ns= new ArrayList(((IStructuredSelection)newSelection).toList());
} else {
ns= new ArrayList();
}
boolean changed= false;
for (Iterator iter= is.iterator(); iter.hasNext();) {
Object element= iter.next();
if (element instanceof IJavaScriptProject) {
IProject project= ((IJavaScriptProject)element).getProject();
if (!project.isOpen() && project.exists()) {
ns.add(project);
changed= true;
}
} else if (element instanceof IProject) {
IProject project= (IProject)element;
if (project.isOpen()) {
IJavaScriptProject jProject= JavaScriptCore.create(project);
if (jProject != null && jProject.exists())
ns.add(jProject);
changed= true;
}
}
}
if (changed) {
newSelection= new StructuredSelection(ns);
setSelection(newSelection);
}
super.handleInvalidSelection(invalidSelection, newSelection);
}
/**
* {@inheritDoc}
*/
protected Object[] addAditionalProblemParents(Object[] elements) {
if (showWorkingSets() && elements != null) {
return fWorkingSetModel.addWorkingSets(elements);
}
return elements;
}
//---- special handling to preserve the selection correctly
private boolean fInPreserveSelection;
protected void preservingSelection(Runnable updateCode) {
try {
fInPreserveSelection= true;
super.preservingSelection(updateCode);
} finally {
fInPreserveSelection= false;
}
}
protected void setSelectionToWidget(ISelection selection, boolean reveal) {
if (true) {
super.setSelectionToWidget(selection, reveal);
return;
}
if (!fInPreserveSelection || !(selection instanceof ITreeSelection)) {
super.setSelectionToWidget(selection, reveal);
return;
}
IContentProvider cp= getContentProvider();
if (!(cp instanceof IMultiElementTreeContentProvider)) {
super.setSelectionToWidget(selection, reveal);
return;
}
IMultiElementTreeContentProvider contentProvider= (IMultiElementTreeContentProvider)cp;
ITreeSelection toRestore= (ITreeSelection)selection;
List pathsToSelect= new ArrayList();
for (Iterator iter= toRestore.iterator(); iter.hasNext();) {
Object element= iter.next();
TreePath[] pathsToRestore= toRestore.getPathsFor(element);
CustomHashtable currentParents= createRootAccessedMap(contentProvider.getTreePaths(element));
for (int i= 0; i < pathsToRestore.length; i++) {
TreePath path= pathsToRestore[i];
Object root= path.getFirstSegment();
if (root != null && path.equals((TreePath)currentParents.get(root), getComparer())) {
pathsToSelect.add(path);
}
}
}
List toSelect= new ArrayList();
for (Iterator iter= pathsToSelect.iterator(); iter.hasNext();) {
TreePath path= (TreePath)iter.next();
int size= path.getSegmentCount();
if (size == 0)
continue;
Widget current= getTree();
int last= size - 1;
Object segment;
for (int i= 0; i < size && current != null && (segment= path.getSegment(i)) != null; i++) {
internalExpandToLevel(current, 1);
current= internalFindChild(current, segment);
if (i == last && current != null)
toSelect.add(current);
}
}
getTree().setSelection((TreeItem[])toSelect.toArray(new TreeItem[toSelect.size()]));
}
private Widget internalFindChild(Widget parent, Object element) {
Item[] items = getChildren(parent);
for (int i = 0; i < items.length; i++) {
Item item = items[i];
Object data = item.getData();
if (data != null && equals(data, element))
return item;
}
return null;
}
private CustomHashtable createRootAccessedMap(TreePath[] paths) {
CustomHashtable result= new CustomHashtable(getComparer());
for (int i= 0; i < paths.length; i++) {
TreePath path= paths[i];
Object root= path.getFirstSegment();
if (root != null) {
result.put(root, path);
}
}
return result;
}
}
public PackageExplorerPart() {
fPostSelectionListener= new ISelectionChangedListener() {
public void selectionChanged(SelectionChangedEvent event) {
handlePostSelectionChanged(event);
}
};
// exception: initialize from preference
fDialogSettings= JavaScriptPlugin.getDefault().getDialogSettingsSection(getClass().getName());
// on by default
fShowLibrariesNode= fDialogSettings.get(TAG_GROUP_LIBRARIES) == null || fDialogSettings.getBoolean(TAG_GROUP_LIBRARIES);
fLinkingEnabled= fDialogSettings.getBoolean(TAG_LINK_EDITOR);
try {
fIsCurrentLayoutFlat= fDialogSettings.getInt(TAG_LAYOUT) == FLAT_LAYOUT;
} catch (NumberFormatException e) {
fIsCurrentLayoutFlat= false;
}
try {
fRootMode= fDialogSettings.getInt(TAG_ROOT_MODE);
} catch (NumberFormatException e) {
fRootMode= ViewActionGroup.SHOW_PROJECTS;
}
}
public void init(IViewSite site, IMemento memento) throws PartInitException {
super.init(site, memento);
if (memento == null) {
String persistedMemento= fDialogSettings.get(TAG_MEMENTO);
if (persistedMemento != null) {
try {
memento= XMLMemento.createReadRoot(new StringReader(persistedMemento));
} catch (WorkbenchException e) {
// don't do anything. Simply don't restore the settings
}
}
}
fMemento= memento;
if (memento != null) {
restoreLayoutState(memento);
restoreLinkingEnabled(memento);
restoreRootMode(memento);
}
if (showWorkingSets()) {
createWorkingSetModel();
}
}
private void restoreRootMode(IMemento memento) {
Integer value= memento.getInteger(TAG_ROOT_MODE);
fRootMode= value == null ? ViewActionGroup.SHOW_PROJECTS : value.intValue();
if (fRootMode != ViewActionGroup.SHOW_PROJECTS && fRootMode != ViewActionGroup.SHOW_WORKING_SETS)
fRootMode= ViewActionGroup.SHOW_PROJECTS;
}
private void restoreLayoutState(IMemento memento) {
Integer layoutState= memento.getInteger(TAG_LAYOUT);
fIsCurrentLayoutFlat= layoutState == null || layoutState.intValue() == FLAT_LAYOUT;
// on by default
Integer groupLibraries= memento.getInteger(TAG_GROUP_LIBRARIES);
fShowLibrariesNode= groupLibraries == null || groupLibraries.intValue() != 0;
}
/**
* Returns the package explorer part of the active perspective. If
* there isn't any package explorer part <code>null</code> is returned.
* @return the package explorer from the active perspective
*/
public static PackageExplorerPart getFromActivePerspective() {
IWorkbenchPage activePage= JavaScriptPlugin.getActivePage();
if (activePage == null)
return null;
IViewPart view= activePage.findView(VIEW_ID);
if (view instanceof PackageExplorerPart)
return (PackageExplorerPart)view;
return null;
}
/**
* Makes the package explorer part visible in the active perspective. If there
* isn't a package explorer part registered <code>null</code> is returned.
* Otherwise the opened view part is returned.
* @return the opened package explorer
*/
public static PackageExplorerPart openInActivePerspective() {
try {
return (PackageExplorerPart)JavaScriptPlugin.getActivePage().showView(VIEW_ID);
} catch(PartInitException pe) {
return null;
}
}
public void dispose() {
XMLMemento memento= XMLMemento.createWriteRoot("packageExplorer"); //$NON-NLS-1$
saveState(memento);
StringWriter writer= new StringWriter();
try {
memento.save(writer);
fDialogSettings.put(TAG_MEMENTO, writer.getBuffer().toString());
} catch (IOException e) {
// don't do anything. Simply don't store the settings
}
if (fContextMenu != null && !fContextMenu.isDisposed())
fContextMenu.dispose();
getSite().getPage().removePartListener(fLinkWithEditorListener); // always remove even if we didn't register
JavaScriptPlugin.getDefault().getPreferenceStore().removePropertyChangeListener(this);
if (fViewer != null) {
fViewer.removeTreeListener(fExpansionListener);
}
if (fActionSet != null)
fActionSet.dispose();
if (fFilterUpdater != null)
ResourcesPlugin.getWorkspace().removeResourceChangeListener(fFilterUpdater);
if (fWorkingSetModel != null)
fWorkingSetModel.dispose();
super.dispose();
}
/* (non-Javadoc)
* @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite)
*/
public void createPartControl(Composite parent) {
final PerformanceStats stats= PerformanceStats.getStats(PERF_CREATE_PART_CONTROL, this);
stats.startRun();
fViewer= createViewer(parent);
fViewer.setUseHashlookup(true);
initDragAndDrop();
setProviders();
JavaScriptPlugin.getDefault().getPreferenceStore().addPropertyChangeListener(this);
MenuManager menuMgr= new MenuManager("#PopupMenu"); //$NON-NLS-1$
menuMgr.setRemoveAllWhenShown(true);
menuMgr.addMenuListener(this);
fContextMenu= menuMgr.createContextMenu(fViewer.getTree());
fViewer.getTree().setMenu(fContextMenu);
// Register viewer with site. This must be done before making the actions.
IWorkbenchPartSite site= getSite();
site.registerContextMenu(menuMgr, fViewer);
site.setSelectionProvider(fViewer);
makeActions(); // call before registering for selection changes
// Set input after filter and sorter has been set. This avoids resorting and refiltering.
restoreFilterAndSorter();
fViewer.setInput(findInputElement());
initFrameActions();
initKeyListener();
fViewer.addPostSelectionChangedListener(fPostSelectionListener);
fViewer.addDoubleClickListener(new IDoubleClickListener() {
public void doubleClick(DoubleClickEvent event) {
fActionSet.handleDoubleClick(event);
}
});
fViewer.addOpenListener(new IOpenListener() {
public void open(OpenEvent event) {
fActionSet.handleOpen(event);
fLastOpenSelection= event.getSelection();
}
});
IStatusLineManager slManager= getViewSite().getActionBars().getStatusLineManager();
fViewer.addSelectionChangedListener(new StatusBarUpdater(slManager));
fViewer.addTreeListener(fExpansionListener);
// Set help for the view
JavaUIHelp.setHelp(fViewer, IJavaHelpContextIds.PACKAGES_VIEW);
fillActionBars();
updateTitle();
fFilterUpdater= new FilterUpdater(fViewer);
ResourcesPlugin.getWorkspace().addResourceChangeListener(fFilterUpdater);
// Sync'ing the package explorer has to be done here. It can't be done
// when restoring the link state since the package explorers input isn't
// set yet.
setLinkingEnabled(isLinkingEnabled());
stats.endRun();
}
private void initFrameActions() {
fActionSet.getUpAction().update();
fActionSet.getBackAction().update();
fActionSet.getForwardAction().update();
}
private ProblemTreeViewer createViewer(Composite composite) {
return new PackageExplorerProblemTreeViewer(composite, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
}
/**
* Answers whether this part shows the packages flat or hierarchical.
* @return <true> if flat layout is selected
*
*
*/
public boolean isFlatLayout() {
return fIsCurrentLayoutFlat;
}
private void setProviders() {
//content provider must be set before the label provider
fContentProvider= createContentProvider();
fContentProvider.setIsFlatLayout(fIsCurrentLayoutFlat);
fContentProvider.setShowLibrariesNode(fShowLibrariesNode);
fViewer.setContentProvider(fContentProvider);
fViewer.setComparer(createElementComparer());
fLabelProvider= createLabelProvider();
fLabelProvider.setIsFlatLayout(fIsCurrentLayoutFlat);
fDecoratingLabelProvider= new DecoratingJavaLabelProvider(fLabelProvider, false, fIsCurrentLayoutFlat);
fViewer.setLabelProvider(fDecoratingLabelProvider);
// problem decoration provided by PackageLabelProvider
}
public void setShowLibrariesNode(boolean enabled) {
fShowLibrariesNode= enabled;
saveDialogSettings();
fContentProvider.setShowLibrariesNode(enabled);
fViewer.getControl().setRedraw(false);
fViewer.refresh();
fViewer.getControl().setRedraw(true);
}
boolean isLibrariesNodeShown() {
return fShowLibrariesNode;
}
public void setFlatLayout(boolean enable) {
// Update current state and inform content and label providers
fIsCurrentLayoutFlat= enable;
saveDialogSettings();
if (fViewer != null) {
fContentProvider.setIsFlatLayout(isFlatLayout());
fLabelProvider.setIsFlatLayout(isFlatLayout());
fDecoratingLabelProvider.setFlatPackageMode(isFlatLayout());
fViewer.getControl().setRedraw(false);
fViewer.refresh();
fViewer.getControl().setRedraw(true);
}
}
/**
* This method should only be called inside this class
* and from test cases.
* @return the created content provider
*/
public PackageExplorerContentProvider createContentProvider() {
IPreferenceStore store= PreferenceConstants.getPreferenceStore();
boolean showCUChildren= store.getBoolean(PreferenceConstants.SHOW_CU_CHILDREN);
if (showProjects())
return new ScriptExplorerContentProvider(showCUChildren);
else
return new WorkingSetAwareContentProvider(showCUChildren, fWorkingSetModel);
}
private PackageExplorerLabelProvider createLabelProvider() {
return new PackageExplorerLabelProvider(fContentProvider);
}
private IElementComparer createElementComparer() {
if (showProjects())
return null;
else
return WorkingSetModel.COMPARER;
}
private void fillActionBars() {
IActionBars actionBars= getViewSite().getActionBars();
fActionSet.fillActionBars(actionBars);
}
private Object findInputElement() {
if (showWorkingSets()) {
return fWorkingSetModel;
} else {
Object input= getSite().getPage().getInput();
if (input instanceof IWorkspace) {
return JavaScriptCore.create(((IWorkspace)input).getRoot());
} else if (input instanceof IContainer) {
IJavaScriptElement element= JavaScriptCore.create((IContainer)input);
if (element != null && element.exists())
return element;
return input;
}
//1GERPRT: ITPJUI:ALL - Packages View is empty when shown in Type Hierarchy Perspective
// we can't handle the input
// fall back to show the workspace
return JavaScriptCore.create(JavaScriptPlugin.getWorkspace().getRoot());
}
}
/* (non-Javadoc)
* @see org.eclipse.ui.part.WorkbenchPart#getAdapter(java.lang.Class)
*/
public Object getAdapter(Class key) {
if (key.equals(ISelectionProvider.class))
return fViewer;
if (key == IShowInSource.class) {
return getShowInSource();
}
if (key == IShowInTargetList.class) {
return new IShowInTargetList() {
public String[] getShowInTargetIds() {
String explorerViewID = ProductProperties.getProperty(IProductConstants.PERSPECTIVE_EXPLORER_VIEW);
if (explorerViewID != null) {
return new String[] { explorerViewID, JavaScriptUI.ID_PACKAGES, IPageLayout.ID_PROJECT_EXPLORER };
}
else {
return new String[] { JavaScriptUI.ID_PACKAGES, IPageLayout.ID_PROJECT_EXPLORER };
}
}
};
}
if (key == IContextProvider.class) {
return JavaUIHelp.getHelpContextProvider(this, IJavaHelpContextIds.PACKAGES_VIEW);
}
return super.getAdapter(key);
}
/**
* Returns the tool tip text for the given element.
* @param element the element
* @return the tooltip
*/
String getToolTipText(Object element) {
String result;
if (!(element instanceof IResource)) {
if (element instanceof IJavaScriptModel) {
result= PackagesMessages.PackageExplorerPart_workspace;
} else if (element instanceof IJavaScriptElement){
result= JavaScriptElementLabels.getTextLabel(element, JavaScriptElementLabels.ALL_FULLY_QUALIFIED);
} else if (element instanceof IWorkingSet) {
result= ((IWorkingSet)element).getLabel();
} else if (element instanceof WorkingSetModel) {
result= PackagesMessages.PackageExplorerPart_workingSetModel;
} else {
result= fLabelProvider.getText(element);
}
} else {
IPath path= ((IResource) element).getFullPath();
if (path.isRoot()) {
result= PackagesMessages.PackageExplorer_title;
} else {
result= path.makeRelative().toString();
}
}
if (fRootMode == ViewActionGroup.SHOW_PROJECTS) {
if (fWorkingSetLabel == null)
return result;
if (result.length() == 0)
return Messages.format(PackagesMessages.PackageExplorer_toolTip, new String[] { fWorkingSetLabel });
return Messages.format(PackagesMessages.PackageExplorer_toolTip2, new String[] { result, fWorkingSetLabel });
} else { // Working set mode. During initialization element and action set can be null.
if (element != null && !(element instanceof IWorkingSet) && !(element instanceof WorkingSetModel) && fActionSet != null) {
FrameList frameList= fActionSet.getFrameList();
int index= frameList.getCurrentIndex();
IWorkingSet ws= null;
while(index >= 0) {
Frame frame= frameList.getFrame(index);
if (frame instanceof TreeFrame) {
Object input= ((TreeFrame)frame).getInput();
if (input instanceof IWorkingSet) {
ws= (IWorkingSet) input;
break;
}
}
index--;
}
if (ws != null) {
return Messages.format(PackagesMessages.PackageExplorer_toolTip3, new String[] {ws.getLabel() , result});
} else {
return result;
}
} else {
return result;
}
}
}
public String getTitleToolTip() {
if (fViewer == null)
return super.getTitleToolTip();
return getToolTipText(fViewer.getInput());
}
/* (non-Javadoc)
* @see org.eclipse.ui.part.WorkbenchPart#setFocus()
*/
public void setFocus() {
fViewer.getTree().setFocus();
}
private ISelection getSelection() {
return fViewer.getSelection();
}
//---- Action handling ----------------------------------------------------------
/* (non-Javadoc)
* @see IMenuListener#menuAboutToShow(IMenuManager)
*/
public void menuAboutToShow(IMenuManager menu) {
JavaScriptPlugin.createStandardGroups(menu);
fActionSet.setContext(new ActionContext(getSelection()));
fActionSet.fillContextMenu(menu);
fActionSet.setContext(null);
}
private void makeActions() {
final PerformanceStats stats= PerformanceStats.getStats(PERF_MAKE_ACTIONS, this);
stats.startRun();
fActionSet= new PackageExplorerActionGroup(this);
if (fWorkingSetModel != null)
fActionSet.getWorkingSetActionGroup().setWorkingSetModel(fWorkingSetModel);
stats.endRun();
}
// ---- Event handling ----------------------------------------------------------
private void initDragAndDrop() {
initDrag();
initDrop();
}
private void initDrag() {
int ops= DND.DROP_COPY | DND.DROP_MOVE | DND.DROP_LINK;
Transfer[] transfers= new Transfer[] {
LocalSelectionTransfer.getTransfer(),
ResourceTransfer.getInstance(),
FileTransfer.getInstance()};
TransferDragSourceListener[] dragListeners= new TransferDragSourceListener[] {
new SelectionTransferDragAdapter(fViewer),
new ResourceTransferDragAdapter(fViewer),
new FileTransferDragAdapter(fViewer)
};
fViewer.addDragSupport(ops, transfers, new JdtViewerDragAdapter(fViewer, dragListeners));
}
private void initDrop() {
int ops= DND.DROP_COPY | DND.DROP_MOVE | DND.DROP_LINK | DND.DROP_DEFAULT;
Transfer[] transfers= new Transfer[] {
LocalSelectionTransfer.getTransfer(),
FileTransfer.getInstance()};
TransferDropTargetListener[] dropListeners= new TransferDropTargetListener[] {
new SelectionTransferDropAdapter(fViewer),
new FileTransferDropAdapter(fViewer),
new WorkingSetDropAdapter(this)
};
fViewer.addDropSupport(ops, transfers, new DelegatingDropAdapter(dropListeners));
}
/**
* Handles post selection changed in viewer.
*
* Links to editor (if option enabled).
* @param event the selection eveny
*/
private void handlePostSelectionChanged(SelectionChangedEvent event) {
ISelection selection= event.getSelection();
// If the selection is the same as the one that triggered the last
// open event then do nothing. The editor already got revealed.
if (isLinkingEnabled() && !selection.equals(fLastOpenSelection)) {
linkToEditor((IStructuredSelection)selection);
}
fLastOpenSelection= null;
}
/* (non-Javadoc)
* @see org.eclipse.ui.part.ISetSelectionTarget#selectReveal(org.eclipse.jface.viewers.ISelection)
*/
public void selectReveal(final ISelection selection) {
Control ctrl= getTreeViewer().getControl();
if (ctrl == null || ctrl.isDisposed())
return;
fContentProvider.runPendingUpdates();
fViewer.setSelection(convertSelection(selection), true);
}
public ISelection convertSelection(ISelection s) {
if (!(s instanceof IStructuredSelection))
return s;
Object[] elements= ((IStructuredSelection)s).toArray();
boolean changed= false;
for (int i= 0; i < elements.length; i++) {
Object convertedElement= convertElement(elements[i]);
changed= changed || convertedElement != elements[i];
elements[i]= convertedElement;
}
if (changed)
return new StructuredSelection(elements);
else
return s;
}
private Object convertElement(Object original) {
if (original instanceof IJavaScriptElement) {
if (original instanceof IJavaScriptUnit) {
IJavaScriptUnit cu= (IJavaScriptUnit) original;
IJavaScriptProject javaProject= cu.getJavaScriptProject();
if (javaProject != null && javaProject.exists() && ! javaProject.isOnIncludepath(cu)) {
// could be a working copy of a .java file that is not on classpath
IResource resource= cu.getResource();
if (resource != null)
return resource;
}
}
return original;
} else if (original instanceof IResource) {
IJavaScriptElement je= JavaScriptCore.create((IResource)original);
if (je != null && je.exists()) {
IJavaScriptProject javaProject= je.getJavaScriptProject();
if (javaProject != null && javaProject.exists()) {
return je;
}
}
} else if (original instanceof IAdaptable) {
IAdaptable adaptable= (IAdaptable)original;
IJavaScriptElement je= (IJavaScriptElement) adaptable.getAdapter(IJavaScriptElement.class);
if (je != null && je.exists())
return je;
IResource r= (IResource) adaptable.getAdapter(IResource.class);
if (r != null) {
je= JavaScriptCore.create(r);
if (je != null && je.exists())
return je;
else
return r;
}
}
return original;
}
public void selectAndReveal(Object element) {
selectReveal(new StructuredSelection(element));
}
public boolean isLinkingEnabled() {
return fLinkingEnabled;
}
/**
* Links to editor (if option enabled)
* @param selection the selection
*/
private void linkToEditor(IStructuredSelection selection) {
// ignore selection changes if the package explorer is not the active part.
// In this case the selection change isn't triggered by a user.
if (!isActivePart())
return;
Object obj= selection.getFirstElement();
if (selection.size() == 1) {
IEditorPart part= EditorUtility.isOpenInEditor(obj);
if (part != null) {
IWorkbenchPage page= getSite().getPage();
page.bringToTop(part);
if (obj instanceof IJavaScriptElement)
EditorUtility.revealInEditor(part, (IJavaScriptElement)obj);
}
}
}
private boolean isActivePart() {
return this == getSite().getPage().getActivePart();
}
public void saveState(IMemento memento) {
if (fViewer == null && fMemento != null) {
// part has not been created -> keep the old state
memento.putMemento(fMemento);
return;
}
memento.putInteger(TAG_ROOT_MODE, fRootMode);
if (fWorkingSetModel != null)
fWorkingSetModel.saveState(memento);
saveLayoutState(memento);
saveLinkingEnabled(memento);
if (fActionSet != null) {
fActionSet.saveFilterAndSorterState(memento);
}
}
private void saveLinkingEnabled(IMemento memento) {
memento.putInteger(TAG_LINK_EDITOR, fLinkingEnabled ? 1 : 0);
}
private void saveLayoutState(IMemento memento) {
if (memento != null) {
memento.putInteger(TAG_LAYOUT, getLayoutAsInt());
memento.putInteger(TAG_GROUP_LIBRARIES, fShowLibrariesNode ? 1 : 0);
}
}
private void saveDialogSettings() {
fDialogSettings.put(TAG_GROUP_LIBRARIES, fShowLibrariesNode);
fDialogSettings.put(TAG_LAYOUT, getLayoutAsInt());
fDialogSettings.put(TAG_ROOT_MODE, fRootMode);
fDialogSettings.put(TAG_LINK_EDITOR, fLinkingEnabled);
}
private int getLayoutAsInt() {
if (fIsCurrentLayoutFlat)
return FLAT_LAYOUT;
else
return HIERARCHICAL_LAYOUT;
}
private void restoreFilterAndSorter() {
setComparator();
if (fMemento != null)
fActionSet.restoreFilterAndSorterState(fMemento);
}
private void restoreLinkingEnabled(IMemento memento) {
Integer val= memento.getInteger(TAG_LINK_EDITOR);
fLinkingEnabled= val != null && val.intValue() != 0;
}
/**
* Create the KeyListener for doing the refresh on the viewer.
*/
private void initKeyListener() {
fViewer.getControl().addKeyListener(new KeyAdapter() {
public void keyReleased(KeyEvent event) {
fActionSet.handleKeyEvent(event);
}
});
}
/**
* An editor has been activated. Set the selection in this Packages Viewer
* to be the editor's input, if linking is enabled.
* @param editor the activated editor
*/
void editorActivated(IEditorPart editor) {
IEditorInput editorInput= editor.getEditorInput();
if (editorInput == null)
return;
Object input= getInputFromEditor(editorInput);
if (input == null)
return;
if (!inputIsSelected(editorInput))
showInput(input);
else
getTreeViewer().getTree().showSelection();
}
private Object getInputFromEditor(IEditorInput editorInput) {
Object input= JavaScriptUI.getEditorInputJavaElement(editorInput);
if (input == null) {
input= editorInput.getAdapter(IFile.class);
}
if (input == null && editorInput instanceof IStorageEditorInput) {
try {
input= ((IStorageEditorInput) editorInput).getStorage();
} catch (CoreException e) {
// ignore
}
}
return input;
}
private boolean inputIsSelected(IEditorInput input) {
IStructuredSelection selection= (IStructuredSelection)fViewer.getSelection();
if (selection.size() != 1)
return false;
IEditorInput selectionAsInput= null;
try {
selectionAsInput= EditorUtility.getEditorInput(selection.getFirstElement());
} catch (JavaScriptModelException e1) {
return false;
}
return input.equals(selectionAsInput);
}
boolean showInput(Object input) {
Object element= null;
if (input instanceof IFile && isOnClassPath((IFile)input)) {
element= JavaScriptCore.create((IFile)input);
}
if (element == null) // try a non Java resource
element= input;
if (element instanceof IJavaScriptUnit || element instanceof IClassFile) {
element = ((IJavaScriptElement) element).getResource();
}
if (element != null) {
ISelection newSelection= new StructuredSelection(element);
if (fViewer.getSelection().equals(newSelection)) {
fViewer.reveal(element);
} else {
try {
fViewer.removePostSelectionChangedListener(fPostSelectionListener);
fViewer.setSelection(newSelection, true);
while (element != null && fViewer.getSelection().isEmpty()) {
// Try to select parent in case element is filtered
element= getParent(element);
if (element != null) {
newSelection= new StructuredSelection(element);
fViewer.setSelection(newSelection, true);
}
}
} finally {
fViewer.addPostSelectionChangedListener(fPostSelectionListener);
}
}
return true;
}
return false;
}
private boolean isOnClassPath(IFile file) {
IJavaScriptProject jproject= JavaScriptCore.create(file.getProject());
return jproject.isOnIncludepath(file);
}
/**
* Returns the element's parent.
* @param element the element
*
* @return the parent or <code>null</code> if there's no parent
*/
private Object getParent(Object element) {
if (element instanceof IJavaScriptElement)
return ((IJavaScriptElement)element).getParent();
else if (element instanceof IResource)
return ((IResource)element).getParent();
else if (element instanceof IJarEntryResource) {
return ((IJarEntryResource)element).getParent();
}
return null;
}
/**
* A compilation unit or class was expanded, expand
* the main type.
* @param element the element
*/
void expandMainType(Object element) {
try {
IType type= null;
if (element instanceof IJavaScriptUnit) {
IJavaScriptUnit cu= (IJavaScriptUnit)element;
IType[] types= cu.getTypes();
if (types.length > 0)
type= types[0];
}
else if (element instanceof IClassFile) {
IClassFile cf= (IClassFile)element;
type= cf.getType();
}
if (type != null) {
final IType type2= type;
Control ctrl= fViewer.getControl();
if (ctrl != null && !ctrl.isDisposed()) {
ctrl.getDisplay().asyncExec(new Runnable() {
public void run() {
Control ctrl2= fViewer.getControl();
if (ctrl2 != null && !ctrl2.isDisposed())
fViewer.expandToLevel(type2, 1);
}
});
}
}
} catch(JavaScriptModelException e) {
// no reveal
}
}
/**
* Returns the TreeViewer.
* @return the tree viewer
*/
public TreeViewer getTreeViewer() {
return fViewer;
}
boolean isExpandable(Object element) {
if (fViewer == null)
return false;
return fViewer.isExpandable(element);
}
void setWorkingSetLabel(String workingSetName) {
fWorkingSetLabel= workingSetName;
setTitleToolTip(getTitleToolTip());
}
/**
* Updates the title text and title tool tip.
* Called whenever the input of the viewer changes.
*/
void updateTitle() {
Object input= fViewer.getInput();
if (input == null
|| (input instanceof IJavaScriptModel)) {
setContentDescription(""); //$NON-NLS-1$
setTitleToolTip(""); //$NON-NLS-1$
} else {
String inputText= JavaScriptElementLabels.getTextLabel(input, AppearanceAwareLabelProvider.DEFAULT_TEXTFLAGS);
setContentDescription(inputText);
setTitleToolTip(getToolTipText(input));
}
}
/**
* Sets the decorator for the package explorer.
*
* @param decorator a label decorator or <code>null</code> for no decorations.
* @deprecated To be removed
*/
public void setLabelDecorator(ILabelDecorator decorator) {
}
/*
* @see IPropertyChangeListener#propertyChange(PropertyChangeEvent)
*/
public void propertyChange(PropertyChangeEvent event) {
if (fViewer == null)
return;
boolean refreshViewer= false;
if (PreferenceConstants.SHOW_CU_CHILDREN.equals(event.getProperty())) {
fActionSet.updateActionBars(getViewSite().getActionBars());
boolean showCUChildren= PreferenceConstants.getPreferenceStore().getBoolean(PreferenceConstants.SHOW_CU_CHILDREN);
((StandardJavaScriptElementContentProvider)fViewer.getContentProvider()).setProvideMembers(showCUChildren);
refreshViewer= true;
} else if (MembersOrderPreferenceCache.isMemberOrderProperty(event.getProperty())) {
refreshViewer= true;
}
if (refreshViewer)
fViewer.refresh();
}
/* (non-Javadoc)
* @see IViewPartInputProvider#getViewPartInput()
*/
public Object getViewPartInput() {
if (fViewer != null) {
return fViewer.getInput();
}
return null;
}
public void collapseAll() {
try {
fViewer.getControl().setRedraw(false);
fViewer.collapseToLevel(getViewPartInput(), AbstractTreeViewer.ALL_LEVELS);
} finally {
fViewer.getControl().setRedraw(true);
}
}
/* (non-Javadoc)
* @see org.eclipse.ui.part.IShowInTarget#show(org.eclipse.ui.part.ShowInContext)
*/
public boolean show(ShowInContext context) {
ISelection selection= context.getSelection();
if (selection instanceof IStructuredSelection) {
// fix for 64634 Navigate/Show in/Package Explorer doesn't work
IStructuredSelection structuredSelection= ((IStructuredSelection) selection);
if (structuredSelection.size() == 1) {
int res= tryToReveal(structuredSelection.getFirstElement());
if (res == IStatus.OK)
return true;
if (res == IStatus.CANCEL)
return false;
} else if (structuredSelection.size() > 1) {
selectReveal(structuredSelection);
return true;
}
}
Object input= context.getInput();
if (input instanceof IEditorInput) {
Object elementOfInput= getInputFromEditor((IEditorInput) input);
return elementOfInput != null && (tryToReveal(elementOfInput) == IStatus.OK);
}
return false;
}
/**
* Returns the <code>IShowInSource</code> for this view.
* @return the <code>IShowInSource</code>
*/
protected IShowInSource getShowInSource() {
return new IShowInSource() {
public ShowInContext getShowInContext() {
return new ShowInContext(
getTreeViewer().getInput(),
getTreeViewer().getSelection());
}
};
}
/* (non-Javadoc)
* @see org.eclipse.wst.jsdt.ui.IPackagesViewPart#setLinkingEnabled(boolean)
*/
public void setLinkingEnabled(boolean enabled) {
fLinkingEnabled= enabled;
saveDialogSettings();
IWorkbenchPage page= getSite().getPage();
if (enabled) {
page.addPartListener(fLinkWithEditorListener);
IEditorPart editor = page.getActiveEditor();
if (editor != null) {
editorActivated(editor);
}
} else {
page.removePartListener(fLinkWithEditorListener);
}
}
/**
* Returns the name for the given element.
* Used as the name for the current frame.
* @param element the elemeny
* @return the name of the frame
*/
String getFrameName(Object element) {
if (element instanceof IJavaScriptElement) {
return ((IJavaScriptElement) element).getElementName();
} else if (element instanceof WorkingSetModel) {
return ""; //$NON-NLS-1$
} else {
return fLabelProvider.getText(element);
}
}
public int tryToReveal(Object element) {
if (revealElementOrParent(element))
return IStatus.OK;
WorkingSetFilterActionGroup workingSetGroup= fActionSet.getWorkingSetActionGroup().getFilterGroup();
if (workingSetGroup != null) {
IWorkingSet workingSet= workingSetGroup.getWorkingSet();
if (workingSetGroup.isFiltered(getVisibleParent(element), element)) {
String message;
if (element instanceof IJavaScriptElement) {
String elementLabel= JavaScriptElementLabels.getElementLabel((IJavaScriptElement)element, JavaScriptElementLabels.ALL_DEFAULT);
message= Messages.format(PackagesMessages.PackageExplorerPart_notFoundSepcific, new String[] {elementLabel, workingSet.getLabel()});
} else {
message= Messages.format(PackagesMessages.PackageExplorer_notFound, workingSet.getLabel());
}
if (MessageDialog.openQuestion(getSite().getShell(), PackagesMessages.PackageExplorer_filteredDialog_title, message)) {
workingSetGroup.setWorkingSet(null, true);
if (revealElementOrParent(element))
return IStatus.OK;
} else {
return IStatus.CANCEL;
}
}
}
// try to remove filters
CustomFiltersActionGroup filterGroup= fActionSet.getCustomFilterActionGroup();
String[] currentFilters= filterGroup.internalGetEnabledFilterIds();
String[] newFilters= filterGroup.removeFiltersFor(getVisibleParent(element), element, getTreeViewer().getContentProvider());
if (currentFilters.length > newFilters.length) {
String message;
if (element instanceof IJavaScriptElement) {
String elementLabel= JavaScriptElementLabels.getElementLabel((IJavaScriptElement)element, JavaScriptElementLabels.ALL_DEFAULT);
message= Messages.format(PackagesMessages.PackageExplorerPart_removeFiltersSpecific, elementLabel);
} else {
message= PackagesMessages.PackageExplorer_removeFilters;
}
if (MessageDialog.openQuestion(getSite().getShell(), PackagesMessages.PackageExplorer_filteredDialog_title, message)) {
filterGroup.setFilters(newFilters);
if (revealElementOrParent(element))
return IStatus.OK;
} else {
return IStatus.CANCEL;
}
}
FrameAction action= fActionSet.getUpAction();
while (action.getFrameList().getCurrentIndex() > 0) {
// only try to go up if there is a parent frame
// fix for bug# 63769 Endless loop after Show in Package Explorer
if (action.getFrameList().getSource().getFrame(IFrameSource.PARENT_FRAME, 0) == null)
break;
action.run();
if (revealElementOrParent(element))
return IStatus.OK;
}
return IStatus.ERROR;
}
private boolean revealElementOrParent(Object element) {
if (revealAndVerify(element))
return true;
element= getVisibleParent(element);
if (element != null) {
if (revealAndVerify(element))
return true;
if (element instanceof IJavaScriptElement) {
IResource resource= ((IJavaScriptElement)element).getResource();
if (resource != null) {
if (revealAndVerify(resource))
return true;
}
}
}
return false;
}
private Object getVisibleParent(Object object) {
// Fix for http://dev.eclipse.org/bugs/show_bug.cgi?id=19104
if (object == null)
return null;
if (!(object instanceof IJavaScriptElement))
return object;
IJavaScriptElement element2= (IJavaScriptElement) object;
switch (element2.getElementType()) {
case IJavaScriptElement.IMPORT_DECLARATION:
case IJavaScriptElement.IMPORT_CONTAINER:
case IJavaScriptElement.EXPORT_DECLARATION:
case IJavaScriptElement.EXPORT_CONTAINER:
case IJavaScriptElement.TYPE:
case IJavaScriptElement.METHOD:
case IJavaScriptElement.FIELD:
case IJavaScriptElement.INITIALIZER:
// select parent cu/classfile
element2= (IJavaScriptElement)element2.getOpenable();
break;
case IJavaScriptElement.JAVASCRIPT_MODEL:
element2= null;
break;
}
return element2;
}
private boolean revealAndVerify(Object element) {
if (element == null)
return false;
selectReveal(new StructuredSelection(element));
return ! getSite().getSelectionProvider().getSelection().isEmpty();
}
public void rootModeChanged(int newMode) {
fRootMode= newMode;
saveDialogSettings();
if (showWorkingSets() && fWorkingSetModel == null) {
createWorkingSetModel();
if (fActionSet != null) {
fActionSet.getWorkingSetActionGroup().setWorkingSetModel(fWorkingSetModel);
}
}
IStructuredSelection selection= new StructuredSelection(((IStructuredSelection) fViewer.getSelection()).toArray());
Object input= fViewer.getInput();
boolean isRootInputChange= JavaScriptCore.create(ResourcesPlugin.getWorkspace().getRoot()).equals(input)
|| (fWorkingSetModel != null && fWorkingSetModel.equals(input))
|| input instanceof IWorkingSet;
try {
fViewer.getControl().setRedraw(false);
if (isRootInputChange) {
fViewer.setInput(null);
}
setProviders();
setComparator();
fActionSet.getWorkingSetActionGroup().fillFilters(fViewer);
if (isRootInputChange) {
fViewer.setInput(findInputElement());
}
fViewer.setSelection(selection, true);
} finally {
fViewer.getControl().setRedraw(true);
}
if (isRootInputChange && showWorkingSets() && fWorkingSetModel.needsConfiguration()) {
ConfigureWorkingSetAction action= new ConfigureWorkingSetAction(getSite());
action.setWorkingSetModel(fWorkingSetModel);
action.run();
fWorkingSetModel.configured();
}
setTitleToolTip(getTitleToolTip());
}
private void createWorkingSetModel() {
SafeRunner.run(new ISafeRunnable() {
public void run() throws Exception {
fWorkingSetModel= new WorkingSetModel(fMemento);
}
public void handleException(Throwable exception) {
fWorkingSetModel= new WorkingSetModel(null);
}
});
}
/**
* @return the selected working set to filter if in root mode {@link ViewActionGroup#SHOW_PROJECTS}
*/
public IWorkingSet getFilterWorkingSet() {
if (!showProjects())
return null;
if (fActionSet == null)
return null;
return fActionSet.getWorkingSetActionGroup().getFilterGroup().getWorkingSet();
}
public WorkingSetModel getWorkingSetModel() {
return fWorkingSetModel;
}
public int getRootMode() {
return fRootMode;
}
/* package */ boolean showProjects() {
return fRootMode == ViewActionGroup.SHOW_PROJECTS;
}
/* package */ boolean showWorkingSets() {
return fRootMode == ViewActionGroup.SHOW_WORKING_SETS;
}
private void setComparator() {
if (showWorkingSets()) {
fViewer.setComparator(new WorkingSetAwareJavaElementSorter());
} else {
fViewer.setComparator(new JavaScriptElementComparator());
}
}
//---- test methods for working set mode -------------------------------
public void internalTestShowWorkingSets(IWorkingSet[] workingSets) {
if (fWorkingSetModel == null)
createWorkingSetModel();
fWorkingSetModel.setActiveWorkingSets(workingSets);
fWorkingSetModel.configured();
rootModeChanged(ViewActionGroup.SHOW_WORKING_SETS);
}
}