| /******************************************************************************* |
| * Copyright (c) 2000, 2011 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| * Benjamin Muskalla <bmuskalla@eclipsesource.com> - [extract method] remember selected access modifier - https://bugs.eclipse.org/bugs/show_bug.cgi?id=101233 |
| *******************************************************************************/ |
| package org.eclipse.jdt.internal.ui.refactoring.code; |
| |
| import java.util.Iterator; |
| import java.util.List; |
| |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.events.ModifyEvent; |
| import org.eclipse.swt.events.ModifyListener; |
| import org.eclipse.swt.events.SelectionAdapter; |
| import org.eclipse.swt.events.SelectionEvent; |
| import org.eclipse.swt.layout.GridData; |
| import org.eclipse.swt.layout.GridLayout; |
| import org.eclipse.swt.widgets.Button; |
| import org.eclipse.swt.widgets.Combo; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.Control; |
| import org.eclipse.swt.widgets.Label; |
| import org.eclipse.swt.widgets.Text; |
| |
| import org.eclipse.jface.dialogs.Dialog; |
| import org.eclipse.jface.dialogs.IDialogSettings; |
| import org.eclipse.jface.layout.PixelConverter; |
| import org.eclipse.jface.preference.IPreferenceStore; |
| import org.eclipse.jface.resource.JFaceResources; |
| |
| import org.eclipse.jface.text.Document; |
| |
| import org.eclipse.ui.PlatformUI; |
| |
| import org.eclipse.ltk.core.refactoring.RefactoringStatus; |
| import org.eclipse.ltk.ui.refactoring.UserInputWizardPage; |
| |
| import org.eclipse.jdt.core.dom.ASTNode; |
| import org.eclipse.jdt.core.dom.AbstractTypeDeclaration; |
| import org.eclipse.jdt.core.dom.AnonymousClassDeclaration; |
| import org.eclipse.jdt.core.dom.ClassInstanceCreation; |
| import org.eclipse.jdt.core.dom.EnumConstantDeclaration; |
| import org.eclipse.jdt.core.dom.Modifier; |
| |
| import org.eclipse.jdt.internal.corext.dom.ASTNodes; |
| import org.eclipse.jdt.internal.corext.refactoring.ParameterInfo; |
| import org.eclipse.jdt.internal.corext.refactoring.code.ExtractMethodRefactoring; |
| import org.eclipse.jdt.internal.corext.util.Messages; |
| |
| import org.eclipse.jdt.ui.PreferenceConstants; |
| import org.eclipse.jdt.ui.text.JavaSourceViewerConfiguration; |
| |
| import org.eclipse.jdt.internal.ui.IJavaHelpContextIds; |
| import org.eclipse.jdt.internal.ui.JavaPlugin; |
| import org.eclipse.jdt.internal.ui.JavaPluginImages; |
| import org.eclipse.jdt.internal.ui.dialogs.TextFieldNavigationHandler; |
| import org.eclipse.jdt.internal.ui.javaeditor.JavaSourceViewer; |
| import org.eclipse.jdt.internal.ui.preferences.JavaPreferencesSettings; |
| import org.eclipse.jdt.internal.ui.refactoring.ChangeParametersControl; |
| import org.eclipse.jdt.internal.ui.refactoring.IParameterListChangeListener; |
| import org.eclipse.jdt.internal.ui.refactoring.RefactoringMessages; |
| import org.eclipse.jdt.internal.ui.util.RowLayouter; |
| import org.eclipse.jdt.internal.ui.util.SWTUtil; |
| import org.eclipse.jdt.internal.ui.viewsupport.BasicElementLabels; |
| |
| |
| public class ExtractMethodInputPage extends UserInputWizardPage { |
| |
| public static final String PAGE_NAME= "ExtractMethodInputPage";//$NON-NLS-1$ |
| |
| private ExtractMethodRefactoring fRefactoring; |
| private Text fTextField; |
| private boolean fFirstTime; |
| private JavaSourceViewer fSignaturePreview; |
| private Document fSignaturePreviewDocument; |
| private IDialogSettings fSettings; |
| |
| private static final String DESCRIPTION = RefactoringMessages.ExtractMethodInputPage_description; |
| private static final String THROW_RUNTIME_EXCEPTIONS= "ThrowRuntimeExceptions"; //$NON-NLS-1$ |
| private static final String GENERATE_JAVADOC= "GenerateJavadoc"; //$NON-NLS-1$ |
| private static final String ACCESS_MODIFIER= "AccessModifier"; //$NON-NLS-1$ |
| |
| public ExtractMethodInputPage() { |
| super(PAGE_NAME); |
| setImageDescriptor(JavaPluginImages.DESC_WIZBAN_REFACTOR_CU); |
| setDescription(DESCRIPTION); |
| fFirstTime= true; |
| fSignaturePreviewDocument= new Document(); |
| } |
| |
| public void createControl(Composite parent) { |
| fRefactoring= (ExtractMethodRefactoring)getRefactoring(); |
| loadSettings(); |
| |
| Composite result= new Composite(parent, SWT.NONE); |
| setControl(result); |
| GridLayout layout= new GridLayout(); |
| layout.numColumns= 2; |
| result.setLayout(layout); |
| RowLayouter layouter= new RowLayouter(2); |
| GridData gd= null; |
| |
| initializeDialogUnits(result); |
| |
| Label label= new Label(result, SWT.NONE); |
| label.setText(getLabelText()); |
| |
| fTextField= createTextInputField(result, SWT.BORDER); |
| fTextField.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); |
| |
| layouter.perform(label, fTextField, 1); |
| |
| ASTNode[] destinations= fRefactoring.getDestinations(); |
| if (destinations.length > 1) { |
| label= new Label(result, SWT.NONE); |
| label.setText(RefactoringMessages.ExtractMethodInputPage_destination_type); |
| final Combo combo= new Combo(result, SWT.READ_ONLY | SWT.DROP_DOWN); |
| SWTUtil.setDefaultVisibleItemCount(combo); |
| for (int i= 0; i < destinations.length; i++) { |
| ASTNode declaration= destinations[i]; |
| combo.add(getLabel(declaration)); |
| } |
| combo.select(0); |
| combo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); |
| combo.addSelectionListener(new SelectionAdapter() { |
| @Override |
| public void widgetSelected(SelectionEvent e) { |
| fRefactoring.setDestination(combo.getSelectionIndex()); |
| updatePreview(getText()); |
| } |
| }); |
| } |
| |
| label= new Label(result, SWT.NONE); |
| label.setText(RefactoringMessages.ExtractMethodInputPage_access_Modifiers); |
| |
| Composite group= new Composite(result, SWT.NONE); |
| group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); |
| layout= new GridLayout(); |
| layout.numColumns= 4; layout.marginWidth= 0; |
| group.setLayout(layout); |
| |
| String[] labels= new String[] { |
| RefactoringMessages.ExtractMethodInputPage_public, |
| RefactoringMessages.ExtractMethodInputPage_protected, |
| RefactoringMessages.ExtractMethodInputPage_default, |
| RefactoringMessages.ExtractMethodInputPage_private |
| }; |
| Integer[] data= new Integer[] {new Integer(Modifier.PUBLIC), new Integer(Modifier.PROTECTED), new Integer(Modifier.NONE), new Integer(Modifier.PRIVATE)}; |
| Integer visibility= new Integer(fRefactoring.getVisibility()); |
| for (int i= 0; i < labels.length; i++) { |
| Button radio= new Button(group, SWT.RADIO); |
| radio.setText(labels[i]); |
| radio.setData(data[i]); |
| if (data[i].equals(visibility)) |
| radio.setSelection(true); |
| radio.addSelectionListener(new SelectionAdapter() { |
| @Override |
| public void widgetSelected(SelectionEvent event) { |
| final Integer selectedModifier= (Integer)event.widget.getData(); |
| fSettings.put(ACCESS_MODIFIER, selectedModifier.intValue()); |
| setVisibility(selectedModifier); |
| } |
| }); |
| } |
| layouter.perform(label, group, 1); |
| |
| if (!fRefactoring.getParameterInfos().isEmpty()) { |
| ChangeParametersControl cp= new ChangeParametersControl(result, SWT.NONE, |
| RefactoringMessages.ExtractMethodInputPage_parameters, |
| new IParameterListChangeListener() { |
| public void parameterChanged(ParameterInfo parameter) { |
| parameterModified(); |
| } |
| public void parameterListChanged() { |
| parameterModified(); |
| } |
| public void parameterAdded(ParameterInfo parameter) { |
| updatePreview(getText()); |
| } |
| }, ChangeParametersControl.Mode.EXTRACT_METHOD); |
| gd= new GridData(GridData.FILL_BOTH); |
| gd.horizontalSpan= 2; |
| cp.setLayoutData(gd); |
| cp.setInput(fRefactoring.getParameterInfos()); |
| } |
| |
| Button checkBox= new Button(result, SWT.CHECK); |
| checkBox.setText(RefactoringMessages.ExtractMethodInputPage_throwRuntimeExceptions); |
| checkBox.setSelection(fSettings.getBoolean(THROW_RUNTIME_EXCEPTIONS)); |
| checkBox.addSelectionListener(new SelectionAdapter() { |
| @Override |
| public void widgetSelected(SelectionEvent e) { |
| setRethrowRuntimeException(((Button)e.widget).getSelection()); |
| } |
| }); |
| layouter.perform(checkBox); |
| |
| checkBox= new Button(result, SWT.CHECK); |
| checkBox.setText(RefactoringMessages.ExtractMethodInputPage_generateJavadocComment); |
| boolean generate= computeGenerateJavadoc(); |
| setGenerateJavadoc(generate); |
| checkBox.setSelection(generate); |
| checkBox.addSelectionListener(new SelectionAdapter() { |
| @Override |
| public void widgetSelected(SelectionEvent e) { |
| setGenerateJavadoc(((Button)e.widget).getSelection()); |
| } |
| }); |
| layouter.perform(checkBox); |
| |
| int duplicates= fRefactoring.getNumberOfDuplicates(); |
| checkBox= new Button(result, SWT.CHECK); |
| if (duplicates == 0) { |
| checkBox.setText(RefactoringMessages.ExtractMethodInputPage_duplicates_none); |
| } else if (duplicates == 1) { |
| checkBox.setText(RefactoringMessages.ExtractMethodInputPage_duplicates_single); |
| } else { |
| checkBox.setText(Messages.format( |
| RefactoringMessages.ExtractMethodInputPage_duplicates_multi, |
| new Integer(duplicates))); |
| } |
| checkBox.setSelection(fRefactoring.getReplaceDuplicates()); |
| checkBox.setEnabled(duplicates > 0); |
| checkBox.addSelectionListener(new SelectionAdapter() { |
| @Override |
| public void widgetSelected(SelectionEvent e) { |
| fRefactoring.setReplaceDuplicates(((Button)e.widget).getSelection()); |
| } |
| }); |
| layouter.perform(checkBox); |
| |
| label= new Label(result, SWT.SEPARATOR | SWT.HORIZONTAL); |
| label.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); |
| layouter.perform(label); |
| |
| createSignaturePreview(result, layouter); |
| |
| Dialog.applyDialogFont(result); |
| PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(), IJavaHelpContextIds.EXTRACT_METHOD_WIZARD_PAGE); |
| } |
| |
| private String getLabel(ASTNode node) { |
| if (node instanceof AbstractTypeDeclaration) { |
| return ((AbstractTypeDeclaration)node).getName().getIdentifier(); |
| } else if (node instanceof AnonymousClassDeclaration) { |
| if (node.getLocationInParent() == ClassInstanceCreation.ANONYMOUS_CLASS_DECLARATION_PROPERTY) { |
| ClassInstanceCreation creation= (ClassInstanceCreation)node.getParent(); |
| return Messages.format( |
| RefactoringMessages.ExtractMethodInputPage_anonymous_type_label, |
| BasicElementLabels.getJavaElementName(ASTNodes.asString(creation.getType()))); |
| } else if (node.getLocationInParent() == EnumConstantDeclaration.ANONYMOUS_CLASS_DECLARATION_PROPERTY) { |
| EnumConstantDeclaration decl= (EnumConstantDeclaration)node.getParent(); |
| return decl.getName().getIdentifier(); |
| } |
| } |
| return "UNKNOWN"; //$NON-NLS-1$ |
| } |
| |
| private Text createTextInputField(Composite parent, int style) { |
| Text result= new Text(parent, style); |
| result.addModifyListener(new ModifyListener() { |
| public void modifyText(ModifyEvent e) { |
| textModified(getText()); |
| } |
| }); |
| TextFieldNavigationHandler.install(result); |
| return result; |
| } |
| |
| private String getText() { |
| if (fTextField == null) |
| return null; |
| return fTextField.getText(); |
| } |
| |
| private String getLabelText(){ |
| return RefactoringMessages.ExtractMethodInputPage_label_text; |
| } |
| |
| private void setVisibility(Integer visibility) { |
| fRefactoring.setVisibility(visibility.intValue()); |
| updatePreview(getText()); |
| } |
| |
| private void setRethrowRuntimeException(boolean value) { |
| fSettings.put(THROW_RUNTIME_EXCEPTIONS, value); |
| fRefactoring.setThrowRuntimeExceptions(value); |
| updatePreview(getText()); |
| } |
| |
| private boolean computeGenerateJavadoc() { |
| boolean result= fRefactoring.getGenerateJavadoc(); |
| if (result) |
| return result; |
| return fSettings.getBoolean(GENERATE_JAVADOC); |
| } |
| |
| private void setGenerateJavadoc(boolean value) { |
| fSettings.put(GENERATE_JAVADOC, value); |
| fRefactoring.setGenerateJavadoc(value); |
| } |
| |
| private void createSignaturePreview(Composite composite, RowLayouter layouter) { |
| Label previewLabel= new Label(composite, SWT.NONE); |
| previewLabel.setText(RefactoringMessages.ExtractMethodInputPage_signature_preview); |
| layouter.perform(previewLabel); |
| |
| IPreferenceStore store= JavaPlugin.getDefault().getCombinedPreferenceStore(); |
| fSignaturePreview= new JavaSourceViewer(composite, null, null, false, SWT.READ_ONLY | SWT.V_SCROLL | SWT.WRAP /*| SWT.BORDER*/, store); |
| fSignaturePreview.configure(new JavaSourceViewerConfiguration(JavaPlugin.getDefault().getJavaTextTools().getColorManager(), store, null, null)); |
| fSignaturePreview.getTextWidget().setFont(JFaceResources.getFont(PreferenceConstants.EDITOR_TEXT_FONT)); |
| fSignaturePreview.adaptBackgroundColor(composite); |
| fSignaturePreview.setDocument(fSignaturePreviewDocument); |
| fSignaturePreview.setEditable(false); |
| |
| //Layouting problems with wrapped text: see https://bugs.eclipse.org/bugs/show_bug.cgi?id=9866 |
| Control signaturePreviewControl= fSignaturePreview.getControl(); |
| PixelConverter pixelConverter= new PixelConverter(signaturePreviewControl); |
| GridData gdata= new GridData(GridData.FILL_BOTH); |
| gdata.widthHint= pixelConverter.convertWidthInCharsToPixels(50); |
| gdata.heightHint= pixelConverter.convertHeightInCharsToPixels(2); |
| signaturePreviewControl.setLayoutData(gdata); |
| layouter.perform(signaturePreviewControl); |
| } |
| |
| private void updatePreview(String text) { |
| if (fSignaturePreview == null) |
| return; |
| |
| if (text.length() == 0) |
| text= "someMethodName"; //$NON-NLS-1$ |
| |
| int top= fSignaturePreview.getTextWidget().getTopPixel(); |
| String signature; |
| try { |
| signature= fRefactoring.getSignature(text); |
| } catch (IllegalArgumentException e) { |
| signature= ""; //$NON-NLS-1$ |
| } |
| fSignaturePreviewDocument.set(signature); |
| fSignaturePreview.getTextWidget().setTopPixel(top); |
| } |
| |
| private void loadSettings() { |
| fSettings= getDialogSettings().getSection(ExtractMethodWizard.DIALOG_SETTING_SECTION); |
| if (fSettings == null) { |
| fSettings= getDialogSettings().addNewSection(ExtractMethodWizard.DIALOG_SETTING_SECTION); |
| fSettings.put(THROW_RUNTIME_EXCEPTIONS, false); |
| fSettings.put(GENERATE_JAVADOC, JavaPreferencesSettings.getCodeGenerationSettings(fRefactoring.getCompilationUnit().getJavaProject()).createComments); |
| fSettings.put(ACCESS_MODIFIER, Modifier.PRIVATE); |
| } |
| fRefactoring.setThrowRuntimeExceptions(fSettings.getBoolean(THROW_RUNTIME_EXCEPTIONS)); |
| final String accessModifier= fSettings.get(ACCESS_MODIFIER); |
| if (accessModifier != null) { |
| fRefactoring.setVisibility(Integer.parseInt(accessModifier)); |
| } |
| } |
| |
| //---- Input validation ------------------------------------------------------ |
| |
| @Override |
| public void setVisible(boolean visible) { |
| if (visible) { |
| if (fFirstTime) { |
| fFirstTime= false; |
| setPageComplete(false); |
| updatePreview(getText()); |
| fTextField.setFocus(); |
| } else { |
| setPageComplete(validatePage(true)); |
| } |
| } |
| super.setVisible(visible); |
| } |
| |
| private void textModified(String text) { |
| fRefactoring.setMethodName(text); |
| RefactoringStatus status= validatePage(true); |
| if (!status.hasFatalError()) { |
| updatePreview(text); |
| } else { |
| fSignaturePreviewDocument.set(""); //$NON-NLS-1$ |
| } |
| setPageComplete(status); |
| } |
| |
| private void parameterModified() { |
| updatePreview(getText()); |
| setPageComplete(validatePage(false)); |
| } |
| |
| private RefactoringStatus validatePage(boolean text) { |
| RefactoringStatus result= new RefactoringStatus(); |
| if (text) { |
| result.merge(validateMethodName()); |
| result.merge(validateParameters()); |
| } else { |
| result.merge(validateParameters()); |
| result.merge(validateMethodName()); |
| } |
| return result; |
| } |
| |
| private RefactoringStatus validateMethodName() { |
| RefactoringStatus result= new RefactoringStatus(); |
| String text= getText(); |
| if ("".equals(text)) { //$NON-NLS-1$ |
| result.addFatalError(RefactoringMessages.ExtractMethodInputPage_validation_emptyMethodName); |
| return result; |
| } |
| result.merge(fRefactoring.checkMethodName()); |
| return result; |
| } |
| |
| private RefactoringStatus validateParameters() { |
| RefactoringStatus result= new RefactoringStatus(); |
| List<ParameterInfo> parameters= fRefactoring.getParameterInfos(); |
| for (Iterator<ParameterInfo> iter= parameters.iterator(); iter.hasNext();) { |
| ParameterInfo info= iter.next(); |
| if ("".equals(info.getNewName())) { //$NON-NLS-1$ |
| result.addFatalError(RefactoringMessages.ExtractMethodInputPage_validation_emptyParameterName); |
| return result; |
| } |
| } |
| result.merge(fRefactoring.checkParameterNames()); |
| result.merge(fRefactoring.checkVarargOrder()); |
| return result; |
| } |
| } |