]> git.uio.no Git - ifi-stolz-refaktor.git/blame - case-study/jdt-before/ui refactoring/org/eclipse/jdt/internal/ui/refactoring/reorg/RenameTypeWizardSimilarElementsPage.java
Case Study: adding data and statistics
[ifi-stolz-refaktor.git] / case-study / jdt-before / ui refactoring / org / eclipse / jdt / internal / ui / refactoring / reorg / RenameTypeWizardSimilarElementsPage.java
CommitLineData
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 *******************************************************************************/
11package org.eclipse.jdt.internal.ui.refactoring.reorg;
12
13import java.util.ArrayList;
14import java.util.HashMap;
15import java.util.HashSet;
16import java.util.Iterator;
17import java.util.List;
18import java.util.Map;
19import java.util.Set;
20
21import org.eclipse.swt.SWT;
22import org.eclipse.swt.custom.CLabel;
23import org.eclipse.swt.custom.SashForm;
24import org.eclipse.swt.custom.ViewForm;
25import org.eclipse.swt.events.SelectionAdapter;
26import org.eclipse.swt.events.SelectionEvent;
27import org.eclipse.swt.graphics.Image;
28import org.eclipse.swt.layout.GridData;
29import org.eclipse.swt.layout.GridLayout;
30import org.eclipse.swt.widgets.Button;
31import org.eclipse.swt.widgets.Composite;
32import org.eclipse.swt.widgets.Control;
33import org.eclipse.swt.widgets.Label;
34import org.eclipse.swt.widgets.Shell;
35import org.eclipse.swt.widgets.Text;
36import org.eclipse.swt.widgets.Tree;
37import org.eclipse.swt.widgets.TreeItem;
38
39import org.eclipse.core.runtime.Assert;
40import org.eclipse.core.runtime.IStatus;
41
42import org.eclipse.jface.dialogs.Dialog;
43import org.eclipse.jface.dialogs.IDialogConstants;
44import org.eclipse.jface.dialogs.StatusDialog;
45import org.eclipse.jface.preference.IPreferenceStore;
46import org.eclipse.jface.resource.ImageDescriptor;
47import org.eclipse.jface.resource.JFaceResources;
48import org.eclipse.jface.viewers.DoubleClickEvent;
49import org.eclipse.jface.viewers.IDoubleClickListener;
50import org.eclipse.jface.viewers.ISelection;
51import org.eclipse.jface.viewers.ISelectionChangedListener;
52import org.eclipse.jface.viewers.IStructuredSelection;
53import org.eclipse.jface.viewers.ITreeContentProvider;
54import org.eclipse.jface.viewers.SelectionChangedEvent;
55import org.eclipse.jface.viewers.StructuredSelection;
56import org.eclipse.jface.viewers.Viewer;
57import org.eclipse.jface.window.Window;
58import org.eclipse.jface.wizard.IWizardPage;
59
60import org.eclipse.jface.text.Document;
61import org.eclipse.jface.text.source.SourceViewer;
62
63import org.eclipse.ui.PlatformUI;
64import org.eclipse.ui.dialogs.ContainerCheckedTreeViewer;
65
66import org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor;
67import org.eclipse.ltk.core.refactoring.participants.RenameRefactoring;
68import org.eclipse.ltk.ui.refactoring.UserInputWizardPage;
69
70import org.eclipse.jdt.core.ICompilationUnit;
71import org.eclipse.jdt.core.IField;
72import org.eclipse.jdt.core.IJavaElement;
73import org.eclipse.jdt.core.ILocalVariable;
74import org.eclipse.jdt.core.IMember;
75import org.eclipse.jdt.core.IMethod;
76import org.eclipse.jdt.core.ISourceRange;
77import org.eclipse.jdt.core.IType;
78import org.eclipse.jdt.core.JavaModelException;
79
80import org.eclipse.jdt.internal.corext.refactoring.Checks;
81import org.eclipse.jdt.internal.corext.refactoring.rename.RenameCompilationUnitProcessor;
82import org.eclipse.jdt.internal.corext.refactoring.rename.RenameTypeProcessor;
83import org.eclipse.jdt.internal.corext.util.JavaConventionsUtil;
84import org.eclipse.jdt.internal.corext.util.Messages;
85
86import org.eclipse.jdt.ui.JavaElementComparator;
87import org.eclipse.jdt.ui.JavaElementLabelProvider;
88import org.eclipse.jdt.ui.JavaElementLabels;
89import org.eclipse.jdt.ui.PreferenceConstants;
90import org.eclipse.jdt.ui.text.JavaSourceViewerConfiguration;
91import org.eclipse.jdt.ui.text.JavaTextTools;
92
93import org.eclipse.jdt.internal.ui.IJavaHelpContextIds;
94import org.eclipse.jdt.internal.ui.JavaPlugin;
95import org.eclipse.jdt.internal.ui.JavaPluginImages;
96import org.eclipse.jdt.internal.ui.dialogs.StatusInfo;
97import org.eclipse.jdt.internal.ui.dialogs.TextFieldNavigationHandler;
98import org.eclipse.jdt.internal.ui.javaeditor.JavaSourceViewer;
99import org.eclipse.jdt.internal.ui.refactoring.RefactoringMessages;
100import org.eclipse.jdt.internal.ui.util.ExceptionHandler;
101import org.eclipse.jdt.internal.ui.util.SWTUtil;
102import org.eclipse.jdt.internal.ui.viewsupport.JavaElementImageProvider;
103import org.eclipse.jdt.internal.ui.wizards.dialogfields.DialogField;
104import org.eclipse.jdt.internal.ui.wizards.dialogfields.IDialogFieldListener;
105import org.eclipse.jdt.internal.ui.wizards.dialogfields.LayoutUtil;
106import org.eclipse.jdt.internal.ui.wizards.dialogfields.StringDialogField;
107
108/**
109 *
110 * Wizard page for displaying a tree of similarly named elements renamed along with a
111 * type.
112 *
113 * @since 3.2
114 *
115 */
116class RenameTypeWizardSimilarElementsPage extends UserInputWizardPage {
117
118 public static class EditElementDialog extends StatusDialog implements IDialogFieldListener {
119
120 private StringDialogField fNameField;
121 private IJavaElement fElementToEdit;
122
123 public EditElementDialog(Shell parent, IJavaElement elementToEdit, String newName) {
124 super(parent);
125 setTitle(RefactoringMessages.RenameTypeWizardSimilarElementsPage_change_element_name);
126 fElementToEdit= elementToEdit;
127
128 fNameField= new StringDialogField();
129 fNameField.setDialogFieldListener(this);
130 fNameField.setLabelText(RefactoringMessages.RenameTypeWizardSimilarElementsPage_enter_new_name);
131
132 fNameField.setText(newName);
133 }
134
135 /*
136 * @see org.eclipse.jface.dialogs.Dialog#isResizable()
137 * @since 3.4
138 */
139 @Override
140 protected boolean isResizable() {
141 return true;
142 }
143
144 /*
145 * (non-Javadoc)
146 *
147 * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite)
148 */
149 @Override
150 protected Control createDialogArea(Composite parent) {
151 final Composite composite= (Composite) super.createDialogArea(parent);
152 LayoutUtil.doDefaultLayout(composite, new DialogField[] { fNameField }, true, SWT.DEFAULT, SWT.DEFAULT);
153 fNameField.postSetFocusOnDialogField(parent.getDisplay());
154
155 LayoutUtil.setWidthHint(fNameField.getLabelControl(null), convertHorizontalDLUsToPixels(IDialogConstants.MINIMUM_MESSAGE_AREA_WIDTH));
156 Text text= fNameField.getTextControl(null);
157 LayoutUtil.setHorizontalGrabbing(text);
158 TextFieldNavigationHandler.install(text);
159
160 Dialog.applyDialogFont(composite);
161 return composite;
162 }
163
164 /*
165 * (non-Javadoc)
166 *
167 * @see org.eclipse.jdt.internal.ui.wizards.dialogfields.IDialogFieldListener#dialogFieldChanged(org.eclipse.jdt.internal.ui.wizards.dialogfields.DialogField)
168 */
169 public void dialogFieldChanged(DialogField field) {
170 if (field == fNameField)
171 updateStatus(validateSettings());
172 }
173
174 private IStatus validateSettings() {
175 final String name= fNameField.getText();
176 if (name.length() == 0) {
177 return new StatusInfo(IStatus.ERROR, RefactoringMessages.RenameTypeWizardSimilarElementsPage_name_empty);
178 }
179 IStatus status= JavaConventionsUtil.validateIdentifier(name, fElementToEdit);
180 if (status.matches(IStatus.ERROR))
181 return status;
182 if (!Checks.startsWithLowerCase(name))
183 return new StatusInfo(IStatus.WARNING, RefactoringMessages.RenameTypeWizardSimilarElementsPage_name_should_start_lowercase);
184
185 if (fElementToEdit instanceof IMember && ((IMember) fElementToEdit).getDeclaringType() != null) {
186 IType type= ((IMember) fElementToEdit).getDeclaringType();
187 if (fElementToEdit instanceof IField) {
188 final IField f= type.getField(name);
189 if (f.exists())
190 return new StatusInfo(IStatus.ERROR, RefactoringMessages.RenameTypeWizardSimilarElementsPage_field_exists);
191 }
192 if (fElementToEdit instanceof IMethod) {
193 final IMethod m= type.getMethod(name, ((IMethod) fElementToEdit).getParameterTypes());
194 if (m.exists())
195 return new StatusInfo(IStatus.ERROR, RefactoringMessages.RenameTypeWizardSimilarElementsPage_method_exists);
196 }
197 }
198
199 // cannot check local variables; no .getLocalVariable(String) in IMember
200
201 return StatusInfo.OK_STATUS;
202 }
203
204 public String getNewName() {
205 return fNameField.getText();
206 }
207 }
208
209 private static class SimilarElementTreeContentProvider implements ITreeContentProvider {
210
211 private Map<IJavaElement, Set<IJavaElement>> fTreeElementMap;
212 private Set<ICompilationUnit> fTopLevelElements;
213
214 /*
215 * @see ITreeContentProvider#getChildren(Object)
216 */
217 public Object[] getChildren(Object parentElement) {
218 final Set<IJavaElement> children= fTreeElementMap.get(parentElement);
219 if (children != null)
220 return children.toArray();
221 else
222 return new Object[0];
223 }
224
225 /*
226 * @see ITreeContentProvider#getParent(Object)
227 */
228 public Object getParent(Object element) {
229 if (element instanceof IMember || element instanceof ILocalVariable) {
230 return ((IJavaElement) element).getParent();
231 }
232 if (element instanceof ICompilationUnit)
233 return null;
234 Assert.isTrue(false, "Should not get here"); //$NON-NLS-1$
235 return null;
236 }
237
238 /*
239 * @see ITreeContentProvider#hasChildren(Object)
240 */
241 public boolean hasChildren(Object element) {
242 return fTreeElementMap.containsKey(element);
243 }
244
245 /*
246 * @see IStructuredContentProvider#getElements(Object)
247 */
248 public Object[] getElements(Object inputElement) {
249 Assert.isTrue(inputElement == null || inputElement instanceof Map);
250 return fTopLevelElements.toArray();
251 }
252
253 /*
254 * @see IContentProvider#dispose()
255 */
256 public void dispose() {
257 fTreeElementMap.clear();
258 fTreeElementMap= null;
259 fTopLevelElements= null;
260 }
261
262 /*
263 * @see IContentProvider#inputChanged(Viewer, Object, Object)
264 */
265 public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
266 Assert.isTrue(newInput == null || newInput instanceof Map);
267 if (newInput == null)
268 return;
269 @SuppressWarnings("unchecked")
270 final Map<IJavaElement, String> similarElementsMap= (Map<IJavaElement, String>) newInput;
271 final IJavaElement[] similarElements= similarElementsMap.keySet().toArray(new IJavaElement[0]);
272 fTreeElementMap= new HashMap<IJavaElement, Set<IJavaElement>>();
273 fTopLevelElements= new HashSet<ICompilationUnit>();
274 for (int i= 0; i < similarElements.length; i++) {
275 final IType declaring= (IType) similarElements[i].getAncestor(IJavaElement.TYPE);
276 if (similarElements[i] instanceof IMember) {
277 // methods, fields, initializers, inner types
278 addToMap(declaring, similarElements[i]);
279 } else {
280 // local variables
281 final IJavaElement parent= similarElements[i].getParent();
282 if (parent instanceof IMember) {
283 // parent is a method or an initializer
284 addToMap(parent, similarElements[i]);
285 addToMap(declaring, parent);
286 }
287 }
288 handleDeclaring(declaring);
289 }
290 }
291
292 private void handleDeclaring(final IJavaElement someType) {
293
294 final IJavaElement enclosing= someType.getParent();
295 if (enclosing instanceof ICompilationUnit) {
296 fTopLevelElements.add((ICompilationUnit) enclosing);
297 addToMap(someType.getParent(), someType);
298 } else {
299 addToMap(enclosing, someType);
300 handleDeclaring(enclosing);
301 }
302 }
303
304 private void addToMap(final IJavaElement key, final IJavaElement element) {
305 Set<IJavaElement> elements= fTreeElementMap.get(key);
306 if (elements == null) {
307 elements= new HashSet<IJavaElement>();
308 fTreeElementMap.put(key, elements);
309 }
310 elements.add(element);
311 }
312
313 }
314
315 private static class SimilarLabelProvider extends JavaElementLabelProvider {
316
317 private Map<ImageDescriptor, Image> fDescriptorImageMap= new HashMap<ImageDescriptor, Image>();
318 private Map<IJavaElement, String> fElementToNewName;
319
320 public SimilarLabelProvider() {
321 super(JavaElementLabelProvider.SHOW_DEFAULT | JavaElementLabelProvider.SHOW_SMALL_ICONS);
322 }
323
324 public void initialize(Map<IJavaElement, String> elementToNewName) {
325 this.fElementToNewName= elementToNewName;
326 }
327
328 @Override
329 public void dispose() {
330 for (Iterator<Image> iter= fDescriptorImageMap.values().iterator(); iter.hasNext();) {
331 Image image= iter.next();
332 image.dispose();
333 }
334 super.dispose();
335 }
336
337 private Image manageImageDescriptor(ImageDescriptor descriptor) {
338 Image image= fDescriptorImageMap.get(descriptor);
339 if (image == null) {
340 image= descriptor.createImage();
341 fDescriptorImageMap.put(descriptor, image);
342 }
343 return image;
344 }
345
346 @Override
347 public Image getImage(Object element) {
348 if (isSimilarElement(element))
349 return manageImageDescriptor(JavaPluginImages.DESC_OBJS_DEFAULT_CHANGE);
350 return super.getImage(element);
351 }
352
353 public Image getJavaImage(Object element) {
354 return super.getImage(element);
355 }
356
357 @Override
358 public String getText(Object element) {
359 if (isSimilarElement(element)) {
360 return Messages.format(RefactoringMessages.RenameTypeWizardSimilarElementsPage_rename_to, new String[] { super.getText(element), fElementToNewName.get(element) } );
361 }
362 return super.getText(element);
363 }
364
365 private boolean isSimilarElement(Object element) {
366 return fElementToNewName.containsKey(element);
367 }
368
369 }
370
371 private static class SimilarElementComparator extends JavaElementComparator {
372
373 /*
374 * (non-Javadoc)
375 * @see org.eclipse.jdt.ui.JavaElementSorter#category(java.lang.Object)
376 */
377 @Override
378 public int category(Object element) {
379
380 /*
381 * We'd like to present the elements in the same order as they
382 * appear in the source. This can be achieved by assigning a
383 * distinct category to every element; the category being derived
384 * from the source position of the element.
385 */
386
387 ISourceRange sourceRange= null;
388 if (element instanceof IMember) {
389 IMember member= (IMember) element;
390 try {
391 sourceRange= member.getNameRange();
392 } catch (JavaModelException e) {
393 // fall through
394 }
395 }
396 if (element instanceof ILocalVariable) {
397 ILocalVariable var= (ILocalVariable) element;
398 sourceRange= var.getNameRange();
399 }
400
401 if (sourceRange != null)
402 return 100 + sourceRange.getOffset(); // +100: safe distance from all other categories.
403
404 return super.category(element);
405 }
406 }
407
408 public static final String PAGE_NAME= "SimilarElementSelectionPage"; //$NON-NLS-1$
409
410 private final long LABEL_FLAGS= JavaElementLabels.DEFAULT_QUALIFIED | JavaElementLabels.ROOT_POST_QUALIFIED | JavaElementLabels.APPEND_ROOT_PATH | JavaElementLabels.M_PARAMETER_TYPES
411 | JavaElementLabels.M_PARAMETER_NAMES | JavaElementLabels.M_APP_RETURNTYPE | JavaElementLabels.M_EXCEPTIONS | JavaElementLabels.F_APP_TYPE_SIGNATURE | JavaElementLabels.T_TYPE_PARAMETERS;
412
413 private Label fSimilarElementsLabel;
414 private SourceViewer fSourceViewer;
415 private ContainerCheckedTreeViewer fTreeViewer;
416 private SimilarLabelProvider fTreeViewerLabelProvider;
417 private Map<IJavaElement, String> fSimilarElementsToNewName;
418 private Button fEditElementButton;
419 private boolean fWasInitialized;
420 private CLabel fCurrentElementLabel;
421
422 public RenameTypeWizardSimilarElementsPage() {
423 super(PAGE_NAME);
424 }
425
426 // --- UI creation
427
428 public void createControl(Composite parent) {
429
430 ViewForm viewForm= new ViewForm(parent, SWT.BORDER | SWT.FLAT);
431
432 Composite inner= new Composite(viewForm, SWT.NULL);
433 GridLayout layout= new GridLayout();
434 inner.setLayout(layout);
435
436 createTreeAndSourceViewer(inner);
437 createButtonComposite(inner);
438 viewForm.setContent(inner);
439
440 setControl(viewForm);
441
442 Dialog.applyDialogFont(viewForm);
443 PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(), IJavaHelpContextIds.RENAME_TYPE_WIZARD_PAGE);
444 }
445
446 private void createTreeAndSourceViewer(Composite superComposite) {
447 SashForm composite= new SashForm(superComposite, SWT.HORIZONTAL);
448 initializeDialogUnits(superComposite);
449 GridData gd= new GridData(GridData.FILL_BOTH);
450 gd.heightHint= convertHeightInCharsToPixels(20);
451 gd.widthHint= convertWidthInCharsToPixels(10);
452 composite.setLayoutData(gd);
453 GridLayout layout= new GridLayout();
454 layout.numColumns= 2;
455 layout.marginWidth= 0;
456 layout.marginHeight= 0;
457 composite.setLayout(layout);
458
459 createSimilarElementTreeComposite(composite);
460 createSourceViewerComposite(composite);
461 composite.setWeights(new int[] { 50, 50 });
462 }
463
464 private void createSimilarElementTreeComposite(Composite parent) {
465 Composite composite= new Composite(parent, SWT.NONE);
466 composite.setLayoutData(new GridData(GridData.FILL_BOTH));
467 GridLayout layout= new GridLayout();
468 layout.marginWidth= 0;
469 layout.marginHeight= 0;
470 composite.setLayout(layout);
471
472 createTypeHierarchyLabel(composite);
473 createTreeViewer(composite);
474 }
475
476 private void createTypeHierarchyLabel(Composite composite) {
477 fSimilarElementsLabel= new Label(composite, SWT.WRAP);
478 GridData gd= new GridData(GridData.FILL_HORIZONTAL);
479 gd.heightHint= JavaElementImageProvider.SMALL_SIZE.x;
480 fSimilarElementsLabel.setLayoutData(gd);
481 fSimilarElementsLabel.setText(RefactoringMessages.RenameTypeWizardSimilarElementsPage_review_similar_elements);
482 }
483
484 private void createTreeViewer(Composite composite) {
485 Tree tree= new Tree(composite, SWT.CHECK | SWT.BORDER | SWT.SINGLE | SWT.V_SCROLL | SWT.H_SCROLL);
486 tree.setLayoutData(new GridData(GridData.FILL_BOTH));
487 fTreeViewer= new ContainerCheckedTreeViewer(tree);
488 fTreeViewer.setUseHashlookup(true);
489 fTreeViewer.setComparator(new SimilarElementComparator());
490 fTreeViewer.setContentProvider(new SimilarElementTreeContentProvider());
491 fTreeViewerLabelProvider= new SimilarLabelProvider();
492 fTreeViewer.setLabelProvider(fTreeViewerLabelProvider);
493 fTreeViewer.addSelectionChangedListener(new ISelectionChangedListener() {
494
495 public void selectionChanged(SelectionChangedEvent event) {
496 RenameTypeWizardSimilarElementsPage.this.treeViewerSelectionChanged(event);
497 }
498 });
499 fTreeViewer.addDoubleClickListener(new IDoubleClickListener() {
500
501 public void doubleClick(DoubleClickEvent event) {
502 RenameTypeWizardSimilarElementsPage.this.editCurrentElement();
503 }
504 });
505 }
506
507 private void createSourceViewerComposite(Composite parent) {
508 Composite c= new Composite(parent, SWT.NONE);
509 c.setLayoutData(new GridData(GridData.FILL_BOTH));
510 GridLayout layout= new GridLayout();
511 layout.marginWidth= 0;
512 layout.marginHeight= 0;
513 c.setLayout(layout);
514
515 createSourceViewerLabel(c);
516 createSourceViewer(c);
517 }
518
519 private void createSourceViewerLabel(Composite c) {
520 fCurrentElementLabel= new CLabel(c, SWT.NONE);
521 GridData gd= new GridData(GridData.FILL_HORIZONTAL);
522 gd.heightHint= JavaElementImageProvider.SMALL_SIZE.x;
523 fCurrentElementLabel.setText(RefactoringMessages.RenameTypeWizardSimilarElementsPage_select_element_to_view_source);
524 fCurrentElementLabel.setLayoutData(gd);
525 }
526
527 private void createSourceViewer(Composite c) {
528 IPreferenceStore store= JavaPlugin.getDefault().getCombinedPreferenceStore();
529 fSourceViewer= new JavaSourceViewer(c, null, null, false, SWT.V_SCROLL | SWT.H_SCROLL | SWT.MULTI | SWT.BORDER | SWT.FULL_SELECTION, store);
530 fSourceViewer.configure(new JavaSourceViewerConfiguration(getJavaTextTools().getColorManager(), store, null, null));
531 fSourceViewer.setEditable(false);
532 fSourceViewer.getControl().setLayoutData(new GridData(GridData.FILL_BOTH));
533 fSourceViewer.getControl().setFont(JFaceResources.getFont(PreferenceConstants.EDITOR_TEXT_FONT));
534 Document document= new Document();
535 getJavaTextTools().setupJavaDocumentPartitioner(document);
536 fSourceViewer.setDocument(document);
537 }
538
539 private static JavaTextTools getJavaTextTools() {
540 return JavaPlugin.getDefault().getJavaTextTools();
541 }
542
543 private void createButtonComposite(Composite superComposite) {
544 Composite buttonComposite= new Composite(superComposite, SWT.NONE);
545 buttonComposite.setLayoutData(new GridData());
546 GridLayout layout= new GridLayout(2, false);
547 layout.marginWidth= 0;
548 buttonComposite.setLayout(layout);
549
550 Button returnToDefaults= new Button(buttonComposite, SWT.PUSH);
551 returnToDefaults.setText(RefactoringMessages.RenameTypeWizardSimilarElementsPage_restore_defaults);
552 returnToDefaults.setLayoutData(new GridData());
553 SWTUtil.setButtonDimensionHint(returnToDefaults);
554 returnToDefaults.addSelectionListener(new SelectionAdapter() {
555
556 @Override
557 public void widgetSelected(SelectionEvent e) {
558 RenameTypeWizardSimilarElementsPage.this.resetDataInRefAndUI();
559 }
560 });
561 fEditElementButton= new Button(buttonComposite, SWT.PUSH);
562 fEditElementButton.setText(RefactoringMessages.RenameTypeWizardSimilarElementsPage_change_name);
563 fEditElementButton.setLayoutData(new GridData());
564 fEditElementButton.setEnabled(false);
565 SWTUtil.setButtonDimensionHint(fEditElementButton);
566 fEditElementButton.addSelectionListener(new SelectionAdapter() {
567
568 @Override
569 public void widgetSelected(SelectionEvent e) {
570 RenameTypeWizardSimilarElementsPage.this.editCurrentElement();
571 }
572 });
573 }
574
575
576 // ---------------------- Acting
577
578 @Override
579 public void setVisible(boolean visible) {
580 if (visible) {
581 initializeUIFromRef();
582 }
583 super.setVisible(visible);
584 selectFirstElement();
585 }
586
587 private void selectFirstElement() {
588 if (fTreeViewer.getTree().getItemCount() > 0) {
589 TreeItem item= fTreeViewer.getTree().getItem(0);
590 if (item.getData() != null) {
591 fTreeViewer.reveal(item.getData());
592 Object data= getFirstSimilarElement(item);
593 if (data != null) {
594 fTreeViewer.setSelection(new StructuredSelection(data));
595 }
596 }
597 }
598 fTreeViewer.getTree().setFocus();
599 }
600
601 private Object getFirstSimilarElement(TreeItem item) {
602 Object data= item.getData();
603 if (isSimilarElement(data)) {
604 return data;
605 } else {
606 TreeItem[] children= item.getItems();
607 for (int i= 0; i < children.length; i++) {
608 Object childData= getFirstSimilarElement(children[i]);
609 if (childData != null)
610 return childData;
611 }
612 }
613 return null;
614 }
615
616 private void initializeUIFromRef() {
617 // Get data from the refactoring
618 final Map<IJavaElement, String> elementsToNewNames= getRenameTypeProcessor().getSimilarElementsToNewNames();
619 try {
620 // To prevent flickering, stop redrawing
621 getShell().setRedraw(false);
622 if (fSimilarElementsToNewName == null || elementsToNewNames != fSimilarElementsToNewName) {
623 fSimilarElementsToNewName= elementsToNewNames;
624 fTreeViewerLabelProvider.initialize(fSimilarElementsToNewName);
625 fTreeViewer.setInput(fSimilarElementsToNewName);
626 }
627 fTreeViewer.expandAll();
628 restoreSelectionAndNames(getRenameTypeProcessor().getSimilarElementsToSelection());
629 } finally {
630 getShell().setRedraw(true);
631 }
632 fWasInitialized= true;
633 }
634
635 private void initializeRefFromUI() {
636 IJavaElement[] selected= getCheckedSimilarElements();
637 Map<IJavaElement, Boolean> selection= getRenameTypeProcessor().getSimilarElementsToSelection();
638 for (Iterator<IJavaElement> iter= selection.keySet().iterator(); iter.hasNext();) {
639 IJavaElement element= iter.next();
640 selection.put(element, Boolean.FALSE);
641 }
642 for (int i= 0; i < selected.length; i++)
643 selection.put(selected[i], Boolean.TRUE);
644
645 }
646
647 private void resetDataInRefAndUI() {
648 getRenameTypeProcessor().resetSelectedSimilarElements();
649 restoreSelectionAndNames(getRenameTypeProcessor().getSimilarElementsToSelection());
650 }
651
652 protected void editCurrentElement() {
653 IStructuredSelection selection= (IStructuredSelection) fTreeViewer.getSelection();
654 if ( (selection != null) && isSimilarElement(selection.getFirstElement())) {
655 IJavaElement element= (IJavaElement) selection.getFirstElement();
656 String newName= fSimilarElementsToNewName.get(element);
657 if (newName == null)
658 return;
659 EditElementDialog dialog= new EditElementDialog(getShell(), element, newName);
660 if (dialog.open() == Window.OK) {
661 String changedName= dialog.getNewName();
662 if (!changedName.equals(newName)) {
663 fSimilarElementsToNewName.put(element, changedName);
664 fTreeViewer.update(element, null);
665 }
666 }
667 }
668 }
669
670 private void restoreSelectionAndNames(final Map<IJavaElement, Boolean> selection) {
671 final Map<IJavaElement, Boolean> selectedElements= selection;
672 for (Iterator<IJavaElement> iter= selectedElements.keySet().iterator(); iter.hasNext();) {
673 IJavaElement element= iter.next();
674 boolean isSelected= selectedElements.get(element).booleanValue();
675 fTreeViewer.setChecked(element, isSelected);
676 fTreeViewer.update(element, null);
677 }
678 }
679
680 // ------------ Navigation
681
682 /*
683 * @see IWizardPage#getNextPage()
684 */
685 @Override
686 public IWizardPage getNextPage() {
687 if (fWasInitialized)
688 initializeRefFromUI();
689 // computes the input successor page
690 // (=create changes)
691 IWizardPage nextPage= super.getNextPage();
692 if (nextPage != this) // if user pressed cancel, then the next page is the current page
693 nextPage.setPreviousPage(this);
694 return nextPage;
695 }
696
697
698 /*
699 * @see IWizardPage#getPreviousPage()
700 */
701 @Override
702 public IWizardPage getPreviousPage() {
703 if (fWasInitialized)
704 initializeRefFromUI();
705 return super.getPreviousPage();
706 }
707
708 /*
709 * @see RefactoringWizardPage#performFinish()
710 */
711 @Override
712 protected boolean performFinish() {
713 initializeRefFromUI();
714 return super.performFinish();
715 }
716
717 // ------------ Helper
718
719 private boolean isSimilarElement(Object element) {
720 if (!fWasInitialized)
721 return false;
722
723 return fSimilarElementsToNewName.containsKey(element);
724 }
725
726 private void treeViewerSelectionChanged(SelectionChangedEvent event) {
727 try {
728 final IJavaElement selection= getFirstSelectedSourceReference(event);
729 setSourceViewerContents(selection);
730 fEditElementButton.setEnabled(selection != null && (isSimilarElement(selection)));
731 fCurrentElementLabel.setText(selection != null ? JavaElementLabels.getElementLabel(selection, LABEL_FLAGS) : RefactoringMessages.RenameTypeWizardSimilarElementsPage_select_element_to_view_source);
732 fCurrentElementLabel.setImage(selection != null ? fTreeViewerLabelProvider.getJavaImage(selection) : null);
733 } catch (JavaModelException e) {
734 ExceptionHandler.handle(e, RefactoringMessages.RenameTypeWizard_defaultPageTitle, RefactoringMessages.RenameTypeWizard_unexpected_exception);
735 }
736 }
737
738 private IJavaElement getFirstSelectedSourceReference(SelectionChangedEvent event) {
739 ISelection s= event.getSelection();
740 if (! (s instanceof IStructuredSelection))
741 return null;
742 IStructuredSelection strSel= (IStructuredSelection) s;
743 if (strSel.size() != 1)
744 return null;
745 Object first= strSel.getFirstElement();
746 if (! (first instanceof IJavaElement))
747 return null;
748 return (IJavaElement) first;
749 }
750
751 private void setSourceViewerContents(IJavaElement el) throws JavaModelException {
752 String EMPTY= ""; //$NON-NLS-1$
753 if (el == null) {
754 fSourceViewer.getDocument().set(EMPTY);
755 return;
756 }
757 ICompilationUnit element= (ICompilationUnit) el.getAncestor(IJavaElement.COMPILATION_UNIT);
758 if (element == null) {
759 fSourceViewer.getDocument().set(EMPTY);
760 return;
761 }
762
763 String contents= element.getSource();
764 try {
765 fSourceViewer.setRedraw(false);
766 fSourceViewer.getDocument().set(contents == null ? EMPTY : contents);
767 ISourceRange sr= getNameRange(el);
768 if (sr != null) {
769 fSourceViewer.setSelectedRange(sr.getOffset(), sr.getLength());
770 }
771 } finally {
772 fSourceViewer.setRedraw(true);
773 }
774 }
775
776 private ISourceRange getNameRange(IJavaElement element) throws JavaModelException {
777 if (element instanceof IMember)
778 return ((IMember) element).getNameRange();
779 else if (element instanceof ILocalVariable)
780 return ((ILocalVariable) element).getNameRange();
781 else
782 return null;
783 }
784
785 private IJavaElement[] getCheckedSimilarElements() {
786 Object[] checked= fTreeViewer.getCheckedElements();
787 List<IJavaElement> elements= new ArrayList<IJavaElement>(checked.length);
788 for (int i= 0; i < checked.length; i++) {
789 if (isSimilarElement(checked[i]))
790 elements.add((IJavaElement) checked[i]);
791 }
792 return elements.toArray(new IJavaElement[elements.size()]);
793 }
794
795 public RenameTypeProcessor getRenameTypeProcessor() {
796 RefactoringProcessor proc= ((RenameRefactoring) getRefactoring()).getProcessor();
797 if (proc instanceof RenameTypeProcessor)
798 return (RenameTypeProcessor) proc;
799 else if (proc instanceof RenameCompilationUnitProcessor) {
800 RenameCompilationUnitProcessor rcu= (RenameCompilationUnitProcessor) proc;
801 return rcu.getRenameTypeProcessor();
802 }
803 Assert.isTrue(false); // Should never get here
804 return null;
805 }
806}