001: /*******************************************************************************
002: * Copyright (c) 2000, 2007 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.jdt.internal.ui.browsing;
011:
012: import org.eclipse.swt.SWT;
013: import org.eclipse.swt.widgets.Composite;
014:
015: import org.eclipse.jface.action.IToolBarManager;
016: import org.eclipse.jface.util.IPropertyChangeListener;
017: import org.eclipse.jface.util.PropertyChangeEvent;
018: import org.eclipse.jface.viewers.DoubleClickEvent;
019: import org.eclipse.jface.viewers.IDoubleClickListener;
020: import org.eclipse.jface.viewers.IStructuredSelection;
021: import org.eclipse.jface.viewers.StructuredViewer;
022: import org.eclipse.jface.viewers.TreeViewer;
023:
024: import org.eclipse.ui.IActionBars;
025: import org.eclipse.ui.IEditorPart;
026: import org.eclipse.ui.IMemento;
027: import org.eclipse.ui.part.IShowInTargetList;
028:
029: import org.eclipse.jdt.core.IClassFile;
030: import org.eclipse.jdt.core.ICompilationUnit;
031: import org.eclipse.jdt.core.IImportContainer;
032: import org.eclipse.jdt.core.IImportDeclaration;
033: import org.eclipse.jdt.core.IJavaElement;
034: import org.eclipse.jdt.core.IMember;
035: import org.eclipse.jdt.core.IType;
036: import org.eclipse.jdt.core.JavaModelException;
037:
038: import org.eclipse.jdt.ui.JavaElementLabels;
039: import org.eclipse.jdt.ui.JavaUI;
040: import org.eclipse.jdt.ui.PreferenceConstants;
041: import org.eclipse.jdt.ui.actions.MemberFilterActionGroup;
042:
043: import org.eclipse.jdt.internal.ui.IJavaHelpContextIds;
044: import org.eclipse.jdt.internal.ui.JavaPlugin;
045: import org.eclipse.jdt.internal.ui.actions.CategoryFilterActionGroup;
046: import org.eclipse.jdt.internal.ui.actions.LexicalSortingAction;
047: import org.eclipse.jdt.internal.ui.preferences.MembersOrderPreferenceCache;
048: import org.eclipse.jdt.internal.ui.viewsupport.AppearanceAwareLabelProvider;
049: import org.eclipse.jdt.internal.ui.viewsupport.ColoredViewersManager;
050: import org.eclipse.jdt.internal.ui.viewsupport.JavaUILabelProvider;
051: import org.eclipse.jdt.internal.ui.viewsupport.ProblemTreeViewer;
052:
053: public class MembersView extends JavaBrowsingPart implements
054: IPropertyChangeListener {
055:
056: private MemberFilterActionGroup fMemberFilterActionGroup;
057: /**
058: * Category filter action group.
059: * @since 3.2
060: */
061: private CategoryFilterActionGroup fCategoryFilterActionGroup;
062:
063: public MembersView() {
064: setHasWorkingSetFilter(false);
065: setHasCustomSetFilter(true);
066: JavaPlugin.getDefault().getPreferenceStore()
067: .addPropertyChangeListener(this );
068: }
069:
070: /* (non-Javadoc)
071: * @see org.eclipse.jdt.internal.ui.browsing.JavaBrowsingPart#getAdapter(java.lang.Class)
072: */
073: public Object getAdapter(Class key) {
074: if (key == IShowInTargetList.class) {
075: return new IShowInTargetList() {
076: public String[] getShowInTargetIds() {
077: return new String[] { JavaUI.ID_PACKAGES };
078: }
079:
080: };
081: }
082: return super .getAdapter(key);
083: }
084:
085: /**
086: * Creates and returns the label provider for this part.
087: *
088: * @return the label provider
089: * @see org.eclipse.jface.viewers.ILabelProvider
090: */
091: protected JavaUILabelProvider createLabelProvider() {
092: return new AppearanceAwareLabelProvider(
093: AppearanceAwareLabelProvider.DEFAULT_TEXTFLAGS
094: | JavaElementLabels.F_APP_TYPE_SIGNATURE
095: | JavaElementLabels.ALL_CATEGORY,
096: AppearanceAwareLabelProvider.DEFAULT_IMAGEFLAGS);
097: }
098:
099: /**
100: * Returns the context ID for the Help system
101: *
102: * @return the string used as ID for the Help context
103: */
104: protected String getHelpContextId() {
105: return IJavaHelpContextIds.MEMBERS_VIEW;
106: }
107:
108: protected String getLinkToEditorKey() {
109: return PreferenceConstants.LINK_BROWSING_MEMBERS_TO_EDITOR;
110: }
111:
112: /* (non-Javadoc)
113: * @see org.eclipse.jdt.internal.ui.browsing.JavaBrowsingPart#createViewer(org.eclipse.swt.widgets.Composite)
114: */
115: protected StructuredViewer createViewer(Composite parent) {
116: ProblemTreeViewer viewer = new ProblemTreeViewer(parent,
117: SWT.MULTI);
118: ColoredViewersManager.install(viewer);
119: fMemberFilterActionGroup = new MemberFilterActionGroup(viewer,
120: JavaUI.ID_MEMBERS_VIEW);
121: return viewer;
122: }
123:
124: protected void fillToolBar(IToolBarManager tbm) {
125: tbm.add(new LexicalSortingAction(getViewer(),
126: JavaUI.ID_MEMBERS_VIEW, getDropSupport()));
127: fMemberFilterActionGroup.contributeToToolBar(tbm);
128: super .fillToolBar(tbm);
129: }
130:
131: /*
132: * @see org.eclipse.jdt.internal.ui.browsing.JavaBrowsingPart#fillActionBars(org.eclipse.ui.IActionBars)
133: * @since 3.2
134: */
135: protected void fillActionBars(IActionBars actionBars) {
136: super .fillActionBars(actionBars);
137: fCategoryFilterActionGroup = new CategoryFilterActionGroup(
138: getViewer(), getViewSite().getId(),
139: getCategoryFilterActionGroupInput());
140: fCategoryFilterActionGroup.contributeToViewMenu(actionBars
141: .getMenuManager());
142: }
143:
144: /*
145: * @see org.eclipse.jdt.internal.ui.browsing.JavaBrowsingPart#setInput(java.lang.Object)
146: * @since 3.2
147: */
148: protected void setInput(Object input) {
149: super .setInput(input);
150: if (fCategoryFilterActionGroup != null)
151: fCategoryFilterActionGroup
152: .setInput(getCategoryFilterActionGroupInput());
153: }
154:
155: private IJavaElement[] getCategoryFilterActionGroupInput() {
156: Object input = getInput();
157: if (input instanceof IJavaElement)
158: return new IJavaElement[] { (IJavaElement) input };
159: return new IJavaElement[0];
160: }
161:
162: /**
163: * Answers if the given <code>element</code> is a valid
164: * input for this part.
165: *
166: * @param element the object to test
167: * @return <true> if the given element is a valid input
168: */
169: protected boolean isValidInput(Object element) {
170: if (element instanceof IType) {
171: IType type = (IType) element;
172: return type.isBinary() || type.getDeclaringType() == null;
173: }
174: return false;
175: }
176:
177: /**
178: * Answers if the given <code>element</code> is a valid
179: * element for this part.
180: *
181: * @param element the object to test
182: * @return <true> if the given element is a valid element
183: */
184: protected boolean isValidElement(Object element) {
185: if (element instanceof IMember)
186: return super .isValidElement(((IMember) element)
187: .getDeclaringType());
188: else if (element instanceof IImportDeclaration)
189: return isValidElement(((IJavaElement) element).getParent());
190: else if (element instanceof IImportContainer) {
191: Object input = getViewer().getInput();
192: if (input instanceof IJavaElement) {
193: ICompilationUnit cu = (ICompilationUnit) ((IJavaElement) input)
194: .getAncestor(IJavaElement.COMPILATION_UNIT);
195: if (cu != null) {
196: ICompilationUnit importContainerCu = (ICompilationUnit) ((IJavaElement) element)
197: .getAncestor(IJavaElement.COMPILATION_UNIT);
198: return cu.equals(importContainerCu);
199: } else {
200: IClassFile cf = (IClassFile) ((IJavaElement) input)
201: .getAncestor(IJavaElement.CLASS_FILE);
202: IClassFile importContainerCf = (IClassFile) ((IJavaElement) element)
203: .getAncestor(IJavaElement.CLASS_FILE);
204: return cf != null && cf.equals(importContainerCf);
205: }
206: }
207: }
208: return false;
209: }
210:
211: /**
212: * Finds the element which has to be selected in this part.
213: *
214: * @param je the Java element which has the focus
215: * @return the element to select
216: */
217: protected IJavaElement findElementToSelect(IJavaElement je) {
218: if (je == null)
219: return null;
220:
221: switch (je.getElementType()) {
222: case IJavaElement.TYPE:
223: if (((IType) je).getDeclaringType() == null)
224: return null;
225: return je;
226: case IJavaElement.METHOD:
227: case IJavaElement.INITIALIZER:
228: case IJavaElement.FIELD:
229: case IJavaElement.PACKAGE_DECLARATION:
230: case IJavaElement.IMPORT_CONTAINER:
231: return je;
232: case IJavaElement.IMPORT_DECLARATION:
233: ICompilationUnit cu = (ICompilationUnit) je.getParent()
234: .getParent();
235: try {
236: if (cu.getImports()[0].equals(je)) {
237: Object selectedElement = getSingleElementFromSelection(getViewer()
238: .getSelection());
239: if (selectedElement instanceof IImportContainer)
240: return (IImportContainer) selectedElement;
241: }
242: } catch (JavaModelException ex) {
243: // return je;
244: }
245: return je;
246: }
247: return null;
248: }
249:
250: /**
251: * Finds the closest Java element which can be used as input for
252: * this part and has the given Java element as child.
253: *
254: * @param je the Java element for which to search the closest input
255: * @return the closest Java element used as input for this part, or <code>null</code>
256: */
257: protected IJavaElement findInputForJavaElement(IJavaElement je) {
258: if (je == null
259: || !je.exists()
260: || (je.getJavaProject() != null && !je.getJavaProject()
261: .isOnClasspath(je)))
262: return null;
263:
264: switch (je.getElementType()) {
265: case IJavaElement.TYPE:
266: IType type = ((IType) je).getDeclaringType();
267: if (type == null)
268: return je;
269: else
270: return findInputForJavaElement(type);
271: case IJavaElement.COMPILATION_UNIT:
272: return getTypeForCU((ICompilationUnit) je);
273: case IJavaElement.CLASS_FILE:
274: return findInputForJavaElement(((IClassFile) je).getType());
275: case IJavaElement.IMPORT_DECLARATION:
276: return findInputForJavaElement(je.getParent());
277: case IJavaElement.PACKAGE_DECLARATION:
278: case IJavaElement.IMPORT_CONTAINER:
279: IJavaElement parent = je.getParent();
280: if (parent instanceof ICompilationUnit) {
281: return getTypeForCU((ICompilationUnit) parent);
282: } else if (parent instanceof IClassFile)
283: return findInputForJavaElement(parent);
284: return null;
285: default:
286: if (je instanceof IMember)
287: return findInputForJavaElement(((IMember) je)
288: .getDeclaringType());
289: }
290: return null;
291: }
292:
293: /*
294: * Implements method from IViewPart.
295: */
296: public void saveState(IMemento memento) {
297: super .saveState(memento);
298: fMemberFilterActionGroup.saveState(memento);
299: }
300:
301: protected void restoreState(IMemento memento) {
302: super .restoreState(memento);
303: fMemberFilterActionGroup.restoreState(memento);
304: getViewer().getControl().setRedraw(false);
305: getViewer().refresh();
306: getViewer().getControl().setRedraw(true);
307: }
308:
309: protected void hookViewerListeners() {
310: super .hookViewerListeners();
311: getViewer().addDoubleClickListener(new IDoubleClickListener() {
312: public void doubleClick(DoubleClickEvent event) {
313: TreeViewer viewer = (TreeViewer) getViewer();
314: Object element = ((IStructuredSelection) event
315: .getSelection()).getFirstElement();
316: if (viewer.isExpandable(element))
317: viewer.setExpandedState(element, !viewer
318: .getExpandedState(element));
319: }
320: });
321: }
322:
323: boolean isInputAWorkingCopy() {
324: Object input = getViewer().getInput();
325: if (input instanceof IJavaElement) {
326: ICompilationUnit cu = (ICompilationUnit) ((IJavaElement) input)
327: .getAncestor(IJavaElement.COMPILATION_UNIT);
328: if (cu != null)
329: return cu.isWorkingCopy();
330: }
331: return false;
332: }
333:
334: protected void restoreSelection() {
335: IEditorPart editor = getViewSite().getPage().getActiveEditor();
336: if (editor != null)
337: setSelectionFromEditor(editor);
338: }
339:
340: /* (non-Javadoc)
341: * @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent)
342: */
343: public void propertyChange(PropertyChangeEvent event) {
344: if (MembersOrderPreferenceCache.isMemberOrderProperty(event
345: .getProperty())) {
346: getViewer().refresh();
347: }
348: }
349:
350: /*
351: * @see org.eclipse.jdt.internal.ui.browsing.JavaBrowsingPart#dispose()
352: */
353: public void dispose() {
354: if (fMemberFilterActionGroup != null) {
355: fMemberFilterActionGroup.dispose();
356: fMemberFilterActionGroup = null;
357: }
358: if (fCategoryFilterActionGroup != null) {
359: fCategoryFilterActionGroup.dispose();
360: fCategoryFilterActionGroup = null;
361: }
362: super.dispose();
363: JavaPlugin.getDefault().getPreferenceStore()
364: .removePropertyChangeListener(this);
365: }
366: }
|