net.sourceforge.texlipse.wizards.TexlipseProjectCreationWizardPage.java Source code

Java tutorial

Introduction

Here is the source code for net.sourceforge.texlipse.wizards.TexlipseProjectCreationWizardPage.java

Source

/*
 * $Id$
 *
 * Copyright (c) 2004-2005 by the TeXlapse Team.
 * 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
 */
package net.sourceforge.texlipse.wizards;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.Arrays;
import java.util.Locale;

import net.sourceforge.texlipse.TexlipsePlugin;
import net.sourceforge.texlipse.builder.BuilderChooser;
import net.sourceforge.texlipse.properties.TexlipseProperties;
import net.sourceforge.texlipse.templates.ProjectTemplateManager;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.fieldassist.AutoCompleteField;
import org.eclipse.jface.fieldassist.TextContentAdapter;
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.DirectoryDialog;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.List;
import org.eclipse.swt.widgets.Text;

/**
 * Prefs-page on the project creation wizard.
 * 
 * @author kpkarlss
 */
public class TexlipseProjectCreationWizardPage extends TexlipseWizardPage {

    // textfield for project name
    private Text projectNameField;

    // project location, if not in workspace
    private Text projectLocationField;

    // textfield for language
    private Text languageField;

    // textfield for template preview
    private Text descriptionField;

    // template chooser
    private List templateList;

    // template type (system/user)
    private Label typeLabel;

    // output format / build order chooser
    private BuilderChooser outputChooser;

    private String workspacePath;

    /**
     * 
     * @param attributes Project attributes
     */
    public TexlipseProjectCreationWizardPage(TexlipseProjectAttributes attributes) {
        super(0, attributes);
    }

    /**
     * Create the layout of the page.
     * @param parent parent component in the UI
     * @return number of components using a status message
     */
    public void createComponents(Composite parent) {

        // path to the workspace root directory
        workspacePath = ResourcesPlugin.getWorkspace().getRoot().getLocation().addTrailingSeparator().toOSString();

        createProjectNameControl(parent);
        addSpacer(parent, 2);
        createProjectLocationControl(parent);
        addSpacer(parent, 2);
        createOutputFormatControl(parent);
        addSeparator(parent);
        addSpacer(parent, 2);
        createLabels(parent);
        createTemplateControl(parent);

        //this updates the template description area and the template type label
        updateEntries();
    }

