]>
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 | * Martin Moebius (m.moebius@gmx.de) - initial API and implementation | |
10 | * (report 28793) | |
11 | * IBM Corporation - updates | |
12 | *******************************************************************************/ | |
13 | ||
14 | package org.eclipse.jdt.ui.actions; | |
15 | ||
16 | import java.lang.reflect.InvocationTargetException; | |
17 | import java.util.ArrayList; | |
18 | import java.util.HashSet; | |
19 | import java.util.List; | |
20 | ||
21 | import org.eclipse.swt.SWT; | |
22 | import org.eclipse.swt.events.SelectionAdapter; | |
23 | import org.eclipse.swt.events.SelectionEvent; | |
24 | import org.eclipse.swt.graphics.Image; | |
25 | import org.eclipse.swt.layout.GridData; | |
26 | import org.eclipse.swt.widgets.Composite; | |
27 | import org.eclipse.swt.widgets.Control; | |
28 | import org.eclipse.swt.widgets.Link; | |
29 | import org.eclipse.swt.widgets.Shell; | |
30 | ||
31 | import org.eclipse.core.runtime.CoreException; | |
32 | import org.eclipse.core.runtime.IStatus; | |
33 | import org.eclipse.core.runtime.NullProgressMonitor; | |
34 | ||
35 | import org.eclipse.jface.dialogs.MessageDialog; | |
36 | import org.eclipse.jface.operation.IRunnableContext; | |
37 | import org.eclipse.jface.viewers.ILabelProvider; | |
38 | import org.eclipse.jface.viewers.IStructuredSelection; | |
39 | import org.eclipse.jface.viewers.ITreeContentProvider; | |
40 | import org.eclipse.jface.viewers.Viewer; | |
41 | import org.eclipse.jface.viewers.ViewerComparator; | |
42 | import org.eclipse.jface.window.Window; | |
43 | ||
44 | import org.eclipse.jface.text.IRewriteTarget; | |
45 | import org.eclipse.jface.text.ITextSelection; | |
46 | ||
47 | import org.eclipse.ui.IEditorPart; | |
48 | import org.eclipse.ui.IWorkbenchSite; | |
49 | import org.eclipse.ui.PlatformUI; | |
50 | import org.eclipse.ui.dialogs.ISelectionStatusValidator; | |
51 | ||
52 | import org.eclipse.jdt.core.ICompilationUnit; | |
53 | import org.eclipse.jdt.core.IField; | |
54 | import org.eclipse.jdt.core.IJavaElement; | |
55 | import org.eclipse.jdt.core.IType; | |
56 | import org.eclipse.jdt.core.JavaModelException; | |
57 | import org.eclipse.jdt.core.Signature; | |
58 | import org.eclipse.jdt.core.dom.CompilationUnit; | |
59 | import org.eclipse.jdt.core.dom.IMethodBinding; | |
60 | import org.eclipse.jdt.core.dom.ITypeBinding; | |
61 | import org.eclipse.jdt.core.dom.IVariableBinding; | |
62 | import org.eclipse.jdt.core.dom.VariableDeclarationFragment; | |
63 | ||
64 | import org.eclipse.jdt.internal.corext.codemanipulation.AddDelegateMethodsOperation; | |
65 | import org.eclipse.jdt.internal.corext.codemanipulation.AddDelegateMethodsOperation.DelegateEntry; | |
66 | import org.eclipse.jdt.internal.corext.codemanipulation.CodeGenerationSettings; | |
67 | import org.eclipse.jdt.internal.corext.codemanipulation.StubUtility2; | |
68 | import org.eclipse.jdt.internal.corext.dom.ASTNodes; | |
69 | import org.eclipse.jdt.internal.corext.refactoring.structure.ASTNodeSearchUtil; | |
70 | import org.eclipse.jdt.internal.corext.refactoring.util.JavaElementUtil; | |
71 | import org.eclipse.jdt.internal.corext.template.java.CodeTemplateContextType; | |
72 | import org.eclipse.jdt.internal.corext.util.JavaModelUtil; | |
73 | import org.eclipse.jdt.internal.corext.util.JdtFlags; | |
74 | import org.eclipse.jdt.internal.corext.util.Messages; | |
75 | ||
76 | import org.eclipse.jdt.ui.JavaUI; | |
77 | import org.eclipse.jdt.ui.SharedASTProvider; | |
78 | ||
79 | import org.eclipse.jdt.internal.ui.IJavaHelpContextIds; | |
80 | import org.eclipse.jdt.internal.ui.JavaPlugin; | |
81 | import org.eclipse.jdt.internal.ui.actions.ActionMessages; | |
82 | import org.eclipse.jdt.internal.ui.actions.ActionUtil; | |
83 | import org.eclipse.jdt.internal.ui.actions.SelectionConverter; | |
84 | import org.eclipse.jdt.internal.ui.actions.WorkbenchRunnableAdapter; | |
85 | import org.eclipse.jdt.internal.ui.dialogs.SourceActionDialog; | |
86 | import org.eclipse.jdt.internal.ui.dialogs.StatusInfo; | |
87 | import org.eclipse.jdt.internal.ui.javaeditor.CompilationUnitEditor; | |
88 | import org.eclipse.jdt.internal.ui.preferences.JavaPreferencesSettings; | |
89 | import org.eclipse.jdt.internal.ui.util.BusyIndicatorRunnableContext; | |
90 | import org.eclipse.jdt.internal.ui.util.ElementValidator; | |
91 | import org.eclipse.jdt.internal.ui.util.ExceptionHandler; | |
92 | import org.eclipse.jdt.internal.ui.viewsupport.BindingLabelProvider; | |
93 | ||
94 | /** | |
95 | * Creates delegate methods for a type's fields. Opens a dialog with a list of fields for | |
96 | * which delegate methods can be generated. User is able to check or uncheck items before | |
97 | * methods are generated. | |
98 | * <p> | |
99 | * Will open the parent compilation unit in a Java editor. The result is unsaved, so the | |
100 | * user can decide if the changes are acceptable. | |
101 | * <p> | |
102 | * The action is applicable to structured selections containing elements of type | |
103 | * <code>IField</code> or <code>IType</code>. | |
104 | * | |
105 | * <p> | |
106 | * This class may be instantiated; it is not intended to be subclassed. | |
107 | * </p> | |
108 | * | |
109 | * @since 2.1 | |
110 | * | |
111 | * @noextend This class is not intended to be subclassed by clients. | |
112 | */ | |
113 | public class AddDelegateMethodsAction extends SelectionDispatchAction { | |
114 | ||
115 | // ---- Helpers ------------------------------------------------------------------- | |
116 | ||
117 | private static class AddDelegateMethodsActionStatusValidator implements ISelectionStatusValidator { | |
118 | ||
119 | private static int fEntries; | |
120 | ||
121 | AddDelegateMethodsActionStatusValidator(int entries) { | |
122 | fEntries= entries; | |
123 | } | |
124 | ||
125 | public IStatus validate(Object[] selection) { | |
126 | int selectedCount= 0; | |
127 | int duplicateCount= 0; | |
128 | if (selection != null && selection.length > 0) { | |
129 | ||
130 | HashSet<String> signatures= new HashSet<String>(selection.length); | |
131 | for (int index= 0; index < selection.length; index++) { | |
132 | if (selection[index] instanceof DelegateEntry) { | |
133 | DelegateEntry delegateEntry= (DelegateEntry) selection[index]; | |
134 | if (!signatures.add(getSignature(delegateEntry.delegateMethod))) | |
135 | duplicateCount++; | |
136 | selectedCount++; | |
137 | } | |
138 | } | |
139 | } | |
140 | if (duplicateCount > 0) { | |
141 | return new StatusInfo(IStatus.ERROR, duplicateCount == 1 | |
142 | ? ActionMessages.AddDelegateMethodsAction_duplicate_methods_singular | |
143 | : Messages.format(ActionMessages.AddDelegateMethodsAction_duplicate_methods_plural, String.valueOf(duplicateCount))); | |
144 | } | |
145 | return new StatusInfo(IStatus.INFO, Messages.format(ActionMessages.AddDelegateMethodsAction_selectioninfo_more, new Object[] { String.valueOf(selectedCount), String.valueOf(fEntries) })); | |
146 | } | |
147 | ||
148 | private String getSignature(IMethodBinding binding) { | |
149 | StringBuffer buf= new StringBuffer(binding.getName()).append('('); | |
150 | ITypeBinding[] parameterTypes= binding.getParameterTypes(); | |
151 | for (int i= 0; i < parameterTypes.length; i++) { | |
152 | buf.append(parameterTypes[i].getTypeDeclaration().getName()); | |
153 | } | |
154 | buf.append(')'); | |
155 | return buf.toString(); | |
156 | } | |
157 | ||
158 | } | |
159 | ||
160 | public static class AddDelegateMethodsContentProvider implements ITreeContentProvider { | |
161 | ||
162 | private DelegateEntry[] fDelegateEntries; | |
163 | private IVariableBinding[] fExpanded= new IVariableBinding[0]; | |
164 | ||
165 | AddDelegateMethodsContentProvider(CompilationUnit astRoot, IType type, IField[] fields) throws JavaModelException { | |
166 | ||
167 | final ITypeBinding binding= ASTNodes.getTypeBinding(astRoot, type); | |
168 | if (binding != null) { | |
169 | fDelegateEntries= StubUtility2.getDelegatableMethods(binding); | |
170 | ||
171 | List<IVariableBinding> expanded= new ArrayList<IVariableBinding>(); | |
172 | for (int index= 0; index < fields.length; index++) { | |
173 | VariableDeclarationFragment fragment= ASTNodeSearchUtil.getFieldDeclarationFragmentNode(fields[index], astRoot); | |
174 | if (fragment != null) { | |
175 | IVariableBinding variableBinding= fragment.resolveBinding(); | |
176 | if (variableBinding != null) | |
177 | expanded.add(variableBinding); | |
178 | } | |
179 | } | |
180 | fExpanded= expanded.toArray(new IVariableBinding[expanded.size()]); | |
181 | } | |
182 | } | |
183 | ||
184 | public void dispose() { | |
185 | } | |
186 | ||
187 | public Object[] getChildren(Object element) { | |
188 | if (element instanceof IVariableBinding) { | |
189 | List<DelegateEntry> result= new ArrayList<DelegateEntry>(); | |
190 | for (int i= 0; i < fDelegateEntries.length; i++) { | |
191 | if (element == fDelegateEntries[i].field) { | |
192 | result.add(fDelegateEntries[i]); | |
193 | } | |
194 | } | |
195 | return result.toArray(); | |
196 | } | |
197 | return null; | |
198 | } | |
199 | ||
200 | public int getCount() { | |
201 | return fDelegateEntries.length; | |
202 | } | |
203 | ||
204 | public Object[] getElements(Object inputElement) { | |
205 | HashSet<IVariableBinding> result= new HashSet<IVariableBinding>(); | |
206 | for (int i= 0; i < fDelegateEntries.length; i++) { | |
207 | DelegateEntry curr= fDelegateEntries[i]; | |
208 | curr.generated_2166174217760458360(result, AddDelegateMethodsContentProvider.this); | |
209 | } | |
210 | return result.toArray(); | |
211 | } | |
212 | ||
213 | public IVariableBinding[] getExpandedElements() { | |
214 | return fExpanded; | |
215 | } | |
216 | ||
217 | public IVariableBinding[] getInitiallySelectedElements() { | |
218 | return fExpanded; | |
219 | } | |
220 | ||
221 | public Object getParent(Object element) { | |
222 | if (element instanceof DelegateEntry) | |
223 | return ((DelegateEntry) element).field; | |
224 | return null; | |
225 | } | |
226 | ||
227 | public boolean hasChildren(Object element) { | |
228 | return element instanceof IVariableBinding; | |
229 | } | |
230 | ||
231 | public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { | |
232 | } | |
233 | } | |
234 | ||
235 | private static class AddDelegateMethodsDialog extends SourceActionDialog { | |
236 | ||
237 | public AddDelegateMethodsDialog(Shell parent, ILabelProvider labelProvider, ITreeContentProvider contentProvider, CompilationUnitEditor editor, IType type, boolean isConstructor) throws JavaModelException { | |
238 | super(parent, labelProvider, contentProvider, editor, type, isConstructor); | |
239 | } | |
240 | ||
241 | @Override | |
242 | protected void configureShell(Shell shell) { | |
243 | super.configureShell(shell); | |
244 | PlatformUI.getWorkbench().getHelpSystem().setHelp(shell, IJavaHelpContextIds.ADD_DELEGATE_METHODS_SELECTION_DIALOG); | |
245 | } | |
246 | ||
247 | /* | |
248 | * @see org.eclipse.jdt.internal.ui.dialogs.SourceActionDialog#createLinkControl(org.eclipse.swt.widgets.Composite) | |
249 | */ | |
250 | @Override | |
251 | protected Control createLinkControl(Composite composite) { | |
252 | Link link= new Link(composite, SWT.WRAP); | |
253 | link.setText(ActionMessages.AddDelegateMethodsAction_template_link_message); | |
254 | link.addSelectionListener(new SelectionAdapter() { | |
255 | @Override | |
256 | public void widgetSelected(SelectionEvent e) { | |
257 | openCodeTempatePage(CodeTemplateContextType.OVERRIDECOMMENT_ID); | |
258 | } | |
259 | }); | |
260 | link.setToolTipText(ActionMessages.AddDelegateMethodsAction_template_link_tooltip); | |
261 | ||
262 | GridData gridData= new GridData(SWT.FILL, SWT.BEGINNING, true, false); | |
263 | gridData.widthHint= convertWidthInCharsToPixels(40); // only expand further if anyone else requires it | |
264 | link.setLayoutData(gridData); | |
265 | return link; | |
266 | } | |
267 | } | |
268 | ||
269 | private static class AddDelegateMethodsLabelProvider extends BindingLabelProvider { | |
270 | ||
271 | @Override | |
272 | public Image getImage(Object element) { | |
273 | if (element instanceof DelegateEntry) { | |
274 | DelegateEntry delegateEntry= (DelegateEntry) element; | |
275 | return super.getImage(delegateEntry.delegateMethod); | |
276 | } else if (element instanceof IVariableBinding) { | |
277 | return super.getImage(element); | |
278 | } | |
279 | return null; | |
280 | } | |
281 | ||
282 | @Override | |
283 | public String getText(Object element) { | |
284 | if (element instanceof DelegateEntry) { | |
285 | DelegateEntry delegateEntry= (DelegateEntry) element; | |
286 | return super.getText(delegateEntry.delegateMethod); | |
287 | } else if (element instanceof IVariableBinding) { | |
288 | return super.getText(element); | |
289 | } | |
290 | return null; | |
291 | } | |
292 | } | |
293 | ||
294 | public static class AddDelegateMethodsViewerComparator extends ViewerComparator { | |
295 | ||
296 | @Override | |
297 | public int category(Object element) { | |
298 | if (element instanceof DelegateEntry) | |
299 | return 0; | |
300 | return 1; | |
301 | } | |
302 | ||
303 | @Override | |
304 | public int compare(Viewer viewer, Object o1, Object o2) { | |
305 | if (o1 instanceof DelegateEntry && o2 instanceof DelegateEntry) { | |
306 | String bindingLabel1= BindingLabelProvider.getBindingLabel(((DelegateEntry) o1).delegateMethod, BindingLabelProvider.DEFAULT_TEXTFLAGS); | |
307 | String bindingLabel2= BindingLabelProvider.getBindingLabel(((DelegateEntry) o2).delegateMethod, BindingLabelProvider.DEFAULT_TEXTFLAGS); | |
308 | return getComparator().compare(bindingLabel1, bindingLabel2); | |
309 | } else if (o1 instanceof IVariableBinding && o2 instanceof IVariableBinding) { | |
310 | return getComparator().compare(((IVariableBinding) o1).getName(), ((IVariableBinding) o2).getName()); | |
311 | } | |
312 | return 0; | |
313 | } | |
314 | } | |
315 | ||
316 | private static final String DIALOG_TITLE= ActionMessages.AddDelegateMethodsAction_error_title; | |
317 | ||
318 | private static boolean hasPrimitiveType(IField field) throws JavaModelException { | |
319 | String signature= field.getTypeSignature(); | |
320 | char first= Signature.getElementType(signature).charAt(0); | |
321 | return (first != Signature.C_RESOLVED && first != Signature.C_UNRESOLVED); | |
322 | } | |
323 | ||
324 | private static boolean isArray(IField field) throws JavaModelException { | |
325 | return Signature.getArrayCount(field.getTypeSignature()) > 0; | |
326 | } | |
327 | ||
328 | private CompilationUnitEditor fEditor; | |
329 | ||
330 | /** | |
331 | * Note: This constructor is for internal use only. Clients should not call this | |
332 | * constructor. | |
333 | * | |
334 | * @param editor the compilation unit editor | |
335 | * | |
336 | * @noreference This constructor is not intended to be referenced by clients. | |
337 | */ | |
338 | public AddDelegateMethodsAction(CompilationUnitEditor editor) { | |
339 | this(editor.getEditorSite()); | |
340 | fEditor= editor; | |
341 | setEnabled(SelectionConverter.getInputAsCompilationUnit(editor) != null); | |
342 | } | |
343 | ||
344 | /** | |
345 | * Creates a new <code>AddDelegateMethodsAction</code>. The action requires that | |
346 | * the selection provided by the site's selection provider is of type <code> | |
347 | * org.eclipse.jface.viewers.IStructuredSelection</code>. | |
348 | * | |
349 | * @param site the site providing context information for this action | |
350 | */ | |
351 | public AddDelegateMethodsAction(IWorkbenchSite site) { | |
352 | super(site); | |
353 | setText(ActionMessages.AddDelegateMethodsAction_label); | |
354 | setDescription(ActionMessages.AddDelegateMethodsAction_description); | |
355 | setToolTipText(ActionMessages.AddDelegateMethodsAction_tooltip); | |
356 | ||
357 | PlatformUI.getWorkbench().getHelpSystem().setHelp(this, IJavaHelpContextIds.ADD_DELEGATE_METHODS_ACTION); | |
358 | } | |
359 | ||
360 | private boolean canEnable(IStructuredSelection selection) throws JavaModelException { | |
361 | if (getSelectedFields(selection) != null) | |
362 | return true; | |
363 | ||
364 | if ((selection.size() == 1) && (selection.getFirstElement() instanceof IType)) { | |
365 | IType type= (IType) selection.getFirstElement(); | |
366 | return type.getCompilationUnit() != null && !type.isInterface() && !type.isAnonymous(); | |
367 | } | |
368 | ||
369 | if ((selection.size() == 1) && (selection.getFirstElement() instanceof ICompilationUnit)) | |
370 | return true; | |
371 | ||
372 | return false; | |
373 | } | |
374 | ||
375 | private boolean canRunOn(IField[] fields) throws JavaModelException { | |
376 | if (fields == null || fields.length == 0) | |
377 | return false; | |
378 | int count= 0; | |
379 | for (int index= 0; index < fields.length; index++) { | |
380 | if (!JdtFlags.isEnum(fields[index]) && !hasPrimitiveType(fields[index]) || isArray(fields[index])) | |
381 | count++; | |
382 | } | |
383 | if (count == 0) | |
384 | MessageDialog.openInformation(getShell(), DIALOG_TITLE, ActionMessages.AddDelegateMethodsAction_not_applicable); | |
385 | return (count > 0); | |
386 | } | |
387 | ||
388 | private boolean canRunOn(IType type) throws JavaModelException { | |
389 | if (type == null || type.getCompilationUnit() == null) { | |
390 | MessageDialog.openInformation(getShell(), DIALOG_TITLE, ActionMessages.AddDelegateMethodsAction_not_in_source_file); | |
391 | return false; | |
392 | } else if (type.isAnnotation()) { | |
393 | MessageDialog.openInformation(getShell(), DIALOG_TITLE, ActionMessages.AddDelegateMethodsAction_annotation_not_applicable); | |
394 | return false; | |
395 | } else if (type.isInterface()) { | |
396 | MessageDialog.openInformation(getShell(), DIALOG_TITLE, ActionMessages.AddDelegateMethodsAction_interface_not_applicable); | |
397 | return false; | |
398 | } | |
399 | return canRunOn(type.getFields()); | |
400 | } | |
401 | ||
402 | private IField[] getSelectedFields(IStructuredSelection selection) { | |
403 | List<?> elements= selection.toList(); | |
404 | if (elements.size() > 0) { | |
405 | IField[] result= new IField[elements.size()]; | |
406 | ICompilationUnit unit= null; | |
407 | for (int index= 0; index < elements.size(); index++) { | |
408 | if (elements.get(index) instanceof IField) { | |
409 | IField field= (IField) elements.get(index); | |
410 | ||
411 | if (index == 0) { | |
412 | // remember the CU of the first element | |
413 | unit= field.getCompilationUnit(); | |
414 | if (unit == null) { | |
415 | return null; | |
416 | } | |
417 | } else if (!unit.equals(field.getCompilationUnit())) { | |
418 | // all fields must be in the same CU | |
419 | return null; | |
420 | } | |
421 | try { | |
422 | final IType type= field.getDeclaringType(); | |
423 | if (type.isInterface() || type.isAnonymous()) { | |
424 | return null; | |
425 | } | |
426 | } catch (JavaModelException exception) { | |
427 | JavaPlugin.log(exception); | |
428 | return null; | |
429 | } | |
430 | ||
431 | result[index]= field; | |
432 | } else { | |
433 | return null; | |
434 | } | |
435 | } | |
436 | return result; | |
437 | } | |
438 | return null; | |
439 | } | |
440 | ||
441 | /* | |
442 | * (non-Javadoc) Method declared on SelectionDispatchAction | |
443 | */ | |
444 | @Override | |
445 | public void run(IStructuredSelection selection) { | |
446 | try { | |
447 | IField[] selectedFields= getSelectedFields(selection); | |
448 | if (canRunOn(selectedFields)) { | |
449 | run(selectedFields[0].getDeclaringType(), selectedFields, false); | |
450 | return; | |
451 | } | |
452 | Object firstElement= selection.getFirstElement(); | |
453 | if (firstElement instanceof IType) | |
454 | run((IType) firstElement, new IField[0], false); | |
455 | else if (firstElement instanceof ICompilationUnit) | |
456 | run(JavaElementUtil.getMainType((ICompilationUnit) firstElement), new IField[0], false); | |
457 | else if (!(firstElement instanceof IField)) | |
458 | MessageDialog.openInformation(getShell(), DIALOG_TITLE, ActionMessages.AddDelegateMethodsAction_not_applicable); | |
459 | } catch (CoreException e) { | |
460 | ExceptionHandler.handle(e, getShell(), DIALOG_TITLE, ActionMessages.AddDelegateMethodsAction_error_actionfailed); | |
461 | } | |
462 | ||
463 | } | |
464 | ||
465 | /* | |
466 | * (non-Javadoc) Method declared on SelectionDispatchAction | |
467 | */ | |
468 | @Override | |
469 | public void run(ITextSelection selection) { | |
470 | try { | |
471 | if (!ActionUtil.isProcessable(fEditor)) | |
472 | return; | |
473 | ||
474 | IJavaElement[] elements= SelectionConverter.codeResolveForked(fEditor, true); | |
475 | if (elements.length == 1 && (elements[0] instanceof IField)) { | |
476 | IField field= (IField) elements[0]; | |
477 | run(field.getDeclaringType(), new IField[] { field}, true); | |
478 | return; | |
479 | } | |
480 | IJavaElement element= SelectionConverter.getElementAtOffset(fEditor); | |
481 | if (element != null) { | |
482 | IType type= (IType) element.getAncestor(IJavaElement.TYPE); | |
483 | if (type != null) { | |
484 | if (type.getFields().length > 0) { | |
485 | run(type, new IField[0], true); | |
486 | return; | |
487 | } | |
488 | } | |
489 | } | |
490 | MessageDialog.openInformation(getShell(), DIALOG_TITLE, ActionMessages.AddDelegateMethodsAction_not_applicable); | |
491 | } catch (CoreException e) { | |
492 | ExceptionHandler.handle(e, getShell(), DIALOG_TITLE, ActionMessages.AddDelegateMethodsAction_error_actionfailed); | |
493 | } catch (InvocationTargetException e) { | |
494 | ExceptionHandler.handle(e, getShell(), DIALOG_TITLE, ActionMessages.AddDelegateMethodsAction_error_actionfailed); | |
495 | } catch (InterruptedException e) { | |
496 | // cancelled | |
497 | } | |
498 | } | |
499 | ||
500 | private void run(IType type, IField[] preselected, boolean editor) throws CoreException { | |
501 | if (!ElementValidator.check(type, getShell(), DIALOG_TITLE, editor)) | |
502 | return; | |
503 | if (!ActionUtil.isEditable(fEditor, getShell(), type)) | |
504 | return; | |
505 | if (!canRunOn(type)) | |
506 | return; | |
507 | showUI(type, preselected); | |
508 | } | |
509 | ||
510 | // ---- Structured Viewer ----------------------------------------------------------- | |
511 | ||
512 | /* | |
513 | * (non-Javadoc) Method declared on SelectionDispatchAction | |
514 | */ | |
515 | @Override | |
516 | public void selectionChanged(IStructuredSelection selection) { | |
517 | try { | |
518 | setEnabled(canEnable(selection)); | |
519 | } catch (JavaModelException e) { | |
520 | // http://bugs.eclipse.org/bugs/show_bug.cgi?id=19253 | |
521 | if (JavaModelUtil.isExceptionToBeLogged(e)) | |
522 | JavaPlugin.log(e); | |
523 | setEnabled(false); | |
524 | } | |
525 | } | |
526 | ||
527 | // ---- Java Editor -------------------------------------------------------------- | |
528 | ||
529 | /* | |
530 | * (non-Javadoc) Method declared on SelectionDispatchAction | |
531 | */ | |
532 | @Override | |
533 | public void selectionChanged(ITextSelection selection) { | |
534 | } | |
535 | ||
536 | private void showUI(IType type, IField[] fields) { | |
537 | try { | |
538 | CompilationUnit astRoot= SharedASTProvider.getAST(type.getCompilationUnit(), SharedASTProvider.WAIT_YES, new NullProgressMonitor()); | |
539 | ||
540 | AddDelegateMethodsContentProvider provider= new AddDelegateMethodsContentProvider(astRoot, type, fields); | |
541 | SourceActionDialog dialog= new AddDelegateMethodsDialog(getShell(), new AddDelegateMethodsLabelProvider(), provider, fEditor, type, false); | |
542 | dialog.setValidator(new AddDelegateMethodsActionStatusValidator(provider.getCount())); | |
543 | AddDelegateMethodsViewerComparator comparator= new AddDelegateMethodsViewerComparator(); | |
544 | dialog.generated_6831724063556090705(comparator); | |
545 | dialog.setMessage(ActionMessages.AddDelegateMethodsAction_message); | |
546 | dialog.setTitle(ActionMessages.AddDelegateMethodsAction_title); | |
547 | IVariableBinding[] expanded= provider.getExpandedElements(); | |
548 | if (expanded.length > 0) { | |
549 | dialog.setExpandedElements(expanded); | |
550 | } else { | |
551 | Object[] elements= provider.getElements(null); | |
552 | if (elements.length > 0) { | |
553 | comparator.sort(null, elements); | |
554 | Object[] expand= { elements[0]}; | |
555 | dialog.setExpandedElements(expand); | |
556 | } | |
557 | } | |
558 | dialog.setInitialSelections(provider.getInitiallySelectedElements()); | |
559 | dialog.setSize(60, 18); | |
560 | int result= dialog.open(); | |
561 | if (result == Window.OK) { | |
562 | Object[] object= dialog.getResult(); | |
563 | if (object == null) { | |
564 | notifyResult(false); | |
565 | return; | |
566 | } | |
567 | List<DelegateEntry> tuples= new ArrayList<DelegateEntry>(object.length); | |
568 | for (int index= 0; index < object.length; index++) { | |
569 | if (object[index] instanceof DelegateEntry) | |
570 | tuples.add((DelegateEntry) object[index]); | |
571 | } | |
572 | IEditorPart part= JavaUI.openInEditor(type); | |
573 | IRewriteTarget target= (IRewriteTarget) part.getAdapter(IRewriteTarget.class); | |
574 | try { | |
575 | if (target != null) | |
576 | target.beginCompoundChange(); | |
577 | CodeGenerationSettings settings= JavaPreferencesSettings.getCodeGenerationSettings(type.getJavaProject()); | |
578 | settings.createComments= dialog.getGenerateComment(); | |
579 | ||
580 | DelegateEntry[] methodToDelegate= tuples.toArray(new DelegateEntry[tuples.size()]); | |
581 | ||
582 | AddDelegateMethodsOperation operation= new AddDelegateMethodsOperation(astRoot, methodToDelegate, dialog.getElementPosition(), settings, true, false); | |
583 | IRunnableContext context= JavaPlugin.getActiveWorkbenchWindow(); | |
584 | if (context == null) | |
585 | context= new BusyIndicatorRunnableContext(); | |
586 | try { | |
587 | PlatformUI.getWorkbench().getProgressService().runInUI(context, new WorkbenchRunnableAdapter(operation, operation.getSchedulingRule()), operation.getSchedulingRule()); | |
588 | } catch (InterruptedException exception) { | |
589 | // User interruption | |
590 | } | |
591 | } finally { | |
592 | if (target != null) | |
593 | target.endCompoundChange(); | |
594 | } | |
595 | } | |
596 | notifyResult(result == Window.OK); | |
597 | } catch (CoreException exception) { | |
598 | ExceptionHandler.handle(exception, DIALOG_TITLE, ActionMessages.AddDelegateMethodsAction_error_actionfailed); | |
599 | } catch (InvocationTargetException e) { | |
600 | ExceptionHandler.handle(e, DIALOG_TITLE, ActionMessages.AddDelegateMethodsAction_error_actionfailed); | |
601 | } | |
602 | } | |
603 | } |