net.sf.eclipsefp.haskell.debug.ui.internal.launch.HaskellArgumentsTab.java Source code

Java tutorial

Introduction

Here is the source code for net.sf.eclipsefp.haskell.debug.ui.internal.launch.HaskellArgumentsTab.java

Source

// Copyright (c) 2003-2008 by Leif Frenzel. All rights reserved.
// This code is made available under the terms of the Eclipse Public License,
// version 1.0 (EPL). See http://www.eclipse.org/legal/epl-v10.html
package net.sf.eclipsefp.haskell.debug.ui.internal.launch;

import java.io.File;
import net.sf.eclipsefp.haskell.debug.core.internal.launch.AbstractHaskellLaunchDelegate;
import net.sf.eclipsefp.haskell.debug.core.internal.launch.IInteractiveLaunchOperationDelegate;
import net.sf.eclipsefp.haskell.debug.core.internal.launch.ILaunchAttributes;
import net.sf.eclipsefp.haskell.debug.ui.internal.util.UITexts;
import net.sf.eclipsefp.haskell.ui.HaskellUIPlugin;
import net.sf.eclipsefp.haskell.ui.util.HaskellUIImages;
import net.sf.eclipsefp.haskell.ui.util.IImageNames;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.ui.AbstractLaunchConfigurationTab;
import org.eclipse.jface.dialogs.IDialogConstants;
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.events.SelectionListener;
import org.eclipse.swt.graphics.Font;
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.DirectoryDialog;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.dialogs.ContainerSelectionDialog;

/** <p>The arguments tab for configuring Haskell launch configurations.</p>
  *
  * @author Leif Frenzel
  */
public class HaskellArgumentsTab extends AbstractLaunchConfigurationTab {

    private Text txtWorkDirectory;
    private Button btnWorkingDirFile;
    private Button btnWorkingDirWorkspace;

    private Button runBackgroundButton;
    private Button syncStreamsButton;
    private Text argumentField;
    private Text fullArgumentField;

    private SelectionAdapter selectionAdapter;

    private String forcedArguments = ILaunchAttributes.EMPTY;

    private final ModifyListener modifyListener = new ModifyListener() {
        @Override
        public void modifyText(final ModifyEvent e) {
            updateLaunchConfigurationDialog();
        }
    };

    // interface methods of ILaunchConfigurationTab
    ///////////////////////////////////////////////

    @Override
    public void createControl(final Composite parent) {
        Composite mainComposite = new Composite(parent, SWT.NONE);
        setControl(mainComposite);

        GridLayout layout = new GridLayout();
        layout.numColumns = 2;
        GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
        mainComposite.setLayout(layout);
        mainComposite.setLayoutData(gridData);
        mainComposite.setFont(parent.getFont());
        createWorkDirectoryComponent(mainComposite);
        createArgumentComponent(mainComposite);
        createVerticalSpacer(mainComposite, 2);
        createRunBackgroundComponent(mainComposite);
        createSyncStreamsComponent(mainComposite);
    }

    @Override
    public void setDefaults(final ILaunchConfigurationWorkingCopy configWc) {
        configWc.setAttribute(ILaunchAttributes.RUN_IN_BACKGROUND, true);
        configWc.setAttribute(ILaunchAttributes.WORKING_DIRECTORY, ILaunchAttributes.EMPTY);
        configWc.setAttribute(ILaunchAttributes.EXTRA_ARGUMENTS, ILaunchAttributes.EMPTY);
        configWc.setAttribute(ILaunchAttributes.SYNC_STREAMS, true);
    }

    @Override
    public void initializeFrom(final ILaunchConfiguration configuration) {
        updateWorkingDirectory(configuration);
        updateArgument(configuration);
        updateRunBackground(configuration);
        updateSyncStreams(configuration);
    }

    @Override
    public void performApply(final ILaunchConfigurationWorkingCopy configWc) {
        String workingDirectory = txtWorkDirectory.getText().trim();
        if (workingDirectory.length() == 0) {
            configWc.setAttribute(ILaunchAttributes.WORKING_DIRECTORY, (String) null);
        } else {
            configWc.setAttribute(ILaunchAttributes.WORKING_DIRECTORY, workingDirectory);
        }

        setAttribute(ILaunchAttributes.RUN_IN_BACKGROUND, configWc, runBackgroundButton.getSelection(), true);

        setAttribute(ILaunchAttributes.SYNC_STREAMS, configWc, syncStreamsButton.getSelection(), true);

        String arguments = argumentField.getText().trim();
        if (arguments.length() == 0) {
            configWc.setAttribute(ILaunchAttributes.EXTRA_ARGUMENTS, (String) null);
        } else {
            configWc.setAttribute(ILaunchAttributes.EXTRA_ARGUMENTS, arguments);
        }
    }

