]>
Commit | Line | Data |
---|---|---|
1b2798f6 EK |
1 | /******************************************************************************* |
2 | * Copyright (c) 2000, 2011 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 | package org.eclipse.jdt.internal.ui.typehierarchy; | |
12 | ||
13 | import java.util.ArrayList; | |
14 | import java.util.List; | |
15 | ||
16 | import org.eclipse.swt.SWT; | |
17 | import org.eclipse.swt.widgets.Composite; | |
18 | import org.eclipse.swt.widgets.Menu; | |
19 | import org.eclipse.swt.widgets.ScrollBar; | |
20 | import org.eclipse.swt.widgets.Table; | |
21 | ||
22 | import org.eclipse.jface.action.IMenuListener; | |
23 | import org.eclipse.jface.action.IMenuManager; | |
24 | import org.eclipse.jface.action.MenuManager; | |
25 | import org.eclipse.jface.action.Separator; | |
26 | import org.eclipse.jface.action.ToolBarManager; | |
27 | import org.eclipse.jface.viewers.ISelection; | |
28 | import org.eclipse.jface.viewers.StructuredSelection; | |
29 | ||
30 | import org.eclipse.ui.IMemento; | |
31 | import org.eclipse.ui.IWorkbenchPartSite; | |
32 | ||
33 | import org.eclipse.jdt.core.IMethod; | |
34 | import org.eclipse.jdt.core.JavaModelException; | |
35 | ||
36 | import org.eclipse.jdt.internal.corext.util.JavaModelUtil; | |
37 | ||
38 | import org.eclipse.jdt.ui.JavaElementLabels; | |
39 | import org.eclipse.jdt.ui.actions.MemberFilterActionGroup; | |
40 | ||
41 | import org.eclipse.jdt.internal.ui.IJavaHelpContextIds; | |
42 | import org.eclipse.jdt.internal.ui.JavaPlugin; | |
43 | import org.eclipse.jdt.internal.ui.filters.SyntheticMembersFilter; | |
44 | import org.eclipse.jdt.internal.ui.util.JavaUIHelp; | |
45 | import org.eclipse.jdt.internal.ui.util.SelectionUtil; | |
46 | import org.eclipse.jdt.internal.ui.viewsupport.DecoratingJavaLabelProvider; | |
47 | import org.eclipse.jdt.internal.ui.viewsupport.ProblemTableViewer; | |
48 | ||
49 | /** | |
50 | * Method viewer shows a list of methods of a input type. | |
51 | * Offers filter actions. | |
52 | * No dependency to the type hierarchy view | |
53 | */ | |
54 | public class MethodsViewer extends ProblemTableViewer { | |
55 | ||
56 | private static final String TAG_SHOWINHERITED= "showinherited"; //$NON-NLS-1$ | |
57 | private static final String TAG_SORTBYDEFININGTYPE= "sortbydefiningtype"; //$NON-NLS-1$ | |
58 | private static final String TAG_VERTICAL_SCROLL= "mv_vertical_scroll"; //$NON-NLS-1$ | |
59 | ||
60 | private MethodsLabelProvider fLabelProvider; | |
61 | ||
62 | private MemberFilterActionGroup fMemberFilterActionGroup; | |
63 | ||
64 | private ShowInheritedMembersAction fShowInheritedMembersAction; | |
65 | private SortByDefiningTypeAction fSortByDefiningTypeAction; | |
66 | ||
67 | public MethodsViewer(Composite parent, final TypeHierarchyLifeCycle lifeCycle) { | |
68 | super(new Table(parent, SWT.MULTI)); | |
69 | ||
70 | addFilter(new SyntheticMembersFilter()); | |
71 | ||
72 | fLabelProvider= new MethodsLabelProvider(lifeCycle, this); | |
73 | ||
74 | setLabelProvider(new DecoratingJavaLabelProvider(fLabelProvider, true)); | |
75 | setContentProvider(new MethodsContentProvider(lifeCycle)); | |
76 | ||
77 | HierarchyViewerSorter sorter= new HierarchyViewerSorter(lifeCycle); | |
78 | sorter.setSortByDefiningType(false); | |
79 | setComparator(sorter); | |
80 | ||
81 | fMemberFilterActionGroup= new MemberFilterActionGroup(this, "HierarchyMethodView", false, MemberFilterActionGroup.ALL_FILTERS & ~MemberFilterActionGroup.FILTER_LOCALTYPES); //$NON-NLS-1$ | |
82 | ||
83 | fShowInheritedMembersAction= new ShowInheritedMembersAction(this, false); | |
84 | fSortByDefiningTypeAction= new SortByDefiningTypeAction(this, false); | |
85 | ||
86 | showInheritedMethodsNoRedraw(false); | |
87 | sortByDefiningTypeNoRedraw(false); | |
88 | ||
89 | JavaUIHelp.setHelp(this, IJavaHelpContextIds.TYPE_HIERARCHY_VIEW); | |
90 | } | |
91 | ||
92 | private void showInheritedMethodsNoRedraw(boolean on) { | |
93 | MethodsContentProvider cprovider= (MethodsContentProvider) getContentProvider(); | |
94 | cprovider.showInheritedMethods(on); | |
95 | fShowInheritedMembersAction.setChecked(on); | |
96 | if (on) { | |
97 | fLabelProvider.setTextFlags(fLabelProvider.getTextFlags() | JavaElementLabels.ALL_POST_QUALIFIED); | |
98 | } else { | |
99 | fLabelProvider.setTextFlags(fLabelProvider.getTextFlags() & ~JavaElementLabels.ALL_POST_QUALIFIED); | |
100 | } | |
101 | if (on) { | |
102 | sortByDefiningTypeNoRedraw(false); | |
103 | } | |
104 | fSortByDefiningTypeAction.setEnabled(!on); | |
105 | ||
106 | } | |
107 | ||
108 | /** | |
109 | * Show inherited methods | |
110 | * @param on the new state | |
111 | */ | |
112 | public void showInheritedMethods(boolean on) { | |
113 | if (on == isShowInheritedMethods()) { | |
114 | return; | |
115 | } | |
116 | try { | |
117 | getTable().setRedraw(false); | |
118 | showInheritedMethodsNoRedraw(on); | |
119 | refresh(); | |
120 | } finally { | |
121 | getTable().setRedraw(true); | |
122 | } | |
123 | } | |
124 | ||
125 | private void sortByDefiningTypeNoRedraw(boolean on) { | |
126 | fSortByDefiningTypeAction.setChecked(on); | |
127 | fLabelProvider.setShowDefiningType(on); | |
128 | ((HierarchyViewerSorter) getComparator()).setSortByDefiningType(on); | |
129 | } | |
130 | ||
131 | /** | |
132 | * Show the name of the defining type | |
133 | * @param on the new state | |
134 | */ | |
135 | public void sortByDefiningType(boolean on) { | |
136 | if (on == isShowDefiningTypes()) { | |
137 | return; | |
138 | } | |
139 | try { | |
140 | getTable().setRedraw(false); | |
141 | sortByDefiningTypeNoRedraw(on); | |
142 | refresh(); | |
143 | } finally { | |
144 | getTable().setRedraw(true); | |
145 | } | |
146 | } | |
147 | ||
148 | /* | |
149 | * @see Viewer#inputChanged(Object, Object) | |
150 | */ | |
151 | @Override | |
152 | protected void inputChanged(Object input, Object oldInput) { | |
153 | super.inputChanged(input, oldInput); | |
154 | } | |
155 | ||
156 | /** | |
157 | * Returns <code>true</code> if inherited methods are shown. | |
158 | * @return <code>true</code> if inherited methods are shown. | |
159 | */ | |
160 | public boolean isShowInheritedMethods() { | |
161 | return ((MethodsContentProvider) getContentProvider()).isShowInheritedMethods(); | |
162 | } | |
163 | ||
164 | /** | |
165 | * Returns <code>true</code> if defining types are shown. | |
166 | * @return <code>true</code> if defining types are shown. | |
167 | */ | |
168 | public boolean isShowDefiningTypes() { | |
169 | return fLabelProvider.isShowDefiningType(); | |
170 | } | |
171 | ||
172 | /** | |
173 | * Saves the state of the filter actions | |
174 | * @param memento the memento | |
175 | */ | |
176 | public void saveState(IMemento memento) { | |
177 | fMemberFilterActionGroup.saveState(memento); | |
178 | ||
179 | memento.putString(TAG_SHOWINHERITED, String.valueOf(isShowInheritedMethods())); | |
180 | memento.putString(TAG_SORTBYDEFININGTYPE, String.valueOf(isShowDefiningTypes())); | |
181 | ||
182 | ScrollBar bar= getTable().getVerticalBar(); | |
183 | int position= bar != null ? bar.getSelection() : 0; | |
184 | memento.putString(TAG_VERTICAL_SCROLL, String.valueOf(position)); | |
185 | } | |
186 | ||
187 | /** | |
188 | * Restores the state of the filter actions | |
189 | * @param memento the memento | |
190 | */ | |
191 | public void restoreState(IMemento memento) { | |
192 | fMemberFilterActionGroup.restoreState(memento); | |
193 | getControl().setRedraw(false); | |
194 | refresh(); | |
195 | getControl().setRedraw(true); | |
196 | ||
197 | boolean showInherited= Boolean.valueOf(memento.getString(TAG_SHOWINHERITED)).booleanValue(); | |
198 | showInheritedMethods(showInherited); | |
199 | ||
200 | boolean showDefiningTypes= Boolean.valueOf(memento.getString(TAG_SORTBYDEFININGTYPE)).booleanValue(); | |
201 | sortByDefiningType(showDefiningTypes); | |
202 | ||
203 | ScrollBar bar= getTable().getVerticalBar(); | |
204 | if (bar != null) { | |
205 | Integer vScroll= memento.getInteger(TAG_VERTICAL_SCROLL); | |
206 | if (vScroll != null) { | |
207 | bar.setSelection(vScroll.intValue()); | |
208 | } | |
209 | } | |
210 | } | |
211 | ||
212 | /** | |
213 | * Attaches a contextmenu listener to the table | |
214 | * @param menuListener the menu listener | |
215 | * @param popupId the popup id | |
216 | * @param viewSite the view site | |
217 | */ | |
218 | public void initContextMenu(IMenuListener menuListener, String popupId, IWorkbenchPartSite viewSite) { | |
219 | MenuManager menuMgr= new MenuManager(); | |
220 | menuMgr.setRemoveAllWhenShown(true); | |
221 | menuMgr.addMenuListener(menuListener); | |
222 | Menu menu= menuMgr.createContextMenu(getTable()); | |
223 | getTable().setMenu(menu); | |
224 | viewSite.registerContextMenu(popupId, menuMgr, this); | |
225 | } | |
226 | ||
227 | ||
228 | /** | |
229 | * Fills up the context menu with items for the method viewer | |
230 | * Should be called by the creator of the context menu | |
231 | * @param menu teh menu manager | |
232 | */ | |
233 | public void contributeToContextMenu(IMenuManager menu) { | |
234 | } | |
235 | ||
236 | /** | |
237 | * Fills up the tool bar with items for the method viewer | |
238 | * Should be called by the creator of the tool bar | |
239 | * @param tbm the tool bar manager | |
240 | */ | |
241 | public void contributeToToolBar(ToolBarManager tbm) { | |
242 | tbm.add(fShowInheritedMembersAction); | |
243 | tbm.add(fSortByDefiningTypeAction); | |
244 | tbm.add(new Separator()); | |
245 | fMemberFilterActionGroup.contributeToToolBar(tbm); | |
246 | } | |
247 | ||
248 | public void dispose() { | |
249 | if (fMemberFilterActionGroup != null) { | |
250 | fMemberFilterActionGroup.dispose(); | |
251 | fMemberFilterActionGroup= null; | |
252 | } | |
253 | } | |
254 | ||
255 | /* | |
256 | * @see StructuredViewer#handleInvalidSelection(ISelection, ISelection) | |
257 | */ | |
258 | @Override | |
259 | protected void handleInvalidSelection(ISelection invalidSelection, ISelection newSelection) { | |
260 | // on change of input, try to keep selected methods stable by selecting a method with the same | |
261 | // signature: See #5466 | |
262 | List<?> oldSelections= SelectionUtil.toList(invalidSelection); | |
263 | List<?> newSelections= SelectionUtil.toList(newSelection); | |
264 | if (!oldSelections.isEmpty()) { | |
265 | ArrayList<Object> newSelectionElements= new ArrayList<Object>(newSelections); | |
266 | try { | |
267 | Object[] currElements= getFilteredChildren(getInput()); | |
268 | for (int i= 0; i < oldSelections.size(); i++) { | |
269 | Object curr= oldSelections.get(i); | |
270 | if (curr instanceof IMethod && !newSelections.contains(curr)) { | |
271 | IMethod method= (IMethod) curr; | |
272 | if (method.exists()) { | |
273 | IMethod similar= findSimilarMethod(method, currElements); | |
274 | if (similar != null) { | |
275 | newSelectionElements.add(similar); | |
276 | } | |
277 | } | |
278 | } | |
279 | } | |
280 | if (!newSelectionElements.isEmpty()) { | |
281 | newSelection= new StructuredSelection(newSelectionElements); | |
282 | } else if (currElements.length > 0) { | |
283 | newSelection= new StructuredSelection(currElements[0]); | |
284 | } | |
285 | } catch (JavaModelException e) { | |
286 | JavaPlugin.log(e); | |
287 | } | |
288 | } | |
289 | setSelection(newSelection); | |
290 | updateSelection(newSelection); | |
291 | } | |
292 | ||
293 | private IMethod findSimilarMethod(IMethod meth, Object[] elements) throws JavaModelException { | |
294 | String name= meth.getElementName(); | |
295 | String[] paramTypes= meth.getParameterTypes(); | |
296 | boolean isConstructor= meth.isConstructor(); | |
297 | ||
298 | for (int i= 0; i < elements.length; i++) { | |
299 | Object curr= elements[i]; | |
300 | if (curr instanceof IMethod && JavaModelUtil.isSameMethodSignature(name, paramTypes, isConstructor, (IMethod) curr)) { | |
301 | return (IMethod) curr; | |
302 | } | |
303 | } | |
304 | return null; | |
305 | } | |
306 | ||
307 | ||
308 | ||
309 | } |