    /**
     * @param parent parent component
     */
    private void createOutputFormatControl(Composite parent) {
        outputChooser = new BuilderChooser(parent);
        GridData ngd = new GridData(GridData.FILL_HORIZONTAL);
        ngd.horizontalSpan = 2;
        outputChooser.getControl().setLayoutData(ngd);
        outputChooser.setSelectedBuilder(
                TexlipsePlugin.getDefault().getPreferenceStore().getInt(TexlipseProperties.BUILDER_NUMBER));
        String o = attributes.getOutputFile();
        attributes.setOutputFile(o.substring(0, o.lastIndexOf('.') + 1) + outputChooser.getSelectedFormat());
        attributes.setOutputFormat(outputChooser.getSelectedFormat());
        outputChooser.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent event) {
                String o = attributes.getOutputFile();
                attributes
                        .setOutputFile(o.substring(0, o.lastIndexOf('.') + 1) + outputChooser.getSelectedFormat());
                attributes.setOutputFormat(outputChooser.getSelectedFormat());
                attributes.setBuilder(outputChooser.getSelectedBuilder());
            }
        });
    }

    /**
     * Create project name settings box.
     * @param composite the parent container
     */
    private void createProjectNameControl(Composite composite) {
        Composite c = new Composite(composite, SWT.NULL);
        c.setLayout(new GridLayout(2, false));
        GridData lgd = new GridData(GridData.FILL_HORIZONTAL);
        lgd.horizontalSpan = 2;
        c.setLayoutData(lgd);

        // add label
        Label label = new Label(c, SWT.LEFT);
        label.setText(TexlipsePlugin.getResourceString("projectWizardNameLabel"));
        label.setToolTipText(TexlipsePlugin.getResourceString("projectWizardNameTooltip"));
        label.setLayoutData(new GridData());

        // add text field
        projectNameField = new Text(c, SWT.SINGLE | SWT.BORDER);
        projectNameField.setText(attributes.getProjectName());
        projectNameField.setToolTipText(TexlipsePlugin.getResourceString("projectWizardNameTooltip"));
        projectNameField.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        projectNameField.addModifyListener(new ModifyListener() {
            public void modifyText(ModifyEvent e) {
                if (!projectNameField.isDisposed()) {
                    validateProjectName(projectNameField.getText());
                    if (!projectLocationField.isEnabled()) {
                        projectLocationField.setText(workspacePath + projectNameField.getText());
                    }
                }
            }
        });

        // add language label
        final Label mainLabel = new Label(c, SWT.LEFT);
        mainLabel.setText(TexlipsePlugin.getResourceString("propertiesLanguage"));
        mainLabel.setToolTipText(TexlipsePlugin.getResourceString("propertiesLanguageDescription"));
        mainLabel.setLayoutData(new GridData());

        // add text field
        languageField = new Text(c, SWT.SINGLE | SWT.BORDER);
        languageField.setText(attributes.getLanguageCode());
        languageField.setToolTipText(TexlipsePlugin.getResourceString("propertiesLanguageDescription"));
        languageField.setLayoutData(new GridData());
        new AutoCompleteField(languageField, new TextContentAdapter(), Locale.getISOLanguages());
        languageField.setTextLimit(2);
        languageField.addModifyListener(new ModifyListener() {
            public void modifyText(ModifyEvent e) {
                if (!languageField.isDisposed()) {
                    String text = languageField.getText();
                    IStatus status = createStatus(IStatus.OK, "");
                    //Has it exactly two characters
                    //Is this a valid language code
                    if (text.length() != 2 || Arrays.binarySearch(Locale.getISOLanguages(), text) < 0) {
                        status = createStatus(IStatus.WARNING,
                                TexlipsePlugin.getResourceString("projectWizardLanguageCodeError"));
                    }
                    attributes.setLanguageCode(text);
                    updateStatus(status, languageField);
                }
            }
        });
    }

    /**
     * Create project name settings box.
     * @param composite the parent container
     */
    private void createProjectLocationControl(Composite parent) {

        // create borders
        Group group = new Group(parent, SWT.NULL);
        group.setText(TexlipsePlugin.getResourceString("projectWizardLocationTitle"));
        group.setLayout(new GridLayout());
        GridData lgd = new GridData(GridData.FILL_HORIZONTAL);
        lgd.horizontalSpan = 2;
        group.setLayoutData(lgd);

        // add radioButtons
        final Button createLocalProjectButton = new Button(group, SWT.RADIO | SWT.LEFT);
        createLocalProjectButton.setLayoutData(new GridData());
        createLocalProjectButton.setText(TexlipsePlugin.getResourceString("projectWizardLocationLocal"));
        createLocalProjectButton.setSelection(true);
        createLocalProjectButton.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent event) {
                //Only execute if this field becomes selected
                if (!createLocalProjectButton.getSelection())
                    return;
                Control[] c = projectLocationField.getParent().getChildren();
                for (int i = 0; i < c.length; i++) {
                    c[i].setEnabled(false);
                }
                projectLocationField.setText(workspacePath + projectNameField.getText());
                attributes.setProjectLocation(null);
                updateStatus(createStatus(IStatus.OK, ""), projectLocationField);
            }
        });
        final Button createExternalProjectButton = new Button(group, SWT.RADIO | SWT.LEFT);
        createExternalProjectButton.setLayoutData(new GridData());
        createExternalProjectButton.setText(TexlipsePlugin.getResourceString("projectWizardLocationExternal"));
        createExternalProjectButton.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent event) {
                //Only execute if this field becomes selected
                if (!createExternalProjectButton.getSelection())
                    return;
                Control[] c = projectLocationField.getParent().getChildren();
                for (int i = 0; i < c.length; i++) {
                    c[i].setEnabled(true);
                }
                projectLocationField.setFocus();
                projectLocationField.setText("");
            }
        });

        Composite composite = new Composite(group, SWT.NULL);
        composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        GridLayout cgl = new GridLayout();
        cgl.numColumns = 3;
        composite.setLayout(cgl);

        // add location label
        Label label = new Label(composite, SWT.LEFT);
        label.setText(TexlipsePlugin.getResourceString("projectWizardLocationLabel"));
        label.setLayoutData(new GridData());
        label.setEnabled(false);

        // add location field
        projectLocationField = new Text(composite, SWT.SINGLE | SWT.BORDER);
        projectLocationField.setText(workspacePath);
        projectLocationField.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        projectLocationField.setEnabled(false);
        projectLocationField.addModifyListener(new ModifyListener() {
            public void modifyText(ModifyEvent e) {
                if (!projectLocationField.isDisposed() && projectLocationField.isEnabled()) {
                    validateProjectLocation(projectLocationField.getText());
                }
            }
        });

        Button browseLocationButton = new Button(composite, SWT.PUSH);
        browseLocationButton.setText(TexlipsePlugin.getResourceString("openBrowse"));
        browseLocationButton.setLayoutData(new GridData());
        browseLocationButton.setEnabled(false);
        browseLocationButton.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent event) {
                DirectoryDialog dialog = new DirectoryDialog(projectLocationField.getShell());
                dialog.setMessage(TexlipsePlugin.getResourceString("projectWizardLocationSelect"));
                dialog.setText(TexlipsePlugin.getResourceString("projectWizardLocationSelect"));
                String current = projectLocationField.getText();
                if (current == null || current.length() == 0) {
                    current = workspacePath;
                }
                dialog.setFilterPath(current);
                String dirStr = dialog.open();
                if (dirStr != null) {
                    File dir = new File(dirStr);
                    if (dir.exists() && dir.isDirectory()) {
                        projectLocationField.setText(dir.getAbsolutePath());
                    }
                }
            }
        });
    }

    /**
     * Check if the external project location is valid.
     * This method updates the status message for the project location.
     * @param text the path to project location
     */
    private void validateProjectLocation(String text) {
        IWorkspace workspace = ResourcesPlugin.getWorkspace();
        String pName = projectNameField.getText();
        //Project needs a name, otherwise an exception is thrown. The name is not important for path checking
        if ("".equals(pName))
            pName = "fdslajflj";
        IProject p = workspace.getRoot().getProject(pName);
        IStatus status = workspace.validateProjectLocation(p, new Path(text));
        if (status.getSeverity() == IStatus.OK) {
            attributes.setProjectLocation(text);
        }
        updateStatus(status, projectLocationField);
    }

    /**
     * Creates labels for the template list and the description text area 
     * to the given Composite object
     * 
     * @param composite the parent container
     */
    private void createLabels(Composite composite) {

        // add label for the list of templates
        Label label = new Label(composite, SWT.LEFT);
        label.setText(TexlipsePlugin.getResourceString("projectWizardTemplateListLabel"));
        label.setToolTipText(TexlipsePlugin.getResourceString("projectWizardTemplateListTooltip"));
        label.setLayoutData(new GridData());

        // add composite containing a label for the description area and templatetype (system/user) label
        Composite c = new Composite(composite, SWT.NONE);
        c.setLayout(new GridLayout(2, false));
        c.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

        // add label for the description area
        Label l = new Label(c, SWT.LEFT);
        l.setText(TexlipsePlugin.getResourceString("projectWizardTemplateDescriptionLabel"));
        l.setToolTipText(TexlipsePlugin.getResourceString("projectWizardTemplateDescriptionTooltip"));
        l.setLayoutData(new GridData());

        // add label for presenting the type of the selected template
        typeLabel = new Label(c, SWT.RIGHT);
        //Note that thetext of this label is set by updateEntries()
        typeLabel.setToolTipText(TexlipsePlugin.getResourceString("projectWizardTemplateTypeTooltip"));
        typeLabel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
    }

    /**
     * Creates a list element containing available templates (system and user)
     * and a text area next to it for showing description about the selected template
     * 
     * @param composite the parent container
     */
    private void createTemplateControl(Composite composite) {
        // add list for templates
        templateList = new List(composite, SWT.SINGLE | SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL);
        templateList.setItems(ProjectTemplateManager.loadTemplateNames());
        templateList.setLayoutData(new GridData(GridData.FILL_VERTICAL));
        templateList.setToolTipText(TexlipsePlugin.getResourceString("projectWizardTemplateTooltip"));
        templateList.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                attributes.setTemplate(templateList.getSelection()[0]);
                updateEntries();
            }
        });

        templateList.setSelection(0);
        // this has to be done, because setSelection() doesn't generate an event
        attributes.setTemplate(templateList.getItem(0));

        // add TextField for the selected template's description
        descriptionField = new Text(composite, SWT.MULTI | SWT.BORDER);
        descriptionField
                .setToolTipText(TexlipsePlugin.getResourceString("projectWizardTemplateDescriptionTooltip"));
        descriptionField.setLayoutData(new GridData(GridData.FILL_BOTH));
        descriptionField.setEditable(false);
    }

    /**
     * Updates the description text area and template type label 
     * 
     */
    private void updateEntries() {
        typeLabel.setText(templateType(attributes.getTemplate()));
        readProjectTemplateDescription(attributes.getTemplate());
    }

    /**
     * Returns the type of the given template.
     * 
     * @param template name of a template (should be the selected item from 
     *   the list element containing all available templates).
     * @return Either "User defined template" or "System defined template" depending
     *   wether the given template is found in plugins templates directory (former if not,
     *   latter if yes).
     */
    private String templateType(String template) {
        URL templateUrl = TexlipsePlugin.getDefault().getBundle()
                .getEntry("templates" + File.separator + template + ".tex");
        if (templateUrl == null)
            return "User defined template";
        else
            return "System template";
    }

    /**
     * Starts to read the given template (assuming it is found
     * from either plugins template directory or user's template directory...
     * if not, the description is set to "") and puts all lines
     * starting with "%%" (excluding "%%") to the description text area.
     * Reading is ended, when a line not starting wiht "%%" is encountered
     * or the end of file is reached.
     *  
     * @param template name of a template
     */
    private void readProjectTemplateDescription(String template) {
        //if system template, then it is found here
        URL templateUrl = TexlipsePlugin.getDefault().getBundle()
                .getEntry("templates" + File.separator + template + ".tex");
        String userTemplate = null;
        if (templateUrl == null) {
            //if not, then the template is user defined 
            File userTemplateFolder = ProjectTemplateManager.getUserTemplateFolder();
            userTemplate = userTemplateFolder.getAbsolutePath() + File.separator + template + ".tex";
        }

        try {
            String line = null;

            BufferedReader r;
            if (templateUrl != null)
                r = new BufferedReader(new InputStreamReader(templateUrl.openStream()));
            else
                r = new BufferedReader(new FileReader(userTemplate));
            StringBuffer sb = new StringBuffer();

            while ((line = r.readLine()) != null) {
                if (!line.startsWith("%%"))
                    break;
                if (line.length() > 2)
                    sb.append(line.substring(2));
                sb.append('\n');
            }

            r.close();
            sb.toString();
            descriptionField.setText(sb.toString());
        } catch (IOException e) {
            TexlipsePlugin.log("Reading a description of template file:", e);
            descriptionField.setText("");
        }
    }

    /**
     * Update the status line when the page becomes visible.
     */
    public void setVisible(boolean visible) {
        super.setVisible(visible);
        if (visible) {
            validateProjectName(projectNameField.getText());
        }
    }

    /**
     * Check if there already is a project under the given name.
     * @param text
     */
    private void validateProjectName(String text) {

        IWorkspace workspace = ResourcesPlugin.getWorkspace();
        IStatus status = workspace.validateName(text, IResource.PROJECT);

        if (status.isOK()) {
            if (workspace.getRoot().getProject(text).exists()) {
                status = createStatus(IStatus.ERROR, TexlipsePlugin.getResourceString("projectWizardNameError"));
            }
            attributes.setProjectName(text);
        }

        updateStatus(status, projectNameField);
    }
}