    @Override
    public boolean isValid(final ILaunchConfiguration launchConfig) {
        setErrorMessage(null);
        setMessage(null);
        return validateWorkDirectory();
    }

    @Override
    public String getName() {
        return UITexts.haskellArgumentsTab_name;
    }

    @Override
    public Image getImage() {
        return HaskellUIImages.getImage(IImageNames.LAUNCH_TAB_ARGUMENTS);
    }

    @Override
    public boolean canSave() {
        return isValid(null);
    }

    // UI creation methods
    //////////////////////

    private void createWorkDirectoryComponent(final Composite parent) {
        Font font = parent.getFont();

        Composite composite = new Composite(parent, SWT.NONE);
        GridLayout layout = new GridLayout();
        layout.marginWidth = 0;
        layout.marginHeight = 0;
        layout.numColumns = 1;
        GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
        composite.setLayout(layout);
        composite.setLayoutData(gridData);

        Label label = new Label(composite, SWT.NONE);
        label.setText(UITexts.haskellArgumentsTab_workDir);
        label.setFont(font);

        txtWorkDirectory = new Text(composite, SWT.BORDER);
        GridData data = new GridData(GridData.FILL_HORIZONTAL);
        data.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH;
        txtWorkDirectory.setLayoutData(data);
        txtWorkDirectory.setFont(font);

        createButtonComposite(parent, font);
    }

