FileDocCategorySizeDatePackage
ExtractStringInputPage.javaAPI DocAndroid 1.5 API19567Wed May 06 22:41:10 BST 2009com.android.ide.eclipse.adt.refactorings.extractstring

ExtractStringInputPage

public class ExtractStringInputPage extends org.eclipse.ltk.ui.refactoring.UserInputWizardPage implements org.eclipse.jface.wizard.IWizardPage
see
ExtractStringRefactoring

Fields Summary
private static HashMap
sLastResFilePath
Last res file path used, shared across the session instances but specific to the current project. The default for unknown projects is {@link #DEFAULT_RES_FILE_PATH}.
private final org.eclipse.core.resources.IProject
mProject
The project where the user selection happened.
private org.eclipse.swt.widgets.Text
mStringIdField
Test field where the user enters the new ID to be generated or replaced with.
private com.android.ide.eclipse.adt.ui.ConfigurationSelector
mConfigSelector
The configuration selector, to select the resource path of the XML file.
private org.eclipse.swt.widgets.Combo
mResFileCombo
The combo to display the existing XML files or enter a new one.
private static final Pattern
RES_XML_FILE_REGEX
Regex pattern to read a valid res XML file path. It checks that the are 2 folders and a leaf file name ending with .xml
private static final String
RES_FOLDER_ABS
Absolute destination folder root, e.g. "/res/"
private static final String
RES_FOLDER_REL
Relative destination folder root, e.g. "res/"
private static final String
DEFAULT_RES_FILE_PATH
private XmlStringFileHelper
mXmlHelper
Constructors Summary
public ExtractStringInputPage(org.eclipse.core.resources.IProject project)

    
       
        super("ExtractStringInputPage");  //$NON-NLS-1$
        mProject = project;
    
Methods Summary
public voidcreateControl(org.eclipse.swt.widgets.Composite parent)
Create the UI for the refactoring wizard.

Note that at that point the initial conditions have been checked in {@link ExtractStringRefactoring}.

        Composite content = new Composite(parent, SWT.NONE);
        GridLayout layout = new GridLayout();
        layout.numColumns = 1;
        content.setLayout(layout);
        
        createStringGroup(content);
        createResFileGroup(content);

        validatePage();
        setControl(content);
    
private voidcreateResFileGroup(org.eclipse.swt.widgets.Composite content)
Creates the lower group with the fields to choose the resource confirmation and the target XML file.

param
content A composite with a 1-column grid layout


        Group group = new Group(content, SWT.NONE);
        group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        group.setText("XML resource to edit");

        GridLayout layout = new GridLayout();
        layout.numColumns = 2;
        group.setLayout(layout);
        
        // line: selection of the res config

        Label label;
        label = new Label(group, SWT.NONE);
        label.setText("Configuration:");

        mConfigSelector = new ConfigurationSelector(group);
        GridData gd = new GridData(2, GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL);
        gd.widthHint = ConfigurationSelector.WIDTH_HINT;
        gd.heightHint = ConfigurationSelector.HEIGHT_HINT;
        mConfigSelector.setLayoutData(gd);
        OnConfigSelectorUpdated onConfigSelectorUpdated = new OnConfigSelectorUpdated();
        mConfigSelector.setOnChangeListener(onConfigSelectorUpdated);
        
        // line: selection of the output file

        label = new Label(group, SWT.NONE);
        label.setText("Resource file:");

        mResFileCombo = new Combo(group, SWT.DROP_DOWN);
        mResFileCombo.select(0);
        mResFileCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        mResFileCombo.addModifyListener(onConfigSelectorUpdated);

        // set output file name to the last one used
        
        String projPath = mProject.getFullPath().toPortableString();
        String filePath = sLastResFilePath.get(projPath);
        
        mResFileCombo.setText(filePath != null ? filePath : DEFAULT_RES_FILE_PATH);
        onConfigSelectorUpdated.run();
    
public voidcreateStringGroup(org.eclipse.swt.widgets.Composite content)
Creates the top group with the field to replace which string and by what and by which options.

param
content A composite with a 1-column grid layout


        final ExtractStringRefactoring ref = getOurRefactoring();
        
        Group group = new Group(content, SWT.NONE);
        group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        if (ref.getMode() == ExtractStringRefactoring.Mode.EDIT_SOURCE) {
            group.setText("String Replacement");
        } else {
            group.setText("New String");
        }

        GridLayout layout = new GridLayout();
        layout.numColumns = 2;
        group.setLayout(layout);

        // line: Textfield for string value (based on selection, if any)
        
        Label label = new Label(group, SWT.NONE);
        label.setText("String");

        String selectedString = ref.getTokenString();
        
        final Text stringValueField = new Text(group, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
        stringValueField.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        stringValueField.setText(selectedString != null ? selectedString : "");  //$NON-NLS-1$
        
        ref.setNewStringValue(stringValueField.getText());

        stringValueField.addModifyListener(new ModifyListener() {
            public void modifyText(ModifyEvent e) {
                if (validatePage()) {
                    ref.setNewStringValue(stringValueField.getText());
                }
            }
        });

        
        // TODO provide an option to replace all occurences of this string instead of
        // just the one.

        // line : Textfield for new ID
        
        label = new Label(group, SWT.NONE);
        if (ref.getMode() == ExtractStringRefactoring.Mode.EDIT_SOURCE) {
            label.setText("Replace by R.string.");
        } else if (ref.getMode() == ExtractStringRefactoring.Mode.SELECT_NEW_ID) {
            label.setText("New R.string.");
        } else {
            label.setText("ID R.string.");
        }

        mStringIdField = new Text(group, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
        mStringIdField.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        mStringIdField.setText(guessId(selectedString));

        ref.setNewStringId(mStringIdField.getText().trim());

        mStringIdField.addModifyListener(new ModifyListener() {
            public void modifyText(ModifyEvent e) {
                if (validatePage()) {
                    ref.setNewStringId(mStringIdField.getText().trim());
                }
            }
        });
    
private ExtractStringRefactoringgetOurRefactoring()
Returns the {@link ExtractStringRefactoring} instance used by this wizard page.

        return (ExtractStringRefactoring) getRefactoring();
    
private java.lang.StringguessId(java.lang.String text)
Utility method to guess a suitable new XML ID based on the selected string.

        if (text == null) {
            return "";  //$NON-NLS-1$
        }

        // make lower case
        text = text.toLowerCase();
        
        // everything not alphanumeric becomes an underscore
        text = text.replaceAll("[^a-zA-Z0-9]+", "_");  //$NON-NLS-1$ //$NON-NLS-2$

        // the id must be a proper Java identifier, so it can't start with a number
        if (text.length() > 0 && !Character.isJavaIdentifierStart(text.charAt(0))) {
            text = "_" + text;  //$NON-NLS-1$
        }
        return text;
    
private booleanvalidatePage()
Validates fields of the wizard input page. Displays errors as appropriate and enable the "Next" button (or not) by calling {@link #setPageComplete(boolean)}.

return
True if the page has been positively validated. It may still have warnings.

        boolean success = true;

        // Analyze fatal errors.
        
        String text = mStringIdField.getText().trim();
        if (text == null || text.length() < 1) {
            setErrorMessage("Please provide a resource ID.");
            success = false;
        } else {
            for (int i = 0; i < text.length(); i++) {
                char c = text.charAt(i);
                boolean ok = i == 0 ?
                        Character.isJavaIdentifierStart(c) :
                        Character.isJavaIdentifierPart(c);
                if (!ok) {
                    setErrorMessage(String.format(
                            "The resource ID must be a valid Java identifier. The character %1$c at position %2$d is not acceptable.",
                            c, i+1));
                    success = false;
                    break;
                }
            }
        }

        String resFile = mResFileCombo.getText();
        if (success) {           
            if (resFile == null || resFile.length() == 0) {
                setErrorMessage("A resource file name is required.");
                success = false;
            } else if (!RES_XML_FILE_REGEX.matcher(resFile).matches()) {
                setErrorMessage("The XML file name is not valid.");
                success = false;
            }
        }
        
        // Analyze info & warnings.
        
        if (success) {
            setErrorMessage(null);

            ExtractStringRefactoring ref = getOurRefactoring();

            ref.setTargetFile(resFile);
            sLastResFilePath.put(mProject.getFullPath().toPortableString(), resFile);

            if (mXmlHelper.isResIdDuplicate(mProject, resFile, text)) {
                String msg = String.format("There's already a string item called '%1$s' in %2$s.",
                        text, resFile);
                if (ref.getMode() == ExtractStringRefactoring.Mode.SELECT_NEW_ID) {
                    setErrorMessage(msg);
                    success = false;
                } else {
                    setMessage(msg, WizardPage.WARNING);
                }
            } else if (mProject.findMember(resFile) == null) {
                setMessage(
                        String.format("File %2$s does not exist and will be created.",
                                text, resFile),
                        WizardPage.INFORMATION);
            } else {
                setMessage(null);
            }
        }

        setPageComplete(success);
        return success;