KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > ui > wizards > buildpaths > newsourcepage > DialogPackageExplorer


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11
12 package org.eclipse.jdt.internal.ui.wizards.buildpaths.newsourcepage;
13
14 import java.util.ArrayList JavaDoc;
15 import java.util.List JavaDoc;
16
17 import org.eclipse.core.runtime.CoreException;
18 import org.eclipse.core.runtime.IProgressMonitor;
19 import org.eclipse.core.runtime.NullProgressMonitor;
20
21 import org.eclipse.core.resources.IFile;
22 import org.eclipse.core.resources.IFolder;
23 import org.eclipse.core.resources.IResource;
24 import org.eclipse.core.resources.IWorkspace;
25 import org.eclipse.core.resources.IWorkspaceRunnable;
26 import org.eclipse.core.resources.ResourcesPlugin;
27
28 import org.eclipse.swt.SWT;
29 import org.eclipse.swt.events.DisposeEvent;
30 import org.eclipse.swt.events.DisposeListener;
31 import org.eclipse.swt.graphics.Color;
32 import org.eclipse.swt.graphics.Image;
33 import org.eclipse.swt.widgets.Composite;
34 import org.eclipse.swt.widgets.Control;
35 import org.eclipse.swt.widgets.Display;
36 import org.eclipse.swt.widgets.Menu;
37
38 import org.eclipse.jface.action.IMenuListener;
39 import org.eclipse.jface.action.IMenuManager;
40 import org.eclipse.jface.action.MenuManager;
41 import org.eclipse.jface.viewers.DoubleClickEvent;
42 import org.eclipse.jface.viewers.IDoubleClickListener;
43 import org.eclipse.jface.viewers.IPostSelectionProvider;
44 import org.eclipse.jface.viewers.ISelection;
45 import org.eclipse.jface.viewers.ISelectionChangedListener;
46 import org.eclipse.jface.viewers.ISelectionProvider;
47 import org.eclipse.jface.viewers.IStructuredSelection;
48 import org.eclipse.jface.viewers.StructuredSelection;
49 import org.eclipse.jface.viewers.TreeViewer;
50 import org.eclipse.jface.viewers.Viewer;
51
52 import org.eclipse.ui.part.ISetSelectionTarget;
53
54 import org.eclipse.jdt.core.IClasspathEntry;
55 import org.eclipse.jdt.core.IJavaProject;
56 import org.eclipse.jdt.core.IPackageFragment;
57 import org.eclipse.jdt.core.IPackageFragmentRoot;
58 import org.eclipse.jdt.core.JavaModelException;
59
60 import org.eclipse.jdt.internal.corext.buildpath.ClasspathModifier;
61 import org.eclipse.jdt.internal.corext.util.Messages;
62
63 import org.eclipse.jdt.ui.JavaElementComparator;
64 import org.eclipse.jdt.ui.JavaElementLabels;
65
66 import org.eclipse.jdt.internal.ui.JavaPlugin;
67 import org.eclipse.jdt.internal.ui.filters.LibraryFilter;
68 import org.eclipse.jdt.internal.ui.filters.OutputFolderFilter;
69 import org.eclipse.jdt.internal.ui.packageview.PackageExplorerContentProvider;
70 import org.eclipse.jdt.internal.ui.packageview.PackageFragmentRootContainer;
71 import org.eclipse.jdt.internal.ui.viewsupport.AppearanceAwareLabelProvider;
72 import org.eclipse.jdt.internal.ui.viewsupport.DecoratingJavaLabelProvider;
73 import org.eclipse.jdt.internal.ui.viewsupport.JavaElementImageProvider;
74 import org.eclipse.jdt.internal.ui.wizards.NewWizardMessages;
75 import org.eclipse.jdt.internal.ui.wizards.buildpaths.CPListElement;
76 import org.eclipse.jdt.internal.ui.wizards.buildpaths.CPListElementAttribute;
77 import org.eclipse.jdt.internal.ui.wizards.buildpaths.CPListLabelProvider;
78 import org.eclipse.jdt.internal.ui.workingsets.WorkingSetModel;
79
80 /**
81  * A package explorer widget that can be used in dialogs. It uses its own
82  * content provider, label provider, element sorter and filter to display
83  * elements that are not shown usually in the package explorer of the
84  * workspace.
85  */

