/******************************************************************************* * Copyright (c) 2000, 2011 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.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.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.ui.views.navigator.LocalSelectionTransfer; 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.JavaScriptPlugin; 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() { return new String[] { IPageLayout.ID_RES_NAV }; } }; } 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.getInstance(), 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.getInstance(), 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.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); } }