org.eclipse.acute.dotnetnew.DotnetNewWizardPage.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.acute.dotnetnew.DotnetNewWizardPage.java

Source

/*******************************************************************************
 * Copyright (c) 2017 Red Hat Inc. and others.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *  Mickael Istria (Red Hat Inc.) - Initial implementation
 *  Lucas Bullen   (Red Hat Inc.) - Logic implementation
 *******************************************************************************/
package org.eclipse.acute.dotnetnew;

import static org.eclipse.swt.events.SelectionListener.widgetSelectedAdapter;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Set;

import org.eclipse.acute.AcutePlugin;
import org.eclipse.acute.AcutePreferenceInitializer;
import org.eclipse.acute.AcutePreferencePage;
import org.eclipse.acute.Messages;
import org.eclipse.acute.dotnetnew.DotnetNewAccessor.Template;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.ICoreRunnable;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.jface.fieldassist.ControlDecoration;
import org.eclipse.jface.fieldassist.FieldDecorationRegistry;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.preference.PreferenceDialog;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ListViewer;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
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.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Link;
import org.eclipse.swt.widgets.List;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IWorkingSet;
import org.eclipse.ui.dialogs.PreferencesUtil;
import org.eclipse.ui.dialogs.WorkingSetGroup;
import org.osgi.framework.Bundle;
import org.osgi.framework.FrameworkUtil;

public class DotnetNewWizardPage extends WizardPage {

    private Set<IWorkingSet> workingSets;
    private File directory;
    private String projectName;
    private Boolean isDirectoryAndProjectLinked = true;

    private Text locationText;
    private Text projectNameText;
    private ListViewer templateViewer;
    private WorkingSetGroup workingSetsGroup;
    private Image linkImage;
    private Button linkButton;
    private ControlDecoration locationControlDecoration;
    private ControlDecoration projectNameControlDecoration;
    private ControlDecoration templateControlDecoration;
    private IPropertyChangeListener updateTemplatesListener;

    protected DotnetNewWizardPage() {
        super(DotnetNewWizardPage.class.getName());
        setTitle(Messages.DotnetNewWizardPage_createProject_title);
        setDescription(Messages.DotnetNewWizardPage_createProject_message);

        Bundle bundle = FrameworkUtil.getBundle(this.getClass());
        URL url = bundle.getEntry("images/dotnet.png"); //$NON-NLS-1$
        ImageDescriptor imageDescriptor = ImageDescriptor.createFromURL(url);
        setImageDescriptor(imageDescriptor);
    }

    public void setDirectory(File directory) {
        this.directory = directory;
    }

    public File getDirectory() {
        if (isDirectoryAndProjectLinked) {
            return directory;
        } else {
            return new File(directory.toString() + "/" + projectName); //$NON-NLS-1$
        }
    }

    public String getProjectName() {
        return projectName;
    }

    public @Nullable Template getTemplate() {
        IStructuredSelection selection = (IStructuredSelection) templateViewer.getSelection();
        if (templateViewer.getList().isEnabled() && selection.isEmpty()) {
            return null;
        }
        return (Template) selection.getFirstElement();
    }

    public IWorkingSet[] getWorkingSets() {
        return workingSetsGroup.getSelectedWorkingSets();
    }

    public void setWorkingSets(Set<IWorkingSet> workingSets) {
        this.workingSets = workingSets;
    }