86 public class DialogPackageExplorer implements IMenuListener, ISelectionProvider, IPostSelectionProvider, ISetSelectionTarget {
87     /**
88      * A extended content provider for the package explorer which can additionally display
89      * an output folder item.
90      */

91     private final class PackageContentProvider extends PackageExplorerContentProvider {
92         public PackageContentProvider() {
93             super(false);
94         }
95         
96         /**
97          * Get the elements of the current project
98          *
99          * @param element the element to get the children from, will
100          * not be used, instead the project children are returned directly
101          * @return returns the children of the project
102          */

103         public Object JavaDoc[] getElements(Object JavaDoc element) {
104             if (fCurrJProject == null || !fCurrJProject.exists())
105                 return new Object JavaDoc[0];
106             return new Object JavaDoc[] {fCurrJProject};
107         }
108         
109         /**
110          * Get the children of the current <code>element</code>. If the
111          * element is of type <code>IPackageFragmentRoot</code> and
112          * displaying the output folders is selected, then an icon for
113          * the output folder is created and displayed additionally.
114          *
115          * @param element the current element to get the children from
116          * @return an array of children
117          */

118         public Object JavaDoc[] getChildren(Object JavaDoc element) {
119             Object JavaDoc[] children= super.getChildren(element);
120             if (((element instanceof IPackageFragmentRoot && !((IPackageFragmentRoot)element).isArchive()) ||
121                     (element instanceof IJavaProject && fCurrJProject.isOnClasspath(fCurrJProject))) && fShowOutputFolders) {
122                 try {
123                     IClasspathEntry entry;
124                     if (element instanceof IPackageFragmentRoot)
125                         entry= ((IPackageFragmentRoot) element).getRawClasspathEntry();
126                     else
127                         entry= ClasspathModifier.getClasspathEntryFor(fCurrJProject.getPath(), fCurrJProject, IClasspathEntry.CPE_SOURCE);
128                     CPListElement parent= CPListElement.createFromExisting(entry, fCurrJProject);
129                     CPListElementAttribute outputFolder= new CPListElementAttribute(parent, CPListElement.OUTPUT,
130                             parent.getAttribute(CPListElement.OUTPUT), true);
131                     Object JavaDoc[] extendedChildren= new Object JavaDoc[children.length + 1];
132                     System.arraycopy(children, 0, extendedChildren, 1, children.length);
133                     extendedChildren[0]= outputFolder;
134                     return extendedChildren;
135                 } catch (JavaModelException e) {
136                     JavaPlugin.log(e);
137                 }
138                 return null;
139             }
140             else
141                 return children;
142         }
143     }
144     
145     /**
146      * A extended label provider for the package explorer which can additionally display
147      * an output folder item.
148      */

149     private final class PackageLabelProvider extends AppearanceAwareLabelProvider {
150         private CPListLabelProvider outputFolderLabel;
151         
152         public PackageLabelProvider(long textFlags, int imageFlags) {
153             super(textFlags, imageFlags);
154             outputFolderLabel= new CPListLabelProvider();
155         }
156         
157         public String JavaDoc getText(Object JavaDoc element) {
158             if (element instanceof CPListElementAttribute)
159                 return outputFolderLabel.getText(element);
160             String JavaDoc text= super.getText(element);
161             try {
162                 if (element instanceof IPackageFragmentRoot) {
163                     IPackageFragmentRoot root= (IPackageFragmentRoot)element;
164                     if (root.exists() && ClasspathModifier.filtersSet(root)) {
165                         IClasspathEntry entry= root.getRawClasspathEntry();
166                         int excluded= entry.getExclusionPatterns().length;
167                         if (excluded == 1)
168                             return Messages.format(NewWizardMessages.DialogPackageExplorer_LabelProvider_SingleExcluded, text);
169                         else if (excluded > 1)
170                             return Messages.format(NewWizardMessages.DialogPackageExplorer_LabelProvider_MultiExcluded, new Object JavaDoc[] {text, new Integer JavaDoc(excluded)});
171                     }
172                 }
173                 if (element instanceof IJavaProject) {
174                     IJavaProject project= (IJavaProject)element;
175                     if (project.exists() && project.isOnClasspath(project)) {
176                         IPackageFragmentRoot root= project.findPackageFragmentRoot(project.getPath());
177                         if (ClasspathModifier.filtersSet(root)) {
178                             IClasspathEntry entry= root.getRawClasspathEntry();
179                             int excluded= entry.getExclusionPatterns().length;
180                             if (excluded == 1)
181                                 return Messages.format(NewWizardMessages.DialogPackageExplorer_LabelProvider_SingleExcluded, text);
182                             else if (excluded > 1)
183                                 return Messages.format(NewWizardMessages.DialogPackageExplorer_LabelProvider_MultiExcluded, new Object JavaDoc[] {text, new Integer JavaDoc(excluded)});
184                         }
185                     }
186                 }
187                 if (element instanceof IFile || element instanceof IFolder) {
188                     IResource resource= (IResource)element;
189                         if (resource.exists() && ClasspathModifier.isExcluded(resource, fCurrJProject))
190                             return Messages.format(NewWizardMessages.DialogPackageExplorer_LabelProvider_Excluded, text);
191                 }
192             } catch (JavaModelException e) {
193                 JavaPlugin.log(e);
194             }
195             return text;
196         }
197         
198         /* (non-Javadoc)
199          * @see org.eclipse.jdt.internal.ui.viewsupport.JavaUILabelProvider#getForeground(java.lang.Object)
200          */

201         public Color getForeground(Object JavaDoc element) {
202             try {
203                 if (element instanceof IPackageFragmentRoot) {
204                     IPackageFragmentRoot root= (IPackageFragmentRoot)element;
205                     if (root.exists() && ClasspathModifier.filtersSet(root))
206                         return getBlueColor();
207                 }
208                 if (element instanceof IJavaProject) {
209                     IJavaProject project= (IJavaProject)element;
210                     if (project.exists() && project.isOnClasspath(project)) {
211                         IPackageFragmentRoot root= project.findPackageFragmentRoot(project.getPath());
212                         if (root != null && ClasspathModifier.filtersSet(root))
213                             return getBlueColor();
214                     }
215                 }
216                 if (element instanceof IFile || element instanceof IFolder) {
217                     IResource resource= (IResource)element;
218                     if (resource.exists() && ClasspathModifier.isExcluded(resource, fCurrJProject))
219                         return getBlueColor();
220                 }
221             } catch (JavaModelException e) {
222                 JavaPlugin.log(e);
223             }
224             return null;
225         }
226         
227         private Color getBlueColor() {
228             return Display.getCurrent().getSystemColor(SWT.COLOR_BLUE);
229         }
230         
231         public Image getImage(Object JavaDoc element) {
232             if (element instanceof CPListElementAttribute)
233                 return outputFolderLabel.getImage(element);
234             return super.getImage(element);
235         }
236         
237         public void dispose() {
238             outputFolderLabel.dispose();
239             super.dispose();
240         }
241     }
242     
243     /**
244      * A extended element sorter for the package explorer which displays the output
245      * folder (if any) as first child of a source folder. The other java elements
246      * are sorted in the normal way.
247      */

248     private final class ExtendedJavaElementSorter extends JavaElementComparator {
249         public ExtendedJavaElementSorter() {
250             super();
251         }
252         
253         public int compare(Viewer viewer, Object JavaDoc e1, Object JavaDoc e2) {
254             if (e1 instanceof CPListElementAttribute)
255                 return -1;
256             if (e2 instanceof CPListElementAttribute)
257                 return 1;
258             return super.compare(viewer, e1, e2);
259         }
260     }
261     
262     /**
263      * An extended filter for the package explorer which filters
264      * libraries,
265      * files named ".classpath" or ".project",
266      * the default package, and
267      * hidden folders.
268      */

269     private final class PackageFilter extends LibraryFilter {
270         private OutputFolderFilter fOutputFolderFilter= new OutputFolderFilter();
271         public boolean select(Viewer viewer, Object JavaDoc parentElement, Object JavaDoc element) {
272             try {
273                 if (element instanceof IFile) {
274                     IFile file= (IFile) element;
275                     if (file.getName().equals(".classpath") || file.getName().equals(".project")) //$NON-NLS-1$//$NON-NLS-2$
276
return false;
277                 } else if (element instanceof IPackageFragmentRoot) {
278                     IClasspathEntry cpe= ((IPackageFragmentRoot)element).getRawClasspathEntry();
279                     if (cpe == null || cpe.getEntryKind() == IClasspathEntry.CPE_CONTAINER || cpe.getEntryKind() == IClasspathEntry.CPE_LIBRARY || cpe.getEntryKind() == IClasspathEntry.CPE_VARIABLE)
280                         return false;
281                 } else if (element instanceof PackageFragmentRootContainer) {
282                     return false;
283                 } else if (element instanceof IPackageFragment) {
284                     IPackageFragment fragment= (IPackageFragment)element;
285                     if (fragment.isDefaultPackage() && !fragment.hasChildren())
286                         return false;
287                 } else if (element instanceof IFolder) {
288                     IFolder folder= (IFolder)element;
289                     if (folder.getName().startsWith(".")) //$NON-NLS-1$
290
return false;
291                 }
292             } catch (JavaModelException e) {
293                 JavaPlugin.log(e);
294             }
295             /*if (element instanceof IPackageFragmentRoot) {
296                 IPackageFragmentRoot root= (IPackageFragmentRoot)element;
297                 if (root.getElementName().endsWith(".jar") || root.getElementName().endsWith(".zip")) //$NON-NLS-1$ //$NON-NLS-2$
298                     return false;
299             }*/

300             return /*super.select(viewer, parentElement, element) &&*/ fOutputFolderFilter.select(viewer, parentElement, element);
301         }
302     }
303     
304     /** The tree showing the project like in the package explorer */
305     private TreeViewer fPackageViewer;
306     /** The tree's context menu */
307     private Menu fContextMenu;
308     /** The action group which is used to fill the context menu. The action group
309      * is also called if the selection on the tree changes */

310     private DialogPackageExplorerActionGroup fActionGroup;
311     /**
312      * Flag to indicate whether output folders
313      * can be created or not. This is used to
314      * set the content correctly in the case
315      * that a IPackageFragmentRoot is selected.
316      *
317      * @see #showOutputFolders(boolean)
318      */

319     private boolean fShowOutputFolders= false;
320     
321     /** Stores the current selection in the tree
322      * @see #getSelection()
323      */

324     private IStructuredSelection fCurrentSelection;
325     
326     /** The current java project
327      * @see #setInput(IJavaProject)
328      */

329     private IJavaProject fCurrJProject;
330     private PackageContentProvider fContentProvider;
331     
332     public DialogPackageExplorer() {
333         fActionGroup= null;
334         fCurrJProject= null;
335         fCurrentSelection= new StructuredSelection();
336     }
337     
338     public Control createControl(Composite parent) {
339         fPackageViewer= new TreeViewer(parent, SWT.MULTI);
340         fPackageViewer.setComparer(WorkingSetModel.COMPARER);
341         fPackageViewer.addFilter(new PackageFilter());
342         fPackageViewer.setComparator(new ExtendedJavaElementSorter());
343         fPackageViewer.addDoubleClickListener(new IDoubleClickListener() {
344             public void doubleClick(DoubleClickEvent event) {
345                 Object JavaDoc element= ((IStructuredSelection)event.getSelection()).getFirstElement();
346                 if (fPackageViewer.isExpandable(element)) {
347                     fPackageViewer.setExpandedState(element, !fPackageViewer.getExpandedState(element));
348                 } else {
349                     if (element instanceof CPListElementAttribute) {
350                         CPListElementAttribute attribute= (CPListElementAttribute)element;
351                         if (attribute.getKey().equals(CPListElement.OUTPUT)) {
352                             fActionGroup.getEditOutputFolderAction().run();
353                         }
354                     }
355                 }
356             }
357         });
358         
359         MenuManager menuMgr= new MenuManager("#PopupMenu"); //$NON-NLS-1$
360
menuMgr.setRemoveAllWhenShown(true);
361         menuMgr.addMenuListener(this);
362         fContextMenu= menuMgr.createContextMenu(fPackageViewer.getTree());
363         fPackageViewer.getTree().setMenu(fContextMenu);
364         parent.addDisposeListener(new DisposeListener() {
365             public void widgetDisposed(DisposeEvent e) {
366                 fContextMenu.dispose();
367             }
368         });
369         
370         return fPackageViewer.getControl();
371     }
372     
373     /**
374      * Sets the action group for the package explorer.
375      * The action group is necessary to populate the
376      * context menu with available actions. If no
377      * context menu is needed, then this method does not
378      * have to be called.
379      *
380      * Should only be called once.
381      *
382      * @param actionGroup the action group to be used for
383      * the context menu.
384      */

385     public void setActionGroup(final DialogPackageExplorerActionGroup actionGroup) {
386         fActionGroup= actionGroup;
387     }
388     
389     /**
390      * Populate the context menu with the necessary actions.
391      *
392      * @see org.eclipse.jface.action.IMenuListener#menuAboutToShow(org.eclipse.jface.action.IMenuManager)
393      */

394     public void menuAboutToShow(IMenuManager manager) {
395         if (fActionGroup == null) // no context menu
396
return;
397         JavaPlugin.createStandardGroups(manager);
398         fActionGroup.fillContextMenu(manager);
399     }
400     
401     /**
402      * Set the content and label provider of the
403      * <code>fPackageViewer</code>
404      */

405     public void setContentProvider() {
406         if (fContentProvider != null) {
407             fContentProvider.dispose();
408         }
409         fContentProvider= new PackageContentProvider();
410         fContentProvider.setIsFlatLayout(true);
411         PackageLabelProvider labelProvider= new PackageLabelProvider(AppearanceAwareLabelProvider.DEFAULT_TEXTFLAGS | JavaElementLabels.P_COMPRESSED,
412                 AppearanceAwareLabelProvider.DEFAULT_IMAGEFLAGS | JavaElementImageProvider.SMALL_ICONS);
413         fPackageViewer.setContentProvider(fContentProvider);
414         fPackageViewer.setLabelProvider(new DecoratingJavaLabelProvider(labelProvider, false));
415     }
416     
417     /**
418      * Set the input for the package explorer.
419      *
420      * @param project the project to be displayed
421      */

422     public void setInput(IJavaProject project) {
423         IJavaProject oldProject= fCurrJProject;
424         fCurrJProject= project;
425         if (fContentProvider != null)
426             fContentProvider.inputChanged(fPackageViewer, oldProject, fCurrJProject);
427         fPackageViewer.setInput(new Object JavaDoc[0]);
428         
429         List JavaDoc selectedElements= new ArrayList JavaDoc();
430         selectedElements.add(fCurrJProject);
431         setSelection(selectedElements);
432     }
433     
434     public void dispose() {
435         if (fContentProvider != null) {
436             fContentProvider.dispose();
437             fContentProvider= null;
438         }
439         if (fActionGroup != null) {
440             fActionGroup.dispose();
441             fActionGroup= null;
442         }
443         fPackageViewer= null;
444     }
445     
446     /**
447      * Set the selection and focus to the list of elements
448      * @param elements the object to be selected and displayed
449      */

450     public void setSelection(final List JavaDoc elements) {
451         if (elements == null || elements.size() == 0)
452             return;
453         try {
454             ResourcesPlugin.getWorkspace().run(new IWorkspaceRunnable() {
455                 public void run(IProgressMonitor monitor) throws CoreException {
456                     fPackageViewer.refresh();
457                     IStructuredSelection selection= new StructuredSelection(elements);
458                     fPackageViewer.setSelection(selection, true);
459                     fPackageViewer.getTree().setFocus();
460                     
461                     if (elements.size() == 1 && elements.get(0) instanceof IJavaProject)
462                         fPackageViewer.expandToLevel(elements.get(0), 1);
463                 }
464             }, ResourcesPlugin.getWorkspace().getRoot(), IWorkspace.AVOID_UPDATE, new NullProgressMonitor());
465         } catch (CoreException e) {
466             JavaPlugin.log(e);
467         }
468     }
469     
470     /**
471      * The current list of selected elements. The
472      * list may be empty if no element is selected.
473      *
474      * @return the current selection
475      */

476     public ISelection getSelection() {
477         return fCurrentSelection;
478     }
479     
480     /**
481      * Get the viewer's control
482      *
483      * @return the viewers control
484      */

485     public Control getViewerControl() {
486         return fPackageViewer.getControl();
487     }
488     
489     /**
490      * Method that is called whenever setting of
491      * output folders is allowed or forbidden (for example
492      * on changing a checkbox with this setting):
493      *
494      * @param showOutputFolders <code>true</code> if output
495      * folders should be shown, <code>false</code> otherwise.
496      */

497     public void showOutputFolders(boolean showOutputFolders) {
498         fShowOutputFolders= showOutputFolders;
499         fActionGroup.getEditOutputFolderAction().showOutputFolders(showOutputFolders);
500         fPackageViewer.refresh();
501     }
502
503     /**
504      * {@inheritDoc}
505      */

506     public void addSelectionChangedListener(ISelectionChangedListener listener) {
507         fPackageViewer.addSelectionChangedListener(listener);
508     }
509
510     /**
511      * {@inheritDoc}
512      */

513     public void removeSelectionChangedListener(ISelectionChangedListener listener) {
514         fPackageViewer.removeSelectionChangedListener(listener);
515     }
516
517     /**
518      * {@inheritDoc}
519      */

520     public void setSelection(ISelection selection) {
521         setSelection(((StructuredSelection)selection).toList());
522     }
523
524     /**
525      * {@inheritDoc}
526      */

527     public void addPostSelectionChangedListener(ISelectionChangedListener listener) {
528         fPackageViewer.addPostSelectionChangedListener(listener);
529     }
530
531     /**
532      * {@inheritDoc}
533      */

534     public void removePostSelectionChangedListener(ISelectionChangedListener listener) {
535         fPackageViewer.removePostSelectionChangedListener(listener);
536     }
537
538     /**
539      * {@inheritDoc}
540      */

541     public void selectReveal(ISelection selection) {
542         setSelection(selection);
543     }
544 }
545
Popular Tags