org.eclipse.cdt.internal.ui.refactoring.extractfunction.ExtractFunctionInputPage.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.cdt.internal.ui.refactoring.extractfunction.ExtractFunctionInputPage.java

Source

/*******************************************************************************
 * Copyright (c) 2000, 2012 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>
 *     Sergey Prigogin (Google)
 *******************************************************************************/
package org.eclipse.cdt.internal.ui.refactoring.extractfunction;

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.ltk.core.refactoring.RefactoringStatus;
import org.eclipse.ltk.ui.refactoring.UserInputWizardPage;
import org.eclipse.osgi.util.NLS;
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.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.PlatformUI;

import org.eclipse.cdt.ui.CUIPlugin;
import org.eclipse.cdt.ui.PreferenceConstants;
import org.eclipse.cdt.ui.text.CSourceViewerConfiguration;

import org.eclipse.cdt.internal.corext.codemanipulation.StubUtility;

import org.eclipse.cdt.internal.ui.CPluginImages;
import org.eclipse.cdt.internal.ui.ICHelpContextIds;
import org.eclipse.cdt.internal.ui.dialogs.TextFieldNavigationHandler;
import org.eclipse.cdt.internal.ui.editor.CSourceViewer;
import org.eclipse.cdt.internal.ui.refactoring.ChangeParametersControl;
import org.eclipse.cdt.internal.ui.refactoring.ChangeParametersControl.Mode;
import org.eclipse.cdt.internal.ui.refactoring.IParameterListChangeListener;
import org.eclipse.cdt.internal.ui.refactoring.NameInformation;
import org.eclipse.cdt.internal.ui.refactoring.StubTypeContext;
import org.eclipse.cdt.internal.ui.refactoring.utils.VisibilityEnum;
import org.eclipse.cdt.internal.ui.util.RowLayouter;

public class ExtractFunctionInputPage extends UserInputWizardPage {
    public static final String PAGE_NAME = "ExtractFunctionInputPage"; //$NON-NLS-1$
    static final String DIALOG_SETTING_SECTION = "ExtractFunctionWizard"; //$NON-NLS-1$

    private ExtractFunctionRefactoring refactoring;
    private ExtractFunctionInformation info;
    private Text textField;
    private boolean firstTime;
    private CSourceViewer signaturePreview;
    private final Document signaturePreviewDocument;
    private IDialogSettings settings;

    private static final String DESCRIPTION = Messages.ExtractFunctionInputPage_description;
    private static final String ACCESS_MODIFIER = "AccessModifier"; //$NON-NLS-1$

    public ExtractFunctionInputPage() {
        super(PAGE_NAME);
        setImageDescriptor(CPluginImages.DESC_WIZBAN_REFACTOR_TU);
        setDescription(DESCRIPTION);
        firstTime = true;
        signaturePreviewDocument = new Document();
    }

    @Override
    public void createControl(Composite parent) {
        refactoring = (ExtractFunctionRefactoring) getRefactoring();
        info = ((ExtractFunctionRefactoring) getRefactoring()).getRefactoringInfo();
        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());

        textField = createTextInputField(result, SWT.BORDER);
        textField.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

        layouter.perform(label, textField, 1);

        label = new Label(result, SWT.NONE);
        label.setText(Messages.ExtractFunctionInputPage_access_modifier);

        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[] { Messages.ExtractFunctionInputPage_public,
                Messages.ExtractFunctionInputPage_protected, Messages.ExtractFunctionInputPage_private };
        VisibilityEnum[] visibilityValues = new VisibilityEnum[] { VisibilityEnum.v_public,
                VisibilityEnum.v_protected, VisibilityEnum.v_private };
        VisibilityEnum visibility = info.getVisibility();
        for (int i = 0; i < labels.length; i++) {
            Button radio = new Button(group, SWT.RADIO);
            radio.setText(labels[i]);
            radio.setData(visibilityValues[i]);
            if (visibilityValues[i].equals(visibility))
                radio.setSelection(true);
            radio.addSelectionListener(new SelectionAdapter() {
                @Override
                public void widgetSelected(SelectionEvent event) {
                    final VisibilityEnum selectedModifier = (VisibilityEnum) event.widget.getData();
                    settings.put(ACCESS_MODIFIER, selectedModifier.toString());
                    setVisibility(selectedModifier);
                }
            });
        }
        layouter.perform(label, group, 1);

        if (!info.getParameters().isEmpty()) {
            Mode mode = info.getMandatoryReturnVariable() != null ? Mode.EXTRACT_METHOD_FIXED_RETURN
                    : Mode.EXTRACT_METHOD;
            ChangeParametersControl paramControl = new ChangeParametersControl(result, SWT.NONE,
                    Messages.ExtractFunctionInputPage_parameters, new IParameterListChangeListener() {
                        @Override
                        public void parameterChanged(NameInformation parameter) {
                            parameterModified();
                        }

                        @Override
                        public void parameterListChanged() {
                            parameterModified();
                        }

                        @Override
                        public void parameterAdded(NameInformation parameter) {
                            updatePreview(getText());
                        }
                    }, mode, new StubTypeContext(refactoring.getTranslationUnit()));
            gd = new GridData(GridData.FILL_BOTH);
            gd.horizontalSpan = 2;
            paramControl.setLayoutData(gd);
            paramControl.setInput(info.getParameters());
        }