    private void createButtonComposite(final Composite parent, final Font font) {
        Composite buttonComposite = new Composite(parent, SWT.NONE);
        GridLayout layout = new GridLayout();
        layout.marginWidth = 0;
        layout.marginHeight = 0;
        layout.numColumns = 1;

        GridData gridData = new GridData(GridData.HORIZONTAL_ALIGN_END);
        buttonComposite.setLayout(layout);
        buttonComposite.setLayoutData(gridData);
        buttonComposite.setFont(font);

        createVerticalSpacer(buttonComposite, 1);
        String browseWS = UITexts.haskellArgumentsTab_browseWs;
        btnWorkingDirWorkspace = createPushButton(buttonComposite, browseWS, null);
        btnWorkingDirWorkspace.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(final SelectionEvent evt) {
                handleWorkspaceWorkingDirectoryButtonSelected();
            }
        });
        String browseFs = UITexts.haskellArgumentsTab_browseFs;
        btnWorkingDirFile = createPushButton(buttonComposite, browseFs, null);
        btnWorkingDirFile.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(final SelectionEvent evt) {
                handleFileWorkingDirectoryButtonSelected();
            }
        });
    }

    private void createArgumentComponent(final Composite parent) {
        Font font = parent.getFont();

        Label label = new Label(parent, SWT.NONE);
        label.setText(UITexts.haskellArgumentsTab_lblArguments);
        GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
        data.horizontalSpan = 2;
        label.setLayoutData(data);
        label.setFont(font);

        int style = SWT.MULTI | SWT.WRAP | SWT.BORDER | SWT.V_SCROLL;
        argumentField = new Text(parent, style);
        data = new GridData(GridData.FILL_BOTH);
        data.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH;
        data.heightHint = 40;
        argumentField.setLayoutData(data);
        argumentField.setFont(font);
        argumentField.addModifyListener(modifyListener);

        Label instruction = new Label(parent, SWT.NONE);
        instruction.setText(UITexts.haskellArgumentsTab_noteQuote);
        data = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
        data.horizontalSpan = 2;
        instruction.setLayoutData(data);
        instruction.setFont(font);

        label = new Label(parent, SWT.NONE);
        label.setText(UITexts.haskellArgumentsTab_lblFullArguments);
        data = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
        data.horizontalSpan = 2;
        label.setLayoutData(data);
        label.setFont(font);

        style = SWT.MULTI | SWT.WRAP | SWT.BORDER | SWT.V_SCROLL | SWT.READ_ONLY;
        fullArgumentField = new Text(parent, style);
        data = new GridData(GridData.FILL_BOTH);
        data.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH;
        data.heightHint = 40;
        fullArgumentField.setLayoutData(data);
        fullArgumentField.setFont(font);

        argumentField.addModifyListener(new ModifyListener() {

            @Override
            public void modifyText(final ModifyEvent e) {
                fullArgumentField.setText(argumentField.getText() + " " + forcedArguments); //$NON-NLS-1$
            }
        });

    }

    private void createRunBackgroundComponent(final Composite parent) {
        runBackgroundButton = new Button(parent, SWT.CHECK);
        runBackgroundButton.setText(UITexts.haskellArgumentsTab_background);
        GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
        data.horizontalSpan = 2;
        runBackgroundButton.setLayoutData(data);
        runBackgroundButton.setFont(parent.getFont());
        runBackgroundButton.addSelectionListener(getSelectionAdapter());
    }

    private void createSyncStreamsComponent(final Composite parent) {
        syncStreamsButton = new Button(parent, SWT.CHECK);
        syncStreamsButton.setText(UITexts.haskellArgumentsTab_syncStreams);
        GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
        data.horizontalSpan = 2;
        syncStreamsButton.setLayoutData(data);
        syncStreamsButton.setFont(parent.getFont());
        syncStreamsButton.addSelectionListener(getSelectionAdapter());
    }

    // helping methods
    //////////////////

    private void updateWorkingDirectory(final ILaunchConfiguration config) {
        String workingDir = ILaunchAttributes.EMPTY;
        try {
            workingDir = config.getAttribute(ILaunchAttributes.WORKING_DIRECTORY, ILaunchAttributes.EMPTY);
        } catch (CoreException ce) {
            HaskellUIPlugin.log(UITexts.error_read_configuration, ce);
        }
        txtWorkDirectory.setText(workingDir);
        txtWorkDirectory.addModifyListener(modifyListener);
    }

    private void updateArgument(final ILaunchConfiguration configuration) {
        String arguments = ILaunchAttributes.EMPTY;
        String fullArguments = ILaunchAttributes.EMPTY;
        try {
            String att = ILaunchAttributes.EXTRA_ARGUMENTS;
            arguments = configuration.getAttribute(att, ILaunchAttributes.EMPTY);
            IInteractiveLaunchOperationDelegate delegate = AbstractHaskellLaunchDelegate.getDelegate(configuration);

            forcedArguments = InteractiveLaunchOperation.concatenate(
                    AbstractHaskellLaunchDelegate.getDelegateArguments(configuration, delegate, "run")); //$NON-NLS-1$
            //configuration.getAttribute( ILaunchAttributes.ARGUMENTS, ILaunchAttributes.EMPTY );
            fullArguments = arguments + " " + forcedArguments; //$NON-NLS-1$
        } catch (CoreException ce) {
            HaskellUIPlugin.log(UITexts.error_read_configuration, ce);
        }
        argumentField.setText(arguments);
        fullArgumentField.setText(fullArguments);

    }

    private void updateRunBackground(final ILaunchConfiguration config) {
        boolean runInBackground = true;
        try {
            runInBackground = config.getAttribute(ILaunchAttributes.RUN_IN_BACKGROUND, true);
        } catch (CoreException ce) {
            HaskellUIPlugin.log(UITexts.error_read_configuration, ce);
        }
        runBackgroundButton.setSelection(runInBackground);
    }

    private void updateSyncStreams(final ILaunchConfiguration config) {
        boolean syncStreams = true;
        try {
            syncStreams = config.getAttribute(ILaunchAttributes.SYNC_STREAMS, true);
        } catch (CoreException ce) {
            HaskellUIPlugin.log(UITexts.error_read_configuration, ce);
        }
        syncStreamsButton.setSelection(syncStreams);
    }

    /** validates the content of the working directory field. */
    private boolean validateWorkDirectory() {
        boolean result = true;
        String value = txtWorkDirectory.getText().trim();
        if (value.length() > 0) {
            File file = new File(value);
            if (!file.exists()) {
                setErrorMessage(UITexts.haskellArgumentsTab_noWorkDir);
                result = false;
            } else if (!file.isDirectory()) {
                String msg = UITexts.haskellArgumentsTab_noDir;
                setErrorMessage(NLS.bind(msg, file.toString()));
                result = false;
            }
        }
        return result;
    }

    /** prompts the user for a working directory location within the
      * workspace and sets the working directory. */
    private void handleWorkspaceWorkingDirectoryButtonSelected() {
        ContainerSelectionDialog containerDialog;
        IWorkspaceRoot wsRoot = ResourcesPlugin.getWorkspace().getRoot();
        String msg = UITexts.haskellArgumentsTab_selectDir;
        containerDialog = new ContainerSelectionDialog(getShell(), wsRoot, false, msg);
        containerDialog.open();
        Object[] resource = containerDialog.getResult();
        String text = null;
        if (resource != null && resource.length > 0) {
            IPath path = (IPath) resource[0];
            text = wsRoot.getLocation().append(path).toOSString();
        }
        if (text != null) {
            txtWorkDirectory.setText(text);
        }
    }

    private void handleFileWorkingDirectoryButtonSelected() {
        DirectoryDialog dialog = new DirectoryDialog(getShell(), SWT.SAVE);
        dialog.setMessage(UITexts.haskellArgumentsTab_selectDir);
        dialog.setFilterPath(txtWorkDirectory.getText());
        String text = dialog.open();
        if (text != null) {
            txtWorkDirectory.setText(text);
        }
    }

    private SelectionListener getSelectionAdapter() {
        if (selectionAdapter == null) {
            selectionAdapter = new SelectionAdapter() {
                @Override
                public void widgetSelected(final SelectionEvent e) {
                    updateLaunchConfigurationDialog();
                }
            };
        }
        return selectionAdapter;
    }
}