| /******************************************************************************* |
| * Copyright (c) 2000, 2006 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.jdt.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.runtime.IAdaptable; |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.core.runtime.ISafeRunnable; |
| import org.eclipse.core.runtime.PerformanceStats; |
| import org.eclipse.core.runtime.SafeRunner; |
| |
| 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.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.ScrollBar; |
| import org.eclipse.swt.widgets.Tree; |
| import org.eclipse.swt.widgets.TreeItem; |
| import org.eclipse.swt.widgets.Widget; |
| |
| 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.ui.IActionBars; |
| import org.eclipse.ui.IEditorInput; |
| import org.eclipse.ui.IEditorPart; |
| import org.eclipse.ui.IFileEditorInput; |
| import org.eclipse.ui.IMemento; |
| import org.eclipse.ui.IPageLayout; |
| import org.eclipse.ui.IPartListener; |
| import org.eclipse.ui.IViewPart; |
| import org.eclipse.ui.IViewSite; |
| import org.eclipse.ui.IWorkbenchPage; |
| import org.eclipse.ui.IWorkbenchPart; |
| 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.jdt.core.IClassFile; |
| import org.eclipse.jdt.core.ICompilationUnit; |
| import org.eclipse.jdt.core.IJavaElement; |
| import org.eclipse.jdt.core.IJavaModel; |
| import org.eclipse.jdt.core.IJavaProject; |
| import org.eclipse.jdt.core.IPackageFragment; |
| import org.eclipse.jdt.core.IPackageFragmentRoot; |
| import org.eclipse.jdt.core.IType; |
| import org.eclipse.jdt.core.JavaCore; |
| import org.eclipse.jdt.core.JavaModelException; |
| |
| import org.eclipse.jdt.internal.corext.util.Messages; |
| |
| import org.eclipse.jdt.ui.IPackagesViewPart; |
| import org.eclipse.jdt.ui.JavaElementLabels; |
| import org.eclipse.jdt.ui.JavaElementSorter; |
| import org.eclipse.jdt.ui.JavaUI; |
| import org.eclipse.jdt.ui.PreferenceConstants; |
| import org.eclipse.jdt.ui.StandardJavaElementContentProvider; |
| import org.eclipse.jdt.ui.actions.CustomFiltersActionGroup; |
| |
| import org.eclipse.jdt.internal.ui.IJavaHelpContextIds; |
| import org.eclipse.jdt.internal.ui.JavaPlugin; |
| import org.eclipse.jdt.internal.ui.dnd.DelegatingDropAdapter; |
| import org.eclipse.jdt.internal.ui.dnd.JdtViewerDragAdapter; |
| import org.eclipse.jdt.internal.ui.dnd.ResourceTransferDragAdapter; |
| import org.eclipse.jdt.internal.ui.filters.OutputFolderFilter; |
| import org.eclipse.jdt.internal.ui.javaeditor.EditorUtility; |
| import org.eclipse.jdt.internal.ui.javaeditor.IClassFileEditorInput; |
| import org.eclipse.jdt.internal.ui.javaeditor.JarEntryEditorInput; |
| import org.eclipse.jdt.internal.ui.preferences.MembersOrderPreferenceCache; |
| import org.eclipse.jdt.internal.ui.util.JavaUIHelp; |
| import org.eclipse.jdt.internal.ui.viewsupport.AppearanceAwareLabelProvider; |
| import org.eclipse.jdt.internal.ui.viewsupport.DecoratingJavaLabelProvider; |
| import org.eclipse.jdt.internal.ui.viewsupport.FilterUpdater; |
| import org.eclipse.jdt.internal.ui.viewsupport.IViewPartInputProvider; |
| import org.eclipse.jdt.internal.ui.viewsupport.JavaElementImageProvider; |
| import org.eclipse.jdt.internal.ui.viewsupport.ProblemTreeViewer; |
| import org.eclipse.jdt.internal.ui.viewsupport.StatusBarUpdater; |
| import org.eclipse.jdt.internal.ui.workingsets.ConfigureWorkingSetAction; |
| import org.eclipse.jdt.internal.ui.workingsets.ViewActionGroup; |
| import org.eclipse.jdt.internal.ui.workingsets.WorkingSetFilterActionGroup; |
| import org.eclipse.jdt.internal.ui.workingsets.WorkingSetModel; |
| |
| /** |
| * 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.jdt.ui/perf/explorer/createPartControl"; //$NON-NLS-1$ |
| private static final String PERF_MAKE_ACTIONS= "org.eclipse.jdt.ui/perf/explorer/makeActions"; //$NON-NLS-1$ |
| |
| private boolean fIsCurrentLayoutFlat; // true means flat, false means hierachical |
| |
| private static final int HIERARCHICAL_LAYOUT= 0x1; |
| private static final int FLAT_LAYOUT= 0x2; |
| |
| public final static String VIEW_ID= JavaUI.ID_PACKAGES; |
| |
| // Persistance tags. |
| static final String TAG_SELECTION= "selection"; //$NON-NLS-1$ |
| static final String TAG_EXPANDED= "expanded"; //$NON-NLS-1$ |
| static final String TAG_ELEMENT= "element"; //$NON-NLS-1$ |
| static final String TAG_PATH= "path"; //$NON-NLS-1$ |
| static final String TAG_VERTICAL_POSITION= "verticalPosition"; //$NON-NLS-1$ |
| static final String TAG_HORIZONTAL_POSITION= "horizontalPosition"; //$NON-NLS-1$ |
| static final String TAG_FILTERS = "filters"; //$NON-NLS-1$ |
| static final String TAG_FILTER = "filter"; //$NON-NLS-1$ |
| static final String TAG_LAYOUT= "layout"; //$NON-NLS-1$ |
| static final String TAG_CURRENT_FRAME= "currentFramge"; //$NON-NLS-1$ |
| static final String TAG_ROOT_MODE= "rootMode"; //$NON-NLS-1$ |
| static final String SETTING_MEMENTO= "memento"; //$NON-NLS-1$ |
| |
| private int fRootMode; |
| private WorkingSetModel fWorkingSetModel; |
| |
| private PackageExplorerLabelProvider fLabelProvider; |
| private PackageExplorerContentProvider fContentProvider; |
| private FilterUpdater fFilterUpdater; |
| |
| private PackageExplorerActionGroup fActionSet; |
| private ProblemTreeViewer fViewer; |
| private Menu fContextMenu; |
| |
| private IMemento fMemento; |
| |
| private ISelection fLastOpenSelection; |
| private ISelectionChangedListener fPostSelectionListener; |
| |
| private String fWorkingSetLabel; |
| |
| private IPartListener fPartListener= new IPartListener() { |
| public void partActivated(IWorkbenchPart part) { |
| if (part instanceof IEditorPart) |
| editorActivated((IEditorPart) part); |
| } |
| public void partBroughtToTop(IWorkbenchPart part) { |
| } |
| public void partClosed(IWorkbenchPart part) { |
| } |
| public void partDeactivated(IWorkbenchPart part) { |
| } |
| public void partOpened(IWorkbenchPart part) { |
| } |
| }; |
| |
| private ITreeViewerListener fExpansionListener= new ITreeViewerListener() { |
| public void treeCollapsed(TreeExpansionEvent event) { |
| } |
| |
| public void treeExpanded(TreeExpansionEvent event) { |
| Object element= event.getElement(); |
| if (element instanceof ICompilationUnit || |
| 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()); |
| } |
| 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); |
| } |
| } |
| |
| /* |
| * @see org.eclipse.jface.viewers.StructuredViewer#filter(java.lang.Object) |
| */ |
| protected Object[] getFilteredChildren(Object parent) { |
| Object[] children = getRawChildren(parent); |
| if (!hasFilters()) { |
| return children; |
| } |
| List list = new ArrayList(); |
| ViewerFilter[] filters = getFilters(); |
| |
| for (int i = 0; i < children.length; i++) { |
| Object object = children[i]; |
| if (!isFiltered(object, parent, filters)) { |
| list.add(object); |
| } |
| } |
| return list.toArray(); |
| } |
| |
| protected boolean evaluateExpandableWithFilters(Object parent) { |
| if (parent instanceof IJavaProject |
| || parent instanceof ICompilationUnit || parent instanceof IClassFile |
| || parent instanceof ClassPathContainer) { |
| return false; |
| } |
| if (parent instanceof IPackageFragmentRoot && ((IPackageFragmentRoot) parent).isArchive()) { |
| return false; |
| } |
| return true; |
| } |
| |
| protected boolean isFiltered(Object object, Object parent, ViewerFilter[] filters) { |
| boolean res= super.isFiltered(object, parent, filters); |
| if (res && isEssential(object)) { |
| return false; |
| } |
| return res; |
| } |
| |
| /* |
| * @see org.eclipse.jface.viewers.StructuredViewer#filter(java.lang.Object[]) |
| * @since 3.0 |
| */ |
| protected Object[] filter(Object[] elements) { |
| if (isFlatLayout()) |
| return super.filter(elements); |
| |
| ViewerFilter[] filters= getFilters(); |
| if (filters == null || filters.length == 0) |
| return elements; |
| |
| ArrayList filtered= new ArrayList(elements.length); |
| Object root= getRoot(); |
| for (int i= 0; i < elements.length; i++) { |
| boolean add= true; |
| if (!isEssential(elements[i])) { |
| for (int j = 0; j < filters.length; j++) { |
| add= filters[j].select(this, root, |
| elements[i]); |
| if (!add) |
| break; |
| } |
| } |
| if (add) |
| filtered.add(elements[i]); |
| } |
| return filtered.toArray(); |
| } |
| |
| /* Checks if a filtered object in essential (ie. is a parent that |
| * should not be removed). |
| */ |
| private boolean isEssential(Object object) { |
| try { |
| if (!isFlatLayout() && object instanceof IPackageFragment) { |
| IPackageFragment fragment = (IPackageFragment) object; |
| return !fragment.isDefaultPackage() && fragment.hasSubpackages(); |
| } |
| } catch (JavaModelException e) { |
| JavaPlugin.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 IJavaProject) { |
| IProject project= ((IJavaProject)element).getProject(); |
| if (!project.isOpen() && project.exists()) { |
| ns.add(project); |
| changed= true; |
| } |
| } else if (element instanceof IProject) { |
| IProject project= (IProject)element; |
| if (project.isOpen()) { |
| IJavaProject jProject= JavaCore.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; |
| } |
| } |
| |
| /* (non-Javadoc) |
| * Method declared on IViewPart. |
| */ |
| private boolean fLinkingEnabled; |
| |
| public void init(IViewSite site, IMemento memento) throws PartInitException { |
| super.init(site, memento); |
| fMemento= memento; |
| if (fMemento == null) { |
| IDialogSettings section= JavaPlugin.getDefault().getDialogSettings().getSection(getSectionName()); |
| if (section != null) { |
| String settings= section.get(SETTING_MEMENTO); |
| if (settings != null) { |
| try { |
| fMemento= XMLMemento.createReadRoot(new StringReader(settings)); |
| } catch (WorkbenchException e) { |
| // don't restore the memento when the settings can't be read. |
| } |
| } |
| } |
| } |
| restoreRootMode(fMemento); |
| if (showWorkingSets()) { |
| createWorkingSetModel(); |
| } |
| restoreLayoutState(memento); |
| } |
| |
| private String getSectionName() { |
| return "org.eclipse.jdt.ui.internal.packageExplorer"; //$NON-NLS-1$ |
| } |
| |
| private void restoreRootMode(IMemento memento) { |
| if (memento != null) { |
| Integer value= fMemento.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; |
| } else { |
| fRootMode= ViewActionGroup.SHOW_PROJECTS; |
| } |
| } |
| |
| private void restoreLayoutState(IMemento memento) { |
| Integer state= null; |
| if (memento != null) |
| state= memento.getInteger(TAG_LAYOUT); |
| |
| // If no memento try an restore from preference store |
| if(state == null) { |
| IPreferenceStore store= JavaPlugin.getDefault().getPreferenceStore(); |
| state= new Integer(store.getInt(TAG_LAYOUT)); |
| } |
| |
| if (state.intValue() == FLAT_LAYOUT) |
| fIsCurrentLayoutFlat= true; |
| else if (state.intValue() == HIERARCHICAL_LAYOUT) |
| fIsCurrentLayoutFlat= false; |
| else |
| fIsCurrentLayoutFlat= true; |
| } |
| |
| /** |
| * Returns the package explorer part of the active perspective. If |
| * there isn't any package explorer part <code>null</code> is returned. |
| */ |
| public static PackageExplorerPart getFromActivePerspective() { |
| IWorkbenchPage activePage= JavaPlugin.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. |
| */ |
| public static PackageExplorerPart openInActivePerspective() { |
| try { |
| return (PackageExplorerPart)JavaPlugin.getActivePage().showView(VIEW_ID); |
| } catch(PartInitException pe) { |
| return null; |
| } |
| } |
| |
| public void dispose() { |
| if (fContextMenu != null && !fContextMenu.isDisposed()) |
| fContextMenu.dispose(); |
| getSite().getPage().removePartListener(fPartListener); |
| JavaPlugin.getDefault().getPreferenceStore().removePropertyChangeListener(this); |
| if (fViewer != null) { |
| fViewer.removeTreeListener(fExpansionListener); |
| XMLMemento memento= XMLMemento.createWriteRoot("packageexplorer"); //$NON-NLS-1$ |
| saveState(memento); |
| StringWriter writer= new StringWriter(); |
| try { |
| memento.save(writer); |
| String sectionName= getSectionName(); |
| IDialogSettings section= JavaPlugin.getDefault().getDialogSettings().getSection(sectionName); |
| if (section == null) { |
| section= JavaPlugin.getDefault().getDialogSettings().addNewSection(sectionName); |
| } |
| section.put(SETTING_MEMENTO, writer.getBuffer().toString()); |
| } catch (IOException e) { |
| // don't do anythiung. Simply don't store the settings |
| } |
| } |
| |
| if (fActionSet != null) |
| fActionSet.dispose(); |
| if (fFilterUpdater != null) |
| ResourcesPlugin.getWorkspace().removeResourceChangeListener(fFilterUpdater); |
| if (fWorkingSetModel != null) |
| fWorkingSetModel.dispose(); |
| super.dispose(); |
| } |
| |
| /** |
| * Implementation of IWorkbenchPart.createPartControl(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(); |
| |
| JavaPlugin.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); |
| site.getPage().addPartListener(fPartListener); |
| |
| if (fMemento != null) { |
| restoreLinkingEnabled(fMemento); |
| } |
| |
| 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); |
| |
| if (fMemento != null) |
| restoreUIState(fMemento); |
| fMemento= null; |
| |
| // Set help for the view |
| JavaUIHelp.setHelp(fViewer, IJavaHelpContextIds.PACKAGES_VIEW); |
| |
| fillActionBars(); |
| |
| updateTitle(); |
| |
| fFilterUpdater= new FilterUpdater(fViewer); |
| ResourcesPlugin.getWorkspace().addResourceChangeListener(fFilterUpdater); |
| |
| // Syncing 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. |
| if (isLinkingEnabled()) { |
| IEditorPart editor= getViewSite().getPage().getActiveEditor(); |
| if (editor != null) { |
| editorActivated(editor); |
| } |
| } |
| |
| stats.endRun(); |
| } |
| |
| private void initFrameActions() { |
| fActionSet.getUpAction().update(); |
| fActionSet.getBackAction().update(); |
| fActionSet.getForwardAction().update(); |
| } |
| |
| /** |
| * This viewer ensures that non-leaves in the hierarchical |
| * layout are not removed by any filters. |
| * |
| * @since 2.1 |
| */ |
| 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. |
| * |
| * @since 2.1 |
| */ |
| public boolean isFlatLayout() { |
| return fIsCurrentLayoutFlat; |
| } |
| |
| private void setProviders() { |
| //content provider must be set before the label provider |
| fContentProvider= createContentProvider(); |
| fContentProvider.setIsFlatLayout(fIsCurrentLayoutFlat); |
| fViewer.setComparer(createElementComparer()); |
| fViewer.setContentProvider(fContentProvider); |
| |
| fLabelProvider= createLabelProvider(); |
| fLabelProvider.setIsFlatLayout(fIsCurrentLayoutFlat); |
| fViewer.setLabelProvider(new DecoratingJavaLabelProvider(fLabelProvider, false, fIsCurrentLayoutFlat)); |
| // problem decoration provided by PackageLabelProvider |
| } |
| |
| void toggleLayout() { |
| |
| // Update current state and inform content and label providers |
| fIsCurrentLayoutFlat= !fIsCurrentLayoutFlat; |
| saveLayoutState(null); |
| |
| fContentProvider.setIsFlatLayout(isFlatLayout()); |
| fLabelProvider.setIsFlatLayout(isFlatLayout()); |
| ((DecoratingJavaLabelProvider) fViewer.getLabelProvider()).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. |
| */ |
| public PackageExplorerContentProvider createContentProvider() { |
| IPreferenceStore store= PreferenceConstants.getPreferenceStore(); |
| boolean showCUChildren= store.getBoolean(PreferenceConstants.SHOW_CU_CHILDREN); |
| if (showProjects()) |
| return new PackageExplorerContentProvider(showCUChildren); |
| else |
| return new WorkingSetAwareContentProvider(showCUChildren, fWorkingSetModel); |
| } |
| |
| private PackageExplorerLabelProvider createLabelProvider() { |
| if (showProjects()) |
| return new PackageExplorerLabelProvider(AppearanceAwareLabelProvider.DEFAULT_TEXTFLAGS | JavaElementLabels.P_COMPRESSED | JavaElementLabels.ALL_CATEGORY, |
| AppearanceAwareLabelProvider.DEFAULT_IMAGEFLAGS | JavaElementImageProvider.SMALL_ICONS, |
| fContentProvider); |
| else |
| return new WorkingSetAwareLabelProvider(AppearanceAwareLabelProvider.DEFAULT_TEXTFLAGS | JavaElementLabels.P_COMPRESSED, |
| AppearanceAwareLabelProvider.DEFAULT_IMAGEFLAGS | JavaElementImageProvider.SMALL_ICONS, |
| 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 JavaCore.create(((IWorkspace)input).getRoot()); |
| } else if (input instanceof IContainer) { |
| IJavaElement element= JavaCore.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 JavaCore.create(JavaPlugin.getWorkspace().getRoot()); |
| } |
| } |
| |
| /** |
| * Answer the property defined by key. |
| */ |
| 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. |
| */ |
| String getToolTipText(Object element) { |
| String result; |
| if (!(element instanceof IResource)) { |
| if (element instanceof IJavaModel) { |
| result= PackagesMessages.PackageExplorerPart_workspace; |
| } else if (element instanceof IJavaElement){ |
| result= JavaElementLabels.getTextLabel(element, JavaElementLabels.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()); |
| } |
| |
| /** |
| * @see IWorkbenchPart#setFocus() |
| */ |
| public void setFocus() { |
| fViewer.getTree().setFocus(); |
| } |
| |
| /** |
| * Returns the current selection. |
| */ |
| private ISelection getSelection() { |
| return fViewer.getSelection(); |
| } |
| |
| //---- Action handling ---------------------------------------------------------- |
| |
| /** |
| * Called when the context menu is about to open. Override |
| * to add your own context dependent menu contributions. |
| */ |
| public void menuAboutToShow(IMenuManager menu) { |
| JavaPlugin.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). |
| */ |
| 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; |
| } |
| |
| public void selectReveal(ISelection selection) { |
| selectReveal(selection, 0); |
| } |
| |
| private void selectReveal(final ISelection selection, final int count) { |
| Control ctrl= getViewer().getControl(); |
| if (ctrl == null || ctrl.isDisposed()) |
| return; |
| ISelection javaSelection= convertSelection(selection); |
| fViewer.setSelection(javaSelection, true); |
| PackageExplorerContentProvider provider= (PackageExplorerContentProvider)getViewer().getContentProvider(); |
| ISelection cs= fViewer.getSelection(); |
| // If we have Pending changes and the element could not be selected then |
| // we try it again on more time by posting the select and reveal asynchronously |
| // to the event queue. See PR http://bugs.eclipse.org/bugs/show_bug.cgi?id=30700 |
| // for a discussion of the underlying problem. |
| if (count == 0 && provider.hasPendingChanges() && !javaSelection.equals(cs)) { |
| ctrl.getDisplay().asyncExec(new Runnable() { |
| public void run() { |
| selectReveal(selection, count + 1); |
| } |
| }); |
| } |
| } |
| |
| 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 IJavaElement) { |
| return original; |
| |
| } else if (original instanceof IResource) { |
| IJavaElement je= JavaCore.create((IResource)original); |
| if (je != null && je.exists()) |
| return je; |
| |
| } else if (original instanceof IAdaptable) { |
| IAdaptable adaptable= (IAdaptable)original; |
| IJavaElement je= (IJavaElement) adaptable.getAdapter(IJavaElement.class); |
| if (je != null && je.exists()) |
| return je; |
| |
| IResource r= (IResource) adaptable.getAdapter(IResource.class); |
| if (r != null) { |
| je= JavaCore.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; |
| } |
| |
| /** |
| * Initializes the linking enabled setting from the preference store. |
| */ |
| private void initLinkingEnabled() { |
| fLinkingEnabled= PreferenceConstants.getPreferenceStore().getBoolean(PreferenceConstants.LINK_PACKAGES_TO_EDITOR); |
| } |
| |
| |
| /** |
| * Links to editor (if option enabled) |
| */ |
| 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 IJavaElement) |
| EditorUtility.revealInEditor(part, (IJavaElement)obj); |
| } |
| } |
| } |
| |
| private boolean isActivePart() { |
| return this == getSite().getPage().getActivePart(); |
| } |
| |
| |
| |
| public void saveState(IMemento memento) { |
| if (fViewer == null) { |
| // part has not been created |
| if (fMemento != null) //Keep the old state; |
| memento.putMemento(fMemento); |
| return; |
| } |
| |
| memento.putInteger(TAG_ROOT_MODE, fRootMode); |
| if (fWorkingSetModel != null) |
| fWorkingSetModel.saveState(memento); |
| |
| // disable the persisting of state which can trigger expensive operations as |
| // a side effect: see bug 52474 and 53958 |
| // saveCurrentFrame(memento); |
| // saveExpansionState(memento); |
| // saveSelectionState(memento); |
| saveLayoutState(memento); |
| saveLinkingEnabled(memento); |
| // commented out because of http://bugs.eclipse.org/bugs/show_bug.cgi?id=4676 |
| // saveScrollState(memento, fViewer.getTree()); |
| fActionSet.saveFilterAndSorterState(memento); |
| } |
| |
| /* |
| private void saveCurrentFrame(IMemento memento) { |
| FrameAction action = fActionSet.getUpAction(); |
| FrameList frameList= action.getFrameList(); |
| |
| if (frameList.getCurrentIndex() > 0) { |
| TreeFrame currentFrame = (TreeFrame) frameList.getCurrentFrame(); |
| // don't persist the working set model as the current frame |
| if (currentFrame.getInput() instanceof WorkingSetModel) |
| return; |
| IMemento frameMemento = memento.createChild(TAG_CURRENT_FRAME); |
| currentFrame.saveState(frameMemento); |
| } |
| } |
| */ |
| |
| private void saveLinkingEnabled(IMemento memento) { |
| memento.putInteger(PreferenceConstants.LINK_PACKAGES_TO_EDITOR, fLinkingEnabled ? 1 : 0); |
| } |
| |
| private void saveLayoutState(IMemento memento) { |
| if (memento != null) { |
| memento.putInteger(TAG_LAYOUT, getLayoutAsInt()); |
| } else { |
| //if memento is null save in preference store |
| IPreferenceStore store= JavaPlugin.getDefault().getPreferenceStore(); |
| store.setValue(TAG_LAYOUT, getLayoutAsInt()); |
| } |
| } |
| |
| private int getLayoutAsInt() { |
| if (fIsCurrentLayoutFlat) |
| return FLAT_LAYOUT; |
| else |
| return HIERARCHICAL_LAYOUT; |
| } |
| |
| protected void saveScrollState(IMemento memento, Tree tree) { |
| ScrollBar bar= tree.getVerticalBar(); |
| int position= bar != null ? bar.getSelection() : 0; |
| memento.putString(TAG_VERTICAL_POSITION, String.valueOf(position)); |
| //save horizontal position |
| bar= tree.getHorizontalBar(); |
| position= bar != null ? bar.getSelection() : 0; |
| memento.putString(TAG_HORIZONTAL_POSITION, String.valueOf(position)); |
| } |
| |
| protected void saveSelectionState(IMemento memento) { |
| Object elements[]= ((IStructuredSelection) fViewer.getSelection()).toArray(); |
| if (elements.length > 0) { |
| IMemento selectionMem= memento.createChild(TAG_SELECTION); |
| for (int i= 0; i < elements.length; i++) { |
| IMemento elementMem= selectionMem.createChild(TAG_ELEMENT); |
| // we can only persist JavaElements for now |
| Object o= elements[i]; |
| if (o instanceof IJavaElement) |
| elementMem.putString(TAG_PATH, ((IJavaElement) elements[i]).getHandleIdentifier()); |
| } |
| } |
| } |
| |
| protected void saveExpansionState(IMemento memento) { |
| Object expandedElements[]= fViewer.getVisibleExpandedElements(); |
| if (expandedElements.length > 0) { |
| IMemento expandedMem= memento.createChild(TAG_EXPANDED); |
| for (int i= 0; i < expandedElements.length; i++) { |
| IMemento elementMem= expandedMem.createChild(TAG_ELEMENT); |
| // we can only persist JavaElements for now |
| Object o= expandedElements[i]; |
| if (o instanceof IJavaElement) |
| elementMem.putString(TAG_PATH, ((IJavaElement) expandedElements[i]).getHandleIdentifier()); |
| } |
| } |
| } |
| |
| private void restoreFilterAndSorter() { |
| fViewer.addFilter(new OutputFolderFilter()); |
| setSorter(); |
| if (fMemento != null) |
| fActionSet.restoreFilterAndSorterState(fMemento); |
| } |
| |
| private void restoreUIState(IMemento memento) { |
| // see comment in save state |
| // restoreCurrentFrame(memento); |
| // restoreExpansionState(memento); |
| // restoreSelectionState(memento); |
| // commented out because of http://bugs.eclipse.org/bugs/show_bug.cgi?id=4676 |
| // restoreScrollState(memento, fViewer.getTree()); |
| } |
| |
| /* |
| private void restoreCurrentFrame(IMemento memento) { |
| IMemento frameMemento = memento.getChild(TAG_CURRENT_FRAME); |
| |
| if (frameMemento != null) { |
| FrameAction action = fActionSet.getUpAction(); |
| FrameList frameList= action.getFrameList(); |
| TreeFrame frame = new TreeFrame(fViewer); |
| frame.restoreState(frameMemento); |
| frame.setName(getFrameName(frame.getInput())); |
| frame.setToolTipText(getToolTipText(frame.getInput())); |
| frameList.gotoFrame(frame); |
| } |
| } |
| */ |
| |
| private void restoreLinkingEnabled(IMemento memento) { |
| Integer val= memento.getInteger(PreferenceConstants.LINK_PACKAGES_TO_EDITOR); |
| if (val != null) { |
| fLinkingEnabled= val.intValue() != 0; |
| } |
| } |
| |
| protected void restoreScrollState(IMemento memento, Tree tree) { |
| ScrollBar bar= tree.getVerticalBar(); |
| if (bar != null) { |
| try { |
| String posStr= memento.getString(TAG_VERTICAL_POSITION); |
| int position; |
| position= new Integer(posStr).intValue(); |
| bar.setSelection(position); |
| } catch (NumberFormatException e) { |
| // ignore, don't set scrollposition |
| } |
| } |
| bar= tree.getHorizontalBar(); |
| if (bar != null) { |
| try { |
| String posStr= memento.getString(TAG_HORIZONTAL_POSITION); |
| int position; |
| position= new Integer(posStr).intValue(); |
| bar.setSelection(position); |
| } catch (NumberFormatException e) { |
| // ignore don't set scroll position |
| } |
| } |
| } |
| |
| protected void restoreSelectionState(IMemento memento) { |
| IMemento childMem; |
| childMem= memento.getChild(TAG_SELECTION); |
| if (childMem != null) { |
| ArrayList list= new ArrayList(); |
| IMemento[] elementMem= childMem.getChildren(TAG_ELEMENT); |
| for (int i= 0; i < elementMem.length; i++) { |
| Object element= JavaCore.create(elementMem[i].getString(TAG_PATH)); |
| if (element != null) |
| list.add(element); |
| } |
| fViewer.setSelection(new StructuredSelection(list)); |
| } |
| } |
| |
| protected void restoreExpansionState(IMemento memento) { |
| IMemento childMem= memento.getChild(TAG_EXPANDED); |
| if (childMem != null) { |
| ArrayList elements= new ArrayList(); |
| IMemento[] elementMem= childMem.getChildren(TAG_ELEMENT); |
| for (int i= 0; i < elementMem.length; i++) { |
| Object element= JavaCore.create(elementMem[i].getString(TAG_PATH)); |
| if (element != null) |
| elements.add(element); |
| } |
| fViewer.setExpandedElements(elements.toArray()); |
| } |
| } |
| |
| /** |
| * 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. |
| */ |
| void editorActivated(IEditorPart editor) { |
| if (!isLinkingEnabled()) |
| return; |
| Object input= getElementOfInput(editor.getEditorInput()); |
| if (input == null) |
| return; |
| if (!inputIsSelected(editor.getEditorInput())) |
| showInput(input); |
| else |
| getTreeViewer().getTree().showSelection(); |
| } |
| |
| 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 (JavaModelException e1) { |
| return false; |
| } |
| return input.equals(selectionAsInput); |
| } |
| |
| boolean showInput(Object input) { |
| Object element= null; |
| |
| if (input instanceof IFile && isOnClassPath((IFile)input)) { |
| element= JavaCore.create((IFile)input); |
| } |
| |
| if (element == null) // try a non Java resource |
| element= input; |
| |
| 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) { |
| IJavaProject jproject= JavaCore.create(file.getProject()); |
| return jproject.isOnClasspath(file); |
| } |
| |
| /** |
| * Returns the element's parent. |
| * |
| * @return the parent or <code>null</code> if there's no parent |
| */ |
| private Object getParent(Object element) { |
| if (element instanceof IJavaElement) |
| return ((IJavaElement)element).getParent(); |
| else if (element instanceof IResource) |
| return ((IResource)element).getParent(); |
| // else if (element instanceof IStorage) { |
| // can't get parent - see bug 22376 |
| // } |
| return null; |
| } |
| |
| /** |
| * A compilation unit or class was expanded, expand |
| * the main type. |
| */ |
| void expandMainType(Object element) { |
| try { |
| IType type= null; |
| if (element instanceof ICompilationUnit) { |
| ICompilationUnit cu= (ICompilationUnit)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(JavaModelException e) { |
| // no reveal |
| } |
| } |
| |
| /** |
| * Returns the element contained in the EditorInput |
| */ |
| Object getElementOfInput(IEditorInput input) { |
| if (input instanceof IClassFileEditorInput) |
| return ((IClassFileEditorInput)input).getClassFile(); |
| else if (input instanceof IFileEditorInput) |
| return ((IFileEditorInput)input).getFile(); |
| else if (input instanceof JarEntryEditorInput) |
| return ((JarEntryEditorInput)input).getStorage(); |
| return null; |
| } |
| |
| /** |
| * Returns the Viewer. |
| */ |
| TreeViewer getViewer() { |
| return fViewer; |
| } |
| |
| /** |
| * Returns the TreeViewer. |
| */ |
| 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 IJavaModel)) { |
| setContentDescription(""); //$NON-NLS-1$ |
| setTitleToolTip(""); //$NON-NLS-1$ |
| } else { |
| String inputText= JavaElementLabels.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); |
| ((StandardJavaElementContentProvider)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); |
| } |
| } |
| |
| public PackageExplorerPart() { |
| initLinkingEnabled(); |
| fPostSelectionListener= new ISelectionChangedListener() { |
| public void selectionChanged(SelectionChangedEvent event) { |
| handlePostSelectionChanged(event); |
| } |
| }; |
| } |
| |
| 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 && tryToReveal(structuredSelection.getFirstElement())) |
| return true; |
| } |
| |
| Object input= context.getInput(); |
| if (input instanceof IEditorInput) { |
| Object elementOfInput= getElementOfInput((IEditorInput)context.getInput()); |
| return elementOfInput != null && tryToReveal(elementOfInput); |
| } |
| |
| return false; |
| } |
| |
| /** |
| * Returns the <code>IShowInSource</code> for this view. |
| */ |
| protected IShowInSource getShowInSource() { |
| return new IShowInSource() { |
| public ShowInContext getShowInContext() { |
| return new ShowInContext( |
| getViewer().getInput(), |
| getViewer().getSelection()); |
| } |
| }; |
| } |
| |
| /* |
| * @see org.eclipse.ui.views.navigator.IResourceNavigator#setLinkingEnabled(boolean) |
| * @since 2.1 |
| */ |
| public void setLinkingEnabled(boolean enabled) { |
| fLinkingEnabled= enabled; |
| PreferenceConstants.getPreferenceStore().setValue(PreferenceConstants.LINK_PACKAGES_TO_EDITOR, enabled); |
| |
| if (enabled) { |
| IEditorPart editor = getSite().getPage().getActiveEditor(); |
| if (editor != null) { |
| editorActivated(editor); |
| } |
| } |
| } |
| |
| /** |
| * Returns the name for the given element. |
| * Used as the name for the current frame. |
| */ |
| String getFrameName(Object element) { |
| if (element instanceof IJavaElement) { |
| return ((IJavaElement) element).getElementName(); |
| } else if (element instanceof WorkingSetModel) { |
| return ""; //$NON-NLS-1$ |
| } else { |
| return fLabelProvider.getText(element); |
| } |
| } |
| |
| void projectStateChanged(Object root) { |
| Control ctrl= fViewer.getControl(); |
| if (ctrl != null && !ctrl.isDisposed()) { |
| fViewer.refresh(root, true); |
| // trigger a syntetic selection change so that action refresh their |
| // enable state. |
| fViewer.setSelection(fViewer.getSelection()); |
| } |
| } |
| |
| public boolean tryToReveal(Object element) { |
| if (revealElementOrParent(element)) |
| return true; |
| |
| WorkingSetFilterActionGroup workingSetGroup= fActionSet.getWorkingSetActionGroup().getFilterGroup(); |
| if (workingSetGroup != null) { |
| IWorkingSet workingSet= workingSetGroup.getWorkingSet(); |
| if (workingSetGroup.isFiltered(getVisibleParent(element), element)) { |
| String 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 true; |
| } |
| } |
| } |
| // 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= PackagesMessages.PackageExplorer_removeFilters; |
| if (MessageDialog.openQuestion(getSite().getShell(), PackagesMessages.PackageExplorer_filteredDialog_title, message)) { |
| filterGroup.setFilters(newFilters); |
| if (revealElementOrParent(element)) |
| return true; |
| } |
| } |
| 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 true; |
| } |
| return false; |
| } |
| |
| private boolean revealElementOrParent(Object element) { |
| if (revealAndVerify(element)) |
| return true; |
| element= getVisibleParent(element); |
| if (element != null) { |
| if (revealAndVerify(element)) |
| return true; |
| if (element instanceof IJavaElement) { |
| IResource resource= ((IJavaElement)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 IJavaElement)) |
| return object; |
| IJavaElement element2= (IJavaElement) object; |
| switch (element2.getElementType()) { |
| case IJavaElement.IMPORT_DECLARATION: |
| case IJavaElement.PACKAGE_DECLARATION: |
| case IJavaElement.IMPORT_CONTAINER: |
| case IJavaElement.TYPE: |
| case IJavaElement.METHOD: |
| case IJavaElement.FIELD: |
| case IJavaElement.INITIALIZER: |
| // select parent cu/classfile |
| element2= (IJavaElement)element2.getOpenable(); |
| break; |
| case IJavaElement.JAVA_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; |
| 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= JavaCore.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(); |
| setSorter(); |
| 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= fMemento != null |
| ? new WorkingSetModel(fMemento) |
| : new WorkingSetModel(); |
| } |
| public void handleException(Throwable exception) { |
| fWorkingSetModel= new WorkingSetModel(); |
| } |
| }); |
| } |
| |
| 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 setSorter() { |
| if (showWorkingSets()) { |
| fViewer.setSorter(new WorkingSetAwareJavaElementSorter()); |
| } else { |
| fViewer.setSorter(new JavaElementSorter()); |
| } |
| } |
| |
| //---- 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); |
| } |
| } |