        int duplicates = refactoring.getNumberOfDuplicates();
        Button checkBox = new Button(result, SWT.CHECK);
        if (duplicates == 0) {
            checkBox.setText(Messages.ExtractFunctionInputPage_duplicates_none);
        } else if (duplicates == 1) {
            checkBox.setText(Messages.ExtractFunctionInputPage_duplicates_single);
        } else {
            checkBox.setText(
                    NLS.bind(Messages.ExtractFunctionInputPage_duplicates_multi, Integer.valueOf(duplicates)));
        }
        checkBox.setSelection(info.isReplaceDuplicates());
        checkBox.setEnabled(duplicates > 0);
        checkBox.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                info.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(),
                ICHelpContextIds.EXTRACT_FUNCTION_WIZARD_PAGE);
    }

    private Text createTextInputField(Composite parent, int style) {
        Text result = new Text(parent, style);
        result.addModifyListener(new ModifyListener() {
            @Override
            public void modifyText(ModifyEvent e) {
                textModified(getText());
            }
        });
        TextFieldNavigationHandler.install(result);
        return result;
    }

    private String getText() {
        if (textField == null)
            return null;
        return textField.getText();
    }

    private String getLabelText() {
        return Messages.ExtractFunctionInputPage_label_text;
    }

    private void setVisibility(VisibilityEnum visibility) {
        info.setVisibility(visibility);
        updatePreview(getText());
    }

    private void createSignaturePreview(Composite composite, RowLayouter layouter) {
        Label previewLabel = new Label(composite, SWT.NONE);
        previewLabel.setText(Messages.ExtractFunctionInputPage_signature_preview);
        layouter.perform(previewLabel);

        IPreferenceStore store = CUIPlugin.getDefault().getCombinedPreferenceStore();
        signaturePreview = new CSourceViewer(composite, null, null, false,
                SWT.READ_ONLY | SWT.V_SCROLL | SWT.WRAP /*| SWT.BORDER*/, store);
        signaturePreview.configure(new CSourceViewerConfiguration(
                CUIPlugin.getDefault().getTextTools().getColorManager(), store, null, null));
        signaturePreview.getTextWidget().setFont(JFaceResources.getFont(PreferenceConstants.EDITOR_TEXT_FONT));
        signaturePreview.adaptBackgroundColor(composite);
        signaturePreview.setDocument(signaturePreviewDocument);
        signaturePreview.setEditable(false);

        // Layouting problems with wrapped text: see http://bugs.eclipse.org/bugs/show_bug.cgi?id=9866
        Control signaturePreviewControl = signaturePreview.getControl();
        PixelConverter pixelConverter = new PixelConverter(signaturePreviewControl);
        GridData gdata = new GridData(GridData.FILL_BOTH);
        gdata.widthHint = pixelConverter.convertWidthInCharsToPixels(50);
        gdata.heightHint = pixelConverter.convertHeightInCharsToPixels(3);
        signaturePreviewControl.setLayoutData(gdata);
        layouter.perform(signaturePreviewControl);
    }

    private void updatePreview(String methodName) {
        if (signaturePreview == null)
            return;

        if (methodName.isEmpty()) {
            methodName = StubUtility.suggestMethodName("extracted", null, //$NON-NLS-1$
                    refactoring.getTranslationUnit());
        }

        int top = signaturePreview.getTextWidget().getTopPixel();
        String signature = refactoring.getSignature(methodName);
        signaturePreviewDocument.set(signature);
        signaturePreview.getTextWidget().setTopPixel(top);
    }

    private void loadSettings() {
        settings = getDialogSettings().getSection(DIALOG_SETTING_SECTION);
        if (settings == null) {
            settings = getDialogSettings().addNewSection(DIALOG_SETTING_SECTION);
            settings.put(ACCESS_MODIFIER, VisibilityEnum.v_private.toString());
        }
        final String accessModifier = settings.get(ACCESS_MODIFIER);
        if (accessModifier != null) {
            info.setVisibility(VisibilityEnum.getEnumForStringRepresentation(accessModifier));
        }
    }

    //---- Input validation ------------------------------------------------------

    @Override
    public void setVisible(boolean visible) {
        if (visible) {
            if (firstTime) {
                firstTime = false;
                setPageComplete(false);
                updatePreview(getText());
                textField.setFocus();
            } else {
                setPageComplete(validatePage(true));
            }
        }
        super.setVisible(visible);
    }

    private void textModified(String methodName) {
        info.setMethodName(methodName);
        RefactoringStatus status = validatePage(true);
        if (!status.hasFatalError()) {
            updatePreview(methodName);
        } else {
            signaturePreviewDocument.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 methodName = getText();
        if (methodName.isEmpty()) {
            result.addFatalError(Messages.ExtractFunctionInputPage_validation_empty_function_name);
            return result;
        }
        result.merge(refactoring.checkMethodName());
        return result;
    }

    private RefactoringStatus validateParameters() {
        RefactoringStatus result = new RefactoringStatus();
        for (NameInformation paramInfo : info.getParameters()) {
            if (paramInfo.getNewName().isEmpty()) {
                result.addFatalError(Messages.ExtractFunctionInputPage_validation_empty_parameter_name);
                return result;
            }
        }
        result.merge(refactoring.checkParameterNames());
        return result;
    }
}