    @Override
    public void createControl(Composite parent) {
        Composite container = new Composite(parent, SWT.NULL);
        setControl(container);
        container.setLayout(new GridLayout(4, false));

        Label locationLabel = new Label(container, SWT.NONE);
        locationLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
        locationLabel.setText(Messages.DotnetNewWizardPage_location);

        Image errorImage = FieldDecorationRegistry.getDefault()
                .getFieldDecoration(FieldDecorationRegistry.DEC_ERROR).getImage();

        locationText = new Text(container, SWT.BORDER);
        locationText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
        locationControlDecoration = new ControlDecoration(locationText, SWT.TOP | SWT.LEFT);
        locationControlDecoration.setImage(errorImage);
        locationControlDecoration.setShowOnlyOnFocus(true);
        locationText.addModifyListener(e -> {
            updateDirectory(locationText.getText());
            setPageComplete(isPageComplete());
        });

        Button browseButton = new Button(container, SWT.NONE);
        browseButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
        browseButton.setText(Messages.DotnetNewWizardPage_browse);
        browseButton.addSelectionListener(widgetSelectedAdapter(e -> {
            DirectoryDialog dialog = new DirectoryDialog(browseButton.getShell());
            String path = dialog.open();
            if (path != null) {
                updateDirectory(path);
            }
            setPageComplete(isPageComplete());
        }));
        Composite linesAboveLink = new Composite(container, SWT.NONE);
        GridData linesAboveLinkLayoutData = new GridData(SWT.FILL, SWT.FILL);
        linesAboveLinkLayoutData.heightHint = linesAboveLinkLayoutData.widthHint = 30;
        linesAboveLink.setLayoutData(linesAboveLinkLayoutData);
        linesAboveLink.addPaintListener(e -> {
            e.gc.setForeground(((Control) e.widget).getDisplay().getSystemColor(SWT.COLOR_DARK_GRAY));
            e.gc.drawLine(0, e.height / 2, e.width / 2, e.height / 2);
            e.gc.drawLine(e.width / 2, e.height / 2, e.width / 2, e.height);
        });

        new Label(container, SWT.NONE);
        new Label(container, SWT.NONE);
        new Label(container, SWT.NONE);

        linkButton = new Button(container, SWT.TOGGLE);
        linkButton.setToolTipText(Messages.DotnetNewWizardPage_linkNames);
        linkButton.setSelection(true);
        try (InputStream iconStream = getClass().getResourceAsStream("/icons/link_obj.png")) { //$NON-NLS-1$
            linkImage = new Image(linkButton.getDisplay(), iconStream);
            linkButton.setImage(linkImage);
        } catch (IOException e1) {
            AcutePlugin.logError(e1);
        }
        linkButton.addSelectionListener(widgetSelectedAdapter(s -> {
            isDirectoryAndProjectLinked = linkButton.getSelection();
            projectNameText.setEnabled(!linkButton.getSelection());
            updateProjectName();
        }));

        Label projectNameLabel = new Label(container, SWT.NONE);
        projectNameLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
        projectNameLabel.setText(Messages.DotnetNewWizardPage_projectName);

        projectNameText = new Text(container, SWT.BORDER);
        projectNameText.setEnabled(false);
        projectNameText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));
        projectNameControlDecoration = new ControlDecoration(projectNameText, SWT.TOP | SWT.LEFT);
        projectNameControlDecoration.setImage(errorImage);
        projectNameControlDecoration.setShowOnlyOnFocus(true);
        projectNameText.addModifyListener(e -> {
            updateProjectName();
            setPageComplete(isPageComplete());
        });
        Composite linesBelowLink = new Composite(container, SWT.NONE);
        GridData linesBelowLinkLayoutData = new GridData(SWT.FILL, SWT.FILL);
        linesBelowLinkLayoutData.heightHint = linesBelowLinkLayoutData.widthHint = 30;
        linesBelowLink.setLayoutData(linesAboveLinkLayoutData);
        linesBelowLink.addPaintListener(e -> {
            e.gc.setForeground(((Control) e.widget).getDisplay().getSystemColor(SWT.COLOR_DARK_GRAY));
            e.gc.drawLine(0, e.height / 2, e.width / 2, e.height / 2);
            e.gc.drawLine(e.width / 2, e.height / 2, e.width / 2, 0);
        });
        new Label(container, SWT.NONE).setLayoutData(new GridData(SWT.FILL, SWT.DEFAULT, true, false, 4, 1));

        Label projectTemplateLabel = new Label(container, SWT.NONE);
        projectTemplateLabel.setText(Messages.DotnetNewWizardPage_projectTemplate);

        List list = new List(container, SWT.V_SCROLL | SWT.BORDER);
        GridData listBoxData = new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1);
        list.setLayoutData(listBoxData);
        templateViewer = new ListViewer(list);
        templateViewer.setContentProvider(new ArrayContentProvider());
        templateViewer.setComparator(new ViewerComparator()); // default uses getLabel()/toString()
        templateViewer.addSelectionChangedListener(e -> {
            setPageComplete(isPageComplete());
        });
        templateControlDecoration = new ControlDecoration(templateViewer.getControl(), SWT.TOP | SWT.LEFT);
        templateControlDecoration.setImage(errorImage);
        updateTemplateList();

        //Update Template List with preferences change
        IPreferenceStore store = AcutePlugin.getDefault().getPreferenceStore();
        updateTemplatesListener = new IPropertyChangeListener() {
            @Override
            public void propertyChange(PropertyChangeEvent event) {
                if (event.getProperty().equals(AcutePreferenceInitializer.explicitDotnetPathPreference)) {
                    updateTemplateList();
                }
            }
        };
        store.addPropertyChangeListener(updateTemplatesListener);

        new Label(container, SWT.NONE);

        new Label(container, SWT.NONE);
        Link preferencesLink = new Link(container, SWT.NONE);
        preferencesLink.setText(Messages.DotnetNewWizardPage_dotnetPreferencesLink);
        preferencesLink.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 2, 1));
        preferencesLink.addSelectionListener(widgetSelectedAdapter(s -> Display.getDefault().asyncExec(() -> {
            PreferenceDialog preferenceDialog = PreferencesUtil.createPreferenceDialogOn(getShell(),
                    AcutePreferencePage.PAGE_ID, new String[] { AcutePreferencePage.PAGE_ID }, null);
            preferenceDialog.setBlockOnOpen(false);
            preferenceDialog.open();
        })));
        new Label(container, SWT.NONE).setLayoutData(new GridData(SWT.FILL, SWT.DEFAULT, true, false, 4, 1));

        Composite workingSetComposite = new Composite(container, SWT.NONE);
        GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, false, 4, 1);
        workingSetComposite.setLayoutData(layoutData);
        workingSetComposite.setLayout(new GridLayout(1, false));
        String[] workingSetIds = new String[] { "org.eclipse.ui.resourceWorkingSetPage" }; //$NON-NLS-1$
        IStructuredSelection wsSel = null;
        if (this.workingSets != null) {
            wsSel = new StructuredSelection(this.workingSets.toArray());
        }
        this.workingSetsGroup = new WorkingSetGroup(workingSetComposite, wsSel, workingSetIds);

        if (directory != null) {
            updateDirectory(directory.getAbsolutePath());
        }
    }

    private void updateTemplateList() {
        if (templateViewer.getList().isDisposed()) {
            return;
        }
        setTemplateViewToText(Messages.DotnetNewWizardPage_loadingTemplates);
        try {
            AcutePlugin.getDotnetCommand();
        } catch (IllegalStateException e) {
            setTemplateViewToText(Messages.DotnetNewWizardPage_dotnetError);
            return;
        }
        Job.create(Messages.DotnetNewWizardPage_retriveTemplates, (ICoreRunnable) monitor -> {
            final java.util.List<Template> templates = DotnetNewAccessor.getTemplates();
            Display.getDefault().asyncExec(() -> {
                templateViewer.getList().removeAll();
                if (!templates.isEmpty()) {
                    ((GridData) templateViewer.getList().getLayoutData()).heightHint = 100;
                    Shell shell = templateViewer.getControl().getShell();
                    shell.setSize(shell.getSize().x, shell.getSize().y + 100);
                    templateViewer.setInput(templates);
                    if (templateViewer.getSelection().isEmpty()) {
                        templateViewer.getList().setSelection(0);
                    }
                    templateViewer.getList().setEnabled(true);
                    setPageComplete(isPageComplete());
                } else {
                    templateViewer.add(Messages.DotnetNewWizardPage_noTemplatesError);
                }
                templateViewer.getControl().getParent().layout();
            });
        }).schedule();
    }

    private void setTemplateViewToText(String text) {
        Display.getDefault().asyncExec(() -> {
            if (templateViewer.getList().getItemCount() > 1) {
                ((GridData) templateViewer.getList().getLayoutData()).heightHint = SWT.DEFAULT;
                Shell shell = templateViewer.getControl().getShell();
                shell.setSize(shell.getSize().x, shell.getSize().y - 100);
            }
            templateViewer.getList().removeAll();
            templateViewer.add(text);
            templateViewer.getControl().getParent().layout();
            templateViewer.getList().setEnabled(false);
        });
    }

    private void updateProjectName() {
        if (!isDirectoryAndProjectLinked) {
            projectName = projectNameText.getText();
        } else if (projectName == null || (directory != null && !projectName.equals(directory.getName()))) {
            projectName = directory.getName();
            projectNameText.setText(projectName);
        }
    }

    private void updateDirectory(String directoryPath) {
        directory = new File(directoryPath);
        if (!locationText.getText().equals(directoryPath)) {
            locationText.setText(directoryPath);
        } else if (isDirectoryAndProjectLinked) {
            updateProjectName();
        }
    }

    @Override
    public boolean isPageComplete() {
        String locationError = ""; //$NON-NLS-1$
        String projectNameError = ""; //$NON-NLS-1$
        String templateError = ""; //$NON-NLS-1$
        if (directory == null || directory.getPath().isEmpty()) {
            locationError = Messages.DotnetNewWizardPage_directroyError_empty;
        } else if (projectName == null || projectName.isEmpty()) {
            projectNameError = Messages.DotnetNewWizardPage_projectError_empty;
        } else if (directory.isFile()) {
            locationError = Messages.DotnetNewWizardPage_locationError_existingFile;
        } else if (directory.getParentFile() == null
                || (!directory.exists() && !directory.getParentFile().canWrite())) {
            locationError = Messages.DotnetNewWizardPage_locationError_unableToCreate;
        } else if (directory.exists() && !directory.canWrite()) {
            locationError = Messages.DotnetNewWizardPage_locationError_unableToWrite;
        } else if (getTemplate() == null) {
            templateError = Messages.DotnetNewWizardPage_templateError_empty;
        } else {
            File dotProject = new File(directory, IProjectDescription.DESCRIPTION_FILE_NAME);
            if (dotProject.exists()) {
                IProjectDescription desc = null;
                try {
                    desc = ResourcesPlugin.getWorkspace()
                            .loadProjectDescription(Path.fromOSString(dotProject.getAbsolutePath()));
                } catch (CoreException e) {
                    projectNameError = Messages.DotnetNewWizardPage_projectError_invalidDotProjectFile;
                }
                if (!desc.getName().equals(projectName)) {
                    projectNameError = Messages.DotnetNewWizardPage_projectError_invalidNameMatch + desc.getName();
                }
            } else {
                IProject project = null;
                try {
                    project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);
                    if (project.exists() && (project.getLocation() == null || !directory.getAbsoluteFile()
                            .equals(project.getLocation().toFile().getAbsoluteFile()))) {
                        projectNameError = Messages.DotnetNewWizardPage_projectError_existingName;
                    }
                } catch (IllegalArgumentException ex) {
                    projectNameError = Messages.DotnetNewWizardPage_projectError_invalidName;
                }
            }
        }

        String error = locationError + projectNameError + templateError;

        if (error.isEmpty()) {
            setErrorMessage(null);
            projectNameControlDecoration.hide();
            locationControlDecoration.hide();
            templateControlDecoration.hide();
        } else {
            if (!locationError.isEmpty()) {
                locationControlDecoration.showHoverText(locationError);
                locationControlDecoration.show();
                projectNameControlDecoration.hide();
                templateControlDecoration.hide();
            } else if (!projectNameError.isEmpty()) {
                projectNameControlDecoration.showHoverText(projectNameError);
                projectNameControlDecoration.show();
                locationControlDecoration.hide();
                templateControlDecoration.hide();
            } else {
                templateControlDecoration.showHoverText(projectNameError);
                templateControlDecoration.show();
                locationControlDecoration.hide();
                projectNameControlDecoration.hide();
            }
            setErrorMessage(error);
        }
        return error.isEmpty();
    }

    @Override
    public void dispose() {
        super.dispose();
        this.linkImage.dispose();
        if (updateTemplatesListener != null) {
            IPreferenceStore store = AcutePlugin.getDefault().getPreferenceStore();
            store.removePropertyChangeListener(updateTemplatesListener);
        }
    }
}